Shield Security for WordPress - Version 11.4.0

Version Description

Download this release

Release Info

Developer paultgoodchild
Plugin Icon 128x128 Shield Security for WordPress
Version 11.4.0
Comparing to
See all releases

Code changes from version 11.3.0 to 11.4.0

Files changed (322) hide show
  1. cl.json +56 -0
  2. icwp-wpsf.php +1 -1
  3. plugin-spec.php +4 -4
  4. readme.txt +73 -68
  5. resources/css/plugin.css +76 -3
  6. resources/images/bootstrap/award-fill.svg +4 -0
  7. resources/images/bootstrap/bar-chart-line-fill.svg +3 -0
  8. resources/images/bootstrap/bar-chart-line.svg +3 -0
  9. resources/images/bootstrap/diagram-3-fill.svg +3 -0
  10. resources/images/bootstrap/people-fill.svg +5 -0
  11. resources/images/bootstrap/people.svg +2 -2
  12. resources/images/bootstrap/person-badge-fill.svg +3 -0
  13. resources/images/bootstrap/puzzle.svg +3 -0
  14. resources/images/bootstrap/shield-fill.svg +3 -0
  15. resources/images/bootstrap/triangle-fill.svg +3 -0
  16. resources/js/plugin.js +24 -0
  17. src/config/feature-firewall.php +3 -0
  18. src/config/feature-hack_protect.php +2 -2
  19. src/config/feature-integrations.php +2 -2
  20. src/config/feature-ips.php +2 -1
  21. src/config/feature-plugin.php +13 -0
  22. src/config/feature-sessions.php +0 -1
  23. src/lib/src/Controller/Admin/AdminBarMenu.php +2 -2
  24. src/lib/src/Controller/Config/Ops/Save.php +1 -1
  25. src/lib/src/Controller/Controller.php +6 -6
  26. src/lib/src/Databases/Base/BaseQuery.php +38 -3
  27. src/lib/src/Databases/BotSignals/EntryVO.php +1 -0
  28. src/lib/src/Databases/Session/EntryVO.php +0 -1
  29. src/lib/src/Databases/Session/Insert.php +0 -1
  30. src/lib/src/Modules/Base/UI.php +3 -0
  31. src/lib/src/Modules/CommentsFilter/ModCon.php +5 -5
  32. src/lib/src/Modules/CommentsFilter/Processor.php +9 -12
  33. src/lib/src/Modules/CommentsFilter/Upgrade.php +8 -8
  34. src/lib/src/Modules/Firewall/Lib/Scan/Checks/ExeFiles.php +1 -1
  35. src/lib/src/Modules/Firewall/Lib/Scan/Checks/Standard.php +2 -2
  36. src/lib/src/Modules/Firewall/ModCon.php +1 -1
  37. src/lib/src/Modules/Firewall/Processor.php +3 -10
  38. src/lib/src/Modules/HackGuard/AjaxHandler.php +11 -13
  39. src/lib/src/Modules/HackGuard/Debug.php +2 -10
  40. src/lib/src/Modules/HackGuard/Lib/FileLocker/FileLockerController.php +20 -24
  41. src/lib/src/Modules/HackGuard/Lib/FileLocker/Ops/Accept.php +3 -3
  42. src/lib/src/Modules/HackGuard/Lib/FileLocker/Ops/AssessLocks.php +1 -1
  43. src/lib/src/Modules/HackGuard/Lib/FileLocker/Ops/BuildEncryptedFilePayload.php +7 -7
  44. src/lib/src/Modules/HackGuard/Lib/FileLocker/Ops/LoadFileLocks.php +1 -1
  45. src/lib/src/Modules/HackGuard/Lib/FileLocker/Ops/ReadOriginalFileContent.php +3 -3
  46. src/lib/src/Modules/HackGuard/Lib/Snapshots/Build/BuildHashesForAsset.php +23 -8
  47. src/lib/src/Modules/HackGuard/Lib/Snapshots/Build/BuildHashesFromApi.php +37 -34
  48. src/lib/src/Modules/HackGuard/Lib/Snapshots/Build/BuildHashesFromDir.php +30 -6
  49. src/lib/src/Modules/HackGuard/Lib/Snapshots/CrowdSourced/SubmitHashes.php +57 -0
  50. src/lib/src/Modules/HackGuard/Lib/Snapshots/FindAssetsToSnap.php +18 -15
  51. src/lib/src/Modules/HackGuard/Lib/Snapshots/Store.php +75 -99
  52. src/lib/src/Modules/HackGuard/Lib/Snapshots/StoreAction/BaseAction.php +7 -10
  53. src/lib/src/Modules/HackGuard/Lib/Snapshots/StoreAction/BaseBulk.php +1 -1
  54. src/lib/src/Modules/HackGuard/Lib/Snapshots/StoreAction/Build.php +3 -3
  55. src/lib/src/Modules/HackGuard/Lib/Snapshots/StoreAction/ScheduleBuildAll.php +20 -8
  56. src/lib/src/Modules/HackGuard/Lib/Snapshots/StoreAction/TouchAll.php +2 -2
  57. src/lib/src/Modules/HackGuard/ModCon.php +2 -2
  58. src/lib/src/Modules/HackGuard/Options.php +3 -3
  59. src/lib/src/Modules/HackGuard/Scan/Controller/Base.php +13 -10
  60. src/lib/src/Modules/HackGuard/Scan/Controller/Wpv.php +2 -2
  61. src/lib/src/Modules/HackGuard/Scan/Results/ConvertBetweenTypes.php +5 -5
  62. src/lib/src/Modules/HackGuard/Scan/ScansController.php +0 -21
  63. src/lib/src/Modules/HackGuard/Scan/Utilities/PtgAddReinstallLinks.php +3 -2
  64. src/lib/src/Modules/IPs/Lib/BlockRequest.php +1 -1
  65. src/lib/src/Modules/IPs/Lib/Bots/BotSignalsController.php +1 -2
  66. src/lib/src/Modules/IPs/Lib/Bots/Calculator/BaseBuildScores.php +1 -1
  67. src/lib/src/Modules/IPs/Lib/Bots/NotBot/NotBotHandler.php +1 -1
  68. src/lib/src/Modules/IPs/Lib/Bots/ShieldNET/BuildData.php +103 -0
  69. src/lib/src/Modules/IPs/Lib/IpAnalyse/BuildDisplay.php +25 -11
  70. src/lib/src/Modules/IPs/ModCon.php +1 -0
  71. src/lib/src/Modules/Insights/Lib/SideMenuBuilder.php +35 -35
  72. src/lib/src/Modules/Integrations/Lib/Bots/UserForms/Handlers/Buddypress.php +1 -1
  73. src/lib/src/Modules/License/AjaxHandler.php +4 -4
  74. src/lib/src/Modules/License/Lib/LicenseEmails.php +9 -10
  75. src/lib/src/Modules/License/Lib/LicenseHandler.php +5 -3
  76. src/lib/src/Modules/License/Lib/LookupRequest.php +1 -1
  77. src/lib/src/Modules/License/Lib/Verify.php +2 -2
  78. src/lib/src/Modules/License/Lib/WpHashes/ApiTokenManager.php +40 -47
  79. src/lib/src/Modules/License/WpCli.php +1 -1
  80. src/lib/src/Modules/LoginGuard/Lib/AntiBot/FormProviders/BuddyPress.php +3 -3
  81. src/lib/src/Modules/LoginGuard/Lib/AntiBot/FormProviders/UltimateMember.php +0 -3
  82. src/lib/src/Modules/LoginGuard/Lib/AntiBot/FormProviders/WordPress.php +5 -5
  83. src/lib/src/Modules/LoginGuard/Lib/TwoFactor/LoginIntentPage.php +31 -25
  84. src/lib/src/Modules/LoginGuard/Lib/TwoFactor/MfaController.php +51 -37
  85. src/lib/src/Modules/LoginGuard/Lib/TwoFactor/Provider/BackupCodes.php +1 -2
  86. src/lib/src/Modules/LoginGuard/Lib/TwoFactor/Provider/GoogleAuth.php +38 -14
  87. src/lib/src/Modules/LoginGuard/Lib/TwoFactor/Provider/Yubikey.php +1 -1
  88. src/lib/src/Modules/Plugin/AdminNotices.php +11 -11
  89. src/lib/src/Modules/Plugin/Debug.php +1 -1
  90. src/lib/src/Modules/Plugin/Insights/DashboardCards.php +1 -1
  91. src/lib/src/Modules/Plugin/Lib/ImportExport/Import.php +48 -48
  92. src/lib/src/Modules/Plugin/Lib/ImportExport/ImportExportController.php +54 -16
  93. src/lib/src/Modules/Plugin/Options.php +10 -2
  94. src/lib/src/Modules/Plugin/Processor.php +2 -15
  95. src/lib/src/Modules/Plugin/Strings.php +11 -4
  96. src/lib/src/Modules/Plugin/UI.php +2 -4
  97. src/lib/src/Modules/Plugin/WpCli.php +1 -1
  98. src/lib/src/Modules/Plugin/WpCli/Import.php +24 -34
  99. src/lib/src/Modules/SecurityAdmin/Strings.php +1 -1
  100. src/lib/src/Modules/Sessions/Processor.php +2 -1
  101. src/lib/src/Modules/Traffic/Strings.php +2 -2
  102. src/lib/src/Modules/UserManagement/Lib/Password/UserPasswordHandler.php +4 -4
  103. src/lib/src/Modules/UserManagement/Lib/Suspend/Base.php +1 -1
  104. src/lib/src/Modules/UserManagement/Suspend/Base.php +1 -1
  105. src/lib/src/Scans/Apc/ConvertVosToResults.php +6 -6
  106. src/lib/src/Scans/Apc/PluginScanner.php +14 -15
  107. src/lib/src/Scans/Apc/ResultsSet.php +1 -1
  108. src/lib/src/Scans/Apc/Utilities/ItemActionHandler.php +2 -2
  109. src/lib/src/Scans/Base/BaseConvertVosToResults.php +5 -5
  110. src/lib/src/Scans/Base/BaseResultsSet.php +29 -35
  111. src/lib/src/Scans/Base/DiffResultForStorage.php +5 -5
  112. src/lib/src/Scans/Base/Utilities/ItemActionHandler.php +23 -23
  113. src/lib/src/Scans/Base/Utilities/ItemActionHandlerAssets.php +12 -9
  114. src/lib/src/Scans/Mal/FileScanner.php +18 -31
  115. src/lib/src/Scans/Mal/ResultsSet.php +1 -1
  116. src/lib/src/Scans/Mal/Table/EntryFormatter.php +6 -21
  117. src/lib/src/Scans/Mal/Utilities/ItemActionHandler.php +3 -3
  118. src/lib/src/Scans/Mal/Utilities/Repair.php +4 -4
  119. src/lib/src/Scans/Ptg/FileScanner.php +106 -40
  120. src/lib/src/Scans/Ptg/ResultsSet.php +24 -24
  121. src/lib/src/Scans/Ptg/Utilities/ItemActionHandler.php +11 -11
  122. src/lib/src/Scans/Ptg/Utilities/Repair.php +28 -24
  123. src/lib/src/Scans/Ufc/ConvertVosToResults.php +6 -6
  124. src/lib/src/Scans/Ufc/ResultsSet.php +1 -1
  125. src/lib/src/Scans/Ufc/Utilities/ItemActionHandler.php +7 -7
  126. src/lib/src/Scans/Wcf/ConvertVosToResults.php +6 -6
  127. src/lib/src/Scans/Wcf/ResultsSet.php +1 -1
  128. src/lib/src/Scans/Wcf/Utilities/ItemActionHandler.php +3 -3
  129. src/lib/src/Scans/Wpv/BuildScanAction.php +7 -7
  130. src/lib/src/Scans/Wpv/ConvertVosToResults.php +9 -9
  131. src/lib/src/Scans/Wpv/ResultItem.php +3 -3
  132. src/lib/src/Scans/Wpv/ResultsSet.php +1 -1
  133. src/lib/src/Scans/Wpv/Scan.php +29 -31
  134. src/lib/src/Scans/Wpv/Utilities/ItemActionHandler.php +3 -3
  135. src/lib/src/Scans/Wpv/Utilities/Repair.php +7 -7
  136. src/lib/src/Scans/Wpv/WpVulnDb/VulnVO.php +42 -0
  137. src/lib/src/ShieldNetApi/Reputation/GetIPReputation.php +22 -0
  138. src/lib/src/ShieldNetApi/Reputation/SendIPReputation.php +20 -0
  139. src/lib/src/ShieldNetApi/ShieldNetApiController.php +54 -2
  140. src/lib/src/ShieldNetApi/ShieldNetApiDataVO.php +9 -8
  141. src/lib/src/ShieldNetApi/Tools/GenerateGoogleAuthQrCode.php +27 -0
  142. src/lib/src/ShieldNetApi/WPHashes/SolicitToken.php +24 -0
  143. src/lib/src/Tables/Build/ScanWpv.php +28 -28
  144. src/lib/src/Tables/Render/WpCliTable/AuditTrail.php +0 -1
  145. src/lib/src/Tables/Render/WpListTable/ScanWpv.php +33 -19
  146. src/lib/src/Tests/VerifyConfig.php +16 -16
  147. src/lib/src/Tests/VerifyUniqueEvents.php +2 -2
  148. src/lib/src/Users/ShieldUserMeta.php +1 -0
  149. src/lib/src/Utilities/Consumer/WpLoginCapture.php +16 -2
  150. src/lib/src/Utilities/Tool/TmpFileStore.php +48 -0
  151. src/lib/vendor/bacon/bacon-qr-code/Module.php +0 -37
  152. src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Common/AbstractEnum.php +0 -115
  153. src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Common/BitArray.php +0 -435
  154. src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Common/BitMatrix.php +0 -350
  155. src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Common/BitUtils.php +0 -51
  156. src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Common/CharacterSetEci.php +0 -134
  157. src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Common/EcBlock.php +0 -65
  158. src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Common/EcBlocks.php +0 -101
  159. src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Common/ErrorCorrectionLevel.php +0 -62
  160. src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Common/FormatInformation.php +0 -236
  161. src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Common/Mode.php +0 -70
  162. src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Common/ReedSolomonCodec.php +0 -476
  163. src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Common/Version.php +0 -687
  164. src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Encoder/BlockPair.php +0 -64
  165. src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Encoder/ByteMatrix.php +0 -158
  166. src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Encoder/Encoder.php +0 -687
  167. src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Encoder/MaskUtil.php +0 -291
  168. src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Encoder/MatrixUtil.php +0 -580
  169. src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Encoder/QrCode.php +0 -201
  170. src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Exception/ExceptionInterface.php +0 -14
  171. src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Exception/InvalidArgumentException.php +0 -14
  172. src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Exception/OutOfBoundsException.php +0 -14
  173. src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Exception/RuntimeException.php +0 -14
  174. src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Exception/UnexpectedValueException.php +0 -14
  175. src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Exception/WriterException.php +0 -14
  176. src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Color/Cmyk.php +0 -160
  177. src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Color/ColorInterface.php +0 -37
  178. src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Color/Gray.php +0 -84
  179. src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Color/Rgb.php +0 -148
  180. src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Image/AbstractRenderer.php +0 -338
  181. src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Image/Decorator/DecoratorInterface.php +0 -63
  182. src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Image/Decorator/FinderPattern.php +0 -210
  183. src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Image/Eps.php +0 -152
  184. src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Image/Png.php +0 -115
  185. src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Image/RendererInterface.php +0 -61
  186. src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Image/Svg.php +0 -146
  187. src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Renderer/RendererInterface.php +0 -26
  188. src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Text/Html.php +0 -91
  189. src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Text/Plain.php +0 -150
  190. src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Writer.php +0 -105
  191. src/lib/vendor/composer/autoload_classmap.php +23 -158
  192. src/lib/vendor/composer/autoload_files.php +0 -1
  193. src/lib/vendor/composer/autoload_namespaces.php +0 -1
  194. src/lib/vendor/composer/autoload_psr4.php +0 -4
  195. src/lib/vendor/composer/autoload_static.php +23 -192
  196. src/lib/vendor/endroid/qr-code/src/Bundle/QrCodeBundle/Controller/QrCodeController.php +0 -64
  197. src/lib/vendor/endroid/qr-code/src/Bundle/QrCodeBundle/DependencyInjection/Compiler/WriterRegistryCompilerPass.php +0 -36
  198. src/lib/vendor/endroid/qr-code/src/Bundle/QrCodeBundle/DependencyInjection/Configuration.php +0 -77
  199. src/lib/vendor/endroid/qr-code/src/Bundle/QrCodeBundle/DependencyInjection/EndroidQrCodeExtension.php +0 -34
  200. src/lib/vendor/endroid/qr-code/src/Bundle/QrCodeBundle/EndroidQrCodeBundle.php +0 -27
  201. src/lib/vendor/endroid/qr-code/src/Bundle/QrCodeBundle/Resources/config/routing.yml +0 -11
  202. src/lib/vendor/endroid/qr-code/src/Bundle/QrCodeBundle/Resources/config/services.yml +0 -31
  203. src/lib/vendor/endroid/qr-code/src/Bundle/QrCodeBundle/Resources/views/QrCode/twigFunctions.html.twig +0 -3
  204. src/lib/vendor/endroid/qr-code/src/ErrorCorrectionLevel.php +0 -20
  205. src/lib/vendor/endroid/qr-code/src/Exception/InvalidPathException.php +0 -14
  206. src/lib/vendor/endroid/qr-code/src/Exception/InvalidWriterException.php +0 -14
  207. src/lib/vendor/endroid/qr-code/src/Exception/MissingFunctionException.php +0 -14
  208. src/lib/vendor/endroid/qr-code/src/Exception/QrCodeException.php +0 -16
  209. src/lib/vendor/endroid/qr-code/src/Exception/UnsupportedExtensionException.php +0 -14
  210. src/lib/vendor/endroid/qr-code/src/Exception/ValidationException.php +0 -14
  211. src/lib/vendor/endroid/qr-code/src/Factory/QrCodeFactory.php +0 -120
  212. src/lib/vendor/endroid/qr-code/src/LabelAlignment.php +0 -19
  213. src/lib/vendor/endroid/qr-code/src/QrCode.php +0 -591
  214. src/lib/vendor/endroid/qr-code/src/QrCodeInterface.php +0 -95
  215. src/lib/vendor/endroid/qr-code/src/StaticWriterRegistry.php +0 -42
  216. src/lib/vendor/endroid/qr-code/src/Twig/Extension/QrCodeExtension.php +0 -117
  217. src/lib/vendor/endroid/qr-code/src/Writer/AbstractBaconWriter.php +0 -40
  218. src/lib/vendor/endroid/qr-code/src/Writer/AbstractWriter.php +0 -63
  219. src/lib/vendor/endroid/qr-code/src/Writer/BinaryWriter.php +0 -52
  220. src/lib/vendor/endroid/qr-code/src/Writer/DebugWriter.php +0 -58
  221. src/lib/vendor/endroid/qr-code/src/Writer/EpsWriter.php +0 -98
  222. src/lib/vendor/endroid/qr-code/src/Writer/PngWriter.php +0 -228
  223. src/lib/vendor/endroid/qr-code/src/Writer/SvgWriter.php +0 -92
  224. src/lib/vendor/endroid/qr-code/src/Writer/WriterInterface.php +0 -57
  225. src/lib/vendor/endroid/qr-code/src/WriterRegistry.php +0 -89
  226. src/lib/vendor/endroid/qr-code/src/WriterRegistryInterface.php +0 -34
  227. src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Base/BaseQuery.php +99 -57
  228. src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Delete.php +21 -4
  229. src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Handler.php +16 -3
  230. src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Insert.php +72 -11
  231. src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Record.php +11 -4
  232. src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Select.php +20 -14
  233. src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Update.php +16 -16
  234. src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Common/BuildColumnFromDef.php +80 -15
  235. src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Common/CreateTable.php +73 -0
  236. src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Common/Iterator.php +3 -3
  237. src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Common/TableSchema.php +44 -30
  238. src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Exceptions/ColumnDoesNotExistException.php +7 -0
  239. src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Utility/User/PluginMeta.php +101 -0
  240. src/lib/vendor/fernleafsystems/wordpress-services/src/Core/Db.php +66 -95
  241. src/lib/vendor/fernleafsystems/wordpress-services/src/Core/Plugins.php +54 -63
  242. src/lib/vendor/fernleafsystems/wordpress-services/src/Core/Themes.php +15 -13
  243. src/lib/vendor/fernleafsystems/wordpress-services/src/Core/VOs/Assets/WpBaseVo.php +75 -0
  244. src/lib/vendor/fernleafsystems/wordpress-services/src/Core/VOs/Assets/WpPluginVo.php +119 -0
  245. src/lib/vendor/fernleafsystems/wordpress-services/src/Core/VOs/Assets/WpThemeVo.php +138 -0
  246. src/lib/vendor/fernleafsystems/wordpress-services/src/Core/VOs/WpBaseVo.php +1 -0
  247. src/lib/vendor/fernleafsystems/wordpress-services/src/Core/VOs/WpPluginVo.php +2 -1
  248. src/lib/vendor/fernleafsystems/wordpress-services/src/Core/VOs/WpThemeVo.php +1 -0
  249. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Consumers/PluginConsumer.php +6 -13
  250. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/File/WriteDataToFileEncrypted.php +1 -1
  251. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/ApiBase.php +43 -46
  252. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/ApiPing.php +1 -5
  253. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/CrowdSourcedHashes/Base.php +8 -0
  254. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/CrowdSourcedHashes/Query/AssetHashesBase.php +27 -0
  255. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/CrowdSourcedHashes/Query/Plugin.php +14 -0
  256. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/CrowdSourcedHashes/Query/RequestVO.php +16 -0
  257. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/CrowdSourcedHashes/Query/Theme.php +14 -0
  258. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/CrowdSourcedHashes/Submit/BaseSubmit.php +30 -0
  259. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/CrowdSourcedHashes/Submit/PreSubmit.php +7 -0
  260. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/CrowdSourcedHashes/Submit/RequestVO.php +18 -0
  261. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/CrowdSourcedHashes/Submit/Submit.php +40 -0
  262. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/AssetHashesBase.php +11 -11
  263. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/Plugin.php +9 -0
  264. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/Theme.php +9 -0
  265. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Malware/Confidence/Retrieve.php +1 -1
  266. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Token/Solicit.php +6 -9
  267. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Verify/Email.php +1 -1
  268. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Vulnerabilities/Base.php +3 -2
  269. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Vulnerabilities/Plugin.php +4 -4
  270. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Vulnerabilities/RequestVO.php +1 -1
  271. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/PluginUserMeta.php +1 -0
  272. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Base/PluginThemeFilesBase.php +8 -8
  273. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Plugin/Base.php +7 -7
  274. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Plugin/Files.php +37 -37
  275. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Theme/Files.php +32 -32
  276. src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/Binarizer.php +0 -89
  277. src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/BinaryBitmap.php +0 -152
  278. src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/ChecksumException.php +0 -44
  279. src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/FormatException.php +0 -52
  280. src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/GDLuminanceSource.php +0 -173
  281. src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/IMagickLuminanceSource.php +0 -149
  282. src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/LuminanceSource.php +0 -159
  283. src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/NotFoundException.php +0 -38
  284. src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/PlanarYUVLuminanceSource.php +0 -172
  285. src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/QrReader.php +0 -84
  286. src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/RGBLuminanceSource.php +0 -310
  287. src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/Reader.php +0 -13
  288. src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/ReaderException.php +0 -48
  289. src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/Result.php +0 -128
  290. src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/ResultPoint.php +0 -140
  291. src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/common/AbstractEnum.php +0 -95
  292. src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/common/BitArray.php +0 -394
  293. src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/common/BitMatrix.php +0 -424
  294. src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/common/BitSource.php +0 -112
  295. src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/common/CharacterSetEci.php +0 -154
  296. src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/common/DecoderResult.php +0 -109
  297. src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/common/DefaultGridSampler.php +0 -89
  298. src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/common/DetectorResult.php +0 -47
  299. src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/common/GlobalHistogramBinarizer.php +0 -206
  300. src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/common/GridSampler.php +0 -177
  301. src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/common/HybridBinarizer.php +0 -259
  302. src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/common/PerspectiveTransform.php +0 -161
  303. src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/common/customFunctions.php +0 -93
  304. src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/common/detector/MathUtils.php +0 -46
  305. src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/common/detector/MonochromeRectangleDetector.php +0 -225
  306. src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/common/reedsolomon/GenericGF.php +0 -181
  307. src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/common/reedsolomon/GenericGFPoly.php +0 -268
  308. src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/common/reedsolomon/ReedSolomonDecoder.php +0 -192
  309. src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/common/reedsolomon/ReedSolomonException.php +0 -31
  310. src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/QRCodeReader.php +0 -222
  311. src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/BitMatrixParser.php +0 -250
  312. src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/DataBlock.php +0 -123
  313. src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/DataMask.php +0 -175
  314. src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/DecodedBitStreamParser.php +0 -359
  315. src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/Decoder.php +0 -214
  316. src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/ErrorCorrectionLevel.php +0 -86
  317. src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/FormatInformation.php +0 -179
  318. src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/Mode.php +0 -118
  319. src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/Version.php +0 -619
  320. src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/detector/AlignmentPattern.php +0 -60
  321. src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/detector/AlignmentPatternFinder.php +0 -277
  322. src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/detector/Detector.php +0 -195
cl.json CHANGED
@@ -1,4 +1,54 @@
1
  {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  "11.3": {
3
  "version": "11.3",
4
  "released_at": 1623057021,
@@ -43,6 +93,12 @@
43
  "404s encountered for requests for assets such as images, javascript and CSS no longer trigger offenses.",
44
  "The 1 exception is if the asset URL is within a plugin/theme directory that doesn't exist on the site."
45
  ]
 
 
 
 
 
 
46
  }
47
  ]
48
  },
1
  {
2
+ "11.4": {
3
+ "version": "11.4",
4
+ "released_at": 1625560514,
5
+ "hrefs": {
6
+ "release": "https://shsec.io/shieldrelease114",
7
+ "upgrade": "https://shsec.io/shieldupgradeguide114"
8
+ },
9
+ "title": "ShieldNET Integration",
10
+ "description": [
11
+ ],
12
+ "items": [
13
+ {
14
+ "type": "new",
15
+ "pro_only": false,
16
+ "title": "Begin ShieldNET Integration To Provide Network Intelligence For Bots & IP Addresses",
17
+ "description": [
18
+ "You can now start to see ShieldNET scores for IP addresses based on the cumulative intelligence gathered for IP addresses.",
19
+ "By combining scores for IP addresses across many different Shield Security installations we can provide a more accurate IP reputation score.",
20
+ "These scores won't be used yet to respond to threats on your WordPress site, but this will be the goal."
21
+ ]
22
+ },
23
+ {
24
+ "type": "improved",
25
+ "pro_only": false,
26
+ "title": "Generating QR codes for Google Authenticator is improved by using the ShieldNET API.",
27
+ "description": [
28
+ "The code necessary to generate QR Code for Google Authenticator is quite large and required the GD extension to be enabled.",
29
+ "Not all WordPress installation offer this, so we've provided a ShieldNET API endpoint to easily generate the QR codes."
30
+ ]
31
+ },
32
+ {
33
+ "type": "improved",
34
+ "pro_only": true,
35
+ "title": "Scanning for vulnerability in WordPress plugins and themes is improved.",
36
+ "description": []
37
+ },
38
+ {
39
+ "type": "improved",
40
+ "pro_only": false,
41
+ "title": "Capturing and managing of user sessions is improved.",
42
+ "description": []
43
+ },
44
+ {
45
+ "type": "improved",
46
+ "pro_only": false,
47
+ "title": "Capturing and managing user 2-Factor Authentication is improved.",
48
+ "description": []
49
+ }
50
+ ]
51
+ },
52
  "11.3": {
53
  "version": "11.3",
54
  "released_at": 1623057021,
93
  "404s encountered for requests for assets such as images, javascript and CSS no longer trigger offenses.",
94
  "The 1 exception is if the asset URL is within a plugin/theme directory that doesn't exist on the site."
95
  ]
96
+ },
97
+ {
98
+ "type": "changed",
99
+ "pro_only": false,
100
+ "title": "Minimum supported WordPress version is now 3.7",
101
+ "description": []
102
  }
103
  ]
104
  },
icwp-wpsf.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: Shield Security
4
  * Plugin URI: https://shsec.io/2f
5
  * Description: Powerful, Easy-To-Use #1 Rated WordPress Security System
6
- * Version: 11.3.0
7
  * Text Domain: wp-simple-firewall
8
  * Domain Path: /languages
9
  * Author: Shield Security
3
  * Plugin Name: Shield Security
4
  * Plugin URI: https://shsec.io/2f
5
  * Description: Powerful, Easy-To-Use #1 Rated WordPress Security System
6
+ * Version: 11.4.0
7
  * Text Domain: wp-simple-firewall
8
  * Domain Path: /languages
9
  * Author: Shield Security
plugin-spec.php CHANGED
@@ -1,8 +1,8 @@
1
  {
2
  "properties": {
3
- "version": "11.3.0",
4
- "release_timestamp": 1623057021,
5
- "build": "202106.0701",
6
  "slug_parent": "icwp",
7
  "slug_plugin": "wpsf",
8
  "human_name": "Shield Security",
@@ -20,7 +20,7 @@
20
  },
21
  "requirements": {
22
  "php": "7.0",
23
- "wordpress": "3.5.2"
24
  },
25
  "upgrade_reqs": {
26
  "10.0": {
1
  {
2
  "properties": {
3
+ "version": "11.4.0",
4
+ "release_timestamp": 1625560514,
5
+ "build": "202107.0601",
6
  "slug_parent": "icwp",
7
  "slug_plugin": "wpsf",
8
  "human_name": "Shield Security",
20
  },
21
  "requirements": {
22
  "php": "7.0",
23
+ "wordpress": "3.7"
24
  },
25
  "upgrade_reqs": {
26
  "10.0": {
readme.txt CHANGED
@@ -4,24 +4,37 @@ Donate link: https://shsec.io/bw
4
  License: GPLv3
5
  License URI: http://www.gnu.org/licenses/gpl.html
6
  Tags: scan, malware, firewall, two factor authentication, login protection
7
- Requires at least: 3.5.2
8
  Requires PHP: 7.0
9
  Recommended PHP: 7.4
10
- Tested up to: 5.7
11
- Stable tag: 11.3.0
12
- Security against hackers and brute force bots with firewall, login security hiding and hardening, Antispam, Audit Trail, Live Traffic, and much more...
 
13
 
14
  == Description ==
15
 
16
- Add expert security to all your WordPress sites with Shield Security, without being a security expert.
 
 
 
 
17
 
18
  #### Get the highest rated 5* Security Plugin for WordPress
19
 
20
  Per download, Shield Security [has the highest 5* rating](https://shsec.io/jl) in the WordPress plugin repository.
21
 
22
- ## Your Goal: Security Is Peace Of Mind and Freedom From Hackers
 
 
 
 
23
 
24
- To be free from hackers, your WordPress Security need to be smarter, adaptive and uncomplicated.
 
 
 
 
25
 
26
  Shield's goal is to help you become free from repetitive and complicated security work, allowing you to *re-focus and re-dedicate yourself to the work you love to do*.
27
 
@@ -36,13 +49,13 @@ Shield Security uses 2 simple key strategies to protect your WordPress sites:
36
 
37
  Bots cause nearly all our security troubles - they're relentless, automatic and powerful.
38
 
39
- Shield Security is the only plugin dedicated to their detection and erradication from your WordPress site.
40
 
41
- Blocking malicious bots before they can do damage is the key strategy to protect and enhance security on a WordPress site.
42
 
43
- Shield uses its features to detect these malicious visitors, then block access to your site altogether. This involves analysing different bot-signals and combining them to confidently identify a visitor as malicious.
44
 
45
- These signals include:
46
 
47
  * site probes that generate 404 errors
48
  * failed logins
@@ -51,13 +64,13 @@ These signals include:
51
  * fake search engine web crawlers
52
  * invalid user agents
53
  * excessive website requests and resource abuse
54
- * and many more signals our security team have identified...
55
 
56
- Early identification and blocking of malicious bots reduces your WordPress site's vulnerability to attack.
57
 
58
  #### Key Strategy #2: Hacking Cure
59
 
60
- Sometimes, even with best security efforts, a site can get hacked. This usually involves file modification: either a hack file is added, or a file is changed.
61
 
62
  There are 3 key WordPress assets whose files can be hacked:
63
 
@@ -69,13 +82,13 @@ Almost every security plugin can now do #1 - it's easy because WordPress.org pro
69
 
70
  But, there are no hashes available for plugins and themes, so they can't do it.
71
 
72
- Shield, however, is **the only WordPress security plugin** that offers full and accurate detection of file modifications for plugins and themes because we **build our own file fingerprints**.
73
 
74
- Shield can compare the file contents of every plugin & theme in the WordPress.org repository, looking for changed or new files
75
 
76
  And, if you're a ShieldPRO client, you can protect premium plugins/themes too, including Yoast SEO and Advanced Custom Fields Pro.
77
 
78
- Where possible, Shield will repair any unrecognised or modified files it detects in those 3 key WordPress areas.
79
 
80
  #### Shield makes Security for WordPress easy
81
 
@@ -90,42 +103,42 @@ Shield Security handles many problems for you, making intelligent security decis
90
 
91
  #### WordPress Security Features You'll Absolutely Love
92
 
93
- * Exclusive [AntiBot Detection Engine](https://shsec.io/ju) - The most powerful Bot Detection system on any WordPress plugin.
94
  * [Automatic Bot & IP Blocking](https://shsec.io/j0) - points-based security system to block bad bots.
95
  * Add Security To Important Forms To Block Bots:
96
- * Login
97
- * Registration
98
- * Password Reset
99
- * [ShieldPRO] WooCommerce & Easy Digital Downloads
100
- * [ShieldPRO] Memberpress, LearnPress, BuddyPress, WP Members, ProfileBuilder
101
- * [Brute Force Protection, Limit Login Attempts + Login Cooldown System](https://shsec.io/iw)
102
  * Powerful Firewall Security Rules
103
  * Restricted Security Admin Access
104
  * [Prevents Unauthorized Changes To Site Even By Admins](https://shsec.io/ix).
105
- * (MFA) [Two-Factor / Multi-Factor Login Authentication](https://shsec.io/iy):
106
  * Email
107
  * Google Authenticator
108
  * Yubikey
109
- * [ShieldPRO] U2F Keys
110
- * [ShieldPRO] Backup Login Codes
111
  * [ShieldPRO] Multiple Yubikey per User
112
  * [ShieldPRO] Remember Me (reduces 2FA requests for users)
113
  * [Block XML-RPC](https://shsec.io/iz) (*including* Pingbacks and Trackbacks)
114
  * Block Anonymous Rest API
115
  * Block, Bypass and Analyse IP Addresses
116
- * [Automatic IP Address Blocking Using Points-Based/Offenses System](https://shsec.io/j0)
117
  * Block or Bypass individual IPs
118
  * Block or Bypass IP Subnets
119
- * Full IP Analysis in 1 place to see their activity on your sites
120
- * Comprehensive WordPress File Scanner for Intrusions and Hacks
121
  * Detect File Changes - [Scan & Repair WordPress Core Files](https://shsec.io/j1)
122
  * [Detect Unknown/Suspicious PHP Files](https://shsec.io/j2)
123
  * Detect Abandoned Plugins.
124
- * [ShieldPRO] Malware Scanner - detects known and unknown malware.
125
- * [ShieldPRO] Plugin and Theme file scanning - identify file changes in your plugins/themes.
126
- * [ShieldPRO] Detect Plugins/Themes With Known Vulnerabilities.
127
- * [Create a **Custom Login URL** by hiding wp-login.php](https://shsec.io/j3)
128
- * Detect (and optionally Block) [Comment SPAM from Bots and Humans](https://shsec.io/jf).
129
  * reCAPTCHA & [hCAPTCHA](https://shsec.io/j4) support
130
  * **Never Block Google**: Automatic Detection and Bypass for GoogleBot, Bing and other Official Search Engines including:
131
  * Google
@@ -140,12 +153,12 @@ Shield Security handles many problems for you, making intelligent security decis
140
  * Pingdom, NodePing, Statuscake, UptimeRobot, GTMetrix
141
  * Stripe, PayPal IPN
142
  * CloudFlare, SEMRush
143
- * Full Audit Trail - [Monitor **All** Site Activity, including](https://shsec.io/j5):
144
  * All login/registration attempts
145
  * Plugin and Theme installation, activation, deactivation etc.
146
  * User creation and promotion
147
  * Page/Post create, update, delete
148
- * Advanced User Sessions Control
149
  * Restrict Multiple User Login
150
  * Restrict Users Session To IP
151
  * Block Use Of Pwned Passwords
@@ -166,8 +179,7 @@ Discover all the advantages of switching your WordPress security Pro at [our Shi
166
 
167
  == Installation ==
168
 
169
- Note: When you enable the plugin, the firewall is not automatically turned on. This plugin contains various different sections of
170
- protection for your site and you should choose which you need based on your own requirements.
171
 
172
  Why do we do this? It's simple: performance and optimization - there is no reason to automatically turn on features for people that don't
173
  need it as each site and set of requirements is different.
@@ -183,28 +195,27 @@ A new menu item will appear on the left-hand side called 'Shield'.
183
 
184
  == Frequently Asked Questions ==
185
 
186
- Please see the dedicated [help centre](https://shsec.io/firewallhelp) for details on features and some FAQs.
187
 
188
- = How does the Shield compare with other WordPress Security Plugins? =
189
 
190
  Easy - we're just better! ;)
191
 
192
- Firstly, we don't modify a single core WordPress or web hosting file. This is important and explains why randomly you upgrade your security plugin and your site dies.
193
 
194
  Ideally you shouldn't use this along side other Anti-SPAM plugins or security plugins. If there is a feature you need, please feel free to suggest it in the support forums.
195
 
196
- = My server has a firewall, why do I need this plugin? =
197
 
198
- This plugin is an application layer firewall, not a server/network firewall. It is designed to interpret web calls to your site to look for attempts to circumvent it and gain unauthorized access.
199
 
200
- Your network firewall is designed to restrict access to your server based on certain types of network traffic. The Shield
201
- is designed to restrict access to your site, based on certain type of web calls.
202
 
203
- = How does the IP Whitelist work? =
204
 
205
- Any IP address that is on the whitelist will not be subject to **any of the firewall processing**. This setting takes priority over all other settings.
206
 
207
- = Does the IP Whitelist support IP ranges? =
208
 
209
  Yes. To specify a range you use CIDR notation. E.g. ABC.DEF.GHJ.KMP/16
210
 
@@ -221,7 +232,7 @@ This happens when any the following 3 conditions are met:
221
  * you have added your IP address to the firewall blacklist,
222
  * you have enabled 2 factor authentication and email doesn't work on your site (and you haven't chosen the override option)
223
 
224
- You can completely turn OFF (and ON) the Shield by creating a special file in the plugin folder.
225
 
226
  Here's how:
227
 
@@ -246,7 +257,7 @@ It is a comma-separated list of pages and parameters. A NEW LINE should be taken
246
 
247
  The first entry on each line (before the first comma) is the page name. The rest of the items on the line are the parameters.
248
 
249
- The following are some simple examples to illustrate:
250
 
251
  **edit.php, featured**
252
 
@@ -262,11 +273,11 @@ be excluded from the firewall processing.
262
  Putting a star first means that these exclusions apply to all pages. So for every page that is accessed, all the parameters
263
  that are url, param and password will be ignored by the firewall.
264
 
265
- = How does the login cooldown work? =
266
 
267
- Login Cooldown prevents more than 1 login attempt to your site every "so-many" seconds. So if you enable a login cooldown of 60 seconds, only 1 login attempt will be processed every 60 seconds. If you login incorrectly, you wont be able to attempt another login for a further 60 seconds.
268
 
269
- This system completely blocks any level of brute-force login attacks and a cooldown of just 1 second goes a long way.
270
 
271
  [More Info](https://shsec.io/2t)
272
 
@@ -274,7 +285,7 @@ This system completely blocks any level of brute-force login attacks and a coold
274
 
275
  This is best [described on the blog](https://shsec.io/2u)
276
 
277
- = How does the 2-factor authentication work? =
278
 
279
  2-Factor Authentication [is best described here](https://shsec.io/2v).
280
 
@@ -293,11 +304,11 @@ You can either manually upgrade, or WordPress will handle it in due course.
293
 
294
  = I'm getting large volumes of comment SPAM. How can I stop this? =
295
 
296
- You can block 100% of automated spam bots and also block and analyse human-generated spam. [This is best described here](https://shsec.io/jg).
297
 
298
  = Do you offer White Label? =
299
 
300
- Yes, we do. You can essentially rename the Shield plugin to whatever you would like it to be.
301
 
302
  It ensures a more consistent brand offering and presents your business offering as a more holistic, integrated solution.
303
 
@@ -307,19 +318,13 @@ We go into [further detail here](https://shsec.io/jh).
307
 
308
  You can use our custom [templates for this purpose](https://shsec.io/ji).
309
 
310
- = How can I remove the WordPress admin footer message that displays my IP address? =
311
-
312
- You can add some custom code to your functions.php exactly as the following:
313
-
314
- `add_filter( 'icwp_wpsf_print_admin_ip_footer', '__return_false' );`
315
-
316
- = How can I change the text/html in the Plugin Badge? =
317
 
318
  Use the following filter and return the HTML/Text you wish to display:
319
 
320
  `add_filter( 'icwp_shield_plugin_badge_text', 'your_function_to_return_text' );`
321
 
322
- = How can I change the roles for login notification emails? =
323
 
324
  Use the following filter and return the role in the function:
325
 
@@ -327,7 +332,7 @@ Use the following filter and return the role in the function:
327
 
328
  Possible options are: network_admin, administrator, editor, author, contributor, subscriber
329
 
330
- = What changes go into each Shield version? =
331
 
332
  The changelog outlines the main changes for each release. We group changes by minor release "Series". Changes in smaller "point" releases are highlighted
333
  using **(.1)** notation. So for example, version 10.1**.1** will have changelog items appended with **(.1)**
@@ -344,11 +349,11 @@ You can view the entire [Shield changelog here](https://shsec.io/shieldwporgfull
344
 
345
  == Changelog ==
346
 
347
- The full Shield Changelog can be viewed from our home page:
348
 
349
  #### [Full Shield Security Changelog](https://shsec.io/shieldwporgfullchangelog)
350
 
351
  ShieldPRO delivers exclusive security features to the serious site administrator to maximise site security
352
- You'll also have direct access to our technical support team.
353
 
354
  [Go Pro](https://shsec.io/aa) or grab the [free ShieldPRO Trial](https://shsec.io/shieldfreetrialwporgreadme).
4
  License: GPLv3
5
  License URI: http://www.gnu.org/licenses/gpl.html
6
  Tags: scan, malware, firewall, two factor authentication, login protection
7
+ Requires at least: 3.7
8
  Requires PHP: 7.0
9
  Recommended PHP: 7.4
10
+ Tested up to: 5.8
11
+ Stable tag: 11.4.0
12
+
13
+ No-Nonsense Security Hardening that protects you against hackers, malicious bots, spammers (no captchas!). Now with exclusive ShieldNET Technology.
14
 
15
  == Description ==
16
 
17
+ Shield is the only NO-nonsense security solution that defends and protects your WordPress sites against hackers and malicious bots of all types. With our exclusive, *no-need-for-captcha* security technology you can limit login attempts, block brute force attacks and prevent 100% bot comment SPAM.
18
+
19
+ Shield Security automatically blocks bad IP addresses while optimising performance so your WordPress site never slows down because of security with large IP lookup tables .
20
+
21
+ ShieldNET is our new and exclusive network-based intelligence platform that draws-in information from all around the globe to help Shield Security plugins be smarter when assessing security threats and taking appropriate action.
22
 
23
  #### Get the highest rated 5* Security Plugin for WordPress
24
 
25
  Per download, Shield Security [has the highest 5* rating](https://shsec.io/jl) in the WordPress plugin repository.
26
 
27
+ ## Leave Behind the Security Marketing Hype and Scare Mongering
28
+
29
+ Our Security solution isn't designed to scare you and make you feel unsafe.
30
+
31
+ Shield simply provide powerful WordPress security without the marketing hype and noise.
32
 
33
+ Shield Security makes intelligent decisions to protect your site and maintain your site security and integrity, so you don't have to.
34
+
35
+ ## Your Goal: Peace Of Mind and Freedom From Hackers
36
+
37
+ To stay protected, your WordPress Security must to be smarter, and uncomplicated. Shield Security is the only WordPress security plugin that can detect the #1 cause of WordPress security hacking - Bad Bots.
38
 
39
  Shield's goal is to help you become free from repetitive and complicated security work, allowing you to *re-focus and re-dedicate yourself to the work you love to do*.
40
 
49
 
50
  Bots cause nearly all our security troubles - they're relentless, automatic and powerful.
51
 
52
+ Shield Security is the only plugin dedicated to their detection and eradication from your WordPress site.
53
 
54
+ Blocking malicious bots before they do damage is the key security strategy to protect and enhance security on a WordPress site.
55
 
56
+ Shield detects these malicious visitors, then blocks their access to your site completely. This involves analysing different security bot-signals and combining them to identify a visitor as malicious.
57
 
58
+ These security signals include:
59
 
60
  * site probes that generate 404 errors
61
  * failed logins
64
  * fake search engine web crawlers
65
  * invalid user agents
66
  * excessive website requests and resource abuse
67
+ * and many more signals our security team have identified.
68
 
69
+ Early identification and blocking of malicious bots reduces your WordPress site's vulnerability to any sort of attack.
70
 
71
  #### Key Strategy #2: Hacking Cure
72
 
73
+ Even with best security efforts, a site can get hacked. This usually involves file modification: either a hack file is added, or a file is changed.
74
 
75
  There are 3 key WordPress assets whose files can be hacked:
76
 
82
 
83
  But, there are no hashes available for plugins and themes, so they can't do it.
84
 
85
+ Shield is **the only WordPress security plugin** that offers full and accurate detection of file modifications for plugins and themes because we **build our own file fingerprints**.
86
 
87
+ Shield Security can compare the file contents of every plugin & theme in the WordPress.org repository, looking for changed or new files
88
 
89
  And, if you're a ShieldPRO client, you can protect premium plugins/themes too, including Yoast SEO and Advanced Custom Fields Pro.
90
 
91
+ Where possible, Shield Security will repair any unrecognised/modified files it detects.
92
 
93
  #### Shield makes Security for WordPress easy
94
 
103
 
104
  #### WordPress Security Features You'll Absolutely Love
105
 
106
+ * Exclusive [AntiBot Detection Engine](https://shsec.io/ju) - The most powerful Bot Detection security system on any WordPress security plugin.
107
  * [Automatic Bot & IP Blocking](https://shsec.io/j0) - points-based security system to block bad bots.
108
  * Add Security To Important Forms To Block Bots:
109
+ * Login Security
110
+ * Registration Security
111
+ * Password Reset Security
112
+ * [ShieldPRO] WooCommerce & Easy Digital Downloads Security
113
+ * [ShieldPRO] Memberpress, LearnPress, BuddyPress, WP Members, ProfileBuilder Security
114
+ * [Brute Force Security Protection, Limit Login Attempts + Login Cooldown Security](https://shsec.io/iw)
115
  * Powerful Firewall Security Rules
116
  * Restricted Security Admin Access
117
  * [Prevents Unauthorized Changes To Site Even By Admins](https://shsec.io/ix).
118
+ * (MFA) [Two-Factor / Multi-Factor Login Security Authentication](https://shsec.io/iy):
119
  * Email
120
  * Google Authenticator
121
  * Yubikey
122
+ * [ShieldPRO] U2F Security Keys
123
+ * [ShieldPRO] Backup Login Security Codes
124
  * [ShieldPRO] Multiple Yubikey per User
125
  * [ShieldPRO] Remember Me (reduces 2FA requests for users)
126
  * [Block XML-RPC](https://shsec.io/iz) (*including* Pingbacks and Trackbacks)
127
  * Block Anonymous Rest API
128
  * Block, Bypass and Analyse IP Addresses
129
+ * [Automatic IP Address Blocking Using Points-Based Security System](https://shsec.io/j0)
130
  * Block or Bypass individual IPs
131
  * Block or Bypass IP Subnets
132
+ * Full IP Security Analysis in 1 place to review activity on your sites
133
+ * Comprehensive WordPress File Security Scanner for Intrusions and Hacks
134
  * Detect File Changes - [Scan & Repair WordPress Core Files](https://shsec.io/j1)
135
  * [Detect Unknown/Suspicious PHP Files](https://shsec.io/j2)
136
  * Detect Abandoned Plugins.
137
+ * [ShieldPRO] Malware Security Scanner - detects known and unknown malware.
138
+ * [ShieldPRO] Plugin and Theme Security Scanning - identify file changes in your plugins/themes.
139
+ * [ShieldPRO] Detect Plugins/Themes With Known Security Vulnerabilities.
140
+ * [Create a **Private Secure Login URL** by hiding wp-login.php](https://shsec.io/j3)
141
+ * Detect (and Block) [Comment SPAM from Bots and Humans](https://shsec.io/jf).
142
  * reCAPTCHA & [hCAPTCHA](https://shsec.io/j4) support
143
  * **Never Block Google**: Automatic Detection and Bypass for GoogleBot, Bing and other Official Search Engines including:
144
  * Google
153
  * Pingdom, NodePing, Statuscake, UptimeRobot, GTMetrix
154
  * Stripe, PayPal IPN
155
  * CloudFlare, SEMRush
156
+ * Full Security Audit Trail - [Monitor **All** Site Activity, including](https://shsec.io/j5):
157
  * All login/registration attempts
158
  * Plugin and Theme installation, activation, deactivation etc.
159
  * User creation and promotion
160
  * Page/Post create, update, delete
161
+ * Advanced User Sessions Security Control
162
  * Restrict Multiple User Login
163
  * Restrict Users Session To IP
164
  * Block Use Of Pwned Passwords
179
 
180
  == Installation ==
181
 
182
+ Note: When you enable the plugin, the firewall is not automatically turned on. This security plugin contains various different sections of security protection for your site and you should choose which you need based on your own requirements.
 
183
 
184
  Why do we do this? It's simple: performance and optimization - there is no reason to automatically turn on features for people that don't
185
  need it as each site and set of requirements is different.
195
 
196
  == Frequently Asked Questions ==
197
 
198
+ Please see the dedicated security [help centre](https://shsec.io/firewallhelp) for details on features and some FAQs.
199
 
200
+ = How does the Shield Security compare with other WordPress Security Plugins? =
201
 
202
  Easy - we're just better! ;)
203
 
204
+ Firstly, we don't modify any core WordPress or web hosting file. This is important and explains why randomly you upgrade your security plugin and your site dies.
205
 
206
  Ideally you shouldn't use this along side other Anti-SPAM plugins or security plugins. If there is a feature you need, please feel free to suggest it in the support forums.
207
 
208
+ = My server has a securiy firewall, why do I need this plugin? =
209
 
210
+ This plugin is an application layer firewall, not a server/network security firewall. It is designed to interpret web calls to your site to look for attempts to circumvent it and gain unauthorized access.
211
 
212
+ Your network security firewall is designed to restrict access to your server based on certain types of network traffic. The Shield Security plugin is designed to restrict access to your site, based on certain types of web calls.
 
213
 
214
+ = How does the IP Security Bypass List work? =
215
 
216
+ Any IP address that is on the whitelist will not be subject to **any of the firewall security processing**. This setting takes priority over all other settings.
217
 
218
+ = Does the IP Bypass support IP ranges? =
219
 
220
  Yes. To specify a range you use CIDR notation. E.g. ABC.DEF.GHJ.KMP/16
221
 
232
  * you have added your IP address to the firewall blacklist,
233
  * you have enabled 2 factor authentication and email doesn't work on your site (and you haven't chosen the override option)
234
 
235
+ You can completely turn OFF (and ON) the Shield Security by creating a special file in the plugin folder.
236
 
237
  Here's how:
238
 
257
 
258
  The first entry on each line (before the first comma) is the page name. The rest of the items on the line are the parameters.
259
 
260
+ The following are some simple security examples to illustrate:
261
 
262
  **edit.php, featured**
263
 
273
  Putting a star first means that these exclusions apply to all pages. So for every page that is accessed, all the parameters
274
  that are url, param and password will be ignored by the firewall.
275
 
276
+ = How does the login cooldown security feature work? =
277
 
278
+ Login Cooldown Security prevents more than 1 login attempt to your site every "so-many" seconds. So if you enable a login cooldown of 60 seconds, only 1 login attempt will be processed every 60 seconds. If you login incorrectly, you wont be able to attempt another login for a further 60 seconds.
279
 
280
+ This security system completely blocks any level of brute-force login attacks and a cooldown of just 1 second goes a long way to adding security to your WordPress login.
281
 
282
  [More Info](https://shsec.io/2t)
283
 
285
 
286
  This is best [described on the blog](https://shsec.io/2u)
287
 
288
+ = How does the 2-factor authentication security work? =
289
 
290
  2-Factor Authentication [is best described here](https://shsec.io/2v).
291
 
304
 
305
  = I'm getting large volumes of comment SPAM. How can I stop this? =
306
 
307
+ You can use Shield Security to block 100% of automated spam bots and also block and analyse human spam. [This is best described here](https://shsec.io/jg).
308
 
309
  = Do you offer White Label? =
310
 
311
+ Yes, we do. You can essentially rename the Shield Security plugin to whatever you would like it to be.
312
 
313
  It ensures a more consistent brand offering and presents your business offering as a more holistic, integrated solution.
314
 
318
 
319
  You can use our custom [templates for this purpose](https://shsec.io/ji).
320
 
321
+ = How can I change the text/html in the Plugin Security Badge? =
 
 
 
 
 
 
322
 
323
  Use the following filter and return the HTML/Text you wish to display:
324
 
325
  `add_filter( 'icwp_shield_plugin_badge_text', 'your_function_to_return_text' );`
326
 
327
+ = How can I change the roles for login notification security emails? =
328
 
329
  Use the following filter and return the role in the function:
330
 
332
 
333
  Possible options are: network_admin, administrator, editor, author, contributor, subscriber
334
 
335
+ = What changes go into each Shield Security release? =
336
 
337
  The changelog outlines the main changes for each release. We group changes by minor release "Series". Changes in smaller "point" releases are highlighted
338
  using **(.1)** notation. So for example, version 10.1**.1** will have changelog items appended with **(.1)**
349
 
350
  == Changelog ==
351
 
352
+ The full Shield Security Changelog can be viewed from our home page:
353
 
354
  #### [Full Shield Security Changelog](https://shsec.io/shieldwporgfullchangelog)
355
 
356
  ShieldPRO delivers exclusive security features to the serious site administrator to maximise site security
357
+ You'll also have direct access to our technical support team for any security related questions you might have.
358
 
359
  [Go Pro](https://shsec.io/aa) or grab the [free ShieldPRO Trial](https://shsec.io/shieldfreetrialwporgreadme).
resources/css/plugin.css CHANGED
@@ -1549,24 +1549,97 @@ body.folded #FooterBannerGoPro {
1549
  #odp-PageHead {
1550
  }
1551
  #apto-PageMainSide {
1552
- background-color: rgba(85, 178, 87, 0.06);
1553
- border-color: rgba(85, 178, 87, 0.2);
1554
  border-width: 1px 1px 1px 0;
1555
  border-style: solid;
 
1556
  }
1557
  #NavSideBar a.nav-link:hover {
1558
- color: black;
1559
  }
1560
  #NavSideBar a.nav-link.active {
1561
  font-weight: bolder;
1562
  font-size: 1rem;
1563
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1564
  .primary_sub_menu {
1565
  }
1566
  .primary_sub_menu a.active {
1567
  border-left: 3px solid rgba(0, 128, 0, 0.4);
1568
  padding-left: 6px !important;
1569
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1570
  #SearchDialog .modal-body {
1571
  min-height: 450px;
1572
  }
1549
  #odp-PageHead {
1550
  }
1551
  #apto-PageMainSide {
1552
+ background-color: rgb(230 239 230);
1553
+ border-color: rgb(177 216 178);
1554
  border-width: 1px 1px 1px 0;
1555
  border-style: solid;
1556
+ min-width: 150px;
1557
  }
1558
  #NavSideBar a.nav-link:hover {
 
1559
  }
1560
  #NavSideBar a.nav-link.active {
1561
  font-weight: bolder;
1562
  font-size: 1rem;
1563
  }
1564
+ #NavSideBar:hover ul.top-level-nav > .nav-item {
1565
+ }
1566
+ #NavSideBar ul.top-level-nav > .nav-item:hover {
1567
+ }
1568
+ #NavSideBar .nav-item {
1569
+ }
1570
+ #NavSideBar .nav-item .nav-icon > svg {
1571
+ width: 24px;
1572
+ height: 24px;
1573
+ color: #333333;
1574
+ }
1575
+ #NavSideBar .nav-item.activesub .nav-icon > svg,
1576
+ #NavSideBar .nav-item .active .nav-icon > svg,
1577
+ #NavSideBar .nav-item:hover .nav-icon > svg {
1578
+ color: #008000;
1579
+ -webkit-transform: scaleX(-1);
1580
+ transform: scaleX(-1);
1581
+ transition: transform 0.25s;
1582
+ }
1583
+ #NavSideBar .nav-item .top-title {
1584
+ color: black;
1585
+ }
1586
+ #NavSideBar .nav-item .top-title > svg {
1587
+ transform-origin: 50% 50%;
1588
+ transform: rotate(60deg);
1589
+ height: 8px;
1590
+ width: 8px;
1591
+ margin-top: -4px;
1592
+ margin-left: 2px;
1593
+ margin-right: -2px;
1594
+ transition: transform 0.5s ease;
1595
+ }
1596
+ #NavSideBar .nav-item.activesub .top-title > svg {
1597
+ transform: rotate(-30deg);
1598
+ }
1599
+ #NavSideBar .nav-item.activesub .top-title,
1600
+ #NavSideBar .nav-item .active .top-title,
1601
+ #NavSideBar .nav-item:hover .top-title {
1602
+ color: #008000;
1603
+ }
1604
  .primary_sub_menu {
1605
  }
1606
  .primary_sub_menu a.active {
1607
  border-left: 3px solid rgba(0, 128, 0, 0.4);
1608
  padding-left: 6px !important;
1609
  }
1610
+ .subnav-menu {
1611
+ visibility: hidden;
1612
+ background-color: rgba(238, 246, 238, 0.99);
1613
+ border: 1px solid rgba(177, 216, 178, 0.99);
1614
+ /*border-left-width: 0;*/
1615
+ position: absolute;
1616
+ left: 90%;
1617
+ width: 100%;
1618
+ z-index: 1000;
1619
+ height: auto;
1620
+ transition: visibility 0s;
1621
+ box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.4);
1622
+ margin-top: -40px;
1623
+ }
1624
+ .with-submenu.activesub .subnav-menu {
1625
+ visibility: visible;
1626
+ opacity: 1;
1627
+ transition: visibility 0s;
1628
+ z-index: 1001;
1629
+ }
1630
+ .primary_side_sub_menu {
1631
+ }
1632
+ .primary_side_sub_menu a {
1633
+ text-decoration: none;
1634
+ color: #111111;
1635
+ }
1636
+ .primary_side_sub_menu a:hover {
1637
+ color: #008000;
1638
+ }
1639
+ .primary_side_sub_menu a.active {
1640
+ border-left: 3px solid rgba(0, 128, 0, 0.4);
1641
+ padding-left: 6px !important;
1642
+ }
1643
  #SearchDialog .modal-body {
1644
  min-height: 450px;
1645
  }
resources/images/bootstrap/award-fill.svg ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-award-fill" viewBox="0 0 16 16">
2
+ <path d="m8 0 1.669.864 1.858.282.842 1.68 1.337 1.32L13.4 6l.306 1.854-1.337 1.32-.842 1.68-1.858.282L8 12l-1.669-.864-1.858-.282-.842-1.68-1.337-1.32L2.6 6l-.306-1.854 1.337-1.32.842-1.68L6.331.864 8 0z"/>
3
+ <path d="M4 11.794V16l4-1 4 1v-4.206l-2.018.306L8 13.126 6.018 12.1 4 11.794z"/>
4
+ </svg>
resources/images/bootstrap/bar-chart-line-fill.svg ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-bar-chart-line-fill" viewBox="0 0 16 16">
2
+ <path d="M11 2a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1v12h.5a.5.5 0 0 1 0 1H.5a.5.5 0 0 1 0-1H1v-3a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1v3h1V7a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1v7h1V2z"/>
3
+ </svg>
resources/images/bootstrap/bar-chart-line.svg ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-bar-chart-line" viewBox="0 0 16 16">
2
+ <path d="M11 2a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1v12h.5a.5.5 0 0 1 0 1H.5a.5.5 0 0 1 0-1H1v-3a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1v3h1V7a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1v7h1V2zm1 12h2V2h-2v12zm-3 0V7H7v7h2zm-5 0v-3H2v3h2z"/>
3
+ </svg>
resources/images/bootstrap/diagram-3-fill.svg ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-diagram-3-fill" viewBox="0 0 16 16">
2
+ <path fill-rule="evenodd" d="M6 3.5A1.5 1.5 0 0 1 7.5 2h1A1.5 1.5 0 0 1 10 3.5v1A1.5 1.5 0 0 1 8.5 6v1H14a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-1 0V8h-5v.5a.5.5 0 0 1-1 0V8h-5v.5a.5.5 0 0 1-1 0v-1A.5.5 0 0 1 2 7h5.5V6A1.5 1.5 0 0 1 6 4.5v-1zm-6 8A1.5 1.5 0 0 1 1.5 10h1A1.5 1.5 0 0 1 4 11.5v1A1.5 1.5 0 0 1 2.5 14h-1A1.5 1.5 0 0 1 0 12.5v-1zm6 0A1.5 1.5 0 0 1 7.5 10h1a1.5 1.5 0 0 1 1.5 1.5v1A1.5 1.5 0 0 1 8.5 14h-1A1.5 1.5 0 0 1 6 12.5v-1zm6 0a1.5 1.5 0 0 1 1.5-1.5h1a1.5 1.5 0 0 1 1.5 1.5v1a1.5 1.5 0 0 1-1.5 1.5h-1a1.5 1.5 0 0 1-1.5-1.5v-1z"/>
3
+ </svg>
resources/images/bootstrap/people-fill.svg ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-people-fill" viewBox="0 0 16 16">
2
+ <path d="M7 14s-1 0-1-1 1-4 5-4 5 3 5 4-1 1-1 1H7zm4-6a3 3 0 1 0 0-6 3 3 0 0 0 0 6z"/>
3
+ <path fill-rule="evenodd" d="M5.216 14A2.238 2.238 0 0 1 5 13c0-1.355.68-2.75 1.936-3.72A6.325 6.325 0 0 0 5 9c-4 0-5 3-5 4s1 1 1 1h4.216z"/>
4
+ <path d="M4.5 8a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5z"/>
5
+ </svg>
resources/images/bootstrap/people.svg CHANGED
@@ -1,3 +1,3 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-people" viewBox="0 0 16 16">
2
- <path d="M15 14s1 0 1-1-1-4-5-4-5 3-5 4 1 1 1 1h8zm-7.978-1A.261.261 0 0 1 7 12.996c.001-.264.167-1.03.76-1.72C8.312 10.629 9.282 10 11 10c1.717 0 2.687.63 3.24 1.276.593.69.758 1.457.76 1.72l-.008.002a.274.274 0 0 1-.014.002H7.022zM11 7a2 2 0 1 0 0-4 2 2 0 0 0 0 4zm3-2a3 3 0 1 1-6 0 3 3 0 0 1 6 0zM6.936 9.28a5.88 5.88 0 0 0-1.23-.247A7.35 7.35 0 0 0 5 9c-4 0-5 3-5 4 0 .667.333 1 1 1h4.216A2.238 2.238 0 0 1 5 13c0-1.01.377-2.042 1.09-2.904.243-.294.526-.569.846-.816zM4.92 10A5.493 5.493 0 0 0 4 13H1c0-.26.164-1.03.76-1.724.545-.636 1.492-1.256 3.16-1.275zM1.5 5.5a3 3 0 1 1 6 0 3 3 0 0 1-6 0zm3-2a2 2 0 1 0 0 4 2 2 0 0 0 0-4z"/>
3
  </svg>
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-people" viewBox="0 0 16 16">
2
+ <path d="M15 14s1 0 1-1-1-4-5-4-5 3-5 4 1 1 1 1h8zm-7.978-1A.261.261 0 0 1 7 12.996c.001-.264.167-1.03.76-1.72C8.312 10.629 9.282 10 11 10c1.717 0 2.687.63 3.24 1.276.593.69.758 1.457.76 1.72l-.008.002a.274.274 0 0 1-.014.002H7.022zM11 7a2 2 0 1 0 0-4 2 2 0 0 0 0 4zm3-2a3 3 0 1 1-6 0 3 3 0 0 1 6 0zM6.936 9.28a5.88 5.88 0 0 0-1.23-.247A7.35 7.35 0 0 0 5 9c-4 0-5 3-5 4 0 .667.333 1 1 1h4.216A2.238 2.238 0 0 1 5 13c0-1.01.377-2.042 1.09-2.904.243-.294.526-.569.846-.816zM4.92 10A5.493 5.493 0 0 0 4 13H1c0-.26.164-1.03.76-1.724.545-.636 1.492-1.256 3.16-1.275zM1.5 5.5a3 3 0 1 1 6 0 3 3 0 0 1-6 0zm3-2a2 2 0 1 0 0 4 2 2 0 0 0 0-4z"/>
3
  </svg>
resources/images/bootstrap/person-badge-fill.svg ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-person-badge-fill" viewBox="0 0 16 16">
2
+ <path d="M2 2a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V2zm4.5 0a.5.5 0 0 0 0 1h3a.5.5 0 0 0 0-1h-3zM8 11a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm5 2.755C12.146 12.825 10.623 12 8 12s-4.146.826-5 1.755V14a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1v-.245z"/>
3
+ </svg>
resources/images/bootstrap/puzzle.svg ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-puzzle" viewBox="0 0 16 16">
2
+ <path d="M3.112 3.645A1.5 1.5 0 0 1 4.605 2H7a.5.5 0 0 1 .5.5v.382c0 .696-.497 1.182-.872 1.469a.459.459 0 0 0-.115.118.113.113 0 0 0-.012.025L6.5 4.5v.003l.003.01c.004.01.014.028.036.053a.86.86 0 0 0 .27.194C7.09 4.9 7.51 5 8 5c.492 0 .912-.1 1.19-.24a.86.86 0 0 0 .271-.194.213.213 0 0 0 .039-.063v-.009a.112.112 0 0 0-.012-.025.459.459 0 0 0-.115-.118c-.375-.287-.872-.773-.872-1.469V2.5A.5.5 0 0 1 9 2h2.395a1.5 1.5 0 0 1 1.493 1.645L12.645 6.5h.237c.195 0 .42-.147.675-.48.21-.274.528-.52.943-.52.568 0 .947.447 1.154.862C15.877 6.807 16 7.387 16 8s-.123 1.193-.346 1.638c-.207.415-.586.862-1.154.862-.415 0-.733-.246-.943-.52-.255-.333-.48-.48-.675-.48h-.237l.243 2.855A1.5 1.5 0 0 1 11.395 14H9a.5.5 0 0 1-.5-.5v-.382c0-.696.497-1.182.872-1.469a.459.459 0 0 0 .115-.118.113.113 0 0 0 .012-.025L9.5 11.5v-.003a.214.214 0 0 0-.039-.064.859.859 0 0 0-.27-.193C8.91 11.1 8.49 11 8 11c-.491 0-.912.1-1.19.24a.859.859 0 0 0-.271.194.214.214 0 0 0-.039.063v.003l.001.006a.113.113 0 0 0 .012.025c.016.027.05.068.115.118.375.287.872.773.872 1.469v.382a.5.5 0 0 1-.5.5H4.605a1.5 1.5 0 0 1-1.493-1.645L3.356 9.5h-.238c-.195 0-.42.147-.675.48-.21.274-.528.52-.943.52-.568 0-.947-.447-1.154-.862C.123 9.193 0 8.613 0 8s.123-1.193.346-1.638C.553 5.947.932 5.5 1.5 5.5c.415 0 .733.246.943.52.255.333.48.48.675.48h.238l-.244-2.855zM4.605 3a.5.5 0 0 0-.498.55l.001.007.29 3.4A.5.5 0 0 1 3.9 7.5h-.782c-.696 0-1.182-.497-1.469-.872a.459.459 0 0 0-.118-.115.112.112 0 0 0-.025-.012L1.5 6.5h-.003a.213.213 0 0 0-.064.039.86.86 0 0 0-.193.27C1.1 7.09 1 7.51 1 8c0 .491.1.912.24 1.19.07.14.14.225.194.271a.213.213 0 0 0 .063.039H1.5l.006-.001a.112.112 0 0 0 .025-.012.459.459 0 0 0 .118-.115c.287-.375.773-.872 1.469-.872H3.9a.5.5 0 0 1 .498.542l-.29 3.408a.5.5 0 0 0 .497.55h1.878c-.048-.166-.195-.352-.463-.557-.274-.21-.52-.528-.52-.943 0-.568.447-.947.862-1.154C6.807 10.123 7.387 10 8 10s1.193.123 1.638.346c.415.207.862.586.862 1.154 0 .415-.246.733-.52.943-.268.205-.415.39-.463.557h1.878a.5.5 0 0 0 .498-.55l-.001-.007-.29-3.4A.5.5 0 0 1 12.1 8.5h.782c.696 0 1.182.497 1.469.872.05.065.091.099.118.115.013.008.021.01.025.012a.02.02 0 0 0 .006.001h.003a.214.214 0 0 0 .064-.039.86.86 0 0 0 .193-.27c.14-.28.24-.7.24-1.191 0-.492-.1-.912-.24-1.19a.86.86 0 0 0-.194-.271.215.215 0 0 0-.063-.039H14.5l-.006.001a.113.113 0 0 0-.025.012.459.459 0 0 0-.118.115c-.287.375-.773.872-1.469.872H12.1a.5.5 0 0 1-.498-.543l.29-3.407a.5.5 0 0 0-.497-.55H9.517c.048.166.195.352.463.557.274.21.52.528.52.943 0 .568-.447.947-.862 1.154C9.193 5.877 8.613 6 8 6s-1.193-.123-1.638-.346C5.947 5.447 5.5 5.068 5.5 4.5c0-.415.246-.733.52-.943.268-.205.415-.39.463-.557H4.605z"/>
3
+ </svg>
resources/images/bootstrap/shield-fill.svg ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-shield-fill" viewBox="0 0 16 16">
2
+ <path d="M5.072.56C6.157.265 7.31 0 8 0s1.843.265 2.928.56c1.11.3 2.229.655 2.887.87a1.54 1.54 0 0 1 1.044 1.262c.596 4.477-.787 7.795-2.465 9.99a11.775 11.775 0 0 1-2.517 2.453 7.159 7.159 0 0 1-1.048.625c-.28.132-.581.24-.829.24s-.548-.108-.829-.24a7.158 7.158 0 0 1-1.048-.625 11.777 11.777 0 0 1-2.517-2.453C1.928 10.487.545 7.169 1.141 2.692A1.54 1.54 0 0 1 2.185 1.43 62.456 62.456 0 0 1 5.072.56z"/>
3
+ </svg>
resources/images/bootstrap/triangle-fill.svg ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-triangle-fill" viewBox="0 0 16 16">
2
+ <path fill-rule="evenodd" d="M7.022 1.566a1.13 1.13 0 0 1 1.96 0l6.857 11.667c.457.778-.092 1.767-.98 1.767H1.144c-.889 0-1.437-.99-.98-1.767L7.022 1.566z"/>
3
+ </svg>
resources/js/plugin.js CHANGED
@@ -99,6 +99,30 @@ var iCWP_WPSF_Toaster = new function () {
99
  }();
100
  iCWP_WPSF_Toaster.initialise();
101
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  var iCWP_WPSF_OptionsFormSubmit = new function () {
103
 
104
  let bRequestCurrentlyRunning = false;
99
  }();
100
  iCWP_WPSF_Toaster.initialise();
101
 
102
+ var iCWP_WPSF_SubMenu = new function () {
103
+ this.initialise = function () {
104
+ jQuery( document ).ready( function () {
105
+ let navBar = jQuery( '#NavSideBar' );
106
+ navBar.on( 'click', 'li.nav-item.with-submenu', function ( evt ) {
107
+ let $theLink = jQuery( evt.currentTarget );
108
+ if ( $theLink.hasClass( 'activesub' ) ) {
109
+ $theLink.removeClass( 'activesub' )
110
+ }
111
+ else {
112
+ jQuery( 'li.nav-item.with-submenu.activesub', navBar ).removeClass( 'activesub' );
113
+ $theLink.addClass( 'activesub' )
114
+ }
115
+ } );
116
+ jQuery( document ).on( 'click', function ( evt ) {
117
+ if ( !jQuery( evt.target ).closest( navBar ).length && jQuery( navBar ).is( ":visible" ) ) {
118
+ jQuery( 'li.nav-item.with-submenu.activesub', navBar ).removeClass( 'activesub' );
119
+ }
120
+ } );
121
+ } );
122
+ };
123
+ }();
124
+ iCWP_WPSF_SubMenu.initialise();
125
+
126
  var iCWP_WPSF_OptionsFormSubmit = new function () {
127
 
128
  let bRequestCurrentlyRunning = false;
src/config/feature-firewall.php CHANGED
@@ -94,6 +94,7 @@
94
  "advanced": true,
95
  "default": "N",
96
  "type": "checkbox",
 
97
  "link_info": "",
98
  "link_blog": "",
99
  "name": "Include Cookies",
@@ -214,6 +215,7 @@
214
  "text": "Return 404"
215
  }
216
  ],
 
217
  "link_info": "",
218
  "link_blog": "",
219
  "name": "Block Response",
@@ -263,6 +265,7 @@
263
  "premium": true,
264
  "default": "default",
265
  "type": "text",
 
266
  "link_info": "",
267
  "link_blog": "",
268
  "name": "Firewall Block Message",
94
  "advanced": true,
95
  "default": "N",
96
  "type": "checkbox",
97
+ "beacon_id": 333,
98
  "link_info": "",
99
  "link_blog": "",
100
  "name": "Include Cookies",
215
  "text": "Return 404"
216
  }
217
  ],
218
+ "beacon_id": 334,
219
  "link_info": "",
220
  "link_blog": "",
221
  "name": "Block Response",
265
  "premium": true,
266
  "default": "default",
267
  "type": "text",
268
+ "beacon_id": 139,
269
  "link_info": "",
270
  "link_blog": "",
271
  "name": "Firewall Block Message",
src/config/feature-hack_protect.php CHANGED
@@ -14,7 +14,7 @@
14
  "order": 70,
15
  "run_if_whitelisted": true,
16
  "run_if_verified_bot": true,
17
- "run_if_wpcli": false
18
  },
19
  "wpcli": {
20
  "root": "hack_guard"
@@ -290,7 +290,7 @@
290
  }
291
  ],
292
  "link_info": "https://shsec.io/b2",
293
- "link_blog": "",
294
  "beacon_id": 223,
295
  "name": "Scan Frequency",
296
  "summary": "Number Of Times To Automatically Scan Core Files In 24 Hours",
14
  "order": 70,
15
  "run_if_whitelisted": true,
16
  "run_if_verified_bot": true,
17
+ "run_if_wpcli": true
18
  },
19
  "wpcli": {
20
  "root": "hack_guard"
290
  }
291
  ],
292
  "link_info": "https://shsec.io/b2",
293
+ "link_blog": "https://shsec.io/kd",
294
  "beacon_id": 223,
295
  "name": "Scan Frequency",
296
  "summary": "Number Of Times To Automatically Scan Core Files In 24 Hours",
src/config/feature-integrations.php CHANGED
@@ -5,7 +5,7 @@
5
  "storage_key": "integrations",
6
  "name": "Integrations",
7
  "menu_title": "Integrations",
8
- "sidebar_name": "3rd Party Integrations",
9
  "show_module_options": true,
10
  "show_module_menu_item": false,
11
  "auto_enabled": true,
@@ -53,7 +53,7 @@
53
  "default": "Y",
54
  "type": "checkbox",
55
  "link_info": "https://shsec.io/ir",
56
- "link_blog": "",
57
  "beacon_id": 404,
58
  "name": "Enable MainWP",
59
  "summary": "Enable The Built-In MainWP Extension",
5
  "storage_key": "integrations",
6
  "name": "Integrations",
7
  "menu_title": "Integrations",
8
+ "sidebar_name": "Integrations",
9
  "show_module_options": true,
10
  "show_module_menu_item": false,
11
  "auto_enabled": true,
53
  "default": "Y",
54
  "type": "checkbox",
55
  "link_info": "https://shsec.io/ir",
56
+ "link_blog": "https://shsec.io/ke",
57
  "beacon_id": 404,
58
  "name": "Enable MainWP",
59
  "summary": "Enable The Built-In MainWP Extension",
src/config/feature-ips.php CHANGED
@@ -636,7 +636,8 @@
636
  "offense_at": "Last Offense",
637
  "blocked_at": "Last Block",
638
  "unblocked_at": "Unblocked",
639
- "bypass_at": "Bypass"
 
640
  }
641
  },
642
  "events": {
636
  "offense_at": "Last Offense",
637
  "blocked_at": "Last Block",
638
  "unblocked_at": "Unblocked",
639
+ "bypass_at": "Bypass",
640
+ "snsent_at": "Sent To ShieldNET"
641
  }
642
  },
643
  "events": {
src/config/feature-plugin.php CHANGED
@@ -154,6 +154,19 @@
154
  "summary": "Permit Anonymous Usage Information Gathering",
155
  "description": "Allows us to gather information on statistics and features in-use across our client installations. This information is strictly anonymous and contains no personally, or otherwise, identifiable data."
156
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
157
  {
158
  "key": "show_advanced",
159
  "section": "section_non_ui",
154
  "summary": "Permit Anonymous Usage Information Gathering",
155
  "description": "Allows us to gather information on statistics and features in-use across our client installations. This information is strictly anonymous and contains no personally, or otherwise, identifiable data."
156
  },
157
+ {
158
+ "key": "enable_shieldnet",
159
+ "section": "section_general_plugin_options",
160
+ "premium": true,
161
+ "default": "Y",
162
+ "type": "checkbox",
163
+ "beacon_id": 437,
164
+ "link_info": "https://shsec.io/kb",
165
+ "link_blog": "https://shsec.io/kc",
166
+ "name": "Enable ShieldNET",
167
+ "summary": "Enhanced Website Security Through Network Intelligence",
168
+ "description": "Enhanced Website Security Through Network Intelligence."
169
+ },
170
  {
171
  "key": "show_advanced",
172
  "section": "section_non_ui",
src/config/feature-sessions.php CHANGED
@@ -71,7 +71,6 @@
71
  "cols_timestamps": {
72
  "logged_in_at": "Session Started",
73
  "last_activity_at": "Last Seen At",
74
- "login_intent_expires_at": "2FA Window Expires",
75
  "secadmin_at": "Security Admin Authenticated"
76
  }
77
  },
71
  "cols_timestamps": {
72
  "logged_in_at": "Session Started",
73
  "last_activity_at": "Last Seen At",
 
74
  "secadmin_at": "Security Admin Authenticated"
75
  }
76
  },
src/lib/src/Controller/Admin/AdminBarMenu.php CHANGED
@@ -17,9 +17,9 @@ class AdminBarMenu {
17
  }
18
 
19
  protected function run() {
20
- add_action( 'admin_init', function ( $adminBar ) {
21
  $this->createAdminBarMenu( $adminBar );
22
- } );
23
  }
24
 
25
  /**
17
  }
18
 
19
  protected function run() {
20
+ add_action( 'admin_bar_menu', function ( $adminBar ) {
21
  $this->createAdminBarMenu( $adminBar );
22
+ }, 100 );
23
  }
24
 
25
  /**
src/lib/src/Controller/Config/Ops/Save.php CHANGED
@@ -8,6 +8,6 @@ use FernleafSystems\Wordpress\Services\Utilities\Options\Transient;
8
  class Save {
9
 
10
  public static function ToWp( ConfigVO $cfg, string $key ) :bool {
11
- return Transient::Set( $key, $cfg->getRawDataAsArray() );
12
  }
13
  }
8
  class Save {
9
 
10
  public static function ToWp( ConfigVO $cfg, string $key ) :bool {
11
+ return Transient::Set( $key, $cfg->getRawData() );
12
  }
13
  }
src/lib/src/Controller/Controller.php CHANGED
@@ -317,6 +317,7 @@ class Controller extends DynPropertiesClass {
317
  $modPlugin = $this->getModule_Plugin();
318
  if ( $modPlugin instanceof Shield\Modules\Base\ModCon ) {
319
  $modPlugin->setActivatedAt();
 
320
  }
321
  }
322
 
@@ -342,12 +343,11 @@ class Controller extends DynPropertiesClass {
342
 
343
  public function hasCacheDir() :bool {
344
  try {
345
- $buildCacheDir = $this->buildPluginCacheDir();
346
  }
347
  catch ( \Exception $e ) {
348
- $buildCacheDir = false;
349
  }
350
- return $buildCacheDir;
351
  }
352
 
353
  /**
@@ -398,7 +398,7 @@ class Controller extends DynPropertiesClass {
398
 
399
  add_filter( 'all_plugins', [ $this, 'filter_hidePluginFromTableList' ] );
400
  add_filter( 'all_plugins', [ $this, 'doPluginLabels' ] );
401
- add_filter( 'plugin_action_links_'.$this->base_file, [ $this, 'onWpPluginActionLinks' ], 50, 1 );
402
  add_filter( 'plugin_row_meta', [ $this, 'onPluginRowMeta' ], 50, 2 );
403
  add_filter( 'site_transient_update_plugins', [ $this, 'filter_hidePluginUpdatesFromUI' ] );
404
  add_action( 'in_plugin_update_message-'.$this->base_file, [ $this, 'onWpPluginUpdateMessage' ] );
@@ -1106,7 +1106,7 @@ class Controller extends DynPropertiesClass {
1106
  if ( empty( $this->root_file ) ) {
1107
  $VO = ( new \FernleafSystems\Wordpress\Services\Utilities\WpOrg\Plugin\Files() )
1108
  ->findPluginFromFile( __FILE__ );
1109
- if ( $VO instanceof \FernleafSystems\Wordpress\Services\Core\VOs\WpPluginVo ) {
1110
  $this->root_file = path_join( WP_PLUGIN_DIR, $VO->file );
1111
  }
1112
  else {
@@ -1273,7 +1273,7 @@ class Controller extends DynPropertiesClass {
1273
  }
1274
 
1275
  public function getShortRequestId() :string {
1276
- return substr( $this->getUniqueRequestId( false ), 0, 10 );
1277
  }
1278
 
1279
  public function hasSessionId() :bool {
317
  $modPlugin = $this->getModule_Plugin();
318
  if ( $modPlugin instanceof Shield\Modules\Base\ModCon ) {
319
  $modPlugin->setActivatedAt();
320
+ do_action( 'shield/plugin_activated' );
321
  }
322
  }
323
 
343
 
344
  public function hasCacheDir() :bool {
345
  try {
346
+ $this->buildPluginCacheDir();
347
  }
348
  catch ( \Exception $e ) {
 
349
  }
350
+ return $this->cache_dir_ready;
351
  }
352
 
353
  /**
398
 
399
  add_filter( 'all_plugins', [ $this, 'filter_hidePluginFromTableList' ] );
400
  add_filter( 'all_plugins', [ $this, 'doPluginLabels' ] );
401
+ add_filter( 'plugin_action_links_'.$this->base_file, [ $this, 'onWpPluginActionLinks' ], 50 );
402
  add_filter( 'plugin_row_meta', [ $this, 'onPluginRowMeta' ], 50, 2 );
403
  add_filter( 'site_transient_update_plugins', [ $this, 'filter_hidePluginUpdatesFromUI' ] );
404
  add_action( 'in_plugin_update_message-'.$this->base_file, [ $this, 'onWpPluginUpdateMessage' ] );
1106
  if ( empty( $this->root_file ) ) {
1107
  $VO = ( new \FernleafSystems\Wordpress\Services\Utilities\WpOrg\Plugin\Files() )
1108
  ->findPluginFromFile( __FILE__ );
1109
+ if ( $VO instanceof \FernleafSystems\Wordpress\Services\Core\VOs\Assets\WpPluginVo ) {
1110
  $this->root_file = path_join( WP_PLUGIN_DIR, $VO->file );
1111
  }
1112
  else {
1273
  }
1274
 
1275
  public function getShortRequestId() :string {
1276
+ return substr( $this->getUniqueRequestId(), 0, 10 );
1277
  }
1278
 
1279
  public function hasSessionId() :bool {
src/lib/src/Databases/Base/BaseQuery.php CHANGED
@@ -54,6 +54,15 @@ abstract class BaseQuery {
54
  protected function customInit() {
55
  }
56
 
 
 
 
 
 
 
 
 
 
57
  /**
58
  * @param string $column
59
  * @param string|array $value
@@ -64,6 +73,10 @@ abstract class BaseQuery {
64
  if ( !$this->isValidComparisonOperator( $operator ) ) {
65
  return $this; // Exception?
66
  }
 
 
 
 
67
 
68
  if ( is_array( $value ) ) {
69
  $value = array_map( 'esc_sql', $value );
@@ -80,7 +93,7 @@ abstract class BaseQuery {
80
 
81
  $rawWheres = $this->getRawWheres();
82
  $rawWheres[] = [
83
- esc_sql( $column ),
84
  $operator,
85
  $value
86
  ];
@@ -88,13 +101,23 @@ abstract class BaseQuery {
88
  return $this->setRawWheres( $rawWheres );
89
  }
90
 
 
 
 
 
 
 
 
 
 
 
91
  /**
92
  * @param string $column
93
  * @param mixed $mValue
94
  * @return $this
95
  */
96
  public function addWhereEquals( string $column, $mValue ) {
97
- return $this->addWhere( $column, $mValue, '=' );
98
  }
99
 
100
  /**
@@ -109,6 +132,18 @@ abstract class BaseQuery {
109
  return $this;
110
  }
111
 
 
 
 
 
 
 
 
 
 
 
 
 
112
  /**
113
  * @param string $column
114
  * @param string $like
@@ -488,7 +523,7 @@ abstract class BaseQuery {
488
  protected function isValidComparisonOperator( $op ) {
489
  return in_array(
490
  strtoupper( $op ),
491
- [ '=', '<', '>', '!=', '<>', '<=', '>=', '<=>', 'IN', 'LIKE', 'NOT LIKE' ]
492
  );
493
  }
494
  }
54
  protected function customInit() {
55
  }
56
 
57
+ /**
58
+ * @param string $columnLeft
59
+ * @param string $columnRight
60
+ * @param string $operator
61
+ */
62
+ public function addWhereCompareColumns( string $columnLeft, string $columnRight, string $operator = '=' ) {
63
+ return $this->addRawWhere( [ $columnLeft, $operator, '`'.$columnRight.'`' ] );
64
+ }
65
+
66
  /**
67
  * @param string $column
68
  * @param string|array $value
73
  if ( !$this->isValidComparisonOperator( $operator ) ) {
74
  return $this; // Exception?
75
  }
76
+ $schema = $this->getDbH()->getTableSchema();
77
+ if ( !$schema->hasColumn( $column ) ) {
78
+ return $this; // Exception?
79
+ }
80
 
81
  if ( is_array( $value ) ) {
82
  $value = array_map( 'esc_sql', $value );
93
 
94
  $rawWheres = $this->getRawWheres();
95
  $rawWheres[] = [
96
+ $column,
97
  $operator,
98
  $value
99
  ];
101
  return $this->setRawWheres( $rawWheres );
102
  }
103
 
104
+ /**
105
+ * @param array $where
106
+ * @return $this
107
+ */
108
+ public function addRawWhere( array $where ) {
109
+ $rawWheres = $this->getRawWheres();
110
+ $rawWheres[] = $where;
111
+ return $this->setRawWheres( $rawWheres );
112
+ }
113
+
114
  /**
115
  * @param string $column
116
  * @param mixed $mValue
117
  * @return $this
118
  */
119
  public function addWhereEquals( string $column, $mValue ) {
120
+ return $this->addWhere( $column, $mValue );
121
  }
122
 
123
  /**
132
  return $this;
133
  }
134
 
135
+ /**
136
+ * @param string $column
137
+ * @param array $values
138
+ * @return $this
139
+ */
140
+ public function addWhereNotIn( string $column, array $values ) {
141
+ if ( !empty( $values ) ) {
142
+ $this->addWhere( $column, $values, 'NOT IN' );
143
+ }
144
+ return $this;
145
+ }
146
+
147
  /**
148
  * @param string $column
149
  * @param string $like
523
  protected function isValidComparisonOperator( $op ) {
524
  return in_array(
525
  strtoupper( $op ),
526
+ [ '=', '<', '>', '!=', '<>', '<=', '>=', '<=>', 'IN', 'NOT IN', 'LIKE', 'NOT LIKE' ]
527
  );
528
  }
529
  }
src/lib/src/Databases/BotSignals/EntryVO.php CHANGED
@@ -29,6 +29,7 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Databases\BotSignals;
29
  * @property int $captchafail_at
30
  * @property int $ratelimit_at
31
  * @property int $updated_at
 
32
  */
33
  class EntryVO extends \FernleafSystems\Wordpress\Plugin\Shield\Databases\Base\EntryVO {
34
 
29
  * @property int $captchafail_at
30
  * @property int $ratelimit_at
31
  * @property int $updated_at
32
+ * @property int $snsent_at
33
  */
34
  class EntryVO extends \FernleafSystems\Wordpress\Plugin\Shield\Databases\Base\EntryVO {
35
 
src/lib/src/Databases/Session/EntryVO.php CHANGED
@@ -11,7 +11,6 @@ use FernleafSystems\Wordpress\Plugin\Shield\Databases\Base;
11
  * @property string wp_username
12
  * @property int last_activity_at
13
  * @property int logged_in_at
14
- * @property int login_intent_expires_at
15
  * @property string session_id
16
  * @property int secadmin_at
17
  */
11
  * @property string wp_username
12
  * @property int last_activity_at
13
  * @property int logged_in_at
 
14
  * @property string session_id
15
  * @property int secadmin_at
16
  */
src/lib/src/Databases/Session/Insert.php CHANGED
@@ -43,7 +43,6 @@ class Insert extends Base\Insert {
43
  'logged_in_at' => $req->ts(),
44
  'last_activity_at' => $req->ts(),
45
  'last_activity_uri' => $req->getUri(),
46
- 'login_intent_expires_at' => 0,
47
  'secadmin_at' => 0,
48
  ],
49
  $data
43
  'logged_in_at' => $req->ts(),
44
  'last_activity_at' => $req->ts(),
45
  'last_activity_uri' => $req->getUri(),
 
46
  'secadmin_at' => 0,
47
  ],
48
  $data
src/lib/src/Modules/Base/UI.php CHANGED
@@ -250,6 +250,9 @@ class UI {
250
  'js_steps' => 'https://cdnjs.cloudflare.com/ajax/libs/jquery-steps/1.1.0/jquery.steps.min.js',
251
  ],
252
  'imgs' => [
 
 
 
253
  'favicon' => $urlBuilder->forImage( 'pluginlogo_24x24.png' ),
254
  'plugin_banner' => $urlBuilder->forImage( 'banner-1500x500-transparent.png' ),
255
  'background_svg' => $urlBuilder->forImage( 'shield/background-blob.svg' )
250
  'js_steps' => 'https://cdnjs.cloudflare.com/ajax/libs/jquery-steps/1.1.0/jquery.steps.min.js',
251
  ],
252
  'imgs' => [
253
+ 'svgs' => [
254
+ 'triangle' => $con->svgs->raw( 'bootstrap/triangle-fill.svg' ),
255
+ ],
256
  'favicon' => $urlBuilder->forImage( 'pluginlogo_24x24.png' ),
257
  'plugin_banner' => $urlBuilder->forImage( 'banner-1500x500-transparent.png' ),
258
  'background_svg' => $urlBuilder->forImage( 'shield/background-blob.svg' )
src/lib/src/Modules/CommentsFilter/ModCon.php CHANGED
@@ -22,16 +22,16 @@ class ModCon extends BaseShield\ModCon {
22
  /** @var Options $opts */
23
  $opts = $this->getOptions();
24
 
25
- $sStyle = $opts->getOpt( 'google_recaptcha_style_comments' );
26
  if ( $this->isPremium() ) {
27
- $oCfg = $this->getCaptchaCfg();
28
- if ( $oCfg->provider == $oCfg::PROV_GOOGLE_RECAP2 ) {
29
- if ( !$oCfg->invisible && $sStyle == 'invisible' ) {
30
  $opts->setOpt( 'google_recaptcha_style_comments', 'default' );
31
  }
32
  }
33
  }
34
- elseif ( !in_array( $sStyle, [ 'disabled', 'default' ] ) ) {
35
  $opts->setOpt( 'google_recaptcha_style_comments', 'default' );
36
  }
37
  }
22
  /** @var Options $opts */
23
  $opts = $this->getOptions();
24
 
25
+ $style = $opts->getOpt( 'google_recaptcha_style_comments' );
26
  if ( $this->isPremium() ) {
27
+ $cfg = $this->getCaptchaCfg();
28
+ if ( $cfg->provider == $cfg::PROV_GOOGLE_RECAP2 ) {
29
+ if ( !$cfg->invisible && $style == 'invisible' ) {
30
  $opts->setOpt( 'google_recaptcha_style_comments', 'default' );
31
  }
32
  }
33
  }
34
+ elseif ( !in_array( $style, [ 'disabled', 'default' ] ) ) {
35
  $opts->setOpt( 'google_recaptcha_style_comments', 'default' );
36
  }
37
  }
src/lib/src/Modules/CommentsFilter/Processor.php CHANGED
@@ -13,11 +13,11 @@ class Processor extends BaseShield\Processor {
13
  $WPU = Services::WpUsers();
14
 
15
  $loadCommentFilter = !$WPU->isUserLoggedIn() ||
16
- !( new Scan\IsEmailTrusted() )->trusted(
17
- $WPU->getCurrentWpUser()->user_email,
18
- $opts->getApprovedMinimum(),
19
- $opts->getTrustedRoles()
20
- );
21
 
22
  ( new Scan\CommentAdditiveCleaner() )
23
  ->setMod( $this->getMod() )
@@ -54,14 +54,11 @@ class Processor extends BaseShield\Processor {
54
  /**
55
  * When you set a new comment as anything but 'spam' a notification email is sent to the post author.
56
  * We suppress this for when we mark as trash by emptying the email notifications list.
57
- * @param array $aEmails
58
  * @return array
59
  */
60
- public function clearCommentNotificationEmail( $aEmails ) {
61
- $sStatus = apply_filters( $this->getCon()->prefix( 'cf_status' ), '' );
62
- if ( in_array( $sStatus, [ 'reject', 'trash' ] ) ) {
63
- $aEmails = [];
64
- }
65
- return $aEmails;
66
  }
67
  }
13
  $WPU = Services::WpUsers();
14
 
15
  $loadCommentFilter = !$WPU->isUserLoggedIn() ||
16
+ !( new Scan\IsEmailTrusted() )->trusted(
17
+ $WPU->getCurrentWpUser()->user_email,
18
+ $opts->getApprovedMinimum(),
19
+ $opts->getTrustedRoles()
20
+ );
21
 
22
  ( new Scan\CommentAdditiveCleaner() )
23
  ->setMod( $this->getMod() )
54
  /**
55
  * When you set a new comment as anything but 'spam' a notification email is sent to the post author.
56
  * We suppress this for when we mark as trash by emptying the email notifications list.
57
+ * @param array $emails
58
  * @return array
59
  */
60
+ public function clearCommentNotificationEmail( $emails ) {
61
+ $status = apply_filters( $this->getCon()->prefix( 'cf_status' ), '' );
62
+ return in_array( $status, [ 'reject', 'trash' ] ) ? [] : $emails;
 
 
 
63
  }
64
  }
src/lib/src/Modules/CommentsFilter/Upgrade.php CHANGED
@@ -20,21 +20,21 @@ class Upgrade extends Base\Upgrade {
20
  }
21
 
22
  protected function upgrade_900() {
23
- $oOpts = $this->getOptions();
24
 
25
- if ( $oOpts->getOpt( 'enable_google_recaptcha_comments' ) === 'N' ) {
26
- $oOpts->setOpt( 'google_recaptcha_style_comments', 'disabled' );
27
  }
28
 
29
- $aMap = [
30
  'comments_cooldown_interval' => 'comments_cooldown',
31
  'comments_token_expire_interval' => 'comments_expire',
32
  'enable_comments_human_spam_filter_items' => 'human_spam_items',
33
  ];
34
- foreach ( $aMap as $sFrom => $sTo ) {
35
- $mVal = $oOpts->getOpt( $sFrom );
36
- if ( $mVal !== false ) {
37
- $oOpts->setOpt( $sTo, $mVal );
38
  }
39
  }
40
  }
20
  }
21
 
22
  protected function upgrade_900() {
23
+ $opts = $this->getOptions();
24
 
25
+ if ( $opts->getOpt( 'enable_google_recaptcha_comments' ) === 'N' ) {
26
+ $opts->setOpt( 'google_recaptcha_style_comments', 'disabled' );
27
  }
28
 
29
+ $map = [
30
  'comments_cooldown_interval' => 'comments_cooldown',
31
  'comments_token_expire_interval' => 'comments_expire',
32
  'enable_comments_human_spam_filter_items' => 'human_spam_items',
33
  ];
34
+ foreach ( $map as $from => $to ) {
35
+ $val = $opts->getOpt( $from );
36
+ if ( $val !== false ) {
37
+ $opts->setOpt( $to, $val );
38
  }
39
  }
40
  }
src/lib/src/Modules/Firewall/Lib/Scan/Checks/ExeFiles.php CHANGED
@@ -23,7 +23,7 @@ class ExeFiles extends Base {
23
  'check' => $this->check,
24
  'type' => 'regex',
25
  ] );
26
- break( 2 );
27
  }
28
  }
29
  }
23
  'check' => $this->check,
24
  'type' => 'regex',
25
  ] );
26
+ break 2;
27
  }
28
  }
29
  }
src/lib/src/Modules/Firewall/Lib/Scan/Checks/Standard.php CHANGED
@@ -39,7 +39,7 @@ class Standard extends Base {
39
  'check' => $this->check,
40
  'type' => 'regex',
41
  ] );
42
- break( 2 );
43
  }
44
  }
45
  }
@@ -60,7 +60,7 @@ class Standard extends Base {
60
  'check' => $this->check,
61
  'type' => 'simple',
62
  ] );
63
- break( 2 );
64
  }
65
  }
66
  }
39
  'check' => $this->check,
40
  'type' => 'regex',
41
  ] );
42
+ break 2;
43
  }
44
  }
45
  }
60
  'check' => $this->check,
61
  'type' => 'simple',
62
  ] );
63
+ break 2;
64
  }
65
  }
66
  }
src/lib/src/Modules/Firewall/ModCon.php CHANGED
@@ -38,7 +38,7 @@ class ModCon extends BaseShield\ModCon {
38
  switch ( $key ) {
39
  case 'text_firewalldie':
40
  $text = sprintf(
41
- __( "You were blocked by the %s.", 'wp-simple-firewall' ),
42
  '<a href="https://wordpress.org/plugins/wp-simple-firewall/" target="_blank">'.$this->getCon()
43
  ->getHumanName().'</a>'
44
  );
38
  switch ( $key ) {
39
  case 'text_firewalldie':
40
  $text = sprintf(
41
+ __( "You were blocked by the %s Firewall.", 'wp-simple-firewall' ),
42
  '<a href="https://wordpress.org/plugins/wp-simple-firewall/" target="_blank">'.$this->getCon()
43
  ->getHumanName().'</a>'
44
  );
src/lib/src/Modules/Firewall/Processor.php CHANGED
@@ -67,13 +67,6 @@ class Processor extends BaseShield\Processor {
67
  return $bPerformScan;
68
  }
69
 
70
- private function runScan() :bool {
71
- $scanner = ( new Lib\Scan\PerformScan() )
72
- ->setMod( $this->getMod() );
73
- $scanner->execute();
74
- $result = $scanner->getCheckResult();
75
- }
76
-
77
  private function isVisitorRequestPermitted() :bool {
78
  $opts = $this->getOptions();
79
 
@@ -131,7 +124,7 @@ class Processor extends BaseShield\Processor {
131
  foreach ( $aFileNames as $sParam => $mValue ) {
132
  if ( is_scalar( $mValue ) && preg_match( $sTerm, (string)$mValue ) ) {
133
  $bFAIL = true;
134
- break( 2 );
135
  }
136
  }
137
  }
@@ -179,7 +172,7 @@ class Processor extends BaseShield\Processor {
179
  foreach ( $aParamValues as $sParam => $mValue ) {
180
  if ( is_scalar( $mValue ) && ( stripos( (string)$mValue, $sTerm ) !== false ) ) {
181
  $bFAIL = true;
182
- break( 2 );
183
  }
184
  }
185
  }
@@ -198,7 +191,7 @@ class Processor extends BaseShield\Processor {
198
  $sParam = sanitize_text_field( $sParam );
199
  $mValue = sanitize_text_field( $mValue );
200
  $bFAIL = true;
201
- break( 2 );
202
  }
203
  }
204
  }
67
  return $bPerformScan;
68
  }
69
 
 
 
 
 
 
 
 
70
  private function isVisitorRequestPermitted() :bool {
71
  $opts = $this->getOptions();
72
 
124
  foreach ( $aFileNames as $sParam => $mValue ) {
125
  if ( is_scalar( $mValue ) && preg_match( $sTerm, (string)$mValue ) ) {
126
  $bFAIL = true;
127
+ break 2;
128
  }
129
  }
130
  }
172
  foreach ( $aParamValues as $sParam => $mValue ) {
173
  if ( is_scalar( $mValue ) && ( stripos( (string)$mValue, $sTerm ) !== false ) ) {
174
  $bFAIL = true;
175
+ break 2;
176
  }
177
  }
178
  }
191
  $sParam = sanitize_text_field( $sParam );
192
  $mValue = sanitize_text_field( $mValue );
193
  $bFAIL = true;
194
+ break 2;
195
  }
196
  }
197
  }
src/lib/src/Modules/HackGuard/AjaxHandler.php CHANGED
@@ -25,7 +25,7 @@ class AjaxHandler extends Shield\Modules\BaseShield\AjaxHandler {
25
  break;
26
 
27
  case 'item_action':
28
- $response = $this->ajaxExec_ScanItemAction( $req->post( 'item_action' ), false );
29
  break;
30
 
31
  case 'bulk_action':
@@ -120,7 +120,7 @@ class AjaxHandler extends Shield\Modules\BaseShield\AjaxHandler {
120
  private function ajaxExec_FileLockerShowDiff() :array {
121
  /** @var ModCon $mod */
122
  $mod = $this->getMod();
123
- $oFLCon = $mod->getFileLocker();
124
  $FS = Services::WpFs();
125
 
126
  $nRID = Services::Request()->post( 'rid' );
@@ -169,12 +169,15 @@ class AjaxHandler extends Shield\Modules\BaseShield\AjaxHandler {
169
  if ( !is_numeric( $nRID ) ) {
170
  throw new \Exception( 'Not a valid file lock request.' );
171
  }
 
 
 
 
172
 
173
- $lock = $oFLCon->getFileLock( $nRID );
174
- $bDiff = $lock->detected_at > 0;
175
- $data[ 'ajax' ] = $oFLCon->createFileDownloadLinks( $lock );
176
- $data[ 'flags' ][ 'has_diff' ] = $bDiff;
177
- $data[ 'html' ][ 'diff' ] = $bDiff ?
178
  ( new FileLocker\Ops\PerformAction() )
179
  ->setMod( $this->getMod() )
180
  ->run( $nRID, 'diff' ) : '';
@@ -271,12 +274,7 @@ class AjaxHandler extends Shield\Modules\BaseShield\AjaxHandler {
271
  return [ 'success' => true ];
272
  }
273
 
274
- /**
275
- * @param string $action
276
- * @param bool $isBulkAction
277
- * @return array
278
- */
279
- private function ajaxExec_ScanItemAction( $action, $isBulkAction = false ) :array {
280
  /** @var ModCon $mod */
281
  $mod = $this->getMod();
282
 
25
  break;
26
 
27
  case 'item_action':
28
+ $response = $this->ajaxExec_ScanItemAction( $req->post( 'item_action' ) );
29
  break;
30
 
31
  case 'bulk_action':
120
  private function ajaxExec_FileLockerShowDiff() :array {
121
  /** @var ModCon $mod */
122
  $mod = $this->getMod();
123
+ $FLCon = $mod->getFileLocker();
124
  $FS = Services::WpFs();
125
 
126
  $nRID = Services::Request()->post( 'rid' );
169
  if ( !is_numeric( $nRID ) ) {
170
  throw new \Exception( 'Not a valid file lock request.' );
171
  }
172
+ $lock = $FLCon->getFileLock( $nRID );
173
+ if ( !$lock instanceof Databases\FileLocker\EntryVO ) {
174
+ throw new \Exception( 'Not a valid file lock request.' );
175
+ }
176
 
177
+ $isDifferent = $lock->detected_at > 0;
178
+ $data[ 'ajax' ] = $FLCon->createFileDownloadLinks( $lock );
179
+ $data[ 'flags' ][ 'has_diff' ] = $isDifferent;
180
+ $data[ 'html' ][ 'diff' ] = $isDifferent ?
 
181
  ( new FileLocker\Ops\PerformAction() )
182
  ->setMod( $this->getMod() )
183
  ->run( $nRID, 'diff' ) : '';
274
  return [ 'success' => true ];
275
  }
276
 
277
+ private function ajaxExec_ScanItemAction( string $action, bool $isBulkAction = false ) :array {
 
 
 
 
 
278
  /** @var ModCon $mod */
279
  $mod = $this->getMod();
280
 
src/lib/src/Modules/HackGuard/Debug.php CHANGED
@@ -2,17 +2,9 @@
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard;
4
 
5
- use FernleafSystems\Wordpress\Plugin\Shield\Modules;
6
-
7
- class Debug extends Modules\Base\Debug {
8
 
9
  public function run() {
10
- die('finish');
11
- }
12
-
13
- private function filelocker() {
14
- /** @var ModCon $mod */
15
- $mod = $this->getMod();
16
- $mod->getFileLocker()->processFileLocks();
17
  }
18
  }
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard;
4
 
5
+ class Debug extends \FernleafSystems\Wordpress\Plugin\Shield\Modules\Base\Debug {
 
 
6
 
7
  public function run() {
8
+ die( 'finish' );
 
 
 
 
 
 
9
  }
10
  }
src/lib/src/Modules/HackGuard/Lib/FileLocker/FileLockerController.php CHANGED
@@ -32,25 +32,20 @@ class FileLockerController {
32
 
33
  protected function run() {
34
  $con = $this->getCon();
 
 
35
  add_filter( $con->prefix( 'admin_bar_menu_items' ), [ $this, 'addAdminMenuBarItem' ], 100 );
36
- add_action( $con->prefix( 'pre_plugin_shutdown' ), [ $this, 'processFileLocks' ] );
37
  }
38
 
39
- public function processFileLocks() {
40
- if ( !$this->getCon()->plugin_deactivating && !$this->getCon()->is_my_upgrade ) {
41
- if ( $this->isFileLockerStateChanged() ) {
42
- $this->deleteAllLocks();
43
- $this->setState( [] );
44
- }
45
- else {
46
- $this->runAnalysis();
47
- }
48
  }
49
  }
50
 
51
  private function isFileLockerStateChanged() :bool {
52
- return $this->getOptions()->isOptChanged( 'file_locker' )
53
- || $this->getState()[ 'abspath' ] !== ABSPATH;
54
  }
55
 
56
  public function addAdminMenuBarItem( array $items ) :array {
@@ -67,20 +62,13 @@ class FileLockerController {
67
  return $items;
68
  }
69
 
70
- /**
71
- * @return int
72
- */
73
- public function countProblems() {
74
  return count( ( new Ops\LoadFileLocks() )
75
  ->setMod( $this->getMod() )
76
  ->withProblems() );
77
  }
78
 
79
- /**
80
- * @param FileLocker\EntryVO $lock
81
- * @return string[]
82
- */
83
- public function createFileDownloadLinks( $lock ) :array {
84
  /** @var HackGuard\ModCon $mod */
85
  $mod = $this->getMod();
86
  $links = [];
@@ -146,14 +134,16 @@ class FileLockerController {
146
  ->loadLocks()[ $ID ] ?? null;
147
  }
148
 
149
- private function runAnalysis() {
150
  // 1. First assess the existing locks for changes.
151
  ( new Ops\AssessLocks() )
152
  ->setMod( $this->getMod() )
153
  ->run();
154
 
155
  // 2. Create any outstanding locks.
156
- $this->runLocksCreation();
 
 
157
  }
158
 
159
  /**
@@ -254,4 +244,10 @@ class FileLockerController {
254
  protected function setState( array $state ) {
255
  $this->getOptions()->setOpt( 'filelocker_state', $state );
256
  }
257
- }
 
 
 
 
 
 
32
 
33
  protected function run() {
34
  $con = $this->getCon();
35
+ add_action( 'wp_loaded', [ $this, 'runAnalysis' ] );
36
+ add_action( $con->prefix( 'pre_plugin_shutdown' ), [ $this, 'checkLockConfig' ] );
37
  add_filter( $con->prefix( 'admin_bar_menu_items' ), [ $this, 'addAdminMenuBarItem' ], 100 );
 
38
  }
39
 
40
+ public function checkLockConfig() {
41
+ if ( !$this->getCon()->plugin_deactivating && $this->isFileLockerStateChanged() ) {
42
+ $this->deleteAllLocks();
43
+ $this->setState( [] );
 
 
 
 
 
44
  }
45
  }
46
 
47
  private function isFileLockerStateChanged() :bool {
48
+ return $this->getOptions()->isOptChanged( 'file_locker' ) || $this->getState()[ 'abspath' ] !== ABSPATH;
 
49
  }
50
 
51
  public function addAdminMenuBarItem( array $items ) :array {
62
  return $items;
63
  }
64
 
65
+ public function countProblems() :int {
 
 
 
66
  return count( ( new Ops\LoadFileLocks() )
67
  ->setMod( $this->getMod() )
68
  ->withProblems() );
69
  }
70
 
71
+ public function createFileDownloadLinks( FileLocker\EntryVO $lock ) :array {
 
 
 
 
72
  /** @var HackGuard\ModCon $mod */
73
  $mod = $this->getMod();
74
  $links = [];
134
  ->loadLocks()[ $ID ] ?? null;
135
  }
136
 
137
+ public function runAnalysis() {
138
  // 1. First assess the existing locks for changes.
139
  ( new Ops\AssessLocks() )
140
  ->setMod( $this->getMod() )
141
  ->run();
142
 
143
  // 2. Create any outstanding locks.
144
+ if ( is_main_network() ) {
145
+ $this->runLocksCreation();
146
+ }
147
  }
148
 
149
  /**
244
  protected function setState( array $state ) {
245
  $this->getOptions()->setOpt( 'filelocker_state', $state );
246
  }
247
+
248
+ /**
249
+ * @deprecated 11.4
250
+ */
251
+ public function processFileLocks() {
252
+ }
253
+ }
src/lib/src/Modules/HackGuard/Lib/FileLocker/Ops/Accept.php CHANGED
@@ -21,17 +21,17 @@ class Accept extends BaseOps {
21
  /** @var ModCon $mod */
22
  $mod = $this->getMod();
23
 
24
- $aPublicKey = $this->getPublicKey();
25
  $raw = ( new BuildEncryptedFilePayload() )
26
  ->setMod( $mod )
27
- ->build( $lock->file, reset( $aPublicKey ) );
28
 
29
  /** @var FileLocker\Update $updater */
30
  $updater = $mod->getDbHandler_FileLocker()->getQueryUpdater();
31
  $success = $updater->updateEntry( $lock, [
32
  'hash_original' => hash_file( 'sha1', $lock->file ),
33
  'content' => base64_encode( $raw ),
34
- 'public_key_id' => key( $aPublicKey ),
35
  'detected_at' => 0,
36
  'updated_at' => Services::Request()->ts(),
37
  'created_at' => Services::Request()->ts(), // update "locked at"
21
  /** @var ModCon $mod */
22
  $mod = $this->getMod();
23
 
24
+ $publicKey = $this->getPublicKey();
25
  $raw = ( new BuildEncryptedFilePayload() )
26
  ->setMod( $mod )
27
+ ->build( $lock->file, reset( $publicKey ) );
28
 
29
  /** @var FileLocker\Update $updater */
30
  $updater = $mod->getDbHandler_FileLocker()->getQueryUpdater();
31
  $success = $updater->updateEntry( $lock, [
32
  'hash_original' => hash_file( 'sha1', $lock->file ),
33
  'content' => base64_encode( $raw ),
34
+ 'public_key_id' => key( $publicKey ),
35
  'detected_at' => 0,
36
  'updated_at' => Services::Request()->ts(),
37
  'created_at' => Services::Request()->ts(), // update "locked at"
src/lib/src/Modules/HackGuard/Lib/FileLocker/Ops/AssessLocks.php CHANGED
@@ -24,7 +24,7 @@ class AssessLocks extends BaseOps {
24
  try {
25
  if ( ( new CompareHash() )->isEqualFileSha1( $lock->file, $lock->hash_original ) ) {
26
  if ( !empty( $lock->hash_current ) ) {
27
- $updater->updateCurrentHash( $lock, '' );
28
  }
29
  }
30
  else {
24
  try {
25
  if ( ( new CompareHash() )->isEqualFileSha1( $lock->file, $lock->hash_original ) ) {
26
  if ( !empty( $lock->hash_current ) ) {
27
+ $updater->updateCurrentHash( $lock );
28
  }
29
  }
30
  else {
src/lib/src/Modules/HackGuard/Lib/FileLocker/Ops/BuildEncryptedFilePayload.php CHANGED
@@ -11,17 +11,17 @@ use FernleafSystems\Wordpress\Services\Services;
11
  class BuildEncryptedFilePayload extends BaseOps {
12
 
13
  /**
14
- * @param string $sPath
15
- * @param string $sPublicKey
16
  * @return string
17
  * @throws \ErrorException
18
  */
19
- public function build( $sPath, $sPublicKey ) {
20
- $oEnc = Services::Encrypt();
21
- $oPayload = $oEnc->sealData( Services::WpFs()->getFileContent( $sPath ), $sPublicKey );
22
- if ( !$oPayload->success ) {
23
  throw new \ErrorException( 'File contents could not be encrypted' );
24
  }
25
- return json_encode( $oPayload->getRawDataAsArray() );
26
  }
27
  }
11
  class BuildEncryptedFilePayload extends BaseOps {
12
 
13
  /**
14
+ * @param string $path
15
+ * @param string $publicKey
16
  * @return string
17
  * @throws \ErrorException
18
  */
19
+ public function build( $path, $publicKey ) {
20
+ $srvEnc = Services::Encrypt();
21
+ $payload = $srvEnc->sealData( Services::WpFs()->getFileContent( $path ), $publicKey );
22
+ if ( !$payload->success ) {
23
  throw new \ErrorException( 'File contents could not be encrypted' );
24
  }
25
+ return json_encode( $payload->getRawData() );
26
  }
27
  }
src/lib/src/Modules/HackGuard/Lib/FileLocker/Ops/LoadFileLocks.php CHANGED
@@ -43,7 +43,7 @@ class LoadFileLocks {
43
  /**
44
  * @return FileLocker\EntryVO[]
45
  */
46
- public function withProblems() {
47
  return array_filter(
48
  $this->loadLocks(),
49
  function ( $lock ) {
43
  /**
44
  * @return FileLocker\EntryVO[]
45
  */
46
+ public function withProblems() :array {
47
  return array_filter(
48
  $this->loadLocks(),
49
  function ( $lock ) {
src/lib/src/Modules/HackGuard/Lib/FileLocker/Ops/ReadOriginalFileContent.php CHANGED
@@ -46,14 +46,14 @@ class ReadOriginalFileContent extends BaseOps {
46
  * @return string|null
47
  */
48
  private function useCacheAndApi( Databases\FileLocker\EntryVO $lock ) {
49
- $sCacheKey = 'file-content-'.$lock->id;
50
- $content = wp_cache_get( $sCacheKey, $this->getCon()->prefix( 'filelocker' ) );
51
  if ( $content === false ) {
52
  $VO = ( new OpenSslEncryptVo() )->applyFromArray( json_decode( $lock->content, true ) );
53
  $content = ( new DecryptFile() )
54
  ->setMod( $this->getMod() )
55
  ->retrieve( $VO, $lock->public_key_id );
56
- wp_cache_set( $sCacheKey, $content, $this->getCon()->prefix( 'filelocker' ), 3 );
57
  }
58
  return $content;
59
  }
46
  * @return string|null
47
  */
48
  private function useCacheAndApi( Databases\FileLocker\EntryVO $lock ) {
49
+ $cacheKey = 'file-content-'.$lock->id;
50
+ $content = wp_cache_get( $cacheKey, $this->getCon()->prefix( 'filelocker' ) );
51
  if ( $content === false ) {
52
  $VO = ( new OpenSslEncryptVo() )->applyFromArray( json_decode( $lock->content, true ) );
53
  $content = ( new DecryptFile() )
54
  ->setMod( $this->getMod() )
55
  ->retrieve( $VO, $lock->public_key_id );
56
+ wp_cache_set( $cacheKey, $content, $this->getCon()->prefix( 'filelocker' ), 3 );
57
  }
58
  return $content;
59
  }
src/lib/src/Modules/HackGuard/Lib/Snapshots/Build/BuildHashesForAsset.php CHANGED
@@ -2,8 +2,10 @@
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\Snapshots\Build;
4
 
5
- use FernleafSystems\Wordpress\Services\Core\VOs\WpPluginVo;
6
- use FernleafSystems\Wordpress\Services\Core\VOs\WpThemeVo;
 
 
7
 
8
  /**
9
  * Class BuildHashesForAsset
@@ -14,26 +16,39 @@ class BuildHashesForAsset {
14
  /**
15
  * @var string
16
  */
17
- private $sHashAlgo = 'md5';
18
 
19
  /**
20
  * All file keys are their normalised file paths, with the ABSPATH stripped from it.
21
- * @param WpPluginVo|WpThemeVo $oAsset
22
  * @return string[]
23
  */
24
- public function build( $oAsset ) {
25
  return ( new BuildHashesFromDir() )
26
  ->setHashAlgo( $this->getHashAlgo() )
27
  ->setDepth( 0 )
28
  ->setFileExts( [] )
29
- ->build( $oAsset->getInstallDir() );
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  }
31
 
32
  /**
33
  * @return string
34
  */
35
  public function getHashAlgo() {
36
- return empty( $this->sHashAlgo ) ? 'md5' : $this->sHashAlgo;
37
  }
38
 
39
  /**
@@ -41,7 +56,7 @@ class BuildHashesForAsset {
41
  * @return static
42
  */
43
  public function setHashAlgo( $sHashAlgo ) {
44
- $this->sHashAlgo = $sHashAlgo;
45
  return $this;
46
  }
47
  }
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\Snapshots\Build;
4
 
5
+ use FernleafSystems\Wordpress\Services\Core\VOs\Assets\{
6
+ WpPluginVo,
7
+ WpThemeVo
8
+ };
9
 
10
  /**
11
  * Class BuildHashesForAsset
16
  /**
17
  * @var string
18
  */
19
+ private $hashAlgo = 'md5';
20
 
21
  /**
22
  * All file keys are their normalised file paths, with the ABSPATH stripped from it.
23
+ * @param WpPluginVo|WpThemeVo $asset
24
  * @return string[]
25
  */
26
+ public function build( $asset ) {
27
  return ( new BuildHashesFromDir() )
28
  ->setHashAlgo( $this->getHashAlgo() )
29
  ->setDepth( 0 )
30
  ->setFileExts( [] )
31
+ ->build( $asset->getInstallDir() );
32
+ }
33
+
34
+ /**
35
+ * All file keys are their normalised file paths, with the ABSPATH stripped from it.
36
+ * @param WpPluginVo|WpThemeVo $asset
37
+ * @return string[]
38
+ */
39
+ public function buildNormalised( $asset ) :array {
40
+ return ( new BuildHashesFromDir() )
41
+ ->setHashAlgo( $this->getHashAlgo() )
42
+ ->setDepth( 0 )
43
+ ->setFileExts( [] )
44
+ ->buildNormalised( $asset->getInstallDir() );
45
  }
46
 
47
  /**
48
  * @return string
49
  */
50
  public function getHashAlgo() {
51
+ return empty( $this->hashAlgo ) ? 'md5' : $this->hashAlgo;
52
  }
53
 
54
  /**
56
  * @return static
57
  */
58
  public function setHashAlgo( $sHashAlgo ) {
59
+ $this->hashAlgo = $sHashAlgo;
60
  return $this;
61
  }
62
  }
src/lib/src/Modules/HackGuard/Lib/Snapshots/Build/BuildHashesFromApi.php CHANGED
@@ -2,7 +2,10 @@
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\Snapshots\Build;
4
 
5
- use FernleafSystems\Wordpress\Services\Core\VOs;
 
 
 
6
  use FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\Hashes;
7
 
8
  /**
@@ -13,76 +16,76 @@ class BuildHashesFromApi {
13
 
14
  /**
15
  * All file keys are their normalised file paths, with the ABSPATH stripped from it.
16
- * @param VOs\WpPluginVo|VOs\WpThemeVo $oAsset
17
  * @return string[] - keys are file paths relative to ABSPATH
18
  * @throws \Exception
19
  */
20
- public function build( $oAsset ) {
21
- if ( !$oAsset->isWpOrg() ) {
22
 
23
- $bApiSupport = false;
24
 
25
- $aApiInfo = ( new Hashes\ApiInfo() )
26
  ->setUseQueryCache( true )
27
  ->getInfo();
28
- if ( is_array( $aApiInfo ) && !empty( $aApiInfo[ 'supported_premium' ] ) ) {
29
- if ( $oAsset instanceof VOs\WpPluginVo ) {
30
- $sSlug = $oAsset->slug;
31
- $sFile = $oAsset->file;
32
- $sName = $oAsset->Name;
33
- $aItems = $aApiInfo[ 'supported_premium' ][ 'plugins' ];
34
  }
35
  else {
36
- $sSlug = $oAsset->stylesheet;
37
- $sFile = $oAsset->stylesheet;
38
- $sName = $oAsset->wp_theme->get( 'Name' );
39
- $aItems = $aApiInfo[ 'supported_premium' ][ 'themes' ];
40
  }
41
 
42
- foreach ( $aItems as $aMaybeItem ) {
43
 
44
- if ( $aMaybeItem[ 'slug' ] == $sSlug
45
- || $aMaybeItem[ 'name' ] == $sName || $aMaybeItem[ 'file' ] == $sFile ) {
46
- $bApiSupport = true;
47
- if ( $oAsset instanceof VOs\WpPluginVo && empty( $oAsset->slug ) ) {
48
- $oAsset->slug = $aMaybeItem[ 'slug' ];
49
  }
50
  break;
51
  }
52
  }
53
  }
54
 
55
- if ( !$bApiSupport ) {
56
  throw new \Exception( 'Not a WordPress.org asset.' );
57
  }
58
  }
59
- return $this->retrieveForAsset( $oAsset );
60
  }
61
 
62
  /**
63
- * @param VOs\WpPluginVo|VOs\WpThemeVo $oAsset
64
  * @return string[]|null
65
  * @throws \Exception
66
  */
67
- private function retrieveForAsset( $oAsset ) {
68
 
69
- if ( $oAsset instanceof VOs\WpPluginVo ) {
70
- $aHashes = ( new Hashes\Plugin() )
71
  ->setUseQueryCache( true )
72
- ->getHashes( $oAsset->slug, $oAsset->Version, 'md5' );
73
  }
74
- elseif ( $oAsset instanceof VOs\WpThemeVo ) {
75
- if ( $oAsset->is_child ) {
76
  throw new \Exception( 'Live hashes are not supported for child themes.' );
77
  }
78
- $aHashes = ( new Hashes\Theme() )
79
  ->setUseQueryCache( true )
80
- ->getHashes( $oAsset->stylesheet, $oAsset->version, 'md5' );
81
  }
82
  else {
83
  throw new \Exception( 'Not a supported asset type' );
84
  }
85
 
86
- return $aHashes;
87
  }
88
  }
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\Snapshots\Build;
4
 
5
+ use FernleafSystems\Wordpress\Services\Core\VOs\Assets\{
6
+ WpPluginVo,
7
+ WpThemeVo
8
+ };
9
  use FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\Hashes;
10
 
11
  /**
16
 
17
  /**
18
  * All file keys are their normalised file paths, with the ABSPATH stripped from it.
19
+ * @param WpPluginVo|WpThemeVo $asset
20
  * @return string[] - keys are file paths relative to ABSPATH
21
  * @throws \Exception
22
  */
23
+ public function build( $asset ) {
24
+ if ( !$asset->isWpOrg() ) {
25
 
26
+ $apiSupport = false;
27
 
28
+ $apiInfo = ( new Hashes\ApiInfo() )
29
  ->setUseQueryCache( true )
30
  ->getInfo();
31
+ if ( is_array( $apiInfo ) && !empty( $apiInfo[ 'supported_premium' ] ) ) {
32
+ if ( $asset->asset_type === 'plugin' ) {
33
+ $slug = $asset->slug;
34
+ $file = $asset->file;
35
+ $name = $asset->Name;
36
+ $items = $apiInfo[ 'supported_premium' ][ 'plugins' ];
37
  }
38
  else {
39
+ $slug = $asset->stylesheet;
40
+ $file = $asset->stylesheet;
41
+ $name = $asset->wp_theme->get( 'Name' );
42
+ $items = $apiInfo[ 'supported_premium' ][ 'themes' ];
43
  }
44
 
45
+ foreach ( $items as $aMaybeItem ) {
46
 
47
+ if ( $aMaybeItem[ 'slug' ] == $slug
48
+ || $aMaybeItem[ 'name' ] == $name || $aMaybeItem[ 'file' ] == $file ) {
49
+ $apiSupport = true;
50
+ if ( $asset->asset_type === 'plugin' && empty( $asset->slug ) ) {
51
+ $asset->slug = $aMaybeItem[ 'slug' ];
52
  }
53
  break;
54
  }
55
  }
56
  }
57
 
58
+ if ( !$apiSupport ) {
59
  throw new \Exception( 'Not a WordPress.org asset.' );
60
  }
61
  }
62
+ return $this->retrieveForAsset( $asset );
63
  }
64
 
65
  /**
66
+ * @param WpPluginVo|WpThemeVo $asset
67
  * @return string[]|null
68
  * @throws \Exception
69
  */
70
+ private function retrieveForAsset( $asset ) {
71
 
72
+ if ( $asset->asset_type === 'plugin' ) {
73
+ $hashes = ( new Hashes\Plugin() )
74
  ->setUseQueryCache( true )
75
+ ->getHashes( $asset->slug, $asset->Version, 'md5' );
76
  }
77
+ elseif ( $asset->asset_type === 'theme' ) {
78
+ if ( $asset->is_child ) {
79
  throw new \Exception( 'Live hashes are not supported for child themes.' );
80
  }
81
+ $hashes = ( new Hashes\Theme() )
82
  ->setUseQueryCache( true )
83
+ ->getHashes( $asset->stylesheet, $asset->version, 'md5' );
84
  }
85
  else {
86
  throw new \Exception( 'Not a supported asset type' );
87
  }
88
 
89
+ return $hashes;
90
  }
91
  }
src/lib/src/Modules/HackGuard/Lib/Snapshots/Build/BuildHashesFromDir.php CHANGED
@@ -3,6 +3,7 @@
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\Snapshots\Build;
4
 
5
  use FernleafSystems\Wordpress\Plugin\Shield\Scans\Helpers\StandardDirectoryIterator;
 
6
 
7
  /**
8
  * Class BuildHashesFromDir
@@ -27,20 +28,20 @@ class BuildHashesFromDir {
27
 
28
  /**
29
  * All file keys are their normalised file paths, with the ABSPATH stripped from it.
30
- * @param string $sDir
31
  * @return string[]
32
  */
33
- public function build( $sDir ) {
34
  $aSnaps = [];
35
  try {
36
- $sDir = wp_normalize_path( $sDir );
37
  $sAlgo = $this->getHashAlgo();
38
- $oDirIt = StandardDirectoryIterator::create( $sDir, $this->nDepth, $this->aFileExts );
39
  foreach ( $oDirIt as $oFile ) {
40
  /** @var \SplFileInfo $oFile */
41
  $sFullPath = $oFile->getPathname();
42
- $sKey = str_replace( $sDir, '', wp_normalize_path( $sFullPath ) );
43
- $aSnaps[ $sKey ] = hash_file( $sAlgo, $sFullPath );
44
  }
45
  }
46
  catch ( \Exception $e ) {
@@ -48,6 +49,29 @@ class BuildHashesFromDir {
48
  return $aSnaps;
49
  }
50
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  /**
52
  * @return string
53
  */
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\Snapshots\Build;
4
 
5
  use FernleafSystems\Wordpress\Plugin\Shield\Scans\Helpers\StandardDirectoryIterator;
6
+ use FernleafSystems\Wordpress\Services\Services;
7
 
8
  /**
9
  * Class BuildHashesFromDir
28
 
29
  /**
30
  * All file keys are their normalised file paths, with the ABSPATH stripped from it.
31
+ * @param string $dir
32
  * @return string[]
33
  */
34
+ public function build( $dir, bool $binary = false ) {
35
  $aSnaps = [];
36
  try {
37
+ $dir = wp_normalize_path( $dir );
38
  $sAlgo = $this->getHashAlgo();
39
+ $oDirIt = StandardDirectoryIterator::create( $dir, $this->nDepth, $this->aFileExts );
40
  foreach ( $oDirIt as $oFile ) {
41
  /** @var \SplFileInfo $oFile */
42
  $sFullPath = $oFile->getPathname();
43
+ $sKey = str_replace( $dir, '', wp_normalize_path( $sFullPath ) );
44
+ $aSnaps[ $sKey ] = hash_file( $sAlgo, $sFullPath, $binary );
45
  }
46
  }
47
  catch ( \Exception $e ) {
49
  return $aSnaps;
50
  }
51
 
52
+ /**
53
+ * All file keys are their normalised file paths, with the ABSPATH stripped from it.
54
+ * @param string $dir
55
+ * @return string[]
56
+ */
57
+ public function buildNormalised( string $dir ) :array {
58
+ $snaps = [];
59
+ $DM = Services::DataManipulation();
60
+ try {
61
+ $dir = wp_normalize_path( $dir );
62
+ $algo = $this->getHashAlgo();
63
+ foreach ( StandardDirectoryIterator::create( $dir, $this->nDepth, $this->aFileExts ) as $file ) {
64
+ /** @var \SplFileInfo $file */
65
+ $fullPath = $file->getPathname();
66
+ $key = str_replace( $dir, '', wp_normalize_path( $fullPath ) );
67
+ $snaps[ $key ] = hash( $algo, $DM->convertLineEndingsDosToLinux( $fullPath ) );
68
+ }
69
+ }
70
+ catch ( \Exception $e ) {
71
+ }
72
+ return $snaps;
73
+ }
74
+
75
  /**
76
  * @return string
77
  */
src/lib/src/Modules/HackGuard/Lib/Snapshots/CrowdSourced/SubmitHashes.php ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php declare( strict_types=1 );
2
+
3
+ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\Snapshots\CrowdSourced;
4
+
5
+ use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\Snapshots\Build;
6
+ use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
7
+ use FernleafSystems\Wordpress\Services\Core\VOs\Assets\{
8
+ WpPluginVo,
9
+ WpThemeVo
10
+ };
11
+ use FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\CrowdSourcedHashes\Submit\{
12
+ PreSubmit,
13
+ Submit
14
+ };
15
+
16
+ class SubmitHashes {
17
+
18
+ use ModConsumer;
19
+
20
+ /**
21
+ * @var WpPluginVo|WpThemeVo
22
+ */
23
+ private $asset;
24
+
25
+ /**
26
+ * @var string[]
27
+ */
28
+ private $hashes;
29
+
30
+ /**
31
+ * @param WpPluginVo|WpThemeVo $asset
32
+ */
33
+ public function run( $asset ) {
34
+ $this->asset = $asset;
35
+
36
+ $this->hashes = ( new Build\BuildHashesForAsset() )
37
+ ->setHashAlgo( 'sha1' )
38
+ ->buildNormalised( $asset );
39
+
40
+ if ( $this->isSubmitRequired() ) {
41
+ $this->submit();
42
+ }
43
+ }
44
+
45
+ private function isSubmitRequired() :bool {
46
+ $response = ( new PreSubmit() )
47
+ ->setHashes( $this->hashes )
48
+ ->query();
49
+ return is_array( $response ) && !empty( $response[ 'hashes' ] ) && $response[ 'hashes' ][ 'submit_required' ];
50
+ }
51
+
52
+ private function submit() :bool {
53
+ $sub = ( new Submit() )->setHashes( $this->hashes );
54
+ $response = $this->asset->asset_type === 'plugin' ? $sub->submitPlugin( $this->asset ) : $sub->submitTheme( $this->asset );
55
+ return !empty( $response ) && empty( $response[ 'error' ] );
56
+ }
57
+ }
src/lib/src/Modules/HackGuard/Lib/Snapshots/FindAssetsToSnap.php CHANGED
@@ -1,9 +1,12 @@
1
- <?php
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\Snapshots;
4
 
5
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
6
- use FernleafSystems\Wordpress\Services\Core\VOs;
 
 
 
7
  use FernleafSystems\Wordpress\Services\Services;
8
 
9
  class FindAssetsToSnap {
@@ -11,26 +14,26 @@ class FindAssetsToSnap {
11
  use ModConsumer;
12
 
13
  /**
14
- * @return VOs\WpPluginVo[]|VOs\WpThemeVo[]
15
  */
16
- public function run() {
17
- $aAssets = [];
18
 
19
- foreach ( Services::WpPlugins()->getPluginsAsVo() as $oAsset ) {
20
- if ( $oAsset->active ) {
21
- $aAssets[] = $oAsset;
22
  }
23
  }
24
 
25
- $oWPT = Services::WpThemes();
26
- $oAsset = $oWPT->getThemeAsVo( $oWPT->getCurrent()->get_stylesheet() );
27
- $aAssets[] = $oAsset;
28
 
29
- if ( $oWPT->isActiveThemeAChild() ) {
30
- $oAsset = $oWPT->getThemeAsVo( $oAsset->wp_theme->get_template() );
31
- $aAssets[] = $oAsset;
32
  }
33
 
34
- return $aAssets;
35
  }
36
  }
1
+ <?php declare( strict_types=1 );
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\Snapshots;
4
 
5
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
6
+ use FernleafSystems\Wordpress\Services\Core\VOs\Assets\{
7
+ WpPluginVo,
8
+ WpThemeVo
9
+ };
10
  use FernleafSystems\Wordpress\Services\Services;
11
 
12
  class FindAssetsToSnap {
14
  use ModConsumer;
15
 
16
  /**
17
+ * @return WpPluginVo[]|WpThemeVo[]
18
  */
19
+ public function run() :array {
20
+ $assets = [];
21
 
22
+ foreach ( Services::WpPlugins()->getPluginsAsVo() as $asset ) {
23
+ if ( $asset->active ) {
24
+ $assets[] = $asset;
25
  }
26
  }
27
 
28
+ $WPT = Services::WpThemes();
29
+ $asset = $WPT->getThemeAsVo( $WPT->getCurrent()->get_stylesheet() );
30
+ $assets[] = $asset;
31
 
32
+ if ( $WPT->isActiveThemeAChild() ) {
33
+ $asset = $WPT->getThemeAsVo( $asset->wp_theme->get_template() );
34
+ $assets[] = $asset;
35
  }
36
 
37
+ return array_filter( $assets );
38
  }
39
  }
src/lib/src/Modules/HackGuard/Lib/Snapshots/Store.php CHANGED
@@ -2,8 +2,10 @@
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\Snapshots;
4
 
5
- use FernleafSystems\Wordpress\Services\Core\VOs\WpPluginVo;
6
- use FernleafSystems\Wordpress\Services\Core\VOs\WpThemeVo;
 
 
7
  use FernleafSystems\Wordpress\Services\Services;
8
 
9
  class Store {
@@ -13,99 +15,76 @@ class Store {
13
  /**
14
  * @var array
15
  */
16
- private $aSnapMeta;
17
 
18
  /**
19
  * @var array
20
  */
21
- private $aSnapData;
22
 
23
  /**
24
  * @var WpPluginVo|WpThemeVo
25
  */
26
- private $oAsset;
27
 
28
  /**
29
  * @var string
30
  */
31
- protected $sWorkingDir;
32
 
33
  /**
34
- * Store constructor.
35
- * @param WpPluginVo|WpThemeVo $oAsset
36
  */
37
- public function __construct( $oAsset ) {
38
- $this->oAsset = $oAsset;
39
  }
40
 
41
  /**
42
  * @return WpPluginVo|WpThemeVo
43
  */
44
  public function getAsset() {
45
- return $this->oAsset;
46
  }
47
 
48
- /**
49
- * @return string
50
- */
51
- public function getContext() {
52
- return ( $this->getAsset() instanceof WpPluginVo ) ? 'plugins' : 'themes';
53
  }
54
 
55
- /**
56
- * @return string
57
- */
58
- public function getSnapStorePath() {
59
  return $this->getBaseSnapPath().'.txt';
60
  }
61
 
62
- /**
63
- * @return string
64
- */
65
- public function getSnapStoreMetaPath() {
66
  return $this->getBaseSnapPath().'_meta'.'.txt';
67
  }
68
 
69
- /**
70
- * @return string
71
- */
72
- private function getBaseSnapPath() {
73
  return path_join( $this->getWorkingDir(), path_join( $this->getContext(), $this->getSlug() ) );
74
  }
75
 
76
- /**
77
- * @return string
78
- */
79
- public function getWorkingDir() {
80
- return $this->sWorkingDir;
81
  }
82
 
83
- /**
84
- * @return string
85
- */
86
- protected function getSlug() {
87
- $oAs = $this->getAsset();
88
- return ( $oAs instanceof WpPluginVo ) ? dirname( $oAs->file ) : $oAs->stylesheet;
89
  }
90
 
91
  /**
92
  * @return string[]
93
  */
94
- public function getSnapData() {
95
- if ( !is_array( $this->aSnapData ) ) {
96
  $this->loadSnapDataIfExists();
97
  }
98
- return is_array( $this->aSnapData ) ? $this->aSnapData : [];
99
  }
100
 
101
- /**
102
- * @return array[]
103
- */
104
- public function getSnapMeta() {
105
- if ( empty( $this->aSnapMeta ) ) {
106
  $this->loadSnapMetaIfExists();
107
  }
108
- return is_array( $this->aSnapMeta ) ? $this->aSnapMeta : [];
109
  }
110
 
111
  /**
@@ -113,10 +92,10 @@ class Store {
113
  */
114
  private function loadSnapDataIfExists() {
115
  try {
116
- $this->aSnapData = $this->readSnapData();
117
  }
118
  catch ( \Exception $e ) {
119
- $this->aSnapData = [];
120
  }
121
  return $this;
122
  }
@@ -126,10 +105,10 @@ class Store {
126
  */
127
  private function loadSnapMetaIfExists() {
128
  try {
129
- $this->aSnapMeta = $this->readSnapMeta();
130
  }
131
  catch ( \Exception $e ) {
132
- $this->aSnapMeta = [];
133
  }
134
  return $this;
135
  }
@@ -137,47 +116,47 @@ class Store {
137
  /**
138
  * @throws \Exception
139
  */
140
- private function readSnapData() {
141
- $oFS = Services::WpFs();
142
 
143
  if ( $this->isReady() && !$this->getSnapStoreExists() ) {
144
  throw new \Exception( sprintf( 'Snapshot store does not exist: "%s"', $this->getSnapStorePath() ) );
145
  }
146
 
147
- $sEncoded = $oFS->getFileContent( $this->getSnapStorePath(), true );
148
- if ( !empty( $sEncoded ) ) {
149
- $aSnap = [];
150
- foreach ( array_map( 'trim', explode( "\n", $sEncoded ) ) as $sLine ) {
151
- list( $sFile, $sHash ) = explode( self::SEPARATOR, $sLine, 2 );
152
- $aSnap[ $sFile ] = $sHash;
153
  }
154
  }
155
- if ( empty( $aSnap ) ) {
156
  throw new \Exception( 'Snapshot data could not be decoded' );
157
  }
158
 
159
- return $aSnap;
160
  }
161
 
162
  /**
163
  * @throws \Exception
164
  */
165
  private function readSnapMeta() {
166
- $oFS = Services::WpFs();
167
 
168
  if ( $this->isReady() && !$this->getSnapStoreExists() ) {
169
  throw new \Exception( sprintf( 'Snapshot store does not exist: "%s"', $this->getSnapStorePath() ) );
170
  }
171
 
172
- $sEncoded = $oFS->getFileContent( $this->getSnapStoreMetaPath(), true );
173
- if ( !empty( $sEncoded ) ) {
174
- $aData = json_decode( $sEncoded, true );
175
  }
176
- if ( empty( $aData ) || !is_array( $aData ) ) {
177
  throw new \Exception( 'Snapshot data could not be decoded' );
178
  }
179
 
180
- return $aData;
181
  }
182
 
183
  /**
@@ -186,13 +165,13 @@ class Store {
186
  */
187
  public function save() {
188
  if ( $this->isReady() ) {
189
- $aToWrite = [];
190
- foreach ( $this->getSnapData() as $sFile => $sHash ) {
191
- $aToWrite[] = sprintf( '%s%s%s', $sFile, self::SEPARATOR, $sHash );
192
  }
193
  Services::WpFs()->putFileContent(
194
  $this->getSnapStorePath(),
195
- implode( "\n", $aToWrite ),
196
  true
197
  );
198
  Services::WpFs()->putFileContent(
@@ -208,26 +187,23 @@ class Store {
208
  * @return bool
209
  * @throws \Exception
210
  */
211
- protected function isReady() {
212
- $oFS = Services::WpFs();
213
- $sDir = dirname( $this->getSnapStorePath() );
214
 
215
  if ( strlen( $this->getContext() ) < 1 ) {
216
  throw new \Exception( 'Context has not been specified' );
217
  }
218
- if ( !$oFS->mkdir( $sDir ) ) {
219
- throw new \Exception( sprintf( 'Store directory could not be created: %s', $sDir ) );
220
  }
221
- if ( !$oFS->exists( $sDir ) ) {
222
- throw new \Exception( sprintf( 'Store directory path does not exist: %s', $sDir ) );
223
  }
224
  return true;
225
  }
226
 
227
- /**
228
- * @return bool
229
- */
230
- public function getSnapStoreExists() {
231
  return Services::WpFs()->exists( $this->getSnapStorePath() ) && $this->isSnapStoreRelevant();
232
  }
233
 
@@ -235,43 +211,43 @@ class Store {
235
  * We try to capture periods wherein which the plugin may have been deactivated and tracking has paused.
236
  * @return bool
237
  */
238
- private function isSnapStoreRelevant() {
239
- $bRelevant = true;
240
- $oFs = Services::WpFs();
241
- $mTime = Services::Request()->ts() - $oFs->getModifiedTime( $this->getSnapStorePath() );
242
  if ( $mTime > DAY_IN_SECONDS ) {
243
- $bRelevant = false;
244
  }
245
  elseif ( $mTime > DAY_IN_SECONDS/2 ) {
246
- $oFs->touch( $this->getSnapStorePath() );
247
  }
248
- return $bRelevant;
249
  }
250
 
251
  /**
252
- * @param array $aData
253
  * @return $this
254
  */
255
- public function setSnapData( $aData ) {
256
- $this->aSnapData = $aData;
257
  return $this;
258
  }
259
 
260
  /**
261
- * @param array $aMeta
262
  * @return $this
263
  */
264
- public function setSnapMeta( $aMeta ) {
265
- $this->aSnapMeta = $aMeta;
266
  return $this;
267
  }
268
 
269
  /**
270
- * @param string $sDir
271
  * @return $this
272
  */
273
- public function setWorkingDir( $sDir ) {
274
- $this->sWorkingDir = $sDir;
275
  return $this;
276
  }
277
  }
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\Snapshots;
4
 
5
+ use FernleafSystems\Wordpress\Services\Core\VOs\Assets\{
6
+ WpPluginVo,
7
+ WpThemeVo
8
+ };
9
  use FernleafSystems\Wordpress\Services\Services;
10
 
11
  class Store {
15
  /**
16
  * @var array
17
  */
18
+ private $snapMeta;
19
 
20
  /**
21
  * @var array
22
  */
23
+ private $snapData;
24
 
25
  /**
26
  * @var WpPluginVo|WpThemeVo
27
  */
28
+ private $asset;
29
 
30
  /**
31
  * @var string
32
  */
33
+ protected $workingDir;
34
 
35
  /**
36
+ * @param WpPluginVo|WpThemeVo $asset
 
37
  */
38
+ public function __construct( $asset ) {
39
+ $this->asset = $asset;
40
  }
41
 
42
  /**
43
  * @return WpPluginVo|WpThemeVo
44
  */
45
  public function getAsset() {
46
+ return $this->asset;
47
  }
48
 
49
+ public function getContext() :string {
50
+ return ( $this->asset->asset_type === 'plugin' ) ? 'plugins' : 'themes';
 
 
 
51
  }
52
 
53
+ public function getSnapStorePath() :string {
 
 
 
54
  return $this->getBaseSnapPath().'.txt';
55
  }
56
 
57
+ public function getSnapStoreMetaPath() :string {
 
 
 
58
  return $this->getBaseSnapPath().'_meta'.'.txt';
59
  }
60
 
61
+ private function getBaseSnapPath() :string {
 
 
 
62
  return path_join( $this->getWorkingDir(), path_join( $this->getContext(), $this->getSlug() ) );
63
  }
64
 
65
+ public function getWorkingDir() :string {
66
+ return $this->workingDir;
 
 
 
67
  }
68
 
69
+ protected function getSlug() :string {
70
+ return ( $this->asset->asset_type === 'plugin' ) ? dirname( $this->asset->file ) : $this->asset->stylesheet;
 
 
 
 
71
  }
72
 
73
  /**
74
  * @return string[]
75
  */
76
+ public function getSnapData() :array {
77
+ if ( !is_array( $this->snapData ) ) {
78
  $this->loadSnapDataIfExists();
79
  }
80
+ return is_array( $this->snapData ) ? $this->snapData : [];
81
  }
82
 
83
+ public function getSnapMeta() :array {
84
+ if ( empty( $this->snapMeta ) ) {
 
 
 
85
  $this->loadSnapMetaIfExists();
86
  }
87
+ return is_array( $this->snapMeta ) ? $this->snapMeta : [];
88
  }
89
 
90
  /**
92
  */
93
  private function loadSnapDataIfExists() {
94
  try {
95
+ $this->snapData = $this->readSnapData();
96
  }
97
  catch ( \Exception $e ) {
98
+ $this->snapData = [];
99
  }
100
  return $this;
101
  }
105
  */
106
  private function loadSnapMetaIfExists() {
107
  try {
108
+ $this->snapMeta = $this->readSnapMeta();
109
  }
110
  catch ( \Exception $e ) {
111
+ $this->snapMeta = [];
112
  }
113
  return $this;
114
  }
116
  /**
117
  * @throws \Exception
118
  */
119
+ private function readSnapData() :array {
120
+ $FS = Services::WpFs();
121
 
122
  if ( $this->isReady() && !$this->getSnapStoreExists() ) {
123
  throw new \Exception( sprintf( 'Snapshot store does not exist: "%s"', $this->getSnapStorePath() ) );
124
  }
125
 
126
+ $encoded = $FS->getFileContent( $this->getSnapStorePath(), true );
127
+ if ( !empty( $encoded ) ) {
128
+ $snap = [];
129
+ foreach ( array_map( 'trim', explode( "\n", $encoded ) ) as $line ) {
130
+ list( $file, $hash ) = explode( self::SEPARATOR, $line, 2 );
131
+ $snap[ $file ] = $hash;
132
  }
133
  }
134
+ if ( empty( $snap ) ) {
135
  throw new \Exception( 'Snapshot data could not be decoded' );
136
  }
137
 
138
+ return $snap;
139
  }
140
 
141
  /**
142
  * @throws \Exception
143
  */
144
  private function readSnapMeta() {
145
+ $FS = Services::WpFs();
146
 
147
  if ( $this->isReady() && !$this->getSnapStoreExists() ) {
148
  throw new \Exception( sprintf( 'Snapshot store does not exist: "%s"', $this->getSnapStorePath() ) );
149
  }
150
 
151
+ $encoded = $FS->getFileContent( $this->getSnapStoreMetaPath(), true );
152
+ if ( !empty( $encoded ) ) {
153
+ $data = json_decode( $encoded, true );
154
  }
155
+ if ( empty( $data ) || !is_array( $data ) ) {
156
  throw new \Exception( 'Snapshot data could not be decoded' );
157
  }
158
 
159
+ return $data;
160
  }
161
 
162
  /**
165
  */
166
  public function save() {
167
  if ( $this->isReady() ) {
168
+ $toWrite = [];
169
+ foreach ( $this->getSnapData() as $file => $hash ) {
170
+ $toWrite[] = sprintf( '%s%s%s', $file, self::SEPARATOR, $hash );
171
  }
172
  Services::WpFs()->putFileContent(
173
  $this->getSnapStorePath(),
174
+ implode( "\n", $toWrite ),
175
  true
176
  );
177
  Services::WpFs()->putFileContent(
187
  * @return bool
188
  * @throws \Exception
189
  */
190
+ protected function isReady() :bool {
191
+ $FS = Services::WpFs();
192
+ $dir = dirname( $this->getSnapStorePath() );
193
 
194
  if ( strlen( $this->getContext() ) < 1 ) {
195
  throw new \Exception( 'Context has not been specified' );
196
  }
197
+ if ( !$FS->mkdir( $dir ) ) {
198
+ throw new \Exception( sprintf( 'Store directory could not be created: %s', $dir ) );
199
  }
200
+ if ( !$FS->exists( $dir ) ) {
201
+ throw new \Exception( sprintf( 'Store directory path does not exist: %s', $dir ) );
202
  }
203
  return true;
204
  }
205
 
206
+ public function getSnapStoreExists() :bool {
 
 
 
207
  return Services::WpFs()->exists( $this->getSnapStorePath() ) && $this->isSnapStoreRelevant();
208
  }
209
 
211
  * We try to capture periods wherein which the plugin may have been deactivated and tracking has paused.
212
  * @return bool
213
  */
214
+ private function isSnapStoreRelevant() :bool {
215
+ $relevant = true;
216
+ $FS = Services::WpFs();
217
+ $mTime = Services::Request()->ts() - $FS->getModifiedTime( $this->getSnapStorePath() );
218
  if ( $mTime > DAY_IN_SECONDS ) {
219
+ $relevant = false;
220
  }
221
  elseif ( $mTime > DAY_IN_SECONDS/2 ) {
222
+ $FS->touch( $this->getSnapStorePath() );
223
  }
224
+ return $relevant;
225
  }
226
 
227
  /**
228
+ * @param array $data
229
  * @return $this
230
  */
231
+ public function setSnapData( array $data ) {
232
+ $this->snapData = $data;
233
  return $this;
234
  }
235
 
236
  /**
237
+ * @param array $meta
238
  * @return $this
239
  */
240
+ public function setSnapMeta( array $meta ) {
241
+ $this->snapMeta = $meta;
242
  return $this;
243
  }
244
 
245
  /**
246
+ * @param string $dir
247
  * @return $this
248
  */
249
+ public function setWorkingDir( string $dir ) {
250
+ $this->workingDir = $dir;
251
  return $this;
252
  }
253
  }
src/lib/src/Modules/HackGuard/Lib/Snapshots/StoreAction/BaseAction.php CHANGED
@@ -5,8 +5,8 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\Snapshot
5
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\Snapshots;
6
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\ModCon;
7
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
8
- use FernleafSystems\Wordpress\Services\Core\VOs\WpPluginVo;
9
- use FernleafSystems\Wordpress\Services\Core\VOs\WpThemeVo;
10
 
11
  class BaseAction {
12
 
@@ -15,24 +15,21 @@ class BaseAction {
15
  /**
16
  * @var WpPluginVo|WpThemeVo
17
  */
18
- private $oAsset;
19
-
20
- public function __construct() {
21
- }
22
 
23
  /**
24
  * @return WpPluginVo|WpThemeVo
25
  */
26
  public function getAsset() {
27
- return $this->oAsset;
28
  }
29
 
30
  /**
31
- * @param WpPluginVo|WpThemeVo $oAsset
32
  * @return static
33
  */
34
- public function setAsset( $oAsset ) {
35
- $this->oAsset = $oAsset;
36
  return $this;
37
  }
38
 
5
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\Snapshots;
6
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\ModCon;
7
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
8
+ use FernleafSystems\Wordpress\Services\Core\VOs\Assets\WpPluginVo;
9
+ use FernleafSystems\Wordpress\Services\Core\VOs\Assets\WpThemeVo;
10
 
11
  class BaseAction {
12
 
15
  /**
16
  * @var WpPluginVo|WpThemeVo
17
  */
18
+ private $asset;
 
 
 
19
 
20
  /**
21
  * @return WpPluginVo|WpThemeVo
22
  */
23
  public function getAsset() {
24
+ return $this->asset;
25
  }
26
 
27
  /**
28
+ * @param WpPluginVo|WpThemeVo $asset
29
  * @return static
30
  */
31
+ public function setAsset( $asset ) {
32
+ $this->asset = $asset;
33
  return $this;
34
  }
35
 
src/lib/src/Modules/HackGuard/Lib/Snapshots/StoreAction/BaseBulk.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\Snapshots\StoreAction;
4
 
1
+ <?php declare( strict_types=1 );
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\Snapshots\StoreAction;
4
 
src/lib/src/Modules/HackGuard/Lib/Snapshots/StoreAction/Build.php CHANGED
@@ -3,7 +3,7 @@
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\Snapshots\StoreAction;
4
 
5
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\Snapshots;
6
- use FernleafSystems\Wordpress\Services\Core\VOs\WpPluginVo;
7
  use FernleafSystems\Wordpress\Services\Services;
8
 
9
  class Build extends BaseAction {
@@ -50,10 +50,10 @@ class Build extends BaseAction {
50
  'ts' => Services::Request()->ts(),
51
  'snap_version' => $this->getCon()->getVersion(),
52
  ];
53
- $meta[ 'unique_id' ] = ( $asset instanceof WpPluginVo ) ?
54
  $asset->file
55
  : $asset->stylesheet;
56
- $meta[ 'name' ] = ( $asset instanceof WpPluginVo ) ?
57
  $asset->Name
58
  : $asset->wp_theme->get( 'Name' );
59
  $meta[ 'version' ] = $asset->version;
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\Snapshots\StoreAction;
4
 
5
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\Snapshots;
6
+ use FernleafSystems\Wordpress\Services\Core\VOs\Assets\WpPluginVo;
7
  use FernleafSystems\Wordpress\Services\Services;
8
 
9
  class Build extends BaseAction {
50
  'ts' => Services::Request()->ts(),
51
  'snap_version' => $this->getCon()->getVersion(),
52
  ];
53
+ $meta[ 'unique_id' ] = $asset->asset_type === 'plugin' ?
54
  $asset->file
55
  : $asset->stylesheet;
56
+ $meta[ 'name' ] = $asset->asset_type === 'plugin' ?
57
  $asset->Name
58
  : $asset->wp_theme->get( 'Name' );
59
  $meta[ 'version' ] = $asset->version;
src/lib/src/Modules/HackGuard/Lib/Snapshots/StoreAction/ScheduleBuildAll.php CHANGED
@@ -1,9 +1,13 @@
1
- <?php
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\Snapshots\StoreAction;
4
 
 
5
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\Snapshots\FindAssetsToSnap;
6
- use FernleafSystems\Wordpress\Services\Core\VOs;
 
 
 
7
  use FernleafSystems\Wordpress\Services\Services;
8
 
9
  class ScheduleBuildAll extends BaseBulk {
@@ -17,6 +21,13 @@ class ScheduleBuildAll extends BaseBulk {
17
  ->run();
18
  }
19
  catch ( \Exception $e ) {
 
 
 
 
 
 
 
20
  }
21
  }
22
  }
@@ -28,23 +39,24 @@ class ScheduleBuildAll extends BaseBulk {
28
  }
29
 
30
  public function schedule() {
31
- $sHook = $this->getCronHook();
32
- if ( wp_next_scheduled( $sHook ) === false && count( $this->getAssetsThatNeedBuilt() ) > 0 ) {
33
- wp_schedule_single_event( Services::Request()->ts() + 15, $sHook );
34
  }
35
  }
36
 
37
  /**
38
  * Only those that don't have a meta file or the versions are different
39
- * @return VOs\WpPluginVo[]|VOs\WpThemeVo[]
40
  */
41
- private function getAssetsThatNeedBuilt() {
42
  return array_filter(
 
43
  ( new FindAssetsToSnap() )
44
  ->setMod( $this->getMod() )
45
  ->run(),
 
46
  function ( $asset ) {
47
- /** @var VOs\WpPluginVo|VOs\WpThemeVo $asset */
48
  try {
49
  $meta = ( new Load() )
50
  ->setMod( $this->getMod() )
1
+ <?php declare( strict_types=1 );
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\Snapshots\StoreAction;
4
 
5
+ use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\Snapshots\CrowdSourced\SubmitHashes;
6
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib\Snapshots\FindAssetsToSnap;
7
+ use FernleafSystems\Wordpress\Services\Core\VOs\Assets\{
8
+ WpPluginVo,
9
+ WpThemeVo
10
+ };
11
  use FernleafSystems\Wordpress\Services\Services;
12
 
13
  class ScheduleBuildAll extends BaseBulk {
21
  ->run();
22
  }
23
  catch ( \Exception $e ) {
24
+ error_log( '[Build Asset] Notice: '.$e->getMessage() );
25
+ }
26
+
27
+ if ( $asset->asset_type === 'plugin' || !$asset->is_child ) {
28
+ ( new SubmitHashes() )
29
+ ->setMod( $this->getMod() )
30
+ ->run( $asset );
31
  }
32
  }
33
  }
39
  }
40
 
41
  public function schedule() {
42
+ $hook = $this->getCronHook();
43
+ if ( wp_next_scheduled( $hook ) === false && count( $this->getAssetsThatNeedBuilt() ) > 0 ) {
44
+ wp_schedule_single_event( Services::Request()->ts() + 15, $hook );
45
  }
46
  }
47
 
48
  /**
49
  * Only those that don't have a meta file or the versions are different
50
+ * @return WpPluginVo[]|WpThemeVo[]
51
  */
52
+ private function getAssetsThatNeedBuilt() :array {
53
  return array_filter(
54
+
55
  ( new FindAssetsToSnap() )
56
  ->setMod( $this->getMod() )
57
  ->run(),
58
+
59
  function ( $asset ) {
 
60
  try {
61
  $meta = ( new Load() )
62
  ->setMod( $this->getMod() )
src/lib/src/Modules/HackGuard/Lib/Snapshots/StoreAction/TouchAll.php CHANGED
@@ -10,11 +10,11 @@ class TouchAll extends BaseBulk {
10
  public function run() {
11
  foreach ( ( new FindAssetsToSnap() )->setMod( $this->getMod() )->run() as $asset ) {
12
  try {
13
- $oStore = ( new Load() )
14
  ->setMod( $this->getMod() )
15
  ->setAsset( $asset )
16
  ->run();
17
- foreach ( [ $oStore->getSnapStorePath(), $oStore->getSnapStoreMetaPath() ] as $path ) {
18
  Services::WpFs()->touch( $path );
19
  }
20
  }
10
  public function run() {
11
  foreach ( ( new FindAssetsToSnap() )->setMod( $this->getMod() )->run() as $asset ) {
12
  try {
13
+ $store = ( new Load() )
14
  ->setMod( $this->getMod() )
15
  ->setAsset( $asset )
16
  ->run();
17
+ foreach ( [ $store->getSnapStorePath(), $store->getSnapStoreMetaPath() ] as $path ) {
18
  Services::WpFs()->touch( $path );
19
  }
20
  }
src/lib/src/Modules/HackGuard/ModCon.php CHANGED
@@ -187,8 +187,8 @@ class ModCon extends BaseShield\ModCon {
187
  * @return string
188
  */
189
  public function getTempDir() {
190
- $sDir = $this->getCon()->getPluginCachePath( 'scans' );
191
- return Services::WpFs()->mkdir( $sDir ) ? $sDir : false;
192
  }
193
 
194
  public function getDbHandler_FileLocker() :Databases\FileLocker\Handler {
187
  * @return string
188
  */
189
  public function getTempDir() {
190
+ $dir = $this->getCon()->getPluginCachePath( 'scans' );
191
+ return Services::WpFs()->mkdir( $dir ) ? $dir : false;
192
  }
193
 
194
  public function getDbHandler_FileLocker() :Databases\FileLocker\Handler {
src/lib/src/Modules/HackGuard/Options.php CHANGED
@@ -272,11 +272,11 @@ class Options extends BaseShield\Options {
272
  }
273
 
274
  /**
275
- * @param bool $bIsScanCron
276
  * @return $this
277
  */
278
- public function setIsScanCron( $bIsScanCron ) {
279
- return $this->setOpt( 'is_scan_cron', $bIsScanCron );
280
  }
281
 
282
  /**
272
  }
273
 
274
  /**
275
+ * @param bool $isCron
276
  * @return $this
277
  */
278
+ public function setIsScanCron( bool $isCron ) {
279
+ return $this->setOpt( 'is_scan_cron', $isCron );
280
  }
281
 
282
  /**
src/lib/src/Modules/HackGuard/Scan/Controller/Base.php CHANGED
@@ -20,7 +20,7 @@ abstract class Base extends ExecOnceModConsumer {
20
  /**
21
  * @var BaseScanActionVO
22
  */
23
- private $oScanActionVO;
24
 
25
  /**
26
  * Base constructor.
@@ -29,6 +29,10 @@ abstract class Base extends ExecOnceModConsumer {
29
  public function __construct() {
30
  }
31
 
 
 
 
 
32
  protected function run() {
33
  add_action(
34
  $this->getCon()->prefix( 'ondemand_scan_'.$this->getSlug() ),
@@ -88,9 +92,8 @@ abstract class Base extends ExecOnceModConsumer {
88
  * @param int|string $itemID
89
  * @param string $action
90
  * @return bool
91
- * @throws \Exception
92
  */
93
- public function executeItemAction( $itemID, string $action ) {
94
  $success = false;
95
 
96
  if ( is_numeric( $itemID ) ) {
@@ -170,10 +173,10 @@ abstract class Base extends ExecOnceModConsumer {
170
  * @return BaseScanActionVO|mixed
171
  */
172
  public function getScanActionVO() {
173
- if ( !$this->oScanActionVO instanceof BaseScanActionVO ) {
174
- $this->oScanActionVO = HackGuard\Scan\ScanActionFromSlug::GetAction( $this->getSlug() );
175
  }
176
- return $this->oScanActionVO;
177
  }
178
 
179
  public function getScanName() :string {
@@ -226,12 +229,12 @@ abstract class Base extends ExecOnceModConsumer {
226
  * TODO: Make private/protected
227
  */
228
  public function runCronAutoRepair() {
229
- $oRes = $this->getItemsToAutoRepair();
230
- if ( $oRes->hasItems() ) {
231
- foreach ( $oRes->getAllItems() as $oItem ) {
232
  try {
233
  $this->getItemActionHandler()
234
- ->setScanItem( $oItem )
235
  ->repair();
236
  }
237
  catch ( \Exception $e ) {
20
  /**
21
  * @var BaseScanActionVO
22
  */
23
+ private $scanActionVO;
24
 
25
  /**
26
  * Base constructor.
29
  public function __construct() {
30
  }
31
 
32
+ protected function canRun() :bool {
33
+ return $this->isReady();
34
+ }
35
+
36
  protected function run() {
37
  add_action(
38
  $this->getCon()->prefix( 'ondemand_scan_'.$this->getSlug() ),
92
  * @param int|string $itemID
93
  * @param string $action
94
  * @return bool
 
95
  */
96
+ public function executeItemAction( int $itemID, string $action ) :bool {
97
  $success = false;
98
 
99
  if ( is_numeric( $itemID ) ) {
173
  * @return BaseScanActionVO|mixed
174
  */
175
  public function getScanActionVO() {
176
+ if ( !$this->scanActionVO instanceof BaseScanActionVO ) {
177
+ $this->scanActionVO = HackGuard\Scan\ScanActionFromSlug::GetAction( $this->getSlug() );
178
  }
179
+ return $this->scanActionVO;
180
  }
181
 
182
  public function getScanName() :string {
229
  * TODO: Make private/protected
230
  */
231
  public function runCronAutoRepair() {
232
+ $results = $this->getItemsToAutoRepair();
233
+ if ( $results->hasItems() ) {
234
+ foreach ( $results->getAllItems() as $item ) {
235
  try {
236
  $this->getItemActionHandler()
237
+ ->setScanItem( $item )
238
  ->repair();
239
  }
240
  catch ( \Exception $e ) {
src/lib/src/Modules/HackGuard/Scan/Controller/Wpv.php CHANGED
@@ -44,12 +44,12 @@ class Wpv extends BaseForAssets {
44
 
45
  /**
46
  * @param string $file
47
- * @return Scans\Wpv\WpVulnDb\WpVulnVO[]
48
  */
49
  public function getPluginVulnerabilities( $file ) {
50
  return array_map(
51
  function ( $item ) {
52
- return $item->getWpVulnVo();
53
  },
54
  $this->getAllResults()->getItemsForSlug( $file )
55
  );
44
 
45
  /**
46
  * @param string $file
47
+ * @return Scans\Wpv\WpVulnDb\VulnVO[]
48
  */
49
  public function getPluginVulnerabilities( $file ) {
50
  return array_map(
51
  function ( $item ) {
52
+ return $item->getVulnVo();
53
  },
54
  $this->getAllResults()->getItemsForSlug( $file )
55
  );
src/lib/src/Modules/HackGuard/Scan/Results/ConvertBetweenTypes.php CHANGED
@@ -19,12 +19,12 @@ class ConvertBetweenTypes {
19
  * @return Databases\Scanner\EntryVO[]|mixed
20
  */
21
  public function fromResultsToVOs( $oResultsSet ) {
22
- $aVos = [];
23
- foreach ( $oResultsSet->getAllItems() as $oIt ) {
24
- /** @var Scans\Base\BaseResultItem $oIt */
25
- $aVos[ $oIt->generateHash() ] = $this->convertResultItemToVO( $oIt );
26
  }
27
- return $aVos;
28
  }
29
 
30
  /**
19
  * @return Databases\Scanner\EntryVO[]|mixed
20
  */
21
  public function fromResultsToVOs( $oResultsSet ) {
22
+ $vos = [];
23
+ foreach ( $oResultsSet->getAllItems() as $item ) {
24
+ /** @var Scans\Base\BaseResultItem $item */
25
+ $vos[ $item->generateHash() ] = $this->convertResultItemToVO( $item );
26
  }
27
+ return $vos;
28
  }
29
 
30
  /**
src/lib/src/Modules/HackGuard/Scan/ScansController.php CHANGED
@@ -43,27 +43,6 @@ class ScansController extends ExecOnceModConsumer {
43
  return $this->scanCons;
44
  }
45
 
46
- /**
47
- * @return int[] - key is scan slug
48
- */
49
- public function getLastScansAt() :array {
50
- /** @var Options $opts */
51
- $opts = $this->getOptions();
52
- /** @var Databases\Events\Select $oSel */
53
- $oSel = $this->getCon()
54
- ->getModule_Events()
55
- ->getDbHandler_Events()
56
- ->getQuerySelector();
57
- $aEvents = $oSel->getLatestForAllEvents();
58
-
59
- $aLatest = [];
60
- foreach ( $opts->getScanSlugs() as $slug ) {
61
- $event = $slug.'_scan_run';
62
- $aLatest[ $slug ] = isset( $aEvents[ $event ] ) ? (int)$aEvents[ $event ]->created_at : 0;
63
- }
64
- return $aLatest;
65
- }
66
-
67
  /**
68
  * @param string $slug
69
  * @return Controller\Base|mixed
43
  return $this->scanCons;
44
  }
45
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
  /**
47
  * @param string $slug
48
  * @return Controller\Base|mixed
src/lib/src/Modules/HackGuard/Scan/Utilities/PtgAddReinstallLinks.php CHANGED
@@ -5,7 +5,7 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Scan\Utiliti
5
  use FernleafSystems\Utilities\Logic\ExecOnce;
6
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard;
7
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Scan\Controller;
8
- use FernleafSystems\Wordpress\Services\Core\VOs\WpPluginVo;
9
  use FernleafSystems\Wordpress\Services\Services;
10
 
11
  class PtgAddReinstallLinks {
@@ -69,7 +69,8 @@ class PtgAddReinstallLinks {
69
  $WPP = Services::WpPlugins();
70
 
71
  $plugin = $WPP->getPluginAsVo( $file );
72
- if ( $plugin instanceof WpPluginVo && $plugin->isWpOrg() && !$WPP->isUpdateAvailable( $file ) ) {
 
73
  $template = '<a href="javascript:void(0)">%s</a>';
74
  $links[ 'icwp-reinstall' ] = sprintf( $template, __( 'Re-Install', 'wp-simple-firewall' ) );
75
  }
5
  use FernleafSystems\Utilities\Logic\ExecOnce;
6
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard;
7
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Scan\Controller;
8
+ use FernleafSystems\Wordpress\Services\Core\VOs\Assets\WpPluginVo;
9
  use FernleafSystems\Wordpress\Services\Services;
10
 
11
  class PtgAddReinstallLinks {
69
  $WPP = Services::WpPlugins();
70
 
71
  $plugin = $WPP->getPluginAsVo( $file );
72
+ if ( $plugin->asset_type === 'plugin'
73
+ && $plugin->isWpOrg() && !$WPP->isUpdateAvailable( $file ) ) {
74
  $template = '<a href="javascript:void(0)">%s</a>';
75
  $links[ 'icwp-reinstall' ] = sprintf( $template, __( 'Re-Install', 'wp-simple-firewall' ) );
76
  }
src/lib/src/Modules/IPs/Lib/BlockRequest.php CHANGED
@@ -83,7 +83,7 @@ class BlockRequest extends ExecOnceModConsumer {
83
  sprintf( _n( '%s minute', '%s minutes', $timeRemaining, 'wp-simple-firewall' ), $timeRemaining )
84
  ),
85
  sprintf( __( 'You tripped the security plugin defenses a total of %s times making you a suspect.', 'wp-simple-firewall' ), $opts->getOffenseLimit() ),
86
- sprintf( __( 'If you believe this to be in error, please contact the site owner and quote your IP address below.', 'wp-simple-firewall' ) ),
87
  ],
88
  'your_ip' => 'Your IP address',
89
  'unblock' => [
83
  sprintf( _n( '%s minute', '%s minutes', $timeRemaining, 'wp-simple-firewall' ), $timeRemaining )
84
  ),
85
  sprintf( __( 'You tripped the security plugin defenses a total of %s times making you a suspect.', 'wp-simple-firewall' ), $opts->getOffenseLimit() ),
86
+ __( 'If you believe this to be in error, please contact the site owner and quote your IP address below.', 'wp-simple-firewall' ),
87
  ],
88
  'your_ip' => 'Your IP address',
89
  'unblock' => [
src/lib/src/Modules/IPs/Lib/Bots/BotSignalsController.php CHANGED
@@ -5,7 +5,6 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Lib\Bots;
5
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base\Common\ExecOnceModConsumer;
6
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\{
7
  BotTrack,
8
- Lib\Bots\Calculator\CalculateVisitorBotScores,
9
  ModCon,
10
  Options
11
  };
@@ -32,7 +31,7 @@ class BotSignalsController extends ExecOnceModConsumer {
32
 
33
  if ( $botScoreMinimum > 0 ) {
34
 
35
- $score = ( new CalculateVisitorBotScores() )
36
  ->setMod( $this->getMod() )
37
  ->setIP( empty( $IP ) ? Services::IP()->getRequestIp() : $IP )
38
  ->probability();
5
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base\Common\ExecOnceModConsumer;
6
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\{
7
  BotTrack,
 
8
  ModCon,
9
  Options
10
  };
31
 
32
  if ( $botScoreMinimum > 0 ) {
33
 
34
+ $score = ( new Calculator\CalculateVisitorBotScores() )
35
  ->setMod( $this->getMod() )
36
  ->setIP( empty( $IP ) ? Services::IP()->getRequestIp() : $IP )
37
  ->probability();
src/lib/src/Modules/IPs/Lib/Bots/Calculator/BaseBuildScores.php CHANGED
@@ -48,7 +48,7 @@ abstract class BaseBuildScores {
48
  $botSignalDBH->getTableSchema()->getColumnNames(),
49
  function ( $col ) {
50
  return preg_match( '#_at$#', $col ) &&
51
- !in_array( $col, [ 'updated_at', 'deleted_at' ] );
52
  }
53
  )
54
  );
48
  $botSignalDBH->getTableSchema()->getColumnNames(),
49
  function ( $col ) {
50
  return preg_match( '#_at$#', $col ) &&
51
+ !in_array( $col, [ 'snsent_at', 'updated_at', 'deleted_at' ] );
52
  }
53
  )
54
  );
src/lib/src/Modules/IPs/Lib/Bots/NotBot/NotBotHandler.php CHANGED
@@ -94,7 +94,7 @@ class NotBotHandler extends ExecOnceModConsumer {
94
 
95
  protected function getHashForVisitorTS( int $timestamp ) {
96
  return hash_hmac( 'sha1',
97
- $timestamp.(string)Services::IP()->getRequestIp(),
98
  $this->getCon()->getSiteInstallationId()
99
  );
100
  }
94
 
95
  protected function getHashForVisitorTS( int $timestamp ) {
96
  return hash_hmac( 'sha1',
97
+ $timestamp.Services::IP()->getRequestIp(),
98
  $this->getCon()->getSiteInstallationId()
99
  );
100
  }
src/lib/src/Modules/IPs/Lib/Bots/ShieldNET/BuildData.php ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php declare( strict_types=1 );
2
+
3
+ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Lib\Bots\ShieldNET;
4
+
5
+ use FernleafSystems\Wordpress\Plugin\Shield\Databases\BotSignals\EntryVO;
6
+ use FernleafSystems\Wordpress\Plugin\Shield\Databases\BotSignals\Select;
7
+ use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\ModCon;
8
+ use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
9
+ use FernleafSystems\Wordpress\Services\Services;
10
+
11
+ class BuildData {
12
+
13
+ use ModConsumer;
14
+
15
+ public function build( bool $quiet = false ) :array {
16
+
17
+ $recordsToSend = $this->getRecords();
18
+ if ( !$quiet ) {
19
+ $this->markRecordsAsSent( $recordsToSend );
20
+ }
21
+
22
+ $results = array_filter( array_map(
23
+ function ( $entryVO ) {
24
+ $data = [
25
+ 'ip' => $entryVO->ip,
26
+ 'signals' => [],
27
+ ];
28
+ foreach ( $entryVO->getRawData() as $col => $value ) {
29
+ if ( strpos( $col, '_at' ) && $value > 0
30
+ && !in_array( $col, [ 'snsent_at', 'updated_at', 'created_at', 'deleted_at' ] ) ) {
31
+ $data[ 'signals' ][] = str_replace( '_at', '', $col );
32
+ }
33
+ }
34
+ return empty( $data[ 'signals' ] ) ? [] : $data;
35
+ },
36
+ $recordsToSend
37
+ ) );
38
+
39
+ // We order with preference towards IPs with more signals.
40
+ // And, if the only signal is "frontpage" we prefer anything else before it.
41
+ usort( $results, function ( $a, $b ) {
42
+ $countA = count( $a[ 'signals' ] );
43
+ $countB = count( $b[ 'signals' ] );
44
+
45
+ if ( $countA == $countB ) {
46
+
47
+ if ( $countA === 1 && in_array( 'frontpage', $a[ 'signals' ] ) ) {
48
+ $order = 1;
49
+ }
50
+ elseif ( $countB === 1 && in_array( 'frontpage', $b[ 'signals' ] ) ) {
51
+ $order = -1;
52
+ }
53
+ else {
54
+ $order = 0;
55
+ }
56
+ }
57
+ else {
58
+ $order = ( count( $a[ 'signals' ] ) > count( $b[ 'signals' ] ) ) ? -1 : 1;
59
+ }
60
+
61
+ return $order;
62
+ } );
63
+
64
+ return array_slice( $results, 0, 50 );
65
+ }
66
+
67
+ /**
68
+ * @param EntryVO[] $records
69
+ */
70
+ private function markRecordsAsSent( array $records ) {
71
+ if ( !empty( $records ) ) {
72
+ /** @var ModCon $mod */
73
+ $mod = $this->getMod();
74
+ Services::WpDb()
75
+ ->doSql(
76
+ sprintf( 'UPDATE `%s` SET `snsent_at`=%s WHERE `id` in (%s);',
77
+ $mod->getDbHandler_BotSignals()->getTableSchema()->table,
78
+ Services::Request()->ts(),
79
+ implode( ',', array_map( function ( $record ) {
80
+ return $record->id;
81
+ }, $records ) )
82
+ )
83
+ );
84
+ }
85
+ }
86
+
87
+ /**
88
+ * Optimised to ensure that only signals are sent if they've been updated since the last SNAPI-Send
89
+ * @return EntryVO[]
90
+ */
91
+ private function getRecords() :array {
92
+ /** @var ModCon $mod */
93
+ $mod = $this->getMod();
94
+ /** @var Select $select */
95
+ $select = $mod->getDbHandler_BotSignals()->getQuerySelector();
96
+ $records = $select->setLimit( 150 )
97
+ ->setOrderBy( 'updated_at', 'DESC' )
98
+ ->addWhereNotIn( 'ip', array_map( 'inet_pton', Services::IP()->getServerPublicIPs() ) )
99
+ ->addWhereCompareColumns( 'updated_at', 'snsent_at', '>' )
100
+ ->query();
101
+ return is_array( $records ) ? $records : [];
102
+ }
103
+ }
src/lib/src/Modules/IPs/Lib/IpAnalyse/BuildDisplay.php CHANGED
@@ -13,6 +13,7 @@ use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Lib\Ops\LookupIpOnList;
13
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\ModCon;
14
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Strings;
15
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
 
16
  use FernleafSystems\Wordpress\Services\Services;
17
  use FernleafSystems\Wordpress\Services\Utilities\Net\IpID;
18
 
@@ -122,6 +123,11 @@ class BuildDisplay {
122
  ->probability();
123
  $isBot = $mod->getBotSignalsController()->isBot( $ip, false );
124
 
 
 
 
 
 
125
  return $this->getMod()->renderTemplate(
126
  '/wpadmin_pages/insights/ips/ip_analyse/ip_general.twig',
127
  [
@@ -134,13 +140,15 @@ class BuildDisplay {
134
  'bypass_ip' => __( 'Add IP Bypass', 'wp-simple-firewall' ),
135
  'unbypass_ip' => __( 'Remove IP Bypass', 'wp-simple-firewall' ),
136
  'delete_notbot' => __( 'Reset For This IP', 'wp-simple-firewall' ),
 
137
 
138
  'status' => [
139
- 'is_you' => __( 'Is It You?', 'wp-simple-firewall' ),
140
- 'offenses' => __( 'Number of offenses', 'wp-simple-firewall' ),
141
- 'is_blocked' => __( 'Is Blocked', 'wp-simple-firewall' ),
142
- 'is_bypass' => __( 'Is Bypass IP', 'wp-simple-firewall' ),
143
- 'ip_reputation' => __( 'IP Reputation Score', 'wp-simple-firewall' ),
 
144
  ],
145
 
146
  'yes' => __( 'Yes', 'wp-simple-firewall' ),
@@ -160,15 +168,21 @@ class BuildDisplay {
160
  'query_ip_whois' => __( 'Query IP Whois', 'wp-simple-firewall' ),
161
  ],
162
  ],
 
 
 
 
 
163
  'vars' => [
164
  'ip' => $ip,
165
  'status' => [
166
- 'is_you' => Services::IP()->checkIp( $ip, Services::IP()->getRequestIp() ),
167
- 'offenses' => $blockIP instanceof Databases\IPs\EntryVO ? $blockIP->transgressions : 0,
168
- 'is_blocked' => $blockIP instanceof Databases\IPs\EntryVO ? $blockIP->blocked_at > 0 : false,
169
- 'is_bypass' => $bypassIP instanceof Databases\IPs\EntryVO,
170
- 'ip_reputation_score' => $botScore,
171
- 'is_bot' => $isBot,
 
172
  ],
173
  'identity' => [
174
  'who_is_it' => $ipName,
13
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\ModCon;
14
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Strings;
15
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
16
+ use FernleafSystems\Wordpress\Plugin\Shield\ShieldNetApi\Reputation\GetIPReputation;
17
  use FernleafSystems\Wordpress\Services\Services;
18
  use FernleafSystems\Wordpress\Services\Utilities\Net\IpID;
19
 
123
  ->probability();
124
  $isBot = $mod->getBotSignalsController()->isBot( $ip, false );
125
 
126
+ $shieldNetScore = ( new GetIPReputation() )
127
+ ->setMod( $con->getModule_Plugin() )
128
+ ->setIP( $ip )
129
+ ->retrieve()[ 'reputation_score' ] ?? '-';
130
+
131
  return $this->getMod()->renderTemplate(
132
  '/wpadmin_pages/insights/ips/ip_analyse/ip_general.twig',
133
  [
140
  'bypass_ip' => __( 'Add IP Bypass', 'wp-simple-firewall' ),
141
  'unbypass_ip' => __( 'Remove IP Bypass', 'wp-simple-firewall' ),
142
  'delete_notbot' => __( 'Reset For This IP', 'wp-simple-firewall' ),
143
+ 'see_details' => __( 'See Details', 'wp-simple-firewall' ),
144
 
145
  'status' => [
146
+ 'is_you' => __( 'Is It You?', 'wp-simple-firewall' ),
147
+ 'offenses' => __( 'Number of offenses', 'wp-simple-firewall' ),
148
+ 'is_blocked' => __( 'Is Blocked', 'wp-simple-firewall' ),
149
+ 'is_bypass' => __( 'Is Bypass IP', 'wp-simple-firewall' ),
150
+ 'ip_reputation' => __( 'IP Reputation Score', 'wp-simple-firewall' ),
151
+ 'snapi_ip_reputation' => __( 'ShieldNET IP Reputation Score', 'wp-simple-firewall' ),
152
  ],
153
 
154
  'yes' => __( 'Yes', 'wp-simple-firewall' ),
168
  'query_ip_whois' => __( 'Query IP Whois', 'wp-simple-firewall' ),
169
  ],
170
  ],
171
+ 'hrefs' => [
172
+ 'snapi_reputation_details' => add_query_arg(
173
+ [ 'ip' => $ip ], 'https://shsec.io/botornot'
174
+ )
175
+ ],
176
  'vars' => [
177
  'ip' => $ip,
178
  'status' => [
179
+ 'is_you' => Services::IP()->checkIp( $ip, Services::IP()->getRequestIp() ),
180
+ 'offenses' => $blockIP instanceof Databases\IPs\EntryVO ? $blockIP->transgressions : 0,
181
+ 'is_blocked' => $blockIP instanceof Databases\IPs\EntryVO ? $blockIP->blocked_at > 0 : false,
182
+ 'is_bypass' => $bypassIP instanceof Databases\IPs\EntryVO,
183
+ 'ip_reputation_score' => $botScore,
184
+ 'snapi_reputation_score' => is_numeric( $shieldNetScore ) ? $shieldNetScore : 'Unavailable',
185
+ 'is_bot' => $isBot,
186
  ],
187
  'identity' => [
188
  'who_is_it' => $ipName,
src/lib/src/Modules/IPs/ModCon.php CHANGED
@@ -146,6 +146,7 @@ class ModCon extends BaseShield\ModCon {
146
  __( 'Warning', 'wp-simple-firewall' ),
147
  __( 'You have %s remaining offenses(s) against this site and then your IP address will be completely blocked.', 'wp-simple-firewall' )
148
  .'<br/><strong>'.__( 'Seriously, stop repeating what you are doing or you will be locked out.', 'wp-simple-firewall' ).'</strong>'
 
149
  );
150
  break;
151
 
146
  __( 'Warning', 'wp-simple-firewall' ),
147
  __( 'You have %s remaining offenses(s) against this site and then your IP address will be completely blocked.', 'wp-simple-firewall' )
148
  .'<br/><strong>'.__( 'Seriously, stop repeating what you are doing or you will be locked out.', 'wp-simple-firewall' ).'</strong>'
149
+ .sprintf( ' [<a href="%s" target="_blank">%s</a>]', 'https://shsec.io/shieldcantaccess', __( 'More Info', 'wp-simple-firewall' ) )
150
  );
151
  break;
152
 
src/lib/src/Modules/Insights/Lib/SideMenuBuilder.php CHANGED
@@ -97,26 +97,27 @@ class SideMenuBuilder {
97
  ],
98
  [
99
  'slug' => $slug.'-blocksettings',
100
- 'title' => sprintf( '%s: %s', __( 'Configure', 'wp-simple-firewall' ), __( 'IP Blocking', 'wp-simple-firewall' ) ),
101
  'href' => $con->getModule_IPs()->getUrl_AdminPage(),
102
  ],
103
  [
104
  'slug' => $slug.'-antibotsettings',
105
- 'title' => sprintf( '%s: %s', __( 'Configure', 'wp-simple-firewall' ), __( 'AntiBot', 'wp-simple-firewall' ) ),
106
  'href' => $con->getModule_IPs()->getUrl_DirectLinkToSection( 'section_antibot' ),
107
  ],
108
  [
109
  'slug' => 'ips-download',
110
  'href' => $con->getModule_IPs()->createFileDownloadLink( 'db_ip' ),
111
  'classes' => [ 'shield_file_download' ],
112
- 'title' => sprintf( __( 'Download (as %s)', 'wp-simple-firewall' ), 'CSV' ),
113
  ],
114
  ];
115
 
116
  return [
117
  'slug' => $slug,
118
- 'title' => __( 'IPs and Bots', 'wp-simple-firewall' ),
119
- 'img' => $this->getCon()->urls->forImage( 'bootstrap/diagram-3.svg' ),
 
120
  'introjs' => [
121
  'body' => __( "Protection begins by detecting bad bots - Review and Analyse all visitor IPs that have an impact on your site.", 'wp-simple-firewall' ),
122
  ],
@@ -133,24 +134,19 @@ class SideMenuBuilder {
133
  $subItems = [
134
  [
135
  'slug' => $slug.'-log',
136
- 'title' => __( 'View Audit Trail Log', 'wp-simple-firewall' ),
137
  'href' => $mod->getUrl_SubInsightsPage( $slug ),
138
  'active' => $this->getInav() === $slug,
139
  ],
140
- [
141
- 'slug' => $slug.'-settings',
142
- 'title' => __( 'Configuration', 'wp-simple-firewall' ),
143
- 'href' => $con->getModule_AuditTrail()->getUrl_AdminPage(),
144
- ],
145
  [
146
  'slug' => 'audit-download',
147
- 'title' => sprintf( __( 'Download (as %s)', 'wp-simple-firewall' ), 'CSV' ),
148
  'href' => $con->getModule_AuditTrail()->createFileDownloadLink( 'db_audit' ),
149
  'classes' => [ 'shield_file_download' ],
150
  ],
151
  [
152
  'slug' => 'audit-glossary',
153
- 'title' => __( 'Audit Trail Glossary', 'wp-simple-firewall' ),
154
  'href' => 'https://shsec.io/audittrailglossary',
155
  'target' => '_blank',
156
  ],
@@ -159,7 +155,7 @@ class SideMenuBuilder {
159
  return [
160
  'slug' => $slug,
161
  'title' => __( 'Audit Trail', 'wp-simple-firewall' ),
162
- 'img' => $this->getCon()->urls->forImage( 'bootstrap/person-lines-fill.svg' ),
163
  'introjs' => [
164
  'body' => __( "Track and review all important actions taken on your site - see the Who, What and When.", 'wp-simple-firewall' ),
165
  ],
@@ -189,7 +185,7 @@ class SideMenuBuilder {
189
  ],
190
  [
191
  'slug' => $slug.'-settings',
192
- 'title' => sprintf( '%s: %s', __( 'Configure', 'wp-simple-firewall' ), __( 'Automatic Scans', 'wp-simple-firewall' ) ),
193
  'href' => $con->getModule_HackGuard()->getUrl_AdminPage(),
194
  ],
195
  ];
@@ -197,7 +193,8 @@ class SideMenuBuilder {
197
  return [
198
  'slug' => $slug,
199
  'title' => __( 'Scans', 'wp-simple-firewall' ),
200
- 'img' => $this->getCon()->urls->forImage( 'bootstrap/shield-shaded.svg' ),
 
201
  'introjs' => [
202
  'body' => sprintf( __( "Run a %s scan at any time, or view the results from the latest scan.", 'wp-simple-firewall' ),
203
  $this->getCon()->getHumanName() ),
@@ -212,7 +209,7 @@ class SideMenuBuilder {
212
  return [
213
  'slug' => 'search',
214
  'title' => __( 'Search', 'wp-simple-firewall' ),
215
- 'img' => $this->getCon()->urls->forImage( 'bootstrap/search.svg' ),
216
  'id' => 'NavMenuSearch',
217
  'href' => $mod->getUrl_SubInsightsPage( 'overview' ),
218
  'introjs' => [
@@ -232,7 +229,8 @@ class SideMenuBuilder {
232
  return [
233
  'slug' => 'reports',
234
  'title' => __( 'Reports', 'wp-simple-firewall' ),
235
- 'img' => $this->getCon()->urls->forImage( 'bootstrap/graph-up.svg' ),
 
236
  'href' => $mod->getUrl_SubInsightsPage( 'reports' ),
237
  'introjs' => [
238
  'body' => __( 'Reports use the built-in stats to show you how Shield is working to secure your site.' ),
@@ -260,7 +258,7 @@ class SideMenuBuilder {
260
  return [
261
  'slug' => 'overview',
262
  'title' => __( 'Overview', 'wp-simple-firewall' ),
263
- 'img' => $this->getCon()->urls->forImage( 'bootstrap/binoculars.svg' ),
264
  'href' => $mod->getUrl_SubInsightsPage( 'overview' ),
265
  'introjs' => [
266
  'body' => sprintf( __( "Review your entire %s configuration at a glance to see what's working and what's not.", 'wp-simple-firewall' ),
@@ -293,8 +291,8 @@ class SideMenuBuilder {
293
 
294
  return [
295
  'slug' => $slug,
296
- 'title' => __( 'Configuration', 'wp-simple-firewall' ),
297
- 'img' => $this->getCon()->urls->forImage( 'bootstrap/sliders.svg' ),
298
  'introjs' => [
299
  'body' => sprintf( __( "%s is a big plugin split into modules, and each with their own options - use these jump-off points to find the specific option you need.", 'wp-simple-firewall' ),
300
  $this->getCon()->getHumanName() ),
@@ -307,7 +305,8 @@ class SideMenuBuilder {
307
  $con = $this->getCon();
308
  return [
309
  'slug' => 'integrations',
310
- 'img' => $this->getCon()->urls->forImage( 'bootstrap/puzzle-fill.svg' ),
 
311
  'title' => __( 'Integrations', 'wp-simple-firewall' ),
312
  'introjs' => [
313
  'body' => __( "Integrate with your favourite plugins to block SPAM and manage Shield better.", 'wp-simple-firewall' ),
@@ -333,7 +332,7 @@ class SideMenuBuilder {
333
  return [
334
  'slug' => 'docs',
335
  'title' => __( "View Docs", 'wp-simple-firewall' ),
336
- 'img' => $this->getCon()->urls->forImage( 'bootstrap/book-half.svg' ),
337
  'href' => $mod->getUrl_SubInsightsPage( 'docs' ),
338
  ];
339
  }
@@ -373,7 +372,8 @@ class SideMenuBuilder {
373
  return [
374
  'slug' => 'license',
375
  'title' => $isPro ? __( 'ShieldPRO', 'wp-simple-firewall' ) : __( 'Go PRO!', 'wp-simple-firewall' ),
376
- 'img' => $this->getCon()->urls->forImage( 'bootstrap/award.svg' ),
 
377
  'href' => $mod->getUrl_SubInsightsPage( 'license' ),
378
  'sub_items' => $subItems,
379
  ];
@@ -414,7 +414,7 @@ class SideMenuBuilder {
414
  return [
415
  'slug' => $slug,
416
  'title' => __( 'Tools', 'wp-simple-firewall' ),
417
- 'img' => $this->getCon()->urls->forImage( 'bootstrap/tools.svg' ),
418
  'introjs' => [
419
  'body' => __( "Important security tools, such a import/export, whitelabel and admin notes.", 'wp-simple-firewall' ),
420
  ],
@@ -431,27 +431,27 @@ class SideMenuBuilder {
431
  $subItems = [
432
  [
433
  'slug' => $slug.'-log',
434
- 'title' => __( 'View Traffic Log', 'wp-simple-firewall' ),
435
  'href' => $mod->getUrl_SubInsightsPage( $slug ),
436
  'active' => $this->getInav() === $slug,
437
  ],
438
  [
439
- 'slug' => $slug.'-ratelimitsettings',
440
- 'title' => sprintf( '%s: %s', __( 'Configure', 'wp-simple-firewall' ), __( 'Rate Limiting', 'wp-simple-firewall' ) ),
441
- 'href' => $con->getModule_Traffic()->getUrl_DirectLinkToSection( 'section_traffic_limiter' ),
442
  ],
443
  [
444
  'slug' => 'traffic-download',
445
  'href' => $con->getModule_Traffic()->createFileDownloadLink( 'db_traffic' ),
446
  'classes' => [ 'shield_file_download' ],
447
- 'title' => sprintf( __( 'Download (as %s)', 'wp-simple-firewall' ), 'CSV' ),
448
  ],
449
  ];
450
 
451
  return [
452
  'slug' => 'traffic',
453
  'title' => __( 'Traffic', 'wp-simple-firewall' ),
454
- 'img' => $this->getCon()->urls->forImage( 'bootstrap/stoplights.svg' ),
455
  'introjs' => [
456
  'body' => __( "Monitor and watch traffic as it hits your site.", 'wp-simple-firewall' ),
457
  ],
@@ -477,18 +477,18 @@ class SideMenuBuilder {
477
  ],
478
  [
479
  'slug' => 'users-settings',
480
- 'title' => sprintf( '%s: %s', __( 'Configure', 'wp-simple-firewall' ), __( 'Sessions', 'wp-simple-firewall' ) ),
481
  'href' => $con->getModule_UserManagement()
482
  ->getUrl_DirectLinkToSection( 'section_user_session_management' ),
483
  ],
484
  [
485
  'slug' => 'users-passwords',
486
- 'title' => sprintf( '%s: %s', __( 'Configure', 'wp-simple-firewall' ), __( 'Password Policies', 'wp-simple-firewall' ) ),
487
  'href' => $con->getModule_UserManagement()->getUrl_DirectLinkToSection( 'section_passwords' ),
488
  ],
489
  [
490
  'slug' => 'users-suspend',
491
- 'title' => sprintf( '%s: %s', __( 'Configure', 'wp-simple-firewall' ), __( 'User Suspension', 'wp-simple-firewall' ) ),
492
  'href' => $con->getModule_UserManagement()->getUrl_DirectLinkToSection( 'section_suspend' ),
493
  ],
494
  ];
@@ -496,7 +496,7 @@ class SideMenuBuilder {
496
  return [
497
  'slug' => 'users',
498
  'title' => __( 'Users', 'wp-simple-firewall' ),
499
- 'img' => $this->getCon()->urls->forImage( 'bootstrap/person-badge.svg' ),
500
  'introjs' => [
501
  'body' => __( 'View sessions, and configure session timeouts and passwords requirements.', 'wp-simple-firewall' ),
502
  ],
97
  ],
98
  [
99
  'slug' => $slug.'-blocksettings',
100
+ 'title' => __( 'Blocking Rules', 'wp-simple-firewall' ),
101
  'href' => $con->getModule_IPs()->getUrl_AdminPage(),
102
  ],
103
  [
104
  'slug' => $slug.'-antibotsettings',
105
+ 'title' => __( 'AntiBot Rules', 'wp-simple-firewall' ),
106
  'href' => $con->getModule_IPs()->getUrl_DirectLinkToSection( 'section_antibot' ),
107
  ],
108
  [
109
  'slug' => 'ips-download',
110
  'href' => $con->getModule_IPs()->createFileDownloadLink( 'db_ip' ),
111
  'classes' => [ 'shield_file_download' ],
112
+ 'title' => sprintf( __( 'Download (%s)', 'wp-simple-firewall' ), 'CSV' ),
113
  ],
114
  ];
115
 
116
  return [
117
  'slug' => $slug,
118
+ 'title' => __( 'IPs & Bots', 'wp-simple-firewall' ),
119
+ 'img' => $this->getCon()->svgs->raw( 'bootstrap/diagram-3.svg' ),
120
+ 'img_hover' => $this->getCon()->svgs->raw( 'bootstrap/diagram-3-fill.svg' ),
121
  'introjs' => [
122
  'body' => __( "Protection begins by detecting bad bots - Review and Analyse all visitor IPs that have an impact on your site.", 'wp-simple-firewall' ),
123
  ],
134
  $subItems = [
135
  [
136
  'slug' => $slug.'-log',
137
+ 'title' => __( 'View Log', 'wp-simple-firewall' ),
138
  'href' => $mod->getUrl_SubInsightsPage( $slug ),
139
  'active' => $this->getInav() === $slug,
140
  ],
 
 
 
 
 
141
  [
142
  'slug' => 'audit-download',
143
+ 'title' => sprintf( __( 'Download (%s)', 'wp-simple-firewall' ), 'CSV' ),
144
  'href' => $con->getModule_AuditTrail()->createFileDownloadLink( 'db_audit' ),
145
  'classes' => [ 'shield_file_download' ],
146
  ],
147
  [
148
  'slug' => 'audit-glossary',
149
+ 'title' => __( 'Glossary', 'wp-simple-firewall' ),
150
  'href' => 'https://shsec.io/audittrailglossary',
151
  'target' => '_blank',
152
  ],
155
  return [
156
  'slug' => $slug,
157
  'title' => __( 'Audit Trail', 'wp-simple-firewall' ),
158
+ 'img' => $this->getCon()->svgs->raw( 'bootstrap/person-lines-fill.svg' ),
159
  'introjs' => [
160
  'body' => __( "Track and review all important actions taken on your site - see the Who, What and When.", 'wp-simple-firewall' ),
161
  ],
185
  ],
186
  [
187
  'slug' => $slug.'-settings',
188
+ 'title' => __( 'Configure', 'wp-simple-firewall' ),
189
  'href' => $con->getModule_HackGuard()->getUrl_AdminPage(),
190
  ],
191
  ];
193
  return [
194
  'slug' => $slug,
195
  'title' => __( 'Scans', 'wp-simple-firewall' ),
196
+ 'img' => $this->getCon()->svgs->raw( 'bootstrap/shield-shaded.svg' ),
197
+ 'img_hover' => $this->getCon()->svgs->raw( 'bootstrap/shield-fill.svg' ),
198
  'introjs' => [
199
  'body' => sprintf( __( "Run a %s scan at any time, or view the results from the latest scan.", 'wp-simple-firewall' ),
200
  $this->getCon()->getHumanName() ),
209
  return [
210
  'slug' => 'search',
211
  'title' => __( 'Search', 'wp-simple-firewall' ),
212
+ 'img' => $this->getCon()->svgs->raw( 'bootstrap/search.svg' ),
213
  'id' => 'NavMenuSearch',
214
  'href' => $mod->getUrl_SubInsightsPage( 'overview' ),
215
  'introjs' => [
229
  return [
230
  'slug' => 'reports',
231
  'title' => __( 'Reports', 'wp-simple-firewall' ),
232
+ 'img' => $this->getCon()->svgs->raw( 'bootstrap/bar-chart-line.svg' ),
233
+ 'img_hover' => $this->getCon()->svgs->raw( 'bootstrap/bar-chart-line-fill.svg' ),
234
  'href' => $mod->getUrl_SubInsightsPage( 'reports' ),
235
  'introjs' => [
236
  'body' => __( 'Reports use the built-in stats to show you how Shield is working to secure your site.' ),
258
  return [
259
  'slug' => 'overview',
260
  'title' => __( 'Overview', 'wp-simple-firewall' ),
261
+ 'img' => $this->getCon()->svgs->raw( 'bootstrap/binoculars.svg' ),
262
  'href' => $mod->getUrl_SubInsightsPage( 'overview' ),
263
  'introjs' => [
264
  'body' => sprintf( __( "Review your entire %s configuration at a glance to see what's working and what's not.", 'wp-simple-firewall' ),
291
 
292
  return [
293
  'slug' => $slug,
294
+ 'title' => __( 'Config', 'wp-simple-firewall' ),
295
+ 'img' => $this->getCon()->svgs->raw( 'bootstrap/sliders.svg' ),
296
  'introjs' => [
297
  'body' => sprintf( __( "%s is a big plugin split into modules, and each with their own options - use these jump-off points to find the specific option you need.", 'wp-simple-firewall' ),
298
  $this->getCon()->getHumanName() ),
305
  $con = $this->getCon();
306
  return [
307
  'slug' => 'integrations',
308
+ 'img' => $this->getCon()->svgs->raw( 'bootstrap/puzzle.svg' ),
309
+ 'img_hover' => $this->getCon()->svgs->raw( 'bootstrap/puzzle-fill.svg' ),
310
  'title' => __( 'Integrations', 'wp-simple-firewall' ),
311
  'introjs' => [
312
  'body' => __( "Integrate with your favourite plugins to block SPAM and manage Shield better.", 'wp-simple-firewall' ),
332
  return [
333
  'slug' => 'docs',
334
  'title' => __( "View Docs", 'wp-simple-firewall' ),
335
+ 'img' => $this->getCon()->svgs->raw( 'bootstrap/book-half.svg' ),
336
  'href' => $mod->getUrl_SubInsightsPage( 'docs' ),
337
  ];
338
  }
372
  return [
373
  'slug' => 'license',
374
  'title' => $isPro ? __( 'ShieldPRO', 'wp-simple-firewall' ) : __( 'Go PRO!', 'wp-simple-firewall' ),
375
+ 'img' => $this->getCon()->svgs->raw( 'bootstrap/award.svg' ),
376
+ 'img_hover' => $this->getCon()->svgs->raw( 'bootstrap/award-fill.svg' ),
377
  'href' => $mod->getUrl_SubInsightsPage( 'license' ),
378
  'sub_items' => $subItems,
379
  ];
414
  return [
415
  'slug' => $slug,
416
  'title' => __( 'Tools', 'wp-simple-firewall' ),
417
+ 'img' => $this->getCon()->svgs->raw( 'bootstrap/tools.svg' ),
418
  'introjs' => [
419
  'body' => __( "Important security tools, such a import/export, whitelabel and admin notes.", 'wp-simple-firewall' ),
420
  ],
431
  $subItems = [
432
  [
433
  'slug' => $slug.'-log',
434
+ 'title' => __( 'View Traffic', 'wp-simple-firewall' ),
435
  'href' => $mod->getUrl_SubInsightsPage( $slug ),
436
  'active' => $this->getInav() === $slug,
437
  ],
438
  [
439
+ 'slug' => $slug.'-settings',
440
+ 'title' => __( 'Configure', 'wp-simple-firewall' ),
441
+ 'href' => $con->getModule_Traffic()->getUrl_DirectLinkToSection( 'section_traffic_options' ),
442
  ],
443
  [
444
  'slug' => 'traffic-download',
445
  'href' => $con->getModule_Traffic()->createFileDownloadLink( 'db_traffic' ),
446
  'classes' => [ 'shield_file_download' ],
447
+ 'title' => sprintf( __( 'Download (%s)', 'wp-simple-firewall' ), 'CSV' ),
448
  ],
449
  ];
450
 
451
  return [
452
  'slug' => 'traffic',
453
  'title' => __( 'Traffic', 'wp-simple-firewall' ),
454
+ 'img' => $this->getCon()->svgs->raw( 'bootstrap/stoplights.svg' ),
455
  'introjs' => [
456
  'body' => __( "Monitor and watch traffic as it hits your site.", 'wp-simple-firewall' ),
457
  ],
477
  ],
478
  [
479
  'slug' => 'users-settings',
480
+ 'title' => sprintf( '%s: %s', __( 'Config', 'wp-simple-firewall' ), __( 'Sessions', 'wp-simple-firewall' ) ),
481
  'href' => $con->getModule_UserManagement()
482
  ->getUrl_DirectLinkToSection( 'section_user_session_management' ),
483
  ],
484
  [
485
  'slug' => 'users-passwords',
486
+ 'title' => __( 'Password Policies', 'wp-simple-firewall' ),
487
  'href' => $con->getModule_UserManagement()->getUrl_DirectLinkToSection( 'section_passwords' ),
488
  ],
489
  [
490
  'slug' => 'users-suspend',
491
+ 'title' => __( 'User Suspension', 'wp-simple-firewall' ),
492
  'href' => $con->getModule_UserManagement()->getUrl_DirectLinkToSection( 'section_suspend' ),
493
  ],
494
  ];
496
  return [
497
  'slug' => 'users',
498
  'title' => __( 'Users', 'wp-simple-firewall' ),
499
+ 'img' => $this->getCon()->svgs->raw( 'bootstrap/person-badge.svg' ),
500
  'introjs' => [
501
  'body' => __( 'View sessions, and configure session timeouts and passwords requirements.', 'wp-simple-firewall' ),
502
  ],
src/lib/src/Modules/Integrations/Lib/Bots/UserForms/Handlers/Buddypress.php CHANGED
@@ -9,7 +9,7 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Integrations\Lib\Bots\
9
  class Buddypress extends Base {
10
 
11
  protected function register() {
12
- add_action( 'bp_signup_validate', [ $this, 'checkRegister_BP' ], 10 );
13
  }
14
 
15
  public function checkRegister_BP() {
9
  class Buddypress extends Base {
10
 
11
  protected function register() {
12
+ add_action( 'bp_signup_validate', [ $this, 'checkRegister_BP' ] );
13
  }
14
 
15
  public function checkRegister_BP() {
src/lib/src/Modules/License/AjaxHandler.php CHANGED
@@ -12,17 +12,17 @@ class AjaxHandler extends Shield\Modules\BaseShield\AjaxHandler {
12
 
13
  switch ( $action ) {
14
  case 'license_handling':
15
- $aResponse = $this->ajaxExec_LicenseHandling();
16
  break;
17
  case 'connection_debug':
18
- $aResponse = $this->ajaxExec_ConnectionDebug();
19
  break;
20
 
21
  default:
22
- $aResponse = parent::processAjaxAction( $action );
23
  }
24
 
25
- return $aResponse;
26
  }
27
 
28
  /**
12
 
13
  switch ( $action ) {
14
  case 'license_handling':
15
+ $response = $this->ajaxExec_LicenseHandling();
16
  break;
17
  case 'connection_debug':
18
+ $response = $this->ajaxExec_ConnectionDebug();
19
  break;
20
 
21
  default:
22
+ $response = parent::processAjaxAction( $action );
23
  }
24
 
25
+ return $response;
26
  }
27
 
28
  /**
src/lib/src/Modules/License/Lib/LicenseEmails.php CHANGED
@@ -15,24 +15,23 @@ class LicenseEmails {
15
  $mod = $this->getMod();
16
  $opts = $this->getOptions();
17
 
18
- $bCanSend = Services::Request()
19
- ->carbon()
20
- ->subDay( 1 )->timestamp > $opts->getOpt( 'last_warning_email_sent_at' );
21
 
22
- if ( $bCanSend ) {
23
  $opts->setOptAt( 'last_warning_email_sent_at' );
24
  $mod->saveModOptions();
25
 
26
- $aMessage = [
27
- __( 'Attempts to verify Shield Pro license has just failed.', 'wp-simple-firewall' ),
28
- sprintf( __( 'Please check your license on-site: %s', 'wp-simple-firewall' ), $mod->getUrl_AdminPage() ),
29
- sprintf( __( 'If this problem persists, please contact support: %s', 'wp-simple-firewall' ), 'https://support.getshieldsecurity.com/' )
30
- ];
31
  $mod->getEmailProcessor()
32
  ->sendEmailWithWrap(
33
  $mod->getPluginReportEmail(),
34
  'Pro License Check Has Failed',
35
- $aMessage
 
 
 
 
36
  );
37
  $this->getCon()->fireEvent( 'lic_fail_email' );
38
  }
15
  $mod = $this->getMod();
16
  $opts = $this->getOptions();
17
 
18
+ $canSend = Services::Request()
19
+ ->carbon()
20
+ ->subDay( 1 )->timestamp > $opts->getOpt( 'last_warning_email_sent_at' );
21
 
22
+ if ( $canSend ) {
23
  $opts->setOptAt( 'last_warning_email_sent_at' );
24
  $mod->saveModOptions();
25
 
 
 
 
 
 
26
  $mod->getEmailProcessor()
27
  ->sendEmailWithWrap(
28
  $mod->getPluginReportEmail(),
29
  'Pro License Check Has Failed',
30
+ [
31
+ __( 'Attempts to verify Shield Pro license has just failed.', 'wp-simple-firewall' ),
32
+ sprintf( __( 'Please check your license on-site: %s', 'wp-simple-firewall' ), $mod->getUrl_AdminPage() ),
33
+ sprintf( __( 'If this problem persists, please contact support: %s', 'wp-simple-firewall' ), 'https://support.getshieldsecurity.com/' )
34
+ ]
35
  );
36
  $this->getCon()->fireEvent( 'lic_fail_email' );
37
  }
src/lib/src/Modules/License/Lib/LicenseHandler.php CHANGED
@@ -33,8 +33,10 @@ class LicenseHandler {
33
 
34
  case 'license_check':
35
  if ( !wp_next_scheduled( $con->prefix( 'adhoc_cron_license_check' ) ) ) {
36
- wp_schedule_single_event( Services::Request()
37
- ->ts() + 20, $con->prefix( 'adhoc_cron_license_check' ) );
 
 
38
  }
39
  break;
40
  }
@@ -200,4 +202,4 @@ class LicenseHandler {
200
  );
201
  return ( Services::Request()->ts() - $nMtime ) > MINUTE_IN_SECONDS;
202
  }
203
- }
33
 
34
  case 'license_check':
35
  if ( !wp_next_scheduled( $con->prefix( 'adhoc_cron_license_check' ) ) ) {
36
+ wp_schedule_single_event(
37
+ Services::Request()->ts() + 20,
38
+ $con->prefix( 'adhoc_cron_license_check' )
39
+ );
40
  }
41
  break;
42
  }
202
  );
203
  return ( Services::Request()->ts() - $nMtime ) > MINUTE_IN_SECONDS;
204
  }
205
+ }
src/lib/src/Modules/License/Lib/LookupRequest.php CHANGED
@@ -30,6 +30,6 @@ class LookupRequest {
30
  $license = $lookup->lookup();
31
  }
32
 
33
- return ( new EddLicenseVO() )->applyFromArray( $license->getRawDataAsArray() );
34
  }
35
  }
30
  $license = $lookup->lookup();
31
  }
32
 
33
+ return ( new EddLicenseVO() )->applyFromArray( $license->getRawData() );
34
  }
35
  }
src/lib/src/Modules/License/Lib/Verify.php CHANGED
@@ -38,7 +38,7 @@ class Verify {
38
  $opts->setOptAt( 'license_activated_at' );
39
  }
40
  $mod->clearLastErrors();
41
- $opts->setOpt( 'license_data', $existing->getRawDataAsArray() ); // need to do this before event
42
  $this->getCon()->fireEvent( 'lic_check_success' );
43
  }
44
  elseif ( $license->isReady() ) {
@@ -75,7 +75,7 @@ class Verify {
75
  }
76
 
77
  $existing->last_request_at = Services::Request()->ts();
78
- $opts->setOpt( 'license_data', $existing->getRawDataAsArray() );
79
  $this->getMod()->saveModOptions();
80
 
81
  if ( !$isSuccessfulApiRequest ) {
38
  $opts->setOptAt( 'license_activated_at' );
39
  }
40
  $mod->clearLastErrors();
41
+ $opts->setOpt( 'license_data', $existing->getRawData() ); // need to do this before event
42
  $this->getCon()->fireEvent( 'lic_check_success' );
43
  }
44
  elseif ( $license->isReady() ) {
75
  }
76
 
77
  $existing->last_request_at = Services::Request()->ts();
78
+ $opts->setOpt( 'license_data', $existing->getRawData() );
79
  $this->getMod()->saveModOptions();
80
 
81
  if ( !$isSuccessfulApiRequest ) {
src/lib/src/Modules/License/Lib/WpHashes/ApiTokenManager.php CHANGED
@@ -4,6 +4,7 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\License\Lib\WpHashes;
4
 
5
  use FernleafSystems\Utilities\Logic\ExecOnce;
6
  use FernleafSystems\Wordpress\Plugin\Shield\Modules;
 
7
  use FernleafSystems\Wordpress\Services\Services;
8
  use FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\Token;
9
 
@@ -15,7 +16,7 @@ class ApiTokenManager {
15
  /**
16
  * @var bool
17
  */
18
- private $bCanRequestOverride = false;
19
 
20
  protected function run() {
21
  add_action( $this->getCon()->prefix( 'event' ), function ( $eventTag ) {
@@ -45,38 +46,34 @@ class ApiTokenManager {
45
  public function getToken() {
46
 
47
  if ( $this->getCon()->getModule_License()->getLicenseHandler()->getLicense()->isValid() ) {
48
- $aT = $this->loadToken();
49
  if ( $this->isExpired() && $this->canRequestNewToken() ) {
50
- $aT = $this->loadToken();
51
  try {
52
- $aT = array_merge( $aT, $this->solicitApiToken() );
53
  }
54
  catch ( \Exception $e ) {
55
  }
56
- $aT[ 'attempt_at' ] = Services::Request()->ts();
57
- $aT[ 'next_attempt_from' ] = Services::Request()->ts() + HOUR_IN_SECONDS;
58
- $this->storeToken( $aT );
59
  }
60
  }
61
  else {
62
  $this->storeToken( [] );
63
  }
64
 
65
- return empty( $aT[ 'token' ] ) ? '' : $aT[ 'token' ];
66
  }
67
 
68
- /**
69
- * @return bool
70
- */
71
- public function hasToken() {
72
- $sTok = $this->getToken();
73
- return strlen( $sTok ) == 40 && !$this->isExpired();
74
  }
75
 
76
  /**
77
- * @return array - return Token exactly as it's saved currently
78
  */
79
- private function loadToken() {
80
  return array_merge(
81
  [
82
  'token' => '',
@@ -89,10 +86,7 @@ class ApiTokenManager {
89
  );
90
  }
91
 
92
- /**
93
- * @return bool
94
- */
95
- private function canRequestNewToken() {
96
  return $this->getCanRequestOverride() ||
97
  (
98
  Services::Request()->ts() >= $this->getNextAttemptAllowedFrom()
@@ -100,11 +94,8 @@ class ApiTokenManager {
100
  );
101
  }
102
 
103
- /**
104
- * @return bool
105
- */
106
- public function getCanRequestOverride() {
107
- return (bool)$this->bCanRequestOverride;
108
  }
109
 
110
  /**
@@ -128,35 +119,29 @@ class ApiTokenManager {
128
  return $this->loadToken()[ 'attempt_at' ];
129
  }
130
 
131
- /**
132
- * @return bool
133
- */
134
- public function isExpired() {
135
  return Services::Request()->ts() > $this->getExpiresAt();
136
  }
137
 
138
- /**
139
- * @return bool
140
- */
141
- public function isNearlyExpired() {
142
  return Services::Request()->carbon()->addHours( 2 )->timestamp > $this->getExpiresAt();
143
  }
144
 
145
  /**
146
- * @param array $aToken
147
  * @return $this
148
  */
149
- private function storeToken( array $aToken = [] ) {
150
- $this->getOptions()->setOpt( 'wphashes_api_token', $aToken );
151
  return $this;
152
  }
153
 
154
  /**
155
- * @param bool $bCanRequest
156
  * @return $this
157
  */
158
- public function setCanRequestOverride( $bCanRequest ) {
159
- $this->bCanRequestOverride = (bool)$bCanRequest;
160
  return $this;
161
  }
162
 
@@ -164,14 +149,22 @@ class ApiTokenManager {
164
  * @return array
165
  * @throws \Exception
166
  */
167
- private function solicitApiToken() {
168
- $aResp = ( new Token\Solicit() )->retrieve(
169
- Services::WpGeneral()->getHomeUrl(),
170
- $this->getCon()->getSiteInstallationId()
171
- );
172
- if ( !is_array( $aResp ) || empty( $aResp[ 'token' ] ) || strlen( $aResp[ 'token' ] ) != 40 ) {
173
- throw new \Exception( 'Could not retrieve token' );
 
 
 
 
 
 
 
174
  }
175
- return $aResp;
 
176
  }
177
  }
4
 
5
  use FernleafSystems\Utilities\Logic\ExecOnce;
6
  use FernleafSystems\Wordpress\Plugin\Shield\Modules;
7
+ use FernleafSystems\Wordpress\Plugin\Shield\ShieldNetApi\WPHashes\SolicitToken;
8
  use FernleafSystems\Wordpress\Services\Services;
9
  use FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\Token;
10
 
16
  /**
17
  * @var bool
18
  */
19
+ private $canRequestOverride = false;
20
 
21
  protected function run() {
22
  add_action( $this->getCon()->prefix( 'event' ), function ( $eventTag ) {
46
  public function getToken() {
47
 
48
  if ( $this->getCon()->getModule_License()->getLicenseHandler()->getLicense()->isValid() ) {
49
+ $token = $this->loadToken();
50
  if ( $this->isExpired() && $this->canRequestNewToken() ) {
51
+ $token = $this->loadToken();
52
  try {
53
+ $token = array_merge( $token, $this->solicitApiToken() );
54
  }
55
  catch ( \Exception $e ) {
56
  }
57
+ $token[ 'attempt_at' ] = Services::Request()->ts();
58
+ $token[ 'next_attempt_from' ] = Services::Request()->ts() + HOUR_IN_SECONDS;
59
+ $this->storeToken( $token );
60
  }
61
  }
62
  else {
63
  $this->storeToken( [] );
64
  }
65
 
66
+ return empty( $token[ 'token' ] ) ? '' : $token[ 'token' ];
67
  }
68
 
69
+ public function hasToken() :bool {
70
+ return strlen( $this->getToken() ) == 40 && !$this->isExpired();
 
 
 
 
71
  }
72
 
73
  /**
74
+ * retrieve Token exactly as it's saved
75
  */
76
+ private function loadToken() :array {
77
  return array_merge(
78
  [
79
  'token' => '',
86
  );
87
  }
88
 
89
+ private function canRequestNewToken() :bool {
 
 
 
90
  return $this->getCanRequestOverride() ||
91
  (
92
  Services::Request()->ts() >= $this->getNextAttemptAllowedFrom()
94
  );
95
  }
96
 
97
+ public function getCanRequestOverride() :bool {
98
+ return $this->canRequestOverride;
 
 
 
99
  }
100
 
101
  /**
119
  return $this->loadToken()[ 'attempt_at' ];
120
  }
121
 
122
+ public function isExpired() :bool {
 
 
 
123
  return Services::Request()->ts() > $this->getExpiresAt();
124
  }
125
 
126
+ public function isNearlyExpired() :bool {
 
 
 
127
  return Services::Request()->carbon()->addHours( 2 )->timestamp > $this->getExpiresAt();
128
  }
129
 
130
  /**
131
+ * @param array $token
132
  * @return $this
133
  */
134
+ private function storeToken( array $token = [] ) {
135
+ $this->getOptions()->setOpt( 'wphashes_api_token', $token );
136
  return $this;
137
  }
138
 
139
  /**
140
+ * @param bool $canRequest
141
  * @return $this
142
  */
143
+ public function setCanRequestOverride( bool $canRequest ) {
144
+ $this->canRequestOverride = $canRequest;
145
  return $this;
146
  }
147
 
149
  * @return array
150
  * @throws \Exception
151
  */
152
+ private function solicitApiToken() :array {
153
+ $response = ( new SolicitToken() )
154
+ ->setMod( $this->getCon()->getModule_Plugin() )
155
+ ->send();
156
+
157
+ if ( empty( $response ) ) {
158
+ // Fallback to legacy lookup, which shouldn't be necessary
159
+ $response = ( new Token\Solicit() )->retrieve(
160
+ Services::WpGeneral()->getHomeUrl(),
161
+ $this->getCon()->getSiteInstallationId()
162
+ );
163
+ if ( !is_array( $response ) || empty( $response[ 'token' ] ) || strlen( $response[ 'token' ] ) != 40 ) {
164
+ throw new \Exception( 'Could not retrieve token' );
165
+ }
166
  }
167
+
168
+ return $response;
169
  }
170
  }
src/lib/src/Modules/License/WpCli.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\License;
4
 
1
+ <?php declare( strict_types=1 );
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\License;
4
 
src/lib/src/Modules/LoginGuard/Lib/AntiBot/FormProviders/BuddyPress.php CHANGED
@@ -1,12 +1,12 @@
1
- <?php
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard\Lib\AntiBot\FormProviders;
4
 
5
  class BuddyPress extends BaseFormProvider {
6
 
7
  protected function register() {
8
- add_action( 'bp_before_registration_submit_buttons', [ $this, 'printFormInsert' ], 10 );
9
- add_action( 'bp_signup_validate', [ $this, 'checkRegister' ], 10 );
10
  }
11
 
12
  /**
1
+ <?php declare( strict_types=1 );
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard\Lib\AntiBot\FormProviders;
4
 
5
  class BuddyPress extends BaseFormProvider {
6
 
7
  protected function register() {
8
+ add_action( 'bp_before_registration_submit_buttons', [ $this, 'printFormInsert' ] );
9
+ add_action( 'bp_signup_validate', [ $this, 'checkRegister' ] );
10
  }
11
 
12
  /**
src/lib/src/Modules/LoginGuard/Lib/AntiBot/FormProviders/UltimateMember.php CHANGED
@@ -24,9 +24,6 @@ class UltimateMember extends BaseFormProvider {
24
  add_action( 'um_submit_form_password_reset', [ $this, 'checkLostPassword' ], 5, 0 );
25
  }
26
 
27
- /**
28
- * @return array
29
- */
30
  public function checkLogin() {
31
  try {
32
  $this->setActionToAudit( 'ultimatemember-login' )
24
  add_action( 'um_submit_form_password_reset', [ $this, 'checkLostPassword' ], 5, 0 );
25
  }
26
 
 
 
 
27
  public function checkLogin() {
28
  try {
29
  $this->setActionToAudit( 'ultimatemember-login' )
src/lib/src/Modules/LoginGuard/Lib/AntiBot/FormProviders/WordPress.php CHANGED
@@ -20,20 +20,20 @@ class WordPress extends BaseFormProvider {
20
 
21
  protected function lostpassword() {
22
  add_action( 'lostpassword_form', [ $this, 'printFormInsert' ] );
23
- add_action( 'lostpassword_post', [ $this, 'checkLostPassword' ], 10, 1 );
24
  }
25
 
26
  /**
27
  * Should be a filter added to WordPress's "authenticate" filter, but before WordPress performs
28
  * it's own authentication (theirs is priority 30, so we could go in at around 20).
29
  * @param null|\WP_User|\WP_Error $oUserOrError
30
- * @param string $sUsername
31
  * @return \WP_User|\WP_Error
32
  */
33
- public function checkLogin( $oUserOrError, $sUsername ) {
34
  try {
35
- if ( !is_wp_error( $oUserOrError ) && !empty( $sUsername ) ) {
36
- $this->setUserToAudit( $sUsername )
37
  ->setActionToAudit( 'login' )
38
  ->checkProviders();
39
  }
20
 
21
  protected function lostpassword() {
22
  add_action( 'lostpassword_form', [ $this, 'printFormInsert' ] );
23
+ add_action( 'lostpassword_post', [ $this, 'checkLostPassword' ] );
24
  }
25
 
26
  /**
27
  * Should be a filter added to WordPress's "authenticate" filter, but before WordPress performs
28
  * it's own authentication (theirs is priority 30, so we could go in at around 20).
29
  * @param null|\WP_User|\WP_Error $oUserOrError
30
+ * @param string $username
31
  * @return \WP_User|\WP_Error
32
  */
33
+ public function checkLogin( $oUserOrError, $username ) {
34
  try {
35
+ if ( !is_wp_error( $oUserOrError ) && !empty( $username ) ) {
36
+ $this->setUserToAudit( $username )
37
  ->setActionToAudit( 'login' )
38
  ->checkProviders();
39
  }
src/lib/src/Modules/LoginGuard/Lib/TwoFactor/LoginIntentPage.php CHANGED
@@ -28,42 +28,47 @@ class LoginIntentPage {
28
  $req = Services::Request();
29
  $WP = Services::WpGeneral();
30
 
31
- $oNotice = $con->getAdminNotices()->getFlashNotice();
32
- if ( $oNotice instanceof NoticeVO ) {
33
- $sMessage = $oNotice->render_data[ 'message' ];
34
  }
35
  else {
36
- $sMessage = $opts->isChainedAuth() ?
37
  __( 'Please supply all authentication codes', 'wp-simple-firewall' )
38
  : __( 'Please supply at least 1 authentication code', 'wp-simple-firewall' );
39
  }
40
 
41
- $sReferUrl = $req->server( 'HTTP_REFERER', '' );
42
- if ( strpos( $sReferUrl, '?' ) ) {
43
- list( $sReferUrl, $sReferQuery ) = explode( '?', $sReferUrl, 2 );
 
 
 
 
44
  }
45
  else {
46
- $sReferQuery = '';
47
  }
48
 
49
- $sRedirectTo = '';
50
- if ( !empty( $sReferQuery ) ) {
51
- parse_str( $sReferQuery, $aReferQueryItems );
52
  if ( !empty( $aReferQueryItems[ 'redirect_to' ] ) ) {
53
- $sRedirectTo = rawurlencode( $aReferQueryItems[ 'redirect_to' ] );
54
  }
55
  }
56
- if ( empty( $sRedirectTo ) ) {
57
- $sRedirectTo = rawurlencode( $req->post( 'redirect_to', $req->getUri() ) );
58
  }
59
 
60
- $sCancelHref = $req->post( 'cancel_href', '' );
61
- if ( empty( $sCancelHref ) && Services::Data()->isValidWebUrl( $sReferUrl ) ) {
62
- $sCancelHref = parse_url( $sReferUrl, PHP_URL_PATH );
63
  }
64
 
65
  $nMfaSkip = (int)( $opts->getMfaSkip()/DAY_IN_SECONDS );
66
- $nTimeRemaining = $mod->getSession()->login_intent_expires_at - $req->ts();
 
67
  $data = [
68
  'strings' => [
69
  'cancel' => __( 'Cancel Login', 'wp-simple-firewall' ),
@@ -72,7 +77,7 @@ class LoginIntentPage {
72
  'seconds' => strtolower( __( 'Seconds', 'wp-simple-firewall' ) ),
73
  'login_expired' => __( 'Login Expired', 'wp-simple-firewall' ),
74
  'verify_my_login' => __( 'Verify My Login', 'wp-simple-firewall' ),
75
- 'message' => $sMessage,
76
  'skip_mfa' => sprintf(
77
  __( "Don't ask again on this browser for %s.", 'wp-simple-firewall' ),
78
  sprintf( _n( '%s day', '%s days', $nMfaSkip, 'wp-simple-firewall' ), $nMfaSkip )
@@ -85,14 +90,14 @@ class LoginIntentPage {
85
  },
86
  $mfaCon->getProvidersForUser( Services::WpUsers()->getCurrentWpUser(), true )
87
  ) ),
88
- 'time_remaining' => $nTimeRemaining,
89
  'message_type' => 'info',
90
  'login_intent_flag' => $mod->getLoginIntentRequestFlag(),
91
  ],
92
  'hrefs' => [
93
  'form_action' => parse_url( $WP->getAdminUrl( '', true ), PHP_URL_PATH ),
94
- 'redirect_to' => $sRedirectTo,
95
- 'cancel_href' => $sCancelHref
96
  ],
97
  'flags' => [
98
  'can_skip_mfa' => $opts->isMfaSkip(),
@@ -117,14 +122,15 @@ class LoginIntentPage {
117
 
118
  $labels = $con->getLabels();
119
  $bannerURL = empty( $labels[ 'url_login2fa_logourl' ] ) ? $con->urls->forImage( 'shield/banner-2FA.png' ) : $labels[ 'url_login2fa_logourl' ];
120
- $nTimeRemaining = $mod->getSession()->login_intent_expires_at - $req->ts();
 
121
  $data = [
122
  'strings' => [
123
  'what_is_this' => __( 'What is this?', 'wp-simple-firewall' ),
124
  'page_title' => sprintf( __( '%s Login Verification', 'wp-simple-firewall' ), $con->getHumanName() ),
125
  ],
126
  'data' => [
127
- 'time_remaining' => $nTimeRemaining,
128
  ],
129
  'hrefs' => [
130
  'css_bootstrap' => $con->urls->forCss( 'bootstrap' ),
@@ -164,4 +170,4 @@ class LoginIntentPage {
164
  Services::DataManipulation()->mergeArraysRecursive(
165
  $mod->getUIHandler()->getBaseDisplayData(), $data ), true );
166
  }
167
- }
28
  $req = Services::Request();
29
  $WP = Services::WpGeneral();
30
 
31
+ $notice = $con->getAdminNotices()->getFlashNotice();
32
+ if ( $notice instanceof NoticeVO ) {
33
+ $msg = $notice->render_data[ 'message' ];
34
  }
35
  else {
36
+ $msg = $opts->isChainedAuth() ?
37
  __( 'Please supply all authentication codes', 'wp-simple-firewall' )
38
  : __( 'Please supply at least 1 authentication code', 'wp-simple-firewall' );
39
  }
40
 
41
+ if ( !empty( $msg ) && !$con->getModule_SecAdmin()->getWhiteLabelController()->isEnabled() ) {
42
+ $msg .= sprintf( ' [<a href="%s" target="_blank">%s</a>]', 'https://shsec.io/shieldcantaccess', __( 'More Info', 'wp-simple-firewall' ) );
43
+ }
44
+
45
+ $referUrl = $req->server( 'HTTP_REFERER', '' );
46
+ if ( strpos( $referUrl, '?' ) ) {
47
+ list( $referUrl, $referQuery ) = explode( '?', $referUrl, 2 );
48
  }
49
  else {
50
+ $referQuery = '';
51
  }
52
 
53
+ $redirectTo = '';
54
+ if ( !empty( $referQuery ) ) {
55
+ parse_str( $referQuery, $aReferQueryItems );
56
  if ( !empty( $aReferQueryItems[ 'redirect_to' ] ) ) {
57
+ $redirectTo = rawurlencode( $aReferQueryItems[ 'redirect_to' ] );
58
  }
59
  }
60
+ if ( empty( $redirectTo ) ) {
61
+ $redirectTo = rawurlencode( $req->post( 'redirect_to', $req->getUri() ) );
62
  }
63
 
64
+ $cancelHref = $req->post( 'cancel_href', '' );
65
+ if ( empty( $cancelHref ) && Services::Data()->isValidWebUrl( $referUrl ) ) {
66
+ $cancelHref = parse_url( $referUrl, PHP_URL_PATH );
67
  }
68
 
69
  $nMfaSkip = (int)( $opts->getMfaSkip()/DAY_IN_SECONDS );
70
+ $timeRemaining = $mfaCon->getLoginIntentExpiresAt() - $req->ts();
71
+
72
  $data = [
73
  'strings' => [
74
  'cancel' => __( 'Cancel Login', 'wp-simple-firewall' ),
77
  'seconds' => strtolower( __( 'Seconds', 'wp-simple-firewall' ) ),
78
  'login_expired' => __( 'Login Expired', 'wp-simple-firewall' ),
79
  'verify_my_login' => __( 'Verify My Login', 'wp-simple-firewall' ),
80
+ 'message' => $msg,
81
  'skip_mfa' => sprintf(
82
  __( "Don't ask again on this browser for %s.", 'wp-simple-firewall' ),
83
  sprintf( _n( '%s day', '%s days', $nMfaSkip, 'wp-simple-firewall' ), $nMfaSkip )
90
  },
91
  $mfaCon->getProvidersForUser( Services::WpUsers()->getCurrentWpUser(), true )
92
  ) ),
93
+ 'time_remaining' => $timeRemaining,
94
  'message_type' => 'info',
95
  'login_intent_flag' => $mod->getLoginIntentRequestFlag(),
96
  ],
97
  'hrefs' => [
98
  'form_action' => parse_url( $WP->getAdminUrl( '', true ), PHP_URL_PATH ),
99
+ 'redirect_to' => $redirectTo,
100
+ 'cancel_href' => $cancelHref
101
  ],
102
  'flags' => [
103
  'can_skip_mfa' => $opts->isMfaSkip(),
122
 
123
  $labels = $con->getLabels();
124
  $bannerURL = empty( $labels[ 'url_login2fa_logourl' ] ) ? $con->urls->forImage( 'shield/banner-2FA.png' ) : $labels[ 'url_login2fa_logourl' ];
125
+ $timeRemaining = $oIC->getLoginIntentExpiresAt() - $req->ts();
126
+
127
  $data = [
128
  'strings' => [
129
  'what_is_this' => __( 'What is this?', 'wp-simple-firewall' ),
130
  'page_title' => sprintf( __( '%s Login Verification', 'wp-simple-firewall' ), $con->getHumanName() ),
131
  ],
132
  'data' => [
133
+ 'time_remaining' => $timeRemaining,
134
  ],
135
  'hrefs' => [
136
  'css_bootstrap' => $con->urls->forCss( 'bootstrap' ),
170
  Services::DataManipulation()->mergeArraysRecursive(
171
  $mod->getUIHandler()->getBaseDisplayData(), $data ), true );
172
  }
173
+ }
src/lib/src/Modules/LoginGuard/Lib/TwoFactor/MfaController.php CHANGED
@@ -5,7 +5,6 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard\Lib\TwoFact
5
  use FernleafSystems\Utilities\Data\Response\StdResponse;
6
  use FernleafSystems\Utilities\Logic\ExecOnce;
7
  use FernleafSystems\Wordpress\Plugin\Shield;
8
- use FernleafSystems\Wordpress\Plugin\Shield\Databases\Session\Update;
9
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard;
10
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard\Lib\TwoFactor\Provider;
11
  use FernleafSystems\Wordpress\Services\Services;
@@ -56,8 +55,6 @@ class MfaController {
56
  }
57
 
58
  private function captureLoginIntent( \WP_User $user ) {
59
- /** @var LoginGuard\Options $opts */
60
- $opts = $this->getOptions();
61
  if ( $this->isSubjectToLoginIntent( $user )
62
  && !Services::WpUsers()->isAppPasswordAuth() && !$this->canUserMfaSkip( $user ) ) {
63
 
@@ -67,11 +64,10 @@ class MfaController {
67
  $provider->captureLoginAttempt( $user );
68
  }
69
 
70
- $this->setLoginIntentExpiresAt(
71
- Services::Request()
72
- ->carbon()
73
- ->addMinutes( $opts->getLoginIntentMinutes() )->timestamp
74
- );
75
  }
76
  }
77
  }
@@ -126,7 +122,7 @@ class MfaController {
126
  }
127
 
128
  private function assessLoginIntent( \WP_User $user ) {
129
- if ( $this->getLoginIntentExpiresAt() > 0 ) {
130
 
131
  if ( $this->isSubjectToLoginIntent( $user ) ) {
132
 
@@ -134,14 +130,14 @@ class MfaController {
134
  $this->processActiveLoginIntent();
135
  }
136
  else {
137
- Services::WpUsers()->logoutUser(); // clears the login and login intent
138
  Services::Response()->redirectHere();
139
  }
140
  }
141
  else {
142
  // This handles the case where an admin changes a setting while a user is logged-in
143
  // So to prevent this, we remove any intent for a user that isn't subject to it right now
144
- $this->removeLoginIntent();
145
  }
146
  }
147
  }
@@ -214,31 +210,32 @@ class MfaController {
214
  // Is 2FA/login-intent submit
215
  if ( $req->request( $this->getLoginIntentRequestFlag() ) == 1 ) {
216
 
 
217
  if ( $req->post( 'cancel' ) == 1 ) {
218
- $WPUsers->logoutUser(); // clears the login and login intent
219
- $sRedirectHref = $req->post( 'cancel_href' );
220
- empty( $sRedirectHref ) ? $WPResp->redirectToLogin() : $WPResp->redirect( $sRedirectHref );
221
  }
222
  elseif ( $this->validateLoginIntentRequest() ) {
223
 
224
  if ( $req->post( 'skip_mfa' ) === 'Y' ) {
225
  ( new MfaSkip() )
226
  ->setMod( $this->getMod() )
227
- ->addMfaSkip( $WPUsers->getCurrentWpUser() );
228
  }
229
 
230
  $con->fireEvent( '2fa_success' );
231
 
232
- $sFlash = __( 'Success', 'wp-simple-firewall' ).'! '.__( 'Thank you for authenticating your login.', 'wp-simple-firewall' );
233
  if ( $opts->isEnabledBackupCodes() ) {
234
- $sFlash .= ' '.__( 'If you used your Backup Code, you will need to reset it.', 'wp-simple-firewall' ); //TODO::
235
  }
236
- $this->getMod()->setFlashAdminNotice( $sFlash );
237
 
238
- $this->removeLoginIntent();
239
 
240
- $sRedirectHref = $req->post( 'redirect_to' );
241
- empty( $sRedirectHref ) ? $WPResp->redirectHere() : $WPResp->redirect( rawurldecode( $sRedirectHref ) );
242
  }
243
  else {
244
  $con->getAdminNotices()
@@ -311,33 +308,50 @@ class MfaController {
311
  return $result;
312
  }
313
 
314
- private function getLoginIntentExpiresAt() :int {
315
- return $this->getCon()
316
- ->getModule_Sessions()
317
- ->getSessionCon()
318
- ->hasSession() ? (int)$this->getMod()->getSession()->login_intent_expires_at : 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
319
  }
320
 
321
  /**
322
  * Use this ONLY when the login intent has been successfully verified.
323
  * @return $this
324
  */
325
- private function removeLoginIntent() {
326
- return $this->setLoginIntentExpiresAt( 0 );
327
- }
 
 
328
 
329
- protected function setLoginIntentExpiresAt( int $expiresAt ) :self {
330
- $sessMod = $this->getCon()->getModule_Sessions();
331
- $sessCon = $sessMod->getSessionCon();
332
- if ( $sessCon->hasSession() ) {
333
- /** @var Update $upd */
334
- $upd = $sessMod->getDbHandler_Sessions()->getQueryUpdater();
335
- $upd->updateLoginIntentExpiresAt( $sessCon->getCurrent(), $expiresAt );
336
- }
337
  return $this;
338
  }
339
 
340
  private function getLoginIntentRequestFlag() :string {
341
  return $this->getCon()->prefix( 'login-intent-request' );
342
  }
 
 
 
 
 
343
  }
5
  use FernleafSystems\Utilities\Data\Response\StdResponse;
6
  use FernleafSystems\Utilities\Logic\ExecOnce;
7
  use FernleafSystems\Wordpress\Plugin\Shield;
 
8
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard;
9
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard\Lib\TwoFactor\Provider;
10
  use FernleafSystems\Wordpress\Services\Services;
55
  }
56
 
57
  private function captureLoginIntent( \WP_User $user ) {
 
 
58
  if ( $this->isSubjectToLoginIntent( $user )
59
  && !Services::WpUsers()->isAppPasswordAuth() && !$this->canUserMfaSkip( $user ) ) {
60
 
64
  $provider->captureLoginAttempt( $user );
65
  }
66
 
67
+ $meta = $this->getCon()->getUserMeta( $user );
68
+ $intents = $meta->login_intents ?? [];
69
+ $intents[ $this->getVisitorID() ] = true;
70
+ $meta->login_intents = $intents;
 
71
  }
72
  }
73
  }
122
  }
123
 
124
  private function assessLoginIntent( \WP_User $user ) {
125
+ if ( $this->hasLoginIntent( $user ) ) {
126
 
127
  if ( $this->isSubjectToLoginIntent( $user ) ) {
128
 
130
  $this->processActiveLoginIntent();
131
  }
132
  else {
133
+ $this->destroyLogin( $user );
134
  Services::Response()->redirectHere();
135
  }
136
  }
137
  else {
138
  // This handles the case where an admin changes a setting while a user is logged-in
139
  // So to prevent this, we remove any intent for a user that isn't subject to it right now
140
+ $this->removeLoginIntent( $user );
141
  }
142
  }
143
  }
210
  // Is 2FA/login-intent submit
211
  if ( $req->request( $this->getLoginIntentRequestFlag() ) == 1 ) {
212
 
213
+ $user = $WPUsers->getCurrentWpUser();
214
  if ( $req->post( 'cancel' ) == 1 ) {
215
+ $this->destroyLogin( $user );
216
+ $redirect = $req->post( 'cancel_href' );
217
+ empty( $redirect ) ? $WPResp->redirectToLogin() : $WPResp->redirect( $redirect );
218
  }
219
  elseif ( $this->validateLoginIntentRequest() ) {
220
 
221
  if ( $req->post( 'skip_mfa' ) === 'Y' ) {
222
  ( new MfaSkip() )
223
  ->setMod( $this->getMod() )
224
+ ->addMfaSkip( $user );
225
  }
226
 
227
  $con->fireEvent( '2fa_success' );
228
 
229
+ $flash = __( 'Success', 'wp-simple-firewall' ).'! '.__( 'Thank you for authenticating your login.', 'wp-simple-firewall' );
230
  if ( $opts->isEnabledBackupCodes() ) {
231
+ $flash .= ' '.__( 'If you used your Backup Code, you will need to reset it.', 'wp-simple-firewall' ); //TODO::
232
  }
233
+ $this->getMod()->setFlashAdminNotice( $flash );
234
 
235
+ $this->removeLoginIntent( $user );
236
 
237
+ $redirect = $req->post( 'redirect_to' );
238
+ empty( $redirect ) ? $WPResp->redirectHere() : $WPResp->redirect( rawurldecode( $redirect ) );
239
  }
240
  else {
241
  $con->getAdminNotices()
308
  return $result;
309
  }
310
 
311
+ public function getLoginIntentExpiresAt() :int {
312
+ /** @var LoginGuard\Options $opts */
313
+ $opts = $this->getOptions();
314
+ $sessCon = $this->getCon()
315
+ ->getModule_Sessions()
316
+ ->getSessionCon();
317
+
318
+ $expiresAt = 0;
319
+ if ( $sessCon->hasSession() && $this->hasLoginIntent( Services::WpUsers()->getCurrentWpUser() ) ) {
320
+ $expiresAt = Services::Request()
321
+ ->carbon()
322
+ ->setTimestamp( $sessCon->getCurrent()->logged_in_at )
323
+ ->addMinutes( $opts->getLoginIntentMinutes() )->timestamp;
324
+ }
325
+ return $expiresAt;
326
+ }
327
+
328
+ private function hasLoginIntent( \WP_User $user ) :bool {
329
+ return !empty( $this->getCon()->getUserMeta( $user )->login_intents[ $this->getVisitorID() ] );
330
+ }
331
+
332
+ private function getVisitorID() :string {
333
+ return md5( Services::Request()->getUserAgent().Services::IP()->getRequestIp() );
334
  }
335
 
336
  /**
337
  * Use this ONLY when the login intent has been successfully verified.
338
  * @return $this
339
  */
340
+ private function removeLoginIntent( $user ) {
341
+ $meta = $this->getCon()->getUserMeta( $user );
342
+ $intents = $meta->login_intents ?? [];
343
+ unset( $intents[ $this->getVisitorID() ] );
344
+ $meta->login_intents = $intents;
345
 
 
 
 
 
 
 
 
 
346
  return $this;
347
  }
348
 
349
  private function getLoginIntentRequestFlag() :string {
350
  return $this->getCon()->prefix( 'login-intent-request' );
351
  }
352
+
353
+ private function destroyLogin( \WP_User $user ) {
354
+ $this->removeLoginIntent( $user );
355
+ Services::WpUsers()->logoutUser();
356
+ }
357
  }
src/lib/src/Modules/LoginGuard/Lib/TwoFactor/Provider/BackupCodes.php CHANGED
@@ -24,7 +24,6 @@ class BackupCodes extends BaseProvider {
24
  }
25
 
26
  protected function getProviderSpecificRenderData( \WP_User $user ) :array {
27
- error_log( var_export( $this->hasValidatedProfile( $user ), true ) );
28
  return [
29
  'strings' => [
30
  'button_gen_code' => __( 'Generate ONE-Time Backup 2FA Login Code', 'wp-simple-firewall' ),
@@ -42,7 +41,7 @@ class BackupCodes extends BaseProvider {
42
  'cant_remove_admins' => sprintf( __( "Sorry, %s may only be removed from another user's account by a Security Administrator.", 'wp-simple-firewall' ), __( 'Backup Codes', 'wp-simple-firewall' ) ),
43
  'provided_by' => sprintf( __( 'Provided by %s', 'wp-simple-firewall' ), $this->getCon()
44
  ->getHumanName() ),
45
- 'remove_more_info' => sprintf( __( 'Understand how to remove Google Authenticator', 'wp-simple-firewall' ) )
46
  ]
47
  ];
48
  }
24
  }
25
 
26
  protected function getProviderSpecificRenderData( \WP_User $user ) :array {
 
27
  return [
28
  'strings' => [
29
  'button_gen_code' => __( 'Generate ONE-Time Backup 2FA Login Code', 'wp-simple-firewall' ),
41
  'cant_remove_admins' => sprintf( __( "Sorry, %s may only be removed from another user's account by a Security Administrator.", 'wp-simple-firewall' ), __( 'Backup Codes', 'wp-simple-firewall' ) ),
42
  'provided_by' => sprintf( __( 'Provided by %s', 'wp-simple-firewall' ), $this->getCon()
43
  ->getHumanName() ),
44
+ 'remove_more_info' => __( 'Understand how to remove Google Authenticator', 'wp-simple-firewall' )
45
  ]
46
  ];
47
  }
src/lib/src/Modules/LoginGuard/Lib/TwoFactor/Provider/GoogleAuth.php CHANGED
@@ -5,6 +5,7 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard\Lib\TwoFact
5
  use Dolondro\GoogleAuthenticator;
6
  use FernleafSystems\Utilities\Data\Response\StdResponse;
7
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard;
 
8
  use FernleafSystems\Wordpress\Services\Services;
9
 
10
  class GoogleAuth extends BaseProvider {
@@ -34,7 +35,7 @@ class GoogleAuth extends BaseProvider {
34
  $validatedProfile = $this->hasValidatedProfile( $user );
35
  return [
36
  'hrefs' => [
37
- 'src_chart_url' => $validatedProfile ? '' : $this->getGaRegisterChartUrl( $user ),
38
  ],
39
  'vars' => [
40
  'ga_secret' => $validatedProfile ? $this->getSecret( $user ) : $this->resetSecret( $user ),
@@ -59,23 +60,46 @@ class GoogleAuth extends BaseProvider {
59
  ];
60
  }
61
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
  /**
63
- * @param \WP_User $user
64
  * @return string
 
65
  */
66
- public function getGaRegisterChartUrl( $user ) {
67
- $url = '';
68
- if ( !empty( $user ) ) {
69
- try {
70
- $url = ( new GoogleAuthenticator\QrImageGenerator\EndroidQrImageGenerator() )
71
- ->generateUri(
72
- $this->getGaSecret( $user )
73
- );
74
- }
75
- catch ( \InvalidArgumentException $e ) {
76
- }
77
  }
78
- return $url;
 
 
 
 
 
 
 
 
 
 
 
79
  }
80
 
81
  public function removeGaOnAccount( \WP_User $user ) :StdResponse {
5
  use Dolondro\GoogleAuthenticator;
6
  use FernleafSystems\Utilities\Data\Response\StdResponse;
7
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\LoginGuard;
8
+ use FernleafSystems\Wordpress\Plugin\Shield\ShieldNetApi\Tools\GenerateGoogleAuthQrCode;
9
  use FernleafSystems\Wordpress\Services\Services;
10
 
11
  class GoogleAuth extends BaseProvider {
35
  $validatedProfile = $this->hasValidatedProfile( $user );
36
  return [
37
  'hrefs' => [
38
+ 'src_chart_url' => $validatedProfile ? '' : $this->getQrImage( $user ),
39
  ],
40
  'vars' => [
41
  'ga_secret' => $validatedProfile ? $this->getSecret( $user ) : $this->resetSecret( $user ),
60
  ];
61
  }
62
 
63
+ public function getQrImage( \WP_User $user ) :string {
64
+ $secret = $this->getGaSecret( $user );
65
+
66
+ try {
67
+ $qrImage = $this->getGaRegisterChartUrl( $secret );
68
+ }
69
+ catch ( \Exception $e ) {
70
+ $qrImage = $this->getGaRegisterChartUrlShieldNet( $secret );
71
+ }
72
+
73
+ return 'data:image/png;base64, '.$qrImage;
74
+ }
75
+
76
  /**
77
+ * @param GoogleAuthenticator\Secret $secret
78
  * @return string
79
+ * @throws \Exception
80
  */
81
+ private function getGaRegisterChartUrl( GoogleAuthenticator\Secret $secret ) :string {
82
+ $rawImage = Services::HttpRequest()
83
+ ->getContent(
84
+ ( new GoogleAuthenticator\QrImageGenerator\GoogleQrImageGenerator() )
85
+ ->generateUri( $secret ),
86
+ [ 'timeout' => 3 ]
87
+ );
88
+ if ( empty( $rawImage ) ) {
89
+ throw new \Exception( "Couldn't load Google chart" );
 
 
90
  }
91
+ return base64_encode( $rawImage );
92
+ }
93
+
94
+ private function getGaRegisterChartUrlShieldNet( GoogleAuthenticator\Secret $secret ) :string {
95
+ return ( new GenerateGoogleAuthQrCode() )
96
+ ->setMod( $this->getCon()->getModule_Plugin() )
97
+ ->getCode(
98
+ $secret->getSecretKey(),
99
+ $secret->getIssuer(),
100
+ $secret->getLabel(),
101
+ 'png'
102
+ );
103
  }
104
 
105
  public function removeGaOnAccount( \WP_User $user ) :StdResponse {
src/lib/src/Modules/LoginGuard/Lib/TwoFactor/Provider/Yubikey.php CHANGED
@@ -43,7 +43,7 @@ class Yubikey extends BaseProvider {
43
  'cant_add_other_user' => sprintf( __( "Sorry, %s may not be added to another user's account.", 'wp-simple-firewall' ), 'Yubikey' ),
44
  'cant_remove_admins' => sprintf( __( "Sorry, %s may only be removed from another user's account by a Security Administrator.", 'wp-simple-firewall' ), __( 'Yubikey', 'wp-simple-firewall' ) ),
45
  'provided_by' => sprintf( __( 'Provided by %s', 'wp-simple-firewall' ), $con->getHumanName() ),
46
- 'remove_more_info' => sprintf( __( 'Understand how to remove Google Authenticator', 'wp-simple-firewall' ) )
47
  ],
48
  ];
49
  }
43
  'cant_add_other_user' => sprintf( __( "Sorry, %s may not be added to another user's account.", 'wp-simple-firewall' ), 'Yubikey' ),
44
  'cant_remove_admins' => sprintf( __( "Sorry, %s may only be removed from another user's account by a Security Administrator.", 'wp-simple-firewall' ), __( 'Yubikey', 'wp-simple-firewall' ) ),
45
  'provided_by' => sprintf( __( 'Provided by %s', 'wp-simple-firewall' ), $con->getHumanName() ),
46
+ 'remove_more_info' => __( 'Understand how to remove Google Authenticator', 'wp-simple-firewall' )
47
  ],
48
  ];
49
  }
src/lib/src/Modules/Plugin/AdminNotices.php CHANGED
@@ -93,9 +93,9 @@ class AdminNotices extends Shield\Modules\Base\AdminNotices {
93
  $notice->render_data = [
94
  'notice_attributes' => [],
95
  'strings' => [
96
- 'title' => sprintf( '%s: %s', __( 'Warning', 'wp-simple-firewall' ),
97
  sprintf( __( "%s Plugin Is Too Old", 'wp-simple-firewall' ), $name ) ),
98
- 'lines' => [
99
  sprintf(
100
  __( 'There are at least 2 major upgrades to the %s plugin since your version.', 'wp-simple-firewall' ),
101
  $name
@@ -186,8 +186,8 @@ class AdminNotices extends Shield\Modules\Base\AdminNotices {
186
  __( 'The SG Optimizer plugin has 2 settings which are breaking your site and certain %s features.', 'wp-simple-firewall' ),
187
  $name
188
  )
189
- .' '.sprintf( 'The problematic options are: "Defer Render-blocking JS" and "Remove Query Strings From Static Resources".' ),
190
- 'learn_more' => sprintf( 'Click here to learn more' ),
191
  'sgoptimizer_turnoff' => __( 'Click here to automatically turn off those options.', 'wp-simple-firewall' )
192
  ],
193
  'ajax' => [
@@ -197,8 +197,8 @@ class AdminNotices extends Shield\Modules\Base\AdminNotices {
197
  }
198
 
199
  private function buildNotice_PluginMailingListSignup( NoticeVO $notice ) {
200
- /** @var Options $oOpts */
201
- $oOpts = $this->getOptions();
202
 
203
  $name = $this->getCon()->getHumanName();
204
  $user = Services::WpUsers()->getCurrentWpUser();
@@ -216,14 +216,14 @@ class AdminNotices extends Shield\Modules\Base\AdminNotices {
216
  and to provide guidance with the %s plugin.', $name, $name ),
217
  'privacy_policy' => sprintf(
218
  'I certify that I have read and agree to the <a href="%s" target="_blank">Privacy Policy</a>',
219
- $oOpts->getDef( 'href_privacy_policy' )
220
  ),
221
- 'consent' => sprintf( __( 'I agree to Ts & Cs', 'wp-simple-firewall' ) )
222
  ],
223
  'hrefs' => [
224
- 'privacy_policy' => $oOpts->getDef( 'href_privacy_policy' )
225
  ],
226
- 'install_days' => $oOpts->getInstallationDays(),
227
  'vars' => [
228
  'name' => $user->first_name,
229
  'user_email' => $user->user_email,
@@ -258,7 +258,7 @@ class AdminNotices extends Shield\Modules\Base\AdminNotices {
258
  'dismiss' => __( "I don't need the setup wizard just now", 'wp-simple-firewall' ),
259
  'title' => sprintf( __( 'Get started quickly with the %s Setup Wizard', 'wp-simple-firewall' ), $name ),
260
  'setup' => sprintf( __( 'The welcome wizard will help you get setup quickly and become familiar with some of the core %s features', 'wp-simple-firewall' ), $name ),
261
- 'launch' => sprintf( __( "Launch the welcome wizard", 'wp-simple-firewall' ), $name ),
262
  ],
263
  'hrefs' => [
264
  'wizard' => $this->getMod()->getUrl_Wizard( 'welcome' ),
93
  $notice->render_data = [
94
  'notice_attributes' => [],
95
  'strings' => [
96
+ 'title' => sprintf( '%s: %s', __( 'Warning', 'wp-simple-firewall' ),
97
  sprintf( __( "%s Plugin Is Too Old", 'wp-simple-firewall' ), $name ) ),
98
+ 'lines' => [
99
  sprintf(
100
  __( 'There are at least 2 major upgrades to the %s plugin since your version.', 'wp-simple-firewall' ),
101
  $name
186
  __( 'The SG Optimizer plugin has 2 settings which are breaking your site and certain %s features.', 'wp-simple-firewall' ),
187
  $name
188
  )
189
+ .' '.'The problematic options are: "Defer Render-blocking JS" and "Remove Query Strings From Static Resources".',
190
+ 'learn_more' => 'Click here to learn more',
191
  'sgoptimizer_turnoff' => __( 'Click here to automatically turn off those options.', 'wp-simple-firewall' )
192
  ],
193
  'ajax' => [
197
  }
198
 
199
  private function buildNotice_PluginMailingListSignup( NoticeVO $notice ) {
200
+ /** @var Options $opts */
201
+ $opts = $this->getOptions();
202
 
203
  $name = $this->getCon()->getHumanName();
204
  $user = Services::WpUsers()->getCurrentWpUser();
216
  and to provide guidance with the %s plugin.', $name, $name ),
217
  'privacy_policy' => sprintf(
218
  'I certify that I have read and agree to the <a href="%s" target="_blank">Privacy Policy</a>',
219
+ $opts->getDef( 'href_privacy_policy' )
220
  ),
221
+ 'consent' => __( 'I agree to Ts & Cs', 'wp-simple-firewall' )
222
  ],
223
  'hrefs' => [
224
+ 'privacy_policy' => $opts->getDef( 'href_privacy_policy' )
225
  ],
226
+ 'install_days' => $opts->getInstallationDays(),
227
  'vars' => [
228
  'name' => $user->first_name,
229
  'user_email' => $user->user_email,
258
  'dismiss' => __( "I don't need the setup wizard just now", 'wp-simple-firewall' ),
259
  'title' => sprintf( __( 'Get started quickly with the %s Setup Wizard', 'wp-simple-firewall' ), $name ),
260
  'setup' => sprintf( __( 'The welcome wizard will help you get setup quickly and become familiar with some of the core %s features', 'wp-simple-firewall' ), $name ),
261
+ 'launch' => sprintf( __( "Launch the welcome wizard", 'wp-simple-firewall' ), $name ),
262
  ],
263
  'hrefs' => [
264
  'wizard' => $this->getMod()->getUrl_Wizard( 'welcome' ),
src/lib/src/Modules/Plugin/Debug.php CHANGED
@@ -7,6 +7,6 @@ use FernleafSystems\Wordpress\Plugin\Shield\Modules;
7
  class Debug extends Modules\Base\Debug {
8
 
9
  public function run() {
10
- die();
11
  }
12
  }
7
  class Debug extends Modules\Base\Debug {
8
 
9
  public function run() {
10
+ die( 'finish' );
11
  }
12
  }
src/lib/src/Modules/Plugin/Insights/DashboardCards.php CHANGED
@@ -359,7 +359,7 @@ class DashboardCards {
359
  ],
360
 
361
  'integrations' => [
362
- 'title' => __( '3rd Party Integrations', 'wp-simple-firewall' ),
363
  'img' => $con->urls->forImage( 'bootstrap/link-45deg.svg' ),
364
  'paras' => [
365
  __( "Shield integrates with 3rd party plugins and services.", 'wp-simple-firewall' ),
359
  ],
360
 
361
  'integrations' => [
362
+ 'title' => __( 'Integrations', 'wp-simple-firewall' ),
363
  'img' => $con->urls->forImage( 'bootstrap/link-45deg.svg' ),
364
  'paras' => [
365
  __( "Shield integrates with 3rd party plugins and services.", 'wp-simple-firewall' ),
src/lib/src/Modules/Plugin/Lib/ImportExport/Import.php CHANGED
@@ -10,12 +10,9 @@ class Import {
10
 
11
  use ModConsumer;
12
 
13
- /**
14
- * @param string $sMethod
15
- */
16
- public function run( $sMethod = 'site' ) {
17
  try {
18
- switch ( $sMethod ) {
19
  case 'file':
20
  $this->fromFileUpload();
21
  break;
@@ -32,63 +29,74 @@ class Import {
32
 
33
  /**
34
  * @param string $path
 
35
  * @throws \Exception
36
  */
37
- public function fromFile( $path ) {
38
- if ( !$this->getCon()->isPluginAdmin() ) {
39
- throw new \Exception( __( 'Not currently logged-in as security admin', 'wp-simple-firewall' ) );
 
 
 
 
 
 
 
 
 
 
40
  }
41
 
42
- $sContent = Services::WpFs()->getFileContent( $path );
43
- if ( empty( $sContent ) ) {
44
- throw new \Exception( __( 'Uploaded file was empty', 'wp-simple-firewall' ) );
45
  }
46
 
47
  {//filter any comment lines
48
- $aParts = array_filter(
49
- array_map( 'trim', explode( "\n", $sContent ) ),
50
- function ( $sLine ) {
51
- return ( strpos( $sLine, '{' ) === 0 );
52
  }
53
  );
54
- if ( empty( $aParts ) ) {
55
  throw new \Exception( __( 'Options data could not be found in uploaded file', 'wp-simple-firewall' ) );
56
  }
57
  }
58
  {//parse the options json
59
- $aData = @json_decode( array_shift( $aParts ), true );
60
- if ( empty( $aData ) || !is_array( $aData ) ) {
61
  throw new \Exception( __( "Options data in the file wasn't of the correct format.", 'wp-simple-firewall' ) );
62
  }
63
  }
64
 
65
- $this->processDataImport( $aData, __( 'uploaded file', 'wp-simple-firewall' ) );
66
  }
67
 
68
  /**
69
  * @throws \Exception
70
  */
71
  public function fromFileUpload() {
 
 
 
72
  if ( Services::Request()->post( 'confirm' ) != 'Y' ) {
73
  throw new \Exception( __( 'Please check the box to confirm your intent to overwrite settings', 'wp-simple-firewall' ) );
74
  }
75
 
76
- $oFs = Services::WpFs();
77
  if ( empty( $_FILES ) || !isset( $_FILES[ 'import_file' ] )
78
  || empty( $_FILES[ 'import_file' ][ 'tmp_name' ] ) ) {
79
  throw new \Exception( __( 'Please select a file to upload', 'wp-simple-firewall' ) );
80
  }
81
  if ( $_FILES[ 'import_file' ][ 'size' ] == 0
82
  || isset( $_FILES[ 'error' ] ) && $_FILES[ 'error' ] != UPLOAD_ERR_OK
83
- || !$oFs->isFile( $_FILES[ 'import_file' ][ 'tmp_name' ] )
84
  || filesize( $_FILES[ 'import_file' ][ 'tmp_name' ] ) === 0
85
  ) {
86
  throw new \Exception( __( 'Uploading of file failed', 'wp-simple-firewall' ) );
87
  }
88
 
89
  $this->fromFile( $_FILES[ 'import_file' ][ 'tmp_name' ] );
90
-
91
- $oFs->deleteFile( $_FILES[ 'import_file' ][ 'tmp_name' ] );
92
  }
93
 
94
  /**
@@ -147,41 +155,41 @@ class Import {
147
  );
148
  $this->getMod()->saveModOptions();
149
 
150
- $aData = [
151
  'shield_action' => 'importexport_export',
152
  'secret' => $sSecretKey,
153
  'url' => Services::WpGeneral()->getHomeUrl()
154
  ];
155
  // Don't send the network setup request if it's the cron.
156
  if ( !is_null( $bEnableNetwork ) && !Services::WpGeneral()->isCron() ) {
157
- $aData[ 'network' ] = $bEnableNetwork ? 'Y' : 'N';
158
  }
159
 
160
  { // Make the request
161
- $sFinalUrl = add_query_arg( $aData, $sMasterSiteUrl );
162
  $sResponse = Services::HttpRequest()->getContent( $sFinalUrl );
163
- $aResponse = @json_decode( $sResponse, true );
164
 
165
- if ( empty( $aResponse ) ) {
166
  throw new \Exception( "Request failed as we couldn't parse the response.", 5 );
167
  }
168
  }
169
 
170
- if ( empty( $aResponse[ 'success' ] ) ) {
171
 
172
- if ( empty ( $aResponse[ 'message' ] ) ) {
173
  throw new \Exception( "Request failed with no error message from the source site.", 6 );
174
  }
175
  else {
176
- throw new \Exception( "Request failed with error message from the source site: ".$aResponse[ 'message' ], 7 );
177
  }
178
  }
179
 
180
- if ( empty( $aResponse[ 'data' ] ) || !is_array( $aResponse[ 'data' ] ) ) {
181
  throw new \Exception( "Response data was empty", 8 );
182
  }
183
 
184
- $this->processDataImport( $aResponse[ 'data' ], $sMasterSiteUrl );
185
 
186
  // Fix for the overwriting of the Master Site URL with an empty string.
187
  // Only do so if we're not turning it off. i.e on or no-change
@@ -204,37 +212,29 @@ class Import {
204
  return 0;
205
  }
206
 
207
- /**
208
- * @param array $aImportData
209
- * @param string $sImportSource
210
- * @return bool
211
- */
212
- private function processDataImport( $aImportData, $sImportSource = 'unspecified' ) {
213
- $bImported = false;
214
 
215
- $bAnythingChanged = false;
216
  foreach ( $this->getCon()->modules as $mod ) {
217
- if ( !empty( $aImportData[ $mod->getOptionsStorageKey() ] ) ) {
218
  $oTheseOpts = $mod->getOptions();
219
  $oTheseOpts->setMultipleOptions(
220
  array_diff_key(
221
- $aImportData[ $mod->getOptionsStorageKey() ],
222
  array_flip( $oTheseOpts->getXferExcluded() )
223
  )
224
  );
225
 
226
- $bAnythingChanged = $bAnythingChanged || $oTheseOpts->getNeedSave();
227
  $mod->saveModOptions( true );
228
  }
229
  }
230
 
231
- if ( $bAnythingChanged ) {
232
  $this->getCon()->fireEvent(
233
  'options_imported',
234
- [ 'audit' => [ 'site' => $sImportSource ] ]
235
  );
236
  }
237
-
238
- return $bImported;
239
  }
240
  }
10
 
11
  use ModConsumer;
12
 
13
+ public function run( string $method = 'site' ) {
 
 
 
14
  try {
15
+ switch ( $method ) {
16
  case 'file':
17
  $this->fromFileUpload();
18
  break;
29
 
30
  /**
31
  * @param string $path
32
+ * @param bool $delete
33
  * @throws \Exception
34
  */
35
+ public function fromFile( string $path, bool $delete = true ) {
36
+ $FS = Services::WpFs();
37
+
38
+ if ( !$FS->isFile( $path ) ) {
39
+ throw new \Exception( "The import file specified isn't a valid file." );
40
+ }
41
+
42
+ $content = $FS->getFileContent( $path );
43
+ if ( $delete ) {
44
+ $FS->deleteFile( $path );
45
+ if ( $FS->exists( $path ) ) {
46
+ throw new \Exception( __( 'Not importing a file that cannot be deleted', 'wp-simple-firewall' ) );
47
+ }
48
  }
49
 
50
+ if ( empty( $content ) ) {
51
+ throw new \Exception( __( 'Import file was empty', 'wp-simple-firewall' ) );
 
52
  }
53
 
54
  {//filter any comment lines
55
+ $parts = array_filter(
56
+ array_map( 'trim', explode( "\n", $content ) ),
57
+ function ( $line ) {
58
+ return ( strpos( $line, '{' ) === 0 );
59
  }
60
  );
61
+ if ( empty( $parts ) ) {
62
  throw new \Exception( __( 'Options data could not be found in uploaded file', 'wp-simple-firewall' ) );
63
  }
64
  }
65
  {//parse the options json
66
+ $data = @json_decode( array_shift( $parts ), true );
67
+ if ( empty( $data ) || !is_array( $data ) ) {
68
  throw new \Exception( __( "Options data in the file wasn't of the correct format.", 'wp-simple-firewall' ) );
69
  }
70
  }
71
 
72
+ $this->processDataImport( $data, __( 'import file', 'wp-simple-firewall' ) );
73
  }
74
 
75
  /**
76
  * @throws \Exception
77
  */
78
  public function fromFileUpload() {
79
+ if ( !$this->getCon()->isPluginAdmin() ) {
80
+ throw new \Exception( __( 'Not currently logged-in as security admin', 'wp-simple-firewall' ) );
81
+ }
82
  if ( Services::Request()->post( 'confirm' ) != 'Y' ) {
83
  throw new \Exception( __( 'Please check the box to confirm your intent to overwrite settings', 'wp-simple-firewall' ) );
84
  }
85
 
86
+ $FS = Services::WpFs();
87
  if ( empty( $_FILES ) || !isset( $_FILES[ 'import_file' ] )
88
  || empty( $_FILES[ 'import_file' ][ 'tmp_name' ] ) ) {
89
  throw new \Exception( __( 'Please select a file to upload', 'wp-simple-firewall' ) );
90
  }
91
  if ( $_FILES[ 'import_file' ][ 'size' ] == 0
92
  || isset( $_FILES[ 'error' ] ) && $_FILES[ 'error' ] != UPLOAD_ERR_OK
93
+ || !$FS->isFile( $_FILES[ 'import_file' ][ 'tmp_name' ] )
94
  || filesize( $_FILES[ 'import_file' ][ 'tmp_name' ] ) === 0
95
  ) {
96
  throw new \Exception( __( 'Uploading of file failed', 'wp-simple-firewall' ) );
97
  }
98
 
99
  $this->fromFile( $_FILES[ 'import_file' ][ 'tmp_name' ] );
 
 
100
  }
101
 
102
  /**
155
  );
156
  $this->getMod()->saveModOptions();
157
 
158
+ $data = [
159
  'shield_action' => 'importexport_export',
160
  'secret' => $sSecretKey,
161
  'url' => Services::WpGeneral()->getHomeUrl()
162
  ];
163
  // Don't send the network setup request if it's the cron.
164
  if ( !is_null( $bEnableNetwork ) && !Services::WpGeneral()->isCron() ) {
165
+ $data[ 'network' ] = $bEnableNetwork ? 'Y' : 'N';
166
  }
167
 
168
  { // Make the request
169
+ $sFinalUrl = add_query_arg( $data, $sMasterSiteUrl );
170
  $sResponse = Services::HttpRequest()->getContent( $sFinalUrl );
171
+ $response = @json_decode( $sResponse, true );
172
 
173
+ if ( empty( $response ) ) {
174
  throw new \Exception( "Request failed as we couldn't parse the response.", 5 );
175
  }
176
  }
177
 
178
+ if ( empty( $response[ 'success' ] ) ) {
179
 
180
+ if ( empty ( $response[ 'message' ] ) ) {
181
  throw new \Exception( "Request failed with no error message from the source site.", 6 );
182
  }
183
  else {
184
+ throw new \Exception( "Request failed with error message from the source site: ".$response[ 'message' ], 7 );
185
  }
186
  }
187
 
188
+ if ( empty( $response[ 'data' ] ) || !is_array( $response[ 'data' ] ) ) {
189
  throw new \Exception( "Response data was empty", 8 );
190
  }
191
 
192
+ $this->processDataImport( $response[ 'data' ], $sMasterSiteUrl );
193
 
194
  // Fix for the overwriting of the Master Site URL with an empty string.
195
  // Only do so if we're not turning it off. i.e on or no-change
212
  return 0;
213
  }
214
 
215
+ private function processDataImport( array $data, string $source = 'unspecified' ) {
 
 
 
 
 
 
216
 
217
+ $anythingChanged = false;
218
  foreach ( $this->getCon()->modules as $mod ) {
219
+ if ( !empty( $data[ $mod->getOptionsStorageKey() ] ) ) {
220
  $oTheseOpts = $mod->getOptions();
221
  $oTheseOpts->setMultipleOptions(
222
  array_diff_key(
223
+ $data[ $mod->getOptionsStorageKey() ],
224
  array_flip( $oTheseOpts->getXferExcluded() )
225
  )
226
  );
227
 
228
+ $anythingChanged = $anythingChanged || $oTheseOpts->getNeedSave();
229
  $mod->saveModOptions( true );
230
  }
231
  }
232
 
233
+ if ( $anythingChanged ) {
234
  $this->getCon()->fireEvent(
235
  'options_imported',
236
+ [ 'audit' => [ 'site' => $source ] ]
237
  );
238
  }
 
 
239
  }
240
  }
src/lib/src/Modules/Plugin/Lib/ImportExport/ImportExportController.php CHANGED
@@ -2,38 +2,54 @@
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Plugin\Lib\ImportExport;
4
 
 
5
  use FernleafSystems\Wordpress\Plugin\Shield;
6
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
7
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\Plugin;
 
8
  use FernleafSystems\Wordpress\Services\Services;
9
 
10
  class ImportExportController {
11
 
 
12
  use ModConsumer;
 
13
 
14
- public function run() {
15
- $oCon = $this->getCon();
16
- /** @var Plugin\Options $oOpts */
17
- $oOpts = $this->getOptions();
 
 
 
 
 
 
 
 
18
 
19
  // Cron
20
- add_action( $oCon->prefix( 'importexport_notify' ), function () {
21
  ( new NotifyWhitelist() )
22
  ->setMod( $this->getMod() )
23
  ->run();
24
  } );
25
 
26
- if ( $oOpts->hasImportExportMasterImportUrl() ) {
 
 
 
 
27
  // For auto update whitelist notifications:
28
- add_action( $oCon->prefix( 'importexport_updatenotified' ), function () {
29
  ( new Import() )
30
  ->setMod( $this->getMod() )
31
  ->run( 'site' );
32
  } );
33
  }
34
 
35
- add_action( $oCon->prefix( 'shield_action' ), function ( $sAction ) {
36
- switch ( $sAction ) {
37
  case 'importexport_export':
38
  ( new Export() )
39
  ->setMod( $this->getMod() )
@@ -57,13 +73,23 @@ class ImportExportController {
57
  } );
58
  }
59
 
 
 
 
 
 
 
 
 
 
 
60
  /**
61
  * We've been notified that there's an update to pull in from the master site so we set a cron to do this.
62
  */
63
  private function runOptionsUpdateNotified() {
64
  $oCon = $this->getCon();
65
- /** @var Plugin\Options $oOpts */
66
- $oOpts = $this->getOptions();
67
 
68
  $sCronHook = $oCon->prefix( 'importexport_updatenotified' );
69
  if ( wp_next_scheduled( $sCronHook ) ) {
@@ -76,18 +102,18 @@ class ImportExportController {
76
 
77
  preg_match( '#.*WordPress/.*\s+(.*)\s?#', Services::Request()->getUserAgent(), $aMatches );
78
  if ( !empty( $aMatches[ 1 ] ) && filter_var( $aMatches[ 1 ], FILTER_VALIDATE_URL ) ) {
79
- $sUrl = parse_url( $aMatches[ 1 ], PHP_URL_HOST );
80
- if ( !empty( $sUrl ) ) {
81
- $sUrl = 'Site: '.$sUrl;
82
  }
83
  }
84
  else {
85
- $sUrl = '';
86
  }
87
 
88
  $this->getCon()->fireEvent(
89
  'import_notify_received',
90
- [ 'audit' => [ 'master_site' => $oOpts->getImportExportMasterImportUrl() ] ]
91
  );
92
  }
93
  }
@@ -109,6 +135,18 @@ class ImportExportController {
109
  }
110
  }
111
 
 
 
 
 
 
 
 
 
 
 
 
 
112
  public function buildInsightsVars() :array {
113
  /** @var Plugin\ModCon $mod */
114
  $mod = $this->getMod();
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Plugin\Lib\ImportExport;
4
 
5
+ use FernleafSystems\Utilities\Logic\ExecOnce;
6
  use FernleafSystems\Wordpress\Plugin\Shield;
7
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
8
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\Plugin;
9
+ use FernleafSystems\Wordpress\Plugin\Shield\Modules\Plugin\Options;
10
  use FernleafSystems\Wordpress\Services\Services;
11
 
12
  class ImportExportController {
13
 
14
+ use ExecOnce;
15
  use ModConsumer;
16
+ use Shield\Crons\PluginCronsConsumer;
17
 
18
+ protected function run() {
19
+ $con = $this->getCon();
20
+ if ( $con->isPremiumActive() ) {
21
+ $this->setupHooks();
22
+ $this->setupCronHooks();
23
+ }
24
+ }
25
+
26
+ private function setupHooks() {
27
+ $con = $this->getCon();
28
+ /** @var Plugin\Options $opts */
29
+ $opts = $this->getOptions();
30
 
31
  // Cron
32
+ add_action( $con->prefix( 'importexport_notify' ), function () {
33
  ( new NotifyWhitelist() )
34
  ->setMod( $this->getMod() )
35
  ->run();
36
  } );
37
 
38
+ add_action( 'shield/plugin_activated', function () {
39
+ $this->importFromFlag();
40
+ } );
41
+
42
+ if ( $opts->hasImportExportMasterImportUrl() ) {
43
  // For auto update whitelist notifications:
44
+ add_action( $con->prefix( 'importexport_updatenotified' ), function () {
45
  ( new Import() )
46
  ->setMod( $this->getMod() )
47
  ->run( 'site' );
48
  } );
49
  }
50
 
51
+ add_action( $con->prefix( 'shield_action' ), function ( $action ) {
52
+ switch ( $action ) {
53
  case 'importexport_export':
54
  ( new Export() )
55
  ->setMod( $this->getMod() )
73
  } );
74
  }
75
 
76
+ private function importFromFlag() {
77
+ try {
78
+ ( new Import() )
79
+ ->setMod( $this->getMod() )
80
+ ->fromFile( $this->getCon()->paths->forFlag( 'import.json' ) );
81
+ }
82
+ catch ( \Exception $e ) {
83
+ }
84
+ }
85
+
86
  /**
87
  * We've been notified that there's an update to pull in from the master site so we set a cron to do this.
88
  */
89
  private function runOptionsUpdateNotified() {
90
  $oCon = $this->getCon();
91
+ /** @var Plugin\Options $opts */
92
+ $opts = $this->getOptions();
93
 
94
  $sCronHook = $oCon->prefix( 'importexport_updatenotified' );
95
  if ( wp_next_scheduled( $sCronHook ) ) {
102
 
103
  preg_match( '#.*WordPress/.*\s+(.*)\s?#', Services::Request()->getUserAgent(), $aMatches );
104
  if ( !empty( $aMatches[ 1 ] ) && filter_var( $aMatches[ 1 ], FILTER_VALIDATE_URL ) ) {
105
+ $url = parse_url( $aMatches[ 1 ], PHP_URL_HOST );
106
+ if ( !empty( $url ) ) {
107
+ $url = 'Site: '.$url;
108
  }
109
  }
110
  else {
111
+ $url = '';
112
  }
113
 
114
  $this->getCon()->fireEvent(
115
  'import_notify_received',
116
+ [ 'audit' => [ 'master_site' => $opts->getImportExportMasterImportUrl() ] ]
117
  );
118
  }
119
  }
135
  }
136
  }
137
 
138
+ public function runDailyCron() {
139
+ /** @var Options $opts */
140
+ $opts = $this->getOptions();
141
+ try {
142
+ ( new Import() )
143
+ ->setMod( $this->getMod() )
144
+ ->fromSite( $opts->getImportExportMasterImportUrl() );
145
+ }
146
+ catch ( \Exception $e ) {
147
+ }
148
+ }
149
+
150
  public function buildInsightsVars() :array {
151
  /** @var Plugin\ModCon $mod */
152
  $mod = $this->getMod();
src/lib/src/Modules/Plugin/Options.php CHANGED
@@ -52,7 +52,7 @@ class Options extends BaseShield\Options {
52
  }
53
 
54
  public function isTrackingEnabled() :bool {
55
- return $this->isOpt( 'enable_tracking', 'Y' );
56
  }
57
 
58
  public function isEnabledWpcli() :bool {
@@ -63,8 +63,12 @@ class Options extends BaseShield\Options {
63
  return !$this->isOpt( 'tracking_permission_set_at', 0 );
64
  }
65
 
 
 
 
 
66
  public function isImportExportPermitted() :bool {
67
- return $this->isPremium() && $this->isOpt( 'importexport_enable', 'Y' );
68
  }
69
 
70
  /**
@@ -75,6 +79,10 @@ class Options extends BaseShield\Options {
75
  return is_array( $whitelist ) ? $whitelist : [];
76
  }
77
 
 
 
 
 
78
  /**
79
  * @param bool $bOnOrOff
80
  * @return $this
52
  }
53
 
54
  public function isTrackingEnabled() :bool {
55
+ return $this->isPremium() || $this->isOpt( 'enable_tracking', 'Y' );
56
  }
57
 
58
  public function isEnabledWpcli() :bool {
63
  return !$this->isOpt( 'tracking_permission_set_at', 0 );
64
  }
65
 
66
+ /**
67
+ * @return bool
68
+ * @deprecated 11.4
69
+ */
70
  public function isImportExportPermitted() :bool {
71
+ return $this->isOpt( 'importexport_enable', 'Y' );
72
  }
73
 
74
  /**
79
  return is_array( $whitelist ) ? $whitelist : [];
80
  }
81
 
82
+ public function isEnabledShieldNET() :bool {
83
+ return $this->isOpt( 'enable_shieldnet', 'Y' );
84
+ }
85
+
86
  /**
87
  * @param bool $bOnOrOff
88
  * @return $this
src/lib/src/Modules/Plugin/Processor.php CHANGED
@@ -27,8 +27,8 @@ class Processor extends BaseShield\Processor {
27
  ->setMod( $this->getMod() )
28
  ->execute();
29
 
30
- if ( $opts->isImportExportPermitted() ) {
31
- $mod->getImpExpController()->run();
32
  }
33
 
34
  add_filter( $con->prefix( 'delete_on_deactivate' ), function ( $isDelete ) use ( $opts ) {
@@ -61,19 +61,6 @@ class Processor extends BaseShield\Processor {
61
 
62
  public function runDailyCron() {
63
  $this->getCon()->fireEvent( 'test_cron_run' );
64
-
65
- /** @var Options $opts */
66
- $opts = $this->getOptions();
67
- if ( $opts->isImportExportPermitted() ) {
68
- try {
69
- ( new Lib\ImportExport\Import() )
70
- ->setMod( $this->getMod() )
71
- ->fromSite( $opts->getImportExportMasterImportUrl() );
72
- }
73
- catch ( \Exception $e ) {
74
- }
75
- }
76
-
77
  ( new CleanStorage() )
78
  ->setCon( $this->getCon() )
79
  ->run();
27
  ->setMod( $this->getMod() )
28
  ->execute();
29
 
30
+ if ( $opts->isOpt( 'importexport_enable', 'Y' ) ) {
31
+ $mod->getImpExpController()->execute();
32
  }
33
 
34
  add_filter( $con->prefix( 'delete_on_deactivate' ), function ( $isDelete ) use ( $opts ) {
61
 
62
  public function runDailyCron() {
63
  $this->getCon()->fireEvent( 'test_cron_run' );
 
 
 
 
 
 
 
 
 
 
 
 
 
64
  ( new CleanStorage() )
65
  ->setCon( $this->getCon() )
66
  ->run();
src/lib/src/Modules/Plugin/Strings.php CHANGED
@@ -96,7 +96,7 @@ class Strings extends Base\Strings {
96
  $titleShort = sprintf( '%s / %s', __( 'Import', 'wp-simple-firewall' ), __( 'Export', 'wp-simple-firewall' ) );
97
  $summary = [
98
  sprintf( '%s - %s', __( 'Purpose', 'wp-simple-firewall' ), __( 'Automatically import options, and deploy configurations across your entire network.', 'wp-simple-firewall' ) ),
99
- sprintf( __( 'This is a Pro-only feature.', 'wp-simple-firewall' ) ),
100
  ];
101
  break;
102
 
@@ -122,9 +122,8 @@ class Strings extends Base\Strings {
122
  sprintf( '%s - %s', __( 'Purpose', 'wp-simple-firewall' ), sprintf( __( 'Setup CAPTCHA for use across %s.', 'wp-simple-firewall' ), $sPlugName ) ),
123
  sprintf( '%s - %s',
124
  __( 'Recommendation', 'wp-simple-firewall' ),
125
- sprintf( __( 'Use of this feature is highly recommend.', 'wp-simple-firewall' ).' '
126
- .sprintf( '%s: %s', __( 'Note', 'wp-simple-firewall' ), __( 'You must create your own CAPTCHA API Keys.', 'wp-simple-firewall' ) )
127
- )
128
  .'<ul class="mt-1"><li>- '.sprintf( ' <a href="%s" target="_blank">%s</a>', 'https://www.google.com/recaptcha/admin', __( 'Google reCAPTCHA Keys', 'wp-simple-firewall' ) )
129
  .'</li><li>- '.sprintf( ' <a href="%s" target="_blank">%s</a>', 'https://dashboard.hcaptcha.com/', __( 'hCaptcha Keys', 'wp-simple-firewall' ) ).'</li></ul>'
130
  ),
@@ -193,6 +192,14 @@ class Strings extends Base\Strings {
193
  ];
194
  break;
195
 
 
 
 
 
 
 
 
 
196
  case 'visitor_address_source' :
197
  $name = __( 'IP Source', 'wp-simple-firewall' );
198
  $summary = __( 'Which IP Address Is Yours', 'wp-simple-firewall' );
96
  $titleShort = sprintf( '%s / %s', __( 'Import', 'wp-simple-firewall' ), __( 'Export', 'wp-simple-firewall' ) );
97
  $summary = [
98
  sprintf( '%s - %s', __( 'Purpose', 'wp-simple-firewall' ), __( 'Automatically import options, and deploy configurations across your entire network.', 'wp-simple-firewall' ) ),
99
+ __( 'This is a Pro-only feature.', 'wp-simple-firewall' ),
100
  ];
101
  break;
102
 
122
  sprintf( '%s - %s', __( 'Purpose', 'wp-simple-firewall' ), sprintf( __( 'Setup CAPTCHA for use across %s.', 'wp-simple-firewall' ), $sPlugName ) ),
123
  sprintf( '%s - %s',
124
  __( 'Recommendation', 'wp-simple-firewall' ),
125
+ __( 'Use of this feature is highly recommend.', 'wp-simple-firewall' )
126
+ .sprintf( ' %s: %s', __( 'Note', 'wp-simple-firewall' ), __( 'You must create your own CAPTCHA API Keys.', 'wp-simple-firewall' ) )
 
127
  .'<ul class="mt-1"><li>- '.sprintf( ' <a href="%s" target="_blank">%s</a>', 'https://www.google.com/recaptcha/admin', __( 'Google reCAPTCHA Keys', 'wp-simple-firewall' ) )
128
  .'</li><li>- '.sprintf( ' <a href="%s" target="_blank">%s</a>', 'https://dashboard.hcaptcha.com/', __( 'hCaptcha Keys', 'wp-simple-firewall' ) ).'</li></ul>'
129
  ),
192
  ];
193
  break;
194
 
195
+ case 'enable_shieldnet' :
196
+ $name = __( 'Enable ShieldNET', 'wp-simple-firewall' );
197
+ $summary = __( 'Enhanced Website Security Through Network Intelligence', 'wp-simple-firewall' );
198
+ $desc = [
199
+ __( 'By leveraging and sharing information about threats to WordPress sites, ShieldNET brings the power of the entire network to your WordPress security.', 'wp-simple-firewall' )
200
+ ];
201
+ break;
202
+
203
  case 'visitor_address_source' :
204
  $name = __( 'IP Source', 'wp-simple-firewall' );
205
  $summary = __( 'Which IP Address Is Yours', 'wp-simple-firewall' );
src/lib/src/Modules/Plugin/UI.php CHANGED
@@ -105,10 +105,8 @@ class UI extends BaseShield\UI {
105
  ->checkAll();
106
  }
107
  if ( $opts->getOpt( 'captcha_checked_at' ) == 0 ) {
108
- $warnings[] = sprintf(
109
- __( "Your captcha key and secret haven't been verified.", 'wp-simple-firewall' ).' '
110
- .__( "Please double-check and make sure you haven't mixed them about, and then re-save.", 'wp-simple-firewall' )
111
- );
112
  }
113
  }
114
  break;
105
  ->checkAll();
106
  }
107
  if ( $opts->getOpt( 'captcha_checked_at' ) == 0 ) {
108
+ $warnings[] = __( "Your captcha key and secret haven't been verified.", 'wp-simple-firewall' ).' '
109
+ .__( "Please double-check and make sure you haven't mixed them about, and then re-save.", 'wp-simple-firewall' );
 
 
110
  }
111
  }
112
  break;
src/lib/src/Modules/Plugin/WpCli.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Plugin;
4
 
1
+ <?php declare( strict_types=1 );
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Plugin;
4
 
src/lib/src/Modules/Plugin/WpCli/Import.php CHANGED
@@ -4,7 +4,6 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\Plugin\WpCli;
4
 
5
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base;
6
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\Plugin\Lib;
7
- use FernleafSystems\Wordpress\Services\Services;
8
  use WP_CLI;
9
 
10
  class Import extends Base\WpCli\BaseWpCliCmd {
@@ -60,26 +59,29 @@ class Import extends Base\WpCli\BaseWpCliCmd {
60
 
61
  /**
62
  * @param array $null
63
- * @param array $aA
64
  * @throws WP_CLI\ExitException
65
  */
66
- public function cmdImport( array $null, array $aA ) {
67
 
68
- $sSource = isset( $aA[ 'source' ] ) ? $aA[ 'source' ] : '';
69
- if ( empty( $sSource ) ) {
70
  WP_CLI::error( __( 'Please use the `--source=` argument to provide the source site URL or path to file.', 'wp-simple-firewall' ) );
71
  }
72
 
73
- if ( !$this->isForceFlag( $aA ) ) {
74
  WP_CLI::confirm( __( "Importing options will overwrite this site's Shield configuration. Are you sure?", 'wp-simple-firewall' ) );
75
  }
76
 
77
  try {
78
- if ( filter_var( $sSource, FILTER_VALIDATE_URL ) ) {
79
- $this->runImportFromSite( $aA );
80
  }
81
  else {
82
- $this->runImportFromFile( $sSource, WP_CLI\Utils\get_flag_value( $aA, 'delete-file', false ) );
 
 
 
83
  }
84
  }
85
  catch ( \Exception $e ) {
@@ -96,39 +98,27 @@ class Import extends Base\WpCli\BaseWpCliCmd {
96
  }
97
 
98
  /**
99
- * @param string $sPath
100
- * @param bool $bDeleteFile
101
  * @throws \Exception
102
  */
103
- private function runImportFromFile( $sPath, $bDeleteFile = false ) {
104
- $oFS = Services::WpFs();
105
- if ( !$oFS->isFile( $sPath ) ) {
106
- throw new \Exception( "The source specified isn't a valid file." );
107
- }
108
- if ( !is_readable( $sPath ) ) {
109
- throw new \Exception( "Couldn't read the source file." );
110
- }
111
-
112
  ( new Lib\ImportExport\Import() )
113
  ->setMod( $this->getMod() )
114
- ->fromFile( $sPath );
115
-
116
- if ( $bDeleteFile ) {
117
- $oFS->deleteFile( $sPath );
118
- }
119
  }
120
 
121
  /**
122
- * @param array $aA
123
  * @throws \Exception
124
  */
125
- private function runImportFromSite( array $aA ) {
126
 
127
- $sSecret = isset( $aA[ 'site-secret' ] ) ? $aA[ 'site-secret' ] : '';
128
- $sSlave = isset( $aA[ 'slave' ] ) ? strtolower( $aA[ 'slave' ] ) : '';
129
- if ( empty( $sSecret ) ) {
130
  WP_CLI::log( __( "No secret provided so we assume we're a registered slave site.", 'wp-simple-firewall' ) );
131
- if ( $sSlave === 'add' ) {
132
  throw new \Exception( "You have elected to set this site up as a slave without providing the `site-secret`.", 'wp-simple-firewall' );
133
  }
134
  }
@@ -136,9 +126,9 @@ class Import extends Base\WpCli\BaseWpCliCmd {
136
  ( new Lib\ImportExport\Import() )
137
  ->setMod( $this->getMod() )
138
  ->fromSite(
139
- $aA[ 'source' ],
140
- $sSecret,
141
- $sSlave === 'add' ? true : ( $sSlave === 'remove' ? false : null )
142
  );
143
  }
144
  }
4
 
5
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\Base;
6
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\Plugin\Lib;
 
7
  use WP_CLI;
8
 
9
  class Import extends Base\WpCli\BaseWpCliCmd {
59
 
60
  /**
61
  * @param array $null
62
+ * @param array $args
63
  * @throws WP_CLI\ExitException
64
  */
65
+ public function cmdImport( array $null, array $args ) {
66
 
67
+ $source = $args[ 'source' ] ?? '';
68
+ if ( empty( $source ) ) {
69
  WP_CLI::error( __( 'Please use the `--source=` argument to provide the source site URL or path to file.', 'wp-simple-firewall' ) );
70
  }
71
 
72
+ if ( !$this->isForceFlag( $args ) ) {
73
  WP_CLI::confirm( __( "Importing options will overwrite this site's Shield configuration. Are you sure?", 'wp-simple-firewall' ) );
74
  }
75
 
76
  try {
77
+ if ( filter_var( $source, FILTER_VALIDATE_URL ) ) {
78
+ $this->runImportFromSite( $args );
79
  }
80
  else {
81
+ $this->runImportFromFile(
82
+ $source,
83
+ (bool)WP_CLI\Utils\get_flag_value( $args, 'delete-file', false )
84
+ );
85
  }
86
  }
87
  catch ( \Exception $e ) {
98
  }
99
 
100
  /**
101
+ * @param string $path
102
+ * @param bool $deleteFile
103
  * @throws \Exception
104
  */
105
+ private function runImportFromFile( string $path, bool $deleteFile = false ) {
 
 
 
 
 
 
 
 
106
  ( new Lib\ImportExport\Import() )
107
  ->setMod( $this->getMod() )
108
+ ->fromFile( $path, $deleteFile );
 
 
 
 
109
  }
110
 
111
  /**
112
+ * @param array $args
113
  * @throws \Exception
114
  */
115
+ private function runImportFromSite( array $args ) {
116
 
117
+ $secret = $args[ 'site-secret' ] ?? '';
118
+ $slave = isset( $args[ 'slave' ] ) ? strtolower( $args[ 'slave' ] ) : '';
119
+ if ( empty( $secret ) ) {
120
  WP_CLI::log( __( "No secret provided so we assume we're a registered slave site.", 'wp-simple-firewall' ) );
121
+ if ( $slave === 'add' ) {
122
  throw new \Exception( "You have elected to set this site up as a slave without providing the `site-secret`.", 'wp-simple-firewall' );
123
  }
124
  }
126
  ( new Lib\ImportExport\Import() )
127
  ->setMod( $this->getMod() )
128
  ->fromSite(
129
+ $args[ 'source' ],
130
+ $secret,
131
+ $slave === 'add' ? true : ( $slave === 'remove' ? false : null )
132
  );
133
  }
134
  }
src/lib/src/Modules/SecurityAdmin/Strings.php CHANGED
@@ -36,7 +36,7 @@ class Strings extends Base\Strings {
36
  $aSummary = [
37
  sprintf( '%s - %s', __( 'Purpose', 'wp-simple-firewall' ), __( 'Restricts access to this plugin preventing unauthorized changes to your security settings.', 'wp-simple-firewall' ) ),
38
  sprintf( '%s - %s', __( 'Recommendation', 'wp-simple-firewall' ), sprintf( __( 'Keep the %s feature turned on.', 'wp-simple-firewall' ), __( 'Security Admin', 'wp-simple-firewall' ) ) ),
39
- sprintf( __( 'You need to also enter a new Security PIN to enable this feature.', 'wp-simple-firewall' ) ),
40
  ];
41
  break;
42
 
36
  $aSummary = [
37
  sprintf( '%s - %s', __( 'Purpose', 'wp-simple-firewall' ), __( 'Restricts access to this plugin preventing unauthorized changes to your security settings.', 'wp-simple-firewall' ) ),
38
  sprintf( '%s - %s', __( 'Recommendation', 'wp-simple-firewall' ), sprintf( __( 'Keep the %s feature turned on.', 'wp-simple-firewall' ), __( 'Security Admin', 'wp-simple-firewall' ) ) ),
39
+ __( 'You need to also enter a new Security PIN to enable this feature.', 'wp-simple-firewall' ),
40
  ];
41
  break;
42
 
src/lib/src/Modules/Sessions/Processor.php CHANGED
@@ -28,7 +28,8 @@ class Processor extends BaseShield\Processor {
28
  add_filter( 'login_message', [ $this, 'printLinkToAdmin' ] );
29
 
30
  $this->setupLoginCaptureHooks();
31
- $this->setToCaptureApplicationLogin( true );
 
32
  }
33
 
34
  protected function captureLogin( \WP_User $user ) {
28
  add_filter( 'login_message', [ $this, 'printLinkToAdmin' ] );
29
 
30
  $this->setupLoginCaptureHooks();
31
+ $this->setToCaptureApplicationLogin( true )
32
+ ->setAllowMultipleCapture( true );
33
  }
34
 
35
  protected function captureLogin( \WP_User $user ) {
src/lib/src/Modules/Traffic/Strings.php CHANGED
@@ -32,7 +32,7 @@ class Strings extends Base\Strings {
32
  $title = sprintf( __( 'Enable Module: %s', 'wp-simple-firewall' ), $sModName );
33
  $summary = [
34
  sprintf( '%s - %s', __( 'Purpose', 'wp-simple-firewall' ), __( 'Monitor and review all requests to your site.', 'wp-simple-firewall' ) ),
35
- sprintf( '%s - %s', __( 'Recommendation', 'wp-simple-firewall' ), sprintf( __( 'Required only if you need to review and investigate and monitor requests to your site', 'wp-simple-firewall' ) ) )
36
  ];
37
  break;
38
 
@@ -52,7 +52,7 @@ class Strings extends Base\Strings {
52
  sprintf( '%s - %s', __( 'Purpose', 'wp-simple-firewall' ), __( 'Prevents excessive requests from a single visitor.', 'wp-simple-firewall' ) ),
53
  sprintf( '%s - %s', __( 'Important', 'wp-simple-firewall' ), sprintf( __( 'This feature is only available while the Traffic Logger is active.', 'wp-simple-firewall' ), __( 'User Management', 'wp-simple-firewall' ) ) ),
54
  sprintf( '%s - %s', __( 'Warning', 'wp-simple-firewall' ), __( 'Use this feature with care.', 'wp-simple-firewall' ) )
55
- .' '.sprintf( __( 'You could block legitimate visitors who load too many pages in quick succession on your site.', 'wp-simple-firewall' ) )
56
  ];
57
  break;
58
 
32
  $title = sprintf( __( 'Enable Module: %s', 'wp-simple-firewall' ), $sModName );
33
  $summary = [
34
  sprintf( '%s - %s', __( 'Purpose', 'wp-simple-firewall' ), __( 'Monitor and review all requests to your site.', 'wp-simple-firewall' ) ),
35
+ sprintf( '%s - %s', __( 'Recommendation', 'wp-simple-firewall' ), __( 'Required only if you need to review and investigate and monitor requests to your site', 'wp-simple-firewall' ) )
36
  ];
37
  break;
38
 
52
  sprintf( '%s - %s', __( 'Purpose', 'wp-simple-firewall' ), __( 'Prevents excessive requests from a single visitor.', 'wp-simple-firewall' ) ),
53
  sprintf( '%s - %s', __( 'Important', 'wp-simple-firewall' ), sprintf( __( 'This feature is only available while the Traffic Logger is active.', 'wp-simple-firewall' ), __( 'User Management', 'wp-simple-firewall' ) ) ),
54
  sprintf( '%s - %s', __( 'Warning', 'wp-simple-firewall' ), __( 'Use this feature with care.', 'wp-simple-firewall' ) )
55
+ .' '.__( 'You could block legitimate visitors who load too many pages in quick succession on your site.', 'wp-simple-firewall' )
56
  ];
57
  break;
58
 
src/lib/src/Modules/UserManagement/Lib/Password/UserPasswordHandler.php CHANGED
@@ -134,14 +134,14 @@ class UserPasswordHandler extends ExecOnceModConsumer {
134
  if ( empty( $aExistingCodes ) ) {
135
  $password = $this->getLoginPassword();
136
  if ( !empty( $password ) ) {
137
- $aFailureMsg = '';
138
  try {
139
  $this->applyPasswordChecks( $password );
140
  $bChecksPassed = true;
141
  }
142
  catch ( \Exception $e ) {
143
  $bChecksPassed = ( $e->getCode() === 999 );
144
- $aFailureMsg = $e->getMessage();
145
  }
146
 
147
  if ( $bChecksPassed ) {
@@ -151,8 +151,8 @@ class UserPasswordHandler extends ExecOnceModConsumer {
151
  }
152
  else {
153
  $msg = __( 'Your security administrator has imposed requirements for password quality.', 'wp-simple-firewall' );
154
- if ( !empty( $aFailureMsg ) ) {
155
- $msg .= '<br/>'.sprintf( __( 'Reason', 'wp-simple-firewall' ).': '.$aFailureMsg );
156
  }
157
  $wpErrors->add( 'shield_password_policy', $msg );
158
  $this->getCon()->fireEvent( 'password_policy_block' );
134
  if ( empty( $aExistingCodes ) ) {
135
  $password = $this->getLoginPassword();
136
  if ( !empty( $password ) ) {
137
+ $failureMsg = '';
138
  try {
139
  $this->applyPasswordChecks( $password );
140
  $bChecksPassed = true;
141
  }
142
  catch ( \Exception $e ) {
143
  $bChecksPassed = ( $e->getCode() === 999 );
144
+ $failureMsg = $e->getMessage();
145
  }
146
 
147
  if ( $bChecksPassed ) {
151
  }
152
  else {
153
  $msg = __( 'Your security administrator has imposed requirements for password quality.', 'wp-simple-firewall' );
154
+ if ( !empty( $failureMsg ) ) {
155
+ $msg .= '<br/>'.__( 'Reason', 'wp-simple-firewall' ).': '.$failureMsg;
156
  }
157
  $wpErrors->add( 'shield_password_policy', $msg );
158
  $this->getCon()->fireEvent( 'password_policy_block' );
src/lib/src/Modules/UserManagement/Lib/Suspend/Base.php CHANGED
@@ -12,7 +12,7 @@ abstract class Base {
12
  const HOOK_PRIORITY = 1000; // so only authenticated user is notified of account state.
13
 
14
  public function run() {
15
- add_filter( 'authenticate', [ $this, 'checkUser' ], static::HOOK_PRIORITY, 1 );
16
  }
17
 
18
  /**
12
  const HOOK_PRIORITY = 1000; // so only authenticated user is notified of account state.
13
 
14
  public function run() {
15
+ add_filter( 'authenticate', [ $this, 'checkUser' ], static::HOOK_PRIORITY );
16
  }
17
 
18
  /**
src/lib/src/Modules/UserManagement/Suspend/Base.php CHANGED
@@ -12,7 +12,7 @@ abstract class Base {
12
  const HOOK_PRIORITY = 1000; // so only authenticated user is notified of account state.
13
 
14
  public function run() {
15
- add_filter( 'authenticate', [ $this, 'checkUser' ], static::HOOK_PRIORITY, 1 );
16
  }
17
 
18
  /**
12
  const HOOK_PRIORITY = 1000; // so only authenticated user is notified of account state.
13
 
14
  public function run() {
15
+ add_filter( 'authenticate', [ $this, 'checkUser' ], static::HOOK_PRIORITY );
16
  }
17
 
18
  /**
src/lib/src/Scans/Apc/ConvertVosToResults.php CHANGED
@@ -11,22 +11,22 @@ use FernleafSystems\Wordpress\Plugin\Shield;
11
  class ConvertVosToResults extends Shield\Scans\Base\BaseConvertVosToResults {
12
 
13
  /**
14
- * @param Shield\Databases\Scanner\EntryVO[] $oVos
15
  * @return ResultsSet
16
  */
17
- public function convert( $oVos ) {
18
  $oRes = new ResultsSet();
19
- foreach ( $oVos as $oVo ) {
20
  $oRes->addItem( $this->convertItem( $oVo ) );
21
  }
22
  return $oRes;
23
  }
24
 
25
  /**
26
- * @param Shield\Databases\Scanner\EntryVO $oVo
27
  * @return ResultItem
28
  */
29
- public function convertItem( $oVo ) {
30
- return ( new ResultItem() )->applyFromArray( $oVo->meta );
31
  }
32
  }
11
  class ConvertVosToResults extends Shield\Scans\Base\BaseConvertVosToResults {
12
 
13
  /**
14
+ * @param Shield\Databases\Scanner\EntryVO[] $VOs
15
  * @return ResultsSet
16
  */
17
+ public function convert( $VOs ) {
18
  $oRes = new ResultsSet();
19
+ foreach ( $VOs as $oVo ) {
20
  $oRes->addItem( $this->convertItem( $oVo ) );
21
  }
22
  return $oRes;
23
  }
24
 
25
  /**
26
+ * @param Shield\Databases\Scanner\EntryVO $VO
27
  * @return ResultItem
28
  */
29
+ public function convertItem( $VO ) {
30
+ return ( new ResultItem() )->applyFromArray( $VO->meta );
31
  }
32
  }
src/lib/src/Scans/Apc/PluginScanner.php CHANGED
@@ -3,7 +3,6 @@
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Apc;
4
 
5
  use FernleafSystems\Wordpress\Plugin\Shield;
6
- use FernleafSystems\Wordpress\Services\Core\VOs\WpPluginVo;
7
  use FernleafSystems\Wordpress\Services\Services;
8
 
9
  /**
@@ -15,23 +14,23 @@ class PluginScanner {
15
  use Shield\Scans\Common\ScanActionConsumer;
16
 
17
  /**
18
- * @param string $sPluginFile
19
  * @return ResultItem|null
20
  */
21
- public function scan( $sPluginFile ) {
22
  $oResultItem = null;
23
 
24
  /** @var ScanActionVO $oAction */
25
  $oAction = $this->getScanActionVO();
26
 
27
- $oPlgn = Services::WpPlugins()->getPluginAsVo( $sPluginFile );
28
- if ( $oPlgn instanceof WpPluginVo && $oPlgn->isWpOrg() ) {
29
- $nLastUpdatedAt = $this->getLastUpdateTime( $sPluginFile );
30
  if ( $nLastUpdatedAt > 0
31
  && ( Services::Request()->ts() - $nLastUpdatedAt > $oAction->abandoned_limit ) ) {
32
 
33
  $oResultItem = new ResultItem();
34
- $oResultItem->slug = $sPluginFile;
35
  $oResultItem->context = 'plugins';
36
  $oResultItem->last_updated_at = $nLastUpdatedAt;
37
  }
@@ -41,25 +40,25 @@ class PluginScanner {
41
  }
42
 
43
  /**
44
- * @param string $sFile
45
  * @return bool
46
  */
47
- private function getLastUpdateTime( $sFile ) {
48
- $sSlug = Services::WpPlugins()->getSlug( $sFile );
49
- if ( empty( $sSlug ) ) {
50
- $sSlug = dirname( $sFile );
51
  }
52
 
53
  if ( !function_exists( 'plugins_api' ) ) {
54
  require_once ABSPATH.'/wp-admin/includes/plugin-install.php';
55
  }
56
- $oApi = plugins_api( 'plugin_information', [
57
- 'slug' => $sSlug,
58
  'fields' => [
59
  'sections' => false,
60
  ],
61
  ] );
62
 
63
- return isset( $oApi->last_updated ) ? strtotime( $oApi->last_updated ) : -1;
64
  }
65
  }
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Apc;
4
 
5
  use FernleafSystems\Wordpress\Plugin\Shield;
 
6
  use FernleafSystems\Wordpress\Services\Services;
7
 
8
  /**
14
  use Shield\Scans\Common\ScanActionConsumer;
15
 
16
  /**
17
+ * @param string $pluginFile
18
  * @return ResultItem|null
19
  */
20
+ public function scan( $pluginFile ) {
21
  $oResultItem = null;
22
 
23
  /** @var ScanActionVO $oAction */
24
  $oAction = $this->getScanActionVO();
25
 
26
+ $plugin = Services::WpPlugins()->getPluginAsVo( $pluginFile );
27
+ if ( $plugin->asset_type === 'plugin' && $plugin->isWpOrg() ) {
28
+ $nLastUpdatedAt = $this->getLastUpdateTime( $pluginFile );
29
  if ( $nLastUpdatedAt > 0
30
  && ( Services::Request()->ts() - $nLastUpdatedAt > $oAction->abandoned_limit ) ) {
31
 
32
  $oResultItem = new ResultItem();
33
+ $oResultItem->slug = $pluginFile;
34
  $oResultItem->context = 'plugins';
35
  $oResultItem->last_updated_at = $nLastUpdatedAt;
36
  }
40
  }
41
 
42
  /**
43
+ * @param string $file
44
  * @return bool
45
  */
46
+ private function getLastUpdateTime( $file ) {
47
+ $slug = Services::WpPlugins()->getSlug( $file );
48
+ if ( empty( $slug ) ) {
49
+ $slug = dirname( $file );
50
  }
51
 
52
  if ( !function_exists( 'plugins_api' ) ) {
53
  require_once ABSPATH.'/wp-admin/includes/plugin-install.php';
54
  }
55
+ $api = plugins_api( 'plugin_information', [
56
+ 'slug' => $slug,
57
  'fields' => [
58
  'sections' => false,
59
  ],
60
  ] );
61
 
62
+ return isset( $api->last_updated ) ? strtotime( $api->last_updated ) : -1;
63
  }
64
  }
src/lib/src/Scans/Apc/ResultsSet.php CHANGED
@@ -6,7 +6,7 @@ use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base;
6
 
7
  /**
8
  * Class ResultsSet
9
- * @property ResultItem[] $aItems
10
  * @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Apc
11
  */
12
  class ResultsSet extends Base\BaseResultsSet {
6
 
7
  /**
8
  * Class ResultsSet
9
+ * @property ResultItem[] $items
10
  * @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Apc
11
  */
12
  class ResultsSet extends Base\BaseResultsSet {
src/lib/src/Scans/Apc/Utilities/ItemActionHandler.php CHANGED
@@ -14,8 +14,8 @@ class ItemActionHandler extends Base\Utilities\ItemActionHandler {
14
  }
15
 
16
  /**
17
- * @param bool $bSuccess
18
  */
19
- protected function fireRepairEvent( $bSuccess ) {
20
  }
21
  }
14
  }
15
 
16
  /**
17
+ * @param bool $success
18
  */
19
+ protected function fireRepairEvent( $success ) {
20
  }
21
  }
src/lib/src/Scans/Base/BaseConvertVosToResults.php CHANGED
@@ -11,20 +11,20 @@ use FernleafSystems\Wordpress\Plugin\Shield\Databases\Scanner\EntryVO;
11
  abstract class BaseConvertVosToResults {
12
 
13
  /**
14
- * @param EntryVO[] $oVos
15
  * @return BaseResultsSet
16
  */
17
- public function convert( $oVos ) {
18
  $oRes = new BaseResultsSet();
19
- foreach ( $oVos as $oVo ) {
20
  $oRes->addItem( $this->convertItem( $oVo ) );
21
  }
22
  return $oRes;
23
  }
24
 
25
  /**
26
- * @param EntryVO $oVo
27
  * @return BaseResultItem
28
  */
29
- abstract public function convertItem( $oVo );
30
  }
11
  abstract class BaseConvertVosToResults {
12
 
13
  /**
14
+ * @param EntryVO[] $VOs
15
  * @return BaseResultsSet
16
  */
17
+ public function convert( $VOs ) {
18
  $oRes = new BaseResultsSet();
19
+ foreach ( $VOs as $oVo ) {
20
  $oRes->addItem( $this->convertItem( $oVo ) );
21
  }
22
  return $oRes;
23
  }
24
 
25
  /**
26
+ * @param EntryVO $VO
27
  * @return BaseResultItem
28
  */
29
+ abstract public function convertItem( $VO );
30
  }
src/lib/src/Scans/Base/BaseResultsSet.php CHANGED
@@ -11,7 +11,7 @@ class BaseResultsSet {
11
  /**
12
  * @var BaseResultItem[]
13
  */
14
- protected $aItems;
15
 
16
  /**
17
  * @var bool
@@ -28,45 +28,45 @@ class BaseResultsSet {
28
  $oItem->hash = $oItem->generateHash();
29
  }
30
  $aI[ $oItem->hash ] = $oItem;
31
- $this->aItems = $aI;
32
  return $this;
33
  }
34
 
35
  /**
36
- * @param string $sHash
37
  * @return BaseResultItem|null
38
  */
39
- public function getItemByHash( $sHash ) {
40
- return $this->getItemExists( $sHash ) ? $this->getAllItems()[ $sHash ] : null;
41
  }
42
 
43
  /**
44
- * @param string $sHash
45
  * @return bool
46
  */
47
- public function getItemExists( $sHash ) {
48
- return isset( $this->getAllItems()[ $sHash ] );
49
  }
50
 
51
  /**
52
  * Ignores the "is_excluded" property on the items
53
  * @return BaseResultItem[]
54
  */
55
- public function getAllItems() {
56
- if ( !is_array( $this->aItems ) ) {
57
- $this->aItems = [];
58
  }
59
- return $this->aItems;
60
  }
61
 
62
  /**
63
  * @return BaseResultItem[]
64
  */
65
- public function getExcludedItems() {
66
  return array_values( array_filter(
67
  $this->getAllItems(),
68
- function ( $oItem ) {
69
- return $oItem->is_excluded;
70
  }
71
  ) );
72
  }
@@ -75,26 +75,20 @@ class BaseResultsSet {
75
  * Honours the exclusion flags
76
  * @return BaseResultItem[]
77
  */
78
- public function getItems() {
79
  return array_values( array_filter(
80
  $this->getAllItems(),
81
- function ( $oItem ) {
82
- return !$this->isFilterExcludedItems() || !$oItem->is_excluded;
83
  }
84
  ) );
85
  }
86
 
87
- /**
88
- * @return int
89
- */
90
- public function countItems() {
91
  return count( $this->getItems() );
92
  }
93
 
94
- /**
95
- * @return bool
96
- */
97
- public function hasItems() {
98
  return $this->countItems() > 0;
99
  }
100
 
@@ -106,22 +100,22 @@ class BaseResultsSet {
106
  }
107
 
108
  /**
109
- * @param BaseResultItem $oItem
110
  * @return $this
111
  */
112
- public function removeItem( $oItem ) {
113
- return $this->removeItemByHash( $oItem->hash );
114
  }
115
 
116
  /**
117
- * @param string $sHash
118
  * @return $this
119
  */
120
- public function removeItemByHash( $sHash ) {
121
- if ( $this->getItemExists( $sHash ) ) {
122
- $aItems = $this->getAllItems();
123
- unset( $aItems[ $sHash ] );
124
- $this->aItems = $aItems;
125
  }
126
  return $this;
127
  }
11
  /**
12
  * @var BaseResultItem[]
13
  */
14
+ protected $items;
15
 
16
  /**
17
  * @var bool
28
  $oItem->hash = $oItem->generateHash();
29
  }
30
  $aI[ $oItem->hash ] = $oItem;
31
+ $this->items = $aI;
32
  return $this;
33
  }
34
 
35
  /**
36
+ * @param string $hash
37
  * @return BaseResultItem|null
38
  */
39
+ public function getItemByHash( $hash ) {
40
+ return $this->getItemExists( $hash ) ? $this->getAllItems()[ $hash ] : null;
41
  }
42
 
43
  /**
44
+ * @param string $hash
45
  * @return bool
46
  */
47
+ public function getItemExists( $hash ) {
48
+ return isset( $this->getAllItems()[ $hash ] );
49
  }
50
 
51
  /**
52
  * Ignores the "is_excluded" property on the items
53
  * @return BaseResultItem[]
54
  */
55
+ public function getAllItems() :array {
56
+ if ( !is_array( $this->items ) ) {
57
+ $this->items = [];
58
  }
59
+ return $this->items;
60
  }
61
 
62
  /**
63
  * @return BaseResultItem[]
64
  */
65
+ public function getExcludedItems() :array {
66
  return array_values( array_filter(
67
  $this->getAllItems(),
68
+ function ( $item ) {
69
+ return $item->is_excluded;
70
  }
71
  ) );
72
  }
75
  * Honours the exclusion flags
76
  * @return BaseResultItem[]
77
  */
78
+ public function getItems() :array {
79
  return array_values( array_filter(
80
  $this->getAllItems(),
81
+ function ( $item ) {
82
+ return !$this->isFilterExcludedItems() || !$item->is_excluded;
83
  }
84
  ) );
85
  }
86
 
87
+ public function countItems() :int {
 
 
 
88
  return count( $this->getItems() );
89
  }
90
 
91
+ public function hasItems() :bool {
 
 
 
92
  return $this->countItems() > 0;
93
  }
94
 
100
  }
101
 
102
  /**
103
+ * @param BaseResultItem $item
104
  * @return $this
105
  */
106
+ public function removeItem( $item ) {
107
+ return $this->removeItemByHash( $item->hash );
108
  }
109
 
110
  /**
111
+ * @param string $hash
112
  * @return $this
113
  */
114
+ public function removeItemByHash( $hash ) {
115
+ if ( $this->getItemExists( $hash ) ) {
116
+ $items = $this->getAllItems();
117
+ unset( $items[ $hash ] );
118
+ $this->items = $items;
119
  }
120
  return $this;
121
  }
src/lib/src/Scans/Base/DiffResultForStorage.php CHANGED
@@ -19,25 +19,25 @@ class DiffResultForStorage {
19
  */
20
  public function diff( $oExistingRes, $oNewResults ) {
21
 
22
- $oToDelete = new ResultsSet();
23
- $oMerger = new Scans\Base\BaseMergeItems();
24
 
25
  // 1 Remove items in EXISTING that are not in NEW
26
  foreach ( $oExistingRes->getAllItems() as $oExistItem ) {
27
  if ( !$oNewResults->getItemExists( $oExistItem->hash ) ) {
28
  $oExistingRes->removeItemByHash( $oExistItem->hash );
29
- $oToDelete->addItem( $oExistItem );
30
  }
31
  }
32
 
33
  // 2 Merge NEW items into Existing items
34
  foreach ( $oNewResults->getAllItems() as $oNewItem ) {
35
  if ( $oExistingRes->getItemExists( $oNewItem->hash ) ) {
36
- $oMerger->mergeItemTo( $oExistingRes->getItemByHash( $oNewItem->hash ), $oNewItem );
37
  $oNewResults->removeItemByHash( $oNewItem->hash );
38
  }
39
  }
40
 
41
- return $oToDelete;
42
  }
43
  }
19
  */
20
  public function diff( $oExistingRes, $oNewResults ) {
21
 
22
+ $toDelete = new ResultsSet();
23
+ $merger = new Scans\Base\BaseMergeItems();
24
 
25
  // 1 Remove items in EXISTING that are not in NEW
26
  foreach ( $oExistingRes->getAllItems() as $oExistItem ) {
27
  if ( !$oNewResults->getItemExists( $oExistItem->hash ) ) {
28
  $oExistingRes->removeItemByHash( $oExistItem->hash );
29
+ $toDelete->addItem( $oExistItem );
30
  }
31
  }
32
 
33
  // 2 Merge NEW items into Existing items
34
  foreach ( $oNewResults->getAllItems() as $oNewItem ) {
35
  if ( $oExistingRes->getItemExists( $oNewItem->hash ) ) {
36
+ $merger->mergeItemTo( $oExistingRes->getItemByHash( $oNewItem->hash ), $oNewItem );
37
  $oNewResults->removeItemByHash( $oNewItem->hash );
38
  }
39
  }
40
 
41
+ return $toDelete;
42
  }
43
  }
src/lib/src/Scans/Base/Utilities/ItemActionHandler.php CHANGED
@@ -73,33 +73,33 @@ abstract class ItemActionHandler {
73
  }
74
 
75
  /**
76
- * @param bool $bAllowDelete
77
  * @return bool
78
  * @throws \Exception
79
  */
80
- public function repair( $bAllowDelete = false ) {
81
- $oRep = $this->getRepairer();
82
- if ( !$oRep->canRepair() ) {
83
  throw new \Exception( 'This item cannot be automatically repaired.' );
84
  }
85
 
86
- $oRep->setAllowDelete( $bAllowDelete );
87
 
88
- $oItem = $this->getScanItem();
89
- $oItem->repaired = $oRep->repairItem();
90
- $this->fireRepairEvent( $oItem->repaired );
91
 
92
- if ( $oItem->repaired ) {
93
  /** @var HackGuard\ModCon $mod */
94
  $mod = $this->getMod();
95
- /** @var Scanner\Delete $oDel */
96
- $oDel = $mod->getDbHandler_ScanResults()->getQueryDeleter();
97
- $oDel->filterByHash( $oItem->hash )
98
- ->filterByScan( $oItem->scan )
99
- ->query();
100
  }
101
 
102
- return $oItem->repaired;
103
  }
104
 
105
  /**
@@ -108,11 +108,11 @@ abstract class ItemActionHandler {
108
  protected function getEntryVO() {
109
  /** @var HackGuard\ModCon $mod */
110
  $mod = $this->getMod();
111
- /** @var Scanner\Select $oSel */
112
- $oSel = $mod->getDbHandler_ScanResults()->getQuerySelector();
113
- return $oSel->filterByHash( $this->getScanItem()->hash )
114
- ->filterByScan( $this->getScanController()->getSlug() )
115
- ->first();
116
  }
117
 
118
  /**
@@ -121,7 +121,7 @@ abstract class ItemActionHandler {
121
  abstract public function getRepairer();
122
 
123
  /**
124
- * @param bool $bSuccess
125
  */
126
- abstract protected function fireRepairEvent( $bSuccess );
127
- }
73
  }
74
 
75
  /**
76
+ * @param bool $allowDelete
77
  * @return bool
78
  * @throws \Exception
79
  */
80
+ public function repair( bool $allowDelete = false ) {
81
+ $repairer = $this->getRepairer();
82
+ if ( !$repairer->canRepair() ) {
83
  throw new \Exception( 'This item cannot be automatically repaired.' );
84
  }
85
 
86
+ $repairer->setAllowDelete( $allowDelete );
87
 
88
+ $item = $this->getScanItem();
89
+ $item->repaired = $repairer->repairItem();
90
+ $this->fireRepairEvent( $item->repaired );
91
 
92
+ if ( $item->repaired ) {
93
  /** @var HackGuard\ModCon $mod */
94
  $mod = $this->getMod();
95
+ /** @var Scanner\Delete $deleter */
96
+ $deleter = $mod->getDbHandler_ScanResults()->getQueryDeleter();
97
+ $deleter->filterByHash( $item->hash )
98
+ ->filterByScan( $item->scan )
99
+ ->query();
100
  }
101
 
102
+ return $item->repaired;
103
  }
104
 
105
  /**
108
  protected function getEntryVO() {
109
  /** @var HackGuard\ModCon $mod */
110
  $mod = $this->getMod();
111
+ /** @var Scanner\Select $selector */
112
+ $selector = $mod->getDbHandler_ScanResults()->getQuerySelector();
113
+ return $selector->filterByHash( $this->getScanItem()->hash )
114
+ ->filterByScan( $this->getScanController()->getSlug() )
115
+ ->first();
116
  }
117
 
118
  /**
121
  abstract public function getRepairer();
122
 
123
  /**
124
+ * @param bool $success
125
  */
126
+ abstract protected function fireRepairEvent( $success );
127
+ }
src/lib/src/Scans/Base/Utilities/ItemActionHandlerAssets.php CHANGED
@@ -4,7 +4,10 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\Utilities;
4
 
5
  use FernleafSystems\Wordpress\Plugin\Shield\Scans\Ptg;
6
  use FernleafSystems\Wordpress\Plugin\Shield\Scans\Wpv;
7
- use FernleafSystems\Wordpress\Services\Core\VOs;
 
 
 
8
  use FernleafSystems\Wordpress\Services\Services;
9
 
10
  abstract class ItemActionHandlerAssets extends ItemActionHandler {
@@ -43,20 +46,20 @@ abstract class ItemActionHandlerAssets extends ItemActionHandler {
43
  }
44
 
45
  /**
46
- * @param string $sSlug
47
- * @return VOs\WpPluginVo|VOs\WpThemeVo|null
48
  * @throws \Exception
49
  */
50
- protected function getAssetFromSlug( $sSlug ) {
51
- if ( Services::WpPlugins()->isInstalled( $sSlug ) ) {
52
- $oAsset = Services::WpPlugins()->getPluginAsVo( $sSlug );
53
  }
54
- elseif ( Services::WpThemes()->isInstalled( $sSlug ) ) {
55
- $oAsset = Services::WpThemes()->getThemeAsVo( $sSlug );
56
  }
57
  else {
58
  throw new \Exception( 'Items is not currently installed.' );
59
  }
60
- return $oAsset;
61
  }
62
  }
4
 
5
  use FernleafSystems\Wordpress\Plugin\Shield\Scans\Ptg;
6
  use FernleafSystems\Wordpress\Plugin\Shield\Scans\Wpv;
7
+ use FernleafSystems\Wordpress\Services\Core\VOs\Assets\{
8
+ WpPluginVo,
9
+ WpThemeVo
10
+ };
11
  use FernleafSystems\Wordpress\Services\Services;
12
 
13
  abstract class ItemActionHandlerAssets extends ItemActionHandler {
46
  }
47
 
48
  /**
49
+ * @param string $slug
50
+ * @return WpPluginVo|WpThemeVo|null
51
  * @throws \Exception
52
  */
53
+ protected function getAssetFromSlug( $slug ) {
54
+ if ( Services::WpPlugins()->isInstalled( $slug ) ) {
55
+ $asset = Services::WpPlugins()->getPluginAsVo( $slug );
56
  }
57
+ elseif ( Services::WpThemes()->isInstalled( $slug ) ) {
58
+ $asset = Services::WpThemes()->getThemeAsVo( $slug );
59
  }
60
  else {
61
  throw new \Exception( 'Items is not currently installed.' );
62
  }
63
+ return $asset;
64
  }
65
  }
src/lib/src/Scans/Mal/FileScanner.php CHANGED
@@ -4,8 +4,10 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Mal;
4
 
5
  use FernleafSystems\Wordpress\Plugin\Shield;
6
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib;
7
- use FernleafSystems\Wordpress\Services\Core\VOs\WpPluginVo;
8
- use FernleafSystems\Wordpress\Services\Core\VOs\WpThemeVo;
 
 
9
  use FernleafSystems\Wordpress\Services\Services;
10
  use FernleafSystems\Wordpress\Services\Utilities;
11
 
@@ -144,35 +146,28 @@ class FileScanner extends Shield\Scans\Base\Files\BaseFileScanner {
144
  * @return ResultItem
145
  */
146
  private function getResultItemFromLines( array $lines, string $fullPath, string $signature ) :ResultItem {
147
- $oResultItem = new ResultItem();
148
- $oResultItem->path_full = wp_normalize_path( $fullPath );
149
- $oResultItem->path_fragment = str_replace( wp_normalize_path( ABSPATH ), '', $oResultItem->path_full );
150
- $oResultItem->is_mal = true;
151
- $oResultItem->mal_sig = base64_encode( $signature );
152
- $oResultItem->fp_confidence = 0;
153
- $oResultItem->file_lines = $lines;
154
- return $oResultItem;
155
  }
156
 
157
- /**
158
- * @param string $fullPath - normalized
159
- * @return bool
160
- */
161
  private function canExcludeFile( string $fullPath ) :bool {
162
  return $this->isValidCoreFile( $fullPath )
163
- || $this->isPluginFileValid( $fullPath ) || $this->isThemeFileValid( $fullPath );
 
164
  }
165
 
166
- /**
167
- * @param string $fullPath - normalized
168
- * @return bool
169
- */
170
  private function isPluginFileValid( string $fullPath ) :bool {
171
  $valid = false;
172
  try {
173
  $oPluginFiles = new Utilities\WpOrg\Plugin\Files();
174
  $plugin = $oPluginFiles->findPluginFromFile( $fullPath );
175
- if ( $plugin instanceof WpPluginVo ) {
176
  $valid = $plugin->isWpOrg() ?
177
  $oPluginFiles->verifyFileContents( $fullPath )
178
  : $this->verifyPremiumAssetFile( $fullPath, $plugin );
@@ -184,16 +179,12 @@ class FileScanner extends Shield\Scans\Base\Files\BaseFileScanner {
184
  return $valid;
185
  }
186
 
187
- /**
188
- * @param string $fullPath - normalized
189
- * @return bool
190
- */
191
  private function isThemeFileValid( string $fullPath ) :bool {
192
  $valid = false;
193
  try {
194
  $oThemeFiles = new Utilities\WpOrg\Theme\Files();
195
  $theme = $oThemeFiles->findThemeFromFile( $fullPath );
196
- if ( $theme instanceof WpThemeVo ) {
197
  $valid = $theme->isWpOrg() ?
198
  $oThemeFiles->verifyFileContents( $fullPath )
199
  : $this->verifyPremiumAssetFile( $fullPath, $theme );
@@ -211,7 +202,7 @@ class FileScanner extends Shield\Scans\Base\Files\BaseFileScanner {
211
  * @return bool
212
  * @throws \Exception
213
  */
214
- private function verifyPremiumAssetFile( $fullPath, $oPluginOrTheme ) :bool {
215
  $valid = false;
216
  $hashes = ( new Lib\Snapshots\Build\BuildHashesFromApi() )
217
  ->build( $oPluginOrTheme );
@@ -223,11 +214,7 @@ class FileScanner extends Shield\Scans\Base\Files\BaseFileScanner {
223
  return $valid;
224
  }
225
 
226
- /**
227
- * @param string $fullPath
228
- * @return bool
229
- */
230
- private function isValidCoreFile( $fullPath ) :bool {
231
  $hash = Services::CoreFileHashes()->getFileHash( $fullPath );
232
  try {
233
  $valid = !empty( $hash )
4
 
5
  use FernleafSystems\Wordpress\Plugin\Shield;
6
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib;
7
+ use FernleafSystems\Wordpress\Services\Core\VOs\Assets\{
8
+ WpPluginVo,
9
+ WpThemeVo
10
+ };
11
  use FernleafSystems\Wordpress\Services\Services;
12
  use FernleafSystems\Wordpress\Services\Utilities;
13
 
146
  * @return ResultItem
147
  */
148
  private function getResultItemFromLines( array $lines, string $fullPath, string $signature ) :ResultItem {
149
+ $item = new ResultItem();
150
+ $item->path_full = wp_normalize_path( $fullPath );
151
+ $item->path_fragment = str_replace( wp_normalize_path( ABSPATH ), '', $item->path_full );
152
+ $item->is_mal = true;
153
+ $item->mal_sig = base64_encode( $signature );
154
+ $item->fp_confidence = 0;
155
+ $item->file_lines = $lines;
156
+ return $item;
157
  }
158
 
 
 
 
 
159
  private function canExcludeFile( string $fullPath ) :bool {
160
  return $this->isValidCoreFile( $fullPath )
161
+ || $this->isPluginFileValid( $fullPath )
162
+ || $this->isThemeFileValid( $fullPath );
163
  }
164
 
 
 
 
 
165
  private function isPluginFileValid( string $fullPath ) :bool {
166
  $valid = false;
167
  try {
168
  $oPluginFiles = new Utilities\WpOrg\Plugin\Files();
169
  $plugin = $oPluginFiles->findPluginFromFile( $fullPath );
170
+ if ( !empty( $plugin ) && $plugin->asset_type === 'plugin' ) {
171
  $valid = $plugin->isWpOrg() ?
172
  $oPluginFiles->verifyFileContents( $fullPath )
173
  : $this->verifyPremiumAssetFile( $fullPath, $plugin );
179
  return $valid;
180
  }
181
 
 
 
 
 
182
  private function isThemeFileValid( string $fullPath ) :bool {
183
  $valid = false;
184
  try {
185
  $oThemeFiles = new Utilities\WpOrg\Theme\Files();
186
  $theme = $oThemeFiles->findThemeFromFile( $fullPath );
187
+ if ( !empty( $theme ) && $theme->asset_type === 'theme' ) {
188
  $valid = $theme->isWpOrg() ?
189
  $oThemeFiles->verifyFileContents( $fullPath )
190
  : $this->verifyPremiumAssetFile( $fullPath, $theme );
202
  * @return bool
203
  * @throws \Exception
204
  */
205
+ private function verifyPremiumAssetFile( string $fullPath, $oPluginOrTheme ) :bool {
206
  $valid = false;
207
  $hashes = ( new Lib\Snapshots\Build\BuildHashesFromApi() )
208
  ->build( $oPluginOrTheme );
214
  return $valid;
215
  }
216
 
217
+ private function isValidCoreFile( string $fullPath ) :bool {
 
 
 
 
218
  $hash = Services::CoreFileHashes()->getFileHash( $fullPath );
219
  try {
220
  $valid = !empty( $hash )
src/lib/src/Scans/Mal/ResultsSet.php CHANGED
@@ -6,7 +6,7 @@ use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base;
6
 
7
  /**
8
  * Class ResultsSet
9
- * @property ResultItem[] $aItems
10
  * @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Mal
11
  */
12
  class ResultsSet extends Base\BaseResultsSet {
6
 
7
  /**
8
  * Class ResultsSet
9
+ * @property ResultItem[] $items
10
  * @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Mal
11
  */
12
  class ResultsSet extends Base\BaseResultsSet {
src/lib/src/Scans/Mal/Table/EntryFormatter.php CHANGED
@@ -24,7 +24,7 @@ class EntryFormatter extends BaseFileEntryFormatter {
24
  /** @var Mal\ResultItem $item */
25
  $item = $this->getResultItem();
26
 
27
- $expl = [
28
  sprintf( '%s: %s', __( 'Pattern Detected' ), $this->getPatternForDisplay( base64_decode( $item->mal_sig ) ) ),
29
  sprintf( '%s: %s', __( 'Affected line numbers' ),
30
  implode( ', ', array_map(
@@ -39,37 +39,22 @@ class EntryFormatter extends BaseFileEntryFormatter {
39
  /** @var HackGuard\Options $opts */
40
  $opts = $this->getOptions();
41
  if ( $opts->isMalUseNetworkIntelligence() ) {
42
- $expl[] = sprintf( '%s: %s/100 [%s]',
43
  __( 'Likelihood That This Is A False Positive' ),
44
  sprintf( '<strong>%s</strong>', (int)$item->fp_confidence ),
45
  sprintf( '<a href="%s" target="_blank">%s</a>', 'https://shsec.io/isthismalware', __( 'more info', 'wp-simple-firewall' ) )
46
  );
47
  }
48
 
49
- return $expl;
50
  }
51
 
52
  /**
53
- * @param string $sText
54
  * @return string
55
  */
56
- private function getPatternForDisplay( $sText ) {
57
- if ( false && function_exists( 'imagecreate' ) ) {
58
- $oImg = imagecreate( 400, 20 );
59
- imagecolorallocate( $oImg, 255, 255, 255 );
60
- $oTxtColour = imagecolorallocate( $oImg, 25, 25, 25 );
61
- imagestring( $oImg, 5, 1, 1, $sText, $oTxtColour );
62
- ob_start();
63
- imagepng( $oImg );
64
- $sImg = ob_get_clean();
65
- imagedestroy( $oImg );
66
- $sPattern = sprintf( '<img src="data:image/png;base64,%s" alt="Pattern" />', base64_encode( $sImg ) );
67
- }
68
- else {
69
- $sPattern = sprintf( '<code style="white-space: nowrap">%s</code>', esc_html( $sText ) );
70
- }
71
-
72
- return $sPattern;
73
  }
74
 
75
  /**
24
  /** @var Mal\ResultItem $item */
25
  $item = $this->getResultItem();
26
 
27
+ $exp = [
28
  sprintf( '%s: %s', __( 'Pattern Detected' ), $this->getPatternForDisplay( base64_decode( $item->mal_sig ) ) ),
29
  sprintf( '%s: %s', __( 'Affected line numbers' ),
30
  implode( ', ', array_map(
39
  /** @var HackGuard\Options $opts */
40
  $opts = $this->getOptions();
41
  if ( $opts->isMalUseNetworkIntelligence() ) {
42
+ $exp[] = sprintf( '%s: %s/100 [%s]',
43
  __( 'Likelihood That This Is A False Positive' ),
44
  sprintf( '<strong>%s</strong>', (int)$item->fp_confidence ),
45
  sprintf( '<a href="%s" target="_blank">%s</a>', 'https://shsec.io/isthismalware', __( 'more info', 'wp-simple-firewall' ) )
46
  );
47
  }
48
 
49
+ return $exp;
50
  }
51
 
52
  /**
53
+ * @param string $text
54
  * @return string
55
  */
56
+ private function getPatternForDisplay( $text ) :string {
57
+ return sprintf( '<code style="white-space: nowrap">%s</code>', esc_html( $text ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
  }
59
 
60
  /**
src/lib/src/Scans/Mal/Utilities/ItemActionHandler.php CHANGED
@@ -31,13 +31,13 @@ class ItemActionHandler extends Base\Utilities\ItemActionHandler {
31
  }
32
 
33
  /**
34
- * @param bool $bSuccess
35
  */
36
- protected function fireRepairEvent( $bSuccess ) {
37
  /** @var Mal\ResultItem $oItem */
38
  $oItem = $this->getScanItem();
39
  $this->getCon()->fireEvent(
40
- $this->getScanController()->getSlug().'_item_repair_'.( $bSuccess ? 'success' : 'fail' ),
41
  [ 'audit' => [ 'fragment' => $oItem->path_full ] ]
42
  );
43
  }
31
  }
32
 
33
  /**
34
+ * @param bool $success
35
  */
36
+ protected function fireRepairEvent( $success ) {
37
  /** @var Mal\ResultItem $oItem */
38
  $oItem = $this->getScanItem();
39
  $this->getCon()->fireEvent(
40
+ $this->getScanController()->getSlug().'_item_repair_'.( $success ? 'success' : 'fail' ),
41
  [ 'audit' => [ 'fragment' => $oItem->path_full ] ]
42
  );
43
  }
src/lib/src/Scans/Mal/Utilities/Repair.php CHANGED
@@ -39,13 +39,13 @@ class Repair extends Shield\Scans\Base\Utilities\BaseRepair {
39
  }
40
  else {
41
  $plugin = ( new WpOrg\Plugin\Files() )->findPluginFromFile( $item->path_full );
42
- if ( $plugin instanceof Services\Core\VOs\WpPluginVo && $plugin->isWpOrg() ) {
43
 
44
  $success = $this->repairItemInPlugin( $item );
45
  }
46
  else {
47
  $theme = ( new WpOrg\Theme\Files() )->findThemeFromFile( $item->path_full );
48
- if ( $theme instanceof Services\Core\VOs\WpThemeVo && $theme->isWpOrg() ) {
49
 
50
  $success = $this->repairItemInTheme( $item );
51
  }
@@ -97,7 +97,7 @@ class Repair extends Shield\Scans\Base\Utilities\BaseRepair {
97
  if ( !$bCanRepair ) {
98
 
99
  $oPlugin = ( new WpOrg\Plugin\Files() )->findPluginFromFile( $oItem->path_full );
100
- if ( $oPlugin instanceof Services\Core\VOs\WpPluginVo ) {
101
  if ( !$oPlugin->isWpOrg() ) {
102
  throw new \Exception( sprintf(
103
  __( "%s not installed from WordPress.org.", 'wp-simple-firewall' ),
@@ -113,7 +113,7 @@ class Repair extends Shield\Scans\Base\Utilities\BaseRepair {
113
  }
114
  else {
115
  $oTheme = ( new WpOrg\Theme\Files() )->findThemeFromFile( $oItem->path_full );
116
- if ( $oTheme instanceof Services\Core\VOs\WpThemeVo ) {
117
  if ( $oTheme->is_child ) {
118
  throw new \Exception( sprintf(
119
  __( "%s is a child of another theme.", 'wp-simple-firewall' ),
39
  }
40
  else {
41
  $plugin = ( new WpOrg\Plugin\Files() )->findPluginFromFile( $item->path_full );
42
+ if ( $plugin instanceof Services\Core\VOs\Assets\WpPluginVo && $plugin->isWpOrg() ) {
43
 
44
  $success = $this->repairItemInPlugin( $item );
45
  }
46
  else {
47
  $theme = ( new WpOrg\Theme\Files() )->findThemeFromFile( $item->path_full );
48
+ if ( $theme instanceof Services\Core\VOs\Assets\WpThemeVo && $theme->isWpOrg() ) {
49
 
50
  $success = $this->repairItemInTheme( $item );
51
  }
97
  if ( !$bCanRepair ) {
98
 
99
  $oPlugin = ( new WpOrg\Plugin\Files() )->findPluginFromFile( $oItem->path_full );
100
+ if ( $oPlugin instanceof Services\Core\VOs\Assets\WpPluginVo ) {
101
  if ( !$oPlugin->isWpOrg() ) {
102
  throw new \Exception( sprintf(
103
  __( "%s not installed from WordPress.org.", 'wp-simple-firewall' ),
113
  }
114
  else {
115
  $oTheme = ( new WpOrg\Theme\Files() )->findThemeFromFile( $oItem->path_full );
116
+ if ( $oTheme instanceof Services\Core\VOs\Assets\WpThemeVo ) {
117
  if ( $oTheme->is_child ) {
118
  throw new \Exception( sprintf(
119
  __( "%s is a child of another theme.", 'wp-simple-firewall' ),
src/lib/src/Scans/Ptg/FileScanner.php CHANGED
@@ -4,8 +4,9 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Ptg;
4
 
5
  use FernleafSystems\Wordpress\Plugin\Shield;
6
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib;
7
- use FernleafSystems\Wordpress\Services\Core\VOs;
8
  use FernleafSystems\Wordpress\Services\Utilities\File\Compare\CompareHash;
 
9
  use FernleafSystems\Wordpress\Services\Utilities\WpOrg\Plugin;
10
  use FernleafSystems\Wordpress\Services\Utilities\WpOrg\Theme;
11
 
@@ -18,7 +19,7 @@ class FileScanner extends Shield\Scans\Base\Files\BaseFileScanner {
18
  /**
19
  * @var Lib\Snapshots\Store
20
  */
21
- private $oAssetStore;
22
 
23
  /**
24
  * @param string $fullPath - in this case it's relative to ABSPATH
@@ -37,76 +38,141 @@ class FileScanner extends Shield\Scans\Base\Files\BaseFileScanner {
37
  throw new \Exception( sprintf( 'Could not load asset for: %s', $fullPath ) );
38
  }
39
 
40
- $assetHashes = $this->getHashes( $asset );
41
- $pathFragment = str_replace( $asset->getInstallDir(), '', $fullPath );
42
- if ( empty( $assetHashes[ $pathFragment ] ) ) {
43
- $item = $this->getNewItem( $asset, $fullPath );
44
- $item->path_fragment = $pathFragment;
45
- $item->is_unrecognised = true;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
  }
47
- elseif ( !( new CompareHash() )->isEqualFileMd5( $fullPath, $assetHashes[ $pathFragment ] ) ) {
 
48
  $item = $this->getNewItem( $asset, $fullPath );
49
  $item->path_fragment = $pathFragment;
50
  $item->is_different = true;
51
  }
52
  }
53
- catch ( \Exception $e ) {
54
- error_log( $e->getMessage() );
55
- }
56
-
57
  return $item;
58
  }
59
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  /**
61
- * @param VOs\WpPluginVo|VOs\WpThemeVo $oAsset
62
  * @return string[]
63
  * @throws \Exception
64
  */
65
- private function getHashes( $oAsset ) {
66
- return $this->getStore( $oAsset )->getSnapData();
67
  }
68
 
69
  /**
70
- * @param VOs\WpPluginVo|VOs\WpThemeVo $oAsset
71
  * @return Lib\Snapshots\Store
72
  * @throws \Exception
73
  */
74
- private function getStore( $oAsset ) {
75
 
76
  // Re-Use the previous store if it's for the same Asset.
77
- if ( !empty( $this->oAssetStore ) ) {
78
- $sUniqueId = ( $oAsset instanceof VOs\WpPluginVo ) ? $oAsset->file : $oAsset->stylesheet;
79
- $aMeta = $this->oAssetStore->getSnapMeta();
80
- if ( $sUniqueId !== $aMeta[ 'unique_id' ] ) {
81
- unset( $this->oAssetStore );
82
  }
83
  }
84
 
85
- if ( empty( $this->oAssetStore ) ) {
86
- $this->oAssetStore = ( new Lib\Snapshots\StoreAction\Load() )
87
  ->setMod( $this->getMod() )
88
- ->setAsset( $oAsset )
89
  ->run();
90
  }
91
 
92
- return $this->oAssetStore;
93
  }
94
 
95
  /**
96
- * @param VOs\WpPluginVo|VOs\WpThemeVo $oAsset
97
- * @param string $sFile
98
  * @return ResultItem
99
  */
100
- private function getNewItem( $oAsset, $sFile ) {
101
- /** @var ResultItem $oItem */
102
- $oItem = $this->getScanActionVO()->getNewResultItem();
103
- $oItem->path_full = $sFile;
104
- $oItem->path_fragment = $sFile; // will eventually be overwritten
105
- $oItem->is_unrecognised = false;
106
- $oItem->is_different = false;
107
- $oItem->is_missing = false;
108
- $oItem->context = ( $oAsset instanceof VOs\WpPluginVo ) ? 'plugins' : 'themes';
109
- $oItem->slug = ( $oAsset instanceof VOs\WpPluginVo ) ? $oAsset->file : $oAsset->stylesheet;
110
- return $oItem;
111
  }
112
  }
4
 
5
  use FernleafSystems\Wordpress\Plugin\Shield;
6
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\HackGuard\Lib;
7
+ use FernleafSystems\Wordpress\Services\Core\VOs\Assets;
8
  use FernleafSystems\Wordpress\Services\Utilities\File\Compare\CompareHash;
9
+ use FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\CrowdSourcedHashes\Query;
10
  use FernleafSystems\Wordpress\Services\Utilities\WpOrg\Plugin;
11
  use FernleafSystems\Wordpress\Services\Utilities\WpOrg\Theme;
12
 
19
  /**
20
  * @var Lib\Snapshots\Store
21
  */
22
+ private $assetStore;
23
 
24
  /**
25
  * @param string $fullPath - in this case it's relative to ABSPATH
38
  throw new \Exception( sprintf( 'Could not load asset for: %s', $fullPath ) );
39
  }
40
 
41
+ $item = $this->scanWithStore( $fullPath, $asset );
42
+ }
43
+ catch ( \Exception $e ) {
44
+ error_log( $e->getMessage() );
45
+ }
46
+
47
+ return $item;
48
+ }
49
+
50
+ /**
51
+ * @param string $fullPath
52
+ * @param Assets\WpPluginVo|Assets\WpThemeVo $asset
53
+ * @return ResultItem|null
54
+ * @throws \InvalidArgumentException|\Exception
55
+ */
56
+ private function scanWithStore( string $fullPath, $asset ) {
57
+ $assetHashes = $this->getStore( $asset )->getSnapData();
58
+ $pathFragment = str_replace( $asset->getInstallDir(), '', $fullPath );
59
+ if ( empty( $assetHashes[ $pathFragment ] ) ) {
60
+ $item = $this->getNewItem( $asset, $fullPath );
61
+ $item->path_fragment = $pathFragment;
62
+ $item->is_unrecognised = true;
63
+ }
64
+ elseif ( !( new CompareHash() )->isEqualFileMd5( $fullPath, $assetHashes[ $pathFragment ] ) ) {
65
+ $item = $this->getNewItem( $asset, $fullPath );
66
+ $item->path_fragment = $pathFragment;
67
+ $item->is_different = true;
68
+ }
69
+ else {
70
+ $item = null;
71
+ }
72
+ return $item;
73
+ }
74
+
75
+ /**
76
+ * @param string $fullPath
77
+ * @param Assets\WpPluginVo|Assets\WpThemeVo $asset
78
+ * @return ResultItem|null
79
+ * @throws \InvalidArgumentException|\Exception
80
+ */
81
+ private function scanWithCsHashes( string $fullPath, $asset ) {
82
+ $assetHashes = $this->loadCsHashes( $asset );
83
+ $pathFragment = str_replace( $asset->getInstallDir(), '', $fullPath );
84
+
85
+ $item = null;
86
+ if ( empty( $assetHashes[ $pathFragment ] ) ) {
87
+ $item = $this->getNewItem( $asset, $fullPath );
88
+ $item->path_fragment = $pathFragment;
89
+ $item->is_unrecognised = true;
90
+ }
91
+ else {
92
+ $found = false;
93
+ foreach ( $assetHashes[ $pathFragment ] as $hash ) {
94
+ if ( ( new CompareHash() )->isEqualFileSha1( $fullPath, $hash ) ) {
95
+ $found = true;
96
+ break;
97
+ }
98
  }
99
+
100
+ if ( !$found ) {
101
  $item = $this->getNewItem( $asset, $fullPath );
102
  $item->path_fragment = $pathFragment;
103
  $item->is_different = true;
104
  }
105
  }
 
 
 
 
106
  return $item;
107
  }
108
 
109
+ private function loadCsHashes( $asset ) {
110
+ $uniqueId = md5( ( $asset instanceof Assets\WpPluginVo ) ? $asset->file : $asset->stylesheet );
111
+ $tmpFileHandler = ( new Shield\Utilities\Tool\TmpFileStore() )
112
+ ->setCon( $this->getCon() );
113
+
114
+ $hashes = $tmpFileHandler->load( $uniqueId );
115
+ if ( empty( $hashes ) ) {
116
+ $hashesResponse = ( $asset instanceof Assets\WpPluginVo ? new Query\Plugin() : new Query\Theme() )
117
+ ->getHashesFromVO( $asset );
118
+ if ( !empty( $hashesResponse[ 'hashes' ] ) ) {
119
+ $hashes = [ 'hashes' ];
120
+ $tmpFileHandler->store( $uniqueId, $hashes );
121
+ }
122
+ }
123
+ return $hashes;
124
+ }
125
+
126
  /**
127
+ * @param Assets\WpPluginVo|Assets\WpThemeVo $asset
128
  * @return string[]
129
  * @throws \Exception
130
  */
131
+ private function getCSHashes( $asset ) {
132
+ return $this->getStore( $asset )->getSnapData();
133
  }
134
 
135
  /**
136
+ * @param Assets\WpPluginVo|Assets\WpThemeVo $asset
137
  * @return Lib\Snapshots\Store
138
  * @throws \Exception
139
  */
140
+ private function getStore( $asset ) {
141
 
142
  // Re-Use the previous store if it's for the same Asset.
143
+ if ( !empty( $this->assetStore ) ) {
144
+ $uniqueId = ( $asset instanceof Assets\WpPluginVo ) ? $asset->file : $asset->stylesheet;
145
+ $meta = $this->assetStore->getSnapMeta();
146
+ if ( $uniqueId !== $meta[ 'unique_id' ] ) {
147
+ unset( $this->assetStore );
148
  }
149
  }
150
 
151
+ if ( empty( $this->assetStore ) ) {
152
+ $this->assetStore = ( new Lib\Snapshots\StoreAction\Load() )
153
  ->setMod( $this->getMod() )
154
+ ->setAsset( $asset )
155
  ->run();
156
  }
157
 
158
+ return $this->assetStore;
159
  }
160
 
161
  /**
162
+ * @param Assets\WpPluginVo|Assets\WpThemeVo $asset
163
+ * @param string $file
164
  * @return ResultItem
165
  */
166
+ private function getNewItem( $asset, $file ) {
167
+ /** @var ResultItem $item */
168
+ $item = $this->getScanActionVO()->getNewResultItem();
169
+ $item->path_full = $file;
170
+ $item->path_fragment = $file; // will eventually be overwritten
171
+ $item->is_unrecognised = false;
172
+ $item->is_different = false;
173
+ $item->is_missing = false;
174
+ $item->context = ( $asset instanceof Assets\WpPluginVo ) ? 'plugins' : 'themes';
175
+ $item->slug = ( $asset instanceof Assets\WpPluginVo ) ? $asset->file : $asset->stylesheet;
176
+ return $item;
177
  }
178
  }
src/lib/src/Scans/Ptg/ResultsSet.php CHANGED
@@ -6,7 +6,7 @@ use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base;
6
 
7
  /**
8
  * Class ResultsSet
9
- * @property ResultItem[] $aItems
10
  * @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Ptg
11
  */
12
  class ResultsSet extends Base\BaseResultsSet {
@@ -38,33 +38,33 @@ class ResultsSet extends Base\BaseResultsSet {
38
  }
39
 
40
  /**
41
- * @param string $sSlug
42
  * @return ResultItem[]
43
  */
44
- public function getItemsForSlug( $sSlug ) {
45
  return array_values( array_filter(
46
  $this->getItems(),
47
- function ( $oItem ) use ( $sSlug ) {
48
- /** @var ResultItem $oItem */
49
- return $oItem->slug == $sSlug;
50
  }
51
  ) );
52
  }
53
 
54
  /**
55
- * @param string $sSlug
56
  * @return ResultsSet
57
  */
58
- public function getResultsSetForSlug( $sSlug ) {
59
- $oRes = new ResultsSet();
60
  array_map(
61
- function ( $oItem ) use ( $oRes ) {
62
- /** @var ResultItem $oItem */
63
- $oRes->addItem( $oItem );
64
  },
65
- $this->getItemsForSlug( $sSlug )
66
  );
67
- return $oRes;
68
  }
69
 
70
  /**
@@ -73,15 +73,15 @@ class ResultsSet extends Base\BaseResultsSet {
73
  * @return ResultsSet[]
74
  */
75
  public function getAllResultsSetsForUniqueSlugs() {
76
- $aCollection = [];
77
- foreach ( $this->getUniqueSlugs() as $sSlug ) {
78
- $oRS = $this->getResultsSetForSlug( $sSlug );
79
- if ( $oRS->hasItems() ) {
80
- $aCollection[ $sSlug ] = $oRS;
81
  }
82
  }
83
- ksort( $aCollection, SORT_NATURAL );
84
- return $aCollection;
85
  }
86
 
87
  /**
@@ -150,9 +150,9 @@ class ResultsSet extends Base\BaseResultsSet {
150
  */
151
  public function getUniqueSlugs() {
152
  return array_unique( array_map(
153
- function ( $oItem ) {
154
- /** @var ResultItem $oItem */
155
- return $oItem->slug;
156
  },
157
  $this->getItems()
158
  ) );
6
 
7
  /**
8
  * Class ResultsSet
9
+ * @property ResultItem[] $items
10
  * @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Ptg
11
  */
12
  class ResultsSet extends Base\BaseResultsSet {
38
  }
39
 
40
  /**
41
+ * @param string $slug
42
  * @return ResultItem[]
43
  */
44
+ public function getItemsForSlug( $slug ) {
45
  return array_values( array_filter(
46
  $this->getItems(),
47
+ function ( $item ) use ( $slug ) {
48
+ /** @var ResultItem $item */
49
+ return $item->slug == $slug;
50
  }
51
  ) );
52
  }
53
 
54
  /**
55
+ * @param string $slug
56
  * @return ResultsSet
57
  */
58
+ public function getResultsSetForSlug( $slug ) {
59
+ $results = new ResultsSet();
60
  array_map(
61
+ function ( $item ) use ( $results ) {
62
+ /** @var ResultItem $item */
63
+ $results->addItem( $item );
64
  },
65
+ $this->getItemsForSlug( $slug )
66
  );
67
+ return $results;
68
  }
69
 
70
  /**
73
  * @return ResultsSet[]
74
  */
75
  public function getAllResultsSetsForUniqueSlugs() {
76
+ $collection = [];
77
+ foreach ( $this->getUniqueSlugs() as $slug ) {
78
+ $results = $this->getResultsSetForSlug( $slug );
79
+ if ( $results->hasItems() ) {
80
+ $collection[ $slug ] = $results;
81
  }
82
  }
83
+ ksort( $collection, SORT_NATURAL );
84
+ return $collection;
85
  }
86
 
87
  /**
150
  */
151
  public function getUniqueSlugs() {
152
  return array_unique( array_map(
153
+ function ( $item ) {
154
+ /** @var ResultItem $item */
155
+ return $item->slug;
156
  },
157
  $this->getItems()
158
  ) );
src/lib/src/Scans/Ptg/Utilities/ItemActionHandler.php CHANGED
@@ -39,21 +39,21 @@ class ItemActionHandler extends Base\Utilities\ItemActionHandlerAssets {
39
  * @throws \Exception
40
  */
41
  private function assetAccept() {
42
- /** @var Ptg\ResultsSet $oRes */
43
- $oRes = $this->getScanController()->getAllResults();
44
 
45
- /** @var Ptg\ResultItem $oMainItem */
46
- $oMainItem = $this->getScanItem();
47
 
48
- foreach ( $oRes->getItemsForSlug( $oMainItem->slug ) as $oItem ) {
49
- $oTmpHandler = clone $this;
50
- $oTmpHandler->setScanItem( $oItem )
51
  ->ignore();
52
  }
53
 
54
  ( new Snapshots\StoreAction\Build() )
55
  ->setMod( $this->getMod() )
56
- ->setAsset( $this->getAssetFromSlug( $oMainItem->slug ) )
57
  ->run();
58
 
59
  return true;
@@ -106,13 +106,13 @@ class ItemActionHandler extends Base\Utilities\ItemActionHandlerAssets {
106
  }
107
 
108
  /**
109
- * @param bool $bSuccess
110
  */
111
- protected function fireRepairEvent( $bSuccess ) {
112
  /** @var Ptg\ResultItem $oItem */
113
  $oItem = $this->getScanItem();
114
  $this->getCon()->fireEvent(
115
- $this->getScanController()->getSlug().'_item_repair_'.( $bSuccess ? 'success' : 'fail' ),
116
  [ 'audit' => [ 'fragment' => $oItem->path_full ] ]
117
  );
118
  }
39
  * @throws \Exception
40
  */
41
  private function assetAccept() {
42
+ /** @var Ptg\ResultsSet $results */
43
+ $results = $this->getScanController()->getAllResults();
44
 
45
+ /** @var Ptg\ResultItem $item */
46
+ $item = $this->getScanItem();
47
 
48
+ foreach ( $results->getItemsForSlug( $item->slug ) as $oItem ) {
49
+ $tmpHandler = clone $this;
50
+ $tmpHandler->setScanItem( $oItem )
51
  ->ignore();
52
  }
53
 
54
  ( new Snapshots\StoreAction\Build() )
55
  ->setMod( $this->getMod() )
56
+ ->setAsset( $this->getAssetFromSlug( $item->slug ) )
57
  ->run();
58
 
59
  return true;
106
  }
107
 
108
  /**
109
+ * @param bool $success
110
  */
111
+ protected function fireRepairEvent( $success ) {
112
  /** @var Ptg\ResultItem $oItem */
113
  $oItem = $this->getScanItem();
114
  $this->getCon()->fireEvent(
115
+ $this->getScanController()->getSlug().'_item_repair_'.( $success ? 'success' : 'fail' ),
116
  [ 'audit' => [ 'fragment' => $oItem->path_full ] ]
117
  );
118
  }
src/lib/src/Scans/Ptg/Utilities/Repair.php CHANGED
@@ -4,8 +4,11 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Ptg\Utilities;
4
 
5
  use FernleafSystems\Wordpress\Plugin\Shield\Scans;
6
  use FernleafSystems\Wordpress\Plugin\Shield\Scans\Ptg;
 
 
 
 
7
  use FernleafSystems\Wordpress\Services\Services;
8
- use FernleafSystems\Wordpress\Services\Core\VOs;
9
  use FernleafSystems\Wordpress\Services\Utilities\WpOrg;
10
 
11
  /**
@@ -19,15 +22,15 @@ class Repair extends Scans\Base\Utilities\BaseRepair {
19
  * @throws \Exception
20
  */
21
  public function repairItem() {
22
- /** @var Ptg\ResultItem $oItem */
23
- $oItem = $this->getScanItem();
24
 
25
  if ( $this->canRepair() ) {
26
- if ( $oItem->context == 'plugins' ) {
27
- $bSuccess = $this->repairPluginFile( $oItem->path_full );
28
  }
29
  else {
30
- $bSuccess = $this->repairThemeFile( $oItem->path_full );
31
  }
32
  }
33
  else {
@@ -43,10 +46,10 @@ class Repair extends Scans\Base\Utilities\BaseRepair {
43
  */
44
  private function repairPluginFile( $sPath ) {
45
  $success = false;
46
- $oFiles = new WpOrg\Plugin\Files();
47
  try {
48
- if ( $oFiles->isValidFileFromPlugin( $sPath ) ) {
49
- $success = $oFiles->replaceFileFromVcs( $sPath );
50
  }
51
  elseif ( $this->isAllowDelete() ) {
52
  $success = (bool)Services::WpFs()->deleteFile( $sPath );
@@ -58,39 +61,40 @@ class Repair extends Scans\Base\Utilities\BaseRepair {
58
  }
59
 
60
  /**
61
- * @param string $sPath
62
  * @return bool
63
  */
64
- private function repairThemeFile( $sPath ) {
65
  $success = false;
66
- $oFiles = new WpOrg\Theme\Files();
67
  try {
68
- if ( $oFiles->isValidFileFromTheme( $sPath ) ) {
69
- $success = $oFiles->replaceFileFromVcs( $sPath );
70
  }
71
  elseif ( $this->isAllowDelete() ) {
72
- $success = (bool)Services::WpFs()->deleteFile( $sPath );
73
  }
74
  }
75
  catch ( \InvalidArgumentException $e ) {
76
  }
77
- return (bool)$success;
78
  }
79
 
80
  /**
81
  * @return bool
82
  */
83
  public function canRepair() {
84
- /** @var Ptg\ResultItem $oItem */
85
- $oItem = $this->getScanItem();
86
- if ( $oItem->context == 'plugins' ) {
87
- $oAsset = Services::WpPlugins()->getPluginAsVo( $oItem->slug );
88
- $bCanRepair = ( $oAsset instanceof VOs\WpPluginVo && $oAsset->isWpOrg() && $oAsset->svn_uses_tags );
 
89
  }
90
  else {
91
- $oAsset = Services::WpThemes()->getThemeAsVo( $oItem->slug );
92
- $bCanRepair = ( $oAsset instanceof VOs\WpThemeVo && $oAsset->isWpOrg() );
93
  }
94
- return $bCanRepair;
95
  }
96
  }
4
 
5
  use FernleafSystems\Wordpress\Plugin\Shield\Scans;
6
  use FernleafSystems\Wordpress\Plugin\Shield\Scans\Ptg;
7
+ use FernleafSystems\Wordpress\Services\Core\VOs\Assets\{
8
+ WpPluginVo,
9
+ WpThemeVo
10
+ };
11
  use FernleafSystems\Wordpress\Services\Services;
 
12
  use FernleafSystems\Wordpress\Services\Utilities\WpOrg;
13
 
14
  /**
22
  * @throws \Exception
23
  */
24
  public function repairItem() {
25
+ /** @var Ptg\ResultItem $item */
26
+ $item = $this->getScanItem();
27
 
28
  if ( $this->canRepair() ) {
29
+ if ( $item->context == 'plugins' ) {
30
+ $bSuccess = $this->repairPluginFile( $item->path_full );
31
  }
32
  else {
33
+ $bSuccess = $this->repairThemeFile( $item->path_full );
34
  }
35
  }
36
  else {
46
  */
47
  private function repairPluginFile( $sPath ) {
48
  $success = false;
49
+ $files = new WpOrg\Plugin\Files();
50
  try {
51
+ if ( $files->isValidFileFromPlugin( $sPath ) ) {
52
+ $success = $files->replaceFileFromVcs( $sPath );
53
  }
54
  elseif ( $this->isAllowDelete() ) {
55
  $success = (bool)Services::WpFs()->deleteFile( $sPath );
61
  }
62
 
63
  /**
64
+ * @param string $path
65
  * @return bool
66
  */
67
+ private function repairThemeFile( $path ) {
68
  $success = false;
69
+ $files = new WpOrg\Theme\Files();
70
  try {
71
+ if ( $files->isValidFileFromTheme( $path ) ) {
72
+ $success = $files->replaceFileFromVcs( $path );
73
  }
74
  elseif ( $this->isAllowDelete() ) {
75
+ $success = (bool)Services::WpFs()->deleteFile( $path );
76
  }
77
  }
78
  catch ( \InvalidArgumentException $e ) {
79
  }
80
+ return $success;
81
  }
82
 
83
  /**
84
  * @return bool
85
  */
86
  public function canRepair() {
87
+ /** @var Ptg\ResultItem $item */
88
+ $item = $this->getScanItem();
89
+ if ( $item->context == 'plugins' ) {
90
+ $asset = Services::WpPlugins()->getPluginAsVo( $item->slug );
91
+ $canRepair = $asset->asset_type === 'plugin'
92
+ && $asset->isWpOrg() && $asset->svn_uses_tags;
93
  }
94
  else {
95
+ $asset = Services::WpThemes()->getThemeAsVo( $item->slug );
96
+ $canRepair = $asset->asset_type === 'theme' && $asset->isWpOrg();
97
  }
98
+ return $canRepair;
99
  }
100
  }
src/lib/src/Scans/Ufc/ConvertVosToResults.php CHANGED
@@ -12,22 +12,22 @@ use FernleafSystems\Wordpress\Plugin\Shield\Scans;
12
  class ConvertVosToResults extends Scans\Base\BaseConvertVosToResults {
13
 
14
  /**
15
- * @param EntryVO[] $oVos
16
  * @return ResultsSet
17
  */
18
- public function convert( $oVos ) {
19
  $oRes = new ResultsSet();
20
- foreach ( $oVos as $oVo ) {
21
  $oRes->addItem( $this->convertItem( $oVo ) );
22
  }
23
  return $oRes;
24
  }
25
 
26
  /**
27
- * @param EntryVO $oVo
28
  * @return ResultItem
29
  */
30
- public function convertItem( $oVo ) {
31
- return ( new ResultItem() )->applyFromArray( $oVo->meta );
32
  }
33
  }
12
  class ConvertVosToResults extends Scans\Base\BaseConvertVosToResults {
13
 
14
  /**
15
+ * @param EntryVO[] $VOs
16
  * @return ResultsSet
17
  */
18
+ public function convert( $VOs ) {
19
  $oRes = new ResultsSet();
20
+ foreach ( $VOs as $oVo ) {
21
  $oRes->addItem( $this->convertItem( $oVo ) );
22
  }
23
  return $oRes;
24
  }
25
 
26
  /**
27
+ * @param EntryVO $VO
28
  * @return ResultItem
29
  */
30
+ public function convertItem( $VO ) {
31
+ return ( new ResultItem() )->applyFromArray( $VO->meta );
32
  }
33
  }
src/lib/src/Scans/Ufc/ResultsSet.php CHANGED
@@ -6,7 +6,7 @@ use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base;
6
 
7
  /**
8
  * Class ResultsSet
9
- * @property ResultItem[] $aItems
10
  * @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Ufc
11
  */
12
  class ResultsSet extends Base\BaseResultsSet {
6
 
7
  /**
8
  * Class ResultsSet
9
+ * @property ResultItem[] $items
10
  * @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Ufc
11
  */
12
  class ResultsSet extends Base\BaseResultsSet {
src/lib/src/Scans/Ufc/Utilities/ItemActionHandler.php CHANGED
@@ -22,14 +22,14 @@ class ItemActionHandler extends Base\Utilities\ItemActionHandler {
22
  }
23
 
24
  /**
25
- * @param bool $bSuccess
26
  */
27
- protected function fireRepairEvent( $bSuccess ) {
28
- /** @var Ufc\ResultItem $oItem */
29
- $oItem = $this->getScanItem();
30
  $this->getCon()->fireEvent(
31
- $this->getScanController()->getSlug().'_item_repair_'.( $bSuccess ? 'success' : 'fail' ),
32
- [ 'audit' => [ 'fragment' => $oItem->path_full ] ]
33
  );
34
  }
35
- }
22
  }
23
 
24
  /**
25
+ * @param bool $success
26
  */
27
+ protected function fireRepairEvent( $success ) {
28
+ /** @var Ufc\ResultItem $item */
29
+ $item = $this->getScanItem();
30
  $this->getCon()->fireEvent(
31
+ $this->getScanController()->getSlug().'_item_repair_'.( $success ? 'success' : 'fail' ),
32
+ [ 'audit' => [ 'fragment' => $item->path_full ] ]
33
  );
34
  }
35
+ }
src/lib/src/Scans/Wcf/ConvertVosToResults.php CHANGED
@@ -12,22 +12,22 @@ use FernleafSystems\Wordpress\Plugin\Shield\Scans;
12
  class ConvertVosToResults extends Scans\Base\BaseConvertVosToResults {
13
 
14
  /**
15
- * @param EntryVO[] $oVos
16
  * @return ResultsSet
17
  */
18
- public function convert( $oVos ) {
19
  $oRes = new ResultsSet();
20
- foreach ( $oVos as $oVo ) {
21
  $oRes->addItem( $this->convertItem( $oVo ) );
22
  }
23
  return $oRes;
24
  }
25
 
26
  /**
27
- * @param EntryVO $oVo
28
  * @return ResultItem
29
  */
30
- public function convertItem( $oVo ) {
31
- return ( new ResultItem() )->applyFromArray( $oVo->meta );
32
  }
33
  }
12
  class ConvertVosToResults extends Scans\Base\BaseConvertVosToResults {
13
 
14
  /**
15
+ * @param EntryVO[] $VOs
16
  * @return ResultsSet
17
  */
18
+ public function convert( $VOs ) {
19
  $oRes = new ResultsSet();
20
+ foreach ( $VOs as $oVo ) {
21
  $oRes->addItem( $this->convertItem( $oVo ) );
22
  }
23
  return $oRes;
24
  }
25
 
26
  /**
27
+ * @param EntryVO $VO
28
  * @return ResultItem
29
  */
30
+ public function convertItem( $VO ) {
31
+ return ( new ResultItem() )->applyFromArray( $VO->meta );
32
  }
33
  }
src/lib/src/Scans/Wcf/ResultsSet.php CHANGED
@@ -6,7 +6,7 @@ use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base;
6
 
7
  /**
8
  * Class ResultsSet
9
- * @property ResultItem[] $aItems
10
  * @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Wcf
11
  */
12
  class ResultsSet extends Base\BaseResultsSet {
6
 
7
  /**
8
  * Class ResultsSet
9
+ * @property ResultItem[] $items
10
  * @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Wcf
11
  */
12
  class ResultsSet extends Base\BaseResultsSet {
src/lib/src/Scans/Wcf/Utilities/ItemActionHandler.php CHANGED
@@ -15,13 +15,13 @@ class ItemActionHandler extends Base\Utilities\ItemActionHandler {
15
  }
16
 
17
  /**
18
- * @param bool $bSuccess
19
  */
20
- protected function fireRepairEvent( $bSuccess ) {
21
  /** @var Wcf\ResultItem $oItem */
22
  $oItem = $this->getScanItem();
23
  $this->getCon()->fireEvent(
24
- $this->getScanController()->getSlug().'_item_repair_'.( $bSuccess ? 'success' : 'fail' ),
25
  [ 'audit' => [ 'fragment' => $oItem->path_full ] ]
26
  );
27
  }
15
  }
16
 
17
  /**
18
+ * @param bool $success
19
  */
20
+ protected function fireRepairEvent( $success ) {
21
  /** @var Wcf\ResultItem $oItem */
22
  $oItem = $this->getScanItem();
23
  $this->getCon()->fireEvent(
24
+ $this->getScanController()->getSlug().'_item_repair_'.( $success ? 'success' : 'fail' ),
25
  [ 'audit' => [ 'fragment' => $oItem->path_full ] ]
26
  );
27
  }
src/lib/src/Scans/Wpv/BuildScanAction.php CHANGED
@@ -8,20 +8,20 @@ use FernleafSystems\Wordpress\Services\Services;
8
  class BuildScanAction extends Shield\Scans\Base\BaseBuildScanAction {
9
 
10
  protected function buildItems() {
11
- /** @var ScanActionVO $oAction */
12
- $oAction = $this->getScanActionVO();
13
 
14
- $aItems = array_map(
15
  function ( $nKey ) {
16
  return 'plugins';
17
  },
18
  array_flip( Services::WpPlugins()->getInstalledPluginFiles() )
19
  );
20
 
21
- $oWpT = Services::WpThemes();
22
- $oTheme = $oWpT->isActiveThemeAChild() ? $oWpT->getCurrentParent() : $oWpT->getCurrent();
23
- $aItems[ $oTheme->get_stylesheet() ] = 'themes';
24
 
25
- $oAction->items = $aItems;
26
  }
27
  }
8
  class BuildScanAction extends Shield\Scans\Base\BaseBuildScanAction {
9
 
10
  protected function buildItems() {
11
+ /** @var ScanActionVO $action */
12
+ $action = $this->getScanActionVO();
13
 
14
+ $items = array_map(
15
  function ( $nKey ) {
16
  return 'plugins';
17
  },
18
  array_flip( Services::WpPlugins()->getInstalledPluginFiles() )
19
  );
20
 
21
+ $WPT = Services::WpThemes();
22
+ $theme = $WPT->isActiveThemeAChild() ? $WPT->getCurrentParent() : $WPT->getCurrent();
23
+ $items[ $theme->get_stylesheet() ] = 'themes';
24
 
25
+ $action->items = $items;
26
  }
27
  }
src/lib/src/Scans/Wpv/ConvertVosToResults.php CHANGED
@@ -11,22 +11,22 @@ use FernleafSystems\Wordpress\Plugin\Shield;
11
  class ConvertVosToResults extends Shield\Scans\Base\BaseConvertVosToResults {
12
 
13
  /**
14
- * @param Shield\Databases\Scanner\EntryVO[] $oVos
15
  * @return ResultsSet
16
  */
17
- public function convert( $oVos ) {
18
- $oRes = new ResultsSet();
19
- foreach ( $oVos as $oVo ) {
20
- $oRes->addItem( $this->convertItem( $oVo ) );
21
  }
22
- return $oRes;
23
  }
24
 
25
  /**
26
- * @param Shield\Databases\Scanner\EntryVO $oVo
27
  * @return ResultItem
28
  */
29
- public function convertItem( $oVo ) {
30
- return ( new ResultItem() )->applyFromArray( $oVo->meta );
31
  }
32
  }
11
  class ConvertVosToResults extends Shield\Scans\Base\BaseConvertVosToResults {
12
 
13
  /**
14
+ * @param Shield\Databases\Scanner\EntryVO[] $VOs
15
  * @return ResultsSet
16
  */
17
+ public function convert( $VOs ) {
18
+ $results = new ResultsSet();
19
+ foreach ( $VOs as $vo ) {
20
+ $results->addItem( $this->convertItem( $vo ) );
21
  }
22
+ return $results;
23
  }
24
 
25
  /**
26
+ * @param Shield\Databases\Scanner\EntryVO $VO
27
  * @return ResultItem
28
  */
29
+ public function convertItem( $VO ) {
30
+ return ( new ResultItem() )->applyFromArray( $VO->meta );
31
  }
32
  }
src/lib/src/Scans/Wpv/ResultItem.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Wpv;
4
 
5
- use FernleafSystems\Wordpress\Plugin\Shield\Scans\Wpv\WpVulnDb\WpVulnVO;
6
 
7
  /**
8
  * Class ResultItem
@@ -18,7 +18,7 @@ class ResultItem extends \FernleafSystems\Wordpress\Plugin\Shield\Scans\Base\Bas
18
  return md5( $this->slug.$this->wpvuln_id );
19
  }
20
 
21
- public function getWpVulnVo() :WpVulnVO {
22
- return ( new WpVulnVO() )->applyFromArray( $this->wpvuln_vo );
23
  }
24
  }
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Wpv;
4
 
5
+ use FernleafSystems\Wordpress\Plugin\Shield\Scans\Wpv\WpVulnDb\VulnVO;
6
 
7
  /**
8
  * Class ResultItem
18
  return md5( $this->slug.$this->wpvuln_id );
19
  }
20
 
21
+ public function getVulnVo() :VulnVO {
22
+ return ( new VulnVO() )->applyFromArray( $this->wpvuln_vo );
23
  }
24
  }
src/lib/src/Scans/Wpv/ResultsSet.php CHANGED
@@ -6,7 +6,7 @@ use FernleafSystems\Wordpress\Plugin\Shield\Scans\Base;
6
 
7
  /**
8
  * Class ResultsSet
9
- * @property ResultItem[] $aItems
10
  * @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Wpv
11
  */
12
  class ResultsSet extends Base\BaseResultsSet {
6
 
7
  /**
8
  * Class ResultsSet
9
+ * @property ResultItem[] $items
10
  * @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Wpv
11
  */
12
  class ResultsSet extends Base\BaseResultsSet {
src/lib/src/Scans/Wpv/Scan.php CHANGED
@@ -31,52 +31,50 @@ class Scan extends Shield\Scans\Base\BaseScan {
31
  }
32
 
33
  /**
34
- * @param string $sContext
35
- * @param string $sFile
36
  * @return ResultsSet
37
  */
38
- protected function scanItem( $sContext, $sFile ) {
39
- $oResultsSet = new ResultsSet();
40
 
41
  $sApiToken = $this->getCon()
42
  ->getModule_License()
43
  ->getWpHashesTokenManager()
44
  ->getToken();
45
 
46
- if ( $sContext == 'plugins' ) {
47
- $oWpPlugins = Services::WpPlugins();
48
- $sSlug = $oWpPlugins->getSlug( $sFile );
49
- if ( empty( $sSlug ) ) {
50
- $sSlug = dirname( $sFile );
51
  }
52
- $sVersion = $oWpPlugins->getPluginAsVo( $sFile )->Version;
53
- $oLookup = new Vulnerabilities\Plugin( $sApiToken );
54
  }
55
  else {
56
- $sSlug = $sFile;
57
- $sVersion = Services::WpThemes()->getTheme( $sSlug )->get( 'Version' );
58
- $oLookup = new Vulnerabilities\Theme( $sApiToken );
59
  }
60
 
61
- $aVulns = $oLookup->getVulnerabilities( $sSlug, $sVersion );
62
- $aVulns = array_filter( array_map(
63
- function ( $aVuln ) {
64
- return empty( $aVuln ) ? null
65
- : ( new Shield\Scans\Wpv\WpVulnDb\WpVulnVO() )->applyFromArray( $aVuln );
66
- },
67
- ( is_array( $aVulns ) ? $aVulns : [] )
68
- ) );
69
 
70
- /** @var Shield\Scans\Wpv\WpVulnDb\WpVulnVO[] $aVulns */
71
- foreach ( $aVulns as $oVo ) {
72
- $oItem = new ResultItem();
73
- $oItem->slug = $sFile;
74
- $oItem->context = $sContext;
75
- $oItem->wpvuln_id = $oVo->id;
76
- $oItem->wpvuln_vo = $oVo->getRawData();
77
- $oResultsSet->addItem( $oItem );
 
 
 
 
78
  }
79
 
80
- return $oResultsSet;
81
  }
82
  }
31
  }
32
 
33
  /**
34
+ * @param string $context
35
+ * @param string $file
36
  * @return ResultsSet
37
  */
38
+ protected function scanItem( $context, $file ) {
39
+ $results = new ResultsSet();
40
 
41
  $sApiToken = $this->getCon()
42
  ->getModule_License()
43
  ->getWpHashesTokenManager()
44
  ->getToken();
45
 
46
+ if ( $context == 'plugins' ) {
47
+ $WPP = Services::WpPlugins();
48
+ $slug = $WPP->getSlug( $file );
49
+ if ( empty( $slug ) ) {
50
+ $slug = dirname( $file );
51
  }
52
+ $version = $WPP->getPluginAsVo( $file )->Version;
53
+ $lookerUpper = new Vulnerabilities\Plugin( $sApiToken );
54
  }
55
  else {
56
+ $slug = $file;
57
+ $version = Services::WpThemes()->getTheme( $slug )->get( 'Version' );
58
+ $lookerUpper = new Vulnerabilities\Theme( $sApiToken );
59
  }
60
 
61
+ $rawVuls = $lookerUpper->getVulnerabilities( $slug, $version );
62
+ if ( is_array( $rawVuls ) && !empty( $rawVuls[ 'meta' ] ) && $rawVuls[ 'meta' ][ 'total' ] > 0 ) {
 
 
 
 
 
 
63
 
64
+ foreach ( array_filter( $rawVuls[ 'vulnerabilities' ] ) as $vul ) {
65
+ $VO = ( new Shield\Scans\Wpv\WpVulnDb\VulnVO() )->applyFromArray( $vul );
66
+ $VO->provider = $rawVuls[ 'meta' ][ 'provider' ];
67
+
68
+ $item = new ResultItem();
69
+ $item->slug = $file;
70
+ $item->context = $context;
71
+ $item->wpvuln_id = $VO->id;
72
+ $item->wpvuln_vo = $VO->getRawData();
73
+
74
+ $results->addItem( $item );
75
+ }
76
  }
77
 
78
+ return $results;
79
  }
80
  }
src/lib/src/Scans/Wpv/Utilities/ItemActionHandler.php CHANGED
@@ -16,13 +16,13 @@ class ItemActionHandler extends Base\Utilities\ItemActionHandlerAssets {
16
  }
17
 
18
  /**
19
- * @param bool $bSuccess
20
  */
21
- protected function fireRepairEvent( $bSuccess ) {
22
  /** @var Wpv\ResultItem $oItem */
23
  $oItem = $this->getScanItem();
24
  $this->getCon()->fireEvent(
25
- $this->getScanController()->getSlug().'_item_repair_'.( $bSuccess ? 'success' : 'fail' ),
26
  [
27
  'audit' => [
28
  'name' => Services::WpPlugins()->getPluginAsVo( $oItem->slug )->Name
16
  }
17
 
18
  /**
19
+ * @param bool $success
20
  */
21
+ protected function fireRepairEvent( $success ) {
22
  /** @var Wpv\ResultItem $oItem */
23
  $oItem = $this->getScanItem();
24
  $this->getCon()->fireEvent(
25
+ $this->getScanController()->getSlug().'_item_repair_'.( $success ? 'success' : 'fail' ),
26
  [
27
  'audit' => [
28
  'name' => Services::WpPlugins()->getPluginAsVo( $oItem->slug )->Name
src/lib/src/Scans/Wpv/Utilities/Repair.php CHANGED
@@ -4,7 +4,7 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Wpv\Utilities;
4
 
5
  use FernleafSystems\Wordpress\Plugin\Shield\Scans;
6
  use FernleafSystems\Wordpress\Plugin\Shield\Scans\Wpv;
7
- use FernleafSystems\Wordpress\Services\Core\VOs;
8
  use FernleafSystems\Wordpress\Services\Services;
9
 
10
  /**
@@ -36,15 +36,15 @@ class Repair extends Scans\Base\Utilities\BaseRepair {
36
  * @return bool
37
  */
38
  public function canRepair() {
39
- /** @var Wpv\ResultItem $oItem */
40
- $oItem = $this->getScanItem();
41
 
42
- if ( $oItem->context == 'plugins' ) {
43
- $oAsset = Services::WpPlugins()->getPluginAsVo( $oItem->slug );
44
  }
45
  else {
46
- $oAsset = Services::WpThemes()->getThemeAsVo( $oItem->slug );
47
  }
48
- return ( $oAsset instanceof VOs\WpPluginVo && $oAsset->hasUpdate() );
49
  }
50
  }
4
 
5
  use FernleafSystems\Wordpress\Plugin\Shield\Scans;
6
  use FernleafSystems\Wordpress\Plugin\Shield\Scans\Wpv;
7
+ use FernleafSystems\Wordpress\Services\Core\VOs\Assets;
8
  use FernleafSystems\Wordpress\Services\Services;
9
 
10
  /**
36
  * @return bool
37
  */
38
  public function canRepair() {
39
+ /** @var Wpv\ResultItem $item */
40
+ $item = $this->getScanItem();
41
 
42
+ if ( $item->context == 'plugins' ) {
43
+ $asset = Services::WpPlugins()->getPluginAsVo( $item->slug );
44
  }
45
  else {
46
+ $asset = Services::WpThemes()->getThemeAsVo( $item->slug );
47
  }
48
+ return ( $asset instanceof Assets\WpPluginVo && $asset->hasUpdate() );
49
  }
50
  }
src/lib/src/Scans/Wpv/WpVulnDb/VulnVO.php ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php declare( strict_types=1 );
2
+
3
+ namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Wpv\WpVulnDb;
4
+
5
+ use FernleafSystems\Utilities\Data\Adapter\DynPropertiesClass;
6
+
7
+ /**
8
+ * Class VulnVO
9
+ * @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Wpv\WpVulnDb
10
+ * @property string|int $id
11
+ * @property string $title
12
+ * @property string $description
13
+ * @property string $vuln_type
14
+ * @property string $fixed_in
15
+ * @property array $references
16
+ * @property int $disclosed_at
17
+ * @property int $created_at
18
+ * @property string $provider
19
+ */
20
+ class VulnVO extends DynPropertiesClass {
21
+
22
+ public function __get( string $key ) {
23
+ $value = parent::__get( $key );
24
+
25
+ if ( preg_match( '#_at$#', $key ) ) {
26
+ $value = (int)$value;
27
+ }
28
+ else {
29
+ switch ( $key ) {
30
+ case 'references':
31
+ if ( !is_array( $value ) ) {
32
+ $value = [];
33
+ }
34
+ break;
35
+ default:
36
+ break;
37
+ }
38
+ }
39
+
40
+ return $value;
41
+ }
42
+ }
src/lib/src/ShieldNetApi/Reputation/GetIPReputation.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php declare( strict_types=1 );
2
+
3
+ namespace FernleafSystems\Wordpress\Plugin\Shield\ShieldNetApi\Reputation;
4
+
5
+ use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Components\IpAddressConsumer;
6
+ use FernleafSystems\Wordpress\Plugin\Shield\ShieldNetApi\Common;
7
+
8
+ class GetIPReputation extends Common\BaseShieldNetApi {
9
+
10
+ const API_ACTION = 'ip/reputation';
11
+ use IpAddressConsumer;
12
+
13
+ public function retrieve() :array {
14
+ $this->shield_net_params_required = false;
15
+ $raw = $this->sendReq();
16
+ return ( is_array( $raw ) && empty( $raw[ 'error' ] ) ) ? $raw[ 'data' ] : [];
17
+ }
18
+
19
+ protected function getApiRequestUrl() :string {
20
+ return sprintf( '%s/%s', parent::getApiRequestUrl(), $this->getIP() );
21
+ }
22
+ }
src/lib/src/ShieldNetApi/Reputation/SendIPReputation.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php declare( strict_types=1 );
2
+
3
+ namespace FernleafSystems\Wordpress\Plugin\Shield\ShieldNetApi\Reputation;
4
+
5
+ use FernleafSystems\Wordpress\Plugin\Shield\ShieldNetApi\Common;
6
+
7
+ class SendIPReputation extends Common\BaseShieldNetApi {
8
+
9
+ const API_ACTION = 'ip/reputation/receive';
10
+
11
+ public function send( array $signalsData ) :bool {
12
+ $this->request_method = 'post';
13
+ $this->shield_net_params_required = false;
14
+ $this->params_body = [
15
+ 'ip_signals' => $signalsData,
16
+ ];
17
+ $raw = $this->sendReq();
18
+ return is_array( $raw ) && empty( $raw[ 'error' ] );
19
+ }
20
+ }
src/lib/src/ShieldNetApi/ShieldNetApiController.php CHANGED
@@ -3,9 +3,12 @@
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\ShieldNetApi;
4
 
5
  use FernleafSystems\Utilities\Data\Adapter\DynPropertiesClass;
 
 
6
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
7
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\Plugin;
8
  use FernleafSystems\Wordpress\Plugin\Shield\ShieldNetApi;
 
9
  use FernleafSystems\Wordpress\Services\Services;
10
 
11
  /**
@@ -16,6 +19,7 @@ use FernleafSystems\Wordpress\Services\Services;
16
  class ShieldNetApiController extends DynPropertiesClass {
17
 
18
  use ModConsumer;
 
19
 
20
  /**
21
  * Automatically throttles request because otherwise PRO-nulled versions of Shield will cause
@@ -31,7 +35,7 @@ class ShieldNetApiController extends DynPropertiesClass {
31
  $now = Services::Request()->ts();
32
  if ( $this->vo->last_handshake_at === 0 ) {
33
 
34
- $canAttempt = $now - MINUTE_IN_SECONDS*5*$this->vo->handshake_fail_count
35
  > $this->vo->last_handshake_attempt_at;
36
  if ( $canAttempt ) {
37
  $handshakeSuccess = ( new ShieldNetApi\Handshake\Verify() )
@@ -54,6 +58,7 @@ class ShieldNetApiController extends DynPropertiesClass {
54
  }
55
 
56
  public function storeVoData() {
 
57
  $this->getOptions()->setOpt( 'snapi_data', $this->vo->getRawData() );
58
  $this->getMod()->saveModOptions();
59
  }
@@ -86,4 +91,51 @@ class ShieldNetApiController extends DynPropertiesClass {
86
 
87
  return $value;
88
  }
89
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\ShieldNetApi;
4
 
5
  use FernleafSystems\Utilities\Data\Adapter\DynPropertiesClass;
6
+ use FernleafSystems\Wordpress\Plugin\Shield\Crons\PluginCronsConsumer;
7
+ use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\Lib\Bots\ShieldNET\BuildData;
8
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\ModConsumer;
9
  use FernleafSystems\Wordpress\Plugin\Shield\Modules\Plugin;
10
  use FernleafSystems\Wordpress\Plugin\Shield\ShieldNetApi;
11
+ use FernleafSystems\Wordpress\Plugin\Shield\ShieldNetApi\Reputation\SendIPReputation;
12
  use FernleafSystems\Wordpress\Services\Services;
13
 
14
  /**
19
  class ShieldNetApiController extends DynPropertiesClass {
20
 
21
  use ModConsumer;
22
+ use PluginCronsConsumer;
23
 
24
  /**
25
  * Automatically throttles request because otherwise PRO-nulled versions of Shield will cause
35
  $now = Services::Request()->ts();
36
  if ( $this->vo->last_handshake_at === 0 ) {
37
 
38
+ $canAttempt = $now - MINUTE_IN_SECONDS*$this->vo->handshake_fail_count
39
  > $this->vo->last_handshake_attempt_at;
40
  if ( $canAttempt ) {
41
  $handshakeSuccess = ( new ShieldNetApi\Handshake\Verify() )
58
  }
59
 
60
  public function storeVoData() {
61
+ $this->vo->data_last_saved_at = Services::Request()->ts();
62
  $this->getOptions()->setOpt( 'snapi_data', $this->vo->getRawData() );
63
  $this->getMod()->saveModOptions();
64
  }
91
 
92
  return $value;
93
  }
94
+
95
+ public function runHourlyCron() {
96
+ $con = $this->getCon();
97
+ $modPlugin = $con->getModule_Plugin();
98
+ /** @var Plugin\Options $modOpts */
99
+ $modOpts = $modPlugin->getOptions();
100
+ if ( is_main_network() && $modOpts->isEnabledShieldNET() && $con->isPremiumActive()
101
+ && $this->canStoreDataReliably() && $this->canHandshake() ) {
102
+
103
+ $this->sendIPReputationData();
104
+ }
105
+ }
106
+
107
+ private function sendIPReputationData() {
108
+ $req = Services::Request();
109
+ if ( $req->carbon()->subDay()->timestamp > $this->vo->last_send_iprep_at ) {
110
+ $this->vo->last_send_iprep_at = $req->ts();
111
+ $this->storeVoData();
112
+
113
+ $data = ( new BuildData() )
114
+ ->setMod( $this->getCon()->getModule_IPs() )
115
+ ->build();
116
+ if ( !empty( $data ) ) {
117
+ ( new SendIPReputation() )
118
+ ->setMod( $this->getMod() )
119
+ ->send( $data );
120
+ }
121
+ }
122
+ }
123
+
124
+ /**
125
+ * Ensuring that previous timestamps are stored recently, we prevent spurious requests being
126
+ * sent to the API when websites can't actually store data to its own options stores.
127
+ *
128
+ * So if the timestamp for the last store is too far in the past, we believe we can't reliably
129
+ * store data.
130
+ */
131
+ private function canStoreDataReliably() :bool {
132
+ if ( Services::Request()->carbon()->subHours( 2 )->timestamp > $this->vo->data_last_saved_at ) {
133
+ $can = false;
134
+ $this->storeVoData();
135
+ }
136
+ else {
137
+ $can = true;
138
+ }
139
+ return $can;
140
+ }
141
+ }
src/lib/src/ShieldNetApi/ShieldNetApiDataVO.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\ShieldNetApi;
4
 
@@ -9,8 +9,10 @@ use FernleafSystems\Utilities\Data\Adapter\DynPropertiesClass;
9
  * @package FernleafSystems\Wordpress\Plugin\Shield\ShieldNetApi
10
  * @property int $last_handshake_at
11
  * @property int $last_handshake_attempt_at
 
12
  * @property int $handshake_fail_count
13
  * @property int[] $nonces
 
14
  */
15
  class ShieldNetApiDataVO extends DynPropertiesClass {
16
 
@@ -30,16 +32,15 @@ class ShieldNetApiDataVO extends DynPropertiesClass {
30
  }
31
  break;
32
 
33
- case 'last_handshake_at':
34
- case 'last_handshake_attempt_at':
35
- case 'handshake_fail_count':
36
- $value = (int)$value;
37
- break;
38
-
39
  default:
40
  break;
41
  }
42
 
 
 
 
 
 
43
  return $value;
44
  }
45
- }
1
+ <?php declare( strict_types=1 );
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\ShieldNetApi;
4
 
9
  * @package FernleafSystems\Wordpress\Plugin\Shield\ShieldNetApi
10
  * @property int $last_handshake_at
11
  * @property int $last_handshake_attempt_at
12
+ * @property int $last_send_iprep_at
13
  * @property int $handshake_fail_count
14
  * @property int[] $nonces
15
+ * @property int $data_last_saved_at
16
  */
17
  class ShieldNetApiDataVO extends DynPropertiesClass {
18
 
32
  }
33
  break;
34
 
 
 
 
 
 
 
35
  default:
36
  break;
37
  }
38
 
39
+ if ( in_array( $key, [ 'handshake_fail_count' ] )
40
+ || preg_match( '#_at$#', $key ) ) {
41
+ $value = (int)$value;
42
+ }
43
+
44
  return $value;
45
  }
46
+ }
src/lib/src/ShieldNetApi/Tools/GenerateGoogleAuthQrCode.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php declare( strict_types=1 );
2
+
3
+ namespace FernleafSystems\Wordpress\Plugin\Shield\ShieldNetApi\Tools;
4
+
5
+ use FernleafSystems\Wordpress\Plugin\Shield\ShieldNetApi\Common;
6
+
7
+ class GenerateGoogleAuthQrCode extends Common\BaseShieldNetApi {
8
+
9
+ const API_ACTION = 'tools/google_auth_qr';
10
+
11
+ public function getCode( string $secret, string $issuer, string $label, string $format = 'png' ) :string {
12
+ $this->shield_net_params_required = false;
13
+ $this->params_query = [
14
+ 'secret' => $secret,
15
+ 'issuer' => $issuer,
16
+ 'label' => $label,
17
+ 'format' => $format,
18
+ ];
19
+ $raw = $this->sendReq();
20
+
21
+ $qrCode = '';
22
+ if ( is_array( $raw ) && empty( $raw[ 'error' ] ) ) {
23
+ $qrCode = $raw[ 'data' ][ 'code' ];
24
+ }
25
+ return $qrCode;
26
+ }
27
+ }
src/lib/src/ShieldNetApi/WPHashes/SolicitToken.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php declare( strict_types=1 );
2
+
3
+ namespace FernleafSystems\Wordpress\Plugin\Shield\ShieldNetApi\WPHashes;
4
+
5
+ use FernleafSystems\Wordpress\Plugin\Shield\ShieldNetApi\Common;
6
+ use FernleafSystems\Wordpress\Services\Services;
7
+
8
+ class SolicitToken extends Common\BaseShieldNetApi {
9
+
10
+ const API_ACTION = 'wphashes/token';
11
+
12
+ public function send() :array {
13
+ $this->shield_net_params_required = false;
14
+ $this->params_query = [
15
+ 'url' => Services::WpGeneral()->getHomeUrl()
16
+ ];
17
+ $raw = $this->sendReq();
18
+ return ( !empty( $raw ) && is_array( $raw[ 'data' ] ) ) ? $raw[ 'data' ] : [];
19
+ }
20
+
21
+ protected function getApiRequestUrl() :string {
22
+ return sprintf( '%s/%s', parent::getApiRequestUrl(), $this->getCon()->getSiteInstallationId() );
23
+ }
24
+ }
src/lib/src/Tables/Build/ScanWpv.php CHANGED
@@ -17,50 +17,50 @@ class ScanWpv extends ScanBase {
17
  * @return array[]
18
  */
19
  public function getEntriesFormatted() :array {
20
- $aEntries = [];
21
 
22
  /** @var ModCon $mod */
23
  $mod = $this->getMod();
24
 
25
- $oWpPlugins = Services::WpPlugins();
26
- $oWpThemes = Services::WpThemes();
27
 
28
  // so that any available update will show
29
- $oWpPlugins->getUpdates( true );
30
- $oWpThemes->getUpdates( true );
31
 
32
  $oConverter = new Scan\Results\ConvertBetweenTypes();
33
- foreach ( $this->getEntriesRaw() as $nKey => $entry ) {
34
  /** @var Shield\Databases\Scanner\EntryVO $entry */
35
- /** @var Shield\Scans\Wpv\ResultItem $oIt */
36
- $oIt = $oConverter
37
  ->setScanController( $mod->getScanCon( $entry->scan ) )
38
  ->convertVoToResultItem( $entry );
39
- $aE = $entry->getRawData();
40
- if ( $oIt->context == 'plugins' ) {
41
- $oAsset = $oWpPlugins->getPluginAsVo( $oIt->slug );
42
- $aE[ 'asset' ] = $oAsset;
43
- $aE[ 'asset_name' ] = $oAsset->Name;
44
- $aE[ 'asset_version' ] = $oAsset->Version;
45
- $aE[ 'can_deactivate' ] = $oWpPlugins->isActive( $oIt->slug );
46
- $aE[ 'has_update' ] = $oWpPlugins->isUpdateAvailable( $oIt->slug );
47
  }
48
  else {
49
- $oAsset = $oWpThemes->getTheme( $oIt->slug );
50
- $aE[ 'asset' ] = $oAsset;
51
- $aE[ 'asset_name' ] = $oAsset->get( 'Name' );
52
- $aE[ 'asset_version' ] = $oAsset->get( 'Version' );
53
- $aE[ 'can_deactivate' ] = false;
54
- $aE[ 'has_update' ] = $oWpThemes->isUpdateAvailable( $oIt->slug );
55
  }
56
- $aE[ 'slug' ] = $oIt->slug;
57
- $aE[ 'wpvuln_vo' ] = $oIt->getWpVulnVo();
58
- $aE[ 'ignored' ] = $this->formatIsIgnored( $entry );
59
- $aE[ 'created_at' ] = $this->formatTimestampField( $entry->created_at );
60
- $aEntries[ $nKey ] = $aE;
61
  }
62
 
63
- return $aEntries;
64
  }
65
 
66
  /**
17
  * @return array[]
18
  */
19
  public function getEntriesFormatted() :array {
20
+ $entries = [];
21
 
22
  /** @var ModCon $mod */
23
  $mod = $this->getMod();
24
 
25
+ $WPP = Services::WpPlugins();
26
+ $WPT = Services::WpThemes();
27
 
28
  // so that any available update will show
29
+ $WPP->getUpdates( true );
30
+ $WPT->getUpdates( true );
31
 
32
  $oConverter = new Scan\Results\ConvertBetweenTypes();
33
+ foreach ( $this->getEntriesRaw() as $key => $entry ) {
34
  /** @var Shield\Databases\Scanner\EntryVO $entry */
35
+ /** @var Shield\Scans\Wpv\ResultItem $item */
36
+ $item = $oConverter
37
  ->setScanController( $mod->getScanCon( $entry->scan ) )
38
  ->convertVoToResultItem( $entry );
39
+ $e = $entry->getRawData();
40
+ if ( $item->context == 'plugins' ) {
41
+ $asset = $WPP->getPluginAsVo( $item->slug );
42
+ $e[ 'asset' ] = $asset;
43
+ $e[ 'asset_name' ] = $asset->Name;
44
+ $e[ 'asset_version' ] = $asset->Version;
45
+ $e[ 'can_deactivate' ] = $WPP->isActive( $item->slug );
46
+ $e[ 'has_update' ] = $WPP->isUpdateAvailable( $item->slug );
47
  }
48
  else {
49
+ $asset = $WPT->getTheme( $item->slug );
50
+ $e[ 'asset' ] = $asset;
51
+ $e[ 'asset_name' ] = $asset->get( 'Name' );
52
+ $e[ 'asset_version' ] = $asset->get( 'Version' );
53
+ $e[ 'can_deactivate' ] = false;
54
+ $e[ 'has_update' ] = $WPT->isUpdateAvailable( $item->slug );
55
  }
56
+ $e[ 'slug' ] = $item->slug;
57
+ $e[ 'wpvuln_vo' ] = $item->getVulnVo();
58
+ $e[ 'ignored' ] = $this->formatIsIgnored( $entry );
59
+ $e[ 'created_at' ] = $this->formatTimestampField( $entry->created_at );
60
+ $entries[ $key ] = $e;
61
  }
62
 
63
+ return $entries;
64
  }
65
 
66
  /**
src/lib/src/Tables/Render/WpCliTable/AuditTrail.php CHANGED
@@ -8,7 +8,6 @@ class AuditTrail extends Base {
8
  $aRows = $this->getDataBuilder()
9
  ->getEntriesFormatted();
10
 
11
- error_log( var_export( array_keys( array_shift( $aRows ) ), true ) );
12
  \WP_CLI\Utils\format_items(
13
  'table',
14
  $aRows,
8
  $aRows = $this->getDataBuilder()
9
  ->getEntriesFormatted();
10
 
 
11
  \WP_CLI\Utils\format_items(
12
  'table',
13
  $aRows,
src/lib/src/Tables/Render/WpListTable/ScanWpv.php CHANGED
@@ -7,37 +7,37 @@ use FernleafSystems\Wordpress\Plugin\Shield\Scans;
7
  class ScanWpv extends ScanBase {
8
 
9
  /**
10
- * @param array $aItem
11
  * @return string
12
  */
13
- public function column_asset( $aItem ) {
14
- $sContent = sprintf( '<span class="asset-title font-weight-bold">%s</span> v%s',
15
- $aItem[ 'asset_name' ], ltrim( $aItem[ 'asset_version' ], 'v' ) );
16
 
17
- $aButtons = [];
18
 
19
- $bHasUpdate = $aItem[ 'has_update' ];
20
- $aButtons[] = $this->buildActionButton_Custom(
21
- $bHasUpdate ? __( 'Apply Update', 'wp-simple-firewall' ) : __( 'No Update Available', 'wp-simple-firewall' ),
22
- [ ( $bHasUpdate ? 'custom-action text-success' : 'disabled' ) ],
23
  [
24
- 'rid' => $aItem[ 'id' ],
25
  'custom-action' => 'item_repair'
26
  ]
27
  );
28
 
29
- if ( $aItem[ 'can_deactivate' ] ) {
30
- $aButtons[] = $this->buildActionButton_Custom(
31
  __( 'Deactivate', 'wp-simple-firewall' ),
32
  [ 'custom-action' ],
33
  [
34
- 'rid' => $aItem[ 'id' ],
35
  'custom-action' => 'item_asset_deactivate'
36
  ]
37
  );
38
  }
39
 
40
- return $sContent.$this->buildActions( $aButtons );
41
  }
42
 
43
  /**
@@ -45,16 +45,30 @@ class ScanWpv extends ScanBase {
45
  * @return string
46
  */
47
  public function column_vulnerability( $item ) {
48
- /** @var Scans\Wpv\WpVulnDb\WpVulnVO $vuln */
49
- $vuln = $item[ 'wpvuln_vo' ];
50
- $sContent = sprintf( '<span class="vuln-title">%s</span>', $vuln->title );
51
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  $buttons = [
53
  $this->getActionButton_Ignore( $item[ 'id' ] ),
54
  sprintf( '<a href="%s" class="btn btn-sm btn-link text-info" target="_blank">%s</a>',
55
- $vuln->url, __( 'More Info', 'wp-simple-firewall' ) ),
56
  ];
57
- return $sContent.$this->buildActions( $buttons );
58
  }
59
 
60
  /**
7
  class ScanWpv extends ScanBase {
8
 
9
  /**
10
+ * @param array $item
11
  * @return string
12
  */
13
+ public function column_asset( $item ) {
14
+ $content = sprintf( '<span class="asset-title font-weight-bold">%s</span> v%s',
15
+ $item[ 'asset_name' ], ltrim( $item[ 'asset_version' ], 'v' ) );
16
 
17
+ $buttons = [];
18
 
19
+ $hasUpdate = $item[ 'has_update' ];
20
+ $buttons[] = $this->buildActionButton_Custom(
21
+ $hasUpdate ? __( 'Apply Update', 'wp-simple-firewall' ) : __( 'No Update Available', 'wp-simple-firewall' ),
22
+ [ ( $hasUpdate ? 'custom-action text-success' : 'disabled' ) ],
23
  [
24
+ 'rid' => $item[ 'id' ],
25
  'custom-action' => 'item_repair'
26
  ]
27
  );
28
 
29
+ if ( $item[ 'can_deactivate' ] ) {
30
+ $buttons[] = $this->buildActionButton_Custom(
31
  __( 'Deactivate', 'wp-simple-firewall' ),
32
  [ 'custom-action' ],
33
  [
34
+ 'rid' => $item[ 'id' ],
35
  'custom-action' => 'item_asset_deactivate'
36
  ]
37
  );
38
  }
39
 
40
+ return $content.$this->buildActions( $buttons );
41
  }
42
 
43
  /**
45
  * @return string
46
  */
47
  public function column_vulnerability( $item ) {
48
+ /** @var Scans\Wpv\WpVulnDb\VulnVO $vul */
49
+ $vul = $item[ 'wpvuln_vo' ];
50
+ $content = sprintf( '<span class="vuln-title">%s</span>', $vul->title );
51
 
52
+ if ( $vul->provider === 'patchstack' ) {
53
+ $url = $vul->references[ 0 ];
54
+ }
55
+ elseif ( $vul->provider === 'wpscan' ) {
56
+ if ( empty( $vul->references[ 'url' ] ) ) {
57
+ $url = sprintf( 'https://wpscan.com/vulnerability/%s', $vul->id );
58
+ }
59
+ else {
60
+ $url = $vul->references[ 'url' ][ 0 ];
61
+ }
62
+ }
63
+ else {
64
+ $url = '';
65
+ }
66
  $buttons = [
67
  $this->getActionButton_Ignore( $item[ 'id' ] ),
68
  sprintf( '<a href="%s" class="btn btn-sm btn-link text-info" target="_blank">%s</a>',
69
+ $url, __( 'More Info', 'wp-simple-firewall' ) ),
70
  ];
71
+ return $content.$this->buildActions( $buttons );
72
  }
73
 
74
  /**
src/lib/src/Tests/VerifyConfig.php CHANGED
@@ -9,35 +9,35 @@ class VerifyConfig {
9
  use OptsConsumer;
10
 
11
  public function run() {
12
- $oOpts = $this->getOpts();
13
- foreach ( $oOpts->getOptionsKeys() as $sKey ) {
14
- $sOptType = $oOpts->getOptionType( $sKey );
15
- if ( empty( $sOptType ) ) {
16
  var_dump( $sKey.': no type' );
17
  continue;
18
  }
19
 
20
- $mDefault = $oOpts->getOptDefault( $sKey );
21
  if ( is_null( $mDefault ) ) {
22
  var_dump( sprintf( '%s: opt has no default.', $sKey ) );
23
  continue;
24
  }
25
 
26
- $mVal = $oOpts->getOpt( $sKey );
27
- $sValType = gettype( $mVal );
28
 
29
- $bBroken = false;
30
- switch ( $sOptType ) {
31
 
32
  case 'integer':
33
- if ( $sValType != 'integer' ) {
34
- $bBroken = true;
35
  }
36
  break;
37
 
38
  case 'text':
39
- if ( $sValType != 'string' ) {
40
- $bBroken = true;
41
  }
42
  break;
43
 
@@ -45,10 +45,10 @@ class VerifyConfig {
45
  break;
46
  }
47
 
48
- if ( $bBroken ) {
49
  var_dump( sprintf( '%s: opt type is %s, value is %s at "%s". Default is: %s',
50
- $sKey, $sOptType, $sValType, var_export( $mVal, true ), $oOpts->getOptDefault( $sKey ) ) );
51
- // $oOpts->resetOptToDefault( $sKey );
52
  }
53
  }
54
  }
9
  use OptsConsumer;
10
 
11
  public function run() {
12
+ $opts = $this->getOpts();
13
+ foreach ( $opts->getOptionsKeys() as $sKey ) {
14
+ $optType = $opts->getOptionType( $sKey );
15
+ if ( empty( $optType ) ) {
16
  var_dump( $sKey.': no type' );
17
  continue;
18
  }
19
 
20
+ $mDefault = $opts->getOptDefault( $sKey );
21
  if ( is_null( $mDefault ) ) {
22
  var_dump( sprintf( '%s: opt has no default.', $sKey ) );
23
  continue;
24
  }
25
 
26
+ $mVal = $opts->getOpt( $sKey );
27
+ $valType = gettype( $mVal );
28
 
29
+ $isBroken = false;
30
+ switch ( $optType ) {
31
 
32
  case 'integer':
33
+ if ( $valType != 'integer' ) {
34
+ $isBroken = true;
35
  }
36
  break;
37
 
38
  case 'text':
39
+ if ( $valType != 'string' ) {
40
+ $isBroken = true;
41
  }
42
  break;
43
 
45
  break;
46
  }
47
 
48
+ if ( $isBroken ) {
49
  var_dump( sprintf( '%s: opt type is %s, value is %s at "%s". Default is: %s',
50
+ $sKey, $optType, $valType, var_export( $mVal, true ), $opts->getOptDefault( $sKey ) ) );
51
+ // $opts->resetOptToDefault( $sKey );
52
  }
53
  }
54
  }
src/lib/src/Tests/VerifyUniqueEvents.php CHANGED
@@ -14,10 +14,10 @@ class VerifyUniqueEvents {
14
  use PluginControllerConsumer;
15
 
16
  public function run() {
17
- $oCon = $this->getCon();
18
 
19
  $aAllKeys = [];
20
- foreach ( $oCon->modules as $mod ) {
21
  $aKeys = array_map(
22
  function ( $aEvt ) {
23
  return $aEvt[ 'key' ];
14
  use PluginControllerConsumer;
15
 
16
  public function run() {
17
+ $con = $this->getCon();
18
 
19
  $aAllKeys = [];
20
+ foreach ( $con->modules as $mod ) {
21
  $aKeys = array_map(
22
  function ( $aEvt ) {
23
  return $aEvt[ 'key' ];
src/lib/src/Users/ShieldUserMeta.php CHANGED
@@ -7,6 +7,7 @@ use FernleafSystems\Wordpress\Services\Services;
7
  /**
8
  * Class UserMeta
9
  * @package FernleafSystems\Wordpress\Plugin\Shield\Users
 
10
  * @property array $email_secret
11
  * @property bool $email_validated
12
  * @property string $backupcode_secret
7
  /**
8
  * Class UserMeta
9
  * @package FernleafSystems\Wordpress\Plugin\Shield\Users
10
+ * @property array $login_intents
11
  * @property array $email_secret
12
  * @property bool $email_validated
13
  * @property string $backupcode_secret
src/lib/src/Utilities/Consumer/WpLoginCapture.php CHANGED
@@ -11,6 +11,11 @@ trait WpLoginCapture {
11
  */
12
  private $isLoginCaptured = false;
13
 
 
 
 
 
 
14
  /**
15
  * @var bool
16
  */
@@ -72,6 +77,11 @@ trait WpLoginCapture {
72
  return $this;
73
  }
74
 
 
 
 
 
 
75
  protected function setupLoginCaptureHooks() {
76
  add_action( 'wp_login', [ $this, 'onWpLogin' ], $this->getHookPriority(), 2 );
77
  if ( !Services::WpUsers()->isProfilePage() ) { // Ignore firing during profile update.
@@ -90,7 +100,9 @@ trait WpLoginCapture {
90
  if ( is_string( $cookie ) ) {
91
  $this->setLoggedInCookie( $cookie );
92
  }
93
- if ( $this->isLoginToBeCaptured() && !$this->isLoginCaptured() && $user instanceof \WP_User ) {
 
 
94
  $this->setLoginCaptured();
95
  $this->captureLogin( $user );
96
  }
@@ -101,7 +113,9 @@ trait WpLoginCapture {
101
  * @param \WP_User $user
102
  */
103
  public function onWpLogin( $username, $user ) {
104
- if ( $this->isLoginToBeCaptured() && !$this->isLoginCaptured() && $user instanceof \WP_User ) {
 
 
105
  $this->setLoginCaptured();
106
  $this->captureLogin( $user );
107
  }
11
  */
12
  private $isLoginCaptured = false;
13
 
14
+ /**
15
+ * @var bool
16
+ */
17
+ private $allowMultipleCapture = false;
18
+
19
  /**
20
  * @var bool
21
  */
77
  return $this;
78
  }
79
 
80
+ protected function setAllowMultipleCapture( bool $multiple = true ) :self {
81
+ $this->allowMultipleCapture = $multiple;
82
+ return $this;
83
+ }
84
+
85
  protected function setupLoginCaptureHooks() {
86
  add_action( 'wp_login', [ $this, 'onWpLogin' ], $this->getHookPriority(), 2 );
87
  if ( !Services::WpUsers()->isProfilePage() ) { // Ignore firing during profile update.
100
  if ( is_string( $cookie ) ) {
101
  $this->setLoggedInCookie( $cookie );
102
  }
103
+ if ( $user instanceof \WP_User
104
+ && $this->isLoginToBeCaptured()
105
+ && ( $this->allowMultipleCapture || !$this->isLoginCaptured() ) ) {
106
  $this->setLoginCaptured();
107
  $this->captureLogin( $user );
108
  }
113
  * @param \WP_User $user
114
  */
115
  public function onWpLogin( $username, $user ) {
116
+ if ( $user instanceof \WP_User
117
+ && $this->isLoginToBeCaptured()
118
+ && ( $this->allowMultipleCapture || !$this->isLoginCaptured() ) ) {
119
  $this->setLoginCaptured();
120
  $this->captureLogin( $user );
121
  }
src/lib/src/Utilities/Tool/TmpFileStore.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php declare( strict_types=1 );
2
+
3
+ namespace FernleafSystems\Wordpress\Plugin\Shield\Utilities\Tool;
4
+
5
+ use FernleafSystems\Wordpress\Plugin\Shield\Modules\PluginControllerConsumer;
6
+ use FernleafSystems\Wordpress\Services\Services;
7
+
8
+ class TmpFileStore {
9
+
10
+ use PluginControllerConsumer;
11
+
12
+ private static $slugs = [];
13
+
14
+ /**
15
+ * @throws \Exception
16
+ */
17
+ public function __construct() {
18
+ if ( $this->getCon()->hasCacheDir() ) {
19
+ add_action( $this->getCon()->prefix( 'plugin_shutdown' ), function () {
20
+ $FS = Services::WpFs();
21
+ foreach ( self::$slugs as $slug ) {
22
+ $FS->deleteFile( path_join( $this->getTmpDir(), $slug ) );
23
+ }
24
+ } );
25
+ }
26
+ else {
27
+ throw new \Exception( "Can't create the cache dir" );
28
+ }
29
+ }
30
+
31
+ /**
32
+ * @param string $slug
33
+ * @return mixed|null
34
+ */
35
+ public function load( string $slug ) {
36
+ $data = Services::WpFs()->getFileContent( path_join( $this->getTmpDir(), $slug ) );
37
+ return empty( $data ) ? null : unserialize( $data );
38
+ }
39
+
40
+ public function store( string $slug, $data ) {
41
+ Services::WpFs()->putFileContent( path_join( $this->getTmpDir(), $slug ), serialize( $data ) );
42
+ self::$slugs[] = $slug;
43
+ }
44
+
45
+ private function getTmpDir() :string {
46
+ return path_join( $this->getCon()->getPluginCachePath(), 'tmp_files' );
47
+ }
48
+ }
src/lib/vendor/bacon/bacon-qr-code/Module.php DELETED
@@ -1,37 +0,0 @@
1
- <?php
2
- /**
3
- * BaconQrCode
4
- *
5
- * @link http://github.com/Bacon/BaconQrCode For the canonical source repository
6
- * @copyright 2013 Ben 'DASPRiD' Scholzen
7
- * @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
8
- */
9
-
10
- namespace BaconQrCode;
11
-
12
- use Zend\ModuleManager\Feature\AutoloaderProviderInterface;
13
-
14
- /**
15
- * Module for generating QR codes.
16
- */
17
- class Module implements AutoloaderProviderInterface
18
- {
19
- /**
20
- * Get autoloader config.
21
- *
22
- * @return array
23
- */
24
- public function getAutoloaderConfig()
25
- {
26
- return array(
27
- 'Zend\Loader\ClassMapAutoloader' => array(
28
- __DIR__ . '/autoload_classmap.php',
29
- ),
30
- 'Zend\Loader\StandardAutoloader' => array(
31
- 'namespaces' => array(
32
- __NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
33
- ),
34
- ),
35
- );
36
- }
37
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Common/AbstractEnum.php DELETED
@@ -1,115 +0,0 @@
1
- <?php
2
- /**
3
- * BaconQrCode
4
- *
5
- * @link http://github.com/Bacon/BaconQrCode For the canonical source repository
6
- * @copyright 2013 Ben 'DASPRiD' Scholzen
7
- * @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
8
- */
9
-
10
- namespace BaconQrCode\Common;
11
-
12
- use BaconQrCode\Exception;
13
- use ReflectionClass;
14
-
15
- /**
16
- * A general enum implementation until we got SplEnum.
17
- */
18
- abstract class AbstractEnum
19
- {
20
- /**
21
- * Default value.
22
- */
23
- const __default = null;
24
-
25
- /**
26
- * Current value.
27
- *
28
- * @var mixed
29
- */
30
- protected $value;
31
-
32
- /**
33
- * Cache of constants.
34
- *
35
- * @var array
36
- */
37
- protected $constants;
38
-
39
- /**
40
- * Whether to handle values strict or not.
41
- *
42
- * @var boolean
43
- */
44
- protected $strict;
45
-
46
- /**
47
- * Creates a new enum.
48
- *
49
- * @param mixed $initialValue
50
- * @param boolean $strict
51
- */
52
- public function __construct($initialValue = null, $strict = false)
53
- {
54
- $this->strict = $strict;
55
- $this->change($initialValue);
56
- }
57
-
58
- /**
59
- * Changes the value of the enum.
60
- *
61
- * @param mixed $value
62
- * @return void
63
- */
64
- public function change($value)
65
- {
66
- if (!in_array($value, $this->getConstList(), $this->strict)) {
67
- throw new Exception\UnexpectedValueException('Value not a const in enum ' . get_class($this));
68
- }
69
-
70
- $this->value = $value;
71
- }
72
-
73
- /**
74
- * Gets current value.
75
- *
76
- * @return mixed
77
- */
78
- public function get()
79
- {
80
- return $this->value;
81
- }
82
-
83
- /**
84
- * Gets all constants (possible values) as an array.
85
- *
86
- * @param boolean $includeDefault
87
- * @return array
88
- */
89
- public function getConstList($includeDefault = true)
90
- {
91
- if ($this->constants === null) {
92
- $reflection = new ReflectionClass($this);
93
- $this->constants = $reflection->getConstants();
94
- }
95
-
96
- if ($includeDefault) {
97
- return $this->constants;
98
- }
99
-
100
- $constants = $this->constants;
101
- unset($constants['__default']);
102
-
103
- return $constants;
104
- }
105
-
106
- /**
107
- * Gets the name of the enum.
108
- *
109
- * @return string
110
- */
111
- public function __toString()
112
- {
113
- return array_search($this->value, $this->getConstList());
114
- }
115
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Common/BitArray.php DELETED
@@ -1,435 +0,0 @@
1
- <?php
2
- /**
3
- * BaconQrCode
4
- *
5
- * @link http://github.com/Bacon/BaconQrCode For the canonical source repository
6
- * @copyright 2013 Ben 'DASPRiD' Scholzen
7
- * @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
8
- */
9
-
10
- namespace BaconQrCode\Common;
11
-
12
- use SplFixedArray;
13
-
14
- /**
15
- * A simple, fast array of bits.
16
- */
17
- class BitArray
18
- {
19
- /**
20
- * Bits represented as an array of integers.
21
- *
22
- * @var SplFixedArray
23
- */
24
- protected $bits;
25
-
26
- /**
27
- * Size of the bit array in bits.
28
- *
29
- * @var integer
30
- */
31
- protected $size;
32
-
33
- /**
34
- * Creates a new bit array with a given size.
35
- *
36
- * @param integer $size
37
- */
38
- public function __construct($size = 0)
39
- {
40
- $this->size = $size;
41
- $this->bits = new SplFixedArray(($this->size + 31) >> 3);
42
- }
43
-
44
- /**
45
- * Gets the size in bits.
46
- *
47
- * @return integer
48
- */
49
- public function getSize()
50
- {
51
- return $this->size;
52
- }
53
-
54
- /**
55
- * Gets the size in bytes.
56
- *
57
- * @return integer
58
- */
59
- public function getSizeInBytes()
60
- {
61
- return ($this->size + 7) >> 3;
62
- }
63
-
64
- /**
65
- * Ensures that the array has a minimum capacity.
66
- *
67
- * @param integer $size
68
- * @return void
69
- */
70
- public function ensureCapacity($size)
71
- {
72
- if ($size > count($this->bits) << 5) {
73
- $this->bits->setSize(($size + 31) >> 5);
74
- }
75
- }
76
-
77
- /**
78
- * Gets a specific bit.
79
- *
80
- * @param integer $i
81
- * @return boolean
82
- */
83
- public function get($i)
84
- {
85
- return ($this->bits[$i >> 5] & (1 << ($i & 0x1f))) !== 0;
86
- }
87
-
88
- /**
89
- * Sets a specific bit.
90
- *
91
- * @param integer $i
92
- * @return void
93
- */
94
- public function set($i)
95
- {
96
- $this->bits[$i >> 5] = $this->bits[$i >> 5] | 1 << ($i & 0x1f);
97
- }
98
-
99
- /**
100
- * Flips a specific bit.
101
- *
102
- * @param integer $i
103
- * @return void
104
- */
105
- public function flip($i)
106
- {
107
- $this->bits[$i >> 5] ^= 1 << ($i & 0x1f);
108
- }
109
-
110
- /**
111
- * Gets the next set bit position from a given position.
112
- *
113
- * @param integer $from
114
- * @return integer
115
- */
116
- public function getNextSet($from)
117
- {
118
- if ($from >= $this->size) {
119
- return $this->size;
120
- }
121
-
122
- $bitsOffset = $from >> 5;
123
- $currentBits = $this->bits[$bitsOffset];
124
- $bitsLength = count($this->bits);
125
-
126
- $currentBits &= ~((1 << ($from & 0x1f)) - 1);
127
-
128
- while ($currentBits === 0) {
129
- if (++$bitsOffset === $bitsLength) {
130
- return $this->size;
131
- }
132
-
133
- $currentBits = $this->bits[$bitsOffset];
134
- }
135
-
136
- $result = ($bitsOffset << 5) + BitUtils::numberOfTrailingZeros($currentBits);
137
-
138
- return $result > $this->size ? $this->size : $result;
139
- }
140
-
141
- /**
142
- * Gets the next unset bit position from a given position.
143
- *
144
- * @param integer $from
145
- * @return integer
146
- */
147
- public function getNextUnset($from)
148
- {
149
- if ($from >= $this->size) {
150
- return $this->size;
151
- }
152
-
153
- $bitsOffset = $from >> 5;
154
- $currentBits = ~$this->bits[$bitsOffset];
155
- $bitsLength = count($this->bits);
156
-
157
- $currentBits &= ~((1 << ($from & 0x1f)) - 1);
158
-
159
- while ($currentBits === 0) {
160
- if (++$bitsOffset === $bitsLength) {
161
- return $this->size;
162
- }
163
-
164
- $currentBits = ~$this->bits[$bitsOffset];
165
- }
166
-
167
- $result = ($bitsOffset << 5) + BitUtils::numberOfTrailingZeros($currentBits);
168
-
169
- return $result > $this->size ? $this->size : $result;
170
- }
171
-
172
- /**
173
- * Sets a bulk of bits.
174
- *
175
- * @param integer $i
176
- * @param integer $newBits
177
- * @return void
178
- */
179
- public function setBulk($i, $newBits)
180
- {
181
- $this->bits[$i >> 5] = $newBits;
182
- }
183
-
184
- /**
185
- * Sets a range of bits.
186
- *
187
- * @param integer $start
188
- * @param integer $end
189
- * @return void
190
- * @throws Exception\InvalidArgumentException
191
- */
192
- public function setRange($start, $end)
193
- {
194
- if ($end < $start) {
195
- throw new Exception\InvalidArgumentException('End must be greater or equal to start');
196
- }
197
-
198
- if ($end === $start) {
199
- return;
200
- }
201
-
202
- $end--;
203
-
204
- $firstInt = $start >> 5;
205
- $lastInt = $end >> 5;
206
-
207
- for ($i = $firstInt; $i <= $lastInt; $i++) {
208
- $firstBit = $i > $firstInt ? 0 : $start & 0x1f;
209
- $lastBit = $i < $lastInt ? 31 : $end & 0x1f;
210
-
211
- if ($firstBit === 0 && $lastBit === 31) {
212
- $mask = 0x7fffffff;
213
- } else {
214
- $mask = 0;
215
-
216
- for ($j = $firstBit; $j < $lastBit; $j++) {
217
- $mask |= 1 << $j;
218
- }
219
- }
220
-
221
- $this->bits[$i] = $this->bits[$i] | $mask;
222
- }
223
- }
224
-
225
- /**
226
- * Clears the bit array, unsetting every bit.
227
- *
228
- * @return void
229
- */
230
- public function clear()
231
- {
232
- $bitsLength = count($this->bits);
233
-
234
- for ($i = 0; $i < $bitsLength; $i++) {
235
- $this->bits[$i] = 0;
236
- }
237
- }
238
-
239
- /**
240
- * Checks if a range of bits is set or not set.
241
- *
242
- * @param integer $start
243
- * @param integer $end
244
- * @param integer $value
245
- * @return boolean
246
- * @throws Exception\InvalidArgumentException
247
- */
248
- public function isRange($start, $end, $value)
249
- {
250
- if ($end < $start) {
251
- throw new Exception\InvalidArgumentException('End must be greater or equal to start');
252
- }
253
-
254
- if ($end === $start) {
255
- return;
256
- }
257
-
258
- $end--;
259
-
260
- $firstInt = $start >> 5;
261
- $lastInt = $end >> 5;
262
-
263
- for ($i = $firstInt; $i <= $lastInt; $i++) {
264
- $firstBit = $i > $firstInt ? 0 : $start & 0x1f;
265
- $lastBit = $i < $lastInt ? 31 : $end & 0x1f;
266
-
267
- if ($firstBit === 0 && $lastBit === 31) {
268
- $mask = 0x7fffffff;
269
- } else {
270
- $mask = 0;
271
-
272
- for ($j = $firstBit; $j <= $lastBit; $j++) {
273
- $mask |= 1 << $j;
274
- }
275
- }
276
-
277
- if (($this->bits[$i] & $mask) !== ($value ? $mask : 0)) {
278
- return false;
279
- }
280
- }
281
-
282
- return true;
283
- }
284
-
285
- /**
286
- * Appends a bit to the array.
287
- *
288
- * @param boolean $bit
289
- * @return void
290
- */
291
- public function appendBit($bit)
292
- {
293
- $this->ensureCapacity($this->size + 1);
294
-
295
- if ($bit) {
296
- $this->bits[$this->size >> 5] = $this->bits[$this->size >> 5] | (1 << ($this->size & 0x1f));
297
- }
298
-
299
- $this->size++;
300
- }
301
-
302
- /**
303
- * Appends a number of bits (up to 32) to the array.
304
- *
305
- * @param integer $value
306
- * @param integer $numBits
307
- * @return void
308
- * @throws Exception\InvalidArgumentException
309
- */
310
- public function appendBits($value, $numBits)
311
- {
312
- if ($numBits < 0 || $numBits > 32) {
313
- throw new Exception\InvalidArgumentException('Num bits must be between 0 and 32');
314
- }
315
-
316
- $this->ensureCapacity($this->size + $numBits);
317
-
318
- for ($numBitsLeft = $numBits; $numBitsLeft > 0; $numBitsLeft--) {
319
- $this->appendBit((($value >> ($numBitsLeft - 1)) & 0x01) === 1);
320
- }
321
- }
322
-
323
- /**
324
- * Appends another bit array to this array.
325
- *
326
- * @param BitArray $other
327
- * @return void
328
- */
329
- public function appendBitArray(self $other)
330
- {
331
- $otherSize = $other->getSize();
332
- $this->ensureCapacity($this->size + $other->getSize());
333
-
334
- for ($i = 0; $i < $otherSize; $i++) {
335
- $this->appendBit($other->get($i));
336
- }
337
- }
338
-
339
- /**
340
- * Makes an exclusive-or comparision on the current bit array.
341
- *
342
- * @param BitArray $other
343
- * @return void
344
- * @throws Exception\InvalidArgumentException
345
- */
346
- public function xorBits(self $other)
347
- {
348
- $bitsLength = count($this->bits);
349
- $otherBits = $other->getBitArray();
350
-
351
- if ($bitsLength !== count($otherBits)) {
352
- throw new Exception\InvalidArgumentException('Sizes don\'t match');
353
- }
354
-
355
- for ($i = 0; $i < $bitsLength; $i++) {
356
- $this->bits[$i] = $this->bits[$i] ^ $otherBits[$i];
357
- }
358
- }
359
-
360
- /**
361
- * Converts the bit array to a byte array.
362
- *
363
- * @param integer $bitOffset
364
- * @param integer $numBytes
365
- * @return SplFixedArray
366
- */
367
- public function toBytes($bitOffset, $numBytes)
368
- {
369
- $bytes = new SplFixedArray($numBytes);
370
-
371
- for ($i = 0; $i < $numBytes; $i++) {
372
- $byte = 0;
373
-
374
- for ($j = 0; $j < 8; $j++) {
375
- if ($this->get($bitOffset)) {
376
- $byte |= 1 << (7 - $j);
377
- }
378
-
379
- $bitOffset++;
380
- }
381
-
382
- $bytes[$i] = $byte;
383
- }
384
-
385
- return $bytes;
386
- }
387
-
388
- /**
389
- * Gets the internal bit array.
390
- *
391
- * @return SplFixedArray
392
- */
393
- public function getBitArray()
394
- {
395
- return $this->bits;
396
- }
397
-
398
- /**
399
- * Reverses the array.
400
- *
401
- * @return void
402
- */
403
- public function reverse()
404
- {
405
- $newBits = new SplFixedArray(count($this->bits));
406
-
407
- for ($i = 0; $i < $this->size; $i++) {
408
- if ($this->get($this->size - $i - 1)) {
409
- $newBits[$i >> 5] = $newBits[$i >> 5] | (1 << ($i & 0x1f));
410
- }
411
- }
412
-
413
- $this->bits = newBits;
414
- }
415
-
416
- /**
417
- * Returns a string representation of the bit array.
418
- *
419
- * @return string
420
- */
421
- public function __toString()
422
- {
423
- $result = '';
424
-
425
- for ($i = 0; $i < $this->size; $i++) {
426
- if (($i & 0x07) === 0) {
427
- $result .= ' ';
428
- }
429
-
430
- $result .= $this->get($i) ? 'X' : '.';
431
- }
432
-
433
- return $result;
434
- }
435
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Common/BitMatrix.php DELETED
@@ -1,350 +0,0 @@
1
- <?php
2
- /**
3
- * BaconQrCode
4
- *
5
- * @link http://github.com/Bacon/BaconQrCode For the canonical source repository
6
- * @copyright 2013 Ben 'DASPRiD' Scholzen
7
- * @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
8
- */
9
-
10
- namespace BaconQrCode\Common;
11
-
12
- use SplFixedArray;
13
-
14
- /**
15
- * Bit matrix.
16
- *
17
- * Represents a 2D matrix of bits. In function arguments below, and throughout
18
- * the common module, x is the column position, and y is the row position. The
19
- * ordering is always x, y. The origin is at the top-left.
20
- */
21
- class BitMatrix
22
- {
23
- /**
24
- * Width of the bit matrix.
25
- *
26
- * @var integer
27
- */
28
- protected $width;
29
-
30
- /**
31
- * Height of the bit matrix.
32
- *
33
- * @var integer
34
- */
35
- protected $height;
36
-
37
- /**
38
- * Size in bits of each individual row.
39
- *
40
- * @var integer
41
- */
42
- protected $rowSize;
43
-
44
- /**
45
- * Bits representation.
46
- *
47
- * @var SplFixedArray
48
- */
49
- protected $bits;
50
-
51
- /**
52
- * Creates a new bit matrix with given dimensions.
53
- *
54
- * @param integer $width
55
- * @param integer|null $height
56
- * @throws Exception\InvalidArgumentException
57
- */
58
- public function __construct($width, $height = null)
59
- {
60
- if ($height === null) {
61
- $height = $width;
62
- }
63
-
64
- if ($width < 1 || $height < 1) {
65
- throw new Exception\InvalidArgumentException('Both dimensions must be greater than zero');
66
- }
67
-
68
- $this->width = $width;
69
- $this->height = $height;
70
- $this->rowSize = ($width + 31) >> 5;
71
- $this->bits = new SplFixedArray($this->rowSize * $height);
72
- }
73
-
74
- /**
75
- * Gets the requested bit, where true means black.
76
- *
77
- * @param integer $x
78
- * @param integer $y
79
- * @return boolean
80
- */
81
- public function get($x, $y)
82
- {
83
- $offset = $y * $this->rowSize + ($x >> 5);
84
- return (BitUtils::unsignedRightShift($this->bits[$offset], ($x & 0x1f)) & 1) !== 0;
85
- }
86
-
87
- /**
88
- * Sets the given bit to true.
89
- *
90
- * @param integer $x
91
- * @param integer $y
92
- * @return void
93
- */
94
- public function set($x, $y)
95
- {
96
- $offset = $y * $this->rowSize + ($x >> 5);
97
- $this->bits[$offset] = $this->bits[$offset] | (1 << ($x & 0x1f));
98
- }
99
-
100
- /**
101
- * Flips the given bit.
102
- *
103
- * @param integer $x
104
- * @param integer $y
105
- * @return void
106
- */
107
- public function flip($x, $y)
108
- {
109
- $offset = $y * $this->rowSize + ($x >> 5);
110
- $this->bits[$offset] = $this->bits[$offset] ^ (1 << ($x & 0x1f));
111
- }
112
-
113
- /**
114
- * Clears all bits (set to false).
115
- *
116
- * @return void
117
- */
118
- public function clear()
119
- {
120
- $max = count($this->bits);
121
-
122
- for ($i = 0; $i < $max; $i++) {
123
- $this->bits[$i] = 0;
124
- }
125
- }
126
-
127
- /**
128
- * Sets a square region of the bit matrix to true.
129
- *
130
- * @param integer $left
131
- * @param integer $top
132
- * @param integer $width
133
- * @param integer $height
134
- * @return void
135
- */
136
- public function setRegion($left, $top, $width, $height)
137
- {
138
- if ($top < 0 || $left < 0) {
139
- throw new Exception\InvalidArgumentException('Left and top must be non-negative');
140
- }
141
-
142
- if ($height < 1 || $width < 1) {
143
- throw new Exception\InvalidArgumentException('Width and height must be at least 1');
144
- }
145
-
146
- $right = $left + $width;
147
- $bottom = $top + $height;
148
-
149
- if ($bottom > $this->height || $right > $this->width) {
150
- throw new Exception\InvalidArgumentException('The region must fit inside the matrix');
151
- }
152
-
153
- for ($y = $top; $y < $bottom; $y++) {
154
- $offset = $y * $this->rowSize;
155
-
156
- for ($x = $left; $x < $right; $x++) {
157
- $index = $offset + ($x >> 5);
158
- $this->bits[$index] = $this->bits[$index] | (1 << ($x & 0x1f));
159
- }
160
- }
161
- }
162
-
163
- /**
164
- * A fast method to retrieve one row of data from the matrix as a BitArray.
165
- *
166
- * @param integer $y
167
- * @param BitArray $row
168
- * @return BitArray
169
- */
170
- public function getRow($y, BitArray $row = null)
171
- {
172
- if ($row === null || $row->getSize() < $this->width) {
173
- $row = new BitArray($this->width);
174
- }
175
-
176
- $offset = $y * $this->rowSize;
177
-
178
- for ($x = 0; $x < $this->rowSize; $x++) {
179
- $row->setBulk($x << 5, $this->bits[$offset + $x]);
180
- }
181
-
182
- return $row;
183
- }
184
-
185
- /**
186
- * Sets a row of data from a BitArray.
187
- *
188
- * @param integer $y
189
- * @param BitArray $row
190
- * @return void
191
- */
192
- public function setRow($y, BitArray $row)
193
- {
194
- $bits = $row->getBitArray();
195
-
196
- for ($i = 0; $i < $this->rowSize; $i++) {
197
- $this->bits[$y * $this->rowSize + $i] = $bits[$i];
198
- }
199
- }
200
-
201
- /**
202
- * This is useful in detecting the enclosing rectangle of a 'pure' barcode.
203
- *
204
- * @return SplFixedArray
205
- */
206
- public function getEnclosingRectangle()
207
- {
208
- $left = $this->width;
209
- $top = $this->height;
210
- $right = -1;
211
- $bottom = -1;
212
-
213
- for ($y = 0; $y < $this->height; $y++) {
214
- for ($x32 = 0; $x32 < $this->rowSize; $x32++) {
215
- $bits = $this->bits[$y * $this->rowSize + $x32];
216
-
217
- if ($bits !== 0) {
218
- if ($y < $top) {
219
- $top = $y;
220
- }
221
-
222
- if ($y > $bottom) {
223
- $bottom = $y;
224
- }
225
-
226
- if ($x32 * 32 < $left) {
227
- $bit = 0;
228
-
229
- while (($bits << (31 - $bit)) === 0) {
230
- $bit++;
231
- }
232
-
233
- if (($x32 * 32 + $bit) < $left) {
234
- $left = $x32 * 32 + $bit;
235
- }
236
- }
237
- }
238
-
239
- if ($x32 * 32 + 31 > $right) {
240
- $bit = 31;
241
-
242
- while (BitUtils::unsignedRightShift($bits, $bit) === 0) {
243
- $bit--;
244
- }
245
-
246
- if (($x32 * 32 + $bit) > $right) {
247
- $right = $x32 * 32 + $bit;
248
- }
249
- }
250
- }
251
- }
252
-
253
- $width = $right - $left;
254
- $height = $bottom - $top;
255
-
256
- if ($width < 0 || $height < 0) {
257
- return null;
258
- }
259
-
260
- return SplFixedArray::fromArray(array($left, $top, $width, $height), false);
261
- }
262
-
263
- /**
264
- * Gets the most top left set bit.
265
- *
266
- * This is useful in detecting a corner of a 'pure' barcode.
267
- *
268
- * @return SplFixedArray
269
- */
270
- public function getTopLeftOnBit()
271
- {
272
- $bitsOffset = 0;
273
-
274
- while ($bitsOffset < count($this->bits) && $this->bits[$bitsOffset] === 0) {
275
- $bitsOffset++;
276
- }
277
-
278
- if ($bitsOffset === count($this->bits)) {
279
- return null;
280
- }
281
-
282
- $x = intval($bitsOffset / $this->rowSize);
283
- $y = ($bitsOffset % $this->rowSize) << 5;
284
-
285
- $bits = $this->bits[$bitsOffset];
286
- $bit = 0;
287
-
288
- while (($bits << (31 - $bit)) === 0) {
289
- $bit++;
290
- }
291
-
292
- $x += $bit;
293
-
294
- return SplFixedArray::fromArray(array($x, $y), false);
295
- }
296
-
297
- /**
298
- * Gets the most bottom right set bit.
299
- *
300
- * This is useful in detecting a corner of a 'pure' barcode.
301
- *
302
- * @return SplFixedArray
303
- */
304
- public function getBottomRightOnBit()
305
- {
306
- $bitsOffset = count($this->bits) - 1;
307
-
308
- while ($bitsOffset >= 0 && $this->bits[$bitsOffset] === 0) {
309
- $bitsOffset--;
310
- }
311
-
312
- if ($bitsOffset < 0) {
313
- return null;
314
- }
315
-
316
- $x = intval($bitsOffset / $this->rowSize);
317
- $y = ($bitsOffset % $this->rowSize) << 5;
318
-
319
- $bits = $this->bits[$bitsOffset];
320
- $bit = 0;
321
-
322
- while (BitUtils::unsignedRightShift($bits, $bit) === 0) {
323
- $bit--;
324
- }
325
-
326
- $x += $bit;
327
-
328
- return SplFixedArray::fromArray(array($x, $y), false);
329
- }
330
-
331
- /**
332
- * Gets the width of the matrix,
333
- *
334
- * @return integer
335
- */
336
- public function getWidth()
337
- {
338
- return $this->width;
339
- }
340
-
341
- /**
342
- * Gets the height of the matrix.
343
- *
344
- * @return integer
345
- */
346
- public function getHeight()
347
- {
348
- return $this->height;
349
- }
350
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Common/BitUtils.php DELETED
@@ -1,51 +0,0 @@
1
- <?php
2
- /**
3
- * BaconQrCode
4
- *
5
- * @link http://github.com/Bacon/BaconQrCode For the canonical source repository
6
- * @copyright 2013 Ben 'DASPRiD' Scholzen
7
- * @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
8
- */
9
-
10
- namespace BaconQrCode\Common;
11
-
12
- /**
13
- * General bit utilities.
14
- *
15
- * All utility methods are based on 32-bit integers and also work on 64-bit
16
- * systems.
17
- */
18
- class BitUtils
19
- {
20
- /**
21
- * Performs an unsigned right shift.
22
- *
23
- * This is the same as the unsigned right shift operator ">>>" in other
24
- * languages.
25
- *
26
- * @param integer $a
27
- * @param integer $b
28
- * @return integer
29
- */
30
- public static function unsignedRightShift($a, $b)
31
- {
32
- return (
33
- $a >= 0
34
- ? $a >> $b
35
- : (($a & 0x7fffffff) >> $b) | (0x40000000 >> ($b - 1))
36
- );
37
- }
38
-
39
- /**
40
- * Gets the number of trailing zeros.
41
- *
42
- * @param integer $i
43
- * @return integer
44
- */
45
- public static function numberOfTrailingZeros($i)
46
- {
47
- $lastPos = strrpos(str_pad(decbin($i), 32, '0', STR_PAD_LEFT), '1');
48
-
49
- return $lastPos === false ? 32 : 31 - $lastPos;
50
- }
51
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Common/CharacterSetEci.php DELETED
@@ -1,134 +0,0 @@
1
- <?php
2
- /**
3
- * BaconQrCode
4
- *
5
- * @link http://github.com/Bacon/BaconQrCode For the canonical source repository
6
- * @copyright 2013 Ben 'DASPRiD' Scholzen
7
- * @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
8
- */
9
-
10
- namespace BaconQrCode\Common;
11
-
12
- /**
13
- * Encapsulates a Character Set ECI, according to "Extended Channel
14
- * Interpretations" 5.3.1.1 of ISO 18004.
15
- */
16
- class CharacterSetEci extends AbstractEnum
17
- {
18
- /**#@+
19
- * Character set constants.
20
- */
21
- const CP437 = 0;
22
- const ISO8859_1 = 1;
23
- const ISO8859_2 = 4;
24
- const ISO8859_3 = 5;
25
- const ISO8859_4 = 6;
26
- const ISO8859_5 = 7;
27
- const ISO8859_6 = 8;
28
- const ISO8859_7 = 9;
29
- const ISO8859_8 = 10;
30
- const ISO8859_9 = 11;
31
- const ISO8859_10 = 12;
32
- const ISO8859_11 = 13;
33
- const ISO8859_12 = 14;
34
- const ISO8859_13 = 15;
35
- const ISO8859_14 = 16;
36
- const ISO8859_15 = 17;
37
- const ISO8859_16 = 18;
38
- const SJIS = 20;
39
- const CP1250 = 21;
40
- const CP1251 = 22;
41
- const CP1252 = 23;
42
- const CP1256 = 24;
43
- const UNICODE_BIG_UNMARKED = 25;
44
- const UTF8 = 26;
45
- const ASCII = 27;
46
- const BIG5 = 28;
47
- const GB18030 = 29;
48
- const EUC_KR = 30;
49
- /**#@-*/
50
-
51
- /**
52
- * Map between character names and their ECI values.
53
- *
54
- * @var array
55
- */
56
- protected static $nameToEci = array(
57
- 'ISO-8859-1' => self::ISO8859_1,
58
- 'ISO-8859-2' => self::ISO8859_2,
59
- 'ISO-8859-3' => self::ISO8859_3,
60
- 'ISO-8859-4' => self::ISO8859_4,
61
- 'ISO-8859-5' => self::ISO8859_5,
62
- 'ISO-8859-6' => self::ISO8859_6,
63
- 'ISO-8859-7' => self::ISO8859_7,
64
- 'ISO-8859-8' => self::ISO8859_8,
65
- 'ISO-8859-9' => self::ISO8859_9,
66
- 'ISO-8859-10' => self::ISO8859_10,
67
- 'ISO-8859-11' => self::ISO8859_11,
68
- 'ISO-8859-12' => self::ISO8859_12,
69
- 'ISO-8859-13' => self::ISO8859_13,
70
- 'ISO-8859-14' => self::ISO8859_14,
71
- 'ISO-8859-15' => self::ISO8859_15,
72
- 'ISO-8859-16' => self::ISO8859_16,
73
- 'SHIFT-JIS' => self::SJIS,
74
- 'WINDOWS-1250' => self::CP1250,
75
- 'WINDOWS-1251' => self::CP1251,
76
- 'WINDOWS-1252' => self::CP1252,
77
- 'WINDOWS-1256' => self::CP1256,
78
- 'UTF-16BE' => self::UNICODE_BIG_UNMARKED,
79
- 'UTF-8' => self::UTF8,
80
- 'ASCII' => self::ASCII,
81
- 'GBK' => self::GB18030,
82
- 'EUC-KR' => self::EUC_KR,
83
- );
84
-
85
- /**
86
- * Additional possible values for character sets.
87
- *
88
- * @var array
89
- */
90
- protected $additionalValues = array(
91
- self::CP437 => 2,
92
- self::ASCII => 170,
93
- );
94
-
95
- /**
96
- * Gets character set ECI by value.
97
- *
98
- * @param string $name
99
- * @return CharacterSetEci|null
100
- */
101
- public static function getCharacterSetECIByValue($value)
102
- {
103
- if ($value < 0 || $value >= 900) {
104
- throw new Exception\InvalidArgumentException('Value must be between 0 and 900');
105
- }
106
-
107
- if (false !== ($key = array_search($value, self::$additionalValues))) {
108
- $value = $key;
109
- }
110
-
111
- try {
112
- return new self($value);
113
- } catch (Exception\UnexpectedValueException $e) {
114
- return null;
115
- }
116
- }
117
-
118
- /**
119
- * Gets character set ECI by name.
120
- *
121
- * @param string $name
122
- * @return CharacterSetEci|null
123
- */
124
- public static function getCharacterSetECIByName($name)
125
- {
126
- $name = strtoupper($name);
127
-
128
- if (isset(self::$nameToEci[$name])) {
129
- return new self(self::$nameToEci[$name]);
130
- }
131
-
132
- return null;
133
- }
134
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Common/EcBlock.php DELETED
@@ -1,65 +0,0 @@
1
- <?php
2
- /**
3
- * BaconQrCode
4
- *
5
- * @link http://github.com/Bacon/BaconQrCode For the canonical source repository
6
- * @copyright 2013 Ben 'DASPRiD' Scholzen
7
- * @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
8
- */
9
-
10
- namespace BaconQrCode\Common;
11
-
12
- /**
13
- * Encapsualtes the parameters for one error-correction block in one symbol
14
- * version. This includes the number of data codewords, and the number of times
15
- * a block with these parameters is used consecutively in the QR code version's
16
- * format.
17
- */
18
- class EcBlock
19
- {
20
- /**
21
- * How many times the block is used.
22
- *
23
- * @var integer
24
- */
25
- protected $count;
26
-
27
- /**
28
- * Number of data codewords.
29
- *
30
- * @var integer
31
- */
32
- protected $dataCodewords;
33
-
34
- /**
35
- * Creates a new EC block.
36
- *
37
- * @param integer $count
38
- * @param integer $dataCodewords
39
- */
40
- public function __construct($count, $dataCodewords)
41
- {
42
- $this->count = $count;
43
- $this->dataCodewords = $dataCodewords;
44
- }
45
-
46
- /**
47
- * Returns how many times the block is used.
48
- *
49
- * @return integer
50
- */
51
- public function getCount()
52
- {
53
- return $this->count;
54
- }
55
-
56
- /**
57
- * Returns the number of data codewords.
58
- *
59
- * @return integer
60
- */
61
- public function getDataCodewords()
62
- {
63
- return $this->dataCodewords;
64
- }
65
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Common/EcBlocks.php DELETED
@@ -1,101 +0,0 @@
1
- <?php
2
- /**
3
- * BaconQrCode
4
- *
5
- * @link http://github.com/Bacon/BaconQrCode For the canonical source repository
6
- * @copyright 2013 Ben 'DASPRiD' Scholzen
7
- * @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
8
- */
9
-
10
- namespace BaconQrCode\Common;
11
-
12
- use SplFixedArray;
13
-
14
- /**
15
- * Encapsulates a set of error-correction blocks in one symbol version. Most
16
- * versions will use blocks of differing sizes within one version, so, this
17
- * encapsulates the parameters for each set of blocks. It also holds the number
18
- * of error-correction codewords per block since it will be the same across all
19
- * blocks within one version.
20
- */
21
- class EcBlocks
22
- {
23
- /**
24
- * Number of EC codewords per block.
25
- *
26
- * @var integer
27
- */
28
- protected $ecCodewordsPerBlock;
29
-
30
- /**
31
- * List of EC blocks.
32
- *
33
- * @var SplFixedArray
34
- */
35
- protected $ecBlocks;
36
-
37
- /**
38
- * Creates a new EC blocks instance.
39
- *
40
- * @param integer $ecCodewordsPerBlock
41
- * @param EcBlock $ecb1
42
- * @param EcBlock|null $ecb2
43
- */
44
- public function __construct($ecCodewordsPerBlock, EcBlock $ecb1, EcBlock $ecb2 = null)
45
- {
46
- $this->ecCodewordsPerBlock = $ecCodewordsPerBlock;
47
-
48
- $this->ecBlocks = new SplFixedArray($ecb2 === null ? 1 : 2);
49
- $this->ecBlocks[0] = $ecb1;
50
-
51
- if ($ecb2 !== null) {
52
- $this->ecBlocks[1] = $ecb2;
53
- }
54
- }
55
-
56
- /**
57
- * Gets the number of EC codewords per block.
58
- *
59
- * @return integer
60
- */
61
- public function getEcCodewordsPerBlock()
62
- {
63
- return $this->ecCodewordsPerBlock;
64
- }
65
-
66
- /**
67
- * Gets the total number of EC block appearances.
68
- *
69
- * @return integer
70
- */
71
- public function getNumBlocks()
72
- {
73
- $total = 0;
74
-
75
- foreach ($this->ecBlocks as $ecBlock) {
76
- $total += $ecBlock->getCount();
77
- }
78
-
79
- return $total;
80
- }
81
-
82
- /**
83
- * Gets the total count of EC codewords.
84
- *
85
- * @return integer
86
- */
87
- public function getTotalEcCodewords()
88
- {
89
- return $this->ecCodewordsPerBlock * $this->getNumBlocks();
90
- }
91
-
92
- /**
93
- * Gets the EC blocks included in this collection.
94
- *
95
- * @return SplFixedArray
96
- */
97
- public function getEcBlocks()
98
- {
99
- return $this->ecBlocks;
100
- }
101
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Common/ErrorCorrectionLevel.php DELETED
@@ -1,62 +0,0 @@
1
- <?php
2
- /**
3
- * BaconQrCode
4
- *
5
- * @link http://github.com/Bacon/BaconQrCode For the canonical source repository
6
- * @copyright 2013 Ben 'DASPRiD' Scholzen
7
- * @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
8
- */
9
-
10
- namespace BaconQrCode\Common;
11
-
12
- /**
13
- * Enum representing the four error correction levels.
14
- */
15
- class ErrorCorrectionLevel extends AbstractEnum
16
- {
17
- /**
18
- * Level L, ~7% correction.
19
- */
20
- const L = 0x1;
21
-
22
- /**
23
- * Level M, ~15% correction.
24
- */
25
- const M = 0x0;
26
-
27
- /**
28
- * Level Q, ~25% correction.
29
- */
30
- const Q = 0x3;
31
-
32
- /**
33
- * Level H, ~30% correction.
34
- */
35
- const H = 0x2;
36
-
37
- /**
38
- * Gets the ordinal of this enumeration constant.
39
- *
40
- * @return integer
41
- */
42
- public function getOrdinal()
43
- {
44
- switch ($this->value) {
45
- case self::L:
46
- return 0;
47
- break;
48
-
49
- case self::M:
50
- return 1;
51
- break;
52
-
53
- case self::Q:
54
- return 2;
55
- break;
56
-
57
- case self::H:
58
- return 3;
59
- break;
60
- }
61
- }
62
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Common/FormatInformation.php DELETED
@@ -1,236 +0,0 @@
1
- <?php
2
- /**
3
- * BaconQrCode
4
- *
5
- * @link http://github.com/Bacon/BaconQrCode For the canonical source repository
6
- * @copyright 2013 Ben 'DASPRiD' Scholzen
7
- * @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
8
- */
9
-
10
- namespace BaconQrCode\Common;
11
-
12
- /**
13
- * Encapsulates a QR Code's format information, including the data mask used and
14
- * error correction level.
15
- */
16
- class FormatInformation
17
- {
18
- /**
19
- * Mask for format information.
20
- */
21
- const FORMAT_INFO_MASK_QR = 0x5412;
22
-
23
- /**
24
- * Lookup table for decoding format information.
25
- *
26
- * See ISO 18004:2006, Annex C, Table C.1
27
- *
28
- * @var array
29
- */
30
- protected static $formatInfoDecodeLookup = array(
31
- array(0x5412, 0x00),
32
- array(0x5125, 0x01),
33
- array(0x5e7c, 0x02),
34
- array(0x5b4b, 0x03),
35
- array(0x45f9, 0x04),
36
- array(0x40ce, 0x05),
37
- array(0x4f97, 0x06),
38
- array(0x4aa0, 0x07),
39
- array(0x77c4, 0x08),
40
- array(0x72f3, 0x09),
41
- array(0x7daa, 0x0a),
42
- array(0x789d, 0x0b),
43
- array(0x662f, 0x0c),
44
- array(0x6318, 0x0d),
45
- array(0x6c41, 0x0e),
46
- array(0x6976, 0x0f),
47
- array(0x1689, 0x10),
48
- array(0x13be, 0x11),
49
- array(0x1ce7, 0x12),
50
- array(0x19d0, 0x13),
51
- array(0x0762, 0x14),
52
- array(0x0255, 0x15),
53
- array(0x0d0c, 0x16),
54
- array(0x083b, 0x17),
55
- array(0x355f, 0x18),
56
- array(0x3068, 0x19),
57
- array(0x3f31, 0x1a),
58
- array(0x3a06, 0x1b),
59
- array(0x24b4, 0x1c),
60
- array(0x2183, 0x1d),
61
- array(0x2eda, 0x1e),
62
- array(0x2bed, 0x1f),
63
- );
64
-
65
- /**
66
- * Offset i holds the number of 1 bits in the binary representation of i.
67
- *
68
- * @var array
69
- */
70
- protected static $bitsSetInHalfByte = array(0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4);
71
-
72
- /**
73
- * Error correction level.
74
- *
75
- * @var ErrorCorrectionLevel
76
- */
77
- protected $ecLevel;
78
-
79
- /**
80
- * Data mask.
81
- *
82
- * @var integer
83
- */
84
- protected $dataMask;
85
-
86
- /**
87
- * Creates a new format information instance.
88
- *
89
- * @param integer $formatInfo
90
- */
91
- protected function __construct($formatInfo)
92
- {
93
- $this->ecLevel = new ErrorCorrectionLevel(($formatInfo >> 3) & 0x3);
94
- $this->dataMask = $formatInfo & 0x7;
95
- }
96
-
97
- /**
98
- * Checks how many bits are different between two integers.
99
- *
100
- * @param integer $a
101
- * @param integer $b
102
- * @return integer
103
- */
104
- public static function numBitsDiffering($a, $b)
105
- {
106
- $a ^= $b;
107
-
108
- return (
109
- self::$bitsSetInHalfByte[$a & 0xf]
110
- + self::$bitsSetInHalfByte[(BitUtils::unsignedRightShift($a, 4) & 0xf)]
111
- + self::$bitsSetInHalfByte[(BitUtils::unsignedRightShift($a, 8) & 0xf)]
112
- + self::$bitsSetInHalfByte[(BitUtils::unsignedRightShift($a, 12) & 0xf)]
113
- + self::$bitsSetInHalfByte[(BitUtils::unsignedRightShift($a, 16) & 0xf)]
114
- + self::$bitsSetInHalfByte[(BitUtils::unsignedRightShift($a, 20) & 0xf)]
115
- + self::$bitsSetInHalfByte[(BitUtils::unsignedRightShift($a, 24) & 0xf)]
116
- + self::$bitsSetInHalfByte[(BitUtils::unsignedRightShift($a, 28) & 0xf)]
117
- );
118
- }
119
-
120
- /**
121
- * Decodes format information.
122
- *
123
- * @param integer $maskedFormatInfo1
124
- * @param integer $maskedFormatInfo2
125
- * @return FormatInformation|null
126
- */
127
- public static function decodeFormatInformation($maskedFormatInfo1, $maskedFormatInfo2)
128
- {
129
- $formatInfo = self::doDecodeFormatInformation($maskedFormatInfo1, $maskedFormatInfo2);
130
-
131
- if ($formatInfo !== null) {
132
- return $formatInfo;
133
- }
134
-
135
- // Should return null, but, some QR codes apparently do not mask this
136
- // info. Try again by actually masking the pattern first.
137
- return self::doDecodeFormatInformation(
138
- $maskedFormatInfo1 ^ self::FORMAT_INFO_MASK_QR,
139
- $maskedFormatInfo2 ^ self::FORMAT_INFO_MASK_QR
140
- );
141
- }
142
-
143
- /**
144
- * Internal method for decoding format information.
145
- *
146
- * @param integer $maskedFormatInfo1
147
- * @param integer $maskedFormatInfo2
148
- * @return FormatInformation|null
149
- */
150
- protected static function doDecodeFormatInformation($maskedFormatInfo1, $maskedFormatInfo2)
151
- {
152
- $bestDifference = PHP_INT_MAX;
153
- $bestFormatInfo = 0;
154
-
155
- foreach (self::$formatInfoDecodeLookup as $decodeInfo) {
156
- $targetInfo = $decodeInfo[0];
157
-
158
- if ($targetInfo === $maskedFormatInfo1 || $targetInfo === $maskedFormatInfo2) {
159
- // Found an exact match
160
- return new self($decodeInfo[1]);
161
- }
162
-
163
- $bitsDifference = self::numBitsDiffering($maskedFormatInfo1, $targetInfo);
164
-
165
- if ($bitsDifference < $bestDifference) {
166
- $bestFormatInfo = $decodeInfo[1];
167
- $bestDifference = $bitsDifference;
168
- }
169
-
170
- if ($maskedFormatInfo1 !== $maskedFormatInfo2) {
171
- // Also try the other option
172
- $bitsDifference = self::numBitsDiffering($maskedFormatInfo2, $targetInfo);
173
-
174
- if ($bitsDifference < $bestDifference) {
175
- $bestFormatInfo = $decodeInfo[1];
176
- $bestDifference = $bitsDifference;
177
- }
178
- }
179
- }
180
-
181
- // Hamming distance of the 32 masked codes is 7, by construction, so
182
- // <= 3 bits differing means we found a match.
183
- if ($bestDifference <= 3) {
184
- return new self($bestFormatInfo);
185
- }
186
-
187
- return null;
188
- }
189
-
190
- /**
191
- * Gets the error correction level.
192
- *
193
- * @return ErrorCorrectionLevel
194
- */
195
- public function getErrorCorrectionLevel()
196
- {
197
- return $this->ecLevel;
198
- }
199
-
200
- /**
201
- * Gets the data mask.
202
- *
203
- * @return integer
204
- */
205
- public function getDataMask()
206
- {
207
- return $this->dataMask;
208
- }
209
-
210
- /**
211
- * Hashes the code of the EC level.
212
- *
213
- * @return integer
214
- */
215
- public function hashCode()
216
- {
217
- return ($this->ecLevel->get() << 3) | $this->dataMask;
218
- }
219
-
220
- /**
221
- * Verifies if this instance equals another one.
222
- *
223
- * @param mixed $other
224
- * @return boolean
225
- */
226
- public function equals($other) {
227
- if (!$other instanceof self) {
228
- return false;
229
- }
230
-
231
- return (
232
- $this->ecLevel->get() === $other->getErrorCorrectionLevel()->get()
233
- && $this->dataMask === $other->getDataMask()
234
- );
235
- }
236
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Common/Mode.php DELETED
@@ -1,70 +0,0 @@
1
- <?php
2
- /**
3
- * BaconQrCode
4
- *
5
- * @link http://github.com/Bacon/BaconQrCode For the canonical source repository
6
- * @copyright 2013 Ben 'DASPRiD' Scholzen
7
- * @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
8
- */
9
-
10
- namespace BaconQrCode\Common;
11
-
12
- /**
13
- * Enum representing various modes in which data can be encoded to bits.
14
- */
15
- class Mode extends AbstractEnum
16
- {
17
- /**#@+
18
- * Mode constants.
19
- */
20
- const TERMINATOR = 0x0;
21
- const NUMERIC = 0x1;
22
- const ALPHANUMERIC = 0x2;
23
- const STRUCTURED_APPEND = 0x3;
24
- const BYTE = 0x4;
25
- const ECI = 0x7;
26
- const KANJI = 0x8;
27
- const FNC1_FIRST_POSITION = 0x5;
28
- const FNC1_SECOND_POSITION = 0x9;
29
- const HANZI = 0xd;
30
- /**#@-*/
31
-
32
- /**
33
- * Character count bits for each version.
34
- *
35
- * @var array
36
- */
37
- protected static $characterCountBitsForVersions = array(
38
- self::TERMINATOR => array(0, 0, 0),
39
- self::NUMERIC => array(10, 12, 14),
40
- self::ALPHANUMERIC => array(9, 11, 13),
41
- self::STRUCTURED_APPEND => array(0, 0, 0),
42
- self::BYTE => array(8, 16, 16),
43
- self::ECI => array(0, 0, 0),
44
- self::KANJI => array(8, 10, 12),
45
- self::FNC1_FIRST_POSITION => array(0, 0, 0),
46
- self::FNC1_SECOND_POSITION => array(0, 0, 0),
47
- self::HANZI => array(8, 10, 12),
48
- );
49
-
50
- /**
51
- * Gets the number of bits used in a specific QR code version.
52
- *
53
- * @param Version $version
54
- * @return integer
55
- */
56
- public function getCharacterCountBits(Version $version)
57
- {
58
- $number = $version->getVersionNumber();
59
-
60
- if ($number <= 9) {
61
- $offset = 0;
62
- } elseif ($number <= 26) {
63
- $offset = 1;
64
- } else {
65
- $offset = 2;
66
- }
67
-
68
- return self::$characterCountBitsForVersions[$this->value][$offset];
69
- }
70
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Common/ReedSolomonCodec.php DELETED
@@ -1,476 +0,0 @@
1
- <?php
2
- /**
3
- * BaconQrCode
4
- *
5
- * @link http://github.com/Bacon/BaconQrCode For the canonical source repository
6
- * @copyright 2013 Ben 'DASPRiD' Scholzen
7
- * @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
8
- */
9
-
10
- namespace BaconQrCode\Common;
11
-
12
- use BaconQrCode\Exception;
13
- use SplFixedArray;
14
-
15
- /**
16
- * Reed-Solomon codec for 8-bit characters.
17
- *
18
- * Based on libfec by Phil Karn, KA9Q.
19
- */
20
- class ReedSolomonCodec
21
- {
22
- /**
23
- * Symbol size in bits.
24
- *
25
- * @var integer
26
- */
27
- protected $symbolSize;
28
-
29
- /**
30
- * Block size in symbols.
31
- *
32
- * @var integer
33
- */
34
- protected $blockSize;
35
-
36
- /**
37
- * First root of RS code generator polynomial, index form.
38
- *
39
- * @var integer
40
- */
41
- protected $firstRoot;
42
-
43
- /**
44
- * Primitive element to generate polynomial roots, index form.
45
- *
46
- * @var integer
47
- */
48
- protected $primitive;
49
-
50
- /**
51
- * Prim-th root of 1, index form.
52
- *
53
- * @var integer
54
- */
55
- protected $iPrimitive;
56
-
57
- /**
58
- * RS code generator polynomial degree (number of roots).
59
- *
60
- * @var integer
61
- */
62
- protected $numRoots;
63
-
64
- /**
65
- * Padding bytes at front of shortened block.
66
- *
67
- * @var integer
68
- */
69
- protected $padding;
70
-
71
- /**
72
- * Log lookup table.
73
- *
74
- * @var SplFixedArray
75
- */
76
- protected $alphaTo;
77
-
78
- /**
79
- * Anti-Log lookup table.
80
- *
81
- * @var SplFixedArray
82
- */
83
- protected $indexOf;
84
-
85
- /**
86
- * Generator polynomial.
87
- *
88
- * @var SplFixedArray
89
- */
90
- protected $generatorPoly;
91
-
92
- /**
93
- * Creates a new reed solomon instance.
94
- *
95
- * @param integer $symbolSize
96
- * @param integer $gfPoly
97
- * @param integer $firstRoot
98
- * @param integer $primitive
99
- * @param integer $numRoots
100
- * @param integer $padding
101
- * @throws Exception\InvalidArgumentException
102
- * @throws Exception\RuntimeException
103
- */
104
- public function __construct($symbolSize, $gfPoly, $firstRoot, $primitive, $numRoots, $padding)
105
- {
106
- if ($symbolSize < 0 || $symbolSize > 8) {
107
- throw new Exception\InvalidArgumentException('Symbol size must be between 0 and 8');
108
- }
109
-
110
- if ($firstRoot < 0 || $firstRoot >= (1 << $symbolSize)) {
111
- throw new Exception\InvalidArgumentException('First root must be between 0 and ' . (1 << $symbolSize));
112
- }
113
-
114
- if ($numRoots < 0 || $numRoots >= (1 << $symbolSize)) {
115
- throw new Exception\InvalidArgumentException('Num roots must be between 0 and ' . (1 << $symbolSize));
116
- }
117
-
118
- if ($padding < 0 || $padding >= ((1 << $symbolSize) - 1 - $numRoots)) {
119
- throw new Exception\InvalidArgumentException('Padding must be between 0 and ' . ((1 << $symbolSize) - 1 - $numRoots));
120
- }
121
-
122
- $this->symbolSize = $symbolSize;
123
- $this->blockSize = (1 << $symbolSize) - 1;
124
- $this->padding = $padding;
125
- $this->alphaTo = SplFixedArray::fromArray(array_fill(0, $this->blockSize + 1, 0), false);
126
- $this->indexOf = SplFixedArray::fromArray(array_fill(0, $this->blockSize + 1, 0), false);
127
-
128
- // Generate galous field lookup table
129
- $this->indexOf[0] = $this->blockSize;
130
- $this->alphaTo[$this->blockSize] = 0;
131
-
132
- $sr = 1;
133
-
134
- for ($i = 0; $i < $this->blockSize; $i++) {
135
- $this->indexOf[$sr] = $i;
136
- $this->alphaTo[$i] = $sr;
137
-
138
- $sr <<= 1;
139
-
140
- if ($sr & (1 << $symbolSize)) {
141
- $sr ^= $gfPoly;
142
- }
143
-
144
- $sr &= $this->blockSize;
145
- }
146
-
147
- if ($sr !== 1) {
148
- throw new Exception\RuntimeException('Field generator polynomial is not primitive');
149
- }
150
-
151
- // Form RS code generator polynomial from its roots
152
- $this->generatorPoly = SplFixedArray::fromArray(array_fill(0, $numRoots + 1, 0), false);
153
- $this->firstRoot = $firstRoot;
154
- $this->primitive = $primitive;
155
- $this->numRoots = $numRoots;
156
-
157
- // Find prim-th root of 1, used in decoding
158
- for ($iPrimitive = 1; ($iPrimitive % $primitive) !== 0; $iPrimitive += $this->blockSize);
159
- $this->iPrimitive = intval($iPrimitive / $primitive);
160
-
161
- $this->generatorPoly[0] = 1;
162
-
163
- for ($i = 0, $root = $firstRoot * $primitive; $i < $numRoots; $i++, $root += $primitive) {
164
- $this->generatorPoly[$i + 1] = 1;
165
-
166
- for ($j = $i; $j > 0; $j--) {
167
- if ($this->generatorPoly[$j] !== 0) {
168
- $this->generatorPoly[$j] = $this->generatorPoly[$j - 1] ^ $this->alphaTo[$this->modNn($this->indexOf[$this->generatorPoly[$j]] + $root)];
169
- } else {
170
- $this->generatorPoly[$j] = $this->generatorPoly[$j - 1];
171
- }
172
- }
173
-
174
- $this->generatorPoly[$j] = $this->alphaTo[$this->modNn($this->indexOf[$this->generatorPoly[0]] + $root)];
175
- }
176
-
177
- // Convert generator poly to index form for quicker encoding
178
- for ($i = 0; $i <= $numRoots; $i++) {
179
- $this->generatorPoly[$i] = $this->indexOf[$this->generatorPoly[$i]];
180
- }
181
- }
182
-
183
- /**
184
- * Encodes data and writes result back into parity array.
185
- *
186
- * @param SplFixedArray $data
187
- * @param SplFixedArray $parity
188
- * @return void
189
- */
190
- public function encode(SplFixedArray $data, SplFixedArray $parity)
191
- {
192
- for ($i = 0; $i < $this->numRoots; $i++) {
193
- $parity[$i] = 0;
194
- }
195
-
196
- $iterations = $this->blockSize - $this->numRoots - $this->padding;
197
-
198
- for ($i = 0; $i < $iterations; $i++) {
199
- $feedback = $this->indexOf[$data[$i] ^ $parity[0]];
200
-
201
- if ($feedback !== $this->blockSize) {
202
- // Feedback term is non-zero
203
- $feedback = $this->modNn($this->blockSize - $this->generatorPoly[$this->numRoots] + $feedback);
204
-
205
- for ($j = 1; $j < $this->numRoots; $j++) {
206
- $parity[$j] = $parity[$j] ^ $this->alphaTo[$this->modNn($feedback + $this->generatorPoly[$this->numRoots - $j])];
207
- }
208
- }
209
-
210
- for ($j = 0; $j < $this->numRoots - 1; $j++) {
211
- $parity[$j] = $parity[$j + 1];
212
- }
213
-
214
- if ($feedback !== $this->blockSize) {
215
- $parity[$this->numRoots - 1] = $this->alphaTo[$this->modNn($feedback + $this->generatorPoly[0])];
216
- } else {
217
- $parity[$this->numRoots - 1] = 0;
218
- }
219
- }
220
- }
221
-
222
- /**
223
- * Decodes received data.
224
- *
225
- * @param SplFixedArray $data
226
- * @param SplFixedArray|null $erasures
227
- * @return null|integer
228
- */
229
- public function decode(SplFixedArray $data, SplFixedArray $erasures = null)
230
- {
231
- // This speeds up the initialization a bit.
232
- $numRootsPlusOne = SplFixedArray::fromArray(array_fill(0, $this->numRoots + 1, 0), false);
233
- $numRoots = SplFixedArray::fromArray(array_fill(0, $this->numRoots, 0), false);
234
-
235
- $lambda = clone $numRootsPlusOne;
236
- $b = clone $numRootsPlusOne;
237
- $t = clone $numRootsPlusOne;
238
- $omega = clone $numRootsPlusOne;
239
- $root = clone $numRoots;
240
- $loc = clone $numRoots;
241
-
242
- $numErasures = ($erasures !== null ? count($erasures) : 0);
243
-
244
- // Form the Syndromes; i.e., evaluate data(x) at roots of g(x)
245
- $syndromes = SplFixedArray::fromArray(array_fill(0, $this->numRoots, $data[0]), false);
246
-
247
- for ($i = 1; $i < $this->blockSize - $this->padding; $i++) {
248
- for ($j = 0; $j < $this->numRoots; $j++) {
249
- if ($syndromes[$j] === 0) {
250
- $syndromes[$j] = $data[$i];
251
- } else {
252
- $syndromes[$j] = $data[$i] ^ $this->alphaTo[
253
- $this->modNn($this->indexOf[$syndromes[$j]] + ($this->firstRoot + $j) * $this->primitive)
254
- ];
255
- }
256
- }
257
- }
258
-
259
- // Convert syndromes to index form, checking for nonzero conditions
260
- $syndromeError = 0;
261
-
262
- for ($i = 0; $i < $this->numRoots; $i++) {
263
- $syndromeError |= $syndromes[$i];
264
- $syndromes[$i] = $this->indexOf[$syndromes[$i]];
265
- }
266
-
267
- if (!$syndromeError) {
268
- // If syndrome is zero, data[] is a codeword and there are no errors
269
- // to correct, so return data[] unmodified.
270
- return 0;
271
- }
272
-
273
- $lambda[0] = 1;
274
-
275
- if ($numErasures > 0) {
276
- // Init lambda to be the erasure locator polynomial
277
- $lambda[1] = $this->alphaTo[$this->modNn($this->primitive * ($this->blockSize - 1 - $erasures[0]))];
278
-
279
- for ($i = 1; $i < $numErasures; $i++) {
280
- $u = $this->modNn($this->primitive * ($this->blockSize - 1 - $erasures[$i]));
281
-
282
- for ($j = $i + 1; $j > 0; $j--) {
283
- $tmp = $this->indexOf[$lambda[$j - 1]];
284
-
285
- if ($tmp !== $this->blockSize) {
286
- $lambda[$j] = $lambda[$j] ^ $this->alphaTo[$this->modNn($u + $tmp)];
287
- }
288
- }
289
- }
290
- }
291
-
292
- for ($i = 0; $i <= $this->numRoots; $i++) {
293
- $b[$i] = $this->indexOf[$lambda[$i]];
294
- }
295
-
296
- // Begin Berlekamp-Massey algorithm to determine error+erasure locator
297
- // polynomial
298
- $r = $numErasures;
299
- $el = $numErasures;
300
-
301
- while (++$r <= $this->numRoots) {
302
- // Compute discrepancy at the r-th step in poly form
303
- $discrepancyR = 0;
304
-
305
- for ($i = 0; $i < $r; $i++) {
306
- if ($lambda[$i] !== 0 && $syndromes[$r - $i - 1] !== $this->blockSize) {
307
- $discrepancyR ^= $this->alphaTo[$this->modNn($this->indexOf[$lambda[$i]] + $syndromes[$r - $i - 1])];
308
- }
309
- }
310
-
311
- $discrepancyR = $this->indexOf[$discrepancyR];
312
-
313
- if ($discrepancyR === $this->blockSize) {
314
- $tmp = $b->toArray();
315
- array_unshift($tmp, $this->blockSize);
316
- array_pop($tmp);
317
- $b = SplFixedArray::fromArray($tmp, false);
318
- } else {
319
- $t[0] = $lambda[0];
320
-
321
- for ($i = 0; $i < $this->numRoots; $i++) {
322
- if ($b[$i] !== $this->blockSize) {
323
- $t[$i + 1] = $lambda[$i + 1] ^ $this->alphaTo[$this->modNn($discrepancyR + $b[$i])];
324
- } else {
325
- $t[$i + 1] = $lambda[$i + 1];
326
- }
327
- }
328
-
329
- if (2 * $el <= $r + $numErasures - 1) {
330
- $el = $r + $numErasures - $el;
331
-
332
- for ($i = 0; $i <= $this->numRoots; $i++) {
333
- $b[$i] = (
334
- $lambda[$i] === 0
335
- ? $this->blockSize
336
- : $this->modNn($this->indexOf[$lambda[$i]] - $discrepancyR + $this->blockSize)
337
- );
338
- }
339
- } else {
340
- $tmp = $b->toArray();
341
- array_unshift($tmp, $this->blockSize);
342
- array_pop($tmp);
343
- $b = SplFixedArray::fromArray($tmp, false);
344
- }
345
-
346
- $lambda = clone $t;
347
- }
348
- }
349
-
350
- // Convert lambda to index form and compute deg(lambda(x))
351
- $degLambda = 0;
352
-
353
- for ($i = 0; $i <= $this->numRoots; $i++) {
354
- $lambda[$i] = $this->indexOf[$lambda[$i]];
355
-
356
- if ($lambda[$i] !== $this->blockSize) {
357
- $degLambda = $i;
358
- }
359
- }
360
-
361
- // Find roots of the error+erasure locator polynomial by Chien search.
362
- $reg = clone $lambda;
363
- $reg[0] = 0;
364
- $count = 0;
365
-
366
- for ($i = 1, $k = $this->iPrimitive - 1; $i <= $this->blockSize; $i++, $k = $this->modNn($k + $this->iPrimitive)) {
367
- $q = 1;
368
-
369
- for ($j = $degLambda; $j > 0; $j--) {
370
- if ($reg[$j] !== $this->blockSize) {
371
- $reg[$j] = $this->modNn($reg[$j] + $j);
372
- $q ^= $this->alphaTo[$reg[$j]];
373
- }
374
- }
375
-
376
- if ($q !== 0) {
377
- // Not a root
378
- continue;
379
- }
380
-
381
- // Store root (index-form) and error location number
382
- $root[$count] = $i;
383
- $loc[$count] = $k;
384
-
385
- if (++$count === $degLambda) {
386
- break;
387
- }
388
- }
389
-
390
- if ($degLambda !== $count) {
391
- // deg(lambda) unequal to number of roots: uncorreactable error
392
- // detected
393
- return null;
394
- }
395
-
396
- // Compute err+eras evaluate poly omega(x) = s(x)*lambda(x) (modulo
397
- // x**numRoots). In index form. Also find deg(omega).
398
- $degOmega = $degLambda - 1;
399
-
400
- for ($i = 0; $i <= $degOmega; $i++) {
401
- $tmp = 0;
402
-
403
- for ($j = $i; $j >= 0; $j--) {
404
- if ($syndromes[$i - $j] !== $this->blockSize && $lambda[$j] !== $this->blockSize) {
405
- $tmp ^= $this->alphaTo[$this->modNn($syndromes[$i - $j] + $lambda[$j])];
406
- }
407
- }
408
-
409
- $omega[$i] = $this->indexOf[$tmp];
410
- }
411
-
412
- // Compute error values in poly-form. num1 = omega(inv(X(l))), num2 =
413
- // inv(X(l))**(firstRoot-1) and den = lambda_pr(inv(X(l))) all in poly
414
- // form.
415
- for ($j = $count - 1; $j >= 0; $j--) {
416
- $num1 = 0;
417
-
418
- for ($i = $degOmega; $i >= 0; $i--) {
419
- if ($omega[$i] !== $this->blockSize) {
420
- $num1 ^= $this->alphaTo[$this->modNn($omega[$i] + $i * $root[$j])];
421
- }
422
- }
423
-
424
- $num2 = $this->alphaTo[$this->modNn($root[$j] * ($this->firstRoot - 1) + $this->blockSize)];
425
- $den = 0;
426
-
427
- // lambda[i+1] for i even is the formal derivativelambda_pr of
428
- // lambda[i]
429
- for ($i = min($degLambda, $this->numRoots - 1) & ~1; $i >= 0; $i -= 2) {
430
- if ($lambda[$i + 1] !== $this->blockSize) {
431
- $den ^= $this->alphaTo[$this->modNn($lambda[$i + 1] + $i * $root[$j])];
432
- }
433
- }
434
-
435
- // Apply error to data
436
- if ($num1 !== 0 && $loc[$j] >= $this->padding) {
437
- $data[$loc[$j] - $this->padding] = $data[$loc[$j] - $this->padding] ^ (
438
- $this->alphaTo[
439
- $this->modNn(
440
- $this->indexOf[$num1] + $this->indexOf[$num2] + $this->blockSize - $this->indexOf[$den]
441
- )
442
- ]
443
- );
444
- }
445
- }
446
-
447
- if ($erasures !== null) {
448
- if (count($erasures) < $count) {
449
- $erasures->setSize($count);
450
- }
451
-
452
- for ($i = 0; $i < $count; $i++) {
453
- $erasures[$i] = $loc[$i];
454
- }
455
- }
456
-
457
- return $count;
458
- }
459
-
460
- /**
461
- * Computes $x % GF_SIZE, where GF_SIZE is 2**GF_BITS - 1, without a slow
462
- * divide.
463
- *
464
- * @param itneger $x
465
- * @return integer
466
- */
467
- protected function modNn($x)
468
- {
469
- while ($x >= $this->blockSize) {
470
- $x -= $this->blockSize;
471
- $x = ($x >> $this->symbolSize) + ($x & $this->blockSize);
472
- }
473
-
474
- return $x;
475
- }
476
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Common/Version.php DELETED
@@ -1,687 +0,0 @@
1
- <?php
2
- /**
3
- * BaconQrCode
4
- *
5
- * @link http://github.com/Bacon/BaconQrCode For the canonical source repository
6
- * @copyright 2013 Ben 'DASPRiD' Scholzen
7
- * @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
8
- */
9
-
10
- namespace BaconQrCode\Common;
11
-
12
- use SplFixedArray;
13
-
14
- /**
15
- * Version representation.
16
- */
17
- class Version
18
- {
19
- /**
20
- * Version decode information.
21
- *
22
- * @var array
23
- */
24
- protected static $versionDecodeInfo = array(
25
- 0x07c94, 0x085bc, 0x09a99, 0x0a4d3, 0x0bbf6, 0x0c762, 0x0d847, 0x0e60d,
26
- 0x0f928, 0x10b78, 0x1145d, 0x12a17, 0x13532, 0x149a6, 0x15683, 0x168c9,
27
- 0x177ec, 0x18ec4, 0x191e1, 0x1afab, 0x1b08e, 0x1cc1a, 0x1d33f, 0x1ed75,
28
- 0x1f250, 0x209d5, 0x216f0, 0x228ba, 0x2379f, 0x24b0b, 0x2542e, 0x26a64,
29
- 0x27541, 0x28c69
30
- );
31
-
32
- /**
33
- * Cached version instances.
34
- *
35
- * @var array
36
- */
37
- protected static $versions = array();
38
-
39
- /**
40
- * Version number of this version.
41
- *
42
- * @var integer
43
- */
44
- protected $versionNumber;
45
-
46
- /**
47
- * Alignment pattern centers.
48
- *
49
- * @var SplFixedArray
50
- */
51
- protected $alignmentPatternCenters;
52
-
53
- /**
54
- * Error correction blocks.
55
- *
56
- * @var SplFixedArray
57
- */
58
- protected $errorCorrectionBlocks;
59
-
60
- /**
61
- * Total number of codewords.
62
- *
63
- * @var integer
64
- */
65
- protected $totalCodewords;
66
-
67
- /**
68
- * Creates a new version.
69
- *
70
- * @param integer $versionNumber
71
- * @param SplFixedArray $alignmentPatternCenters
72
- * @param SplFixedArray $ecBlocks
73
- */
74
- protected function __construct(
75
- $versionNumber,
76
- SplFixedArray $alignmentPatternCenters,
77
- SplFixedArray $ecBlocks
78
- ) {
79
- $this->versionNumber = $versionNumber;
80
- $this->alignmentPatternCenters = $alignmentPatternCenters;
81
- $this->errorCorrectionBlocks = $ecBlocks;
82
-
83
- $totalCodewords = 0;
84
- $ecCodewords = $ecBlocks[0]->getEcCodewordsPerBlock();
85
-
86
- foreach ($ecBlocks[0]->getEcBlocks() as $ecBlock) {
87
- $totalCodewords += $ecBlock->getCount() * ($ecBlock->getDataCodewords() + $ecCodewords);
88
- }
89
-
90
- $this->totalCodewords = $totalCodewords;
91
- }
92
-
93
- /**
94
- * Gets the version number.
95
- *
96
- * @return integer
97
- */
98
- public function getVersionNumber()
99
- {
100
- return $this->versionNumber;
101
- }
102
-
103
- /**
104
- * Gets the alignment pattern centers.
105
- *
106
- * @return SplFixedArray
107
- */
108
- public function getAlignmentPatternCenters()
109
- {
110
- return $this->alignmentPatternCenters;
111
- }
112
-
113
- /**
114
- * Gets the total number of codewords.
115
- *
116
- * @return integer
117
- */
118
- public function getTotalCodewords()
119
- {
120
- return $this->totalCodewords;
121
- }
122
-
123
- /**
124
- * Gets the dimension for the current version.
125
- *
126
- * @return integer
127
- */
128
- public function getDimensionForVersion()
129
- {
130
- return 17 + 4 * $this->versionNumber;
131
- }
132
-
133
- /**
134
- * Gets the number of EC blocks for a specific EC level.
135
- *
136
- * @param ErrorCorrectionLevel $ecLevel
137
- * @return integer
138
- */
139
- public function getEcBlocksForLevel(ErrorCorrectionLevel $ecLevel)
140
- {
141
- return $this->errorCorrectionBlocks[$ecLevel->getOrdinal()];
142
- }
143
-
144
- /**
145
- * Gets a provisional version number for a specific dimension.
146
- *
147
- * @param integer $dimension
148
- * @return Version
149
- * @throws Exception\InvalidArgumentException
150
- */
151
- public static function getProvisionalVersionForDimension($dimension)
152
- {
153
- if ($dimension % 4 !== 1) {
154
- throw new Exception\InvalidArgumentException('Dimension is not 1 mod 4');
155
- }
156
-
157
- return self::getVersionForNumber(($dimension - 17) >> 2);
158
- }
159
-
160
- /**
161
- * Gets a version instance for a specific version number.
162
- *
163
- * @param integer $versionNumber
164
- * @return Version
165
- * @throws Exception\InvalidArgumentException
166
- */
167
- public static function getVersionForNumber($versionNumber)
168
- {
169
- if ($versionNumber < 1 || $versionNumber > 40) {
170
- throw new Exception\InvalidArgumentException('Version number must be between 1 and 40');
171
- }
172
-
173
- if (!isset(self::$versions[$versionNumber])) {
174
- self::buildVersion($versionNumber);
175
- }
176
-
177
- return self::$versions[$versionNumber - 1];
178
- }
179
-
180
- /**
181
- * Decodes version information from an integer and returns the version.
182
- *
183
- * @param integer $versionBits
184
- * @return Version|null
185
- */
186
- public static function decodeVersionInformation($versionBits)
187
- {
188
- $bestDifference = PHP_INT_MAX;
189
- $bestVersion = 0;
190
-
191
- foreach (self::$versionDecodeInfo as $i => $targetVersion) {
192
- if ($targetVersion === $versionBits) {
193
- return self::getVersionForNumber($i + 7);
194
- }
195
-
196
- $bitsDifference = FormatInformation::numBitsDiffering($versionBits, $targetVersion);
197
-
198
- if ($bitsDifference < $bestDifference) {
199
- $bestVersion = $i + 7;
200
- $bestDifference = $bitsDifference;
201
- }
202
- }
203
-
204
- if ($bestDifference <= 3) {
205
- return self::getVersionForNumber($bestVersion);
206
- }
207
-
208
- return null;
209
- }
210
-
211
- /**
212
- * Builds the function pattern for the current version.
213
- *
214
- * @return BitMatrix
215
- */
216
- public function buildFunctionPattern()
217
- {
218
- $dimension = $this->getDimensionForVersion();
219
- $bitMatrix = new BitMatrix($dimension);
220
-
221
- // Top left finder pattern + separator + format
222
- $bitMatrix->setRegion(0, 0, 9, 9);
223
- // Top right finder pattern + separator + format
224
- $bitMatrix->setRegion($dimension - 8, 0, 8, 9);
225
- // Bottom left finder pattern + separator + format
226
- $bitMatrix->setRegion(0, $dimension - 8, 9, 8);
227
-
228
- // Alignment patterns
229
- $max = count($this->alignmentPatternCenters);
230
-
231
- for ($x = 0; $x < $max; $x++) {
232
- $i = $this->alignmentPatternCenters[$x] - 2;
233
-
234
- for ($y = 0; $y < $max; $y++) {
235
- if (($x === 0 && ($y === 0 || $y === $max - 1)) || ($x === $max - 1 && $y === 0)) {
236
- // No alignment patterns near the three finder paterns
237
- continue;
238
- }
239
-
240
- $bitMatrix->setRegion($this->alignmentPatternCenters[$y] - 2, $i, 5, 5);
241
- }
242
- }
243
-
244
- // Vertical timing pattern
245
- $bitMatrix->setRegion(6, 9, 1, $dimension - 17);
246
- // Horizontal timing pattern
247
- $bitMatrix->setRegion(9, 6, $dimension - 17, 1);
248
-
249
- if ($this->versionNumber > 6) {
250
- // Version info, top right
251
- $bitMatrix->setRegion($dimension - 11, 0, 3, 6);
252
- // Version info, bottom left
253
- $bitMatrix->setRegion(0, $dimension - 11, 6, 3);
254
- }
255
-
256
- return $bitMatrix;
257
- }
258
-
259
- /**
260
- * Returns a string representation for the version.
261
- *
262
- * @return string
263
- */
264
- public function __toString()
265
- {
266
- return (string) $this->versionNumber;
267
- }
268
-
269
- /**
270
- * Build and cache a specific version.
271
- *
272
- * See ISO 18004:2006 6.5.1 Table 9.
273
- *
274
- * @param integer $versionNumber
275
- * @return void
276
- */
277
- protected static function buildVersion($versionNumber)
278
- {
279
- switch ($versionNumber) {
280
- case 1:
281
- $patterns = array();
282
- $ecBlocks = array(
283
- new EcBlocks(7, new EcBlock(1, 19)),
284
- new EcBlocks(10, new EcBlock(1, 16)),
285
- new EcBlocks(13, new EcBlock(1, 13)),
286
- new EcBlocks(17, new EcBlock(1, 9)),
287
- );
288
- break;
289
-
290
- case 2:
291
- $patterns = array(6, 18);
292
- $ecBlocks = array(
293
- new EcBlocks(10, new EcBlock(1, 34)),
294
- new EcBlocks(16, new EcBlock(1, 28)),
295
- new EcBlocks(22, new EcBlock(1, 22)),
296
- new EcBlocks(28, new EcBlock(1, 16)),
297
- );
298
- break;
299
-
300
- case 3:
301
- $patterns = array(6, 22);
302
- $ecBlocks = array(
303
- new EcBlocks(15, new EcBlock(1, 55)),
304
- new EcBlocks(26, new EcBlock(1, 44)),
305
- new EcBlocks(18, new EcBlock(2, 17)),
306
- new EcBlocks(22, new EcBlock(2, 13)),
307
- );
308
- break;
309
-
310
- case 4:
311
- $patterns = array(6, 26);
312
- $ecBlocks = array(
313
- new EcBlocks(20, new EcBlock(1, 80)),
314
- new EcBlocks(18, new EcBlock(2, 32)),
315
- new EcBlocks(26, new EcBlock(3, 24)),
316
- new EcBlocks(16, new EcBlock(4, 9)),
317
- );
318
- break;
319
-
320
- case 5:
321
- $patterns = array(6, 30);
322
- $ecBlocks = array(
323
- new EcBlocks(26, new EcBlock(1, 108)),
324
- new EcBlocks(24, new EcBlock(2, 43)),
325
- new EcBlocks(18, new EcBlock(2, 15), new EcBlock(2, 16)),
326
- new EcBlocks(22, new EcBlock(2, 11), new EcBlock(2, 12)),
327
- );
328
- break;
329
-
330
- case 6:
331
- $patterns = array(6, 34);
332
- $ecBlocks = array(
333
- new EcBlocks(18, new EcBlock(2, 68)),
334
- new EcBlocks(16, new EcBlock(4, 27)),
335
- new EcBlocks(24, new EcBlock(4, 19)),
336
- new EcBlocks(28, new EcBlock(4, 15)),
337
- );
338
- break;
339
-
340
- case 7:
341
- $patterns = array(6, 22, 38);
342
- $ecBlocks = array(
343
- new EcBlocks(20, new EcBlock(2, 78)),
344
- new EcBlocks(18, new EcBlock(4, 31)),
345
- new EcBlocks(18, new EcBlock(2, 14), new EcBlock(4, 15)),
346
- new EcBlocks(26, new EcBlock(4, 13), new EcBlock(1, 14)),
347
- );
348
- break;
349
-
350
- case 8:
351
- $patterns = array(6, 24, 42);
352
- $ecBlocks = array(
353
- new EcBlocks(24, new EcBlock(2, 97)),
354
- new EcBlocks(22, new EcBlock(2, 38), new EcBlock(2, 39)),
355
- new EcBlocks(22, new EcBlock(4, 18), new EcBlock(2, 19)),
356
- new EcBlocks(26, new EcBlock(4, 14), new EcBlock(2, 15)),
357
- );
358
- break;
359
-
360
- case 9:
361
- $patterns = array(6, 26, 46);
362
- $ecBlocks = array(
363
- new EcBlocks(30, new EcBlock(2, 116)),
364
- new EcBlocks(22, new EcBlock(3, 36), new EcBlock(2, 37)),
365
- new EcBlocks(20, new EcBlock(4, 16), new EcBlock(4, 17)),
366
- new EcBlocks(24, new EcBlock(4, 12), new EcBlock(4, 13)),
367
- );
368
- break;
369
-
370
- case 10:
371
- $patterns = array(6, 28, 50);
372
- $ecBlocks = array(
373
- new EcBlocks(18, new EcBlock(2, 68), new EcBlock(2, 69)),
374
- new EcBlocks(26, new EcBlock(4, 43), new EcBlock(1, 44)),
375
- new EcBlocks(24, new EcBlock(6, 19), new EcBlock(2, 20)),
376
- new EcBlocks(28, new EcBlock(6, 15), new EcBlock(2, 16)),
377
- );
378
- break;
379
-
380
- case 11:
381
- $patterns = array(6, 30, 54);
382
- $ecBlocks = array(
383
- new EcBlocks(20, new EcBlock(4, 81)),
384
- new EcBlocks(30, new EcBlock(1, 50), new EcBlock(4, 51)),
385
- new EcBlocks(28, new EcBlock(4, 22), new EcBlock(4, 23)),
386
- new EcBlocks(24, new EcBlock(3, 12), new EcBlock(8, 13)),
387
- );
388
- break;
389
-
390
- case 12:
391
- $patterns = array(6, 32, 58);
392
- $ecBlocks = array(
393
- new EcBlocks(24, new EcBlock(2, 92), new EcBlock(2, 93)),
394
- new EcBlocks(22, new EcBlock(6, 36), new EcBlock(2, 37)),
395
- new EcBlocks(26, new EcBlock(4, 20), new EcBlock(6, 21)),
396
- new EcBlocks(28, new EcBlock(7, 14), new EcBlock(4, 15)),
397
- );
398
- break;
399
-
400
- case 13:
401
- $patterns = array(6, 34, 62);
402
- $ecBlocks = array(
403
- new EcBlocks(26, new EcBlock(4, 107)),
404
- new EcBlocks(22, new EcBlock(8, 37), new EcBlock(1, 38)),
405
- new EcBlocks(24, new EcBlock(8, 20), new EcBlock(4, 21)),
406
- new EcBlocks(22, new EcBlock(12, 11), new EcBlock(4, 12)),
407
- );
408
- break;
409
-
410
- case 14:
411
- $patterns = array(6, 26, 46, 66);
412
- $ecBlocks = array(
413
- new EcBlocks(30, new EcBlock(3, 115), new EcBlock(1, 116)),
414
- new EcBlocks(24, new EcBlock(4, 40), new EcBlock(5, 41)),
415
- new EcBlocks(20, new EcBlock(11, 16), new EcBlock(5, 17)),
416
- new EcBlocks(24, new EcBlock(11, 12), new EcBlock(5, 13)),
417
- );
418
- break;
419
-
420
- case 15:
421
- $patterns = array(6, 26, 48, 70);
422
- $ecBlocks = array(
423
- new EcBlocks(22, new EcBlock(5, 87), new EcBlock(1, 88)),
424
- new EcBlocks(24, new EcBlock(5, 41), new EcBlock(5, 42)),
425
- new EcBlocks(30, new EcBlock(5, 24), new EcBlock(7, 25)),
426
- new EcBlocks(24, new EcBlock(11, 12), new EcBlock(7, 13)),
427
- );
428
- break;
429
-
430
- case 16:
431
- $patterns = array(6, 26, 50, 74);
432
- $ecBlocks = array(
433
- new EcBlocks(24, new EcBlock(5, 98), new EcBlock(1, 99)),
434
- new EcBlocks(28, new EcBlock(7, 45), new EcBlock(3, 46)),
435
- new EcBlocks(24, new EcBlock(15, 19), new EcBlock(2, 20)),
436
- new EcBlocks(30, new EcBlock(3, 15), new EcBlock(13, 16)),
437
- );
438
- break;
439
-
440
- case 17:
441
- $patterns = array(6, 30, 54, 78);
442
- $ecBlocks = array(
443
- new EcBlocks(28, new EcBlock(1, 107), new EcBlock(5, 108)),
444
- new EcBlocks(28, new EcBlock(10, 46), new EcBlock(1, 47)),
445
- new EcBlocks(28, new EcBlock(1, 22), new EcBlock(15, 23)),
446
- new EcBlocks(28, new EcBlock(2, 14), new EcBlock(17, 15)),
447
- );
448
- break;
449
-
450
- case 18:
451
- $patterns = array(6, 30, 56, 82);
452
- $ecBlocks = array(
453
- new EcBlocks(30, new EcBlock(5, 120), new EcBlock(1, 121)),
454
- new EcBlocks(26, new EcBlock(9, 43), new EcBlock(4, 44)),
455
- new EcBlocks(28, new EcBlock(17, 22), new EcBlock(1, 23)),
456
- new EcBlocks(28, new EcBlock(2, 14), new EcBlock(19, 15)),
457
- );
458
- break;
459
-
460
- case 19:
461
- $patterns = array(6, 30, 58, 86);
462
- $ecBlocks = array(
463
- new EcBlocks(28, new EcBlock(3, 113), new EcBlock(4, 114)),
464
- new EcBlocks(26, new EcBlock(3, 44), new EcBlock(11, 45)),
465
- new EcBlocks(26, new EcBlock(17, 21), new EcBlock(4, 22)),
466
- new EcBlocks(26, new EcBlock(9, 13), new EcBlock(16, 14)),
467
- );
468
- break;
469
-
470
- case 20:
471
- $patterns = array(6, 34, 62, 90);
472
- $ecBlocks = array(
473
- new EcBlocks(28, new EcBlock(3, 107), new EcBlock(5, 108)),
474
- new EcBlocks(26, new EcBlock(3, 41), new EcBlock(13, 42)),
475
- new EcBlocks(30, new EcBlock(15, 24), new EcBlock(5, 25)),
476
- new EcBlocks(28, new EcBlock(15, 15), new EcBlock(10, 16)),
477
- );
478
- break;
479
-
480
- case 21:
481
- $patterns = array(6, 28, 50, 72, 94);
482
- $ecBlocks = array(
483
- new EcBlocks(28, new EcBlock(4, 116), new EcBlock(4, 117)),
484
- new EcBlocks(26, new EcBlock(17, 42)),
485
- new EcBlocks(28, new EcBlock(17, 22), new EcBlock(6, 23)),
486
- new EcBlocks(30, new EcBlock(19, 16), new EcBlock(6, 17)),
487
- );
488
- break;
489
-
490
- case 22:
491
- $patterns = array(6, 26, 50, 74, 98);
492
- $ecBlocks = array(
493
- new EcBlocks(28, new EcBlock(2, 111), new EcBlock(7, 112)),
494
- new EcBlocks(28, new EcBlock(17, 46)),
495
- new EcBlocks(30, new EcBlock(7, 24), new EcBlock(16, 25)),
496
- new EcBlocks(24, new EcBlock(34, 13)),
497
- );
498
- break;
499
-
500
- case 23:
501
- $patterns = array(6, 30, 54, 78, 102);
502
- $ecBlocks = array(
503
- new EcBlocks(30, new EcBlock(4, 121), new EcBlock(5, 122)),
504
- new EcBlocks(28, new EcBlock(4, 47), new EcBlock(14, 48)),
505
- new EcBlocks(30, new EcBlock(11, 24), new EcBlock(14, 25)),
506
- new EcBlocks(30, new EcBlock(16, 15), new EcBlock(14, 16)),
507
- );
508
- break;
509
-
510
- case 24:
511
- $patterns = array(6, 28, 54, 80, 106);
512
- $ecBlocks = array(
513
- new EcBlocks(30, new EcBlock(6, 117), new EcBlock(4, 118)),
514
- new EcBlocks(28, new EcBlock(6, 45), new EcBlock(14, 46)),
515
- new EcBlocks(30, new EcBlock(11, 24), new EcBlock(16, 25)),
516
- new EcBlocks(30, new EcBlock(30, 16), new EcBlock(2, 17)),
517
- );
518
- break;
519
-
520
- case 25:
521
- $patterns = array(6, 32, 58, 84, 110);
522
- $ecBlocks = array(
523
- new EcBlocks(26, new EcBlock(8, 106), new EcBlock(4, 107)),
524
- new EcBlocks(28, new EcBlock(8, 47), new EcBlock(13, 48)),
525
- new EcBlocks(30, new EcBlock(7, 24), new EcBlock(22, 25)),
526
- new EcBlocks(30, new EcBlock(22, 15), new EcBlock(13, 16)),
527
- );
528
- break;
529
-
530
- case 26:
531
- $patterns = array(6, 30, 58, 86, 114);
532
- $ecBlocks = array(
533
- new EcBlocks(28, new EcBlock(10, 114), new EcBlock(2, 115)),
534
- new EcBlocks(28, new EcBlock(19, 46), new EcBlock(4, 47)),
535
- new EcBlocks(28, new EcBlock(28, 22), new EcBlock(6, 23)),
536
- new EcBlocks(30, new EcBlock(33, 16), new EcBlock(4, 17)),
537
- );
538
- break;
539
-
540
- case 27:
541
- $patterns = array(6, 34, 62, 90, 118);
542
- $ecBlocks = array(
543
- new EcBlocks(30, new EcBlock(8, 122), new EcBlock(4, 123)),
544
- new EcBlocks(28, new EcBlock(22, 45), new EcBlock(3, 46)),
545
- new EcBlocks(30, new EcBlock(8, 23), new EcBlock(26, 24)),
546
- new EcBlocks(30, new EcBlock(12, 15), new EcBlock(28, 16)),
547
- );
548
- break;
549
-
550
- case 28:
551
- $patterns = array(6, 26, 50, 74, 98, 122);
552
- $ecBlocks = array(
553
- new EcBlocks(30, new EcBlock(3, 117), new EcBlock(10, 118)),
554
- new EcBlocks(28, new EcBlock(3, 45), new EcBlock(23, 46)),
555
- new EcBlocks(30, new EcBlock(4, 24), new EcBlock(31, 25)),
556
- new EcBlocks(30, new EcBlock(11, 15), new EcBlock(31, 16)),
557
- );
558
- break;
559
-
560
- case 29:
561
- $patterns = array(6, 30, 54, 78, 102, 126);
562
- $ecBlocks = array(
563
- new EcBlocks(30, new EcBlock(7, 116), new EcBlock(7, 117)),
564
- new EcBlocks(28, new EcBlock(21, 45), new EcBlock(7, 46)),
565
- new EcBlocks(30, new EcBlock(1, 23), new EcBlock(37, 24)),
566
- new EcBlocks(30, new EcBlock(19, 15), new EcBlock(26, 16)),
567
- );
568
- break;
569
-
570
- case 30:
571
- $patterns = array(6, 26, 52, 78, 104, 130);
572
- $ecBlocks = array(
573
- new EcBlocks(30, new EcBlock(5, 115), new EcBlock(10, 116)),
574
- new EcBlocks(28, new EcBlock(19, 47), new EcBlock(10, 48)),
575
- new EcBlocks(30, new EcBlock(15, 24), new EcBlock(25, 25)),
576
- new EcBlocks(30, new EcBlock(23, 15), new EcBlock(25, 16)),
577
- );
578
- break;
579
-
580
- case 31:
581
- $patterns = array(6, 30, 56, 82, 108, 134);
582
- $ecBlocks = array(
583
- new EcBlocks(30, new EcBlock(13, 115), new EcBlock(3, 116)),
584
- new EcBlocks(28, new EcBlock(2, 46), new EcBlock(29, 47)),
585
- new EcBlocks(30, new EcBlock(42, 24), new EcBlock(1, 25)),
586
- new EcBlocks(30, new EcBlock(23, 15), new EcBlock(28, 16)),
587
- );
588
- break;
589
-
590
- case 32:
591
- $patterns = array(6, 34, 60, 86, 112, 138);
592
- $ecBlocks = array(
593
- new EcBlocks(30, new EcBlock(17, 115)),
594
- new EcBlocks(28, new EcBlock(10, 46), new EcBlock(23, 47)),
595
- new EcBlocks(30, new EcBlock(10, 24), new EcBlock(35, 25)),
596
- new EcBlocks(30, new EcBlock(19, 15), new EcBlock(35, 16)),
597
- );
598
- break;
599
-
600
- case 33:
601
- $patterns = array(6, 30, 58, 86, 114, 142);
602
- $ecBlocks = array(
603
- new EcBlocks(30, new EcBlock(17, 115), new EcBlock(1, 116)),
604
- new EcBlocks(28, new EcBlock(14, 46), new EcBlock(21, 47)),
605
- new EcBlocks(30, new EcBlock(29, 24), new EcBlock(19, 25)),
606
- new EcBlocks(30, new EcBlock(11, 15), new EcBlock(46, 16)),
607
- );
608
- break;
609
-
610
- case 34:
611
- $patterns = array(6, 34, 62, 90, 118, 146);
612
- $ecBlocks = array(
613
- new EcBlocks(30, new EcBlock(13, 115), new EcBlock(6, 116)),
614
- new EcBlocks(28, new EcBlock(14, 46), new EcBlock(23, 47)),
615
- new EcBlocks(30, new EcBlock(44, 24), new EcBlock(7, 25)),
616
- new EcBlocks(30, new EcBlock(59, 16), new EcBlock(1, 17)),
617
- );
618
- break;
619
-
620
- case 35:
621
- $patterns = array(6, 30, 54, 78, 102, 126, 150);
622
- $ecBlocks = array(
623
- new EcBlocks(30, new EcBlock(12, 121), new EcBlock(7, 122)),
624
- new EcBlocks(28, new EcBlock(12, 47), new EcBlock(26, 48)),
625
- new EcBlocks(30, new EcBlock(39, 24), new EcBlock(14, 25)),
626
- new EcBlocks(30, new EcBlock(22, 15), new EcBlock(41, 16)),
627
- );
628
- break;
629
-
630
- case 36:
631
- $patterns = array(6, 24, 50, 76, 102, 128, 154);
632
- $ecBlocks = array(
633
- new EcBlocks(30, new EcBlock(6, 121), new EcBlock(14, 122)),
634
- new EcBlocks(28, new EcBlock(6, 47), new EcBlock(34, 48)),
635
- new EcBlocks(30, new EcBlock(46, 24), new EcBlock(10, 25)),
636
- new EcBlocks(30, new EcBlock(2, 15), new EcBlock(64, 16)),
637
- );
638
- break;
639
-
640
- case 37:
641
- $patterns = array(6, 28, 54, 80, 106, 132, 158);
642
- $ecBlocks = array(
643
- new EcBlocks(30, new EcBlock(17, 122), new EcBlock(4, 123)),
644
- new EcBlocks(28, new EcBlock(29, 46), new EcBlock(14, 47)),
645
- new EcBlocks(30, new EcBlock(49, 24), new EcBlock(10, 25)),
646
- new EcBlocks(30, new EcBlock(24, 15), new EcBlock(46, 16)),
647
- );
648
- break;
649
-
650
- case 38:
651
- $patterns = array(6, 32, 58, 84, 110, 136, 162);
652
- $ecBlocks = array(
653
- new EcBlocks(30, new EcBlock(4, 122), new EcBlock(18, 123)),
654
- new EcBlocks(28, new EcBlock(13, 46), new EcBlock(32, 47)),
655
- new EcBlocks(30, new EcBlock(48, 24), new EcBlock(14, 25)),
656
- new EcBlocks(30, new EcBlock(42, 15), new EcBlock(32, 16)),
657
- );
658
- break;
659
-
660
- case 39:
661
- $patterns = array(6, 26, 54, 82, 110, 138, 166);
662
- $ecBlocks = array(
663
- new EcBlocks(30, new EcBlock(20, 117), new EcBlock(4, 118)),
664
- new EcBlocks(28, new EcBlock(40, 47), new EcBlock(7, 48)),
665
- new EcBlocks(30, new EcBlock(43, 24), new EcBlock(22, 25)),
666
- new EcBlocks(30, new EcBlock(10, 15), new EcBlock(67, 16)),
667
- );
668
- break;
669
-
670
- case 40:
671
- $patterns = array(6, 30, 58, 86, 114, 142, 170);
672
- $ecBlocks = array(
673
- new EcBlocks(30, new EcBlock(19, 118), new EcBlock(6, 119)),
674
- new EcBlocks(28, new EcBlock(18, 47), new EcBlock(31, 48)),
675
- new EcBlocks(30, new EcBlock(34, 24), new EcBlock(34, 25)),
676
- new EcBlocks(30, new EcBlock(20, 15), new EcBlock(61, 16)),
677
- );
678
- break;
679
- }
680
-
681
- self::$versions[$versionNumber - 1] = new self(
682
- $versionNumber,
683
- SplFixedArray::fromArray($patterns, false),
684
- SplFixedArray::fromArray($ecBlocks, false)
685
- );
686
- }
687
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Encoder/BlockPair.php DELETED
@@ -1,64 +0,0 @@
1
- <?php
2
- /**
3
- * BaconQrCode
4
- *
5
- * @link http://github.com/Bacon/BaconQrCode For the canonical source repository
6
- * @copyright 2013 Ben 'DASPRiD' Scholzen
7
- * @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
8
- */
9
-
10
- namespace BaconQrCode\Encoder;
11
-
12
- use SplFixedArray;
13
-
14
- /**
15
- * Block pair.
16
- */
17
- class BlockPair
18
- {
19
- /**
20
- * Data bytes in the block.
21
- *
22
- * @var SplFixedArray
23
- */
24
- protected $dataBytes;
25
-
26
- /**
27
- * Error correction bytes in the block.
28
- *
29
- * @var SplFixedArray
30
- */
31
- protected $errorCorrectionBytes;
32
-
33
- /**
34
- * Creates a new block pair.
35
- *
36
- * @param SplFixedArray $data
37
- * @param SplFixedArray $errorCorrection
38
- */
39
- public function __construct(SplFixedArray $data, SplFixedArray $errorCorrection)
40
- {
41
- $this->dataBytes = $data;
42
- $this->errorCorrectionBytes = $errorCorrection;
43
- }
44
-
45
- /**
46
- * Gets the data bytes.
47
- *
48
- * @return SplFixedArray
49
- */
50
- public function getDataBytes()
51
- {
52
- return $this->dataBytes;
53
- }
54
-
55
- /**
56
- * Gets the error correction bytes.
57
- *
58
- * @return SplFixedArray
59
- */
60
- public function getErrorCorrectionBytes()
61
- {
62
- return $this->errorCorrectionBytes;
63
- }
64
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Encoder/ByteMatrix.php DELETED
@@ -1,158 +0,0 @@
1
- <?php
2
- /**
3
- * BaconQrCode
4
- *
5
- * @link http://github.com/Bacon/BaconQrCode For the canonical source repository
6
- * @copyright 2013 Ben 'DASPRiD' Scholzen
7
- * @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
8
- */
9
-
10
- namespace BaconQrCode\Encoder;
11
-
12
- use SplFixedArray;
13
-
14
- /**
15
- * Byte matrix.
16
- */
17
- class ByteMatrix
18
- {
19
- /**
20
- * Bytes in the matrix, represented as array.
21
- *
22
- * @var SplFixedArray
23
- */
24
- protected $bytes;
25
-
26
- /**
27
- * Width of the matrix.
28
- *
29
- * @var integer
30
- */
31
- protected $width;
32
-
33
- /**
34
- * Height of the matrix.
35
- *
36
- * @var integer
37
- */
38
- protected $height;
39
-
40
- /**
41
- * Creates a new byte matrix.
42
- *
43
- * @param integer $width
44
- * @param integer $height
45
- */
46
- public function __construct($width, $height)
47
- {
48
- $this->height = $height;
49
- $this->width = $width;
50
- $this->bytes = new SplFixedArray($height);
51
-
52
- for ($y = 0; $y < $height; $y++) {
53
- $this->bytes[$y] = new SplFixedArray($width);
54
- }
55
- }
56
-
57
- /**
58
- * Gets the width of the matrix.
59
- *
60
- * @return integer
61
- */
62
- public function getWidth()
63
- {
64
- return $this->width;
65
- }
66
-
67
- /**
68
- * Gets the height of the matrix.
69
- *
70
- * @return integer
71
- */
72
- public function getHeight()
73
- {
74
- return $this->height;
75
- }
76
-
77
- /**
78
- * Gets the internal representation of the matrix.
79
- *
80
- * @return SplFixedArray
81
- */
82
- public function getArray()
83
- {
84
- return $this->bytes;
85
- }
86
-
87
- /**
88
- * Gets the byte for a specific position.
89
- *
90
- * @param integer $x
91
- * @param integer $y
92
- * @return integer
93
- */
94
- public function get($x, $y)
95
- {
96
- return $this->bytes[$y][$x];
97
- }
98
-
99
- /**
100
- * Sets the byte for a specific position.
101
- *
102
- * @param integer $x
103
- * @param integer $y
104
- * @param integer $value
105
- * @return void
106
- */
107
- public function set($x, $y, $value)
108
- {
109
- $this->bytes[$y][$x] = (int) $value;
110
- }
111
-
112
- /**
113
- * Clears the matrix with a specific value.
114
- *
115
- * @param integer $value
116
- * @return void
117
- */
118
- public function clear($value)
119
- {
120
- for ($y = 0; $y < $this->height; $y++) {
121
- for ($x = 0; $x < $this->width; $x++) {
122
- $this->bytes[$y][$x] = $value;
123
- }
124
- }
125
- }
126
-
127
- /**
128
- * Returns a string representation of the matrix.
129
- *
130
- * @return string
131
- */
132
- public function __toString()
133
- {
134
- $result = '';
135
-
136
- for ($y = 0; $y < $this->height; $y++) {
137
- for ($x = 0; $x < $this->width; $x++) {
138
- switch ($this->bytes[$y][$x]) {
139
- case 0:
140
- $result .= ' 0';
141
- break;
142
-
143
- case 1:
144
- $result .= ' 1';
145
- break;
146
-
147
- default:
148
- $result .= ' ';
149
- break;
150
- }
151
- }
152
-
153
- $result .= "\n";
154
- }
155
-
156
- return $result;
157
- }
158
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Encoder/Encoder.php DELETED
@@ -1,687 +0,0 @@
1
- <?php
2
- /**
3
- * BaconQrCode
4
- *
5
- * @link http://github.com/Bacon/BaconQrCode For the canonical source repository
6
- * @copyright 2013 Ben 'DASPRiD' Scholzen
7
- * @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
8
- */
9
-
10
- namespace BaconQrCode\Encoder;
11
-
12
- use BaconQrCode\Common\BitArray;
13
- use BaconQrCode\Common\CharacterSetEci;
14
- use BaconQrCode\Common\ErrorCorrectionLevel;
15
- use BaconQrCode\Common\Mode;
16
- use BaconQrCode\Common\ReedSolomonCodec;
17
- use BaconQrCode\Common\Version;
18
- use BaconQrCode\Exception;
19
- use SplFixedArray;
20
-
21
- /**
22
- * Encoder.
23
- */
24
- class Encoder
25
- {
26
- /**
27
- * Default byte encoding.
28
- */
29
- const DEFAULT_BYTE_MODE_ECODING = 'ISO-8859-1';
30
-
31
- /**
32
- * The original table is defined in the table 5 of JISX0510:2004 (p.19).
33
- *
34
- * @var array
35
- */
36
- protected static $alphanumericTable = array(
37
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0x00-0x0f
38
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0x10-0x1f
39
- 36, -1, -1, -1, 37, 38, -1, -1, -1, -1, 39, 40, -1, 41, 42, 43, // 0x20-0x2f
40
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 44, -1, -1, -1, -1, -1, // 0x30-0x3f
41
- -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, // 0x40-0x4f
42
- 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, // 0x50-0x5f
43
- );
44
-
45
- /**
46
- * Codec cache.
47
- *
48
- * @var array
49
- */
50
- protected static $codecs = array();
51
-
52
- /**
53
- * Encodes "content" with the error correction level "ecLevel".
54
- *
55
- * @param string $content
56
- * @param ErrorCorrectionLevel $ecLevel
57
- * @param ? $hints
58
- * @return QrCode
59
- */
60
- public static function encode($content, ErrorCorrectionLevel $ecLevel, $encoding = self::DEFAULT_BYTE_MODE_ECODING)
61
- {
62
- // Pick an encoding mode appropriate for the content. Note that this
63
- // will not attempt to use multiple modes / segments even if that were
64
- // more efficient. Would be nice.
65
- $mode = self::chooseMode($content, $encoding);
66
-
67
- // This will store the header information, like mode and length, as well
68
- // as "header" segments like an ECI segment.
69
- $headerBits = new BitArray();
70
-
71
- // Append ECI segment if applicable
72
- if ($mode->get() === Mode::BYTE && $encoding !== self::DEFAULT_BYTE_MODE_ECODING) {
73
- $eci = CharacterSetEci::getCharacterSetEciByName($encoding);
74
-
75
- if ($eci !== null) {
76
- self::appendEci($eci, $headerBits);
77
- }
78
- }
79
-
80
- // (With ECI in place,) Write the mode marker
81
- self::appendModeInfo($mode, $headerBits);
82
-
83
- // Collect data within the main segment, separately, to count its size
84
- // if needed. Don't add it to main payload yet.
85
- $dataBits = new BitArray();
86
- self::appendBytes($content, $mode, $dataBits, $encoding);
87
-
88
- // Hard part: need to know version to know how many bits length takes.
89
- // But need to know how many bits it takes to know version. First we
90
- // take a guess at version by assuming version will be the minimum, 1:
91
- $provisionalBitsNeeded = $headerBits->getSize()
92
- + $mode->getCharacterCountBits(Version::getVersionForNumber(1))
93
- + $dataBits->getSize();
94
- $provisionalVersion = self::chooseVersion($provisionalBitsNeeded, $ecLevel);
95
-
96
- // Use that guess to calculate the right version. I am still not sure
97
- // this works in 100% of cases.
98
- $bitsNeeded = $headerBits->getSize()
99
- + $mode->getCharacterCountBits($provisionalVersion)
100
- + $dataBits->getSize();
101
- $version = self::chooseVersion($bitsNeeded, $ecLevel);
102
-
103
- $headerAndDataBits = new BitArray();
104
- $headerAndDataBits->appendBitArray($headerBits);
105
-
106
- // Find "length" of main segment and write it.
107
- $numLetters = ($mode->get() === Mode::BYTE ? $dataBits->getSizeInBytes() : strlen($content));
108
- self::appendLengthInfo($numLetters, $version, $mode, $headerAndDataBits);
109
-
110
- // Put data together into the overall payload.
111
- $headerAndDataBits->appendBitArray($dataBits);
112
- $ecBlocks = $version->getEcBlocksForLevel($ecLevel);
113
- $numDataBytes = $version->getTotalCodewords() - $ecBlocks->getTotalEcCodewords();
114
-
115
- // Terminate the bits properly.
116
- self::terminateBits($numDataBytes, $headerAndDataBits);
117
-
118
- // Interleave data bits with error correction code.
119
- $finalBits = self::interleaveWithEcBytes(
120
- $headerAndDataBits,
121
- $version->getTotalCodewords(),
122
- $numDataBytes,
123
- $ecBlocks->getNumBlocks()
124
- );
125
-
126
- $qrCode = new QrCode();
127
- $qrCode->setErrorCorrectionLevel($ecLevel);
128
- $qrCode->setMode($mode);
129
- $qrCode->setVersion($version);
130
-
131
- // Choose the mask pattern and set to "qrCode".
132
- $dimension = $version->getDimensionForVersion();
133
- $matrix = new ByteMatrix($dimension, $dimension);
134
- $maskPattern = self::chooseMaskPattern($finalBits, $ecLevel, $version, $matrix);
135
- $qrCode->setMaskPattern($maskPattern);
136
-
137
- // Build the matrix and set it to "qrCode".
138
- MatrixUtil::buildMatrix($finalBits, $ecLevel, $version, $maskPattern, $matrix);
139
- $qrCode->setMatrix($matrix);
140
-
141
- return $qrCode;
142
- }
143
-
144
- /**
145
- * Gets the alphanumeric code for a byte.
146
- *
147
- * @param string|integer $code
148
- * @return integer
149
- */
150
- protected static function getAlphanumericCode($code)
151
- {
152
- $code = (is_string($code) ? ord($code) : $code);
153
-
154
- if (isset(self::$alphanumericTable[$code])) {
155
- return self::$alphanumericTable[$code];
156
- }
157
-
158
- return -1;
159
- }
160
-
161
- /**
162
- * Chooses the best mode for a given content.
163
- *
164
- * @param string $content
165
- * @param string $encoding
166
- * @return Mode
167
- */
168
- protected static function chooseMode($content, $encoding = null)
169
- {
170
- if (strcasecmp($encoding, 'SHIFT-JIS') === 0) {
171
- return self::isOnlyDoubleByteKanji($content) ? new Mode(Mode::KANJI) : new Mode(Mode::BYTE);
172
- }
173
-
174
- $hasNumeric = false;
175
- $hasAlphanumeric = false;
176
- $contentLength = strlen($content);
177
-
178
- for ($i = 0; $i < $contentLength; $i++) {
179
- $char = $content[$i];
180
-
181
- if (ctype_digit($char)) {
182
- $hasNumeric = true;
183
- } elseif (self::getAlphanumericCode($char) !== -1) {
184
- $hasAlphanumeric = true;
185
- } else {
186
- return new Mode(Mode::BYTE);
187
- }
188
- }
189
-
190
- if ($hasAlphanumeric) {
191
- return new Mode(Mode::ALPHANUMERIC);
192
- } elseif ($hasNumeric) {
193
- return new Mode(Mode::NUMERIC);
194
- }
195
-
196
- return new Mode(Mode::BYTE);
197
- }
198
-
199
- /**
200
- * Calculates the mask penalty for a matrix.
201
- *
202
- * @param ByteMatrix $matrix
203
- * @return integer
204
- */
205
- protected static function calculateMaskPenalty(ByteMatrix $matrix)
206
- {
207
- return (
208
- MaskUtil::applyMaskPenaltyRule1($matrix)
209
- + MaskUtil::applyMaskPenaltyRule2($matrix)
210
- + MaskUtil::applyMaskPenaltyRule3($matrix)
211
- + MaskUtil::applyMaskPenaltyRule4($matrix)
212
- );
213
- }
214
-
215
- /**
216
- * Chooses the best mask pattern for a matrix.
217
- *
218
- * @param BitArray $bits
219
- * @param ErrorCorrectionLevel $ecLevel
220
- * @param Version $version
221
- * @param ByteMatrix $matrix
222
- * @return integer
223
- */
224
- protected static function chooseMaskPattern(
225
- BitArray $bits,
226
- ErrorCorrectionLevel $ecLevel,
227
- Version $version,
228
- ByteMatrix $matrix
229
- ) {
230
- $minPenality = PHP_INT_MAX;
231
- $bestMaskPattern = -1;
232
-
233
- for ($maskPattern = 0; $maskPattern < QrCode::NUM_MASK_PATTERNS; $maskPattern++) {
234
- MatrixUtil::buildMatrix($bits, $ecLevel, $version, $maskPattern, $matrix);
235
- $penalty = self::calculateMaskPenalty($matrix);
236
-
237
- if ($penalty < $minPenality) {
238
- $minPenality = $penalty;
239
- $bestMaskPattern = $maskPattern;
240
- }
241
- }
242
-
243
- return $bestMaskPattern;
244
- }
245
-
246
- /**
247
- * Chooses the best version for the input.
248
- *
249
- * @param integer $numInputBits
250
- * @param ErrorCorrectionLevel $ecLevel
251
- * @return Version
252
- * @throws Exception\WriterException
253
- */
254
- protected static function chooseVersion($numInputBits, ErrorCorrectionLevel $ecLevel)
255
- {
256
- for ($versionNum = 1; $versionNum <= 40; $versionNum++) {
257
- $version = Version::getVersionForNumber($versionNum);
258
- $numBytes = $version->getTotalCodewords();
259
-
260
- $ecBlocks = $version->getEcBlocksForLevel($ecLevel);
261
- $numEcBytes = $ecBlocks->getTotalEcCodewords();
262
-
263
- $numDataBytes = $numBytes - $numEcBytes;
264
- $totalInputBytes = intval(($numInputBits + 8) / 8);
265
-
266
- if ($numDataBytes >= $totalInputBytes) {
267
- return $version;
268
- }
269
- }
270
-
271
- throw new Exception\WriterException('Data too big');
272
- }
273
-
274
- /**
275
- * Terminates the bits in a bit array.
276
- *
277
- * @param integer $numDataBytes
278
- * @param BitArray $bits
279
- * @throws Exception\WriterException
280
- */
281
- protected static function terminateBits($numDataBytes, BitArray $bits)
282
- {
283
- $capacity = $numDataBytes << 3;
284
-
285
- if ($bits->getSize() > $capacity) {
286
- throw new Exception\WriterException('Data bits cannot fit in the QR code');
287
- }
288
-
289
- for ($i = 0; $i < 4 && $bits->getSize() < $capacity; $i++) {
290
- $bits->appendBit(false);
291
- }
292
-
293
- $numBitsInLastByte = $bits->getSize() & 0x7;
294
-
295
- if ($numBitsInLastByte > 0) {
296
- for ($i = $numBitsInLastByte; $i < 8; $i++) {
297
- $bits->appendBit(false);
298
- }
299
- }
300
-
301
- $numPaddingBytes = $numDataBytes - $bits->getSizeInBytes();
302
-
303
- for ($i = 0; $i < $numPaddingBytes; $i++) {
304
- $bits->appendBits(($i & 0x1) === 0 ? 0xec : 0x11, 8);
305
- }
306
-
307
- if ($bits->getSize() !== $capacity) {
308
- throw new Exception\WriterException('Bits size does not equal capacity');
309
- }
310
- }
311
-
312
- /**
313
- * Gets number of data- and EC bytes for a block ID.
314
- *
315
- * @param integer $numTotalBytes
316
- * @param integer $numDataBytes
317
- * @param integer $numRsBlocks
318
- * @param integer $blockId
319
- * @return array
320
- * @throws Exception\WriterException
321
- */
322
- protected static function getNumDataBytesAndNumEcBytesForBlockId(
323
- $numTotalBytes,
324
- $numDataBytes,
325
- $numRsBlocks,
326
- $blockId
327
- ) {
328
- if ($blockId >= $numRsBlocks) {
329
- throw new Exception\WriterException('Block ID too large');
330
- }
331
-
332
- $numRsBlocksInGroup2 = $numTotalBytes % $numRsBlocks;
333
- $numRsBlocksInGroup1 = $numRsBlocks - $numRsBlocksInGroup2;
334
- $numTotalBytesInGroup1 = intval($numTotalBytes / $numRsBlocks);
335
- $numTotalBytesInGroup2 = $numTotalBytesInGroup1 + 1;
336
- $numDataBytesInGroup1 = intval($numDataBytes / $numRsBlocks);
337
- $numDataBytesInGroup2 = $numDataBytesInGroup1 + 1;
338
- $numEcBytesInGroup1 = $numTotalBytesInGroup1 - $numDataBytesInGroup1;
339
- $numEcBytesInGroup2 = $numTotalBytesInGroup2 - $numDataBytesInGroup2;
340
-
341
- if ($numEcBytesInGroup1 !== $numEcBytesInGroup2) {
342
- throw new Exception\WriterException('EC bytes mismatch');
343
- }
344
-
345
- if ($numRsBlocks !== $numRsBlocksInGroup1 + $numRsBlocksInGroup2) {
346
- throw new Exception\WriterException('RS blocks mismatch');
347
- }
348
-
349
- if ($numTotalBytes !==
350
- (($numDataBytesInGroup1 + $numEcBytesInGroup1) * $numRsBlocksInGroup1)
351
- + (($numDataBytesInGroup2 + $numEcBytesInGroup2) * $numRsBlocksInGroup2)
352
- ) {
353
- throw new Exception\WriterException('Total bytes mismatch');
354
- }
355
-
356
- if ($blockId < $numRsBlocksInGroup1) {
357
- return array($numDataBytesInGroup1, $numEcBytesInGroup1);
358
- } else {
359
- return array($numDataBytesInGroup2, $numEcBytesInGroup2);
360
- }
361
- }
362
-
363
- /**
364
- * Interleaves data with EC bytes.
365
- *
366
- * @param BitArray $bits
367
- * @param integer $numTotalBytes
368
- * @param integer $numDataBytes
369
- * @param integer $numRsBlocks
370
- * @return BitArray
371
- * @throws Exception\WriterException
372
- */
373
- protected static function interleaveWithEcBytes(BitArray $bits, $numTotalBytes, $numDataBytes, $numRsBlocks)
374
- {
375
- if ($bits->getSizeInBytes() !== $numDataBytes) {
376
- throw new Exception\WriterException('Number of bits and data bytes does not match');
377
- }
378
-
379
- $dataBytesOffset = 0;
380
- $maxNumDataBytes = 0;
381
- $maxNumEcBytes = 0;
382
-
383
- $blocks = new SplFixedArray($numRsBlocks);
384
-
385
- for ($i = 0; $i < $numRsBlocks; $i++) {
386
- list($numDataBytesInBlock, $numEcBytesInBlock) = self::getNumDataBytesAndNumEcBytesForBlockId(
387
- $numTotalBytes,
388
- $numDataBytes,
389
- $numRsBlocks,
390
- $i
391
- );
392
-
393
- $size = $numDataBytesInBlock;
394
- $dataBytes = $bits->toBytes(8 * $dataBytesOffset, $size);
395
- $ecBytes = self::generateEcBytes($dataBytes, $numEcBytesInBlock);
396
- $blocks[$i] = new BlockPair($dataBytes, $ecBytes);
397
-
398
- $maxNumDataBytes = max($maxNumDataBytes, $size);
399
- $maxNumEcBytes = max($maxNumEcBytes, count($ecBytes));
400
- $dataBytesOffset += $numDataBytesInBlock;
401
- }
402
-
403
- if ($numDataBytes !== $dataBytesOffset) {
404
- throw new Exception\WriterException('Data bytes does not match offset');
405
- }
406
-
407
- $result = new BitArray();
408
-
409
- for ($i = 0; $i < $maxNumDataBytes; $i++) {
410
- foreach ($blocks as $block) {
411
- $dataBytes = $block->getDataBytes();
412
-
413
- if ($i < count($dataBytes)) {
414
- $result->appendBits($dataBytes[$i], 8);
415
- }
416
- }
417
- }
418
-
419
- for ($i = 0; $i < $maxNumEcBytes; $i++) {
420
- foreach ($blocks as $block) {
421
- $ecBytes = $block->getErrorCorrectionBytes();
422
-
423
- if ($i < count($ecBytes)) {
424
- $result->appendBits($ecBytes[$i], 8);
425
- }
426
- }
427
- }
428
-
429
- if ($numTotalBytes !== $result->getSizeInBytes()) {
430
- throw new Exception\WriterException('Interleaving error: ' . $numTotalBytes . ' and ' . $result->getSizeInBytes() . ' differ');
431
- }
432
-
433
- return $result;
434
- }
435
-
436
- /**
437
- * Generates EC bytes for given data.
438
- *
439
- * @param SplFixedArray $dataBytes
440
- * @param integer $numEcBytesInBlock
441
- * @return SplFixedArray
442
- */
443
- protected static function generateEcBytes(SplFixedArray $dataBytes, $numEcBytesInBlock)
444
- {
445
- $numDataBytes = count($dataBytes);
446
- $toEncode = new SplFixedArray($numDataBytes + $numEcBytesInBlock);
447
-
448
- for ($i = 0; $i < $numDataBytes; $i++) {
449
- $toEncode[$i] = $dataBytes[$i] & 0xff;
450
- }
451
-
452
- $ecBytes = new SplFixedArray($numEcBytesInBlock);
453
- $codec = self::getCodec($numDataBytes, $numEcBytesInBlock);
454
- $codec->encode($toEncode, $ecBytes);
455
-
456
- return $ecBytes;
457
- }
458
-
459
- /**
460
- * Gets an RS codec and caches it.
461
- *
462
- * @param integer $numDataBytes
463
- * @param integer $numEcBytesInBlock
464
- * @return ReedSolomonCodec
465
- */
466
- protected static function getCodec($numDataBytes, $numEcBytesInBlock)
467
- {
468
- $cacheId = $numDataBytes . '-' . $numEcBytesInBlock;
469
-
470
- if (!isset(self::$codecs[$cacheId])) {
471
- self::$codecs[$cacheId] = new ReedSolomonCodec(
472
- 8,
473
- 0x11d,
474
- 0,
475
- 1,
476
- $numEcBytesInBlock,
477
- 255 - $numDataBytes - $numEcBytesInBlock
478
- );
479
- }
480
-
481
- return self::$codecs[$cacheId];
482
- }
483
-
484
- /**
485
- * Appends mode information to a bit array.
486
- *
487
- * @param Mode $mode
488
- * @param BitArray $bits
489
- * @return void
490
- */
491
- protected static function appendModeInfo(Mode $mode, BitArray $bits)
492
- {
493
- $bits->appendBits($mode->get(), 4);
494
- }
495
-
496
- /**
497
- * Appends length information to a bit array.
498
- *
499
- * @param integer $numLetters
500
- * @param Version $version
501
- * @param Mode $mode
502
- * @param BitArray $bits
503
- * @return void
504
- * @throws Exception\WriterException
505
- */
506
- protected static function appendLengthInfo($numLetters, Version $version, Mode $mode, BitArray $bits)
507
- {
508
- $numBits = $mode->getCharacterCountBits($version);
509
-
510
- if ($numLetters >= (1 << $numBits)) {
511
- throw new Exception\WriterException($numLetters . ' is bigger than ' . ((1 << $numBits) - 1));
512
- }
513
-
514
- $bits->appendBits($numLetters, $numBits);
515
- }
516
-
517
- /**
518
- * Appends bytes to a bit array in a specific mode.
519
- *
520
- * @param stirng $content
521
- * @param Mode $mode
522
- * @param BitArray $bits
523
- * @param string $encoding
524
- * @return void
525
- * @throws Exception\WriterException
526
- */
527
- protected static function appendBytes($content, Mode $mode, BitArray $bits, $encoding)
528
- {
529
- switch ($mode->get()) {
530
- case Mode::NUMERIC:
531
- self::appendNumericBytes($content, $bits);
532
- break;
533
-
534
- case Mode::ALPHANUMERIC:
535
- self::appendAlphanumericBytes($content, $bits);
536
- break;
537
-
538
- case Mode::BYTE:
539
- self::append8BitBytes($content, $bits, $encoding);
540
- break;
541
-
542
- case Mode::KANJI:
543
- self::appendKanjiBytes($content, $bits);
544
- break;
545
-
546
- default:
547
- throw new Exception\WriterException('Invalid mode: ' . $mode->get());
548
- }
549
- }
550
-
551
- /**
552
- * Appends numeric bytes to a bit array.
553
- *
554
- * @param string $content
555
- * @param BitArray $bits
556
- * @return void
557
- */
558
- protected static function appendNumericBytes($content, BitArray $bits)
559
- {
560
- $length = strlen($content);
561
- $i = 0;
562
-
563
- while ($i < $length) {
564
- $num1 = (int) $content[$i];
565
-
566
- if ($i + 2 < $length) {
567
- // Encode three numeric letters in ten bits.
568
- $num2 = (int) $content[$i + 1];
569
- $num3 = (int) $content[$i + 2];
570
- $bits->appendBits($num1 * 100 + $num2 * 10 + $num3, 10);
571
- $i += 3;
572
- } elseif ($i + 1 < $length) {
573
- // Encode two numeric letters in seven bits.
574
- $num2 = (int) $content[$i + 1];
575
- $bits->appendBits($num1 * 10 + $num2, 7);
576
- $i += 2;
577
- } else {
578
- // Encode one numeric letter in four bits.
579
- $bits->appendBits($num1, 4);
580
- $i++;
581
- }
582
- }
583
- }
584
-
585
- /**
586
- * Appends alpha-numeric bytes to a bit array.
587
- *
588
- * @param string $content
589
- * @param BitArray $bits
590
- * @return void
591
- */
592
- protected static function appendAlphanumericBytes($content, BitArray $bits)
593
- {
594
- $length = strlen($content);
595
- $i = 0;
596
-
597
- while ($i < $length) {
598
- if (-1 === ($code1 = self::getAlphanumericCode($content[$i]))) {
599
- throw new Exception\WriterException('Invalid alphanumeric code');
600
- }
601
-
602
- if ($i + 1 < $length) {
603
- if (-1 === ($code2 = self::getAlphanumericCode($content[$i + 1]))) {
604
- throw new Exception\WriterException('Invalid alphanumeric code');
605
- }
606
-
607
- // Encode two alphanumeric letters in 11 bits.
608
- $bits->appendBits($code1 * 45 + $code2, 11);
609
- $i += 2;
610
- } else {
611
- // Encode one alphanumeric letter in six bits.
612
- $bits->appendBits($code1, 6);
613
- $i++;
614
- }
615
- }
616
- }
617
-
618
- /**
619
- * Appends regular 8-bit bytes to a bit array.
620
- *
621
- * @param string $content
622
- * @param BitArray $bits
623
- * @return void
624
- */
625
- protected static function append8BitBytes($content, BitArray $bits, $encoding)
626
- {
627
- if (false === ($bytes = @iconv('utf-8', $encoding, $content))) {
628
- throw new Exception\WriterException('Could not encode content to ' . $encoding);
629
- }
630
-
631
- $length = strlen($bytes);
632
-
633
- for ($i = 0; $i < $length; $i++) {
634
- $bits->appendBits(ord($bytes[$i]), 8);
635
- }
636
- }
637
-
638
- /**
639
- * Appends KANJI bytes to a bit array.
640
- *
641
- * @param string $content
642
- * @param BitArray $bits
643
- * @return void
644
- */
645
- protected static function appendKanjiBytes($content, BitArray $bits)
646
- {
647
- if (strlen($content) % 2 > 0) {
648
- // We just do a simple length check here. The for loop will check
649
- // individual characters.
650
- throw new Exception\WriterException('Content does not seem to be encoded in SHIFT-JIS');
651
- }
652
-
653
- $length = strlen($content);
654
-
655
- for ($i = 0; $i < $length; $i += 2) {
656
- $byte1 = ord($content[$i]) & 0xff;
657
- $byte2 = ord($content[$i + 1]) & 0xff;
658
- $code = ($byte1 << 8) | $byte2;
659
-
660
- if ($code >= 0x8140 && $code <= 0x9ffc) {
661
- $subtracted = $code - 0x8140;
662
- } elseif ($code >= 0xe040 && $code <= 0xebbf) {
663
- $subtracted = $code - 0xc140;
664
- } else {
665
- throw new Exception\WriterException('Invalid byte sequence');
666
- }
667
-
668
- $encoded = (($subtracted >> 8) * 0xc0) + ($subtracted & 0xff);
669
-
670
- $bits->appendBits($encoded, 13);
671
- }
672
- }
673
-
674
- /**
675
- * Appends ECI information to a bit array.
676
- *
677
- * @param CharacterSetEci $eci
678
- * @param BitArray $bits
679
- * @return void
680
- */
681
- protected static function appendEci(CharacterSetEci $eci, BitArray $bits)
682
- {
683
- $mode = new Mode(Mode::ECI);
684
- $bits->appendBits($mode->get(), 4);
685
- $bits->appendBits($eci->get(), 8);
686
- }
687
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Encoder/MaskUtil.php DELETED
@@ -1,291 +0,0 @@
1
- <?php
2
- /**
3
- * BaconQrCode
4
- *
5
- * @link http://github.com/Bacon/BaconQrCode For the canonical source repository
6
- * @copyright 2013 Ben 'DASPRiD' Scholzen
7
- * @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
8
- */
9
-
10
- namespace BaconQrCode\Encoder;
11
-
12
- use BaconQrCode\Common\BitUtils;
13
-
14
- /**
15
- * Mask utility.
16
- */
17
- class MaskUtil
18
- {
19
- /**#@+
20
- * Penalty weights from section 6.8.2.1
21
- */
22
- const N1 = 3;
23
- const N2 = 3;
24
- const N3 = 40;
25
- const N4 = 10;
26
- /**#@-*/
27
-
28
- /**
29
- * Applies mask penalty rule 1 and returns the penalty.
30
- *
31
- * Finds repetitive cells with the same color and gives penalty to them.
32
- * Example: 00000 or 11111.
33
- *
34
- * @param ByteMatrix $matrix
35
- * @return integer
36
- */
37
- public static function applyMaskPenaltyRule1(ByteMatrix $matrix)
38
- {
39
- return (
40
- self::applyMaskPenaltyRule1Internal($matrix, true)
41
- + self::applyMaskPenaltyRule1Internal($matrix, false)
42
- );
43
- }
44
-
45
- /**
46
- * Applies mask penalty rule 2 and returns the penalty.
47
- *
48
- * Finds 2x2 blocks with the same color and gives penalty to them. This is
49
- * actually equivalent to the spec's rule, which is to find MxN blocks and
50
- * give a penalty proportional to (M-1)x(N-1), because this is the number of
51
- * 2x2 blocks inside such a block.
52
- *
53
- * @param ByteMatrix $matrix
54
- * @return integer
55
- */
56
- public static function applyMaskPenaltyRule2(ByteMatrix $matrix)
57
- {
58
- $penalty = 0;
59
- $array = $matrix->getArray();
60
- $width = $matrix->getWidth();
61
- $height = $matrix->getHeight();
62
-
63
- for ($y = 0; $y < $height - 1; $y++) {
64
- for ($x = 0; $x < $width - 1; $x++) {
65
- $value = $array[$y][$x];
66
-
67
- if ($value === $array[$y][$x + 1] && $value === $array[$y + 1][$x] && $value === $array[$y + 1][$x + 1]) {
68
- $penalty++;
69
- }
70
- }
71
- }
72
-
73
- return self::N2 * $penalty;
74
- }
75
-
76
- /**
77
- * Applies mask penalty rule 3 and returns the penalty.
78
- *
79
- * Finds consecutive cells of 00001011101 or 10111010000, and gives penalty
80
- * to them. If we find patterns like 000010111010000, we give penalties
81
- * twice (i.e. 40 * 2).
82
- *
83
- * @param ByteMatrix $matrix
84
- * @return integer
85
- */
86
- public static function applyMaskPenaltyRule3(ByteMatrix $matrix)
87
- {
88
- $penalty = 0;
89
- $array = $matrix->getArray();
90
- $width = $matrix->getWidth();
91
- $height = $matrix->getHeight();
92
-
93
- for ($y = 0; $y < $height; $y++) {
94
- for ($x = 0; $x < $width; $x++) {
95
- if (
96
- $x + 6 < $width
97
- && $array[$y][$x] === 1
98
- && $array[$y][$x + 1] === 0
99
- && $array[$y][$x + 2] === 1
100
- && $array[$y][$x + 3] === 1
101
- && $array[$y][$x + 4] === 1
102
- && $array[$y][$x + 5] === 0
103
- && $array[$y][$x + 6] === 1
104
- && (
105
- (
106
- $x + 10 < $width
107
- && $array[$y][$x + 7] === 0
108
- && $array[$y][$x + 8] === 0
109
- && $array[$y][$x + 9] === 0
110
- && $array[$y][$x + 10] === 0
111
- )
112
- || (
113
- $x - 4 >= 0
114
- && $array[$y][$x - 1] === 0
115
- && $array[$y][$x - 2] === 0
116
- && $array[$y][$x - 3] === 0
117
- && $array[$y][$x - 4] === 0
118
- )
119
- )
120
- ) {
121
- $penalty += self::N3;
122
- }
123
-
124
- if (
125
- $y + 6 < $height
126
- && $array[$y][$x] === 1
127
- && $array[$y + 1][$x] === 0
128
- && $array[$y + 2][$x] === 1
129
- && $array[$y + 3][$x] === 1
130
- && $array[$y + 4][$x] === 1
131
- && $array[$y + 5][$x] === 0
132
- && $array[$y + 6][$x] === 1
133
- && (
134
- (
135
- $y + 10 < $height
136
- && $array[$y + 7][$x] === 0
137
- && $array[$y + 8][$x] === 0
138
- && $array[$y + 9][$x] === 0
139
- && $array[$y + 10][$x] === 0
140
- )
141
- || (
142
- $y - 4 >= 0
143
- && $array[$y - 1][$x] === 0
144
- && $array[$y - 2][$x] === 0
145
- && $array[$y - 3][$x] === 0
146
- && $array[$y - 4][$x] === 0
147
- )
148
- )
149
- ) {
150
- $penalty += self::N3;
151
- }
152
- }
153
- }
154
-
155
- return $penalty;
156
- }
157
-
158
- /**
159
- * Applies mask penalty rule 4 and returns the penalty.
160
- *
161
- * Calculates the ratio of dark cells and gives penalty if the ratio is far
162
- * from 50%. It gives 10 penalty for 5% distance.
163
- *
164
- * @param ByteMatrix $matrix
165
- * @return integer
166
- */
167
- public static function applyMaskPenaltyRule4(ByteMatrix $matrix)
168
- {
169
- $numDarkCells = 0;
170
-
171
- $array = $matrix->getArray();
172
- $width = $matrix->getWidth();
173
- $height = $matrix->getHeight();
174
-
175
- for ($y = 0; $y < $height; $y++) {
176
- $arrayY = $array[$y];
177
-
178
- for ($x = 0; $x < $width; $x++) {
179
- if ($arrayY[$x] === 1) {
180
- $numDarkCells++;
181
- }
182
- }
183
- }
184
-
185
- $numTotalCells = $height * $width;
186
- $darkRatio = $numDarkCells / $numTotalCells;
187
- $fixedPercentVariances = (int) (abs($darkRatio - 0.5) * 20);
188
-
189
- return $fixedPercentVariances * self::N4;
190
- }
191
-
192
- /**
193
- * Returns the mask bit for "getMaskPattern" at "x" and "y".
194
- *
195
- * See 8.8 of JISX0510:2004 for mask pattern conditions.
196
- *
197
- * @param integer $maskPattern
198
- * @param integer $x
199
- * @param integer $y
200
- * @return integer
201
- * @throws Exception\InvalidArgumentException
202
- */
203
- public static function getDataMaskBit($maskPattern, $x, $y)
204
- {
205
- switch ($maskPattern) {
206
- case 0:
207
- $intermediate = ($y + $x) & 0x1;
208
- break;
209
-
210
- case 1:
211
- $intermediate = $y & 0x1;
212
- break;
213
-
214
- case 2:
215
- $intermediate = $x % 3;
216
- break;
217
-
218
- case 3:
219
- $intermediate = ($y + $x) % 3;
220
- break;
221
-
222
- case 4:
223
- $intermediate = (BitUtils::unsignedRightShift($y, 1) + ($x / 3)) & 0x1;
224
- break;
225
-
226
- case 5:
227
- $temp = $y * $x;
228
- $intermediate = ($temp & 0x1) + ($temp % 3);
229
- break;
230
-
231
- case 6:
232
- $temp = $y * $x;
233
- $intermediate = (($temp & 0x1) + ($temp % 3)) & 0x1;
234
- break;
235
-
236
- case 7:
237
- $temp = $y * $x;
238
- $intermediate = (($temp % 3) + (($y + $x) & 0x1)) & 0x1;
239
- break;
240
-
241
- default:
242
- throw new Exception\InvalidArgumentException('Invalid mask pattern: ' . $maskPattern);
243
- }
244
-
245
- return $intermediate === 0;
246
- }
247
-
248
- /**
249
- * Helper function for applyMaskPenaltyRule1.
250
- *
251
- * We need this for doing this calculation in both vertical and horizontal
252
- * orders respectively.
253
- *
254
- * @param ByteMatrix $matrix
255
- * @param boolean $isHorizontal
256
- * @return integer
257
- */
258
- protected static function applyMaskPenaltyRule1Internal(ByteMatrix $matrix, $isHorizontal)
259
- {
260
- $penalty = 0;
261
- $iLimit = $isHorizontal ? $matrix->getHeight() : $matrix->getWidth();
262
- $jLimit = $isHorizontal ? $matrix->getWidth() : $matrix->getHeight();
263
- $array = $matrix->getArray();
264
-
265
- for ($i = 0; $i < $iLimit; $i++) {
266
- $numSameBitCells = 0;
267
- $prevBit = -1;
268
-
269
- for ($j = 0; $j < $jLimit; $j++) {
270
- $bit = $isHorizontal ? $array[$i][$j] : $array[$j][$i];
271
-
272
- if ($bit === $prevBit) {
273
- $numSameBitCells++;
274
- } else {
275
- if ($numSameBitCells >= 5) {
276
- $penalty += self::N1 + ($numSameBitCells - 5);
277
- }
278
-
279
- $numSameBitCells = 1;
280
- $prevBit = $bit;
281
- }
282
- }
283
-
284
- if ($numSameBitCells >= 5) {
285
- $penalty += self::N1 + ($numSameBitCells - 5);
286
- }
287
- }
288
-
289
- return $penalty;
290
- }
291
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Encoder/MatrixUtil.php DELETED
@@ -1,580 +0,0 @@
1
- <?php
2
- /**
3
- * BaconQrCode
4
- *
5
- * @link http://github.com/Bacon/BaconQrCode For the canonical source repository
6
- * @copyright 2013 Ben 'DASPRiD' Scholzen
7
- * @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
8
- */
9
-
10
- namespace BaconQrCode\Encoder;
11
-
12
- use BaconQrCode\Common\BitArray;
13
- use BaconQrCode\Common\ErrorCorrectionLevel;
14
- use BaconQrCode\Common\Version;
15
- use BaconQrCode\Exception;
16
-
17
- /**
18
- * Matrix utility.
19
- */
20
- class MatrixUtil
21
- {
22
- /**
23
- * Position detection pattern.
24
- *
25
- * @var array
26
- */
27
- protected static $positionDetectionPattern = array(
28
- array(1, 1, 1, 1, 1, 1, 1),
29
- array(1, 0, 0, 0, 0, 0, 1),
30
- array(1, 0, 1, 1, 1, 0, 1),
31
- array(1, 0, 1, 1, 1, 0, 1),
32
- array(1, 0, 1, 1, 1, 0, 1),
33
- array(1, 0, 0, 0, 0, 0, 1),
34
- array(1, 1, 1, 1, 1, 1, 1),
35
- );
36
-
37
- /**
38
- * Position adjustment pattern.
39
- *
40
- * @var array
41
- */
42
- protected static $positionAdjustmentPattern = array(
43
- array(1, 1, 1, 1, 1),
44
- array(1, 0, 0, 0, 1),
45
- array(1, 0, 1, 0, 1),
46
- array(1, 0, 0, 0, 1),
47
- array(1, 1, 1, 1, 1),
48
- );
49
-
50
- /**
51
- * Coordinates for position adjustment patterns for each version.
52
- *
53
- * @var array
54
- */
55
- protected static $positionAdjustmentPatternCoordinateTable = array(
56
- array(null, null, null, null, null, null, null), // Version 1
57
- array( 6, 18, null, null, null, null, null), // Version 2
58
- array( 6, 22, null, null, null, null, null), // Version 3
59
- array( 6, 26, null, null, null, null, null), // Version 4
60
- array( 6, 30, null, null, null, null, null), // Version 5
61
- array( 6, 34, null, null, null, null, null), // Version 6
62
- array( 6, 22, 38, null, null, null, null), // Version 7
63
- array( 6, 24, 42, null, null, null, null), // Version 8
64
- array( 6, 26, 46, null, null, null, null), // Version 9
65
- array( 6, 28, 50, null, null, null, null), // Version 10
66
- array( 6, 30, 54, null, null, null, null), // Version 11
67
- array( 6, 32, 58, null, null, null, null), // Version 12
68
- array( 6, 34, 62, null, null, null, null), // Version 13
69
- array( 6, 26, 46, 66, null, null, null), // Version 14
70
- array( 6, 26, 48, 70, null, null, null), // Version 15
71
- array( 6, 26, 50, 74, null, null, null), // Version 16
72
- array( 6, 30, 54, 78, null, null, null), // Version 17
73
- array( 6, 30, 56, 82, null, null, null), // Version 18
74
- array( 6, 30, 58, 86, null, null, null), // Version 19
75
- array( 6, 34, 62, 90, null, null, null), // Version 20
76
- array( 6, 28, 50, 72, 94, null, null), // Version 21
77
- array( 6, 26, 50, 74, 98, null, null), // Version 22
78
- array( 6, 30, 54, 78, 102, null, null), // Version 23
79
- array( 6, 28, 54, 80, 106, null, null), // Version 24
80
- array( 6, 32, 58, 84, 110, null, null), // Version 25
81
- array( 6, 30, 58, 86, 114, null, null), // Version 26
82
- array( 6, 34, 62, 90, 118, null, null), // Version 27
83
- array( 6, 26, 50, 74, 98, 122, null), // Version 28
84
- array( 6, 30, 54, 78, 102, 126, null), // Version 29
85
- array( 6, 26, 52, 78, 104, 130, null), // Version 30
86
- array( 6, 30, 56, 82, 108, 134, null), // Version 31
87
- array( 6, 34, 60, 86, 112, 138, null), // Version 32
88
- array( 6, 30, 58, 86, 114, 142, null), // Version 33
89
- array( 6, 34, 62, 90, 118, 146, null), // Version 34
90
- array( 6, 30, 54, 78, 102, 126, 150), // Version 35
91
- array( 6, 24, 50, 76, 102, 128, 154), // Version 36
92
- array( 6, 28, 54, 80, 106, 132, 158), // Version 37
93
- array( 6, 32, 58, 84, 110, 136, 162), // Version 38
94
- array( 6, 26, 54, 82, 110, 138, 166), // Version 39
95
- array( 6, 30, 58, 86, 114, 142, 170), // Version 40
96
- );
97
-
98
- /**
99
- * Type information coordinates.
100
- *
101
- * @var array
102
- */
103
- protected static $typeInfoCoordinates = array(
104
- array(8, 0),
105
- array(8, 1),
106
- array(8, 2),
107
- array(8, 3),
108
- array(8, 4),
109
- array(8, 5),
110
- array(8, 7),
111
- array(8, 8),
112
- array(7, 8),
113
- array(5, 8),
114
- array(4, 8),
115
- array(3, 8),
116
- array(2, 8),
117
- array(1, 8),
118
- array(0, 8),
119
- );
120
-
121
- /**
122
- * Version information polynomial.
123
- *
124
- * @var integer
125
- */
126
- protected static $versionInfoPoly = 0x1f25;
127
-
128
- /**
129
- * Type information polynomial.
130
- *
131
- * @var integer
132
- */
133
- protected static $typeInfoPoly = 0x537;
134
-
135
- /**
136
- * Type information mask pattern.
137
- *
138
- * @var integer
139
- */
140
- protected static $typeInfoMaskPattern = 0x5412;
141
-
142
- /**
143
- * Clears a given matrix.
144
- *
145
- * @param ByteMatrix $matrix
146
- * @return void
147
- */
148
- public static function clearMatrix(ByteMatrix $matrix)
149
- {
150
- $matrix->clear(-1);
151
- }
152
-
153
- /**
154
- * Builds a complete matrix.
155
- *
156
- * @param BitArray $dataBits
157
- * @param ErrorCorrectionLevel $level
158
- * @param Version $version
159
- * @param integer $maskPattern
160
- * @param ByteMatrix $matrix
161
- * @return void
162
- */
163
- public static function buildMatrix(
164
- BitArray $dataBits,
165
- ErrorCorrectionLevel $level,
166
- Version $version,
167
- $maskPattern,
168
- ByteMatrix $matrix
169
- ) {
170
- self::clearMatrix($matrix);
171
- self::embedBasicPatterns($version, $matrix);
172
- self::embedTypeInfo($level, $maskPattern, $matrix);
173
- self::maybeEmbedVersionInfo($version, $matrix);
174
- self::embedDataBits($dataBits, $maskPattern, $matrix);
175
- }
176
-
177
- /**
178
- * Embeds type information into a matrix.
179
- *
180
- * @param ErrorCorrectionLevel $level
181
- * @param integer $maskPattern
182
- * @param ByteMatrix $matrix
183
- * @return void
184
- */
185
- protected static function embedTypeInfo(ErrorCorrectionLevel $level, $maskPattern, ByteMatrix $matrix)
186
- {
187
- $typeInfoBits = new BitArray();
188
- self::makeTypeInfoBits($level, $maskPattern, $typeInfoBits);
189
-
190
- $typeInfoBitsSize = $typeInfoBits->getSize();
191
-
192
- for ($i = 0; $i < $typeInfoBitsSize; $i++) {
193
- $bit = $typeInfoBits->get($typeInfoBitsSize - 1 - $i);
194
-
195
- $x1 = self::$typeInfoCoordinates[$i][0];
196
- $y1 = self::$typeInfoCoordinates[$i][1];
197
-
198
- $matrix->set($x1, $y1, $bit);
199
-
200
- if ($i < 8) {
201
- $x2 = $matrix->getWidth() - $i - 1;
202
- $y2 = 8;
203
- } else {
204
- $x2 = 8;
205
- $y2 = $matrix->getHeight() - 7 + ($i - 8);
206
- }
207
-
208
- $matrix->set($x2, $y2, $bit);
209
- }
210
- }
211
-
212
- /**
213
- * Generates type information bits and appends them to a bit array.
214
- *
215
- * @param ErrorCorrectionLevel $level
216
- * @param integer $maskPattern
217
- * @param BitArray $bits
218
- * @return void
219
- * @throws Exception\RuntimeException
220
- */
221
- protected static function makeTypeInfoBits(ErrorCorrectionLevel $level, $maskPattern, BitArray $bits)
222
- {
223
- $typeInfo = ($level->get() << 3) | $maskPattern;
224
- $bits->appendBits($typeInfo, 5);
225
-
226
- $bchCode = self::calculateBchCode($typeInfo, self::$typeInfoPoly);
227
- $bits->appendBits($bchCode, 10);
228
-
229
- $maskBits = new BitArray();
230
- $maskBits->appendBits(self::$typeInfoMaskPattern, 15);
231
- $bits->xorBits($maskBits);
232
-
233
- if ($bits->getSize() !== 15) {
234
- throw new Exception\RuntimeException('Bit array resulted in invalid size: ' . $bits->getSize());
235
- }
236
- }
237
-
238
- /**
239
- * Embeds version information if required.
240
- *
241
- * @param Version $version
242
- * @param ByteMatrix $matrix
243
- * @return void
244
- */
245
- protected static function maybeEmbedVersionInfo(Version $version, ByteMatrix $matrix)
246
- {
247
- if ($version->getVersionNumber() < 7) {
248
- return;
249
- }
250
-
251
- $versionInfoBits = new BitArray();
252
- self::makeVersionInfoBits($version, $versionInfoBits);
253
-
254
- $bitIndex = 6 * 3 - 1;
255
-
256
- for ($i = 0; $i < 6; $i++) {
257
- for ($j = 0; $j < 3; $j++) {
258
- $bit = $versionInfoBits->get($bitIndex);
259
- $bitIndex--;
260
-
261
- $matrix->set($i, $matrix->getHeight() - 11 + $j, $bit);
262
- $matrix->set($matrix->getHeight() - 11 + $j, $i, $bit);
263
- }
264
- }
265
- }
266
-
267
- /**
268
- * Generates version information bits and appends them to a bit array.
269
- *
270
- * @param Version $version
271
- * @param BitArray $bits
272
- * @return void
273
- * @throws Exception\RuntimeException
274
- */
275
- protected static function makeVersionInfoBits(Version $version, BitArray $bits)
276
- {
277
- $bits->appendBits($version->getVersionNumber(), 6);
278
-
279
- $bchCode = self::calculateBchCode($version->getVersionNumber(), self::$versionInfoPoly);
280
- $bits->appendBits($bchCode, 12);
281
-
282
- if ($bits->getSize() !== 18) {
283
- throw new Exception\RuntimeException('Bit array resulted in invalid size: ' . $bits->getSize());
284
- }
285
- }
286
-
287
- /**
288
- * Calculates the BHC code for a value and a polynomial.
289
- *
290
- * @param integer $value
291
- * @param integer $poly
292
- * @return integer
293
- */
294
- protected static function calculateBchCode($value, $poly)
295
- {
296
- $msbSetInPoly = self::findMsbSet($poly);
297
- $value <<= $msbSetInPoly - 1;
298
-
299
- while (self::findMsbSet($value) >= $msbSetInPoly) {
300
- $value ^= $poly << (self::findMsbSet($value) - $msbSetInPoly);
301
- }
302
-
303
- return $value;
304
- }
305
-
306
- /**
307
- * Finds and MSB set.
308
- *
309
- * @param integer $value
310
- * @return integer
311
- */
312
- protected static function findMsbSet($value)
313
- {
314
- $numDigits = 0;
315
-
316
- while ($value !== 0) {
317
- $value >>= 1;
318
- $numDigits++;
319
- }
320
-
321
- return $numDigits;
322
- }
323
-
324
- /**
325
- * Embeds basic patterns into a matrix.
326
- *
327
- * @param Version $version
328
- * @param ByteMatrix $matrix
329
- * @return void
330
- */
331
- protected static function embedBasicPatterns(Version $version, ByteMatrix $matrix)
332
- {
333
- self::embedPositionDetectionPatternsAndSeparators($matrix);
334
- self::embedDarkDotAtLeftBottomCorner($matrix);
335
- self::maybeEmbedPositionAdjustmentPatterns($version, $matrix);
336
- self::embedTimingPatterns($matrix);
337
- }
338
-
339
- /**
340
- * Embeds position detection patterns and separators into a byte matrix.
341
- *
342
- * @param ByteMatrix $matrix
343
- * @return void
344
- */
345
- protected static function embedPositionDetectionPatternsAndSeparators(ByteMatrix $matrix)
346
- {
347
- $pdpWidth = count(self::$positionDetectionPattern[0]);
348
-
349
- self::embedPositionDetectionPattern(0, 0, $matrix);
350
- self::embedPositionDetectionPattern($matrix->getWidth() - $pdpWidth, 0, $matrix);
351
- self::embedPositionDetectionPattern(0, $matrix->getWidth() - $pdpWidth, $matrix);
352
-
353
- $hspWidth = 8;
354
-
355
- self::embedHorizontalSeparationPattern(0, $hspWidth - 1, $matrix);
356
- self::embedHorizontalSeparationPattern($matrix->getWidth() - $hspWidth, $hspWidth - 1, $matrix);
357
- self::embedHorizontalSeparationPattern(0, $matrix->getWidth() - $hspWidth, $matrix);
358
-
359
- $vspSize = 7;
360
-
361
- self::embedVerticalSeparationPattern($vspSize, 0, $matrix);
362
- self::embedVerticalSeparationPattern($matrix->getHeight() - $vspSize - 1, 0, $matrix);
363
- self::embedVerticalSeparationPattern($vspSize, $matrix->getHeight() - $vspSize, $matrix);
364
- }
365
-
366
- /**
367
- * Embeds a single position detection pattern into a byte matrix.
368
- *
369
- * @param integer $xStart
370
- * @param integer $yStart
371
- * @param ByteMatrix $matrix
372
- * @return void
373
- */
374
- protected static function embedPositionDetectionPattern($xStart, $yStart, ByteMatrix $matrix)
375
- {
376
- for ($y = 0; $y < 7; $y++) {
377
- for ($x = 0; $x < 7; $x++) {
378
- $matrix->set($xStart + $x, $yStart + $y, self::$positionDetectionPattern[$y][$x]);
379
- }
380
- }
381
- }
382
-
383
- /**
384
- * Embeds a single horizontal separation pattern.
385
- *
386
- * @param integer $xStart
387
- * @param integer $yStart
388
- * @param ByteMatrix $matrix
389
- * @return void
390
- * @throws Exception\RuntimeException
391
- */
392
- protected static function embedHorizontalSeparationPattern($xStart, $yStart, ByteMatrix $matrix)
393
- {
394
- for ($x = 0; $x < 8; $x++) {
395
- if ($matrix->get($xStart + $x, $yStart) !== -1) {
396
- throw new Exception\RuntimeException('Byte already set');
397
- }
398
-
399
- $matrix->set($xStart + $x, $yStart, 0);
400
- }
401
- }
402
-
403
- /**
404
- * Embeds a single vertical separation pattern.
405
- *
406
- * @param integer $xStart
407
- * @param integer $yStart
408
- * @param ByteMatrix $matrix
409
- * @return void
410
- * @throws Exception\RuntimeException
411
- */
412
- protected static function embedVerticalSeparationPattern($xStart, $yStart, ByteMatrix $matrix)
413
- {
414
- for ($y = 0; $y < 7; $y++) {
415
- if ($matrix->get($xStart, $yStart + $y) !== -1) {
416
- throw new Exception\RuntimeException('Byte already set');
417
- }
418
-
419
- $matrix->set($xStart, $yStart + $y, 0);
420
- }
421
- }
422
-
423
- /**
424
- * Embeds a dot at the left bottom corner.
425
- *
426
- * @param ByteMatrix $matrix
427
- * @return void
428
- * @throws Exception\RuntimeException
429
- */
430
- protected static function embedDarkDotAtLeftBottomCorner(ByteMatrix $matrix)
431
- {
432
- if ($matrix->get(8, $matrix->getHeight() - 8) === 0) {
433
- throw new Exception\RuntimeException('Byte already set to 0');
434
- }
435
-
436
- $matrix->set(8, $matrix->getHeight() - 8, 1);
437
- }
438
-
439
- /**
440
- * Embeds position adjustment patterns if required.
441
- *
442
- * @param Version $version
443
- * @param ByteMatrix $matrix
444
- * @return void
445
- */
446
- protected static function maybeEmbedPositionAdjustmentPatterns(Version $version, ByteMatrix $matrix)
447
- {
448
- if ($version->getVersionNumber() < 2) {
449
- return;
450
- }
451
-
452
- $index = $version->getVersionNumber() - 1;
453
-
454
- $coordinates = self::$positionAdjustmentPatternCoordinateTable[$index];
455
- $numCoordinates = count($coordinates);
456
-
457
- for ($i = 0; $i < $numCoordinates; $i++) {
458
- for ($j = 0; $j < $numCoordinates; $j++) {
459
- $y = $coordinates[$i];
460
- $x = $coordinates[$j];
461
-
462
- if ($x === null || $y === null) {
463
- continue;
464
- }
465
-
466
- if ($matrix->get($x, $y) === -1) {
467
- self::embedPositionAdjustmentPattern($x - 2, $y - 2, $matrix);
468
- }
469
- }
470
- }
471
- }
472
-
473
- /**
474
- * Embeds a single position adjustment pattern.
475
- *
476
- * @param integer $xStart
477
- * @param intger $yStart
478
- * @param ByteMatrix $matrix
479
- * @return void
480
- */
481
- protected static function embedPositionAdjustmentPattern($xStart, $yStart, ByteMatrix $matrix)
482
- {
483
- for ($y = 0; $y < 5; $y++) {
484
- for ($x = 0; $x < 5; $x++) {
485
- $matrix->set($xStart + $x, $yStart + $y, self::$positionAdjustmentPattern[$y][$x]);
486
- }
487
- }
488
- }
489
-
490
- /**
491
- * Embeds timing patterns into a matrix.
492
- *
493
- * @param ByteMatrix $matrix
494
- * @return void
495
- */
496
- protected static function embedTimingPatterns(ByteMatrix $matrix)
497
- {
498
- $matrixWidth = $matrix->getWidth();
499
-
500
- for ($i = 8; $i < $matrixWidth - 8; $i++) {
501
- $bit = ($i + 1) % 2;
502
-
503
- if ($matrix->get($i, 6) === -1) {
504
- $matrix->set($i, 6, $bit);
505
- }
506
-
507
- if ($matrix->get(6, $i) === -1) {
508
- $matrix->set(6, $i, $bit);
509
- }
510
- }
511
- }
512
-
513
- /**
514
- * Embeds "dataBits" using "getMaskPattern".
515
- *
516
- * For debugging purposes, it skips masking process if "getMaskPattern" is
517
- * -1. See 8.7 of JISX0510:2004 (p.38) for how to embed data bits.
518
- *
519
- * @param BitArray $dataBits
520
- * @param integer $maskPattern
521
- * @param ByteMatrix $matrix
522
- * @return void
523
- * @throws Exception\WriterException
524
- */
525
- protected static function embedDataBits(BitArray $dataBits, $maskPattern, ByteMatrix $matrix)
526
- {
527
- $bitIndex = 0;
528
- $direction = -1;
529
-
530
- // Start from the right bottom cell.
531
- $x = $matrix->getWidth() - 1;
532
- $y = $matrix->getHeight() - 1;
533
-
534
- while ($x > 0) {
535
- // Skip vertical timing pattern.
536
- if ($x === 6) {
537
- $x--;
538
- }
539
-
540
- while ($y >= 0 && $y < $matrix->getHeight()) {
541
- for ($i = 0; $i < 2; $i++) {
542
- $xx = $x - $i;
543
-
544
- // Skip the cell if it's not empty.
545
- if ($matrix->get($xx, $y) !== -1) {
546
- continue;
547
- }
548
-
549
- if ($bitIndex < $dataBits->getSize()) {
550
- $bit = $dataBits->get($bitIndex);
551
- $bitIndex++;
552
- } else {
553
- // Padding bit. If there is no bit left, we'll fill the
554
- // left cells with 0, as described in 8.4.9 of
555
- // JISX0510:2004 (p. 24).
556
- $bit = false;
557
- }
558
-
559
- // Skip masking if maskPattern is -1.
560
- if ($maskPattern !== -1 && MaskUtil::getDataMaskBit($maskPattern, $xx, $y)) {
561
- $bit = !$bit;
562
- }
563
-
564
- $matrix->set($xx, $y, $bit);
565
- }
566
-
567
- $y += $direction;
568
- }
569
-
570
- $direction = -$direction;
571
- $y += $direction;
572
- $x -= 2;
573
- }
574
-
575
- // All bits should be consumed
576
- if ($bitIndex !== $dataBits->getSize()) {
577
- throw new Exception\WriterException('Not all bits consumed (' . $bitIndex . ' out of ' . $dataBits->getSize() .')');
578
- }
579
- }
580
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Encoder/QrCode.php DELETED
@@ -1,201 +0,0 @@
1
- <?php
2
- /**
3
- * BaconQrCode
4
- *
5
- * @link http://github.com/Bacon/BaconQrCode For the canonical source repository
6
- * @copyright 2013 Ben 'DASPRiD' Scholzen
7
- * @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
8
- */
9
-
10
- namespace BaconQrCode\Encoder;
11
-
12
- use BaconQrCode\Common\ErrorCorrectionLevel;
13
- use BaconQrCode\Common\Mode;
14
- use BaconQrCode\Common\Version;
15
-
16
- /**
17
- * QR code.
18
- */
19
- class QrCode
20
- {
21
- /**
22
- * Number of possible mask patterns.
23
- */
24
- const NUM_MASK_PATTERNS = 8;
25
-
26
- /**
27
- * Mode of the QR code.
28
- *
29
- * @var Mode
30
- */
31
- protected $mode;
32
-
33
- /**
34
- * EC level of the QR code.
35
- *
36
- * @var ErrorCorrectionLevel
37
- */
38
- protected $errorCorrectionLevel;
39
-
40
- /**
41
- * Version of the QR code.
42
- *
43
- * @var Version
44
- */
45
- protected $version;
46
-
47
- /**
48
- * Mask pattern of the QR code.
49
- *
50
- * @var integer
51
- */
52
- protected $maskPattern = -1;
53
-
54
- /**
55
- * Matrix of the QR code.
56
- *
57
- * @var ByteMatrix
58
- */
59
- protected $matrix;
60
-
61
- /**
62
- * Gets the mode.
63
- *
64
- * @return Mode
65
- */
66
- public function getMode()
67
- {
68
- return $this->mode;
69
- }
70
-
71
- /**
72
- * Sets the mode.
73
- *
74
- * @param Mode $mode
75
- * @return void
76
- */
77
- public function setMode(Mode $mode)
78
- {
79
- $this->mode = $mode;
80
- }
81
-
82
- /**
83
- * Gets the EC level.
84
- *
85
- * @return ErrorCorrectionLevel
86
- */
87
- public function getErrorCorrectionLevel()
88
- {
89
- return $this->errorCorrectionLevel;
90
- }
91
-
92
- /**
93
- * Sets the EC level.
94
- *
95
- * @param ErrorCorrectionLevel $errorCorrectionLevel
96
- * @return void
97
- */
98
- public function setErrorCorrectionLevel(ErrorCorrectionLevel $errorCorrectionLevel)
99
- {
100
- $this->errorCorrectionLevel = $errorCorrectionLevel;
101
- }
102
-
103
- /**
104
- * Gets the version.
105
- *
106
- * @return Version
107
- */
108
- public function getVersion()
109
- {
110
- return $this->version;
111
- }
112
-
113
- /**
114
- * Sets the version.
115
- *
116
- * @param Version $version
117
- * @return void
118
- */
119
- public function setVersion(Version $version)
120
- {
121
- $this->version = $version;
122
- }
123
-
124
- /**
125
- * Gets the mask pattern.
126
- *
127
- * @return integer
128
- */
129
- public function getMaskPattern()
130
- {
131
- return $this->maskPattern;
132
- }
133
-
134
- /**
135
- * Sets the mask pattern.
136
- *
137
- * @param integer $maskPattern
138
- * @return void
139
- */
140
- public function setMaskPattern($maskPattern)
141
- {
142
- $this->maskPattern = $maskPattern;
143
- }
144
-
145
- /**
146
- * Gets the matrix.
147
- *
148
- * @return ByteMatrix
149
- */
150
- public function getMatrix()
151
- {
152
- return $this->matrix;
153
- }
154
-
155
- /**
156
- * Sets the matrix.
157
- *
158
- * @param ByteMatrix $matrix
159
- * @return void
160
- */
161
- public function setMatrix(ByteMatrix $matrix)
162
- {
163
- $this->matrix = $matrix;
164
- }
165
-
166
- /**
167
- * Validates whether a mask pattern is valid.
168
- *
169
- * @param integer $maskPattern
170
- * @return boolean
171
- */
172
- public static function isValidMaskPattern($maskPattern)
173
- {
174
- return $maskPattern > 0 && $maskPattern < self::NUM_MASK_PATTERNS;
175
- }
176
-
177
- /**
178
- * Returns a string representation of the QR code.
179
- *
180
- * @return string
181
- */
182
- public function __toString()
183
- {
184
- $result = "<<\n"
185
- . " mode: " . $this->mode . "\n"
186
- . " ecLevel: " . $this->errorCorrectionLevel . "\n"
187
- . " version: " . $this->version . "\n"
188
- . " maskPattern: " . $this->maskPattern . "\n";
189
-
190
- if ($this->matrix === null) {
191
- $result .= " matrix: null\n";
192
- } else {
193
- $result .= " matrix:\n";
194
- $result .= $this->matrix;
195
- }
196
-
197
- $result .= ">>\n";
198
-
199
- return $result;
200
- }
201
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Exception/ExceptionInterface.php DELETED
@@ -1,14 +0,0 @@
1
- <?php
2
- /**
3
- * BaconQrCode
4
- *
5
- * @link http://github.com/Bacon/BaconQrCode For the canonical source repository
6
- * @copyright 2013 Ben 'DASPRiD' Scholzen
7
- * @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
8
- */
9
-
10
- namespace BaconQrCode\Exception;
11
-
12
- interface ExceptionInterface
13
- {
14
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Exception/InvalidArgumentException.php DELETED
@@ -1,14 +0,0 @@
1
- <?php
2
- /**
3
- * BaconQrCode
4
- *
5
- * @link http://github.com/Bacon/BaconQrCode For the canonical source repository
6
- * @copyright 2013 Ben 'DASPRiD' Scholzen
7
- * @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
8
- */
9
-
10
- namespace BaconQrCode\Exception;
11
-
12
- class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
13
- {
14
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Exception/OutOfBoundsException.php DELETED
@@ -1,14 +0,0 @@
1
- <?php
2
- /**
3
- * BaconQrCode
4
- *
5
- * @link http://github.com/Bacon/BaconQrCode For the canonical source repository
6
- * @copyright 2013 Ben 'DASPRiD' Scholzen
7
- * @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
8
- */
9
-
10
- namespace BaconQrCode\Exception;
11
-
12
- class OutOfBoundsException extends \OutOfBoundsException implements ExceptionInterface
13
- {
14
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Exception/RuntimeException.php DELETED
@@ -1,14 +0,0 @@
1
- <?php
2
- /**
3
- * BaconQrCode
4
- *
5
- * @link http://github.com/Bacon/BaconQrCode For the canonical source repository
6
- * @copyright 2013 Ben 'DASPRiD' Scholzen
7
- * @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
8
- */
9
-
10
- namespace BaconQrCode\Exception;
11
-
12
- class RuntimeException extends \RuntimeException implements ExceptionInterface
13
- {
14
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Exception/UnexpectedValueException.php DELETED
@@ -1,14 +0,0 @@
1
- <?php
2
- /**
3
- * BaconQrCode
4
- *
5
- * @link http://github.com/Bacon/BaconQrCode For the canonical source repository
6
- * @copyright 2013 Ben 'DASPRiD' Scholzen
7
- * @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
8
- */
9
-
10
- namespace BaconQrCode\Exception;
11
-
12
- class UnexpectedValueException extends \UnexpectedValueException implements ExceptionInterface
13
- {
14
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Exception/WriterException.php DELETED
@@ -1,14 +0,0 @@
1
- <?php
2
- /**
3
- * BaconQrCode
4
- *
5
- * @link http://github.com/Bacon/BaconQrCode For the canonical source repository
6
- * @copyright 2013 Ben 'DASPRiD' Scholzen
7
- * @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
8
- */
9
-
10
- namespace BaconQrCode\Exception;
11
-
12
- class WriterException extends \RuntimeException implements ExceptionInterface
13
- {
14
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Color/Cmyk.php DELETED
@@ -1,160 +0,0 @@
1
- <?php
2
- /**
3
- * BaconQrCode
4
- *
5
- * @link http://github.com/Bacon/BaconQrCode For the canonical source repository
6
- * @copyright 2013 Ben 'DASPRiD' Scholzen
7
- * @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
8
- */
9
-
10
- namespace BaconQrCode\Renderer\Color;
11
-
12
- use BaconQrCode\Exception;
13
-
14
- /**
15
- * CMYK color.
16
- */
17
- class Cmyk implements ColorInterface
18
- {
19
- /**
20
- * Cyan value.
21
- *
22
- * @var integer
23
- */
24
- protected $cyan;
25
-
26
- /**
27
- * Magenta value.
28
- *
29
- * @var integer
30
- */
31
- protected $magenta;
32
-
33
- /**
34
- * Yellow value.
35
- *
36
- * @var integer
37
- */
38
- protected $yellow;
39
-
40
- /**
41
- * Black value.
42
- *
43
- * @var integer
44
- */
45
- protected $black;
46
-
47
- /**
48
- * Creates a new CMYK color.
49
- *
50
- * @param integer $cyan
51
- * @param integer $magenta
52
- * @param integer $yellow
53
- * @param integer $black
54
- */
55
- public function __construct($cyan, $magenta, $yellow, $black)
56
- {
57
- if ($cyan < 0 || $cyan > 100) {
58
- throw new Exception\InvalidArgumentException('Cyan must be between 0 and 100');
59
- }
60
-
61
- if ($magenta < 0 || $magenta > 100) {
62
- throw new Exception\InvalidArgumentException('Magenta must be between 0 and 100');
63
- }
64
-
65
- if ($yellow < 0 || $yellow > 100) {
66
- throw new Exception\InvalidArgumentException('Yellow must be between 0 and 100');
67
- }
68
-
69
- if ($black < 0 || $black > 100) {
70
- throw new Exception\InvalidArgumentException('Black must be between 0 and 100');
71
- }
72
-
73
- $this->cyan = (int) $cyan;
74
- $this->magenta = (int) $magenta;
75
- $this->yellow = (int) $yellow;
76
- $this->black = (int) $black;
77
- }
78
-
79
- /**
80
- * Returns the cyan value.
81
- *
82
- * @return integer
83
- */
84
- public function getCyan()
85
- {
86
- return $this->cyan;
87
- }
88
-
89
- /**
90
- * Returns the magenta value.
91
- *
92
- * @return integer
93
- */
94
- public function getMagenta()
95
- {
96
- return $this->magenta;
97
- }
98
-
99
- /**
100
- * Returns the yellow value.
101
- *
102
- * @return integer
103
- */
104
- public function getYellow()
105
- {
106
- return $this->yellow;
107
- }
108
-
109
- /**
110
- * Returns the black value.
111
- *
112
- * @return integer
113
- */
114
- public function getBlack()
115
- {
116
- return $this->black;
117
- }
118
-
119
- /**
120
- * toRgb(): defined by ColorInterface.
121
- *
122
- * @see ColorInterface::toRgb()
123
- * @return Rgb
124
- */
125
- public function toRgb()
126
- {
127
- $k = $this->black / 100;
128
- $c = (-$k * $this->cyan + $k * 100 + $this->cyan) / 100;
129
- $m = (-$k * $this->magenta + $k * 100 + $this->magenta) / 100;
130
- $y = (-$k * $this->yellow + $k * 100 + $this->yellow) / 100;
131
-
132
- return new Rgb(
133
- -$c * 255 + 255,
134
- -$m * 255 + 255,
135
- -$y * 255 + 255
136
- );
137
- }
138
-
139
- /**
140
- * toCmyk(): defined by ColorInterface.
141
- *
142
- * @see ColorInterface::toCmyk()
143
- * @return Cmyk
144
- */
145
- public function toCmyk()
146
- {
147
- return $this;
148
- }
149
-
150
- /**
151
- * toGray(): defined by ColorInterface.
152
- *
153
- * @see ColorInterface::toGray()
154
- * @return Gray
155
- */
156
- public function toGray()
157
- {
158
- return $this->toRgb()->toGray();
159
- }
160
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Color/ColorInterface.php DELETED
@@ -1,37 +0,0 @@
1
- <?php
2
- /**
3
- * BaconQrCode
4
- *
5
- * @link http://github.com/Bacon/BaconQrCode For the canonical source repository
6
- * @copyright 2013 Ben 'DASPRiD' Scholzen
7
- * @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
8
- */
9
-
10
- namespace BaconQrCode\Renderer\Color;
11
-
12
- /**
13
- * Color interface.
14
- */
15
- interface ColorInterface
16
- {
17
- /**
18
- * Converts the color to RGB.
19
- *
20
- * @return Rgb
21
- */
22
- public function toRgb();
23
-
24
- /**
25
- * Converts the color to CMYK.
26
- *
27
- * @return Cmyk
28
- */
29
- public function toCmyk();
30
-
31
- /**
32
- * Converts the color to gray.
33
- *
34
- * @return Gray
35
- */
36
- public function toGray();
37
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Color/Gray.php DELETED
@@ -1,84 +0,0 @@
1
- <?php
2
- /**
3
- * BaconQrCode
4
- *
5
- * @link http://github.com/Bacon/BaconQrCode For the canonical source repository
6
- * @copyright 2013 Ben 'DASPRiD' Scholzen
7
- * @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
8
- */
9
-
10
- namespace BaconQrCode\Renderer\Color;
11
-
12
- use BaconQrCode\Exception;
13
-
14
- /**
15
- * Gray color.
16
- */
17
- class Gray implements ColorInterface
18
- {
19
- /**
20
- * Gray value.
21
- *
22
- * @var integer
23
- */
24
- protected $gray;
25
-
26
- /**
27
- * Creates a new gray color.
28
- *
29
- * A low gray value means black, while a high value means white.
30
- *
31
- * @param integer $gray
32
- */
33
- public function __construct($gray)
34
- {
35
- if ($gray < 0 || $gray > 100) {
36
- throw new Exception\InvalidArgumentException('Gray must be between 0 and 100');
37
- }
38
-
39
- $this->gray = (int) $gray;
40
- }
41
-
42
- /**
43
- * Returns the gray value.
44
- *
45
- * @return integer
46
- */
47
- public function getGray()
48
- {
49
- return $this->gray;
50
- }
51
-
52
- /**
53
- * toRgb(): defined by ColorInterface.
54
- *
55
- * @see ColorInterface::toRgb()
56
- * @return Rgb
57
- */
58
- public function toRgb()
59
- {
60
- return new Rgb($this->gray * 2.55, $this->gray * 2.55, $this->gray * 2.55);
61
- }
62
-
63
- /**
64
- * toCmyk(): defined by ColorInterface.
65
- *
66
- * @see ColorInterface::toCmyk()
67
- * @return Cmyk
68
- */
69
- public function toCmyk()
70
- {
71
- return new Cmyk(0, 0, 0, 100 - $this->gray);
72
- }
73
-
74
- /**
75
- * toGray(): defined by ColorInterface.
76
- *
77
- * @see ColorInterface::toGray()
78
- * @return Gray
79
- */
80
- public function toGray()
81
- {
82
- return $this;
83
- }
84
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Color/Rgb.php DELETED
@@ -1,148 +0,0 @@
1
- <?php
2
- /**
3
- * BaconQrCode
4
- *
5
- * @link http://github.com/Bacon/BaconQrCode For the canonical source repository
6
- * @copyright 2013 Ben 'DASPRiD' Scholzen
7
- * @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
8
- */
9
-
10
- namespace BaconQrCode\Renderer\Color;
11
-
12
- use BaconQrCode\Exception;
13
-
14
- /**
15
- * RGB color.
16
- */
17
- class Rgb implements ColorInterface
18
- {
19
- /**
20
- * Red value.
21
- *
22
- * @var integer
23
- */
24
- protected $red;
25
-
26
- /**
27
- * Green value.
28
- *
29
- * @var integer
30
- */
31
- protected $green;
32
-
33
- /**
34
- * Blue value.
35
- *
36
- * @var integer
37
- */
38
- protected $blue;
39
-
40
- /**
41
- * Creates a new RGB color.
42
- *
43
- * @param integer $red
44
- * @param integer $green
45
- * @param integer $blue
46
- */
47
- public function __construct($red, $green, $blue)
48
- {
49
- if ($red < 0 || $red > 255) {
50
- throw new Exception\InvalidArgumentException('Red must be between 0 and 255');
51
- }
52
-
53
- if ($green < 0 || $green > 255) {
54
- throw new Exception\InvalidArgumentException('Green must be between 0 and 255');
55
- }
56
-
57
- if ($blue < 0 || $blue > 255) {
58
- throw new Exception\InvalidArgumentException('Blue must be between 0 and 255');
59
- }
60
-
61
- $this->red = (int) $red;
62
- $this->green = (int) $green;
63
- $this->blue = (int) $blue;
64
- }
65
-
66
- /**
67
- * Returns the red value.
68
- *
69
- * @return integer
70
- */
71
- public function getRed()
72
- {
73
- return $this->red;
74
- }
75
-
76
- /**
77
- * Returns the green value.
78
- *
79
- * @return integer
80
- */
81
- public function getGreen()
82
- {
83
- return $this->green;
84
- }
85
-
86
- /**
87
- * Returns the blue value.
88
- *
89
- * @return integer
90
- */
91
- public function getBlue()
92
- {
93
- return $this->blue;
94
- }
95
-
96
- /**
97
- * Returns a hexadecimal string representation of the RGB value.
98
- *
99
- * @return string
100
- */
101
- public function __toString()
102
- {
103
- return sprintf('%02x%02x%02x', $this->red, $this->green, $this->blue);
104
- }
105
-
106
- /**
107
- * toRgb(): defined by ColorInterface.
108
- *
109
- * @see ColorInterface::toRgb()
110
- * @return Rgb
111
- */
112
- public function toRgb()
113
- {
114
- return $this;
115
- }
116
-
117
- /**
118
- * toCmyk(): defined by ColorInterface.
119
- *
120
- * @see ColorInterface::toCmyk()
121
- * @return Cmyk
122
- */
123
- public function toCmyk()
124
- {
125
- $c = 1 - ($this->red / 255);
126
- $m = 1 - ($this->green / 255);
127
- $y = 1 - ($this->blue / 255);
128
- $k = min($c, $m, $y);
129
-
130
- return new Cmyk(
131
- 100 * ($c - $k) / (1 - $k),
132
- 100 * ($m - $k) / (1 - $k),
133
- 100 * ($y - $k) / (1 - $k),
134
- 100 * $k
135
- );
136
- }
137
-
138
- /**
139
- * toGray(): defined by ColorInterface.
140
- *
141
- * @see ColorInterface::toGray()
142
- * @return Gray
143
- */
144
- public function toGray()
145
- {
146
- return new Gray(($this->red * 0.21 + $this->green * 0.71 + $this->blue * 0.07) / 2.55);
147
- }
148
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Image/AbstractRenderer.php DELETED
@@ -1,338 +0,0 @@
1
- <?php
2
- /**
3
- * BaconQrCode
4
- *
5
- * @link http://github.com/Bacon/BaconQrCode For the canonical source repository
6
- * @copyright 2013 Ben 'DASPRiD' Scholzen
7
- * @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
8
- */
9
-
10
- namespace BaconQrCode\Renderer\Image;
11
-
12
- use BaconQrCode\Encoder\QrCode;
13
- use BaconQrCode\Renderer\Color;
14
- use BaconQrCode\Renderer\Image\Decorator\DecoratorInterface;
15
- use BaconQrCode\Exception;
16
-
17
- /**
18
- * Image renderer, supporting multiple backends.
19
- */
20
- abstract class AbstractRenderer implements RendererInterface
21
- {
22
- /**
23
- * Margin around the QR code, also known as quiet zone.
24
- *
25
- * @var integer
26
- */
27
- protected $margin = 4;
28
-
29
- /**
30
- * Requested width of the rendered image.
31
- *
32
- * @var integer
33
- */
34
- protected $width = 0;
35
-
36
- /**
37
- * Requested height of the rendered image.
38
- *
39
- * @var integer
40
- */
41
- protected $height = 0;
42
-
43
- /**
44
- * Whether dimensions should be rounded down.
45
- *
46
- * @var boolean
47
- */
48
- protected $roundDimensions = true;
49
-
50
- /**
51
- * Final width of the image.
52
- *
53
- * @var integer
54
- */
55
- protected $finalWidth;
56
-
57
- /**
58
- * Final height of the image.
59
- *
60
- * @var integer
61
- */
62
- protected $finalHeight;
63
-
64
- /**
65
- * Size of each individual block.
66
- *
67
- * @var integer
68
- */
69
- protected $blockSize;
70
-
71
- /**
72
- * Background color.
73
- *
74
- * @var Color\ColorInterface
75
- */
76
- protected $backgroundColor;
77
-
78
- /**
79
- * Whether dimensions should be rounded down
80
- *
81
- * @var boolean
82
- */
83
- protected $floorToClosestDimension;
84
-
85
- /**
86
- * Foreground color.
87
- *
88
- * @var Color\ColorInterface
89
- */
90
- protected $foregroundColor;
91
-
92
- /**
93
- * Decorators used on QR codes.
94
- *
95
- * @var array
96
- */
97
- protected $decorators = array();
98
-
99
- /**
100
- * Sets the margin around the QR code.
101
- *
102
- * @param integer $margin
103
- * @return AbstractRenderer
104
- * @throws Exception\InvalidArgumentException
105
- */
106
- public function setMargin($margin)
107
- {
108
- if ($margin < 0) {
109
- throw new Exception\InvalidArgumentException('Margin must be equal to greater than 0');
110
- }
111
-
112
- $this->margin = (int) $margin;
113
- return $this;
114
- }
115
-
116
- /**
117
- * Gets the margin around the QR code.
118
- *
119
- * @return integer
120
- */
121
- public function getMargin()
122
- {
123
- return $this->margin;
124
- }
125
-
126
- /**
127
- * Sets the height around the renderd image.
128
- *
129
- * If the width is smaller than the matrix width plus padding, the renderer
130
- * will automatically use that as the width instead of the specified one.
131
- *
132
- * @param integer $width
133
- * @return AbstractRenderer
134
- */
135
- public function setWidth($width)
136
- {
137
- $this->width = (int) $width;
138
- return $this;
139
- }
140
-
141
- /**
142
- * Gets the width of the rendered image.
143
- *
144
- * @return integer
145
- */
146
- public function getWidth()
147
- {
148
- return $this->width;
149
- }
150
-
151
- /**
152
- * Sets the height around the renderd image.
153
- *
154
- * If the height is smaller than the matrix height plus padding, the
155
- * renderer will automatically use that as the height instead of the
156
- * specified one.
157
- *
158
- * @param integer $height
159
- * @return AbstractRenderer
160
- */
161
- public function setHeight($height)
162
- {
163
- $this->height = (int) $height;
164
- return $this;
165
- }
166
-
167
- /**
168
- * Gets the height around the rendered image.
169
- *
170
- * @return integer
171
- */
172
- public function getHeight()
173
- {
174
- return $this->height;
175
- }
176
-
177
- /**
178
- * Sets whether dimensions should be rounded down.
179
- *
180
- * @param boolean $flag
181
- * @return AbstractRenderer
182
- */
183
- public function setRoundDimensions($flag)
184
- {
185
- $this->floorToClosestDimension = $flag;
186
- return $this;
187
- }
188
-
189
- /**
190
- * Gets whether dimensions should be rounded down.
191
- *
192
- * @return boolean
193
- */
194
- public function shouldRoundDimensions()
195
- {
196
- return $this->floorToClosestDimension;
197
- }
198
-
199
- /**
200
- * Sets background color.
201
- *
202
- * @param Color\ColorInterface $color
203
- * @return AbstractRenderer
204
- */
205
- public function setBackgroundColor(Color\ColorInterface $color)
206
- {
207
- $this->backgroundColor = $color;
208
- return $this;
209
- }
210
-
211
- /**
212
- * Gets background color.
213
- *
214
- * @return Color\ColorInterface
215
- */
216
- public function getBackgroundColor()
217
- {
218
- if ($this->backgroundColor === null) {
219
- $this->backgroundColor = new Color\Gray(100);
220
- }
221
-
222
- return $this->backgroundColor;
223
- }
224
-
225
- /**
226
- * Sets foreground color.
227
- *
228
- * @param Color\ColorInterface $color
229
- * @return AbstractRenderer
230
- */
231
- public function setForegroundColor(Color\ColorInterface $color)
232
- {
233
- $this->foregroundColor = $color;
234
- return $this;
235
- }
236
-
237
- /**
238
- * Gets foreground color.
239
- *
240
- * @return Color\ColorInterface
241
- */
242
- public function getForegroundColor()
243
- {
244
- if ($this->foregroundColor === null) {
245
- $this->foregroundColor = new Color\Gray(0);
246
- }
247
-
248
- return $this->foregroundColor;
249
- }
250
-
251
- /**
252
- * Adds a decorator to the renderer.
253
- *
254
- * @param DecoratorInterface $decorator
255
- * @return AbstractRenderer
256
- */
257
- public function addDecorator(DecoratorInterface $decorator)
258
- {
259
- $this->decorators[] = $decorator;
260
- return $this;
261
- }
262
-
263
- /**
264
- * render(): defined by RendererInterface.
265
- *
266
- * @see RendererInterface::render()
267
- * @param QrCode $qrCode
268
- * @return string
269
- */
270
- public function render(QrCode $qrCode)
271
- {
272
- $input = $qrCode->getMatrix();
273
- $inputWidth = $input->getWidth();
274
- $inputHeight = $input->getHeight();
275
- $qrWidth = $inputWidth + ($this->getMargin() << 1);
276
- $qrHeight = $inputHeight + ($this->getMargin() << 1);
277
- $outputWidth = max($this->getWidth(), $qrWidth);
278
- $outputHeight = max($this->getHeight(), $qrHeight);
279
- $multiple = (int) min($outputWidth / $qrWidth, $outputHeight / $qrHeight);
280
-
281
- if ($this->shouldRoundDimensions()) {
282
- $outputWidth -= $outputWidth % $multiple;
283
- $outputHeight -= $outputHeight % $multiple;
284
- }
285
-
286
- // Padding includes both the quiet zone and the extra white pixels to
287
- // accommodate the requested dimensions. For example, if input is 25x25
288
- // the QR will be 33x33 including the quiet zone. If the requested size
289
- // is 200x160, the multiple will be 4, for a QR of 132x132. These will
290
- // handle all the padding from 100x100 (the actual QR) up to 200x160.
291
- $leftPadding = (int) (($outputWidth - ($inputWidth * $multiple)) / 2);
292
- $topPadding = (int) (($outputHeight - ($inputHeight * $multiple)) / 2);
293
-
294
- // Store calculated parameters
295
- $this->finalWidth = $outputWidth;
296
- $this->finalHeight = $outputHeight;
297
- $this->blockSize = $multiple;
298
-
299
- $this->init();
300
- $this->addColor('background', $this->getBackgroundColor());
301
- $this->addColor('foreground', $this->getForegroundColor());
302
- $this->drawBackground('background');
303
-
304
- foreach ($this->decorators as $decorator) {
305
- $decorator->preProcess(
306
- $qrCode,
307
- $this,
308
- $outputWidth,
309
- $outputHeight,
310
- $leftPadding,
311
- $topPadding,
312
- $multiple
313
- );
314
- }
315
-
316
- for ($inputY = 0, $outputY = $topPadding; $inputY < $inputHeight; $inputY++, $outputY += $multiple) {
317
- for ($inputX = 0, $outputX = $leftPadding; $inputX < $inputWidth; $inputX++, $outputX += $multiple) {
318
- if ($input->get($inputX, $inputY) === 1) {
319
- $this->drawBlock($outputX, $outputY, 'foreground');
320
- }
321
- }
322
- }
323
-
324
- foreach ($this->decorators as $decorator) {
325
- $decorator->postProcess(
326
- $qrCode,
327
- $this,
328
- $outputWidth,
329
- $outputHeight,
330
- $leftPadding,
331
- $topPadding,
332
- $multiple
333
- );
334
- }
335
-
336
- return $this->getByteStream();
337
- }
338
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Image/Decorator/DecoratorInterface.php DELETED
@@ -1,63 +0,0 @@
1
- <?php
2
- /**
3
- * BaconQrCode
4
- *
5
- * @link http://github.com/Bacon/BaconQrCode For the canonical source repository
6
- * @copyright 2013 Ben 'DASPRiD' Scholzen
7
- * @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
8
- */
9
-
10
- namespace BaconQrCode\Renderer\Image\Decorator;
11
-
12
- use BaconQrCode\Encoder\QrCode;
13
- use BaconQrCode\Renderer\Image\RendererInterface;
14
-
15
- /**
16
- * Decorator interface.
17
- */
18
- interface DecoratorInterface
19
- {
20
- /**
21
- * Pre-process a QR code.
22
- *
23
- * @param QrCode $qrCode
24
- * @param RendererInterface $renderer
25
- * @param integer $outputWidth
26
- * @param integer $outputHeight
27
- * @param integer $leftPadding
28
- * @param integer $topPadding
29
- * @param integer $multiple
30
- * @return void
31
- */
32
- public function preProcess(
33
- QrCode $qrCode,
34
- RendererInterface $renderer,
35
- $outputWidth,
36
- $outputHeight,
37
- $leftPadding,
38
- $topPadding,
39
- $multiple
40
- );
41
-
42
- /**
43
- * Post-process a QR code.
44
- *
45
- * @param QrCode $qrCode
46
- * @param RendererInterface $renderer
47
- * @param integer $outputWidth
48
- * @param integer $outputHeight
49
- * @param integer $leftPadding
50
- * @param integer $topPadding
51
- * @param integer $multiple
52
- * @return void
53
- */
54
- public function postProcess(
55
- QrCode $qrCode,
56
- RendererInterface $renderer,
57
- $outputWidth,
58
- $outputHeight,
59
- $leftPadding,
60
- $topPadding,
61
- $multiple
62
- );
63
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Image/Decorator/FinderPattern.php DELETED
@@ -1,210 +0,0 @@
1
- <?php
2
- /**
3
- * BaconQrCode
4
- *
5
- * @link http://github.com/Bacon/BaconQrCode For the canonical source repository
6
- * @copyright 2013 Ben 'DASPRiD' Scholzen
7
- * @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
8
- */
9
-
10
- namespace BaconQrCode\Renderer\Image\Decorator;
11
-
12
- use BaconQrCode\Encoder\QrCode;
13
- use BaconQrCode\Renderer\Image\RendererInterface;
14
- use BaconQrCode\Renderer\Color;
15
-
16
- /**
17
- * Finder pattern decorator.
18
- */
19
- class FinderPattern implements DecoratorInterface
20
- {
21
- /**
22
- * @var Color\ColorInterface
23
- */
24
- protected $innerColor;
25
-
26
- /**
27
- * @varColor\ColorInterface
28
- */
29
- protected $outerColor;
30
-
31
- /**
32
- * Outer position detection pattern.
33
- *
34
- * @var array
35
- */
36
- protected static $outerPositionDetectionPattern = array(
37
- array(1, 1, 1, 1, 1, 1, 1),
38
- array(1, 0, 0, 0, 0, 0, 1),
39
- array(1, 0, 0, 0, 0, 0, 1),
40
- array(1, 0, 0, 0, 0, 0, 1),
41
- array(1, 0, 0, 0, 0, 0, 1),
42
- array(1, 0, 0, 0, 0, 0, 1),
43
- array(1, 1, 1, 1, 1, 1, 1),
44
- );
45
-
46
- /**
47
- * Inner position detection pattern.
48
- *
49
- * @var array
50
- */
51
- protected static $innerPositionDetectionPattern = array(
52
- array(0, 0, 0, 0, 0, 0, 0),
53
- array(0, 0, 0, 0, 0, 0, 0),
54
- array(0, 0, 1, 1, 1, 0, 0),
55
- array(0, 0, 1, 1, 1, 0, 0),
56
- array(0, 0, 1, 1, 1, 0, 0),
57
- array(0, 0, 0, 0, 0, 0, 0),
58
- array(0, 0, 0, 0, 0, 0, 0),
59
- );
60
-
61
- /**
62
- * Sets outer color.
63
- *
64
- * @param Color\ColorInterface $color
65
- * @return FinderPattern
66
- */
67
- public function setOuterColor(Color\ColorInterface $color)
68
- {
69
- $this->outerColor = $color;
70
- return $this;
71
- }
72
-
73
- /**
74
- * Gets outer color.
75
- *
76
- * @return Color\ColorInterface
77
- */
78
- public function getOuterColor()
79
- {
80
- if ($this->outerColor === null) {
81
- $this->outerColor = new Color\Gray(100);
82
- }
83
-
84
- return $this->outerColor;
85
- }
86
-
87
- /**
88
- * Sets inner color.
89
- *
90
- * @param Color\ColorInterface $color
91
- * @return FinderPattern
92
- */
93
- public function setInnerColor(Color\ColorInterface $color)
94
- {
95
- $this->innerColor = $color;
96
- return $this;
97
- }
98
-
99
- /**
100
- * Gets inner color.
101
- *
102
- * @return Color\ColorInterface
103
- */
104
- public function getInnerColor()
105
- {
106
- if ($this->innerColor === null) {
107
- $this->innerColor = new Color\Gray(0);
108
- }
109
-
110
- return $this->innerColor;
111
- }
112
-
113
- /**
114
- * preProcess(): defined by DecoratorInterface.
115
- *
116
- * @see DecoratorInterface::preProcess()
117
- * @param QrCode $qrCode
118
- * @param RendererInterface $renderer
119
- * @param integer $outputWidth
120
- * @param integer $outputHeight
121
- * @param integer $leftPadding
122
- * @param integer $topPadding
123
- * @param integer $multiple
124
- * @return void
125
- */
126
- public function preProcess(
127
- QrCode $qrCode,
128
- RendererInterface $renderer,
129
- $outputWidth,
130
- $outputHeight,
131
- $leftPadding,
132
- $topPadding,
133
- $multiple
134
- ) {
135
- $matrix = $qrCode->getMatrix();
136
- $positions = array(
137
- array(0, 0),
138
- array($matrix->getWidth() - 7, 0),
139
- array(0, $matrix->getHeight() - 7),
140
- );
141
-
142
- foreach (self::$outerPositionDetectionPattern as $y => $row) {
143
- foreach ($row as $x => $isSet) {
144
- foreach ($positions as $position) {
145
- $matrix->set($x + $position[0], $y + $position[1], 0);
146
- }
147
- }
148
- }
149
- }
150
-
151
- /**
152
- * postProcess(): defined by DecoratorInterface.
153
- *
154
- * @see DecoratorInterface::postProcess()
155
- *
156
- * @param QrCode $qrCode
157
- * @param RendererInterface $renderer
158
- * @param integer $outputWidth
159
- * @param integer $outputHeight
160
- * @param integer $leftPadding
161
- * @param integer $topPadding
162
- * @param integer $multiple
163
- * @return void
164
- */
165
- public function postProcess(
166
- QrCode $qrCode,
167
- RendererInterface $renderer,
168
- $outputWidth,
169
- $outputHeight,
170
- $leftPadding,
171
- $topPadding,
172
- $multiple
173
- ) {
174
- $matrix = $qrCode->getMatrix();
175
- $positions = array(
176
- array(0, 0),
177
- array($matrix->getWidth() - 7, 0),
178
- array(0, $matrix->getHeight() - 7),
179
- );
180
-
181
- $renderer->addColor('finder-outer', $this->getOuterColor());
182
- $renderer->addColor('finder-inner', $this->getInnerColor());
183
-
184
- foreach (self::$outerPositionDetectionPattern as $y => $row) {
185
- foreach ($row as $x => $isOuterSet) {
186
- $isInnerSet = self::$innerPositionDetectionPattern[$y][$x];
187
-
188
- if ($isOuterSet) {
189
- foreach ($positions as $position) {
190
- $renderer->drawBlock(
191
- $leftPadding + $x * $multiple + $position[0] * $multiple,
192
- $topPadding + $y * $multiple + $position[1] * $multiple,
193
- 'finder-outer'
194
- );
195
- }
196
- }
197
-
198
- if ($isInnerSet) {
199
- foreach ($positions as $position) {
200
- $renderer->drawBlock(
201
- $leftPadding + $x * $multiple + $position[0] * $multiple,
202
- $topPadding + $y * $multiple + $position[1] * $multiple,
203
- 'finder-inner'
204
- );
205
- }
206
- }
207
- }
208
- }
209
- }
210
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Image/Eps.php DELETED
@@ -1,152 +0,0 @@
1
- <?php
2
- /**
3
- * BaconQrCode
4
- *
5
- * @link http://github.com/Bacon/BaconQrCode For the canonical source repository
6
- * @copyright 2013 Ben 'DASPRiD' Scholzen
7
- * @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
8
- */
9
-
10
- namespace BaconQrCode\Renderer\Image;
11
-
12
- use BaconQrCode\Renderer\Color\ColorInterface;
13
- use BaconQrCode\Renderer\Color\Rgb;
14
- use BaconQrCode\Renderer\Color\Cmyk;
15
- use BaconQrCode\Renderer\Color\Gray;
16
-
17
- /**
18
- * EPS backend.
19
- */
20
- class Eps extends AbstractRenderer
21
- {
22
- /**
23
- * EPS string.
24
- *
25
- * @var string
26
- */
27
- protected $eps;
28
-
29
- /**
30
- * Colors used for drawing.
31
- *
32
- * @var array
33
- */
34
- protected $colors = array();
35
-
36
- /**
37
- * Current color.
38
- *
39
- * @var string
40
- */
41
- protected $currentColor;
42
-
43
- /**
44
- * init(): defined by RendererInterface.
45
- *
46
- * @see ImageRendererInterface::init()
47
- * @return void
48
- */
49
- public function init()
50
- {
51
- $this->eps = "%!PS-Adobe-3.0 EPSF-3.0\n"
52
- . "%%BoundingBox: 0 0 " . $this->finalWidth . " " . $this->finalHeight . "\n"
53
- . "/F { rectfill } def\n";
54
- }
55
-
56
- /**
57
- * addColor(): defined by RendererInterface.
58
- *
59
- * @see ImageRendererInterface::addColor()
60
- * @param string $id
61
- * @param ColorInterface $color
62
- * @return void
63
- */
64
- public function addColor($id, ColorInterface $color)
65
- {
66
- if (
67
- !$color instanceof Rgb
68
- && !$color instanceof Cmyk
69
- && !$color instanceof Gray
70
- ) {
71
- $color = $color->toCmyk();
72
- }
73
-
74
- $this->colors[$id] = $color;
75
- }
76
-
77
- /**
78
- * drawBackground(): defined by RendererInterface.
79
- *
80
- * @see ImageRendererInterface::drawBackground()
81
- * @param string $colorId
82
- * @return void
83
- */
84
- public function drawBackground($colorId)
85
- {
86
- $this->setColor($colorId);
87
- $this->eps .= "0 0 " . $this->finalWidth . " " . $this->finalHeight . " F\n";
88
- }
89
-
90
- /**
91
- * drawBlock(): defined by RendererInterface.
92
- *
93
- * @see ImageRendererInterface::drawBlock()
94
- * @param integer $x
95
- * @param integer $y
96
- * @param string $colorId
97
- * @return void
98
- */
99
- public function drawBlock($x, $y, $colorId)
100
- {
101
- $this->setColor($colorId);
102
- $this->eps .= $x . " " . ($this->finalHeight - $y - $this->blockSize) . " " . $this->blockSize . " " . $this->blockSize . " F\n";
103
- }
104
-
105
- /**
106
- * getByteStream(): defined by RendererInterface.
107
- *
108
- * @see ImageRendererInterface::getByteStream()
109
- * @return string
110
- */
111
- public function getByteStream()
112
- {
113
- return $this->eps;
114
- }
115
-
116
- /**
117
- * Sets color to use.
118
- *
119
- * @param string $colorId
120
- * @return void
121
- */
122
- protected function setColor($colorId)
123
- {
124
- if ($colorId !== $this->currentColor) {
125
- $color = $this->colors[$colorId];
126
-
127
- if ($color instanceof Rgb) {
128
- $this->eps .= sprintf(
129
- "%F %F %F setrgbcolor\n",
130
- $color->getRed() / 100,
131
- $color->getGreen() / 100,
132
- $color->getBlue() / 100
133
- );
134
- } elseif ($color instanceof Cmyk) {
135
- $this->eps .= sprintf(
136
- "%F %F %F %F setcmykcolor\n",
137
- $color->getCyan() / 100,
138
- $color->getMagenta() / 100,
139
- $color->getYellow() / 100,
140
- $color->getBlack() / 100
141
- );
142
- } elseif ($color instanceof Gray) {
143
- $this->eps .= sprintf(
144
- "%F setgray\n",
145
- $color->getGray() / 100
146
- );
147
- }
148
-
149
- $this->currentColor = $colorId;
150
- }
151
- }
152
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Image/Png.php DELETED
@@ -1,115 +0,0 @@
1
- <?php
2
- /**
3
- * BaconQrCode
4
- *
5
- * @link http://github.com/Bacon/BaconQrCode For the canonical source repository
6
- * @copyright 2013 Ben 'DASPRiD' Scholzen
7
- * @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
8
- */
9
-
10
- namespace BaconQrCode\Renderer\Image;
11
-
12
- use BaconQrCode\Exception;
13
- use BaconQrCode\Renderer\Color\ColorInterface;
14
-
15
- /**
16
- * PNG backend.
17
- */
18
- class Png extends AbstractRenderer
19
- {
20
- /**
21
- * Image resource used when drawing.
22
- *
23
- * @var resource
24
- */
25
- protected $image;
26
-
27
- /**
28
- * Colors used for drawing.
29
- *
30
- * @var array
31
- */
32
- protected $colors = array();
33
-
34
- /**
35
- * init(): defined by RendererInterface.
36
- *
37
- * @see ImageRendererInterface::init()
38
- * @return void
39
- */
40
- public function init()
41
- {
42
- $this->image = imagecreatetruecolor($this->finalWidth, $this->finalHeight);
43
- }
44
-
45
- /**
46
- * addColor(): defined by RendererInterface.
47
- *
48
- * @see ImageRendererInterface::addColor()
49
- * @param string $id
50
- * @param ColorInterface $color
51
- * @return void
52
- * @throws Exception\RuntimeException
53
- */
54
- public function addColor($id, ColorInterface $color)
55
- {
56
- if ($this->image === null) {
57
- throw new Exception\RuntimeException('Colors can only be added after init');
58
- }
59
-
60
- $color = $color->toRgb();
61
-
62
- $this->colors[$id] = imagecolorallocate(
63
- $this->image,
64
- $color->getRed(),
65
- $color->getGreen(),
66
- $color->getBlue()
67
- );
68
- }
69
-
70
- /**
71
- * drawBackground(): defined by RendererInterface.
72
- *
73
- * @see ImageRendererInterface::drawBackground()
74
- * @param string $colorId
75
- * @return void
76
- */
77
- public function drawBackground($colorId)
78
- {
79
- imagefill($this->image, 0, 0, $this->colors[$colorId]);
80
- }
81
-
82
- /**
83
- * drawBlock(): defined by RendererInterface.
84
- *
85
- * @see ImageRendererInterface::drawBlock()
86
- * @param integer $x
87
- * @param integer $y
88
- * @param string $colorId
89
- * @return void
90
- */
91
- public function drawBlock($x, $y, $colorId)
92
- {
93
- imagefilledrectangle(
94
- $this->image,
95
- $x,
96
- $y,
97
- $x + $this->blockSize - 1,
98
- $y + $this->blockSize - 1,
99
- $this->colors[$colorId]
100
- );
101
- }
102
-
103
- /**
104
- * getByteStream(): defined by RendererInterface.
105
- *
106
- * @see ImageRendererInterface::getByteStream()
107
- * @return string
108
- */
109
- public function getByteStream()
110
- {
111
- ob_start();
112
- imagepng($this->image);
113
- return ob_get_clean();
114
- }
115
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Image/RendererInterface.php DELETED
@@ -1,61 +0,0 @@
1
- <?php
2
- /**
3
- * BaconQrCode
4
- *
5
- * @link http://github.com/Bacon/BaconQrCode For the canonical source repository
6
- * @copyright 2013 Ben 'DASPRiD' Scholzen
7
- * @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
8
- */
9
-
10
- namespace BaconQrCode\Renderer\Image;
11
-
12
- use BaconQrCode\Renderer\Color\ColorInterface;
13
- use BaconQrCode\Renderer\RendererInterface as GeneralRendererInterface;
14
-
15
- /**
16
- * Renderer interface.
17
- */
18
- interface RendererInterface extends GeneralRendererInterface
19
- {
20
- /**
21
- * Initiates the drawing area.
22
- *
23
- * @return void
24
- */
25
- public function init();
26
-
27
- /**
28
- * Adds a color to the drawing area.
29
- *
30
- * @param string $id
31
- * @param ColorInterface $color
32
- * @return void
33
- */
34
- public function addColor($id, ColorInterface $color);
35
-
36
- /**
37
- * Draws the background.
38
- *
39
- * @param string $colorId
40
- * @return void
41
- */
42
- public function drawBackground($colorId);
43
-
44
- /**
45
- * Draws a block at a specified position.
46
- *
47
- * @param integer $x
48
- * @param integer $y
49
- * @param string $colorId
50
- * @return void
51
- */
52
- public function drawBlock($x, $y, $colorId);
53
-
54
- /**
55
- * Returns the byte stream representing the QR code.
56
- *
57
- * @return string
58
- */
59
- public function getByteStream();
60
-
61
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Image/Svg.php DELETED
@@ -1,146 +0,0 @@
1
- <?php
2
- /**
3
- * BaconQrCode
4
- *
5
- * @link http://github.com/Bacon/BaconQrCode For the canonical source repository
6
- * @copyright 2013 Ben 'DASPRiD' Scholzen
7
- * @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
8
- */
9
-
10
- namespace BaconQrCode\Renderer\Image;
11
-
12
- use BaconQrCode\Exception;
13
- use BaconQrCode\Renderer\Color\ColorInterface;
14
- use SimpleXMLElement;
15
-
16
- /**
17
- * SVG backend.
18
- */
19
- class Svg extends AbstractRenderer
20
- {
21
- /**
22
- * SVG resource.
23
- *
24
- * @var SimpleXMLElement
25
- */
26
- protected $svg;
27
-
28
- /**
29
- * Colors used for drawing.
30
- *
31
- * @var array
32
- */
33
- protected $colors = array();
34
-
35
- /**
36
- * Prototype IDs.
37
- *
38
- * @var array
39
- */
40
- protected $prototypeIds = array();
41
-
42
- /**
43
- * init(): defined by RendererInterface.
44
- *
45
- * @see ImageRendererInterface::init()
46
- * @return void
47
- */
48
- public function init()
49
- {
50
- $this->svg = new SimpleXMLElement(
51
- '<?xml version="1.0" encoding="UTF-8"?>'
52
- . '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"/>'
53
- );
54
- $this->svg->addAttribute('version', '1.1');
55
- $this->svg->addAttribute('width', $this->finalWidth . 'px');
56
- $this->svg->addAttribute('height', $this->finalHeight . 'px');
57
- $this->svg->addAttribute('viewBox', '0 0 ' . $this->finalWidth . ' ' . $this->finalHeight);
58
- $this->svg->addChild('defs');
59
- }
60
-
61
- /**
62
- * addColor(): defined by RendererInterface.
63
- *
64
- * @see ImageRendererInterface::addColor()
65
- * @param string $id
66
- * @param ColorInterface $color
67
- * @return void
68
- * @throws Exception\InvalidArgumentException
69
- */
70
- public function addColor($id, ColorInterface $color)
71
- {
72
- $this->colors[$id] = (string) $color->toRgb();
73
- }
74
-
75
- /**
76
- * drawBackground(): defined by RendererInterface.
77
- *
78
- * @see ImageRendererInterface::drawBackground()
79
- * @param string $colorId
80
- * @return void
81
- */
82
- public function drawBackground($colorId)
83
- {
84
- $rect = $this->svg->addChild('rect');
85
- $rect->addAttribute('x', 0);
86
- $rect->addAttribute('y', 0);
87
- $rect->addAttribute('width', $this->finalWidth);
88
- $rect->addAttribute('height', $this->finalHeight);
89
- $rect->addAttribute('fill', '#' . $this->colors[$colorId]);
90
- }
91
-
92
- /**
93
- * drawBlock(): defined by RendererInterface.
94
- *
95
- * @see ImageRendererInterface::drawBlock()
96
- * @param integer $x
97
- * @param integer $y
98
- * @param string $colorId
99
- * @return void
100
- */
101
- public function drawBlock($x, $y, $colorId)
102
- {
103
- $use = $this->svg->addChild('use');
104
- $use->addAttribute('x', $x);
105
- $use->addAttribute('y', $y);
106
- $use->addAttribute(
107
- 'xlink:href',
108
- $this->getRectPrototypeId($colorId),
109
- 'http://www.w3.org/1999/xlink'
110
- );
111
- }
112
-
113
- /**
114
- * getByteStream(): defined by RendererInterface.
115
- *
116
- * @see ImageRendererInterface::getByteStream()
117
- * @return string
118
- */
119
- public function getByteStream()
120
- {
121
- return $this->svg->asXML();
122
- }
123
-
124
- /**
125
- * Get the prototype ID for a color.
126
- *
127
- * @param integer $colorId
128
- * @return string
129
- */
130
- protected function getRectPrototypeId($colorId)
131
- {
132
- if (!isset($this->prototypeIds[$colorId])) {
133
- $id = 'r' . dechex(count($this->prototypeIds));
134
-
135
- $rect = $this->svg->defs->addChild('rect');
136
- $rect->addAttribute('id', $id);
137
- $rect->addAttribute('width', $this->blockSize);
138
- $rect->addAttribute('height', $this->blockSize);
139
- $rect->addAttribute('fill', '#' . $this->colors[$colorId]);
140
-
141
- $this->prototypeIds[$colorId] = '#' . $id;
142
- }
143
-
144
- return $this->prototypeIds[$colorId];
145
- }
146
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Renderer/RendererInterface.php DELETED
@@ -1,26 +0,0 @@
1
- <?php
2
- /**
3
- * BaconQrCode
4
- *
5
- * @link http://github.com/Bacon/BaconQrCode For the canonical source repository
6
- * @copyright 2013 Ben 'DASPRiD' Scholzen
7
- * @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
8
- */
9
-
10
- namespace BaconQrCode\Renderer;
11
-
12
- use BaconQrCode\Encoder\QrCode;
13
-
14
- /**
15
- * Renderer interface.
16
- */
17
- interface RendererInterface
18
- {
19
- /**
20
- * Renders a QR code.
21
- *
22
- * @param QrCode $qrCode
23
- * @return string
24
- */
25
- public function render(QrCode $qrCode);
26
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Text/Html.php DELETED
@@ -1,91 +0,0 @@
1
- <?php
2
- /**
3
- * BaconQrCode
4
- *
5
- * @link http://github.com/Bacon/BaconQrCode For the canonical source repository
6
- * @copyright 2013 Ben 'DASPRiD' Scholzen
7
- * @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
8
- */
9
-
10
- namespace BaconQrCode\Renderer\Text;
11
-
12
- use BaconQrCode\Encoder\QrCode;
13
-
14
- /**
15
- * Html renderer.
16
- */
17
- class Html extends Plain
18
- {
19
- /**
20
- * HTML CSS class attribute value.
21
- *
22
- * @var string
23
- */
24
- protected $class = '';
25
-
26
- /**
27
- * HTML CSS style definition for the code element.
28
- *
29
- * @var string
30
- */
31
- protected $style = 'font-family: monospace; line-height: 0.65em; letter-spacing: -1px';
32
-
33
- /**
34
- * Set CSS class name.
35
- *
36
- * @param string $class
37
- */
38
- public function setClass($class)
39
- {
40
- $this->class = $class;
41
- }
42
-
43
- /**
44
- * Get CSS class name.
45
- *
46
- * @return string
47
- */
48
- public function getClass()
49
- {
50
- return $this->class;
51
- }
52
-
53
- /**
54
- * Set CSS style value.
55
- *
56
- * @param string $style
57
- */
58
- public function setStyle($style)
59
- {
60
- $this->style = $style;
61
- }
62
-
63
- /**
64
- * Get CSS style value.
65
- *
66
- * @return string
67
- */
68
- public function getStyle()
69
- {
70
- return $this->style;
71
- }
72
-
73
- /**
74
- * render(): defined by RendererInterface.
75
- *
76
- * @see RendererInterface::render()
77
- * @param QrCode $qrCode
78
- * @return string
79
- */
80
- public function render(QrCode $qrCode)
81
- {
82
- $textCode = parent::render($qrCode);
83
-
84
- $result = '<pre'
85
- . ' style="' . htmlspecialchars($this->style, ENT_QUOTES, 'utf-8') . '"'
86
- . ' class="' . htmlspecialchars($this->class, ENT_QUOTES, 'utf-8') . '"'
87
- . '>' . $textCode . '</pre>';
88
-
89
- return $result;
90
- }
91
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Text/Plain.php DELETED
@@ -1,150 +0,0 @@
1
- <?php
2
- /**
3
- * BaconQrCode
4
- *
5
- * @link http://github.com/Bacon/BaconQrCode For the canonical source repository
6
- * @copyright 2013 Ben 'DASPRiD' Scholzen
7
- * @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
8
- */
9
-
10
- namespace BaconQrCode\Renderer\Text;
11
-
12
- use BaconQrCode\Exception;
13
- use BaconQrCode\Encoder\QrCode;
14
- use BaconQrCode\Renderer\RendererInterface;
15
-
16
- /**
17
- * Plaintext renderer.
18
- */
19
- class Plain implements RendererInterface
20
- {
21
- /**
22
- * Margin around the QR code, also known as quiet zone.
23
- *
24
- * @var integer
25
- */
26
- protected $margin = 1;
27
-
28
- /**
29
- * Char used for full block.
30
- *
31
- * UTF-8 FULL BLOCK (U+2588)
32
- *
33
- * @var string
34
- * @link http://www.fileformat.info/info/unicode/char/2588/index.htm
35
- */
36
- protected $fullBlock = "\xE2\x96\x88";
37
-
38
- /**
39
- * Char used for empty space
40
- *
41
- * @var string
42
- */
43
- protected $emptyBlock = ' ';
44
-
45
- /**
46
- * Set char used as full block (occupied space, "black").
47
- *
48
- * @param string $fullBlock
49
- */
50
- public function setFullBlock($fullBlock)
51
- {
52
- $this->fullBlock = $fullBlock;
53
- }
54
-
55
- /**
56
- * Get char used as full block (occupied space, "black").
57
- *
58
- * @return string
59
- */
60
- public function getFullBlock()
61
- {
62
- return $this->fullBlock;
63
- }
64
-
65
- /**
66
- * Set char used as empty block (empty space, "white").
67
- *
68
- * @param string $emptyBlock
69
- */
70
- public function setEmptyBlock($emptyBlock)
71
- {
72
- $this->emptyBlock = $emptyBlock;
73
- }
74
-
75
- /**
76
- * Get char used as empty block (empty space, "white").
77
- *
78
- * @return string
79
- */
80
- public function getEmptyBlock()
81
- {
82
- return $this->emptyBlock;
83
- }
84
-
85
- /**
86
- * Sets the margin around the QR code.
87
- *
88
- * @param integer $margin
89
- * @return AbstractRenderer
90
- * @throws Exception\InvalidArgumentException
91
- */
92
- public function setMargin($margin)
93
- {
94
- if ($margin < 0) {
95
- throw new Exception\InvalidArgumentException('Margin must be equal to greater than 0');
96
- }
97
-
98
- $this->margin = (int) $margin;
99
-
100
- return $this;
101
- }
102
-
103
- /**
104
- * Gets the margin around the QR code.
105
- *
106
- * @return integer
107
- */
108
- public function getMargin()
109
- {
110
- return $this->margin;
111
- }
112
-
113
- /**
114
- * render(): defined by RendererInterface.
115
- *
116
- * @see RendererInterface::render()
117
- * @param QrCode $qrCode
118
- * @return string
119
- */
120
- public function render(QrCode $qrCode)
121
- {
122
- $result = '';
123
- $matrix = $qrCode->getMatrix();
124
- $width = $matrix->getWidth();
125
-
126
- // Top margin
127
- for ($x = 0; $x < $this->margin; $x++) {
128
- $result .= str_repeat($this->emptyBlock, $width + 2 * $this->margin)."\n";
129
- }
130
-
131
- // Body
132
- $array = $matrix->getArray();
133
-
134
- foreach ($array as $row) {
135
- $result .= str_repeat($this->emptyBlock, $this->margin); // left margin
136
- foreach ($row as $byte) {
137
- $result .= $byte ? $this->fullBlock : $this->emptyBlock;
138
- }
139
- $result .= str_repeat($this->emptyBlock, $this->margin); // right margin
140
- $result .= "\n";
141
- }
142
-
143
- // Bottom margin
144
- for ($x = 0; $x < $this->margin; $x++) {
145
- $result .= str_repeat($this->emptyBlock, $width + 2 * $this->margin)."\n";
146
- }
147
-
148
- return $result;
149
- }
150
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/bacon/bacon-qr-code/src/BaconQrCode/Writer.php DELETED
@@ -1,105 +0,0 @@
1
- <?php
2
- /**
3
- * BaconQrCode
4
- *
5
- * @link http://github.com/Bacon/BaconQrCode For the canonical source repository
6
- * @copyright 2013 Ben 'DASPRiD' Scholzen
7
- * @license http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
8
- */
9
-
10
- namespace BaconQrCode;
11
-
12
- use BaconQrCode\Common\ErrorCorrectionLevel;
13
- use BaconQrCode\Encoder\Encoder;
14
- use BaconQrCode\Exception;
15
- use BaconQrCode\Renderer\RendererInterface;
16
-
17
- /**
18
- * QR code writer.
19
- */
20
- class Writer
21
- {
22
- /**
23
- * Renderer instance.
24
- *
25
- * @var RendererInterface
26
- */
27
- protected $renderer;
28
-
29
- /**
30
- * Creates a new writer with a specific renderer.
31
- *
32
- * @param RendererInterface $renderer
33
- */
34
- public function __construct(RendererInterface $renderer)
35
- {
36
- $this->renderer = $renderer;
37
- }
38
-
39
- /**
40
- * Sets the renderer used to create a byte stream.
41
- *
42
- * @param RendererInterface $renderer
43
- * @return Writer
44
- */
45
- public function setRenderer(RendererInterface $renderer)
46
- {
47
- $this->renderer = $renderer;
48
- return $this;
49
- }
50
-
51
- /**
52
- * Gets the renderer used to create a byte stream.
53
- *
54
- * @return RendererInterface
55
- */
56
- public function getRenderer()
57
- {
58
- return $this->renderer;
59
- }
60
-
61
- /**
62
- * Writes QR code and returns it as string.
63
- *
64
- * Content is a string which *should* be encoded in UTF-8, in case there are
65
- * non ASCII-characters present.
66
- *
67
- * @param string $content
68
- * @param string $encoding
69
- * @param integer $ecLevel
70
- * @return string
71
- * @throws Exception\InvalidArgumentException
72
- */
73
- public function writeString(
74
- $content,
75
- $encoding = Encoder::DEFAULT_BYTE_MODE_ECODING,
76
- $ecLevel = ErrorCorrectionLevel::L
77
- ) {
78
- if (strlen($content) === 0) {
79
- throw new Exception\InvalidArgumentException('Found empty contents');
80
- }
81
-
82
- $qrCode = Encoder::encode($content, new ErrorCorrectionLevel($ecLevel), $encoding);
83
-
84
- return $this->getRenderer()->render($qrCode);
85
- }
86
-
87
- /**
88
- * Writes QR code to a file.
89
- *
90
- * @see Writer::writeString()
91
- * @param string $content
92
- * @param string $filename
93
- * @param string $encoding
94
- * @param integer $ecLevel
95
- * @return void
96
- */
97
- public function writeFile(
98
- $content,
99
- $filename,
100
- $encoding = Encoder::DEFAULT_BYTE_MODE_ECODING,
101
- $ecLevel = ErrorCorrectionLevel::L
102
- ) {
103
- file_put_contents($filename, $this->writeString($content, $encoding, $ecLevel));
104
- }
105
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/composer/autoload_classmap.php CHANGED
@@ -6,45 +6,6 @@ $vendorDir = dirname(dirname(__FILE__));
6
  $baseDir = dirname($vendorDir);
7
 
8
  return array(
9
- 'BaconQrCode\\Common\\AbstractEnum' => $vendorDir . '/bacon/bacon-qr-code/src/BaconQrCode/Common/AbstractEnum.php',
10
- 'BaconQrCode\\Common\\BitArray' => $vendorDir . '/bacon/bacon-qr-code/src/BaconQrCode/Common/BitArray.php',
11
- 'BaconQrCode\\Common\\BitMatrix' => $vendorDir . '/bacon/bacon-qr-code/src/BaconQrCode/Common/BitMatrix.php',
12
- 'BaconQrCode\\Common\\BitUtils' => $vendorDir . '/bacon/bacon-qr-code/src/BaconQrCode/Common/BitUtils.php',
13
- 'BaconQrCode\\Common\\CharacterSetEci' => $vendorDir . '/bacon/bacon-qr-code/src/BaconQrCode/Common/CharacterSetEci.php',
14
- 'BaconQrCode\\Common\\EcBlock' => $vendorDir . '/bacon/bacon-qr-code/src/BaconQrCode/Common/EcBlock.php',
15
- 'BaconQrCode\\Common\\EcBlocks' => $vendorDir . '/bacon/bacon-qr-code/src/BaconQrCode/Common/EcBlocks.php',
16
- 'BaconQrCode\\Common\\ErrorCorrectionLevel' => $vendorDir . '/bacon/bacon-qr-code/src/BaconQrCode/Common/ErrorCorrectionLevel.php',
17
- 'BaconQrCode\\Common\\FormatInformation' => $vendorDir . '/bacon/bacon-qr-code/src/BaconQrCode/Common/FormatInformation.php',
18
- 'BaconQrCode\\Common\\Mode' => $vendorDir . '/bacon/bacon-qr-code/src/BaconQrCode/Common/Mode.php',
19
- 'BaconQrCode\\Common\\ReedSolomonCodec' => $vendorDir . '/bacon/bacon-qr-code/src/BaconQrCode/Common/ReedSolomonCodec.php',
20
- 'BaconQrCode\\Common\\Version' => $vendorDir . '/bacon/bacon-qr-code/src/BaconQrCode/Common/Version.php',
21
- 'BaconQrCode\\Encoder\\BlockPair' => $vendorDir . '/bacon/bacon-qr-code/src/BaconQrCode/Encoder/BlockPair.php',
22
- 'BaconQrCode\\Encoder\\ByteMatrix' => $vendorDir . '/bacon/bacon-qr-code/src/BaconQrCode/Encoder/ByteMatrix.php',
23
- 'BaconQrCode\\Encoder\\Encoder' => $vendorDir . '/bacon/bacon-qr-code/src/BaconQrCode/Encoder/Encoder.php',
24
- 'BaconQrCode\\Encoder\\MaskUtil' => $vendorDir . '/bacon/bacon-qr-code/src/BaconQrCode/Encoder/MaskUtil.php',
25
- 'BaconQrCode\\Encoder\\MatrixUtil' => $vendorDir . '/bacon/bacon-qr-code/src/BaconQrCode/Encoder/MatrixUtil.php',
26
- 'BaconQrCode\\Encoder\\QrCode' => $vendorDir . '/bacon/bacon-qr-code/src/BaconQrCode/Encoder/QrCode.php',
27
- 'BaconQrCode\\Exception\\ExceptionInterface' => $vendorDir . '/bacon/bacon-qr-code/src/BaconQrCode/Exception/ExceptionInterface.php',
28
- 'BaconQrCode\\Exception\\InvalidArgumentException' => $vendorDir . '/bacon/bacon-qr-code/src/BaconQrCode/Exception/InvalidArgumentException.php',
29
- 'BaconQrCode\\Exception\\OutOfBoundsException' => $vendorDir . '/bacon/bacon-qr-code/src/BaconQrCode/Exception/OutOfBoundsException.php',
30
- 'BaconQrCode\\Exception\\RuntimeException' => $vendorDir . '/bacon/bacon-qr-code/src/BaconQrCode/Exception/RuntimeException.php',
31
- 'BaconQrCode\\Exception\\UnexpectedValueException' => $vendorDir . '/bacon/bacon-qr-code/src/BaconQrCode/Exception/UnexpectedValueException.php',
32
- 'BaconQrCode\\Exception\\WriterException' => $vendorDir . '/bacon/bacon-qr-code/src/BaconQrCode/Exception/WriterException.php',
33
- 'BaconQrCode\\Renderer\\Color\\Cmyk' => $vendorDir . '/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Color/Cmyk.php',
34
- 'BaconQrCode\\Renderer\\Color\\ColorInterface' => $vendorDir . '/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Color/ColorInterface.php',
35
- 'BaconQrCode\\Renderer\\Color\\Gray' => $vendorDir . '/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Color/Gray.php',
36
- 'BaconQrCode\\Renderer\\Color\\Rgb' => $vendorDir . '/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Color/Rgb.php',
37
- 'BaconQrCode\\Renderer\\Image\\AbstractRenderer' => $vendorDir . '/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Image/AbstractRenderer.php',
38
- 'BaconQrCode\\Renderer\\Image\\Decorator\\DecoratorInterface' => $vendorDir . '/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Image/Decorator/DecoratorInterface.php',
39
- 'BaconQrCode\\Renderer\\Image\\Decorator\\FinderPattern' => $vendorDir . '/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Image/Decorator/FinderPattern.php',
40
- 'BaconQrCode\\Renderer\\Image\\Eps' => $vendorDir . '/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Image/Eps.php',
41
- 'BaconQrCode\\Renderer\\Image\\Png' => $vendorDir . '/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Image/Png.php',
42
- 'BaconQrCode\\Renderer\\Image\\RendererInterface' => $vendorDir . '/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Image/RendererInterface.php',
43
- 'BaconQrCode\\Renderer\\Image\\Svg' => $vendorDir . '/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Image/Svg.php',
44
- 'BaconQrCode\\Renderer\\RendererInterface' => $vendorDir . '/bacon/bacon-qr-code/src/BaconQrCode/Renderer/RendererInterface.php',
45
- 'BaconQrCode\\Renderer\\Text\\Html' => $vendorDir . '/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Text/Html.php',
46
- 'BaconQrCode\\Renderer\\Text\\Plain' => $vendorDir . '/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Text/Plain.php',
47
- 'BaconQrCode\\Writer' => $vendorDir . '/bacon/bacon-qr-code/src/BaconQrCode/Writer.php',
48
  'Base32\\Base32' => $vendorDir . '/christian-riesen/base32/src/Base32.php',
49
  'Carbon\\Carbon' => $vendorDir . '/nesbot/carbon/src/Carbon/Carbon.php',
50
  'Carbon\\CarbonInterval' => $vendorDir . '/nesbot/carbon/src/Carbon/CarbonInterval.php',
@@ -62,34 +23,6 @@ return array(
62
  'Dolondro\\GoogleAuthenticator\\SecretFactory' => $vendorDir . '/dolondro/google-authenticator/src/SecretFactory.php',
63
  'Elliotchance\\Iterator\\AbstractPagedIterator' => $vendorDir . '/elliotchance/iterator/src/Elliotchance/Iterator/AbstractPagedIterator.php',
64
  'Elliotchance\\Iterator\\PagedIteratorTest' => $vendorDir . '/elliotchance/iterator/tests/Elliotchance/Iterator/PagedIteratorTest.php',
65
- 'Endroid\\QrCode\\Bundle\\QrCodeBundle\\Controller\\QrCodeController' => $vendorDir . '/endroid/qr-code/src/Bundle/QrCodeBundle/Controller/QrCodeController.php',
66
- 'Endroid\\QrCode\\Bundle\\QrCodeBundle\\DependencyInjection\\Compiler\\WriterRegistryCompilerPass' => $vendorDir . '/endroid/qr-code/src/Bundle/QrCodeBundle/DependencyInjection/Compiler/WriterRegistryCompilerPass.php',
67
- 'Endroid\\QrCode\\Bundle\\QrCodeBundle\\DependencyInjection\\Configuration' => $vendorDir . '/endroid/qr-code/src/Bundle/QrCodeBundle/DependencyInjection/Configuration.php',
68
- 'Endroid\\QrCode\\Bundle\\QrCodeBundle\\DependencyInjection\\EndroidQrCodeExtension' => $vendorDir . '/endroid/qr-code/src/Bundle/QrCodeBundle/DependencyInjection/EndroidQrCodeExtension.php',
69
- 'Endroid\\QrCode\\Bundle\\QrCodeBundle\\EndroidQrCodeBundle' => $vendorDir . '/endroid/qr-code/src/Bundle/QrCodeBundle/EndroidQrCodeBundle.php',
70
- 'Endroid\\QrCode\\ErrorCorrectionLevel' => $vendorDir . '/endroid/qr-code/src/ErrorCorrectionLevel.php',
71
- 'Endroid\\QrCode\\Exception\\InvalidPathException' => $vendorDir . '/endroid/qr-code/src/Exception/InvalidPathException.php',
72
- 'Endroid\\QrCode\\Exception\\InvalidWriterException' => $vendorDir . '/endroid/qr-code/src/Exception/InvalidWriterException.php',
73
- 'Endroid\\QrCode\\Exception\\MissingFunctionException' => $vendorDir . '/endroid/qr-code/src/Exception/MissingFunctionException.php',
74
- 'Endroid\\QrCode\\Exception\\QrCodeException' => $vendorDir . '/endroid/qr-code/src/Exception/QrCodeException.php',
75
- 'Endroid\\QrCode\\Exception\\UnsupportedExtensionException' => $vendorDir . '/endroid/qr-code/src/Exception/UnsupportedExtensionException.php',
76
- 'Endroid\\QrCode\\Exception\\ValidationException' => $vendorDir . '/endroid/qr-code/src/Exception/ValidationException.php',
77
- 'Endroid\\QrCode\\Factory\\QrCodeFactory' => $vendorDir . '/endroid/qr-code/src/Factory/QrCodeFactory.php',
78
- 'Endroid\\QrCode\\LabelAlignment' => $vendorDir . '/endroid/qr-code/src/LabelAlignment.php',
79
- 'Endroid\\QrCode\\QrCode' => $vendorDir . '/endroid/qr-code/src/QrCode.php',
80
- 'Endroid\\QrCode\\QrCodeInterface' => $vendorDir . '/endroid/qr-code/src/QrCodeInterface.php',
81
- 'Endroid\\QrCode\\StaticWriterRegistry' => $vendorDir . '/endroid/qr-code/src/StaticWriterRegistry.php',
82
- 'Endroid\\QrCode\\Twig\\Extension\\QrCodeExtension' => $vendorDir . '/endroid/qr-code/src/Twig/Extension/QrCodeExtension.php',
83
- 'Endroid\\QrCode\\WriterRegistry' => $vendorDir . '/endroid/qr-code/src/WriterRegistry.php',
84
- 'Endroid\\QrCode\\WriterRegistryInterface' => $vendorDir . '/endroid/qr-code/src/WriterRegistryInterface.php',
85
- 'Endroid\\QrCode\\Writer\\AbstractBaconWriter' => $vendorDir . '/endroid/qr-code/src/Writer/AbstractBaconWriter.php',
86
- 'Endroid\\QrCode\\Writer\\AbstractWriter' => $vendorDir . '/endroid/qr-code/src/Writer/AbstractWriter.php',
87
- 'Endroid\\QrCode\\Writer\\BinaryWriter' => $vendorDir . '/endroid/qr-code/src/Writer/BinaryWriter.php',
88
- 'Endroid\\QrCode\\Writer\\DebugWriter' => $vendorDir . '/endroid/qr-code/src/Writer/DebugWriter.php',
89
- 'Endroid\\QrCode\\Writer\\EpsWriter' => $vendorDir . '/endroid/qr-code/src/Writer/EpsWriter.php',
90
- 'Endroid\\QrCode\\Writer\\PngWriter' => $vendorDir . '/endroid/qr-code/src/Writer/PngWriter.php',
91
- 'Endroid\\QrCode\\Writer\\SvgWriter' => $vendorDir . '/endroid/qr-code/src/Writer/SvgWriter.php',
92
- 'Endroid\\QrCode\\Writer\\WriterInterface' => $vendorDir . '/endroid/qr-code/src/Writer/WriterInterface.php',
93
  'FernleafSystems\\Utilities\\Data\\Adapter\\DynProperties' => $vendorDir . '/fernleafsystems/utilities/src/Data/Adapter/DynProperties.php',
94
  'FernleafSystems\\Utilities\\Data\\Adapter\\DynPropertiesClass' => $vendorDir . '/fernleafsystems/utilities/src/Data/Adapter/DynPropertiesClass.php',
95
  'FernleafSystems\\Utilities\\Data\\Adapter\\DynamicProperties' => $vendorDir . '/fernleafsystems/utilities/src/Data/Adapter/DynamicProperties.php',
@@ -109,12 +42,15 @@ return array(
109
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Base\\Update' => $vendorDir . '/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Update.php',
110
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Common\\AlignTableWithSchema' => $vendorDir . '/fernleafsystems/wordpress-plugin-core/src/Databases/Common/AlignTableWithSchema.php',
111
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Common\\BuildColumnFromDef' => $vendorDir . '/fernleafsystems/wordpress-plugin-core/src/Databases/Common/BuildColumnFromDef.php',
 
112
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Common\\HandlerConsumer' => $vendorDir . '/fernleafsystems/wordpress-plugin-core/src/Databases/Common/HandlerConsumer.php',
113
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Common\\Iterator' => $vendorDir . '/fernleafsystems/wordpress-plugin-core/src/Databases/Common/Iterator.php',
114
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Common\\RecordConsumer' => $vendorDir . '/fernleafsystems/wordpress-plugin-core/src/Databases/Common/RecordConsumer.php',
115
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Common\\SubQueryLoader' => $vendorDir . '/fernleafsystems/wordpress-plugin-core/src/Databases/Common/SubQueryLoader.php',
116
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Common\\TableSchema' => $vendorDir . '/fernleafsystems/wordpress-plugin-core/src/Databases/Common/TableSchema.php',
 
117
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Exceptions\\NoSlugProvidedException' => $vendorDir . '/fernleafsystems/wordpress-plugin-core/src/Databases/Exceptions/NoSlugProvidedException.php',
 
118
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\ChangeTrack\\Diff\\Base' => $baseDir . '/src/ChangeTrack/Diff/Base.php',
119
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\ChangeTrack\\Diff\\DiffComments' => $baseDir . '/src/ChangeTrack/Diff/DiffComments.php',
120
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\ChangeTrack\\Diff\\DiffMedia' => $baseDir . '/src/ChangeTrack/Diff/DiffMedia.php',
@@ -400,6 +336,7 @@ return array(
400
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\Build\\BuildHashesForAsset' => $baseDir . '/src/Modules/HackGuard/Lib/Snapshots/Build/BuildHashesForAsset.php',
401
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\Build\\BuildHashesFromApi' => $baseDir . '/src/Modules/HackGuard/Lib/Snapshots/Build/BuildHashesFromApi.php',
402
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\Build\\BuildHashesFromDir' => $baseDir . '/src/Modules/HackGuard/Lib/Snapshots/Build/BuildHashesFromDir.php',
 
403
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\FindAssetsToSnap' => $baseDir . '/src/Modules/HackGuard/Lib/Snapshots/FindAssetsToSnap.php',
404
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\Store' => $baseDir . '/src/Modules/HackGuard/Lib/Snapshots/Store.php',
405
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\StoreAction\\BaseAction' => $baseDir . '/src/Modules/HackGuard/Lib/Snapshots/StoreAction/BaseAction.php',
@@ -490,6 +427,7 @@ return array(
490
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\NotBot\\InsertNotBotJs' => $baseDir . '/src/Modules/IPs/Lib/Bots/NotBot/InsertNotBotJs.php',
491
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\NotBot\\NotBotHandler' => $baseDir . '/src/Modules/IPs/Lib/Bots/NotBot/NotBotHandler.php',
492
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\NotBot\\TestNotBotLoading' => $baseDir . '/src/Modules/IPs/Lib/Bots/NotBot/TestNotBotLoading.php',
 
493
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\IpAnalyse\\BuildDisplay' => $baseDir . '/src/Modules/IPs/Lib/IpAnalyse/BuildDisplay.php',
494
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\IpAnalyse\\FindAllPluginIps' => $baseDir . '/src/Modules/IPs/Lib/IpAnalyse/FindAllPluginIps.php',
495
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\OffenseTracker' => $baseDir . '/src/Modules/IPs/Lib/OffenseTracker.php',
@@ -884,7 +822,7 @@ return array(
884
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wpv\\ScanActionVO' => $baseDir . '/src/Scans/Wpv/ScanActionVO.php',
885
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wpv\\Utilities\\ItemActionHandler' => $baseDir . '/src/Scans/Wpv/Utilities/ItemActionHandler.php',
886
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wpv\\Utilities\\Repair' => $baseDir . '/src/Scans/Wpv/Utilities/Repair.php',
887
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wpv\\WpVulnDb\\WpVulnVO' => $baseDir . '/src/Scans/Wpv/WpVulnDb/WpVulnVO.php',
888
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\Common\\BaseApi' => $baseDir . '/src/ShieldNetApi/Common/BaseApi.php',
889
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\Common\\BaseShieldNetApi' => $baseDir . '/src/ShieldNetApi/Common/BaseShieldNetApi.php',
890
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\FileLocker\\DecryptFile' => $baseDir . '/src/ShieldNetApi/FileLocker/DecryptFile.php',
@@ -892,10 +830,14 @@ return array(
892
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\Handshake\\Verify' => $baseDir . '/src/ShieldNetApi/Handshake/Verify.php',
893
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\HandshakingNonce' => $baseDir . '/src/ShieldNetApi/HandshakingNonce.php',
894
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\Reputation\\BotScoringLogic' => $baseDir . '/src/ShieldNetApi/Reputation/BotScoringLogic.php',
 
 
895
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\ShieldNetApiController' => $baseDir . '/src/ShieldNetApi/ShieldNetApiController.php',
896
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\ShieldNetApiDataVO' => $baseDir . '/src/ShieldNetApi/ShieldNetApiDataVO.php',
897
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\SureSend\\SendEmail' => $baseDir . '/src/ShieldNetApi/SureSend/SendEmail.php',
898
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\Telemetry\\SendTelemetry' => $baseDir . '/src/ShieldNetApi/Telemetry/SendTelemetry.php',
 
 
899
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Build\\AdminNotes' => $baseDir . '/src/Tables/Build/AdminNotes.php',
900
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Build\\AuditTrail' => $baseDir . '/src/Tables/Build/AuditTrail.php',
901
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Build\\BaseBuild' => $baseDir . '/src/Tables/Build/BaseBuild.php',
@@ -954,6 +896,7 @@ return array(
954
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\Tool\\DbTableExport' => $baseDir . '/src/Utilities/Tool/DbTableExport.php',
955
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\Tool\\FormatBytes' => $baseDir . '/src/Utilities/Tool/FormatBytes.php',
956
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\Tool\\IpListSort' => $baseDir . '/src/Utilities/Tool/IpListSort.php',
 
957
  'FernleafSystems\\Wordpress\\Services\\Core\\AdminNotices' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/AdminNotices.php',
958
  'FernleafSystems\\Wordpress\\Services\\Core\\Comments' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/Comments.php',
959
  'FernleafSystems\\Wordpress\\Services\\Core\\CoreFileHashes' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/CoreFileHashes.php',
@@ -980,6 +923,9 @@ return array(
980
  'FernleafSystems\\Wordpress\\Services\\Core\\Upgrades\\UpgraderSkin' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/Upgrades/UpgraderSkin.php',
981
  'FernleafSystems\\Wordpress\\Services\\Core\\Upgrades\\UpgraderSkinLegacy' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/Upgrades/UpgraderSkinLegacy.php',
982
  'FernleafSystems\\Wordpress\\Services\\Core\\Users' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/Users.php',
 
 
 
983
  'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpBaseVo' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/VOs/WpBaseVo.php',
984
  'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpHttpResponseVo' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/VOs/WpHttpResponseVo.php',
985
  'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpPluginVo' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/VOs/WpPluginVo.php',
@@ -1016,6 +962,15 @@ return array(
1016
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\RequestVO' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/RequestVO.php',
1017
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\ApiBase' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/ApiBase.php',
1018
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\ApiPing' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/ApiPing.php',
 
 
 
 
 
 
 
 
 
1019
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\Hashes\\ApiInfo' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/ApiInfo.php',
1020
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\Hashes\\AssetHashesBase' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/AssetHashesBase.php',
1021
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\Hashes\\Base' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/Base.php',
@@ -1118,7 +1073,6 @@ return array(
1118
  'LZCompressor\\LZString' => $vendorDir . '/nullpunkt/lz-string-php/src/LZCompressor/LZString.php',
1119
  'LZCompressor\\LZUtil' => $vendorDir . '/nullpunkt/lz-string-php/src/LZCompressor/LZUtil.php',
1120
  'LZCompressor\\LZUtil16' => $vendorDir . '/nullpunkt/lz-string-php/src/LZCompressor/LZUtil16.php',
1121
- 'MyCLabs\\Enum\\Enum' => $vendorDir . '/myclabs/php-enum/src/Enum.php',
1122
  'Pimple\\Container' => $vendorDir . '/pimple/pimple/src/Pimple/Container.php',
1123
  'Pimple\\Exception\\ExpectedInvokableException' => $vendorDir . '/pimple/pimple/src/Pimple/Exception/ExpectedInvokableException.php',
1124
  'Pimple\\Exception\\FrozenServiceException' => $vendorDir . '/pimple/pimple/src/Pimple/Exception/FrozenServiceException.php',
@@ -1144,7 +1098,6 @@ return array(
1144
  'Psr\\Container\\ContainerExceptionInterface' => $vendorDir . '/psr/container/src/ContainerExceptionInterface.php',
1145
  'Psr\\Container\\ContainerInterface' => $vendorDir . '/psr/container/src/ContainerInterface.php',
1146
  'Psr\\Container\\NotFoundExceptionInterface' => $vendorDir . '/psr/container/src/NotFoundExceptionInterface.php',
1147
- 'QrReader' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/QrReader.php',
1148
  'Ramsey\\Uuid\\BinaryUtils' => $vendorDir . '/ramsey/uuid/src/BinaryUtils.php',
1149
  'Ramsey\\Uuid\\Builder\\DefaultUuidBuilder' => $vendorDir . '/ramsey/uuid/src/Builder/DefaultUuidBuilder.php',
1150
  'Ramsey\\Uuid\\Builder\\DegradedUuidBuilder' => $vendorDir . '/ramsey/uuid/src/Builder/DegradedUuidBuilder.php',
@@ -1200,36 +1153,6 @@ return array(
1200
  'ReCaptcha\\RequestMethod\\SocketPost' => $vendorDir . '/google/recaptcha/src/ReCaptcha/RequestMethod/SocketPost.php',
1201
  'ReCaptcha\\RequestParameters' => $vendorDir . '/google/recaptcha/src/ReCaptcha/RequestParameters.php',
1202
  'ReCaptcha\\Response' => $vendorDir . '/google/recaptcha/src/ReCaptcha/Response.php',
1203
- 'Symfony\\Component\\OptionsResolver\\Exception\\AccessException' => $vendorDir . '/symfony/options-resolver/Exception/AccessException.php',
1204
- 'Symfony\\Component\\OptionsResolver\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/options-resolver/Exception/ExceptionInterface.php',
1205
- 'Symfony\\Component\\OptionsResolver\\Exception\\InvalidArgumentException' => $vendorDir . '/symfony/options-resolver/Exception/InvalidArgumentException.php',
1206
- 'Symfony\\Component\\OptionsResolver\\Exception\\InvalidOptionsException' => $vendorDir . '/symfony/options-resolver/Exception/InvalidOptionsException.php',
1207
- 'Symfony\\Component\\OptionsResolver\\Exception\\MissingOptionsException' => $vendorDir . '/symfony/options-resolver/Exception/MissingOptionsException.php',
1208
- 'Symfony\\Component\\OptionsResolver\\Exception\\NoSuchOptionException' => $vendorDir . '/symfony/options-resolver/Exception/NoSuchOptionException.php',
1209
- 'Symfony\\Component\\OptionsResolver\\Exception\\OptionDefinitionException' => $vendorDir . '/symfony/options-resolver/Exception/OptionDefinitionException.php',
1210
- 'Symfony\\Component\\OptionsResolver\\Exception\\UndefinedOptionsException' => $vendorDir . '/symfony/options-resolver/Exception/UndefinedOptionsException.php',
1211
- 'Symfony\\Component\\OptionsResolver\\Options' => $vendorDir . '/symfony/options-resolver/Options.php',
1212
- 'Symfony\\Component\\OptionsResolver\\OptionsResolver' => $vendorDir . '/symfony/options-resolver/OptionsResolver.php',
1213
- 'Symfony\\Component\\OptionsResolver\\OptionsResolverInterface' => $vendorDir . '/symfony/options-resolver/OptionsResolverInterface.php',
1214
- 'Symfony\\Component\\PropertyAccess\\Exception\\AccessException' => $vendorDir . '/symfony/property-access/Exception/AccessException.php',
1215
- 'Symfony\\Component\\PropertyAccess\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/property-access/Exception/ExceptionInterface.php',
1216
- 'Symfony\\Component\\PropertyAccess\\Exception\\InvalidArgumentException' => $vendorDir . '/symfony/property-access/Exception/InvalidArgumentException.php',
1217
- 'Symfony\\Component\\PropertyAccess\\Exception\\InvalidPropertyPathException' => $vendorDir . '/symfony/property-access/Exception/InvalidPropertyPathException.php',
1218
- 'Symfony\\Component\\PropertyAccess\\Exception\\NoSuchIndexException' => $vendorDir . '/symfony/property-access/Exception/NoSuchIndexException.php',
1219
- 'Symfony\\Component\\PropertyAccess\\Exception\\NoSuchPropertyException' => $vendorDir . '/symfony/property-access/Exception/NoSuchPropertyException.php',
1220
- 'Symfony\\Component\\PropertyAccess\\Exception\\OutOfBoundsException' => $vendorDir . '/symfony/property-access/Exception/OutOfBoundsException.php',
1221
- 'Symfony\\Component\\PropertyAccess\\Exception\\RuntimeException' => $vendorDir . '/symfony/property-access/Exception/RuntimeException.php',
1222
- 'Symfony\\Component\\PropertyAccess\\Exception\\UnexpectedTypeException' => $vendorDir . '/symfony/property-access/Exception/UnexpectedTypeException.php',
1223
- 'Symfony\\Component\\PropertyAccess\\PropertyAccess' => $vendorDir . '/symfony/property-access/PropertyAccess.php',
1224
- 'Symfony\\Component\\PropertyAccess\\PropertyAccessor' => $vendorDir . '/symfony/property-access/PropertyAccessor.php',
1225
- 'Symfony\\Component\\PropertyAccess\\PropertyAccessorBuilder' => $vendorDir . '/symfony/property-access/PropertyAccessorBuilder.php',
1226
- 'Symfony\\Component\\PropertyAccess\\PropertyAccessorInterface' => $vendorDir . '/symfony/property-access/PropertyAccessorInterface.php',
1227
- 'Symfony\\Component\\PropertyAccess\\PropertyPath' => $vendorDir . '/symfony/property-access/PropertyPath.php',
1228
- 'Symfony\\Component\\PropertyAccess\\PropertyPathBuilder' => $vendorDir . '/symfony/property-access/PropertyPathBuilder.php',
1229
- 'Symfony\\Component\\PropertyAccess\\PropertyPathInterface' => $vendorDir . '/symfony/property-access/PropertyPathInterface.php',
1230
- 'Symfony\\Component\\PropertyAccess\\PropertyPathIterator' => $vendorDir . '/symfony/property-access/PropertyPathIterator.php',
1231
- 'Symfony\\Component\\PropertyAccess\\PropertyPathIteratorInterface' => $vendorDir . '/symfony/property-access/PropertyPathIteratorInterface.php',
1232
- 'Symfony\\Component\\PropertyAccess\\StringUtil' => $vendorDir . '/symfony/property-access/StringUtil.php',
1233
  'Symfony\\Component\\Translation\\Catalogue\\AbstractOperation' => $vendorDir . '/symfony/translation/Catalogue/AbstractOperation.php',
1234
  'Symfony\\Component\\Translation\\Catalogue\\MergeOperation' => $vendorDir . '/symfony/translation/Catalogue/MergeOperation.php',
1235
  'Symfony\\Component\\Translation\\Catalogue\\OperationInterface' => $vendorDir . '/symfony/translation/Catalogue/OperationInterface.php',
@@ -1699,64 +1622,6 @@ return array(
1699
  'ZxcvbnPhp\\Scorer' => $vendorDir . '/fernleafsystems/zxcvbn-php/src/Scorer.php',
1700
  'ZxcvbnPhp\\TimeEstimator' => $vendorDir . '/fernleafsystems/zxcvbn-php/src/TimeEstimator.php',
1701
  'ZxcvbnPhp\\Zxcvbn' => $vendorDir . '/fernleafsystems/zxcvbn-php/src/Zxcvbn.php',
1702
- 'Zxing\\Binarizer' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/Binarizer.php',
1703
- 'Zxing\\BinaryBitmap' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/BinaryBitmap.php',
1704
- 'Zxing\\ChecksumException' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/ChecksumException.php',
1705
- 'Zxing\\Common\\BitArray' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/common/BitArray.php',
1706
- 'Zxing\\Common\\BitMatrix' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/common/BitMatrix.php',
1707
- 'Zxing\\Common\\BitSource' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/common/BitSource.php',
1708
- 'Zxing\\Common\\CharacterSetECI' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/common/CharacterSetEci.php',
1709
- 'Zxing\\Common\\CharacterSetEci\\AbstractEnum\\AbstractEnum' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/common/AbstractEnum.php',
1710
- 'Zxing\\Common\\DecoderResult' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/common/DecoderResult.php',
1711
- 'Zxing\\Common\\DefaultGridSampler' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/common/DefaultGridSampler.php',
1712
- 'Zxing\\Common\\DetectorResult' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/common/DetectorResult.php',
1713
- 'Zxing\\Common\\Detector\\MathUtils' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/common/detector/MathUtils.php',
1714
- 'Zxing\\Common\\Detector\\MonochromeRectangleDetector' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/common/detector/MonochromeRectangleDetector.php',
1715
- 'Zxing\\Common\\GlobalHistogramBinarizer' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/common/GlobalHistogramBinarizer.php',
1716
- 'Zxing\\Common\\GridSampler' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/common/GridSampler.php',
1717
- 'Zxing\\Common\\HybridBinarizer' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/common/HybridBinarizer.php',
1718
- 'Zxing\\Common\\PerspectiveTransform' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/common/PerspectiveTransform.php',
1719
- 'Zxing\\Common\\Reedsolomon\\GenericGF' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/common/reedsolomon/GenericGF.php',
1720
- 'Zxing\\Common\\Reedsolomon\\GenericGFPoly' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/common/reedsolomon/GenericGFPoly.php',
1721
- 'Zxing\\Common\\Reedsolomon\\ReedSolomonDecoder' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/common/reedsolomon/ReedSolomonDecoder.php',
1722
- 'Zxing\\Common\\Reedsolomon\\ReedSolomonException' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/common/reedsolomon/ReedSolomonException.php',
1723
- 'Zxing\\FormatException' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/FormatException.php',
1724
- 'Zxing\\GDLuminanceSource' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/GDLuminanceSource.php',
1725
- 'Zxing\\IMagickLuminanceSource' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/IMagickLuminanceSource.php',
1726
- 'Zxing\\LuminanceSource' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/LuminanceSource.php',
1727
- 'Zxing\\NotFoundException' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/NotFoundException.php',
1728
- 'Zxing\\PlanarYUVLuminanceSource' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/PlanarYUVLuminanceSource.php',
1729
- 'Zxing\\Qrcode\\Decoder\\BitMatrixParser' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/BitMatrixParser.php',
1730
- 'Zxing\\Qrcode\\Decoder\\DataBlock' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/DataBlock.php',
1731
- 'Zxing\\Qrcode\\Decoder\\DataMask' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/DataMask.php',
1732
- 'Zxing\\Qrcode\\Decoder\\DataMask000' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/DataMask.php',
1733
- 'Zxing\\Qrcode\\Decoder\\DataMask001' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/DataMask.php',
1734
- 'Zxing\\Qrcode\\Decoder\\DataMask010' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/DataMask.php',
1735
- 'Zxing\\Qrcode\\Decoder\\DataMask011' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/DataMask.php',
1736
- 'Zxing\\Qrcode\\Decoder\\DataMask100' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/DataMask.php',
1737
- 'Zxing\\Qrcode\\Decoder\\DataMask101' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/DataMask.php',
1738
- 'Zxing\\Qrcode\\Decoder\\DataMask110' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/DataMask.php',
1739
- 'Zxing\\Qrcode\\Decoder\\DataMask111' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/DataMask.php',
1740
- 'Zxing\\Qrcode\\Decoder\\DecodedBitStreamParser' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/DecodedBitStreamParser.php',
1741
- 'Zxing\\Qrcode\\Decoder\\Decoder' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/Decoder.php',
1742
- 'Zxing\\Qrcode\\Decoder\\ECB' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/Version.php',
1743
- 'Zxing\\Qrcode\\Decoder\\ECBlocks' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/Version.php',
1744
- 'Zxing\\Qrcode\\Decoder\\ErrorCorrectionLevel' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/ErrorCorrectionLevel.php',
1745
- 'Zxing\\Qrcode\\Decoder\\FormatInformation' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/FormatInformation.php',
1746
- 'Zxing\\Qrcode\\Decoder\\Mode' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/Mode.php',
1747
- 'Zxing\\Qrcode\\Decoder\\Version' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/Version.php',
1748
- 'Zxing\\Qrcode\\Detector\\AlignmentPattern' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/qrcode/detector/AlignmentPattern.php',
1749
- 'Zxing\\Qrcode\\Detector\\AlignmentPatternFinder' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/qrcode/detector/AlignmentPatternFinder.php',
1750
- 'Zxing\\Qrcode\\Detector\\Detector' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/qrcode/detector/Detector.php',
1751
- 'Zxing\\Qrcode\\Detector\\FinderPattern' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/qrcode/detector/FinderPattern.php',
1752
- 'Zxing\\Qrcode\\Detector\\FinderPatternFinder' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/qrcode/detector/FinderPatternFinder.php',
1753
- 'Zxing\\Qrcode\\Detector\\FinderPatternInfo' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/qrcode/detector/FinderPatternInfo.php',
1754
- 'Zxing\\Qrcode\\QRCodeReader' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/qrcode/QRCodeReader.php',
1755
- 'Zxing\\RGBLuminanceSource' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/RGBLuminanceSource.php',
1756
- 'Zxing\\Reader' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/Reader.php',
1757
- 'Zxing\\ReaderException' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/ReaderException.php',
1758
- 'Zxing\\Result' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/Result.php',
1759
- 'Zxing\\ResultPoint' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/ResultPoint.php',
1760
  'u2flib_server\\Error' => $baseDir . '/custom/U2F/Yubico/U2F.php',
1761
  'u2flib_server\\RegisterRequest' => $baseDir . '/custom/U2F/Yubico/U2F.php',
1762
  'u2flib_server\\Registration' => $baseDir . '/custom/U2F/Yubico/U2F.php',
6
  $baseDir = dirname($vendorDir);
7
 
8
  return array(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  'Base32\\Base32' => $vendorDir . '/christian-riesen/base32/src/Base32.php',
10
  'Carbon\\Carbon' => $vendorDir . '/nesbot/carbon/src/Carbon/Carbon.php',
11
  'Carbon\\CarbonInterval' => $vendorDir . '/nesbot/carbon/src/Carbon/CarbonInterval.php',
23
  'Dolondro\\GoogleAuthenticator\\SecretFactory' => $vendorDir . '/dolondro/google-authenticator/src/SecretFactory.php',
24
  'Elliotchance\\Iterator\\AbstractPagedIterator' => $vendorDir . '/elliotchance/iterator/src/Elliotchance/Iterator/AbstractPagedIterator.php',
25
  'Elliotchance\\Iterator\\PagedIteratorTest' => $vendorDir . '/elliotchance/iterator/tests/Elliotchance/Iterator/PagedIteratorTest.php',
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  'FernleafSystems\\Utilities\\Data\\Adapter\\DynProperties' => $vendorDir . '/fernleafsystems/utilities/src/Data/Adapter/DynProperties.php',
27
  'FernleafSystems\\Utilities\\Data\\Adapter\\DynPropertiesClass' => $vendorDir . '/fernleafsystems/utilities/src/Data/Adapter/DynPropertiesClass.php',
28
  'FernleafSystems\\Utilities\\Data\\Adapter\\DynamicProperties' => $vendorDir . '/fernleafsystems/utilities/src/Data/Adapter/DynamicProperties.php',
42
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Base\\Update' => $vendorDir . '/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Update.php',
43
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Common\\AlignTableWithSchema' => $vendorDir . '/fernleafsystems/wordpress-plugin-core/src/Databases/Common/AlignTableWithSchema.php',
44
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Common\\BuildColumnFromDef' => $vendorDir . '/fernleafsystems/wordpress-plugin-core/src/Databases/Common/BuildColumnFromDef.php',
45
+ 'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Common\\CreateTable' => $vendorDir . '/fernleafsystems/wordpress-plugin-core/src/Databases/Common/CreateTable.php',
46
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Common\\HandlerConsumer' => $vendorDir . '/fernleafsystems/wordpress-plugin-core/src/Databases/Common/HandlerConsumer.php',
47
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Common\\Iterator' => $vendorDir . '/fernleafsystems/wordpress-plugin-core/src/Databases/Common/Iterator.php',
48
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Common\\RecordConsumer' => $vendorDir . '/fernleafsystems/wordpress-plugin-core/src/Databases/Common/RecordConsumer.php',
49
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Common\\SubQueryLoader' => $vendorDir . '/fernleafsystems/wordpress-plugin-core/src/Databases/Common/SubQueryLoader.php',
50
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Common\\TableSchema' => $vendorDir . '/fernleafsystems/wordpress-plugin-core/src/Databases/Common/TableSchema.php',
51
+ 'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Exceptions\\ColumnDoesNotExistException' => $vendorDir . '/fernleafsystems/wordpress-plugin-core/src/Databases/Exceptions/ColumnDoesNotExistException.php',
52
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Exceptions\\NoSlugProvidedException' => $vendorDir . '/fernleafsystems/wordpress-plugin-core/src/Databases/Exceptions/NoSlugProvidedException.php',
53
+ 'FernleafSystems\\Wordpress\\Plugin\\Core\\Utility\\User\\PluginMeta' => $vendorDir . '/fernleafsystems/wordpress-plugin-core/src/Utility/User/PluginMeta.php',
54
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\ChangeTrack\\Diff\\Base' => $baseDir . '/src/ChangeTrack/Diff/Base.php',
55
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\ChangeTrack\\Diff\\DiffComments' => $baseDir . '/src/ChangeTrack/Diff/DiffComments.php',
56
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\ChangeTrack\\Diff\\DiffMedia' => $baseDir . '/src/ChangeTrack/Diff/DiffMedia.php',
336
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\Build\\BuildHashesForAsset' => $baseDir . '/src/Modules/HackGuard/Lib/Snapshots/Build/BuildHashesForAsset.php',
337
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\Build\\BuildHashesFromApi' => $baseDir . '/src/Modules/HackGuard/Lib/Snapshots/Build/BuildHashesFromApi.php',
338
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\Build\\BuildHashesFromDir' => $baseDir . '/src/Modules/HackGuard/Lib/Snapshots/Build/BuildHashesFromDir.php',
339
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\CrowdSourced\\SubmitHashes' => $baseDir . '/src/Modules/HackGuard/Lib/Snapshots/CrowdSourced/SubmitHashes.php',
340
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\FindAssetsToSnap' => $baseDir . '/src/Modules/HackGuard/Lib/Snapshots/FindAssetsToSnap.php',
341
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\Store' => $baseDir . '/src/Modules/HackGuard/Lib/Snapshots/Store.php',
342
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\StoreAction\\BaseAction' => $baseDir . '/src/Modules/HackGuard/Lib/Snapshots/StoreAction/BaseAction.php',
427
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\NotBot\\InsertNotBotJs' => $baseDir . '/src/Modules/IPs/Lib/Bots/NotBot/InsertNotBotJs.php',
428
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\NotBot\\NotBotHandler' => $baseDir . '/src/Modules/IPs/Lib/Bots/NotBot/NotBotHandler.php',
429
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\NotBot\\TestNotBotLoading' => $baseDir . '/src/Modules/IPs/Lib/Bots/NotBot/TestNotBotLoading.php',
430
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\ShieldNET\\BuildData' => $baseDir . '/src/Modules/IPs/Lib/Bots/ShieldNET/BuildData.php',
431
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\IpAnalyse\\BuildDisplay' => $baseDir . '/src/Modules/IPs/Lib/IpAnalyse/BuildDisplay.php',
432
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\IpAnalyse\\FindAllPluginIps' => $baseDir . '/src/Modules/IPs/Lib/IpAnalyse/FindAllPluginIps.php',
433
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\OffenseTracker' => $baseDir . '/src/Modules/IPs/Lib/OffenseTracker.php',
822
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wpv\\ScanActionVO' => $baseDir . '/src/Scans/Wpv/ScanActionVO.php',
823
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wpv\\Utilities\\ItemActionHandler' => $baseDir . '/src/Scans/Wpv/Utilities/ItemActionHandler.php',
824
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wpv\\Utilities\\Repair' => $baseDir . '/src/Scans/Wpv/Utilities/Repair.php',
825
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wpv\\WpVulnDb\\VulnVO' => $baseDir . '/src/Scans/Wpv/WpVulnDb/VulnVO.php',
826
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\Common\\BaseApi' => $baseDir . '/src/ShieldNetApi/Common/BaseApi.php',
827
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\Common\\BaseShieldNetApi' => $baseDir . '/src/ShieldNetApi/Common/BaseShieldNetApi.php',
828
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\FileLocker\\DecryptFile' => $baseDir . '/src/ShieldNetApi/FileLocker/DecryptFile.php',
830
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\Handshake\\Verify' => $baseDir . '/src/ShieldNetApi/Handshake/Verify.php',
831
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\HandshakingNonce' => $baseDir . '/src/ShieldNetApi/HandshakingNonce.php',
832
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\Reputation\\BotScoringLogic' => $baseDir . '/src/ShieldNetApi/Reputation/BotScoringLogic.php',
833
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\Reputation\\GetIPReputation' => $baseDir . '/src/ShieldNetApi/Reputation/GetIPReputation.php',
834
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\Reputation\\SendIPReputation' => $baseDir . '/src/ShieldNetApi/Reputation/SendIPReputation.php',
835
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\ShieldNetApiController' => $baseDir . '/src/ShieldNetApi/ShieldNetApiController.php',
836
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\ShieldNetApiDataVO' => $baseDir . '/src/ShieldNetApi/ShieldNetApiDataVO.php',
837
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\SureSend\\SendEmail' => $baseDir . '/src/ShieldNetApi/SureSend/SendEmail.php',
838
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\Telemetry\\SendTelemetry' => $baseDir . '/src/ShieldNetApi/Telemetry/SendTelemetry.php',
839
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\Tools\\GenerateGoogleAuthQrCode' => $baseDir . '/src/ShieldNetApi/Tools/GenerateGoogleAuthQrCode.php',
840
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\WPHashes\\SolicitToken' => $baseDir . '/src/ShieldNetApi/WPHashes/SolicitToken.php',
841
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Build\\AdminNotes' => $baseDir . '/src/Tables/Build/AdminNotes.php',
842
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Build\\AuditTrail' => $baseDir . '/src/Tables/Build/AuditTrail.php',
843
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Build\\BaseBuild' => $baseDir . '/src/Tables/Build/BaseBuild.php',
896
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\Tool\\DbTableExport' => $baseDir . '/src/Utilities/Tool/DbTableExport.php',
897
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\Tool\\FormatBytes' => $baseDir . '/src/Utilities/Tool/FormatBytes.php',
898
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\Tool\\IpListSort' => $baseDir . '/src/Utilities/Tool/IpListSort.php',
899
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\Tool\\TmpFileStore' => $baseDir . '/src/Utilities/Tool/TmpFileStore.php',
900
  'FernleafSystems\\Wordpress\\Services\\Core\\AdminNotices' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/AdminNotices.php',
901
  'FernleafSystems\\Wordpress\\Services\\Core\\Comments' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/Comments.php',
902
  'FernleafSystems\\Wordpress\\Services\\Core\\CoreFileHashes' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/CoreFileHashes.php',
923
  'FernleafSystems\\Wordpress\\Services\\Core\\Upgrades\\UpgraderSkin' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/Upgrades/UpgraderSkin.php',
924
  'FernleafSystems\\Wordpress\\Services\\Core\\Upgrades\\UpgraderSkinLegacy' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/Upgrades/UpgraderSkinLegacy.php',
925
  'FernleafSystems\\Wordpress\\Services\\Core\\Users' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/Users.php',
926
+ 'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\Assets\\WpBaseVo' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/VOs/Assets/WpBaseVo.php',
927
+ 'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\Assets\\WpPluginVo' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/VOs/Assets/WpPluginVo.php',
928
+ 'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\Assets\\WpThemeVo' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/VOs/Assets/WpThemeVo.php',
929
  'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpBaseVo' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/VOs/WpBaseVo.php',
930
  'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpHttpResponseVo' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/VOs/WpHttpResponseVo.php',
931
  'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpPluginVo' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/VOs/WpPluginVo.php',
962
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\RequestVO' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/RequestVO.php',
963
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\ApiBase' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/ApiBase.php',
964
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\ApiPing' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/ApiPing.php',
965
+ 'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\CrowdSourcedHashes\\Base' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/CrowdSourcedHashes/Base.php',
966
+ 'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\CrowdSourcedHashes\\Query\\AssetHashesBase' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/CrowdSourcedHashes/Query/AssetHashesBase.php',
967
+ 'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\CrowdSourcedHashes\\Query\\Plugin' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/CrowdSourcedHashes/Query/Plugin.php',
968
+ 'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\CrowdSourcedHashes\\Query\\RequestVO' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/CrowdSourcedHashes/Query/RequestVO.php',
969
+ 'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\CrowdSourcedHashes\\Query\\Theme' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/CrowdSourcedHashes/Query/Theme.php',
970
+ 'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\CrowdSourcedHashes\\Submit\\BaseSubmit' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/CrowdSourcedHashes/Submit/BaseSubmit.php',
971
+ 'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\CrowdSourcedHashes\\Submit\\PreSubmit' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/CrowdSourcedHashes/Submit/PreSubmit.php',
972
+ 'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\CrowdSourcedHashes\\Submit\\RequestVO' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/CrowdSourcedHashes/Submit/RequestVO.php',
973
+ 'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\CrowdSourcedHashes\\Submit\\Submit' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/CrowdSourcedHashes/Submit/Submit.php',
974
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\Hashes\\ApiInfo' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/ApiInfo.php',
975
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\Hashes\\AssetHashesBase' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/AssetHashesBase.php',
976
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\Hashes\\Base' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/Base.php',
1073
  'LZCompressor\\LZString' => $vendorDir . '/nullpunkt/lz-string-php/src/LZCompressor/LZString.php',
1074
  'LZCompressor\\LZUtil' => $vendorDir . '/nullpunkt/lz-string-php/src/LZCompressor/LZUtil.php',
1075
  'LZCompressor\\LZUtil16' => $vendorDir . '/nullpunkt/lz-string-php/src/LZCompressor/LZUtil16.php',
 
1076
  'Pimple\\Container' => $vendorDir . '/pimple/pimple/src/Pimple/Container.php',
1077
  'Pimple\\Exception\\ExpectedInvokableException' => $vendorDir . '/pimple/pimple/src/Pimple/Exception/ExpectedInvokableException.php',
1078
  'Pimple\\Exception\\FrozenServiceException' => $vendorDir . '/pimple/pimple/src/Pimple/Exception/FrozenServiceException.php',
1098
  'Psr\\Container\\ContainerExceptionInterface' => $vendorDir . '/psr/container/src/ContainerExceptionInterface.php',
1099
  'Psr\\Container\\ContainerInterface' => $vendorDir . '/psr/container/src/ContainerInterface.php',
1100
  'Psr\\Container\\NotFoundExceptionInterface' => $vendorDir . '/psr/container/src/NotFoundExceptionInterface.php',
 
1101
  'Ramsey\\Uuid\\BinaryUtils' => $vendorDir . '/ramsey/uuid/src/BinaryUtils.php',
1102
  'Ramsey\\Uuid\\Builder\\DefaultUuidBuilder' => $vendorDir . '/ramsey/uuid/src/Builder/DefaultUuidBuilder.php',
1103
  'Ramsey\\Uuid\\Builder\\DegradedUuidBuilder' => $vendorDir . '/ramsey/uuid/src/Builder/DegradedUuidBuilder.php',
1153
  'ReCaptcha\\RequestMethod\\SocketPost' => $vendorDir . '/google/recaptcha/src/ReCaptcha/RequestMethod/SocketPost.php',
1154
  'ReCaptcha\\RequestParameters' => $vendorDir . '/google/recaptcha/src/ReCaptcha/RequestParameters.php',
1155
  'ReCaptcha\\Response' => $vendorDir . '/google/recaptcha/src/ReCaptcha/Response.php',
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1156
  'Symfony\\Component\\Translation\\Catalogue\\AbstractOperation' => $vendorDir . '/symfony/translation/Catalogue/AbstractOperation.php',
1157
  'Symfony\\Component\\Translation\\Catalogue\\MergeOperation' => $vendorDir . '/symfony/translation/Catalogue/MergeOperation.php',
1158
  'Symfony\\Component\\Translation\\Catalogue\\OperationInterface' => $vendorDir . '/symfony/translation/Catalogue/OperationInterface.php',
1622
  'ZxcvbnPhp\\Scorer' => $vendorDir . '/fernleafsystems/zxcvbn-php/src/Scorer.php',
1623
  'ZxcvbnPhp\\TimeEstimator' => $vendorDir . '/fernleafsystems/zxcvbn-php/src/TimeEstimator.php',
1624
  'ZxcvbnPhp\\Zxcvbn' => $vendorDir . '/fernleafsystems/zxcvbn-php/src/Zxcvbn.php',
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1625
  'u2flib_server\\Error' => $baseDir . '/custom/U2F/Yubico/U2F.php',
1626
  'u2flib_server\\RegisterRequest' => $baseDir . '/custom/U2F/Yubico/U2F.php',
1627
  'u2flib_server\\Registration' => $baseDir . '/custom/U2F/Yubico/U2F.php',
src/lib/vendor/composer/autoload_files.php CHANGED
@@ -8,7 +8,6 @@ $baseDir = dirname($vendorDir);
8
  return array(
9
  '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
10
  '320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php',
11
- '626dcc41390ebdaa619faa02d99943b0' => $vendorDir . '/khanamiryan/qrcode-detector-decoder/lib/common/customFunctions.php',
12
  'e39a8b23c42d4e1452234d762b03835a' => $vendorDir . '/ramsey/uuid/src/functions.php',
13
  'def43f6c87e4f8dfd0c9e1b1bab14fe8' => $vendorDir . '/symfony/polyfill-iconv/bootstrap.php',
14
  'b14ca0bb4d408c293d6ea9b68f1b4abe' => $baseDir . '/functions/functions.php',
8
  return array(
9
  '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
10
  '320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php',
 
11
  'e39a8b23c42d4e1452234d762b03835a' => $vendorDir . '/ramsey/uuid/src/functions.php',
12
  'def43f6c87e4f8dfd0c9e1b1bab14fe8' => $vendorDir . '/symfony/polyfill-iconv/bootstrap.php',
13
  'b14ca0bb4d408c293d6ea9b68f1b4abe' => $baseDir . '/functions/functions.php',
src/lib/vendor/composer/autoload_namespaces.php CHANGED
@@ -9,6 +9,5 @@ return array(
9
  'UpdateHelper\\' => array($vendorDir . '/kylekatarnls/update-helper/src'),
10
  'Twig_' => array($vendorDir . '/twig/twig/lib'),
11
  'Pimple' => array($vendorDir . '/pimple/pimple/src'),
12
- 'BaconQrCode' => array($vendorDir . '/bacon/bacon-qr-code/src'),
13
  '' => array($vendorDir . '/elliotchance/iterator/tests', $vendorDir . '/elliotchance/iterator/src'),
14
  );
9
  'UpdateHelper\\' => array($vendorDir . '/kylekatarnls/update-helper/src'),
10
  'Twig_' => array($vendorDir . '/twig/twig/lib'),
11
  'Pimple' => array($vendorDir . '/pimple/pimple/src'),
 
12
  '' => array($vendorDir . '/elliotchance/iterator/tests', $vendorDir . '/elliotchance/iterator/src'),
13
  );
src/lib/vendor/composer/autoload_psr4.php CHANGED
@@ -13,20 +13,16 @@ return array(
13
  'Symfony\\Polyfill\\Ctype\\' => array($vendorDir . '/symfony/polyfill-ctype'),
14
  'Symfony\\Component\\Yaml\\' => array($vendorDir . '/symfony/yaml'),
15
  'Symfony\\Component\\Translation\\' => array($vendorDir . '/symfony/translation'),
16
- 'Symfony\\Component\\PropertyAccess\\' => array($vendorDir . '/symfony/property-access'),
17
- 'Symfony\\Component\\OptionsResolver\\' => array($vendorDir . '/symfony/options-resolver'),
18
  'ReCaptcha\\' => array($vendorDir . '/google/recaptcha/src/ReCaptcha'),
19
  'Ramsey\\Uuid\\' => array($vendorDir . '/ramsey/uuid/src'),
20
  'Psr\\Container\\' => array($vendorDir . '/psr/container/src'),
21
  'Psr\\Cache\\' => array($vendorDir . '/psr/cache/src'),
22
- 'MyCLabs\\Enum\\' => array($vendorDir . '/myclabs/php-enum/src'),
23
  'LZCompressor\\' => array($vendorDir . '/nullpunkt/lz-string-php/src/LZCompressor'),
24
  'Html2Text\\' => array($vendorDir . '/soundasleep/html2text/src'),
25
  'FernleafSystems\\Wordpress\\Services\\' => array($vendorDir . '/fernleafsystems/wordpress-services/src'),
26
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\' => array($baseDir . '/src'),
27
  'FernleafSystems\\Wordpress\\Plugin\\Core\\' => array($vendorDir . '/fernleafsystems/wordpress-plugin-core/src'),
28
  'FernleafSystems\\Utilities\\' => array($vendorDir . '/fernleafsystems/utilities/src'),
29
- 'Endroid\\QrCode\\' => array($vendorDir . '/endroid/qr-code/src'),
30
  'Dolondro\\GoogleAuthenticator\\' => array($vendorDir . '/dolondro/google-authenticator/src'),
31
  'Base32\\' => array($vendorDir . '/christian-riesen/base32/src'),
32
  '' => array($vendorDir . '/nesbot/carbon/src'),
13
  'Symfony\\Polyfill\\Ctype\\' => array($vendorDir . '/symfony/polyfill-ctype'),
14
  'Symfony\\Component\\Yaml\\' => array($vendorDir . '/symfony/yaml'),
15
  'Symfony\\Component\\Translation\\' => array($vendorDir . '/symfony/translation'),
 
 
16
  'ReCaptcha\\' => array($vendorDir . '/google/recaptcha/src/ReCaptcha'),
17
  'Ramsey\\Uuid\\' => array($vendorDir . '/ramsey/uuid/src'),
18
  'Psr\\Container\\' => array($vendorDir . '/psr/container/src'),
19
  'Psr\\Cache\\' => array($vendorDir . '/psr/cache/src'),
 
20
  'LZCompressor\\' => array($vendorDir . '/nullpunkt/lz-string-php/src/LZCompressor'),
21
  'Html2Text\\' => array($vendorDir . '/soundasleep/html2text/src'),
22
  'FernleafSystems\\Wordpress\\Services\\' => array($vendorDir . '/fernleafsystems/wordpress-services/src'),
23
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\' => array($baseDir . '/src'),
24
  'FernleafSystems\\Wordpress\\Plugin\\Core\\' => array($vendorDir . '/fernleafsystems/wordpress-plugin-core/src'),
25
  'FernleafSystems\\Utilities\\' => array($vendorDir . '/fernleafsystems/utilities/src'),
 
26
  'Dolondro\\GoogleAuthenticator\\' => array($vendorDir . '/dolondro/google-authenticator/src'),
27
  'Base32\\' => array($vendorDir . '/christian-riesen/base32/src'),
28
  '' => array($vendorDir . '/nesbot/carbon/src'),
src/lib/vendor/composer/autoload_static.php CHANGED
@@ -9,7 +9,6 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
9
  public static $files = array (
10
  '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
11
  '320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php',
12
- '626dcc41390ebdaa619faa02d99943b0' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/common/customFunctions.php',
13
  'e39a8b23c42d4e1452234d762b03835a' => __DIR__ . '/..' . '/ramsey/uuid/src/functions.php',
14
  'def43f6c87e4f8dfd0c9e1b1bab14fe8' => __DIR__ . '/..' . '/symfony/polyfill-iconv/bootstrap.php',
15
  'b14ca0bb4d408c293d6ea9b68f1b4abe' => __DIR__ . '/../..' . '/functions/functions.php',
@@ -31,8 +30,6 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
31
  'Symfony\\Polyfill\\Ctype\\' => 23,
32
  'Symfony\\Component\\Yaml\\' => 23,
33
  'Symfony\\Component\\Translation\\' => 30,
34
- 'Symfony\\Component\\PropertyAccess\\' => 33,
35
- 'Symfony\\Component\\OptionsResolver\\' => 34,
36
  ),
37
  'R' =>
38
  array (
@@ -44,10 +41,6 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
44
  'Psr\\Container\\' => 14,
45
  'Psr\\Cache\\' => 10,
46
  ),
47
- 'M' =>
48
- array (
49
- 'MyCLabs\\Enum\\' => 13,
50
- ),
51
  'L' =>
52
  array (
53
  'LZCompressor\\' => 13,
@@ -63,10 +56,6 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
63
  'FernleafSystems\\Wordpress\\Plugin\\Core\\' => 38,
64
  'FernleafSystems\\Utilities\\' => 26,
65
  ),
66
- 'E' =>
67
- array (
68
- 'Endroid\\QrCode\\' => 15,
69
- ),
70
  'D' =>
71
  array (
72
  'Dolondro\\GoogleAuthenticator\\' => 29,
@@ -106,14 +95,6 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
106
  array (
107
  0 => __DIR__ . '/..' . '/symfony/translation',
108
  ),
109
- 'Symfony\\Component\\PropertyAccess\\' =>
110
- array (
111
- 0 => __DIR__ . '/..' . '/symfony/property-access',
112
- ),
113
- 'Symfony\\Component\\OptionsResolver\\' =>
114
- array (
115
- 0 => __DIR__ . '/..' . '/symfony/options-resolver',
116
- ),
117
  'ReCaptcha\\' =>
118
  array (
119
  0 => __DIR__ . '/..' . '/google/recaptcha/src/ReCaptcha',
@@ -130,10 +111,6 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
130
  array (
131
  0 => __DIR__ . '/..' . '/psr/cache/src',
132
  ),
133
- 'MyCLabs\\Enum\\' =>
134
- array (
135
- 0 => __DIR__ . '/..' . '/myclabs/php-enum/src',
136
- ),
137
  'LZCompressor\\' =>
138
  array (
139
  0 => __DIR__ . '/..' . '/nullpunkt/lz-string-php/src/LZCompressor',
@@ -158,10 +135,6 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
158
  array (
159
  0 => __DIR__ . '/..' . '/fernleafsystems/utilities/src',
160
  ),
161
- 'Endroid\\QrCode\\' =>
162
- array (
163
- 0 => __DIR__ . '/..' . '/endroid/qr-code/src',
164
- ),
165
  'Dolondro\\GoogleAuthenticator\\' =>
166
  array (
167
  0 => __DIR__ . '/..' . '/dolondro/google-authenticator/src',
@@ -198,13 +171,6 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
198
  0 => __DIR__ . '/..' . '/pimple/pimple/src',
199
  ),
200
  ),
201
- 'B' =>
202
- array (
203
- 'BaconQrCode' =>
204
- array (
205
- 0 => __DIR__ . '/..' . '/bacon/bacon-qr-code/src',
206
- ),
207
- ),
208
  );
209
 
210
  public static $fallbackDirsPsr0 = array (
@@ -213,45 +179,6 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
213
  );
214
 
215
  public static $classMap = array (
216
- 'BaconQrCode\\Common\\AbstractEnum' => __DIR__ . '/..' . '/bacon/bacon-qr-code/src/BaconQrCode/Common/AbstractEnum.php',
217
- 'BaconQrCode\\Common\\BitArray' => __DIR__ . '/..' . '/bacon/bacon-qr-code/src/BaconQrCode/Common/BitArray.php',
218
- 'BaconQrCode\\Common\\BitMatrix' => __DIR__ . '/..' . '/bacon/bacon-qr-code/src/BaconQrCode/Common/BitMatrix.php',
219
- 'BaconQrCode\\Common\\BitUtils' => __DIR__ . '/..' . '/bacon/bacon-qr-code/src/BaconQrCode/Common/BitUtils.php',
220
- 'BaconQrCode\\Common\\CharacterSetEci' => __DIR__ . '/..' . '/bacon/bacon-qr-code/src/BaconQrCode/Common/CharacterSetEci.php',
221
- 'BaconQrCode\\Common\\EcBlock' => __DIR__ . '/..' . '/bacon/bacon-qr-code/src/BaconQrCode/Common/EcBlock.php',
222
- 'BaconQrCode\\Common\\EcBlocks' => __DIR__ . '/..' . '/bacon/bacon-qr-code/src/BaconQrCode/Common/EcBlocks.php',
223
- 'BaconQrCode\\Common\\ErrorCorrectionLevel' => __DIR__ . '/..' . '/bacon/bacon-qr-code/src/BaconQrCode/Common/ErrorCorrectionLevel.php',
224
- 'BaconQrCode\\Common\\FormatInformation' => __DIR__ . '/..' . '/bacon/bacon-qr-code/src/BaconQrCode/Common/FormatInformation.php',
225
- 'BaconQrCode\\Common\\Mode' => __DIR__ . '/..' . '/bacon/bacon-qr-code/src/BaconQrCode/Common/Mode.php',
226
- 'BaconQrCode\\Common\\ReedSolomonCodec' => __DIR__ . '/..' . '/bacon/bacon-qr-code/src/BaconQrCode/Common/ReedSolomonCodec.php',
227
- 'BaconQrCode\\Common\\Version' => __DIR__ . '/..' . '/bacon/bacon-qr-code/src/BaconQrCode/Common/Version.php',
228
- 'BaconQrCode\\Encoder\\BlockPair' => __DIR__ . '/..' . '/bacon/bacon-qr-code/src/BaconQrCode/Encoder/BlockPair.php',
229
- 'BaconQrCode\\Encoder\\ByteMatrix' => __DIR__ . '/..' . '/bacon/bacon-qr-code/src/BaconQrCode/Encoder/ByteMatrix.php',
230
- 'BaconQrCode\\Encoder\\Encoder' => __DIR__ . '/..' . '/bacon/bacon-qr-code/src/BaconQrCode/Encoder/Encoder.php',
231
- 'BaconQrCode\\Encoder\\MaskUtil' => __DIR__ . '/..' . '/bacon/bacon-qr-code/src/BaconQrCode/Encoder/MaskUtil.php',
232
- 'BaconQrCode\\Encoder\\MatrixUtil' => __DIR__ . '/..' . '/bacon/bacon-qr-code/src/BaconQrCode/Encoder/MatrixUtil.php',
233
- 'BaconQrCode\\Encoder\\QrCode' => __DIR__ . '/..' . '/bacon/bacon-qr-code/src/BaconQrCode/Encoder/QrCode.php',
234
- 'BaconQrCode\\Exception\\ExceptionInterface' => __DIR__ . '/..' . '/bacon/bacon-qr-code/src/BaconQrCode/Exception/ExceptionInterface.php',
235
- 'BaconQrCode\\Exception\\InvalidArgumentException' => __DIR__ . '/..' . '/bacon/bacon-qr-code/src/BaconQrCode/Exception/InvalidArgumentException.php',
236
- 'BaconQrCode\\Exception\\OutOfBoundsException' => __DIR__ . '/..' . '/bacon/bacon-qr-code/src/BaconQrCode/Exception/OutOfBoundsException.php',
237
- 'BaconQrCode\\Exception\\RuntimeException' => __DIR__ . '/..' . '/bacon/bacon-qr-code/src/BaconQrCode/Exception/RuntimeException.php',
238
- 'BaconQrCode\\Exception\\UnexpectedValueException' => __DIR__ . '/..' . '/bacon/bacon-qr-code/src/BaconQrCode/Exception/UnexpectedValueException.php',
239
- 'BaconQrCode\\Exception\\WriterException' => __DIR__ . '/..' . '/bacon/bacon-qr-code/src/BaconQrCode/Exception/WriterException.php',
240
- 'BaconQrCode\\Renderer\\Color\\Cmyk' => __DIR__ . '/..' . '/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Color/Cmyk.php',
241
- 'BaconQrCode\\Renderer\\Color\\ColorInterface' => __DIR__ . '/..' . '/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Color/ColorInterface.php',
242
- 'BaconQrCode\\Renderer\\Color\\Gray' => __DIR__ . '/..' . '/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Color/Gray.php',
243
- 'BaconQrCode\\Renderer\\Color\\Rgb' => __DIR__ . '/..' . '/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Color/Rgb.php',
244
- 'BaconQrCode\\Renderer\\Image\\AbstractRenderer' => __DIR__ . '/..' . '/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Image/AbstractRenderer.php',
245
- 'BaconQrCode\\Renderer\\Image\\Decorator\\DecoratorInterface' => __DIR__ . '/..' . '/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Image/Decorator/DecoratorInterface.php',
246
- 'BaconQrCode\\Renderer\\Image\\Decorator\\FinderPattern' => __DIR__ . '/..' . '/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Image/Decorator/FinderPattern.php',
247
- 'BaconQrCode\\Renderer\\Image\\Eps' => __DIR__ . '/..' . '/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Image/Eps.php',
248
- 'BaconQrCode\\Renderer\\Image\\Png' => __DIR__ . '/..' . '/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Image/Png.php',
249
- 'BaconQrCode\\Renderer\\Image\\RendererInterface' => __DIR__ . '/..' . '/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Image/RendererInterface.php',
250
- 'BaconQrCode\\Renderer\\Image\\Svg' => __DIR__ . '/..' . '/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Image/Svg.php',
251
- 'BaconQrCode\\Renderer\\RendererInterface' => __DIR__ . '/..' . '/bacon/bacon-qr-code/src/BaconQrCode/Renderer/RendererInterface.php',
252
- 'BaconQrCode\\Renderer\\Text\\Html' => __DIR__ . '/..' . '/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Text/Html.php',
253
- 'BaconQrCode\\Renderer\\Text\\Plain' => __DIR__ . '/..' . '/bacon/bacon-qr-code/src/BaconQrCode/Renderer/Text/Plain.php',
254
- 'BaconQrCode\\Writer' => __DIR__ . '/..' . '/bacon/bacon-qr-code/src/BaconQrCode/Writer.php',
255
  'Base32\\Base32' => __DIR__ . '/..' . '/christian-riesen/base32/src/Base32.php',
256
  'Carbon\\Carbon' => __DIR__ . '/..' . '/nesbot/carbon/src/Carbon/Carbon.php',
257
  'Carbon\\CarbonInterval' => __DIR__ . '/..' . '/nesbot/carbon/src/Carbon/CarbonInterval.php',
@@ -269,34 +196,6 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
269
  'Dolondro\\GoogleAuthenticator\\SecretFactory' => __DIR__ . '/..' . '/dolondro/google-authenticator/src/SecretFactory.php',
270
  'Elliotchance\\Iterator\\AbstractPagedIterator' => __DIR__ . '/..' . '/elliotchance/iterator/src/Elliotchance/Iterator/AbstractPagedIterator.php',
271
  'Elliotchance\\Iterator\\PagedIteratorTest' => __DIR__ . '/..' . '/elliotchance/iterator/tests/Elliotchance/Iterator/PagedIteratorTest.php',
272
- 'Endroid\\QrCode\\Bundle\\QrCodeBundle\\Controller\\QrCodeController' => __DIR__ . '/..' . '/endroid/qr-code/src/Bundle/QrCodeBundle/Controller/QrCodeController.php',
273
- 'Endroid\\QrCode\\Bundle\\QrCodeBundle\\DependencyInjection\\Compiler\\WriterRegistryCompilerPass' => __DIR__ . '/..' . '/endroid/qr-code/src/Bundle/QrCodeBundle/DependencyInjection/Compiler/WriterRegistryCompilerPass.php',
274
- 'Endroid\\QrCode\\Bundle\\QrCodeBundle\\DependencyInjection\\Configuration' => __DIR__ . '/..' . '/endroid/qr-code/src/Bundle/QrCodeBundle/DependencyInjection/Configuration.php',
275
- 'Endroid\\QrCode\\Bundle\\QrCodeBundle\\DependencyInjection\\EndroidQrCodeExtension' => __DIR__ . '/..' . '/endroid/qr-code/src/Bundle/QrCodeBundle/DependencyInjection/EndroidQrCodeExtension.php',
276
- 'Endroid\\QrCode\\Bundle\\QrCodeBundle\\EndroidQrCodeBundle' => __DIR__ . '/..' . '/endroid/qr-code/src/Bundle/QrCodeBundle/EndroidQrCodeBundle.php',
277
- 'Endroid\\QrCode\\ErrorCorrectionLevel' => __DIR__ . '/..' . '/endroid/qr-code/src/ErrorCorrectionLevel.php',
278
- 'Endroid\\QrCode\\Exception\\InvalidPathException' => __DIR__ . '/..' . '/endroid/qr-code/src/Exception/InvalidPathException.php',
279
- 'Endroid\\QrCode\\Exception\\InvalidWriterException' => __DIR__ . '/..' . '/endroid/qr-code/src/Exception/InvalidWriterException.php',
280
- 'Endroid\\QrCode\\Exception\\MissingFunctionException' => __DIR__ . '/..' . '/endroid/qr-code/src/Exception/MissingFunctionException.php',
281
- 'Endroid\\QrCode\\Exception\\QrCodeException' => __DIR__ . '/..' . '/endroid/qr-code/src/Exception/QrCodeException.php',
282
- 'Endroid\\QrCode\\Exception\\UnsupportedExtensionException' => __DIR__ . '/..' . '/endroid/qr-code/src/Exception/UnsupportedExtensionException.php',
283
- 'Endroid\\QrCode\\Exception\\ValidationException' => __DIR__ . '/..' . '/endroid/qr-code/src/Exception/ValidationException.php',
284
- 'Endroid\\QrCode\\Factory\\QrCodeFactory' => __DIR__ . '/..' . '/endroid/qr-code/src/Factory/QrCodeFactory.php',
285
- 'Endroid\\QrCode\\LabelAlignment' => __DIR__ . '/..' . '/endroid/qr-code/src/LabelAlignment.php',
286
- 'Endroid\\QrCode\\QrCode' => __DIR__ . '/..' . '/endroid/qr-code/src/QrCode.php',
287
- 'Endroid\\QrCode\\QrCodeInterface' => __DIR__ . '/..' . '/endroid/qr-code/src/QrCodeInterface.php',
288
- 'Endroid\\QrCode\\StaticWriterRegistry' => __DIR__ . '/..' . '/endroid/qr-code/src/StaticWriterRegistry.php',
289
- 'Endroid\\QrCode\\Twig\\Extension\\QrCodeExtension' => __DIR__ . '/..' . '/endroid/qr-code/src/Twig/Extension/QrCodeExtension.php',
290
- 'Endroid\\QrCode\\WriterRegistry' => __DIR__ . '/..' . '/endroid/qr-code/src/WriterRegistry.php',
291
- 'Endroid\\QrCode\\WriterRegistryInterface' => __DIR__ . '/..' . '/endroid/qr-code/src/WriterRegistryInterface.php',
292
- 'Endroid\\QrCode\\Writer\\AbstractBaconWriter' => __DIR__ . '/..' . '/endroid/qr-code/src/Writer/AbstractBaconWriter.php',
293
- 'Endroid\\QrCode\\Writer\\AbstractWriter' => __DIR__ . '/..' . '/endroid/qr-code/src/Writer/AbstractWriter.php',
294
- 'Endroid\\QrCode\\Writer\\BinaryWriter' => __DIR__ . '/..' . '/endroid/qr-code/src/Writer/BinaryWriter.php',
295
- 'Endroid\\QrCode\\Writer\\DebugWriter' => __DIR__ . '/..' . '/endroid/qr-code/src/Writer/DebugWriter.php',
296
- 'Endroid\\QrCode\\Writer\\EpsWriter' => __DIR__ . '/..' . '/endroid/qr-code/src/Writer/EpsWriter.php',
297
- 'Endroid\\QrCode\\Writer\\PngWriter' => __DIR__ . '/..' . '/endroid/qr-code/src/Writer/PngWriter.php',
298
- 'Endroid\\QrCode\\Writer\\SvgWriter' => __DIR__ . '/..' . '/endroid/qr-code/src/Writer/SvgWriter.php',
299
- 'Endroid\\QrCode\\Writer\\WriterInterface' => __DIR__ . '/..' . '/endroid/qr-code/src/Writer/WriterInterface.php',
300
  'FernleafSystems\\Utilities\\Data\\Adapter\\DynProperties' => __DIR__ . '/..' . '/fernleafsystems/utilities/src/Data/Adapter/DynProperties.php',
301
  'FernleafSystems\\Utilities\\Data\\Adapter\\DynPropertiesClass' => __DIR__ . '/..' . '/fernleafsystems/utilities/src/Data/Adapter/DynPropertiesClass.php',
302
  'FernleafSystems\\Utilities\\Data\\Adapter\\DynamicProperties' => __DIR__ . '/..' . '/fernleafsystems/utilities/src/Data/Adapter/DynamicProperties.php',
@@ -316,12 +215,15 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
316
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Base\\Update' => __DIR__ . '/..' . '/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Update.php',
317
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Common\\AlignTableWithSchema' => __DIR__ . '/..' . '/fernleafsystems/wordpress-plugin-core/src/Databases/Common/AlignTableWithSchema.php',
318
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Common\\BuildColumnFromDef' => __DIR__ . '/..' . '/fernleafsystems/wordpress-plugin-core/src/Databases/Common/BuildColumnFromDef.php',
 
319
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Common\\HandlerConsumer' => __DIR__ . '/..' . '/fernleafsystems/wordpress-plugin-core/src/Databases/Common/HandlerConsumer.php',
320
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Common\\Iterator' => __DIR__ . '/..' . '/fernleafsystems/wordpress-plugin-core/src/Databases/Common/Iterator.php',
321
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Common\\RecordConsumer' => __DIR__ . '/..' . '/fernleafsystems/wordpress-plugin-core/src/Databases/Common/RecordConsumer.php',
322
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Common\\SubQueryLoader' => __DIR__ . '/..' . '/fernleafsystems/wordpress-plugin-core/src/Databases/Common/SubQueryLoader.php',
323
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Common\\TableSchema' => __DIR__ . '/..' . '/fernleafsystems/wordpress-plugin-core/src/Databases/Common/TableSchema.php',
 
324
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Exceptions\\NoSlugProvidedException' => __DIR__ . '/..' . '/fernleafsystems/wordpress-plugin-core/src/Databases/Exceptions/NoSlugProvidedException.php',
 
325
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\ChangeTrack\\Diff\\Base' => __DIR__ . '/../..' . '/src/ChangeTrack/Diff/Base.php',
326
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\ChangeTrack\\Diff\\DiffComments' => __DIR__ . '/../..' . '/src/ChangeTrack/Diff/DiffComments.php',
327
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\ChangeTrack\\Diff\\DiffMedia' => __DIR__ . '/../..' . '/src/ChangeTrack/Diff/DiffMedia.php',
@@ -607,6 +509,7 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
607
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\Build\\BuildHashesForAsset' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Lib/Snapshots/Build/BuildHashesForAsset.php',
608
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\Build\\BuildHashesFromApi' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Lib/Snapshots/Build/BuildHashesFromApi.php',
609
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\Build\\BuildHashesFromDir' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Lib/Snapshots/Build/BuildHashesFromDir.php',
 
610
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\FindAssetsToSnap' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Lib/Snapshots/FindAssetsToSnap.php',
611
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\Store' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Lib/Snapshots/Store.php',
612
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\StoreAction\\BaseAction' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Lib/Snapshots/StoreAction/BaseAction.php',
@@ -697,6 +600,7 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
697
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\NotBot\\InsertNotBotJs' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/Bots/NotBot/InsertNotBotJs.php',
698
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\NotBot\\NotBotHandler' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/Bots/NotBot/NotBotHandler.php',
699
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\NotBot\\TestNotBotLoading' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/Bots/NotBot/TestNotBotLoading.php',
 
700
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\IpAnalyse\\BuildDisplay' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/IpAnalyse/BuildDisplay.php',
701
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\IpAnalyse\\FindAllPluginIps' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/IpAnalyse/FindAllPluginIps.php',
702
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\OffenseTracker' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/OffenseTracker.php',
@@ -1091,7 +995,7 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
1091
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wpv\\ScanActionVO' => __DIR__ . '/../..' . '/src/Scans/Wpv/ScanActionVO.php',
1092
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wpv\\Utilities\\ItemActionHandler' => __DIR__ . '/../..' . '/src/Scans/Wpv/Utilities/ItemActionHandler.php',
1093
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wpv\\Utilities\\Repair' => __DIR__ . '/../..' . '/src/Scans/Wpv/Utilities/Repair.php',
1094
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wpv\\WpVulnDb\\WpVulnVO' => __DIR__ . '/../..' . '/src/Scans/Wpv/WpVulnDb/WpVulnVO.php',
1095
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\Common\\BaseApi' => __DIR__ . '/../..' . '/src/ShieldNetApi/Common/BaseApi.php',
1096
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\Common\\BaseShieldNetApi' => __DIR__ . '/../..' . '/src/ShieldNetApi/Common/BaseShieldNetApi.php',
1097
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\FileLocker\\DecryptFile' => __DIR__ . '/../..' . '/src/ShieldNetApi/FileLocker/DecryptFile.php',
@@ -1099,10 +1003,14 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
1099
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\Handshake\\Verify' => __DIR__ . '/../..' . '/src/ShieldNetApi/Handshake/Verify.php',
1100
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\HandshakingNonce' => __DIR__ . '/../..' . '/src/ShieldNetApi/HandshakingNonce.php',
1101
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\Reputation\\BotScoringLogic' => __DIR__ . '/../..' . '/src/ShieldNetApi/Reputation/BotScoringLogic.php',
 
 
1102
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\ShieldNetApiController' => __DIR__ . '/../..' . '/src/ShieldNetApi/ShieldNetApiController.php',
1103
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\ShieldNetApiDataVO' => __DIR__ . '/../..' . '/src/ShieldNetApi/ShieldNetApiDataVO.php',
1104
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\SureSend\\SendEmail' => __DIR__ . '/../..' . '/src/ShieldNetApi/SureSend/SendEmail.php',
1105
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\Telemetry\\SendTelemetry' => __DIR__ . '/../..' . '/src/ShieldNetApi/Telemetry/SendTelemetry.php',
 
 
1106
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Build\\AdminNotes' => __DIR__ . '/../..' . '/src/Tables/Build/AdminNotes.php',
1107
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Build\\AuditTrail' => __DIR__ . '/../..' . '/src/Tables/Build/AuditTrail.php',
1108
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Build\\BaseBuild' => __DIR__ . '/../..' . '/src/Tables/Build/BaseBuild.php',
@@ -1161,6 +1069,7 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
1161
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\Tool\\DbTableExport' => __DIR__ . '/../..' . '/src/Utilities/Tool/DbTableExport.php',
1162
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\Tool\\FormatBytes' => __DIR__ . '/../..' . '/src/Utilities/Tool/FormatBytes.php',
1163
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\Tool\\IpListSort' => __DIR__ . '/../..' . '/src/Utilities/Tool/IpListSort.php',
 
1164
  'FernleafSystems\\Wordpress\\Services\\Core\\AdminNotices' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/AdminNotices.php',
1165
  'FernleafSystems\\Wordpress\\Services\\Core\\Comments' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/Comments.php',
1166
  'FernleafSystems\\Wordpress\\Services\\Core\\CoreFileHashes' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/CoreFileHashes.php',
@@ -1187,6 +1096,9 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
1187
  'FernleafSystems\\Wordpress\\Services\\Core\\Upgrades\\UpgraderSkin' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/Upgrades/UpgraderSkin.php',
1188
  'FernleafSystems\\Wordpress\\Services\\Core\\Upgrades\\UpgraderSkinLegacy' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/Upgrades/UpgraderSkinLegacy.php',
1189
  'FernleafSystems\\Wordpress\\Services\\Core\\Users' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/Users.php',
 
 
 
1190
  'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpBaseVo' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/VOs/WpBaseVo.php',
1191
  'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpHttpResponseVo' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/VOs/WpHttpResponseVo.php',
1192
  'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpPluginVo' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/VOs/WpPluginVo.php',
@@ -1223,6 +1135,15 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
1223
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\RequestVO' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/RequestVO.php',
1224
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\ApiBase' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/ApiBase.php',
1225
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\ApiPing' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/ApiPing.php',
 
 
 
 
 
 
 
 
 
1226
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\Hashes\\ApiInfo' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/ApiInfo.php',
1227
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\Hashes\\AssetHashesBase' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/AssetHashesBase.php',
1228
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\Hashes\\Base' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/Base.php',
@@ -1325,7 +1246,6 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
1325
  'LZCompressor\\LZString' => __DIR__ . '/..' . '/nullpunkt/lz-string-php/src/LZCompressor/LZString.php',
1326
  'LZCompressor\\LZUtil' => __DIR__ . '/..' . '/nullpunkt/lz-string-php/src/LZCompressor/LZUtil.php',
1327
  'LZCompressor\\LZUtil16' => __DIR__ . '/..' . '/nullpunkt/lz-string-php/src/LZCompressor/LZUtil16.php',
1328
- 'MyCLabs\\Enum\\Enum' => __DIR__ . '/..' . '/myclabs/php-enum/src/Enum.php',
1329
  'Pimple\\Container' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Container.php',
1330
  'Pimple\\Exception\\ExpectedInvokableException' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Exception/ExpectedInvokableException.php',
1331
  'Pimple\\Exception\\FrozenServiceException' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Exception/FrozenServiceException.php',
@@ -1351,7 +1271,6 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
1351
  'Psr\\Container\\ContainerExceptionInterface' => __DIR__ . '/..' . '/psr/container/src/ContainerExceptionInterface.php',
1352
  'Psr\\Container\\ContainerInterface' => __DIR__ . '/..' . '/psr/container/src/ContainerInterface.php',
1353
  'Psr\\Container\\NotFoundExceptionInterface' => __DIR__ . '/..' . '/psr/container/src/NotFoundExceptionInterface.php',
1354
- 'QrReader' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/QrReader.php',
1355
  'Ramsey\\Uuid\\BinaryUtils' => __DIR__ . '/..' . '/ramsey/uuid/src/BinaryUtils.php',
1356
  'Ramsey\\Uuid\\Builder\\DefaultUuidBuilder' => __DIR__ . '/..' . '/ramsey/uuid/src/Builder/DefaultUuidBuilder.php',
1357
  'Ramsey\\Uuid\\Builder\\DegradedUuidBuilder' => __DIR__ . '/..' . '/ramsey/uuid/src/Builder/DegradedUuidBuilder.php',
@@ -1407,36 +1326,6 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
1407
  'ReCaptcha\\RequestMethod\\SocketPost' => __DIR__ . '/..' . '/google/recaptcha/src/ReCaptcha/RequestMethod/SocketPost.php',
1408
  'ReCaptcha\\RequestParameters' => __DIR__ . '/..' . '/google/recaptcha/src/ReCaptcha/RequestParameters.php',
1409
  'ReCaptcha\\Response' => __DIR__ . '/..' . '/google/recaptcha/src/ReCaptcha/Response.php',
1410
- 'Symfony\\Component\\OptionsResolver\\Exception\\AccessException' => __DIR__ . '/..' . '/symfony/options-resolver/Exception/AccessException.php',
1411
- 'Symfony\\Component\\OptionsResolver\\Exception\\ExceptionInterface' => __DIR__ . '/..' . '/symfony/options-resolver/Exception/ExceptionInterface.php',
1412
- 'Symfony\\Component\\OptionsResolver\\Exception\\InvalidArgumentException' => __DIR__ . '/..' . '/symfony/options-resolver/Exception/InvalidArgumentException.php',
1413
- 'Symfony\\Component\\OptionsResolver\\Exception\\InvalidOptionsException' => __DIR__ . '/..' . '/symfony/options-resolver/Exception/InvalidOptionsException.php',
1414
- 'Symfony\\Component\\OptionsResolver\\Exception\\MissingOptionsException' => __DIR__ . '/..' . '/symfony/options-resolver/Exception/MissingOptionsException.php',
1415
- 'Symfony\\Component\\OptionsResolver\\Exception\\NoSuchOptionException' => __DIR__ . '/..' . '/symfony/options-resolver/Exception/NoSuchOptionException.php',
1416
- 'Symfony\\Component\\OptionsResolver\\Exception\\OptionDefinitionException' => __DIR__ . '/..' . '/symfony/options-resolver/Exception/OptionDefinitionException.php',
1417
- 'Symfony\\Component\\OptionsResolver\\Exception\\UndefinedOptionsException' => __DIR__ . '/..' . '/symfony/options-resolver/Exception/UndefinedOptionsException.php',
1418
- 'Symfony\\Component\\OptionsResolver\\Options' => __DIR__ . '/..' . '/symfony/options-resolver/Options.php',
1419
- 'Symfony\\Component\\OptionsResolver\\OptionsResolver' => __DIR__ . '/..' . '/symfony/options-resolver/OptionsResolver.php',
1420
- 'Symfony\\Component\\OptionsResolver\\OptionsResolverInterface' => __DIR__ . '/..' . '/symfony/options-resolver/OptionsResolverInterface.php',
1421
- 'Symfony\\Component\\PropertyAccess\\Exception\\AccessException' => __DIR__ . '/..' . '/symfony/property-access/Exception/AccessException.php',
1422
- 'Symfony\\Component\\PropertyAccess\\Exception\\ExceptionInterface' => __DIR__ . '/..' . '/symfony/property-access/Exception/ExceptionInterface.php',
1423
- 'Symfony\\Component\\PropertyAccess\\Exception\\InvalidArgumentException' => __DIR__ . '/..' . '/symfony/property-access/Exception/InvalidArgumentException.php',
1424
- 'Symfony\\Component\\PropertyAccess\\Exception\\InvalidPropertyPathException' => __DIR__ . '/..' . '/symfony/property-access/Exception/InvalidPropertyPathException.php',
1425
- 'Symfony\\Component\\PropertyAccess\\Exception\\NoSuchIndexException' => __DIR__ . '/..' . '/symfony/property-access/Exception/NoSuchIndexException.php',
1426
- 'Symfony\\Component\\PropertyAccess\\Exception\\NoSuchPropertyException' => __DIR__ . '/..' . '/symfony/property-access/Exception/NoSuchPropertyException.php',
1427
- 'Symfony\\Component\\PropertyAccess\\Exception\\OutOfBoundsException' => __DIR__ . '/..' . '/symfony/property-access/Exception/OutOfBoundsException.php',
1428
- 'Symfony\\Component\\PropertyAccess\\Exception\\RuntimeException' => __DIR__ . '/..' . '/symfony/property-access/Exception/RuntimeException.php',
1429
- 'Symfony\\Component\\PropertyAccess\\Exception\\UnexpectedTypeException' => __DIR__ . '/..' . '/symfony/property-access/Exception/UnexpectedTypeException.php',
1430
- 'Symfony\\Component\\PropertyAccess\\PropertyAccess' => __DIR__ . '/..' . '/symfony/property-access/PropertyAccess.php',
1431
- 'Symfony\\Component\\PropertyAccess\\PropertyAccessor' => __DIR__ . '/..' . '/symfony/property-access/PropertyAccessor.php',
1432
- 'Symfony\\Component\\PropertyAccess\\PropertyAccessorBuilder' => __DIR__ . '/..' . '/symfony/property-access/PropertyAccessorBuilder.php',
1433
- 'Symfony\\Component\\PropertyAccess\\PropertyAccessorInterface' => __DIR__ . '/..' . '/symfony/property-access/PropertyAccessorInterface.php',
1434
- 'Symfony\\Component\\PropertyAccess\\PropertyPath' => __DIR__ . '/..' . '/symfony/property-access/PropertyPath.php',
1435
- 'Symfony\\Component\\PropertyAccess\\PropertyPathBuilder' => __DIR__ . '/..' . '/symfony/property-access/PropertyPathBuilder.php',
1436
- 'Symfony\\Component\\PropertyAccess\\PropertyPathInterface' => __DIR__ . '/..' . '/symfony/property-access/PropertyPathInterface.php',
1437
- 'Symfony\\Component\\PropertyAccess\\PropertyPathIterator' => __DIR__ . '/..' . '/symfony/property-access/PropertyPathIterator.php',
1438
- 'Symfony\\Component\\PropertyAccess\\PropertyPathIteratorInterface' => __DIR__ . '/..' . '/symfony/property-access/PropertyPathIteratorInterface.php',
1439
- 'Symfony\\Component\\PropertyAccess\\StringUtil' => __DIR__ . '/..' . '/symfony/property-access/StringUtil.php',
1440
  'Symfony\\Component\\Translation\\Catalogue\\AbstractOperation' => __DIR__ . '/..' . '/symfony/translation/Catalogue/AbstractOperation.php',
1441
  'Symfony\\Component\\Translation\\Catalogue\\MergeOperation' => __DIR__ . '/..' . '/symfony/translation/Catalogue/MergeOperation.php',
1442
  'Symfony\\Component\\Translation\\Catalogue\\OperationInterface' => __DIR__ . '/..' . '/symfony/translation/Catalogue/OperationInterface.php',
@@ -1906,64 +1795,6 @@ class ComposerStaticInit4fc2c6daaffaf40b64b79b6d26830171
1906
  'ZxcvbnPhp\\Scorer' => __DIR__ . '/..' . '/fernleafsystems/zxcvbn-php/src/Scorer.php',
1907
  'ZxcvbnPhp\\TimeEstimator' => __DIR__ . '/..' . '/fernleafsystems/zxcvbn-php/src/TimeEstimator.php',
1908
  'ZxcvbnPhp\\Zxcvbn' => __DIR__ . '/..' . '/fernleafsystems/zxcvbn-php/src/Zxcvbn.php',
1909
- 'Zxing\\Binarizer' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/Binarizer.php',
1910
- 'Zxing\\BinaryBitmap' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/BinaryBitmap.php',
1911
- 'Zxing\\ChecksumException' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/ChecksumException.php',
1912
- 'Zxing\\Common\\BitArray' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/common/BitArray.php',
1913
- 'Zxing\\Common\\BitMatrix' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/common/BitMatrix.php',
1914
- 'Zxing\\Common\\BitSource' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/common/BitSource.php',
1915
- 'Zxing\\Common\\CharacterSetECI' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/common/CharacterSetEci.php',
1916
- 'Zxing\\Common\\CharacterSetEci\\AbstractEnum\\AbstractEnum' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/common/AbstractEnum.php',
1917
- 'Zxing\\Common\\DecoderResult' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/common/DecoderResult.php',
1918
- 'Zxing\\Common\\DefaultGridSampler' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/common/DefaultGridSampler.php',
1919
- 'Zxing\\Common\\DetectorResult' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/common/DetectorResult.php',
1920
- 'Zxing\\Common\\Detector\\MathUtils' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/common/detector/MathUtils.php',
1921
- 'Zxing\\Common\\Detector\\MonochromeRectangleDetector' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/common/detector/MonochromeRectangleDetector.php',
1922
- 'Zxing\\Common\\GlobalHistogramBinarizer' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/common/GlobalHistogramBinarizer.php',
1923
- 'Zxing\\Common\\GridSampler' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/common/GridSampler.php',
1924
- 'Zxing\\Common\\HybridBinarizer' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/common/HybridBinarizer.php',
1925
- 'Zxing\\Common\\PerspectiveTransform' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/common/PerspectiveTransform.php',
1926
- 'Zxing\\Common\\Reedsolomon\\GenericGF' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/common/reedsolomon/GenericGF.php',
1927
- 'Zxing\\Common\\Reedsolomon\\GenericGFPoly' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/common/reedsolomon/GenericGFPoly.php',
1928
- 'Zxing\\Common\\Reedsolomon\\ReedSolomonDecoder' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/common/reedsolomon/ReedSolomonDecoder.php',
1929
- 'Zxing\\Common\\Reedsolomon\\ReedSolomonException' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/common/reedsolomon/ReedSolomonException.php',
1930
- 'Zxing\\FormatException' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/FormatException.php',
1931
- 'Zxing\\GDLuminanceSource' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/GDLuminanceSource.php',
1932
- 'Zxing\\IMagickLuminanceSource' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/IMagickLuminanceSource.php',
1933
- 'Zxing\\LuminanceSource' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/LuminanceSource.php',
1934
- 'Zxing\\NotFoundException' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/NotFoundException.php',
1935
- 'Zxing\\PlanarYUVLuminanceSource' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/PlanarYUVLuminanceSource.php',
1936
- 'Zxing\\Qrcode\\Decoder\\BitMatrixParser' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/BitMatrixParser.php',
1937
- 'Zxing\\Qrcode\\Decoder\\DataBlock' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/DataBlock.php',
1938
- 'Zxing\\Qrcode\\Decoder\\DataMask' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/DataMask.php',
1939
- 'Zxing\\Qrcode\\Decoder\\DataMask000' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/DataMask.php',
1940
- 'Zxing\\Qrcode\\Decoder\\DataMask001' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/DataMask.php',
1941
- 'Zxing\\Qrcode\\Decoder\\DataMask010' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/DataMask.php',
1942
- 'Zxing\\Qrcode\\Decoder\\DataMask011' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/DataMask.php',
1943
- 'Zxing\\Qrcode\\Decoder\\DataMask100' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/DataMask.php',
1944
- 'Zxing\\Qrcode\\Decoder\\DataMask101' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/DataMask.php',
1945
- 'Zxing\\Qrcode\\Decoder\\DataMask110' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/DataMask.php',
1946
- 'Zxing\\Qrcode\\Decoder\\DataMask111' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/DataMask.php',
1947
- 'Zxing\\Qrcode\\Decoder\\DecodedBitStreamParser' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/DecodedBitStreamParser.php',
1948
- 'Zxing\\Qrcode\\Decoder\\Decoder' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/Decoder.php',
1949
- 'Zxing\\Qrcode\\Decoder\\ECB' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/Version.php',
1950
- 'Zxing\\Qrcode\\Decoder\\ECBlocks' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/Version.php',
1951
- 'Zxing\\Qrcode\\Decoder\\ErrorCorrectionLevel' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/ErrorCorrectionLevel.php',
1952
- 'Zxing\\Qrcode\\Decoder\\FormatInformation' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/FormatInformation.php',
1953
- 'Zxing\\Qrcode\\Decoder\\Mode' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/Mode.php',
1954
- 'Zxing\\Qrcode\\Decoder\\Version' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/Version.php',
1955
- 'Zxing\\Qrcode\\Detector\\AlignmentPattern' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/qrcode/detector/AlignmentPattern.php',
1956
- 'Zxing\\Qrcode\\Detector\\AlignmentPatternFinder' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/qrcode/detector/AlignmentPatternFinder.php',
1957
- 'Zxing\\Qrcode\\Detector\\Detector' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/qrcode/detector/Detector.php',
1958
- 'Zxing\\Qrcode\\Detector\\FinderPattern' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/qrcode/detector/FinderPattern.php',
1959
- 'Zxing\\Qrcode\\Detector\\FinderPatternFinder' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/qrcode/detector/FinderPatternFinder.php',
1960
- 'Zxing\\Qrcode\\Detector\\FinderPatternInfo' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/qrcode/detector/FinderPatternInfo.php',
1961
- 'Zxing\\Qrcode\\QRCodeReader' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/qrcode/QRCodeReader.php',
1962
- 'Zxing\\RGBLuminanceSource' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/RGBLuminanceSource.php',
1963
- 'Zxing\\Reader' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/Reader.php',
1964
- 'Zxing\\ReaderException' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/ReaderException.php',
1965
- 'Zxing\\Result' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/Result.php',
1966
- 'Zxing\\ResultPoint' => __DIR__ . '/..' . '/khanamiryan/qrcode-detector-decoder/lib/ResultPoint.php',
1967
  'u2flib_server\\Error' => __DIR__ . '/../..' . '/custom/U2F/Yubico/U2F.php',
1968
  'u2flib_server\\RegisterRequest' => __DIR__ . '/../..' . '/custom/U2F/Yubico/U2F.php',
1969
  'u2flib_server\\Registration' => __DIR__ . '/../..' . '/custom/U2F/Yubico/U2F.php',
9
  public static $files = array (
10
  '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
11
  '320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php',
 
12
  'e39a8b23c42d4e1452234d762b03835a' => __DIR__ . '/..' . '/ramsey/uuid/src/functions.php',
13
  'def43f6c87e4f8dfd0c9e1b1bab14fe8' => __DIR__ . '/..' . '/symfony/polyfill-iconv/bootstrap.php',
14
  'b14ca0bb4d408c293d6ea9b68f1b4abe' => __DIR__ . '/../..' . '/functions/functions.php',
30
  'Symfony\\Polyfill\\Ctype\\' => 23,
31
  'Symfony\\Component\\Yaml\\' => 23,
32
  'Symfony\\Component\\Translation\\' => 30,
 
 
33
  ),
34
  'R' =>
35
  array (
41
  'Psr\\Container\\' => 14,
42
  'Psr\\Cache\\' => 10,
43
  ),
 
 
 
 
44
  'L' =>
45
  array (
46
  'LZCompressor\\' => 13,
56
  'FernleafSystems\\Wordpress\\Plugin\\Core\\' => 38,
57
  'FernleafSystems\\Utilities\\' => 26,
58
  ),
 
 
 
 
59
  'D' =>
60
  array (
61
  'Dolondro\\GoogleAuthenticator\\' => 29,
95
  array (
96
  0 => __DIR__ . '/..' . '/symfony/translation',
97
  ),
 
 
 
 
 
 
 
 
98
  'ReCaptcha\\' =>
99
  array (
100
  0 => __DIR__ . '/..' . '/google/recaptcha/src/ReCaptcha',
111
  array (
112
  0 => __DIR__ . '/..' . '/psr/cache/src',
113
  ),
 
 
 
 
114
  'LZCompressor\\' =>
115
  array (
116
  0 => __DIR__ . '/..' . '/nullpunkt/lz-string-php/src/LZCompressor',
135
  array (
136
  0 => __DIR__ . '/..' . '/fernleafsystems/utilities/src',
137
  ),
 
 
 
 
138
  'Dolondro\\GoogleAuthenticator\\' =>
139
  array (
140
  0 => __DIR__ . '/..' . '/dolondro/google-authenticator/src',
171
  0 => __DIR__ . '/..' . '/pimple/pimple/src',
172
  ),
173
  ),
 
 
 
 
 
 
 
174
  );
175
 
176
  public static $fallbackDirsPsr0 = array (
179
  );
180
 
181
  public static $classMap = array (
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
182
  'Base32\\Base32' => __DIR__ . '/..' . '/christian-riesen/base32/src/Base32.php',
183
  'Carbon\\Carbon' => __DIR__ . '/..' . '/nesbot/carbon/src/Carbon/Carbon.php',
184
  'Carbon\\CarbonInterval' => __DIR__ . '/..' . '/nesbot/carbon/src/Carbon/CarbonInterval.php',
196
  'Dolondro\\GoogleAuthenticator\\SecretFactory' => __DIR__ . '/..' . '/dolondro/google-authenticator/src/SecretFactory.php',
197
  'Elliotchance\\Iterator\\AbstractPagedIterator' => __DIR__ . '/..' . '/elliotchance/iterator/src/Elliotchance/Iterator/AbstractPagedIterator.php',
198
  'Elliotchance\\Iterator\\PagedIteratorTest' => __DIR__ . '/..' . '/elliotchance/iterator/tests/Elliotchance/Iterator/PagedIteratorTest.php',
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
199
  'FernleafSystems\\Utilities\\Data\\Adapter\\DynProperties' => __DIR__ . '/..' . '/fernleafsystems/utilities/src/Data/Adapter/DynProperties.php',
200
  'FernleafSystems\\Utilities\\Data\\Adapter\\DynPropertiesClass' => __DIR__ . '/..' . '/fernleafsystems/utilities/src/Data/Adapter/DynPropertiesClass.php',
201
  'FernleafSystems\\Utilities\\Data\\Adapter\\DynamicProperties' => __DIR__ . '/..' . '/fernleafsystems/utilities/src/Data/Adapter/DynamicProperties.php',
215
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Base\\Update' => __DIR__ . '/..' . '/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Update.php',
216
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Common\\AlignTableWithSchema' => __DIR__ . '/..' . '/fernleafsystems/wordpress-plugin-core/src/Databases/Common/AlignTableWithSchema.php',
217
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Common\\BuildColumnFromDef' => __DIR__ . '/..' . '/fernleafsystems/wordpress-plugin-core/src/Databases/Common/BuildColumnFromDef.php',
218
+ 'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Common\\CreateTable' => __DIR__ . '/..' . '/fernleafsystems/wordpress-plugin-core/src/Databases/Common/CreateTable.php',
219
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Common\\HandlerConsumer' => __DIR__ . '/..' . '/fernleafsystems/wordpress-plugin-core/src/Databases/Common/HandlerConsumer.php',
220
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Common\\Iterator' => __DIR__ . '/..' . '/fernleafsystems/wordpress-plugin-core/src/Databases/Common/Iterator.php',
221
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Common\\RecordConsumer' => __DIR__ . '/..' . '/fernleafsystems/wordpress-plugin-core/src/Databases/Common/RecordConsumer.php',
222
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Common\\SubQueryLoader' => __DIR__ . '/..' . '/fernleafsystems/wordpress-plugin-core/src/Databases/Common/SubQueryLoader.php',
223
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Common\\TableSchema' => __DIR__ . '/..' . '/fernleafsystems/wordpress-plugin-core/src/Databases/Common/TableSchema.php',
224
+ 'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Exceptions\\ColumnDoesNotExistException' => __DIR__ . '/..' . '/fernleafsystems/wordpress-plugin-core/src/Databases/Exceptions/ColumnDoesNotExistException.php',
225
  'FernleafSystems\\Wordpress\\Plugin\\Core\\Databases\\Exceptions\\NoSlugProvidedException' => __DIR__ . '/..' . '/fernleafsystems/wordpress-plugin-core/src/Databases/Exceptions/NoSlugProvidedException.php',
226
+ 'FernleafSystems\\Wordpress\\Plugin\\Core\\Utility\\User\\PluginMeta' => __DIR__ . '/..' . '/fernleafsystems/wordpress-plugin-core/src/Utility/User/PluginMeta.php',
227
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\ChangeTrack\\Diff\\Base' => __DIR__ . '/../..' . '/src/ChangeTrack/Diff/Base.php',
228
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\ChangeTrack\\Diff\\DiffComments' => __DIR__ . '/../..' . '/src/ChangeTrack/Diff/DiffComments.php',
229
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\ChangeTrack\\Diff\\DiffMedia' => __DIR__ . '/../..' . '/src/ChangeTrack/Diff/DiffMedia.php',
509
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\Build\\BuildHashesForAsset' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Lib/Snapshots/Build/BuildHashesForAsset.php',
510
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\Build\\BuildHashesFromApi' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Lib/Snapshots/Build/BuildHashesFromApi.php',
511
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\Build\\BuildHashesFromDir' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Lib/Snapshots/Build/BuildHashesFromDir.php',
512
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\CrowdSourced\\SubmitHashes' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Lib/Snapshots/CrowdSourced/SubmitHashes.php',
513
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\FindAssetsToSnap' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Lib/Snapshots/FindAssetsToSnap.php',
514
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\Store' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Lib/Snapshots/Store.php',
515
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\HackGuard\\Lib\\Snapshots\\StoreAction\\BaseAction' => __DIR__ . '/../..' . '/src/Modules/HackGuard/Lib/Snapshots/StoreAction/BaseAction.php',
600
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\NotBot\\InsertNotBotJs' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/Bots/NotBot/InsertNotBotJs.php',
601
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\NotBot\\NotBotHandler' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/Bots/NotBot/NotBotHandler.php',
602
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\NotBot\\TestNotBotLoading' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/Bots/NotBot/TestNotBotLoading.php',
603
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\Bots\\ShieldNET\\BuildData' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/Bots/ShieldNET/BuildData.php',
604
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\IpAnalyse\\BuildDisplay' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/IpAnalyse/BuildDisplay.php',
605
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\IpAnalyse\\FindAllPluginIps' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/IpAnalyse/FindAllPluginIps.php',
606
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\Lib\\OffenseTracker' => __DIR__ . '/../..' . '/src/Modules/IPs/Lib/OffenseTracker.php',
995
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wpv\\ScanActionVO' => __DIR__ . '/../..' . '/src/Scans/Wpv/ScanActionVO.php',
996
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wpv\\Utilities\\ItemActionHandler' => __DIR__ . '/../..' . '/src/Scans/Wpv/Utilities/ItemActionHandler.php',
997
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wpv\\Utilities\\Repair' => __DIR__ . '/../..' . '/src/Scans/Wpv/Utilities/Repair.php',
998
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Wpv\\WpVulnDb\\VulnVO' => __DIR__ . '/../..' . '/src/Scans/Wpv/WpVulnDb/VulnVO.php',
999
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\Common\\BaseApi' => __DIR__ . '/../..' . '/src/ShieldNetApi/Common/BaseApi.php',
1000
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\Common\\BaseShieldNetApi' => __DIR__ . '/../..' . '/src/ShieldNetApi/Common/BaseShieldNetApi.php',
1001
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\FileLocker\\DecryptFile' => __DIR__ . '/../..' . '/src/ShieldNetApi/FileLocker/DecryptFile.php',
1003
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\Handshake\\Verify' => __DIR__ . '/../..' . '/src/ShieldNetApi/Handshake/Verify.php',
1004
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\HandshakingNonce' => __DIR__ . '/../..' . '/src/ShieldNetApi/HandshakingNonce.php',
1005
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\Reputation\\BotScoringLogic' => __DIR__ . '/../..' . '/src/ShieldNetApi/Reputation/BotScoringLogic.php',
1006
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\Reputation\\GetIPReputation' => __DIR__ . '/../..' . '/src/ShieldNetApi/Reputation/GetIPReputation.php',
1007
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\Reputation\\SendIPReputation' => __DIR__ . '/../..' . '/src/ShieldNetApi/Reputation/SendIPReputation.php',
1008
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\ShieldNetApiController' => __DIR__ . '/../..' . '/src/ShieldNetApi/ShieldNetApiController.php',
1009
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\ShieldNetApiDataVO' => __DIR__ . '/../..' . '/src/ShieldNetApi/ShieldNetApiDataVO.php',
1010
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\SureSend\\SendEmail' => __DIR__ . '/../..' . '/src/ShieldNetApi/SureSend/SendEmail.php',
1011
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\Telemetry\\SendTelemetry' => __DIR__ . '/../..' . '/src/ShieldNetApi/Telemetry/SendTelemetry.php',
1012
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\Tools\\GenerateGoogleAuthQrCode' => __DIR__ . '/../..' . '/src/ShieldNetApi/Tools/GenerateGoogleAuthQrCode.php',
1013
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\ShieldNetApi\\WPHashes\\SolicitToken' => __DIR__ . '/../..' . '/src/ShieldNetApi/WPHashes/SolicitToken.php',
1014
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Build\\AdminNotes' => __DIR__ . '/../..' . '/src/Tables/Build/AdminNotes.php',
1015
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Build\\AuditTrail' => __DIR__ . '/../..' . '/src/Tables/Build/AuditTrail.php',
1016
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tables\\Build\\BaseBuild' => __DIR__ . '/../..' . '/src/Tables/Build/BaseBuild.php',
1069
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\Tool\\DbTableExport' => __DIR__ . '/../..' . '/src/Utilities/Tool/DbTableExport.php',
1070
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\Tool\\FormatBytes' => __DIR__ . '/../..' . '/src/Utilities/Tool/FormatBytes.php',
1071
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\Tool\\IpListSort' => __DIR__ . '/../..' . '/src/Utilities/Tool/IpListSort.php',
1072
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\Tool\\TmpFileStore' => __DIR__ . '/../..' . '/src/Utilities/Tool/TmpFileStore.php',
1073
  'FernleafSystems\\Wordpress\\Services\\Core\\AdminNotices' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/AdminNotices.php',
1074
  'FernleafSystems\\Wordpress\\Services\\Core\\Comments' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/Comments.php',
1075
  'FernleafSystems\\Wordpress\\Services\\Core\\CoreFileHashes' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/CoreFileHashes.php',
1096
  'FernleafSystems\\Wordpress\\Services\\Core\\Upgrades\\UpgraderSkin' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/Upgrades/UpgraderSkin.php',
1097
  'FernleafSystems\\Wordpress\\Services\\Core\\Upgrades\\UpgraderSkinLegacy' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/Upgrades/UpgraderSkinLegacy.php',
1098
  'FernleafSystems\\Wordpress\\Services\\Core\\Users' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/Users.php',
1099
+ 'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\Assets\\WpBaseVo' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/VOs/Assets/WpBaseVo.php',
1100
+ 'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\Assets\\WpPluginVo' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/VOs/Assets/WpPluginVo.php',
1101
+ 'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\Assets\\WpThemeVo' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/VOs/Assets/WpThemeVo.php',
1102
  'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpBaseVo' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/VOs/WpBaseVo.php',
1103
  'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpHttpResponseVo' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/VOs/WpHttpResponseVo.php',
1104
  'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpPluginVo' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/VOs/WpPluginVo.php',
1135
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\RequestVO' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/RequestVO.php',
1136
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\ApiBase' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/ApiBase.php',
1137
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\ApiPing' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/ApiPing.php',
1138
+ 'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\CrowdSourcedHashes\\Base' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/CrowdSourcedHashes/Base.php',
1139
+ 'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\CrowdSourcedHashes\\Query\\AssetHashesBase' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/CrowdSourcedHashes/Query/AssetHashesBase.php',
1140
+ 'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\CrowdSourcedHashes\\Query\\Plugin' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/CrowdSourcedHashes/Query/Plugin.php',
1141
+ 'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\CrowdSourcedHashes\\Query\\RequestVO' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/CrowdSourcedHashes/Query/RequestVO.php',
1142
+ 'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\CrowdSourcedHashes\\Query\\Theme' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/CrowdSourcedHashes/Query/Theme.php',
1143
+ 'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\CrowdSourcedHashes\\Submit\\BaseSubmit' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/CrowdSourcedHashes/Submit/BaseSubmit.php',
1144
+ 'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\CrowdSourcedHashes\\Submit\\PreSubmit' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/CrowdSourcedHashes/Submit/PreSubmit.php',
1145
+ 'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\CrowdSourcedHashes\\Submit\\RequestVO' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/CrowdSourcedHashes/Submit/RequestVO.php',
1146
+ 'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\CrowdSourcedHashes\\Submit\\Submit' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/CrowdSourcedHashes/Submit/Submit.php',
1147
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\Hashes\\ApiInfo' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/ApiInfo.php',
1148
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\Hashes\\AssetHashesBase' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/AssetHashesBase.php',
1149
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\Hashes\\Base' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/Base.php',
1246
  'LZCompressor\\LZString' => __DIR__ . '/..' . '/nullpunkt/lz-string-php/src/LZCompressor/LZString.php',
1247
  'LZCompressor\\LZUtil' => __DIR__ . '/..' . '/nullpunkt/lz-string-php/src/LZCompressor/LZUtil.php',
1248
  'LZCompressor\\LZUtil16' => __DIR__ . '/..' . '/nullpunkt/lz-string-php/src/LZCompressor/LZUtil16.php',
 
1249
  'Pimple\\Container' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Container.php',
1250
  'Pimple\\Exception\\ExpectedInvokableException' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Exception/ExpectedInvokableException.php',
1251
  'Pimple\\Exception\\FrozenServiceException' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Exception/FrozenServiceException.php',
1271
  'Psr\\Container\\ContainerExceptionInterface' => __DIR__ . '/..' . '/psr/container/src/ContainerExceptionInterface.php',
1272
  'Psr\\Container\\ContainerInterface' => __DIR__ . '/..' . '/psr/container/src/ContainerInterface.php',
1273
  'Psr\\Container\\NotFoundExceptionInterface' => __DIR__ . '/..' . '/psr/container/src/NotFoundExceptionInterface.php',
 
1274
  'Ramsey\\Uuid\\BinaryUtils' => __DIR__ . '/..' . '/ramsey/uuid/src/BinaryUtils.php',
1275
  'Ramsey\\Uuid\\Builder\\DefaultUuidBuilder' => __DIR__ . '/..' . '/ramsey/uuid/src/Builder/DefaultUuidBuilder.php',
1276
  'Ramsey\\Uuid\\Builder\\DegradedUuidBuilder' => __DIR__ . '/..' . '/ramsey/uuid/src/Builder/DegradedUuidBuilder.php',
1326
  'ReCaptcha\\RequestMethod\\SocketPost' => __DIR__ . '/..' . '/google/recaptcha/src/ReCaptcha/RequestMethod/SocketPost.php',
1327
  'ReCaptcha\\RequestParameters' => __DIR__ . '/..' . '/google/recaptcha/src/ReCaptcha/RequestParameters.php',
1328
  'ReCaptcha\\Response' => __DIR__ . '/..' . '/google/recaptcha/src/ReCaptcha/Response.php',
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1329
  'Symfony\\Component\\Translation\\Catalogue\\AbstractOperation' => __DIR__ . '/..' . '/symfony/translation/Catalogue/AbstractOperation.php',
1330
  'Symfony\\Component\\Translation\\Catalogue\\MergeOperation' => __DIR__ . '/..' . '/symfony/translation/Catalogue/MergeOperation.php',
1331
  'Symfony\\Component\\Translation\\Catalogue\\OperationInterface' => __DIR__ . '/..' . '/symfony/translation/Catalogue/OperationInterface.php',
1795
  'ZxcvbnPhp\\Scorer' => __DIR__ . '/..' . '/fernleafsystems/zxcvbn-php/src/Scorer.php',
1796
  'ZxcvbnPhp\\TimeEstimator' => __DIR__ . '/..' . '/fernleafsystems/zxcvbn-php/src/TimeEstimator.php',
1797
  'ZxcvbnPhp\\Zxcvbn' => __DIR__ . '/..' . '/fernleafsystems/zxcvbn-php/src/Zxcvbn.php',
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1798
  'u2flib_server\\Error' => __DIR__ . '/../..' . '/custom/U2F/Yubico/U2F.php',
1799
  'u2flib_server\\RegisterRequest' => __DIR__ . '/../..' . '/custom/U2F/Yubico/U2F.php',
1800
  'u2flib_server\\Registration' => __DIR__ . '/../..' . '/custom/U2F/Yubico/U2F.php',
src/lib/vendor/endroid/qr-code/src/Bundle/QrCodeBundle/Controller/QrCodeController.php DELETED
@@ -1,64 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * (c) Jeroen van den Enden <info@endroid.nl>
5
- *
6
- * This source file is subject to the MIT license that is bundled
7
- * with this source code in the file LICENSE.
8
- */
9
-
10
- namespace Endroid\QrCode\Bundle\QrCodeBundle\Controller;
11
-
12
- use Endroid\QrCode\Factory\QrCodeFactory;
13
- use Symfony\Bundle\FrameworkBundle\Controller\Controller;
14
- use Symfony\Component\HttpFoundation\Response;
15
- use Symfony\Component\HttpFoundation\Request;
16
-
17
- /**
18
- * QR code controller.
19
- */
20
- class QrCodeController extends Controller
21
- {
22
- /**
23
- * @param Request $request
24
- * @param string $text
25
- * @param string $extension
26
- *
27
- * @return Response
28
- */
29
- public function generateAction(Request $request, $text, $extension)
30
- {
31
- $options = $request->query->all();
32
-
33
- $qrCode = $this->getQrCodeFactory()->create($text, $options);
34
- $qrCode->setWriterByExtension($extension);
35
-
36
- return new Response($qrCode->writeString(), Response::HTTP_OK, ['Content-Type' => $qrCode->getContentType()]);
37
- }
38
-
39
- /**
40
- * @return Response
41
- */
42
- public function twigFunctionsAction()
43
- {
44
- if (!$this->has('twig')) {
45
- throw new \LogicException('You can not use the "@Template" annotation if the Twig Bundle is not available.');
46
- }
47
-
48
- $param = [
49
- 'message' => 'QR Code',
50
- ];
51
-
52
- $renderedView = $this->get('twig')->render('@EndroidQrCode/QrCode/twigFunctions.html.twig', $param);
53
-
54
- return new Response($renderedView, Response::HTTP_OK);
55
- }
56
-
57
- /**
58
- * @return QrCodeFactory
59
- */
60
- protected function getQrCodeFactory()
61
- {
62
- return $this->get('endroid.qrcode.factory');
63
- }
64
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/endroid/qr-code/src/Bundle/QrCodeBundle/DependencyInjection/Compiler/WriterRegistryCompilerPass.php DELETED
@@ -1,36 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * (c) Jeroen van den Enden <info@endroid.nl>
5
- *
6
- * This source file is subject to the MIT license that is bundled
7
- * with this source code in the file LICENSE.
8
- */
9
-
10
- namespace Endroid\QrCode\Bundle\QrCodeBundle\DependencyInjection\Compiler;
11
-
12
- use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
13
- use Symfony\Component\DependencyInjection\ContainerBuilder;
14
- use Symfony\Component\DependencyInjection\Reference;
15
-
16
- class WriterRegistryCompilerPass implements CompilerPassInterface
17
- {
18
- /**
19
- * {@inheritdoc}
20
- */
21
- public function process(ContainerBuilder $container)
22
- {
23
- if (!$container->has('endroid.qrcode.writer_registry')) {
24
- return;
25
- }
26
-
27
- $writerRegistryDefinition = $container->findDefinition('endroid.qrcode.writer_registry');
28
-
29
- $taggedServices = $container->findTaggedServiceIds('endroid.qrcode.writer');
30
- foreach ($taggedServices as $id => $tags) {
31
- foreach ($tags as $attributes) {
32
- $writerRegistryDefinition->addMethodCall('addWriter', [new Reference($id), isset($attributes['set_as_default']) && $attributes['set_as_default']]);
33
- }
34
- }
35
- }
36
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/endroid/qr-code/src/Bundle/QrCodeBundle/DependencyInjection/Configuration.php DELETED
@@ -1,77 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * (c) Jeroen van den Enden <info@endroid.nl>
5
- *
6
- * This source file is subject to the MIT license that is bundled
7
- * with this source code in the file LICENSE.
8
- */
9
-
10
- namespace Endroid\QrCode\Bundle\QrCodeBundle\DependencyInjection;
11
-
12
- use Endroid\QrCode\ErrorCorrectionLevel;
13
- use Endroid\QrCode\LabelAlignment;
14
- use Predis\Response\Error;
15
- use Symfony\Component\Config\Definition\Builder\TreeBuilder;
16
- use Symfony\Component\Config\Definition\ConfigurationInterface;
17
-
18
- class Configuration implements ConfigurationInterface
19
- {
20
- public function getConfigTreeBuilder()
21
- {
22
- $treeBuilder = new TreeBuilder();
23
-
24
- $treeBuilder
25
- ->root('endroid_qr_code')
26
- ->children()
27
- ->scalarNode('writer')->end()
28
- ->integerNode('size')->min(0)->end()
29
- ->integerNode('margin')->min(0)->end()
30
- ->scalarNode('encoding')->defaultValue('UTF-8')->end()
31
- ->scalarNode('error_correction_level')
32
- ->validate()
33
- ->ifNotInArray(ErrorCorrectionLevel::toArray())
34
- ->thenInvalid('Invalid error correction level %s')
35
- ->end()
36
- ->end()
37
- ->arrayNode('foreground_color')
38
- ->children()
39
- ->scalarNode('r')->isRequired()->end()
40
- ->scalarNode('g')->isRequired()->end()
41
- ->scalarNode('b')->isRequired()->end()
42
- ->end()
43
- ->end()
44
- ->arrayNode('background_color')
45
- ->children()
46
- ->scalarNode('r')->isRequired()->end()
47
- ->scalarNode('g')->isRequired()->end()
48
- ->scalarNode('b')->isRequired()->end()
49
- ->end()
50
- ->end()
51
- ->scalarNode('logo_path')->end()
52
- ->integerNode('logo_width')->end()
53
- ->scalarNode('label')->end()
54
- ->integerNode('label_font_size')->end()
55
- ->scalarNode('label_font_path')->end()
56
- ->scalarNode('label_alignment')
57
- ->validate()
58
- ->ifNotInArray(LabelAlignment::toArray())
59
- ->thenInvalid('Invalid label alignment %s')
60
- ->end()
61
- ->end()
62
- ->arrayNode('label_margin')
63
- ->children()
64
- ->scalarNode('t')->end()
65
- ->scalarNode('r')->end()
66
- ->scalarNode('b')->end()
67
- ->scalarNode('l')->end()
68
- ->end()
69
- ->end()
70
- ->booleanNode('validate_result')->end()
71
- ->end()
72
- ->end()
73
- ;
74
-
75
- return $treeBuilder;
76
- }
77
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/endroid/qr-code/src/Bundle/QrCodeBundle/DependencyInjection/EndroidQrCodeExtension.php DELETED
@@ -1,34 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * (c) Jeroen van den Enden <info@endroid.nl>
5
- *
6
- * This source file is subject to the MIT license that is bundled
7
- * with this source code in the file LICENSE.
8
- */
9
-
10
- namespace Endroid\QrCode\Bundle\QrCodeBundle\DependencyInjection;
11
-
12
- use Symfony\Component\Config\Definition\Processor;
13
- use Symfony\Component\HttpKernel\DependencyInjection\Extension;
14
- use Symfony\Component\DependencyInjection\ContainerBuilder;
15
- use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
16
- use Symfony\Component\Config\FileLocator;
17
-
18
- class EndroidQrCodeExtension extends Extension
19
- {
20
- /**
21
- * {@inheritdoc}
22
- */
23
- public function load(array $configs, ContainerBuilder $container)
24
- {
25
- $processor = new Processor();
26
- $config = $processor->processConfiguration(new Configuration(), $configs);
27
-
28
- $loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
29
- $loader->load('services.yml');
30
-
31
- $factoryDefinition = $container->getDefinition('endroid.qrcode.factory');
32
- $factoryDefinition->replaceArgument(0, $config);
33
- }
34
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/endroid/qr-code/src/Bundle/QrCodeBundle/EndroidQrCodeBundle.php DELETED
@@ -1,27 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * (c) Jeroen van den Enden <info@endroid.nl>
5
- *
6
- * This source file is subject to the MIT license that is bundled
7
- * with this source code in the file LICENSE.
8
- */
9
-
10
- namespace Endroid\QrCode\Bundle\QrCodeBundle;
11
-
12
- use Endroid\QrCode\Bundle\QrCodeBundle\DependencyInjection\Compiler\WriterRegistryCompilerPass;
13
- use Symfony\Component\DependencyInjection\ContainerBuilder;
14
- use Symfony\Component\HttpKernel\Bundle\Bundle;
15
-
16
- class EndroidQrCodeBundle extends Bundle
17
- {
18
- /**
19
- * {@inheritdoc}
20
- */
21
- public function build(ContainerBuilder $container)
22
- {
23
- parent::build($container);
24
-
25
- $container->addCompilerPass(new WriterRegistryCompilerPass());
26
- }
27
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/endroid/qr-code/src/Bundle/QrCodeBundle/Resources/config/routing.yml DELETED
@@ -1,11 +0,0 @@
1
- endroid_qrcode_generate:
2
- path: /{text}.{extension}
3
- requirements:
4
- text: "[\\w\\W]+"
5
- defaults:
6
- _controller: EndroidQrCodeBundle:QrCode:generate
7
-
8
- endroid_qrcode_twig_functions:
9
- path: /twig
10
- defaults:
11
- _controller: EndroidQrCodeBundle:QrCode:twigFunctions
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/endroid/qr-code/src/Bundle/QrCodeBundle/Resources/config/services.yml DELETED
@@ -1,31 +0,0 @@
1
- services:
2
- endroid.qrcode.factory:
3
- class: Endroid\QrCode\Factory\QrCodeFactory
4
- arguments: [ null, '@endroid.qrcode.writer_registry' ]
5
- endroid.qrcode.twig.extension:
6
- class: Endroid\QrCode\Twig\Extension\QrCodeExtension
7
- arguments: [ '@endroid.qrcode.factory', '@router']
8
- tags:
9
- - { name: twig.extension }
10
- endroid.qrcode.writer_registry:
11
- class: Endroid\QrCode\WriterRegistry
12
- endroid.qrcode.writer.binary_writer:
13
- class: Endroid\QrCode\Writer\BinaryWriter
14
- tags:
15
- - { name: endroid.qrcode.writer }
16
- endroid.qrcode.writer.debug_writer:
17
- class: Endroid\QrCode\Writer\DebugWriter
18
- tags:
19
- - { name: endroid.qrcode.writer }
20
- endroid.qrcode.writer.eps_writer:
21
- class: Endroid\QrCode\Writer\EpsWriter
22
- tags:
23
- - { name: endroid.qrcode.writer }
24
- endroid.qrcode.writer.png_writer:
25
- class: Endroid\QrCode\Writer\PngWriter
26
- tags:
27
- - { name: endroid.qrcode.writer, set_as_default: true }
28
- endroid.qrcode.writer.svg_writer:
29
- class: Endroid\QrCode\Writer\SvgWriter
30
- tags:
31
- - { name: endroid.qrcode.writer }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/endroid/qr-code/src/Bundle/QrCodeBundle/Resources/views/QrCode/twigFunctions.html.twig DELETED
@@ -1,3 +0,0 @@
1
- <img src="{{ qrcode_path(message) }}" />
2
- <img src="{{ qrcode_url(message, { writer: 'svg' }) }}" />
3
- <img src="{{ qrcode_data_uri(message, { writer: 'svg', size: 150 }) }}" />
 
 
 
src/lib/vendor/endroid/qr-code/src/ErrorCorrectionLevel.php DELETED
@@ -1,20 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * (c) Jeroen van den Enden <info@endroid.nl>
5
- *
6
- * This source file is subject to the MIT license that is bundled
7
- * with this source code in the file LICENSE.
8
- */
9
-
10
- namespace Endroid\QrCode;
11
-
12
- use MyCLabs\Enum\Enum;
13
-
14
- class ErrorCorrectionLevel extends Enum
15
- {
16
- const LOW = 'low';
17
- const MEDIUM = 'medium';
18
- const QUARTILE = 'quartile';
19
- const HIGH = 'high';
20
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/endroid/qr-code/src/Exception/InvalidPathException.php DELETED
@@ -1,14 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * (c) Jeroen van den Enden <info@endroid.nl>
5
- *
6
- * This source file is subject to the MIT license that is bundled
7
- * with this source code in the file LICENSE.
8
- */
9
-
10
- namespace Endroid\QrCode\Exception;
11
-
12
- class InvalidPathException extends QrCodeException
13
- {
14
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/endroid/qr-code/src/Exception/InvalidWriterException.php DELETED
@@ -1,14 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * (c) Jeroen van den Enden <info@endroid.nl>
5
- *
6
- * This source file is subject to the MIT license that is bundled
7
- * with this source code in the file LICENSE.
8
- */
9
-
10
- namespace Endroid\QrCode\Exception;
11
-
12
- class InvalidWriterException extends QrCodeException
13
- {
14
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/endroid/qr-code/src/Exception/MissingFunctionException.php DELETED
@@ -1,14 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * (c) Jeroen van den Enden <info@endroid.nl>
5
- *
6
- * This source file is subject to the MIT license that is bundled
7
- * with this source code in the file LICENSE.
8
- */
9
-
10
- namespace Endroid\QrCode\Exception;
11
-
12
- class MissingFunctionException extends QrCodeException
13
- {
14
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/endroid/qr-code/src/Exception/QrCodeException.php DELETED
@@ -1,16 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * (c) Jeroen van den Enden <info@endroid.nl>
5
- *
6
- * This source file is subject to the MIT license that is bundled
7
- * with this source code in the file LICENSE.
8
- */
9
-
10
- namespace Endroid\QrCode\Exception;
11
-
12
- use Exception;
13
-
14
- abstract class QrCodeException extends Exception
15
- {
16
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/endroid/qr-code/src/Exception/UnsupportedExtensionException.php DELETED
@@ -1,14 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * (c) Jeroen van den Enden <info@endroid.nl>
5
- *
6
- * This source file is subject to the MIT license that is bundled
7
- * with this source code in the file LICENSE.
8
- */
9
-
10
- namespace Endroid\QrCode\Exception;
11
-
12
- class UnsupportedExtensionException extends QrCodeException
13
- {
14
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/endroid/qr-code/src/Exception/ValidationException.php DELETED
@@ -1,14 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * (c) Jeroen van den Enden <info@endroid.nl>
5
- *
6
- * This source file is subject to the MIT license that is bundled
7
- * with this source code in the file LICENSE.
8
- */
9
-
10
- namespace Endroid\QrCode\Exception;
11
-
12
- class ValidationException extends QrCodeException
13
- {
14
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/endroid/qr-code/src/Factory/QrCodeFactory.php DELETED
@@ -1,120 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * (c) Jeroen van den Enden <info@endroid.nl>
5
- *
6
- * This source file is subject to the MIT license that is bundled
7
- * with this source code in the file LICENSE.
8
- */
9
-
10
- namespace Endroid\QrCode\Factory;
11
-
12
- use Endroid\QrCode\QrCode;
13
- use Endroid\QrCode\WriterRegistryInterface;
14
- use Symfony\Component\OptionsResolver\OptionsResolver;
15
- use Symfony\Component\PropertyAccess\PropertyAccess;
16
-
17
- class QrCodeFactory
18
- {
19
- /**
20
- * @var array
21
- */
22
- protected $definedOptions = [
23
- 'writer',
24
- 'size',
25
- 'margin',
26
- 'foreground_color',
27
- 'background_color',
28
- 'encoding',
29
- 'error_correction_level',
30
- 'logo_path',
31
- 'logo_width',
32
- 'label',
33
- 'label_font_size',
34
- 'label_font_path',
35
- 'label_alignment',
36
- 'label_margin',
37
- 'validate_result',
38
- ];
39
-
40
- /**
41
- * @var array
42
- */
43
- protected $defaultOptions;
44
-
45
- /**
46
- * @var WriterRegistryInterface
47
- */
48
- protected $writerRegistry;
49
-
50
- /**
51
- * @var OptionsResolver
52
- */
53
- protected $optionsResolver;
54
-
55
- /**
56
- * @param array $defaultOptions
57
- * @param WriterRegistryInterface $writerRegistry
58
- */
59
- public function __construct(array $defaultOptions = [], WriterRegistryInterface $writerRegistry = null)
60
- {
61
- $this->defaultOptions = $defaultOptions;
62
- $this->writerRegistry = $writerRegistry;
63
- }
64
-
65
- /**
66
- * @param string $text
67
- * @param array $options
68
- *
69
- * @return QrCode
70
- */
71
- public function create($text = '', array $options = [])
72
- {
73
- $options = $this->getOptionsResolver()->resolve($options);
74
- $accessor = PropertyAccess::createPropertyAccessor();
75
-
76
- $qrCode = new QrCode($text);
77
-
78
- if ($this->writerRegistry instanceof WriterRegistryInterface) {
79
- $qrCode->setWriterRegistry($this->writerRegistry);
80
- }
81
-
82
- foreach ($this->definedOptions as $option) {
83
- if (isset($options[$option])) {
84
- if ('writer' === $option) {
85
- $options['writer_by_name'] = $options[$option];
86
- $option = 'writer_by_name';
87
- }
88
- $accessor->setValue($qrCode, $option, $options[$option]);
89
- }
90
- }
91
-
92
- return $qrCode;
93
- }
94
-
95
- /**
96
- * @return OptionsResolver
97
- */
98
- protected function getOptionsResolver()
99
- {
100
- if (!$this->optionsResolver instanceof OptionsResolver) {
101
- $this->optionsResolver = $this->createOptionsResolver();
102
- }
103
-
104
- return $this->optionsResolver;
105
- }
106
-
107
- /**
108
- * @return OptionsResolver
109
- */
110
- protected function createOptionsResolver()
111
- {
112
- $optionsResolver = new OptionsResolver();
113
- $optionsResolver
114
- ->setDefaults($this->defaultOptions)
115
- ->setDefined($this->definedOptions)
116
- ;
117
-
118
- return $optionsResolver;
119
- }
120
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/endroid/qr-code/src/LabelAlignment.php DELETED
@@ -1,19 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * (c) Jeroen van den Enden <info@endroid.nl>
5
- *
6
- * This source file is subject to the MIT license that is bundled
7
- * with this source code in the file LICENSE.
8
- */
9
-
10
- namespace Endroid\QrCode;
11
-
12
- use MyCLabs\Enum\Enum;
13
-
14
- class LabelAlignment extends Enum
15
- {
16
- const LEFT = 'left';
17
- const CENTER = 'center';
18
- const RIGHT = 'right';
19
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/endroid/qr-code/src/QrCode.php DELETED
@@ -1,591 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * (c) Jeroen van den Enden <info@endroid.nl>
5
- *
6
- * This source file is subject to the MIT license that is bundled
7
- * with this source code in the file LICENSE.
8
- */
9
-
10
- namespace Endroid\QrCode;
11
-
12
- use Endroid\QrCode\Exception\InvalidPathException;
13
- use Endroid\QrCode\Exception\InvalidWriterException;
14
- use Endroid\QrCode\Exception\UnsupportedExtensionException;
15
- use Endroid\QrCode\Writer\WriterInterface;
16
-
17
- class QrCode implements QrCodeInterface
18
- {
19
- const LABEL_FONT_PATH_DEFAULT = __DIR__.'/../assets/noto_sans.otf';
20
-
21
- /**
22
- * @var string
23
- */
24
- protected $text;
25
-
26
- /**
27
- * @var int
28
- */
29
- protected $size = 300;
30
-
31
- /**
32
- * @var int
33
- */
34
- protected $margin = 10;
35
-
36
- /**
37
- * @var array
38
- */
39
- protected $foregroundColor = [
40
- 'r' => 0,
41
- 'g' => 0,
42
- 'b' => 0,
43
- ];
44
-
45
- /**
46
- * @var array
47
- */
48
- protected $backgroundColor = [
49
- 'r' => 255,
50
- 'g' => 255,
51
- 'b' => 255,
52
- ];
53
-
54
- /**
55
- * @var string
56
- */
57
- protected $encoding = 'UTF-8';
58
-
59
- /**
60
- * @var ErrorCorrectionLevel
61
- */
62
- protected $errorCorrectionLevel;
63
-
64
- /**
65
- * @var string
66
- */
67
- protected $logoPath;
68
-
69
- /**
70
- * @var int
71
- */
72
- protected $logoWidth;
73
-
74
- /**
75
- * @var string
76
- */
77
- protected $label;
78
-
79
- /**
80
- * @var int
81
- */
82
- protected $labelFontSize = 16;
83
-
84
- /**
85
- * @var string
86
- */
87
- protected $labelFontPath = self::LABEL_FONT_PATH_DEFAULT;
88
-
89
- /**
90
- * @var LabelAlignment
91
- */
92
- protected $labelAlignment;
93
-
94
- /**
95
- * @var array
96
- */
97
- protected $labelMargin = [
98
- 't' => 0,
99
- 'r' => 10,
100
- 'b' => 10,
101
- 'l' => 10,
102
- ];
103
-
104
- /**
105
- * @var WriterRegistryInterface
106
- */
107
- protected $writerRegistry;
108
-
109
- /**
110
- * @var WriterInterface
111
- */
112
- protected $writer;
113
-
114
- /**
115
- * @var bool
116
- */
117
- protected $validateResult = false;
118
-
119
- /**
120
- * @param string $text
121
- */
122
- public function __construct($text = '')
123
- {
124
- $this->text = $text;
125
-
126
- $this->errorCorrectionLevel = new ErrorCorrectionLevel(ErrorCorrectionLevel::LOW);
127
- $this->labelAlignment = new LabelAlignment(LabelAlignment::CENTER);
128
-
129
- $this->writerRegistry = new StaticWriterRegistry();
130
- }
131
-
132
- /**
133
- * @param string $text
134
- *
135
- * @return $this
136
- */
137
- public function setText($text)
138
- {
139
- $this->text = $text;
140
-
141
- return $this;
142
- }
143
-
144
- /**
145
- * {@inheritdoc}
146
- */
147
- public function getText()
148
- {
149
- return $this->text;
150
- }
151
-
152
- /**
153
- * @param int $size
154
- *
155
- * @return $this
156
- */
157
- public function setSize($size)
158
- {
159
- $this->size = $size;
160
-
161
- return $this;
162
- }
163
-
164
- /**
165
- * {@inheritdoc}
166
- */
167
- public function getSize()
168
- {
169
- return $this->size;
170
- }
171
-
172
- /**
173
- * @param int $margin
174
- *
175
- * @return $this
176
- */
177
- public function setMargin($margin)
178
- {
179
- $this->margin = $margin;
180
-
181
- return $this;
182
- }
183
-
184
- /**
185
- * {@inheritdoc}
186
- */
187
- public function getMargin()
188
- {
189
- return $this->margin;
190
- }
191
-
192
- /**
193
- * @param array $foregroundColor
194
- *
195
- * @return $this
196
- */
197
- public function setForegroundColor($foregroundColor)
198
- {
199
- $this->foregroundColor = $foregroundColor;
200
-
201
- return $this;
202
- }
203
-
204
- /**
205
- * {@inheritdoc}
206
- */
207
- public function getForegroundColor()
208
- {
209
- return $this->foregroundColor;
210
- }
211
-
212
- /**
213
- * @param array $backgroundColor
214
- *
215
- * @return $this
216
- */
217
- public function setBackgroundColor($backgroundColor)
218
- {
219
- $this->backgroundColor = $backgroundColor;
220
-
221
- return $this;
222
- }
223
-
224
- /**
225
- * {@inheritdoc}
226
- */
227
- public function getBackgroundColor()
228
- {
229
- return $this->backgroundColor;
230
- }
231
-
232
- /**
233
- * @param string $encoding
234
- *
235
- * @return $this
236
- */
237
- public function setEncoding($encoding)
238
- {
239
- $this->encoding = $encoding;
240
-
241
- return $this;
242
- }
243
-
244
- /**
245
- * {@inheritdoc}
246
- */
247
- public function getEncoding()
248
- {
249
- return $this->encoding;
250
- }
251
-
252
- /**
253
- * @param string $errorCorrectionLevel
254
- *
255
- * @return $this
256
- */
257
- public function setErrorCorrectionLevel($errorCorrectionLevel)
258
- {
259
- $this->errorCorrectionLevel = new ErrorCorrectionLevel($errorCorrectionLevel);
260
-
261
- return $this;
262
- }
263
-
264
- /**
265
- * {@inheritdoc}
266
- */
267
- public function getErrorCorrectionLevel()
268
- {
269
- return $this->errorCorrectionLevel->getValue();
270
- }
271
-
272
- /**
273
- * @param string $logoPath
274
- *
275
- * @return $this
276
- *
277
- * @throws InvalidPathException
278
- */
279
- public function setLogoPath($logoPath)
280
- {
281
- $logoPath = realpath($logoPath);
282
-
283
- if (!is_file($logoPath)) {
284
- throw new InvalidPathException('Invalid logo path: '.$logoPath);
285
- }
286
-
287
- $this->logoPath = $logoPath;
288
-
289
- return $this;
290
- }
291
-
292
- /**
293
- * {@inheritdoc}
294
- */
295
- public function getLogoPath()
296
- {
297
- return $this->logoPath;
298
- }
299
-
300
- /**
301
- * @param int $logoWidth
302
- *
303
- * @return $this
304
- */
305
- public function setLogoWidth($logoWidth)
306
- {
307
- $this->logoWidth = $logoWidth;
308
-
309
- return $this;
310
- }
311
-
312
- /**
313
- * {@inheritdoc}
314
- */
315
- public function getLogoWidth()
316
- {
317
- return $this->logoWidth;
318
- }
319
-
320
- /**
321
- * @param string $label
322
- * @param int $labelFontSize
323
- * @param string $labelFontPath
324
- * @param string $labelAlignment
325
- * @param array $labelMargin
326
- *
327
- * @return $this
328
- */
329
- public function setLabel($label, $labelFontSize = null, $labelFontPath = null, $labelAlignment = null, $labelMargin = null)
330
- {
331
- $this->label = $label;
332
-
333
- if (null !== $labelFontSize) {
334
- $this->setLabelFontSize($labelFontSize);
335
- }
336
-
337
- if (null !== $labelFontPath) {
338
- $this->setLabelFontPath($labelFontPath);
339
- }
340
-
341
- if (null !== $labelAlignment) {
342
- $this->setLabelAlignment($labelAlignment);
343
- }
344
-
345
- if (null !== $labelMargin) {
346
- $this->setLabelMargin($labelMargin);
347
- }
348
-
349
- return $this;
350
- }
351
-
352
- /**
353
- * {@inheritdoc}
354
- */
355
- public function getLabel()
356
- {
357
- return $this->label;
358
- }
359
-
360
- /**
361
- * @param int $labelFontSize
362
- *
363
- * @return $this
364
- */
365
- public function setLabelFontSize($labelFontSize)
366
- {
367
- $this->labelFontSize = $labelFontSize;
368
-
369
- return $this;
370
- }
371
-
372
- /**
373
- * {@inheritdoc}
374
- */
375
- public function getLabelFontSize()
376
- {
377
- return $this->labelFontSize;
378
- }
379
-
380
- /**
381
- * @param string $labelFontPath
382
- *
383
- * @return $this
384
- *
385
- * @throws InvalidPathException
386
- */
387
- public function setLabelFontPath($labelFontPath)
388
- {
389
- $labelFontPath = realpath($labelFontPath);
390
-
391
- if (!is_file($labelFontPath)) {
392
- throw new InvalidPathException('Invalid label font path: '.$labelFontPath);
393
- }
394
-
395
- $this->labelFontPath = $labelFontPath;
396
-
397
- return $this;
398
- }
399
-
400
- /**
401
- * {@inheritdoc}
402
- */
403
- public function getLabelFontPath()
404
- {
405
- return $this->labelFontPath;
406
- }
407
-
408
- /**
409
- * @param string $labelAlignment
410
- *
411
- * @return $this
412
- */
413
- public function setLabelAlignment($labelAlignment)
414
- {
415
- $this->labelAlignment = new LabelAlignment($labelAlignment);
416
-
417
- return $this;
418
- }
419
-
420
- /**
421
- * {@inheritdoc}
422
- */
423
- public function getLabelAlignment()
424
- {
425
- return $this->labelAlignment->getValue();
426
- }
427
-
428
- /**
429
- * @param int[] $labelMargin
430
- *
431
- * @return $this
432
- */
433
- public function setLabelMargin(array $labelMargin)
434
- {
435
- $this->labelMargin = array_merge($this->labelMargin, $labelMargin);
436
-
437
- return $this;
438
- }
439
-
440
- /**
441
- * {@inheritdoc}
442
- */
443
- public function getLabelMargin()
444
- {
445
- return $this->labelMargin;
446
- }
447
-
448
- /**
449
- * @param WriterRegistryInterface $writerRegistry
450
- *
451
- * @return $this
452
- */
453
- public function setWriterRegistry(WriterRegistryInterface $writerRegistry)
454
- {
455
- $this->writerRegistry = $writerRegistry;
456
-
457
- return $this;
458
- }
459
-
460
- /**
461
- * @param WriterInterface $writer
462
- *
463
- * @return $this
464
- */
465
- public function setWriter(WriterInterface $writer)
466
- {
467
- $this->writer = $writer;
468
-
469
- return $this;
470
- }
471
-
472
- /**
473
- * @param WriterInterface $name
474
- *
475
- * @return WriterInterface
476
- */
477
- public function getWriter($name = null)
478
- {
479
- if (!is_null($name)) {
480
- return $this->writerRegistry->getWriter($name);
481
- }
482
-
483
- if ($this->writer instanceof WriterInterface) {
484
- return $this->writer;
485
- }
486
-
487
- return $this->writerRegistry->getDefaultWriter();
488
- }
489
-
490
- /**
491
- * @param string $name
492
- *
493
- * @return $this
494
- *
495
- * @throws InvalidWriterException
496
- */
497
- public function setWriterByName($name)
498
- {
499
- $this->writer = $this->writerRegistry->getWriter($name);
500
-
501
- return $this;
502
- }
503
-
504
- /**
505
- * @param string $path
506
- *
507
- * @return $this
508
- */
509
- public function setWriterByPath($path)
510
- {
511
- $extension = pathinfo($path, PATHINFO_EXTENSION);
512
-
513
- $this->setWriterByExtension($extension);
514
-
515
- return $this;
516
- }
517
-
518
- /**
519
- * @param string $extension
520
- *
521
- * @return $this
522
- *
523
- * @throws UnsupportedExtensionException
524
- */
525
- public function setWriterByExtension($extension)
526
- {
527
- foreach ($this->writerRegistry->getWriters() as $writer) {
528
- if ($writer->supportsExtension($extension)) {
529
- $this->writer = $writer;
530
-
531
- return $this;
532
- }
533
- }
534
-
535
- throw new UnsupportedExtensionException('Missing writer for extension "'.$extension.'"');
536
- }
537
-
538
- /**
539
- * @param bool $validateResult
540
- *
541
- * @return $this
542
- */
543
- public function setValidateResult($validateResult)
544
- {
545
- $this->validateResult = $validateResult;
546
-
547
- return $this;
548
- }
549
-
550
- /**
551
- * {@inheritdoc}
552
- */
553
- public function getValidateResult()
554
- {
555
- return $this->validateResult;
556
- }
557
-
558
- /**
559
- * @return string
560
- */
561
- public function writeString()
562
- {
563
- return $this->getWriter()->writeString($this);
564
- }
565
-
566
- /**
567
- * @return string
568
- */
569
- public function writeDataUri()
570
- {
571
- return $this->getWriter()->writeDataUri($this);
572
- }
573
-
574
- /**
575
- * @param string $path
576
- */
577
- public function writeFile($path)
578
- {
579
- return $this->getWriter()->writeFile($this, $path);
580
- }
581
-
582
- /**
583
- * @return string
584
- *
585
- * @throws InvalidWriterException
586
- */
587
- public function getContentType()
588
- {
589
- return $this->getWriter()->getContentType();
590
- }
591
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/endroid/qr-code/src/QrCodeInterface.php DELETED
@@ -1,95 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * (c) Jeroen van den Enden <info@endroid.nl>
5
- *
6
- * This source file is subject to the MIT license that is bundled
7
- * with this source code in the file LICENSE.
8
- */
9
-
10
- namespace Endroid\QrCode;
11
-
12
- interface QrCodeInterface
13
- {
14
- /**
15
- * @return string
16
- */
17
- public function getText();
18
-
19
- /**
20
- * @return int
21
- */
22
- public function getSize();
23
-
24
- /**
25
- * @return int
26
- */
27
- public function getMargin();
28
-
29
- /**
30
- * @return int[]
31
- */
32
- public function getForegroundColor();
33
-
34
- /**
35
- * @return int[]
36
- */
37
- public function getBackgroundColor();
38
-
39
- /**
40
- * @return string
41
- */
42
- public function getEncoding();
43
-
44
- /**
45
- * @return string
46
- */
47
- public function getErrorCorrectionLevel();
48
-
49
- /**
50
- * @return string
51
- */
52
- public function getLogoPath();
53
-
54
- /**
55
- * @return int
56
- */
57
- public function getLogoWidth();
58
-
59
- /**
60
- * @return string
61
- */
62
- public function getLabel();
63
-
64
- /**
65
- * @return string
66
- */
67
- public function getLabelFontPath();
68
-
69
- /**
70
- * @return int
71
- */
72
- public function getLabelFontSize();
73
-
74
- /**
75
- * @return string
76
- */
77
- public function getLabelAlignment();
78
-
79
- /**
80
- * @return int[]
81
- */
82
- public function getLabelMargin();
83
-
84
- /**
85
- * @return bool
86
- */
87
- public function getValidateResult();
88
-
89
- /**
90
- * @param WriterRegistryInterface $writerRegistry
91
- *
92
- * @return mixed
93
- */
94
- public function setWriterRegistry(WriterRegistryInterface $writerRegistry);
95
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/endroid/qr-code/src/StaticWriterRegistry.php DELETED
@@ -1,42 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * (c) Jeroen van den Enden <info@endroid.nl>
5
- *
6
- * This source file is subject to the MIT license that is bundled
7
- * with this source code in the file LICENSE.
8
- */
9
-
10
- namespace Endroid\QrCode;
11
-
12
- use Endroid\QrCode\Writer\BinaryWriter;
13
- use Endroid\QrCode\Writer\DebugWriter;
14
- use Endroid\QrCode\Writer\EpsWriter;
15
- use Endroid\QrCode\Writer\PngWriter;
16
- use Endroid\QrCode\Writer\SvgWriter;
17
-
18
- class StaticWriterRegistry extends WriterRegistry
19
- {
20
- /**
21
- * {@inheritdoc}
22
- */
23
- public function __construct()
24
- {
25
- parent::__construct();
26
-
27
- $this->loadWriters();
28
- }
29
-
30
- protected function loadWriters()
31
- {
32
- if (count($this->writers) > 0) {
33
- return;
34
- }
35
-
36
- $this->addWriter(new BinaryWriter());
37
- $this->addWriter(new DebugWriter());
38
- $this->addWriter(new EpsWriter());
39
- $this->addWriter(new PngWriter(), true);
40
- $this->addWriter(new SvgWriter());
41
- }
42
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/endroid/qr-code/src/Twig/Extension/QrCodeExtension.php DELETED
@@ -1,117 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * (c) Jeroen van den Enden <info@endroid.nl>
5
- *
6
- * This source file is subject to the MIT license that is bundled
7
- * with this source code in the file LICENSE.
8
- */
9
-
10
- namespace Endroid\QrCode\Twig\Extension;
11
-
12
- use Endroid\QrCode\Exception\UnsupportedExtensionException;
13
- use Endroid\QrCode\Factory\QrCodeFactory;
14
- use Endroid\QrCode\WriterRegistryInterface;
15
- use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
16
- use Symfony\Component\Routing\RouterInterface;
17
- use Twig_Extension;
18
- use Twig_SimpleFunction;
19
-
20
- class QrCodeExtension extends Twig_Extension
21
- {
22
- /**
23
- * @var QrCodeFactory
24
- */
25
- protected $qrCodeFactory;
26
-
27
- /**
28
- * @var RouterInterface
29
- */
30
- protected $router;
31
-
32
- /**
33
- * @param QrCodeFactory $qrCodeFactory
34
- * @param RouterInterface $router
35
- * @param WriterRegistryInterface $writerRegistry
36
- */
37
- public function __construct(QrCodeFactory $qrCodeFactory, RouterInterface $router)
38
- {
39
- $this->qrCodeFactory = $qrCodeFactory;
40
- $this->router = $router;
41
- }
42
-
43
- /**
44
- * {@inheritdoc}
45
- */
46
- public function getFunctions()
47
- {
48
- return [
49
- new Twig_SimpleFunction('qrcode_path', [$this, 'qrCodePathFunction']),
50
- new Twig_SimpleFunction('qrcode_url', [$this, 'qrCodeUrlFunction']),
51
- new Twig_SimpleFunction('qrcode_data_uri', [$this, 'qrCodeDataUriFunction']),
52
- ];
53
- }
54
-
55
- /**
56
- * @param string $text
57
- * @param array $options
58
- *
59
- * @return string
60
- */
61
- public function qrcodeUrlFunction($text, array $options = [])
62
- {
63
- return $this->getQrCodeReference($text, $options, UrlGeneratorInterface::ABSOLUTE_URL);
64
- }
65
-
66
- /**
67
- * @param string $text
68
- * @param array $options
69
- *
70
- * @return string
71
- */
72
- public function qrCodePathFunction($text, array $options = [])
73
- {
74
- return $this->getQrCodeReference($text, $options, UrlGeneratorInterface::ABSOLUTE_PATH);
75
- }
76
-
77
- /**
78
- * @param string $text
79
- * @param array $options
80
- * @param int $referenceType
81
- *
82
- * @return string
83
- */
84
- public function getQrCodeReference($text, array $options = [], $referenceType)
85
- {
86
- $qrCode = $this->qrCodeFactory->create($text, $options);
87
- $supportedExtensions = $qrCode->getWriter()->getSupportedExtensions();
88
-
89
- $options['text'] = $text;
90
- $options['extension'] = current($supportedExtensions);
91
-
92
- return $this->router->generate('endroid_qrcode_generate', $options, $referenceType);
93
- }
94
-
95
- /**
96
- * @param string $text
97
- * @param array $options
98
- *
99
- * @return string
100
- *
101
- * @throws UnsupportedExtensionException
102
- */
103
- public function qrcodeDataUriFunction($text, array $options = [])
104
- {
105
- $qrCode = $this->qrCodeFactory->create($text, $options);
106
-
107
- return $qrCode->writeDataUri();
108
- }
109
-
110
- /**
111
- * @return string
112
- */
113
- public function getName()
114
- {
115
- return 'qrcode';
116
- }
117
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/endroid/qr-code/src/Writer/AbstractBaconWriter.php DELETED
@@ -1,40 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * (c) Jeroen van den Enden <info@endroid.nl>
5
- *
6
- * This source file is subject to the MIT license that is bundled
7
- * with this source code in the file LICENSE.
8
- */
9
-
10
- namespace Endroid\QrCode\Writer;
11
-
12
- use BaconQrCode\Renderer\Color\Rgb;
13
-
14
- abstract class AbstractBaconWriter extends AbstractWriter
15
- {
16
- /**
17
- * @param array $color
18
- *
19
- * @return Rgb
20
- */
21
- protected function convertColor(array $color)
22
- {
23
- $color = new Rgb($color['r'], $color['g'], $color['b']);
24
-
25
- return $color;
26
- }
27
-
28
- /**
29
- * @param string $errorCorrectionLevel
30
- *
31
- * @return string
32
- */
33
- protected function convertErrorCorrectionLevel($errorCorrectionLevel)
34
- {
35
- $name = strtoupper(substr($errorCorrectionLevel, 0, 1));
36
- $errorCorrectionLevel = constant('BaconQrCode\Common\ErrorCorrectionLevel::'.$name);
37
-
38
- return $errorCorrectionLevel;
39
- }
40
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/endroid/qr-code/src/Writer/AbstractWriter.php DELETED
@@ -1,63 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * (c) Jeroen van den Enden <info@endroid.nl>
5
- *
6
- * This source file is subject to the MIT license that is bundled
7
- * with this source code in the file LICENSE.
8
- */
9
-
10
- namespace Endroid\QrCode\Writer;
11
-
12
- use Endroid\QrCode\QrCodeInterface;
13
- use ReflectionClass;
14
-
15
- abstract class AbstractWriter implements WriterInterface
16
- {
17
- /**
18
- * {@inheritdoc}
19
- */
20
- public function writeDataUri(QrCodeInterface $qrCode)
21
- {
22
- $dataUri = 'data:'.$this->getContentType().';base64,'.base64_encode($this->writeString($qrCode));
23
-
24
- return $dataUri;
25
- }
26
-
27
- /**
28
- * {@inheritdoc}
29
- */
30
- public function writeFile(QrCodeInterface $qrCode, $path)
31
- {
32
- $string = $this->writeString($qrCode);
33
- file_put_contents($path, $string);
34
- }
35
-
36
- /**
37
- * {@inheritdoc}
38
- */
39
- public static function supportsExtension($extension)
40
- {
41
- return in_array($extension, static::getSupportedExtensions());
42
- }
43
-
44
- /**
45
- * {@inheritdoc}
46
- */
47
- public static function getSupportedExtensions()
48
- {
49
- return [];
50
- }
51
-
52
- /**
53
- * {@inheritdoc}
54
- */
55
- public function getName()
56
- {
57
- $reflectionClass = new ReflectionClass($this);
58
- $className = $reflectionClass->getShortName();
59
- $name = strtolower(preg_replace('/(?<!^)[A-Z]/', '_$0', str_replace('Writer', '', $className)));
60
-
61
- return $name;
62
- }
63
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/endroid/qr-code/src/Writer/BinaryWriter.php DELETED
@@ -1,52 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * (c) Jeroen van den Enden <info@endroid.nl>
5
- *
6
- * This source file is subject to the MIT license that is bundled
7
- * with this source code in the file LICENSE.
8
- */
9
-
10
- namespace Endroid\QrCode\Writer;
11
-
12
- use Endroid\QrCode\QrCodeInterface;
13
-
14
- class BinaryWriter extends AbstractWriter
15
- {
16
- /**
17
- * {@inheritdoc}
18
- */
19
- public function writeString(QrCodeInterface $qrCode)
20
- {
21
- $string = '
22
- 0001010101
23
- 0001010101
24
- 1000101010
25
- 0001010101
26
- 0101010101
27
- 0001010101
28
- 0001010101
29
- 0001010101
30
- 0001010101
31
- 1000101010
32
- ';
33
-
34
- return $string;
35
- }
36
-
37
- /**
38
- * {@inheritdoc}
39
- */
40
- public static function getContentType()
41
- {
42
- return 'text/plain';
43
- }
44
-
45
- /**
46
- * {@inheritdoc}
47
- */
48
- public static function getSupportedExtensions()
49
- {
50
- return ['bin', 'txt'];
51
- }
52
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/endroid/qr-code/src/Writer/DebugWriter.php DELETED
@@ -1,58 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * (c) Jeroen van den Enden <info@endroid.nl>
5
- *
6
- * This source file is subject to the MIT license that is bundled
7
- * with this source code in the file LICENSE.
8
- */
9
-
10
- namespace Endroid\QrCode\Writer;
11
-
12
- use Endroid\QrCode\QrCodeInterface;
13
- use ReflectionClass;
14
- use Exception;
15
-
16
- class DebugWriter extends AbstractWriter
17
- {
18
- /**
19
- * {@inheritdoc}
20
- */
21
- public function writeString(QrCodeInterface $qrCode)
22
- {
23
- $data = [];
24
-
25
- $reflectionClass = new ReflectionClass($qrCode);
26
- foreach ($reflectionClass->getMethods() as $method) {
27
- $methodName = $method->getShortName();
28
- if (0 === strpos($methodName, 'get') && 0 == $method->getNumberOfParameters()) {
29
- $value = $qrCode->{$methodName}();
30
- if (is_array($value) && !is_object(current($value))) {
31
- $value = '['.implode(', ', $value).']';
32
- } elseif (is_bool($value)) {
33
- $value = $value ? 'true' : 'false';
34
- } elseif (is_string($value)) {
35
- $value = '"'.$value.'"';
36
- } elseif (is_null($value)) {
37
- $value = 'null';
38
- }
39
- try {
40
- $data[] = $methodName.': '.$value;
41
- } catch (Exception $exception) {
42
- }
43
- }
44
- }
45
-
46
- $string = implode(" \n", $data);
47
-
48
- return $string;
49
- }
50
-
51
- /**
52
- * {@inheritdoc}
53
- */
54
- public static function getContentType()
55
- {
56
- return 'text/plain';
57
- }
58
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/endroid/qr-code/src/Writer/EpsWriter.php DELETED
@@ -1,98 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * (c) Jeroen van den Enden <info@endroid.nl>
5
- *
6
- * This source file is subject to the MIT license that is bundled
7
- * with this source code in the file LICENSE.
8
- */
9
-
10
- namespace Endroid\QrCode\Writer;
11
-
12
- use BaconQrCode\Renderer\Image\Eps;
13
- use BaconQrCode\Writer;
14
- use Endroid\QrCode\QrCodeInterface;
15
-
16
- class EpsWriter extends AbstractBaconWriter
17
- {
18
- /**
19
- * {@inheritdoc}
20
- */
21
- public function writeString(QrCodeInterface $qrCode)
22
- {
23
- $renderer = new Eps();
24
- $renderer->setWidth($qrCode->getSize());
25
- $renderer->setHeight($qrCode->getSize());
26
- $renderer->setMargin(0);
27
- $renderer->setForegroundColor($this->convertColor($qrCode->getForegroundColor()));
28
- $renderer->setBackgroundColor($this->convertColor($qrCode->getBackgroundColor()));
29
-
30
- $writer = new Writer($renderer);
31
- $string = $writer->writeString($qrCode->getText(), $qrCode->getEncoding(), $this->convertErrorCorrectionLevel($qrCode->getErrorCorrectionLevel()));
32
-
33
- $string = $this->addMargin($string, $qrCode);
34
-
35
- return $string;
36
- }
37
-
38
- /**
39
- * @param string $string
40
- * @param QrCodeInterface $qrCode
41
- *
42
- * @return string
43
- */
44
- protected function addMargin($string, QrCodeInterface $qrCode)
45
- {
46
- $targetSize = $qrCode->getSize() + $qrCode->getMargin() * 2;
47
-
48
- $lines = explode("\n", $string);
49
-
50
- $sourceBlockSize = 0;
51
- $additionalWhitespace = $qrCode->getSize();
52
- foreach ($lines as $line) {
53
- if (preg_match('#[0-9]+ [0-9]+ [0-9]+ [0-9]+ F#i', $line) && false === strpos($line, $qrCode->getSize().' '.$qrCode->getSize().' F')) {
54
- $parts = explode(' ', $line);
55
- $sourceBlockSize = $parts[2];
56
- $additionalWhitespace = min($additionalWhitespace, $parts[0]);
57
- }
58
- }
59
-
60
- $blockCount = ($qrCode->getSize() - 2 * $additionalWhitespace) / $sourceBlockSize;
61
- $targetBlockSize = $qrCode->getSize() / $blockCount;
62
-
63
- foreach ($lines as &$line) {
64
- if (false !== strpos($line, 'BoundingBox')) {
65
- $line = '%%BoundingBox: 0 0 '.$targetSize.' '.$targetSize;
66
- } elseif (false !== strpos($line, $qrCode->getSize().' '.$qrCode->getSize().' F')) {
67
- $line = '0 0 '.$targetSize.' '.$targetSize.' F';
68
- } elseif (preg_match('#[0-9]+ [0-9]+ [0-9]+ [0-9]+ F#i', $line)) {
69
- $parts = explode(' ', $line);
70
- $parts[0] = $qrCode->getMargin() + $targetBlockSize * ($parts[0] - $additionalWhitespace) / $sourceBlockSize;
71
- $parts[1] = $qrCode->getMargin() + $targetBlockSize * ($parts[1] - $sourceBlockSize - $additionalWhitespace) / $sourceBlockSize;
72
- $parts[2] = $targetBlockSize;
73
- $parts[3] = $targetBlockSize;
74
- $line = implode(' ', $parts);
75
- }
76
- }
77
-
78
- $string = implode("\n", $lines);
79
-
80
- return $string;
81
- }
82
-
83
- /**
84
- * {@inheritdoc}
85
- */
86
- public static function getContentType()
87
- {
88
- return 'image/eps';
89
- }
90
-
91
- /**
92
- * {@inheritdoc}
93
- */
94
- public static function getSupportedExtensions()
95
- {
96
- return ['eps'];
97
- }
98
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/endroid/qr-code/src/Writer/PngWriter.php DELETED
@@ -1,228 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * (c) Jeroen van den Enden <info@endroid.nl>
5
- *
6
- * This source file is subject to the MIT license that is bundled
7
- * with this source code in the file LICENSE.
8
- */
9
-
10
- namespace Endroid\QrCode\Writer;
11
-
12
- use BaconQrCode\Renderer\Image\Png;
13
- use BaconQrCode\Writer;
14
- use Endroid\QrCode\Exception\MissingFunctionException;
15
- use Endroid\QrCode\Exception\ValidationException;
16
- use Endroid\QrCode\LabelAlignment;
17
- use Endroid\QrCode\QrCodeInterface;
18
- use QrReader;
19
-
20
- class PngWriter extends AbstractBaconWriter
21
- {
22
- /**
23
- * {@inheritdoc}
24
- */
25
- public function writeString(QrCodeInterface $qrCode)
26
- {
27
- $renderer = new Png();
28
- $renderer->setWidth($qrCode->getSize());
29
- $renderer->setHeight($qrCode->getSize());
30
- $renderer->setMargin(0);
31
- $renderer->setForegroundColor($this->convertColor($qrCode->getForegroundColor()));
32
- $renderer->setBackgroundColor($this->convertColor($qrCode->getBackgroundColor()));
33
-
34
- $writer = new Writer($renderer);
35
- $string = $writer->writeString($qrCode->getText(), $qrCode->getEncoding(), $this->convertErrorCorrectionLevel($qrCode->getErrorCorrectionLevel()));
36
-
37
- $image = imagecreatefromstring($string);
38
- $image = $this->addMargin($image, $qrCode->getMargin(), $qrCode->getSize(), $qrCode->getForegroundColor(), $qrCode->getBackgroundColor());
39
-
40
- if ($qrCode->getLogoPath()) {
41
- $image = $this->addLogo($image, $qrCode->getLogoPath(), $qrCode->getLogoWidth());
42
- }
43
-
44
- if ($qrCode->getLabel()) {
45
- $image = $this->addLabel($image, $qrCode->getLabel(), $qrCode->getLabelFontPath(), $qrCode->getLabelFontSize(), $qrCode->getLabelAlignment(), $qrCode->getLabelMargin(), $qrCode->getForegroundColor(), $qrCode->getBackgroundColor());
46
- }
47
-
48
- $string = $this->imageToString($image);
49
-
50
- if ($qrCode->getValidateResult()) {
51
- $reader = new QrReader($string, QrReader::SOURCE_TYPE_BLOB);
52
- if ($reader->text() !== $qrCode->getText()) {
53
- throw new ValidationException(
54
- 'Built-in validation reader read "'.$reader->text().'" instead of "'.$qrCode->getText().'".
55
- Adjust your parameters to increase readability or disable built-in validation.');
56
- }
57
- }
58
-
59
- return $string;
60
- }
61
-
62
- /**
63
- * @param resource $sourceImage
64
- * @param int $margin
65
- * @param int $size
66
- * @param int[] $foregroundColor
67
- * @param int[] $backgroundColor
68
- *
69
- * @return resource
70
- */
71
- protected function addMargin($sourceImage, $margin, $size, array $foregroundColor, array $backgroundColor)
72
- {
73
- $additionalWhitespace = $this->calculateAdditionalWhiteSpace($sourceImage, $foregroundColor);
74
-
75
- if (0 == $additionalWhitespace && 0 == $margin) {
76
- return $sourceImage;
77
- }
78
-
79
- $targetImage = imagecreatetruecolor($size + $margin * 2, $size + $margin * 2);
80
- $backgroundColor = imagecolorallocate($targetImage, $backgroundColor['r'], $backgroundColor['g'], $backgroundColor['b']);
81
- imagefill($targetImage, 0, 0, $backgroundColor);
82
- imagecopyresampled($targetImage, $sourceImage, $margin, $margin, $additionalWhitespace, $additionalWhitespace, $size, $size, $size - 2 * $additionalWhitespace, $size - 2 * $additionalWhitespace);
83
-
84
- return $targetImage;
85
- }
86
-
87
- /**
88
- * @param resource $image
89
- * @param int[] $foregroundColor
90
- *
91
- * @return int
92
- */
93
- protected function calculateAdditionalWhiteSpace($image, array $foregroundColor)
94
- {
95
- $width = imagesx($image);
96
- $height = imagesy($image);
97
-
98
- $foregroundColor = imagecolorallocate($image, $foregroundColor['r'], $foregroundColor['g'], $foregroundColor['b']);
99
-
100
- $whitespace = $width;
101
- for ($y = 0; $y < $height; ++$y) {
102
- for ($x = 0; $x < $width; ++$x) {
103
- $color = imagecolorat($image, $x, $y);
104
- if ($color == $foregroundColor || $x == $whitespace) {
105
- $whitespace = min($whitespace, $x);
106
- break;
107
- }
108
- }
109
- }
110
-
111
- return $whitespace;
112
- }
113
-
114
- /**
115
- * @param resource $sourceImage
116
- * @param string $logoPath
117
- * @param int $logoWidth
118
- *
119
- * @return resource
120
- */
121
- protected function addLogo($sourceImage, $logoPath, $logoWidth = null)
122
- {
123
- $logoImage = imagecreatefromstring(file_get_contents($logoPath));
124
- $logoSourceWidth = imagesx($logoImage);
125
- $logoSourceHeight = imagesy($logoImage);
126
- $logoTargetWidth = $logoWidth;
127
-
128
- if (null === $logoTargetWidth) {
129
- $logoTargetWidth = $logoSourceWidth;
130
- $logoTargetHeight = $logoSourceHeight;
131
- } else {
132
- $scale = $logoTargetWidth / $logoSourceWidth;
133
- $logoTargetHeight = intval($scale * imagesy($logoImage));
134
- }
135
-
136
- $logoX = imagesx($sourceImage) / 2 - $logoTargetWidth / 2;
137
- $logoY = imagesy($sourceImage) / 2 - $logoTargetHeight / 2;
138
- imagecopyresampled($sourceImage, $logoImage, $logoX, $logoY, 0, 0, $logoTargetWidth, $logoTargetHeight, $logoSourceWidth, $logoSourceHeight);
139
-
140
- return $sourceImage;
141
- }
142
-
143
- /**
144
- * @param resource $sourceImage
145
- * @param string $label
146
- * @param string $labelFontPath
147
- * @param int $labelFontSize
148
- * @param string $labelAlignment
149
- * @param int[] $labelMargin
150
- * @param int[] $foregroundColor
151
- * @param int[] $backgroundColor
152
- *
153
- * @return resource
154
- *
155
- * @throws MissingFunctionException
156
- */
157
- protected function addLabel($sourceImage, $label, $labelFontPath, $labelFontSize, $labelAlignment, $labelMargin, array $foregroundColor, array $backgroundColor)
158
- {
159
- if (!function_exists('imagettfbbox')) {
160
- throw new MissingFunctionException('Missing function "imagettfbbox". Did you install the FreeType library?');
161
- }
162
-
163
- $labelBox = imagettfbbox($labelFontSize, 0, $labelFontPath, $label);
164
- $labelBoxWidth = intval($labelBox[2] - $labelBox[0]);
165
- $labelBoxHeight = intval($labelBox[0] - $labelBox[7]);
166
-
167
- $sourceWidth = imagesx($sourceImage);
168
- $sourceHeight = imagesy($sourceImage);
169
- $targetWidth = $sourceWidth;
170
- $targetHeight = $sourceHeight + $labelBoxHeight + $labelMargin['t'] + $labelMargin['b'];
171
-
172
- // Create empty target image
173
- $targetImage = imagecreatetruecolor($targetWidth, $targetHeight);
174
- $foregroundColor = imagecolorallocate($targetImage, $foregroundColor['r'], $foregroundColor['g'], $foregroundColor['b']);
175
- $backgroundColor = imagecolorallocate($targetImage, $backgroundColor['r'], $backgroundColor['g'], $backgroundColor['b']);
176
- imagefill($targetImage, 0, 0, $backgroundColor);
177
-
178
- // Copy source image to target image
179
- imagecopyresampled($targetImage, $sourceImage, 0, 0, 0, 0, $sourceWidth, $sourceHeight, $sourceWidth, $sourceHeight);
180
-
181
- switch ($labelAlignment) {
182
- case LabelAlignment::LEFT:
183
- $labelX = $labelMargin['l'];
184
- break;
185
- case LabelAlignment::RIGHT:
186
- $labelX = $targetWidth - $labelBoxWidth - $labelMargin['r'];
187
- break;
188
- default:
189
- $labelX = intval($targetWidth / 2 - $labelBoxWidth / 2);
190
- break;
191
- }
192
-
193
- $labelY = $targetHeight - $labelMargin['b'];
194
- imagettftext($targetImage, $labelFontSize, 0, $labelX, $labelY, $foregroundColor, $labelFontPath, $label);
195
-
196
- return $targetImage;
197
- }
198
-
199
- /**
200
- * @param resource $image
201
- *
202
- * @return string
203
- */
204
- protected function imageToString($image)
205
- {
206
- ob_start();
207
- imagepng($image);
208
- $string = ob_get_clean();
209
-
210
- return $string;
211
- }
212
-
213
- /**
214
- * {@inheritdoc}
215
- */
216
- public static function getContentType()
217
- {
218
- return 'image/png';
219
- }
220
-
221
- /**
222
- * {@inheritdoc}
223
- */
224
- public static function getSupportedExtensions()
225
- {
226
- return ['png'];
227
- }
228
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/endroid/qr-code/src/Writer/SvgWriter.php DELETED
@@ -1,92 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * (c) Jeroen van den Enden <info@endroid.nl>
5
- *
6
- * This source file is subject to the MIT license that is bundled
7
- * with this source code in the file LICENSE.
8
- */
9
-
10
- namespace Endroid\QrCode\Writer;
11
-
12
- use BaconQrCode\Renderer\Image\Svg;
13
- use BaconQrCode\Writer;
14
- use Endroid\QrCode\QrCodeInterface;
15
- use SimpleXMLElement;
16
-
17
- class SvgWriter extends AbstractBaconWriter
18
- {
19
- /**
20
- * {@inheritdoc}
21
- */
22
- public function writeString(QrCodeInterface $qrCode)
23
- {
24
- $renderer = new Svg();
25
- $renderer->setWidth($qrCode->getSize());
26
- $renderer->setHeight($qrCode->getSize());
27
- $renderer->setMargin(0);
28
- $renderer->setForegroundColor($this->convertColor($qrCode->getForegroundColor()));
29
- $renderer->setBackgroundColor($this->convertColor($qrCode->getBackgroundColor()));
30
-
31
- $writer = new Writer($renderer);
32
- $string = $writer->writeString($qrCode->getText(), $qrCode->getEncoding(), $this->convertErrorCorrectionLevel($qrCode->getErrorCorrectionLevel()));
33
-
34
- $string = $this->addMargin($string, $qrCode->getMargin(), $qrCode->getSize());
35
-
36
- return $string;
37
- }
38
-
39
- /**
40
- * @param string $string
41
- * @param int $margin
42
- * @param int $size
43
- *
44
- * @return string
45
- */
46
- protected function addMargin($string, $margin, $size)
47
- {
48
- $targetSize = $size + $margin * 2;
49
-
50
- $xml = new SimpleXMLElement($string);
51
- $xml['width'] = $targetSize;
52
- $xml['height'] = $targetSize;
53
- $xml['viewBox'] = '0 0 '.$targetSize.' '.$targetSize;
54
- $xml->rect['width'] = $targetSize;
55
- $xml->rect['height'] = $targetSize;
56
-
57
- $additionalWhitespace = $targetSize;
58
- foreach ($xml->use as $block) {
59
- $additionalWhitespace = min($additionalWhitespace, (int) $block['x']);
60
- }
61
-
62
- $sourceBlockSize = (int) $xml->defs->rect['width'];
63
- $blockCount = ($size - 2 * $additionalWhitespace) / $sourceBlockSize;
64
- $targetBlockSize = $size / $blockCount;
65
-
66
- $xml->defs->rect['width'] = $targetBlockSize;
67
- $xml->defs->rect['height'] = $targetBlockSize;
68
-
69
- foreach ($xml->use as $block) {
70
- $block['x'] = $margin + $targetBlockSize * ($block['x'] - $additionalWhitespace) / $sourceBlockSize;
71
- $block['y'] = $margin + $targetBlockSize * ($block['y'] - $additionalWhitespace) / $sourceBlockSize;
72
- }
73
-
74
- return $xml->asXML();
75
- }
76
-
77
- /**
78
- * {@inheritdoc}
79
- */
80
- public static function getContentType()
81
- {
82
- return 'image/svg+xml';
83
- }
84
-
85
- /**
86
- * {@inheritdoc}
87
- */
88
- public static function getSupportedExtensions()
89
- {
90
- return ['svg'];
91
- }
92
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/endroid/qr-code/src/Writer/WriterInterface.php DELETED
@@ -1,57 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * (c) Jeroen van den Enden <info@endroid.nl>
5
- *
6
- * This source file is subject to the MIT license that is bundled
7
- * with this source code in the file LICENSE.
8
- */
9
-
10
- namespace Endroid\QrCode\Writer;
11
-
12
- use Endroid\QrCode\QrCodeInterface;
13
-
14
- interface WriterInterface
15
- {
16
- /**
17
- * @param QrCodeInterface $qrCode
18
- *
19
- * @return string
20
- */
21
- public function writeString(QrCodeInterface $qrCode);
22
-
23
- /**
24
- * @param QrCodeInterface $qrCode
25
- *
26
- * @return string
27
- */
28
- public function writeDataUri(QrCodeInterface $qrCode);
29
-
30
- /**
31
- * @param QrCodeInterface $qrCode
32
- * @param string $path
33
- */
34
- public function writeFile(QrCodeInterface $qrCode, $path);
35
-
36
- /**
37
- * @return string
38
- */
39
- public static function getContentType();
40
-
41
- /**
42
- * @param string $extension
43
- *
44
- * @return bool
45
- */
46
- public static function supportsExtension($extension);
47
-
48
- /**
49
- * @return string[]
50
- */
51
- public static function getSupportedExtensions();
52
-
53
- /**
54
- * @return string
55
- */
56
- public function getName();
57
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/endroid/qr-code/src/WriterRegistry.php DELETED
@@ -1,89 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * (c) Jeroen van den Enden <info@endroid.nl>
5
- *
6
- * This source file is subject to the MIT license that is bundled
7
- * with this source code in the file LICENSE.
8
- */
9
-
10
- namespace Endroid\QrCode;
11
-
12
- use Endroid\QrCode\Exception\InvalidWriterException;
13
- use Endroid\QrCode\Writer\WriterInterface;
14
-
15
- class WriterRegistry implements WriterRegistryInterface
16
- {
17
- /**
18
- * @var WriterInterface[]
19
- */
20
- protected $writers;
21
-
22
- /**
23
- * @var WriterInterface
24
- */
25
- protected $defaultWriter;
26
-
27
- public function __construct()
28
- {
29
- $this->writers = [];
30
- }
31
-
32
- /**
33
- * {@inheritdoc}
34
- */
35
- public function addWriter(WriterInterface $writer, $setAsDefault = false)
36
- {
37
- $this->writers[$writer->getName()] = $writer;
38
-
39
- if ($setAsDefault || 1 === count($this->writers)) {
40
- $this->defaultWriter = $writer;
41
- }
42
- }
43
-
44
- /**
45
- * @param $name
46
- *
47
- * @return WriterInterface
48
- */
49
- public function getWriter($name)
50
- {
51
- $this->assertValidWriter($name);
52
-
53
- return $this->writers[$name];
54
- }
55
-
56
- /**
57
- * @return WriterInterface
58
- *
59
- * @throws InvalidWriterException
60
- */
61
- public function getDefaultWriter()
62
- {
63
- if ($this->defaultWriter instanceof WriterInterface) {
64
- return $this->defaultWriter;
65
- }
66
-
67
- throw new InvalidWriterException('Please set the default writer via the second argument of addWriter');
68
- }
69
-
70
- /**
71
- * @return WriterInterface[]
72
- */
73
- public function getWriters()
74
- {
75
- return $this->writers;
76
- }
77
-
78
- /**
79
- * @param string $writer
80
- *
81
- * @throws InvalidWriterException
82
- */
83
- protected function assertValidWriter($writer)
84
- {
85
- if (!isset($this->writers[$writer])) {
86
- throw new InvalidWriterException('Invalid writer "'.$writer.'"');
87
- }
88
- }
89
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/endroid/qr-code/src/WriterRegistryInterface.php DELETED
@@ -1,34 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * (c) Jeroen van den Enden <info@endroid.nl>
5
- *
6
- * This source file is subject to the MIT license that is bundled
7
- * with this source code in the file LICENSE.
8
- */
9
-
10
- namespace Endroid\QrCode;
11
-
12
- use Endroid\QrCode\Writer\WriterInterface;
13
-
14
- interface WriterRegistryInterface
15
- {
16
- /**
17
- * @param WriterInterface $writer
18
- *
19
- * @return $this
20
- */
21
- public function addWriter(WriterInterface $writer);
22
-
23
- /**
24
- * @param $name
25
- *
26
- * @return WriterInterface
27
- */
28
- public function getWriter($name);
29
-
30
- /**
31
- * @return WriterInterface[]
32
- */
33
- public function getWriters();
34
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Base/BaseQuery.php CHANGED
@@ -3,6 +3,7 @@
3
  namespace FernleafSystems\Wordpress\Plugin\Core\Databases\Base;
4
 
5
  use Carbon\Carbon;
 
6
  use FernleafSystems\Wordpress\Services\Services;
7
 
8
  abstract class BaseQuery {
@@ -54,16 +55,37 @@ abstract class BaseQuery {
54
  protected function customInit() {
55
  }
56
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
  /**
58
  * @param string $column
59
  * @param string|array $value
60
  * @param string $operator
61
  * @return $this
62
  */
63
- public function addWhere( $column, $value, $operator = '=' ) {
64
  if ( !$this->isValidComparisonOperator( $operator ) ) {
65
  return $this; // Exception?
66
  }
 
 
 
 
67
 
68
  if ( is_array( $value ) ) {
69
  $value = array_map( 'esc_sql', $value );
@@ -78,13 +100,16 @@ abstract class BaseQuery {
78
  }
79
  }
80
 
81
- $rawWheres = $this->getRawWheres();
82
- $rawWheres[] = [
83
- esc_sql( $column ),
84
- $operator,
85
- $value
86
- ];
87
 
 
 
 
 
 
 
 
88
  return $this->setRawWheres( $rawWheres );
89
  }
90
 
@@ -139,19 +164,16 @@ abstract class BaseQuery {
139
  }
140
 
141
  /**
142
- * @param string $sColumn
143
- * @param mixed $mValue
144
  * @return $this
145
  */
146
- public function addWhereSearch( $sColumn, $mValue ) {
147
- return $this->addWhere( $sColumn, $mValue, 'LIKE' );
148
  }
149
 
150
- /**
151
- * @return string
152
- */
153
- public function buildExtras() {
154
- $aExtras = array_filter(
155
  [
156
  $this->getGroupBy(),
157
  $this->buildOrderBy(),
@@ -159,20 +181,14 @@ abstract class BaseQuery {
159
  $this->buildOffsetPhrase(),
160
  ]
161
  );
162
- return implode( "\n", $aExtras );
163
  }
164
 
165
- /**
166
- * @return string
167
- */
168
- public function buildLimitPhrase() {
169
  return $this->hasLimit() ? sprintf( 'LIMIT %s', $this->getLimit() ) : '';
170
  }
171
 
172
- /**
173
- * @return string
174
- */
175
- protected function buildOffsetPhrase() {
176
  return $this->hasLimit() ? sprintf( 'OFFSET %s', $this->getOffset() ) : '';
177
  }
178
 
@@ -190,18 +206,17 @@ abstract class BaseQuery {
190
  return (int)$this->getLimit()*( $this->getPage() - 1 );
191
  }
192
 
193
- /**
194
- * @return string
195
- */
196
- public function buildWhere() {
197
- $wheres = $this->getRawWheres();
198
- if ( !$this->isIncludeSoftDeletedRows() ) {
199
- $wheres[] = [ 'deleted_at', '=', 0 ];
200
- }
201
  $wheres = array_map( function ( array $where ) {
202
  return $this->rawWhereToString( $where );
203
  }, $wheres );
204
- return implode( ' AND ', $wheres );
 
205
  }
206
 
207
  public function buildQuery() :string {
@@ -238,7 +253,7 @@ abstract class BaseQuery {
238
  * @param int $ts
239
  * @return $this
240
  */
241
- public function filterByBoundary_Day( $ts ) {
242
  $carbon = ( new Carbon() )->setTimestamp( $ts );
243
  return $this->filterByBoundary( $carbon->startOfDay()->timestamp, $carbon->endOfDay()->timestamp );
244
  }
@@ -247,7 +262,7 @@ abstract class BaseQuery {
247
  * @param int $ts
248
  * @return $this
249
  */
250
- public function filterByBoundary_Hour( $ts ) {
251
  $carbon = ( new Carbon() )->setTimestamp( $ts );
252
  return $this->filterByBoundary( $carbon->startOfHour()->timestamp, $carbon->endOfHour()->timestamp );
253
  }
@@ -256,7 +271,7 @@ abstract class BaseQuery {
256
  * @param int $ts
257
  * @return $this
258
  */
259
- public function filterByBoundary_Month( $ts ) {
260
  $carbon = ( new Carbon() )->setTimestamp( $ts );
261
  return $this->filterByBoundary( $carbon->startOfMonth()->timestamp, $carbon->endOfMonth()->timestamp );
262
  }
@@ -265,7 +280,7 @@ abstract class BaseQuery {
265
  * @param int $ts
266
  * @return $this
267
  */
268
- public function filterByBoundary_Week( $ts ) {
269
  $carbon = ( new Carbon() )->setTimestamp( $ts );
270
  return $this->filterByBoundary( $carbon->startOfWeek()->timestamp, $carbon->endOfWeek()->timestamp );
271
  }
@@ -274,13 +289,21 @@ abstract class BaseQuery {
274
  * @param int $ts
275
  * @return $this
276
  */
277
- public function filterByBoundary_Year( $ts ) {
278
  $carbon = ( new Carbon() )->setTimestamp( $ts );
279
  return $this->filterByBoundary( $carbon->startOfYear()->timestamp, $carbon->endOfYear()->timestamp );
280
  }
281
 
 
 
 
 
 
 
 
 
282
  protected function getBaseQuery() :string {
283
- return "SELECT * FROM `%s` WHERE %s %s";
284
  }
285
 
286
  /**
@@ -291,7 +314,7 @@ abstract class BaseQuery {
291
  }
292
 
293
  /**
294
- * @param Handler $dbh
295
  * @return $this
296
  */
297
  public function setDbH( $dbh ) {
@@ -299,9 +322,17 @@ abstract class BaseQuery {
299
  return $this;
300
  }
301
 
 
 
 
 
302
  public function query() :bool {
 
 
 
 
303
  $this->lastQueryResult = Services::WpDb()->doSql( $this->buildQuery() );
304
- return ( $this->lastQueryResult === false ) ? false : $this->lastQueryResult > 0;
305
  }
306
 
307
  /**
@@ -326,15 +357,31 @@ abstract class BaseQuery {
326
  return is_array( $this->rawWheres ) ? $this->rawWheres : [];
327
  }
328
 
 
 
 
 
 
 
 
 
329
  public function getGroupBy() :string {
330
  return empty( $this->groupBy ) ? '' : sprintf( 'GROUP BY `%s`', $this->groupBy );
331
  }
332
 
333
  protected function buildOrderBy() :string {
334
  $order = '';
 
 
 
335
  if ( !is_array( $this->orderBys ) ) {
336
  // Defaults to created_at if aOrderBys is untouched. Set to empty array for no order
337
- $this->orderBys = [ 'created_at' => 'DESC' ];
 
 
 
 
 
338
  }
339
  if ( !empty( $this->orderBys ) ) {
340
  $orders = [];
@@ -359,7 +406,7 @@ abstract class BaseQuery {
359
  }
360
 
361
  protected function rawWhereToString( array $rawWhere ) :string {
362
- return vsprintf( '`%s` %s %s', $rawWhere );
363
  }
364
 
365
  /**
@@ -411,24 +458,21 @@ abstract class BaseQuery {
411
  * @return $this
412
  */
413
  public function setOrderBy( string $orderByColumn, $order = 'DESC', $replace = false ) {
414
- if ( empty( $orderByColumn ) ) {
415
- $this->orderBys = $orderByColumn;
416
  }
417
- else {
418
- if ( !is_array( $this->orderBys ) || $replace ) {
419
- $this->orderBys = [];
420
- }
421
  $this->orderBys[ $orderByColumn ] = $order;
422
  }
423
  return $this;
424
  }
425
 
426
  /**
427
- * @param int $nPage
428
  * @return $this
429
  */
430
- public function setPage( $nPage ) {
431
- $this->page = $nPage;
432
  return $this;
433
  }
434
 
@@ -454,13 +498,11 @@ abstract class BaseQuery {
454
 
455
  /**
456
  * Very basic
457
- * @param string $op
458
- * @return bool
459
  */
460
- protected function isValidComparisonOperator( $op ) {
461
  return in_array(
462
  strtoupper( $op ),
463
- [ '=', '<', '>', '!=', '<>', '<=', '>=', '<=>', 'IN', 'LIKE', 'NOT LIKE' ]
464
  );
465
  }
466
  }
3
  namespace FernleafSystems\Wordpress\Plugin\Core\Databases\Base;
4
 
5
  use Carbon\Carbon;
6
+ use FernleafSystems\Wordpress\Plugin\Core\Databases\Exceptions\ColumnDoesNotExistException;
7
  use FernleafSystems\Wordpress\Services\Services;
8
 
9
  abstract class BaseQuery {
55
  protected function customInit() {
56
  }
57
 
58
+ /**
59
+ * @param string $columnLeft
60
+ * @param string $columnRight
61
+ * @param string $operator
62
+ */
63
+ public function addWhereCompareColumns( string $columnLeft, string $columnRight, string $operator = '=' ) {
64
+ $schema = $this->getDbH()->getTableSchema();
65
+ if ( !$schema->hasColumn( $columnLeft ) ) {
66
+ throw new ColumnDoesNotExistException( sprintf( 'Column "%s" does not exist in this table', $columnLeft ) );
67
+ }
68
+ if ( !$schema->hasColumn( $columnRight ) ) {
69
+ throw new ColumnDoesNotExistException( sprintf( 'Column "%s" does not exist in this table', $columnRight ) );
70
+ }
71
+
72
+ return $this->addRawWhere( [ '`'.$columnLeft.'`', $operator, '`'.$columnRight.'`' ] );
73
+ }
74
+
75
  /**
76
  * @param string $column
77
  * @param string|array $value
78
  * @param string $operator
79
  * @return $this
80
  */
81
+ public function addWhere( string $column, $value, string $operator = '=' ) {
82
  if ( !$this->isValidComparisonOperator( $operator ) ) {
83
  return $this; // Exception?
84
  }
85
+ $schema = $this->getDbH()->getTableSchema();
86
+ if ( !$schema->hasColumn( $column ) ) {
87
+ throw new ColumnDoesNotExistException( sprintf( 'Column "%s" does not exist in this table', $column ) );
88
+ }
89
 
90
  if ( is_array( $value ) ) {
91
  $value = array_map( 'esc_sql', $value );
100
  }
101
  }
102
 
103
+ return $this->addRawWhere( [ '`'.$column.'`', $operator, $value ] );
104
+ }
 
 
 
 
105
 
106
+ /**
107
+ * @param array $where
108
+ * @return $this
109
+ */
110
+ public function addRawWhere( array $where ) {
111
+ $rawWheres = $this->getRawWheres();
112
+ $rawWheres[] = $where;
113
  return $this->setRawWheres( $rawWheres );
114
  }
115
 
164
  }
165
 
166
  /**
167
+ * @param string $column
168
+ * @param mixed $value
169
  * @return $this
170
  */
171
+ public function addWhereSearch( $column, $value ) {
172
+ return $this->addWhere( $column, $value, 'LIKE' );
173
  }
174
 
175
+ public function buildExtras() :string {
176
+ $extras = array_filter(
 
 
 
177
  [
178
  $this->getGroupBy(),
179
  $this->buildOrderBy(),
181
  $this->buildOffsetPhrase(),
182
  ]
183
  );
184
+ return implode( "\n", $extras );
185
  }
186
 
187
+ public function buildLimitPhrase() :string {
 
 
 
188
  return $this->hasLimit() ? sprintf( 'LIMIT %s', $this->getLimit() ) : '';
189
  }
190
 
191
+ protected function buildOffsetPhrase() :string {
 
 
 
192
  return $this->hasLimit() ? sprintf( 'OFFSET %s', $this->getOffset() ) : '';
193
  }
194
 
206
  return (int)$this->getLimit()*( $this->getPage() - 1 );
207
  }
208
 
209
+ public function buildWhere() :string {
210
+ $wheres = array_merge(
211
+ $this->getRawWheres(),
212
+ $this->getDynamicWheres()
213
+ );
214
+
 
 
215
  $wheres = array_map( function ( array $where ) {
216
  return $this->rawWhereToString( $where );
217
  }, $wheres );
218
+
219
+ return empty( $wheres ) ? '' : 'WHERE '.implode( ' AND ', $wheres );
220
  }
221
 
222
  public function buildQuery() :string {
253
  * @param int $ts
254
  * @return $this
255
  */
256
+ public function filterByBoundary_Day( int $ts ) {
257
  $carbon = ( new Carbon() )->setTimestamp( $ts );
258
  return $this->filterByBoundary( $carbon->startOfDay()->timestamp, $carbon->endOfDay()->timestamp );
259
  }
262
  * @param int $ts
263
  * @return $this
264
  */
265
+ public function filterByBoundary_Hour( int $ts ) {
266
  $carbon = ( new Carbon() )->setTimestamp( $ts );
267
  return $this->filterByBoundary( $carbon->startOfHour()->timestamp, $carbon->endOfHour()->timestamp );
268
  }
271
  * @param int $ts
272
  * @return $this
273
  */
274
+ public function filterByBoundary_Month( int $ts ) {
275
  $carbon = ( new Carbon() )->setTimestamp( $ts );
276
  return $this->filterByBoundary( $carbon->startOfMonth()->timestamp, $carbon->endOfMonth()->timestamp );
277
  }
280
  * @param int $ts
281
  * @return $this
282
  */
283
+ public function filterByBoundary_Week( int $ts ) {
284
  $carbon = ( new Carbon() )->setTimestamp( $ts );
285
  return $this->filterByBoundary( $carbon->startOfWeek()->timestamp, $carbon->endOfWeek()->timestamp );
286
  }
289
  * @param int $ts
290
  * @return $this
291
  */
292
+ public function filterByBoundary_Year( int $ts ) {
293
  $carbon = ( new Carbon() )->setTimestamp( $ts );
294
  return $this->filterByBoundary( $carbon->startOfYear()->timestamp, $carbon->endOfYear()->timestamp );
295
  }
296
 
297
+ /**
298
+ * @param array $ids
299
+ * @return $this
300
+ */
301
+ public function filterByIDs( array $ids ) {
302
+ return $this->addWhereIn( 'id', array_map( 'intval', $ids ) );
303
+ }
304
+
305
  protected function getBaseQuery() :string {
306
+ return "";
307
  }
308
 
309
  /**
314
  }
315
 
316
  /**
317
+ * @param Handler|mixed $dbh
318
  * @return $this
319
  */
320
  public function setDbH( $dbh ) {
322
  return $this;
323
  }
324
 
325
+ protected function preQuery() :bool {
326
+ return true;
327
+ }
328
+
329
  public function query() :bool {
330
+ return $this->preQuery() && $this->execQuerySql();
331
+ }
332
+
333
+ protected function execQuerySql() :bool {
334
  $this->lastQueryResult = Services::WpDb()->doSql( $this->buildQuery() );
335
+ return $this->lastQueryResult !== false && $this->lastQueryResult > 0;
336
  }
337
 
338
  /**
357
  return is_array( $this->rawWheres ) ? $this->rawWheres : [];
358
  }
359
 
360
+ public function getDynamicWheres() :array {
361
+ $wheres = [];
362
+ if ( !$this->isIncludeSoftDeletedRows() && $this->getDbH()->getTableSchema()->hasColumn( 'deleted_at' ) ) {
363
+ $wheres[] = [ 'deleted_at', '=', 0 ];
364
+ }
365
+ return $wheres;
366
+ }
367
+
368
  public function getGroupBy() :string {
369
  return empty( $this->groupBy ) ? '' : sprintf( 'GROUP BY `%s`', $this->groupBy );
370
  }
371
 
372
  protected function buildOrderBy() :string {
373
  $order = '';
374
+
375
+ $schema = $this->getDbH()->getTableSchema();
376
+
377
  if ( !is_array( $this->orderBys ) ) {
378
  // Defaults to created_at if aOrderBys is untouched. Set to empty array for no order
379
+ if ( $schema->hasColumn( 'created_at' ) ) {
380
+ $this->orderBys = [ 'created_at' => 'DESC' ];
381
+ }
382
+ else {
383
+ $this->orderBys = [ 'id' => 'DESC' ];
384
+ }
385
  }
386
  if ( !empty( $this->orderBys ) ) {
387
  $orders = [];
406
  }
407
 
408
  protected function rawWhereToString( array $rawWhere ) :string {
409
+ return vsprintf( '%s %s %s', $rawWhere );
410
  }
411
 
412
  /**
458
  * @return $this
459
  */
460
  public function setOrderBy( string $orderByColumn, $order = 'DESC', $replace = false ) {
461
+ if ( !is_array( $this->orderBys ) || $replace ) {
462
+ $this->orderBys = [];
463
  }
464
+ if ( $this->getDbH()->getTableSchema()->hasColumn( $orderByColumn ) ) {
 
 
 
465
  $this->orderBys[ $orderByColumn ] = $order;
466
  }
467
  return $this;
468
  }
469
 
470
  /**
471
+ * @param int $page
472
  * @return $this
473
  */
474
+ public function setPage( int $page ) {
475
+ $this->page = $page;
476
  return $this;
477
  }
478
 
498
 
499
  /**
500
  * Very basic
 
 
501
  */
502
+ protected function isValidComparisonOperator( string $op ) :bool {
503
  return in_array(
504
  strtoupper( $op ),
505
+ [ '=', '<', '>', '!=', '<>', '<=', '>=', '<=>', 'IN', 'NOT IN', 'LIKE', 'NOT LIKE' ]
506
  );
507
  }
508
  }
src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Delete.php CHANGED
@@ -8,7 +8,10 @@ class Delete extends BaseQuery {
8
 
9
  private $isSoftDelete = false;
10
 
11
- public function query() :bool {
 
 
 
12
  if ( $this->isSoftDelete && $this->getDbH()->getTableSchema()->hasColumn( 'deleted_at' ) ) {
13
 
14
  $updateWheres = [];
@@ -24,7 +27,12 @@ class Delete extends BaseQuery {
24
  $this->lastQueryResult = $updater->getLastQueryResult();
25
  }
26
  else {
27
- $success = parent::query();
 
 
 
 
 
28
  }
29
  return $success;
30
  }
@@ -95,17 +103,21 @@ class Delete extends BaseQuery {
95
  }
96
 
97
  protected function getBaseQuery() :string {
98
- return "DELETE FROM `%s` WHERE %s %s";
99
  }
100
 
101
  /**
102
  * Offset never applies to DELETE
103
  * @return string
104
  */
105
- protected function buildOffsetPhrase() {
106
  return '';
107
  }
108
 
 
 
 
 
109
  public function setIsHardDelete() {
110
  $this->isSoftDelete = false;
111
  return $this;
@@ -115,4 +127,9 @@ class Delete extends BaseQuery {
115
  $this->isSoftDelete = true;
116
  return $this;
117
  }
 
 
 
 
 
118
  }
8
 
9
  private $isSoftDelete = false;
10
 
11
+ private $allowEmptyWhere = false;
12
+
13
+ protected function execQuerySql() :bool {
14
+ $success = false;
15
  if ( $this->isSoftDelete && $this->getDbH()->getTableSchema()->hasColumn( 'deleted_at' ) ) {
16
 
17
  $updateWheres = [];
27
  $this->lastQueryResult = $updater->getLastQueryResult();
28
  }
29
  else {
30
+ if ( empty( $this->buildWhere() ) && !$this->allowEmptyWhere ) {
31
+ error_log( sprintf( 'Attempt to DELETE with empty WHERE with query: "%s"', $this->buildQuery() ) );
32
+ }
33
+ else {
34
+ $success = parent::execQuerySql();
35
+ }
36
  }
37
  return $success;
38
  }
103
  }
104
 
105
  protected function getBaseQuery() :string {
106
+ return "DELETE FROM `%s` %s %s";
107
  }
108
 
109
  /**
110
  * Offset never applies to DELETE
111
  * @return string
112
  */
113
+ protected function buildOffsetPhrase() :string {
114
  return '';
115
  }
116
 
117
+ public function getDynamicWheres() :array {
118
+ return [];
119
+ }
120
+
121
  public function setIsHardDelete() {
122
  $this->isSoftDelete = false;
123
  return $this;
127
  $this->isSoftDelete = true;
128
  return $this;
129
  }
130
+
131
+ public function setAllowEmptyWheres( bool $allow ) {
132
+ $this->allowEmptyWhere = $allow;
133
+ return $this;
134
+ }
135
  }
src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Handler.php CHANGED
@@ -33,6 +33,8 @@ abstract class Handler {
33
  */
34
  protected $schema;
35
 
 
 
36
  public function __construct( array $tableDefinition ) {
37
  if ( empty( $tableDefinition[ 'slug' ] ) ) {
38
  throw new NoSlugProvidedException( 'Slug not provided in Table Definition' );
@@ -59,7 +61,7 @@ abstract class Handler {
59
 
60
  $this->tableCreate();
61
 
62
- if ( !$this->isReady( true ) ) {
63
  $this->tableDelete();
64
  $this->tableCreate();
65
  }
@@ -78,7 +80,9 @@ abstract class Handler {
78
  'primary_key' => 'id',
79
  'cols_custom' => [],
80
  'cols_timestamps' => [],
81
- 'has_updated_at' => false,
 
 
82
  'col_older_than' => 'created_at',
83
  'autoexpire' => 0,
84
  'has_ip_col' => false,
@@ -203,7 +207,7 @@ abstract class Handler {
203
  return Services::WpDb()->getIfTableExists( $this->getTable() );
204
  }
205
 
206
- public function tableTrimExcess( int $rowsLimit ) :self {
207
  try {
208
  $this->getQueryDeleter()->deleteExcess( $rowsLimit );
209
  }
@@ -235,6 +239,15 @@ abstract class Handler {
235
  return $this->schema;
236
  }
237
 
 
 
 
 
 
 
 
 
 
238
  /**
239
  * @return $this
240
  */
33
  */
34
  protected $schema;
35
 
36
+ private $allowAutoDelete = false;
37
+
38
  public function __construct( array $tableDefinition ) {
39
  if ( empty( $tableDefinition[ 'slug' ] ) ) {
40
  throw new NoSlugProvidedException( 'Slug not provided in Table Definition' );
61
 
62
  $this->tableCreate();
63
 
64
+ if ( !$this->isReady( true ) && $this->allowAutoDelete ) {
65
  $this->tableDelete();
66
  $this->tableCreate();
67
  }
80
  'primary_key' => 'id',
81
  'cols_custom' => [],
82
  'cols_timestamps' => [],
83
+ 'has_updated_at' => true,
84
+ 'has_created_at' => true,
85
+ 'has_deleted_at' => true,
86
  'col_older_than' => 'created_at',
87
  'autoexpire' => 0,
88
  'has_ip_col' => false,
207
  return Services::WpDb()->getIfTableExists( $this->getTable() );
208
  }
209
 
210
+ public function tableTrimExcess( int $rowsLimit ) {
211
  try {
212
  $this->getQueryDeleter()->deleteExcess( $rowsLimit );
213
  }
239
  return $this->schema;
240
  }
241
 
242
+ /**
243
+ * @param bool $allowAutoDelete
244
+ * @return $this
245
+ */
246
+ public function setAllowAutoDelete( bool $allowAutoDelete ) {
247
+ $this->allowAutoDelete = true;
248
+ return $this;
249
+ }
250
+
251
  /**
252
  * @return $this
253
  */
src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Insert.php CHANGED
@@ -11,6 +11,29 @@ class Insert extends BaseQuery {
11
  */
12
  protected $insertData;
13
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  public function getInsertData() :array {
15
  return array_intersect_key(
16
  is_array( $this->insertData ) ? $this->insertData : [],
@@ -18,12 +41,26 @@ class Insert extends BaseQuery {
18
  );
19
  }
20
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
  /**
22
- * @param Record $record
23
  * @return bool
24
  */
25
  public function insert( $record ) :bool {
26
- return $this->setInsertData( $record->getRawData() )->query() === 1;
27
  }
28
 
29
  /**
@@ -31,7 +68,7 @@ class Insert extends BaseQuery {
31
  * @param array $data
32
  * @return $this
33
  */
34
- protected function setInsertData( $data ) {
35
  $this->insertData = array_intersect_key(
36
  is_array( $data ) ? $data : [],
37
  array_flip( $this->getDbH()->getTableSchema()->getColumnNames() )
@@ -44,21 +81,35 @@ class Insert extends BaseQuery {
44
  * @throws \Exception
45
  */
46
  protected function verifyInsertData() {
47
- $baseData = [ 'created_at' => Services::Request()->ts() ];
48
- if ( $this->getDbH()->getTableSchema()->hasColumn( 'updated_at' ) ) {
 
 
 
 
 
49
  $baseData[ 'updated_at' ] = Services::Request()->ts();
50
  }
 
51
  return $this->setInsertData( array_merge( $baseData, $this->getInsertData() ) );
52
  }
53
 
54
- public function query() :bool {
 
 
 
 
 
 
 
 
 
55
  try {
56
- $this->verifyInsertData();
57
  $this->lastQueryResult = Services::WpDb()
58
  ->insertDataIntoTable(
59
- $this->getDbH()->getTable(),
60
- $this->getInsertData()
61
- );
62
  $success = (bool)$this->lastQueryResult;
63
  }
64
  catch ( \Exception $e ) {
@@ -72,7 +123,17 @@ class Insert extends BaseQuery {
72
  *
73
  * @return string
74
  */
75
- protected function buildOffsetPhrase() {
76
  return '';
77
  }
 
 
 
 
 
 
 
 
 
 
78
  }
11
  */
12
  protected $insertData;
13
 
14
+ /**
15
+ * @var bool
16
+ */
17
+ private $isIgnore = false;
18
+
19
+ /**
20
+ * @var bool
21
+ */
22
+ private $useWpDbHelper = false;
23
+
24
+ public function buildQuery() :string {
25
+ return sprintf( $this->getBaseQuery(),
26
+ $this->getInsertModifier(),
27
+ $this->getDbH()->getTableSchema()->table,
28
+ $this->getColumnsForQuery(),
29
+ $this->getValuesForQuery()
30
+ );
31
+ }
32
+
33
+ protected function getBaseQuery() :string {
34
+ return "INSERT %s INTO `%s` (%s) VALUES (%s)";
35
+ }
36
+
37
  public function getInsertData() :array {
38
  return array_intersect_key(
39
  is_array( $this->insertData ) ? $this->insertData : [],
41
  );
42
  }
43
 
44
+ protected function getColumnsForQuery() :string {
45
+ return '`'.implode( '`,`', array_keys( $this->getInsertData() ) ).'`';
46
+ }
47
+
48
+ protected function getValuesForQuery() :string {
49
+ return "'".implode( "','", array_map( function ( $value ) {
50
+ return esc_sql( $value );
51
+ }, $this->getInsertData() ) )."'";
52
+ }
53
+
54
+ public function getInsertModifier() :string {
55
+ return $this->isIgnore ? 'IGNORE' : '';
56
+ }
57
+
58
  /**
59
+ * @param Record|mixed $record
60
  * @return bool
61
  */
62
  public function insert( $record ) :bool {
63
+ return $this->setInsertData( $record->getRawData() )->query();
64
  }
65
 
66
  /**
68
  * @param array $data
69
  * @return $this
70
  */
71
+ public function setInsertData( array $data ) {
72
  $this->insertData = array_intersect_key(
73
  is_array( $data ) ? $data : [],
74
  array_flip( $this->getDbH()->getTableSchema()->getColumnNames() )
81
  * @throws \Exception
82
  */
83
  protected function verifyInsertData() {
84
+ $schema = $this->getDbH()->getTableSchema();
85
+
86
+ $baseData = [];
87
+ if ( $schema->has_created_at ) {
88
+ $baseData[ 'created_at' ] = Services::Request()->ts();
89
+ }
90
+ if ( $schema->has_updated_at ) {
91
  $baseData[ 'updated_at' ] = Services::Request()->ts();
92
  }
93
+
94
  return $this->setInsertData( array_merge( $baseData, $this->getInsertData() ) );
95
  }
96
 
97
+ protected function execQuerySql() :bool {
98
+ return $this->useWpDbHelper ? $this->queryWithWpDbInsertHelper() : parent::execQuerySql();
99
+ }
100
+
101
+ protected function preQuery() :bool {
102
+ $this->verifyInsertData();
103
+ return true;
104
+ }
105
+
106
+ public function queryWithWpDbInsertHelper() :bool {
107
  try {
 
108
  $this->lastQueryResult = Services::WpDb()
109
  ->insertDataIntoTable(
110
+ $this->getDbH()->getTable(),
111
+ $this->getInsertData()
112
+ );
113
  $success = (bool)$this->lastQueryResult;
114
  }
115
  catch ( \Exception $e ) {
123
  *
124
  * @return string
125
  */
126
+ protected function buildOffsetPhrase() :string {
127
  return '';
128
  }
129
+
130
+ public function setIgnore( bool $ignore = true ) {
131
+ $this->isIgnore = $ignore;
132
+ return $this;
133
+ }
134
+
135
+ public function setUseHelper( bool $useHelper = true ) {
136
+ $this->useWpDbHelper = $useHelper;
137
+ return $this;
138
+ }
139
  }
src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Record.php CHANGED
@@ -3,6 +3,7 @@
3
  namespace FernleafSystems\Wordpress\Plugin\Core\Databases\Base;
4
 
5
  use FernleafSystems\Utilities\Data\Adapter\DynPropertiesClass;
 
6
 
7
  /**
8
  * @property int $id
@@ -12,6 +13,8 @@ use FernleafSystems\Utilities\Data\Adapter\DynPropertiesClass;
12
  */
13
  class Record extends DynPropertiesClass {
14
 
 
 
15
  public function __construct( array $row = [] ) {
16
  $this->applyFromArray( $row );
17
  }
@@ -26,6 +29,10 @@ class Record extends DynPropertiesClass {
26
 
27
  switch ( $key ) {
28
 
 
 
 
 
29
  case 'meta':
30
  if ( is_string( $value ) && !empty( $value ) ) {
31
  $value = base64_decode( $value );
@@ -58,6 +65,10 @@ class Record extends DynPropertiesClass {
58
 
59
  switch ( $key ) {
60
 
 
 
 
 
61
  case 'meta':
62
  if ( !is_array( $value ) ) {
63
  $value = [];
@@ -72,10 +83,6 @@ class Record extends DynPropertiesClass {
72
  parent::__set( $key, $value );
73
  }
74
 
75
- public function getCreatedAt() :int {
76
- return (int)$this->created_at;
77
- }
78
-
79
  public function getHash() :string {
80
  $data = $this->getRawData();
81
  asort( $data );
3
  namespace FernleafSystems\Wordpress\Plugin\Core\Databases\Base;
4
 
5
  use FernleafSystems\Utilities\Data\Adapter\DynPropertiesClass;
6
+ use FernleafSystems\Wordpress\Plugin\Core\Databases\Common\HandlerConsumer;
7
 
8
  /**
9
  * @property int $id
13
  */
14
  class Record extends DynPropertiesClass {
15
 
16
+ use HandlerConsumer;
17
+
18
  public function __construct( array $row = [] ) {
19
  $this->applyFromArray( $row );
20
  }
29
 
30
  switch ( $key ) {
31
 
32
+ case 'ip':
33
+ $value = inet_ntop( $value );
34
+ break;
35
+
36
  case 'meta':
37
  if ( is_string( $value ) && !empty( $value ) ) {
38
  $value = base64_decode( $value );
65
 
66
  switch ( $key ) {
67
 
68
+ case 'ip':
69
+ $value = inet_pton( $value );
70
+ break;
71
+
72
  case 'meta':
73
  if ( !is_array( $value ) ) {
74
  $value = [];
83
  parent::__set( $key, $value );
84
  }
85
 
 
 
 
 
86
  public function getHash() :string {
87
  $data = $this->getRawData();
88
  asort( $data );
src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Select.php CHANGED
@@ -90,10 +90,6 @@ class Select extends BaseQuery {
90
  return $substitute;
91
  }
92
 
93
- public function sumColumn() :int {
94
- return (int)$this->setIsCount( true )->queryWithResult();
95
- }
96
-
97
  public function count() :int {
98
  return (int)$this->setIsCount( true )->queryWithResult();
99
  }
@@ -105,6 +101,12 @@ class Select extends BaseQuery {
105
  return $this->setIsSum( true )->queryWithResult();
106
  }
107
 
 
 
 
 
 
 
108
  /**
109
  * @return Record|\stdClass|mixed|null
110
  */
@@ -114,7 +116,7 @@ class Select extends BaseQuery {
114
  }
115
 
116
  protected function getBaseQuery() :string {
117
- return "SELECT %s FROM `%s` WHERE %s %s";
118
  }
119
 
120
  public function getColumnsToSelect() :array {
@@ -134,6 +136,10 @@ class Select extends BaseQuery {
134
  return $a;
135
  }
136
 
 
 
 
 
137
  protected function getSelectDataFormat() :string {
138
  if ( $this->isResultsAsVO() ) {
139
  $format = ARRAY_A;
@@ -149,11 +155,11 @@ class Select extends BaseQuery {
149
  }
150
 
151
  public function isCount() :bool {
152
- return (bool)$this->isCount;
153
  }
154
 
155
  public function isSum() :bool {
156
- return (bool)$this->isSum;
157
  }
158
 
159
  public function isCustomSelect() :bool {
@@ -171,7 +177,7 @@ class Select extends BaseQuery {
171
  /**
172
  * COUNT, DISTINCT, & normal SELECT
173
  */
174
- public function query() :bool {
175
  $mData = [];
176
 
177
  if ( $this->isCount() || $this->isSum() ) {
@@ -272,32 +278,32 @@ class Select extends BaseQuery {
272
  return $this;
273
  }
274
 
275
- public function setCustomSelect( string $select ) :self {
276
  $this->customSelect = $select;
277
  return $this;
278
  }
279
 
280
- public function setIsCount( bool $isCount ) :self {
281
  $this->isCount = $isCount;
282
  return $this;
283
  }
284
 
285
- public function setIsSum( bool $sum ) :self {
286
  $this->isSum = $sum;
287
  return $this;
288
  }
289
 
290
- public function setIsDistinct( bool $distinct ) :self {
291
  $this->isDistinct = $distinct;
292
  return $this;
293
  }
294
 
295
- public function setResultsAsVo( bool $asVO ) :self {
296
  $this->resultsAsVO = $asVO;
297
  return $this;
298
  }
299
 
300
- public function setSelectResultsFormat( string $format ) :self {
301
  $this->resultFormat = $format;
302
  return $this;
303
  }
90
  return $substitute;
91
  }
92
 
 
 
 
 
93
  public function count() :int {
94
  return (int)$this->setIsCount( true )->queryWithResult();
95
  }
101
  return $this->setIsSum( true )->queryWithResult();
102
  }
103
 
104
+ public function sumColumn( string $column ) :int {
105
+ return (int)$this->reset()
106
+ ->setColumnsToSelect( [ $column ] )
107
+ ->sum();
108
+ }
109
+
110
  /**
111
  * @return Record|\stdClass|mixed|null
112
  */
116
  }
117
 
118
  protected function getBaseQuery() :string {
119
+ return "SELECT %s FROM `%s` %s %s";
120
  }
121
 
122
  public function getColumnsToSelect() :array {
136
  return $a;
137
  }
138
 
139
+ public function getRawWheres() :array {
140
+ return is_array( $this->rawWheres ) ? $this->rawWheres : [];
141
+ }
142
+
143
  protected function getSelectDataFormat() :string {
144
  if ( $this->isResultsAsVO() ) {
145
  $format = ARRAY_A;
155
  }
156
 
157
  public function isCount() :bool {
158
+ return $this->isCount;
159
  }
160
 
161
  public function isSum() :bool {
162
+ return $this->isSum;
163
  }
164
 
165
  public function isCustomSelect() :bool {
177
  /**
178
  * COUNT, DISTINCT, & normal SELECT
179
  */
180
+ protected function execQuerySql() :bool {
181
  $mData = [];
182
 
183
  if ( $this->isCount() || $this->isSum() ) {
278
  return $this;
279
  }
280
 
281
+ public function setCustomSelect( string $select ) {
282
  $this->customSelect = $select;
283
  return $this;
284
  }
285
 
286
+ public function setIsCount( bool $isCount ) {
287
  $this->isCount = $isCount;
288
  return $this;
289
  }
290
 
291
+ public function setIsSum( bool $sum ) {
292
  $this->isSum = $sum;
293
  return $this;
294
  }
295
 
296
+ public function setIsDistinct( bool $distinct ) {
297
  $this->isDistinct = $distinct;
298
  return $this;
299
  }
300
 
301
+ public function setResultsAsVo( bool $asVO ) {
302
  $this->resultsAsVO = $asVO;
303
  return $this;
304
  }
305
 
306
+ public function setSelectResultsFormat( string $format ) {
307
  $this->resultFormat = $format;
308
  return $this;
309
  }
src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Base/Update.php CHANGED
@@ -77,10 +77,6 @@ class Update extends Insert {
77
  $success = true;
78
  }
79
  else {
80
- if ( $this->getDbH()->getTableSchema()->hasColumn( 'updated_at' )
81
- && !isset( $updateData[ 'updated_at' ] ) ) {
82
- $updateData[ 'updated_at' ] = Services::Request()->ts();
83
- }
84
  if ( $this->updateById( $record->id, $updateData ) ) {
85
  $record->applyFromArray( array_merge( $record->getRawData(), $updateData ) );
86
  $success = true;
@@ -96,24 +92,28 @@ class Update extends Insert {
96
  * @param array $updateData
97
  * @return bool true is success or no update necessary
98
  */
99
- public function updateById( $id, $updateData = [] ) {
100
- $success = true;
 
 
 
101
 
102
- if ( !empty( $updateData ) ) {
103
- $success = $this->setUpdateId( $id )
104
- ->setUpdateData( $updateData )
105
- ->query();
 
106
  }
107
- return $success;
108
  }
109
 
110
- public function query() :bool {
111
  $this->lastQueryResult = Services::WpDb()
112
  ->updateRowsFromTableWhere(
113
- $this->getDbH()->getTable(),
114
- $this->getUpdateData(),
115
- $this->getUpdateWheres()
116
- );
117
  return (bool)$this->lastQueryResult;
118
  }
119
  }
77
  $success = true;
78
  }
79
  else {
 
 
 
 
80
  if ( $this->updateById( $record->id, $updateData ) ) {
81
  $record->applyFromArray( array_merge( $record->getRawData(), $updateData ) );
82
  $success = true;
92
  * @param array $updateData
93
  * @return bool true is success or no update necessary
94
  */
95
+ public function updateById( int $id, array $updateData = [] ) {
96
+ return $this->setUpdateId( $id )
97
+ ->setUpdateData( $updateData )
98
+ ->query();
99
+ }
100
 
101
+ protected function preQuery() :bool {
102
+ $data = $this->getUpdateData();
103
+ if ( !empty( $data ) && !isset( $data[ 'updated_at' ] ) && $this->getDbH()->getTableSchema()->has_updated_at ) {
104
+ $data[ 'updated_at' ] = Services::Request()->ts();
105
+ $this->setUpdateData( $data );
106
  }
107
+ return !empty( $data );
108
  }
109
 
110
+ protected function execQuerySql() :bool {
111
  $this->lastQueryResult = Services::WpDb()
112
  ->updateRowsFromTableWhere(
113
+ $this->getDbH()->getTable(),
114
+ $this->getUpdateData(),
115
+ $this->getUpdateWheres()
116
+ );
117
  return (bool)$this->lastQueryResult;
118
  }
119
  }
src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Common/BuildColumnFromDef.php CHANGED
@@ -9,12 +9,17 @@ class BuildColumnFromDef {
9
  const MACROTYPE_PRIMARYID = 'primary_id';
10
  const MACROTYPE_TIMESTAMP = 'timestamp';
11
  const MACROTYPE_UNSIGNEDINT = 'unsigned_int';
 
 
12
  const MACROTYPE_HASH = 'hash';
 
 
13
  const MACROTYPE_IP = 'ip';
14
  const MACROTYPE_META = 'meta';
15
  const MACROTYPE_TEXT = 'text';
16
  const MACROTYPE_URL = 'url';
17
  const MACROTYPE_BOOL = 'bool';
 
18
  const MACROTYPE_VARCHAR = 'varchar';
19
 
20
  private $def;
@@ -39,7 +44,7 @@ class BuildColumnFromDef {
39
  );
40
  }
41
 
42
- protected function buildStructure() :array {
43
  return Services::DataManipulation()->mergeArraysRecursive(
44
  $this->getMacroTypeDef( $this->def[ 'macro_type' ] ?? '' ),
45
  $this->def
@@ -49,6 +54,29 @@ class BuildColumnFromDef {
49
  protected function getMacroTypeDef( string $macroType ) :array {
50
  switch ( $macroType ) {
51
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  case self::MACROTYPE_HASH:
53
  $def = array_merge(
54
  $this->getMacroTypeDef( self::MACROTYPE_VARCHAR ),
@@ -59,12 +87,59 @@ class BuildColumnFromDef {
59
  );
60
  break;
61
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
  case self::MACROTYPE_IP:
63
  $def = [
64
  'type' => 'varbinary',
65
  'length' => 16,
66
- 'attr' => [],
67
- 'default' => 'NULL',
 
68
  'comment' => 'IP Address',
69
  ];
70
  break;
@@ -96,7 +171,7 @@ class BuildColumnFromDef {
96
  case self::MACROTYPE_VARCHAR:
97
  $def = [
98
  'type' => 'varchar',
99
- 'length' => 60,
100
  'attr' => [
101
  'NOT NULL',
102
  ],
@@ -104,17 +179,6 @@ class BuildColumnFromDef {
104
  ];
105
  break;
106
 
107
- case self::MACROTYPE_BOOL:
108
- $def = array_merge(
109
- $this->getMacroTypeDef( self::MACROTYPE_UNSIGNEDINT ),
110
- [
111
- 'type' => 'tinyint',
112
- 'length' => 1,
113
- 'comment' => 'Boolean',
114
- ]
115
- );
116
- break;
117
-
118
  case self::MACROTYPE_TIMESTAMP:
119
  $def = array_merge(
120
  $this->getMacroTypeDef( self::MACROTYPE_UNSIGNEDINT ),
@@ -145,6 +209,7 @@ class BuildColumnFromDef {
145
  ]
146
  );
147
  $def[ 'attr' ][] = 'AUTO_INCREMENT';
 
148
  break;
149
 
150
  default:
9
  const MACROTYPE_PRIMARYID = 'primary_id';
10
  const MACROTYPE_TIMESTAMP = 'timestamp';
11
  const MACROTYPE_UNSIGNEDINT = 'unsigned_int';
12
+ const MACROTYPE_FOREIGN_KEY_ID = 'foreign_key_id';
13
+ const MACROTYPE_BINARYHASH = 'binary_hash';
14
  const MACROTYPE_HASH = 'hash';
15
+ const MACROTYPE_SHA1 = 'sha1';
16
+ const MACROTYPE_MD5 = 'md5';
17
  const MACROTYPE_IP = 'ip';
18
  const MACROTYPE_META = 'meta';
19
  const MACROTYPE_TEXT = 'text';
20
  const MACROTYPE_URL = 'url';
21
  const MACROTYPE_BOOL = 'bool';
22
+ const MACROTYPE_CHAR = 'char';
23
  const MACROTYPE_VARCHAR = 'varchar';
24
 
25
  private $def;
44
  );
45
  }
46
 
47
+ public function buildStructure() :array {
48
  return Services::DataManipulation()->mergeArraysRecursive(
49
  $this->getMacroTypeDef( $this->def[ 'macro_type' ] ?? '' ),
50
  $this->def
54
  protected function getMacroTypeDef( string $macroType ) :array {
55
  switch ( $macroType ) {
56
 
57
+ case self::MACROTYPE_BOOL:
58
+ $def = array_merge(
59
+ $this->getMacroTypeDef( self::MACROTYPE_UNSIGNEDINT ),
60
+ [
61
+ 'type' => 'tinyint',
62
+ 'length' => 1,
63
+ 'comment' => 'Boolean',
64
+ ]
65
+ );
66
+ break;
67
+
68
+ case self::MACROTYPE_CHAR:
69
+ $def = [
70
+ 'type' => 'char',
71
+ 'length' => 1,
72
+ 'attr' => [
73
+ 'NOT NULL',
74
+ ],
75
+ 'default' => "''",
76
+ 'comment' => 'Fixed-Length String',
77
+ ];
78
+ break;
79
+
80
  case self::MACROTYPE_HASH:
81
  $def = array_merge(
82
  $this->getMacroTypeDef( self::MACROTYPE_VARCHAR ),
87
  );
88
  break;
89
 
90
+ case self::MACROTYPE_BINARYHASH:
91
+ $def = [
92
+ 'type' => 'binary',
93
+ 'length' => 16,
94
+ 'attr' => [
95
+ 'NOT NULL',
96
+ ],
97
+ ];
98
+ break;
99
+
100
+ case self::MACROTYPE_SHA1:
101
+ $def = array_merge(
102
+ $this->getMacroTypeDef( self::MACROTYPE_BINARYHASH ),
103
+ [
104
+ 'length' => 20,
105
+ 'comment' => 'SHA1 Hash',
106
+ ]
107
+ );
108
+ break;
109
+
110
+ case self::MACROTYPE_MD5:
111
+ $def = array_merge(
112
+ $this->getMacroTypeDef( self::MACROTYPE_BINARYHASH ),
113
+ [
114
+ 'length' => 16,
115
+ 'comment' => 'MD5 Hash',
116
+ ]
117
+ );
118
+ break;
119
+
120
+ case self::MACROTYPE_FOREIGN_KEY_ID:
121
+ $def = array_merge(
122
+ $this->getMacroTypeDef( self::MACROTYPE_UNSIGNEDINT ),
123
+ [
124
+ 'comment' => 'Foreign Key For Primary ID',
125
+ 'foreign_key' => [
126
+ 'ref_col' => 'id',
127
+ 'wp_prefix' => true,
128
+ 'cascade_update' => true,
129
+ 'cascade_delete' => true
130
+ ],
131
+ ]
132
+ );
133
+ unset( $def[ 'default' ] );
134
+ break;
135
+
136
  case self::MACROTYPE_IP:
137
  $def = [
138
  'type' => 'varbinary',
139
  'length' => 16,
140
+ 'attr' => [
141
+ 'NOT NULL'
142
+ ],
143
  'comment' => 'IP Address',
144
  ];
145
  break;
171
  case self::MACROTYPE_VARCHAR:
172
  $def = [
173
  'type' => 'varchar',
174
+ 'length' => 120,
175
  'attr' => [
176
  'NOT NULL',
177
  ],
179
  ];
180
  break;
181
 
 
 
 
 
 
 
 
 
 
 
 
182
  case self::MACROTYPE_TIMESTAMP:
183
  $def = array_merge(
184
  $this->getMacroTypeDef( self::MACROTYPE_UNSIGNEDINT ),
209
  ]
210
  );
211
  $def[ 'attr' ][] = 'AUTO_INCREMENT';
212
+ unset( $def[ 'default' ] );
213
  break;
214
 
215
  default:
src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Common/CreateTable.php ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php declare( strict_types=1 );
2
+
3
+ namespace FernleafSystems\Wordpress\Plugin\Core\Databases\Common;
4
+
5
+ use FernleafSystems\Wordpress\Services\Services;
6
+
7
+ /**
8
+ * Class CreateTable
9
+ * @package FernleafSystems\Wordpress\Plugin\Core\Databases\Common
10
+ */
11
+ class CreateTable {
12
+
13
+ /**
14
+ * @var TableSchema
15
+ */
16
+ private $schema;
17
+
18
+ /**
19
+ * @param TableSchema $tableSchema
20
+ */
21
+ public function __construct( $tableSchema ) {
22
+ $this->schema = $tableSchema;
23
+ }
24
+
25
+ public function buildCreateSQL() :string {
26
+ return sprintf(
27
+ 'CREATE TABLE `%s` (
28
+ %s
29
+ ) %s;',
30
+ $this->schema->table,
31
+ implode( ", \n", $this->buildCreateBody() ),
32
+ Services::WpDb()->getCharCollate()
33
+ );
34
+ }
35
+
36
+ public function buildCreateBody() :array {
37
+ return array_merge(
38
+ $this->buildColumns(),
39
+ $this->buildPrimaryKey(),
40
+ $this->buildForeignKeys()
41
+ );
42
+ }
43
+
44
+ public function buildColumns() :array {
45
+ $cols = [];
46
+ foreach ( $this->schema->enumerateColumns() as $col => $def ) {
47
+ $cols[] = sprintf( '%s %s', $col, $def );
48
+ }
49
+ return $cols;
50
+ }
51
+
52
+ public function buildPrimaryKey() :array {
53
+ return [ sprintf( 'PRIMARY KEY (%s)', $this->schema->getPrimaryKeyColumnName() ) ];
54
+ }
55
+
56
+ public function buildForeignKeys() :array {
57
+ $WPDB = Services::WpDb();
58
+ $fKeys = [];
59
+ foreach ( $this->schema->getColumnsDefs() as $col => $def ) {
60
+ $fk = $def[ 'foreign_key' ] ?? null;
61
+ if ( !empty( $fk ) ) {
62
+ $fKeys[] = sprintf( 'FOREIGN KEY (%s) REFERENCES %s(%s) %s %s',
63
+ $col,
64
+ sprintf( '%s%s', ( $fk[ 'wp_prefix' ] ?? true ) ? $WPDB->getPrefix() : '', $fk[ 'ref_table' ] ),
65
+ $fk[ 'ref_col' ],
66
+ ( $fk[ 'cascade_delete' ] ?? true ) ? 'ON DELETE CASCADE' : '',
67
+ ( $fk[ 'cascade_update' ] ?? true ) ? 'ON UPDATE CASCADE' : ''
68
+ );
69
+ }
70
+ }
71
+ return $fKeys;
72
+ }
73
+ }
src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Common/Iterator.php CHANGED
@@ -49,15 +49,15 @@ class Iterator extends AbstractPagedIterator {
49
  }
50
 
51
  /**
52
- * @param int $nPage - always starts at 0
53
  * @return array
54
  */
55
- public function getPage( $nPage ) {
56
  $aParams = $this->getFinalQueryFilters();
57
 
58
  $this->getSelector()
59
  ->setResultsAsVo( true )
60
- ->setPage( $nPage + 1 ) // Pages start at 1, not zero.
61
  ->setLimit( $this->getPageSize() )
62
  ->setOrderBy( $aParams[ 'orderby' ], $aParams[ 'order' ] );
63
 
49
  }
50
 
51
  /**
52
+ * @param int $page - always starts at 0
53
  * @return array
54
  */
55
+ public function getPage( $page ) {
56
  $aParams = $this->getFinalQueryFilters();
57
 
58
  $this->getSelector()
59
  ->setResultsAsVo( true )
60
+ ->setPage( $page + 1 ) // Pages start at 1, not zero.
61
  ->setLimit( $this->getPageSize() )
62
  ->setOrderBy( $aParams[ 'orderby' ], $aParams[ 'order' ] );
63
 
src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Common/TableSchema.php CHANGED
@@ -15,8 +15,11 @@ use FernleafSystems\Wordpress\Services\Services;
15
  * @property string[] $cols_ids
16
  * @property string[] $cols_custom
17
  * @property string[] $cols_timestamps
 
18
  * @property string $col_older_than
19
  * @property bool $has_updated_at
 
 
20
  * @property int $autoexpire
21
  * @property bool $has_ip_col
22
  * @property bool $is_ip_binary
@@ -29,7 +32,7 @@ class TableSchema extends DynPropertiesClass {
29
  $val = parent::__get( $key );
30
  switch ( $key ) {
31
  case 'has_ip_col':
32
- $val = array_key_exists( 'ip', $this->enumerateColumns() );
33
  break;
34
  case 'is_ip_binary':
35
  $val = $this->has_ip_col && ( stripos( $this->cols_custom[ 'ip' ], 'varbinary' ) !== false );
@@ -45,6 +48,11 @@ class TableSchema extends DynPropertiesClass {
45
  case 'has_updated_at':
46
  $val = is_null( $val ) ? true : $val;
47
  break;
 
 
 
 
 
48
  default:
49
  break;
50
  }
@@ -60,27 +68,19 @@ class TableSchema extends DynPropertiesClass {
60
  }
61
 
62
  public function buildCreate() :string {
63
- $cols = [];
64
- foreach ( $this->enumerateColumns() as $col => $def ) {
65
- $cols[] = sprintf( '%s %s', $col, $def );
66
- }
67
- $cols[] = $this->getPrimaryKeyDef();
68
-
69
- return sprintf(
70
- 'CREATE TABLE %s (
71
- %s
72
- ) %s;',
73
- $this->table,
74
- implode( ", ", $cols ),
75
- Services::WpDb()->getCharCollate()
76
- );
77
  }
78
 
79
  /**
80
  * @return string[]
81
  */
82
  public function getColumnNames() :array {
83
- return array_keys( $this->enumerateColumns() );
 
 
 
 
 
84
  }
85
 
86
  /**
@@ -100,6 +100,22 @@ class TableSchema extends DynPropertiesClass {
100
  );
101
  }
102
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103
  /**
104
  * @return string[]
105
  */
@@ -114,20 +130,22 @@ class TableSchema extends DynPropertiesClass {
114
  */
115
  protected function getColumns_Timestamps() :array {
116
 
117
- $standardTsCols = [
118
- 'created_at' => [
119
- 'comment' => 'Created'
120
- ],
121
- 'deleted_at' => [
122
- 'comment' => 'Soft Deleted'
123
- ],
124
- ];
125
-
126
  if ( $this->has_updated_at && !array_key_exists( 'updated_at', $this->cols_timestamps ) ) {
127
  $standardTsCols[ 'updated_at' ] = [
128
  'comment' => 'Last Updated'
129
  ];
130
  }
 
 
 
 
 
 
 
 
 
 
131
 
132
  return array_map(
133
  function ( array $colDef ) {
@@ -141,11 +159,7 @@ class TableSchema extends DynPropertiesClass {
141
  );
142
  }
143
 
144
- protected function getPrimaryKeyDef() :string {
145
- return sprintf( 'PRIMARY KEY (%s)', $this->getPrimaryKeyColumnName() );
146
- }
147
-
148
- protected function getPrimaryKeyColumnName() :string {
149
  return $this->primary_key ?? static::PRIMARY_KEY;
150
  }
151
 
15
  * @property string[] $cols_ids
16
  * @property string[] $cols_custom
17
  * @property string[] $cols_timestamps
18
+ * @property array[] $foreign_keys
19
  * @property string $col_older_than
20
  * @property bool $has_updated_at
21
+ * @property bool $has_created_at
22
+ * @property bool $has_deleted_at
23
  * @property int $autoexpire
24
  * @property bool $has_ip_col
25
  * @property bool $is_ip_binary
32
  $val = parent::__get( $key );
33
  switch ( $key ) {
34
  case 'has_ip_col':
35
+ $val = in_array( 'ip', $this->getColumnNames() );
36
  break;
37
  case 'is_ip_binary':
38
  $val = $this->has_ip_col && ( stripos( $this->cols_custom[ 'ip' ], 'varbinary' ) !== false );
48
  case 'has_updated_at':
49
  $val = is_null( $val ) ? true : $val;
50
  break;
51
+ case 'foreign_keys':
52
+ if ( !is_array( $val ) ) {
53
+ $val = [];
54
+ }
55
+ break;
56
  default:
57
  break;
58
  }
68
  }
69
 
70
  public function buildCreate() :string {
71
+ return ( new CreateTable( $this ) )->buildCreateSQL();
 
 
 
 
 
 
 
 
 
 
 
 
 
72
  }
73
 
74
  /**
75
  * @return string[]
76
  */
77
  public function getColumnNames() :array {
78
+ return array_keys( $this->getColumnsDefs() );
79
+ }
80
+
81
+ public function getColumnType( string $col ) :string {
82
+ $defs = $this->getColumnsDefs();
83
+ return isset( $defs[ $col ] ) ? $defs[ $col ][ 'type' ] : '';
84
  }
85
 
86
  /**
100
  );
101
  }
102
 
103
+ /**
104
+ * @return array[]
105
+ */
106
+ public function getColumnsDefs() :array {
107
+ return array_map(
108
+ function ( array $colDef ) {
109
+ return ( new BuildColumnFromDef( $colDef ) )->buildStructure();
110
+ },
111
+ array_merge(
112
+ $this->getColumn_ID(),
113
+ $this->cols_custom ?? [],
114
+ $this->getColumns_Timestamps()
115
+ )
116
+ );
117
+ }
118
+
119
  /**
120
  * @return string[]
121
  */
130
  */
131
  protected function getColumns_Timestamps() :array {
132
 
133
+ $standardTsCols = [];
 
 
 
 
 
 
 
 
134
  if ( $this->has_updated_at && !array_key_exists( 'updated_at', $this->cols_timestamps ) ) {
135
  $standardTsCols[ 'updated_at' ] = [
136
  'comment' => 'Last Updated'
137
  ];
138
  }
139
+ if ( $this->has_created_at && !array_key_exists( 'created_at', $this->cols_timestamps ) ) {
140
+ $standardTsCols[ 'created_at' ] = [
141
+ 'comment' => 'Created'
142
+ ];
143
+ }
144
+ if ( $this->has_deleted_at && !array_key_exists( 'deleted_at', $this->cols_timestamps ) ) {
145
+ $standardTsCols[ 'deleted_at' ] = [
146
+ 'comment' => 'Soft Deleted'
147
+ ];
148
+ }
149
 
150
  return array_map(
151
  function ( array $colDef ) {
159
  );
160
  }
161
 
162
+ public function getPrimaryKeyColumnName() :string {
 
 
 
 
163
  return $this->primary_key ?? static::PRIMARY_KEY;
164
  }
165
 
src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Databases/Exceptions/ColumnDoesNotExistException.php ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <?php declare( strict_types=1 );
2
+
3
+ namespace FernleafSystems\Wordpress\Plugin\Core\Databases\Exceptions;
4
+
5
+ class ColumnDoesNotExistException extends \InvalidArgumentException {
6
+
7
+ }
src/lib/vendor/fernleafsystems/wordpress-plugin-core/src/Utility/User/PluginMeta.php ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php declare( strict_types=1 );
2
+
3
+ namespace FernleafSystems\Wordpress\Plugin\Core\Utility\User;
4
+
5
+ use FernleafSystems\Wordpress\Services\Services;
6
+
7
+ /**
8
+ * Class PluginMeta
9
+ * @property string $prefix
10
+ * @property int $user_id
11
+ * @property array $flash_msg
12
+ */
13
+ class PluginMeta extends \FernleafSystems\Utilities\Data\Adapter\DynPropertiesClass {
14
+
15
+ /**
16
+ * @var PluginMeta[]
17
+ */
18
+ private static $metas;
19
+
20
+ /**
21
+ * @param string $prefix
22
+ * @param int $userID
23
+ * @return PluginMeta
24
+ * @throws \Exception
25
+ */
26
+ public static function Load( string $prefix, $userID = 0 ) {
27
+ if ( !is_array( self::$metas ) ) {
28
+ self::$metas = [];
29
+ }
30
+ if ( empty( $userID ) ) {
31
+ $userID = Services::WpUsers()->getCurrentWpUserId();
32
+ }
33
+ if ( empty( $userID ) ) {
34
+ throw new \Exception( 'Attempting to get meta of non-logged in user.' );
35
+ }
36
+
37
+ if ( !isset( self::$metas[ $prefix.$userID ] ) ) {
38
+ static::AddToCache( new static( $prefix, $userID ) );
39
+ }
40
+
41
+ return self::$metas[ $prefix.$userID ];
42
+ }
43
+
44
+ /**
45
+ * @param static $meta
46
+ */
47
+ public static function AddToCache( $meta ) {
48
+ self::$metas[ $meta->prefix.$meta->user_id ] = $meta;
49
+ }
50
+
51
+ public function __construct( string $prefix, int $userID = 0 ) {
52
+ $store = Services::WpUsers()->getUserMeta( $prefix.'-meta', $userID );
53
+ if ( !is_array( $store ) ) {
54
+ $store = [];
55
+ }
56
+ $this->applyFromArray( $store );
57
+ $this->prefix = $prefix;
58
+ $this->user_id = $userID;
59
+ add_action( 'shutdown', [ $this, 'save' ], 5 );
60
+ }
61
+
62
+ /**
63
+ * @return $this
64
+ */
65
+ public function delete() {
66
+ if ( $this->user_id > 0 ) {
67
+ Services::WpUsers()->deleteUserMeta( $this->getStorageKey(), $this->user_id );
68
+ remove_action( 'shutdown', [ $this, 'save' ], 5 );
69
+ }
70
+ return $this;
71
+ }
72
+
73
+ /**
74
+ * @return $this
75
+ */
76
+ public function save() {
77
+ if ( $this->user_id > 0 ) {
78
+ Services::WpUsers()->updateUserMeta(
79
+ $this->getStorageKey(), $this->getRawData(), $this->user_id );
80
+ }
81
+ return $this;
82
+ }
83
+
84
+ /**
85
+ * @param string $key
86
+ * @param mixed $value
87
+ */
88
+ public function __set( string $key, $value ) {
89
+ parent::__set( $key, $value );
90
+ $this->save();
91
+ }
92
+
93
+ public function __unset( string $key ) {
94
+ parent::__unset( $key );
95
+ $this->save();
96
+ }
97
+
98
+ private function getStorageKey() :string {
99
+ return $this->prefix.'-meta';
100
+ }
101
+ }
src/lib/vendor/fernleafsystems/wordpress-services/src/Core/Db.php CHANGED
@@ -10,131 +10,106 @@ class Db {
10
  /**
11
  * @var \wpdb
12
  */
13
- protected $oWpdb;
14
 
15
  /**
16
- * @param string $sSQL
17
  * @return array
18
  */
19
- public function dbDelta( $sSQL ) {
20
  require_once( ABSPATH.'wp-admin/includes/upgrade.php' );
21
- return dbDelta( $sSQL );
22
  }
23
 
24
  /**
25
- * @param string $sTable
26
- * @param array $aWhere - delete where (associative array)
27
  * @return false|int
28
  */
29
- public function deleteRowsFromTableWhere( $sTable, $aWhere ) {
30
- return $this->loadWpdb()->delete( $sTable, $aWhere );
31
  }
32
 
33
  /**
34
  * Will completely remove this table from the database
35
  *
36
- * @param string $sTable
37
  * @return bool|int
38
  */
39
- public function doDropTable( $sTable ) {
40
- $sQuery = sprintf( 'DROP TABLE IF EXISTS `%s`', $sTable );
41
- return $this->doSql( $sQuery );
42
  }
43
 
44
  /**
45
  * Alias for doTruncateTable()
46
  *
47
- * @param string $sTable
48
  * @return bool|int
49
  */
50
- public function doEmptyTable( $sTable ) {
51
- return $this->doTruncateTable( $sTable );
52
  }
53
 
54
  /**
55
  * Given any SQL query, will perform it using the WordPress database object.
56
  *
57
- * @param string $sSqlQuery
58
- * @return int|bool (number of rows affected or just true/false)
59
  */
60
- public function doSql( $sSqlQuery ) {
61
- return $this->loadWpdb()->query( $sSqlQuery );
62
  }
63
 
64
  /**
65
- * @param string $sTable
66
  * @return bool|int
67
  */
68
- public function doTruncateTable( $sTable ) {
69
- if ( !$this->getIfTableExists( $sTable ) ) {
70
- return false;
71
- }
72
- $sQuery = sprintf( 'TRUNCATE TABLE `%s`', $sTable );
73
- return $this->doSql( $sQuery );
74
  }
75
 
76
- public function getCharCollate() {
77
  return $this->getWpdb()->get_charset_collate();
78
  }
79
 
80
- /**
81
- * @param string $sTable
82
- * @return bool
83
- */
84
- public function getIfTableExists( $sTable ) {
85
- $sQuery = sprintf( "SHOW TABLES LIKE '%s'", $sTable );
86
- $mResult = $this->loadWpdb()->get_var( $sQuery );
87
  return !is_null( $mResult );
88
  }
89
 
90
  /**
91
- * @param string $sTableName
92
- * @param string $sArrayMapCallBack
93
  * @return array
94
  */
95
- public function getColumnsForTable( $sTableName, $sArrayMapCallBack = '' ) {
96
- $aColumns = $this->loadWpdb()->get_col( "DESCRIBE ".$sTableName, 0 );
97
 
98
- if ( !empty( $sArrayMapCallBack ) && function_exists( $sArrayMapCallBack ) ) {
99
- return array_map( $sArrayMapCallBack, $aColumns );
100
  }
101
- return $aColumns;
102
  }
103
 
104
- /**
105
- * @param bool $bSiteBase
106
- * @return string
107
- */
108
- public function getPrefix( $bSiteBase = true ) {
109
- $oDb = $this->loadWpdb();
110
- return $bSiteBase ? $oDb->base_prefix : $oDb->prefix;
111
  }
112
 
113
- /**
114
- * @return string
115
- */
116
- public function getTable_Comments() {
117
  return $this->loadWpdb()->comments;
118
  }
119
 
120
- /**
121
- * @return string
122
- */
123
- public function getTable_Options() {
124
  return $this->loadWpdb()->options;
125
  }
126
 
127
- /**
128
- * @return string
129
- */
130
- public function getTable_Posts() {
131
  return $this->loadWpdb()->posts;
132
  }
133
 
134
- /**
135
- * @return string
136
- */
137
- public function getTable_Users() {
138
  return $this->loadWpdb()->users;
139
  }
140
 
@@ -147,65 +122,61 @@ class Db {
147
  }
148
 
149
  /**
150
- * @param string $sTable
151
- * @param array $aData
152
  * @return int|bool
153
  */
154
- public function insertDataIntoTable( $sTable, $aData ) {
155
- return $this->loadWpdb()->insert( $sTable, $aData );
156
  }
157
 
158
  /**
159
- * @param string $sTable
160
- * @param string $nFormat
161
  * @return mixed
162
  */
163
- public function selectAllFromTable( $sTable, $nFormat = ARRAY_A ) {
164
- $sQuery = sprintf( "SELECT * FROM `%s` WHERE `deleted_at` = 0", $sTable );
165
- return $this->loadWpdb()->get_results( $sQuery, $nFormat );
166
  }
167
 
168
  /**
169
- * @param string $sQuery
170
- * @param $nFormat
171
  * @return array|bool
172
  */
173
- public function selectCustom( $sQuery, $nFormat = ARRAY_A ) {
174
- return $this->loadWpdb()->get_results( $sQuery, $nFormat );
175
  }
176
 
177
  /**
178
- * @param $sQuery
179
- * @param string $nFormat
180
  * @return null|object|array
181
  */
182
- public function selectRow( $sQuery, $nFormat = ARRAY_A ) {
183
- return $this->loadWpdb()->get_row( $sQuery, $nFormat );
184
  }
185
 
186
  /**
187
- * @param string $sTable
188
- * @param array $aData - new insert data (associative array, column=>data)
189
- * @param array $aWhere - insert where (associative array)
190
  * @return int|bool (number of rows affected)
191
  */
192
- public function updateRowsFromTableWhere( $sTable, $aData, $aWhere ) {
193
- return $this->loadWpdb()->update( $sTable, $aData, $aWhere );
194
  }
195
 
196
- /**
197
- * Loads our WPDB object if required.
198
- *
199
- * @return \wpdb
200
- */
201
- protected function loadWpdb() {
202
- if ( is_null( $this->oWpdb ) ) {
203
- $this->oWpdb = $this->getWpdb();
204
  }
205
- return $this->oWpdb;
206
  }
207
 
208
  /**
 
209
  */
210
  private function getWpdb() {
211
  global $wpdb;
10
  /**
11
  * @var \wpdb
12
  */
13
+ protected $wpdb;
14
 
15
  /**
16
+ * @param string $sql
17
  * @return array
18
  */
19
+ public function dbDelta( string $sql ) {
20
  require_once( ABSPATH.'wp-admin/includes/upgrade.php' );
21
+ return dbDelta( $sql );
22
  }
23
 
24
  /**
25
+ * @param string $table
26
+ * @param array $where - delete where (associative array)
27
  * @return false|int
28
  */
29
+ public function deleteRowsFromTableWhere( string $table, array $where ) {
30
+ return $this->loadWpdb()->delete( $table, $where );
31
  }
32
 
33
  /**
34
  * Will completely remove this table from the database
35
  *
36
+ * @param string $table
37
  * @return bool|int
38
  */
39
+ public function doDropTable( string $table ) {
40
+ return $this->doSql( sprintf( 'DROP TABLE IF EXISTS `%s`', $table ) );
 
41
  }
42
 
43
  /**
44
  * Alias for doTruncateTable()
45
  *
46
+ * @param string $table
47
  * @return bool|int
48
  */
49
+ public function doEmptyTable( string $table ) {
50
+ return $this->doTruncateTable( $table );
51
  }
52
 
53
  /**
54
  * Given any SQL query, will perform it using the WordPress database object.
55
  *
56
+ * @param string $sqlQuery
57
+ * @return mixed|int|bool (number of rows affected or just true/false)
58
  */
59
+ public function doSql( string $sqlQuery ) {
60
+ return $this->loadWpdb()->query( $sqlQuery );
61
  }
62
 
63
  /**
64
+ * @param string $table
65
  * @return bool|int
66
  */
67
+ public function doTruncateTable( string $table ) {
68
+ return $this->getIfTableExists( $table ) ?
69
+ $this->doSql( sprintf( 'TRUNCATE TABLE `%s`', $table ) )
70
+ : false;
 
 
71
  }
72
 
73
+ public function getCharCollate() :string {
74
  return $this->getWpdb()->get_charset_collate();
75
  }
76
 
77
+ public function getIfTableExists( string $table ) :bool {
78
+ $mResult = $this->loadWpdb()->get_var( sprintf( "SHOW TABLES LIKE '%s'", $table ) );
 
 
 
 
 
79
  return !is_null( $mResult );
80
  }
81
 
82
  /**
83
+ * @param string $tableName
84
+ * @param callable $callBack
85
  * @return array
86
  */
87
+ public function getColumnsForTable( $tableName, $callBack = '' ) :array {
88
+ $columns = $this->loadWpdb()->get_col( "DESCRIBE ".$tableName, 0 );
89
 
90
+ if ( !empty( $callBack ) && function_exists( $callBack ) ) {
91
+ return array_map( $callBack, $columns );
92
  }
93
+ return is_array( $columns ) ? $columns : [];
94
  }
95
 
96
+ public function getPrefix( bool $siteBase = true ) :string {
97
+ return $siteBase ? $this->loadWpdb()->base_prefix : $this->loadWpdb()->prefix;
 
 
 
 
 
98
  }
99
 
100
+ public function getTable_Comments() :string {
 
 
 
101
  return $this->loadWpdb()->comments;
102
  }
103
 
104
+ public function getTable_Options() :string {
 
 
 
105
  return $this->loadWpdb()->options;
106
  }
107
 
108
+ public function getTable_Posts() :string {
 
 
 
109
  return $this->loadWpdb()->posts;
110
  }
111
 
112
+ public function getTable_Users() :string {
 
 
 
113
  return $this->loadWpdb()->users;
114
  }
115
 
122
  }
123
 
124
  /**
125
+ * @param string $table
126
+ * @param array $data
127
  * @return int|bool
128
  */
129
+ public function insertDataIntoTable( $table, $data ) {
130
+ return $this->loadWpdb()->insert( $table, $data );
131
  }
132
 
133
  /**
134
+ * @param string $table
135
+ * @param string $format
136
  * @return mixed
137
  */
138
+ public function selectAllFromTable( string $table, $format = ARRAY_A ) {
139
+ return $this->loadWpdb()
140
+ ->get_results( sprintf( "SELECT * FROM `%s` WHERE `deleted_at` = 0", $table ), $format );
141
  }
142
 
143
  /**
144
+ * @param string $query
145
+ * @param $format
146
  * @return array|bool
147
  */
148
+ public function selectCustom( $query, $format = ARRAY_A ) {
149
+ return $this->loadWpdb()->get_results( $query, $format );
150
  }
151
 
152
  /**
153
+ * @param string $query
154
+ * @param string $format
155
  * @return null|object|array
156
  */
157
+ public function selectRow( string $query, $format = ARRAY_A ) {
158
+ return $this->loadWpdb()->get_row( $query, $format );
159
  }
160
 
161
  /**
162
+ * @param string $table
163
+ * @param array $data - new insert data (associative array, column=>data)
164
+ * @param array $where - insert where (associative array)
165
  * @return int|bool (number of rows affected)
166
  */
167
+ public function updateRowsFromTableWhere( string $table, array $data, array $where ) {
168
+ return $this->loadWpdb()->update( $table, $data, $where );
169
  }
170
 
171
+ public function loadWpdb() :\wpdb {
172
+ if ( !$this->wpdb instanceof \wpdb ) {
173
+ $this->wpdb = $this->getWpdb();
 
 
 
 
 
174
  }
175
+ return $this->wpdb;
176
  }
177
 
178
  /**
179
+ * @return \wpdb
180
  */
181
  private function getWpdb() {
182
  global $wpdb;
src/lib/vendor/fernleafsystems/wordpress-services/src/Core/Plugins.php CHANGED
@@ -3,19 +3,17 @@
3
  namespace FernleafSystems\Wordpress\Services\Core;
4
 
5
  use FernleafSystems\Wordpress\Services\Core\Upgrades;
6
- use FernleafSystems\Wordpress\Services\Core\VOs\WpPluginVo;
7
  use FernleafSystems\Wordpress\Services\Services;
8
 
9
- /**
10
- * Class Plugins
11
- * @package FernleafSystems\Wordpress\Services\Core
12
- */
13
  class Plugins {
14
 
 
 
15
  /**
16
- * @var WpPluginVo[]
17
  */
18
- private $aLoadedVOs;
19
 
20
  /**
21
  * @param string $file
@@ -311,20 +309,20 @@ class Plugins {
311
 
312
  /**
313
  * @param string $file
314
- * @param bool $bReload
315
- * @return WpPluginVo|null
316
  */
317
- public function getPluginAsVo( $file, $bReload = false ) {
318
  try {
319
- if ( !is_array( $this->aLoadedVOs ) ) {
320
- $this->aLoadedVOs = [];
321
  }
322
- if ( $bReload || !isset( $this->aLoadedVOs[ $file ] ) ) {
323
- $this->aLoadedVOs[ $file ] = new WpPluginVo( $file );
324
  }
325
- $asset = $this->aLoadedVOs[ $file ];
326
  }
327
- catch ( \Exception $oE ) {
328
  $asset = null;
329
  }
330
  return $asset;
@@ -372,10 +370,10 @@ class Plugins {
372
  * @return string[]
373
  */
374
  public function getInstalledWpOrgPluginFiles() {
375
- return array_values( array_filter(
376
- $this->getInstalledPluginFiles(),
377
- function ( $file ) {
378
- return $this->isWpOrg( $file );
379
  }
380
  ) );
381
  }
@@ -391,72 +389,66 @@ class Plugins {
391
  }
392
 
393
  /**
394
- * @return WpPluginVo[]
395
  */
396
- public function getPluginsAsVo() {
397
- return array_filter(
398
- array_map(
399
- function ( $sPluginFile ) {
400
- return $this->getPluginAsVo( $sPluginFile );
401
- },
402
- $this->getInstalledPluginFiles()
403
- )
404
- );
405
  }
406
 
407
  /**
408
  * @return \stdClass[] - keys are plugin base files
409
  */
410
  public function getAllExtendedData() {
411
- $oData = Services::WpGeneral()->getTransient( 'update_plugins' );
412
  return array_merge(
413
- isset( $oData->no_update ) ? $oData->no_update : [],
414
- isset( $oData->response ) ? $oData->response : []
415
  );
416
  }
417
 
418
  /**
419
- * @param string $sBaseFile
420
  * @return array
421
  */
422
- public function getExtendedData( $sBaseFile ) {
423
- $aData = $this->getAllExtendedData();
424
- return isset( $aData[ $sBaseFile ] ) ?
425
- Services::DataManipulation()->convertStdClassToArray( $aData[ $sBaseFile ] )
426
  : [];
427
  }
428
 
429
- /**
430
- * @return array
431
- */
432
- public function getAllSlugs() {
433
- $aSlugs = [];
434
 
435
- foreach ( $this->getAllExtendedData() as $sBaseName => $oPlugData ) {
436
- if ( isset( $oPlugData->slug ) ) {
437
- $aSlugs[ $sBaseName ] = $oPlugData->slug;
438
  }
439
  }
440
 
441
- return $aSlugs;
442
  }
443
 
444
  /**
445
- * @param $sBaseName
446
  * @return string
447
  */
448
- public function getSlug( $sBaseName ) {
449
- $aInfo = $this->getExtendedData( $sBaseName );
450
- return isset( $aInfo[ 'slug' ] ) ? $aInfo[ 'slug' ] : '';
451
  }
452
 
453
  /**
454
- * @param string $sBaseName
455
  * @return bool
456
  * @deprecated 1.1.17
457
  */
458
- public function isWpOrg( $sBaseName ) {
459
- return $this->getPluginAsVo( $sBaseName )->isWpOrg();
460
  }
461
 
462
  /**
@@ -472,8 +464,8 @@ class Plugins {
472
  * @return string
473
  */
474
  public function getUpdateNewVersion( $file ) {
475
- $oInfo = $this->getUpdateInfo( $file );
476
- return ( !is_null( $oInfo ) && isset( $oInfo->new_version ) ) ? $oInfo->new_version : '';
477
  }
478
 
479
  /**
@@ -493,7 +485,7 @@ class Plugins {
493
  * @param string $file
494
  * @return string
495
  */
496
- public function getUrl_Activate( $file ) {
497
  return $this->getUrl_Action( $file, 'activate' );
498
  }
499
 
@@ -501,7 +493,7 @@ class Plugins {
501
  * @param string $file
502
  * @return string
503
  */
504
- public function getUrl_Deactivate( $file ) {
505
  return $this->getUrl_Action( $file, 'deactivate' );
506
  }
507
 
@@ -509,7 +501,7 @@ class Plugins {
509
  * @param string $file
510
  * @return string
511
  */
512
- public function getUrl_Upgrade( $file ) {
513
  return add_query_arg( [
514
  'action' => 'upgrade-plugin',
515
  'plugin' => urlencode( $file ),
@@ -522,20 +514,19 @@ class Plugins {
522
  * @param string $action
523
  * @return string
524
  */
525
- protected function getUrl_Action( $file, $action ) {
526
  return add_query_arg( [
527
  'action' => $action,
528
  'plugin' => urlencode( $file ),
529
  '_wpnonce' => wp_create_nonce( $action.'-plugin_'.$file )
530
- ], self_admin_url( 'plugins.php' )
531
- );
532
  }
533
 
534
  /**
535
  * @param string $file
536
  * @return bool
537
  */
538
- public function isActive( $file ) {
539
  return $this->isInstalled( $file ) && is_plugin_active( $file );
540
  }
541
 
3
  namespace FernleafSystems\Wordpress\Services\Core;
4
 
5
  use FernleafSystems\Wordpress\Services\Core\Upgrades;
6
+ use FernleafSystems\Wordpress\Services\Core\VOs\Assets;
7
  use FernleafSystems\Wordpress\Services\Services;
8
 
 
 
 
 
9
  class Plugins {
10
 
11
+ private $aLoadedVOs;
12
+
13
  /**
14
+ * @var Assets\WpPluginVo[]
15
  */
16
+ private $loadedVOs;
17
 
18
  /**
19
  * @param string $file
309
 
310
  /**
311
  * @param string $file
312
+ * @param bool $reload
313
+ * @return Assets\WpPluginVo|null
314
  */
315
+ public function getPluginAsVo( string $file, bool $reload = false ) {
316
  try {
317
+ if ( !is_array( $this->loadedVOs ) ) {
318
+ $this->loadedVOs = [];
319
  }
320
+ if ( $reload || !isset( $this->loadedVOs[ $file ] ) ) {
321
+ $this->loadedVOs[ $file ] = new Assets\WpPluginVo( $file );
322
  }
323
+ $asset = $this->loadedVOs[ $file ];
324
  }
325
+ catch ( \Exception $e ) {
326
  $asset = null;
327
  }
328
  return $asset;
370
  * @return string[]
371
  */
372
  public function getInstalledWpOrgPluginFiles() {
373
+ return array_keys( array_filter(
374
+ $this->getPluginsAsVo(),
375
+ function ( $plugin ) {
376
+ return $plugin->isWpOrg();
377
  }
378
  ) );
379
  }
389
  }
390
 
391
  /**
392
+ * @return Assets\WpPluginVo[]
393
  */
394
+ public function getPluginsAsVo() :array {
395
+ $plugins = [];
396
+ foreach ( $this->getInstalledPluginFiles() as $pluginFile ) {
397
+ $plugins[ $pluginFile ] = $this->getPluginAsVo( $pluginFile );
398
+ }
399
+ return $plugins;
 
 
 
400
  }
401
 
402
  /**
403
  * @return \stdClass[] - keys are plugin base files
404
  */
405
  public function getAllExtendedData() {
406
+ $data = Services::WpGeneral()->getTransient( 'update_plugins' );
407
  return array_merge(
408
+ $data->no_update ?? [],
409
+ $data->response ?? []
410
  );
411
  }
412
 
413
  /**
414
+ * @param string $baseFile
415
  * @return array
416
  */
417
+ public function getExtendedData( $baseFile ) {
418
+ $data = $this->getAllExtendedData();
419
+ return isset( $data[ $baseFile ] ) ?
420
+ Services::DataManipulation()->convertStdClassToArray( $data[ $baseFile ] )
421
  : [];
422
  }
423
 
424
+ public function getAllSlugs() :array {
425
+ $slugs = [];
 
 
 
426
 
427
+ foreach ( $this->getAllExtendedData() as $basename => $data ) {
428
+ if ( isset( $data->slug ) ) {
429
+ $slugs[ $basename ] = $data->slug;
430
  }
431
  }
432
 
433
+ return $slugs;
434
  }
435
 
436
  /**
437
+ * @param $baseName
438
  * @return string
439
  */
440
+ public function getSlug( $baseName ) {
441
+ $info = $this->getExtendedData( $baseName );
442
+ return $info[ 'slug' ] ?? '';
443
  }
444
 
445
  /**
446
+ * @param string $baseName
447
  * @return bool
448
  * @deprecated 1.1.17
449
  */
450
+ public function isWpOrg( $baseName ) {
451
+ return $this->getPluginAsVo( $baseName )->isWpOrg();
452
  }
453
 
454
  /**
464
  * @return string
465
  */
466
  public function getUpdateNewVersion( $file ) {
467
+ $info = $this->getUpdateInfo( $file );
468
+ return ( !is_null( $info ) && isset( $info->new_version ) ) ? $info->new_version : '';
469
  }
470
 
471
  /**
485
  * @param string $file
486
  * @return string
487
  */
488
+ public function getUrl_Activate( $file ) :string {
489
  return $this->getUrl_Action( $file, 'activate' );
490
  }
491
 
493
  * @param string $file
494
  * @return string
495
  */
496
+ public function getUrl_Deactivate( $file ) :string {
497
  return $this->getUrl_Action( $file, 'deactivate' );
498
  }
499
 
501
  * @param string $file
502
  * @return string
503
  */
504
+ public function getUrl_Upgrade( $file ) :string {
505
  return add_query_arg( [
506
  'action' => 'upgrade-plugin',
507
  'plugin' => urlencode( $file ),
514
  * @param string $action
515
  * @return string
516
  */
517
+ protected function getUrl_Action( $file, $action ) :string {
518
  return add_query_arg( [
519
  'action' => $action,
520
  'plugin' => urlencode( $file ),
521
  '_wpnonce' => wp_create_nonce( $action.'-plugin_'.$file )
522
+ ], self_admin_url( 'plugins.php' ) );
 
523
  }
524
 
525
  /**
526
  * @param string $file
527
  * @return bool
528
  */
529
+ public function isActive( $file ) :bool {
530
  return $this->isInstalled( $file ) && is_plugin_active( $file );
531
  }
532
 
src/lib/vendor/fernleafsystems/wordpress-services/src/Core/Themes.php CHANGED
@@ -3,7 +3,7 @@
3
  namespace FernleafSystems\Wordpress\Services\Core;
4
 
5
  use FernleafSystems\Wordpress\Services\Core\Upgrades;
6
- use FernleafSystems\Wordpress\Services\Core\VOs\WpThemeVo;
7
  use FernleafSystems\Wordpress\Services\Services;
8
  use FernleafSystems\Wordpress\Services\Utilities\WpOrg\Theme\Api;
9
 
@@ -13,10 +13,12 @@ use FernleafSystems\Wordpress\Services\Utilities\WpOrg\Theme\Api;
13
  */
14
  class Themes {
15
 
 
 
16
  /**
17
- * @var WpThemeVo[]
18
  */
19
- private $aLoadedVOs;
20
 
21
  /**
22
  * @param string $stylesheet
@@ -189,18 +191,18 @@ class Themes {
189
 
190
  /**
191
  * @param string $stylesheet
192
- * @param bool $bReload
193
- * @return WpThemeVo|null
194
  */
195
- public function getThemeAsVo( $stylesheet, $bReload = false ) {
196
  try {
197
- if ( !is_array( $this->aLoadedVOs ) ) {
198
- $this->aLoadedVOs = [];
199
  }
200
- if ( $bReload || !isset( $this->aLoadedVOs[ $stylesheet ] ) ) {
201
- $this->aLoadedVOs[ $stylesheet ] = new WpThemeVo( $stylesheet );
202
  }
203
- $asset = $this->aLoadedVOs[ $stylesheet ];
204
  }
205
  catch ( \Exception $e ) {
206
  $asset = null;
@@ -209,9 +211,9 @@ class Themes {
209
  }
210
 
211
  /**
212
- * @return WpThemeVo[]
213
  */
214
- public function getThemesAsVo() {
215
  return array_filter(
216
  array_map(
217
  function ( $stylesheet ) {
3
  namespace FernleafSystems\Wordpress\Services\Core;
4
 
5
  use FernleafSystems\Wordpress\Services\Core\Upgrades;
6
+ use FernleafSystems\Wordpress\Services\Core\VOs\Assets;
7
  use FernleafSystems\Wordpress\Services\Services;
8
  use FernleafSystems\Wordpress\Services\Utilities\WpOrg\Theme\Api;
9
 
13
  */
14
  class Themes {
15
 
16
+ private $aLoadedVOs;
17
+
18
  /**
19
+ * @var Assets\WpThemeVo[]
20
  */
21
+ private $loadedVOs;
22
 
23
  /**
24
  * @param string $stylesheet
191
 
192
  /**
193
  * @param string $stylesheet
194
+ * @param bool $reload
195
+ * @return Assets\WpThemeVo|null
196
  */
197
+ public function getThemeAsVo( string $stylesheet, bool $reload = false ) {
198
  try {
199
+ if ( !is_array( $this->loadedVOs ) ) {
200
+ $this->loadedVOs = [];
201
  }
202
+ if ( $reload || !isset( $this->loadedVOs[ $stylesheet ] ) ) {
203
+ $this->loadedVOs[ $stylesheet ] = new Assets\WpThemeVo( $stylesheet );
204
  }
205
+ $asset = $this->loadedVOs[ $stylesheet ];
206
  }
207
  catch ( \Exception $e ) {
208
  $asset = null;
211
  }
212
 
213
  /**
214
+ * @return Assets\WpThemeVo[]
215
  */
216
+ public function getThemesAsVo() :array {
217
  return array_filter(
218
  array_map(
219
  function ( $stylesheet ) {
src/lib/vendor/fernleafsystems/wordpress-services/src/Core/VOs/Assets/WpBaseVo.php ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace FernleafSystems\Wordpress\Services\Core\VOs\Assets;
4
+
5
+ use FernleafSystems\Utilities\Data\Adapter\DynPropertiesClass;
6
+
7
+ /**
8
+ * Class WpBaseVo
9
+ * @package FernleafSystems\Wordpress\Services\Core\VOs
10
+ * @property string Name
11
+ * @property string Version
12
+ * @property string Description
13
+ * @property string Author
14
+ * @property string AuthorURI
15
+ * @property string TextDomain
16
+ * @property string DomainPath
17
+ * @property bool $active
18
+ * @property string $version - alias for Version
19
+ * @property string $unique_id - alias for file/stylesheet
20
+ * @property string $asset_type - plugin or theme
21
+ */
22
+ abstract class WpBaseVo extends DynPropertiesClass {
23
+
24
+ protected $hasExtendedData = false;
25
+
26
+ public function __get( string $key ) {
27
+
28
+ if ( empty( $this->hasExtendedData ) && in_array( $key, $this->getExtendedDataSlugs() ) ) {
29
+ $this->applyFromArray( array_merge( $this->getRawData(), $this->getExtendedData() ) );
30
+ $this->hasExtendedData = true;
31
+ }
32
+
33
+ $value = parent::__get( $key );
34
+
35
+ switch ( $key ) {
36
+
37
+ case 'wp_info':
38
+ if ( is_null( $value ) ) {
39
+ $value = $this->loadWpInfo();
40
+ $this->wp_info = $value;
41
+ }
42
+ break;
43
+
44
+ default:
45
+ break;
46
+ }
47
+
48
+ return $value;
49
+ }
50
+
51
+ abstract public function getInstallDir() :string;
52
+
53
+ public function hasUpdate() :bool {
54
+ $this->new_version;
55
+ return !empty( $this->new_version ) && version_compare( $this->new_version, $this->Version, '>' );
56
+ }
57
+
58
+ abstract public function isWpOrg() :bool;
59
+
60
+ abstract protected function getExtendedData() :array;
61
+
62
+ /**
63
+ * @return string[]
64
+ */
65
+ protected function getExtendedDataSlugs() :array {
66
+ return [
67
+ 'new_version',
68
+ ];
69
+ }
70
+
71
+ /**
72
+ * @return mixed|false
73
+ */
74
+ abstract protected function loadWpInfo();
75
+ }
src/lib/vendor/fernleafsystems/wordpress-services/src/Core/VOs/Assets/WpPluginVo.php ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace FernleafSystems\Wordpress\Services\Core\VOs\Assets;
4
+
5
+ use FernleafSystems\Wordpress\Services\Services;
6
+ use FernleafSystems\Wordpress\Services\Utilities\WpOrg\Plugin;
7
+
8
+ /**
9
+ * Class WpPluginVo
10
+ * @package FernleafSystems\Wordpress\Services\Core\VOs
11
+ * @property string PluginURI
12
+ * @property bool Network
13
+ * @property string Title
14
+ * @property string AuthorName
15
+ * Extended Properties:
16
+ * @property string $id
17
+ * @property string $slug
18
+ * @property string $plugin
19
+ * @property string $new_version
20
+ * @property string $url
21
+ * @property string $package - the update package URL
22
+ * Custom Properties:
23
+ * @property string $file
24
+ * @property bool $svn_uses_tags
25
+ * @property Plugin\VOs\PluginInfoVO $wp_info
26
+ */
27
+ class WpPluginVo extends WpBaseVo {
28
+
29
+ /**
30
+ * WpPluginVo constructor.
31
+ * @param string $baseFile
32
+ * @throws \Exception
33
+ */
34
+ public function __construct( string $baseFile ) {
35
+ $WPP = Services::WpPlugins();
36
+ $p = $WPP->getPlugin( $baseFile );
37
+ if ( empty( $p ) ) {
38
+ throw new \Exception( sprintf( 'Plugin file %s does not exist', $baseFile ) );
39
+ }
40
+ $this->applyFromArray( $p );
41
+ $this->file = $baseFile;
42
+ $this->active = $WPP->isActive( $baseFile );
43
+ }
44
+
45
+ public function __get( string $key ) {
46
+
47
+ $value = parent::__get( $key );
48
+
49
+ switch ( $key ) {
50
+
51
+ case 'asset_type':
52
+ $value = 'plugin';
53
+ break;
54
+
55
+ case 'unique_id':
56
+ $value = $this->file;
57
+ break;
58
+
59
+ case 'version':
60
+ $value = $this->Version;
61
+ break;
62
+
63
+ case 'svn_uses_tags':
64
+ if ( is_null( $value ) ) {
65
+ $value = ( new Plugin\Versions() )
66
+ ->setWorkingSlug( $this->slug )
67
+ ->exists( $this->Version, true );
68
+ $this->svn_uses_tags = $value;
69
+ }
70
+ break;
71
+
72
+ default:
73
+ break;
74
+ }
75
+
76
+ return $value;
77
+ }
78
+
79
+ public function getInstallDir() :string {
80
+ return wp_normalize_path( trailingslashit( dirname( path_join( WP_PLUGIN_DIR, $this->file ) ) ) );
81
+ }
82
+
83
+ public function isWpOrg() :bool {
84
+ $this->id; // loads the data
85
+ return strpos( (string)$this->id, 'w.org/' ) === 0;
86
+ }
87
+
88
+ protected function getExtendedData() :array {
89
+ return Services::WpPlugins()->getExtendedData( $this->file );
90
+ }
91
+
92
+ /**
93
+ * @return string[]
94
+ */
95
+ protected function getExtendedDataSlugs() :array {
96
+ return array_merge( parent::getExtendedDataSlugs(), [
97
+ 'id',
98
+ 'slug',
99
+ 'plugin',
100
+ 'package',
101
+ 'url',
102
+ ] );
103
+ }
104
+
105
+ /**
106
+ * @return false|Plugin\VOs\PluginInfoVO
107
+ */
108
+ protected function loadWpInfo() {
109
+ try {
110
+ $info = ( new Plugin\Api() )
111
+ ->setWorkingSlug( $this->slug )
112
+ ->getInfo();
113
+ }
114
+ catch ( \Exception $e ) {
115
+ $info = false;
116
+ }
117
+ return $info;
118
+ }
119
+ }
src/lib/vendor/fernleafsystems/wordpress-services/src/Core/VOs/Assets/WpThemeVo.php ADDED
@@ -0,0 +1,138 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace FernleafSystems\Wordpress\Services\Core\VOs\Assets;
4
+
5
+ use FernleafSystems\Wordpress\Services\Services;
6
+ use FernleafSystems\Wordpress\Services\Utilities\WpOrg\Theme;
7
+
8
+ /**
9
+ * Class WpThemeVo
10
+ * @package FernleafSystems\Wordpress\Services\Core\VOs
11
+ * @property string $theme - the stylesheet
12
+ * @property string $stylesheet - the stylesheet
13
+ * @property \WP_Theme $wp_theme
14
+ * @property Theme\VOs\ThemeInfoVO|false $wp_info - wp.org theme info
15
+ * @property string $new_version
16
+ * @property string $url
17
+ * @property string $package
18
+ * @property string $requires
19
+ * @property string $requires_php
20
+ * @property bool $is_child
21
+ * @property bool $is_parent
22
+ *
23
+ * Dynamic Properties:
24
+ * @property string $slug (alias for Stylesheet)
25
+ */
26
+ class WpThemeVo extends WpBaseVo {
27
+
28
+ /**
29
+ * WpPluginVo constructor.
30
+ * @param string $stylesheet - the name of the theme folder.
31
+ * @throws \Exception
32
+ */
33
+ public function __construct( string $stylesheet ) {
34
+ $WPT = Services::WpThemes();
35
+ $t = $WPT->getTheme( $stylesheet );
36
+ if ( empty( $t ) ) {
37
+ throw new \Exception( sprintf( 'Theme file %s does not exist', $stylesheet ) );
38
+ }
39
+ $this->wp_theme = $t;
40
+ $this->stylesheet = $stylesheet;
41
+ $this->active = $WPT->isActive( $stylesheet );
42
+ $this->is_child = $this->active && $WPT->isActiveThemeAChild();
43
+ $this->is_parent = !$this->active && $WPT->isActiveParent( $stylesheet );
44
+ }
45
+
46
+ public function __get( string $key ) {
47
+
48
+ $value = parent::__get( $key );
49
+
50
+ if ( in_array( $key, $this->getWpThemeKeys() ) ) {
51
+ $value = $this->wp_theme->get( $key );
52
+ }
53
+ else {
54
+ switch ( $key ) {
55
+
56
+ case 'asset_type':
57
+ $value = 'theme';
58
+ break;
59
+
60
+ case 'slug':
61
+ case 'unique_id':
62
+ $value = $this->stylesheet;
63
+ break;
64
+
65
+ case 'version':
66
+ if ( is_null( $value ) ) {
67
+ $value = $this->Version;
68
+ }
69
+ break;
70
+
71
+ default:
72
+ break;
73
+ }
74
+ }
75
+
76
+ return $value;
77
+ }
78
+
79
+ /**
80
+ * @return string[]
81
+ */
82
+ private function getWpThemeKeys() :array {
83
+ return [
84
+ 'Name',
85
+ 'ThemeURI',
86
+ 'Description',
87
+ 'Author',
88
+ 'AuthorURI',
89
+ 'Version',
90
+ 'Template',
91
+ 'Status',
92
+ 'Tags',
93
+ 'TextDomain',
94
+ 'DomainPath',
95
+ ];
96
+ }
97
+
98
+ public function getInstallDir() :string {
99
+ return wp_normalize_path( trailingslashit( $this->wp_theme->get_stylesheet_directory() ) );
100
+ }
101
+
102
+ public function isWpOrg() :bool {
103
+ $this->wp_info;
104
+ return !empty( $this->wp_info );
105
+ }
106
+
107
+ protected function getExtendedData() :array {
108
+ return Services::WpThemes()->getExtendedData( $this->stylesheet );
109
+ }
110
+
111
+ /**
112
+ * @inheritDoc
113
+ */
114
+ protected function getExtendedDataSlugs() :array {
115
+ return array_merge( parent::getExtendedDataSlugs(), [
116
+ 'theme',
117
+ 'package',
118
+ 'requires',
119
+ 'requires_php',
120
+ 'url',
121
+ ] );
122
+ }
123
+
124
+ /**
125
+ * @return false|Theme\VOs\ThemeInfoVO
126
+ */
127
+ protected function loadWpInfo() {
128
+ try {
129
+ $info = ( new Theme\Api() )
130
+ ->setWorkingSlug( $this->stylesheet )
131
+ ->getInfo();
132
+ }
133
+ catch ( \Exception $e ) {
134
+ $info = false;
135
+ }
136
+ return $info;
137
+ }
138
+ }
src/lib/vendor/fernleafsystems/wordpress-services/src/Core/VOs/WpBaseVo.php CHANGED
@@ -20,6 +20,7 @@ use FernleafSystems\Wordpress\Services\Utilities\WpOrg\Theme;
20
  * @property bool $active
21
  * @property string $version - alias for Version
22
  * @property string $unique_id - alias for file/stylesheet
 
23
  */
24
  abstract class WpBaseVo {
25
 
20
  * @property bool $active
21
  * @property string $version - alias for Version
22
  * @property string $unique_id - alias for file/stylesheet
23
+ * @deprecated
24
  */
25
  abstract class WpBaseVo {
26
 
src/lib/vendor/fernleafsystems/wordpress-services/src/Core/VOs/WpPluginVo.php CHANGED
@@ -23,6 +23,7 @@ use FernleafSystems\Wordpress\Services\Utilities\WpOrg\Plugin;
23
  * @property string $file
24
  * @property bool $svn_uses_tags
25
  * @property Plugin\VOs\PluginInfoVO $wp_info
 
26
  */
27
  class WpPluginVo extends WpBaseVo {
28
 
@@ -117,7 +118,7 @@ class WpPluginVo extends WpBaseVo {
117
  ->setWorkingSlug( $this->slug )
118
  ->getInfo();
119
  }
120
- catch ( \Exception $oE ) {
121
  $oInfo = false;
122
  }
123
  return $oInfo;
23
  * @property string $file
24
  * @property bool $svn_uses_tags
25
  * @property Plugin\VOs\PluginInfoVO $wp_info
26
+ * @deprecated
27
  */
28
  class WpPluginVo extends WpBaseVo {
29
 
118
  ->setWorkingSlug( $this->slug )
119
  ->getInfo();
120
  }
121
+ catch ( \Exception $e ) {
122
  $oInfo = false;
123
  }
124
  return $oInfo;
src/lib/vendor/fernleafsystems/wordpress-services/src/Core/VOs/WpThemeVo.php CHANGED
@@ -19,6 +19,7 @@ use FernleafSystems\Wordpress\Services\Utilities\WpOrg\Theme;
19
  * @property string $requires_php
20
  * @property bool $is_child
21
  * @property bool $is_parent
 
22
  */
23
  class WpThemeVo extends WpBaseVo {
24
 
19
  * @property string $requires_php
20
  * @property bool $is_child
21
  * @property bool $is_parent
22
+ * @deprecated
23
  */
24
  class WpThemeVo extends WpBaseVo {
25
 
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Consumers/PluginConsumer.php CHANGED
@@ -1,13 +1,9 @@
1
- <?php
2
 
3
  namespace FernleafSystems\Wordpress\Services\Utilities\Consumers;
4
 
5
- use FernleafSystems\Wordpress\Services\Core\VOs\WpPluginVo;
6
 
7
- /**
8
- * Trait PluginConsumer
9
- * @package FernleafSystems\Wordpress\Services\Utilities\Consumers
10
- */
11
  trait PluginConsumer {
12
 
13
  /**
@@ -22,19 +18,16 @@ trait PluginConsumer {
22
  return $this->oWorkingPlugin;
23
  }
24
 
25
- /**
26
- * @return bool
27
- */
28
- public function hasWorkingPlugin() {
29
  return $this->oWorkingPlugin instanceof WpPluginVo;
30
  }
31
 
32
  /**
33
- * @param WpPluginVo $oPlugin
34
  * @return $this
35
  */
36
- public function setWorkingPlugin( $oPlugin ) {
37
- $this->oWorkingPlugin = $oPlugin;
38
  return $this;
39
  }
40
  }
1
+ <?php declare( strict_types=1 );
2
 
3
  namespace FernleafSystems\Wordpress\Services\Utilities\Consumers;
4
 
5
+ use FernleafSystems\Wordpress\Services\Core\VOs\Assets\WpPluginVo;
6
 
 
 
 
 
7
  trait PluginConsumer {
8
 
9
  /**
18
  return $this->oWorkingPlugin;
19
  }
20
 
21
+ public function hasWorkingPlugin() :bool {
 
 
 
22
  return $this->oWorkingPlugin instanceof WpPluginVo;
23
  }
24
 
25
  /**
26
+ * @param WpPluginVo $plugin
27
  * @return $this
28
  */
29
+ public function setWorkingPlugin( $plugin ) {
30
+ $this->oWorkingPlugin = $plugin;
31
  return $this;
32
  }
33
  }
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/File/WriteDataToFileEncrypted.php CHANGED
@@ -26,7 +26,7 @@ class WriteDataToFileEncrypted {
26
  throw new \Exception( 'Could not seal data with message: '.$oEncrypted->message );
27
  }
28
 
29
- $bSuccess = Services::WpFs()->putFileContent( $sPath, json_encode( $oEncrypted->getRawDataAsArray() ) );
30
  if ( $bSuccess && !empty( $sPrivateKeyForVerify ) ) {
31
  $bSuccess = ( new ReadDataFromFileEncrypted() )->run( $sPath, $sPrivateKeyForVerify ) === $sData;
32
  }
26
  throw new \Exception( 'Could not seal data with message: '.$oEncrypted->message );
27
  }
28
 
29
+ $bSuccess = Services::WpFs()->putFileContent( $sPath, json_encode( $oEncrypted->getRawData() ) );
30
  if ( $bSuccess && !empty( $sPrivateKeyForVerify ) ) {
31
  $bSuccess = ( new ReadDataFromFileEncrypted() )->run( $sPath, $sPrivateKeyForVerify ) === $sData;
32
  }
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/ApiBase.php CHANGED
@@ -11,7 +11,8 @@ use FernleafSystems\Wordpress\Services\Utilities\Integrations\RequestVO;
11
  */
12
  abstract class ApiBase {
13
 
14
- const API_URL = 'https://wphashes.com/api/apto-wphashes/v1/';
 
15
  const API_ENDPOINT = '';
16
  const REQUEST_TYPE = 'GET';
17
  const RESPONSE_DATA_KEY = '';
@@ -21,34 +22,30 @@ abstract class ApiBase {
21
  /**
22
  * @var RequestVO
23
  */
24
- private $oReq;
25
 
26
  /**
27
  * @var bool
28
  */
29
- private $bUseQueryCache = false;
30
 
31
  /**
32
  * @var array
33
  */
34
- private static $aQueryCache = [];
35
 
36
  /**
37
- * ApiBase constructor.
38
- * @param string $sApiToken
39
  */
40
- public function __construct( $sApiToken = null ) {
41
- $this->setApiToken( $sApiToken );
42
  }
43
 
44
  protected function getApiUrl() :string {
45
- return static::API_URL.static::API_ENDPOINT;
46
  }
47
 
48
- /**
49
- * @return array
50
- */
51
- protected function getQueryData() {
52
  return empty( static::$API_TOKEN ) ? [] : [ 'token' => static::$API_TOKEN ];
53
  }
54
 
@@ -56,10 +53,10 @@ abstract class ApiBase {
56
  * @return RequestVO|mixed
57
  */
58
  protected function getRequestVO() {
59
- if ( !isset( $this->oReq ) ) {
60
- $this->oReq = $this->newReqVO();
61
  }
62
- return $this->oReq;
63
  }
64
 
65
  /**
@@ -73,16 +70,16 @@ abstract class ApiBase {
73
  * @return array|mixed|null
74
  */
75
  public function query() {
76
- $aData = $this->fireRequestDecodeResponse();
77
- if ( is_array( $aData ) ) {
78
  if ( strlen( static::RESPONSE_DATA_KEY ) > 0 ) {
79
- $aData = isset( $aData[ static::RESPONSE_DATA_KEY ] ) ? $aData[ static::RESPONSE_DATA_KEY ] : null;
80
  }
81
  }
82
  else {
83
- $aData = null;
84
  }
85
- return $aData;
86
  }
87
 
88
  /**
@@ -100,14 +97,14 @@ abstract class ApiBase {
100
  $this->preRequest();
101
  switch ( static::REQUEST_TYPE ) {
102
  case 'POST':
103
- $sResponse = $this->fireRequest_POST();
104
  break;
105
  case 'GET':
106
  default:
107
- $sResponse = $this->fireRequest_GET();
108
  break;
109
  }
110
- return $sResponse;
111
  }
112
 
113
  protected function preRequest() {
@@ -117,62 +114,62 @@ abstract class ApiBase {
117
  * @return string
118
  */
119
  protected function fireRequest_GET() {
120
- $sResponse = null;
121
 
122
- $sUrl = add_query_arg( $this->getQueryData(), $this->getApiUrl() );
123
- $sSig = md5( $sUrl );
124
 
125
- if ( $this->isUseQueryCache() && isset( self::$aQueryCache[ $sSig ] ) ) {
126
- $sResponse = self::$aQueryCache[ $sSig ];
127
  }
128
 
129
- if ( is_null( $sResponse ) ) {
130
- $sResponse = ( new HttpRequest() )->getContent( $sUrl );
131
  if ( $this->isUseQueryCache() ) {
132
- self::$aQueryCache[ $sSig ] = $sResponse;
133
  }
134
  }
135
 
136
- return $sResponse;
137
  }
138
 
139
  /**
140
  * @return string|null
141
  */
142
  protected function fireRequest_POST() {
143
- $oHttp = new HttpRequest();
144
- $oHttp
145
  ->post(
146
  add_query_arg( $this->getQueryData(), $this->getApiUrl() ),
147
- [ 'body' => $this->getRequestVO()->getRawDataAsArray() ]
148
  );
149
- return $oHttp->isSuccess() ? $oHttp->lastResponse->body : null;
150
  }
151
 
152
  /**
153
  * @return bool
154
  */
155
- public function isUseQueryCache() {
156
- return (bool)$this->bUseQueryCache;
157
  }
158
 
159
  /**
160
- * @param string $sToken
161
  * @return $this
162
  */
163
- public function setApiToken( $sToken ) {
164
- if ( is_string( $sToken ) && preg_match( '#^[a-z0-9]{32,}$#', $sToken ) ) {
165
- static::$API_TOKEN = $sToken;
166
  }
167
  return $this;
168
  }
169
 
170
  /**
171
- * @param bool $bUseQueryCache
172
  * @return $this
173
  */
174
- public function setUseQueryCache( $bUseQueryCache ) {
175
- $this->bUseQueryCache = $bUseQueryCache;
176
  return $this;
177
  }
178
  }
11
  */
12
  abstract class ApiBase {
13
 
14
+ const API_URL = 'https://wphashes.com/api/apto-wphashes';
15
+ const API_VERSION = 1;
16
  const API_ENDPOINT = '';
17
  const REQUEST_TYPE = 'GET';
18
  const RESPONSE_DATA_KEY = '';
22
  /**
23
  * @var RequestVO
24
  */
25
+ private $req;
26
 
27
  /**
28
  * @var bool
29
  */
30
+ private $useQueryCache = false;
31
 
32
  /**
33
  * @var array
34
  */
35
+ private static $QueryCache = [];
36
 
37
  /**
38
+ * @param string $apiToken
 
39
  */
40
+ public function __construct( $apiToken = null ) {
41
+ $this->setApiToken( $apiToken );
42
  }
43
 
44
  protected function getApiUrl() :string {
45
+ return sprintf( '%s/v%s/%s', static::API_URL, static::API_VERSION, static::API_ENDPOINT );
46
  }
47
 
48
+ protected function getQueryData() :array {
 
 
 
49
  return empty( static::$API_TOKEN ) ? [] : [ 'token' => static::$API_TOKEN ];
50
  }
51
 
53
  * @return RequestVO|mixed
54
  */
55
  protected function getRequestVO() {
56
+ if ( !isset( $this->req ) ) {
57
+ $this->req = $this->newReqVO();
58
  }
59
+ return $this->req;
60
  }
61
 
62
  /**
70
  * @return array|mixed|null
71
  */
72
  public function query() {
73
+ $data = $this->fireRequestDecodeResponse();
74
+ if ( is_array( $data ) ) {
75
  if ( strlen( static::RESPONSE_DATA_KEY ) > 0 ) {
76
+ $data = $data[ static::RESPONSE_DATA_KEY ] ?? null;
77
  }
78
  }
79
  else {
80
+ $data = null;
81
  }
82
+ return $data;
83
  }
84
 
85
  /**
97
  $this->preRequest();
98
  switch ( static::REQUEST_TYPE ) {
99
  case 'POST':
100
+ $response = $this->fireRequest_POST();
101
  break;
102
  case 'GET':
103
  default:
104
+ $response = $this->fireRequest_GET();
105
  break;
106
  }
107
+ return $response;
108
  }
109
 
110
  protected function preRequest() {
114
  * @return string
115
  */
116
  protected function fireRequest_GET() {
117
+ $response = null;
118
 
119
+ $url = add_query_arg( $this->getQueryData(), $this->getApiUrl() );
120
+ $sig = md5( $url );
121
 
122
+ if ( $this->isUseQueryCache() && isset( self::$QueryCache[ $sig ] ) ) {
123
+ $response = self::$QueryCache[ $sig ];
124
  }
125
 
126
+ if ( is_null( $response ) ) {
127
+ $response = ( new HttpRequest() )->getContent( $url );
128
  if ( $this->isUseQueryCache() ) {
129
+ self::$QueryCache[ $sig ] = $response;
130
  }
131
  }
132
 
133
+ return $response;
134
  }
135
 
136
  /**
137
  * @return string|null
138
  */
139
  protected function fireRequest_POST() {
140
+ $http = new HttpRequest();
141
+ $http
142
  ->post(
143
  add_query_arg( $this->getQueryData(), $this->getApiUrl() ),
144
+ [ 'body' => $this->getRequestVO()->getRawData() ]
145
  );
146
+ return $http->isSuccess() ? $http->lastResponse->body : null;
147
  }
148
 
149
  /**
150
  * @return bool
151
  */
152
+ public function isUseQueryCache() :bool {
153
+ return (bool)$this->useQueryCache;
154
  }
155
 
156
  /**
157
+ * @param string $token
158
  * @return $this
159
  */
160
+ public function setApiToken( $token ) {
161
+ if ( is_string( $token ) && preg_match( '#^[a-z0-9]{32,}$#', $token ) ) {
162
+ static::$API_TOKEN = $token;
163
  }
164
  return $this;
165
  }
166
 
167
  /**
168
+ * @param bool $useQueryCache
169
  * @return $this
170
  */
171
+ public function setUseQueryCache( bool $useQueryCache ) {
172
+ $this->useQueryCache = $useQueryCache;
173
  return $this;
174
  }
175
  }
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/ApiPing.php CHANGED
@@ -2,16 +2,12 @@
2
 
3
  namespace FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes;
4
 
5
- /**
6
- * Class ApiPing
7
- * @package FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes
8
- */
9
  class ApiPing extends ApiBase {
10
 
11
  const API_ENDPOINT = 'ping';
12
 
13
  public function ping() :bool {
14
  $r = $this->query();
15
- return ( is_array( $r ) && isset( $r[ 'pong' ] ) ) ? ( $r[ 'pong' ] == 'ping' ) : false;
16
  }
17
  }
2
 
3
  namespace FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes;
4
 
 
 
 
 
5
  class ApiPing extends ApiBase {
6
 
7
  const API_ENDPOINT = 'ping';
8
 
9
  public function ping() :bool {
10
  $r = $this->query();
11
+ return is_array( $r ) && isset( $r[ 'pong' ] ) && $r[ 'pong' ] == 'ping';
12
  }
13
  }
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/CrowdSourcedHashes/Base.php ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ <?php declare( strict_types=1 );
2
+
3
+ namespace FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\CrowdSourcedHashes;
4
+
5
+ abstract class Base extends \FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\ApiBase {
6
+
7
+ const API_ENDPOINT = 'cshashes';
8
+ }
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/CrowdSourcedHashes/Query/AssetHashesBase.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php declare( strict_types=1 );
2
+
3
+ namespace FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\CrowdSourcedHashes\Query;
4
+
5
+ use FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\CrowdSourcedHashes\Base;
6
+
7
+ abstract class AssetHashesBase extends Base {
8
+
9
+ const DEFAULT_HASH_ALGO = 'sha1';
10
+ const RESPONSE_DATA_KEY = 'hashes';
11
+
12
+ protected function getApiUrl() :string {
13
+ /** @var RequestVO $req */
14
+ $req = $this->getRequestVO();
15
+ return sprintf( '%s/%s/%s/%s', parent::getApiUrl(), $req->type, $req->slug, $req->version );
16
+ }
17
+
18
+ public function getHashes( string $type, string $slug, string $version ) :array {
19
+ /** @var RequestVO $req */
20
+ $req = $this->getRequestVO();
21
+ $req->type = $type;
22
+ $req->slug = trim( sanitize_key( $slug ), '-_' );
23
+ $req->version = trim( $version, 'v' );
24
+ $result = $this->query();
25
+ return is_array( $result ) ? $result : [];
26
+ }
27
+ }
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/CrowdSourcedHashes/Query/Plugin.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php declare( strict_types=1 );
2
+
3
+ namespace FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\CrowdSourcedHashes\Query;
4
+
5
+ use FernleafSystems\Wordpress\Services;
6
+
7
+ class Plugin extends AssetHashesBase {
8
+
9
+ const TYPE = 'p';
10
+
11
+ public function getHashesFromVO( Services\Core\VOs\Assets\WpPluginVo $VO ) :array {
12
+ return $this->getHashes( static::TYPE, $VO->slug, $VO->Version );
13
+ }
14
+ }
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/CrowdSourcedHashes/Query/RequestVO.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php declare( strict_types=1 );
2
+
3
+ namespace FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\CrowdSourcedHashes\Query;
4
+
5
+ use FernleafSystems\Wordpress\Services\Utilities\Integrations;
6
+
7
+ /**
8
+ * Class RequestVO
9
+ * @package FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\CrowdSourcedHashes\Query
10
+ * @property string $type
11
+ * @property string $version
12
+ * @property string $slug
13
+ */
14
+ class RequestVO extends Integrations\RequestVO {
15
+
16
+ }
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/CrowdSourcedHashes/Query/Theme.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php declare( strict_types=1 );
2
+
3
+ namespace FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\CrowdSourcedHashes\Query;
4
+
5
+ use FernleafSystems\Wordpress\Services;
6
+
7
+ class Theme extends AssetHashesBase {
8
+
9
+ const TYPE = 't';
10
+
11
+ public function getHashesFromVO( Services\Core\VOs\Assets\WpThemeVo $VO ) :array {
12
+ return $this->getHashes( static::TYPE, $VO->stylesheet, $VO->version );
13
+ }
14
+ }
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/CrowdSourcedHashes/Submit/BaseSubmit.php ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php declare( strict_types=1 );
2
+
3
+ namespace FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\CrowdSourcedHashes\Submit;
4
+
5
+ use FernleafSystems\Wordpress\Services;
6
+
7
+ abstract class BaseSubmit extends Services\Utilities\Integrations\WpHashes\CrowdSourcedHashes\Base {
8
+
9
+ const API_ENDPOINT = 'cshashes/submit';
10
+
11
+ protected $hashes;
12
+
13
+ public function setHashes( array $hashes ) {
14
+ ksort( $hashes );
15
+ $this->hashes = $hashes;
16
+ return $this;
17
+ }
18
+
19
+ public function preRequest() {
20
+ /** @var RequestVO $req */
21
+ $req = $this->getRequestVO();
22
+ $req->hash = sha1( json_encode( $this->hashes ) );
23
+ }
24
+
25
+ protected function getApiUrl() :string {
26
+ /** @var RequestVO $req */
27
+ $req = $this->getRequestVO();
28
+ return sprintf( '%s/%s', parent::getApiUrl(), $req->hash );
29
+ }
30
+ }
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/CrowdSourcedHashes/Submit/PreSubmit.php ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <?php declare( strict_types=1 );
2
+
3
+ namespace FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\CrowdSourcedHashes\Submit;
4
+
5
+ class PreSubmit extends BaseSubmit {
6
+
7
+ }
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/CrowdSourcedHashes/Submit/RequestVO.php ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php declare( strict_types=1 );
2
+
3
+ namespace FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\CrowdSourcedHashes\Submit;
4
+
5
+ use FernleafSystems\Wordpress\Services\Utilities\Integrations;
6
+
7
+ /**
8
+ * Class RequestVO
9
+ * @package FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\Hashes
10
+ * @property string $type
11
+ * @property string $version
12
+ * @property string $slug
13
+ * @property string $hash
14
+ * @property string[] $hashes
15
+ */
16
+ class RequestVO extends Integrations\RequestVO {
17
+
18
+ }
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/CrowdSourcedHashes/Submit/Submit.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php declare( strict_types=1 );
2
+
3
+ namespace FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\CrowdSourcedHashes\Submit;
4
+
5
+ use FernleafSystems\Wordpress\Services\Core\VOs\Assets;
6
+
7
+ class Submit extends BaseSubmit {
8
+
9
+ const REQUEST_TYPE = 'POST';
10
+
11
+ public function preRequest() {
12
+ parent::preRequest();
13
+
14
+ /** @var RequestVO $req */
15
+ $req = $this->getRequestVO();
16
+ $req->hashes = $this->hashes; // hashes are sent with a full submit
17
+ }
18
+
19
+ public function submitPlugin( Assets\WpPluginVo $VO ) :array {
20
+ /** @var RequestVO $req */
21
+ $req = $this->getRequestVO();
22
+
23
+ $req->type = 'p';
24
+ $req->slug = $VO->slug;
25
+ $req->version = $VO->Version;
26
+
27
+ return $this->query();
28
+ }
29
+
30
+ public function submitTheme( Assets\WpThemeVo $VO ) :array {
31
+ /** @var RequestVO $req */
32
+ $req = $this->getRequestVO();
33
+
34
+ $req->type = 't';
35
+ $req->slug = $VO->stylesheet;
36
+ $req->version = $VO->Version;
37
+
38
+ return $this->query();
39
+ }
40
+ }
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/AssetHashesBase.php CHANGED
@@ -17,7 +17,7 @@ abstract class AssetHashesBase extends Base {
17
  'locale' => false,
18
  'hash' => false,
19
  ],
20
- $this->getRequestVO()->getRawDataAsArray()
21
  ) ) );
22
  return sprintf( '%s/%s', parent::getApiUrl(), implode( '/', $data ) );
23
  }
@@ -30,31 +30,31 @@ abstract class AssetHashesBase extends Base {
30
  }
31
 
32
  protected function preRequest() {
33
- /** @var RequestVO $oReq */
34
- $oReq = $this->getRequestVO();
35
- if ( empty( $oReq->hash ) ) {
36
  $this->setHashAlgo( static::DEFAULT_HASH_ALGO );
37
  }
38
- if ( empty( $oReq->type ) ) {
39
  $this->setType( static::TYPE );
40
  }
41
  }
42
 
43
  /**
44
- * @param string $sHashAlgo
45
  * @return $this
46
  */
47
- public function setHashAlgo( $sHashAlgo ) {
48
- $this->getRequestVO()->hash = $sHashAlgo;
49
  return $this;
50
  }
51
 
52
  /**
53
- * @param string $sType
54
  * @return $this
55
  */
56
- public function setType( $sType ) {
57
- $this->getRequestVO()->type = $sType;
58
  return $this;
59
  }
60
  }
17
  'locale' => false,
18
  'hash' => false,
19
  ],
20
+ $this->getRequestVO()->getRawData()
21
  ) ) );
22
  return sprintf( '%s/%s', parent::getApiUrl(), implode( '/', $data ) );
23
  }
30
  }
31
 
32
  protected function preRequest() {
33
+ /** @var RequestVO $req */
34
+ $req = $this->getRequestVO();
35
+ if ( empty( $req->hash ) ) {
36
  $this->setHashAlgo( static::DEFAULT_HASH_ALGO );
37
  }
38
+ if ( empty( $req->type ) ) {
39
  $this->setType( static::TYPE );
40
  }
41
  }
42
 
43
  /**
44
+ * @param string $algo
45
  * @return $this
46
  */
47
+ public function setHashAlgo( $algo ) {
48
+ $this->getRequestVO()->hash = $algo;
49
  return $this;
50
  }
51
 
52
  /**
53
+ * @param string $type
54
  * @return $this
55
  */
56
+ public function setType( $type ) {
57
+ $this->getRequestVO()->type = $type;
58
  return $this;
59
  }
60
  }
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/Plugin.php CHANGED
@@ -12,9 +12,18 @@ class Plugin extends PluginThemeBase {
12
 
13
  const TYPE = 'plugin';
14
 
 
 
 
 
 
 
 
 
15
  /**
16
  * @param Services\Core\VOs\WpPluginVo $VO
17
  * @return array|null
 
18
  */
19
  public function getHashesFromVO( Services\Core\VOs\WpPluginVo $VO ) {
20
  return $this->getHashes( $VO->slug, $VO->Version );
12
 
13
  const TYPE = 'plugin';
14
 
15
+ /**
16
+ * @param Services\Core\VOs\Assets\WpPluginVo $VO
17
+ * @return array|null
18
+ */
19
+ public function getPluginHashes( Services\Core\VOs\Assets\WpPluginVo $VO ) {
20
+ return $this->getHashes( $VO->slug, $VO->Version );
21
+ }
22
+
23
  /**
24
  * @param Services\Core\VOs\WpPluginVo $VO
25
  * @return array|null
26
+ * @deprecated 2.15
27
  */
28
  public function getHashesFromVO( Services\Core\VOs\WpPluginVo $VO ) {
29
  return $this->getHashes( $VO->slug, $VO->Version );
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/Theme.php CHANGED
@@ -12,9 +12,18 @@ class Theme extends PluginThemeBase {
12
 
13
  const TYPE = 'theme';
14
 
 
 
 
 
 
 
 
 
15
  /**
16
  * @param Services\Core\VOs\WpThemeVo $oVO
17
  * @return array|null
 
18
  */
19
  public function getHashesFromVO( Services\Core\VOs\WpThemeVo $oVO ) {
20
  return $this->getHashes( $oVO->stylesheet, $oVO->version );
12
 
13
  const TYPE = 'theme';
14
 
15
+ /**
16
+ * @param Services\Core\VOs\Assets\WpThemeVo $VO
17
+ * @return array|null
18
+ */
19
+ public function getThemeHashes( Services\Core\VOs\Assets\WpThemeVo $VO ) {
20
+ return $this->getHashes( $VO->stylesheet, $VO->Version );
21
+ }
22
+
23
  /**
24
  * @param Services\Core\VOs\WpThemeVo $oVO
25
  * @return array|null
26
+ * @deprecated 2.15
27
  */
28
  public function getHashesFromVO( Services\Core\VOs\WpThemeVo $oVO ) {
29
  return $this->getHashes( $oVO->stylesheet, $oVO->version );
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Malware/Confidence/Retrieve.php CHANGED
@@ -20,7 +20,7 @@ class Retrieve extends Base {
20
  'hash' => false,
21
  'algo' => false,
22
  ],
23
- $this->getRequestVO()->getRawDataAsArray()
24
  ) );
25
  return sprintf( '%s/%s', parent::getApiUrl(), implode( '/', $data ) );
26
  }
20
  'hash' => false,
21
  'algo' => false,
22
  ],
23
+ $this->getRequestVO()->getRawData()
24
  ) );
25
  return sprintf( '%s/%s', parent::getApiUrl(), implode( '/', $data ) );
26
  }
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Token/Solicit.php CHANGED
@@ -28,14 +28,11 @@ class Solicit extends Base {
28
  return sprintf( '%s/%s/%s', parent::getApiUrl(), $req->action, $req->install_id );
29
  }
30
 
31
- /**
32
- * @inheritDoc
33
- */
34
- protected function getQueryData() {
35
- /** @var RequestVO $oReq */
36
- $oReq = $this->getRequestVO();
37
- $aData = parent::getQueryData();
38
- $aData[ 'url' ] = $oReq->url;
39
- return $aData;
40
  }
41
  }
28
  return sprintf( '%s/%s/%s', parent::getApiUrl(), $req->action, $req->install_id );
29
  }
30
 
31
+ protected function getQueryData() :array {
32
+ /** @var RequestVO $req */
33
+ $req = $this->getRequestVO();
34
+ $data = parent::getQueryData();
35
+ $data[ 'url' ] = $req->url;
36
+ return $data;
 
 
 
37
  }
38
  }
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Verify/Email.php CHANGED
@@ -25,7 +25,7 @@ class Email extends Base {
25
  'action' => false,
26
  'address' => false,
27
  ],
28
- $this->getRequestVO()->getRawDataAsArray()
29
  ) ) );
30
  return sprintf( '%s/%s', parent::getApiUrl(), implode( '/', $data ) );
31
  }
25
  'action' => false,
26
  'address' => false,
27
  ],
28
+ $this->getRequestVO()->getRawData()
29
  ) ) );
30
  return sprintf( '%s/%s', parent::getApiUrl(), implode( '/', $data ) );
31
  }
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Vulnerabilities/Base.php CHANGED
@@ -7,8 +7,9 @@ use FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes;
7
  abstract class Base extends WpHashes\ApiBase {
8
 
9
  const API_ENDPOINT = 'vulnerabilities';
 
 
10
  const ASSET_TYPE = '';
11
- const RESPONSE_DATA_KEY = 'vulnerabilities';
12
 
13
  /**
14
  * @return array[]|null
@@ -18,7 +19,7 @@ abstract class Base extends WpHashes\ApiBase {
18
  }
19
 
20
  protected function getApiUrl() :string {
21
- return parent::getApiUrl().'/'.$this->getRequestVO()->type;
22
  }
23
 
24
  /**
7
  abstract class Base extends WpHashes\ApiBase {
8
 
9
  const API_ENDPOINT = 'vulnerabilities';
10
+ const API_VERSION = 2;
11
+ const RESPONSE_DATA_KEY = 'data';
12
  const ASSET_TYPE = '';
 
13
 
14
  /**
15
  * @return array[]|null
19
  }
20
 
21
  protected function getApiUrl() :string {
22
+ return sprintf( '%s/%s', parent::getApiUrl(), $this->getRequestVO()->type );
23
  }
24
 
25
  /**
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Vulnerabilities/Plugin.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  namespace FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\Vulnerabilities;
4
 
5
- use FernleafSystems\Wordpress\Services;
6
 
7
  /**
8
  * Class Plugin
@@ -13,10 +13,10 @@ class Plugin extends BasePluginTheme {
13
  const ASSET_TYPE = 'plugin';
14
 
15
  /**
16
- * @param Services\Core\VOs\WpPluginVo $oPluginVO
17
  * @return array[]|null
18
  */
19
- public function getFromVO( Services\Core\VOs\WpPluginVo $oPluginVO ) {
20
- return $this->getVulnerabilities( $oPluginVO->slug, $oPluginVO->Version );
21
  }
22
  }
2
 
3
  namespace FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\Vulnerabilities;
4
 
5
+ use FernleafSystems\Wordpress\Services\Core\VOs\Assets\WpPluginVo;
6
 
7
  /**
8
  * Class Plugin
13
  const ASSET_TYPE = 'plugin';
14
 
15
  /**
16
+ * @param WpPluginVo $plugin
17
  * @return array[]|null
18
  */
19
+ public function getFromVO( WpPluginVo $plugin ) {
20
+ return $this->getVulnerabilities( $plugin->slug, $plugin->Version );
21
  }
22
  }
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Vulnerabilities/RequestVO.php CHANGED
@@ -1,4 +1,4 @@
1
- <?php
2
 
3
  namespace FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\Vulnerabilities;
4
 
1
+ <?php declare( strict_types=1 );
2
 
3
  namespace FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\Vulnerabilities;
4
 
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/PluginUserMeta.php CHANGED
@@ -10,6 +10,7 @@ use FernleafSystems\Wordpress\Services\Services;
10
  * @property string $prefix
11
  * @property int $user_id
12
  * @property array $flash_msg
 
13
  */
14
  class PluginUserMeta {
15
 
10
  * @property string $prefix
11
  * @property int $user_id
12
  * @property array $flash_msg
13
+ * @deprecated
14
  */
15
  class PluginUserMeta {
16
 
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Base/PluginThemeFilesBase.php CHANGED
@@ -11,12 +11,12 @@ use FernleafSystems\Wordpress\Services;
11
  abstract class PluginThemeFilesBase {
12
 
13
  /**
14
- * @param string $sFullFilePath
15
  * @return bool
16
  */
17
- public function replaceFileFromVcs( $sFullFilePath ) {
18
- $sTmpFile = $this->getOriginalFileFromVcs( $sFullFilePath );
19
- return !empty( $sTmpFile ) && Services\Services::WpFs()->move( $sTmpFile, $sFullFilePath );
20
  }
21
 
22
  /**
@@ -42,15 +42,15 @@ abstract class PluginThemeFilesBase {
42
  }
43
 
44
  /**
45
- * @param string $sFullFilePath
46
  * @return string|null
47
  */
48
- abstract public function getOriginalFileFromVcs( $sFullFilePath );
49
 
50
  /**
51
  * Gets the path of the plugin file relative to its own home plugin dir. (not wp-content/plugins/)
52
- * @param string $sFile
53
  * @return string
54
  */
55
- abstract protected function getRelativeFilePathFromItsInstallDir( $sFile );
56
  }
11
  abstract class PluginThemeFilesBase {
12
 
13
  /**
14
+ * @param string $fullFilePath
15
  * @return bool
16
  */
17
+ public function replaceFileFromVcs( $fullFilePath ) {
18
+ $sTmpFile = $this->getOriginalFileFromVcs( $fullFilePath );
19
+ return !empty( $sTmpFile ) && Services\Services::WpFs()->move( $sTmpFile, $fullFilePath );
20
  }
21
 
22
  /**
42
  }
43
 
44
  /**
45
+ * @param string $fullFilePath
46
  * @return string|null
47
  */
48
+ abstract public function getOriginalFileFromVcs( $fullFilePath );
49
 
50
  /**
51
  * Gets the path of the plugin file relative to its own home plugin dir. (not wp-content/plugins/)
52
+ * @param string $file
53
  * @return string
54
  */
55
+ abstract protected function getRelativeFilePathFromItsInstallDir( $file );
56
  }
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Plugin/Base.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  namespace FernleafSystems\Wordpress\Services\Utilities\WpOrg\Plugin;
4
 
5
- use FernleafSystems\Wordpress\Services\Core\VOs\WpPluginVo;
6
  use FernleafSystems\Wordpress\Services\Services;
7
 
8
  /**
@@ -32,14 +32,14 @@ trait Base {
32
  * @return string
33
  */
34
  public function getWorkingVersion() {
35
- $sVersion = $this->sWorkingPluginVersion;
36
- if ( empty( $sVersion ) ) {
37
- $oP = Services::WpPlugins()->getPluginAsVo( $this->getWorkingSlug() );
38
- if ( $oP instanceof WpPluginVo ) {
39
- $sVersion = $oP->Version;
40
  }
41
  }
42
- return $sVersion;
43
  }
44
 
45
  /**
2
 
3
  namespace FernleafSystems\Wordpress\Services\Utilities\WpOrg\Plugin;
4
 
5
+ use FernleafSystems\Wordpress\Services\Core\VOs\Assets\WpPluginVo;
6
  use FernleafSystems\Wordpress\Services\Services;
7
 
8
  /**
32
  * @return string
33
  */
34
  public function getWorkingVersion() {
35
+ $version = $this->sWorkingPluginVersion;
36
+ if ( empty( $version ) ) {
37
+ $p = Services::WpPlugins()->getPluginAsVo( $this->getWorkingSlug() );
38
+ if ( $p instanceof WpPluginVo ) {
39
+ $version = $p->Version;
40
  }
41
  }
42
+ return $version;
43
  }
44
 
45
  /**
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Plugin/Files.php CHANGED
@@ -14,73 +14,73 @@ class Files extends Services\Utilities\WpOrg\Base\PluginThemeFilesBase {
14
 
15
  /**
16
  * Given a full root path on the file system for a file, locate the plugin to which this file belongs.
17
- * @param string $sFullFilePath
18
- * @return Services\Core\VOs\WpPluginVo|null
19
  */
20
- public function findPluginFromFile( $sFullFilePath ) {
21
- $oThePlugin = null;
22
 
23
- $sFragment = $this->getPluginPathFragmentFromPath( $sFullFilePath );
24
 
25
- if ( !empty( $sFragment ) && strpos( $sFragment, '/' ) > 0 ) {
26
- $oWpPlugins = Services\Services::WpPlugins();
27
- $sDir = substr( $sFragment, 0, strpos( $sFragment, '/' ) );
28
- foreach ( $oWpPlugins->getInstalledPluginFiles() as $sPluginFile ) {
29
- if ( $sDir == dirname( $sPluginFile ) ) {
30
- $oThePlugin = $oWpPlugins->getPluginAsVo( $sPluginFile );
31
  break;
32
  }
33
  }
34
  }
35
- return $oThePlugin;
36
  }
37
 
38
  /**
39
  * Verifies the file exists on the SVN repository for the particular version that's installed.
40
- * @param string $sFullFilePath
41
  * @return bool
42
  * @throws \InvalidArgumentException
43
  */
44
- public function isValidFileFromPlugin( $sFullFilePath ) {
45
 
46
- $oThePlugin = $this->findPluginFromFile( $sFullFilePath );
47
- if ( !$oThePlugin instanceof Services\Core\VOs\WpPluginVo ) {
48
  throw new \InvalidArgumentException( 'Not actually a plugin file.', 1 );
49
  }
50
- if ( !$oThePlugin->isWpOrg() ) {
51
  throw new \InvalidArgumentException( 'Not a WordPress.org plugin.', 2 );
52
  }
53
 
54
  // if uses SVN tags, use that version. Otherwise trunk.
55
  return ( new Repo() )
56
- ->setWorkingSlug( $oThePlugin->slug )
57
- ->setWorkingVersion( ( $oThePlugin->svn_uses_tags ? $oThePlugin->Version : 'trunk' ) )
58
- ->existsInVcs( $this->getRelativeFilePathFromItsInstallDir( $sFullFilePath ) );
59
  }
60
 
61
  /**
62
- * @param string $sFullFilePath
63
  * @return bool
64
  */
65
- public function replaceFileFromVcs( $sFullFilePath ) {
66
- $sTmpFile = $this->getOriginalFileFromVcs( $sFullFilePath );
67
- return !empty( $sTmpFile ) && Services\Services::WpFs()->move( $sTmpFile, $sFullFilePath );
68
  }
69
 
70
  /**
71
- * @param string $sFullFilePath
72
  * @return string|null
73
  */
74
- public function getOriginalFileFromVcs( $sFullFilePath ) {
75
- $sTmpFile = null;
76
- $oThePlugin = $this->findPluginFromFile( $sFullFilePath );
77
- if ( $oThePlugin instanceof Services\Core\VOs\WpPluginVo ) {
78
- $sTmpFile = ( new Repo() )
79
- ->setWorkingSlug( $oThePlugin->slug )
80
- ->setWorkingVersion( ( $oThePlugin->svn_uses_tags ? $oThePlugin->Version : 'trunk' ) )
81
- ->downloadFromVcs( $this->getRelativeFilePathFromItsInstallDir( $sFullFilePath ) );
82
  }
83
- return $sTmpFile;
84
  }
85
 
86
  /**
@@ -105,11 +105,11 @@ class Files extends Services\Utilities\WpOrg\Base\PluginThemeFilesBase {
105
 
106
  /**
107
  * Gets the path of the plugin file relative to its own home plugin dir. (not wp-content/plugins/)
108
- * @param string $sFile
109
  * @return string
110
  */
111
- protected function getRelativeFilePathFromItsInstallDir( $sFile ) {
112
- $sRelDirFragment = $this->getPluginPathFragmentFromPath( $sFile );
113
  return substr( $sRelDirFragment, strpos( $sRelDirFragment, '/' ) + 1 );
114
  }
115
  }
14
 
15
  /**
16
  * Given a full root path on the file system for a file, locate the plugin to which this file belongs.
17
+ * @param string $fullFilePath
18
+ * @return Services\Core\VOs\Assets\WpPluginVo|null
19
  */
20
+ public function findPluginFromFile( $fullFilePath ) {
21
+ $thePlugin = null;
22
 
23
+ $fragment = $this->getPluginPathFragmentFromPath( $fullFilePath );
24
 
25
+ if ( !empty( $fragment ) && strpos( $fragment, '/' ) > 0 ) {
26
+ $WPP = Services\Services::WpPlugins();
27
+ $dir = substr( $fragment, 0, strpos( $fragment, '/' ) );
28
+ foreach ( $WPP->getInstalledPluginFiles() as $pluginFile ) {
29
+ if ( $dir == dirname( $pluginFile ) ) {
30
+ $thePlugin = $WPP->getPluginAsVo( $pluginFile );
31
  break;
32
  }
33
  }
34
  }
35
+ return $thePlugin;
36
  }
37
 
38
  /**
39
  * Verifies the file exists on the SVN repository for the particular version that's installed.
40
+ * @param string $fullFilePath
41
  * @return bool
42
  * @throws \InvalidArgumentException
43
  */
44
+ public function isValidFileFromPlugin( $fullFilePath ) {
45
 
46
+ $thePlugin = $this->findPluginFromFile( $fullFilePath );
47
+ if ( !$thePlugin instanceof Services\Core\VOs\Assets\WpPluginVo ) {
48
  throw new \InvalidArgumentException( 'Not actually a plugin file.', 1 );
49
  }
50
+ if ( !$thePlugin->isWpOrg() ) {
51
  throw new \InvalidArgumentException( 'Not a WordPress.org plugin.', 2 );
52
  }
53
 
54
  // if uses SVN tags, use that version. Otherwise trunk.
55
  return ( new Repo() )
56
+ ->setWorkingSlug( $thePlugin->slug )
57
+ ->setWorkingVersion( ( $thePlugin->svn_uses_tags ? $thePlugin->Version : 'trunk' ) )
58
+ ->existsInVcs( $this->getRelativeFilePathFromItsInstallDir( $fullFilePath ) );
59
  }
60
 
61
  /**
62
+ * @param string $fullFilePath
63
  * @return bool
64
  */
65
+ public function replaceFileFromVcs( $fullFilePath ) {
66
+ $tmpFile = $this->getOriginalFileFromVcs( $fullFilePath );
67
+ return !empty( $tmpFile ) && Services\Services::WpFs()->move( $tmpFile, $fullFilePath );
68
  }
69
 
70
  /**
71
+ * @param string $fullFilePath
72
  * @return string|null
73
  */
74
+ public function getOriginalFileFromVcs( $fullFilePath ) {
75
+ $tmpFile = null;
76
+ $thePlugin = $this->findPluginFromFile( $fullFilePath );
77
+ if ( $thePlugin instanceof Services\Core\VOs\Assets\WpPluginVo ) {
78
+ $tmpFile = ( new Repo() )
79
+ ->setWorkingSlug( $thePlugin->slug )
80
+ ->setWorkingVersion( ( $thePlugin->svn_uses_tags ? $thePlugin->Version : 'trunk' ) )
81
+ ->downloadFromVcs( $this->getRelativeFilePathFromItsInstallDir( $fullFilePath ) );
82
  }
83
+ return $tmpFile;
84
  }
85
 
86
  /**
105
 
106
  /**
107
  * Gets the path of the plugin file relative to its own home plugin dir. (not wp-content/plugins/)
108
+ * @param string $file
109
  * @return string
110
  */
111
+ protected function getRelativeFilePathFromItsInstallDir( $file ) {
112
+ $sRelDirFragment = $this->getPluginPathFragmentFromPath( $file );
113
  return substr( $sRelDirFragment, strpos( $sRelDirFragment, '/' ) + 1 );
114
  }
115
  }
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Theme/Files.php CHANGED
@@ -14,25 +14,25 @@ class Files extends Services\Utilities\WpOrg\Base\PluginThemeFilesBase {
14
 
15
  /**
16
  * Given a full root path on the file system for a file, locate the plugin to which this file belongs.
17
- * @param string $sFullFilePath
18
- * @return Services\Core\VOs\WpThemeVo|null
19
  */
20
- public function findThemeFromFile( $sFullFilePath ) {
21
- $oTheTheme = null;
22
 
23
- $sFragment = $this->getThemePathFragmentFromPath( $sFullFilePath );
24
 
25
  if ( !empty( $sFragment ) && strpos( $sFragment, '/' ) > 0 ) {
26
  $oWpThemes = Services\Services::WpThemes();
27
- $sDir = substr( $sFragment, 0, strpos( $sFragment, '/' ) );
28
- foreach ( $oWpThemes->getThemes() as $oTheme ) {
29
- if ( $sDir == $oTheme->get_stylesheet() ) {
30
- $oTheTheme = $oWpThemes->getThemeAsVo( $sDir );
31
  break;
32
  }
33
  }
34
  }
35
- return $oTheTheme;
36
  }
37
 
38
  /**
@@ -43,28 +43,28 @@ class Files extends Services\Utilities\WpOrg\Base\PluginThemeFilesBase {
43
  */
44
  public function isValidFileFromTheme( $sFullFilePath ) {
45
 
46
- $oTheTheme = $this->findThemeFromFile( $sFullFilePath );
47
- if ( !$oTheTheme instanceof Services\Core\VOs\WpThemeVo ) {
48
  throw new \InvalidArgumentException( 'Not actually a theme file.', 1 );
49
  }
50
- if ( !$oTheTheme->isWpOrg() ) {
51
  throw new \InvalidArgumentException( 'Not a WordPress.org theme.', 2 );
52
  }
53
 
54
  // if uses SVN tags, use that version. Otherwise trunk.
55
  return ( new Repo() )
56
- ->setWorkingSlug( $oTheTheme->stylesheet )
57
- ->setWorkingVersion( $oTheTheme->version )
58
  ->existsInVcs( $this->getRelativeFilePathFromItsInstallDir( $sFullFilePath ) );
59
  }
60
 
61
  /**
62
- * @param string $sFullFilePath
63
  * @return bool
64
  */
65
- public function replaceFileFromVcs( $sFullFilePath ) {
66
- $sTmpFile = $this->getOriginalFileFromVcs( $sFullFilePath );
67
- return !empty( $sTmpFile ) && Services\Services::WpFs()->move( $sTmpFile, $sFullFilePath );
68
  }
69
 
70
  /**
@@ -81,19 +81,19 @@ class Files extends Services\Utilities\WpOrg\Base\PluginThemeFilesBase {
81
  }
82
 
83
  /**
84
- * @param string $sFullFilePath
85
  * @return string|null
86
  */
87
- public function getOriginalFileFromVcs( $sFullFilePath ) {
88
- $sTmpFile = null;
89
- $oTheTheme = $this->findThemeFromFile( $sFullFilePath );
90
- if ( $oTheTheme instanceof Services\Core\VOs\WpThemeVo ) {
91
- $sTmpFile = ( new Repo() )
92
- ->setWorkingSlug( $oTheTheme->stylesheet )
93
- ->setWorkingVersion( $oTheTheme->version )
94
- ->downloadFromVcs( $this->getRelativeFilePathFromItsInstallDir( $sFullFilePath ) );
95
  }
96
- return $sTmpFile;
97
  }
98
 
99
  /**
@@ -118,11 +118,11 @@ class Files extends Services\Utilities\WpOrg\Base\PluginThemeFilesBase {
118
 
119
  /**
120
  * Gets the path of the plugin file relative to its own home plugin dir. (not wp-content/plugins/)
121
- * @param string $sFile
122
  * @return string
123
  */
124
- protected function getRelativeFilePathFromItsInstallDir( $sFile ) {
125
- $sRelDirFragment = $this->getThemePathFragmentFromPath( $sFile );
126
  return substr( $sRelDirFragment, strpos( $sRelDirFragment, '/' ) + 1 );
127
  }
128
  }
14
 
15
  /**
16
  * Given a full root path on the file system for a file, locate the plugin to which this file belongs.
17
+ * @param string $fullFilePath
18
+ * @return Services\Core\VOs\Assets\WpThemeVo|null
19
  */
20
+ public function findThemeFromFile( string $fullFilePath ) {
21
+ $theTheme = null;
22
 
23
+ $sFragment = $this->getThemePathFragmentFromPath( $fullFilePath );
24
 
25
  if ( !empty( $sFragment ) && strpos( $sFragment, '/' ) > 0 ) {
26
  $oWpThemes = Services\Services::WpThemes();
27
+ $dir = substr( $sFragment, 0, strpos( $sFragment, '/' ) );
28
+ foreach ( $oWpThemes->getThemes() as $theme ) {
29
+ if ( $dir == $theme->get_stylesheet() ) {
30
+ $theTheme = $oWpThemes->getThemeAsVo( $dir );
31
  break;
32
  }
33
  }
34
  }
35
+ return $theTheme;
36
  }
37
 
38
  /**
43
  */
44
  public function isValidFileFromTheme( $sFullFilePath ) {
45
 
46
+ $theTheme = $this->findThemeFromFile( $sFullFilePath );
47
+ if ( !$theTheme instanceof Services\Core\VOs\Assets\WpThemeVo ) {
48
  throw new \InvalidArgumentException( 'Not actually a theme file.', 1 );
49
  }
50
+ if ( !$theTheme->isWpOrg() ) {
51
  throw new \InvalidArgumentException( 'Not a WordPress.org theme.', 2 );
52
  }
53
 
54
  // if uses SVN tags, use that version. Otherwise trunk.
55
  return ( new Repo() )
56
+ ->setWorkingSlug( $theTheme->stylesheet )
57
+ ->setWorkingVersion( $theTheme->version )
58
  ->existsInVcs( $this->getRelativeFilePathFromItsInstallDir( $sFullFilePath ) );
59
  }
60
 
61
  /**
62
+ * @param string $fullFilePath
63
  * @return bool
64
  */
65
+ public function replaceFileFromVcs( $fullFilePath ) {
66
+ $sTmpFile = $this->getOriginalFileFromVcs( $fullFilePath );
67
+ return !empty( $sTmpFile ) && Services\Services::WpFs()->move( $sTmpFile, $fullFilePath );
68
  }
69
 
70
  /**
81
  }
82
 
83
  /**
84
+ * @param string $fullFilePath
85
  * @return string|null
86
  */
87
+ public function getOriginalFileFromVcs( $fullFilePath ) {
88
+ $tmpFile = null;
89
+ $theTheme = $this->findThemeFromFile( $fullFilePath );
90
+ if ( $theTheme instanceof Services\Core\VOs\Assets\WpThemeVo ) {
91
+ $tmpFile = ( new Repo() )
92
+ ->setWorkingSlug( $theTheme->stylesheet )
93
+ ->setWorkingVersion( $theTheme->version )
94
+ ->downloadFromVcs( $this->getRelativeFilePathFromItsInstallDir( $fullFilePath ) );
95
  }
96
+ return $tmpFile;
97
  }
98
 
99
  /**
118
 
119
  /**
120
  * Gets the path of the plugin file relative to its own home plugin dir. (not wp-content/plugins/)
121
+ * @param string $file
122
  * @return string
123
  */
124
+ protected function getRelativeFilePathFromItsInstallDir( $file ) {
125
+ $sRelDirFragment = $this->getThemePathFragmentFromPath( $file );
126
  return substr( $sRelDirFragment, strpos( $sRelDirFragment, '/' ) + 1 );
127
  }
128
  }
src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/Binarizer.php DELETED
@@ -1,89 +0,0 @@
1
- <?php
2
- /*
3
- * Copyright 2009 ZXing authors
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
-
18
-
19
- namespace Zxing;
20
-
21
- use Zxing\Common\BitArray;
22
- use Zxing\Common\BitMatrix;
23
-
24
- /**
25
- * This class hierarchy provides a set of methods to convert luminance data to 1 bit data.
26
- * It allows the algorithm to vary polymorphically, for example allowing a very expensive
27
- * thresholding technique for servers and a fast one for mobile. It also permits the implementation
28
- * to vary, e.g. a JNI version for Android and a Java fallback version for other platforms.
29
- *
30
- * @author dswitkin@google.com (Daniel Switkin)
31
- */
32
- abstract class Binarizer {
33
-
34
- private $source;
35
-
36
- protected function __construct($source) {
37
- $this->source = $source;
38
- }
39
-
40
- public final function getLuminanceSource() {
41
- return $this->source;
42
- }
43
-
44
- /**
45
- * Converts one row of luminance data to 1 bit data. May actually do the conversion, or return
46
- * cached data. Callers should assume this method is expensive and call it as seldom as possible.
47
- * This method is intended for decoding 1D barcodes and may choose to apply sharpening.
48
- * For callers which only examine one row of pixels at a time, the same BitArray should be reused
49
- * and passed in with each call for performance. However it is legal to keep more than one row
50
- * at a time if needed.
51
- *
52
- * @param y The row to fetch, which must be in [0, bitmap height)
53
- * @param row An optional preallocated array. If null or too small, it will be ignored.
54
- * If used, the Binarizer will call BitArray.clear(). Always use the returned object.
55
- * @return The array of bits for this row (true means black).
56
- * @throws NotFoundException if row can't be binarized
57
- */
58
- public abstract function getBlackRow($y, $row);
59
-
60
- /**
61
- * Converts a 2D array of luminance data to 1 bit data. As above, assume this method is expensive
62
- * and do not call it repeatedly. This method is intended for decoding 2D barcodes and may or
63
- * may not apply sharpening. Therefore, a row from this matrix may not be identical to one
64
- * fetched using getBlackRow(), so don't mix and match between them.
65
- *
66
- * @return The 2D array of bits for the image (true means black).
67
- * @throws NotFoundException if image can't be binarized to make a matrix
68
- */
69
- public abstract function getBlackMatrix();
70
-
71
- /**
72
- * Creates a new object with the same type as this Binarizer implementation, but with pristine
73
- * state. This is needed because Binarizer implementations may be stateful, e.g. keeping a cache
74
- * of 1 bit data. See Effective Java for why we can't use Java's clone() method.
75
- *
76
- * @param source The LuminanceSource this Binarizer will operate on.
77
- * @return A new concrete Binarizer implementation object.
78
- */
79
- public abstract function createBinarizer($source);
80
-
81
- public final function getWidth() {
82
- return $this->source->getWidth();
83
- }
84
-
85
- public final function getHeight() {
86
- return $this->source->getHeight();
87
- }
88
-
89
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/BinaryBitmap.php DELETED
@@ -1,152 +0,0 @@
1
- <?php
2
- /*
3
- * Copyright 2009 ZXing authors
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
-
18
- namespace Zxing;
19
-
20
- use Zxing\Common\BitArray;
21
- use Zxing\Common\BitMatrix;
22
-
23
-
24
- /**
25
- * This class is the core bitmap class used by ZXing to represent 1 bit data. Reader objects
26
- * accept a BinaryBitmap and attempt to decode it.
27
- *
28
- * @author dswitkin@google.com (Daniel Switkin)
29
- */
30
- final class BinaryBitmap {
31
-
32
- private $binarizer;
33
- private $matrix;
34
-
35
- public function __construct($binarizer) {
36
- if ($binarizer == null) {
37
- throw new \InvalidArgumentException("Binarizer must be non-null.");
38
- }
39
- $this->binarizer = $binarizer;
40
- }
41
-
42
- /**
43
- * @return The width of the bitmap.
44
- */
45
- public function getWidth() {
46
- return $this->binarizer->getWidth();
47
- }
48
-
49
- /**
50
- * @return The height of the bitmap.
51
- */
52
- public function getHeight() {
53
- return $this->binarizer->getHeight();
54
- }
55
-
56
- /**
57
- * Converts one row of luminance data to 1 bit data. May actually do the conversion, or return
58
- * cached data. Callers should assume this method is expensive and call it as seldom as possible.
59
- * This method is intended for decoding 1D barcodes and may choose to apply sharpening.
60
- *
61
- * @param y The row to fetch, which must be in [0, bitmap height)
62
- * @param row An optional preallocated array. If null or too small, it will be ignored.
63
- * If used, the Binarizer will call BitArray.clear(). Always use the returned object.
64
- * @return The array of bits for this row (true means black).
65
- * @throws NotFoundException if row can't be binarized
66
- */
67
- public function getBlackRow($y, $row) {
68
- return $this->binarizer->getBlackRow($y, $row);
69
- }
70
-
71
- /**
72
- * Converts a 2D array of luminance data to 1 bit. As above, assume this method is expensive
73
- * and do not call it repeatedly. This method is intended for decoding 2D barcodes and may or
74
- * may not apply sharpening. Therefore, a row from this matrix may not be identical to one
75
- * fetched using getBlackRow(), so don't mix and match between them.
76
- *
77
- * @return The 2D array of bits for the image (true means black).
78
- * @throws NotFoundException if image can't be binarized to make a matrix
79
- */
80
- public function getBlackMatrix(){
81
- // The matrix is created on demand the first time it is requested, then cached. There are two
82
- // reasons for this:
83
- // 1. This work will never be done if the caller only installs 1D Reader objects, or if a
84
- // 1D Reader finds a barcode before the 2D Readers run.
85
- // 2. This work will only be done once even if the caller installs multiple 2D Readers.
86
- if ($this->matrix == null) {
87
- $this->matrix = $this->binarizer->getBlackMatrix();
88
- }
89
- return $this->matrix;
90
- }
91
-
92
- /**
93
- * @return Whether this bitmap can be cropped.
94
- */
95
- public function isCropSupported() {
96
- return $this->binarizer->getLuminanceSource()->isCropSupported();
97
- }
98
-
99
- /**
100
- * Returns a new object with cropped image data. Implementations may keep a reference to the
101
- * original data rather than a copy. Only callable if isCropSupported() is true.
102
- *
103
- * @param left The left coordinate, which must be in [0,getWidth())
104
- * @param top The top coordinate, which must be in [0,getHeight())
105
- * @param width The width of the rectangle to crop.
106
- * @param height The height of the rectangle to crop.
107
- * @return A cropped version of this object.
108
- */
109
- public function crop($left, $top, $width, $height) {
110
- $newSource = $this->binarizer->getLuminanceSource()->crop($left, $top, $width, $height);
111
- return new BinaryBitmap($this->binarizer->createBinarizer($newSource));
112
- }
113
-
114
- /**
115
- * @return Whether this bitmap supports counter-clockwise rotation.
116
- */
117
- public function isRotateSupported() {
118
- return $this->binarizer->getLuminanceSource()->isRotateSupported();
119
- }
120
-
121
- /**
122
- * Returns a new object with rotated image data by 90 degrees counterclockwise.
123
- * Only callable if {@link #isRotateSupported()} is true.
124
- *
125
- * @return A rotated version of this object.
126
- */
127
- public function rotateCounterClockwise() {
128
- $newSource = $this->binarizer->getLuminanceSource()->rotateCounterClockwise();
129
- return new BinaryBitmap($this->binarizer->createBinarizer($newSource));
130
- }
131
-
132
- /**
133
- * Returns a new object with rotated image data by 45 degrees counterclockwise.
134
- * Only callable if {@link #isRotateSupported()} is true.
135
- *
136
- * @return A rotated version of this object.
137
- */
138
- public function rotateCounterClockwise45() {
139
- $newSource = $this->binarizer->getLuminanceSource()->rotateCounterClockwise45();
140
- return new BinaryBitmap($this->binarizer->createBinarizer($newSource));
141
- }
142
-
143
- //@Override
144
- public function toString() {
145
- try {
146
- return $this->getBlackMatrix()->toString();
147
- } catch (NotFoundException $e) {
148
- return "";
149
- }
150
- }
151
-
152
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/ChecksumException.php DELETED
@@ -1,44 +0,0 @@
1
- <?php
2
- /*
3
- * Copyright 2007 ZXing authors
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
-
18
- namespace Zxing;
19
-
20
- /**
21
- * Thrown when a barcode was successfully detected and decoded, but
22
- * was not returned because its checksum feature failed.
23
- *
24
- * @author Sean Owen
25
- */
26
- final class ChecksumException extends ReaderException {
27
-
28
- private static $instance;
29
-
30
-
31
-
32
- public static function getChecksumInstance($cause=null) {
33
- if (self::$isStackTrace) {
34
- return new ChecksumException($cause);
35
- } else {
36
- if(!self::$instance){
37
- self::$instance = new ChecksumException($cause);
38
- }
39
- return self::$instance;
40
- }
41
- }
42
-
43
-
44
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/FormatException.php DELETED
@@ -1,52 +0,0 @@
1
- <?php
2
- /*
3
- * Copyright 2007 ZXing authors
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
-
18
- namespace Zxing;
19
-
20
- /**
21
- * Thrown when a barcode was successfully detected, but some aspect of
22
- * the content did not conform to the barcode's format rules. This could have
23
- * been due to a mis-detection.
24
- *
25
- * @author Sean Owen
26
- */
27
- final class FormatException extends ReaderException {
28
-
29
- private static $instance;
30
-
31
-
32
- public function __construct($cause=null) {
33
-
34
- if($cause){
35
- parent::__construct($cause);
36
- }
37
-
38
- }
39
-
40
-
41
- public static function getFormatInstance($cause=null) {
42
- if(!self::$instance){
43
- self::$instance = new FormatException();
44
- }
45
- if (self::$isStackTrace) {
46
- return new FormatException($cause);
47
- } else {
48
- return self::$instance;
49
- }
50
- }
51
- }
52
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/GDLuminanceSource.php DELETED
@@ -1,173 +0,0 @@
1
- <?php
2
-
3
-
4
- namespace Zxing;
5
-
6
- /**
7
- * This class is used to help decode images from files which arrive as GD Resource
8
- * It does not support rotation.
9
- *
10
- *
11
- *
12
- */
13
- final class GDLuminanceSource extends LuminanceSource {
14
-
15
- public $luminances;
16
- private $dataWidth;
17
- private $dataHeight;
18
- private $left;
19
- private $top;
20
- private $gdImage;
21
-
22
-
23
-
24
- public function __construct($gdImage,
25
- $dataWidth,
26
- $dataHeight,
27
- $left=null,
28
- $top=null,
29
- $width=null,
30
- $height=null) {
31
- if(!$left&&!$top&&!$width&&!$height){
32
- $this->GDLuminanceSource($gdImage,$dataWidth,$dataHeight);
33
- return;
34
- }
35
- parent::__construct($width, $height);
36
- if ($left + $width > $dataWidth || $top + $height > $dataHeight) {
37
- throw new \InvalidArgumentException("Crop rectangle does not fit within image data.");
38
- }
39
- $this->luminances = $gdImage;
40
- $this->dataWidth = $dataWidth;
41
- $this->dataHeight = $dataHeight;
42
- $this->left = $left;
43
- $this->top = $top;
44
- }
45
-
46
- public function GDLuminanceSource($gdImage, $width, $height)
47
- {
48
- parent::__construct($width, $height);
49
-
50
- $this->dataWidth = $width;
51
- $this->dataHeight = $height;
52
- $this->left = 0;
53
- $this->top = 0;
54
- $this->$gdImage = $gdImage;
55
-
56
-
57
- // In order to measure pure decoding speed, we convert the entire image to a greyscale array
58
- // up front, which is the same as the Y channel of the YUVLuminanceSource in the real app.
59
- $this->luminances = array();
60
- //$this->luminances = $this->grayScaleToBitmap($this->grayscale());
61
-
62
- $array = array();
63
- $rgb = array();
64
-
65
- for($j=0;$j<$height;$j++){
66
- for($i=0;$i<$width;$i++){
67
- $argb = imagecolorat($this->$gdImage, $i, $j);
68
- $pixel = imagecolorsforindex($this->$gdImage, $argb);
69
- $r = $pixel['red'];
70
- $g = $pixel['green'];
71
- $b = $pixel['blue'];
72
- if ($r == $g && $g == $b) {
73
- // Image is already greyscale, so pick any channel.
74
-
75
- $this->luminances[] = $r;//(($r + 128) % 256) - 128;
76
- } else {
77
- // Calculate luminance cheaply, favoring green.
78
- $this->luminances[] = ($r+2*$g+$b)/4;//(((($r + 2 * $g + $b) / 4) + 128) % 256) - 128;
79
- }
80
- }
81
- }
82
-
83
-
84
-
85
- /*
86
-
87
- for ($y = 0; $y < $height; $y++) {
88
- $offset = $y * $width;
89
- for ($x = 0; $x < $width; $x++) {
90
- $pixel = $pixels[$offset + $x];
91
- $r = ($pixel >> 16) & 0xff;
92
- $g = ($pixel >> 8) & 0xff;
93
- $b = $pixel & 0xff;
94
- if ($r == $g && $g == $b) {
95
- // Image is already greyscale, so pick any channel.
96
-
97
- $this->luminances[intval($offset + $x)] = (($r+128) % 256) - 128;
98
- } else {
99
- // Calculate luminance cheaply, favoring green.
100
- $this->luminances[intval($offset + $x)] = (((($r + 2 * $g + $b) / 4)+128)%256) - 128;
101
- }
102
-
103
-
104
-
105
- }
106
- */
107
- //}
108
- // $this->luminances = $this->grayScaleToBitmap($this->luminances);
109
-
110
- }
111
-
112
- //@Override
113
- public function getRow($y, $row=null) {
114
- if ($y < 0 || $y >= $this->getHeight()) {
115
- throw new \InvalidArgumentException("Requested row is outside the image: " + y);
116
- }
117
- $width = $this->getWidth();
118
- if ($row == null || count($row) < $width) {
119
- $row = array();
120
- }
121
- $offset = ($y + $this->top) * $this->dataWidth + $this->left;
122
- $row = arraycopy($this->luminances,$offset, $row, 0, $width);
123
- return $row;
124
- }
125
-
126
- //@Override
127
- public function getMatrix() {
128
- $width = $this->getWidth();
129
- $height = $this->getHeight();
130
-
131
- // If the caller asks for the entire underlying image, save the copy and give them the
132
- // original data. The docs specifically warn that result.length must be ignored.
133
- if ($width == $this->dataWidth && $height == $this->dataHeight) {
134
- return $this->luminances;
135
- }
136
-
137
- $area = $width * $height;
138
- $matrix = array();
139
- $inputOffset = $this->top * $this->dataWidth + $this->left;
140
-
141
- // If the width matches the full width of the underlying data, perform a single copy.
142
- if ($width == $this->dataWidth) {
143
- $matrix = arraycopy($this->luminances, $inputOffset, $matrix, 0, $area);
144
- return $matrix;
145
- }
146
-
147
- // Otherwise copy one cropped row at a time.
148
- $rgb = $this->luminances;
149
- for ($y = 0; $y < $height; $y++) {
150
- $outputOffset = $y * $width;
151
- $matrix = arraycopy($rgb, $inputOffset, $matrix, $outputOffset, $width);
152
- $inputOffset += $this->dataWidth;
153
- }
154
- return $matrix;
155
- }
156
-
157
- //@Override
158
- public function isCropSupported() {
159
- return true;
160
- }
161
-
162
- //@Override
163
- public function crop($left, $top, $width, $height) {
164
- return new GDLuminanceSource($this->luminances,
165
- $this->dataWidth,
166
- $this->dataHeight,
167
- $this->left + $left,
168
- $this->top + $top,
169
- $width,
170
- $height);
171
- }
172
-
173
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/IMagickLuminanceSource.php DELETED
@@ -1,149 +0,0 @@
1
- <?php
2
-
3
-
4
- namespace Zxing;
5
-
6
- /**
7
- * This class is used to help decode images from files which arrive as GD Resource
8
- * It does not support rotation.
9
- *
10
- *
11
- *
12
- */
13
- final class IMagickLuminanceSource extends LuminanceSource {
14
-
15
- public $luminances;
16
- private $dataWidth;
17
- private $dataHeight;
18
- private $left;
19
- private $top;
20
- private $image;
21
-
22
-
23
-
24
- public function __construct($image,
25
- $dataWidth,
26
- $dataHeight,
27
- $left=null,
28
- $top=null,
29
- $width=null,
30
- $height=null) {
31
- if(!$left&&!$top&&!$width&&!$height){
32
- $this->_IMagickLuminanceSource($image,$dataWidth,$dataHeight);
33
- return;
34
- }
35
- parent::__construct($width, $height);
36
- if ($left + $width > $dataWidth || $top + $height > $dataHeight) {
37
- throw new \InvalidArgumentException("Crop rectangle does not fit within image data.");
38
- }
39
- $this->luminances = $image;
40
- $this->dataWidth = $dataWidth;
41
- $this->dataHeight = $dataHeight;
42
- $this->left = $left;
43
- $this->top = $top;
44
- }
45
-
46
- public function _IMagickLuminanceSource($image, $width, $height)
47
- {
48
- parent::__construct($width, $height);
49
-
50
- $this->dataWidth = $width;
51
- $this->dataHeight = $height;
52
- $this->left = 0;
53
- $this->top = 0;
54
- $this->image = $image;
55
-
56
-
57
- // In order to measure pure decoding speed, we convert the entire image to a greyscale array
58
- // up front, which is the same as the Y channel of the YUVLuminanceSource in the real app.
59
- $this->luminances = array();
60
-
61
- $image->setImageColorspace (\Imagick::COLORSPACE_GRAY);
62
- // $image->newPseudoImage(0, 0, "magick:rose");
63
- $pixels = $image->exportImagePixels(1, 1, $width, $height, "RGB", \Imagick::COLORSPACE_RGB);
64
-
65
- $array = array();
66
- $rgb = array();
67
-
68
-
69
- for($i=0;$i<count($pixels);$i+=3){
70
-
71
- $r = $pixels[$i]& 0xff;
72
- $g = $pixels[$i+1]& 0xff;
73
- $b = $pixels[$i+2]& 0xff;
74
- if ($r == $g && $g == $b) {
75
- // Image is already greyscale, so pick any channel.
76
-
77
- $this->luminances[] = $r;//(($r + 128) % 256) - 128;
78
- } else {
79
- // Calculate luminance cheaply, favoring green.
80
- $this->luminances[] = ($r+2*$g+$b)/4;//(((($r + 2 * $g + $b) / 4) + 128) % 256) - 128;
81
- }
82
- }
83
-
84
-
85
-
86
- }
87
-
88
- //@Override
89
- public function getRow($y, $row=null) {
90
- if ($y < 0 || $y >= $this->getHeight()) {
91
- throw new \InvalidArgumentException("Requested row is outside the image: " + y);
92
- }
93
- $width = $this->getWidth();
94
- if ($row == null || count($row) < $width) {
95
- $row = array();
96
- }
97
- $offset = ($y + $this->top) * $this->dataWidth + $this->left;
98
- $row = arraycopy($this->luminances,$offset, $row, 0, $width);
99
- return $row;
100
- }
101
-
102
- //@Override
103
- public function getMatrix() {
104
- $width = $this->getWidth();
105
- $height = $this->getHeight();
106
-
107
- // If the caller asks for the entire underlying image, save the copy and give them the
108
- // original data. The docs specifically warn that result.length must be ignored.
109
- if ($width == $this->dataWidth && $height == $this->dataHeight) {
110
- return $this->luminances;
111
- }
112
-
113
- $area = $width * $height;
114
- $matrix = array();
115
- $inputOffset = $this->top * $this->dataWidth + $this->left;
116
-
117
- // If the width matches the full width of the underlying data, perform a single copy.
118
- if ($width == $this->dataWidth) {
119
- $matrix = arraycopy($this->luminances, $inputOffset, $matrix, 0, $area);
120
- return $matrix;
121
- }
122
-
123
- // Otherwise copy one cropped row at a time.
124
- $rgb = $this->luminances;
125
- for ($y = 0; $y < $height; $y++) {
126
- $outputOffset = $y * $width;
127
- $matrix = arraycopy($rgb, $inputOffset, $matrix, $outputOffset, $width);
128
- $inputOffset += $this->dataWidth;
129
- }
130
- return $matrix;
131
- }
132
-
133
- //@Override
134
- public function isCropSupported() {
135
- return true;
136
- }
137
-
138
- //@Override
139
- public function crop($left, $top, $width, $height) {
140
- return new GDLuminanceSource($this->luminances,
141
- $this->dataWidth,
142
- $this->dataHeight,
143
- $this->left + $left,
144
- $this->top + $top,
145
- $width,
146
- $height);
147
- }
148
-
149
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/LuminanceSource.php DELETED
@@ -1,159 +0,0 @@
1
- <?php
2
- /*
3
- * Copyright 2009 ZXing authors
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
-
18
- namespace Zxing;
19
-
20
- /**
21
- * The purpose of this class hierarchy is to abstract different bitmap implementations across
22
- * platforms into a standard interface for requesting greyscale luminance values. The interface
23
- * only provides immutable methods; therefore crop and rotation create copies. This is to ensure
24
- * that one Reader does not modify the original luminance source and leave it in an unknown state
25
- * for other Readers in the chain.
26
- *
27
- * @author dswitkin@google.com (Daniel Switkin)
28
- */
29
- abstract class LuminanceSource {
30
-
31
- private $width;
32
- private $height;
33
-
34
- function __construct($width, $height) {
35
- $this->width = $width;
36
- $this->height = $height;
37
- }
38
-
39
- /**
40
- * Fetches one row of luminance data from the underlying platform's bitmap. Values range from
41
- * 0 (black) to 255 (white). Because Java does not have an unsigned byte type, callers will have
42
- * to bitwise and with 0xff for each value. It is preferable for implementations of this method
43
- * to only fetch this row rather than the whole image, since no 2D Readers may be installed and
44
- * getMatrix() may never be called.
45
- *
46
- * @param $y; The row to fetch, which must be in [0,getHeight())
47
- * @param $row; An optional preallocated array. If null or too small, it will be ignored.
48
- * Always use the returned object, and ignore the .length of the array.
49
- * @return array
50
- * An array containing the luminance data.
51
- */
52
- public abstract function getRow($y, $row);
53
-
54
- /**
55
- * Fetches luminance data for the underlying bitmap. Values should be fetched using:
56
- * {@code int luminance = array[y * width + x] & 0xff}
57
- *
58
- * @return A row-major 2D array of luminance values. Do not use result.length as it may be
59
- * larger than width * height bytes on some platforms. Do not modify the contents
60
- * of the result.
61
- */
62
- public abstract function getMatrix();
63
-
64
- /**
65
- * @return The width of the bitmap.
66
- */
67
- public final function getWidth() {
68
- return $this->width;
69
- }
70
-
71
- /**
72
- * @return The height of the bitmap.
73
- */
74
- public final function getHeight() {
75
- return $this->height;
76
- }
77
-
78
- /**
79
- * @return Whether this subclass supports cropping.
80
- */
81
- public function isCropSupported() {
82
- return false;
83
- }
84
-
85
- /**
86
- * Returns a new object with cropped image data. Implementations may keep a reference to the
87
- * original data rather than a copy. Only callable if isCropSupported() is true.
88
- *
89
- * @param left The left coordinate, which must be in [0,getWidth())
90
- * @param top The top coordinate, which must be in [0,getHeight())
91
- * @param width The width of the rectangle to crop.
92
- * @param height The height of the rectangle to crop.
93
- * @return A cropped version of this object.
94
- */
95
- public function crop($left, $top, $width, $height) {
96
- throw new \Exception("This luminance source does not support cropping.");
97
- }
98
-
99
- /**
100
- * @return Whether this subclass supports counter-clockwise rotation.
101
- */
102
- public function isRotateSupported() {
103
- return false;
104
- }
105
-
106
- /**
107
- * @return a wrapper of this {@code LuminanceSource} which inverts the luminances it returns -- black becomes
108
- * white and vice versa, and each value becomes (255-value).
109
- */
110
- public function invert() {
111
- return new InvertedLuminanceSource($this);
112
- }
113
-
114
- /**
115
- * Returns a new object with rotated image data by 90 degrees counterclockwise.
116
- * Only callable if {@link #isRotateSupported()} is true.
117
- *
118
- * @return A rotated version of this object.
119
- */
120
- public function rotateCounterClockwise() {
121
- throw new \Exception("This luminance source does not support rotation by 90 degrees.");
122
- }
123
-
124
- /**
125
- * Returns a new object with rotated image data by 45 degrees counterclockwise.
126
- * Only callable if {@link #isRotateSupported()} is true.
127
- *
128
- * @return A rotated version of this object.
129
- */
130
- public function rotateCounterClockwise45() {
131
- throw new \Exception("This luminance source does not support rotation by 45 degrees.");
132
- }
133
-
134
- //@Override
135
- public final function toString() {
136
- $row = array();
137
- $result = '';
138
- for ($y = 0;$y < $this->height; $y++) {
139
- $row = $this->getRow($y, $row);
140
- for ($x = 0; $x < $this->width; $x++) {
141
- $luminance = $row[$x] & 0xFF;
142
- $c='';
143
- if ($luminance < 0x40) {
144
- $c = '#';
145
- } else if ($luminance < 0x80) {
146
- $c = '+';
147
- } else if ($luminance < 0xC0) {
148
- $c = '.';
149
- } else {
150
- $c = ' ';
151
- }
152
- $result.=($c);
153
- }
154
- $result.=('\n');
155
- }
156
- return $result;
157
- }
158
-
159
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/NotFoundException.php DELETED
@@ -1,38 +0,0 @@
1
- <?php
2
- /*
3
- * Copyright 2007 ZXing authors
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
-
18
- namespace Zxing;
19
-
20
- /**
21
- * Thrown when a barcode was not found in the image. It might have been
22
- * partially detected but could not be confirmed.
23
- *
24
- * @author Sean Owen
25
- */
26
- final class NotFoundException extends ReaderException {
27
-
28
- private static $instance;
29
-
30
-
31
- public static function getNotFoundInstance() {
32
- if(!self::$instance ){
33
- self::$instance = new NotFoundException();
34
- }
35
- return self::$instance;
36
- }
37
-
38
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/PlanarYUVLuminanceSource.php DELETED
@@ -1,172 +0,0 @@
1
- <?php
2
- /*
3
- * Copyright 2009 ZXing authors
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
-
18
- namespace Zxing;
19
-
20
- /**
21
- * This object extends LuminanceSource around an array of YUV data returned from the camera driver,
22
- * with the option to crop to a rectangle within the full data. This can be used to exclude
23
- * superfluous pixels around the perimeter and speed up decoding.
24
- *
25
- * It works for any pixel format where the Y channel is planar and appears first, including
26
- * YCbCr_420_SP and YCbCr_422_SP.
27
- *
28
- * @author dswitkin@google.com (Daniel Switkin)
29
- */
30
- final class PlanarYUVLuminanceSource extends LuminanceSource {
31
-
32
- private static $THUMBNAIL_SCALE_FACTOR = 2;
33
-
34
- private $yuvData;
35
- private $dataWidth;
36
- private $dataHeight;
37
- private $left;
38
- private $top;
39
-
40
- public function __construct($yuvData,
41
- $dataWidth,
42
- $dataHeight,
43
- $left,
44
- $top,
45
- $width,
46
- $height,
47
- $reverseHorizontal) {
48
- parent::__construct($width, $height);
49
-
50
- if ($left + $width > $dataWidth || $top + $height > $dataHeight) {
51
- throw new IllegalArgumentException("Crop rectangle does not fit within image data.");
52
- }
53
-
54
- $this->yuvData = $yuvData;
55
- $this->dataWidth = $dataWidth;
56
- $this->dataHeight = $dataHeight;
57
- $this->left = $left;
58
- $this->top = $top;
59
- if ($reverseHorizontal) {
60
- $this->reverseHorizontal($width, $height);
61
- }
62
- }
63
-
64
- //@Override
65
- public function getRow($y, $row=null) {
66
- if ($y < 0 || $y >= getHeight()) {
67
- throw new IllegalArgumentException("Requested row is outside the image: " + y);
68
- }
69
- $width = $this->getWidth();
70
- if ($row == null || count($row) < $width) {
71
- $row = array();//new byte[width];
72
- }
73
- $offset = ($y + $this->top) * $this->dataWidth + $this->left;
74
- $row = arraycopy($this->yuvData, $offset, $row, 0, $width);
75
- return $row;
76
- }
77
-
78
- //@Override
79
- public function getMatrix() {
80
- $width = $this->getWidth();
81
- $height = $this->getHeight();
82
-
83
- // If the caller asks for the entire underlying image, save the copy and give them the
84
- // original data. The docs specifically warn that result.length must be ignored.
85
- if ($width == $this->dataWidth && $height == $this->dataHeight) {
86
- return $this->yuvData;
87
- }
88
-
89
- $area = $width * $height;
90
- $matrix = array();//new byte[area];
91
- $inputOffset = $this->top * $this->dataWidth + $this->left;
92
-
93
- // If the width matches the full width of the underlying data, perform a single copy.
94
- if ($width == $this->dataWidth) {
95
- $matrix = arraycopy($this->yuvData, $inputOffset, $matrix, 0, $area);
96
- return $matrix;
97
- }
98
-
99
- // Otherwise copy one cropped row at a time.
100
- $yuv = $this->yuvData;
101
- for ($y = 0; $y < $height; $y++) {
102
- $outputOffset = $y * $width;
103
- $matrix = arraycopy($this->yuvData, $inputOffset, $matrix, $outputOffset, $width);
104
- $inputOffset += $this->dataWidth;
105
- }
106
- return $matrix;
107
- }
108
-
109
- // @Override
110
- public function isCropSupported() {
111
- return true;
112
- }
113
-
114
- // @Override
115
- public function crop($left, $top, $width, $height) {
116
- return new PlanarYUVLuminanceSource($this->yuvData,
117
- $this->dataWidth,
118
- $this->dataHeight,
119
- $this->left + $left,
120
- $this->top + $top,
121
- $width,
122
- $height,
123
- false);
124
- }
125
-
126
- public function renderThumbnail() {
127
- $width = intval($this->getWidth() / self::$THUMBNAIL_SCALE_FACTOR);
128
- $height = intval($this->getHeight() / self::$THUMBNAIL_SCALE_FACTOR);
129
- $pixels = array();//new int[width * height];
130
- $yuv = $this->yuvData;
131
- $inputOffset = $this->top * $this->dataWidth + $this->left;
132
-
133
- for ($y = 0; $y < $height; $y++) {
134
- $outputOffset = $y * $width;
135
- for ($x = 0; $x < $width; $x++) {
136
- $grey = intval32bits($yuv[$inputOffset + $x * self::$THUMBNAIL_SCALE_FACTOR] & 0xff);
137
- $pixels[$outputOffset + $x] = intval32bits(0xFF000000 | ($grey * 0x00010101));
138
- }
139
- $inputOffset += $this->dataWidth * self::$THUMBNAIL_SCALE_FACTOR;
140
- }
141
- return $pixels;
142
- }
143
-
144
- /**
145
- * @return width of image from {@link #renderThumbnail()}
146
- */
147
- /*
148
- public int getThumbnailWidth() {
149
- return getWidth() / THUMBNAIL_SCALE_FACTOR;
150
- }*/
151
-
152
- /**
153
- * @return height of image from {@link #renderThumbnail()}
154
- */
155
- /*
156
- public int getThumbnailHeight() {
157
- return getHeight() / THUMBNAIL_SCALE_FACTOR;
158
- }
159
-
160
- private void reverseHorizontal(int width, int height) {
161
- byte[] yuvData = this.yuvData;
162
- for (int y = 0, rowStart = top * dataWidth + left; y < height; y++, rowStart += dataWidth) {
163
- int middle = rowStart + width / 2;
164
- for (int x1 = rowStart, x2 = rowStart + width - 1; x1 < middle; x1++, x2--) {
165
- byte temp = yuvData[x1];
166
- yuvData[x1] = yuvData[x2];
167
- yuvData[x2] = temp;
168
- }
169
- }
170
- }
171
- */
172
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/QrReader.php DELETED
@@ -1,84 +0,0 @@
1
- <?php
2
-
3
- final class QrReader
4
- {
5
- const SOURCE_TYPE_FILE = 'file';
6
- const SOURCE_TYPE_BLOB = 'blob';
7
- const SOURCE_TYPE_RESOURCE = 'resource';
8
- public $result;
9
-
10
- function __construct($imgsource, $sourcetype = QrReader::SOURCE_TYPE_FILE, $isUseImagickIfAvailable = true)
11
- {
12
-
13
- try {
14
- switch($sourcetype) {
15
- case QrReader::SOURCE_TYPE_FILE:
16
- if($isUseImagickIfAvailable && extension_loaded('imagick')) {
17
- $im = new Imagick();
18
- $im->readImage($imgsource);
19
- }else {
20
- $image = file_get_contents($imgsource);
21
- $im = imagecreatefromstring($image);
22
- }
23
-
24
- break;
25
-
26
- case QrReader::SOURCE_TYPE_BLOB:
27
- if($isUseImagickIfAvailable && extension_loaded('imagick')) {
28
- $im = new Imagick();
29
- $im->readimageblob($imgsource);
30
- }else {
31
- $im = imagecreatefromstring($imgsource);
32
- }
33
-
34
- break;
35
-
36
- case QrReader::SOURCE_TYPE_RESOURCE:
37
- $im = $imgsource;
38
- if($isUseImagickIfAvailable && extension_loaded('imagick')) {
39
- $isUseImagickIfAvailable = true;
40
- }else {
41
- $isUseImagickIfAvailable = false;
42
- }
43
-
44
- break;
45
- }
46
-
47
- if($isUseImagickIfAvailable && extension_loaded('imagick')) {
48
- $width = $im->getImageWidth();
49
- $height = $im->getImageHeight();
50
- $source = new \Zxing\IMagickLuminanceSource($im, $width, $height);
51
- }else {
52
- $width = imagesx($im);
53
- $height = imagesy($im);
54
- $source = new \Zxing\GDLuminanceSource($im, $width, $height);
55
- }
56
- $histo = new \Zxing\Common\HybridBinarizer($source);
57
- $bitmap = new \Zxing\BinaryBitmap($histo);
58
- $reader = new \Zxing\Qrcode\QRCodeReader();
59
-
60
- $this->result = $reader->decode($bitmap);
61
- }catch (\Zxing\NotFoundException $er){
62
- $this->result = false;
63
- }catch( \Zxing\FormatException $er){
64
- $this->result = false;
65
- }catch( \Zxing\ChecksumException $er){
66
- $this->result = false;
67
- }
68
- }
69
-
70
- public function text()
71
- {
72
- if(method_exists($this->result,'toString')) {
73
- return ($this->result->toString());
74
- }else{
75
- return $this->result;
76
- }
77
- }
78
-
79
- public function decode()
80
- {
81
- return $this->text();
82
- }
83
- }
84
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/RGBLuminanceSource.php DELETED
@@ -1,310 +0,0 @@
1
- <?php
2
- /*
3
- * Copyright 2009 ZXing authors
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
-
18
- namespace Zxing;
19
-
20
- /**
21
- * This class is used to help decode images from files which arrive as RGB data from
22
- * an ARGB pixel array. It does not support rotation.
23
- *
24
- * @author dswitkin@google.com (Daniel Switkin)
25
- * @author Betaminos
26
- */
27
- final class RGBLuminanceSource extends LuminanceSource {
28
-
29
- public $luminances;
30
- private $dataWidth;
31
- private $dataHeight;
32
- private $left;
33
- private $top;
34
- private $pixels;
35
-
36
-
37
-
38
- public function __construct($pixels,
39
- $dataWidth,
40
- $dataHeight,
41
- $left=null,
42
- $top=null,
43
- $width=null,
44
- $height=null) {
45
- if(!$left&&!$top&&!$width&&!$height){
46
- $this->RGBLuminanceSource_($pixels,$dataWidth,$dataHeight);
47
- return;
48
- }
49
- parent::__construct($width, $height);
50
- if ($left + $width > $dataWidth || $top + $height > $dataHeight) {
51
- throw new \InvalidArgumentException("Crop rectangle does not fit within image data.");
52
- }
53
- $this->luminances = $pixels;
54
- $this->dataWidth = $dataWidth;
55
- $this->dataHeight = $dataHeight;
56
- $this->left = $left;
57
- $this->top = $top;
58
- }
59
-
60
- public function RGBLuminanceSource_($width, $height, $pixels)
61
- {
62
- parent::__construct($width, $height);
63
-
64
- $this->dataWidth = $width;
65
- $this->dataHeight = $height;
66
- $this->left = 0;
67
- $this->top = 0;
68
- $this->pixels = $pixels;
69
-
70
-
71
- // In order to measure pure decoding speed, we convert the entire image to a greyscale array
72
- // up front, which is the same as the Y channel of the YUVLuminanceSource in the real app.
73
- $this->luminances = array();
74
- //$this->luminances = $this->grayScaleToBitmap($this->grayscale());
75
-
76
- foreach ($pixels as $key => $pixel) {
77
- $r = $pixel['red'];
78
- $g = $pixel['green'];
79
- $b = $pixel['blue'];
80
-
81
- /* if (($pixel & 0xFF000000) == 0) {
82
- $pixel = 0xFFFFFFFF; // = white
83
- }
84
-
85
- // .229R + 0.587G + 0.114B (YUV/YIQ for PAL and NTSC)
86
-
87
- $this->luminances[$key] =
88
- (306 * (($pixel >> 16) & 0xFF) +
89
- 601 * (($pixel >> 8) & 0xFF) +
90
- 117 * ($pixel & 0xFF) +
91
- 0x200) >> 10;
92
-
93
- */
94
- //$r = ($pixel >> 16) & 0xff;
95
- //$g = ($pixel >> 8) & 0xff;
96
- //$b = $pixel & 0xff;
97
- if ($r == $g && $g == $b) {
98
- // Image is already greyscale, so pick any channel.
99
-
100
- $this->luminances[$key] = $r;//(($r + 128) % 256) - 128;
101
- } else {
102
- // Calculate luminance cheaply, favoring green.
103
- $this->luminances[$key] = ($r+2*$g+$b)/4;//(((($r + 2 * $g + $b) / 4) + 128) % 256) - 128;
104
- }
105
-
106
- }
107
-
108
- /*
109
-
110
- for ($y = 0; $y < $height; $y++) {
111
- $offset = $y * $width;
112
- for ($x = 0; $x < $width; $x++) {
113
- $pixel = $pixels[$offset + $x];
114
- $r = ($pixel >> 16) & 0xff;
115
- $g = ($pixel >> 8) & 0xff;
116
- $b = $pixel & 0xff;
117
- if ($r == $g && $g == $b) {
118
- // Image is already greyscale, so pick any channel.
119
-
120
- $this->luminances[intval($offset + $x)] = (($r+128) % 256) - 128;
121
- } else {
122
- // Calculate luminance cheaply, favoring green.
123
- $this->luminances[intval($offset + $x)] = (((($r + 2 * $g + $b) / 4)+128)%256) - 128;
124
- }
125
-
126
-
127
-
128
- }
129
- */
130
- //}
131
- // $this->luminances = $this->grayScaleToBitmap($this->luminances);
132
-
133
- }
134
- function grayscale(){
135
- $width = $this->dataWidth;
136
- $height = $this->dataHeight;
137
-
138
- $ret = fill_array(0, $width*$height,0);
139
- for ($y = 0; $y < $height; $y++)
140
- {
141
- for ($x = 0; $x < $width; $x++)
142
- {
143
- $gray = $this->getPixel($x, $y,$width,$height);
144
-
145
- $ret[$x+$y*$width] = $gray;
146
- }
147
- }
148
- return $ret;
149
- }
150
- function getPixel($x,$y,$width,$height){
151
- $image = $this->pixels;
152
- if ($width < $x) {
153
- die('error');
154
- }
155
- if ($height < $y) {
156
- die('error');
157
- }
158
- $point = ($x) + ($y * $width);
159
-
160
- $r = $image[$point]['red'];//($image[$point] >> 16) & 0xff;
161
- $g = $image[$point]['green'];//($image[$point] >> 8) & 0xff;
162
- $b = $image[$point]['blue'];//$image[$point] & 0xff;
163
-
164
- $p = intval(($r*33 +$g*34 + $b*33)/100);
165
-
166
-
167
- return $p;
168
-
169
- }
170
-
171
-
172
- function getMiddleBrightnessPerArea($image)
173
- {
174
- $numSqrtArea = 4;
175
- //obtain middle brightness((min + max) / 2) per area
176
- $areaWidth = floor($this->dataWidth / $numSqrtArea);
177
- $areaHeight = floor($this->dataHeight / $numSqrtArea);
178
- $minmax = fill_array(0,$numSqrtArea,0);
179
- for ($i = 0; $i < $numSqrtArea; $i++)
180
- {
181
- $minmax[$i] = fill_array(0,$numSqrtArea,0);
182
- for ($i2 = 0; $i2 < $numSqrtArea; $i2++)
183
- {
184
- $minmax[$i][$i2] = array(0,0);
185
- }
186
- }
187
- for ($ay = 0; $ay < $numSqrtArea; $ay++)
188
- {
189
- for ($ax = 0; $ax < $numSqrtArea; $ax++)
190
- {
191
- $minmax[$ax][$ay][0] = 0xFF;
192
- for ($dy = 0; $dy < $areaHeight; $dy++)
193
- {
194
- for ($dx = 0; $dx < $areaWidth; $dx++)
195
- {
196
- $target = $image[intval($areaWidth * $ax + $dx+($areaHeight * $ay + $dy)*$this->dataWidth)];
197
- if ($target < $minmax[$ax][$ay][0])
198
- $minmax[$ax][$ay][0] = $target;
199
- if ($target > $minmax[$ax][$ay][1])
200
- $minmax[$ax][$ay][1] = $target;
201
- }
202
- }
203
- //minmax[ax][ay][0] = (minmax[ax][ay][0] + minmax[ax][ay][1]) / 2;
204
- }
205
- }
206
- $middle = array();
207
- for ($i3 = 0; $i3 < $numSqrtArea; $i3++)
208
- {
209
- $middle[$i3] = array();
210
- }
211
- for ($ay = 0; $ay < $numSqrtArea; $ay++)
212
- {
213
- for ($ax = 0; $ax < $numSqrtArea; $ax++)
214
- {
215
- $middle[$ax][$ay] = floor(($minmax[$ax][$ay][0] + $minmax[$ax][$ay][1]) / 2);
216
- //Console.out.print(middle[ax][ay] + ",");
217
- }
218
- //Console.out.println("");
219
- }
220
- //Console.out.println("");
221
-
222
- return $middle;
223
- }
224
-
225
- function grayScaleToBitmap ($grayScale)
226
- {
227
- $middle = $this->getMiddleBrightnessPerArea($grayScale);
228
- $sqrtNumArea = count($middle);
229
- $areaWidth = floor($this->dataWidth/ $sqrtNumArea);
230
- $areaHeight = floor($this->dataHeight / $sqrtNumArea);
231
- $bitmap = fill_array(0,$this->dataWidth*$this->dataHeight,0);
232
-
233
- for ($ay = 0; $ay < $sqrtNumArea; $ay++)
234
- {
235
- for ($ax = 0; $ax < $sqrtNumArea; $ax++)
236
- {
237
- for ($dy = 0; $dy < $areaHeight; $dy++)
238
- {
239
- for ($dx = 0; $dx < $areaWidth; $dx++)
240
- {
241
- $bitmap[intval($areaWidth * $ax + $dx+ ($areaHeight * $ay + $dy)*$this->dataWidth)] = ($grayScale[intval($areaWidth * $ax + $dx+ ($areaHeight * $ay + $dy)*$this->dataWidth)] < $middle[$ax][$ay])?0:255;
242
- }
243
- }
244
- }
245
- }
246
- return $bitmap;
247
- }
248
-
249
- //@Override
250
- public function getRow($y, $row=null) {
251
- if ($y < 0 || $y >= $this->getHeight()) {
252
- throw new \InvalidArgumentException("Requested row is outside the image: " + y);
253
- }
254
- $width = $this->getWidth();
255
- if ($row == null || count($row) < $width) {
256
- $row = array();
257
- }
258
- $offset = ($y + $this->top) * $this->dataWidth + $this->left;
259
- $row = arraycopy($this->luminances,$offset, $row, 0, $width);
260
- return $row;
261
- }
262
-
263
- //@Override
264
- public function getMatrix() {
265
- $width = $this->getWidth();
266
- $height = $this->getHeight();
267
-
268
- // If the caller asks for the entire underlying image, save the copy and give them the
269
- // original data. The docs specifically warn that result.length must be ignored.
270
- if ($width == $this->dataWidth && $height == $this->dataHeight) {
271
- return $this->luminances;
272
- }
273
-
274
- $area = $width * $height;
275
- $matrix = array();
276
- $inputOffset = $this->top * $this->dataWidth + $this->left;
277
-
278
- // If the width matches the full width of the underlying data, perform a single copy.
279
- if ($width == $this->dataWidth) {
280
- $matrix = arraycopy($this->luminances, $inputOffset, $matrix, 0, $area);
281
- return $matrix;
282
- }
283
-
284
- // Otherwise copy one cropped row at a time.
285
- $rgb = $this->luminances;
286
- for ($y = 0; $y < $height; $y++) {
287
- $outputOffset = $y * $width;
288
- $matrix = arraycopy($rgb, $inputOffset, $matrix, $outputOffset, $width);
289
- $inputOffset += $this->dataWidth;
290
- }
291
- return $matrix;
292
- }
293
-
294
- //@Override
295
- public function isCropSupported() {
296
- return true;
297
- }
298
-
299
- //@Override
300
- public function crop($left, $top, $width, $height) {
301
- return new RGBLuminanceSource($this->luminances,
302
- $this->dataWidth,
303
- $this->dataHeight,
304
- $this->left + $left,
305
- $this->top + $top,
306
- $width,
307
- $height);
308
- }
309
-
310
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/Reader.php DELETED
@@ -1,13 +0,0 @@
1
- <?php
2
-
3
- namespace Zxing;
4
-
5
- interface Reader {
6
-
7
- public function decode($image);
8
-
9
-
10
- public function reset();
11
-
12
-
13
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/ReaderException.php DELETED
@@ -1,48 +0,0 @@
1
- <?php
2
- /*
3
- * Copyright 2007 ZXing authors
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
-
18
- namespace Zxing;
19
-
20
- /**
21
- * The general exception class throw when something goes wrong during decoding of a barcode.
22
- * This includes, but is not limited to, failing checksums / error correction algorithms, being
23
- * unable to locate finder timing patterns, and so on.
24
- *
25
- * @author Sean Owen
26
- */
27
- abstract class ReaderException extends \Exception {
28
-
29
- // disable stack traces when not running inside test units
30
- //protected static $isStackTrace = System.getProperty("surefire.test.class.path") != null;
31
- protected static $isStackTrace = false;
32
-
33
- function ReaderException($cause=null) {
34
- if($cause){
35
- parent::__construct($cause);
36
- }
37
- }
38
-
39
-
40
- // Prevent stack traces from being taken
41
- // srowen says: huh, my IDE is saying this is not an override. native methods can't be overridden?
42
- // This, at least, does not hurt. Because we use a singleton pattern here, it doesn't matter anyhow.
43
- //@Override
44
- public final function fillInStackTrace() {
45
- return null;
46
- }
47
-
48
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/Result.php DELETED
@@ -1,128 +0,0 @@
1
- <?php
2
- /*
3
- * Copyright 2007 ZXing authors
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
-
18
- namespace Zxing;
19
-
20
-
21
- /**
22
- * <p>Encapsulates the result of decoding a barcode within an image.</p>
23
- *
24
- * @author Sean Owen
25
- */
26
- final class Result {
27
-
28
- private $text;
29
- private $rawBytes;
30
- private $resultPoints;
31
- private $format;
32
- private $resultMetadata;
33
- private $timestamp;
34
-
35
-
36
-
37
- public function __construct($text,
38
- $rawBytes,
39
- $resultPoints,
40
- $format,
41
- $timestamp = '') {
42
-
43
- $this->text = $text;
44
- $this->rawBytes = $rawBytes;
45
- $this->resultPoints = $resultPoints;
46
- $this->format = $format;
47
- $this->resultMetadata = null;
48
- $this->timestamp = $timestamp?$timestamp:time();
49
- }
50
-
51
- /**
52
- * @return raw text encoded by the barcode
53
- */
54
- public function getText() {
55
- return $this->text;
56
- }
57
-
58
- /**
59
- * @return raw bytes encoded by the barcode, if applicable, otherwise {@code null}
60
- */
61
- public function getRawBytes() {
62
- return $this->rawBytes;
63
- }
64
-
65
- /**
66
- * @return points related to the barcode in the image. These are typically points
67
- * identifying finder patterns or the corners of the barcode. The exact meaning is
68
- * specific to the type of barcode that was decoded.
69
- */
70
- public function getResultPoints() {
71
- return $this->resultPoints;
72
- }
73
-
74
- /**
75
- * @return {@link BarcodeFormat} representing the format of the barcode that was decoded
76
- */
77
- public function getBarcodeFormat() {
78
- return $this->format;
79
- }
80
-
81
- /**
82
- * @return {@link Map} mapping {@link ResultMetadataType} keys to values. May be
83
- * {@code null}. This contains optional metadata about what was detected about the barcode,
84
- * like orientation.
85
- */
86
- public function getResultMetadata() {
87
- return $this->resultMetadata;
88
- }
89
-
90
- public function putMetadata($type, $value) {
91
- if ($this->resultMetadata == null) {
92
- $this->resultMetadata = array();
93
- }
94
- $resultMetadata[$type] = $value;
95
- }
96
-
97
- public function putAllMetadata($metadata) {
98
- if ($metadata != null) {
99
- if ($this->resultMetadata == null) {
100
- $this->resultMetadata = $metadata;
101
- } else {
102
- $this->resultMetadata = array_merge($this->resultMetadata, $metadata);
103
- }
104
- }
105
- }
106
-
107
- public function addResultPoints($newPoints) {
108
- $oldPoints = $this->resultPoints;
109
- if ($oldPoints == null) {
110
- $this->resultPoints = $newPoints;
111
- } else if ($newPoints != null && count($newPoints) > 0) {
112
- $allPoints = fill_array(0,count($oldPoints)+count($newPoints),0);
113
- $allPoints = arraycopy($oldPoints, 0, $allPoints, 0, count($oldPoints));
114
- $allPoints = arraycopy($newPoints, 0, $allPoints, count($oldPoints), count($newPoints));
115
- $this->resultPoints = $allPoints;
116
- }
117
- }
118
-
119
- public function getTimestamp() {
120
- return $this->timestamp;
121
- }
122
-
123
- //@Override
124
- public function toString() {
125
- return $this->text;
126
- }
127
-
128
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/ResultPoint.php DELETED
@@ -1,140 +0,0 @@
1
- <?php
2
- /*
3
- * Copyright 2007 ZXing authors
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
-
18
- namespace Zxing;
19
-
20
- use Zxing\Common\Detector\MathUtils;
21
-
22
- /**
23
- * <p>Encapsulates a point of interest in an image containing a barcode. Typically, this
24
- * would be the location of a finder pattern or the corner of the barcode, for example.</p>
25
- *
26
- * @author Sean Owen
27
- */
28
- class ResultPoint {
29
-
30
- private $x;
31
- private $y;
32
-
33
- public function __construct($x, $y) {
34
- $this->x = (float)($x);
35
- $this->y = (float)($y);
36
- }
37
-
38
- public final function getX() {
39
- return (float)($this->x);
40
- }
41
-
42
- public final function getY() {
43
- return (float)($this->y);
44
- }
45
-
46
- //@Override
47
- public final function equals($other) {
48
- if ($other instanceof ResultPoint) {
49
- $otherPoint = $other;
50
- return $this->x == $otherPoint->x && $this->y == $otherPoint->y;
51
- }
52
- return false;
53
- }
54
-
55
- //@Override
56
- public final function hashCode() {
57
- return 31 * floatToIntBits($this->x) + floatToIntBits($this->y);
58
- }
59
-
60
- //@Override
61
- public final function toString() {
62
- $result = '';
63
- $result.= ('(');
64
- $result.=($this->x);
65
- $result.=(',');
66
- $result.=($this->y);
67
- $result.=(')');
68
- return $result;
69
- }
70
-
71
- /**
72
- * Orders an array of three ResultPoints in an order [A,B,C] such that AB is less than AC
73
- * and BC is less than AC, and the angle between BC and BA is less than 180 degrees.
74
- *
75
- * @param patterns array of three {@code ResultPoint} to order
76
- */
77
- public static function orderBestPatterns($patterns) {
78
-
79
- // Find distances between pattern centers
80
- $zeroOneDistance = self::distance($patterns[0], $patterns[1]);
81
- $oneTwoDistance = self::distance($patterns[1], $patterns[2]);
82
- $zeroTwoDistance = self::distance($patterns[0], $patterns[2]);
83
-
84
- $pointA='';
85
- $pointB='';
86
- $pointC='';
87
- // Assume one closest to other two is B; A and C will just be guesses at first
88
- if ($oneTwoDistance >= $zeroOneDistance && $oneTwoDistance >= $zeroTwoDistance) {
89
- $pointB = $patterns[0];
90
- $pointA = $patterns[1];
91
- $pointC = $patterns[2];
92
- } else if ($zeroTwoDistance >= $oneTwoDistance && $zeroTwoDistance >= $zeroOneDistance) {
93
- $pointB = $patterns[1];
94
- $pointA = $patterns[0];
95
- $pointC = $patterns[2];
96
- } else {
97
- $pointB = $patterns[2];
98
- $pointA = $patterns[0];
99
- $pointC = $patterns[1];
100
- }
101
-
102
- // Use cross product to figure out whether A and C are correct or flipped.
103
- // This asks whether BC x BA has a positive z component, which is the arrangement
104
- // we want for A, B, C. If it's negative, then we've got it flipped around and
105
- // should swap A and C.
106
- if (self::crossProductZ($pointA, $pointB, $pointC) < 0.0) {
107
- $temp = $pointA;
108
- $pointA = $pointC;
109
- $pointC = $temp;
110
- }
111
-
112
- $patterns[0] = $pointA;
113
- $patterns[1] = $pointB;
114
- $patterns[2] = $pointC;
115
- return $patterns;
116
- }
117
-
118
-
119
- /**
120
- * @param pattern1 first pattern
121
- * @param pattern2 second pattern
122
- * @return distance between two points
123
- */
124
- public static function distance($pattern1, $pattern2) {
125
- return MathUtils::distance($pattern1->x, $pattern1->y, $pattern2->x, $pattern2->y);
126
- }
127
-
128
- /**
129
- * Returns the z component of the cross product between vectors BC and BA.
130
- */
131
- private static function crossProductZ($pointA,
132
- $pointB,
133
- $pointC) {
134
- $bX = $pointB->x;
135
- $bY = $pointB->y;
136
- return (($pointC->x - $bX) * ($pointA->y - $bY)) - (($pointC->y - $bY) * ($pointA->x - $bX));
137
- }
138
-
139
-
140
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/common/AbstractEnum.php DELETED
@@ -1,95 +0,0 @@
1
- <?php
2
-
3
- namespace Zxing\Common\CharacterSetEci\AbstractEnum;
4
-
5
- use \Zxing\NotFoundException;
6
- use ReflectionClass;
7
- /**
8
- * A general enum implementation until we got SplEnum.
9
- */
10
- final class AbstractEnum
11
- {
12
- /**
13
- * Default value.
14
- */
15
- const __default = null;
16
- /**
17
- * Current value.
18
- *
19
- * @var mixed
20
- */
21
- protected $value;
22
- /**
23
- * Cache of constants.
24
- *
25
- * @var array
26
- */
27
- protected $constants;
28
- /**
29
- * Whether to handle values strict or not.
30
- *
31
- * @var boolean
32
- */
33
- protected $strict;
34
- /**
35
- * Creates a new enum.
36
- *
37
- * @param mixed $initialValue
38
- * @param boolean $strict
39
- */
40
- public function __construct($initialValue = null, $strict = false)
41
- {
42
- $this->strict = $strict;
43
- $this->change($initialValue);
44
- }
45
- /**
46
- * Changes the value of the enum.
47
- *
48
- * @param mixed $value
49
- * @return void
50
- */
51
- public function change($value)
52
- {
53
- if (!in_array($value, $this->getConstList(), $this->strict)) {
54
- throw new Exception\UnexpectedValueException('Value not a const in enum ' . get_class($this));
55
- }
56
- $this->value = $value;
57
- }
58
- /**
59
- * Gets current value.
60
- *
61
- * @return mixed
62
- */
63
- public function get()
64
- {
65
- return $this->value;
66
- }
67
- /**
68
- * Gets all constants (possible values) as an array.
69
- *
70
- * @param boolean $includeDefault
71
- * @return array
72
- */
73
- public function getConstList($includeDefault = true)
74
- {
75
- if ($this->constants === null) {
76
- $reflection = new ReflectionClass($this);
77
- $this->constants = $reflection->getConstants();
78
- }
79
- if ($includeDefault) {
80
- return $this->constants;
81
- }
82
- $constants = $this->constants;
83
- unset($constants['__default']);
84
- return $constants;
85
- }
86
- /**
87
- * Gets the name of the enum.
88
- *
89
- * @return string
90
- */
91
- public function __toString()
92
- {
93
- return array_search($this->value, $this->getConstList());
94
- }
95
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/common/BitArray.php DELETED
@@ -1,394 +0,0 @@
1
- <?php
2
- /**
3
- * Created by PhpStorm.
4
- * User: Ashot
5
- * Date: 3/25/15
6
- * Time: 11:51
7
- */
8
-
9
- /*
10
- * Copyright 2007 ZXing authors
11
- *
12
- * Licensed under the Apache License, Version 2.0 (the "License");
13
- * you may not use this file except in compliance with the License.
14
- * You may obtain a copy of the License at
15
- *
16
- * http://www.apache.org/licenses/LICENSE-2.0
17
- *
18
- * Unless required by applicable law or agreed to in writing, software
19
- * distributed under the License is distributed on an "AS IS" BASIS,
20
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21
- * See the License for the specific language governing permissions and
22
- * limitations under the License.
23
- */
24
-
25
- namespace Zxing\Common;
26
-
27
- /**
28
- * <p>A simple, fast array of bits, represented compactly by an array of ints internally.</p>
29
- *
30
- * @author Sean Owen
31
- */
32
-
33
- final class BitArray {
34
-
35
- private $bits;
36
- private $size;
37
-
38
-
39
-
40
- public function __construct($bits=array(),$size=0) {
41
-
42
- if(!$bits&&!$size){
43
- $this->$size = 0;
44
- $this->bits = array();
45
- }elseif($bits&&!$size){
46
- $this->size = $bits;
47
- $this->bits = $this->makeArray($bits);
48
- }else{
49
- $this->bits = $bits;
50
- $this->size = $size;
51
- }
52
-
53
- }
54
-
55
-
56
-
57
-
58
- public function getSize() {
59
- return $this->size;
60
- }
61
-
62
- public function getSizeInBytes() {
63
- return ($this->size + 7) / 8;
64
- }
65
-
66
- private function ensureCapacity($size) {
67
- if ($size > count($this->bits) * 32) {
68
- $newBits = $this->makeArray($size);
69
- $newBits = arraycopy($this->bits, 0, $newBits, 0, count($this->bits));
70
- $this->bits = $newBits;
71
- }
72
- }
73
-
74
- /**
75
- * @param $i; bit to get
76
- * @return true iff bit i is set
77
- */
78
- public function get($i) {
79
- $key = intval($i / 32);
80
- return intval32bits($this->bits[$key] & (1 << ($i & 0x1F))) != 0;
81
- }
82
-
83
- /**
84
- * Sets bit i.
85
- *
86
- * @param i bit to set
87
- */
88
- public function set($i) {
89
- $this->bits[intval($i / 32)] |= 1 << ($i & 0x1F);
90
- $this->bits[intval($i / 32)] = overflow($this->bits[intval($i / 32)]);
91
- }
92
-
93
- /**
94
- * Flips bit i.
95
- *
96
- * @param i bit to set
97
- */
98
- public function flip($i) {
99
- $this->bits[intval($i / 32)] ^= 1 << ($i & 0x1F);
100
- $this->bits[intval($i / 32)] = overflow32($this->bits[intval($i / 32)]);
101
- }
102
-
103
- /**
104
- * @param from first bit to check
105
- * @return index of first bit that is set, starting from the given index, or size if none are set
106
- * at or beyond this given index
107
- * @see #getNextUnset(int)
108
- */
109
- public function getNextSet($from) {
110
- if ($from >= $this->size) {
111
- return $this->size;
112
- }
113
- $bitsOffset = intval($from / 32);
114
- $currentBits = (int)$this->bits[$bitsOffset];
115
- // mask off lesser bits first
116
- $currentBits &= ~((1 << ($from & 0x1F)) - 1);
117
- while ($currentBits == 0) {
118
- if (++$bitsOffset == count($this->bits)) {
119
- return $this->size;
120
- }
121
- $currentBits = $this->bits[$bitsOffset];
122
- }
123
- $result = ($bitsOffset * 32) + numberOfTrailingZeros($currentBits); //numberOfTrailingZeros
124
- return $result > $this->size ? $this->size : $result;
125
- }
126
-
127
- /**
128
- * @param from index to start looking for unset bit
129
- * @return index of next unset bit, or {@code size} if none are unset until the end
130
- * @see #getNextSet(int)
131
- */
132
- public function getNextUnset($from) {
133
- if ($from >= $this->size) {
134
- return $this->size;
135
- }
136
- $bitsOffset = intval($from / 32);
137
- $currentBits = ~$this->bits[$bitsOffset];
138
- // mask off lesser bits first
139
- $currentBits &= ~((1 << ($from & 0x1F)) - 1);
140
- while ($currentBits == 0) {
141
- if (++$bitsOffset == count($this->bits)) {
142
- return $this->size;
143
- }
144
- $currentBits = overflow32(~$this->bits[$bitsOffset]);
145
- }
146
- $result = ($bitsOffset * 32) + numberOfTrailingZeros($currentBits);
147
- return $result > $this->size ? $this->size : $result;
148
- }
149
-
150
- /**
151
- * Sets a block of 32 bits, starting at bit i.
152
- *
153
- * @param i first bit to set
154
- * @param newBits the new value of the next 32 bits. Note again that the least-significant bit
155
- * corresponds to bit i, the next-least-significant to i+1, and so on.
156
- */
157
- public function setBulk($i, $newBits) {
158
- $this->bits[intval($i / 32)] = $newBits;
159
- }
160
-
161
- /**
162
- * Sets a range of bits.
163
- *
164
- * @param start start of range, inclusive.
165
- * @param end end of range, exclusive
166
- */
167
- public function setRange($start, $end) {
168
- if ($end < $start) {
169
- throw new \InvalidArgumentException();
170
- }
171
- if ($end == $start) {
172
- return;
173
- }
174
- $end--; // will be easier to treat this as the last actually set bit -- inclusive
175
- $firstInt = intval($start / 32);
176
- $lastInt = intval($end / 32);
177
- for ($i = $firstInt; $i <= $lastInt; $i++) {
178
- $firstBit = $i > $firstInt ? 0 : $start & 0x1F;
179
- $lastBit = $i < $lastInt ? 31 : $end & 0x1F;
180
- $mask = 0;
181
- if ($firstBit == 0 && $lastBit == 31) {
182
- $mask = -1;
183
- } else {
184
- $mask = 0;
185
- for ($j = $firstBit; $j <= $lastBit; $j++) {
186
- $mask |= 1 << $j;
187
- }
188
- }
189
- $this->bits[$i] = overflow32($this->bits[$i]|$mask);
190
- }
191
- }
192
-
193
- /**
194
- * Clears all bits (sets to false).
195
- */
196
- public function clear() {
197
- $max = count($this->bits);
198
- for ($i = 0; $i < $max; $i++) {
199
- $this->bits[$i] = 0;
200
- }
201
- }
202
-
203
- /**
204
- * Efficient method to check if a range of bits is set, or not set.
205
- *
206
- * @param start start of range, inclusive.
207
- * @param end end of range, exclusive
208
- * @param value if true, checks that bits in range are set, otherwise checks that they are not set
209
- * @return true iff all bits are set or not set in range, according to value argument
210
- * @throws InvalidArgumentException if end is less than or equal to start
211
- */
212
- public function isRange($start, $end, $value) {
213
- if ($end < $start) {
214
- throw new \InvalidArgumentException();
215
- }
216
- if ($end == $start) {
217
- return true; // empty range matches
218
- }
219
- $end--; // will be easier to treat this as the last actually set bit -- inclusive
220
- $firstInt = intval($start / 32);
221
- $lastInt = intval($end / 32);
222
- for ($i = $firstInt; $i <= $lastInt; $i++) {
223
- $firstBit = $i > $firstInt ? 0 : $start & 0x1F;
224
- $lastBit = $i < $lastInt ? 31 :$end & 0x1F;
225
- $mask = 0;
226
- if ($firstBit == 0 && $lastBit == 31) {
227
- $mask = -1;
228
- } else {
229
- $mask = 0;
230
- for ($j = $firstBit; $j <= $lastBit; $j++) {
231
- $mask = overflow32($mask|(1 << $j));
232
- }
233
- }
234
-
235
- // Return false if we're looking for 1s and the masked bits[i] isn't all 1s (that is,
236
- // equals the mask, or we're looking for 0s and the masked portion is not all 0s
237
- if (($this->bits[$i] & $mask) != ($value ? $mask : 0)) {
238
- return false;
239
- }
240
- }
241
- return true;
242
- }
243
-
244
- public function appendBit($bit) {
245
- $this->ensureCapacity($this->size + 1);
246
- if ($bit) {
247
- $this->bits[intval($this->size / 32)] |= 1 << ($this->size & 0x1F);
248
- }
249
- $this->size++;
250
- }
251
-
252
- /**
253
- * Appends the least-significant bits, from value, in order from most-significant to
254
- * least-significant. For example, appending 6 bits from 0x000001E will append the bits
255
- * 0, 1, 1, 1, 1, 0 in that order.
256
- *
257
- * @param value {@code int} containing bits to append
258
- * @param numBits bits from value to append
259
- */
260
- public function appendBits($value, $numBits) {
261
- if ($numBits < 0 || $numBits > 32) {
262
- throw new \InvalidArgumentException("Num bits must be between 0 and 32");
263
- }
264
- $this->ensureCapacity($this->size + $numBits);
265
- for ($numBitsLeft = $numBits; $numBitsLeft > 0; $numBitsLeft--) {
266
- $this->appendBit((($value >> ($numBitsLeft - 1)) & 0x01) == 1);
267
- }
268
- }
269
-
270
- public function appendBitArray($other) {
271
- $otherSize = $other->size;
272
- $this->ensureCapacity($this->size + $otherSize);
273
- for ($i = 0; $i < $otherSize; $i++) {
274
- $this->appendBit($other->get($i));
275
- }
276
- }
277
-
278
- public function _xor($other) {
279
- if (count($this->bits) != count($other->bits)) {
280
- throw new \InvalidArgumentException("Sizes don't match");
281
- }
282
- for ($i = 0; $i < count($this->bits); $i++) {
283
- // The last byte could be incomplete (i.e. not have 8 bits in
284
- // it) but there is no problem since 0 XOR 0 == 0.
285
- $this->bits[$i] ^= $other->bits[$i];
286
- }
287
- }
288
-
289
- /**
290
- *
291
- * @param bitOffset first bit to start writing
292
- * @param array array to write into. Bytes are written most-significant byte first. This is the opposite
293
- * of the internal representation, which is exposed by {@link #getBitArray()}
294
- * @param offset position in array to start writing
295
- * @param numBytes how many bytes to write
296
- */
297
- public function toBytes($bitOffset, &$array, $offset, $numBytes) {
298
- for ($i = 0; $i < $numBytes; $i++) {
299
- $theByte = 0;
300
- for ($j = 0; $j < 8; $j++) {
301
- if ($this->get($bitOffset)) {
302
- $theByte |= 1 << (7 - $j);
303
- }
304
- $bitOffset++;
305
- }
306
- $array[(int)($offset + $i)] = $theByte;
307
- }
308
- }
309
-
310
- /**
311
- * @return underlying array of ints. The first element holds the first 32 bits, and the least
312
- * significant bit is bit 0.
313
- */
314
- public function getBitArray() {
315
- return $this->bits;
316
- }
317
-
318
- /**
319
- * Reverses all bits in the array.
320
- */
321
- public function reverse() {
322
- $newBits = array();
323
- // reverse all int's first
324
- $len = (($this->size-1) / 32);
325
- $oldBitsLen = $len + 1;
326
- for ($i = 0; $i < $oldBitsLen; $i++) {
327
- $x = $this->bits[$i];/*
328
- $x = (($x >> 1) & 0x55555555L) | (($x & 0x55555555L) << 1);
329
- $x = (($x >> 2) & 0x33333333L) | (($x & 0x33333333L) << 2);
330
- $x = (($x >> 4) & 0x0f0f0f0fL) | (($x & 0x0f0f0f0fL) << 4);
331
- $x = (($x >> 8) & 0x00ff00ffL) | (($x & 0x00ff00ffL) << 8);
332
- $x = (($x >> 16) & 0x0000ffffL) | (($x & 0x0000ffffL) << 16);*/
333
- $x = (($x >> 1) & 0x55555555) | (($x & 0x55555555) << 1);
334
- $x = (($x >> 2) & 0x33333333) | (($x & 0x33333333) << 2);
335
- $x = (($x >> 4) & 0x0f0f0f0f) | (($x & 0x0f0f0f0f) << 4);
336
- $x = (($x >> 8) & 0x00ff00ff) | (($x & 0x00ff00ff) << 8);
337
- $x = (($x >> 16) & 0x0000ffff) | (($x & 0x0000ffff) << 16);
338
- $newBits[(int)$len - $i] = (int) $x;
339
- }
340
- // now correct the int's if the bit size isn't a multiple of 32
341
- if ($this->size != $oldBitsLen * 32) {
342
- $leftOffset = $oldBitsLen * 32 - $this->size;
343
- $mask = 1;
344
- for ($i = 0; $i < 31 - $leftOffset; $i++) {
345
- $mask = ($mask << 1) | 1;
346
- }
347
- $currentInt = ($newBits[0] >> $leftOffset) & $mask;
348
- for ($i = 1; $i < $oldBitsLen; $i++) {
349
- $nextInt = $newBits[$i];
350
- $currentInt |= $nextInt << (32 - $leftOffset);
351
- $newBits[intval($i) - 1] = $currentInt;
352
- $currentInt = ($nextInt >> $leftOffset) & $mask;
353
- }
354
- $newBits[intval($oldBitsLen) - 1] = $currentInt;
355
- }
356
- $bits = $newBits;
357
- }
358
-
359
- private static function makeArray($size) {
360
- return array();
361
- }
362
-
363
- // @Override
364
- public function equals($o) {
365
- if (!($o instanceof BitArray)) {
366
- return false;
367
- }
368
- $other = $o;
369
- return $this->size == $other->size && $this->bits===$other->bits;
370
- }
371
-
372
- //@Override
373
- public function hashCode() {
374
- return 31 * $this->size +hashCode($this->bits);
375
- }
376
-
377
- // @Override
378
- public function toString() {
379
- $result = '';
380
- for ($i = 0; $i < $this->size; $i++) {
381
- if (($i & 0x07) == 0) {
382
- $result.=' ';
383
- }
384
- $result.= ($this->get($i) ? 'X' : '.');
385
- }
386
- return (string) $result;
387
- }
388
-
389
- // @Override
390
- public function _clone() {
391
- return new BitArray($this->bits, $this->size);
392
- }
393
-
394
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/common/BitMatrix.php DELETED
@@ -1,424 +0,0 @@
1
- <?php
2
- namespace Zxing\Common;
3
-
4
-
5
- final class BitMatrix {
6
- private $width;
7
- private $height;
8
- private $rowSize;
9
- private $bits;
10
-
11
- public function __construct($width, $height=false, $rowSize=false, $bits=false) {
12
- if(!$height){
13
- $height = $width;
14
- }
15
- if(!$rowSize){
16
- $rowSize = intval(($width + 31) / 32);
17
- }
18
- if(!$bits){
19
- $bits = fill_array(0,$rowSize*$height,0);array();//new int[rowSize * height];
20
- }
21
- $this->width = $width;
22
- $this->height = $height;
23
- $this->rowSize = $rowSize;
24
- $this->bits = $bits;
25
- }
26
- public static function parse($stringRepresentation, $setString, $unsetString){
27
- if (!$stringRepresentation) {
28
- throw new \InvalidArgumentException();
29
- }
30
- $bits = array();
31
- $bitsPos = 0;
32
- $rowStartPos = 0;
33
- $rowLength = -1;
34
- $nRows = 0;
35
- $pos = 0;
36
- while ($pos < strlen($stringRepresentation)) {
37
- if ($stringRepresentation{$pos} == '\n' ||
38
- $stringRepresentation->{$pos} == '\r') {
39
- if ($bitsPos > $rowStartPos) {
40
- if($rowLength == -1) {
41
- $rowLength = $bitsPos - $rowStartPos;
42
- }
43
- else if ($bitsPos - $rowStartPos != $rowLength) {
44
- throw new \InvalidArgumentException("row lengths do not match");
45
- }
46
- $rowStartPos = $bitsPos;
47
- $nRows++;
48
- }
49
- $pos++;
50
- }
51
- else if (substr($stringRepresentation,$pos, strlen($setString))==$setString) {
52
- $pos += strlen($setString);
53
- $bits[$bitsPos] = true;
54
- $bitsPos++;
55
- }
56
- else if (substr($stringRepresentation, $pos + strlen($unsetString))==$unsetString) {
57
- $pos += strlen($unsetString);
58
- $bits[$bitsPos] = false;
59
- $bitsPos++;
60
- } else {
61
- throw new \InvalidArgumentException(
62
- "illegal character encountered: " . substr($stringRepresentation,$pos));
63
- }
64
- }
65
-
66
- // no EOL at end?
67
- if ($bitsPos > $rowStartPos) {
68
- if($rowLength == -1) {
69
- $rowLength = $bitsPos - $rowStartPos;
70
- } else if ($bitsPos - $rowStartPos != $rowLength) {
71
- throw new \InvalidArgumentException("row lengths do not match");
72
- }
73
- $nRows++;
74
- }
75
-
76
- $matrix = new BitMatrix($rowLength, $nRows);
77
- for ($i = 0; $i < $bitsPos; $i++) {
78
- if ($bits[$i]) {
79
- $matrix->set($i % $rowLength, $i / $rowLength);
80
- }
81
- }
82
- return $matrix;
83
- }
84
-
85
- /**
86
- * <p>Gets the requested bit, where true means black.</p>
87
- *
88
- * @param $x; The horizontal component (i.e. which column)
89
- * @param $y; The vertical component (i.e. which row)
90
- * @return value of given bit in matrix
91
- */
92
- public function get($x, $y) {
93
-
94
- $offset = intval($y * $this->rowSize + ($x / 32));
95
- if(!isset($this->bits[$offset])){
96
- $this->bits[$offset] = 0;
97
- }
98
-
99
- // return (($this->bits[$offset] >> ($x & 0x1f)) & 1) != 0;
100
- return (uRShift($this->bits[$offset],($x & 0x1f)) & 1) != 0;//было >>> вместо >>, не знаю как эмулировать беззнаковый сдвиг
101
- }
102
-
103
- /**
104
- * <p>Sets the given bit to true.</p>
105
- *
106
- * @param $x; The horizontal component (i.e. which column)
107
- * @param $y; The vertical component (i.e. which row)
108
- */
109
- public function set($x, $y) {
110
- $offset = intval($y * $this->rowSize + ($x / 32));
111
- if(!isset($this->bits[$offset])){
112
- $this->bits[$offset] = 0;
113
- }
114
- //$this->bits[$offset] = $this->bits[$offset];
115
-
116
- // if($this->bits[$offset]>200748364){
117
- //$this->bits= array(0,0,-16777216,-1,-1,-1,-1,65535,0,0,0,0,0,0,0,-16777216,-1,-1,-1,-1,65535,0,0,0,0,0,0,0,-16777216,-1,-1,-1,-1,65535,0,0,0,0,0,0,0,-16777216,-1,-1,-1,-1,65535,0,0,0,0,0,0,0,-16777216,-1,-1,-1,-1,65535,0,0,0,0,0,0,0,-16777216,-1,-1,-1,-1,65535,0,0,0,0,0,0,0,-16777216,-1,-1,-1,-1,65535,0,0,0,0,0,0,0,-16777216,-1,-1,-1,-1,65535,0,0,0,0,0,0,0,-16777216,-1,-1,-1,-1,65535,0,0,0,0,0,0,0,-16777216,-1,-1,-1,-1,65535,0,0,0,0,0,0,0,-16777216,-1,-1,-1,-1,65535,0,0,0,0,0,0,0,-1090519040,-1,-1,-1,-1,65535,0,0,0,0,0,0,0,1056964608,-1,-1,-1,-1,65535,0,0,0,0,0,0,0,-1358954496,-1,-1,-1,-1,65535,0,0,0,0,0,0,0,117440512,-1,-1,-1,-1,65535,0,0,0,0,0,0,0,50331648,-1,-1,-1,-1,65535,0,0,0,0,0,0,0,33554432,-1,-1,536870911,-4096,65279,0,0,0,0,0,0,0,0,-1,-1,65535,-4096,65535,0,0,0,0,0,0,0,0,-193,536870911,0,-4096,65279,0,0,0,0,0,0,0,0,-254,32767,0,-4096,61951,0,0,0,0,0,0,0,0,20913920,0,0,-4096,50175,0,0,0,0,0,0,0,0,0,0,0,-4096,60159,0,0,0,0,0,0,0,0,0,0,0,-4096,64255,0,0,0,0,0,0,0,0,0,0,0,-8192,56319,0,0,0,0,0,0,0,0,0,0,0,-4096,16777215,0,0,0,0,0,0,0,0,0,0,0,-4096,16777215,0,0,0,0,0,0,0,0,0,0,0,-4096,16777215,0,0,0,0,0,0,0,0,0,0,0,-4096,16777215,0,0,0,0,0,0,0,0,0,0,0,-4096,16777215,0,0,0,0,0,0,0,0,0,0,0,-4096,16777215,0,0,0,0,0,0,0,0,0,0,0,-4096,16777215,0,0,0,0,0,0,0,0,0,0,0,-4096,16777215,0,0,0,0,0,0,0,251658240,0,0,0,-4096,-1,255,0,256,0,0,0,0,117440512,0,0,0,-4096,-1,255,0,512,0,0,0,0,117440512,0,0,0,-4096,-1,255,0,1024,0,0,0,0,117440512,0,0,0,-4096,-1,223,0,256,0,0,0,0,117440512,0,0,33030144,-4096,-1,191,0,256,0,0,0,0,117440512,0,0,33554428,-4096,-1,255,0,768,0,0,0,0,117440512,0,402849792,67108862,-8192,-1,255,0,768,0,0,0,0,117440512,0,470278396,63045630,-8192,-1,255,0,256,0,0,0,0,251658240,-8388608,470278399,58720286,-8192,-1,2686975,0,3842,0,0,0,0,251658240,-131072,1007149567,58720286,-8192,-1,2031615,0,3879,0,0,0,0,251658240,536739840,1007092192,58720286,-8192,-1,851967,0,3840,0,0,0,0,251658240,917504,1007092192,58720284,-8192,-1,2031615,0,3968,0,0,0,0,251658240,917504,1007092160,59244060,-8192,-1,65535,0,7936,0,0,0,0,251658240,917504,1009779136,59244060,-8192,-1,9371647,0,1792,0,0,0,0,251658240,917504,946921920,59244060,-8192,-1,8585215,0,1792,0,0,0,0,117440512,-15859712,477159875,59244060,-8192,-1,65535,0,12032,0,0,0,0,251658240,-15859712,52490691,59244060,-8192,-1,-1,0,65408,0,0,0,0,251658240,-15859712,58778051,59244060,-8192,-1,-1,0,65473,0,0,0,0,251658240,-15859712,125886915,59244060,-8192,-1,-1,0,65472,0,0,0,0,251658240,-15859712,58778051,59244060,-8192,-1,-1,0,65408,0,0,0,0,251658240,-15859712,8380867,59244060,-8192,-1,-1,0,65473,0,0,0,0,251658240,-15859712,8380867,59244060,-8192,-1,-1,0,131011,0,0,0,0,251658240,-15859712,8380867,58720284,-8192,-1,-1,0,130947,0,0,0,0,251658240,-15859712,2089411,58720284,-8192,-1,-1,0,130947,0,0,0,0,251658240,-32636928,449,58720284,-8192,-1,-1,33554431,131015,0,0,0,0,251658240,786432,448,62914588,-8192,-1,-1,16777215,131015,0,0,0,0,251658240,786432,448,67108860,-8192,-1,-1,553648127,131015,0,0,0,0,251658240,786432,946864576,67108860,-8192,-1,-1,32505855,131015,0,0,0,0,251658240,786432,946921976,8388604,-8192,-1,-1,8191999,131015,0,0,0,0,251658240,-262144,946921983,248,-8192,-1,-1,8126463,196551,0,0,0,0,251658240,-262144,7397887,0,-8192,-1,-1,16777215,262087,0,0,0,0,251658240,-262144,8257543,0,-8192,-1,-1,-2121269249,262095,0,0,0,0,520093696,0,8257536,0,-8192,-1,-1,-201326593,262095,0,0,0,0,520290304,0,8257536,117963776,-8192,-1,-1,-201326593,262095,0,0,0,0,520093696,0,-2140143616,118488579,-8192,-1,-1,-201326593,131023,0,0,0,0,520093696,0,-2131697280,118488579,-8192,-1,-1,-503316481,131023,0,0,0,0,520093696,2145386496,-2131631232,118484995,-16384,-1,-1,-469762049,262095,0,0,0,0,520093696,2147221504,552649600,118481344,-16384,-1,-1,-469762049,131023,0,0,0,0,520290304,2147221504,2029002240,118481344,-16384,-1,-1,-469762049,262031,0,0,0,0,520290304,-266600448,2029001791,125952960,-16384,-1,-1,-469762049,262031,0,0,0,0,1057423360,-266600448,2027953215,133177312,-16384,-1,-1,-134217729,262111,0,0,0,0,1058471936,-266600448,-119531393,133177343,-16384,-1,-1,-134217729,262111,0,0,0,0,1058471936,-2145648640,-253754369,66068479,-16384,-1,-1,-134217729,262111,0,0,0,0,1058471936,236716032,-253754369,15729663,-16384,-1,-1,-134217729,262095,0,0,0,0,1057947648,236716032,-253754369,6348807,-16384,-1,-1,-134217729,262095,0,0,0,0,524222464,236716032,-253690305,6348803,-16384,-1,-1,-134217729,262111,0,0,0,0,521076736,2115764224,-253625344,14737411,-16384,-1,-1,-134217729,262095,0,0,0,0,522125312,2115764224,-253625344,14743555,-16384,-1,-1,-134217729,262111,0,0,16772608,0,1073676288,-31719424,-2014283776,14810115,-16384,-1,-1,-1,262143,0,0,16776704,0,1065287680,-1642594304,-1879178880,14810115,-16384,-1,-1,-1,524287,0,0,16776192,0,2139029504,264241152,-2013396089,14809091,-16384,-1,-1,-1,262095,0,0,16776192,0,2139029504,264241152,-2080636025,14803335,-16384,-1,-1,-1,262087,0,0,16776192,0,2147418112,264241152,-2132803581,14803847,-16384,-1,-1,-402653185,524259,0,0,8386048,0,2147418112,0,-2132688896,123783,-16384,-1,-1,1207959551,262112,0,0,16775168,0,2147418112,0,14794752,1046535,-16384,-1,-1,268435455,262128,0,0,16775168,0,2147418112,0,14712832,1047615,-16384,-1,-1,536870911,524284,0,0,16776705,0,2147418112,0,14680832,1047615,-16384,-1,-1,-1,524287,0,0,16776704,0,2147418112,-1048576,14681087,1046591,-32768,-1,-1,-1,524287,0,0,16776704,0,2147418112,-524288,-2132802561,2080831,-32768,-1,-1,-1,524287,0,0,16776705,0,2147418112,-524288,-31718401,2080831,-32768,-1,-1,-1,1048575,0,0,16776193,0,2147418112,3670016,-31718528,2080831,-32768,-1,-1,-1,524287,0,0,16776195,0,2147418112,3670016,-31718528,134086719,-32768,-1,-1,-1,524287,0,0,16776195,0,2147418112,3670016,253494144,268173368,-32768,-1,-1,-1,524287,0,0,16775171,0,2147418112,3670016,268174208,268173368,-32768,-1,-1,-1,1048575,0,0,16771072,0,2147418112,-63438848,268174223,31457328,-32768,-1,-1,-1,1048575,0,0,10418176,0,-65536,-63438848,133957519,14807040,-32768,-1,-1,-1,2097151,0,0,15923200,0,2147418112,-63438848,1968015,14809095,-32768,-1,-1,-1,1048575,0,0,12808192,0,2147418112,-63438848,2082703,12711943,-32768,-1,-1,-1,2097151,0,0,6420480,0,2147418112,-63438848,2082703,14343,-32768,-1,-1,-1,2097151,0,0,15202304,0,-65536,-63438848,2082703,1849351,-32768,-1,-1,-1,2097151,0,0,15464448,0,-65536,-63438848,264472335,1849351,-32768,-1,-1,-1,4194303,0,0,16371712,0,-65536,-63438848,264472335,14343,-32768,-1,-1,-1,8388607,0,0,0,0,-65536,-63438848,532907791,235010048,-32768,-1,-1,-1,16777215,0,0,0,0,-65536,-63438848,-1603833,235010160,-32768,-1,-1,-1,16777215,0,0,0,0,-65536,3670016,-30976,67238000,-32768,-1,-1,-1,16777215,0,0,0,0,-65536,3670016,-30976,48,-32768,-1,-1,-1,16777215,0,0,0,0,-65536,3670016,-29391104,768,-32768,-1,-1,-1,16777215,0,0,0,0,-65536,3670016,-29391104,768,-32768,-1,-1,-1,16777215,0,0,0,0,-65536,-524287,-65042433,768,-32768,-1,-1,-1,16777215,0,0,0,0,-65536,-524287,2082441215,0,-65536,-1,-1,-1,16777215,0,0,0,0,-13697024,-524287,511,0,-65536,-1,-1,-1,16777215,0,0,0,0,-12648448,1,0,0,-65536,-1,-1,-1,14680063,0,0,0,0,-12648448,1,0,0,-65536,-1,-1,-1,16777215,0,0,0,0,-65536,1,0,0,-65536,-1,-1,-1,14680063,0,0,0,0,-8454144,1,0,0,-65536,-1,-1,-1,12582911,0,0,0,0,-12648448,1,0,0,-65536,-1,-1,-1,2097151,0,0,0,0,-12648448,1,0,0,-65536,-1,-1,-1,1048575,0,0,0,0,-14745600,1,0,0,-65536,-1,-1,-1,3145727,0,0,0,0,1056964608,1,0,0,-65536,-1,-1,-1,1048575,0,0,0,0,1056964608,1,0,0,-65536,-1,-1,-1,1048575,0,0,0,0,1056964608,1,0,0,-65536,-1,-1,-1,524287,0,0,0,0,2130706432,1,0,0,-65536,-1,-1,-1,1048575,0,0,0,0,1056964608,1,0,0,-65536,-1,-1,-1,524287,0,0,0,0,2130706432,1,0,0,-65536,-1,-1,-1,524287,0,0,0,0,2130706432,1,0,0,-65536,-1,-1,-1,1048575,0,0,0,0,2130706432,1,0,0,-65536,-1,-1,-1,1048575,0,0,0,0,50331648,1,0,0,-65536,-1,-1,-1,1048575,0,0,0,0,117440512,1,0,-268435456,-1,-1,-1,-1,524287,0,0,0,0,251658240,1,0,-320,-1,-1,-1,-1,262143,0,0,0,0,520093696,1,-2048,-1,-1,-1,-1,-1,262143,0,0,0,0,1056964608,-16777213,-1,-1,-1,-1,-1,-1,131071,0,0,0,0,-16777216,-121,-1,-1,-1,-1,-1,-1,131071,0,0,0,0,-16777216,-1,-1,-1,-1,-1,-1,-1,131071,0,0,0,0,-16777216,-1,-1,-1,-1,-1,-1,-1,131071,0,0,0,0,-16777216,-1,-1,-1,-1,-1,-1,-1,131071,0,0,0,0,-16777216,-1,-1,-1,-1,-1,-1,-1,65535,0,0,0,0,-16777216,-1,-1,-1,-1,-1,-1,-1,65535,0,0,0,0,-16777216,-1,-1,-1,-1,-1,-1,-1,131071,0,0,0,0,-16777216,-1,-1,-1,-1,-1,-1,-1,262143,0,0,0,0,-16777216,-1,-1,-1,-1,-1,-1,-1,524287,0,0,0,0,-16777216,-1,-1,-1,-1,-1,-1,-1,524287,0,0,0,0,-16777216,-1,-1,-1,-1,-1,-1,-1,589823,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,8179,0,0,0,0,50331648,-1,-1,-1,-1,-1,-1,-1,4080,0,0,0,0,117440512,-1,-1,-1,-1,-1,-1,-1,1016,0,0,0,0,251658240,-1,-1,-1,-1,-1,-1,1073741823,1020,0,0,0,0,50331648,-1,-1,-1,-1,-1,-1,536870911,254,0,0,0,0,50331648,-1,-1,-1,-1,-1,-1,536870911,255,0,0,0,0,50331648,-1,-1,-1,-1,-1,-1,-1879048193,127,0,0,0,0,50331648,-1,-1,-1,-1,-1,-1,-469762049,63,0,0,0,0,1191182336,-1,-1,-1,-1,1023999,0,-520093712,15,0,0,0,0,-218103808,-1,-1,-1,-1,0,-8454144,-260046849,7,0,0,0,0,0,-193,-1,-1,-1057947649,-2147483648,-1,-58720257,1,0,0,0,0,0,-251,-1,-1,-1057423361,-2074,-1,-1,0,0,0,0,0,0,-59648,-1,-1,-1,-1,-1,1073741823,0,0,0,0,0,0,-65536,-1,-1,-1,-1,-1,268435455,0,0,0,0,0,0,-65536,-1,-1,-1,-1,-1,67108863,0,0,0,0,0,0,-65536,-1,-1,-1,-1,-1,8388607,0,0,0,0,0,0,0,-403603456,-1,-1,-1,-1,262143,0,0,0,8388656,0,0,0,-1891434496,-1,-1,-1,-1,16383,0,0,0,8388608,0,0,0,-1612513280,-1,-1,-1,-1,63,0,0,0,0,0,0,0,-24320,-1,-1,-1,8388607,0,0,0,0,0,0,0,0,-256,-1,-1,1073741823,1,0,0,0,0,0,0,0,1610612736,-15,-1,-1,16383,0,0,0,0,0,0,0,0,-16646144,-1,-1,251658239,0,0,0,0,0,0,0,0,0,-51200,-1,-1,40959,0,0,0,0,0,0,268419584,103809024,-12713984,-1,-2147483137,4194303,0,0,0,0,0,0,0,402620416,-2144010240,-13631487,-32513,3,20480,0,0,0,0,0,0,0,419299328,0,-262144,-1,0,0,0,0,0,0,0,0,0,0,0,-5832704,268049407,0,0,0,0,0,0,0,0,0,0,0,0,33030144,0,0,0,0,0,0,0,0,0,0,0,0,3670016,0,0,0,0,0,0,0,0,0,0,0,0,1572864,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,458752,0,0,0,0,0,0,0,0,0,0,0,0,229376,0,0,0,0,0,0,0,0,0,0,0,0,32768,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8192,0,0,0,0,0,0,0,0,0,0,0,0,8192,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31744,0,0,0,0,0,0,0,0,0,0,0,0,31744,0,0,0,0,0,0,0,0,0,0,0,0,64512,0,0,0,0,0,0,0,0,0,0,0,0,15872,0,0,0,0,0,0,0,0,0,0,0,0,3584,0,0,0,0,0,0,0,0,0,0,0,0,7680,0,0,0,0,0,0,0,0,0,0,0,0,512,0,0,0,0,0,0,0,0,0,0,0,0,3968,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3840,0,0,0,0,0,0,0,0,0,0,0,0,1855,0,0,0,0,0,0,0,0,0,0,0,0,63,0,0,0,0,0,0,0,0,0,0,0,0,15,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,134217728,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,124,0,0,0,0,0,0,0,0,0,0,0,-260046848,63,0,0,0,0,0,0,0,0,0,0,0,-17301504,127,0,0,0,0,0,0,0,0,0,0,0,-524288,127,0,0,0,0,0,0,0,0,0,0,0,-262144,127,0,0,0,0,0,0,0,0,0,0,0,-262144,63,0,0,0,0,0,0,0,0,0,0,0,-262144,63,0,0,0,0,0,0,0,0,0,0,0,-262144,63,0,0,0,0,0,0,0,0,0,0,0,-262144,31,0,0,0,0,0,0,0,0,0,0,0,-262144,63,0,0,0,0,3,0,0,0,0,0,0,-262144,63,0,0,0,0,7,0,0,0,0,0,0,-262144,63,0,0,0,0,63,0,0,0,0,0,0,-262144,63,0,0,0,0,511,0,0,0,0,0,0,-524288,31,0,0,0,0,8191,0,0,0,0,0,0,-1048576,63,0,0,0,0,131071,0,0,0,0,0,0,-524288,63,0,0,0,0,262143,0,0,0,0,0,0,-524288,63,0,0,0,0,131071,0,0,0,0,0,0,-1048576,63,0,0,0,0,262143,0,0,0,0,0,0,-1048576,63,0,0,0,0,262143,0,0,0,0,0,0,-1048576,63,0,0,0,0,262143,0,0,0,0,0,0,-1048576,63,0,0,0,0,262143,0,0,0,0,0,0,-2097152,127,0,0,0,0,262143,0,0,0,0,0,0,-2097152,127,0,0,0,0,262143,0,0,0,0,0,0,-1048576,127,0,0,0,0,262143,0,0,0,0,0,0,-1048576,127,0,0,0,0,262143,0,0,0,0,0,0,-2097152,255,0,0,0,0,262143,0,0,0,0,0,0,-2097152,255,0,0,0,0,262142,0,0,0,0,0,0,-2097152,255,0,0,0,0,262142,0,0,0,0,0,0,-2097152,255,0,0,0,0,262142,0,0,0,0,0,0,-2097152,255,0,0,0,0,262140,0,0,0,0,0,0,-2097152,255,0,0,0,0,131068,0,0,0,0,0,0,-4194304,255,0,0,0,0,131068,0,0,0,0,0,0,-4194304,255,0,0,0,0,65528,0,0,0,0,0,0,-8388608,255,0,0,0,0,65528,0,0,0,0,0,0,-8388608,255,0,0,0,0,65528,0,0,0,0,0,0,-8388608,255,0,0,0,0,32760,0,0,0,0,0,0,-8388608,255,0,0,0,0,32760,0,0,0,0,0,0,-16777216,255,0,0,-2147483648,255,16368,0,0,0,0,0,0,-16777216,255,0,0,-536870912,1023,16368,0,0,0,0,0,0,-33554432,255,0,0,-16777216,4095,16352,0,0,0,0,0,0,-33554432,255,0,0,-8388608,262143,16352,0,0,0,0,0,0,-33554432,255,0,0,-1048576,2097151,16352,0,0,0,0,0,0,-67108864,255,0,0,-524288,8388607,16352,0,0,0,0,0,0,-67108864,255,0,0,-262144,16777215,16320,0,0,0,0,0,0,-67108864,255,0,0,-131072,16777215,100679648,0,0,0,0,0,0,-67108864,255,0,0,-16384,16776959,125861824,0,0,0,0,0,0,-134217728,255,0,0,-4096,16773121,62930880,0,0,0,0,0,0,-134217728,127,0,0,2147482624,16252928,32704,0,0,0,0,0,0,-134217728,127,0,0,268435200,14680064,16320,0,0,0,0,0,0,-134217728,127,0,0,134217600,0,32704,0,0,0,0,0,0,-33554432,127,0,1056964608,67108736,0,32704,0,0,0,0,0,0,-33554432,127,0,2130706432,33554368,0,65408,0,0,0,0,0,0,-33554432,127,0,-16777216,8388576,0,32640,0,0,0,0,0,0,-134217728,127,0,-16777216,2097136,0,32640,0,0,0,0,0,0,-134217728,63,0,-16776960,1048573,0,32640,0,0,0,0,0,0,-536870912,63,0,-16776448,1048575,0,32640,0,0,0,0,0,0,-536870912,63,0,-33553664,6291455,66752,32640,0,0,0,0,0,0,-536870912,63,0,2013266688,2097148,229376,32640,0,0,0,0,0,0,-536870912,63,0,256,4194300,229376,32640,0,0,0,0,0,0,-536870912,63,0,0,524280,196608,32512,0,0,8,0,0,0,-1073741824,63,0,0,-200,15,65280,0,0,24,0,0,0,-1073741824,63,0,0,-1867768,127,32512,0,0,56,0,0,0,-1073741824,63,0,0,-1056768,4095,32512,0,0,124,0,0,0,-1073741824,63,0,0,-1050624,8191,32512,0,0,508,0,0,0,-2147483648,31,0,0,-7866368,8191,32512,0,0,1020,0,0,0,-2147483648,31,0,0,-33030656,8095,32512,0,0,2046,0,0,0,-2147483648,63,0,0,-66586624,771,32512,0,0,4094,0,0,0,0,63,0,0,-134184960,1,32256,0,0,8190,0,0,0,0,63,0,0,1610612736,0,32256,0,0,16382,0,0,0,-2147483648,63,0,0,0,0,15872,0,0,32767,0,0,0,-2147483648,31,0,0,0,0,15872,0,-2147483648,65535,0,0,0,-2147483648,31,0,0,0,0,7680,0,0,65535,0,0,0,-2147483648,31,0,0,134217728,0,7680,0,-2147483648,65535,0,0,0,-2147483648,31,0,0,0,0,7680,0,-2147483648,65535,0,0,0,-2147483648,31,0,0,0,0,7680,0,-1073741824,65535,0,0,0,-2147483648,31,0,0,0,0,3072,0,-1073741824,65535,0,0,0,-2147483648,31,0,0,0,0,3072,0,-1073741824,65535,0,0,0,-2147483648,31,0,0,0,0,0,0,-2147483648,65535,0,0,0,-2147483648,31,0,0,0,0,0,0,-1073741824,65535,0,0,0,0,31,0,0,0,0,0,0,-1073741824,65535,0,0,0,0,31,0,0,0,0,0,0,-2147483648,65535,0,0,0,0,30,0,0,0,0,0,0,-1073741824,65535,0,0,0,0,30,0,0,0,0,0,0,-2147483648,65535,0,0,0,0,30,0,0,0,0,0,0,0,65535,0,0,0,0,28,0,0,0,0,0,0,0,65535,0,0,0,0,28,0,0,0,0,0,0,0,65535,0,0,0,0,28,0,0,0,0,0,0,0,65535,0,0,0,0,24,0,0,0,0,0,0,-2147483648,65535,0,0,0,0,0,0,0,0,0,0,0,-536870912,65535);//[$offset] |= intval32bits(1 << ($x & 0x1f));
118
- $bob = $this->bits[$offset];
119
- $bob |= 1 << ($x & 0x1f);
120
- $this->bits[$offset] |= overflow32($bob);
121
- //$this->bits[$offset] = intval32bits($this->bits[$offset]);
122
-
123
- //}
124
- //16777216
125
- }
126
-
127
- public function _unset($x, $y) {//было unset, php не позволяет использовать unset
128
- $offset = intval($y * $this->rowSize + ($x / 32));
129
- $this->bits[$offset] &= ~(1 << ($x & 0x1f));
130
- }
131
-
132
-
133
- /**1 << (249 & 0x1f)
134
- * <p>Flips the given bit.</p>
135
- *
136
- * @param $x; The horizontal component (i.e. which column)
137
- * @param $y; The vertical component (i.e. which row)
138
- */
139
- public function flip($x, $y) {
140
- $offset = $y * $this->rowSize + intval($x / 32);
141
-
142
- $this->bits[$offset] = overflow32($this->bits[$offset]^(1 << ($x & 0x1f)));
143
- }
144
-
145
- /**
146
- * Exclusive-or (XOR): Flip the bit in this {@code BitMatrix} if the corresponding
147
- * mask bit is set.
148
- *
149
- * @param $mask; XOR mask
150
- */
151
- public function _xor($mask) {//было xor, php не позволяет использовать xor
152
- if ($this->width != $mask->getWidth() || $this->height != $mask->getHeight()
153
- || $this->rowSize != $mask->getRowSize()) {
154
- throw new \InvalidArgumentException("input matrix dimensions do not match");
155
- }
156
- $rowArray = new BitArray($this->width / 32 + 1);
157
- for ($y = 0; $y < $this->height; $y++) {
158
- $offset = $y * $this->rowSize;
159
- $row = $mask->getRow($y, $rowArray)->getBitArray();
160
- for ($x = 0; $x < $this->rowSize; $x++) {
161
- $this->bits[$offset + $x] ^= $row[$x];
162
- }
163
- }
164
- }
165
-
166
- /**
167
- * Clears all bits (sets to false).
168
- */
169
- public function clear() {
170
- $max = count($this->bits);
171
- for ($i = 0; $i < $max; $i++) {
172
- $this->bits[$i] = 0;
173
- }
174
- }
175
-
176
- /**
177
- * <p>Sets a square region of the bit matrix to true.</p>
178
- *
179
- * @param $left; The horizontal position to begin at (inclusive)
180
- * @param $top; The vertical position to begin at (inclusive)
181
- * @param $width; The width of the region
182
- * @param $height; The height of the region
183
- */
184
- public function setRegion($left, $top, $width, $height) {
185
- if ($top < 0 || $left < 0) {
186
- throw new \InvalidArgumentException("Left and top must be nonnegative");
187
- }
188
- if ($height < 1 || $width < 1) {
189
- throw new \InvalidArgumentException("Height and width must be at least 1");
190
- }
191
- $right = $left + $width;
192
- $bottom = $top + $height;
193
- if ($bottom > $this->height || $right > $this->width) { //> this.height || right > this.width
194
- throw new \InvalidArgumentException("The region must fit inside the matrix");
195
- }
196
- for ($y = $top; $y < $bottom; $y++) {
197
- $offset = $y * $this->rowSize;
198
- for ($x = $left; $x < $right; $x++) {
199
- $this->bits[$offset + intval($x / 32)] = overflow32($this->bits[$offset + intval($x / 32)]|= 1 << ($x & 0x1f));
200
- }
201
- }
202
- }
203
-
204
- /**
205
- * A fast method to retrieve one row of data from the matrix as a BitArray.
206
- *
207
- * @param $y; The row to retrieve
208
- * @param $row; An optional caller-allocated BitArray, will be allocated if null or too small
209
- * @return The resulting BitArray - this reference should always be used even when passing
210
- * your own row
211
- */
212
- public function getRow($y, $row) {
213
- if ($row == null || $row->getSize() < $this->width) {
214
- $row = new BitArray($this->width);
215
- } else {
216
- $row->clear();
217
- }
218
- $offset = $y * $this->rowSize;
219
- for ($x = 0; $x < $this->rowSize; $x++) {
220
- $row->setBulk($x * 32, $this->bits[$offset + $x]);
221
- }
222
- return $row;
223
- }
224
-
225
- /**
226
- * @param $y; row to set
227
- * @param $row; {@link BitArray} to copy from
228
- */
229
- public function setRow($y, $row) {
230
- $this->bits = arraycopy($row->getBitArray(), 0, $this->bits, $y * $this->rowSize, $this->rowSize);
231
- }
232
-
233
- /**
234
- * Modifies this {@code BitMatrix} to represent the same but rotated 180 degrees
235
- */
236
- public function rotate180() {
237
- $width = $this->getWidth();
238
- $height = $this-getHeight();
239
- $topRow = new BitArray($width);
240
- $bottomRow = new BitArray($width);
241
- for ($i = 0; $i < ($height+1) / 2; $i++) {
242
- $topRow = $this->getRow($i, $topRow);
243
- $bottomRow = $this->getRow($height - 1 - $i, $bottomRow);
244
- $topRow->reverse();
245
- $bottomRow->reverse();
246
- $this->setRow($i, $bottomRow);
247
- $this->setRow($height - 1 - $i, $topRow);
248
- }
249
- }
250
-
251
- /**
252
- * This is useful in detecting the enclosing rectangle of a 'pure' barcode.
253
- *
254
- * @return {@code left,top,width,height} enclosing rectangle of all 1 bits, or null if it is all white
255
- */
256
- public function getEnclosingRectangle() {
257
- $left = $this->width;
258
- $top = $this->height;
259
- $right = -1;
260
- $bottom = -1;
261
-
262
- for ($y = 0; $y < $this->height; $y++) {
263
- for ($x32 = 0; $x32 < $this->rowSize; $x32++) {
264
- $theBits = $this->bits[$y * $this->rowSize + $x32];
265
- if ($theBits != 0) {
266
- if ($y < $top) {
267
- $top = $y;
268
- }
269
- if ($y > $bottom) {
270
- $bottom = $y;
271
- }
272
- if ($x32 * 32 < $left) {
273
- $bit = 0;
274
- while (($theBits << (31 - $bit)) == 0) {
275
- $bit++;
276
- }
277
- if (($x32 * 32 + $bit) < $left) {
278
- $left = $x32 * 32 + $bit;
279
- }
280
- }
281
- if ($x32 * 32 + 31 > $right) {
282
- $bit = 31;
283
- while ((sdvig3($theBits, $bit)) == 0) {//>>>
284
- $bit--;
285
- }
286
- if (($x32 * 32 + $bit) > $right) {
287
- $right = $x32 * 32 + $bit;
288
- }
289
- }
290
- }
291
- }
292
- }
293
-
294
- $width = $right - $left;
295
- $height = $bottom - $top;
296
-
297
- if ($width < 0 || $height < 0) {
298
- return null;
299
- }
300
-
301
- return array($left, $top, $width, $height);
302
- }
303
-
304
- /**
305
- * This is useful in detecting a corner of a 'pure' barcode.
306
- *
307
- * @return {@code x,y} coordinate of top-left-most 1 bit, or null if it is all white
308
- */
309
- public function getTopLeftOnBit() {
310
- $bitsOffset = 0;
311
- while ($bitsOffset < count($this->bits) && $this->bits[$bitsOffset] == 0) {
312
- $bitsOffset++;
313
- }
314
- if ($bitsOffset == count($this->bits)) {
315
- return null;
316
- }
317
- $y = $bitsOffset / $this->rowSize;
318
- $x = ($bitsOffset % $this->rowSize) * 32;
319
-
320
- $theBits = $this->bits[$bitsOffset];
321
- $bit = 0;
322
- while (($theBits << (31-$bit)) == 0) {
323
- $bit++;
324
- }
325
- $x += $bit;
326
- return array($x, $y);
327
- }
328
-
329
- public function getBottomRightOnBit() {
330
- $bitsOffset = count($this->bits) - 1;
331
- while ($bitsOffset >= 0 && $this->bits[$bitsOffset] == 0) {
332
- $bitsOffset--;
333
- }
334
- if ($bitsOffset < 0) {
335
- return null;
336
- }
337
-
338
- $y = $bitsOffset / $this->rowSize;
339
- $x = ($bitsOffset % $this->rowSize) * 32;
340
-
341
- $theBits = $this->bits[$bitsOffset];
342
- $bit = 31;
343
- while ((sdvig3($theBits, $bit)) == 0) {//>>>
344
- $bit--;
345
- }
346
- $x += $bit;
347
-
348
- return array($x, $y);
349
- }
350
-
351
- /**
352
- * @return The width of the matrix
353
- */
354
- public function getWidth() {
355
- return $this->width;
356
- }
357
-
358
- /**
359
- * @return The height of the matrix
360
- */
361
- public function getHeight() {
362
- return $this->height;
363
- }
364
-
365
- /**
366
- * @return The row size of the matrix
367
- */
368
- public function getRowSize() {
369
- return $this->rowSize;
370
- }
371
-
372
- //@Override
373
- public function equals($o) {
374
- if (!($o instanceof BitMatrix)) {
375
- return false;
376
- }
377
- $other = $o;
378
- return $this->width == $other->width && $this->height == $other->height && $this->rowSize == $other->rowSize &&
379
- $this->bits===$other->bits;
380
- }
381
-
382
- //@Override
383
- public function hashCode() {
384
- $hash = $this->width;
385
- $hash = 31 * $hash + $this->width;
386
- $hash = 31 * $hash + $this->height;
387
- $hash = 31 * $hash + $this->rowSize;
388
- $hash = 31 * $hash + hashCode($this->bits);
389
- return $hash;
390
- }
391
-
392
- //@Override
393
- public function toString($setString='', $unsetString='',$lineSeparator='') {
394
- if(!$setString||!$unsetString){
395
- return (string)"X "." ";
396
- }
397
- if($lineSeparator&&$lineSeparator!=="\n"){
398
- return $this->toString_($setString, $unsetString, $lineSeparator);
399
- }
400
- return (string)($setString. $unsetString. "\n");
401
- }
402
-
403
- /**
404
- * @deprecated call {@link #toString(String,String)} only, which uses \n line separator always
405
- */
406
- // @Deprecated
407
- public function toString_($setString, $unsetString, $lineSeparator) {
408
- //$result = new StringBuilder(height * (width + 1));
409
- $result = '';
410
- for ($y = 0; $y < $this->height; $y++) {
411
- for ($x = 0; $x < $this->width; $x++) {
412
- $result .= ($this->get($x, $y) ? $setString : $unsetString);
413
- }
414
- $result .= ($lineSeparator);
415
- }
416
- return (string)$result;
417
- }
418
-
419
- // @Override
420
- public function _clone() {//clone()
421
- return new BitMatrix($this->width, $this->height, $this->rowSize, $this->bits);
422
- }
423
-
424
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/common/BitSource.php DELETED
@@ -1,112 +0,0 @@
1
- <?php
2
- /*
3
- * Copyright 2007 ZXing authors
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
-
18
- namespace Zxing\Common;
19
-
20
- /**
21
- * <p>This provides an easy abstraction to read bits at a time from a sequence of bytes, where the
22
- * number of bits read is not often a multiple of 8.</p>
23
- *
24
- * <p>This class is thread-safe but not reentrant -- unless the caller modifies the bytes array
25
- * it passed in, in which case all bets are off.</p>
26
- *
27
- * @author Sean Owen
28
- */
29
- final class BitSource {
30
-
31
- private $bytes;
32
- private $byteOffset = 0;
33
- private $bitOffset = 0;
34
-
35
- /**
36
- * @param bytes bytes from which this will read bits. Bits will be read from the first byte first.
37
- * Bits are read within a byte from most-significant to least-significant bit.
38
- */
39
- public function __construct($bytes) {
40
- $this->bytes = $bytes;
41
- }
42
-
43
- /**
44
- * @return index of next bit in current byte which would be read by the next call to {@link #readBits(int)}.
45
- */
46
- public function getBitOffset() {
47
- return $this->bitOffset;
48
- }
49
-
50
- /**
51
- * @return index of next byte in input byte array which would be read by the next call to {@link #readBits(int)}.
52
- */
53
- public function getByteOffset() {
54
- return $this->byteOffset;
55
- }
56
-
57
- /**
58
- * @param numBits number of bits to read
59
- * @return int representing the bits read. The bits will appear as the least-significant
60
- * bits of the int
61
- * @throws IllegalArgumentException if numBits isn't in [1,32] or more than is available
62
- */
63
- public function readBits($numBits) {
64
- if ($numBits < 1 || $numBits > 32 || $numBits > $this->available()) {
65
- throw new \InvalidArgumentException(strval($numBits));
66
- }
67
-
68
- $result = 0;
69
-
70
- // First, read remainder from current byte
71
- if ($this->bitOffset > 0) {
72
- $bitsLeft = 8 - $this->bitOffset;
73
- $toRead = $numBits < $bitsLeft ? $numBits : $bitsLeft;
74
- $bitsToNotRead = $bitsLeft - $toRead;
75
- $mask = (0xFF >> (8 - $toRead)) << $bitsToNotRead;
76
- $result = ($this->bytes[$this->byteOffset] & $mask) >> $bitsToNotRead;
77
- $numBits -= $toRead;
78
- $this->bitOffset += $toRead;
79
- if ($this->bitOffset == 8) {
80
- $this->bitOffset = 0;
81
- $this->byteOffset++;
82
- }
83
- }
84
-
85
- // Next read whole bytes
86
- if ($numBits > 0) {
87
- while ($numBits >= 8) {
88
- $result = ($result << 8) | ($this->bytes[$this->byteOffset] & 0xFF);
89
- $this->byteOffset++;
90
- $numBits -= 8;
91
- }
92
-
93
- // Finally read a partial byte
94
- if ($numBits > 0) {
95
- $bitsToNotRead = 8 - $numBits;
96
- $mask = (0xFF >> $bitsToNotRead) << $bitsToNotRead;
97
- $result = ($result << $numBits) | (($this->bytes[$this->byteOffset] & $mask) >> $bitsToNotRead);
98
- $this->bitOffset += $numBits;
99
- }
100
- }
101
-
102
- return $result;
103
- }
104
-
105
- /**
106
- * @return number of bits that can be read successfully
107
- */
108
- public function available() {
109
- return 8 * (count($this->bytes) - $this->byteOffset) - $this->bitOffset;
110
- }
111
-
112
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/common/CharacterSetEci.php DELETED
@@ -1,154 +0,0 @@
1
- <?php
2
-
3
-
4
- namespace Zxing\Common;
5
- use Zxing\Common\AbstractEnum;
6
- /**
7
- * Encapsulates a Character Set ECI, according to "Extended Channel
8
- * Interpretations" 5.3.1.1 of ISO 18004.
9
- */
10
- final class CharacterSetECI
11
- {
12
- private static $name = null;
13
- /**#@+
14
- * Character set constants.
15
- */
16
- const CP437 = 0;
17
- const ISO8859_1 = 1;
18
- const ISO8859_2 = 4;
19
- const ISO8859_3 = 5;
20
- const ISO8859_4 = 6;
21
- const ISO8859_5 = 7;
22
- const ISO8859_6 = 8;
23
- const ISO8859_7 = 9;
24
- const ISO8859_8 = 10;
25
- const ISO8859_9 = 11;
26
- const ISO8859_10 = 12;
27
- const ISO8859_11 = 13;
28
- const ISO8859_12 = 14;
29
- const ISO8859_13 = 15;
30
- const ISO8859_14 = 16;
31
- const ISO8859_15 = 17;
32
- const ISO8859_16 = 18;
33
- const SJIS = 20;
34
- const CP1250 = 21;
35
- const CP1251 = 22;
36
- const CP1252 = 23;
37
- const CP1256 = 24;
38
- const UNICODE_BIG_UNMARKED = 25;
39
- const UTF8 = 26;
40
- const ASCII = 27;
41
- const BIG5 = 28;
42
- const GB18030 = 29;
43
- const EUC_KR = 30;
44
- /**#@-*/
45
- /**
46
- * Map between character names and their ECI values.
47
- *
48
- * @var array
49
- */
50
- protected static $nameToEci = array(
51
- 'ISO-8859-1' => self::ISO8859_1,
52
- 'ISO-8859-2' => self::ISO8859_2,
53
- 'ISO-8859-3' => self::ISO8859_3,
54
- 'ISO-8859-4' => self::ISO8859_4,
55
- 'ISO-8859-5' => self::ISO8859_5,
56
- 'ISO-8859-6' => self::ISO8859_6,
57
- 'ISO-8859-7' => self::ISO8859_7,
58
- 'ISO-8859-8' => self::ISO8859_8,
59
- 'ISO-8859-9' => self::ISO8859_9,
60
- 'ISO-8859-10' => self::ISO8859_10,
61
- 'ISO-8859-11' => self::ISO8859_11,
62
- 'ISO-8859-12' => self::ISO8859_12,
63
- 'ISO-8859-13' => self::ISO8859_13,
64
- 'ISO-8859-14' => self::ISO8859_14,
65
- 'ISO-8859-15' => self::ISO8859_15,
66
- 'ISO-8859-16' => self::ISO8859_16,
67
- 'SHIFT-JIS' => self::SJIS,
68
- 'WINDOWS-1250' => self::CP1250,
69
- 'WINDOWS-1251' => self::CP1251,
70
- 'WINDOWS-1252' => self::CP1252,
71
- 'WINDOWS-1256' => self::CP1256,
72
- 'UTF-16BE' => self::UNICODE_BIG_UNMARKED,
73
- 'UTF-8' => self::UTF8,
74
- 'ASCII' => self::ASCII,
75
- 'GBK' => self::GB18030,
76
- 'EUC-KR' => self::EUC_KR,
77
- );
78
- /**
79
- * Additional possible values for character sets.
80
- *
81
- * @var array
82
- */
83
- protected static $additionalValues = array(
84
- self::CP437 => 2,
85
- self::ASCII => 170,
86
- );
87
- /**
88
- * Gets character set ECI by value.
89
- *
90
- * @param string $name
91
- * @return CharacterSetEci|null
92
- */
93
- public static function getCharacterSetECIByValue($value)
94
- {
95
- if ($value < 0 || $value >= 900) {
96
- throw new Exception\InvalidArgumentException('Value must be between 0 and 900');
97
- }
98
- if (false !== ($key = array_search($value, self::$additionalValues))) {
99
- $value = $key;
100
- }
101
- array_search($value, self::$nameToEci);
102
- try
103
- {
104
- self::setName($value);
105
- return new self($value);
106
- } catch (Exception\UnexpectedValueException $e) {
107
- return null;
108
- }
109
- }
110
-
111
- private static function setName($value)
112
- {
113
- foreach (self::$nameToEci as $name => $key) {
114
- if($key == $value)
115
- {
116
- self::$name = $name;
117
- return true;
118
- }
119
- }
120
- if(self::$name == null)
121
- {
122
- foreach (self::$additionalValues as $name => $key) {
123
- if($key == $value)
124
- {
125
- self::$name = $name;
126
- return true;
127
- }
128
- }
129
- }
130
- }
131
- /**
132
- * Gets character set ECI name.
133
- *
134
- * @return character set ECI name|null
135
- */
136
- public static function name()
137
- {
138
- return self::$name;
139
- }
140
- /**
141
- * Gets character set ECI by name.
142
- *
143
- * @param string $name
144
- * @return CharacterSetEci|null
145
- */
146
- public static function getCharacterSetECIByName($name)
147
- {
148
- $name = strtoupper($name);
149
- if (isset(self::$nameToEci[$name])) {
150
- return new self(self::$nameToEci[$name]);
151
- }
152
- return null;
153
- }
154
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/common/DecoderResult.php DELETED
@@ -1,109 +0,0 @@
1
- <?php
2
- /*
3
- * Copyright 2007 ZXing authors
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
-
18
- namespace Zxing\Common;
19
-
20
-
21
-
22
- /**
23
- * <p>Encapsulates the result of decoding a matrix of bits. This typically
24
- * applies to 2D barcode formats. For now it contains the raw bytes obtained,
25
- * as well as a String interpretation of those bytes, if applicable.</p>
26
- *
27
- * @author Sean Owen
28
- */
29
- final class DecoderResult {
30
-
31
- private $rawBytes;
32
- private $text;
33
- private $byteSegments;
34
- private $ecLevel;
35
- private $errorsCorrected;
36
- private $erasures;
37
- private $other;
38
- private $structuredAppendParity;
39
- private $structuredAppendSequenceNumber;
40
-
41
-
42
-
43
- public function __construct($rawBytes,
44
- $text,
45
- $byteSegments,
46
- $ecLevel,
47
- $saSequence = -1,
48
- $saParity = -1) {
49
- $this->rawBytes = $rawBytes;
50
- $this->text = $text;
51
- $this->byteSegments = $byteSegments;
52
- $this->ecLevel = $ecLevel;
53
- $this->structuredAppendParity = $saParity;
54
- $this->structuredAppendSequenceNumber = $saSequence;
55
- }
56
-
57
- public function getRawBytes() {
58
- return $this->rawBytes;
59
- }
60
-
61
- public function getText() {
62
- return $this->text;
63
- }
64
-
65
- public function getByteSegments() {
66
- return $this->byteSegments;
67
- }
68
-
69
- public function getECLevel() {
70
- return $this->ecLevel;
71
- }
72
-
73
- public function getErrorsCorrected() {
74
- return $this->errorsCorrected;
75
- }
76
-
77
- public function setErrorsCorrected($errorsCorrected) {
78
- $this->errorsCorrected = $errorsCorrected;
79
- }
80
-
81
- public function getErasures() {
82
- return $this->erasures;
83
- }
84
-
85
- public function setErasures($erasures) {
86
- $this->erasures = $erasures;
87
- }
88
-
89
- public function getOther() {
90
- return $this->other;
91
- }
92
-
93
- public function setOther($other) {
94
- $this->other = $other;
95
- }
96
-
97
- public function hasStructuredAppend() {
98
- return $this->structuredAppendParity >= 0 && $this->structuredAppendSequenceNumber >= 0;
99
- }
100
-
101
- public function getStructuredAppendParity() {
102
- return $this->structuredAppendParity;
103
- }
104
-
105
- public function getStructuredAppendSequenceNumber() {
106
- return $this->structuredAppendSequenceNumber;
107
- }
108
-
109
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/common/DefaultGridSampler.php DELETED
@@ -1,89 +0,0 @@
1
- <?php
2
- /*
3
- * Copyright 2007 ZXing authors
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
-
18
- namespace Zxing\Common;
19
-
20
- use Zxing\NotFoundException;
21
-
22
- /**
23
- * @author Sean Owen
24
- */
25
- final class DefaultGridSampler extends GridSampler {
26
-
27
- //@Override
28
- public function sampleGrid($image,
29
- $dimensionX,
30
- $dimensionY,
31
- $p1ToX, $p1ToY,
32
- $p2ToX, $p2ToY,
33
- $p3ToX, $p3ToY,
34
- $p4ToX, $p4ToY,
35
- $p1FromX, $p1FromY,
36
- $p2FromX, $p2FromY,
37
- $p3FromX, $p3FromY,
38
- $p4FromX, $p4FromY) {
39
-
40
- $transform = PerspectiveTransform::quadrilateralToQuadrilateral(
41
- $p1ToX, $p1ToY, $p2ToX, $p2ToY, $p3ToX, $p3ToY, $p4ToX, $p4ToY,
42
- $p1FromX, $p1FromY, $p2FromX, $p2FromY, $p3FromX, $p3FromY, $p4FromX, $p4FromY);
43
-
44
- return $this->sampleGrid_($image, $dimensionX, $dimensionY, $transform);
45
- }
46
-
47
- //@Override
48
- public function sampleGrid_($image,
49
- $dimensionX,
50
- $dimensionY,
51
- $transform) {
52
- if ($dimensionX <= 0 || $dimensionY <= 0) {
53
- throw NotFoundException::getNotFoundInstance();
54
- }
55
- $bits = new BitMatrix($dimensionX, $dimensionY);
56
- $points = fill_array(0,2 * $dimensionX,0.0);
57
- for ($y = 0; $y < $dimensionY; $y++) {
58
- $max = count($points);
59
- $iValue = (float) $y + 0.5;
60
- for ($x = 0; $x < $max; $x += 2) {
61
- $points[$x] = (float) ($x / 2) + 0.5;
62
- $points[$x + 1] = $iValue;
63
- }
64
- $transform->transformPoints($points);
65
- // Quick check to see if points transformed to something inside the image;
66
- // sufficient to check the endpoints
67
- $this->checkAndNudgePoints($image, $points);
68
- try {
69
- for ($x = 0; $x < $max; $x += 2) {
70
- if ($image->get((int) $points[$x], (int) $points[$x + 1])) {
71
- // Black(-ish) pixel
72
- $bits->set($x / 2, $y);
73
- }
74
- }
75
- } catch (\Exception $aioobe) {//ArrayIndexOutOfBoundsException
76
- // This feels wrong, but, sometimes if the finder patterns are misidentified, the resulting
77
- // transform gets "twisted" such that it maps a straight line of points to a set of points
78
- // whose endpoints are in bounds, but others are not. There is probably some mathematical
79
- // way to detect this about the transformation that I don't know yet.
80
- // This results in an ugly runtime exception despite our clever checks above -- can't have
81
- // that. We could check each point's coordinates but that feels duplicative. We settle for
82
- // catching and wrapping ArrayIndexOutOfBoundsException.
83
- throw NotFoundException::getNotFoundInstance();
84
- }
85
- }
86
- return $bits;
87
- }
88
-
89
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/common/DetectorResult.php DELETED
@@ -1,47 +0,0 @@
1
- <?php
2
- /*
3
- * Copyright 2007 ZXing authors
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
-
18
- namespace Zxing\Common;
19
-
20
- use Zxing\ResultPoint;
21
-
22
- /**
23
- * <p>Encapsulates the result of detecting a barcode in an image. This includes the raw
24
- * matrix of black/white pixels corresponding to the barcode, and possibly points of interest
25
- * in the image, like the location of finder patterns or corners of the barcode in the image.</p>
26
- *
27
- * @author Sean Owen
28
- */
29
- class DetectorResult {
30
-
31
- private $bits;
32
- private $points;
33
-
34
- public function __construct($bits, $points) {
35
- $this->bits = $bits;
36
- $this->points = $points;
37
- }
38
-
39
- public final function getBits() {
40
- return $this->bits;
41
- }
42
-
43
- public final function getPoints() {
44
- return $this->points;
45
- }
46
-
47
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/common/GlobalHistogramBinarizer.php DELETED
@@ -1,206 +0,0 @@
1
- <?php
2
- /*
3
- * Copyright 2009 ZXing authors
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
-
18
- namespace Zxing\Common;
19
-
20
- use Zxing\Binarizer;
21
- use Zxing\LuminanceSource;
22
- use Zxing\NotFoundException;
23
-
24
- /**
25
- * This Binarizer implementation uses the old ZXing global histogram approach. It is suitable
26
- * for low-end mobile devices which don't have enough CPU or memory to use a local thresholding
27
- * algorithm. However, because it picks a global black point, it cannot handle difficult shadows
28
- * and gradients.
29
- *
30
- * Faster mobile devices and all desktop applications should probably use HybridBinarizer instead.
31
- *
32
- * @author dswitkin@google.com (Daniel Switkin)
33
- * @author Sean Owen
34
- */
35
-
36
- class GlobalHistogramBinarizer extends Binarizer {
37
-
38
- private static $LUMINANCE_BITS = 5;
39
- private static $LUMINANCE_SHIFT=3;
40
- private static $LUMINANCE_BUCKETS = 32;
41
-
42
- private static $EMPTY = array();
43
-
44
- private $luminances=array();
45
- private $buckets = array();
46
- private $source = array();
47
-
48
- public function __construct($source) {
49
-
50
- self::$LUMINANCE_SHIFT = 8 - self::$LUMINANCE_BITS;
51
- self::$LUMINANCE_BUCKETS = 1 << self::$LUMINANCE_BITS;
52
-
53
- parent::__construct($source);
54
-
55
- $this->luminances = self::$EMPTY;
56
- $this->buckets = fill_array(0, self::$LUMINANCE_BUCKETS,0);
57
- $this->source = $source;
58
- }
59
-
60
- // Applies simple sharpening to the row data to improve performance of the 1D Readers.
61
- //@Override
62
- public function getBlackRow($y, $row=null) {
63
- $this->source = $this->getLuminanceSource();
64
- $width = $this->source->getWidth();
65
- if ($row == null || $row->getSize() < $width) {
66
- $row = new BitArray($width);
67
- } else {
68
- $row->clear();
69
- }
70
-
71
- $this->initArrays($width);
72
- $localLuminances = $this->source->getRow($y, $this->luminances);
73
- $localBuckets = $this->buckets;
74
- for ($x = 0; $x < $width; $x++) {
75
- $pixel = $localLuminances[$x] & 0xff;
76
- $localBuckets[$pixel >> self::$LUMINANCE_SHIFT]++;
77
- }
78
- $blackPoint = $this->estimateBlackPoint($localBuckets);
79
-
80
- $left = $localLuminances[0] & 0xff;
81
- $center = $localLuminances[1] & 0xff;
82
- for ($x = 1; $x < $width - 1; $x++) {
83
- $right = $localLuminances[$x + 1] & 0xff;
84
- // A simple -1 4 -1 box filter with a weight of 2.
85
- $luminance = (($center * 4) - $left - $right) / 2;
86
- if ($luminance < $blackPoint) {
87
- $row->set($x);
88
- }
89
- $left = $center;
90
- $center = $right;
91
- }
92
- return $row;
93
- }
94
-
95
- // Does not sharpen the data, as this call is intended to only be used by 2D Readers.
96
- //@Override
97
- public function getBlackMatrix(){
98
- $source = $this->getLuminanceSource();
99
- $width = $source->getWidth();
100
- $height = $source->getHeight();
101
- $matrix = new BitMatrix($width, $height);
102
-
103
- // Quickly calculates the histogram by sampling four rows from the image. This proved to be
104
- // more robust on the blackbox tests than sampling a diagonal as we used to do.
105
- $this->initArrays($width);
106
- $localBuckets = $this->buckets;
107
- for ($y = 1; $y < 5; $y++) {
108
- $row = intval($height * $y / 5);
109
- $localLuminances = $source->getRow($row, $this->luminances);
110
- $right = intval(($width * 4) / 5);
111
- for ($x = intval($width / 5); $x < $right; $x++) {
112
- $pixel = intval32bits($localLuminances[intval($x)] & 0xff);
113
- $localBuckets[intval32bits($pixel >> self::$LUMINANCE_SHIFT)]++;
114
- }
115
- }
116
- $blackPoint = $this->estimateBlackPoint($localBuckets);
117
-
118
- // We delay reading the entire image luminance until the black point estimation succeeds.
119
- // Although we end up reading four rows twice, it is consistent with our motto of
120
- // "fail quickly" which is necessary for continuous scanning.
121
- $localLuminances = $source->getMatrix();
122
- for ($y = 0; $y < $height; $y++) {
123
- $offset = $y * $width;
124
- for ($x = 0; $x< $width; $x++) {
125
- $pixel = intval($localLuminances[$offset + $x] & 0xff);
126
- if ($pixel < $blackPoint) {
127
- $matrix->set($x, $y);
128
- }
129
- }
130
- }
131
-
132
- return $matrix;
133
- }
134
-
135
- //@Override
136
- public function createBinarizer($source) {
137
- return new GlobalHistogramBinarizer($source);
138
- }
139
-
140
- private function initArrays($luminanceSize) {
141
- if (count($this->luminances) < $luminanceSize) {
142
- $this->luminances = array();
143
- }
144
- for ($x = 0; $x < self::$LUMINANCE_BUCKETS; $x++) {
145
- $this->buckets[$x] = 0;
146
- }
147
- }
148
-
149
- private static function estimateBlackPoint($buckets){
150
- // Find the tallest peak in the histogram.
151
- $numBuckets = count($buckets);
152
- $maxBucketCount = 0;
153
- $firstPeak = 0;
154
- $firstPeakSize = 0;
155
- for ($x = 0; $x < $numBuckets; $x++) {
156
- if ($buckets[$x] > $firstPeakSize) {
157
- $firstPeak = $x;
158
- $firstPeakSize = $buckets[$x];
159
- }
160
- if ($buckets[$x] > $maxBucketCount) {
161
- $maxBucketCount = $buckets[$x];
162
- }
163
- }
164
-
165
- // Find the second-tallest peak which is somewhat far from the tallest peak.
166
- $secondPeak = 0;
167
- $secondPeakScore = 0;
168
- for ($x = 0; $x < $numBuckets; $x++) {
169
- $distanceToBiggest = $x - $firstPeak;
170
- // Encourage more distant second peaks by multiplying by square of distance.
171
- $score = $buckets[$x] * $distanceToBiggest * $distanceToBiggest;
172
- if ($score > $secondPeakScore) {
173
- $secondPeak = $x;
174
- $secondPeakScore = $score;
175
- }
176
- }
177
-
178
- // Make sure firstPeak corresponds to the black peak.
179
- if ($firstPeak > $secondPeak) {
180
- $temp = $firstPeak;
181
- $firstPeak = $secondPeak;
182
- $secondPeak = $temp;
183
- }
184
-
185
- // If there is too little contrast in the image to pick a meaningful black point, throw rather
186
- // than waste time trying to decode the image, and risk false positives.
187
- if ($secondPeak - $firstPeak <= $numBuckets / 16) {
188
- throw NotFoundException::getNotFoundInstance();
189
- }
190
-
191
- // Find a valley between them that is low and closer to the white peak.
192
- $bestValley = $secondPeak - 1;
193
- $bestValleyScore = -1;
194
- for ($x = $secondPeak - 1; $x > $firstPeak; $x--) {
195
- $fromFirst = $x - $firstPeak;
196
- $score = $fromFirst * $fromFirst * ($secondPeak - $x) * ($maxBucketCount - $buckets[$x]);
197
- if ($score > $bestValleyScore) {
198
- $bestValley = $x;
199
- $bestValleyScore = $score;
200
- }
201
- }
202
-
203
- return intval32bits($bestValley << self::$LUMINANCE_SHIFT);
204
- }
205
-
206
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/common/GridSampler.php DELETED
@@ -1,177 +0,0 @@
1
- <?php
2
- /*
3
- * Copyright 2007 ZXing authors
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
-
18
- namespace Zxing\Common;
19
-
20
- use Zxing\NotFoundException;
21
-
22
- /**
23
- * Implementations of this class can, given locations of finder patterns for a QR code in an
24
- * image, sample the right points in the image to reconstruct the QR code, accounting for
25
- * perspective distortion. It is abstracted since it is relatively expensive and should be allowed
26
- * to take advantage of platform-specific optimized implementations, like Sun's Java Advanced
27
- * Imaging library, but which may not be available in other environments such as J2ME, and vice
28
- * versa.
29
- *
30
- * The implementation used can be controlled by calling {@link #setGridSampler(GridSampler)}
31
- * with an instance of a class which implements this interface.
32
- *
33
- * @author Sean Owen
34
- */
35
- abstract class GridSampler {
36
-
37
- private static $gridSampler;
38
-
39
- /**
40
- * Sets the implementation of GridSampler used by the library. One global
41
- * instance is stored, which may sound problematic. But, the implementation provided
42
- * ought to be appropriate for the entire platform, and all uses of this library
43
- * in the whole lifetime of the JVM. For instance, an Android activity can swap in
44
- * an implementation that takes advantage of native platform libraries.
45
- *
46
- * @param newGridSampler The platform-specific object to install.
47
- */
48
- public static function setGridSampler($newGridSampler) {
49
- self::$gridSampler = $newGridSampler;
50
- }
51
-
52
- /**
53
- * @return the current implementation of GridSampler
54
- */
55
- public static function getInstance() {
56
- if(!self::$gridSampler){
57
- self::$gridSampler = new DefaultGridSampler();
58
- }
59
- return self::$gridSampler;
60
- }
61
-
62
- /**
63
- * Samples an image for a rectangular matrix of bits of the given dimension. The sampling
64
- * transformation is determined by the coordinates of 4 points, in the original and transformed
65
- * image space.
66
- *
67
- * @param image image to sample
68
- * @param dimensionX width of {@link BitMatrix} to sample from image
69
- * @param dimensionY height of {@link BitMatrix} to sample from image
70
- * @param p1ToX point 1 preimage X
71
- * @param p1ToY point 1 preimage Y
72
- * @param p2ToX point 2 preimage X
73
- * @param p2ToY point 2 preimage Y
74
- * @param p3ToX point 3 preimage X
75
- * @param p3ToY point 3 preimage Y
76
- * @param p4ToX point 4 preimage X
77
- * @param p4ToY point 4 preimage Y
78
- * @param p1FromX point 1 image X
79
- * @param p1FromY point 1 image Y
80
- * @param p2FromX point 2 image X
81
- * @param p2FromY point 2 image Y
82
- * @param p3FromX point 3 image X
83
- * @param p3FromY point 3 image Y
84
- * @param p4FromX point 4 image X
85
- * @param p4FromY point 4 image Y
86
- * @return {@link BitMatrix} representing a grid of points sampled from the image within a region
87
- * defined by the "from" parameters
88
- * @throws NotFoundException if image can't be sampled, for example, if the transformation defined
89
- * by the given points is invalid or results in sampling outside the image boundaries
90
- */
91
- public abstract function sampleGrid($image,
92
- $dimensionX,
93
- $dimensionY,
94
- $p1ToX, $p1ToY,
95
- $p2ToX, $p2ToY,
96
- $p3ToX, $p3ToY,
97
- $p4ToX, $p4ToY,
98
- $p1FromX, $p1FromY,
99
- $p2FromX, $p2FromY,
100
- $p3FromX, $p3FromY,
101
- $p4FromX, $p4FromY);
102
-
103
- public abstract function sampleGrid_($image,
104
- $dimensionX,
105
- $dimensionY,
106
- $transform);
107
-
108
- /**
109
- * <p>Checks a set of points that have been transformed to sample points on an image against
110
- * the image's dimensions to see if the point are even within the image.</p>
111
- *
112
- * <p>This method will actually "nudge" the endpoints back onto the image if they are found to be
113
- * barely (less than 1 pixel) off the image. This accounts for imperfect detection of finder
114
- * patterns in an image where the QR Code runs all the way to the image border.</p>
115
- *
116
- * <p>For efficiency, the method will check points from either end of the line until one is found
117
- * to be within the image. Because the set of points are assumed to be linear, this is valid.</p>
118
- *
119
- * @param image image into which the points should map
120
- * @param points actual points in x1,y1,...,xn,yn form
121
- * @throws NotFoundException if an endpoint is lies outside the image boundaries
122
- */
123
- protected static function checkAndNudgePoints($image,
124
- $points) {
125
- $width = $image->getWidth();
126
- $height = $image->getHeight();
127
- // Check and nudge points from start until we see some that are OK:
128
- $nudged = true;
129
- for ($offset = 0; $offset < count($points) && $nudged; $offset += 2) {
130
- $x = (int) $points[$offset];
131
- $y = (int) $points[$offset + 1];
132
- if ($x < -1 || $x > $width || $y < -1 || $y > $height) {
133
- throw NotFoundException::getNotFoundInstance();
134
- }
135
- $nudged = false;
136
- if ($x == -1) {
137
- $points[$offset] = 0.0;
138
- $nudged = true;
139
- } else if ($x == $width) {
140
- $points[$offset] = $width - 1;
141
- $nudged = true;
142
- }
143
- if ($y == -1) {
144
- $points[$offset + 1] = 0.0;
145
- $nudged = true;
146
- } else if ($y == $height) {
147
- $points[$offset + 1] = $height - 1;
148
- $nudged = true;
149
- }
150
- }
151
- // Check and nudge points from end:
152
- $nudged = true;
153
- for ($offset = count($points) - 2; $offset >= 0 && $nudged; $offset -= 2) {
154
- $x = (int) $points[$offset];
155
- $y = (int) $points[$offset + 1];
156
- if ($x < -1 || $x > $width || $y < -1 || $y > $height) {
157
- throw NotFoundException::getNotFoundInstance();
158
- }
159
- $nudged = false;
160
- if ($x == -1) {
161
- $points[$offset] = 0.0;
162
- $nudged = true;
163
- } else if ($x == $width) {
164
- $points[$offset] = $width - 1;
165
- $nudged = true;
166
- }
167
- if ($y == -1) {
168
- $points[$offset + 1] = 0.0;
169
- $nudged = true;
170
- } else if ($y == $height) {
171
- $points[$offset + 1] = $height - 1;
172
- $nudged = true;
173
- }
174
- }
175
- }
176
-
177
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/common/HybridBinarizer.php DELETED
@@ -1,259 +0,0 @@
1
- <?php
2
- /*
3
- * Copyright 2009 ZXing authors
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
-
18
- namespace Zxing\Common;
19
-
20
- use Zxing\Binarizer;
21
- use Zxing\LuminanceSource;
22
- use Zxing\NotFoundException;
23
-
24
- /**
25
- * This class implements a local thresholding algorithm, which while slower than the
26
- * GlobalHistogramBinarizer, is fairly efficient for what it does. It is designed for
27
- * high frequency images of barcodes with black data on white backgrounds. For this application,
28
- * it does a much better job than a global blackpoint with severe shadows and gradients.
29
- * However it tends to produce artifacts on lower frequency images and is therefore not
30
- * a good general purpose binarizer for uses outside ZXing.
31
- *
32
- * This class extends GlobalHistogramBinarizer, using the older histogram approach for 1D readers,
33
- * and the newer local approach for 2D readers. 1D decoding using a per-row histogram is already
34
- * inherently local, and only fails for horizontal gradients. We can revisit that problem later,
35
- * but for now it was not a win to use local blocks for 1D.
36
- *
37
- * This Binarizer is the default for the unit tests and the recommended class for library users.
38
- *
39
- * @author dswitkin@google.com (Daniel Switkin)
40
- */
41
- final class HybridBinarizer extends GlobalHistogramBinarizer {
42
-
43
- // This class uses 5x5 blocks to compute local luminance, where each block is 8x8 pixels.
44
- // So this is the smallest dimension in each axis we can accept.
45
- private static $BLOCK_SIZE_POWER = 3;
46
- private static $BLOCK_SIZE = 8; // ...0100...00
47
- private static $BLOCK_SIZE_MASK = 7; // ...0011...11
48
- private static $MINIMUM_DIMENSION = 40;
49
- private static $MIN_DYNAMIC_RANGE=24;
50
-
51
- private $matrix;
52
-
53
- public function __construct($source) {
54
-
55
- parent::__construct($source);
56
- self::$BLOCK_SIZE_POWER = 3;
57
- self::$BLOCK_SIZE = 1 << self::$BLOCK_SIZE_POWER; // ...0100...00
58
- self::$BLOCK_SIZE_MASK = self::$BLOCK_SIZE - 1; // ...0011...11
59
- self::$MINIMUM_DIMENSION = self::$BLOCK_SIZE * 5;
60
- self::$MIN_DYNAMIC_RANGE = 24;
61
-
62
- }
63
-
64
- /**
65
- * Calculates the final BitMatrix once for all requests. This could be called once from the
66
- * constructor instead, but there are some advantages to doing it lazily, such as making
67
- * profiling easier, and not doing heavy lifting when callers don't expect it.
68
- */
69
- //@Override
70
- public function getBlackMatrix(){
71
- if ($this->matrix != null) {
72
- return $this->matrix;
73
- }
74
- $source = $this->getLuminanceSource();
75
- $width = $source->getWidth();
76
- $height = $source->getHeight();
77
- if ($width >= self::$MINIMUM_DIMENSION && $height >= self::$MINIMUM_DIMENSION) {
78
- $luminances = $source->getMatrix();
79
- $subWidth = $width >> self::$BLOCK_SIZE_POWER;
80
- if (($width & self::$BLOCK_SIZE_MASK) != 0) {
81
- $subWidth++;
82
- }
83
- $subHeight = $height >> self::$BLOCK_SIZE_POWER;
84
- if (($height & self::$BLOCK_SIZE_MASK) != 0) {
85
- $subHeight++;
86
- }
87
- $blackPoints = $this->calculateBlackPoints($luminances, $subWidth, $subHeight, $width, $height);
88
-
89
- $newMatrix = new BitMatrix($width, $height);
90
- $this->calculateThresholdForBlock($luminances, $subWidth, $subHeight, $width, $height, $blackPoints, $newMatrix);
91
- $this->matrix = $newMatrix;
92
- } else {
93
- // If the image is too small, fall back to the global histogram approach.
94
- $this->matrix = parent::getBlackMatrix();
95
- }
96
- return $this->matrix;
97
- }
98
-
99
- //@Override
100
- public function createBinarizer($source) {
101
- return new HybridBinarizer($source);
102
- }
103
-
104
- /**
105
- * For each block in the image, calculate the average black point using a 5x5 grid
106
- * of the blocks around it. Also handles the corner cases (fractional blocks are computed based
107
- * on the last pixels in the row/column which are also used in the previous block).
108
- */
109
- private static function calculateThresholdForBlock($luminances,
110
- $subWidth,
111
- $subHeight,
112
- $width,
113
- $height,
114
- $blackPoints,
115
- $matrix) {
116
- for ($y = 0; $y < $subHeight; $y++) {
117
- $yoffset = intval32bits($y << self::$BLOCK_SIZE_POWER);
118
- $maxYOffset = $height - self::$BLOCK_SIZE;
119
- if ($yoffset > $maxYOffset) {
120
- $yoffset = $maxYOffset;
121
- }
122
- for ($x = 0; $x < $subWidth; $x++) {
123
- $xoffset = intval32bits($x << self::$BLOCK_SIZE_POWER);
124
- $maxXOffset = $width - self::$BLOCK_SIZE;
125
- if ($xoffset > $maxXOffset) {
126
- $xoffset = $maxXOffset;
127
- }
128
- $left = self::cap($x, 2, $subWidth - 3);
129
- $top = self::cap($y, 2, $subHeight - 3);
130
- $sum = 0;
131
- for ($z = -2; $z <= 2; $z++) {
132
- $blackRow = $blackPoints[$top + $z];
133
- $sum += $blackRow[$left - 2] + $blackRow[$left - 1] + $blackRow[$left] + $blackRow[$left + 1] + $blackRow[$left + 2];
134
- }
135
- $average = intval($sum / 25);
136
-
137
- self::thresholdBlock($luminances, $xoffset, $yoffset, $average, $width, $matrix);
138
- }
139
- }
140
- }
141
-
142
- private static function cap($value, $min, $max) {
143
- if($value<$min){
144
- return $min;
145
- }elseif($value>$max){
146
- return $max;
147
- }else{
148
- return $value;
149
- }
150
-
151
-
152
-
153
- }
154
-
155
- /**
156
- * Applies a single threshold to a block of pixels.
157
- */
158
- private static function thresholdBlock($luminances,
159
- $xoffset,
160
- $yoffset,
161
- $threshold,
162
- $stride,
163
- $matrix) {
164
-
165
- for ($y = 0, $offset = $yoffset * $stride + $xoffset; $y < self::$BLOCK_SIZE; $y++, $offset += $stride) {
166
- for ($x = 0; $x < self::$BLOCK_SIZE; $x++) {
167
- // Comparison needs to be <= so that black == 0 pixels are black even if the threshold is 0.
168
- if (($luminances[$offset + $x] & 0xFF) <= $threshold) {
169
- $matrix->set($xoffset + $x, $yoffset + $y);
170
- }
171
- }
172
- }
173
- }
174
-
175
- /**
176
- * Calculates a single black point for each block of pixels and saves it away.
177
- * See the following thread for a discussion of this algorithm:
178
- * http://groups.google.com/group/zxing/browse_thread/thread/d06efa2c35a7ddc0
179
- */
180
- private static function calculateBlackPoints($luminances,
181
- $subWidth,
182
- $subHeight,
183
- $width,
184
- $height) {
185
- $blackPoints = fill_array(0,$subHeight,0);
186
- foreach($blackPoints as $key=>$point){
187
- $blackPoints[$key] = fill_array(0,$subWidth,0);
188
- }
189
- for ($y = 0; $y < $subHeight; $y++) {
190
- $yoffset = intval32bits($y << self::$BLOCK_SIZE_POWER);
191
- $maxYOffset = $height - self::$BLOCK_SIZE;
192
- if ($yoffset > $maxYOffset) {
193
- $yoffset = $maxYOffset;
194
- }
195
- for ($x = 0; $x < $subWidth; $x++) {
196
- $xoffset = intval32bits($x << self::$BLOCK_SIZE_POWER);
197
- $maxXOffset = $width - self::$BLOCK_SIZE;
198
- if ($xoffset > $maxXOffset) {
199
- $xoffset = $maxXOffset;
200
- }
201
- $sum = 0;
202
- $min = 0xFF;
203
- $max = 0;
204
- for ($yy = 0, $offset = $yoffset * $width + $xoffset; $yy < self::$BLOCK_SIZE; $yy++, $offset += $width) {
205
- for ($xx = 0; $xx < self::$BLOCK_SIZE; $xx++) {
206
- $pixel = intval32bits(intval($luminances[intval($offset +$xx)]) & 0xFF);
207
- $sum += $pixel;
208
- // still looking for good contrast
209
- if ($pixel < $min) {
210
- $min = $pixel;
211
- }
212
- if ($pixel > $max) {
213
- $max = $pixel;
214
- }
215
- }
216
- // short-circuit min/max tests once dynamic range is met
217
- if ($max - $min > self::$MIN_DYNAMIC_RANGE) {
218
- // finish the rest of the rows quickly
219
- for ($yy++, $offset += $width; $yy < self::$BLOCK_SIZE; $yy++, $offset += $width) {
220
- for ($xx = 0; $xx < self::$BLOCK_SIZE; $xx++) {
221
- $sum += intval32bits($luminances[$offset +$xx] & 0xFF);
222
- }
223
- }
224
- }
225
- }
226
-
227
- // The default estimate is the average of the values in the block.
228
- $average = intval32bits($sum >> (self::$BLOCK_SIZE_POWER * 2));
229
- if ($max - $min <= self::$MIN_DYNAMIC_RANGE) {
230
- // If variation within the block is low, assume this is a block with only light or only
231
- // dark pixels. In that case we do not want to use the average, as it would divide this
232
- // low contrast area into black and white pixels, essentially creating data out of noise.
233
- //
234
- // The default assumption is that the block is light/background. Since no estimate for
235
- // the level of dark pixels exists locally, use half the min for the block.
236
- $average = intval($min / 2);
237
-
238
- if ($y > 0 && $x > 0) {
239
- // Correct the "white background" assumption for blocks that have neighbors by comparing
240
- // the pixels in this block to the previously calculated black points. This is based on
241
- // the fact that dark barcode symbology is always surrounded by some amount of light
242
- // background for which reasonable black point estimates were made. The bp estimated at
243
- // the boundaries is used for the interior.
244
-
245
- // The (min < bp) is arbitrary but works better than other heuristics that were tried.
246
- $averageNeighborBlackPoint =
247
- intval(($blackPoints[$y - 1][$x] + (2 * $blackPoints[$y][$x - 1]) + $blackPoints[$y - 1][$x - 1]) / 4);
248
- if ($min < $averageNeighborBlackPoint) {
249
- $average = $averageNeighborBlackPoint;
250
- }
251
- }
252
- }
253
- $blackPoints[$y][$x] = intval($average);
254
- }
255
- }
256
- return $blackPoints;
257
- }
258
-
259
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/common/PerspectiveTransform.php DELETED
@@ -1,161 +0,0 @@
1
- <?php
2
- /*
3
- * Copyright 2007 ZXing authors
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
-
18
- namespace Zxing\Common;
19
-
20
- /**
21
- * <p>This class implements a perspective transform in two dimensions. Given four source and four
22
- * destination points, it will compute the transformation implied between them. The code is based
23
- * directly upon section 3.4.2 of George Wolberg's "Digital Image Warping"; see pages 54-56.</p>
24
- *
25
- * @author Sean Owen
26
- */
27
- final class PerspectiveTransform {
28
-
29
- private $a11;
30
- private $a12;
31
- private $a13;
32
- private $a21;
33
- private $a22;
34
- private $a23;
35
- private $a31;
36
- private $a32;
37
- private $a33;
38
-
39
- private function __construct($a11, $a21, $a31,
40
- $a12, $a22, $a32,
41
- $a13, $a23, $a33) {
42
- $this->a11 = $a11;
43
- $this->a12 = $a12;
44
- $this->a13 = $a13;
45
- $this->a21 = $a21;
46
- $this->a22 = $a22;
47
- $this->a23 = $a23;
48
- $this->a31 = $a31;
49
- $this->a32 = $a32;
50
- $this->a33 = $a33;
51
- }
52
-
53
- public static function quadrilateralToQuadrilateral($x0, $y0,
54
- $x1, $y1,
55
- $x2, $y2,
56
- $x3, $y3,
57
- $x0p, $y0p,
58
- $x1p, $y1p,
59
- $x2p, $y2p,
60
- $x3p, $y3p) {
61
-
62
- $qToS = self::quadrilateralToSquare($x0, $y0, $x1, $y1, $x2, $y2, $x3, $y3);
63
- $sToQ = self::squareToQuadrilateral($x0p, $y0p, $x1p, $y1p, $x2p, $y2p, $x3p, $y3p);
64
- return $sToQ->times($qToS);
65
- }
66
-
67
- public function transformPoints(&$points,&$yValues=0) {
68
- if($yValues) {
69
- $this->transformPoints_($points,$yValues);
70
- return;
71
- }
72
- $max =count($points);
73
- $a11 = $this->a11;
74
- $a12 = $this->a12;
75
- $a13 = $this->a13;
76
- $a21 = $this->a21;
77
- $a22 = $this->a22;
78
- $a23 = $this->a23;
79
- $a31 = $this->a31;
80
- $a32 = $this->a32;
81
- $a33 = $this->a33;
82
- for ($i = 0; $i < $max; $i += 2) {
83
- $x = $points[$i];
84
- $y = $points[$i + 1];
85
- $denominator = $a13 * $x + $a23 * $y + $a33;
86
- $points[$i] = ($a11 * $x + $a21 * $y + $a31) / $denominator;
87
- $points[$i + 1] = ($a12 * $x + $a22 * $y +$a32) / $denominator;
88
- }
89
- }
90
-
91
- public function transformPoints_(&$xValues, &$yValues) {
92
- $n = count($xValues);
93
- for ($i = 0; $i < $n; $i ++) {
94
- $x = $xValues[$i];
95
- $y = $yValues[$i];
96
- $denominator = $this->a13 * $x + $this->a23 * $y + $this->a33;
97
- $xValues[$i] = ($this->a11 * $x + $this->a21 * $y + $this->a31) / $denominator;
98
- $yValues[$i] = ($this->a12 * $x + $this->a22 *$y + $this->a32) / $denominator;
99
- }
100
- }
101
-
102
- public static function squareToQuadrilateral($x0, $y0,
103
- $x1, $y1,
104
- $x2, $y2,
105
- $x3, $y3) {
106
- $dx3 = $x0 - $x1 + $x2 - $x3;
107
- $dy3 = $y0 - $y1 + $y2 - $y3;
108
- if ($dx3 == 0.0 && $dy3 == 0.0) {
109
- // Affine
110
- return new PerspectiveTransform($x1 - $x0, $x2 - $x1, $x0,
111
- $y1 - $y0, $y2 - $y1, $y0,
112
- 0.0, 0.0, 1.0);
113
- } else {
114
- $dx1 = $x1 - $x2;
115
- $dx2 = $x3 - $x2;
116
- $dy1 = $y1 - $y2;
117
- $dy2 = $y3 - $y2;
118
- $denominator = $dx1 * $dy2 - $dx2 * $dy1;
119
- $a13 = ($dx3 * $dy2 - $dx2 * $dy3) / $denominator;
120
- $a23 = ($dx1 * $dy3 - $dx3 * $dy1) / $denominator;
121
- return new PerspectiveTransform($x1 - $x0 + $a13 * $x1, $x3 - $x0 + $a23 * $x3, $x0,
122
- $y1 - $y0 + $a13 * $y1, $y3 - $y0 + $a23 * $y3, $y0,
123
- $a13, $a23, 1.0);
124
- }
125
- }
126
-
127
- public static function quadrilateralToSquare($x0, $y0,
128
- $x1, $y1,
129
- $x2, $y2,
130
- $x3, $y3) {
131
- // Here, the adjoint serves as the inverse:
132
- return self::squareToQuadrilateral($x0, $y0, $x1, $y1, $x2, $y2, $x3, $y3)->buildAdjoint();
133
- }
134
-
135
- function buildAdjoint() {
136
- // Adjoint is the transpose of the cofactor matrix:
137
- return new PerspectiveTransform($this->a22 * $this->a33 - $this->a23 * $this->a32,
138
- $this->a23 * $this->a31 - $this->a21 * $this->a33,
139
- $this->a21 * $this->a32 - $this->a22 * $this->a31,
140
- $this->a13 * $this->a32 - $this->a12 * $this->a33,
141
- $this->a11 * $this->a33 - $this->a13 * $this->a31,
142
- $this->a12 * $this->a31 - $this->a11 * $this->a32,
143
- $this->a12 * $this->a23 - $this->a13 * $this->a22,
144
- $this->a13 * $this->a21 - $this->a11 * $this->a23,
145
- $this->a11 * $this->a22 - $this->a12 * $this->a21);
146
- }
147
-
148
- function times($other) {
149
- return new PerspectiveTransform($this->a11 * $other->a11 + $this->a21 * $other->a12 + $this->a31 * $other->a13,
150
- $this->a11 * $other->a21 + $this->a21 * $other->a22 + $this->a31 * $other->a23,
151
- $this->a11 * $other->a31 + $this->a21 * $other->a32 + $this->a31 * $other->a33,
152
- $this->a12 * $other->a11 + $this->a22 * $other->a12 + $this->a32 * $other->a13,
153
- $this->a12 * $other->a21 + $this->a22 * $other->a22 + $this->a32 * $other->a23,
154
- $this->a12 * $other->a31 + $this->a22 * $other->a32 + $this->a32 * $other->a33,
155
- $this->a13 * $other->a11 + $this->a23 * $other->a12 + $this->a33 * $other->a13,
156
- $this->a13 * $other->a21 + $this->a23 * $other->a22 + $this->a33 * $other->a23,
157
- $this->a13 * $other->a31 + $this->a23 * $other->a32 + $this->a33 * $other->a33);
158
-
159
- }
160
-
161
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/common/customFunctions.php DELETED
@@ -1,93 +0,0 @@
1
- <?php
2
- function arraycopy($srcArray,$srcPos,$destArray, $destPos, $length){//System.arraycopy
3
-
4
- $srcArrayToCopy = array_slice($srcArray,$srcPos,$length);
5
- array_splice($destArray,$destPos,$length,$srcArrayToCopy);
6
- return $destArray;
7
- }
8
-
9
-
10
- function overflow32($value) {//There is no need to overflow 64 bits to 32 bit
11
- return $value;
12
- }
13
-
14
- function hashCode( $s )
15
- {
16
- $h = 0;
17
- $len = strlen($s);
18
- for($i = 0; $i < $len; $i++)
19
- {
20
- $h = overflow32(31 * $h + ord($s[$i]));
21
- }
22
-
23
- return $h;
24
- }
25
-
26
-
27
- function numberOfTrailingZeros($i) {
28
- if ($i == 0) return 32;
29
- $num = 0;
30
- while (($i & 1) == 0) {
31
- $i >>= 1;
32
- $num++;
33
- }
34
- return $num;
35
- }
36
- function intval32bits($value)
37
- {
38
- $value = ($value & 0xFFFFFFFF);
39
-
40
- if ($value & 0x80000000)
41
- $value = -((~$value & 0xFFFFFFFF) + 1);
42
-
43
- return $value;
44
- }
45
-
46
- function uRShift($a, $b)
47
- {
48
-
49
- if($b == 0) return $a;
50
- return ($a >> $b) & ~(1<<(8*PHP_INT_SIZE-1)>>($b-1));
51
- }
52
- /*
53
- function sdvig3($num,$count=1){//>>> 32 bit
54
- $s = decbin($num);
55
-
56
- $sarray = str_split($s,1);
57
- $sarray = array_slice($sarray,-32);//32bit
58
-
59
- for($i=0;$i<=1;$i++) {
60
- array_pop($sarray);
61
- array_unshift($sarray, '0');
62
- }
63
- return bindec(implode($sarray));
64
- }
65
- */
66
-
67
- function sdvig3($a,$b) {
68
-
69
- if ($a >= 0) {
70
- return bindec(decbin($a>>$b)); //simply right shift for positive number
71
- }
72
-
73
- $bin = decbin($a>>$b);
74
-
75
- $bin = substr($bin, $b); // zero fill on the left side
76
-
77
- $o = bindec($bin);
78
- return $o;
79
- }
80
-
81
- function floatToIntBits($float_val)
82
- {
83
- $int = unpack('i', pack('f', $float_val));
84
- return $int[1];
85
- }
86
-
87
- function fill_array($index,$count,$value){
88
- if($count<=0){
89
- return array(0);
90
- }else {
91
- return array_fill($index, $count, $value);
92
- }
93
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/common/detector/MathUtils.php DELETED
@@ -1,46 +0,0 @@
1
- <?php
2
- /*
3
- * Copyright 2012 ZXing authors
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
-
18
- namespace Zxing\Common\Detector;
19
-
20
- final class MathUtils {
21
-
22
- private function __construct() {
23
-
24
- }
25
-
26
- /**
27
- * Ends up being a bit faster than {@link Math#round(float)}. This merely rounds its
28
- * argument to the nearest int, where x.5 rounds up to x+1. Semantics of this shortcut
29
- * differ slightly from {@link Math#round(float)} in that half rounds down for negative
30
- * values. -2.5 rounds to -3, not -2. For purposes here it makes no difference.
31
- *
32
- * @param d real value to round
33
- * @return nearest {@code int}
34
- */
35
- public static function round($d) {
36
- return (int) ($d + ($d < 0.0 ? -0.5 : 0.5));
37
- }
38
-
39
- public static function distance($aX, $aY, $bX, $bY) {
40
- $xDiff = $aX - $bX;
41
- $yDiff = $aY - $bY;
42
- return (float) sqrt($xDiff * $xDiff + $yDiff * $yDiff);
43
- }
44
-
45
-
46
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/common/detector/MonochromeRectangleDetector.php DELETED
@@ -1,225 +0,0 @@
1
- <?php
2
- /**
3
- * Created by PhpStorm.
4
- * User: Ashot
5
- * Date: 3/24/15
6
- * Time: 21:23
7
- */
8
- namespace Zxing\Common\Detector;
9
-
10
- use \Zxing\NotFoundException;
11
- use \Zxing\ResultPoint;
12
- use \Zxing\BitMatrix;
13
-
14
- /*
15
- *
16
- *
17
- import com.google.zxing.NotFoundException;
18
- import com.google.zxing.ResultPoint;
19
- import com.google.zxing.common.BitMatrix;
20
-
21
- */
22
- //require_once('./lib/NotFoundException.php');
23
- //require_once('./lib/ResultPoint.php');
24
- //require_once('./lib/common/BitMatrix.php');
25
-
26
-
27
- /**
28
- * <p>A somewhat generic detector that looks for a barcode-like rectangular region within an image.
29
- * It looks within a mostly white region of an image for a region of black and white, but mostly
30
- * black. It returns the four corners of the region, as best it can determine.</p>
31
- *
32
- * @author Sean Owen
33
- * @port Ashot Khanamiryan
34
- */
35
- class MonochromeRectangleDetector {
36
- private static $MAX_MODULES = 32;
37
- private $image;
38
- function __construct($image){
39
- $this->image = $image;
40
-
41
- }
42
-
43
- /**
44
- * <p>Detects a rectangular region of black and white -- mostly black -- with a region of mostly
45
- * white, in an image.</p>
46
- *
47
- * @return {@link ResultPoint}[] describing the corners of the rectangular region. The first and
48
- * last points are opposed on the diagonal, as are the second and third. The first point will be
49
- * the topmost point and the last, the bottommost. The second point will be leftmost and the
50
- * third, the rightmost
51
- * @throws NotFoundException if no Data Matrix Code can be found
52
- */
53
- public function detect(){
54
-
55
- $height = $this->image->getHeight();
56
- $width = $this->image->getWidth();
57
- $halfHeight = $height / 2;
58
- $halfWidth = $width / 2;
59
-
60
- $deltaY = max(1, $height / (self::$MAX_MODULES * 8));
61
- $deltaX = max(1, $width / (self::$MAX_MODULES * 8));
62
-
63
-
64
- $top = 0;
65
- $bottom = $height;
66
- $left = 0;
67
- $right = $width;
68
- $pointA = $this->findCornerFromCenter($halfWidth, 0, $left, $right,
69
- $halfHeight, -$deltaY, $top, $bottom, $halfWidth / 2);
70
- $top = (int) $pointA->getY() - 1;
71
- $pointB = $this->findCornerFromCenter($halfWidth, -$deltaX, $left,$right,
72
- $halfHeight, 0, $top, $bottom, $halfHeight / 2);
73
- $left = (int) $pointB->getX() - 1;
74
- $pointC = $this->findCornerFromCenter($halfWidth, $deltaX, $left, $right,
75
- $halfHeight, 0, $top, $bottom, $halfHeight / 2);
76
- $right = (int) $pointC->getX() + 1;
77
- $pointD = $this->findCornerFromCenter($halfWidth, 0, $left, $right,
78
- $halfHeight, $deltaY, $top, $bottom, $halfWidth / 2);
79
- $bottom = (int) $pointD->getY() + 1;
80
-
81
- // Go try to find po$A again with better information -- might have been off at first.
82
- $pointA = $this->findCornerFromCenter($halfWidth, 0, $left, $right,
83
- $halfHeight, -$deltaY, $top, $bottom, $halfWidth / 4);
84
-
85
- return new ResultPoint( $pointA, $pointB, $pointC, $pointD );
86
-
87
- }
88
-
89
-
90
-
91
- /**
92
- * Attempts to locate a corner of the barcode by scanning up, down, left or right from a center
93
- * point which should be within the barcode.
94
- *
95
- * @param centerX center's x component (horizontal)
96
- * @param deltaX same as deltaY but change in x per step instead
97
- * @param left minimum value of x
98
- * @param right maximum value of x
99
- * @param centerY center's y component (vertical)
100
- * @param deltaY change in y per step. If scanning up this is negative; down, positive;
101
- * left or right, 0
102
- * @param top minimum value of y to search through (meaningless when di == 0)
103
- * @param bottom maximum value of y
104
- * @param maxWhiteRun maximum run of white pixels that can still be considered to be within
105
- * the barcode
106
- * @return a {@link com.google.zxing.ResultPoint} encapsulating the corner that was found
107
- * @throws NotFoundException if such a point cannot be found
108
- */
109
- private function findCornerFromCenter($centerX,
110
- $deltaX,
111
- $left,
112
- $right,
113
- $centerY,
114
- $deltaY,
115
- $top,
116
- $bottom,
117
- $maxWhiteRun){
118
- $lastRange = null;
119
- for ($y = $centerY, $x = $centerX;
120
- $y < $bottom && $y >= $top && $x < $right && $x >= $left;
121
- $y += $deltaY, $x += $deltaX) {
122
- $range = 0;
123
- if ($deltaX == 0) {
124
- // horizontal slices, up and down
125
- $range = $this->blackWhiteRange($y, $maxWhiteRun, $left, $right, true);
126
- } else {
127
- // vertical slices, left and right
128
- $range = $this->blackWhiteRange($x, $maxWhiteRun, $top, $bottom, false);
129
- }
130
- if ($range == null) {
131
- if ($lastRange == null) {
132
- throw NotFoundException::getNotFoundInstance();
133
- }
134
- // lastRange was found
135
- if ($deltaX == 0) {
136
- $lastY = $y - $deltaY;
137
- if ($lastRange[0] < $centerX) {
138
- if ($lastRange[1] > $centerX) {
139
- // straddle, choose one or the other based on direction
140
- return new ResultPoint($deltaY > 0 ? $lastRange[0] : $lastRange[1], $lastY);
141
- }
142
- return new ResultPoint($lastRange[0], $lastY);
143
- } else {
144
- return new ResultPoint($lastRange[1], $lastY);
145
- }
146
- } else {
147
- $lastX = $x - $deltaX;
148
- if ($lastRange[0] < $centerY) {
149
- if ($lastRange[1] > $centerY) {
150
- return new ResultPoint($lastX, $deltaX < 0 ? $lastRange[0] : $lastRange[1]);
151
- }
152
- return new ResultPoint($lastX, $lastRange[0]);
153
- } else {
154
- return new ResultPoint($lastX, $lastRange[1]);
155
- }
156
- }
157
- }
158
- $lastRange = $range;
159
- }
160
- throw NotFoundException::getNotFoundInstance();
161
- }
162
-
163
-
164
-
165
- /**
166
- * Computes the start and end of a region of pixels, either horizontally or vertically, that could
167
- * be part of a Data Matrix barcode.
168
- *
169
- * @param fixedDimension if scanning horizontally, this is the row (the fixed vertical location)
170
- * where we are scanning. If scanning vertically it's the column, the fixed horizontal location
171
- * @param maxWhiteRun largest run of white pixels that can still be considered part of the
172
- * barcode region
173
- * @param minDim minimum pixel location, horizontally or vertically, to consider
174
- * @param maxDim maximum pixel location, horizontally or vertically, to consider
175
- * @param horizontal if true, we're scanning left-right, instead of up-down
176
- * @return int[] with start and end of found range, or null if no such range is found
177
- * (e.g. only white was found)
178
- */
179
-
180
- private function blackWhiteRange($fixedDimension, $maxWhiteRun, $minDim, $maxDim, $horizontal){
181
- $center = ($minDim + $maxDim) / 2;
182
-
183
- // Scan left/up first
184
- $start = $center;
185
- while ($start >= $minDim) {
186
- if ($horizontal ? $this->image->get($start, $fixedDimension) : $this->image->get($fixedDimension, $start)) {
187
- $start--;
188
- } else {
189
- $whiteRunStart = $start;
190
- do {
191
- $start--;
192
- } while ($start >= $minDim && !($horizontal ? $this->image->get($start, $fixedDimension) :
193
- $this->image->get($fixedDimension, $start)));
194
- $whiteRunSize = $whiteRunStart - $start;
195
- if ($start < $minDim || $whiteRunSize > $maxWhiteRun) {
196
- $start = $whiteRunStart;
197
- break;
198
- }
199
- }
200
- }
201
- $start++;
202
-
203
- // Then try right/down
204
- $end = $center;
205
- while ($end < $maxDim) {
206
- if ($horizontal ? $this->image->get($end, $fixedDimension) : $this->image->get($fixedDimension, $end)) {
207
- $end++;
208
- } else {
209
- $whiteRunStart = $end;
210
- do {
211
- $end++;
212
- } while ($end < $maxDim && !($horizontal ? $this->image->get($end, $fixedDimension) :
213
- $this->image->get($fixedDimension, $end)));
214
- $whiteRunSize = $end - $whiteRunStart;
215
- if ($end >= $maxDim || $whiteRunSize > $maxWhiteRun) {
216
- $end = $whiteRunStart;
217
- break;
218
- }
219
- }
220
- }
221
- $end--;
222
-
223
- return $end > $start ? array($start, $end) : null;
224
- }
225
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/common/reedsolomon/GenericGF.php DELETED
@@ -1,181 +0,0 @@
1
- <?php
2
- /*
3
- * Copyright 2007 ZXing authors
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
-
18
- namespace Zxing\Common\Reedsolomon;
19
-
20
- /**
21
- * <p>This class contains utility methods for performing mathematical operations over
22
- * the Galois Fields. Operations use a given primitive polynomial in calculations.</p>
23
- *
24
- * <p>Throughout this package, elements of the GF are represented as an {@code int}
25
- * for convenience and speed (but at the cost of memory).
26
- * </p>
27
- *
28
- * @author Sean Owen
29
- * @author David Olivier
30
- */
31
- final class GenericGF {
32
-
33
- public static $AZTEC_DATA_12;
34
- public static $AZTEC_DATA_10;
35
- public static $AZTEC_DATA_6;
36
- public static $AZTEC_PARAM;
37
- public static $QR_CODE_FIELD_256;
38
- public static $DATA_MATRIX_FIELD_256;
39
- public static $AZTEC_DATA_8;
40
- public static $MAXICODE_FIELD_64;
41
-
42
- private $expTable;
43
- private $logTable;
44
- private $zero;
45
- private $one;
46
- private $size;
47
- private $primitive;
48
- private $generatorBase;
49
-
50
-
51
- public static function Init(){
52
- self::$AZTEC_DATA_12 = new GenericGF(0x1069, 4096, 1); // x^12 + x^6 + x^5 + x^3 + 1
53
- self::$AZTEC_DATA_10 = new GenericGF(0x409, 1024, 1); // x^10 + x^3 + 1
54
- self::$AZTEC_DATA_6 = new GenericGF(0x43, 64, 1); // x^6 + x + 1
55
- self::$AZTEC_PARAM = new GenericGF(0x13, 16, 1); // x^4 + x + 1
56
- self::$QR_CODE_FIELD_256 = new GenericGF(0x011D, 256, 0); // x^8 + x^4 + x^3 + x^2 + 1
57
- self::$DATA_MATRIX_FIELD_256 = new GenericGF(0x012D, 256, 1); // x^8 + x^5 + x^3 + x^2 + 1
58
- self::$AZTEC_DATA_8 = self::$DATA_MATRIX_FIELD_256;
59
- self::$MAXICODE_FIELD_64 = self::$AZTEC_DATA_6;
60
- }
61
-
62
-
63
- /**
64
- * Create a representation of GF(size) using the given primitive polynomial.
65
- *
66
- * @param primitive irreducible polynomial whose coefficients are represented by
67
- * the bits of an int, where the least-significant bit represents the constant
68
- * coefficient
69
- * @param size the size of the field
70
- * @param b the factor b in the generator polynomial can be 0- or 1-based
71
- * (g(x) = (x+a^b)(x+a^(b+1))...(x+a^(b+2t-1))).
72
- * In most cases it should be 1, but for QR code it is 0.
73
- */
74
- public function __construct($primitive, $size, $b) {
75
- $this->primitive = $primitive;
76
- $this->size = $size;
77
- $this->generatorBase = $b;
78
-
79
- $this->expTable = array();
80
- $this->logTable =array();
81
- $x = 1;
82
- for ($i = 0; $i < $size; $i++) {
83
- $this->expTable[$i] = $x;
84
- $x *= 2; // we're assuming the generator alpha is 2
85
- if ($x >= $size) {
86
- $x ^= $primitive;
87
- $x &= $size-1;
88
- }
89
- }
90
- for ($i = 0; $i < $size-1; $i++) {
91
- $this->logTable[$this->expTable[$i]] = $i;
92
- }
93
- // logTable[0] == 0 but this should never be used
94
- $this->zero = new GenericGFPoly($this, array(0));
95
- $this->one = new GenericGFPoly($this, array(1));
96
- }
97
-
98
- function getZero() {
99
- return $this->zero;
100
- }
101
-
102
- function getOne() {
103
- return $this->one;
104
- }
105
-
106
- /**
107
- * @return the monomial representing coefficient * x^degree
108
- */
109
- function buildMonomial($degree, $coefficient) {
110
- if ($degree < 0) {
111
- throw new \InvalidArgumentException();
112
- }
113
- if ($coefficient == 0) {
114
- return $this->zero;
115
- }
116
- $coefficients = fill_array(0,$degree+1,0);//new int[degree + 1];
117
- $coefficients[0] = $coefficient;
118
- return new GenericGFPoly($this, $coefficients);
119
- }
120
-
121
- /**
122
- * Implements both addition and subtraction -- they are the same in GF(size).
123
- *
124
- * @return sum/difference of a and b
125
- */
126
- static function addOrSubtract($a, $b) {
127
- return $a ^ $b;
128
- }
129
-
130
- /**
131
- * @return 2 to the power of a in GF(size)
132
- */
133
- function exp($a) {
134
- return $this->expTable[$a];
135
- }
136
-
137
- /**
138
- * @return base 2 log of a in GF(size)
139
- */
140
- function log($a) {
141
- if ($a == 0) {
142
- throw new \InvalidArgumentException();
143
- }
144
- return $this->logTable[$a];
145
- }
146
-
147
- /**
148
- * @return multiplicative inverse of a
149
- */
150
- function inverse($a) {
151
- if ($a == 0) {
152
- throw new Exception();
153
- }
154
- return $this->expTable[$this->size - $this->logTable[$a] - 1];
155
- }
156
-
157
- /**
158
- * @return product of a and b in GF(size)
159
- */
160
- function multiply($a, $b) {
161
- if ($a == 0 || $b == 0) {
162
- return 0;
163
- }
164
- return $this->expTable[($this->logTable[$a] + $this->logTable[$b]) % ($this->size - 1)];
165
- }
166
-
167
- public function getSize() {
168
- return $this->size;
169
- }
170
-
171
- public function getGeneratorBase() {
172
- return $this->generatorBase;
173
- }
174
-
175
- // @Override
176
- public function toString() {
177
- return "GF(0x" . dechex(intval($this->primitive)) . ',' . $this->size . ')';
178
- }
179
-
180
- }
181
- GenericGF::Init();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/common/reedsolomon/GenericGFPoly.php DELETED
@@ -1,268 +0,0 @@
1
- <?php
2
- /*
3
- * Copyright 2007 ZXing authors
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
-
18
- namespace Zxing\Common\Reedsolomon;
19
-
20
- /**
21
- * <p>Represents a polynomial whose coefficients are elements of a GF.
22
- * Instances of this class are immutable.</p>
23
- *
24
- * <p>Much credit is due to William Rucklidge since portions of this code are an indirect
25
- * port of his C++ Reed-Solomon implementation.</p>
26
- *
27
- * @author Sean Owen
28
- */
29
- final class GenericGFPoly {
30
-
31
- private $field;
32
- private $coefficients;
33
-
34
- /**
35
- * @param field the {@link GenericGF} instance representing the field to use
36
- * to perform computations
37
- * @param coefficients array coefficients as ints representing elements of GF(size), arranged
38
- * from most significant (highest-power term) coefficient to least significant
39
- * @throws IllegalArgumentException if argument is null or empty,
40
- * or if leading coefficient is 0 and this is not a
41
- * constant polynomial (that is, it is not the monomial "0")
42
- */
43
- function __construct($field, $coefficients) {
44
- if (count($coefficients) == 0) {
45
- throw new \InvalidArgumentException();
46
- }
47
- $this->field = $field;
48
- $coefficientsLength = count($coefficients);
49
- if ($coefficientsLength > 1 && $coefficients[0] == 0) {
50
- // Leading term must be non-zero for anything except the constant polynomial "0"
51
- $firstNonZero = 1;
52
- while ($firstNonZero < $coefficientsLength && $coefficients[$firstNonZero] == 0) {
53
- $firstNonZero++;
54
- }
55
- if ($firstNonZero == $coefficientsLength) {
56
- $this->coefficients = array(0);
57
- } else {
58
- $this->coefficients = fill_array(0,$coefficientsLength - $firstNonZero,0);
59
- $this->coefficients = arraycopy($coefficients,
60
- $firstNonZero,
61
- $this->coefficients,
62
- 0,
63
- count($this->coefficients));
64
- }
65
- } else {
66
- $this->coefficients = $coefficients;
67
- }
68
- }
69
-
70
- function getCoefficients() {
71
- return $this->coefficients;
72
- }
73
-
74
- /**
75
- * @return degree of this polynomial
76
- */
77
- function getDegree() {
78
- return count($this->coefficients) - 1;
79
- }
80
-
81
- /**
82
- * @return true iff this polynomial is the monomial "0"
83
- */
84
- function isZero() {
85
- return $this->coefficients[0] == 0;
86
- }
87
-
88
- /**
89
- * @return coefficient of x^degree term in this polynomial
90
- */
91
- function getCoefficient($degree) {
92
- return $this->coefficients[count($this->coefficients) - 1 - $degree];
93
- }
94
-
95
- /**
96
- * @return evaluation of this polynomial at a given point
97
- */
98
- function evaluateAt($a) {
99
- if ($a == 0) {
100
- // Just return the x^0 coefficient
101
- return $this->getCoefficient(0);
102
- }
103
- $size = count($this->coefficients);
104
- if ($a == 1) {
105
- // Just the sum of the coefficients
106
- $result = 0;
107
- foreach ($this->coefficients as $coefficient ) {
108
- $result = GenericGF::addOrSubtract($result, $coefficient);
109
- }
110
- return $result;
111
- }
112
- $result = $this->coefficients[0];
113
- for ($i = 1; $i < $size; $i++) {
114
- $result = GenericGF::addOrSubtract($this->field->multiply($a, $result), $this->coefficients[$i]);
115
- }
116
- return $result;
117
- }
118
-
119
- function addOrSubtract($other) {
120
- if ($this->field !== $other->field) {
121
- throw new \InvalidArgumentException("GenericGFPolys do not have same GenericGF field");
122
- }
123
- if ($this->isZero()) {
124
- return $other;
125
- }
126
- if ($other->isZero()) {
127
- return $this;
128
- }
129
-
130
- $smallerCoefficients = $this->coefficients;
131
- $largerCoefficients = $other->coefficients;
132
- if (count($smallerCoefficients) > count($largerCoefficients)) {
133
- $temp = $smallerCoefficients;
134
- $smallerCoefficients = $largerCoefficients;
135
- $largerCoefficients = $temp;
136
- }
137
- $sumDiff = fill_array(0,count($largerCoefficients),0);
138
- $lengthDiff = count($largerCoefficients) - count($smallerCoefficients);
139
- // Copy high-order terms only found in higher-degree polynomial's coefficients
140
- $sumDiff = arraycopy($largerCoefficients, 0, $sumDiff, 0, $lengthDiff);
141
-
142
- for ($i = $lengthDiff; $i < count($largerCoefficients); $i++) {
143
- $sumDiff[$i] = GenericGF::addOrSubtract($smallerCoefficients[$i - $lengthDiff], $largerCoefficients[$i]);
144
- }
145
-
146
- return new GenericGFPoly($this->field, $sumDiff);
147
- }
148
-
149
- function multiply($other) {
150
- if(is_int($other)){
151
- return $this->multiply_($other);
152
- }
153
- if ($this->field !== $other->field) {
154
- throw new \InvalidArgumentException("GenericGFPolys do not have same GenericGF field");
155
- }
156
- if ($this->isZero() || $other->isZero()) {
157
- return $this->field->getZero();
158
- }
159
- $aCoefficients = $this->coefficients;
160
- $aLength = count($aCoefficients);
161
- $bCoefficients = $other->coefficients;
162
- $bLength = count($bCoefficients);
163
- $product = fill_array(0,$aLength + $bLength - 1,0);
164
- for ($i = 0; $i < $aLength; $i++) {
165
- $aCoeff = $aCoefficients[$i];
166
- for ($j = 0; $j < $bLength; $j++) {
167
- $product[$i + $j] = GenericGF::addOrSubtract($product[$i + $j],
168
- $this->field->multiply($aCoeff, $bCoefficients[$j]));
169
- }
170
- }
171
- return new GenericGFPoly($this->field, $product);
172
- }
173
-
174
- function multiply_($scalar) {
175
- if ($scalar == 0) {
176
- return $this->field->getZero();
177
- }
178
- if ($scalar == 1) {
179
- return $this;
180
- }
181
- $size = count($this->coefficients);
182
- $product = fill_array(0,$size,0);
183
- for ($i = 0; $i < $size; $i++) {
184
- $product[$i] = $this->field->multiply($this->coefficients[$i], $scalar);
185
- }
186
- return new GenericGFPoly($this->field, $product);
187
- }
188
-
189
- function multiplyByMonomial($degree, $coefficient) {
190
- if ($degree < 0) {
191
- throw new \InvalidArgumentException();
192
- }
193
- if ($coefficient == 0) {
194
- return $this->field->getZero();
195
- }
196
- $size = count($this->coefficients);
197
- $product = fill_array(0,$size + $degree,0);
198
- for ($i = 0; $i < $size; $i++) {
199
- $product[$i] = $this->field->multiply($this->coefficients[$i], $coefficient);
200
- }
201
- return new GenericGFPoly($this->field, $product);
202
- }
203
-
204
- function divide($other) {
205
- if ($this->field !==$other->field) {
206
- throw new \InvalidArgumentException("GenericGFPolys do not have same GenericGF field");
207
- }
208
- if ($other->isZero()) {
209
- throw new \InvalidArgumentException("Divide by 0");
210
- }
211
-
212
- $quotient = $this->field->getZero();
213
- $remainder = $this;
214
-
215
- $denominatorLeadingTerm = $other->getCoefficient($other->getDegree());
216
- $inverseDenominatorLeadingTerm = $this->field->inverse($denominatorLeadingTerm);
217
-
218
- while ($remainder->getDegree() >= $other->getDegree() && !$remainder->isZero()) {
219
- $degreeDifference = $remainder->getDegree() - $other->getDegree();
220
- $scale = $this->field->multiply($remainder->getCoefficient($remainder->getDegree()), $inverseDenominatorLeadingTerm);
221
- $term = $other->multiplyByMonomial($degreeDifference, $scale);
222
- $iterationQuotient = $this->field->buildMonomial($degreeDifference, $scale);
223
- $quotient = $quotient->addOrSubtract($iterationQuotient);
224
- $remainder = $remainder->addOrSubtract($term);
225
- }
226
-
227
- return array($quotient, $remainder );
228
- }
229
-
230
- //@Override
231
- public function toString() {
232
- $result = '';
233
- for ($degree = $this->getDegree(); $degree >= 0; $degree--) {
234
- $coefficient = $this->getCoefficient($degree);
235
- if ($coefficient != 0) {
236
- if ($coefficient < 0) {
237
- $result.=" - ";
238
- $coefficient = -$coefficient;
239
- } else {
240
- if (strlen($result) > 0) {
241
- $result .= " + ";
242
- }
243
- }
244
- if ($degree == 0 || $coefficient != 1) {
245
- $alphaPower = $this->field->log($coefficient);
246
- if ($alphaPower == 0) {
247
- $result.='1';
248
- } else if ($alphaPower == 1) {
249
- $result.='a';
250
- } else {
251
- $result.="a^";
252
- $result.=($alphaPower);
253
- }
254
- }
255
- if ($degree != 0) {
256
- if ($degree == 1) {
257
- $result.='x';
258
- } else {
259
- $result.="x^";
260
- $result.= $degree;
261
- }
262
- }
263
- }
264
- }
265
- return $result;
266
- }
267
-
268
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/common/reedsolomon/ReedSolomonDecoder.php DELETED
@@ -1,192 +0,0 @@
1
- <?php
2
- /*
3
- * Copyright 2007 ZXing authors
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
-
18
- namespace Zxing\Common\Reedsolomon;
19
-
20
- /**
21
- * <p>Implements Reed-Solomon decoding, as the name implies.</p>
22
- *
23
- * <p>The algorithm will not be explained here, but the following references were helpful
24
- * in creating this implementation:</p>
25
- *
26
- * <ul>
27
- * <li>Bruce Maggs.
28
- * <a href="http://www.cs.cmu.edu/afs/cs.cmu.edu/project/pscico-guyb/realworld/www/rs_decode.ps">
29
- * "Decoding Reed-Solomon Codes"</a> (see discussion of Forney's Formula)</li>
30
- * <li>J.I. Hall. <a href="www.mth.msu.edu/~jhall/classes/codenotes/GRS.pdf">
31
- * "Chapter 5. Generalized Reed-Solomon Codes"</a>
32
- * (see discussion of Euclidean algorithm)</li>
33
- * </ul>
34
- *
35
- * <p>Much credit is due to William Rucklidge since portions of this code are an indirect
36
- * port of his C++ Reed-Solomon implementation.</p>
37
- *
38
- * @author Sean Owen
39
- * @author William Rucklidge
40
- * @author sanfordsquires
41
- */
42
- final class ReedSolomonDecoder {
43
-
44
- private $field;
45
-
46
- public function __construct($field) {
47
- $this->field = $field;
48
- }
49
-
50
- /**
51
- * <p>Decodes given set of received codewords, which include both data and error-correction
52
- * codewords. Really, this means it uses Reed-Solomon to detect and correct errors, in-place,
53
- * in the input.</p>
54
- *
55
- * @param received data and error-correction codewords
56
- * @param twoS number of error-correction codewords available
57
- * @throws ReedSolomonException if decoding fails for any reason
58
- */
59
- public function decode(&$received, $twoS) {
60
- $poly = new GenericGFPoly($this->field, $received);
61
- $syndromeCoefficients = fill_array(0,$twoS,0);
62
- $noError = true;
63
- for ($i = 0; $i < $twoS; $i++) {
64
- $eval = $poly->evaluateAt($this->field->exp($i + $this->field->getGeneratorBase()));
65
- $syndromeCoefficients[count($syndromeCoefficients) - 1 - $i] = $eval;
66
- if ($eval != 0) {
67
- $noError = false;
68
- }
69
- }
70
- if ($noError) {
71
- return;
72
- }
73
- $syndrome = new GenericGFPoly($this->field, $syndromeCoefficients);
74
- $sigmaOmega =
75
- $this->runEuclideanAlgorithm($this->field->buildMonomial($twoS, 1), $syndrome, $twoS);
76
- $sigma = $sigmaOmega[0];
77
- $omega = $sigmaOmega[1];
78
- $errorLocations = $this->findErrorLocations($sigma);
79
- $errorMagnitudes = $this->findErrorMagnitudes($omega, $errorLocations);
80
- for ($i = 0; $i < count($errorLocations); $i++) {
81
- $position = count($received) - 1 - $this->field->log($errorLocations[$i]);
82
- if ($position < 0) {
83
- throw new ReedSolomonException("Bad error location");
84
- }
85
- $received[$position] = GenericGF::addOrSubtract($received[$position], $errorMagnitudes[$i]);
86
- }
87
-
88
- }
89
-
90
- private function runEuclideanAlgorithm($a, $b, $R)
91
- {
92
- // Assume a's degree is >= b's
93
- if ($a->getDegree() < $b->getDegree()) {
94
- $temp = $a;
95
- $a = $b;
96
- $b = $temp;
97
- }
98
-
99
- $rLast = $a;
100
- $r = $b;
101
- $tLast = $this->field->getZero();
102
- $t = $this->field->getOne();
103
-
104
- // Run Euclidean algorithm until r's degree is less than R/2
105
- while ($r->getDegree() >= $R / 2) {
106
- $rLastLast = $rLast;
107
- $tLastLast = $tLast;
108
- $rLast = $r;
109
- $tLast = $t;
110
-
111
- // Divide rLastLast by rLast, with quotient in q and remainder in r
112
- if ($rLast->isZero()) {
113
- // Oops, Euclidean algorithm already terminated?
114
- throw new ReedSolomonException("r_{i-1} was zero");
115
- }
116
- $r = $rLastLast;
117
- $q = $this->field->getZero();
118
- $denominatorLeadingTerm = $rLast->getCoefficient($rLast->getDegree());
119
- $dltInverse = $this->field->inverse($denominatorLeadingTerm);
120
- while ($r->getDegree() >= $rLast->getDegree() && !$r->isZero()) {
121
- $degreeDiff = $r->getDegree() - $rLast->getDegree();
122
- $scale = $this->field->multiply($r->getCoefficient($r->getDegree()), $dltInverse);
123
- $q = $q->addOrSubtract($this->field->buildMonomial($degreeDiff, $scale));
124
- $r = $r->addOrSubtract($rLast->multiplyByMonomial($degreeDiff, $scale));
125
- }
126
-
127
- $t = $q->multiply($tLast)->addOrSubtract($tLastLast);
128
-
129
- if ($r->getDegree() >= $rLast->getDegree()) {
130
- throw new IllegalStateException("Division algorithm failed to reduce polynomial?");
131
- }
132
- }
133
-
134
- $sigmaTildeAtZero = $t->getCoefficient(0);
135
- if ($sigmaTildeAtZero == 0) {
136
- throw new ReedSolomonException("sigmaTilde(0) was zero");
137
- }
138
-
139
- $inverse = $this->field->inverse($sigmaTildeAtZero);
140
- $sigma = $t->multiply($inverse);
141
- $omega = $r->multiply($inverse);
142
- return array($sigma, $omega);
143
- }
144
-
145
- private function findErrorLocations($errorLocator) {
146
- // This is a direct application of Chien's search
147
- $numErrors = $errorLocator->getDegree();
148
- if ($numErrors == 1) { // shortcut
149
- return array($errorLocator->getCoefficient(1) );
150
- }
151
- $result = fill_array(0,$numErrors,0);
152
- $e = 0;
153
- for ($i = 1; $i < $this->field->getSize() && $e < $numErrors; $i++) {
154
- if ($errorLocator->evaluateAt($i) == 0) {
155
- $result[$e] = $this->field->inverse($i);
156
- $e++;
157
- }
158
- }
159
- if ($e != $numErrors) {
160
- throw new ReedSolomonException("Error locator degree does not match number of roots");
161
- }
162
- return $result;
163
- }
164
-
165
- private function findErrorMagnitudes($errorEvaluator, $errorLocations) {
166
- // This is directly applying Forney's Formula
167
- $s = count($errorLocations);
168
- $result = fill_array(0,$s,0);
169
- for ($i = 0; $i < $s; $i++) {
170
- $xiInverse = $this->field->inverse($errorLocations[$i]);
171
- $denominator = 1;
172
- for ($j = 0; $j < $s; $j++) {
173
- if ($i != $j) {
174
- //denominator = field.multiply(denominator,
175
- // GenericGF.addOrSubtract(1, field.multiply(errorLocations[j], xiInverse)));
176
- // Above should work but fails on some Apple and Linux JDKs due to a Hotspot bug.
177
- // Below is a funny-looking workaround from Steven Parkes
178
- $term = $this->field->multiply($errorLocations[$j], $xiInverse);
179
- $termPlus1 = ($term & 0x1) == 0 ? $term | 1 : $term & ~1;
180
- $denominator = $this->field->multiply($denominator, $termPlus1);
181
- }
182
- }
183
- $result[$i] = $this->field->multiply($errorEvaluator->evaluateAt($xiInverse),
184
- $this->field->inverse($denominator));
185
- if ($this->field->getGeneratorBase() != 0) {
186
- $result[$i] = $this->field->multiply($result[$i], $xiInverse);
187
- }
188
- }
189
- return $result;
190
- }
191
-
192
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/common/reedsolomon/ReedSolomonException.php DELETED
@@ -1,31 +0,0 @@
1
- <?php
2
- /*
3
- * Copyright 2007 ZXing authors
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
-
18
- namespace Zxing\Common\Reedsolomon;
19
-
20
- /**
21
- * <p>Thrown when an exception occurs during Reed-Solomon decoding, such as when
22
- * there are too many errors to correct.</p>
23
- *
24
- * @author Sean Owen
25
- */
26
- final class ReedSolomonException extends \Exception {
27
-
28
-
29
- }
30
-
31
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/QRCodeReader.php DELETED
@@ -1,222 +0,0 @@
1
- <?php
2
- /*
3
- * Copyright 2007 ZXing authors
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
-
18
- namespace Zxing\Qrcode;
19
-
20
- use Zxing\BarcodeFormat;
21
- use Zxing\BinaryBitmap;
22
- use Zxing\ChecksumException;
23
- use Zxing\DecodeHintType;
24
- use Zxing\FormatException;
25
- use Zxing\NotFoundException;
26
- use Zxing\Reader;
27
- use Zxing\Result;
28
- use Zxing\ResultMetadataType;
29
- use Zxing\ResultPoint;
30
- use Zxing\Common\BitMatrix;
31
- use Zxing\Common\DecoderResult;
32
- use Zxing\Common\DetectorResult;
33
- use Zxing\Qrcode\Decoder\Decoder;
34
- use Zxing\Qrcode\Decoder\QRCodeDecoderMetaData;
35
- use Zxing\Qrcode\Detector\Detector;
36
-
37
-
38
-
39
- /**
40
- * This implementation can detect and decode QR Codes in an image.
41
- *
42
- * @author Sean Owen
43
- */
44
- class QRCodeReader implements Reader {
45
-
46
-
47
- private static $NO_POINTS = array();
48
- private $decoder;
49
-
50
- function __construct(){
51
- $this->decoder = new Decoder();
52
-
53
- }
54
-
55
- protected final function getDecoder() {
56
- return $this->decoder;
57
- }
58
-
59
- /**
60
- * Locates and decodes a QR code in an image.
61
- *
62
- * @return a String representing the content encoded by the QR code
63
- * @throws NotFoundException if a QR code cannot be found
64
- * @throws FormatException if a QR code cannot be decoded
65
- * @throws ChecksumException if error correction fails
66
- */
67
- //@Override
68
-
69
-
70
- // @Override
71
- public function decode($image, $hints=null){/* Map<DecodeHintType,?> hints*/
72
- $decoderResult = null;
73
- $points = array();
74
- if ($hints != null && $hints['PURE_BARCODE']) {//hints.containsKey(DecodeHintType.PURE_BARCODE)) {
75
- $bits = $this->extractPureBits($image->getBlackMatrix());
76
- $decoderResult = $this->decoder->decode($bits, $hints);
77
- $points = self::$NO_POINTS;
78
- } else {
79
- $detector = new Detector($image->getBlackMatrix());
80
- $detectorResult = $detector->detect($hints);
81
-
82
- $decoderResult = $this->decoder->decode($detectorResult->getBits(), $hints);
83
- $points = $detectorResult->getPoints();
84
- }
85
-
86
- // If the code was mirrored: swap the bottom-left and the top-right points.
87
- if ($decoderResult->getOther() instanceof QRCodeDecoderMetaData) {
88
- $decoderResult->getOther()->applyMirroredCorrection($points);
89
- }
90
-
91
- $result = new Result($decoderResult->getText(), $decoderResult->getRawBytes(), $points, 'QR_CODE');//BarcodeFormat.QR_CODE
92
- $byteSegments = $decoderResult->getByteSegments();
93
- if ($byteSegments != null) {
94
- $result->putMetadata('BYTE_SEGMENTS', $byteSegments);//ResultMetadataType.BYTE_SEGMENTS
95
- }
96
- $ecLevel = $decoderResult->getECLevel();
97
- if ($ecLevel != null) {
98
- $result->putMetadata('ERROR_CORRECTION_LEVEL', $ecLevel);//ResultMetadataType.ERROR_CORRECTION_LEVEL
99
- }
100
- if ($decoderResult->hasStructuredAppend()) {
101
- $result->putMetadata('STRUCTURED_APPEND_SEQUENCE',//ResultMetadataType.STRUCTURED_APPEND_SEQUENCE
102
- $decoderResult->getStructuredAppendSequenceNumber());
103
- $result->putMetadata('STRUCTURED_APPEND_PARITY',//ResultMetadataType.STRUCTURED_APPEND_PARITY
104
- $decoderResult->getStructuredAppendParity());
105
- }
106
- return $result;
107
- }
108
-
109
- //@Override
110
- public function reset() {
111
- // do nothing
112
- }
113
-
114
- /**
115
- * This method detects a code in a "pure" image -- that is, pure monochrome image
116
- * which contains only an unrotated, unskewed, image of a code, with some white border
117
- * around it. This is a specialized method that works exceptionally fast in this special
118
- * case.
119
- *
120
- * @see com.google.zxing.datamatrix.DataMatrixReader#extractPureBits(BitMatrix)
121
- */
122
- private static function extractPureBits($image) {
123
-
124
- $leftTopBlack = $image->getTopLeftOnBit();
125
- $rightBottomBlack = $image->getBottomRightOnBit();
126
- if ($leftTopBlack == null || $rightBottomBlack == null) {
127
- throw NotFoundException::getNotFoundInstance();
128
- }
129
-
130
- $moduleSize = self::moduleSize($leftTopBlack, $image);
131
-
132
- $top = $leftTopBlack[1];
133
- $bottom = $rightBottomBlack[1];
134
- $left = $leftTopBlack[0];
135
- $right = $rightBottomBlack[0];
136
-
137
- // Sanity check!
138
- if ($left >= $right || $top >= $bottom) {
139
- throw NotFoundException::getNotFoundInstance();
140
- }
141
-
142
- if ($bottom - $top != $right - $left) {
143
- // Special case, where bottom-right module wasn't black so we found something else in the last row
144
- // Assume it's a square, so use height as the width
145
- $right = $left + ($bottom - $top);
146
- }
147
-
148
- $matrixWidth = round(($right - $left + 1) / $moduleSize);
149
- $matrixHeight = round(($bottom - $top + 1) / $moduleSize);
150
- if ($matrixWidth <= 0 || $matrixHeight <= 0) {
151
- throw NotFoundException::getNotFoundInstance();
152
- }
153
- if ($matrixHeight != $matrixWidth) {
154
- // Only possibly decode square regions
155
- throw NotFoundException::getNotFoundInstance();
156
- }
157
-
158
- // Push in the "border" by half the module width so that we start
159
- // sampling in the middle of the module. Just in case the image is a
160
- // little off, this will help recover.
161
- $nudge = (int) ($moduleSize / 2.0);// $nudge = (int) ($moduleSize / 2.0f);
162
- $top += $nudge;
163
- $left += $nudge;
164
-
165
- // But careful that this does not sample off the edge
166
- // "right" is the farthest-right valid pixel location -- right+1 is not necessarily
167
- // This is positive by how much the inner x loop below would be too large
168
- $nudgedTooFarRight = $left + (int) (($matrixWidth - 1) * $moduleSize) - $right;
169
- if ($nudgedTooFarRight > 0) {
170
- if ($nudgedTooFarRight > $nudge) {
171
- // Neither way fits; abort
172
- throw NotFoundException::getNotFoundInstance();
173
- }
174
- $left -= $nudgedTooFarRight;
175
- }
176
- // See logic above
177
- $nudgedTooFarDown = $top + (int) (($matrixHeight - 1) * $moduleSize) - $bottom;
178
- if ($nudgedTooFarDown > 0) {
179
- if ($nudgedTooFarDown > $nudge) {
180
- // Neither way fits; abort
181
- throw NotFoundException::getNotFoundInstance();
182
- }
183
- $top -= $nudgedTooFarDown;
184
- }
185
-
186
- // Now just read off the bits
187
- $bits = new BitMatrix($matrixWidth, $matrixHeight);
188
- for ($y = 0; $y < $matrixHeight; $y++) {
189
- $iOffset = $top + (int) ($y * $moduleSize);
190
- for ($x = 0; $x < $matrixWidth; $x++) {
191
- if ($image->get($left + (int) ($x * $moduleSize), $iOffset)) {
192
- $bits->set($x, $y);
193
- }
194
- }
195
- }
196
- return $bits;
197
- }
198
-
199
- private static function moduleSize($leftTopBlack, $image) {
200
- $height = $image->getHeight();
201
- $width = $image->getWidth();
202
- $x = $leftTopBlack[0];
203
- $y = $leftTopBlack[1];
204
- $inBlack = true;
205
- $transitions = 0;
206
- while ($x < $width && $y < $height) {
207
- if ($inBlack != $image->get($x, $y)) {
208
- if (++$transitions == 5) {
209
- break;
210
- }
211
- $inBlack = !$inBlack;
212
- }
213
- $x++;
214
- $y++;
215
- }
216
- if ($x == $width || $y == $height) {
217
- throw NotFoundException::getNotFoundInstance();
218
- }
219
- return ($x - $leftTopBlack[0]) / 7.0; //return ($x - $leftTopBlack[0]) / 7.0f;
220
- }
221
-
222
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/BitMatrixParser.php DELETED
@@ -1,250 +0,0 @@
1
- <?php
2
- /*
3
- * Copyright 2007 ZXing authors
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
-
18
- namespace Zxing\Qrcode\Decoder;
19
-
20
- use Zxing\FormatException;
21
- use Zxing\Common\BitMatrix;
22
-
23
- /**
24
- * @author Sean Owen
25
- */
26
- final class BitMatrixParser {
27
-
28
- private $bitMatrix;
29
- private $parsedVersion;
30
- private $parsedFormatInfo;
31
- private $mirror;
32
-
33
- /**
34
- * @param bitMatrix {@link BitMatrix} to parse
35
- * @throws FormatException if dimension is not >= 21 and 1 mod 4
36
- */
37
- function __construct($bitMatrix) {
38
- $dimension = $bitMatrix->getHeight();
39
- if ($dimension < 21 || ($dimension & 0x03) != 1) {
40
- throw FormatException::getFormatInstance();
41
- }
42
- $this->bitMatrix = $bitMatrix;
43
- }
44
-
45
- /**
46
- * <p>Reads format information from one of its two locations within the QR Code.</p>
47
- *
48
- * @return {@link FormatInformation} encapsulating the QR Code's format info
49
- * @throws FormatException if both format information locations cannot be parsed as
50
- * the valid encoding of format information
51
- */
52
- function readFormatInformation() {
53
-
54
- if ($this->parsedFormatInfo != null) {
55
- return $this->parsedFormatInfo;
56
- }
57
-
58
- // Read top-left format info bits
59
- $formatInfoBits1 = 0;
60
- for ($i = 0; $i < 6; $i++) {
61
- $formatInfoBits1 = $this->copyBit($i, 8, $formatInfoBits1);
62
- }
63
- // .. and skip a bit in the timing pattern ...
64
- $formatInfoBits1 = $this->copyBit(7, 8, $formatInfoBits1);
65
- $formatInfoBits1 = $this->copyBit(8, 8, $formatInfoBits1);
66
- $formatInfoBits1 = $this->copyBit(8, 7, $formatInfoBits1);
67
- // .. and skip a bit in the timing pattern ...
68
- for ($j = 5; $j >= 0; $j--) {
69
- $formatInfoBits1 = $this->copyBit(8, $j, $formatInfoBits1);
70
- }
71
-
72
- // Read the top-right/bottom-left pattern too
73
- $dimension = $this->bitMatrix->getHeight();
74
- $formatInfoBits2 = 0;
75
- $jMin = $dimension - 7;
76
- for ($j = $dimension - 1; $j >= $jMin; $j--) {
77
- $formatInfoBits2 = $this->copyBit(8, $j, $formatInfoBits2);
78
- }
79
- for ($i = $dimension - 8; $i < $dimension; $i++) {
80
- $formatInfoBits2 = $this->copyBit($i, 8, $formatInfoBits2);
81
- }
82
-
83
- $parsedFormatInfo = FormatInformation::decodeFormatInformation($formatInfoBits1, $formatInfoBits2);
84
- if ($parsedFormatInfo != null) {
85
- return $parsedFormatInfo;
86
- }
87
- throw FormatException::getFormatInstance();
88
- }
89
-
90
- /**
91
- * <p>Reads version information from one of its two locations within the QR Code.</p>
92
- *
93
- * @return {@link Version} encapsulating the QR Code's version
94
- * @throws FormatException if both version information locations cannot be parsed as
95
- * the valid encoding of version information
96
- */
97
- function readVersion(){
98
-
99
- if ($this->parsedVersion != null) {
100
- return $this->parsedVersion;
101
- }
102
-
103
- $dimension = $this->bitMatrix->getHeight();
104
-
105
- $provisionalVersion = ($dimension - 17) / 4;
106
- if ($provisionalVersion <= 6) {
107
- return Version::getVersionForNumber($provisionalVersion);
108
- }
109
-
110
- // Read top-right version info: 3 wide by 6 tall
111
- $versionBits = 0;
112
- $ijMin = $dimension - 11;
113
- for ($j = 5; $j >= 0; $j--) {
114
- for ($i = $dimension - 9; $i >= $ijMin; $i--) {
115
- $versionBits = $this->copyBit($i, $j, $versionBits);
116
- }
117
- }
118
-
119
- $theParsedVersion = Version::decodeVersionInformation($versionBits);
120
- if ($theParsedVersion != null && $theParsedVersion->getDimensionForVersion() == $dimension) {
121
- $this->parsedVersion = $theParsedVersion;
122
- return $theParsedVersion;
123
- }
124
-
125
- // Hmm, failed. Try bottom left: 6 wide by 3 tall
126
- $versionBits = 0;
127
- for ($i = 5; $i >= 0; $i--) {
128
- for ($j = $dimension - 9; $j >=$ijMin; $j--) {
129
- $versionBits = $this->copyBit($i, $j, $versionBits);
130
- }
131
- }
132
-
133
- $theParsedVersion = Version::decodeVersionInformation($versionBits);
134
- if ($theParsedVersion != null && $theParsedVersion->getDimensionForVersion() == $dimension) {
135
- $this->parsedVersion = $theParsedVersion;
136
- return $theParsedVersion;
137
- }
138
- throw FormatException::getFormatInstance();
139
- }
140
-
141
- private function copyBit($i, $j, $versionBits) {
142
- $bit = $this->mirror ? $this->bitMatrix->get($j, $i) : $this->bitMatrix->get($i, $j);
143
- return $bit ? ($versionBits << 1) | 0x1 : $versionBits << 1;
144
- }
145
-
146
- /**
147
- * <p>Reads the bits in the {@link BitMatrix} representing the finder pattern in the
148
- * correct order in order to reconstruct the codewords bytes contained within the
149
- * QR Code.</p>
150
- *
151
- * @return bytes encoded within the QR Code
152
- * @throws FormatException if the exact number of bytes expected is not read
153
- */
154
- function readCodewords(){
155
-
156
- $formatInfo = $this->readFormatInformation();
157
- $version = $this->readVersion();
158
-
159
- // Get the data mask for the format used in this QR Code. This will exclude
160
- // some bits from reading as we wind through the bit matrix.
161
- $dataMask = DataMask::forReference($formatInfo->getDataMask());
162
- $dimension = $this->bitMatrix->getHeight();
163
- $dataMask->unmaskBitMatrix($this->bitMatrix, $dimension);
164
-
165
- $functionPattern = $version->buildFunctionPattern();
166
-
167
- $readingUp = true;
168
- if($version->getTotalCodewords()) {
169
- $result = fill_array(0, $version->getTotalCodewords(), 0);
170
- }else{
171
- $result = array();
172
- }
173
- $resultOffset = 0;
174
- $currentByte = 0;
175
- $bitsRead = 0;
176
- // Read columns in pairs, from right to left
177
- for ($j = $dimension - 1; $j > 0; $j -= 2) {
178
- if ($j == 6) {
179
- // Skip whole column with vertical alignment pattern;
180
- // saves time and makes the other code proceed more cleanly
181
- $j--;
182
- }
183
- // Read alternatingly from bottom to top then top to bottom
184
- for ($count = 0; $count < $dimension; $count++) {
185
- $i = $readingUp ? $dimension - 1 - $count : $count;
186
- for ($col = 0; $col < 2; $col++) {
187
- // Ignore bits covered by the function pattern
188
- if (!$functionPattern->get($j - $col, $i)) {
189
- // Read a bit
190
- $bitsRead++;
191
- $currentByte <<= 1;
192
- if ($this->bitMatrix->get($j - $col, $i)) {
193
- $currentByte |= 1;
194
- }
195
- // If we've made a whole byte, save it off
196
- if ($bitsRead == 8) {
197
- $result[$resultOffset++] = $currentByte; //(byte)
198
- $bitsRead = 0;
199
- $currentByte = 0;
200
- }
201
- }
202
- }
203
- }
204
- $readingUp ^= true; // readingUp = !readingUp; // switch directions
205
- }
206
- if ($resultOffset != $version->getTotalCodewords()) {
207
- throw FormatException::getFormatInstance();
208
- }
209
- return $result;
210
- }
211
-
212
- /**
213
- * Revert the mask removal done while reading the code words. The bit matrix should revert to its original state.
214
- */
215
- function remask() {
216
- if ($this->parsedFormatInfo == null) {
217
- return; // We have no format information, and have no data mask
218
- }
219
- $dataMask = DataMask::forReference($this->parsedFormatInfo->getDataMask());
220
- $dimension = $this->bitMatrix->getHeight();
221
- $dataMask->unmaskBitMatrix($this->bitMatrix, $dimension);
222
- }
223
-
224
- /**
225
- * Prepare the parser for a mirrored operation.
226
- * This flag has effect only on the {@link #readFormatInformation()} and the
227
- * {@link #readVersion()}. Before proceeding with {@link #readCodewords()} the
228
- * {@link #mirror()} method should be called.
229
- *
230
- * @param mirror Whether to read version and format information mirrored.
231
- */
232
- function setMirror($mirror) {
233
- $parsedVersion = null;
234
- $parsedFormatInfo = null;
235
- $this->mirror = $mirror;
236
- }
237
-
238
- /** Mirror the bit matrix in order to attempt a second reading. */
239
- function mirror() {
240
- for ($x = 0; $x < $this->bitMatrix->getWidth(); $x++) {
241
- for ($y = $x + 1; $y < $this->bitMatrix->getHeight(); $y++) {
242
- if ($this->bitMatrix->get($x, $y) != $this->bitMatrix->get($y, $x)) {
243
- $this->bitMatrix->flip($y, $x);
244
- $this->bitMatrix->flip($x, $y);
245
- }
246
- }
247
- }
248
- }
249
-
250
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/DataBlock.php DELETED
@@ -1,123 +0,0 @@
1
- <?php
2
- /*
3
- * Copyright 2007 ZXing authors
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
-
18
- namespace Zxing\Qrcode\Decoder;
19
-
20
- /**
21
- * <p>Encapsulates a block of data within a QR Code. QR Codes may split their data into
22
- * multiple blocks, each of which is a unit of data and error-correction codewords. Each
23
- * is represented by an instance of this class.</p>
24
- *
25
- * @author Sean Owen
26
- */
27
- final class DataBlock {
28
-
29
- private $numDataCodewords;
30
- private $codewords; //byte[]
31
-
32
- private function __construct($numDataCodewords, $codewords) {
33
- $this->numDataCodewords = $numDataCodewords;
34
- $this->codewords = $codewords;
35
- }
36
-
37
- /**
38
- * <p>When QR Codes use multiple data blocks, they are actually interleaved.
39
- * That is, the first byte of data block 1 to n is written, then the second bytes, and so on. This
40
- * method will separate the data into original blocks.</p>
41
- *
42
- * @param rawCodewords bytes as read directly from the QR Code
43
- * @param version version of the QR Code
44
- * @param ecLevel error-correction level of the QR Code
45
- * @return DataBlocks containing original bytes, "de-interleaved" from representation in the
46
- * QR Code
47
- */
48
- static function getDataBlocks($rawCodewords,
49
- $version,
50
- $ecLevel) {
51
-
52
- if (count($rawCodewords) != $version->getTotalCodewords()) {
53
- throw new \InvalidArgumentException();
54
- }
55
-
56
- // Figure out the number and size of data blocks used by this version and
57
- // error correction level
58
- $ecBlocks = $version->getECBlocksForLevel($ecLevel);
59
-
60
- // First count the total number of data blocks
61
- $totalBlocks = 0;
62
- $ecBlockArray = $ecBlocks->getECBlocks();
63
- foreach ($ecBlockArray as $ecBlock) {
64
- $totalBlocks += $ecBlock->getCount();
65
- }
66
-
67
- // Now establish DataBlocks of the appropriate size and number of data codewords
68
- $result = array();//new DataBlock[$totalBlocks];
69
- $numResultBlocks = 0;
70
- foreach ($ecBlockArray as $ecBlock) {
71
- for ($i = 0; $i < $ecBlock->getCount(); $i++) {
72
- $numDataCodewords = $ecBlock->getDataCodewords();
73
- $numBlockCodewords = $ecBlocks->getECCodewordsPerBlock() + $numDataCodewords;
74
- $result[$numResultBlocks++] = new DataBlock($numDataCodewords, fill_array(0,$numBlockCodewords,0));
75
- }
76
- }
77
-
78
- // All blocks have the same amount of data, except that the last n
79
- // (where n may be 0) have 1 more byte. Figure out where these start.
80
- $shorterBlocksTotalCodewords = count($result[0]->codewords);
81
- $longerBlocksStartAt = count($result) - 1;
82
- while ($longerBlocksStartAt >= 0) {
83
- $numCodewords = count($result[$longerBlocksStartAt]->codewords);
84
- if ($numCodewords == $shorterBlocksTotalCodewords) {
85
- break;
86
- }
87
- $longerBlocksStartAt--;
88
- }
89
- $longerBlocksStartAt++;
90
-
91
- $shorterBlocksNumDataCodewords = $shorterBlocksTotalCodewords - $ecBlocks->getECCodewordsPerBlock();
92
- // The last elements of result may be 1 element longer;
93
- // first fill out as many elements as all of them have
94
- $rawCodewordsOffset = 0;
95
- for ($i = 0; $i < $shorterBlocksNumDataCodewords; $i++) {
96
- for ($j = 0; $j < $numResultBlocks; $j++) {
97
- $result[$j]->codewords[$i] = $rawCodewords[$rawCodewordsOffset++];
98
- }
99
- }
100
- // Fill out the last data block in the longer ones
101
- for ($j = $longerBlocksStartAt; $j < $numResultBlocks; $j++) {
102
- $result[$j]->codewords[$shorterBlocksNumDataCodewords] = $rawCodewords[$rawCodewordsOffset++];
103
- }
104
- // Now add in error correction blocks
105
- $max = count($result[0]->codewords);
106
- for ($i = $shorterBlocksNumDataCodewords; $i < $max; $i++) {
107
- for ($j = 0; $j < $numResultBlocks; $j++) {
108
- $iOffset = $j < $longerBlocksStartAt ? $i : $i + 1;
109
- $result[$j]->codewords[$iOffset] = $rawCodewords[$rawCodewordsOffset++];
110
- }
111
- }
112
- return $result;
113
- }
114
-
115
- function getNumDataCodewords() {
116
- return $this->numDataCodewords;
117
- }
118
-
119
- function getCodewords() {
120
- return $this->codewords;
121
- }
122
-
123
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/DataMask.php DELETED
@@ -1,175 +0,0 @@
1
- <?php
2
- /*
3
- * Copyright 2007 ZXing authors
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
-
18
- namespace Zxing\Qrcode\Decoder;
19
-
20
- use Zxing\Common\BitMatrix;
21
-
22
- /**
23
- * <p>Encapsulates data masks for the data bits in a QR code, per ISO 18004:2006 6.8. Implementations
24
- * of this class can un-mask a raw BitMatrix. For simplicity, they will unmask the entire BitMatrix,
25
- * including areas used for finder patterns, timing patterns, etc. These areas should be unused
26
- * after the point they are unmasked anyway.</p>
27
- *
28
- * <p>Note that the diagram in section 6.8.1 is misleading since it indicates that i is column position
29
- * and j is row position. In fact, as the text says, i is row position and j is column position.</p>
30
- *
31
- * @author Sean Owen
32
- */
33
- abstract class DataMask
34
- {
35
-
36
- /**
37
- * See ISO 18004:2006 6.8.1
38
- */
39
- private static $DATA_MASKS = array();
40
-
41
- static function Init()
42
- {
43
- self::$DATA_MASKS = array(
44
- new DataMask000(),
45
- new DataMask001(),
46
- new DataMask010(),
47
- new DataMask011(),
48
- new DataMask100(),
49
- new DataMask101(),
50
- new DataMask110(),
51
- new DataMask111(),
52
- );
53
- }
54
-
55
- function __construct()
56
- {
57
-
58
- }
59
-
60
- /**
61
- * <p>Implementations of this method reverse the data masking process applied to a QR Code and
62
- * make its bits ready to read.</p>
63
- *
64
- * @param bits representation of QR Code bits
65
- * @param dimension dimension of QR Code, represented by bits, being unmasked
66
- */
67
- final function unmaskBitMatrix($bits, $dimension)
68
- {
69
- for ($i = 0; $i < $dimension; $i++) {
70
- for ($j = 0; $j < $dimension; $j++) {
71
- if ($this->isMasked($i, $j)) {
72
- $bits->flip($j, $i);
73
- }
74
- }
75
- }
76
- }
77
-
78
- abstract function isMasked($i, $j);
79
-
80
- /**
81
- * @param reference a value between 0 and 7 indicating one of the eight possible
82
- * data mask patterns a QR Code may use
83
- * @return DataMask encapsulating the data mask pattern
84
- */
85
- static function forReference($reference)
86
- {
87
- if ($reference < 0 || $reference > 7) {
88
- throw new \InvalidArgumentException();
89
- }
90
- return self::$DATA_MASKS[$reference];
91
- }
92
- }
93
- DataMask::Init();
94
- /**
95
- * 000: mask bits for which (x + y) mod 2 == 0
96
- */
97
- final class DataMask000 extends DataMask {
98
- // @Override
99
- function isMasked($i, $j) {
100
- return (($i + $j) & 0x01) == 0;
101
- }
102
- }
103
-
104
- /**
105
- * 001: mask bits for which x mod 2 == 0
106
- */
107
- final class DataMask001 extends DataMask {
108
- //@Override
109
- function isMasked($i, $j) {
110
- return ($i & 0x01) == 0;
111
- }
112
- }
113
-
114
- /**
115
- * 010: mask bits for which y mod 3 == 0
116
- */
117
- final class DataMask010 extends DataMask {
118
- //@Override
119
- function isMasked($i, $j) {
120
- return $j % 3 == 0;
121
- }
122
- }
123
-
124
- /**
125
- * 011: mask bits for which (x + y) mod 3 == 0
126
- */
127
- final class DataMask011 extends DataMask {
128
- //@Override
129
- function isMasked($i, $j) {
130
- return ($i + $j) % 3 == 0;
131
- }
132
- }
133
-
134
- /**
135
- * 100: mask bits for which (x/2 + y/3) mod 2 == 0
136
- */
137
- final class DataMask100 extends DataMask {
138
- //@Override
139
- function isMasked($i, $j) {
140
- return intval((intval($i / 2) + intval($j /3)) & 0x01) == 0;
141
- }
142
- }
143
-
144
- /**
145
- * 101: mask bits for which xy mod 2 + xy mod 3 == 0
146
- */
147
- final class DataMask101 extends DataMask {
148
- //@Override
149
- function isMasked($i, $j) {
150
- $temp = $i * $j;
151
- return ($temp & 0x01) + ($temp % 3) == 0;
152
- }
153
- }
154
-
155
- /**
156
- * 110: mask bits for which (xy mod 2 + xy mod 3) mod 2 == 0
157
- */
158
- final class DataMask110 extends DataMask {
159
- //@Override
160
- function isMasked($i, $j) {
161
- $temp = $i * $j;
162
- return ((($temp & 0x01) + ($temp % 3)) & 0x01) == 0;
163
- }
164
- }
165
-
166
- /**
167
- * 111: mask bits for which ((x+y)mod 2 + xy mod 3) mod 2 == 0
168
- */
169
- final class DataMask111 extends DataMask {
170
- //@Override
171
- function isMasked($i, $j) {
172
- return (((($i + $j) & 0x01) + (($i * $j) % 3)) & 0x01) == 0;
173
- }
174
- }
175
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/DecodedBitStreamParser.php DELETED
@@ -1,359 +0,0 @@
1
- <?php
2
- /*
3
- * Copyright 2007 ZXing authors
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
-
18
- namespace Zxing\Qrcode\Decoder;
19
-
20
- use Zxing\DecodeHintType;
21
- use Zxing\FormatException;
22
- use Zxing\Common\BitSource;
23
- use Zxing\Common\CharacterSetECI;
24
- use Zxing\Common\DecoderResult;
25
- use Zxing\Common\StringUtils;
26
-
27
-
28
-
29
- /**
30
- * <p>QR Codes can encode text as bits in one of several modes, and can use multiple modes
31
- * in one QR Code. This class decodes the bits back into text.</p>
32
- *
33
- * <p>See ISO 18004:2006, 6.4.3 - 6.4.7</p>
34
- *
35
- * @author Sean Owen
36
- */
37
- final class DecodedBitStreamParser {
38
-
39
- /**
40
- * See ISO 18004:2006, 6.4.4 Table 5
41
- */
42
- private static $ALPHANUMERIC_CHARS = array(
43
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B',
44
- 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
45
- 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
46
- ' ', '$', '%', '*', '+', '-', '.', '/', ':'
47
- );
48
- private static $GB2312_SUBSET = 1;
49
-
50
-
51
- private function DecodedBitStreamParser() {
52
-
53
-
54
- }
55
-
56
- static function decode($bytes,
57
- $version,
58
- $ecLevel,
59
- $hints) {
60
- $bits = new BitSource($bytes);
61
- $result = '';//new StringBuilder(50);
62
- $byteSegments = array();
63
- $symbolSequence = -1;
64
- $parityData = -1;
65
-
66
- try {
67
- $currentCharacterSetECI = null;
68
- $fc1InEffect = false;
69
- $mode='';
70
- do {
71
- // While still another segment to read...
72
- if ($bits->available() < 4) {
73
- // OK, assume we're done. Really, a TERMINATOR mode should have been recorded here
74
- $mode = Mode::$TERMINATOR;
75
- } else {
76
- $mode = Mode::forBits($bits->readBits(4)); // mode is encoded by 4 bits
77
- }
78
- if ($mode != Mode::$TERMINATOR) {
79
- if ($mode == Mode::$FNC1_FIRST_POSITION || $mode == Mode::$FNC1_SECOND_POSITION) {
80
- // We do little with FNC1 except alter the parsed result a bit according to the spec
81
- $fc1InEffect = true;
82
- } else if ($mode == Mode::$STRUCTURED_APPEND) {
83
- if ($bits->available() < 16) {
84
- throw FormatException::getFormatInstance();
85
- }
86
- // sequence number and parity is added later to the result metadata
87
- // Read next 8 bits (symbol sequence #) and 8 bits (parity data), then continue
88
- $symbolSequence = $bits->readBits(8);
89
- $parityData = $bits->readBits(8);
90
- } else if ($mode == Mode::$ECI) {
91
- // Count doesn't apply to ECI
92
- $value = self::parseECIValue($bits);
93
- $currentCharacterSetECI = CharacterSetECI::getCharacterSetECIByValue($value);
94
- if ($currentCharacterSetECI == null) {
95
- throw FormatException::getFormatInstance();
96
- }
97
- } else {
98
- // First handle Hanzi mode which does not start with character count
99
- if ($mode == Mode::$HANZI) {
100
- //chinese mode contains a sub set indicator right after mode indicator
101
- $subset = $bits->readBits(4);
102
- $countHanzi = $bits->readBits($mode->getCharacterCountBits($version));
103
- if ($subset == self::$GB2312_SUBSET) {
104
- self::decodeHanziSegment($bits, $result, $countHanzi);
105
- }
106
- } else {
107
- // "Normal" QR code modes:
108
- // How many characters will follow, encoded in this mode?
109
- $count = $bits->readBits($mode->getCharacterCountBits($version));
110
- if ($mode == Mode::$NUMERIC) {
111
- self::decodeNumericSegment($bits, $result, $count);
112
- } else if ($mode == Mode::$ALPHANUMERIC) {
113
- self::decodeAlphanumericSegment($bits, $result, $count, $fc1InEffect);
114
- } else if ($mode == Mode::$BYTE) {
115
- self::decodeByteSegment($bits, $result, $count, $currentCharacterSetECI, $byteSegments, $hints);
116
- } else if ($mode == Mode::$KANJI) {
117
- self::decodeKanjiSegment($bits, $result, $count);
118
- } else {
119
- throw FormatException::getFormatInstance();
120
- }
121
- }
122
- }
123
- }
124
- } while ($mode != Mode::$TERMINATOR);
125
- } catch (IllegalArgumentException $iae) {
126
- // from readBits() calls
127
- throw FormatException::getFormatInstance();
128
- }
129
-
130
- return new DecoderResult($bytes,
131
- $result,
132
- empty($byteSegments) ? null : $byteSegments,
133
- $ecLevel == null ? null : 'L',//ErrorCorrectionLevel::toString($ecLevel),
134
- $symbolSequence,
135
- $parityData);
136
- }
137
-
138
- /**
139
- * See specification GBT 18284-2000
140
- */
141
- private static function decodeHanziSegment($bits,
142
- &$result,
143
- $count) {
144
- // Don't crash trying to read more bits than we have available.
145
- if ($count * 13 > $bits->available()) {
146
- throw FormatException::getFormatInstance();
147
- }
148
-
149
- // Each character will require 2 bytes. Read the characters as 2-byte pairs
150
- // and decode as GB2312 afterwards
151
- $buffer = fill_array(0,2 * $count,0);
152
- $offset = 0;
153
- while ($count > 0) {
154
- // Each 13 bits encodes a 2-byte character
155
- $twoBytes = $bits->readBits(13);
156
- $assembledTwoBytes = (($twoBytes / 0x060) << 8) | ($twoBytes % 0x060);
157
- if ($assembledTwoBytes < 0x003BF) {
158
- // In the 0xA1A1 to 0xAAFE range
159
- $assembledTwoBytes += 0x0A1A1;
160
- } else {
161
- // In the 0xB0A1 to 0xFAFE range
162
- $assembledTwoBytes += 0x0A6A1;
163
- }
164
- $buffer[$offset] = (($assembledTwoBytes >> 8) & 0xFF);//(byte)
165
- $buffer[$offset + 1] = ($assembledTwoBytes & 0xFF);//(byte)
166
- $offset += 2;
167
- $count--;
168
- }
169
-
170
- try {
171
- $result .= iconv('GB2312', 'UTF-8', implode($buffer));
172
- } catch (UnsupportedEncodingException $ignored) {
173
- throw FormatException::getFormatInstance();
174
- }
175
- }
176
-
177
- private static function decodeKanjiSegment($bits,
178
- &$result,
179
- $count) {
180
- // Don't crash trying to read more bits than we have available.
181
- if ($count * 13 > $bits->available()) {
182
- throw FormatException::getFormatInstance();
183
- }
184
-
185
- // Each character will require 2 bytes. Read the characters as 2-byte pairs
186
- // and decode as Shift_JIS afterwards
187
- $buffer = array(0,2 * $count,0);
188
- $offset = 0;
189
- while ($count > 0) {
190
- // Each 13 bits encodes a 2-byte character
191
- $twoBytes = $bits->readBits(13);
192
- $assembledTwoBytes = (($twoBytes / 0x0C0) << 8) | ($twoBytes % 0x0C0);
193
- if ($assembledTwoBytes < 0x01F00) {
194
- // In the 0x8140 to 0x9FFC range
195
- $assembledTwoBytes += 0x08140;
196
- } else {
197
- // In the 0xE040 to 0xEBBF range
198
- $assembledTwoBytes += 0x0C140;
199
- }
200
- $buffer[$offset] = ($assembledTwoBytes >> 8);//(byte)
201
- $buffer[$offset + 1] = $assembledTwoBytes; //(byte)
202
- $offset += 2;
203
- $count--;
204
- }
205
- // Shift_JIS may not be supported in some environments:
206
- try {
207
- $result .= iconv('shift-jis','utf-8',implode($buffer));
208
-
209
-
210
- } catch (UnsupportedEncodingException $ignored) {
211
- throw FormatException::getFormatInstance();
212
- }
213
- }
214
-
215
- private static function decodeByteSegment($bits,
216
- &$result,
217
- $count,
218
- $currentCharacterSetECI,
219
- &$byteSegments,
220
- $hints) {
221
- // Don't crash trying to read more bits than we have available.
222
- if (8 * $count > $bits->available()) {
223
- throw FormatException::getFormatInstance();
224
- }
225
-
226
- $readBytes = fill_array(0,$count,0);
227
- for ($i = 0; $i < $count; $i++) {
228
- $readBytes[$i] = $bits->readBits(8);//(byte)
229
- }
230
- $text = implode(array_map('chr',$readBytes));
231
- $encoding = '';
232
- if ($currentCharacterSetECI == null) {
233
- // The spec isn't clear on this mode; see
234
- // section 6.4.5: t does not say which encoding to assuming
235
- // upon decoding. I have seen ISO-8859-1 used as well as
236
- // Shift_JIS -- without anything like an ECI designator to
237
- // give a hint.
238
-
239
- $encoding = mb_detect_encoding($text, $hints);
240
- } else {
241
- $encoding = $currentCharacterSetECI->name();
242
- }
243
- try {
244
- // $result.= mb_convert_encoding($text ,$encoding);//(new String(readBytes, encoding));
245
- $result.= $text;//(new String(readBytes, encoding));
246
- } catch (UnsupportedEncodingException $ignored) {
247
- throw FormatException::getFormatInstance();
248
- }
249
- $byteSegments = array_merge($byteSegments, $readBytes);
250
- }
251
-
252
- private static function toAlphaNumericChar($value) {
253
- if ($value >= count(self::$ALPHANUMERIC_CHARS)) {
254
- throw FormatException::getFormatInstance();
255
- }
256
- return self::$ALPHANUMERIC_CHARS[$value];
257
- }
258
-
259
- private static function decodeAlphanumericSegment($bits,
260
- &$result,
261
- $count,
262
- $fc1InEffect) {
263
- // Read two characters at a time
264
- $start = strlen($result);
265
- while ($count > 1) {
266
- if ($bits->available() < 11) {
267
- throw FormatException::getFormatInstance();
268
- }
269
- $nextTwoCharsBits = $bits->readBits(11);
270
- $result.=(self::toAlphaNumericChar($nextTwoCharsBits / 45));
271
- $result.=(self::toAlphaNumericChar($nextTwoCharsBits % 45));
272
- $count -= 2;
273
- }
274
- if ($count == 1) {
275
- // special case: one character left
276
- if ($bits->available() < 6) {
277
- throw FormatException::getFormatInstance();
278
- }
279
- $result.=self::toAlphaNumericChar($bits->readBits(6));
280
- }
281
- // See section 6.4.8.1, 6.4.8.2
282
- if ($fc1InEffect) {
283
- // We need to massage the result a bit if in an FNC1 mode:
284
- for ($i = $start; $i < strlen($result); $i++) {
285
- if ($result{$i} == '%') {
286
- if ($i < strlen($result) - 1 && $result{$i + 1} == '%') {
287
- // %% is rendered as %
288
- $result = substr_replace($result,'',$i + 1,1);//deleteCharAt(i + 1);
289
- } else {
290
- // In alpha mode, % should be converted to FNC1 separator 0x1D
291
- $result.setCharAt($i, chr(0x1D));
292
- }
293
- }
294
- }
295
- }
296
- }
297
-
298
- private static function decodeNumericSegment($bits,
299
- &$result,
300
- $count) {
301
- // Read three digits at a time
302
- while ($count >= 3) {
303
- // Each 10 bits encodes three digits
304
- if ($bits->available() < 10) {
305
- throw FormatException::getFormatInstance();
306
- }
307
- $threeDigitsBits = $bits->readBits(10);
308
- if ($threeDigitsBits >= 1000) {
309
- throw FormatException::getFormatInstance();
310
- }
311
- $result.=(self::toAlphaNumericChar($threeDigitsBits / 100));
312
- $result.=(self::toAlphaNumericChar(($threeDigitsBits / 10) % 10));
313
- $result.=(self::toAlphaNumericChar($threeDigitsBits % 10));
314
- $count -= 3;
315
- }
316
- if ($count == 2) {
317
- // Two digits left over to read, encoded in 7 bits
318
- if ($bits->available() < 7) {
319
- throw FormatException::getFormatInstance();
320
- }
321
- $twoDigitsBits = $bits->readBits(7);
322
- if ($twoDigitsBits >= 100) {
323
- throw FormatException::getFormatInstance();
324
- }
325
- $result.=(self::toAlphaNumericChar($twoDigitsBits / 10));
326
- $result.=(self::toAlphaNumericChar($twoDigitsBits % 10));
327
- } else if ($count == 1) {
328
- // One digit left over to read
329
- if ($bits->available() < 4) {
330
- throw FormatException::getFormatInstance();
331
- }
332
- $digitBits = $bits->readBits(4);
333
- if ($digitBits >= 10) {
334
- throw FormatException::getFormatInstance();
335
- }
336
- $result.=(self::toAlphaNumericChar($digitBits));
337
- }
338
- }
339
-
340
- private static function parseECIValue($bits) {
341
- $firstByte = $bits->readBits(8);
342
- if (($firstByte & 0x80) == 0) {
343
- // just one byte
344
- return $firstByte & 0x7F;
345
- }
346
- if (($firstByte & 0xC0) == 0x80) {
347
- // two bytes
348
- $secondByte = $bits->readBits(8);
349
- return (($firstByte & 0x3F) << 8) | $secondByte;
350
- }
351
- if (($firstByte & 0xE0) == 0xC0) {
352
- // three bytes
353
- $secondThirdBytes = $bits->readBits(16);
354
- return (($firstByte & 0x1F) << 16) | $secondThirdBytes;
355
- }
356
- throw FormatException::getFormatInstance();
357
- }
358
-
359
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/Decoder.php DELETED
@@ -1,214 +0,0 @@
1
- <?php
2
- /*
3
- * Copyright 2007 ZXing authors
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
-
18
- namespace Zxing\Qrcode\Decoder;
19
-
20
- use Zxing\ChecksumException;
21
- use Zxing\DecodeHintType;
22
- use Zxing\FormatException;
23
- use Zxing\Common\BitMatrix;
24
- use Zxing\Common\DecoderResult;
25
- use Zxing\Common\Reedsolomon\GenericGF;
26
- use Zxing\Common\Reedsolomon\ReedSolomonDecoder;
27
- use Zxing\Common\Reedsolomon\ReedSolomonException;
28
-
29
-
30
-
31
- /**
32
- * <p>The main class which implements QR Code decoding -- as opposed to locating and extracting
33
- * the QR Code from an image.</p>
34
- *
35
- * @author Sean Owen
36
- */
37
- final class Decoder {
38
-
39
- private $rsDecoder;
40
-
41
- public function __construct() {
42
- $this->rsDecoder = new ReedSolomonDecoder(GenericGF::$QR_CODE_FIELD_256);
43
- }
44
-
45
-
46
- function decode($variable, $hints=null){
47
- if(is_array($variable)){
48
- return $this->decodeImage($variable,$hints);
49
- }elseif(is_object($variable)&&$variable instanceof BitMatrix){
50
- return $this->decodeBits($variable,$hints);
51
- }elseif(is_object($variable)&&$variable instanceof BitMatrixParser){
52
- return $this->decodeParser($variable,$hints);
53
- }else{
54
- die('decode error Decoder.php');
55
- }
56
-
57
-
58
- }
59
-
60
- /**
61
- * <p>Convenience method that can decode a QR Code represented as a 2D array of booleans.
62
- * "true" is taken to mean a black module.</p>
63
- *
64
- * @param image booleans representing white/black QR Code modules
65
- * @param hints decoding hints that should be used to influence decoding
66
- * @return text and bytes encoded within the QR Code
67
- * @throws FormatException if the QR Code cannot be decoded
68
- * @throws ChecksumException if error correction fails
69
- */
70
- public function decodeImage($image, $hints=null)
71
- {
72
- $dimension = count($image);
73
- $bits = new BitMatrix($dimension);
74
- for ($i = 0; $i < $dimension; $i++) {
75
- for ($j = 0; $j < $dimension; $j++) {
76
- if ($image[$i][$j]) {
77
- $bits->set($j, $i);
78
- }
79
- }
80
- }
81
- return $this->decode($bits, $hints);
82
- }
83
-
84
-
85
-
86
- /**
87
- * <p>Decodes a QR Code represented as a {@link BitMatrix}. A 1 or "true" is taken to mean a black module.</p>
88
- *
89
- * @param bits booleans representing white/black QR Code modules
90
- * @param hints decoding hints that should be used to influence decoding
91
- * @return text and bytes encoded within the QR Code
92
- * @throws FormatException if the QR Code cannot be decoded
93
- * @throws ChecksumException if error correction fails
94
- */
95
- public function decodeBits($bits, $hints=null)
96
- {
97
-
98
- // Construct a parser and read version, error-correction level
99
- $parser = new BitMatrixParser($bits);
100
- $fe = null;
101
- $ce = null;
102
- try {
103
- return $this->decode($parser, $hints);
104
- } catch (FormatException $e) {
105
- $fe = $e;
106
- } catch (ChecksumException $e) {
107
- $ce = $e;
108
- }
109
-
110
- try {
111
-
112
- // Revert the bit matrix
113
- $parser->remask();
114
-
115
- // Will be attempting a mirrored reading of the version and format info.
116
- $parser->setMirror(true);
117
-
118
- // Preemptively read the version.
119
- $parser->readVersion();
120
-
121
- // Preemptively read the format information.
122
- $parser->readFormatInformation();
123
-
124
- /*
125
- * Since we're here, this means we have successfully detected some kind
126
- * of version and format information when mirrored. This is a good sign,
127
- * that the QR code may be mirrored, and we should try once more with a
128
- * mirrored content.
129
- */
130
- // Prepare for a mirrored reading.
131
- $parser->mirror();
132
-
133
- $result = $this->decode($parser, $hints);
134
-
135
- // Success! Notify the caller that the code was mirrored.
136
- $result->setOther(new QRCodeDecoderMetaData(true));
137
-
138
- return $result;
139
-
140
- } catch (FormatException $e ) {// catch (FormatException | ChecksumException e) {
141
- // Throw the exception from the original reading
142
- if ($fe != null) {
143
- throw $fe;
144
- }
145
- if ($ce != null) {
146
- throw $ce;
147
- }
148
- throw $e;
149
-
150
- }
151
- }
152
-
153
- private function decodeParser($parser,$hints=null)
154
- {
155
- $version = $parser->readVersion();
156
- $ecLevel = $parser->readFormatInformation()->getErrorCorrectionLevel();
157
-
158
- // Read codewords
159
- $codewords = $parser->readCodewords();
160
- // Separate into data blocks
161
- $dataBlocks = DataBlock::getDataBlocks($codewords, $version, $ecLevel);
162
-
163
- // Count total number of data bytes
164
- $totalBytes = 0;
165
- foreach ($dataBlocks as $dataBlock) {
166
- $totalBytes += $dataBlock->getNumDataCodewords();
167
- }
168
- $resultBytes = fill_array(0,$totalBytes,0);
169
- $resultOffset = 0;
170
-
171
- // Error-correct and copy data blocks together into a stream of bytes
172
- foreach ($dataBlocks as $dataBlock) {
173
- $codewordBytes = $dataBlock->getCodewords();
174
- $numDataCodewords = $dataBlock->getNumDataCodewords();
175
- $this->correctErrors($codewordBytes, $numDataCodewords);
176
- for ($i = 0; $i < $numDataCodewords; $i++) {
177
- $resultBytes[$resultOffset++] = $codewordBytes[$i];
178
- }
179
- }
180
-
181
- // Decode the contents of that stream of bytes
182
- return DecodedBitStreamParser::decode($resultBytes, $version, $ecLevel, $hints);
183
- }
184
-
185
- /**
186
- * <p>Given data and error-correction codewords received, possibly corrupted by errors, attempts to
187
- * correct the errors in-place using Reed-Solomon error correction.</p>
188
- *
189
- * @param codewordBytes data and error correction codewords
190
- * @param numDataCodewords number of codewords that are data bytes
191
- * @throws ChecksumException if error correction fails
192
- */
193
- private function correctErrors(&$codewordBytes, $numDataCodewords){
194
- $numCodewords = count($codewordBytes);
195
- // First read into an array of ints
196
- $codewordsInts =fill_array(0,$numCodewords,0);
197
- for ($i = 0; $i < $numCodewords; $i++) {
198
- $codewordsInts[$i] = $codewordBytes[$i] & 0xFF;
199
- }
200
- $numECCodewords = count($codewordBytes)- $numDataCodewords;
201
- try {
202
- $this->rsDecoder->decode($codewordsInts, $numECCodewords);
203
- } catch (ReedSolomonException $ignored) {
204
- throw ChecksumException::getChecksumInstance();
205
- }
206
- // Copy back into array of bytes -- only need to worry about the bytes that were data
207
- // We don't care about errors in the error-correction codewords
208
- for ($i = 0; $i < $numDataCodewords; $i++) {
209
- $codewordBytes[$i] = $codewordsInts[$i];
210
- }
211
-
212
- }
213
-
214
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/ErrorCorrectionLevel.php DELETED
@@ -1,86 +0,0 @@
1
- <?php
2
- /*
3
- * Copyright 2007 ZXing authors
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
-
18
- namespace Zxing\Qrcode\Decoder;
19
-
20
- /**
21
- * <p>See ISO 18004:2006, 6.5.1. This enum encapsulates the four error correction levels
22
- * defined by the QR code standard.</p>
23
- *
24
- * @author Sean Owen
25
- */
26
- class ErrorCorrectionLevel {
27
-
28
-
29
- private static $FOR_BITS;
30
-
31
-
32
- private $bits;
33
- private $ordinal;
34
-
35
- function __construct($bits,$ordinal=0) {
36
- $this->bits = $bits;
37
- $this->ordinal = $ordinal;
38
- }
39
-
40
- public static function Init(){
41
- self::$FOR_BITS = array(
42
-
43
-
44
- new ErrorCorrectionLevel(0x00,1), //M
45
- new ErrorCorrectionLevel(0x01,0), //L
46
- new ErrorCorrectionLevel(0x02,3), //H
47
- new ErrorCorrectionLevel(0x03,2), //Q
48
-
49
- );
50
- }
51
- /** L = ~7% correction */
52
- // self::$L = new ErrorCorrectionLevel(0x01);
53
- /** M = ~15% correction */
54
- //self::$M = new ErrorCorrectionLevel(0x00);
55
- /** Q = ~25% correction */
56
- //self::$Q = new ErrorCorrectionLevel(0x03);
57
- /** H = ~30% correction */
58
- //self::$H = new ErrorCorrectionLevel(0x02);
59
-
60
-
61
- public function getBits() {
62
- return $this->bits;
63
- }
64
- public function toString() {
65
- return $this->bits;
66
- }
67
- public function getOrdinal() {
68
- return $this->ordinal;
69
- }
70
-
71
- /**
72
- * @param bits int containing the two bits encoding a QR Code's error correction level
73
- * @return ErrorCorrectionLevel representing the encoded error correction level
74
- */
75
- public static function forBits($bits) {
76
- if ($bits < 0 || $bits >= count(self::$FOR_BITS)) {
77
- throw new \InvalidArgumentException();
78
- }
79
- $level = self::$FOR_BITS[$bits];
80
- // $lev = self::$$bit;
81
- return $level;
82
- }
83
-
84
-
85
- }
86
- ErrorCorrectionLevel::Init();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/FormatInformation.php DELETED
@@ -1,179 +0,0 @@
1
- <?php
2
- /*
3
- * Copyright 2007 ZXing authors
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
-
18
- namespace Zxing\Qrcode\Decoder;
19
-
20
- /**
21
- * <p>Encapsulates a QR Code's format information, including the data mask used and
22
- * error correction level.</p>
23
- *
24
- * @author Sean Owen
25
- * @see DataMask
26
- * @see ErrorCorrectionLevel
27
- */
28
- final class FormatInformation {
29
-
30
- public static $FORMAT_INFO_MASK_QR;
31
-
32
- /**
33
- * See ISO 18004:2006, Annex C, Table C.1
34
- */
35
- public static $FORMAT_INFO_DECODE_LOOKUP;
36
- /**
37
- * Offset i holds the number of 1 bits in the binary representation of i
38
- */
39
- private static $BITS_SET_IN_HALF_BYTE;
40
-
41
- private $errorCorrectionLevel;
42
- private $dataMask;
43
-
44
- public static function Init(){
45
-
46
- self::$FORMAT_INFO_MASK_QR= 0x5412;
47
- self::$BITS_SET_IN_HALF_BYTE = array(0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4);
48
- self::$FORMAT_INFO_DECODE_LOOKUP = array(
49
- array(0x5412, 0x00),
50
- array (0x5125, 0x01),
51
- array(0x5E7C, 0x02),
52
- array(0x5B4B, 0x03),
53
- array(0x45F9, 0x04),
54
- array(0x40CE, 0x05),
55
- array(0x4F97, 0x06),
56
- array(0x4AA0, 0x07),
57
- array(0x77C4, 0x08),
58
- array(0x72F3, 0x09),
59
- array(0x7DAA, 0x0A),
60
- array(0x789D, 0x0B),
61
- array(0x662F, 0x0C),
62
- array(0x6318, 0x0D),
63
- array(0x6C41, 0x0E),
64
- array(0x6976, 0x0F),
65
- array(0x1689, 0x10),
66
- array(0x13BE, 0x11),
67
- array(0x1CE7, 0x12),
68
- array(0x19D0, 0x13),
69
- array(0x0762, 0x14),
70
- array(0x0255, 0x15),
71
- array(0x0D0C, 0x16),
72
- array(0x083B, 0x17),
73
- array(0x355F, 0x18),
74
- array(0x3068, 0x19),
75
- array(0x3F31, 0x1A),
76
- array(0x3A06, 0x1B),
77
- array(0x24B4, 0x1C),
78
- array(0x2183, 0x1D),
79
- array(0x2EDA, 0x1E),
80
- array(0x2BED, 0x1F),
81
- );
82
-
83
- }
84
- private function __construct($formatInfo) {
85
- // Bits 3,4
86
- $this->errorCorrectionLevel = ErrorCorrectionLevel::forBits(($formatInfo >> 3) & 0x03);
87
- // Bottom 3 bits
88
- $this->dataMask = ($formatInfo & 0x07);//(byte)
89
- }
90
-
91
- static function numBitsDiffering($a, $b) {
92
- $a ^= $b; // a now has a 1 bit exactly where its bit differs with b's
93
- // Count bits set quickly with a series of lookups:
94
- return self::$BITS_SET_IN_HALF_BYTE[$a & 0x0F] +
95
- self::$BITS_SET_IN_HALF_BYTE[intval(uRShift($a, 4) & 0x0F)] +
96
- self::$BITS_SET_IN_HALF_BYTE[(uRShift($a ,8) & 0x0F)] +
97
- self::$BITS_SET_IN_HALF_BYTE[(uRShift($a , 12) & 0x0F)] +
98
- self::$BITS_SET_IN_HALF_BYTE[(uRShift($a, 16) & 0x0F)] +
99
- self::$BITS_SET_IN_HALF_BYTE[(uRShift($a , 20) & 0x0F)] +
100
- self::$BITS_SET_IN_HALF_BYTE[(uRShift($a, 24) & 0x0F)] +
101
- self::$BITS_SET_IN_HALF_BYTE[(uRShift($a ,28) & 0x0F)];
102
- }
103
-
104
- /**
105
- * @param maskedFormatInfo1; format info indicator, with mask still applied
106
- * @param maskedFormatInfo2; second copy of same info; both are checked at the same time
107
- * to establish best match
108
- * @return information about the format it specifies, or {@code null}
109
- * if doesn't seem to match any known pattern
110
- */
111
- static function decodeFormatInformation($maskedFormatInfo1, $maskedFormatInfo2) {
112
- $formatInfo = self::doDecodeFormatInformation($maskedFormatInfo1, $maskedFormatInfo2);
113
- if ($formatInfo != null) {
114
- return $formatInfo;
115
- }
116
- // Should return null, but, some QR codes apparently
117
- // do not mask this info. Try again by actually masking the pattern
118
- // first
119
- return self::doDecodeFormatInformation($maskedFormatInfo1 ^ self::$FORMAT_INFO_MASK_QR,
120
- $maskedFormatInfo2 ^ self::$FORMAT_INFO_MASK_QR);
121
- }
122
-
123
- private static function doDecodeFormatInformation($maskedFormatInfo1, $maskedFormatInfo2) {
124
- // Find the int in FORMAT_INFO_DECODE_LOOKUP with fewest bits differing
125
- $bestDifference = PHP_INT_MAX;
126
- $bestFormatInfo = 0;
127
- foreach (self::$FORMAT_INFO_DECODE_LOOKUP as $decodeInfo ) {
128
- $targetInfo = $decodeInfo[0];
129
- if ($targetInfo == $maskedFormatInfo1 || $targetInfo == $maskedFormatInfo2) {
130
- // Found an exact match
131
- return new FormatInformation($decodeInfo[1]);
132
- }
133
- $bitsDifference = self::numBitsDiffering($maskedFormatInfo1, $targetInfo);
134
- if ($bitsDifference < $bestDifference) {
135
- $bestFormatInfo = $decodeInfo[1];
136
- $bestDifference = $bitsDifference;
137
- }
138
- if ($maskedFormatInfo1 != $maskedFormatInfo2) {
139
- // also try the other option
140
- $bitsDifference = self::numBitsDiffering($maskedFormatInfo2, $targetInfo);
141
- if ($bitsDifference < $bestDifference) {
142
- $bestFormatInfo = $decodeInfo[1];
143
- $bestDifference = $bitsDifference;
144
- }
145
- }
146
- }
147
- // Hamming distance of the 32 masked codes is 7, by construction, so <= 3 bits
148
- // differing means we found a match
149
- if ($bestDifference <= 3) {
150
- return new FormatInformation($bestFormatInfo);
151
- }
152
- return null;
153
- }
154
-
155
- function getErrorCorrectionLevel() {
156
- return $this->errorCorrectionLevel;
157
- }
158
-
159
- function getDataMask() {
160
- return $this->dataMask;
161
- }
162
-
163
- //@Override
164
- public function hashCode() {
165
- return ($this->errorCorrectionLevel->ordinal() << 3) | intval($this->dataMask);
166
- }
167
-
168
- //@Override
169
- public function equals($o) {
170
- if (!($o instanceof FormatInformation)) {
171
- return false;
172
- }
173
- $other =$o;
174
- return $this->errorCorrectionLevel == $other->errorCorrectionLevel &&
175
- $this->dataMask == $other->dataMask;
176
- }
177
-
178
- }
179
- FormatInformation::Init();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/Mode.php DELETED
@@ -1,118 +0,0 @@
1
- <?php
2
- /*
3
- * Copyright 2007 ZXing authors
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
-
18
- namespace Zxing\Qrcode\Decoder;
19
-
20
- /**
21
- * <p>See ISO 18004:2006, 6.4.1, Tables 2 and 3. This enum encapsulates the various modes in which
22
- * data can be encoded to bits in the QR code standard.</p>
23
- *
24
- * @author Sean Owen
25
- */
26
- class Mode {
27
- static $TERMINATOR;
28
- static $NUMERIC;
29
- static $ALPHANUMERIC;
30
- static $STRUCTURED_APPEND;
31
- static $BYTE;
32
- static $ECI;
33
- static $KANJI;
34
- static $FNC1_FIRST_POSITION;
35
- static $FNC1_SECOND_POSITION;
36
- static $HANZI;
37
-
38
-
39
- private $characterCountBitsForVersions;
40
- private $bits;
41
-
42
- function __construct($characterCountBitsForVersions, $bits) {
43
- $this->characterCountBitsForVersions = $characterCountBitsForVersions;
44
- $this->bits = $bits;
45
- }
46
- static function Init()
47
- {
48
-
49
-
50
- self::$TERMINATOR = new Mode(array(0, 0, 0), 0x00); // Not really a mode...
51
- self::$NUMERIC = new Mode(array(10, 12, 14), 0x01);
52
- self::$ALPHANUMERIC = new Mode(array(9, 11, 13), 0x02);
53
- self::$STRUCTURED_APPEND = new Mode(array(0, 0, 0), 0x03); // Not supported
54
- self::$BYTE = new Mode(array(8, 16, 16), 0x04);
55
- self::$ECI = new Mode(array(0, 0, 0), 0x07); // character counts don't apply
56
- self::$KANJI = new Mode(array(8, 10, 12), 0x08);
57
- self::$FNC1_FIRST_POSITION = new Mode(array(0, 0, 0), 0x05);
58
- self::$FNC1_SECOND_POSITION =new Mode(array(0, 0, 0), 0x09);
59
- /** See GBT 18284-2000; "Hanzi" is a transliteration of this mode name. */
60
- self::$HANZI = new Mode(array(8, 10, 12), 0x0D);
61
- }
62
- /**
63
- * @param bits four bits encoding a QR Code data mode
64
- * @return Mode encoded by these bits
65
- * @throws IllegalArgumentException if bits do not correspond to a known mode
66
- */
67
- public static function forBits($bits) {
68
- switch ($bits) {
69
- case 0x0:
70
- return self::$TERMINATOR;
71
- case 0x1:
72
- return self::$NUMERIC;
73
- case 0x2:
74
- return self::$ALPHANUMERIC;
75
- case 0x3:
76
- return self::$STRUCTURED_APPEND;
77
- case 0x4:
78
- return self::$BYTE;
79
- case 0x5:
80
- return self::$FNC1_FIRST_POSITION;
81
- case 0x7:
82
- return self::$ECI;
83
- case 0x8:
84
- return self::$KANJI;
85
- case 0x9:
86
- return self::$FNC1_SECOND_POSITION;
87
- case 0xD:
88
- // 0xD is defined in GBT 18284-2000, may not be supported in foreign country
89
- return self::$HANZI;
90
- default:
91
- throw new \InvalidArgumentException();
92
- }
93
- }
94
-
95
- /**
96
- * @param version version in question
97
- * @return number of bits used, in this QR Code symbol {@link Version}, to encode the
98
- * count of characters that will follow encoded in this Mode
99
- */
100
- public function getCharacterCountBits($version) {
101
- $number = $version->getVersionNumber();
102
- $offset = 0;
103
- if ($number <= 9) {
104
- $offset = 0;
105
- } else if ($number <= 26) {
106
- $offset = 1;
107
- } else {
108
- $offset = 2;
109
- }
110
- return $this->characterCountBitsForVersions[$offset];
111
- }
112
-
113
- public function getBits() {
114
- return $this->bits;
115
- }
116
-
117
- }
118
- Mode::Init();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/decoder/Version.php DELETED
@@ -1,619 +0,0 @@
1
- <?php
2
- /*
3
- * Copyright 2007 ZXing authors
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
-
18
- namespace Zxing\Qrcode\Decoder;
19
-
20
- use Zxing\FormatException;
21
- use Zxing\Common\BitMatrix;
22
-
23
- /**
24
- * See ISO 18004:2006 Annex D
25
- *
26
- * @author Sean Owen
27
- */
28
- class Version
29
- {
30
-
31
- /**
32
- * See ISO 18004:2006 Annex D.
33
- * Element i represents the raw version bits that specify version i + 7
34
- */
35
- private static $VERSION_DECODE_INFO = array(
36
- 0x07C94, 0x085BC, 0x09A99, 0x0A4D3, 0x0BBF6,
37
- 0x0C762, 0x0D847, 0x0E60D, 0x0F928, 0x10B78,
38
- 0x1145D, 0x12A17, 0x13532, 0x149A6, 0x15683,
39
- 0x168C9, 0x177EC, 0x18EC4, 0x191E1, 0x1AFAB,
40
- 0x1B08E, 0x1CC1A, 0x1D33F, 0x1ED75, 0x1F250,
41
- 0x209D5, 0x216F0, 0x228BA, 0x2379F, 0x24B0B,
42
- 0x2542E, 0x26A64, 0x27541, 0x28C69
43
- );
44
-
45
- private static $VERSIONS;
46
- private $versionNumber;
47
- private $alignmentPatternCenters;
48
- private $ecBlocks;
49
- private $totalCodewords;
50
-
51
- public function __construct($versionNumber,
52
- $alignmentPatternCenters,
53
- $ecBlocks)
54
- {//ECBlocks... ecBlocks
55
-
56
-
57
-
58
- $this->versionNumber = $versionNumber;
59
- $this->alignmentPatternCenters = $alignmentPatternCenters;
60
- $this->ecBlocks = $ecBlocks;
61
- $total = 0;
62
- if(is_array($ecBlocks)) {
63
- $ecCodewords = $ecBlocks[0]->getECCodewordsPerBlock();
64
- $ecbArray = $ecBlocks[0]->getECBlocks();
65
- }else{
66
- $ecCodewords = $ecBlocks->getECCodewordsPerBlock();
67
- $ecbArray = $ecBlocks->getECBlocks();
68
- }
69
- foreach ($ecbArray as $ecBlock) {
70
- $total += $ecBlock->getCount() * ($ecBlock->getDataCodewords() + $ecCodewords);
71
- }
72
- $this->totalCodewords = $total;
73
- }
74
- public function getVersionNumber()
75
- {
76
- return $this->versionNumber;
77
- }
78
-
79
- public function getAlignmentPatternCenters()
80
- {
81
- return $this->alignmentPatternCenters;
82
- }
83
-
84
- public function getTotalCodewords()
85
- {
86
- return $this->totalCodewords;
87
- }
88
-
89
- public function getDimensionForVersion()
90
- {
91
- return 17 + 4 * $this->versionNumber;
92
- }
93
-
94
- public function getECBlocksForLevel($ecLevel)
95
- {
96
- return $this->ecBlocks[$ecLevel->getOrdinal()];
97
- }
98
-
99
- /**
100
- * <p>Deduces version information purely from QR Code dimensions.</p>
101
- *
102
- * @param dimension dimension in modules
103
- * @return Version for a QR Code of that dimension
104
- * @throws FormatException if dimension is not 1 mod 4
105
- */
106
- public static function getProvisionalVersionForDimension($dimension)
107
- {
108
- if ($dimension % 4 != 1) {
109
- throw FormatException::getFormatInstance();
110
- }
111
- try {
112
- return self::getVersionForNumber(($dimension - 17) / 4);
113
- } catch (InvalidArgumentException $ignored) {
114
- throw FormatException::getFormatInstance();
115
- }
116
- }
117
-
118
- public static function getVersionForNumber($versionNumber)
119
- {
120
- if ($versionNumber < 1 || $versionNumber > 40) {
121
- throw new \InvalidArgumentException();
122
- }
123
- if(!self::$VERSIONS){
124
-
125
- self::$VERSIONS = self::buildVersions();
126
-
127
- }
128
- return self::$VERSIONS[$versionNumber - 1];
129
- }
130
-
131
- static function decodeVersionInformation($versionBits)
132
- {
133
- $bestDifference = PHP_INT_MAX;
134
- $bestVersion = 0;
135
- for ($i = 0; $i < count(self::$VERSION_DECODE_INFO); $i++) {
136
- $targetVersion = self::$VERSION_DECODE_INFO[$i];
137
- // Do the version info bits match exactly? done.
138
- if ($targetVersion == $versionBits) {
139
- return self::getVersionForNumber($i + 7);
140
- }
141
- // Otherwise see if this is the closest to a real version info bit string
142
- // we have seen so far
143
- $bitsDifference = FormatInformation::numBitsDiffering($versionBits, $targetVersion);
144
- if ($bitsDifference < $bestDifference) {
145
- $bestVersion = $i + 7;
146
- $bestDifference = $bitsDifference;
147
- }
148
- }
149
- // We can tolerate up to 3 bits of error since no two version info codewords will
150
- // differ in less than 8 bits.
151
- if ($bestDifference <= 3) {
152
- return self::getVersionForNumber($bestVersion);
153
- }
154
- // If we didn't find a close enough match, fail
155
- return null;
156
- }
157
-
158
- /**
159
- * See ISO 18004:2006 Annex E
160
- */
161
- function buildFunctionPattern()
162
- {
163
- $dimension = self::getDimensionForVersion();
164
- $bitMatrix = new BitMatrix($dimension);
165
-
166
- // Top left finder pattern + separator + format
167
- $bitMatrix->setRegion(0, 0, 9, 9);
168
- // Top right finder pattern + separator + format
169
- $bitMatrix->setRegion($dimension - 8, 0, 8, 9);
170
- // Bottom left finder pattern + separator + format
171
- $bitMatrix->setRegion(0, $dimension - 8, 9, 8);
172
-
173
- // Alignment patterns
174
- $max = count($this->alignmentPatternCenters);
175
- for ($x = 0; $x < $max; $x++) {
176
- $i = $this->alignmentPatternCenters[$x] - 2;
177
- for ($y = 0; $y < $max; $y++) {
178
- if (($x == 0 && ($y == 0 || $y == $max - 1)) || ($x == $max - 1 && $y == 0)) {
179
- // No alignment patterns near the three finder paterns
180
- continue;
181
- }
182
- $bitMatrix->setRegion($this->alignmentPatternCenters[$y] - 2, $i, 5, 5);
183
- }
184
- }
185
-
186
- // Vertical timing pattern
187
- $bitMatrix->setRegion(6, 9, 1, $dimension - 17);
188
- // Horizontal timing pattern
189
- $bitMatrix->setRegion(9, 6, $dimension - 17, 1);
190
-
191
- if ($this->versionNumber > 6) {
192
- // Version info, top right
193
- $bitMatrix->setRegion($dimension - 11, 0, 3, 6);
194
- // Version info, bottom left
195
- $bitMatrix->setRegion(0, $dimension - 11, 6, 3);
196
- }
197
-
198
- return $bitMatrix;
199
- }
200
- /**
201
- * See ISO 18004:2006 6.5.1 Table 9
202
- */
203
- private static function buildVersions()
204
- {
205
-
206
-
207
- return array(
208
- new Version(1, array(),
209
- array(new ECBlocks(7, array(new ECB(1, 19))),
210
- new ECBlocks(10, array(new ECB(1, 16))),
211
- new ECBlocks(13, array(new ECB(1, 13))),
212
- new ECBlocks(17, array(new ECB(1, 9))))),
213
- new Version(2, array(6, 18),
214
- array(new ECBlocks(10, array(new ECB(1, 34))),
215
- new ECBlocks(16, array(new ECB(1, 28))),
216
- new ECBlocks(22, array(new ECB(1, 22))),
217
- new ECBlocks(28, array(new ECB(1, 16))))),
218
- new Version(3, array(6, 22),
219
- array( new ECBlocks(15, array(new ECB(1, 55))),
220
- new ECBlocks(26, array(new ECB(1, 44))),
221
- new ECBlocks(18, array(new ECB(2, 17))),
222
- new ECBlocks(22, array(new ECB(2, 13))))),
223
- new Version(4, array(6, 26),
224
- array(new ECBlocks(20, array(new ECB(1, 80))),
225
- new ECBlocks(18, array(new ECB(2, 32))),
226
- new ECBlocks(26, array(new ECB(2, 24))),
227
- new ECBlocks(16, array(new ECB(4, 9))))),
228
- new Version(5, array(6, 30),
229
- array(new ECBlocks(26, array(new ECB(1, 108))),
230
- new ECBlocks(24, array(new ECB(2, 43))),
231
- new ECBlocks(18, array(new ECB(2, 15),
232
- new ECB(2, 16))),
233
- new ECBlocks(22, array(new ECB(2, 11),
234
- new ECB(2, 12))))),
235
- new Version(6, array(6, 34),
236
- array(new ECBlocks(18, array(new ECB(2, 68))),
237
- new ECBlocks(16, array(new ECB(4, 27))),
238
- new ECBlocks(24, array(new ECB(4, 19))),
239
- new ECBlocks(28, array(new ECB(4, 15))))),
240
- new Version(7, array(6, 22, 38),
241
- array(new ECBlocks(20, array(new ECB(2, 78))),
242
- new ECBlocks(18, array(new ECB(4, 31))),
243
- new ECBlocks(18, array(new ECB(2, 14),
244
- new ECB(4, 15))),
245
- new ECBlocks(26, array(new ECB(4, 13),
246
- new ECB(1, 14))))),
247
- new Version(8, array(6, 24, 42),
248
- array(new ECBlocks(24, array(new ECB(2, 97))),
249
- new ECBlocks(22, array(new ECB(2, 38),
250
- new ECB(2, 39))),
251
- new ECBlocks(22, array(new ECB(4, 18),
252
- new ECB(2, 19))),
253
- new ECBlocks(26, array(new ECB(4, 14),
254
- new ECB(2, 15))))),
255
- new Version(9, array(6, 26, 46),
256
- array(new ECBlocks(30, array(new ECB(2, 116))),
257
- new ECBlocks(22, array(new ECB(3, 36),
258
- new ECB(2, 37))),
259
- new ECBlocks(20, array(new ECB(4, 16),
260
- new ECB(4, 17))),
261
- new ECBlocks(24, array(new ECB(4, 12),
262
- new ECB(4, 13))))),
263
- new Version(10, array(6, 28, 50),
264
- array(new ECBlocks(18, array(new ECB(2, 68),
265
- new ECB(2, 69))),
266
- new ECBlocks(26, array(new ECB(4, 43),
267
- new ECB(1, 44))),
268
- new ECBlocks(24, array(new ECB(6, 19),
269
- new ECB(2, 20))),
270
- new ECBlocks(28, array(new ECB(6, 15),
271
- new ECB(2, 16))))),
272
- new Version(11, array(6, 30, 54),
273
- array(new ECBlocks(20, array(new ECB(4, 81))),
274
- new ECBlocks(30, array(new ECB(1, 50),
275
- new ECB(4, 51))),
276
- new ECBlocks(28, array(new ECB(4, 22),
277
- new ECB(4, 23))),
278
- new ECBlocks(24, array(new ECB(3, 12),
279
- new ECB(8, 13))))),
280
- new Version(12, array(6, 32, 58),
281
- array(new ECBlocks(24, array(new ECB(2, 92),
282
- new ECB(2, 93))),
283
- new ECBlocks(22, array(new ECB(6, 36),
284
- new ECB(2, 37))),
285
- new ECBlocks(26, array(new ECB(4, 20),
286
- new ECB(6, 21))),
287
- new ECBlocks(28, array(new ECB(7, 14),
288
- new ECB(4, 15))))),
289
- new Version(13, array(6, 34, 62),
290
- array(new ECBlocks(26, array(new ECB(4, 107))),
291
- new ECBlocks(22, array(new ECB(8, 37),
292
- new ECB(1, 38))),
293
- new ECBlocks(24, array(new ECB(8, 20),
294
- new ECB(4, 21))),
295
- new ECBlocks(22, array(new ECB(12, 11),
296
- new ECB(4, 12))))),
297
- new Version(14, array(6, 26, 46, 66),
298
- array(new ECBlocks(30, array(new ECB(3, 115),
299
- new ECB(1, 116))),
300
- new ECBlocks(24, array(new ECB(4, 40),
301
- new ECB(5, 41))),
302
- new ECBlocks(20, array(new ECB(11, 16),
303
- new ECB(5, 17))),
304
- new ECBlocks(24, array(new ECB(11, 12),
305
- new ECB(5, 13))))),
306
- new Version(15, array(6, 26, 48, 70),
307
- array(new ECBlocks(22, array(new ECB(5, 87),
308
- new ECB(1, 88))),
309
- new ECBlocks(24, array(new ECB(5, 41),
310
- new ECB(5, 42))),
311
- new ECBlocks(30, array(new ECB(5, 24),
312
- new ECB(7, 25))),
313
- new ECBlocks(24, array(new ECB(11, 12),
314
- new ECB(7, 13))))),
315
- new Version(16, array(6, 26, 50, 74),
316
- array(new ECBlocks(24, array(new ECB(5, 98),
317
- new ECB(1, 99))),
318
- new ECBlocks(28, array(new ECB(7, 45),
319
- new ECB(3, 46))),
320
- new ECBlocks(24, array(new ECB(15, 19),
321
- new ECB(2, 20))),
322
- new ECBlocks(30, array(new ECB(3, 15),
323
- new ECB(13, 16))))),
324
- new Version(17, array(6, 30, 54, 78),
325
- array(new ECBlocks(28, array(new ECB(1, 107),
326
- new ECB(5, 108))),
327
- new ECBlocks(28, array(new ECB(10, 46),
328
- new ECB(1, 47))),
329
- new ECBlocks(28, array(new ECB(1, 22),
330
- new ECB(15, 23))),
331
- new ECBlocks(28, array(new ECB(2, 14),
332
- new ECB(17, 15))))),
333
- new Version(18, array(6, 30, 56, 82),
334
- array(new ECBlocks(30, array(new ECB(5, 120),
335
- new ECB(1, 121))),
336
- new ECBlocks(26, array(new ECB(9, 43),
337
- new ECB(4, 44))),
338
- new ECBlocks(28, array(new ECB(17, 22),
339
- new ECB(1, 23))),
340
- new ECBlocks(28, array(new ECB(2, 14),
341
- new ECB(19, 15))))),
342
- new Version(19, array(6, 30, 58, 86),
343
- array(new ECBlocks(28, array(new ECB(3, 113),
344
- new ECB(4, 114))),
345
- new ECBlocks(26, array(new ECB(3, 44),
346
- new ECB(11, 45))),
347
- new ECBlocks(26, array(new ECB(17, 21),
348
- new ECB(4, 22))),
349
- new ECBlocks(26, array(new ECB(9, 13),
350
- new ECB(16, 14))))),
351
- new Version(20, array(6, 34, 62, 90),
352
- array(new ECBlocks(28, array(new ECB(3, 107),
353
- new ECB(5, 108))),
354
- new ECBlocks(26, array(new ECB(3, 41),
355
- new ECB(13, 42))),
356
- new ECBlocks(30, array(new ECB(15, 24),
357
- new ECB(5, 25))),
358
- new ECBlocks(28, array(new ECB(15, 15),
359
- new ECB(10, 16))))),
360
- new Version(21, array(6, 28, 50, 72, 94),
361
- array( new ECBlocks(28, array(new ECB(4, 116),
362
- new ECB(4, 117))),
363
- new ECBlocks(26, array(new ECB(17, 42))),
364
- new ECBlocks(28, array(new ECB(17, 22),
365
- new ECB(6, 23))),
366
- new ECBlocks(30, array(new ECB(19, 16),
367
- new ECB(6, 17))))),
368
- new Version(22, array(6, 26, 50, 74, 98),
369
- array(new ECBlocks(28, array(new ECB(2, 111),
370
- new ECB(7, 112))),
371
- new ECBlocks(28, array(new ECB(17, 46))),
372
- new ECBlocks(30, array(new ECB(7, 24),
373
- new ECB(16, 25))),
374
- new ECBlocks(24, array(new ECB(34, 13))))),
375
- new Version(23, array(6, 30, 54, 78, 102),
376
- new ECBlocks(30, array(new ECB(4, 121),
377
- new ECB(5, 122))),
378
- new ECBlocks(28, array(new ECB(4, 47),
379
- new ECB(14, 48))),
380
- new ECBlocks(30, array(new ECB(11, 24),
381
- new ECB(14, 25))),
382
- new ECBlocks(30, array(new ECB(16, 15),
383
- new ECB(14, 16)))),
384
- new Version(24, array(6, 28, 54, 80, 106),
385
- array(new ECBlocks(30, array(new ECB(6, 117),
386
- new ECB(4, 118))),
387
- new ECBlocks(28, array(new ECB(6, 45),
388
- new ECB(14, 46))),
389
- new ECBlocks(30, array(new ECB(11, 24),
390
- new ECB(16, 25))),
391
- new ECBlocks(30, array(new ECB(30, 16),
392
- new ECB(2, 17))))),
393
- new Version(25, array(6, 32, 58, 84, 110),
394
- array(new ECBlocks(26, array(new ECB(8, 106),
395
- new ECB(4, 107))),
396
- new ECBlocks(28, array(new ECB(8, 47),
397
- new ECB(13, 48))),
398
- new ECBlocks(30, array(new ECB(7, 24),
399
- new ECB(22, 25))),
400
- new ECBlocks(30, array(new ECB(22, 15),
401
- new ECB(13, 16))))),
402
- new Version(26, array(6, 30, 58, 86, 114),
403
- array(new ECBlocks(28, array(new ECB(10, 114),
404
- new ECB(2, 115))),
405
- new ECBlocks(28, array(new ECB(19, 46),
406
- new ECB(4, 47))),
407
- new ECBlocks(28, array(new ECB(28, 22),
408
- new ECB(6, 23))),
409
- new ECBlocks(30, array(new ECB(33, 16),
410
- new ECB(4, 17))))),
411
- new Version(27, array(6, 34, 62, 90, 118),
412
- array(new ECBlocks(30, array(new ECB(8, 122),
413
- new ECB(4, 123))),
414
- new ECBlocks(28, array(new ECB(22, 45),
415
- new ECB(3, 46))),
416
- new ECBlocks(30, array(new ECB(8, 23),
417
- new ECB(26, 24))),
418
- new ECBlocks(30, array(new ECB(12, 15),
419
- new ECB(28, 16))))),
420
- new Version(28, array(6, 26, 50, 74, 98, 122),
421
- array(new ECBlocks(30, array(new ECB(3, 117),
422
- new ECB(10, 118))),
423
- new ECBlocks(28, array(new ECB(3, 45),
424
- new ECB(23, 46))),
425
- new ECBlocks(30, array(new ECB(4, 24),
426
- new ECB(31, 25))),
427
- new ECBlocks(30, array(new ECB(11, 15),
428
- new ECB(31, 16))))),
429
- new Version(29, array(6, 30, 54, 78, 102, 126),
430
- array(new ECBlocks(30, array(new ECB(7, 116),
431
- new ECB(7, 117))),
432
- new ECBlocks(28, array(new ECB(21, 45),
433
- new ECB(7, 46))),
434
- new ECBlocks(30, array(new ECB(1, 23),
435
- new ECB(37, 24))),
436
- new ECBlocks(30, array(new ECB(19, 15),
437
- new ECB(26, 16))))),
438
- new Version(30, array(6, 26, 52, 78, 104, 130),
439
- array(new ECBlocks(30, array(new ECB(5, 115),
440
- new ECB(10, 116))),
441
- new ECBlocks(28, array(new ECB(19, 47),
442
- new ECB(10, 48))),
443
- new ECBlocks(30, array(new ECB(15, 24),
444
- new ECB(25, 25))),
445
- new ECBlocks(30, array(new ECB(23, 15),
446
- new ECB(25, 16))))),
447
- new Version(31, array(6, 30, 56, 82, 108, 134),
448
- array(new ECBlocks(30, array(new ECB(13, 115),
449
- new ECB(3, 116))),
450
- new ECBlocks(28, array(new ECB(2, 46),
451
- new ECB(29, 47))),
452
- new ECBlocks(30, array(new ECB(42, 24),
453
- new ECB(1, 25))),
454
- new ECBlocks(30, array(new ECB(23, 15),
455
- new ECB(28, 16))))),
456
- new Version(32, array(6, 34, 60, 86, 112, 138),
457
- array(new ECBlocks(30, array(new ECB(17, 115))),
458
- new ECBlocks(28, array(new ECB(10, 46),
459
- new ECB(23, 47))),
460
- new ECBlocks(30, array(new ECB(10, 24),
461
- new ECB(35, 25))),
462
- new ECBlocks(30, array(new ECB(19, 15),
463
- new ECB(35, 16))))),
464
- new Version(33, array(6, 30, 58, 86, 114, 142),
465
- array(new ECBlocks(30, array(new ECB(17, 115),
466
- new ECB(1, 116))),
467
- new ECBlocks(28, array(new ECB(14, 46),
468
- new ECB(21, 47))),
469
- new ECBlocks(30, array(new ECB(29, 24),
470
- new ECB(19, 25))),
471
- new ECBlocks(30, array(new ECB(11, 15),
472
- new ECB(46, 16))))),
473
- new Version(34, array(6, 34, 62, 90, 118, 146),
474
- array(new ECBlocks(30, array(new ECB(13, 115),
475
- new ECB(6, 116))),
476
- new ECBlocks(28, array(new ECB(14, 46),
477
- new ECB(23, 47))),
478
- new ECBlocks(30, array(new ECB(44, 24),
479
- new ECB(7, 25))),
480
- new ECBlocks(30, array(new ECB(59, 16),
481
- new ECB(1, 17))))),
482
- new Version(35, array(6, 30, 54, 78, 102, 126, 150),
483
- array(new ECBlocks(30, array(new ECB(12, 121),
484
- new ECB(7, 122))),
485
- new ECBlocks(28, array(new ECB(12, 47),
486
- new ECB(26, 48))),
487
- new ECBlocks(30, array(new ECB(39, 24),
488
- new ECB(14, 25))),
489
- new ECBlocks(30, array(new ECB(22, 15),
490
- new ECB(41, 16))))),
491
- new Version(36, array(6, 24, 50, 76, 102, 128, 154),
492
- array(new ECBlocks(30, array(new ECB(6, 121),
493
- new ECB(14, 122))),
494
- new ECBlocks(28, array(new ECB(6, 47),
495
- new ECB(34, 48))),
496
- new ECBlocks(30, array(new ECB(46, 24),
497
- new ECB(10, 25))),
498
- new ECBlocks(30, array(new ECB(2, 15),
499
- new ECB(64, 16))))),
500
- new Version(37, array(6, 28, 54, 80, 106, 132, 158),
501
- array(new ECBlocks(30, array(new ECB(17, 122),
502
- new ECB(4, 123))),
503
- new ECBlocks(28, array(new ECB(29, 46),
504
- new ECB(14, 47))),
505
- new ECBlocks(30, array(new ECB(49, 24),
506
- new ECB(10, 25))),
507
- new ECBlocks(30, array(new ECB(24, 15),
508
- new ECB(46, 16))))),
509
- new Version(38, array(6, 32, 58, 84, 110, 136, 162),
510
- array(new ECBlocks(30, array(new ECB(4, 122),
511
- new ECB(18, 123))),
512
- new ECBlocks(28, array(new ECB(13, 46),
513
- new ECB(32, 47))),
514
- new ECBlocks(30, array(new ECB(48, 24),
515
- new ECB(14, 25))),
516
- new ECBlocks(30, array(new ECB(42, 15),
517
- new ECB(32, 16))))),
518
- new Version(39, array(6, 26, 54, 82, 110, 138, 166),
519
- array(new ECBlocks(30, array(new ECB(20, 117),
520
- new ECB(4, 118))),
521
- new ECBlocks(28, array(new ECB(40, 47),
522
- new ECB(7, 48))),
523
- new ECBlocks(30, array(new ECB(43, 24),
524
- new ECB(22, 25))),
525
- new ECBlocks(30, array(new ECB(10, 15),
526
- new ECB(67, 16))))),
527
- new Version(40, array(6, 30, 58, 86, 114, 142, 170),
528
- array(new ECBlocks(30, array(new ECB(19, 118),
529
- new ECB(6, 119))),
530
- new ECBlocks(28, array(new ECB(18, 47),
531
- new ECB(31, 48))),
532
- new ECBlocks(30, array(new ECB(34, 24),
533
- new ECB(34, 25))),
534
- new ECBlocks(30, array(new ECB(20, 15),
535
- new ECB(61, 16)))))
536
- );
537
- }
538
- }
539
-
540
- /**
541
- * <p>Encapsulates a set of error-correction blocks in one symbol version. Most versions will
542
- * use blocks of differing sizes within one version, so, this encapsulates the parameters for
543
- * each set of blocks. It also holds the number of error-correction codewords per block since it
544
- * will be the same across all blocks within one version.</p>
545
- */
546
- final class ECBlocks
547
- {
548
- private $ecCodewordsPerBlock;
549
- private $ecBlocks;
550
-
551
- function __construct($ecCodewordsPerBlock, $ecBlocks)
552
- {
553
- $this->ecCodewordsPerBlock = $ecCodewordsPerBlock;
554
- $this->ecBlocks = $ecBlocks;
555
- }
556
-
557
- public function getECCodewordsPerBlock()
558
- {
559
- return $this->ecCodewordsPerBlock;
560
- }
561
-
562
- public function getNumBlocks()
563
- {
564
- $total = 0;
565
- foreach ($this->ecBlocks as $ecBlock) {
566
- $total += $ecBlock->getCount();
567
- }
568
- return $total;
569
- }
570
-
571
- public function getTotalECCodewords()
572
- {
573
- return $this->ecCodewordsPerBlock * $this->getNumBlocks();
574
- }
575
-
576
- public function getECBlocks()
577
- {
578
- return $this->ecBlocks;
579
- }
580
- }
581
-
582
- /**
583
- * <p>Encapsualtes the parameters for one error-correction block in one symbol version.
584
- * This includes the number of data codewords, and the number of times a block with these
585
- * parameters is used consecutively in the QR code version's format.</p>
586
- */
587
- final class ECB
588
- {
589
- private $count;
590
- private $dataCodewords;
591
-
592
- function __construct($count, $dataCodewords)
593
- {
594
- $this->count = $count;
595
- $this->dataCodewords = $dataCodewords;
596
- }
597
-
598
- public function getCount()
599
- {
600
- return $this->count;
601
- }
602
-
603
- public function getDataCodewords()
604
- {
605
- return $this->dataCodewords;
606
- }
607
-
608
-
609
- //@Override
610
- public function toString()
611
- {
612
- die('Version ECB toString()');
613
- // return parent::$versionNumber;
614
- }
615
-
616
-
617
- }
618
-
619
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/detector/AlignmentPattern.php DELETED
@@ -1,60 +0,0 @@
1
- <?php
2
- /*
3
- * Copyright 2007 ZXing authors
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
-
18
- namespace Zxing\Qrcode\Detector;
19
-
20
- use Zxing\ResultPoint;
21
-
22
- /**
23
- * <p>Encapsulates an alignment pattern, which are the smaller square patterns found in
24
- * all but the simplest QR Codes.</p>
25
- *
26
- * @author Sean Owen
27
- */
28
- final class AlignmentPattern extends ResultPoint {
29
-
30
- private $estimatedModuleSize;
31
-
32
- function __construct($posX, $posY, $estimatedModuleSize) {
33
- parent::__construct($posX, $posY);
34
- $this->estimatedModuleSize = $estimatedModuleSize;
35
- }
36
-
37
- /**
38
- * <p>Determines if this alignment pattern "about equals" an alignment pattern at the stated
39
- * position and size -- meaning, it is at nearly the same center with nearly the same size.</p>
40
- */
41
- function aboutEquals($moduleSize, $i, $j) {
42
- if (abs($i - $this->getY()) <= $moduleSize && abs($j - $this->getX()) <= $moduleSize) {
43
- $moduleSizeDiff = abs($moduleSize - $this->estimatedModuleSize);
44
- return $moduleSizeDiff <= 1.0 || $moduleSizeDiff <= $this->estimatedModuleSize;
45
- }
46
- return false;
47
- }
48
-
49
- /**
50
- * Combines this object's current estimate of a finder pattern position and module size
51
- * with a new estimate. It returns a new {@code FinderPattern} containing an average of the two.
52
- */
53
- function combineEstimate($i, $j, $newModuleSize) {
54
- $combinedX = ($this->getX() + $j) / 2.0;
55
- $combinedY = ($this->getY() + $i) / 2.0;
56
- $combinedModuleSize = ($this->estimatedModuleSize + $newModuleSize) / 2.0;
57
- return new AlignmentPattern($combinedX, $combinedY, $combinedModuleSize);
58
- }
59
-
60
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/detector/AlignmentPatternFinder.php DELETED
@@ -1,277 +0,0 @@
1
- <?php
2
- /*
3
- * Copyright 2007 ZXing authors
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
-
18
- namespace Zxing\Qrcode\Detector;
19
-
20
- use Zxing\NotFoundException;
21
- use Zxing\ResultPointCallback;
22
- use Zxing\Common\BitMatrix;
23
-
24
-
25
- /**
26
- * <p>This class attempts to find alignment patterns in a QR Code. Alignment patterns look like finder
27
- * patterns but are smaller and appear at regular intervals throughout the image.</p>
28
- *
29
- * <p>At the moment this only looks for the bottom-right alignment pattern.</p>
30
- *
31
- * <p>This is mostly a simplified copy of {@link FinderPatternFinder}. It is copied,
32
- * pasted and stripped down here for maximum performance but does unfortunately duplicate
33
- * some code.</p>
34
- *
35
- * <p>This class is thread-safe but not reentrant. Each thread must allocate its own object.</p>
36
- *
37
- * @author Sean Owen
38
- */
39
- final class AlignmentPatternFinder {
40
-
41
- private $image;
42
- private $possibleCenters;
43
- private $startX;
44
- private $startY;
45
- private $width;
46
- private $height;
47
- private $moduleSize;
48
- private $crossCheckStateCount;
49
- private $resultPointCallback;
50
-
51
- /**
52
- * <p>Creates a finder that will look in a portion of the whole image.</p>
53
- *
54
- * @param image image to search
55
- * @param startX left column from which to start searching
56
- * @param startY top row from which to start searching
57
- * @param width width of region to search
58
- * @param height height of region to search
59
- * @param moduleSize estimated module size so far
60
- */
61
- function __construct($image,
62
- $startX,
63
- $startY,
64
- $width,
65
- $height,
66
- $moduleSize,
67
- $resultPointCallback) {
68
- $this->image = $image;
69
- $this->possibleCenters = array();
70
- $this->startX = $startX;
71
- $this->startY = $startY;
72
- $this->width = $width;
73
- $this->height = $height;
74
- $this->moduleSize = $moduleSize;
75
- $this->crossCheckStateCount = array();
76
- $this->resultPointCallback = $resultPointCallback;
77
- }
78
-
79
- /**
80
- * <p>This method attempts to find the bottom-right alignment pattern in the image. It is a bit messy since
81
- * it's pretty performance-critical and so is written to be fast foremost.</p>
82
- *
83
- * @return {@link AlignmentPattern} if found
84
- * @throws NotFoundException if not found
85
- */
86
- function find() {
87
- $startX = $this->startX;
88
- $height = $this->height;
89
- $maxJ = $startX + $this->width;
90
- $middleI = $this->startY + ($height / 2);
91
- // We are looking for black/white/black modules in 1:1:1 ratio;
92
- // this tracks the number of black/white/black modules seen so far
93
- $stateCount = array();
94
- for ($iGen = 0; $iGen < $height; $iGen++) {
95
- // Search from middle outwards
96
- $i = $middleI + (($iGen & 0x01) == 0 ? ($iGen + 1) / 2 : -(($iGen + 1) / 2));
97
- $i = intval($i);
98
- $stateCount[0] = 0;
99
- $stateCount[1] = 0;
100
- $stateCount[2] = 0;
101
- $j = $startX;
102
- // Burn off leading white pixels before anything else; if we start in the middle of
103
- // a white run, it doesn't make sense to count its length, since we don't know if the
104
- // white run continued to the left of the start point
105
- while ($j < $maxJ && !$this->image->get($j, $i)) {
106
- $j++;
107
- }
108
- $currentState = 0;
109
- while ($j < $maxJ) {
110
- if ($this->image->get($j, $i)) {
111
- // Black pixel
112
- if ($currentState == 1) { // Counting black pixels
113
- $stateCount[$currentState]++;
114
- } else { // Counting white pixels
115
- if ($currentState == 2) { // A winner?
116
- if ($this->foundPatternCross($stateCount)) { // Yes
117
- $confirmed = $this->handlePossibleCenter($stateCount, $i, $j);
118
- if ($confirmed != null) {
119
- return $confirmed;
120
- }
121
- }
122
- $stateCount[0] = $stateCount[2];
123
- $stateCount[1] = 1;
124
- $stateCount[2] = 0;
125
- $currentState = 1;
126
- } else {
127
- $stateCount[++$currentState]++;
128
- }
129
- }
130
- } else { // White pixel
131
- if ($currentState == 1) { // Counting black pixels
132
- $currentState++;
133
- }
134
- $stateCount[$currentState]++;
135
- }
136
- $j++;
137
- }
138
- if ($this->foundPatternCross($stateCount)) {
139
- $confirmed = $this->handlePossibleCenter($stateCount, $i, $maxJ);
140
- if ($confirmed != null) {
141
- return $confirmed;
142
- }
143
- }
144
-
145
- }
146
-
147
- // Hmm, nothing we saw was observed and confirmed twice. If we had
148
- // any guess at all, return it.
149
- if (count($this->possibleCenters)) {
150
- return $this->possibleCenters[0];
151
- }
152
-
153
- throw NotFoundException::getNotFoundInstance();
154
- }
155
-
156
- /**
157
- * Given a count of black/white/black pixels just seen and an end position,
158
- * figures the location of the center of this black/white/black run.
159
- */
160
- private static function centerFromEnd($stateCount, $end) {
161
- return (float) ($end - $stateCount[2]) - $stateCount[1] / 2.0;
162
- }
163
-
164
- /**
165
- * @param stateCount count of black/white/black pixels just read
166
- * @return true iff the proportions of the counts is close enough to the 1/1/1 ratios
167
- * used by alignment patterns to be considered a match
168
- */
169
- private function foundPatternCross($stateCount) {
170
- $moduleSize = $this->moduleSize;
171
- $maxVariance = $moduleSize / 2.0;
172
- for ($i = 0; $i < 3; $i++) {
173
- if (abs($moduleSize - $stateCount[$i]) >= $maxVariance) {
174
- return false;
175
- }
176
- }
177
- return true;
178
- }
179
-
180
- /**
181
- * <p>After a horizontal scan finds a potential alignment pattern, this method
182
- * "cross-checks" by scanning down vertically through the center of the possible
183
- * alignment pattern to see if the same proportion is detected.</p>
184
- *
185
- * @param startI row where an alignment pattern was detected
186
- * @param centerJ center of the section that appears to cross an alignment pattern
187
- * @param maxCount maximum reasonable number of modules that should be
188
- * observed in any reading state, based on the results of the horizontal scan
189
- * @return vertical center of alignment pattern, or {@link Float#NaN} if not found
190
- */
191
- private function crossCheckVertical($startI, $centerJ, $maxCount,
192
- $originalStateCountTotal) {
193
- $image = $this->image;
194
-
195
- $maxI = $image->getHeight();
196
- $stateCount = $this->crossCheckStateCount;
197
- $stateCount[0] = 0;
198
- $stateCount[1] = 0;
199
- $stateCount[2] = 0;
200
-
201
- // Start counting up from center
202
- $i = $startI;
203
- while ($i >= 0 && $image->get($centerJ, $i) && $stateCount[1] <= $maxCount) {
204
- $stateCount[1]++;
205
- $i--;
206
- }
207
- // If already too many modules in this state or ran off the edge:
208
- if ($i < 0 || $stateCount[1] > $maxCount) {
209
- return NAN;
210
- }
211
- while ($i >= 0 && !$image->get($centerJ, $i) && $stateCount[0] <= $maxCount) {
212
- $stateCount[0]++;
213
- $i--;
214
- }
215
- if ($stateCount[0] > $maxCount) {
216
- return NAN;
217
- }
218
-
219
- // Now also count down from center
220
- $i = $startI + 1;
221
- while ($i < $maxI && $image->get($centerJ, $i) && $stateCount[1] <= $maxCount) {
222
- $stateCount[1]++;
223
- $i++;
224
- }
225
- if ($i == $maxI || $stateCount[1] > $maxCount) {
226
- return NAN;
227
- }
228
- while ($i < $maxI && !$image->get($centerJ, $i) && $stateCount[2] <= $maxCount) {
229
- $stateCount[2]++;
230
- $i++;
231
- }
232
- if ($stateCount[2] > $maxCount) {
233
- return NAN;
234
- }
235
-
236
- $stateCountTotal = $stateCount[0] + $stateCount[1] + $stateCount[2];
237
- if (5 * abs($stateCountTotal - $originalStateCountTotal) >= 2 * $originalStateCountTotal) {
238
- return NAN;
239
- }
240
-
241
- return $this->foundPatternCross($stateCount) ? $this->centerFromEnd($stateCount, $i) : NAN;
242
- }
243
-
244
- /**
245
- * <p>This is called when a horizontal scan finds a possible alignment pattern. It will
246
- * cross check with a vertical scan, and if successful, will see if this pattern had been
247
- * found on a previous horizontal scan. If so, we consider it confirmed and conclude we have
248
- * found the alignment pattern.</p>
249
- *
250
- * @param stateCount reading state module counts from horizontal scan
251
- * @param i row where alignment pattern may be found
252
- * @param j end of possible alignment pattern in row
253
- * @return {@link AlignmentPattern} if we have found the same pattern twice, or null if not
254
- */
255
- private function handlePossibleCenter($stateCount, $i, $j) {
256
- $stateCountTotal = $stateCount[0] + $stateCount[1] + $stateCount[2];
257
- $centerJ = $this->centerFromEnd($stateCount, $j);
258
- $centerI = $this->crossCheckVertical($i, (int) $centerJ, 2 * $stateCount[1], $stateCountTotal);
259
- if (!is_nan($centerI)) {
260
- $estimatedModuleSize = (float) ($stateCount[0] + $stateCount[1] + $stateCount[2]) / 3.0;
261
- foreach ($this->possibleCenters as $center) {
262
- // Look for about the same center and module size:
263
- if ($center->aboutEquals($estimatedModuleSize, $centerI, $centerJ)) {
264
- return $center->combineEstimate($centerI, $centerJ, $estimatedModuleSize);
265
- }
266
- }
267
- // Hadn't found this before; save it
268
- $point = new AlignmentPattern($centerJ, $centerI, $estimatedModuleSize);
269
- $this->possibleCenters[] = $point;
270
- if ($this->resultPointCallback != null) {
271
- $this->resultPointCallback->foundPossibleResultPoint($point);
272
- }
273
- }
274
- return null;
275
- }
276
-
277
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/vendor/khanamiryan/qrcode-detector-decoder/lib/qrcode/detector/Detector.php DELETED
@@ -1,405 +0,0 @@
1
- <?php
2
- /*
3
- * Copyright 2007 ZXing authors
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
-
18
- namespace Zxing\Qrcode\Detector;
19
-
20
- use Zxing\DecodeHintType;
21
- use Zxing\FormatException;
22
- use Zxing\NotFoundException;
23
- use Zxing\ResultPoint;
24
- use Zxing\ResultPointCallback;
25
- use Zxing\Common\BitMatrix;
26
- use Zxing\Common\DetectorResult;
27
- use Zxing\Common\GridSampler;
28
- use Zxing\Common\PerspectiveTransform;
29
- use Zxing\Common\Detector\MathUtils;
30
- use Zxing\Qrcode\Decoder\Version;
31
-
32
-
33
- /**
34
- * <p>Encapsulates logic that can detect a QR Code in an image, even if the QR Code
35
- * is rotated or skewed, or partially obscured.</p>
36
- *
37
- * @author Sean Owen
38
- */
39
- ?>
40
- <?php
41
- class Detector {
42
-
43
- private $image;
44
- private $resultPointCallback;
45
-
46
- public function __construct($image) {
47
- $this->image = $image;
48
- }
49
-
50
- protected final function getImage() {
51
- return $this->image;
52
- }
53
-
54
- protected final function getResultPointCallback() {
55
- return $this->resultPointCallback;
56
- }
57
-
58
- /**
59
- * <p>Detects a QR Code in an image.</p>
60
- *
61
- * @return {@link DetectorResult} encapsulating results of detecting a QR Code
62
- * @throws NotFoundException if QR Code cannot be found
63
- * @throws FormatException if a QR Code cannot be decoded
64
- */
65
-
66
-
67
- /**
68
- * <p>Detects a QR Code in an image.</p>
69
- *
70
- * @param hints optional hints to detector
71
- * @return {@link DetectorResult} encapsulating results of detecting a QR Code
72
- * @throws NotFoundException if QR Code cannot be found
73
- * @throws FormatException if a QR Code cannot be decoded
74
- */
75
- public final function detect($hints=null){/*Map<DecodeHintType,?>*/
76
-
77
- $resultPointCallback = $hints == null ? null :
78
- $hints->get('NEED_RESULT_POINT_CALLBACK');
79
- /* resultPointCallback = hints == null ? null :
80
- (ResultPointCallback) hints.get(DecodeHintType.NEED_RESULT_POINT_CALLBACK);*/
81
- $finder = new FinderPatternFinder($this->image, $resultPointCallback);
82
- $info = $finder->find($hints);
83
-
84
- return $this->processFinderPatternInfo($info);
85
- }
86
-
87
- protected final function processFinderPatternInfo($info){
88
-
89
- $topLeft = $info->getTopLeft();
90
- $topRight = $info->getTopRight();
91
- $bottomLeft = $info->getBottomLeft();
92
-
93
- $moduleSize = (float) $this->calculateModuleSize($topLeft, $topRight, $bottomLeft);
94
- if ($moduleSize < 1.0) {
95
- throw NotFoundException::getNotFoundInstance();
96
- }
97
- $dimension =(int) $this->computeDimension($topLeft, $topRight, $bottomLeft, $moduleSize);
98
- $provisionalVersion = Version::getProvisionalVersionForDimension($dimension);
99
- $modulesBetweenFPCenters = $provisionalVersion->getDimensionForVersion() - 7;
100
-
101
- $alignmentPattern = null;
102
- // Anything above version 1 has an alignment pattern
103
- if (count($provisionalVersion->getAlignmentPatternCenters())> 0) {
104
-
105
- // Guess where a "bottom right" finder pattern would have been
106
- $bottomRightX = $topRight->getX() - $topLeft->getX() + $bottomLeft->getX();
107
- $bottomRightY = $topRight->getY() - $topLeft->getY() + $bottomLeft->getY();
108
-
109
- // Estimate that alignment pattern is closer by 3 modules
110
- // from "bottom right" to known top left location
111
- $correctionToTopLeft = 1.0 - 3.0 / (float) $modulesBetweenFPCenters;
112
- $estAlignmentX = (int) ($topLeft->getX() + $correctionToTopLeft * ($bottomRightX - $topLeft->getX()));
113
- $estAlignmentY = (int) ($topLeft->getY() + $correctionToTopLeft * ($bottomRightY - $topLeft->getY()));
114
-
115
- // Kind of arbitrary -- expand search radius before giving up
116
- for ($i = 4; $i <= 16; $i <<= 1) {//??????????
117
- try {
118
- $alignmentPattern = $this->findAlignmentInRegion($moduleSize,
119
- $estAlignmentX,
120
- $estAlignmentY,
121
- (float) $i);
122
- break;
123
- } catch (NotFoundException $re) {
124
- // try next round
125
- }
126
- }
127
- // If we didn't find alignment pattern... well try anyway without it
128
- }
129
-
130
- $transform =
131
- $this->createTransform($topLeft, $topRight, $bottomLeft, $alignmentPattern, $dimension);
132
-
133
- $bits = $this->sampleGrid($this->image, $transform, $dimension);
134
-
135
- $points = array();
136
- if ($alignmentPattern == null) {
137
- $points = array($bottomLeft, $topLeft, $topRight);
138
- } else {
139
- // die('$points = new ResultPoint[]{bottomLeft, topLeft, topRight, alignmentPattern};');
140
- $points = array($bottomLeft, $topLeft, $topRight, $alignmentPattern);
141
- }
142
- return new DetectorResult($bits, $points);
143
- }
144
-
145
- private static function createTransform($topLeft,
146
- $topRight,
147
- $bottomLeft,
148
- $alignmentPattern,
149
- $dimension) {
150
- $dimMinusThree = (float) $dimension - 3.5;
151
- $bottomRightX = 0.0;
152
- $bottomRightY = 0.0;
153
- $sourceBottomRightX = 0.0;
154
- $sourceBottomRightY = 0.0;
155
- if ($alignmentPattern != null) {
156
- $bottomRightX = $alignmentPattern->getX();
157
- $bottomRightY = $alignmentPattern->getY();
158
- $sourceBottomRightX = $dimMinusThree - 3.0;
159
- $sourceBottomRightY = $sourceBottomRightX;
160
- } else {
161
- // Don't have an alignment pattern, just make up the bottom-right point
162
- $bottomRightX = ($topRight->getX() - $topLeft->getX()) + $bottomLeft->getX();
163
- $bottomRightY = ($topRight->getY() - $topLeft->getY()) + $bottomLeft->getY();
164
- $sourceBottomRightX = $dimMinusThree;
165
- $sourceBottomRightY = $dimMinusThree;
166
- }
167
-
168
- return PerspectiveTransform::quadrilateralToQuadrilateral(
169
- 3.5,
170
- 3.5,
171
- $dimMinusThree,
172
- 3.5,
173
- $sourceBottomRightX,
174
- $sourceBottomRightY,
175
- 3.5,
176
- $dimMinusThree,
177
- $topLeft->getX(),
178
- $topLeft->getY(),
179
- $topRight->getX(),
180
- $topRight->getY(),
181
- $bottomRightX,
182
- $bottomRightY,
183
- $bottomLeft->getX(),
184
- $bottomLeft->getY());
185
- }
186
-
187
- private static function sampleGrid($image, $transform,
188
- $dimension) {
189
-
190
- $sampler = GridSampler::getInstance();
191
- return $sampler->sampleGrid_($image, $dimension, $dimension, $transform);
192
- }
193
-
194
- /**
195
- * <p>Computes the dimension (number of modules on a size)