Shield Security for WordPress - Version 7.3.2

Version Description

  • Current Release = Released: 18th April, 2019 - Release Notes

  • (v.2) IMPROVED: Provided inline links for new Bot Signals options.

  • (v.2) CHANGED: Added a workaround for WPML plugin using old, buggy version of TWIG library.

  • (v.1) FIX: Protection against 404 tracking blocking visitors in some cases.

  • (v.0) NEW: [PRO] 7x New Bot Signals - rules to catch and block bad bots.

  • (v.0) ADDED: Date picker for filtering Audit Log entries.

  • (v.0) IMPROVED: Audit Log viewer now combines entries from the same request into 1 for better readability.

  • (v.0) CHANGED: Use a more refined clearing of WP Fastest Cache.

  • (v.0) FIX: Error displayed when deleting plugins in some cases.

  • (v.0) UPDATED: Translations for Chinese, Finnish, Turkish, Dutch, Italian, and German.

Download this release

Release Info

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

Code changes from version 7.2.3 to 7.3.2

Files changed (163) hide show
  1. changelog.html +77 -0
  2. icwp-plugin-controller.php +6 -14
  3. icwp-wpsf.php +14 -2
  4. languages/wp-simple-firewall-de_DE.mo +0 -0
  5. languages/wp-simple-firewall-fi.mo +0 -0
  6. languages/wp-simple-firewall-it_IT.mo +0 -0
  7. languages/wp-simple-firewall-nl_NL.mo +0 -0
  8. languages/wp-simple-firewall-ro_RO.mo +0 -0
  9. languages/wp-simple-firewall-sr_RS.mo +0 -0
  10. languages/wp-simple-firewall-tr_TR.mo +0 -0
  11. languages/wp-simple-firewall-zh_CN.mo +0 -0
  12. plugin-spec.php +4 -2
  13. readme.txt +18 -48
  14. resources/images/pluginlogo_32x32.png +0 -0
  15. resources/images/pluginlogo_col_32x32.png +0 -0
  16. resources/js/base64.min.js +1 -0
  17. resources/js/featherlight.js +60 -34
  18. resources/js/lz-string.min.js +1 -0
  19. resources/js/plugin.js +57 -1
  20. src/common/icwp-edd.php +2 -2
  21. src/common/icwp-render.php +14 -19
  22. src/common/icwp-wpfunctions.php +13 -11
  23. src/common/wp-admin-notices.php +1 -1
  24. src/config/feature-hack_protect.php +42 -0
  25. src/config/feature-ips.php +255 -21
  26. src/config/feature-login_protect.php +1 -0
  27. src/config/feature-mousetrap.php +0 -162
  28. src/config/feature-plugin.php +20 -10
  29. src/features/admin_access_restriction.php +10 -10
  30. src/features/autoupdates.php +11 -11
  31. src/features/base.php +95 -37
  32. src/features/base_wpsf.php +44 -10
  33. src/features/comments_filter.php +3 -3
  34. src/features/firewall.php +6 -6
  35. src/features/hack_protect.php +197 -15
  36. src/features/headers.php +5 -5
  37. src/features/insights.php +41 -10
  38. src/features/ips.php +244 -34
  39. src/features/license.php +4 -4
  40. src/features/lockdown.php +3 -3
  41. src/features/login_protect.php +17 -14
  42. src/features/mousetrap.php +0 -209
  43. src/features/plugin.php +83 -11
  44. src/features/sessions.php +1 -1
  45. src/features/statistics.php +1 -1
  46. src/features/traffic.php +4 -4
  47. src/features/user_management.php +3 -3
  48. src/lib/src/AuditTrail/Auditor.php +5 -2
  49. src/lib/src/Databases/Base/BaseQuery.php +14 -2
  50. src/lib/src/Databases/Base/EntryVO.php +2 -2
  51. src/lib/src/Databases/Base/Handler.php +2 -2
  52. src/lib/src/Databases/Base/Insert.php +3 -3
  53. src/lib/src/Databases/Base/Select.php +3 -3
  54. src/lib/src/Databases/Base/Update.php +3 -3
  55. src/lib/src/Databases/Session/Update.php +1 -1
  56. src/lib/src/Databases/Tally/Update.php +1 -1
  57. src/lib/src/Modules/IPs/BotTrack/Base.php +45 -0
  58. src/lib/src/Modules/IPs/BotTrack/Track404.php +25 -0
  59. src/lib/src/Modules/{MouseTrap/FakeWebCrawler.php → IPs/BotTrack/TrackFakeWebCrawler.php} +8 -20
  60. src/lib/src/Modules/{MouseTrap/LinkCheese.php → IPs/BotTrack/TrackLinkCheese.php} +15 -26
  61. src/lib/src/Modules/IPs/BotTrack/TrackLoginFailed.php +47 -0
  62. src/lib/src/Modules/IPs/BotTrack/TrackLoginInvalid.php +39 -0
  63. src/lib/src/Modules/IPs/BotTrack/TrackUserAgent.php +23 -0
  64. src/lib/src/Modules/IPs/BotTrack/TrackXmlRpc.php +24 -0
  65. src/lib/src/Modules/MouseTrap/Base.php +0 -44
  66. src/lib/src/Modules/MouseTrap/Detect404.php +0 -34
  67. src/lib/src/Modules/MouseTrap/DetectXmlRpc.php +0 -36
  68. src/lib/src/Modules/MouseTrap/InvalidUsername.php +0 -55
  69. src/lib/src/Scans/Apc/ResultsSet.php +2 -2
  70. src/lib/src/Scans/Apc/Scanner.php +1 -2
  71. src/lib/src/Scans/Base/BaseConvertResultsToVos.php +1 -1
  72. src/lib/src/Scans/Base/BaseResultsSet.php +1 -1
  73. src/lib/src/Scans/Helpers/BuildHashesFromDir.php +2 -2
  74. src/lib/src/Scans/Helpers/ScannerRecursiveFilterIterator.php +1 -1
  75. src/lib/src/Scans/Helpers/StandardDirectoryIterator.php +1 -1
  76. src/lib/src/Scans/Ptg/ResultsSet.php +2 -2
  77. src/lib/src/Scans/Ptg/ScanAssetDir.php +1 -1
  78. src/lib/src/Scans/Ptg/ScannerBase.php +1 -1
  79. src/lib/src/Scans/Ptg/Snapshots/Store.php +3 -3
  80. src/lib/src/Scans/Realtime/Files/Backup.php +27 -0
  81. src/lib/src/Scans/Realtime/Files/Process.php +75 -0
  82. src/lib/src/Scans/Realtime/Files/Revert.php +33 -0
  83. src/lib/src/Scans/Realtime/Files/TestWritable.php +26 -0
  84. src/lib/src/Scans/Realtime/Files/Verify.php +19 -0
  85. src/lib/src/Scans/Ufc/Scanner.php +3 -3
  86. src/lib/src/Scans/Wpv/ResultsSet.php +2 -2
  87. src/lib/src/Scans/Wpv/Scanner.php +2 -2
  88. src/lib/src/Scans/Wpv/WpVulnDb/RetrieveForItem.php +4 -4
  89. src/lib/src/Tables/Build/AdminNotes.php +1 -1
  90. src/lib/src/Tables/Build/AuditTrail.php +44 -12
  91. src/lib/src/Tables/Build/BaseBuild.php +3 -3
  92. src/lib/src/Tables/Build/Ip.php +1 -1
  93. src/lib/src/Tables/Build/ScanApc.php +1 -1
  94. src/lib/src/Tables/Build/ScanPtg.php +1 -1
  95. src/lib/src/Tables/Build/ScanUfc.php +1 -1
  96. src/lib/src/Tables/Build/ScanWcf.php +1 -1
  97. src/lib/src/Tables/Build/ScanWpv.php +1 -1
  98. src/lib/src/Tables/Build/Sessions.php +1 -1
  99. src/lib/src/Tables/Build/Traffic.php +2 -2
  100. src/lib/src/Tables/Render/Base.php +4 -4
  101. src/lib/vendor/composer/ClassLoader.php +4 -4
  102. src/lib/vendor/composer/autoload_classmap.php +25 -8
  103. src/lib/vendor/composer/autoload_namespaces.php +1 -0
  104. src/lib/vendor/composer/autoload_psr4.php +1 -0
  105. src/lib/vendor/composer/autoload_static.php +39 -8
  106. src/lib/vendor/composer/installed.json +409 -321
  107. src/lib/vendor/elliotchance/iterator/src/Elliotchance/Iterator/AbstractPagedIterator.php +144 -0
  108. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Iterators/WpUserIterator.php +134 -0
  109. src/lib/vendor/nullpunkt/lz-string-php/src/LZCompressor/LZContext.php +91 -0
  110. src/lib/vendor/nullpunkt/lz-string-php/src/LZCompressor/LZData.php +29 -0
  111. src/lib/vendor/nullpunkt/lz-string-php/src/LZCompressor/LZReverseDictionary.php +33 -0
  112. src/lib/vendor/nullpunkt/lz-string-php/src/LZCompressor/LZString.php +298 -0
  113. src/lib/vendor/nullpunkt/lz-string-php/src/LZCompressor/LZUtil.php +110 -0
  114. src/lib/vendor/nullpunkt/lz-string-php/src/LZCompressor/LZUtil16.php +90 -0
  115. src/processors/admin_access_restriction.php +2 -2
  116. src/processors/audit_trail_auditor.php +1 -2
  117. src/processors/audit_trail_auditor_base.php +1 -1
  118. src/processors/audit_trail_changetracking.php +1 -1
  119. src/processors/audit_trail_emails.php +2 -2
  120. src/processors/audit_trail_users.php +0 -14
  121. src/processors/autoupdates.php +9 -9
  122. src/processors/base.php +5 -5
  123. src/processors/base_plugin.php +1 -1
  124. src/processors/base_wpsf.php +15 -13
  125. src/processors/comments_filter.php +49 -23
  126. src/processors/commentsfilter_antibotspam.php +2 -2
  127. src/processors/commentsfilter_googlerecaptcha.php +1 -1
  128. src/processors/commentsfilter_humanspam.php +3 -3
  129. src/processors/email.php +1 -1
  130. src/processors/firewall.php +3 -3
  131. src/processors/hack_protect.php +14 -1
  132. src/processors/hackprotect_integrity.php +3 -3
  133. src/processors/hackprotect_realtime.php +59 -0
  134. src/processors/hackprotect_scan_apc.php +1 -1
  135. src/processors/hackprotect_scan_ptg.php +5 -5
  136. src/processors/hackprotect_scan_wcf.php +4 -4
  137. src/processors/hackprotect_scanner.php +4 -4
  138. src/processors/headers.php +2 -2
  139. src/processors/ips.php +48 -126
  140. src/processors/lockdown.php +1 -80
  141. src/processors/login_protect.php +30 -17
  142. src/processors/loginprotect_cooldown.php +9 -33
  143. src/processors/loginprotect_intent.php +1 -1
  144. src/processors/loginprotect_intent_tracker.php +2 -2
  145. src/processors/loginprotect_intentprovider_ga.php +1 -1
  146. src/processors/loginprotect_intentprovider_yubikey.php +1 -1
  147. src/processors/loginprotect_wplogin.php +1 -5
  148. src/processors/mousetrap.php +0 -51
  149. src/processors/plugin.php +10 -10
  150. src/processors/plugin_badge.php +2 -2
  151. src/processors/plugin_importexport.php +2 -2
  152. src/processors/plugin_notes.php +1 -1
  153. src/processors/plugin_tracking.php +1 -1
  154. src/processors/sessions.php +1 -1
  155. src/processors/statistics.php +3 -3
  156. src/processors/statistics_reporting.php +2 -2
  157. src/processors/statistics_tally.php +3 -3
  158. src/processors/traffic_logger.php +9 -7
  159. src/wizards/login_protect.php +2 -2
  160. src/wizards/plugin.php +1 -1
  161. templates/php/admin_bootstrap.php +6 -0
  162. templates/twig/wpadmin_pages/insights_new/audit/audit_table.twig +34 -6
  163. templates/twig/wpadmin_pages/insights_new/insights/index.twig +14 -1
changelog.html CHANGED
@@ -1,4 +1,81 @@
1
  <!DOCTYPE html><html><head><meta charset="utf-8"><title>Untitled Document.md</title><style></style></head><body id="preview">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  <p>= 6.9.0 - Series =<br>
3
  <em>Released: 6th September, 2018</em> - <a href="https://icwp.io/dc">Release Notes</a></p>
4
  <ul>
1
  <!DOCTYPE html><html><head><meta charset="utf-8"><title>Untitled Document.md</title><style></style></head><body id="preview">
2
+ <p>= 7.1 - Series =<br>
3
+ <em>Released: 21st February, 2019</em> - <a href="https://icwp.io/ek">Release Notes</a></p>
4
+ <ul>
5
+ <li><strong>(v.2)</strong> IMPROVED: Firewall email notification content now better reflect the information in the audit trail.</li>
6
+ <li><strong>(v.2)</strong> FIX: Firewall email notification was breaking in some instances.</li>
7
+ <li><strong>(v.1)</strong> FIX: IP retrieval.</li>
8
+ <li><strong>(v.0)</strong> NEW: Moved Import/Export UI from Wizard to main Shield Dashboard.</li>
9
+ <li><strong>(v.0)</strong> NEW: [<strong>PRO</strong>] Option to import/export settings using file downloads/uploads</li>
10
+ <li><strong>(v.0)</strong> NEW: [<strong>PRO</strong>] Option to allow visitors to automatically unblock themselves (once in 24hrs)</li>
11
+ <li><strong>(v.0)</strong> NEW: Integrated changelog directly into plugin admin for easy updates (between releases)</li>
12
+ <li><strong>(v.0)</strong> FIXED: WP Core files scanner now correctly ignores certain files as it used to do, pre-v7. e.g. wp-config-sample.php</li>
13
+ <li><strong>(v.0)</strong> FIXED: Shield was indicating plugin/theme file editing was possible, when it in-fact was disabled.</li>
14
+ <li><strong>(v.0)</strong> IMPROVED: Consolidate crons into fewer crons. e.g. all scans run under the same cron.</li>
15
+ </ul>
16
+ <p>= 7.0 - Series =<br>
17
+ <em>Released: 28th January, 2019</em> - <a href="https://icwp.io/ef">Release Notes</a></p>
18
+ <ul>
19
+ <li><strong>(v.4)</strong> IMPROVED: Refactored IP address blocking with improved audit trail messages.</li>
20
+ <li><strong>(v.4)</strong> CHANGED: Expanded anonymous REST API whitelist to include ‘wpstatistics’ namespace.</li>
21
+ <li><strong>(v.4)</strong> IMPROVED: Access protection for shield temp/caching dir.</li>
22
+ <li><strong>(v.4)</strong> IMPROVED: Clarification on reCAPTCHA - v3 is <strong>not</strong> supported.</li>
23
+ <li><strong>(v.4)</strong> IMPROVED: Clarification on user sessions timeout - Shield sets an absolutely session maximum.</li>
24
+ <li><strong>(v.4)</strong> IMPROVED: Options form submission is adjusted to work around poorly restrictive webhosts.</li>
25
+ <li><strong>(v.4)</strong> FIX: Various tweaks and fixes across the plugin.</li>
26
+ <li><strong>(v.4)</strong> FIX: Error with ClassicPress.</li>
27
+ <li><strong>(v.3)</strong> NEW: Automatically whitelist anonymous REST API Access for 3 plugins: Contact Form 7, WooCommerce, JetPack.</li>
28
+ <li><strong>(v.3)</strong> IMPROVED: Security admin login failure messages are clearer.</li>
29
+ <li><strong>(v.3)</strong> IMPROVED: Admin notification for email sending 2FA verification easily lets you resend email.</li>
30
+ <li><strong>(v.3)</strong> IMPROVED: File download code for WordPress Core file scanner repairs.</li>
31
+ <li><strong>(v.3)</strong> IMPROVED: Attempt to also capture B/CC email addresses included in outgoing emails in Audit logs.</li>
32
+ <li><strong>(v.3)</strong> FIX: Allow use of IPv4 ranges in whitelist again.</li>
33
+ <li><strong>(v.3)</strong> CHANGED: Numerous code refactoring and improvements building upon the major v7 release and prepping for v7.1.</li>
34
+ <li><strong>(v.1-2)</strong> FIXED: Some JS fixes.</li>
35
+ <li><strong>(v.0)</strong> NEW: New primary UI for Shield site security management. Easy access to scans, audit trail, user sessions etc.</li>
36
+ <li><strong>(v.0)</strong> NEW: Supports only PHP 5.4 or higher</li>
37
+ <li><strong>(v.0)</strong> NEW: Rebuilt scans architecture and UI</li>
38
+ <li><strong>(v.0)</strong> NEW: A huge amount of code cleaning and refactoring</li>
39
+ <li><strong>(v.0)</strong> CHANGED: Too many many changes and bug fixes to list -best to just take a look! :)</li>
40
+ </ul>
41
+ <p>= 6.10 - Series =<br>
42
+ <em>Released: 15th October, 2018</em> - <a href="https://icwp.io/dg">Release Notes</a></p>
43
+ <ul>
44
+ <li><strong>(v.9)</strong> FIXED: Admin notices displaying to non-admins.</li>
45
+ <li><strong>(v.7)</strong> ADDED: [<strong>PRO</strong>] New option to specify usernames for Security Admin role.</li>
46
+ <li><strong>(v.7)</strong> IMPROVED: Idle user detection.</li>
47
+ <li><strong>(v.7)</strong> IMPROVED: Support for redirect/cancel URLs in 2FA login page.</li>
48
+ <li><strong>(v.7)</strong> CHANGED: Final release before Shield v7. Small warning shown on plugins page if PHP &lt; 5.4</li>
49
+ <li><strong>(v.6)</strong> ADDED: New option to control plugin automatic updates.</li>
50
+ <li><strong>(v.6)</strong> IMPROVED: Enhancements to the experimental bot JS.</li>
51
+ <li><strong>(v.6)</strong> IMPROVED: Support for Easy Digital Downloads forms.</li>
52
+ <li><strong>(v.5)</strong> Release skipped.</li>
53
+ <li><strong>(v.4)</strong> FIXED: Couldn’t deactivate plugin.</li>
54
+ <li><strong>(v.3)</strong> ADDED: Support for Ultimate Member forms</li>
55
+ <li><strong>(v.3)</strong> ADDED: Support for LearnPress login/registration forms</li>
56
+ <li><strong>(v.3)</strong> FIXED: Security Admin now correctly honours the WordPress Options zone setting.</li>
57
+ <li><strong>(v.3)</strong> IMPROVED: Distinguish which sub-site (sub-domain) for WPMS installations on <a href="https://icwp.io/c1">Traffic Watcher</a>.</li>
58
+ <li><strong>(v.3)</strong> IMPROVED: Server’s own IP lookup is only attempted once.</li>
59
+ <li><strong>(v.3)</strong> ADDED: Experimental feature to help with some custom 3rd party login/registration forms</li>
60
+ <li><strong>(v.2)</strong> IMPROVED: Visitor IP address detection</li>
61
+ <li><strong>(v.2)</strong> IMPROVED: Automatic whitelisting of Manage WP IP addresses</li>
62
+ <li><strong>(v.2)</strong> IMPROVED: SPAM Comments code enhanced and optimised</li>
63
+ <li><strong>(v.2)</strong> IMPROVED: IP Whitelisting code enhanced and optimised</li>
64
+ <li><strong>(v.2)</strong> IMPROVED: Code cleaning and refactoring.</li>
65
+ <li><strong>(v.1)</strong> FIXED: Googlebot PHP error notice.</li>
66
+ <li><strong>(v.0)</strong> NEW: [<strong>PRO</strong>] 2FA Login Backup Codes - all users can create a backup login code in-case their MFA factors are temporarily unavailable.</li>
67
+ <li><strong>(v.0)</strong> NEW: [<strong>PRO</strong>] White Label - you can now specify custom image for 2FA login screen.</li>
68
+ <li><strong>(v.0)</strong> ADDED: [<strong>PRO</strong>] Custom Exclusion Rules for Traffic Watcher so you can exclude certain User Agents and request paths.</li>
69
+ <li><strong>(v.0)</strong> ADDED: Detection of official spiders/bots for Google, Bing, Apple and Yandex - these visitors will never get blacklisted.</li>
70
+ <li><strong>(v.0)</strong> IMPROVED: Two-Factor Authentication system much improved (+ critical bug fix).</li>
71
+ <li><strong>(v.0)</strong> IMPROVED: Audit Trail entries for 2FA login factors.</li>
72
+ <li><strong>(v.0)</strong> IMPROVED: Fixes for Two-Factor Authentication wizard UX.</li>
73
+ <li><strong>(v.0)</strong> IMPROVED: Traffic Watcher now honours the IP Whitelist.</li>
74
+ <li><strong>(v.0)</strong> IMPROVED: Security Admin restriction for creating/editing/deleting Administrator users is much improved.</li>
75
+ <li><strong>(v.0)</strong> IMPROVED: All Shield cookies are SSL-only by default for HTTPS sites.</li>
76
+ <li><strong>(v.0)</strong> FIXED: GASP checkbox Javascript breaking in a particular scenario.</li>
77
+ <li><strong>(v.0)</strong> ADDED: Optional plugin deactivation survey.</li>
78
+ </ul>
79
  <p>= 6.9.0 - Series =<br>
80
  <em>Released: 6th September, 2018</em> - <a href="https://icwp.io/dc">Release Notes</a></p>
81
  <ul>
icwp-plugin-controller.php CHANGED
@@ -244,15 +244,6 @@ class ICWP_WPSF_Plugin_Controller extends ICWP_WPSF_Foundation {
244
  return $this->aRequirementsMessages;
245
  }
246
 
247
- /**
248
- * Registers the plugins activation, deactivate and uninstall hooks.
249
- */
250
- protected function registerActivationHooks() {
251
- register_activation_hook( $this->getRootFile(), array( $this, 'onWpActivatePlugin' ) );
252
- register_deactivation_hook( $this->getRootFile(), array( $this, 'onWpDeactivatePlugin' ) );
253
- // register_uninstall_hook( $this->oPluginVo->getRootFile(), array( $this, 'onWpUninstallPlugin' ) );
254
- }
255
-
256
  /**
257
  */
258
  public function onWpDeactivatePlugin() {
@@ -269,8 +260,9 @@ class ICWP_WPSF_Plugin_Controller extends ICWP_WPSF_Foundation {
269
  }
270
 
271
  public function onWpActivatePlugin() {
272
- do_action( $this->prefix( 'plugin_activate' ) );
273
- $this->loadAllFeatures( true, true );
 
274
  }
275
 
276
  /**
@@ -311,7 +303,7 @@ class ICWP_WPSF_Plugin_Controller extends ICWP_WPSF_Foundation {
311
  /**
312
  */
313
  protected function doRegisterHooks() {
314
- $this->registerActivationHooks();
315
 
316
  add_action( 'init', array( $this, 'onWpInit' ), -1000 );
317
  add_action( 'admin_init', array( $this, 'onWpAdminInit' ) );
@@ -661,7 +653,7 @@ class ICWP_WPSF_Plugin_Controller extends ICWP_WPSF_Foundation {
661
  $sUrl = $this->getPluginUrl_Css( $sCssAsset.'.css' );
662
  if ( !empty( $sUrl ) ) {
663
  $sUnique = $this->prefix( $sCssAsset );
664
- wp_register_style( $sUnique, $sUrl, $sDependent, $this->getVersion().rand() );
665
  wp_enqueue_style( $sUnique );
666
  $sDependent = $sUnique;
667
  }
@@ -677,7 +669,7 @@ class ICWP_WPSF_Plugin_Controller extends ICWP_WPSF_Foundation {
677
  $sUrl = $this->getPluginUrl_Css( $sCssAsset.'.css' );
678
  if ( !empty( $sUrl ) ) {
679
  $sUnique = $this->prefix( $sCssAsset );
680
- wp_register_style( $sUnique, $sUrl, $sDependent, $this->getVersion().rand() );
681
  wp_enqueue_style( $sUnique );
682
  $sDependent = $sUnique;
683
  }
244
  return $this->aRequirementsMessages;
245
  }
246
 
 
 
 
 
 
 
 
 
 
247
  /**
248
  */
249
  public function onWpDeactivatePlugin() {
260
  }
261
 
262
  public function onWpActivatePlugin() {
263
+ /** @var ICWP_WPSF_FeatureHandler_Plugin $oP */
264
+ $oP = $this->getModule( 'plugin' );
265
+ $oP->setActivatedAt();
266
  }
267
 
268
  /**
303
  /**
304
  */
305
  protected function doRegisterHooks() {
306
+ register_deactivation_hook( $this->getRootFile(), [ $this, 'onWpDeactivatePlugin' ] );
307
 
308
  add_action( 'init', array( $this, 'onWpInit' ), -1000 );
309
  add_action( 'admin_init', array( $this, 'onWpAdminInit' ) );
653
  $sUrl = $this->getPluginUrl_Css( $sCssAsset.'.css' );
654
  if ( !empty( $sUrl ) ) {
655
  $sUnique = $this->prefix( $sCssAsset );
656
+ wp_register_style( $sUnique, $sUrl, $sDependent, $this->getVersion() );
657
  wp_enqueue_style( $sUnique );
658
  $sDependent = $sUnique;
659
  }
669
  $sUrl = $this->getPluginUrl_Css( $sCssAsset.'.css' );
670
  if ( !empty( $sUrl ) ) {
671
  $sUnique = $this->prefix( $sCssAsset );
672
+ wp_register_style( $sUnique, $sUrl, $sDependent, $this->getVersion() );
673
  wp_enqueue_style( $sUnique );
674
  $sDependent = $sUnique;
675
  }
icwp-wpsf.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: Shield Security
4
  * Plugin URI: https://icwp.io/2f
5
  * Description: Powerful, Easy-To-Use #1 Rated WordPress Security System
6
- * Version: 7.2.3
7
  * Text Domain: wp-simple-firewall
8
  * Domain Path: /languages/
9
  * Author: One Dollar Plugin
@@ -52,4 +52,16 @@ add_action( 'plugins_loaded', 'icwp_wpsf_init', 1 ); // use 0 for extensions to
52
  function icwp_wpsf_init() {
53
  $sRootFile = __FILE__;
54
  require_once( dirname( __FILE__ ).'/init.php' );
55
- }
 
 
 
 
 
 
 
 
 
 
 
 
3
  * Plugin Name: Shield Security
4
  * Plugin URI: https://icwp.io/2f
5
  * Description: Powerful, Easy-To-Use #1 Rated WordPress Security System
6
+ * Version: 7.3.2
7
  * Text Domain: wp-simple-firewall
8
  * Domain Path: /languages/
9
  * Author: One Dollar Plugin
52
  function icwp_wpsf_init() {
53
  $sRootFile = __FILE__;
54
  require_once( dirname( __FILE__ ).'/init.php' );
55
+ }
56
+
57
+ function icwp_wpsf_onactivate() {
58
+ icwp_wpsf_init();
59
+ if ( class_exists( 'ICWP_WPSF_Plugin_Controller' ) ) {
60
+ try {
61
+ ICWP_WPSF_Plugin_Controller::GetInstance()->onWpActivatePlugin();
62
+ }
63
+ catch ( Exception $oE ) {
64
+ }
65
+ }
66
+ }
67
+ register_activation_hook( __FILE__, 'icwp_wpsf_onactivate' );
languages/wp-simple-firewall-de_DE.mo CHANGED
Binary file
languages/wp-simple-firewall-fi.mo CHANGED
Binary file
languages/wp-simple-firewall-it_IT.mo CHANGED
Binary file
languages/wp-simple-firewall-nl_NL.mo CHANGED
Binary file
languages/wp-simple-firewall-ro_RO.mo CHANGED
Binary file
languages/wp-simple-firewall-sr_RS.mo CHANGED
Binary file
languages/wp-simple-firewall-tr_TR.mo CHANGED
Binary file
languages/wp-simple-firewall-zh_CN.mo ADDED
Binary file
plugin-spec.php CHANGED
@@ -1,7 +1,7 @@
1
  {
2
  "properties": {
3
- "version": "7.2.3",
4
- "release_timestamp": 1553515200,
5
  "slug_parent": "icwp",
6
  "slug_plugin": "wpsf",
7
  "human_name": "Shield",
@@ -49,6 +49,8 @@
49
  "bootstrap4.bundle.min",
50
  "jquery",
51
  "plugin",
 
 
52
  "featherlight",
53
  "jquery.fileDownload"
54
  ]
1
  {
2
  "properties": {
3
+ "version": "7.3.2",
4
+ "release_timestamp": 1555588846,
5
  "slug_parent": "icwp",
6
  "slug_plugin": "wpsf",
7
  "human_name": "Shield",
49
  "bootstrap4.bundle.min",
50
  "jquery",
51
  "plugin",
52
+ "base64.min",
53
+ "lz-string.min",
54
  "featherlight",
55
  "jquery.fileDownload"
56
  ]
readme.txt CHANGED
@@ -7,8 +7,8 @@ Tags: scan, firewall, two factor authentication, login protection, security
7
  Requires at least: 3.5.0
8
  Requires PHP: 5.4.0
9
  Recommended PHP: 7.0
10
- Tested up to: 5.1
11
- Stable tag: 7.2.3
12
 
13
  All-In-One protection against hackers and bot attacks. Easy to use Scanners, 2-Factor Authentication, login protection, auto IP blocker, and so much more...
14
 
@@ -16,7 +16,7 @@ All-In-One protection against hackers and bot attacks. Easy to use Scanners, 2-F
16
 
17
  ### The highest rated 5* Security Plugin for WordPress
18
 
19
- Shield has the highest average 5* rating for any WordPress security plugin (2019/03). [See what people are saying here](https://wordpress.org/support/plugin/wp-simple-firewall/reviews/?filter=5)..
20
 
21
  #### Our Mission: No Site Left Behind.
22
 
@@ -362,12 +362,21 @@ You will always be able to use Shield Security and its free features in-full.
362
 
363
  [Go Pro for just $1/month](https://icwp.io/aa).
364
 
365
- = 7.2.3 - Current Release =
366
- *Released: 25th March, 2019* - [Release Notes](https://icwp.io/ep)
367
 
368
- * **(v.3)** FIX: Unable to turn off the Abandoned Plugin scanner.
369
- * **(v.3)** FIX: Fix bug with some DNS lookup failures for some ISPs.
370
- * **(v.3)** FIX: Fix display notice for 'disallow file editing' setting when IP is whitelisted.
 
 
 
 
 
 
 
 
 
371
 
372
  = 7.2 - Series =
373
  *Released: 7th March, 2019* - [Release Notes](https://icwp.io/ep)
@@ -380,43 +389,4 @@ You will always be able to use Shield Security and its free features in-full.
380
  * **(v.0)** FIX: Fix bug with Security Admin passwords.
381
  * **(v.0)** FIX: Fix bug with vulnerability scanner not correctly comparing versions.
382
 
383
- = 7.1 - Series =
384
- *Released: 21st February, 2019* - [Release Notes](https://icwp.io/ek)
385
-
386
- * **(v.2)** IMPROVED: Firewall email notification content now better reflect the information in the audit trail.
387
- * **(v.2)** FIX: Firewall email notification was breaking in some instances.
388
- * **(v.1)** FIX: IP retrieval.
389
- * **(v.0)** NEW: Moved Import/Export UI from Wizard to main Shield Dashboard.
390
- * **(v.0)** NEW: [**PRO**] Option to import/export settings using file downloads/uploads
391
- * **(v.0)** NEW: [**PRO**] Option to allow visitors to automatically unblock themselves (once in 24hrs)
392
- * **(v.0)** NEW: Integrated changelog directly into plugin admin for easy updates (between releases)
393
- * **(v.0)** FIXED: WP Core files scanner now correctly ignores certain files as it used to do, pre-v7. e.g. wp-config-sample.php
394
- * **(v.0)** FIXED: Shield was indicating plugin/theme file editing was possible, when it in-fact was disabled.
395
- * **(v.0)** IMPROVED: Consolidate crons into fewer crons. e.g. all scans run under the same cron.
396
-
397
- = 7.0 - Series =
398
- *Released: 28th January, 2019* - [Release Notes](https://icwp.io/ef)
399
-
400
- * **(v.4)** IMPROVED: Refactored IP address blocking with improved audit trail messages.
401
- * **(v.4)** CHANGED: Expanded anonymous REST API whitelist to include 'wpstatistics' namespace.
402
- * **(v.4)** IMPROVED: Access protection for shield temp/caching dir.
403
- * **(v.4)** IMPROVED: Clarification on reCAPTCHA - v3 is **not** supported.
404
- * **(v.4)** IMPROVED: Clarification on user sessions timeout - Shield sets an absolutely session maximum.
405
- * **(v.4)** IMPROVED: Options form submission is adjusted to work around poorly restrictive webhosts.
406
- * **(v.4)** FIX: Various tweaks and fixes across the plugin.
407
- * **(v.4)** FIX: Error with ClassicPress.
408
- * **(v.3)** NEW: Automatically whitelist anonymous REST API Access for 3 plugins: Contact Form 7, WooCommerce, JetPack.
409
- * **(v.3)** IMPROVED: Security admin login failure messages are clearer.
410
- * **(v.3)** IMPROVED: Admin notification for email sending 2FA verification easily lets you resend email.
411
- * **(v.3)** IMPROVED: File download code for WordPress Core file scanner repairs.
412
- * **(v.3)** IMPROVED: Attempt to also capture B/CC email addresses included in outgoing emails in Audit logs.
413
- * **(v.3)** FIX: Allow use of IPv4 ranges in whitelist again.
414
- * **(v.3)** CHANGED: Numerous code refactoring and improvements building upon the major v7 release and prepping for v7.1.
415
- * **(v.1-2)** FIXED: Some JS fixes.
416
- * **(v.0)** NEW: New primary UI for Shield site security management. Easy access to scans, audit trail, user sessions etc.
417
- * **(v.0)** NEW: Supports only PHP 5.4 or higher
418
- * **(v.0)** NEW: Rebuilt scans architecture and UI
419
- * **(v.0)** NEW: A huge amount of code cleaning and refactoring
420
- * **(v.0)** CHANGED: Too many many changes and bug fixes to list -best to just take a look! :)
421
-
422
- #### [Full Changelog](https://ps.w.org/wp-simple-firewall/trunk/changelog.html)
7
  Requires at least: 3.5.0
8
  Requires PHP: 5.4.0
9
  Recommended PHP: 7.0
10
+ Tested up to: 5.2
11
+ Stable tag: 7.3.2
12
 
13
  All-In-One protection against hackers and bot attacks. Easy to use Scanners, 2-Factor Authentication, login protection, auto IP blocker, and so much more...
14
 
16
 
17
  ### The highest rated 5* Security Plugin for WordPress
18
 
19
+ Shield has the highest average 5* rating for any WordPress security plugin (2019/04). [See what people are saying here](https://wordpress.org/support/plugin/wp-simple-firewall/reviews/?filter=5)..
20
 
21
  #### Our Mission: No Site Left Behind.
22
 
362
 
363
  [Go Pro for just $1/month](https://icwp.io/aa).
364
 
365
+ = 7.3.2 - Current Release =
366
+ *Released: 18th April, 2019* - [Release Notes](https://icwp.io/f0)
367
 
368
+ * **(v.2)** IMPROVED: Provided inline links for new [Bot Signals](https://icwp.io/ez) options.
369
+ * **(v.2)** CHANGED: Added a workaround for WPML plugin using old, buggy version of TWIG library.
370
+ * **(v.1)** FIX: Protection against 404 tracking blocking visitors in some cases.
371
+ * **(v.0)** NEW: [**PRO**] [7x New Bot Signals](https://icwp.io/ez) - rules to catch and block bad bots.
372
+ * **(v.0)** ADDED: Date picker for filtering Audit Log entries.
373
+ * **(v.0)** IMPROVED: Audit Log viewer now combines entries from the same request into 1 for better readability.
374
+ * **(v.0)** CHANGED: Use a more refined clearing of WP Fastest Cache.
375
+ * **(v.0)** FIX: Error displayed when deleting plugins in some cases.
376
+ * **(v.0)** UPDATED: Translations for Chinese, Finnish, Turkish, Dutch, Italian, and German.
377
+
378
+ = 7.3 - Series =
379
+ *Released: 15th April, 2019* - [Release Notes](https://icwp.io/f0)
380
 
381
  = 7.2 - Series =
382
  *Released: 7th March, 2019* - [Release Notes](https://icwp.io/ep)
389
  * **(v.0)** FIX: Fix bug with Security Admin passwords.
390
  * **(v.0)** FIX: Fix bug with vulnerability scanner not correctly comparing versions.
391
 
392
+ #### [Full Changelog](https://icwp.io/shieldwporgfullchangelog)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
resources/images/pluginlogo_32x32.png CHANGED
Binary file
resources/images/pluginlogo_col_32x32.png ADDED
Binary file
resources/js/base64.min.js ADDED
@@ -0,0 +1 @@
 
1
+ (function(global,factory){typeof exports==="object"&&typeof module!=="undefined"?module.exports=factory(global):typeof define==="function"&&define.amd?define(factory):factory(global)})(typeof self!=="undefined"?self:typeof window!=="undefined"?window:typeof global!=="undefined"?global:this,function(global){"use strict";var _Base64=global.Base64;var version="2.5.0";var buffer;if(typeof module!=="undefined"&&module.exports){try{buffer=eval("require('buffer').Buffer")}catch(err){buffer=undefined}}var b64chars="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";var b64tab=function(bin){var t={};for(var i=0,l=bin.length;i<l;i++)t[bin.charAt(i)]=i;return t}(b64chars);var fromCharCode=String.fromCharCode;var cb_utob=function(c){if(c.length<2){var cc=c.charCodeAt(0);return cc<128?c:cc<2048?fromCharCode(192|cc>>>6)+fromCharCode(128|cc&63):fromCharCode(224|cc>>>12&15)+fromCharCode(128|cc>>>6&63)+fromCharCode(128|cc&63)}else{var cc=65536+(c.charCodeAt(0)-55296)*1024+(c.charCodeAt(1)-56320);return fromCharCode(240|cc>>>18&7)+fromCharCode(128|cc>>>12&63)+fromCharCode(128|cc>>>6&63)+fromCharCode(128|cc&63)}};var re_utob=/[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g;var utob=function(u){return u.replace(re_utob,cb_utob)};var cb_encode=function(ccc){var padlen=[0,2,1][ccc.length%3],ord=ccc.charCodeAt(0)<<16|(ccc.length>1?ccc.charCodeAt(1):0)<<8|(ccc.length>2?ccc.charCodeAt(2):0),chars=[b64chars.charAt(ord>>>18),b64chars.charAt(ord>>>12&63),padlen>=2?"=":b64chars.charAt(ord>>>6&63),padlen>=1?"=":b64chars.charAt(ord&63)];return chars.join("")};var btoa=global.btoa?function(b){return global.btoa(b)}:function(b){return b.replace(/[\s\S]{1,3}/g,cb_encode)};var _encode=buffer?buffer.from&&Uint8Array&&buffer.from!==Uint8Array.from?function(u){return(u.constructor===buffer.constructor?u:buffer.from(u)).toString("base64")}:function(u){return(u.constructor===buffer.constructor?u:new buffer(u)).toString("base64")}:function(u){return btoa(utob(u))};var encode=function(u,urisafe){return!urisafe?_encode(String(u)):_encode(String(u)).replace(/[+\/]/g,function(m0){return m0=="+"?"-":"_"}).replace(/=/g,"")};var encodeURI=function(u){return encode(u,true)};var re_btou=new RegExp(["[À-ß][€-¿]","[à-ï][€-¿]{2}","[ð-÷][€-¿]{3}"].join("|"),"g");var cb_btou=function(cccc){switch(cccc.length){case 4:var cp=(7&cccc.charCodeAt(0))<<18|(63&cccc.charCodeAt(1))<<12|(63&cccc.charCodeAt(2))<<6|63&cccc.charCodeAt(3),offset=cp-65536;return fromCharCode((offset>>>10)+55296)+fromCharCode((offset&1023)+56320);case 3:return fromCharCode((15&cccc.charCodeAt(0))<<12|(63&cccc.charCodeAt(1))<<6|63&cccc.charCodeAt(2));default:return fromCharCode((31&cccc.charCodeAt(0))<<6|63&cccc.charCodeAt(1))}};var btou=function(b){return b.replace(re_btou,cb_btou)};var cb_decode=function(cccc){var len=cccc.length,padlen=len%4,n=(len>0?b64tab[cccc.charAt(0)]<<18:0)|(len>1?b64tab[cccc.charAt(1)]<<12:0)|(len>2?b64tab[cccc.charAt(2)]<<6:0)|(len>3?b64tab[cccc.charAt(3)]:0),chars=[fromCharCode(n>>>16),fromCharCode(n>>>8&255),fromCharCode(n&255)];chars.length-=[0,0,2,1][padlen];return chars.join("")};var _atob=global.atob?function(a){return global.atob(a)}:function(a){return a.replace(/\S{1,4}/g,cb_decode)};var atob=function(a){return _atob(String(a).replace(/[^A-Za-z0-9\+\/]/g,""))};var _decode=buffer?buffer.from&&Uint8Array&&buffer.from!==Uint8Array.from?function(a){return(a.constructor===buffer.constructor?a:buffer.from(a,"base64")).toString()}:function(a){return(a.constructor===buffer.constructor?a:new buffer(a,"base64")).toString()}:function(a){return btou(_atob(a))};var decode=function(a){return _decode(String(a).replace(/[-_]/g,function(m0){return m0=="-"?"+":"/"}).replace(/[^A-Za-z0-9\+\/]/g,""))};var noConflict=function(){var Base64=global.Base64;global.Base64=_Base64;return Base64};global.Base64={VERSION:version,atob:atob,btoa:btoa,fromBase64:decode,toBase64:encode,utob:utob,encode:encode,encodeURI:encodeURI,btou:btou,decode:decode,noConflict:noConflict,__buffer__:buffer};if(typeof Object.defineProperty==="function"){var noEnum=function(v){return{value:v,enumerable:false,writable:true,configurable:true}};global.Base64.extendString=function(){Object.defineProperty(String.prototype,"fromBase64",noEnum(function(){return decode(this)}));Object.defineProperty(String.prototype,"toBase64",noEnum(function(urisafe){return encode(this,urisafe)}));Object.defineProperty(String.prototype,"toBase64URI",noEnum(function(){return encode(this,true)}))}}if(global["Meteor"]){Base64=global.Base64}if(typeof module!=="undefined"&&module.exports){module.exports.Base64=global.Base64}else if(typeof define==="function"&&define.amd){define([],function(){return global.Base64})}return{Base64:global.Base64}});
resources/js/featherlight.js CHANGED
@@ -1,8 +1,8 @@
1
  /**
2
  * Featherlight - ultra slim jQuery lightbox
3
- * Version 1.7.1 - http://noelboss.github.io/featherlight/
4
  *
5
- * Copyright 2017, Noël Raoul Bossart (http://www.noelboss.com)
6
  * MIT Licensed.
7
  **/
8
  (function($) {
@@ -12,7 +12,10 @@
12
  if('console' in window){ window.console.info('Too much lightness, Featherlight needs jQuery.'); }
13
  return;
14
  }
15
-
 
 
 
16
  /* Featherlight is exported as $.featherlight.
17
  It is a function used to open a featherlight lightbox.
18
 
@@ -68,8 +71,9 @@
68
 
69
  // NOTE: List of available [iframe attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe).
70
  var iFrameAttributeSet = {
71
- allowfullscreen: 1, frameborder: 1, height: 1, longdesc: 1, marginheight: 1, marginwidth: 1,
72
- name: 1, referrerpolicy: 1, scrolling: 1, sandbox: 1, src: 1, srcdoc: 1, width: 1
 
73
  };
74
 
75
  // Converts camelCased attributes to dasherized versions for given prefix:
@@ -166,6 +170,9 @@
166
 
167
  /* close when click on background/anywhere/null or closebox */
168
  self.$instance.on(self.closeTrigger+'.'+self.namespace, function(event) {
 
 
 
169
  var $target = $(event.target);
170
  if( ('background' === self.closeOnClick && $target.is('.'+self.namespace))
171
  || 'anywhere' === self.closeOnClick
@@ -234,25 +241,22 @@
234
 
235
  /* sets the content of $instance to $content */
236
  setContent: function($content){
237
- var self = this;
238
- /* we need a special class for the iframe */
239
- if($content.is('iframe')) {
240
- self.$instance.addClass(self.namespace+'-iframe');
241
- }
242
 
243
- self.$instance.removeClass(self.namespace+'-loading');
 
244
 
245
- /* replace content by appending to existing one before it is removed
246
- this insures that featherlight-inner remain at the same relative
247
- position to any other items added to featherlight-content */
248
- self.$instance.find('.'+self.namespace+'-inner')
249
- .not($content) /* excluded new content, important if persisted */
250
- .slice(1).remove().end() /* In the unexpected event where there are many inner elements, remove all but the first one */
251
- .replaceWith($.contains(self.$instance[0], $content[0]) ? '' : $content);
252
 
253
- self.$content = $content.addClass(self.namespace+'-inner');
254
 
255
- return self;
256
  },
257
 
258
  /* opens the lightbox. "this" contains $instance with the lightbox, and with the config.
@@ -325,8 +329,8 @@
325
  /* Calculate the worst ratio so that dimensions fit */
326
  /* Note: -1 to avoid rounding errors */
327
  var ratio = Math.max(
328
- w / (parseInt(this.$content.parent().css('width'),10)-1),
329
- h / (parseInt(this.$content.parent().css('height'),10)-1));
330
  /* Resize content */
331
  if (ratio > 1) {
332
  ratio = h / Math.floor(h / ratio); /* Round ratio down so height calc works */
@@ -361,7 +365,7 @@
361
  process: function(elem) { return this.persist !== false ? $(elem) : $(elem).clone(true); }
362
  },
363
  image: {
364
- regex: /\.(png|jpg|jpeg|gif|tiff|bmp|svg)(\?\S*)?$/i,
365
  process: function(url) {
366
  var self = this,
367
  deferred = $.Deferred(),
@@ -476,30 +480,33 @@
476
  /* make a copy */
477
  config = $.extend({}, config);
478
 
479
- /* Only for openTrigger and namespace... */
480
  var namespace = config.namespace || Klass.defaults.namespace,
481
  tempConfig = $.extend({}, Klass.defaults, Klass.readElementConfig($source[0], namespace), config),
482
  sharedPersist;
483
  var handler = function(event) {
 
484
  /* ... since we might as well compute the config on the actual target */
485
  var elemConfig = $.extend(
486
- {$source: $source, $currentTarget: $(this)},
487
  Klass.readElementConfig($source[0], tempConfig.namespace),
488
- Klass.readElementConfig(this, tempConfig.namespace),
489
  config);
490
- var fl = sharedPersist || $(this).data('featherlight-persisted') || new Klass($content, elemConfig);
491
  if(fl.persist === 'shared') {
492
  sharedPersist = fl;
493
  } else if(fl.persist !== false) {
494
- $(this).data('featherlight-persisted', fl);
 
 
 
495
  }
496
- elemConfig.$currentTarget.blur(); // Otherwise 'enter' key might trigger the dialog again
497
  fl.open(event);
498
  };
499
 
500
  $source.on(tempConfig.openTrigger+'.'+tempConfig.namespace, tempConfig.filter, handler);
501
 
502
- return handler;
503
  },
504
 
505
  current: function() {
@@ -524,8 +531,9 @@
524
  _onReady: function() {
525
  var Klass = this;
526
  if(Klass.autoBind){
 
527
  /* Bind existing elements */
528
- $(Klass.autoBind).each(function(){
529
  Klass.attach($(this));
530
  });
531
  /* If a click propagates to the document level, then we have an item that was added later on */
@@ -533,10 +541,18 @@
533
  if (evt.isDefaultPrevented()) {
534
  return;
535
  }
 
 
 
 
 
 
536
  /* Bind featherlight */
537
- var handler = Klass.attach($(evt.currentTarget));
538
  /* Dispatch event directly */
539
- handler(evt);
 
 
540
  });
541
  }
542
  },
@@ -557,6 +573,9 @@
557
  },
558
 
559
  beforeOpen: function(_super, event) {
 
 
 
560
  // Remember focus:
561
  this._previouslyActive = document.activeElement;
562
 
@@ -573,18 +592,25 @@
573
 
574
  this._$previouslyWithTabIndex.add(this._$previouslyTabbable).attr('tabindex', -1);
575
 
576
- document.activeElement.blur();
 
 
577
  return _super(event);
578
  },
579
 
580
  afterClose: function(_super, event) {
581
  var r = _super(event);
 
582
  var self = this;
583
  this._$previouslyTabbable.removeAttr('tabindex');
584
  this._$previouslyWithTabIndex.each(function(i, elem) {
585
  $(elem).attr('tabindex', self._previousWithTabIndices[i]);
586
  });
587
  this._previouslyActive.focus();
 
 
 
 
588
  return r;
589
  },
590
 
1
  /**
2
  * Featherlight - ultra slim jQuery lightbox
3
+ * Version 1.7.13 - http://noelboss.github.io/featherlight/
4
  *
5
+ * Copyright 2018, Noël Raoul Bossart (http://www.noelboss.com)
6
  * MIT Licensed.
7
  **/
8
  (function($) {
12
  if('console' in window){ window.console.info('Too much lightness, Featherlight needs jQuery.'); }
13
  return;
14
  }
15
+ if($.fn.jquery.match(/-ajax/)) {
16
+ if('console' in window){ window.console.info('Featherlight needs regular jQuery, not the slim version.'); }
17
+ return;
18
+ }
19
  /* Featherlight is exported as $.featherlight.
20
  It is a function used to open a featherlight lightbox.
21
 
71
 
72
  // NOTE: List of available [iframe attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe).
73
  var iFrameAttributeSet = {
74
+ allow: 1, allowfullscreen: 1, frameborder: 1, height: 1, longdesc: 1, marginheight: 1, marginwidth: 1,
75
+ mozallowfullscreen: 1, name: 1, referrerpolicy: 1, sandbox: 1, scrolling: 1, src: 1, srcdoc: 1, style: 1,
76
+ webkitallowfullscreen: 1, width: 1
77
  };
78
 
79
  // Converts camelCased attributes to dasherized versions for given prefix:
170
 
171
  /* close when click on background/anywhere/null or closebox */
172
  self.$instance.on(self.closeTrigger+'.'+self.namespace, function(event) {
173
+ if(event.isDefaultPrevented()) {
174
+ return;
175
+ }
176
  var $target = $(event.target);
177
  if( ('background' === self.closeOnClick && $target.is('.'+self.namespace))
178
  || 'anywhere' === self.closeOnClick
241
 
242
  /* sets the content of $instance to $content */
243
  setContent: function($content){
244
+ this.$instance.removeClass(this.namespace+'-loading');
 
 
 
 
245
 
246
+ /* we need a special class for the iframe */
247
+ this.$instance.toggleClass(this.namespace+'-iframe', $content.is('iframe'));
248
 
249
+ /* replace content by appending to existing one before it is removed
250
+ this insures that featherlight-inner remain at the same relative
251
+ position to any other items added to featherlight-content */
252
+ this.$instance.find('.'+this.namespace+'-inner')
253
+ .not($content) /* excluded new content, important if persisted */
254
+ .slice(1).remove().end() /* In the unexpected event where there are many inner elements, remove all but the first one */
255
+ .replaceWith($.contains(this.$instance[0], $content[0]) ? '' : $content);
256
 
257
+ this.$content = $content.addClass(this.namespace+'-inner');
258
 
259
+ return this;
260
  },
261
 
262
  /* opens the lightbox. "this" contains $instance with the lightbox, and with the config.
329
  /* Calculate the worst ratio so that dimensions fit */
330
  /* Note: -1 to avoid rounding errors */
331
  var ratio = Math.max(
332
+ w / (this.$content.parent().width()-1),
333
+ h / (this.$content.parent().height()-1));
334
  /* Resize content */
335
  if (ratio > 1) {
336
  ratio = h / Math.floor(h / ratio); /* Round ratio down so height calc works */
365
  process: function(elem) { return this.persist !== false ? $(elem) : $(elem).clone(true); }
366
  },
367
  image: {
368
+ regex: /\.(png|jpg|jpeg|gif|tiff?|bmp|svg)(\?\S*)?$/i,
369
  process: function(url) {
370
  var self = this,
371
  deferred = $.Deferred(),
480
  /* make a copy */
481
  config = $.extend({}, config);
482
 
483
+ /* Only for openTrigger, filter & namespace... */
484
  var namespace = config.namespace || Klass.defaults.namespace,
485
  tempConfig = $.extend({}, Klass.defaults, Klass.readElementConfig($source[0], namespace), config),
486
  sharedPersist;
487
  var handler = function(event) {
488
+ var $target = $(event.currentTarget);
489
  /* ... since we might as well compute the config on the actual target */
490
  var elemConfig = $.extend(
491
+ {$source: $source, $currentTarget: $target},
492
  Klass.readElementConfig($source[0], tempConfig.namespace),
493
+ Klass.readElementConfig(event.currentTarget, tempConfig.namespace),
494
  config);
495
+ var fl = sharedPersist || $target.data('featherlight-persisted') || new Klass($content, elemConfig);
496
  if(fl.persist === 'shared') {
497
  sharedPersist = fl;
498
  } else if(fl.persist !== false) {
499
+ $target.data('featherlight-persisted', fl);
500
+ }
501
+ if (elemConfig.$currentTarget.blur) {
502
+ elemConfig.$currentTarget.blur(); // Otherwise 'enter' key might trigger the dialog again
503
  }
 
504
  fl.open(event);
505
  };
506
 
507
  $source.on(tempConfig.openTrigger+'.'+tempConfig.namespace, tempConfig.filter, handler);
508
 
509
+ return {filter: tempConfig.filter, handler: handler};
510
  },
511
 
512
  current: function() {
531
  _onReady: function() {
532
  var Klass = this;
533
  if(Klass.autoBind){
534
+ var $autobound = $(Klass.autoBind);
535
  /* Bind existing elements */
536
+ $autobound.each(function(){
537
  Klass.attach($(this));
538
  });
539
  /* If a click propagates to the document level, then we have an item that was added later on */
541
  if (evt.isDefaultPrevented()) {
542
  return;
543
  }
544
+ var $cur = $(evt.currentTarget);
545
+ var len = $autobound.length;
546
+ $autobound = $autobound.add($cur);
547
+ if(len === $autobound.length) {
548
+ return; /* already bound */
549
+ }
550
  /* Bind featherlight */
551
+ var data = Klass.attach($cur);
552
  /* Dispatch event directly */
553
+ if (!data.filter || $(evt.target).parentsUntil($cur, data.filter).length > 0) {
554
+ data.handler(evt);
555
+ }
556
  });
557
  }
558
  },
573
  },
574
 
575
  beforeOpen: function(_super, event) {
576
+ // Used to disable scrolling
577
+ $(document.documentElement).addClass('with-featherlight');
578
+
579
  // Remember focus:
580
  this._previouslyActive = document.activeElement;
581
 
592
 
593
  this._$previouslyWithTabIndex.add(this._$previouslyTabbable).attr('tabindex', -1);
594
 
595
+ if (document.activeElement.blur) {
596
+ document.activeElement.blur();
597
+ }
598
  return _super(event);
599
  },
600
 
601
  afterClose: function(_super, event) {
602
  var r = _super(event);
603
+ // Restore focus
604
  var self = this;
605
  this._$previouslyTabbable.removeAttr('tabindex');
606
  this._$previouslyWithTabIndex.each(function(i, elem) {
607
  $(elem).attr('tabindex', self._previousWithTabIndices[i]);
608
  });
609
  this._previouslyActive.focus();
610
+ // Restore scroll
611
+ if(Featherlight.opened().length === 0) {
612
+ $(document.documentElement).removeClass('with-featherlight');
613
+ }
614
  return r;
615
  },
616
 
resources/js/lz-string.min.js ADDED
@@ -0,0 +1 @@
 
1
+ var LZString=function(){function o(o,r){if(!t[o]){t[o]={};for(var n=0;n<o.length;n++)t[o][o.charAt(n)]=n}return t[o][r]}var r=String.fromCharCode,n="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-$",t={},i={compressToBase64:function(o){if(null==o)return"";var r=i._compress(o,6,function(o){return n.charAt(o)});switch(r.length%4){default:case 0:return r;case 1:return r+"===";case 2:return r+"==";case 3:return r+"="}},decompressFromBase64:function(r){return null==r?"":""==r?null:i._decompress(r.length,32,function(e){return o(n,r.charAt(e))})},compressToUTF16:function(o){return null==o?"":i._compress(o,15,function(o){return r(o+32)})+" "},decompressFromUTF16:function(o){return null==o?"":""==o?null:i._decompress(o.length,16384,function(r){return o.charCodeAt(r)-32})},compressToUint8Array:function(o){for(var r=i.compress(o),n=new Uint8Array(2*r.length),e=0,t=r.length;t>e;e++){var s=r.charCodeAt(e);n[2*e]=s>>>8,n[2*e+1]=s%256}return n},decompressFromUint8Array:function(o){if(null===o||void 0===o)return i.decompress(o);for(var n=new Array(o.length/2),e=0,t=n.length;t>e;e++)n[e]=256*o[2*e]+o[2*e+1];var s=[];return n.forEach(function(o){s.push(r(o))}),i.decompress(s.join(""))},compressToEncodedURIComponent:function(o){return null==o?"":i._compress(o,6,function(o){return e.charAt(o)})},decompressFromEncodedURIComponent:function(r){return null==r?"":""==r?null:(r=r.replace(/ /g,"+"),i._decompress(r.length,32,function(n){return o(e,r.charAt(n))}))},compress:function(o){return i._compress(o,16,function(o){return r(o)})},_compress:function(o,r,n){if(null==o)return"";var e,t,i,s={},p={},u="",c="",a="",l=2,f=3,h=2,d=[],m=0,v=0;for(i=0;i<o.length;i+=1)if(u=o.charAt(i),Object.prototype.hasOwnProperty.call(s,u)||(s[u]=f++,p[u]=!0),c=a+u,Object.prototype.hasOwnProperty.call(s,c))a=c;else{if(Object.prototype.hasOwnProperty.call(p,a)){if(a.charCodeAt(0)<256){for(e=0;h>e;e++)m<<=1,v==r-1?(v=0,d.push(n(m)),m=0):v++;for(t=a.charCodeAt(0),e=0;8>e;e++)m=m<<1|1&t,v==r-1?(v=0,d.push(n(m)),m=0):v++,t>>=1}else{for(t=1,e=0;h>e;e++)m=m<<1|t,v==r-1?(v=0,d.push(n(m)),m=0):v++,t=0;for(t=a.charCodeAt(0),e=0;16>e;e++)m=m<<1|1&t,v==r-1?(v=0,d.push(n(m)),m=0):v++,t>>=1}l--,0==l&&(l=Math.pow(2,h),h++),delete p[a]}else for(t=s[a],e=0;h>e;e++)m=m<<1|1&t,v==r-1?(v=0,d.push(n(m)),m=0):v++,t>>=1;l--,0==l&&(l=Math.pow(2,h),h++),s[c]=f++,a=String(u)}if(""!==a){if(Object.prototype.hasOwnProperty.call(p,a)){if(a.charCodeAt(0)<256){for(e=0;h>e;e++)m<<=1,v==r-1?(v=0,d.push(n(m)),m=0):v++;for(t=a.charCodeAt(0),e=0;8>e;e++)m=m<<1|1&t,v==r-1?(v=0,d.push(n(m)),m=0):v++,t>>=1}else{for(t=1,e=0;h>e;e++)m=m<<1|t,v==r-1?(v=0,d.push(n(m)),m=0):v++,t=0;for(t=a.charCodeAt(0),e=0;16>e;e++)m=m<<1|1&t,v==r-1?(v=0,d.push(n(m)),m=0):v++,t>>=1}l--,0==l&&(l=Math.pow(2,h),h++),delete p[a]}else for(t=s[a],e=0;h>e;e++)m=m<<1|1&t,v==r-1?(v=0,d.push(n(m)),m=0):v++,t>>=1;l--,0==l&&(l=Math.pow(2,h),h++)}for(t=2,e=0;h>e;e++)m=m<<1|1&t,v==r-1?(v=0,d.push(n(m)),m=0):v++,t>>=1;for(;;){if(m<<=1,v==r-1){d.push(n(m));break}v++}return d.join("")},decompress:function(o){return null==o?"":""==o?null:i._decompress(o.length,32768,function(r){return o.charCodeAt(r)})},_decompress:function(o,n,e){var t,i,s,p,u,c,a,l,f=[],h=4,d=4,m=3,v="",w=[],A={val:e(0),position:n,index:1};for(i=0;3>i;i+=1)f[i]=i;for(p=0,c=Math.pow(2,2),a=1;a!=c;)u=A.val&A.position,A.position>>=1,0==A.position&&(A.position=n,A.val=e(A.index++)),p|=(u>0?1:0)*a,a<<=1;switch(t=p){case 0:for(p=0,c=Math.pow(2,8),a=1;a!=c;)u=A.val&A.position,A.position>>=1,0==A.position&&(A.position=n,A.val=e(A.index++)),p|=(u>0?1:0)*a,a<<=1;l=r(p);break;case 1:for(p=0,c=Math.pow(2,16),a=1;a!=c;)u=A.val&A.position,A.position>>=1,0==A.position&&(A.position=n,A.val=e(A.index++)),p|=(u>0?1:0)*a,a<<=1;l=r(p);break;case 2:return""}for(f[3]=l,s=l,w.push(l);;){if(A.index>o)return"";for(p=0,c=Math.pow(2,m),a=1;a!=c;)u=A.val&A.position,A.position>>=1,0==A.position&&(A.position=n,A.val=e(A.index++)),p|=(u>0?1:0)*a,a<<=1;switch(l=p){case 0:for(p=0,c=Math.pow(2,8),a=1;a!=c;)u=A.val&A.position,A.position>>=1,0==A.position&&(A.position=n,A.val=e(A.index++)),p|=(u>0?1:0)*a,a<<=1;f[d++]=r(p),l=d-1,h--;break;case 1:for(p=0,c=Math.pow(2,16),a=1;a!=c;)u=A.val&A.position,A.position>>=1,0==A.position&&(A.position=n,A.val=e(A.index++)),p|=(u>0?1:0)*a,a<<=1;f[d++]=r(p),l=d-1,h--;break;case 2:return w.join("")}if(0==h&&(h=Math.pow(2,m),m++),f[l])v=f[l];else{if(l!==d)return null;v=s+s.charAt(0)}w.push(v),f[d++]=s+v.charAt(0),h--,s=v,0==h&&(h=Math.pow(2,m),m++)}}};return i}();"function"==typeof define&&define.amd?define(function(){return LZString}):"undefined"!=typeof module&&null!=module&&(module.exports=LZString);
resources/js/plugin.js CHANGED
@@ -47,6 +47,29 @@ var iCWP_WPSF_OptionsPages = new function () {
47
 
48
  }();
49
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  var iCWP_WPSF_Toaster = new function () {
51
 
52
  this.showMessage = function ( sMessage, bSuccess ) {
@@ -111,10 +134,19 @@ var iCWP_WPSF_OptionsFormSubmit = new function () {
111
  } );
112
 
113
  if ( $bPasswordsReady ) {
 
 
 
 
 
114
  var aReq = jQuery.extend(
115
  icwp_wpsf_vars_base.ajax.mod_options,
116
- { 'form_params': btoa( $oForm.serialize() ) }
 
 
 
117
  );
 
118
  jQuery.post( ajaxurl, aReq,
119
  function ( oResponse ) {
120
  var sMessage;
@@ -128,6 +160,30 @@ var iCWP_WPSF_OptionsFormSubmit = new function () {
128
  iCWP_WPSF_Toaster.showMessage( sMessage, oResponse.success );
129
  // iCWP_WPSF_Growl.showMessage( sMessage, oResponse.success );
130
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131
  ).always( function () {
132
  bRequestCurrentlyRunning = false;
133
  setTimeout( function () {
47
 
48
  }();
49
 
50
+
51
+ if ( false && typeof icwp_wpsf_vars_base !== 'undefined' ) {
52
+ var iCWP_WPSF_OptsPageRender = new function () {
53
+
54
+ this.initialise = function () {
55
+ jQuery( document ).ready( function () {
56
+
57
+ jQuery.post( ajaxurl, icwp_wpsf_vars_base.ajax.mod_opts_render,
58
+ function ( oResponse ) {
59
+ jQuery( '#ContentHolder' ).html( oResponse.data.html );
60
+ }
61
+ ).fail(
62
+ function () {
63
+ }
64
+ ).always( function () {
65
+ }
66
+ );
67
+ } );
68
+ };
69
+ }();
70
+ iCWP_WPSF_OptsPageRender.initialise();
71
+ }
72
+
73
  var iCWP_WPSF_Toaster = new function () {
74
 
75
  this.showMessage = function ( sMessage, bSuccess ) {
134
  } );
135
 
136
  if ( $bPasswordsReady ) {
137
+ /**
138
+ * First try with base64 and failover to lz-string upon abject failure.
139
+ * This works around mod_security rules that even unpack b64 encoded params and look
140
+ * for patterns within them.
141
+ */
142
  var aReq = jQuery.extend(
143
  icwp_wpsf_vars_base.ajax.mod_options,
144
+ {
145
+ 'form_params': Base64.encode( $oForm.serialize() ),
146
+ 'enc_params': 'b64'
147
+ }
148
  );
149
+
150
  jQuery.post( ajaxurl, aReq,
151
  function ( oResponse ) {
152
  var sMessage;
160
  iCWP_WPSF_Toaster.showMessage( sMessage, oResponse.success );
161
  // iCWP_WPSF_Growl.showMessage( sMessage, oResponse.success );
162
  }
163
+ ).fail(
164
+ function () {
165
+ iCWP_WPSF_Toaster.showMessage( 'The request was blocked. Retrying an alternative...', false );
166
+ aReq = jQuery.extend(
167
+ icwp_wpsf_vars_base.ajax.mod_options,
168
+ {
169
+ 'form_params': Base64.encode( LZString.compress( $oForm.serialize() ) ),
170
+ 'enc_params': 'lz-string'
171
+ }
172
+ );
173
+ jQuery.post( ajaxurl, aReq,
174
+ function ( oResponse ) {
175
+ var sMessage;
176
+ if ( oResponse === null || typeof oResponse.data === 'undefined'
177
+ || typeof oResponse.data.message === 'undefined' ) {
178
+ sMessage = oResponse.success ? 'Success' : 'Failure';
179
+ }
180
+ else {
181
+ sMessage = oResponse.data.message;
182
+ }
183
+ iCWP_WPSF_Toaster.showMessage( sMessage, oResponse.success );
184
+ }
185
+ )
186
+ }
187
  ).always( function () {
188
  bRequestCurrentlyRunning = false;
189
  setTimeout( function () {
src/common/icwp-edd.php CHANGED
@@ -1,7 +1,7 @@
1
  <?php
2
 
3
- use \FernleafSystems\Wordpress\Plugin\Shield\License\EddLicenseVO;
4
- use \FernleafSystems\Wordpress\Services\Services;
5
 
6
  class ICWP_WPSF_Edd {
7
 
1
  <?php
2
 
3
+ use FernleafSystems\Wordpress\Plugin\Shield\License\EddLicenseVO;
4
+ use FernleafSystems\Wordpress\Services\Services;
5
 
6
  class ICWP_WPSF_Edd {
7
 
src/common/icwp-render.php CHANGED
@@ -54,18 +54,18 @@ class ICWP_WPSF_Render extends ICWP_WPSF_Foundation {
54
  protected $nTemplateEngine;
55
 
56
  /**
57
- * @var Twig_Environment
58
  */
59
  protected $oTwigEnv;
60
 
61
  /**
62
- * @var Twig_Loader_Filesystem
63
  */
64
  protected $oTwigLoader;
65
 
66
  /**
67
  * @return string
68
- * @throws Exception
69
  */
70
  public function render() {
71
 
@@ -139,25 +139,20 @@ class ICWP_WPSF_Render extends ICWP_WPSF_Foundation {
139
  }
140
 
141
  /**
142
- * @return Twig_Environment
143
  */
144
  protected function getTwigEnvironment() {
145
- return new Twig_Environment( $this->getTwigLoader(),
146
- array(
147
- 'debug' => true,
148
- 'strict_variables' => true,
149
- )
150
- );
151
- }
152
-
153
- /**
154
- * @return Twig_Loader_Filesystem
155
- */
156
- protected function getTwigLoader() {
157
- if ( !isset( $this->oTwigLoader ) ) {
158
- $this->oTwigLoader = new Twig_Loader_Filesystem( $this->getTemplateRootMain() );
159
  }
160
- return $this->oTwigLoader;
161
  }
162
 
163
  /**
54
  protected $nTemplateEngine;
55
 
56
  /**
57
+ * @var \Twig\Environment
58
  */
59
  protected $oTwigEnv;
60
 
61
  /**
62
+ * @var \Twig\Loader\FilesystemLoader
63
  */
64
  protected $oTwigLoader;
65
 
66
  /**
67
  * @return string
68
+ * @throws \Exception
69
  */
70
  public function render() {
71
 
139
  }
140
 
141
  /**
142
+ * @return \Twig\Environment|\Twig_Environment
143
  */
144
  protected function getTwigEnvironment() {
145
+ $aConf = [
146
+ 'debug' => true,
147
+ 'strict_variables' => true,
148
+ ];
149
+ if ( class_exists( 'Twig_Environment' ) ) {
150
+ $oEnv = new Twig_Environment( new Twig_Loader_Filesystem( $this->getTemplateRootMain() ), $aConf );
151
+ }
152
+ else {
153
+ $oEnv = new \Twig\Environment( new \Twig\Loader\FilesystemLoader( $this->getTemplateRootMain() ), $aConf );
 
 
 
 
 
154
  }
155
+ return $oEnv;
156
  }
157
 
158
  /**
src/common/icwp-wpfunctions.php CHANGED
@@ -899,16 +899,18 @@ class ICWP_WPSF_WpFunctions extends ICWP_WPSF_Foundation {
899
  if ( !defined( 'DONOTCACHEPAGE' ) ) {
900
  define( 'DONOTCACHEPAGE', true );
901
  }
902
- // WP Fastest Cache
903
- if ( isset( $GLOBALS[ 'wp_fastest_cache' ] ) and is_object( $GLOBALS[ 'wp_fastest_cache' ] )
904
- && method_exists( $GLOBALS[ 'wp_fastest_cache' ], 'deleteCache' )
905
- && is_callable( array(
906
- $GLOBALS[ 'wp_fastest_cache' ],
907
- 'deleteCache'
908
- ) )
909
- ) {
910
- $GLOBALS[ 'wp_fastest_cache' ]->deleteCache(); //WpFastestCache
911
- }
 
 
912
  return DONOTCACHEPAGE;
913
  }
914
 
@@ -925,8 +927,8 @@ class ICWP_WPSF_WpFunctions extends ICWP_WPSF_Foundation {
925
  }
926
 
927
  /**
928
- * @deprecated
929
  * @return string[]
 
930
  */
931
  public function getCoreChecksums() {
932
  return \FernleafSystems\Wordpress\Services\Services::WpGeneral()->getCoreChecksums();
899
  if ( !defined( 'DONOTCACHEPAGE' ) ) {
900
  define( 'DONOTCACHEPAGE', true );
901
  }
902
+
903
+ add_action( 'shutdown', function () {
904
+ // WP Fastest Cache
905
+ if ( isset( $GLOBALS[ 'wp_fastest_cache' ] ) &&
906
+ $GLOBALS[ 'wp_fastest_cache' ] instanceof \WpFastestCache
907
+ && method_exists( $GLOBALS[ 'wp_fastest_cache' ], 'singleDeleteCache' ) ) {
908
+ $nPostId = $this->getCurrentPostId();
909
+ if ( $nPostId > 0 ) {
910
+ $GLOBALS[ 'wp_fastest_cache' ]->singleDeleteCache( false, $this->getCurrentPostId() );
911
+ }
912
+ }
913
+ } );
914
  return DONOTCACHEPAGE;
915
  }
916
 
927
  }
928
 
929
  /**
 
930
  * @return string[]
931
+ * @deprecated
932
  */
933
  public function getCoreChecksums() {
934
  return \FernleafSystems\Wordpress\Services\Services::WpGeneral()->getCoreChecksums();
src/common/wp-admin-notices.php CHANGED
@@ -103,7 +103,7 @@ class ICWP_WPSF_WpAdminNotices extends ICWP_WPSF_Foundation {
103
  * @throws \Exception
104
  */
105
  protected function getCurrentUserMeta() {
106
- return \FernleafSystems\Wordpress\Services\Services::WpUsers()->metaVoForUser( rtrim( $this->getPrefix(), '-' ) );
107
  }
108
 
109
  /**
103
  * @throws \Exception
104
  */
105
  protected function getCurrentUserMeta() {
106
+ return Services::WpUsers()->metaVoForUser( rtrim( $this->getPrefix(), '-' ) );
107
  }
108
 
109
  /**
src/config/feature-hack_protect.php CHANGED
@@ -25,6 +25,15 @@
25
  "Purpose - Set how often the Hack Guard scans will run."
26
  ]
27
  },
 
 
 
 
 
 
 
 
 
28
  {
29
  "slug": "section_core_file_integrity_scan",
30
  "title": "WordPress Core File Scanner",
@@ -110,6 +119,18 @@
110
  "summary": "Enable (or Disable) The Hack Guard Module",
111
  "description": "Un-Checking this option will completely disable the Hack Guard module"
112
  },
 
 
 
 
 
 
 
 
 
 
 
 
113
  {
114
  "key": "enable_wpvuln_scan",
115
  "section": "section_wpvuln_scan",
@@ -547,6 +568,27 @@
547
  "transferable": false,
548
  "type": "boolean",
549
  "default": false
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
550
  }
551
  ],
552
  "definitions": {
25
  "Purpose - Set how often the Hack Guard scans will run."
26
  ]
27
  },
28
+ {
29
+ "slug": "section_realtime",
30
+ "title": "Realtime Protection",
31
+ "title_short": "Realtime Protection",
32
+ "summary": [
33
+ "Purpose - Provides realtime protection for certain key files.",
34
+ "Recommendation - Keep realtime protection turned on to protect key files."
35
+ ]
36
+ },
37
  {
38
  "slug": "section_core_file_integrity_scan",
39
  "title": "WordPress Core File Scanner",
119
  "summary": "Enable (or Disable) The Hack Guard Module",
120
  "description": "Un-Checking this option will completely disable the Hack Guard module"
121
  },
122
+ {
123
+ "key": "rt_file_wpconfig",
124
+ "section": "section_non_ui",
125
+ "premium": true,
126
+ "default": "N",
127
+ "type": "checkbox",
128
+ "link_info": "",
129
+ "link_blog": "",
130
+ "name": "WP Config",
131
+ "summary": "Lock WP Config Against Any Changes",
132
+ "description": "As soon as changes are detected to the WP config file the file will be reverted."
133
+ },
134
  {
135
  "key": "enable_wpvuln_scan",
136
  "section": "section_wpvuln_scan",
568
  "transferable": false,
569
  "type": "boolean",
570
  "default": false
571
+ },
572
+ {
573
+ "key": "rt_file_hashes",
574
+ "section": "section_non_ui",
575
+ "transferable": false,
576
+ "type": "array",
577
+ "default": []
578
+ },
579
+ {
580
+ "key": "rt_file_backup_names",
581
+ "section": "section_non_ui",
582
+ "transferable": false,
583
+ "type": "array",
584
+ "default": []
585
+ },
586
+ {
587
+ "key": "rt_can_write_files",
588
+ "section": "section_non_ui",
589
+ "transferable": false,
590
+ "type": "array",
591
+ "default": []
592
  }
593
  ],
594
  "definitions": {
src/config/feature-ips.php CHANGED
@@ -2,11 +2,11 @@
2
  "slug": "ips",
3
  "properties": {
4
  "slug": "ips",
5
- "name": "IP Manager",
6
  "show_module_menu_item": false,
7
  "show_module_options": true,
8
  "storage_key": "ips",
9
- "tagline": "Manage Visitor IP Address",
10
  "show_central": true,
11
  "access_restricted": true,
12
  "premium": false,
@@ -42,19 +42,43 @@
42
  "slug": "section_auto_black_list",
43
  "primary": true,
44
  "title": "Automatic IP Black List",
45
- "title_short": "Auto Black List",
46
  "summary": [
47
  "Purpose - The Automatic IP Black List system will block the IP addresses of naughty visitors after a specified number of transgressions.",
48
  "Recommendation - Keep the Automatic IP Black List feature turned on."
49
  ]
50
  },
51
  {
52
- "slug": "section_reqtracking",
53
- "title": "Bad Request Tracking",
54
- "title_short": "Request Tracking",
55
  "summary": [
56
- "Purpose - Track strange behaviour to determine whether visitors are legitimate.",
57
- "Recommendation - These aren't security issues in their own right, but may indicate probing bots."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
  ]
59
  },
60
  {
@@ -107,7 +131,7 @@
107
  {
108
  "key": "auto_expire",
109
  "section": "section_auto_black_list",
110
- "default": "minute",
111
  "type": "select",
112
  "value_options": [
113
  {
@@ -149,7 +173,7 @@
149
  "text": "With Shield Bot Protection"
150
  }
151
  ],
152
- "link_info": "",
153
  "link_blog": "",
154
  "name": "User Auto Unblock",
155
  "summary": "Allow Visitors To Unblock Their IP",
@@ -170,30 +194,240 @@
170
  },
171
  {
172
  "key": "track_404",
173
- "section": "section_reqtracking",
174
- "sensitive": false,
 
175
  "type": "select",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
176
  "premium": true,
177
  "default": "disabled",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
178
  "value_options": [
179
  {
180
  "value_key": "disabled",
181
- "text": "Ignore 404s"
182
  },
183
  {
184
- "value_key": "log-only",
185
- "text": "Log Only (Audit Trail)"
186
  },
187
  {
188
- "value_key": "assign-transgression",
189
  "text": "Increment Transgression"
 
 
 
 
 
 
 
 
190
  }
191
  ],
192
- "link_info": "https://icwp.io/e7",
193
- "link_blog": "",
194
- "name": "Track 404s",
195
- "summary": "Use 404s As An Transgression",
196
- "description": "Repeated 404s may indicate a probing bot especially where WP Login has been renamed."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
197
  },
198
  {
199
  "key": "text_remainingtrans",
2
  "slug": "ips",
3
  "properties": {
4
  "slug": "ips",
5
+ "name": "Block Bad IPs/Visitors",
6
  "show_module_menu_item": false,
7
  "show_module_options": true,
8
  "storage_key": "ips",
9
+ "tagline": "Automatically detect bots and malicious visitors and stop them dead.",
10
  "show_central": true,
11
  "access_restricted": true,
12
  "premium": false,
42
  "slug": "section_auto_black_list",
43
  "primary": true,
44
  "title": "Automatic IP Black List",
45
+ "title_short": "Auto IP Blocking Rules",
46
  "summary": [
47
  "Purpose - The Automatic IP Black List system will block the IP addresses of naughty visitors after a specified number of transgressions.",
48
  "Recommendation - Keep the Automatic IP Black List feature turned on."
49
  ]
50
  },
51
  {
52
+ "slug": "section_logins",
53
+ "title": "Capture Login Bots",
54
+ "title_short": "Login Bots",
55
  "summary": [
56
+ "Recommendation - Enable to capture bots/spiders that don't honour 'nofollow' directives."
57
+ ]
58
+ },
59
+ {
60
+ "slug": "section_probes",
61
+ "title": "Capture Probing Bots",
62
+ "title_short": "Probing Bots",
63
+ "summary": [
64
+ "Recommendation - Enable to capture bots/spiders that don't honour 'nofollow' directives."
65
+ ]
66
+ },
67
+ {
68
+ "slug": "section_behaviours",
69
+ "title": "Identify Common Bot Behaviours",
70
+ "title_short": "Bot Behaviours",
71
+ "summary": [
72
+ "Recommendation - Enable to capture bots/spiders that don't honour 'nofollow' directives."
73
+ ]
74
+ },
75
+ {
76
+ "slug": "section_enable_plugin_feature_bottrap",
77
+ "title": "Enable Module: BotTrap",
78
+ "title_short": "Enable Module",
79
+ "summary": [
80
+ "Purpose - BotTrap monitors a typical set of bot behaviours to help identify probing bots.",
81
+ "Recommendation - Enable as many bot traps as possible."
82
  ]
83
  },
84
  {
131
  {
132
  "key": "auto_expire",
133
  "section": "section_auto_black_list",
134
+ "default": "hour",
135
  "type": "select",
136
  "value_options": [
137
  {
173
  "text": "With Shield Bot Protection"
174
  }
175
  ],
176
+ "link_info": "https://icwp.io/f8",
177
  "link_blog": "",
178
  "name": "User Auto Unblock",
179
  "summary": "Allow Visitors To Unblock Their IP",
194
  },
195
  {
196
  "key": "track_404",
197
+ "section": "section_probes",
198
+ "premium": true,
199
+ "default": "log",
200
  "type": "select",
201
+ "value_options": [
202
+ {
203
+ "value_key": "disabled",
204
+ "text": "Disabled"
205
+ },
206
+ {
207
+ "value_key": "log",
208
+ "text": "Audit Log Only"
209
+ },
210
+ {
211
+ "value_key": "transgression-single",
212
+ "text": "Increment Transgression"
213
+ },
214
+ {
215
+ "value_key": "transgression-double",
216
+ "text": "Double Transgression"
217
+ },
218
+ {
219
+ "value_key": "block",
220
+ "text": "Immediate Block"
221
+ }
222
+ ],
223
+ "link_info": "https://icwp.io/f5",
224
+ "link_blog": "https://icwp.io/f7",
225
+ "name": "404 Detect",
226
+ "summary": "Identify A Bot When It Hits A 404",
227
+ "description": "Detect When A Visitor Browses To A Non-Existent Page."
228
+ },
229
+ {
230
+ "key": "track_linkcheese",
231
+ "section": "section_probes",
232
  "premium": true,
233
  "default": "disabled",
234
+ "type": "select",
235
+ "value_options": [
236
+ {
237
+ "value_key": "disabled",
238
+ "text": "Disabled"
239
+ },
240
+ {
241
+ "value_key": "log",
242
+ "text": "Audit Log Only"
243
+ },
244
+ {
245
+ "value_key": "transgression-single",
246
+ "text": "Increment Transgression"
247
+ },
248
+ {
249
+ "value_key": "transgression-double",
250
+ "text": "Double Transgression"
251
+ },
252
+ {
253
+ "value_key": "block",
254
+ "text": "Immediate Block"
255
+ }
256
+ ],
257
+ "link_info": "https://icwp.io/f5",
258
+ "link_blog": "https://icwp.io/f6",
259
+ "name": "Link Cheese",
260
+ "summary": "Tempt A Bot With A Fake Link To Follow",
261
+ "description": "Detect A Bot That Follows A 'no-follow' Link."
262
+ },
263
+ {
264
+ "key": "track_xmlrpc",
265
+ "section": "section_probes",
266
+ "default": "log",
267
+ "premium": true,
268
+ "type": "select",
269
  "value_options": [
270
  {
271
  "value_key": "disabled",
272
+ "text": "Disabled"
273
  },
274
  {
275
+ "value_key": "log",
276
+ "text": "Audit Log Only"
277
  },
278
  {
279
+ "value_key": "transgression-single",
280
  "text": "Increment Transgression"
281
+ },
282
+ {
283
+ "value_key": "transgression-double",
284
+ "text": "Double Transgression"
285
+ },
286
+ {
287
+ "value_key": "block",
288
+ "text": "Immediate Block"
289
  }
290
  ],
291
+ "link_info": "https://icwp.io/f5",
292
+ "link_blog": "https://icwp.io/f7",
293
+ "name": "XML-RPC Access",
294
+ "summary": "Identify A Bot When It Accesses XML-RPC",
295
+ "description": "If you don't use XML-RPC, why would anyone access it?"
296
+ },
297
+ {
298
+ "key": "track_loginfailed",
299
+ "section": "section_logins",
300
+ "default": "transgression-single",
301
+ "type": "select",
302
+ "value_options": [
303
+ {
304
+ "value_key": "disabled",
305
+ "text": "Disabled"
306
+ },
307
+ {
308
+ "value_key": "log",
309
+ "text": "Audit Log Only"
310
+ },
311
+ {
312
+ "value_key": "transgression-single",
313
+ "text": "Increment Transgression"
314
+ },
315
+ {
316
+ "value_key": "transgression-double",
317
+ "text": "Double Transgression"
318
+ },
319
+ {
320
+ "value_key": "block",
321
+ "text": "Immediate Block"
322
+ }
323
+ ],
324
+ "link_info": "https://icwp.io/f5",
325
+ "link_blog": "https://icwp.io/f7",
326
+ "name": "Failed Login",
327
+ "summary": "Detect Failed Login Attempts By Valid Usernames",
328
+ "description": "Penalise a visitor who fails to login using a valid username."
329
+ },
330
+ {
331
+ "key": "track_logininvalid",
332
+ "section": "section_logins",
333
+ "premium": true,
334
+ "default": "log",
335
+ "type": "select",
336
+ "value_options": [
337
+ {
338
+ "value_key": "disabled",
339
+ "text": "Disabled"
340
+ },
341
+ {
342
+ "value_key": "log",
343
+ "text": "Audit Log Only"
344
+ },
345
+ {
346
+ "value_key": "transgression-single",
347
+ "text": "Increment Transgression"
348
+ },
349
+ {
350
+ "value_key": "transgression-double",
351
+ "text": "Double Transgression"
352
+ },
353
+ {
354
+ "value_key": "block",
355
+ "text": "Immediate Block"
356
+ }
357
+ ],
358
+ "link_info": "https://icwp.io/f5",
359
+ "link_blog": "https://icwp.io/f7",
360
+ "name": "Invalid Usernames",
361
+ "summary": "Detect Invalid Username Logins",
362
+ "description": "Identify A Bot When It Tries To Login With A Non-Existent Username."
363
+ },
364
+ {
365
+ "key": "track_fakewebcrawler",
366
+ "section": "section_behaviours",
367
+ "premium": true,
368
+ "default": "log",
369
+ "type": "select",
370
+ "value_options": [
371
+ {
372
+ "value_key": "disabled",
373
+ "text": "Disabled"
374
+ },
375
+ {
376
+ "value_key": "log",
377
+ "text": "Audit Log Only"
378
+ },
379
+ {
380
+ "value_key": "transgression-single",
381
+ "text": "Increment Transgression"
382
+ },
383
+ {
384
+ "value_key": "transgression-double",
385
+ "text": "Double Transgression"
386
+ },
387
+ {
388
+ "value_key": "block",
389
+ "text": "Immediate Block"
390
+ }
391
+ ],
392
+ "link_info": "https://icwp.io/f5",
393
+ "link_blog": "https://icwp.io/f7",
394
+ "name": "Fake Web Crawler",
395
+ "summary": "Detect Fake Search Engine Crawlers",
396
+ "description": "Identify a Bot when it presents as an official web crawler, but analysis shows it's fake."
397
+ },
398
+ {
399
+ "key": "track_useragent",
400
+ "section": "section_behaviours",
401
+ "premium": true,
402
+ "default": "log",
403
+ "type": "select",
404
+ "value_options": [
405
+ {
406
+ "value_key": "disabled",
407
+ "text": "Disabled"
408
+ },
409
+ {
410
+ "value_key": "log",
411
+ "text": "Audit Log Only"
412
+ },
413
+ {
414
+ "value_key": "transgression-single",
415
+ "text": "Increment Transgression"
416
+ },
417
+ {
418
+ "value_key": "transgression-double",
419
+ "text": "Double Transgression"
420
+ },
421
+ {
422
+ "value_key": "block",
423
+ "text": "Immediate Block"
424
+ }
425
+ ],
426
+ "link_info": "https://icwp.io/f5",
427
+ "link_blog": "https://icwp.io/f7",
428
+ "name": "Empty User Agents",
429
+ "summary": "Detect Requests With Empty User Agents",
430
+ "description": "Identify a request as a bot if the user agent is not provided."
431
  },
432
  {
433
  "key": "text_remainingtrans",
src/config/feature-login_protect.php CHANGED
@@ -291,6 +291,7 @@
291
  "key": "login_limit_interval",
292
  "section": "section_brute_force_login_protection",
293
  "default": "10",
 
294
  "type": "integer",
295
  "link_info": "https://icwp.io/3q",
296
  "link_blog": "https://icwp.io/9o",
291
  "key": "login_limit_interval",
292
  "section": "section_brute_force_login_protection",
293
  "default": "10",
294
+ "min": 0,
295
  "type": "integer",
296
  "link_info": "https://icwp.io/3q",
297
  "link_blog": "https://icwp.io/9o",
src/config/feature-mousetrap.php DELETED
@@ -1,162 +0,0 @@
1
- {
2
- "slug": "mousetrap",
3
- "properties": {
4
- "slug": "mousetrap",
5
- "name": "MouseTrap",
6
- "show_module_menu_item": false,
7
- "show_module_options": true,
8
- "storage_key": "mousetrap",
9
- "tagline": "Identify, Trap and Block Bots",
10
- "show_central": true,
11
- "access_restricted": true,
12
- "premium": false,
13
- "run_if_whitelisted": false,
14
- "run_if_verified_bot": false,
15
- "order": 30
16
- },
17
- "sections": [
18
- {
19
- "slug": "section_cheese",
20
- "primary": true,
21
- "title": "Tempt Bots With Links",
22
- "title_short": "Link Cheese",
23
- "summary": [
24
- "Recommendation - Enable to capture bots/spiders that don't honour 'nofollow' directives."
25
- ]
26
- },
27
- {
28
- "slug": "section_enable_plugin_feature_mousetrap",
29
- "title": "Enable Module: MouseTrap",
30
- "title_short": "Enable Module",
31
- "summary": [
32
- "Purpose - MouseTrap monitors a typical set of bot behaviours to help identify probing bots.",
33
- "Recommendation - Enable as many mouse traps as possible."
34
- ]
35
- },
36
- {
37
- "slug": "section_non_ui",
38
- "hidden": true
39
- }
40
- ],
41
- "options": [
42
- {
43
- "key": "enable_mousetrap",
44
- "section": "section_enable_plugin_feature_mousetrap",
45
- "default": "Y",
46
- "type": "checkbox",
47
- "link_info": "",
48
- "link_blog": "",
49
- "name": "Enable MouseTrap",
50
- "summary": "Enable (or Disable) The MouseTrap module",
51
- "description": "Un-Checking this option will completely disable the MouseTrap module"
52
- },
53
- {
54
- "key": "404_detect",
55
- "section": "section_cheese",
56
- "default": "disabled",
57
- "type": "select",
58
- "value_options": [
59
- {
60
- "value_key": "disabled",
61
- "text": "Disabled"
62
- },
63
- {
64
- "value_key": "transgression",
65
- "text": "Increment Transgression"
66
- },
67
- {
68
- "value_key": "block",
69
- "text": "Immediate Block"
70
- }
71
- ],
72
- "link_info": "",
73
- "link_blog": "",
74
- "name": "404 Detect",
75
- "summary": "Identify A Bot When It Hits A 404",
76
- "description": "Detect When A Visitor Browses To A Non-Existent Page."
77
- },
78
- {
79
- "key": "link_cheese",
80
- "section": "section_cheese",
81
- "default": "transgression",
82
- "type": "select",
83
- "value_options": [
84
- {
85
- "value_key": "disabled",
86
- "text": "Disabled"
87
- },
88
- {
89
- "value_key": "transgression",
90
- "text": "Increment Transgression"
91
- },
92
- {
93
- "value_key": "block",
94
- "text": "Immediate Block"
95
- }
96
- ],
97
- "link_info": "",
98
- "link_blog": "",
99
- "name": "Link Cheese",
100
- "summary": "Tempt A Bot With A Link To Follow",
101
- "description": "Detect A Bot That Follows A 'no-follow' Link."
102
- },
103
- {
104
- "key": "invalid_username",
105
- "section": "section_cheese",
106
- "default": "transgression",
107
- "type": "select",
108
- "value_options": [
109
- {
110
- "value_key": "disabled",
111
- "text": "Disabled"
112
- },
113
- {
114
- "value_key": "transgression",
115
- "text": "Increment Transgression"
116
- },
117
- {
118
- "value_key": "block",
119
- "text": "Immediate Block"
120
- }
121
- ],
122
- "link_info": "",
123
- "link_blog": "",
124
- "name": "Invalid Usernames",
125
- "summary": "Detect Invalid Username Logins",
126
- "description": "Identify A Bot When It Tries To Login With A Non-Existent Username."
127
- },
128
- {
129
- "key": "fake_webcrawler",
130
- "section": "section_cheese",
131
- "default": "transgression",
132
- "type": "select",
133
- "value_options": [
134
- {
135
- "value_key": "disabled",
136
- "text": "Disabled"
137
- },
138
- {
139
- "value_key": "transgression",
140
- "text": "Increment Transgression"
141
- },
142
- {
143
- "value_key": "block",
144
- "text": "Immediate Block"
145
- }
146
- ],
147
- "link_info": "",
148
- "link_blog": "",
149
- "name": "Fake Web Crawler",
150
- "summary": "Detect Fake Search Engine Crawlers",
151
- "description": "Identify a Bot when it presents as an official web crawler, but analysis shows it's fake."
152
- },
153
- {
154
- "key": "insights_last_firewall_block_at",
155
- "transferable": false,
156
- "section": "section_non_ui",
157
- "default": 0
158
- }
159
- ],
160
- "definitions": {
161
- }
162
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/config/feature-plugin.php CHANGED
@@ -367,6 +367,13 @@
367
  "type": "integer",
368
  "default": 0
369
  },
 
 
 
 
 
 
 
370
  {
371
  "key": "importexport_secretkey_expires_at",
372
  "section": "section_non_ui",
@@ -416,6 +423,13 @@
416
  "section": "section_non_ui",
417
  "type": "text",
418
  "default": ""
 
 
 
 
 
 
 
419
  }
420
  ],
421
  "definitions": {
@@ -437,14 +451,18 @@
437
  {
438
  "slug": "insights",
439
  "storage_key": "insights",
440
- "menu_priority": 5,
441
- "min_php": "5.4"
442
  },
443
  {
444
  "slug": "admin_access_restriction",
445
  "storage_key": "admin_access_restriction",
446
  "load_priority": 11
447
  },
 
 
 
 
 
448
  {
449
  "slug": "hack_protect",
450
  "storage_key": "hack_protect"
@@ -478,11 +496,6 @@
478
  "slug": "lockdown",
479
  "storage_key": "lockdown"
480
  },
481
- {
482
- "slug": "ips",
483
- "storage_key": "ips",
484
- "load_priority": 12
485
- },
486
  {
487
  "slug": "statistics",
488
  "storage_key": "statistics",
@@ -530,9 +543,6 @@
530
  "ip_detect": {
531
  "title": "IP Detection"
532
  },
533
- "license": {
534
- "title": "Go Pro"
535
- },
536
  "admin_access_restriction": {
537
  "title": "Security Admin"
538
  },
367
  "type": "integer",
368
  "default": 0
369
  },
370
+ {
371
+ "key": "activated_at",
372
+ "transferable": false,
373
+ "section": "section_non_ui",
374
+ "type": "integer",
375
+ "default": 0
376
+ },
377
  {
378
  "key": "importexport_secretkey_expires_at",
379
  "section": "section_non_ui",
423
  "section": "section_non_ui",
424
  "type": "text",
425
  "default": ""
426
+ },
427
+ {
428
+ "key": "openssl_private_key",
429
+ "transferable": false,
430
+ "section": "section_non_ui",
431
+ "type": "text",
432
+ "default": ""
433
  }
434
  ],
435
  "definitions": {
451
  {
452
  "slug": "insights",
453
  "storage_key": "insights",
454
+ "menu_priority": 5
 
455
  },
456
  {
457
  "slug": "admin_access_restriction",
458
  "storage_key": "admin_access_restriction",
459
  "load_priority": 11
460
  },
461
+ {
462
+ "slug": "ips",
463
+ "storage_key": "ips",
464
+ "load_priority": 12
465
+ },
466
  {
467
  "slug": "hack_protect",
468
  "storage_key": "hack_protect"
496
  "slug": "lockdown",
497
  "storage_key": "lockdown"
498
  },
 
 
 
 
 
499
  {
500
  "slug": "statistics",
501
  "storage_key": "statistics",
543
  "ip_detect": {
544
  "title": "IP Detection"
545
  },
 
 
 
546
  "admin_access_restriction": {
547
  "title": "Security Admin"
548
  },
src/features/admin_access_restriction.php CHANGED
@@ -54,10 +54,10 @@ class ICWP_WPSF_FeatureHandler_AdminAccessRestriction extends ICWP_WPSF_FeatureH
54
  * @return array
55
  */
56
  private function ajaxExec_SecAdminCheck() {
57
- return array(
58
  'timeleft' => $this->getSecAdminTimeLeft(),
59
  'success' => $this->isSecAdminSessionValid()
60
- );
61
  }
62
 
63
  /**
@@ -106,10 +106,10 @@ class ICWP_WPSF_FeatureHandler_AdminAccessRestriction extends ICWP_WPSF_FeatureH
106
  * @return array
107
  */
108
  private function ajaxExec_SecAdminLoginBox() {
109
- return array(
110
  'success' => 'true',
111
  'html' => $this->renderAdminAccessAjaxLoginForm()
112
- );
113
  }
114
 
115
  /**
@@ -118,14 +118,14 @@ class ICWP_WPSF_FeatureHandler_AdminAccessRestriction extends ICWP_WPSF_FeatureH
118
  */
119
  protected function renderAdminAccessAjaxLoginForm( $sMessage = '' ) {
120
 
121
- $aData = array(
122
  'ajax' => array(
123
  'sec_admin_login' => json_encode( $this->getSecAdminLoginAjaxData() )
124
  ),
125
  'strings' => array(
126
  'access_message' => empty( $sMessage ) ? _wpsf__( 'Enter your Security Admin Access Key' ) : $sMessage
127
  )
128
- );
129
  return $this->renderTemplate( 'snippets/admin_access_login', $aData );
130
  }
131
 
@@ -251,11 +251,11 @@ class ICWP_WPSF_FeatureHandler_AdminAccessRestriction extends ICWP_WPSF_FeatureH
251
 
252
  // Verify whitelabel images
253
  if ( $this->isWlEnabled() ) {
254
- $aImages = array(
255
  'wl_menuiconurl',
256
  'wl_dashboardlogourl',
257
  'wl_login2fa_logourl',
258
- );
259
  $oDP = $this->loadDP();
260
  $oOpts = $this->getOptionsVo();
261
  foreach ( $aImages as $sKey ) {
@@ -424,7 +424,7 @@ class ICWP_WPSF_FeatureHandler_AdminAccessRestriction extends ICWP_WPSF_FeatureH
424
  $sMenu = $sMain;
425
  }
426
 
427
- return array(
428
  'name_main' => $sMain,
429
  'name_menu' => $sMenu,
430
  'name_company' => $this->getOpt( 'wl_companyname' ),
@@ -433,7 +433,7 @@ class ICWP_WPSF_FeatureHandler_AdminAccessRestriction extends ICWP_WPSF_FeatureH
433
  'url_icon' => $this->buildWlImageUrl( 'wl_menuiconurl' ),
434
  'url_dashboardlogourl' => $this->buildWlImageUrl( 'wl_dashboardlogourl' ),
435
  'url_login2fa_logourl' => $this->buildWlImageUrl( 'wl_login2fa_logourl' ),
436
- );
437
  }
438
 
439
  /**
54
  * @return array
55
  */
56
  private function ajaxExec_SecAdminCheck() {
57
+ return [
58
  'timeleft' => $this->getSecAdminTimeLeft(),
59
  'success' => $this->isSecAdminSessionValid()
60
+ ];
61
  }
62
 
63
  /**
106
  * @return array
107
  */
108
  private function ajaxExec_SecAdminLoginBox() {
109
+ return [
110
  'success' => 'true',
111
  'html' => $this->renderAdminAccessAjaxLoginForm()
112
+ ];
113
  }
114
 
115
  /**
118
  */
119
  protected function renderAdminAccessAjaxLoginForm( $sMessage = '' ) {
120
 
121
+ $aData = [
122
  'ajax' => array(
123
  'sec_admin_login' => json_encode( $this->getSecAdminLoginAjaxData() )
124
  ),
125
  'strings' => array(
126
  'access_message' => empty( $sMessage ) ? _wpsf__( 'Enter your Security Admin Access Key' ) : $sMessage
127
  )
128
+ ];
129
  return $this->renderTemplate( 'snippets/admin_access_login', $aData );
130
  }
131
 
251
 
252
  // Verify whitelabel images
253
  if ( $this->isWlEnabled() ) {
254
+ $aImages = [
255
  'wl_menuiconurl',
256
  'wl_dashboardlogourl',
257
  'wl_login2fa_logourl',
258
+ ];
259
  $oDP = $this->loadDP();
260
  $oOpts = $this->getOptionsVo();
261
  foreach ( $aImages as $sKey ) {
424
  $sMenu = $sMain;
425
  }
426
 
427
+ return [
428
  'name_main' => $sMain,
429
  'name_menu' => $sMenu,
430
  'name_company' => $this->getOpt( 'wl_companyname' ),
433
  'url_icon' => $this->buildWlImageUrl( 'wl_menuiconurl' ),
434
  'url_dashboardlogourl' => $this->buildWlImageUrl( 'wl_dashboardlogourl' ),
435
  'url_login2fa_logourl' => $this->buildWlImageUrl( 'wl_login2fa_logourl' ),
436
+ ];
437
  }
438
 
439
  /**
src/features/autoupdates.php CHANGED
@@ -17,11 +17,11 @@ class ICWP_WPSF_FeatureHandler_Autoupdates extends ICWP_WPSF_FeatureHandler_Base
17
  * @return string[]
18
  */
19
  public function getAutoupdatePlugins() {
20
- $aSelected = array();
21
  if ( $this->isAutoupdateIndividualPlugins() ) {
22
- $aSelected = $this->getOpt( 'selected_plugins', array() );
23
  if ( !is_array( $aSelected ) ) {
24
- $aSelected = array();
25
  }
26
  }
27
  return $aSelected;
@@ -31,15 +31,15 @@ class ICWP_WPSF_FeatureHandler_Autoupdates extends ICWP_WPSF_FeatureHandler_Base
31
  * @return array
32
  */
33
  public function getDelayTracking() {
34
- $aTracking = $this->getOpt( 'delay_tracking', array() );
35
  if ( !is_array( $aTracking ) ) {
36
- $aTracking = array();
37
  }
38
  $aTracking = $this->loadDP()->mergeArraysRecursive(
39
  array(
40
- 'core' => array(),
41
- 'plugins' => array(),
42
- 'themes' => array(),
43
  ),
44
  $aTracking
45
  );
@@ -205,7 +205,7 @@ class ICWP_WPSF_FeatureHandler_Autoupdates extends ICWP_WPSF_FeatureHandler_Base
205
  public function addInsightsNoticeData( $aAllNotices ) {
206
  $aNotices = array(
207
  'title' => _wpsf__( 'Automatic Updates' ),
208
- 'messages' => array()
209
  );
210
  { //really disabled?
211
  $oWp = Services::WpGeneral();
@@ -239,7 +239,7 @@ class ICWP_WPSF_FeatureHandler_Autoupdates extends ICWP_WPSF_FeatureHandler_Base
239
  'title' => _wpsf__( 'Automatic Updates' ),
240
  'sub' => _wpsf__( 'Control WordPress Automatic Updates' ),
241
  ),
242
- 'key_opts' => array(),
243
  'href_options' => $this->getUrl_AdminPage()
244
  );
245
 
@@ -365,7 +365,7 @@ class ICWP_WPSF_FeatureHandler_Autoupdates extends ICWP_WPSF_FeatureHandler_Base
365
  throw new \Exception( sprintf( 'A section slug was defined but with no associated strings. Slug: "%s".', $sSectionSlug ) );
366
  }
367
  $aOptionsParams[ 'title' ] = $sTitle;
368
- $aOptionsParams[ 'summary' ] = ( isset( $aSummary ) && is_array( $aSummary ) ) ? $aSummary : array();
369
  $aOptionsParams[ 'title_short' ] = $sTitleShort;
370
  return $aOptionsParams;
371
  }
17
  * @return string[]
18
  */
19
  public function getAutoupdatePlugins() {
20
+ $aSelected = [];
21
  if ( $this->isAutoupdateIndividualPlugins() ) {
22
+ $aSelected = $this->getOpt( 'selected_plugins', [] );
23
  if ( !is_array( $aSelected ) ) {
24
+ $aSelected = [];
25
  }
26
  }
27
  return $aSelected;
31
  * @return array
32
  */
33
  public function getDelayTracking() {
34
+ $aTracking = $this->getOpt( 'delay_tracking', [] );
35
  if ( !is_array( $aTracking ) ) {
36
+ $aTracking = [];
37
  }
38
  $aTracking = $this->loadDP()->mergeArraysRecursive(
39
  array(
40
+ 'core' => [],
41
+ 'plugins' => [],
42
+ 'themes' => [],
43
  ),
44
  $aTracking
45
  );
205
  public function addInsightsNoticeData( $aAllNotices ) {
206
  $aNotices = array(
207
  'title' => _wpsf__( 'Automatic Updates' ),
208
+ 'messages' => []
209
  );
210
  { //really disabled?
211
  $oWp = Services::WpGeneral();
239
  'title' => _wpsf__( 'Automatic Updates' ),
240
  'sub' => _wpsf__( 'Control WordPress Automatic Updates' ),
241
  ),
242
+ 'key_opts' => [],
243
  'href_options' => $this->getUrl_AdminPage()
244
  );
245
 
365
  throw new \Exception( sprintf( 'A section slug was defined but with no associated strings. Slug: "%s".', $sSectionSlug ) );
366
  }
367
  $aOptionsParams[ 'title' ] = $sTitle;
368
+ $aOptionsParams[ 'summary' ] = ( isset( $aSummary ) && is_array( $aSummary ) ) ? $aSummary : [];
369
  $aOptionsParams[ 'title_short' ] = $sTitleShort;
370
  return $aOptionsParams;
371
  }
src/features/base.php CHANGED
@@ -52,7 +52,7 @@ abstract class ICWP_WPSF_FeatureHandler_Base extends ICWP_WPSF_Foundation {
52
  * @param array $aMod
53
  * @throws \Exception
54
  */
55
- public function __construct( $oPluginController, $aMod = array() ) {
56
  if ( empty( self::$oPluginController ) ) {
57
  if ( !$oPluginController instanceof ICWP_WPSF_Plugin_Controller ) {
58
  throw new \Exception( 'Plugin controller not supplied to Module' );
@@ -165,6 +165,10 @@ abstract class ICWP_WPSF_FeatureHandler_Base extends ICWP_WPSF_Foundation {
165
  if ( empty( $aAjaxResponse ) ) {
166
  switch ( Services::Request()->request( 'exec' ) ) {
167
 
 
 
 
 
168
  case 'mod_options':
169
  $aAjaxResponse = $this->ajaxExec_ModOptions();
170
  break;
@@ -211,14 +215,35 @@ abstract class ICWP_WPSF_FeatureHandler_Base extends ICWP_WPSF_Foundation {
211
  }
212
 
213
  /**
214
- * @param bool $bBase64Encoded
215
  * @return array
216
  */
217
- protected function getAjaxFormParams( $bBase64Encoded = false ) {
 
218
  $aFormParams = [];
219
- $sRaw = Services::Request()->post( 'form_params', '' );
220
  if ( !empty( $sRaw ) ) {
221
- parse_str( ( $bBase64Encoded ? base64_decode( $sRaw ) : $sRaw ), $aFormParams );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
222
  }
223
  return $aFormParams;
224
  }
@@ -229,7 +254,7 @@ abstract class ICWP_WPSF_FeatureHandler_Base extends ICWP_WPSF_Foundation {
229
  */
230
  public function fRegisterAdminNotices( $aAdminNotices ) {
231
  if ( !is_array( $aAdminNotices ) ) {
232
- $aAdminNotices = array();
233
  }
234
  return array_merge( $aAdminNotices, $this->getOptionsVo()->getAdminNotices() );
235
  }
@@ -582,7 +607,7 @@ abstract class ICWP_WPSF_FeatureHandler_Base extends ICWP_WPSF_Foundation {
582
  $aItems[ $sMenuPageTitle ] = array(
583
  $sMenuTitleName,
584
  $this->getModSlug(),
585
- array( $this, 'displayModuleAdminPage' ),
586
  $this->getIfShowModuleMenuItem()
587
  );
588
 
@@ -611,7 +636,7 @@ abstract class ICWP_WPSF_FeatureHandler_Base extends ICWP_WPSF_Foundation {
611
  * @return array
612
  */
613
  protected function getAdditionalMenuItem() {
614
- return array();
615
  }
616
 
617
  /**
@@ -707,7 +732,7 @@ abstract class ICWP_WPSF_FeatureHandler_Base extends ICWP_WPSF_Foundation {
707
  * @return $this
708
  */
709
  public function clearLastErrors() {
710
- return $this->setLastErrors( array() );
711
  }
712
 
713
  /**
@@ -718,7 +743,7 @@ abstract class ICWP_WPSF_FeatureHandler_Base extends ICWP_WPSF_Foundation {
718
  public function getLastErrors( $bAsString = true, $sGlue = " " ) {
719
  $aErrors = $this->getOpt( 'last_errors' );
720
  if ( !is_array( $aErrors ) ) {
721
- $aErrors = array();
722
  }
723
  return $bAsString ? implode( $sGlue, $aErrors ) : $aErrors;
724
  }
@@ -783,13 +808,13 @@ abstract class ICWP_WPSF_FeatureHandler_Base extends ICWP_WPSF_Foundation {
783
  * @param array|string $mErrors
784
  * @return $this
785
  */
786
- public function setLastErrors( $mErrors = array() ) {
787
  if ( !is_array( $mErrors ) ) {
788
  if ( is_string( $mErrors ) ) {
789
  $mErrors = array( $mErrors );
790
  }
791
  else {
792
- $mErrors = array();
793
  }
794
  }
795
  return $this->setOpt( 'last_errors', $mErrors );
@@ -966,7 +991,7 @@ abstract class ICWP_WPSF_FeatureHandler_Base extends ICWP_WPSF_Foundation {
966
  $aOptions[ $nSectionKey ] = $this->loadStrings_SectionTitles( $aSection );
967
  }
968
 
969
- $aWarnings = array();
970
  if ( !$oOptsVo->isSectionReqsMet( $aSection[ 'slug' ] ) ) {
971
  $aWarnings[] = _wpsf__( 'Unfortunately your WordPress and/or PHP versions are too old to support this feature.' );
972
  }
@@ -1016,7 +1041,7 @@ abstract class ICWP_WPSF_FeatureHandler_Base extends ICWP_WPSF_Foundation {
1016
  case 'array':
1017
 
1018
  if ( empty( $mCurrent ) || !is_array( $mCurrent ) ) {
1019
- $mCurrent = array();
1020
  }
1021
 
1022
  $aOptParams[ 'rows' ] = count( $mCurrent ) + 2;
@@ -1026,7 +1051,7 @@ abstract class ICWP_WPSF_FeatureHandler_Base extends ICWP_WPSF_Foundation {
1026
 
1027
  case 'comma_separated_lists':
1028
 
1029
- $aNewValues = array();
1030
  if ( !empty( $mCurrent ) && is_array( $mCurrent ) ) {
1031
 
1032
  foreach ( $mCurrent as $sPage => $aParams ) {
@@ -1040,7 +1065,7 @@ abstract class ICWP_WPSF_FeatureHandler_Base extends ICWP_WPSF_Foundation {
1040
 
1041
  case 'multiple_select':
1042
  if ( !is_array( $mCurrent ) ) {
1043
- $mCurrent = array();
1044
  }
1045
  break;
1046
 
@@ -1098,7 +1123,7 @@ abstract class ICWP_WPSF_FeatureHandler_Base extends ICWP_WPSF_Foundation {
1098
  * @return array - map of each option to its option type
1099
  */
1100
  protected function getAllFormOptionsAndTypes() {
1101
- $aOpts = array();
1102
 
1103
  foreach ( $this->buildOptions() as $aOptionsSection ) {
1104
  if ( !empty( $aOptionsSection ) ) {
@@ -1136,11 +1161,29 @@ abstract class ICWP_WPSF_FeatureHandler_Base extends ICWP_WPSF_Foundation {
1136
  catch ( \Exception $oE ) {
1137
  $sForm = 'Error during form render';
1138
  }
1139
- return array(
1140
  'success' => $bSuccess,
1141
  'html' => $sForm,
1142
  'message' => $sMessage
1143
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1144
  }
1145
 
1146
  /**
@@ -1238,7 +1281,7 @@ abstract class ICWP_WPSF_FeatureHandler_Base extends ICWP_WPSF_Foundation {
1238
  * @throws \Exception
1239
  */
1240
  private function doSaveStandardOptions() {
1241
- $aForm = $this->getAjaxFormParams( true );
1242
  if ( empty( $aForm[ 'plugin_form_submit' ] ) || $aForm[ 'plugin_form_submit' ] !== 'Y' ) {
1243
  throw new \Exception( 'Not a standard plugin options form submission' );
1244
  }
@@ -1376,29 +1419,43 @@ abstract class ICWP_WPSF_FeatureHandler_Base extends ICWP_WPSF_Foundation {
1376
  }
1377
 
1378
  /**
 
1379
  */
1380
  public function displayModuleAdminPage() {
1381
  if ( $this->canDisplayOptionsForm() ) {
1382
- $this->displayModulePage();
1383
  }
1384
  else {
1385
- $this->displayRestrictedPage();
1386
  }
1387
  }
1388
 
 
 
 
 
 
 
 
 
 
1389
  /**
1390
  * Override this to customize anything with the display of the page
1391
  * @param array $aData
 
1392
  */
1393
- protected function displayModulePage( $aData = array() ) {
1394
  // Get Base Data
1395
  $aData = $this->loadDP()->mergeArraysRecursive( $this->getBaseDisplayData( true ), $aData );
1396
  $aData[ 'content' ][ 'options_form' ] = $this->renderOptionsForm();
1397
 
1398
- echo $this->renderTemplate( 'index.php', $aData );
1399
  }
1400
 
1401
- protected function displayRestrictedPage() {
 
 
 
1402
  $aData = $this->loadDP()
1403
  ->mergeArraysRecursive(
1404
  $this->getBaseDisplayData( false ),
@@ -1408,7 +1465,7 @@ abstract class ICWP_WPSF_FeatureHandler_Base extends ICWP_WPSF_Foundation {
1408
  )
1409
  )
1410
  );
1411
- echo $this->renderTemplate( 'access_restricted.php', $aData );
1412
  }
1413
 
1414
  /**
@@ -1550,13 +1607,13 @@ abstract class ICWP_WPSF_FeatureHandler_Base extends ICWP_WPSF_Foundation {
1550
  * @return array[]
1551
  */
1552
  protected function getModulesSummaryData() {
1553
- return apply_filters( $this->prefix( 'collect_mod_summary' ), array() );
1554
  }
1555
 
1556
  /**
1557
- * @uses nonce
1558
  * @param string $sWizardSlug
1559
  * @return string
 
1560
  */
1561
  public function getUrl_Wizard( $sWizardSlug ) {
1562
  $aDef = $this->getWizardDefinition( $sWizardSlug );
@@ -1603,7 +1660,7 @@ abstract class ICWP_WPSF_FeatureHandler_Base extends ICWP_WPSF_Foundation {
1603
  */
1604
  public function getWizardDefinitions() {
1605
  $aW = $this->getDef( 'wizards' );
1606
- return is_array( $aW ) ? $aW : array();
1607
  }
1608
 
1609
  /**
@@ -1685,7 +1742,8 @@ abstract class ICWP_WPSF_FeatureHandler_Base extends ICWP_WPSF_Foundation {
1685
  'icwp_wpsf_vars_base',
1686
  [
1687
  'ajax' => [
1688
- 'mod_options' => $this->getAjaxActionData( 'mod_options' ),
 
1689
  ]
1690
  ]
1691
  );
@@ -1696,7 +1754,7 @@ abstract class ICWP_WPSF_FeatureHandler_Base extends ICWP_WPSF_Foundation {
1696
  * @param array $aData
1697
  * @param string $sSubView
1698
  */
1699
- protected function display( $aData = array(), $sSubView = '' ) {
1700
  }
1701
 
1702
  /**
@@ -1714,7 +1772,7 @@ abstract class ICWP_WPSF_FeatureHandler_Base extends ICWP_WPSF_Foundation {
1714
  }
1715
 
1716
  if ( !isset( $aData[ 'notice_classes' ] ) ) {
1717
- $aData[ 'notice_classes' ] = array();
1718
  }
1719
  if ( is_array( $aData[ 'notice_classes' ] ) ) {
1720
  $aData[ 'notice_classes' ][] = $aData[ 'notice_attributes' ][ 'type' ];
@@ -1741,7 +1799,7 @@ abstract class ICWP_WPSF_FeatureHandler_Base extends ICWP_WPSF_Foundation {
1741
  * @param bool $bUseTwig
1742
  * @return string
1743
  */
1744
- public function renderTemplate( $sTemplate, $aData = array(), $bUseTwig = false ) {
1745
  if ( empty( $aData[ 'unique_render_id' ] ) ) {
1746
  $aData[ 'unique_render_id' ] = 'noticeid-'.substr( md5( mt_rand() ), 0, 5 );
1747
  }
@@ -1769,7 +1827,7 @@ abstract class ICWP_WPSF_FeatureHandler_Base extends ICWP_WPSF_Foundation {
1769
  */
1770
  public function exportTransferableOptions( $aTransferableOptions ) {
1771
  if ( !is_array( $aTransferableOptions ) ) {
1772
- $aTransferableOptions = array();
1773
  }
1774
  $aTransferableOptions[ $this->getOptionsStorageKey() ] = $this->getOptionsVo()->getTransferableOptions();
1775
  return $aTransferableOptions;
@@ -1824,7 +1882,7 @@ abstract class ICWP_WPSF_FeatureHandler_Base extends ICWP_WPSF_Foundation {
1824
  * @return array
1825
  */
1826
  protected function getHelpVideoOptions() {
1827
- $aOptions = $this->getOpt( 'help_video_options', array() );
1828
  if ( is_null( $aOptions ) || !is_array( $aOptions ) ) {
1829
  $aOptions = array(
1830
  'closed' => false,
@@ -1901,7 +1959,7 @@ abstract class ICWP_WPSF_FeatureHandler_Base extends ICWP_WPSF_Foundation {
1901
  * @return $this
1902
  */
1903
  protected function resetHelpVideoOptions() {
1904
- return $this->setOpt( 'help_video_options', array() );
1905
  }
1906
 
1907
  /**
@@ -1947,8 +2005,8 @@ abstract class ICWP_WPSF_FeatureHandler_Base extends ICWP_WPSF_Foundation {
1947
  }
1948
 
1949
  /**
1950
- * @deprecated
1951
  * @return string
 
1952
  */
1953
  public function getVersion() {
1954
  return $this->getCon()->getVersion();
52
  * @param array $aMod
53
  * @throws \Exception
54
  */
55
+ public function __construct( $oPluginController, $aMod = [] ) {
56
  if ( empty( self::$oPluginController ) ) {
57
  if ( !$oPluginController instanceof ICWP_WPSF_Plugin_Controller ) {
58
  throw new \Exception( 'Plugin controller not supplied to Module' );
165
  if ( empty( $aAjaxResponse ) ) {
166
  switch ( Services::Request()->request( 'exec' ) ) {
167
 
168
+ case 'mod_opts_render':
169
+ $aAjaxResponse = $this->ajaxExec_ModOptionsRender();
170
+ break;
171
+
172
  case 'mod_options':
173
  $aAjaxResponse = $this->ajaxExec_ModOptions();
174
  break;
215
  }
216
 
217
  /**
218
+ * @param string $sEncoding
219
  * @return array
220
  */
221
+ protected function getAjaxFormParams( $sEncoding = 'none' ) {
222
+ $oReq = Services::Request();
223
  $aFormParams = [];
224
+ $sRaw = $oReq->post( 'form_params', '' );
225
  if ( !empty( $sRaw ) ) {
226
+
227
+ $sMaybeEncoding = $oReq->post( 'enc_params' );
228
+ if ( in_array( $sMaybeEncoding, [ 'none', 'lz-string', 'b64' ] ) ) {
229
+ $sEncoding = $sMaybeEncoding;
230
+ }
231
+
232
+ switch ( $sEncoding ) {
233
+ case 'lz-string':
234
+ $sRaw = \LZCompressor\LZString::decompress( base64_decode( $sRaw ) );
235
+ break;
236
+
237
+ case 'b64':
238
+ $sRaw = base64_decode( $sRaw );
239
+ break;
240
+
241
+ case 'none':
242
+ default:
243
+ break;
244
+ }
245
+
246
+ parse_str( $sRaw, $aFormParams );
247
  }
248
  return $aFormParams;
249
  }
254
  */
255
  public function fRegisterAdminNotices( $aAdminNotices ) {
256
  if ( !is_array( $aAdminNotices ) ) {
257
+ $aAdminNotices = [];
258
  }
259
  return array_merge( $aAdminNotices, $this->getOptionsVo()->getAdminNotices() );
260
  }
607
  $aItems[ $sMenuPageTitle ] = array(
608
  $sMenuTitleName,
609
  $this->getModSlug(),
610
+ [ $this, 'displayModuleAdminPage' ],
611
  $this->getIfShowModuleMenuItem()
612
  );
613
 
636
  * @return array
637
  */
638
  protected function getAdditionalMenuItem() {
639
+ return [];
640
  }
641
 
642
  /**
732
  * @return $this
733
  */
734
  public function clearLastErrors() {
735
+ return $this->setLastErrors( [] );
736
  }
737
 
738
  /**
743
  public function getLastErrors( $bAsString = true, $sGlue = " " ) {
744
  $aErrors = $this->getOpt( 'last_errors' );
745
  if ( !is_array( $aErrors ) ) {
746
+ $aErrors = [];
747
  }
748
  return $bAsString ? implode( $sGlue, $aErrors ) : $aErrors;
749
  }
808
  * @param array|string $mErrors
809
  * @return $this
810
  */
811
+ public function setLastErrors( $mErrors = [] ) {
812
  if ( !is_array( $mErrors ) ) {
813
  if ( is_string( $mErrors ) ) {
814
  $mErrors = array( $mErrors );
815
  }
816
  else {
817
+ $mErrors = [];
818
  }
819
  }
820
  return $this->setOpt( 'last_errors', $mErrors );
991
  $aOptions[ $nSectionKey ] = $this->loadStrings_SectionTitles( $aSection );
992
  }
993
 
994
+ $aWarnings = [];
995
  if ( !$oOptsVo->isSectionReqsMet( $aSection[ 'slug' ] ) ) {
996
  $aWarnings[] = _wpsf__( 'Unfortunately your WordPress and/or PHP versions are too old to support this feature.' );
997
  }
1041
  case 'array':
1042
 
1043
  if ( empty( $mCurrent ) || !is_array( $mCurrent ) ) {
1044
+ $mCurrent = [];
1045
  }
1046
 
1047
  $aOptParams[ 'rows' ] = count( $mCurrent ) + 2;
1051
 
1052
  case 'comma_separated_lists':
1053
 
1054
+ $aNewValues = [];
1055
  if ( !empty( $mCurrent ) && is_array( $mCurrent ) ) {
1056
 
1057
  foreach ( $mCurrent as $sPage => $aParams ) {
1065
 
1066
  case 'multiple_select':
1067
  if ( !is_array( $mCurrent ) ) {
1068
+ $mCurrent = [];
1069
  }
1070
  break;
1071
 
1123
  * @return array - map of each option to its option type
1124
  */
1125
  protected function getAllFormOptionsAndTypes() {
1126
+ $aOpts = [];
1127
 
1128
  foreach ( $this->buildOptions() as $aOptionsSection ) {
1129
  if ( !empty( $aOptionsSection ) ) {
1161
  catch ( \Exception $oE ) {
1162
  $sForm = 'Error during form render';
1163
  }
1164
+ return [
1165
  'success' => $bSuccess,
1166
  'html' => $sForm,
1167
  'message' => $sMessage
1168
+ ];
1169
+ }
1170
+
1171
+ /**
1172
+ * @return array
1173
+ */
1174
+ protected function ajaxExec_ModOptionsRender() {
1175
+ if ( $this->canDisplayOptionsForm() ) {
1176
+ $sContent = $this->renderModulePage();
1177
+ }
1178
+ else {
1179
+ $sContent = $this->renderRestrictedPage();
1180
+ }
1181
+
1182
+ return [
1183
+ 'success' => true,
1184
+ 'html' => $sContent,
1185
+ 'message' => 'loaded'
1186
+ ];
1187
  }
1188
 
1189
  /**
1281
  * @throws \Exception
1282
  */
1283
  private function doSaveStandardOptions() {
1284
+ $aForm = $this->getAjaxFormParams( 'b64' ); // standard options use b64 and failover to lz-string
1285
  if ( empty( $aForm[ 'plugin_form_submit' ] ) || $aForm[ 'plugin_form_submit' ] !== 'Y' ) {
1286
  throw new \Exception( 'Not a standard plugin options form submission' );
1287
  }
1419
  }
1420
 
1421
  /**
1422
+ * @uses echo()
1423
  */
1424
  public function displayModuleAdminPage() {
1425
  if ( $this->canDisplayOptionsForm() ) {
1426
+ echo $this->renderModulePage();
1427
  }
1428
  else {
1429
+ echo $this->renderRestrictedPage();
1430
  }
1431
  }
1432
 
1433
+ /**
1434
+ * Not yet used but may be used above to replace renderModulePage() to load
1435
+ * options pages by AJAX.
1436
+ * @return string
1437
+ */
1438
+ private function renderAdminBootstrap() {
1439
+ return $this->renderTemplate( 'admin_bootstrap.php' );
1440
+ }
1441
+
1442
  /**
1443
  * Override this to customize anything with the display of the page
1444
  * @param array $aData
1445
+ * @return string
1446
  */
1447
+ protected function renderModulePage( $aData = [] ) {
1448
  // Get Base Data
1449
  $aData = $this->loadDP()->mergeArraysRecursive( $this->getBaseDisplayData( true ), $aData );
1450
  $aData[ 'content' ][ 'options_form' ] = $this->renderOptionsForm();
1451
 
1452
+ return $this->renderTemplate( 'index.php', $aData );
1453
  }
1454
 
1455
+ /**
1456
+ * @return string
1457
+ */
1458
+ protected function renderRestrictedPage() {
1459
  $aData = $this->loadDP()
1460
  ->mergeArraysRecursive(
1461
  $this->getBaseDisplayData( false ),
1465
  )
1466
  )
1467
  );
1468
+ return $this->renderTemplate( 'access_restricted.php', $aData );
1469
  }
1470
 
1471
  /**
1607
  * @return array[]
1608
  */
1609
  protected function getModulesSummaryData() {
1610
+ return apply_filters( $this->prefix( 'collect_mod_summary' ), [] );
1611
  }
1612
 
1613
  /**
 
1614
  * @param string $sWizardSlug
1615
  * @return string
1616
+ * @uses nonce
1617
  */
1618
  public function getUrl_Wizard( $sWizardSlug ) {
1619
  $aDef = $this->getWizardDefinition( $sWizardSlug );
1660
  */
1661
  public function getWizardDefinitions() {
1662
  $aW = $this->getDef( 'wizards' );
1663
+ return is_array( $aW ) ? $aW : [];
1664
  }
1665
 
1666
  /**
1742
  'icwp_wpsf_vars_base',
1743
  [
1744
  'ajax' => [
1745
+ 'mod_options' => $this->getAjaxActionData( 'mod_options' ),
1746
+ 'mod_opts_render' => $this->getAjaxActionData( 'mod_opts_render' ),
1747
  ]
1748
  ]
1749
  );
1754
  * @param array $aData
1755
  * @param string $sSubView
1756
  */
1757
+ protected function display( $aData = [], $sSubView = '' ) {
1758
  }
1759
 
1760
  /**
1772
  }
1773
 
1774
  if ( !isset( $aData[ 'notice_classes' ] ) ) {
1775
+ $aData[ 'notice_classes' ] = [];
1776
  }
1777
  if ( is_array( $aData[ 'notice_classes' ] ) ) {
1778
  $aData[ 'notice_classes' ][] = $aData[ 'notice_attributes' ][ 'type' ];
1799
  * @param bool $bUseTwig
1800
  * @return string
1801
  */
1802
+ public function renderTemplate( $sTemplate, $aData = [], $bUseTwig = false ) {
1803
  if ( empty( $aData[ 'unique_render_id' ] ) ) {
1804
  $aData[ 'unique_render_id' ] = 'noticeid-'.substr( md5( mt_rand() ), 0, 5 );
1805
  }
1827
  */
1828
  public function exportTransferableOptions( $aTransferableOptions ) {
1829
  if ( !is_array( $aTransferableOptions ) ) {
1830
+ $aTransferableOptions = [];
1831
  }
1832
  $aTransferableOptions[ $this->getOptionsStorageKey() ] = $this->getOptionsVo()->getTransferableOptions();
1833
  return $aTransferableOptions;
1882
  * @return array
1883
  */
1884
  protected function getHelpVideoOptions() {
1885
+ $aOptions = $this->getOpt( 'help_video_options', [] );
1886
  if ( is_null( $aOptions ) || !is_array( $aOptions ) ) {
1887
  $aOptions = array(
1888
  'closed' => false,
1959
  * @return $this
1960
  */
1961
  protected function resetHelpVideoOptions() {
1962
+ return $this->setOpt( 'help_video_options', [] );
1963
  }
1964
 
1965
  /**
2005
  }
2006
 
2007
  /**
 
2008
  * @return string
2009
+ * @deprecated
2010
  */
2011
  public function getVersion() {
2012
  return $this->getCon()->getVersion();
src/features/base_wpsf.php CHANGED
@@ -14,6 +14,11 @@ class ICWP_WPSF_FeatureHandler_BaseWpsf extends ICWP_WPSF_FeatureHandler_Base {
14
  */
15
  static protected $bIsVerifiedBot;
16
 
 
 
 
 
 
17
  /**
18
  * @return ICWP_WPSF_Processor_Sessions
19
  */
@@ -50,9 +55,9 @@ class ICWP_WPSF_FeatureHandler_BaseWpsf extends ICWP_WPSF_FeatureHandler_Base {
50
  * @return array
51
  */
52
  protected function getGoogleRecaptchaConfig() {
53
- $aConfig = apply_filters( $this->prefix( 'google_recaptcha_config' ), array() );
54
  if ( !is_array( $aConfig ) ) {
55
- $aConfig = array();
56
  }
57
  $aConfig = array_merge(
58
  array(
@@ -297,7 +302,7 @@ class ICWP_WPSF_FeatureHandler_BaseWpsf extends ICWP_WPSF_FeatureHandler_Base {
297
  * @return string[]
298
  */
299
  protected function cleanStringArray( $aArray, $sPregReplacePattern ) {
300
- $aCleaned = array();
301
  if ( !is_array( $aArray ) ) {
302
  return $aCleaned;
303
  }
@@ -315,7 +320,7 @@ class ICWP_WPSF_FeatureHandler_BaseWpsf extends ICWP_WPSF_FeatureHandler_Base {
315
  * @return array
316
  */
317
  public function getInsightsOpts() {
318
- $aOpts = array();
319
  $oOpts = $this->getOptionsVo();
320
  foreach ( $oOpts->getOptionsKeys() as $sOpt ) {
321
  if ( strpos( $sOpt, 'insights_' ) === 0 ) {
@@ -338,13 +343,13 @@ class ICWP_WPSF_FeatureHandler_BaseWpsf extends ICWP_WPSF_FeatureHandler_Base {
338
  * @return array
339
  */
340
  protected function getModDisabledInsight() {
341
- return array(
342
  'name' => _wpsf__( 'Module Disabled' ),
343
  'enabled' => false,
344
  'summary' => _wpsf__( 'All features of this module are completely disabled' ),
345
  'weight' => 2,
346
  'href' => $this->getUrl_DirectLinkToOption( $this->getEnableModOptKey() ),
347
- );
348
  }
349
 
350
  /**
@@ -373,21 +378,50 @@ class ICWP_WPSF_FeatureHandler_BaseWpsf extends ICWP_WPSF_FeatureHandler_Base {
373
  return array( $sTitle, $sTitleShort, $aSummary );
374
  }
375
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
376
  /**
377
  * Used to mark an IP address for immediate block
378
  * @return $this
379
  */
380
  public function setIpBlocked() {
381
- add_filter( $this->prefix( 'ip_block_it' ), '__return_true' );
382
- return $this;
383
  }
384
 
385
  /**
386
  * Used to mark an IP address for transgression/black-mark
 
 
 
 
 
 
 
 
 
387
  * @return $this
388
  */
389
- public function setIpTransgressed() {
390
- add_filter( $this->prefix( 'ip_black_mark' ), '__return_true' );
 
 
 
 
 
391
  return $this;
392
  }
393
  }
14
  */
15
  static protected $bIsVerifiedBot;
16
 
17
+ /**
18
+ * @var string
19
+ */
20
+ static private $mIpAction;
21
+
22
  /**
23
  * @return ICWP_WPSF_Processor_Sessions
24
  */
55
  * @return array
56
  */
57
  protected function getGoogleRecaptchaConfig() {
58
+ $aConfig = apply_filters( $this->prefix( 'google_recaptcha_config' ), [] );
59
  if ( !is_array( $aConfig ) ) {
60
+ $aConfig = [];
61
  }
62
  $aConfig = array_merge(
63
  array(
302
  * @return string[]
303
  */
304
  protected function cleanStringArray( $aArray, $sPregReplacePattern ) {
305
+ $aCleaned = [];
306
  if ( !is_array( $aArray ) ) {
307
  return $aCleaned;
308
  }
320
  * @return array
321
  */
322
  public function getInsightsOpts() {
323
+ $aOpts = [];
324
  $oOpts = $this->getOptionsVo();
325
  foreach ( $oOpts->getOptionsKeys() as $sOpt ) {
326
  if ( strpos( $sOpt, 'insights_' ) === 0 ) {
343
  * @return array
344
  */
345
  protected function getModDisabledInsight() {
346
+ return [
347
  'name' => _wpsf__( 'Module Disabled' ),
348
  'enabled' => false,
349
  'summary' => _wpsf__( 'All features of this module are completely disabled' ),
350
  'weight' => 2,
351
  'href' => $this->getUrl_DirectLinkToOption( $this->getEnableModOptKey() ),
352
+ ];
353
  }
354
 
355
  /**
378
  return array( $sTitle, $sTitleShort, $aSummary );
379
  }
380
 
381
+ /**
382
+ * @return bool
383
+ */
384
+ public function getIfIpTransgressed() {
385
+ $mAction = $this->getIpAction();
386
+ return !empty( $mAction ) &&
387
+ ( ( is_numeric( $mAction ) && $mAction > 0 ) || in_array( $mAction, [ 'block' ] ) );
388
+ }
389
+
390
+ /**
391
+ * @return int|string|null
392
+ */
393
+ public function getIpAction() {
394
+ return self::$mIpAction;
395
+ }
396
+
397
  /**
398
  * Used to mark an IP address for immediate block
399
  * @return $this
400
  */
401
  public function setIpBlocked() {
402
+ return $this->setIpAction( 'block' );
 
403
  }
404
 
405
  /**
406
  * Used to mark an IP address for transgression/black-mark
407
+ * @param int $nIncrementCount
408
+ * @return $this
409
+ */
410
+ public function setIpTransgressed( $nIncrementCount = 1 ) {
411
+ return $this->setIpAction( $nIncrementCount );
412
+ }
413
+
414
+ /**
415
+ * @param string|int $mNewAction
416
  * @return $this
417
  */
418
+ private function setIpAction( $mNewAction ) {
419
+ if ( in_array( $mNewAction, [ 'block' ] ) ) {
420
+ self::$mIpAction = $mNewAction;
421
+ }
422
+ else if ( empty( self::$mIpAction ) || ( is_numeric( self::$mIpAction ) && $mNewAction > self::$mIpAction ) ) {
423
+ self::$mIpAction = $mNewAction;
424
+ }
425
  return $this;
426
  }
427
  }
src/features/comments_filter.php CHANGED
@@ -28,7 +28,7 @@ class ICWP_WPSF_FeatureHandler_CommentsFilter extends ICWP_WPSF_FeatureHandler_B
28
  * @return array
29
  */
30
  public function getCommentData() {
31
- return ( isset( $this->aCommentData ) && is_array( $this->aCommentData ) ) ? $this->aCommentData : array();
32
  }
33
 
34
  /**
@@ -138,7 +138,7 @@ class ICWP_WPSF_FeatureHandler_CommentsFilter extends ICWP_WPSF_FeatureHandler_B
138
  'title' => _wpsf__( 'SPAM Blocking' ),
139
  'sub' => _wpsf__( 'Block Bot & Human Comment SPAM' ),
140
  ),
141
- 'key_opts' => array(),
142
  'href_options' => $this->getUrl_AdminPage()
143
  );
144
 
@@ -225,7 +225,7 @@ class ICWP_WPSF_FeatureHandler_CommentsFilter extends ICWP_WPSF_FeatureHandler_B
225
  list( $sTitle, $sTitleShort, $aSummary ) = $this->loadStrings_SectionTitlesDefaults( $aOptionsParams );
226
  }
227
  $aOptionsParams[ 'title' ] = $sTitle;
228
- $aOptionsParams[ 'summary' ] = ( isset( $aSummary ) && is_array( $aSummary ) ) ? $aSummary : array();
229
  $aOptionsParams[ 'title_short' ] = $sTitleShort;
230
  return $aOptionsParams;
231
  }
28
  * @return array
29
  */
30
  public function getCommentData() {
31
+ return ( isset( $this->aCommentData ) && is_array( $this->aCommentData ) ) ? $this->aCommentData : [];
32
  }
33
 
34
  /**
138
  'title' => _wpsf__( 'SPAM Blocking' ),
139
  'sub' => _wpsf__( 'Block Bot & Human Comment SPAM' ),
140
  ),
141
+ 'key_opts' => [],
142
  'href_options' => $this->getUrl_AdminPage()
143
  );
144
 
225
  list( $sTitle, $sTitleShort, $aSummary ) = $this->loadStrings_SectionTitlesDefaults( $aOptionsParams );
226
  }
227
  $aOptionsParams[ 'title' ] = $sTitle;
228
+ $aOptionsParams[ 'summary' ] = ( isset( $aSummary ) && is_array( $aSummary ) ) ? $aSummary : [];
229
  $aOptionsParams[ 'title_short' ] = $sTitleShort;
230
  return $aOptionsParams;
231
  }
src/features/firewall.php CHANGED
@@ -7,7 +7,7 @@ class ICWP_WPSF_FeatureHandler_Firewall extends ICWP_WPSF_FeatureHandler_BaseWps
7
  */
8
  public function getDefaultWhitelist() {
9
  $aW = $this->getDef( 'default_whitelist' );
10
- return is_array( $aW ) ? $aW : array();
11
  }
12
 
13
  /**
@@ -21,7 +21,7 @@ class ICWP_WPSF_FeatureHandler_Firewall extends ICWP_WPSF_FeatureHandler_BaseWps
21
  }
22
 
23
  $aW = $this->getCustomWhitelist();
24
- $aParams = isset( $aW[ $sPage ] ) ? $aW[ $sPage ] : array();
25
  $aParams[] = $sParam;
26
  natsort( $aParams );
27
  $aW[ $sPage ] = array_unique( $aParams );
@@ -33,8 +33,8 @@ class ICWP_WPSF_FeatureHandler_Firewall extends ICWP_WPSF_FeatureHandler_BaseWps
33
  * @return array
34
  */
35
  public function getCustomWhitelist() {
36
- $aW = $this->getOpt( 'page_params_whitelist', array() );
37
- return is_array( $aW ) ? $aW : array();
38
  }
39
 
40
  /**
@@ -84,7 +84,7 @@ class ICWP_WPSF_FeatureHandler_Firewall extends ICWP_WPSF_FeatureHandler_BaseWps
84
  'title' => _wpsf__( 'Firewall' ),
85
  'sub' => _wpsf__( 'Block Malicious Requests' ),
86
  ),
87
- 'key_opts' => array(),
88
  'href_options' => $this->getUrl_AdminPage()
89
  );
90
 
@@ -170,7 +170,7 @@ class ICWP_WPSF_FeatureHandler_Firewall extends ICWP_WPSF_FeatureHandler_BaseWps
170
  list( $sTitle, $sTitleShort, $aSummary ) = $this->loadStrings_SectionTitlesDefaults( $aOptionsParams );
171
  }
172
  $aOptionsParams[ 'title' ] = $sTitle;
173
- $aOptionsParams[ 'summary' ] = ( isset( $aSummary ) && is_array( $aSummary ) ) ? $aSummary : array();
174
  $aOptionsParams[ 'title_short' ] = $sTitleShort;
175
  return $aOptionsParams;
176
  }
7
  */
8
  public function getDefaultWhitelist() {
9
  $aW = $this->getDef( 'default_whitelist' );
10
+ return is_array( $aW ) ? $aW : [];
11
  }
12
 
13
  /**
21
  }
22
 
23
  $aW = $this->getCustomWhitelist();
24
+ $aParams = isset( $aW[ $sPage ] ) ? $aW[ $sPage ] : [];
25
  $aParams[] = $sParam;
26
  natsort( $aParams );
27
  $aW[ $sPage ] = array_unique( $aParams );
33
  * @return array
34
  */
35
  public function getCustomWhitelist() {
36
+ $aW = $this->getOpt( 'page_params_whitelist', [] );
37
+ return is_array( $aW ) ? $aW : [];
38
  }
39
 
40
  /**
84
  'title' => _wpsf__( 'Firewall' ),
85
  'sub' => _wpsf__( 'Block Malicious Requests' ),
86
  ),
87
+ 'key_opts' => [],
88
  'href_options' => $this->getUrl_AdminPage()
89
  );
90
 
170
  list( $sTitle, $sTitleShort, $aSummary ) = $this->loadStrings_SectionTitlesDefaults( $aOptionsParams );
171
  }
172
  $aOptionsParams[ 'title' ] = $sTitle;
173
+ $aOptionsParams[ 'summary' ] = ( isset( $aSummary ) && is_array( $aSummary ) ) ? $aSummary : [];
174
  $aOptionsParams[ 'title_short' ] = $sTitleShort;
175
  return $aOptionsParams;
176
  }
src/features/hack_protect.php CHANGED
@@ -125,6 +125,7 @@ class ICWP_WPSF_FeatureHandler_HackProtect extends ICWP_WPSF_FeatureHandler_Base
125
  }
126
 
127
  $this->setOpt( 'ptg_candiskwrite_at', 0 );
 
128
  }
129
 
130
  /**
@@ -235,7 +236,7 @@ class ICWP_WPSF_FeatureHandler_HackProtect extends ICWP_WPSF_FeatureHandler_Base
235
  * @return $this
236
  */
237
  protected function clearIcSnapshots() {
238
- return $this->setIcSnapshotUsers( array() );
239
  }
240
 
241
  /**
@@ -285,9 +286,9 @@ class ICWP_WPSF_FeatureHandler_HackProtect extends ICWP_WPSF_FeatureHandler_Base
285
  * @return array
286
  */
287
  public function getUfcFileExclusions() {
288
- $aExclusions = $this->getOpt( 'ufc_exclusions', array() );
289
  if ( empty( $aExclusions ) || !is_array( $aExclusions ) ) {
290
- $aExclusions = array();
291
  }
292
  return $aExclusions;
293
  }
@@ -306,7 +307,7 @@ class ICWP_WPSF_FeatureHandler_HackProtect extends ICWP_WPSF_FeatureHandler_Base
306
  */
307
  public function setUfcFileExclusions( $aExclusions ) {
308
  if ( !is_array( $aExclusions ) ) {
309
- $aExclusions = array();
310
  }
311
  return $this->setOpt( 'ufc_exclusions', array_filter( array_map( 'trim', $aExclusions ) ) );
312
  }
@@ -315,7 +316,7 @@ class ICWP_WPSF_FeatureHandler_HackProtect extends ICWP_WPSF_FeatureHandler_Base
315
  * @return $this
316
  */
317
  protected function cleanFileExclusions() {
318
- $aExclusions = array();
319
 
320
  $oFS = $this->loadFS();
321
  foreach ( $this->getUfcFileExclusions() as $nKey => $sExclusion ) {
@@ -648,7 +649,7 @@ class ICWP_WPSF_FeatureHandler_HackProtect extends ICWP_WPSF_FeatureHandler_Base
648
  * @return array
649
  */
650
  protected function getSectionNotices( $sSectionSlug ) {
651
- $aNotices = array();
652
  switch ( $sSectionSlug ) {
653
 
654
  case 'section_core_file_integrity_scan':
@@ -790,7 +791,7 @@ class ICWP_WPSF_FeatureHandler_HackProtect extends ICWP_WPSF_FeatureHandler_Base
790
  }
791
 
792
  try {
793
- $aSuccessfulItems = array();
794
 
795
  foreach ( $aItemIds as $sId ) {
796
  if ( $oTablePro->executeItemAction( $sId, $sAction ) ) {
@@ -858,12 +859,30 @@ class ICWP_WPSF_FeatureHandler_HackProtect extends ICWP_WPSF_FeatureHandler_Base
858
  * @return array
859
  */
860
  protected function getSectionWarnings( $sSection ) {
861
- $aWarnings = array();
862
 
863
- if ( $sSection == 'section_pluginthemes_guard' ) {
864
- if ( !$this->canPtgWriteToDisk() ) {
865
- $aWarnings[] = sprintf( _wpsf__( 'Sorry, this feature is not available because we cannot write to disk at this location: "%s"' ), $this->getPtgSnapsBaseDir() );
866
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
867
  }
868
 
869
  return $aWarnings;
@@ -877,6 +896,154 @@ class ICWP_WPSF_FeatureHandler_HackProtect extends ICWP_WPSF_FeatureHandler_Base
877
  return false;
878
  }
879
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
880
  /**
881
  * @param array $aAllNotices
882
  * @return array
@@ -884,7 +1051,7 @@ class ICWP_WPSF_FeatureHandler_HackProtect extends ICWP_WPSF_FeatureHandler_Base
884
  public function addInsightsNoticeData( $aAllNotices ) {
885
  $aNotices = array(
886
  'title' => _wpsf__( 'Scans' ),
887
- 'messages' => array()
888
  );
889
 
890
  {// Core files
@@ -1008,7 +1175,7 @@ class ICWP_WPSF_FeatureHandler_HackProtect extends ICWP_WPSF_FeatureHandler_Base
1008
  'title' => _wpsf__( 'Hack Guard' ),
1009
  'sub' => _wpsf__( 'Threats/Intrusions Detection & Repair' ),
1010
  ),
1011
- 'key_opts' => array(),
1012
  'href_options' => $this->getUrl_AdminPage()
1013
  );
1014
 
@@ -1137,6 +1304,15 @@ class ICWP_WPSF_FeatureHandler_HackProtect extends ICWP_WPSF_FeatureHandler_Base
1137
  );
1138
  break;
1139
 
 
 
 
 
 
 
 
 
 
1140
  case 'section_enable_plugin_feature_hack_protection_tools' :
1141
  $sTitle = sprintf( _wpsf__( 'Enable Module: %s' ), $this->getMainFeatureName() );
1142
  $aSummary = array(
@@ -1215,7 +1391,7 @@ class ICWP_WPSF_FeatureHandler_HackProtect extends ICWP_WPSF_FeatureHandler_Base
1215
  throw new \Exception( sprintf( 'A section slug was defined but with no associated strings. Slug: "%s".', $sSectionSlug ) );
1216
  }
1217
  $aOptionsParams[ 'title' ] = $sTitle;
1218
- $aOptionsParams[ 'summary' ] = ( isset( $aSummary ) && is_array( $aSummary ) ) ? $aSummary : array();
1219
  $aOptionsParams[ 'title_short' ] = $sTitleShort;
1220
  return $aOptionsParams;
1221
  }
@@ -1369,6 +1545,12 @@ class ICWP_WPSF_FeatureHandler_HackProtect extends ICWP_WPSF_FeatureHandler_Base
1369
  $sDescription = _wpsf__( "Abandoned plugins will be highlighted on the main plugins page." );
1370
  break;
1371
 
 
 
 
 
 
 
1372
  default:
1373
  throw new \Exception( sprintf( 'An option has been defined but without strings assigned to it. Option key: "%s".', $sKey ) );
1374
  }
125
  }
126
 
127
  $this->setOpt( 'ptg_candiskwrite_at', 0 );
128
+ $this->resetRtBackupFiles();
129
  }
130
 
131
  /**
236
  * @return $this
237
  */
238
  protected function clearIcSnapshots() {
239
+ return $this->setIcSnapshotUsers( [] );
240
  }
241
 
242
  /**
286
  * @return array
287
  */
288
  public function getUfcFileExclusions() {
289
+ $aExclusions = $this->getOpt( 'ufc_exclusions', [] );
290
  if ( empty( $aExclusions ) || !is_array( $aExclusions ) ) {
291
+ $aExclusions = [];
292
  }
293
  return $aExclusions;
294
  }
307
  */
308
  public function setUfcFileExclusions( $aExclusions ) {
309
  if ( !is_array( $aExclusions ) ) {
310
+ $aExclusions = [];
311
  }
312
  return $this->setOpt( 'ufc_exclusions', array_filter( array_map( 'trim', $aExclusions ) ) );
313
  }
316
  * @return $this
317
  */
318
  protected function cleanFileExclusions() {
319
+ $aExclusions = [];
320
 
321
  $oFS = $this->loadFS();
322
  foreach ( $this->getUfcFileExclusions() as $nKey => $sExclusion ) {
649
  * @return array
650
  */
651
  protected function getSectionNotices( $sSectionSlug ) {
652
+ $aNotices = [];
653
  switch ( $sSectionSlug ) {
654
 
655
  case 'section_core_file_integrity_scan':
791
  }
792
 
793
  try {
794
+ $aSuccessfulItems = [];
795
 
796
  foreach ( $aItemIds as $sId ) {
797
  if ( $oTablePro->executeItemAction( $sId, $sAction ) ) {
859
  * @return array
860
  */
861
  protected function getSectionWarnings( $sSection ) {
862
+ $aWarnings = [];
863
 
864
+ switch ( $sSection ) {
865
+
866
+ case 'section_pluginthemes_guard':
867
+ if ( !$this->canPtgWriteToDisk() ) {
868
+ $aWarnings[] = sprintf( _wpsf__( 'Sorry, this feature is not available because we cannot write to disk at this location: "%s"' ), $this->getPtgSnapsBaseDir() );
869
+ }
870
+ break;
871
+
872
+ case 'section_realtime':
873
+ if ( !Services::Encrypt()->isSupportedOpenSslDataEncryption() ) {
874
+ $aWarnings[] = sprintf( _wpsf__( 'Not available because the %s extension is not available.' ), 'OpenSSL' );
875
+ }
876
+ if ( !Services::WpFs()->isFilesystemAccessDirect() ) {
877
+ $aWarnings[] = sprintf( _wpsf__( "Not available because PHP/WordPress doesn't have direct filesystem access." ), 'OpenSSL' );
878
+ }
879
+ else {
880
+ $sPath = $this->getRtMapFileKeyToFilePath( 'wpconfig' );
881
+ if ( !$this->getRtCanWriteFile( $sPath ) ) {
882
+ $aWarnings[] = sprintf( _wpsf__( "The %s file isn't writable and so can't be further protected." ), 'wp-config.php' );
883
+ }
884
+ }
885
+ break;
886
  }
887
 
888
  return $aWarnings;
896
  return false;
897
  }
898
 
899
+ /**
900
+ * cleans out any reference to any backup files
901
+ */
902
+ private function resetRtBackupFiles() {
903
+ $oCon = $this->getCon();
904
+ $oFs = Services::WpFs();
905
+ $oOpts = $this->getOptionsVo();
906
+ foreach ( [ 'htaccess', 'wpconfig' ] as $sFileKey ) {
907
+ if ( $oOpts->isOptChanged( 'rt_file_'.$sFileKey ) ) {
908
+ $sPath = $this->getRtMapFileKeyToFilePath( $sFileKey );
909
+ try {
910
+ $sBackupFile = $oCon->getPluginCachePath( $this->getRtFileBackupName( $sPath ) );
911
+ if ( $oFs->exists( $sBackupFile ) ) {
912
+ $oFs->deleteFile( $sBackupFile );
913
+ }
914
+
915
+ if ( !$this->getRtCanWriteFile( $sPath ) ) {
916
+ $this->setOpt( 'rt_file_'.$sFileKey, 'N' );
917
+ }
918
+ }
919
+ catch ( \Exception $oE ) {
920
+ }
921
+ $this->setRtFileHash( $sPath, '' )
922
+ ->setRtFileBackupName( $sPath, '' );
923
+ }
924
+ }
925
+ }
926
+
927
+ /**
928
+ * @param string $sKey
929
+ * @return string|null
930
+ */
931
+ private function getRtMapFileKeyToFilePath( $sKey ) {
932
+ $aMap = [
933
+ 'wpconfig' => Services::WpGeneral()->getPath_WpConfig(),
934
+ 'htaccess' => path_join( ABSPATH, '.htaccess' ),
935
+ ];
936
+ return isset( $aMap[ $sKey ] ) ? $aMap[ $sKey ] : null;
937
+ }
938
+
939
+ /**
940
+ * @return array
941
+ */
942
+ public function getRtFileBackupNames() {
943
+ $aF = $this->getOpt( 'rt_file_backup_names', [] );
944
+ return is_array( $aF ) ? $aF : [];
945
+ }
946
+
947
+ /**
948
+ * @param string $sFile
949
+ * @return string|null
950
+ */
951
+ public function getRtFileBackupName( $sFile ) {
952
+ $aD = $this->getRtFileBackupNames();
953
+ return isset( $aD[ $sFile ] ) ? $aD[ $sFile ] : null;
954
+ }
955
+
956
+ /**
957
+ * @return array
958
+ */
959
+ public function getRtFileHashes() {
960
+ $aF = $this->getOpt( 'rt_file_hashes', [] );
961
+ return is_array( $aF ) ? $aF : [];
962
+ }
963
+
964
+ /**
965
+ * @param string $sFile
966
+ * @return string|null
967
+ */
968
+ public function getRtFileHash( $sFile ) {
969
+ $aD = $this->getRtFileHashes();
970
+ return isset( $aD[ $sFile ] ) ? $aD[ $sFile ] : null;
971
+ }
972
+
973
+ /**
974
+ * @param string $sFile
975
+ * @param string $sName
976
+ * @return $this
977
+ */
978
+ public function setRtFileBackupName( $sFile, $sName ) {
979
+ $aD = $this->getRtFileBackupNames();
980
+ $aD[ $sFile ] = $sName;
981
+ return $this->setOpt( 'rt_file_backup_names', $aD );
982
+ }
983
+
984
+ /**
985
+ * @param string $sFile
986
+ * @param string $sHash
987
+ * @return $this
988
+ */
989
+ public function setRtFileHash( $sFile, $sHash ) {
990
+ $aD = $this->getRtFileHashes();
991
+ $aD[ $sFile ] = $sHash;
992
+ return $this->setOpt( 'rt_file_hashes', $aD );
993
+ }
994
+
995
+ /**
996
+ * @return array
997
+ */
998
+ public function getRtCanWriteFiles() {
999
+ $aF = $this->getOpt( 'rt_can_write_files', [] );
1000
+ return is_array( $aF ) ? $aF : [];
1001
+ }
1002
+
1003
+ /**
1004
+ * @param string $sFile
1005
+ * @return bool
1006
+ */
1007
+ public function getRtCanWriteFile( $sFile ) {
1008
+ $aFiles = $this->getRtCanWriteFiles();
1009
+ if ( isset( $aFiles[ $sFile ] ) ) {
1010
+ $bCanWrite = $aFiles[ $sFile ] > 0;
1011
+ }
1012
+ else {
1013
+ $bCanWrite = ( new Shield\Scans\Realtime\Files\TestWritable() )->run( $sFile );
1014
+ $this->setRtCanWriteFile( $sFile, $bCanWrite );
1015
+ }
1016
+ return $bCanWrite;
1017
+ }
1018
+
1019
+ /**
1020
+ * @return bool
1021
+ */
1022
+ public function isRtAvailable() {
1023
+ return $this->isPremium()
1024
+ && Services::WpFs()->isFilesystemAccessDirect()
1025
+ && Services::Encrypt()->isSupportedOpenSslDataEncryption();
1026
+ }
1027
+
1028
+ /**
1029
+ * @return bool
1030
+ */
1031
+ public function isRtEnabledWpConfig() {
1032
+ return $this->isRtAvailable() && $this->isOpt( 'rt_file_wpconfig', 'Y' )
1033
+ && $this->getRtCanWriteFile( $this->getRtMapFileKeyToFilePath( 'wpconfig' ) );
1034
+ }
1035
+
1036
+ /**
1037
+ * @param string $sPath
1038
+ * @param bool $bCanWrite
1039
+ * @return $this
1040
+ */
1041
+ public function setRtCanWriteFile( $sPath, $bCanWrite ) {
1042
+ $aFiles = $this->getRtCanWriteFiles();
1043
+ $aFiles[ $sPath ] = $bCanWrite ? Services::Request()->ts() : 0;
1044
+ return $this->setOpt( 'rt_can_write_files', $aFiles );
1045
+ }
1046
+
1047
  /**
1048
  * @param array $aAllNotices
1049
  * @return array
1051
  public function addInsightsNoticeData( $aAllNotices ) {
1052
  $aNotices = array(
1053
  'title' => _wpsf__( 'Scans' ),
1054
+ 'messages' => []
1055
  );
1056
 
1057
  {// Core files
1175
  'title' => _wpsf__( 'Hack Guard' ),
1176
  'sub' => _wpsf__( 'Threats/Intrusions Detection & Repair' ),
1177
  ),
1178
+ 'key_opts' => [],
1179
  'href_options' => $this->getUrl_AdminPage()
1180
  );
1181
 
1304
  );
1305
  break;
1306
 
1307
+ case 'section_realtime' :
1308
+ $sTitle = _wpsf__( 'Realtime Site Protection' );
1309
+ $sTitleShort = _wpsf__( 'Realtime Protection' );
1310
+ $aSummary = array(
1311
+ sprintf( '%s - %s', _wpsf__( 'Purpose' ), _wpsf__( 'Provides realtime protection for certain key files.' ) ),
1312
+ sprintf( '%s - %s', _wpsf__( 'Recommendation' ), _wpsf__( 'Keep realtime protection turned on to protect key files.' ) ),
1313
+ );
1314
+ break;
1315
+
1316
  case 'section_enable_plugin_feature_hack_protection_tools' :
1317
  $sTitle = sprintf( _wpsf__( 'Enable Module: %s' ), $this->getMainFeatureName() );
1318
  $aSummary = array(
1391
  throw new \Exception( sprintf( 'A section slug was defined but with no associated strings. Slug: "%s".', $sSectionSlug ) );
1392
  }
1393
  $aOptionsParams[ 'title' ] = $sTitle;
1394
+ $aOptionsParams[ 'summary' ] = ( isset( $aSummary ) && is_array( $aSummary ) ) ? $aSummary : [];
1395
  $aOptionsParams[ 'title_short' ] = $sTitleShort;
1396
  return $aOptionsParams;
1397
  }
1545
  $sDescription = _wpsf__( "Abandoned plugins will be highlighted on the main plugins page." );
1546
  break;
1547
 
1548
+ case 'rt_file_wpconfig' :
1549
+ $sName = _wpsf__( 'WP Config' );
1550
+ $sSummary = _wpsf__( 'Realtime Protection For WP Config File' );
1551
+ $sDescription = _wpsf__( "Realtime protection for the wp-config.php file." );
1552
+ break;
1553
+
1554
  default:
1555
  throw new \Exception( sprintf( 'An option has been defined but without strings assigned to it. Option key: "%s".', $sKey ) );
1556
  }
src/features/headers.php CHANGED
@@ -51,9 +51,9 @@ class ICWP_WPSF_FeatureHandler_Headers extends ICWP_WPSF_FeatureHandler_BaseWpsf
51
  * @return array
52
  */
53
  public function getCspHosts() {
54
- $aHosts = $this->getOpt( 'xcsp_hosts', array() );
55
  if ( empty( $aHosts ) || !is_array( $aHosts ) ) {
56
- $aHosts = array();
57
  }
58
  return $aHosts;
59
  }
@@ -62,7 +62,7 @@ class ICWP_WPSF_FeatureHandler_Headers extends ICWP_WPSF_FeatureHandler_BaseWpsf
62
  $aDomains = $this->getCspHosts();
63
  if ( !empty( $aDomains ) && is_array( $aDomains ) ) {
64
  $oDP = $this->loadDP();
65
- $aValidDomains = array();
66
  foreach ( $aDomains as $sDomain ) {
67
  $bValidDomain = false;
68
  $sDomain = trim( $sDomain );
@@ -131,7 +131,7 @@ class ICWP_WPSF_FeatureHandler_Headers extends ICWP_WPSF_FeatureHandler_BaseWpsf
131
  'title' => _wpsf__( 'HTTP Security Headers' ),
132
  'sub' => _wpsf__( 'Protect Visitors With Powerful HTTP Headers' ),
133
  ),
134
- 'key_opts' => array(),
135
  'href_options' => $this->getUrl_AdminPage()
136
  );
137
 
@@ -207,7 +207,7 @@ class ICWP_WPSF_FeatureHandler_Headers extends ICWP_WPSF_FeatureHandler_BaseWpsf
207
  throw new \Exception( sprintf( 'A section slug was defined but with no associated strings. Slug: "%s".', $sSectionSlug ) );
208
  }
209
  $aOptionsParams[ 'title' ] = $sTitle;
210
- $aOptionsParams[ 'summary' ] = ( isset( $aSummary ) && is_array( $aSummary ) ) ? $aSummary : array();
211
  $aOptionsParams[ 'title_short' ] = $sTitleShort;
212
  return $aOptionsParams;
213
  }
51
  * @return array
52
  */
53
  public function getCspHosts() {
54
+ $aHosts = $this->getOpt( 'xcsp_hosts', [] );
55
  if ( empty( $aHosts ) || !is_array( $aHosts ) ) {
56
+ $aHosts = [];
57
  }
58
  return $aHosts;
59
  }
62
  $aDomains = $this->getCspHosts();
63
  if ( !empty( $aDomains ) && is_array( $aDomains ) ) {
64
  $oDP = $this->loadDP();
65
+ $aValidDomains = [];
66
  foreach ( $aDomains as $sDomain ) {
67
  $bValidDomain = false;
68
  $sDomain = trim( $sDomain );
131
  'title' => _wpsf__( 'HTTP Security Headers' ),
132
  'sub' => _wpsf__( 'Protect Visitors With Powerful HTTP Headers' ),
133
  ),
134
+ 'key_opts' => [],
135
  'href_options' => $this->getUrl_AdminPage()
136
  );
137
 
207
  throw new \Exception( sprintf( 'A section slug was defined but with no associated strings. Slug: "%s".', $sSectionSlug ) );
208
  }
209
  $aOptionsParams[ 'title' ] = $sTitle;
210
+ $aOptionsParams[ 'summary' ] = ( isset( $aSummary ) && is_array( $aSummary ) ) ? $aSummary : [];
211
  $aOptionsParams[ 'title_short' ] = $sTitleShort;
212
  return $aOptionsParams;
213
  }
src/features/insights.php CHANGED
@@ -4,10 +4,19 @@ use FernleafSystems\Wordpress\Services\Services;
4
 
5
  class ICWP_WPSF_FeatureHandler_Insights extends ICWP_WPSF_FeatureHandler_BaseWpsf {
6
 
 
 
 
 
 
 
 
 
 
7
  /**
8
  * @param array $aData
9
  */
10
- protected function displayModulePage( $aData = array() ) {
11
  $oCon = $this->getCon();
12
  $oReq = Services::Request();
13
  $aSecNotices = $this->getNotices();
@@ -65,7 +74,7 @@ class ICWP_WPSF_FeatureHandler_Insights extends ICWP_WPSF_FeatureHandler_BaseWps
65
  'render_table_audittrail' => $oAuditMod->getAjaxActionData( 'render_table_audittrail', true ),
66
  'item_addparamwhite' => $oAuditMod->getAjaxActionData( 'item_addparamwhite', true )
67
  ),
68
- 'flags' => array(),
69
  'strings' => array(
70
  'title_filter_form' => _wpsf__( 'Audit Trail Filters' ),
71
  ),
@@ -105,13 +114,13 @@ class ICWP_WPSF_FeatureHandler_Insights extends ICWP_WPSF_FeatureHandler_BaseWps
105
  'summary_whitelist' => sprintf( _wpsf__( 'IP addresses that are never blocked by %s.' ), $nPluginName ),
106
  'summary_blacklist' => sprintf( _wpsf__( 'IP addresses that have tripped %s defenses.' ), $nPluginName ),
107
  ),
108
- 'vars' => array(),
109
  );
110
  break;
111
 
112
  case 'notes':
113
  $aData = array(
114
- 'vars' => array(),
115
  'ajax' => array(
116
  'render_table_adminnotes' => $oModPlugin->getAjaxActionData( 'render_table_adminnotes', true ),
117
  'item_delete' => $oModPlugin->getAjaxActionData( 'note_delete', true ),
@@ -167,7 +176,7 @@ class ICWP_WPSF_FeatureHandler_Insights extends ICWP_WPSF_FeatureHandler_BaseWps
167
  'bulk_action' => $oModUsers->getAjaxActionData( 'bulk_action', true ),
168
 
169
  ),
170
- 'flags' => array(),
171
  'strings' => array(
172
  'title_filter_form' => _wpsf__( 'Sessions Table Filters' ),
173
  ),
@@ -197,7 +206,7 @@ class ICWP_WPSF_FeatureHandler_Insights extends ICWP_WPSF_FeatureHandler_BaseWps
197
  'maxlength' => $this->getDef( 'license_key_length' ),
198
  )
199
  ),
200
- 'ajax' => array(),
201
  'hrefs' => array(
202
  'shield_pro_url' => 'https://icwp.io/shieldpro',
203
  'shield_pro_more_info_url' => 'https://icwp.io/shld1',
@@ -243,7 +252,7 @@ class ICWP_WPSF_FeatureHandler_Insights extends ICWP_WPSF_FeatureHandler_BaseWps
243
  'active' => false
244
  );
245
 
246
- $oDp = \FernleafSystems\Wordpress\Services\Services::DataManipulation();
247
  $aData = $oDp->mergeArraysRecursive(
248
  $this->getBaseDisplayData( false ),
249
  array(
@@ -251,7 +260,8 @@ class ICWP_WPSF_FeatureHandler_Insights extends ICWP_WPSF_FeatureHandler_BaseWps
251
  'page_container' => 'page-insights page-'.$sNavSection
252
  ),
253
  'flags' => array(
254
- 'show_promo' => !$bIsPro
 
255
  ),
256
  'hrefs' => array(
257
  'go_pro' => 'https://icwp.io/shieldgoprofeature',
@@ -266,7 +276,7 @@ class ICWP_WPSF_FeatureHandler_Insights extends ICWP_WPSF_FeatureHandler_BaseWps
266
  ),
267
  $aData
268
  );
269
- echo $this->renderTemplate( sprintf( '/wpadmin_pages/insights_new/%s/index.twig', $sNavSection ), $aData, true );
270
  }
271
 
272
  public function insertCustomJsVars_Admin() {
@@ -325,6 +335,27 @@ class ICWP_WPSF_FeatureHandler_Insights extends ICWP_WPSF_FeatureHandler_BaseWps
325
  wp_enqueue_script( $sUnique );
326
  }
327
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
328
  break;
329
  }
330
  }
@@ -360,7 +391,7 @@ class ICWP_WPSF_FeatureHandler_Insights extends ICWP_WPSF_FeatureHandler_BaseWps
360
  * @return array[]
361
  */
362
  protected function getInsightsModsSummary() {
363
- $aMods = array();
364
  foreach ( $this->getModulesSummaryData() as $aMod ) {
365
  if ( !in_array( $aMod[ 'slug' ], array( 'insights' ) ) ) {
366
  $aMods[] = $aMod;
4
 
5
  class ICWP_WPSF_FeatureHandler_Insights extends ICWP_WPSF_FeatureHandler_BaseWpsf {
6
 
7
+ protected function doPostConstruction() {
8
+ /** @var ICWP_WPSF_FeatureHandler_Plugin $oP */
9
+ $oP = $this->getCon()->getModule( 'plugin' );
10
+ $nActivatedAt = $oP->getActivatedAt();
11
+ if ( $nActivatedAt > 0 && Services::Request()->ts() - $nActivatedAt < 5 ) {
12
+ Services::Response()->redirect( $this->getUrl_AdminPage() );
13
+ }
14
+ }
15
+
16
  /**
17
  * @param array $aData
18
  */
19
+ protected function renderModulePage( $aData = [] ) {
20
  $oCon = $this->getCon();
21
  $oReq = Services::Request();
22
  $aSecNotices = $this->getNotices();
74
  'render_table_audittrail' => $oAuditMod->getAjaxActionData( 'render_table_audittrail', true ),
75
  'item_addparamwhite' => $oAuditMod->getAjaxActionData( 'item_addparamwhite', true )
76
  ),
77
+ 'flags' => [],
78
  'strings' => array(
79
  'title_filter_form' => _wpsf__( 'Audit Trail Filters' ),
80
  ),
114
  'summary_whitelist' => sprintf( _wpsf__( 'IP addresses that are never blocked by %s.' ), $nPluginName ),
115
  'summary_blacklist' => sprintf( _wpsf__( 'IP addresses that have tripped %s defenses.' ), $nPluginName ),
116
  ),
117
+ 'vars' => [],
118
  );
119
  break;
120
 
121
  case 'notes':
122
  $aData = array(
123
+ 'vars' => [],
124
  'ajax' => array(
125
  'render_table_adminnotes' => $oModPlugin->getAjaxActionData( 'render_table_adminnotes', true ),
126
  'item_delete' => $oModPlugin->getAjaxActionData( 'note_delete', true ),
176
  'bulk_action' => $oModUsers->getAjaxActionData( 'bulk_action', true ),
177
 
178
  ),
179
+ 'flags' => [],
180
  'strings' => array(
181
  'title_filter_form' => _wpsf__( 'Sessions Table Filters' ),
182
  ),
206
  'maxlength' => $this->getDef( 'license_key_length' ),
207
  )
208
  ),
209
+ 'ajax' => [],
210
  'hrefs' => array(
211
  'shield_pro_url' => 'https://icwp.io/shieldpro',
212
  'shield_pro_more_info_url' => 'https://icwp.io/shld1',
252
  'active' => false
253
  );
254
 
255
+ $oDp = Services::DataManipulation();
256
  $aData = $oDp->mergeArraysRecursive(
257
  $this->getBaseDisplayData( false ),
258
  array(
260
  'page_container' => 'page-insights page-'.$sNavSection
261
  ),
262
  'flags' => array(
263
+ 'show_promo' => !$bIsPro,
264
+ 'show_guided_tour' => $oModPlugin->getIfShowIntroVideo(),
265
  ),
266
  'hrefs' => array(
267
  'go_pro' => 'https://icwp.io/shieldgoprofeature',
276
  ),
277
  $aData
278
  );
279
+ return $this->renderTemplate( sprintf( '/wpadmin_pages/insights_new/%s/index.twig', $sNavSection ), $aData, true );
280
  }
281
 
282
  public function insertCustomJsVars_Admin() {
335
  wp_enqueue_script( $sUnique );
336
  }
337
 
338
+ if ( $sNav == 'audit' ) {
339
+ $sUnique = $this->prefix( 'datepicker' );
340
+ wp_register_script(
341
+ $sUnique, //TODO: use an includes services for CNDJS
342
+ 'https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.8.0/js/bootstrap-datepicker.min.js',
343
+ array_unique( $aStdDeps ),
344
+ $oConn->getVersion(),
345
+ false
346
+ );
347
+ wp_enqueue_script( $sUnique );
348
+
349
+ wp_register_style(
350
+ $sUnique,
351
+ 'https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.8.0/css/bootstrap-datepicker.min.css',
352
+ [],
353
+ $oConn->getVersion(),
354
+ false
355
+ );
356
+ wp_enqueue_style( $sUnique );
357
+ }
358
+
359
  break;
360
  }
361
  }
391
  * @return array[]
392
  */
393
  protected function getInsightsModsSummary() {
394
+ $aMods = [];
395
  foreach ( $this->getModulesSummaryData() as $aMod ) {
396
  if ( !in_array( $aMod[ 'slug' ], array( 'insights' ) ) ) {
397
  $aMods[] = $aMod;
src/features/ips.php CHANGED
@@ -9,6 +9,12 @@ class ICWP_WPSF_FeatureHandler_Ips extends ICWP_WPSF_FeatureHandler_BaseWpsf {
9
  const LIST_MANUAL_BLACK = 'MB';
10
  const LIST_AUTO_BLACK = 'AB';
11
 
 
 
 
 
 
 
12
  /**
13
  * @return bool
14
  */
@@ -24,13 +30,6 @@ class ICWP_WPSF_FeatureHandler_Ips extends ICWP_WPSF_FeatureHandler_BaseWpsf {
24
  return $this->getOpt( 'transgression_limit' );
25
  }
26
 
27
- /**
28
- * @return string
29
- */
30
- public function getOptTracking404() {
31
- return $this->getOpt( 'track_404' );
32
- }
33
-
34
  /**
35
  * @return int
36
  */
@@ -41,18 +40,10 @@ class ICWP_WPSF_FeatureHandler_Ips extends ICWP_WPSF_FeatureHandler_BaseWpsf {
41
  /**
42
  * @return bool
43
  */
44
- public function isAutoBlackListFeatureEnabled() {
45
  return ( $this->getOptTransgressionLimit() > 0 );
46
  }
47
 
48
- /**
49
- * @premium
50
- * @return bool
51
- */
52
- public function is404Tracking() {
53
- return !$this->isOpt( 'track_404', 'disabled' );
54
- }
55
-
56
  /**
57
  * @param array $aAjaxResponse
58
  * @return array
@@ -88,10 +79,10 @@ class ICWP_WPSF_FeatureHandler_Ips extends ICWP_WPSF_FeatureHandler_BaseWpsf {
88
  $bSuccess = false;
89
  $nId = Services::Request()->post( 'rid', -1 );
90
  if ( !is_numeric( $nId ) || $nId < 0 ) {
91
- $sMessage = _wpsf__( "Invalid entry selected" );
92
  }
93
  else if ( $oProcessor->getDbHandler()->getQueryDeleter()->deleteById( $nId ) ) {
94
- $sMessage = _wpsf__( "IP address deleted" );
95
  $bSuccess = true;
96
  }
97
  else {
@@ -264,6 +255,120 @@ class ICWP_WPSF_FeatureHandler_Ips extends ICWP_WPSF_FeatureHandler_BaseWpsf {
264
  return !$this->isOpt( 'user_auto_recover', 'disabled' );
265
  }
266
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
267
  /**
268
  * @param string $sOptKey
269
  * @return string
@@ -300,7 +405,7 @@ class ICWP_WPSF_FeatureHandler_Ips extends ICWP_WPSF_FeatureHandler_BaseWpsf {
300
  * @throws \Exception
301
  */
302
  protected function loadStrings_SectionTitles( $aOptionsParams ) {
303
-
304
  switch ( $aOptionsParams[ 'slug' ] ) {
305
 
306
  case 'section_enable_plugin_feature_ips' :
@@ -314,28 +419,66 @@ class ICWP_WPSF_FeatureHandler_Ips extends ICWP_WPSF_FeatureHandler_BaseWpsf {
314
  break;
315
 
316
  case 'section_auto_black_list' :
317
- $sTitle = _wpsf__( 'Automatic IP Black List' );
 
318
  $aSummary = array(
319
  sprintf( '%s - %s', _wpsf__( 'Purpose' ), _wpsf__( 'The Automatic IP Black List system will block the IP addresses of naughty visitors after a specified number of transgressions.' ) ),
320
- sprintf( '%s - %s', _wpsf__( 'Recommendation' ), sprintf( _wpsf__( 'Keep the %s feature turned on.' ), _wpsf__( 'Automatic IP Black List' ) ) )
 
 
321
  );
322
- $sTitleShort = _wpsf__( 'Auto Black List' );
323
  break;
324
 
325
- case 'section_reqtracking' :
326
- $sTitle = _wpsf__( 'Bad Request Tracking' );
327
- $sTitleShort = _wpsf__( 'Request Tracking' );
328
  $aSummary = array(
329
- sprintf( '%s - %s', _wpsf__( 'Purpose' ), _wpsf__( 'Track strange behaviour to determine whether visitors are legitimate.' ) ),
330
- sprintf( '%s - %s', _wpsf__( 'Recommendation' ), _wpsf__( "These aren't security issues in their own right, but may indicate probing bots." ) )
 
331
  );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
332
  break;
333
 
334
  default:
335
  list( $sTitle, $sTitleShort, $aSummary ) = $this->loadStrings_SectionTitlesDefaults( $aOptionsParams );
336
  }
337
  $aOptionsParams[ 'title' ] = $sTitle;
338
- $aOptionsParams[ 'summary' ] = ( isset( $aSummary ) && is_array( $aSummary ) ) ? $aSummary : array();
339
  $aOptionsParams[ 'title_short' ] = $sTitleShort;
340
  return $aOptionsParams;
341
  }
@@ -378,12 +521,6 @@ class ICWP_WPSF_FeatureHandler_Ips extends ICWP_WPSF_FeatureHandler_BaseWpsf {
378
  $sDescription = _wpsf__( 'Allow visitors blocked by the plugin to automatically unblock themselves.' );
379
  break;
380
 
381
- case 'track_404' :
382
- $sName = _wpsf__( 'Track 404s' );
383
- $sSummary = _wpsf__( 'Use 404s As An Transgression' );
384
- $sDescription = _wpsf__( 'Repeated 404s may indicate a probing bot.' );
385
- break;
386
-
387
  case 'text_loginfailed' :
388
  $sName = _wpsf__( 'Login Failed' );
389
  $sSummary = _wpsf__( 'Visitor Triggers The IP Transgression System Through A Failed Login' );
@@ -396,6 +533,55 @@ class ICWP_WPSF_FeatureHandler_Ips extends ICWP_WPSF_FeatureHandler_BaseWpsf {
396
  $sDescription = _wpsf__( 'This message is displayed if the visitor triggered the IP Transgression system and reports how many transgressions remain before being blocked.' );
397
  break;
398
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
399
  default:
400
  throw new \Exception( sprintf( 'An option has been defined but without strings assigned to it. Option key: "%s".', $aOptionsParams[ 'key' ] ) );
401
  }
@@ -462,4 +648,28 @@ class ICWP_WPSF_FeatureHandler_Ips extends ICWP_WPSF_FeatureHandler_BaseWpsf {
462
  }
463
  }
464
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
465
  }
9
  const LIST_MANUAL_BLACK = 'MB';
10
  const LIST_AUTO_BLACK = 'AB';
11
 
12
+ protected function updateHandler() {
13
+ if ( $this->isOpt( 'track_404', 'assign-transgression' ) ) {
14
+ $this->setOpt( 'track_404', 'transgression-single' ); // fix for older options values
15
+ }
16
+ }
17
+
18
  /**
19
  * @return bool
20
  */
30
  return $this->getOpt( 'transgression_limit' );
31
  }
32
 
 
 
 
 
 
 
 
33
  /**
34
  * @return int
35
  */
40
  /**
41
  * @return bool
42
  */
43
+ public function isAutoBlackListEnabled() {
44
  return ( $this->getOptTransgressionLimit() > 0 );
45
  }
46
 
 
 
 
 
 
 
 
 
47
  /**
48
  * @param array $aAjaxResponse
49
  * @return array
79
  $bSuccess = false;
80
  $nId = Services::Request()->post( 'rid', -1 );
81
  if ( !is_numeric( $nId ) || $nId < 0 ) {
82
+ $sMessage = _wpsf__( 'Invalid entry selected' );
83
  }
84
  else if ( $oProcessor->getDbHandler()->getQueryDeleter()->deleteById( $nId ) ) {
85
+ $sMessage = _wpsf__( 'IP address deleted' );
86
  $bSuccess = true;
87
  }
88
  else {
255
  return !$this->isOpt( 'user_auto_recover', 'disabled' );
256
  }
257
 
258
+ /**
259
+ * @return bool
260
+ */
261
+ public function isEnabledTrack404() {
262
+ return $this->isSelectOptionEnabled( 'track_404' );
263
+ }
264
+
265
+ /**
266
+ * @return bool
267
+ */
268
+ public function isEnabledTrackFakeWebCrawler() {
269
+ return $this->isSelectOptionEnabled( 'track_fakewebcrawler' );
270
+ }
271
+
272
+ /**
273
+ * @return bool
274
+ */
275
+ public function isEnabledTrackLoginInvalid() {
276
+ return $this->isSelectOptionEnabled( 'track_logininvalid' );
277
+ }
278
+
279
+ /**
280
+ * @return bool
281
+ */
282
+ public function isEnabledTrackLoginFailed() {
283
+ return $this->isSelectOptionEnabled( 'track_loginfailed' );
284
+ }
285
+
286
+ /**
287
+ * @return bool
288
+ */
289
+ public function isEnabledTrackLinkCheese() {
290
+ return $this->isSelectOptionEnabled( 'track_linkcheese' );
291
+ }
292
+
293
+ /**
294
+ * @return bool
295
+ */
296
+ public function isEnabledTrackXmlRpc() {
297
+ return $this->isSelectOptionEnabled( 'track_xmlrpc' );
298
+ }
299
+
300
+ /**
301
+ * @param string $sOptionKey
302
+ * @return bool
303
+ */
304
+ public function isTrackOptTransgression( $sOptionKey ) {
305
+ return strpos( $this->getOpt( $sOptionKey ), 'transgression' ) !== false;
306
+ }
307
+
308
+ /**
309
+ * @param string $sOptionKey
310
+ * @return bool
311
+ */
312
+ public function isTrackOptDoubleTransgression( $sOptionKey ) {
313
+ return $this->isOpt( $sOptionKey, 'transgression-double' );
314
+ }
315
+
316
+ /**
317
+ * @param string $sOptionKey
318
+ * @return bool
319
+ */
320
+ public function isTrackOptLogOnly( $sOptionKey ) {
321
+ return $this->isOpt( $sOptionKey, 'log' );
322
+ }
323
+
324
+ /**
325
+ * @param string $sOptionKey
326
+ * @return bool
327
+ */
328
+ public function isTrackOptImmediateBlock( $sOptionKey ) {
329
+ return $this->isOpt( $sOptionKey, 'block' );
330
+ }
331
+
332
+ /**
333
+ * @param string $sOptionKey
334
+ * @return bool
335
+ */
336
+ protected function isSelectOptionEnabled( $sOptionKey ) {
337
+ $bOptPrem = $this->getOptionsVo()->isOptPremium( $sOptionKey );
338
+ return ( !$bOptPrem || $this->getCon()->isPremiumActive() ) && !$this->isOpt( $sOptionKey, 'disabled' );
339
+ }
340
+
341
+ /**
342
+ * @param string $sSection
343
+ * @return array
344
+ */
345
+ protected function getSectionWarnings( $sSection ) {
346
+ $aWarnings = [];
347
+
348
+ switch ( $sSection ) {
349
+
350
+ case 'section_auto_black_list':
351
+ if ( !$this->isAutoBlackListEnabled() ) {
352
+ $aWarnings[] = sprintf( '%s: %s', _wpsf__( 'Note' ), _wpsf__( "IP blocking is turned-off because the transgressions limit is set to 0." ) );
353
+ }
354
+ break;
355
+
356
+ case 'section_behaviours':
357
+ case 'section_probes':
358
+ case 'section_logins':
359
+ if ( !$this->isAutoBlackListEnabled() ) {
360
+ $aWarnings[] = _wpsf__( "Since the transgressions limit is set to 0, these options have no effect." );
361
+ }
362
+
363
+ if ( $sSection == 'section_behaviours' && strlen( Services::Request()->getUserAgent() ) == 0 ) {
364
+ $aWarnings[] = _wpsf__( "Your User Agent appears to be empty. We recommend not turning on this option." );
365
+ }
366
+ break;
367
+ }
368
+
369
+ return $aWarnings;
370
+ }
371
+
372
  /**
373
  * @param string $sOptKey
374
  * @return string
405
  * @throws \Exception
406
  */
407
  protected function loadStrings_SectionTitles( $aOptionsParams ) {
408
+ $sName = $this->getCon()->getHumanName();
409
  switch ( $aOptionsParams[ 'slug' ] ) {
410
 
411
  case 'section_enable_plugin_feature_ips' :
419
  break;
420
 
421
  case 'section_auto_black_list' :
422
+ $sTitle = _wpsf__( 'Auto IP Blocking Rules' );
423
+ $sTitleShort = _wpsf__( 'Auto IP Blocking Rules' );
424
  $aSummary = array(
425
  sprintf( '%s - %s', _wpsf__( 'Purpose' ), _wpsf__( 'The Automatic IP Black List system will block the IP addresses of naughty visitors after a specified number of transgressions.' ) ),
426
+ sprintf( '%s - %s', _wpsf__( 'Recommendation' ), sprintf( _wpsf__( 'Keep the %s feature turned on.' ), _wpsf__( 'Automatic IP Black List' ) ) ),
427
+ _wpsf__( "Think of 'transgressions' as just a counter for the number of times a visitor does something bad." )
428
+ .' '.sprintf( _wpsf__( 'When the counter reaches the limit below (default: 10), %s will block that completely IP.' ), $sName )
429
  );
 
430
  break;
431
 
432
+ case 'section_enable_plugin_feature_bottrap' :
433
+ $sTitle = _wpsf__( 'Identify And Capture Bots Based On Their Site Activity' );
 
434
  $aSummary = array(
435
+ _wpsf__( "A bot doesn't know what's real and what's not, so it probes many different avenues until it finds something it recognises." ),
436
+ _wpsf__( "Bot-Trap monitors a set of typical bot behaviours to help identify probing bots." ),
437
+ sprintf( '%s - %s', _wpsf__( 'Recommendation' ), _wpsf__( 'Enable as many mouse traps as possible.' ) )
438
  );
439
+ $sTitleShort = _wpsf__( 'Bot-Trap' );
440
+ break;
441
+
442
+ case 'section_logins':
443
+ $sTitle = _wpsf__( 'Detect & Capture Login Bots' );
444
+ $sTitleShort = _wpsf__( 'Detect Login Bots' );
445
+ $aSummary = [
446
+ sprintf( '%s - %s', _wpsf__( 'Summary' ),
447
+ _wpsf__( "Certain bots are designed to test your logins and this feature lets you decide how to handle them." ) ),
448
+ sprintf( '%s - %s', _wpsf__( 'Recommendation' ),
449
+ _wpsf__( "Enable as many options as possible." ) ),
450
+ sprintf( '%s - %s', _wpsf__( 'Warning' ),
451
+ _wpsf__( "Legitimate users may get their password wrong, so take care not to block this." ) ),
452
+ ];
453
+ break;
454
+
455
+ case 'section_probes':
456
+ $sTitle = _wpsf__( 'Detect & Capture Probing Bots' );
457
+ $sTitleShort = _wpsf__( 'Detect Probing Bots' );
458
+ $aSummary = [
459
+ sprintf( '%s - %s', _wpsf__( 'Summary' ),
460
+ _wpsf__( "Bots are designed to probe and this feature is dedicated to detecting probing bots." ) ),
461
+ sprintf( '%s - %s', _wpsf__( 'Recommendation' ),
462
+ _wpsf__( "Enable as many options as possible." ) ),
463
+ ];
464
+ break;
465
+
466
+ case 'section_behaviours':
467
+ $sTitle = _wpsf__( 'Detect Behaviours Common To Bots' );
468
+ $sTitleShort = _wpsf__( 'Detect Bot Behaviours' );
469
+ $aSummary = [
470
+ sprintf( '%s - %s', _wpsf__( 'Summary' ),
471
+ _wpsf__( "Detect characteristics and behaviour commonly associated with illegitimate bots." ) ),
472
+ sprintf( '%s - %s', _wpsf__( 'Recommendation' ),
473
+ _wpsf__( "Enable as many options as possible." ) ),
474
+ ];
475
  break;
476
 
477
  default:
478
  list( $sTitle, $sTitleShort, $aSummary ) = $this->loadStrings_SectionTitlesDefaults( $aOptionsParams );
479
  }
480
  $aOptionsParams[ 'title' ] = $sTitle;
481
+ $aOptionsParams[ 'summary' ] = ( isset( $aSummary ) && is_array( $aSummary ) ) ? $aSummary : [];
482
  $aOptionsParams[ 'title_short' ] = $sTitleShort;
483
  return $aOptionsParams;
484
  }
521
  $sDescription = _wpsf__( 'Allow visitors blocked by the plugin to automatically unblock themselves.' );
522
  break;
523
 
 
 
 
 
 
 
524
  case 'text_loginfailed' :
525
  $sName = _wpsf__( 'Login Failed' );
526
  $sSummary = _wpsf__( 'Visitor Triggers The IP Transgression System Through A Failed Login' );
533
  $sDescription = _wpsf__( 'This message is displayed if the visitor triggered the IP Transgression system and reports how many transgressions remain before being blocked.' );
534
  break;
535
 
536
+ case 'track_404' :
537
+ $sName = _wpsf__( '404 Detect' );
538
+ $sSummary = _wpsf__( 'Identify A Bot When It Hits A 404' );
539
+ $sDescription = _wpsf__( "Detect when a visitor tries to load a non-existent page." )
540
+ .'<br/>'._wpsf__( "Care should be taken to ensure you don't have legitimate links on your site that are 404s." );
541
+ break;
542
+
543
+ case 'track_xmlrpc' :
544
+ $sName = _wpsf__( 'XML-RPC Access' );
545
+ $sSummary = _wpsf__( 'Identify A Bot When It Accesses XML-RPC' );
546
+ $sDescription = _wpsf__( "If you don't use XML-RPC, there's no reason anything should be accessing it." )
547
+ .'<br/>'._wpsf__( "Be careful the ensure you don't block legitimate XML-RPC traffic if your site needs it." )
548
+ .'<br/>'._wpsf__( "We recommend transgressions here in-case of blocking valid request unless you're sure." );
549
+ break;
550
+
551
+ case 'track_linkcheese' :
552
+ $sName = _wpsf__( 'Link Cheese' );
553
+ $sSummary = _wpsf__( 'Tempt A Bot With A Fake Link To Follow' );
554
+ $sDescription = _wpsf__( "Detect a bot when it follows a fake 'no-follow' link." )
555
+ .'<br/>'._wpsf__( "This works because legitimate web crawlers respect 'robots.txt' and 'nofollow' directives." );
556
+ break;
557
+
558
+ case 'track_logininvalid' :
559
+ $sName = _wpsf__( 'Invalid Usernames' );
560
+ $sSummary = _wpsf__( "Detect Attempted Logins With Usernames That Don't Exist" );
561
+ $sDescription = _wpsf__( "Identify a Bot when it tries to login with a non-existent username." )
562
+ .'<br/>'._wpsf__( "This includes the default 'admin' if you've removed that account." );
563
+ break;
564
+
565
+ case 'track_loginfailed' :
566
+ $sName = _wpsf__( 'Failed Login' );
567
+ $sSummary = _wpsf__( 'Detect Failed Login Attempts Using Valid Usernames' );
568
+ $sDescription = _wpsf__( "Penalise a visitor when they try to login using a valid username, but it fails." );
569
+ break;
570
+
571
+ case 'track_fakewebcrawler' :
572
+ $sName = _wpsf__( 'Fake Web Crawler' );
573
+ $sSummary = _wpsf__( 'Detect Fake Search Engine Crawlers' );
574
+ $sDescription = _wpsf__( "Identify a Bot when it presents as an official web crawler, but analysis shows it's fake." );
575
+ break;
576
+
577
+ case 'track_useragent' :
578
+ $sName = _wpsf__( 'Empty User Agents' );
579
+ $sSummary = _wpsf__( 'Detect Requests With Empty User Agents' );
580
+ $sDescription = _wpsf__( "Identify a bot when the user agent is not provided." )
581
+ .'<br />'.sprintf( '%s: <code>%s</code>',
582
+ _wpsf__( 'Your user agent is' ), Services::Request()->getUserAgent() );
583
+ break;
584
+
585
  default:
586
  throw new \Exception( sprintf( 'An option has been defined but without strings assigned to it. Option key: "%s".', $aOptionsParams[ 'key' ] ) );
587
  }
648
  }
649
  }
650
  }
651
+
652
+ /**
653
+ * @return string
654
+ * @deprecated 7.3
655
+ */
656
+ public function getOptTracking404() {
657
+ return $this->getOpt( 'track_404' );
658
+ }
659
+
660
+ /**
661
+ * @return bool
662
+ * @deprecated 7.3
663
+ */
664
+ public function is404Tracking() {
665
+ return !$this->isOpt( 'track_404', 'disabled' );
666
+ }
667
+
668
+ /**
669
+ * @deprecated
670
+ * @return bool
671
+ */
672
+ public function isAutoBlackListFeatureEnabled() {
673
+ return $this->isAutoBlackListEnabled();
674
+ }
675
  }
src/features/license.php CHANGED
@@ -60,15 +60,15 @@ class ICWP_WPSF_FeatureHandler_License extends ICWP_WPSF_FeatureHandler_BaseWpsf
60
  * @return array
61
  */
62
  protected function getLicenseData() {
63
- $aData = $this->getOpt( 'license_data', array() );
64
- return is_array( $aData ) ? $aData : array();
65
  }
66
 
67
  /**
68
  * @return $this
69
  */
70
  protected function clearLicenseData() {
71
- return $this->setOpt( 'license_data', array() );
72
  }
73
 
74
  /**
@@ -726,7 +726,7 @@ class ICWP_WPSF_FeatureHandler_License extends ICWP_WPSF_FeatureHandler_BaseWpsf
726
  }
727
 
728
  $aOptionsParams[ 'title' ] = $sTitle;
729
- $aOptionsParams[ 'summary' ] = ( isset( $aSummary ) && is_array( $aSummary ) ) ? $aSummary : array();
730
  $aOptionsParams[ 'title_short' ] = $sTitleShort;
731
  return $aOptionsParams;
732
  }
60
  * @return array
61
  */
62
  protected function getLicenseData() {
63
+ $aData = $this->getOpt( 'license_data', [] );
64
+ return is_array( $aData ) ? $aData : [];
65
  }
66
 
67
  /**
68
  * @return $this
69
  */
70
  protected function clearLicenseData() {
71
+ return $this->setOpt( 'license_data', [] );
72
  }
73
 
74
  /**
726
  }
727
 
728
  $aOptionsParams[ 'title' ] = $sTitle;
729
+ $aOptionsParams[ 'summary' ] = ( isset( $aSummary ) && is_array( $aSummary ) ) ? $aSummary : [];
730
  $aOptionsParams[ 'title_short' ] = $sTitleShort;
731
  return $aOptionsParams;
732
  }
src/features/lockdown.php CHANGED
@@ -67,7 +67,7 @@ class ICWP_WPSF_FeatureHandler_Lockdown extends ICWP_WPSF_FeatureHandler_BaseWps
67
  public function addInsightsNoticeData( $aAllNotices ) {
68
  $aNotices = array(
69
  'title' => _wpsf__( 'Lockdown' ),
70
- 'messages' => array()
71
  );
72
 
73
  { //edit plugins
@@ -99,7 +99,7 @@ class ICWP_WPSF_FeatureHandler_Lockdown extends ICWP_WPSF_FeatureHandler_BaseWps
99
  'title' => _wpsf__( 'WordPress Lockdown' ),
100
  'sub' => _wpsf__( 'Restrict WP Functionality e.g. XMLRPC & REST API' ),
101
  ),
102
- 'key_opts' => array(),
103
  'href_options' => $this->getUrl_AdminPage()
104
  );
105
 
@@ -195,7 +195,7 @@ class ICWP_WPSF_FeatureHandler_Lockdown extends ICWP_WPSF_FeatureHandler_BaseWps
195
  throw new \Exception( sprintf( 'A section slug was defined but with no associated strings. Slug: "%s".', $sSectionSlug ) );
196
  }
197
  $aOptionsParams[ 'title' ] = $sTitle;
198
- $aOptionsParams[ 'summary' ] = ( isset( $aSummary ) && is_array( $aSummary ) ) ? $aSummary : array();
199
  $aOptionsParams[ 'title_short' ] = $sTitleShort;
200
  return $aOptionsParams;
201
  }
67
  public function addInsightsNoticeData( $aAllNotices ) {
68
  $aNotices = array(
69
  'title' => _wpsf__( 'Lockdown' ),
70
+ 'messages' => []
71
  );
72
 
73
  { //edit plugins
99
  'title' => _wpsf__( 'WordPress Lockdown' ),
100
  'sub' => _wpsf__( 'Restrict WP Functionality e.g. XMLRPC & REST API' ),
101
  ),
102
+ 'key_opts' => [],
103
  'href_options' => $this->getUrl_AdminPage()
104
  );
105
 
195
  throw new \Exception( sprintf( 'A section slug was defined but with no associated strings. Slug: "%s".', $sSectionSlug ) );
196
  }
197
  $aOptionsParams[ 'title' ] = $sTitle;
198
+ $aOptionsParams[ 'summary' ] = ( isset( $aSummary ) && is_array( $aSummary ) ) ? $aSummary : [];
199
  $aOptionsParams[ 'title_short' ] = $sTitleShort;
200
  return $aOptionsParams;
201
  }
src/features/login_protect.php CHANGED
@@ -24,10 +24,6 @@ class ICWP_WPSF_FeatureHandler_LoginProtect extends ICWP_WPSF_FeatureHandler_Bas
24
  ->sendEmailVerifyCanSend();
25
  }
26
 
27
- if ( $this->getOpt( 'login_limit_interval' ) < 0 ) {
28
- $this->getOptionsVo()->resetOptToDefault( 'login_limit_interval' );
29
- }
30
-
31
  $aIds = $this->getAntiBotFormSelectors();
32
  foreach ( $aIds as $nKey => $sId ) {
33
  $sId = trim( strip_tags( $sId ) );
@@ -153,7 +149,7 @@ class ICWP_WPSF_FeatureHandler_LoginProtect extends ICWP_WPSF_FeatureHandler_Bas
153
  * @return array
154
  */
155
  public function getEmail2FaRoles() {
156
- $aRoles = $this->getOpt( 'two_factor_auth_user_roles', array() );
157
  if ( empty( $aRoles ) || !is_array( $aRoles ) ) {
158
  $aRoles = $this->getOptEmailTwoFactorRolesDefaults();
159
  $this->setOpt( 'two_factor_auth_user_roles', $aRoles );
@@ -185,6 +181,13 @@ class ICWP_WPSF_FeatureHandler_LoginProtect extends ICWP_WPSF_FeatureHandler_Bas
185
  return $aTwoAuthRoles;
186
  }
187
 
 
 
 
 
 
 
 
188
  /**
189
  * @return string
190
  */
@@ -287,7 +290,7 @@ class ICWP_WPSF_FeatureHandler_LoginProtect extends ICWP_WPSF_FeatureHandler_Bas
287
  $oMeta = $this->getCon()->getUserMeta( $oUser );
288
  $aHashes = $oMeta->hash_loginmfa;
289
  if ( !is_array( $aHashes ) ) {
290
- $aHashes = array();
291
  $oMeta->hash_loginmfa = $aHashes;
292
  }
293
  return $aHashes;
@@ -392,7 +395,7 @@ class ICWP_WPSF_FeatureHandler_LoginProtect extends ICWP_WPSF_FeatureHandler_Bas
392
  * @return bool
393
  */
394
  public function isCooldownEnabled() {
395
- return (int)$this->getOpt( 'login_limit_interval' ) > 0;
396
  }
397
 
398
  /**
@@ -490,7 +493,7 @@ class ICWP_WPSF_FeatureHandler_LoginProtect extends ICWP_WPSF_FeatureHandler_Bas
490
  * @return array
491
  */
492
  protected function getSectionWarnings( $sSection ) {
493
- $aWarnings = array();
494
 
495
  if ( $sSection == 'section_brute_force_login_protection' && !$this->isPremium() ) {
496
  $sIntegration = $this->getPremiumOnlyIntegration();
@@ -583,7 +586,7 @@ class ICWP_WPSF_FeatureHandler_LoginProtect extends ICWP_WPSF_FeatureHandler_Bas
583
  protected function ajaxExec_GenBackupCodes() {
584
  /** @var ICWP_WPSF_Processor_LoginProtect $oPro */
585
  $oPro = $this->loadProcessor();
586
- $sPass = $oPro->getProcessorLoginIntent()
587
  ->getProcessorBackupCodes()
588
  ->resetSecret( Services::WpUsers()->getCurrentWpUser() );
589
 
@@ -610,8 +613,8 @@ class ICWP_WPSF_FeatureHandler_LoginProtect extends ICWP_WPSF_FeatureHandler_Bas
610
  * @return array
611
  */
612
  public function getAntiBotFormSelectors() {
613
- $aIds = $this->getOpt( 'antibot_form_ids', array() );
614
- return is_array( $aIds ) ? $aIds : array();
615
  }
616
 
617
  public function onWpEnqueueJs() {
@@ -664,7 +667,7 @@ class ICWP_WPSF_FeatureHandler_LoginProtect extends ICWP_WPSF_FeatureHandler_Bas
664
 
665
  /** @var ICWP_WPSF_Processor_LoginProtect $oPro */
666
  $oPro = $this->loadProcessor();
667
- $oPro->getProcessorLoginIntent()
668
  ->getProcessorBackupCodes()
669
  ->deleteSecret( Services::WpUsers()->getCurrentWpUser() );
670
  $this->setFlashAdminNotice( _wpsf__( 'Multi-factor login backup code has been removed from your profile' ) );
@@ -735,7 +738,7 @@ class ICWP_WPSF_FeatureHandler_LoginProtect extends ICWP_WPSF_FeatureHandler_Bas
735
  'title' => _wpsf__( 'Login Guard' ),
736
  'sub' => _wpsf__( 'Brute Force Protection & Identity Verification' ),
737
  ),
738
- 'key_opts' => array(),
739
  'href_options' => $this->getUrl_AdminPage()
740
  );
741
 
@@ -882,7 +885,7 @@ class ICWP_WPSF_FeatureHandler_LoginProtect extends ICWP_WPSF_FeatureHandler_Bas
882
 
883
  $aOptionsParams[ 'title' ] = $sTitle;
884
  $aOptionsParams[ 'title_short' ] = $sTitleShort;
885
- $aOptionsParams[ 'summary' ] = ( isset( $aSummary ) && is_array( $aSummary ) ) ? $aSummary : array();
886
  return $aOptionsParams;
887
  }
888
 
24
  ->sendEmailVerifyCanSend();
25
  }
26
 
 
 
 
 
27
  $aIds = $this->getAntiBotFormSelectors();
28
  foreach ( $aIds as $nKey => $sId ) {
29
  $sId = trim( strip_tags( $sId ) );
149
  * @return array
150
  */
151
  public function getEmail2FaRoles() {
152
+ $aRoles = $this->getOpt( 'two_factor_auth_user_roles', [] );
153
  if ( empty( $aRoles ) || !is_array( $aRoles ) ) {
154
  $aRoles = $this->getOptEmailTwoFactorRolesDefaults();
155
  $this->setOpt( 'two_factor_auth_user_roles', $aRoles );
181
  return $aTwoAuthRoles;
182
  }
183
 
184
+ /**
185
+ * @return int
186
+ */
187
+ public function getCooldownInterval() {
188
+ return (int)$this->getOpt( 'login_limit_interval' );
189
+ }
190
+
191
  /**
192
  * @return string
193
  */
290
  $oMeta = $this->getCon()->getUserMeta( $oUser );
291
  $aHashes = $oMeta->hash_loginmfa;
292
  if ( !is_array( $aHashes ) ) {
293
+ $aHashes = [];
294
  $oMeta->hash_loginmfa = $aHashes;
295
  }
296
  return $aHashes;
395
  * @return bool
396
  */
397
  public function isCooldownEnabled() {
398
+ return $this->getCooldownInterval() > 0;
399
  }
400
 
401
  /**
493
  * @return array
494
  */
495
  protected function getSectionWarnings( $sSection ) {
496
+ $aWarnings = [];
497
 
498
  if ( $sSection == 'section_brute_force_login_protection' && !$this->isPremium() ) {
499
  $sIntegration = $this->getPremiumOnlyIntegration();
586
  protected function ajaxExec_GenBackupCodes() {
587
  /** @var ICWP_WPSF_Processor_LoginProtect $oPro */
588
  $oPro = $this->loadProcessor();
589
+ $sPass = $oPro->getSubProIntent()
590
  ->getProcessorBackupCodes()
591
  ->resetSecret( Services::WpUsers()->getCurrentWpUser() );
592
 
613
  * @return array
614
  */
615
  public function getAntiBotFormSelectors() {
616
+ $aIds = $this->getOpt( 'antibot_form_ids', [] );
617
+ return is_array( $aIds ) ? $aIds : [];
618
  }
619
 
620
  public function onWpEnqueueJs() {
667
 
668
  /** @var ICWP_WPSF_Processor_LoginProtect $oPro */
669
  $oPro = $this->loadProcessor();
670
+ $oPro->getSubProIntent()
671
  ->getProcessorBackupCodes()
672
  ->deleteSecret( Services::WpUsers()->getCurrentWpUser() );
673
  $this->setFlashAdminNotice( _wpsf__( 'Multi-factor login backup code has been removed from your profile' ) );
738
  'title' => _wpsf__( 'Login Guard' ),
739
  'sub' => _wpsf__( 'Brute Force Protection & Identity Verification' ),
740
  ),
741
+ 'key_opts' => [],
742
  'href_options' => $this->getUrl_AdminPage()
743
  );
744
 
885
 
886
  $aOptionsParams[ 'title' ] = $sTitle;
887
  $aOptionsParams[ 'title_short' ] = $sTitleShort;
888
+ $aOptionsParams[ 'summary' ] = ( isset( $aSummary ) && is_array( $aSummary ) ) ? $aSummary : [];
889
  return $aOptionsParams;
890
  }
891
 
src/features/mousetrap.php DELETED
@@ -1,209 +0,0 @@
1
- <?php
2
-
3
- use FernleafSystems\Wordpress\Services\Services;
4
-
5
- class ICWP_WPSF_FeatureHandler_Mousetrap extends ICWP_WPSF_FeatureHandler_BaseWpsf {
6
-
7
- protected function doPostConstruction() {
8
- }
9
-
10
- /**
11
- * @return bool
12
- */
13
- public function isEnabled404() {
14
- return $this->isSelectOptionEnabled( '404_detect' );
15
- }
16
-
17
- /**
18
- * @return bool
19
- */
20
- public function isEnabledFakeWebCrawler() {
21
- return $this->isSelectOptionEnabled( 'fake_webcrawler' );
22
- }
23
-
24
- /**
25
- * @return bool
26
- */
27
- public function isEnabledInvalidUsernames() {
28
- return $this->isSelectOptionEnabled( 'invalid_username' );
29
- }
30
-
31
- /**
32
- * @return bool
33
- */
34
- public function isEnabledLinkCheese() {
35
- return $this->isSelectOptionEnabled( 'link_cheese' );
36
- }
37
-
38
- /**
39
- * @return bool
40
- */
41
- public function isEnabledXmlRpcDetect() {
42
- return $this->isSelectOptionEnabled( 'xmlrpc' );
43
- }
44
-
45
- /**
46
- * @return bool
47
- */
48
- public function isTransgression404() {
49
- return $this->isSelectOptionTransgression( '404_detect' );
50
- }
51
-
52
- /**
53
- * @return bool
54
- */
55
- public function isTransgressionLinkCheese() {
56
- return $this->isSelectOptionTransgression( 'link_cheese' );
57
- }
58
-
59
- /**
60
- * @return bool
61
- */
62
- public function isTransgressionInvalidUsernames() {
63
- return $this->isSelectOptionTransgression( 'invalid_username' );
64
- }
65
-
66
- /**
67
- * @return bool
68
- */
69
- public function isTransgressionFakeWebCrawler() {
70
- return $this->isSelectOptionTransgression( 'fake_webcrawler' );
71
- }
72
-
73
- /**
74
- * @return bool
75
- */
76
- public function isTransgressionXmlRpc() {
77
- return $this->isSelectOptionTransgression( 'xmlrpc' );
78
- }
79
-
80
- /**
81
- * @param string $sOptionKey
82
- * @return bool
83
- */
84
- protected function isSelectOptionTransgression( $sOptionKey ) {
85
- return $this->isOpt( $sOptionKey, 'transgression' );
86
- }
87
-
88
- /**
89
- * @param string $sOptionKey
90
- * @return bool
91
- */
92
- protected function isSelectOptionEnabled( $sOptionKey ) {
93
- return !$this->isOpt( $sOptionKey, 'disabled' );
94
- }
95
-
96
- /**
97
- * @return bool
98
- */
99
- private function getMouseTrapResponseType() {
100
- return $this->getOpt( 'mousetrap_bot_response' );
101
- }
102
-
103
- /**
104
- * @return bool
105
- */
106
- public function isMouseTrapEnabled() {
107
- return $this->isPremium() && ( $this->getMouseTrapResponseType() != 'disabled' );
108
- }
109
-
110
- /**
111
- * @return bool
112
- */
113
- public function isMouseTrayBlock() {
114
- return $this->getMouseTrapResponseType() === 'block';
115
- }
116
-
117
- /**
118
- * @return bool
119
- */
120
- public function isMouseTrapTransgression() {
121
- return $this->getMouseTrapResponseType() === 'transgression';
122
- }
123
-
124
- /**
125
- * @param array $aOptionsParams
126
- * @return array
127
- * @throws \Exception
128
- */
129
- protected function loadStrings_SectionTitles( $aOptionsParams ) {
130
-
131
- switch ( $aOptionsParams[ 'slug' ] ) {
132
-
133
- case 'section_enable_plugin_feature_mousetrap' :
134
- $sTitle = _wpsf__( 'Identify And Capture Bots Based On Their Site Activity' );
135
- $aSummary = array(
136
- _wpsf__( "A bot doesn't know what's real and what's not, so it probes many different avenues until it finds something it recognises." ),
137
- _wpsf__( "MouseTrap monitors a set of typical bot behaviours to help identify probing bots." ),
138
- sprintf( '%s - %s', _wpsf__( 'Recommendation' ), _wpsf__( 'Enable as many mouse traps as possible.' ) )
139
- );
140
- $sTitleShort = _wpsf__( 'Bot MouseTrap' );
141
- break;
142
-
143
- case 'section_cheese' :
144
- $sTitle = _wpsf__( 'Capture Bot Activity' );
145
- $aSummary = [
146
- sprintf( '%s - %s', _wpsf__( 'Recommendation' ), _wpsf__( "Enable as many options as possible." ) )
147
- ];
148
- $sTitleShort = _wpsf__( 'Bot Cheeses' );
149
- break;
150
-
151
- default:
152
- list( $sTitle, $sTitleShort, $aSummary ) = $this->loadStrings_SectionTitlesDefaults( $aOptionsParams );
153
- }
154
- $aOptionsParams[ 'title' ] = $sTitle;
155
- $aOptionsParams[ 'summary' ] = ( isset( $aSummary ) && is_array( $aSummary ) ) ? $aSummary : array();
156
- $aOptionsParams[ 'title_short' ] = $sTitleShort;
157
- return $aOptionsParams;
158
- }
159
-
160
- /**
161
- * @param array $aOptionsParams
162
- * @return array
163
- * @throws \Exception
164
- */
165
- protected function loadStrings_Options( $aOptionsParams ) {
166
-
167
- switch ( $aOptionsParams[ 'key' ] ) {
168
-
169
- case 'enable_mousetrap' :
170
- $sName = sprintf( _wpsf__( 'Enable %s Module' ), $this->getMainFeatureName() );
171
- $sSummary = sprintf( _wpsf__( 'Enable (or Disable) The %s Module' ), $this->getMainFeatureName() );
172
- $sDescription = sprintf( _wpsf__( 'Un-Checking this option will completely disable the %s module.' ), $this->getMainFeatureName() );
173
- break;
174
-
175
- case '404_detect' :
176
- $sName = _wpsf__( '404 Detect' );
177
- $sSummary = _wpsf__( 'Identify A Bot When It Hits A 404' );
178
- $sDescription = _wpsf__( "Detect when a visitor tries to load a non-existent page." )
179
- .'<br/>'._wpsf__( "Care should be taken to ensure you don't have legitimate links on your site that are 404s." );
180
- break;
181
-
182
- case 'link_cheese' :
183
- $sName = _wpsf__( 'Link Cheese' );
184
- $sSummary = _wpsf__( 'Tempt A Bot With A Link To Follow' );
185
- $sDescription = _wpsf__( "Detect a bot when it follows a 'no-follow' link." );
186
- break;
187
-
188
- case 'invalid_username' :
189
- $sName = _wpsf__( 'Invalid Usernames' );
190
- $sSummary = _wpsf__( 'Detect Invalid Username Logins' );
191
- $sDescription = _wpsf__( "Identify a Bot when it tries to login with a non-existent username" );
192
- break;
193
-
194
- case 'fake_webcrawler' :
195
- $sName = _wpsf__( 'Fake Web Crawler' );
196
- $sSummary = _wpsf__( 'Detect Fake Search Engine Crawlers' );
197
- $sDescription = _wpsf__( "Identify a Bot when it presents as an official web crawler, but analysis shows it's fake." );
198
- break;
199
-
200
- default:
201
- throw new \Exception( sprintf( 'An option has been defined but without strings assigned to it. Option key: "%s".', $aOptionsParams[ 'key' ] ) );
202
- }
203
-
204
- $aOptionsParams[ 'name' ] = $sName;
205
- $aOptionsParams[ 'summary' ] = $sSummary;
206
- $aOptionsParams[ 'description' ] = $sDescription;
207
- return $aOptionsParams;
208
- }
209
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/features/plugin.php CHANGED
@@ -315,7 +315,7 @@ class ICWP_WPSF_FeatureHandler_Plugin extends ICWP_WPSF_FeatureHandler_BaseWpsf
315
  * @return array
316
  */
317
  public function ajaxExec_SendDeactivateSurvey() {
318
- $aResults = array();
319
  foreach ( $_POST as $sKey => $sValue ) {
320
  if ( strpos( $sKey, 'reason_' ) === 0 ) {
321
  $aResults[] = str_replace( 'reason_', '', $sKey ).': '.$sValue;
@@ -495,7 +495,7 @@ class ICWP_WPSF_FeatureHandler_Plugin extends ICWP_WPSF_FeatureHandler_BaseWpsf
495
  public function getActivePluginFeatures() {
496
  $aActiveFeatures = $this->getDef( 'active_plugin_features' );
497
 
498
- $aPluginFeatures = array();
499
  if ( !empty( $aActiveFeatures ) && is_array( $aActiveFeatures ) ) {
500
 
501
  foreach ( $aActiveFeatures as $nPosition => $aFeature ) {
@@ -597,6 +597,55 @@ class ICWP_WPSF_FeatureHandler_Plugin extends ICWP_WPSF_FeatureHandler_BaseWpsf
597
  return $this->getOpt( 'installation_time', 0 );
598
  }
599
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
600
  /**
601
  * @return int - the real install timestamp
602
  */
@@ -642,8 +691,8 @@ class ICWP_WPSF_FeatureHandler_Plugin extends ICWP_WPSF_FeatureHandler_BaseWpsf
642
  /**
643
  * Ensure we always a valid installation ID.
644
  *
645
- * @deprecated but still used because it aligns with stats collection
646
  * @return string
 
647
  */
648
  public function getPluginInstallationId() {
649
  $sId = $this->getOpt( 'unique_installation_id', '' );
@@ -654,6 +703,29 @@ class ICWP_WPSF_FeatureHandler_Plugin extends ICWP_WPSF_FeatureHandler_BaseWpsf
654
  return $sId;
655
  }
656
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
657
  /**
658
  * @param string $sNewId - leave empty to reset if the current isn't valid
659
  * @return string
@@ -711,8 +783,8 @@ class ICWP_WPSF_FeatureHandler_Plugin extends ICWP_WPSF_FeatureHandler_BaseWpsf
711
  * @return string[]
712
  */
713
  public function getImportExportWhitelist() {
714
- $aWhitelist = $this->getOpt( 'importexport_whitelist', array() );
715
- return is_array( $aWhitelist ) ? $aWhitelist : array();
716
  }
717
 
718
  /**
@@ -803,7 +875,7 @@ class ICWP_WPSF_FeatureHandler_Plugin extends ICWP_WPSF_FeatureHandler_BaseWpsf
803
  protected function cleanImportExportWhitelistUrls() {
804
  $oDP = $this->loadDP();
805
 
806
- $aCleaned = array();
807
  $aWhitelistUrls = $this->getImportExportWhitelist();
808
  foreach ( $aWhitelistUrls as $nKey => $sUrl ) {
809
 
@@ -870,8 +942,8 @@ class ICWP_WPSF_FeatureHandler_Plugin extends ICWP_WPSF_FeatureHandler_BaseWpsf
870
  $aOptionData = $this->getOptionsVo()->getRawData_SingleOption( 'visitor_address_source' );
871
  $aValueOptions = $aOptionData[ 'value_options' ];
872
 
873
- $aMap = array();
874
- $aEmpties = array();
875
  foreach ( $aValueOptions as $aOptionValue ) {
876
  $sKey = $aOptionValue[ 'value_key' ];
877
  if ( $sKey == 'AUTO_DETECT_IP' ) {
@@ -1001,7 +1073,7 @@ class ICWP_WPSF_FeatureHandler_Plugin extends ICWP_WPSF_FeatureHandler_BaseWpsf
1001
  'title' => _wpsf__( 'General Settings' ),
1002
  'sub' => sprintf( _wpsf__( 'General %s Settings' ), $this->getCon()->getHumanName() ),
1003
  ),
1004
- 'key_opts' => array(),
1005
  'href_options' => $this->getUrl_AdminPage()
1006
  );
1007
 
@@ -1025,7 +1097,7 @@ class ICWP_WPSF_FeatureHandler_Plugin extends ICWP_WPSF_FeatureHandler_BaseWpsf
1025
  'summary' => $bHasSupportEmail ?
1026
  sprintf( _wpsf__( 'Email address for reports set to: %s' ), $this->supplyPluginReportEmail() )
1027
  : sprintf( _wpsf__( 'No address provided - defaulting to: %s' ), Services::WpGeneral()
1028
- ->getSiteAdminEmail() ),
1029
  'weight' => 0,
1030
  'href' => $this->getUrl_DirectLinkToOption( 'block_send_email_address' ),
1031
  );
@@ -1108,7 +1180,7 @@ class ICWP_WPSF_FeatureHandler_Plugin extends ICWP_WPSF_FeatureHandler_BaseWpsf
1108
  throw new \Exception( sprintf( 'A section slug was defined but with no associated strings. Slug: "%s".', $aOptionsParams[ 'slug' ] ) );
1109
  }
1110
  $aOptionsParams[ 'title' ] = $sTitle;
1111
- $aOptionsParams[ 'summary' ] = ( isset( $aSummary ) && is_array( $aSummary ) ) ? $aSummary : array();
1112
  $aOptionsParams[ 'title_short' ] = $sTitleShort;
1113
  return $aOptionsParams;
1114
  }
315
  * @return array
316
  */
317
  public function ajaxExec_SendDeactivateSurvey() {
318
+ $aResults = [];
319
  foreach ( $_POST as $sKey => $sValue ) {
320
  if ( strpos( $sKey, 'reason_' ) === 0 ) {
321
  $aResults[] = str_replace( 'reason_', '', $sKey ).': '.$sValue;
495
  public function getActivePluginFeatures() {
496
  $aActiveFeatures = $this->getDef( 'active_plugin_features' );
497
 
498
+ $aPluginFeatures = [];
499
  if ( !empty( $aActiveFeatures ) && is_array( $aActiveFeatures ) ) {
500
 
501
  foreach ( $aActiveFeatures as $nPosition => $aFeature ) {
597
  return $this->getOpt( 'installation_time', 0 );
598
  }
599
 
600
+ /**
601
+ * @return string
602
+ */
603
+ public function getOpenSslPrivateKey() {
604
+ $sKey = null;
605
+ $oEnc = Services::Encrypt();
606
+ if ( $oEnc->isSupportedOpenSslDataEncryption() ) {
607
+ $sKey = $this->getOpt( 'openssl_private_key' );
608
+ if ( empty( $sKey ) ) {
609
+ try {
610
+ $aKeys = $oEnc->createNewPrivatePublicKeyPair();
611
+ if ( !empty( $aKeys[ 'private' ] ) ) {
612
+ $sKey = $aKeys[ 'private' ];
613
+ $this->setOpt( 'openssl_private_key', base64_encode( $sKey ) );
614
+ }
615
+ }
616
+ catch ( \Exception $oE ) {
617
+ }
618
+ }
619
+ else {
620
+ $sKey = base64_decode( $sKey );
621
+ }
622
+ }
623
+ return $sKey;
624
+ }
625
+
626
+ /**
627
+ * @return string|null
628
+ */
629
+ public function getOpenSslPublicKey() {
630
+ $sKey = null;
631
+ if ( $this->hasOpenSslPrivateKey() ) {
632
+ try {
633
+ $sKey = Services::Encrypt()->getPublicKeyFromPrivateKey( $this->getOpenSslPrivateKey() );
634
+ }
635
+ catch ( \Exception $oE ) {
636
+ }
637
+ }
638
+ return $sKey;
639
+ }
640
+
641
+ /**
642
+ * @return bool
643
+ */
644
+ public function hasOpenSslPrivateKey() {
645
+ $sKey = $this->getOpenSslPrivateKey();
646
+ return !empty( $sKey );
647
+ }
648
+
649
  /**
650
  * @return int - the real install timestamp
651
  */
691
  /**
692
  * Ensure we always a valid installation ID.
693
  *
 
694
  * @return string
695
+ * @deprecated but still used because it aligns with stats collection
696
  */
697
  public function getPluginInstallationId() {
698
  $sId = $this->getOpt( 'unique_installation_id', '' );
703
  return $sId;
704
  }
705
 
706
+ /**
707
+ * @return int
708
+ */
709
+ public function getActivatedAt() {
710
+ return (int)$this->getOpt( 'activated_at', 0 );
711
+ }
712
+
713
+ /**
714
+ * @return bool
715
+ */
716
+ public function getIfShowIntroVideo() {
717
+ $nNow = Services::Request()->ts();
718
+ return ( $nNow - $this->getActivatedAt() < 8 )
719
+ && ( $nNow - $this->getInstallDate() < 15 );
720
+ }
721
+
722
+ /**
723
+ * @return $this
724
+ */
725
+ public function setActivatedAt() {
726
+ return $this->setOpt( 'activated_at', Services::Request()->ts() );
727
+ }
728
+
729
  /**
730
  * @param string $sNewId - leave empty to reset if the current isn't valid
731
  * @return string
783
  * @return string[]
784
  */
785
  public function getImportExportWhitelist() {
786
+ $aWhitelist = $this->getOpt( 'importexport_whitelist', [] );
787
+ return is_array( $aWhitelist ) ? $aWhitelist : [];
788
  }
789
 
790
  /**
875
  protected function cleanImportExportWhitelistUrls() {
876
  $oDP = $this->loadDP();
877
 
878
+ $aCleaned = [];
879
  $aWhitelistUrls = $this->getImportExportWhitelist();
880
  foreach ( $aWhitelistUrls as $nKey => $sUrl ) {
881
 
942
  $aOptionData = $this->getOptionsVo()->getRawData_SingleOption( 'visitor_address_source' );
943
  $aValueOptions = $aOptionData[ 'value_options' ];
944
 
945
+ $aMap = [];
946
+ $aEmpties = [];
947
  foreach ( $aValueOptions as $aOptionValue ) {
948
  $sKey = $aOptionValue[ 'value_key' ];
949
  if ( $sKey == 'AUTO_DETECT_IP' ) {
1073
  'title' => _wpsf__( 'General Settings' ),
1074
  'sub' => sprintf( _wpsf__( 'General %s Settings' ), $this->getCon()->getHumanName() ),
1075
  ),
1076
+ 'key_opts' => [],
1077
  'href_options' => $this->getUrl_AdminPage()
1078
  );
1079
 
1097
  'summary' => $bHasSupportEmail ?
1098
  sprintf( _wpsf__( 'Email address for reports set to: %s' ), $this->supplyPluginReportEmail() )
1099
  : sprintf( _wpsf__( 'No address provided - defaulting to: %s' ), Services::WpGeneral()
1100
+ ->getSiteAdminEmail() ),
1101
  'weight' => 0,
1102
  'href' => $this->getUrl_DirectLinkToOption( 'block_send_email_address' ),
1103
  );
1180
  throw new \Exception( sprintf( 'A section slug was defined but with no associated strings. Slug: "%s".', $aOptionsParams[ 'slug' ] ) );
1181
  }
1182
  $aOptionsParams[ 'title' ] = $sTitle;
1183
+ $aOptionsParams[ 'summary' ] = ( isset( $aSummary ) && is_array( $aSummary ) ) ? $aSummary : [];
1184
  $aOptionsParams[ 'title_short' ] = $sTitleShort;
1185
  return $aOptionsParams;
1186
  }
src/features/sessions.php CHANGED
@@ -50,7 +50,7 @@ class ICWP_WPSF_FeatureHandler_Sessions extends ICWP_WPSF_FeatureHandler_BaseWps
50
  throw new \Exception( sprintf( 'A section slug was defined but with no associated strings. Slug: "%s".', $sSectionSlug ) );
51
  }
52
  $aOptionsParams[ 'title' ] = $sTitle;
53
- $aOptionsParams[ 'summary' ] = ( isset( $aSummary ) && is_array( $aSummary ) ) ? $aSummary : array();
54
  $aOptionsParams[ 'title_short' ] = $sTitleShort;
55
  return $aOptionsParams;
56
  }
50
  throw new \Exception( sprintf( 'A section slug was defined but with no associated strings. Slug: "%s".', $sSectionSlug ) );
51
  }
52
  $aOptionsParams[ 'title' ] = $sTitle;
53
+ $aOptionsParams[ 'summary' ] = ( isset( $aSummary ) && is_array( $aSummary ) ) ? $aSummary : [];
54
  $aOptionsParams[ 'title_short' ] = $sTitleShort;
55
  return $aOptionsParams;
56
  }
src/features/statistics.php CHANGED
@@ -59,7 +59,7 @@ class ICWP_WPSF_FeatureHandler_Statistics extends ICWP_WPSF_FeatureHandler_BaseW
59
  throw new \Exception( sprintf( 'A section slug was defined but with no associated strings. Slug: "%s".', $sSectionSlug ) );
60
  }
61
  $aOptionsParams[ 'title' ] = $sTitle;
62
- $aOptionsParams[ 'summary' ] = ( isset( $aSummary ) && is_array( $aSummary ) ) ? $aSummary : array();
63
  $aOptionsParams[ 'title_short' ] = $sTitleShort;
64
  return $aOptionsParams;
65
  }
59
  throw new \Exception( sprintf( 'A section slug was defined but with no associated strings. Slug: "%s".', $sSectionSlug ) );
60
  }
61
  $aOptionsParams[ 'title' ] = $sTitle;
62
+ $aOptionsParams[ 'summary' ] = ( isset( $aSummary ) && is_array( $aSummary ) ) ? $aSummary : [];
63
  $aOptionsParams[ 'title_short' ] = $sTitleShort;
64
  return $aOptionsParams;
65
  }
src/features/traffic.php CHANGED
@@ -48,7 +48,7 @@ class ICWP_WPSF_FeatureHandler_Traffic extends ICWP_WPSF_FeatureHandler_BaseWpsf
48
  * @return array
49
  */
50
  protected function getSectionWarnings( $sSection ) {
51
- $aWarnings = array();
52
 
53
  if ( !$this->isPremium() ) {
54
  $aWarnings[] = sprintf( _wpsf__( '%s is a Pro-only feature.' ), _wpsf__( 'Traffic Watch' ) );
@@ -75,7 +75,7 @@ class ICWP_WPSF_FeatureHandler_Traffic extends ICWP_WPSF_FeatureHandler_BaseWpsf
75
  */
76
  protected function getExclusions() {
77
  $aEx = $this->getOpt( 'type_exclusions' );
78
- return is_array( $aEx ) ? $aEx : array();
79
  }
80
 
81
  /**
@@ -83,7 +83,7 @@ class ICWP_WPSF_FeatureHandler_Traffic extends ICWP_WPSF_FeatureHandler_BaseWpsf
83
  */
84
  public function getCustomExclusions() {
85
  $aEx = $this->getOpt( 'custom_exclusions' );
86
- return is_array( $aEx ) ? $aEx : array();
87
  }
88
 
89
  /**
@@ -229,7 +229,7 @@ class ICWP_WPSF_FeatureHandler_Traffic extends ICWP_WPSF_FeatureHandler_BaseWpsf
229
  throw new \Exception( sprintf( 'A section slug was defined but with no associated strings. Slug: "%s".', $sSectionSlug ) );
230
  }
231
  $aOptionsParams[ 'title' ] = $sTitle;
232
- $aOptionsParams[ 'summary' ] = ( isset( $aSummary ) && is_array( $aSummary ) ) ? $aSummary : array();
233
  $aOptionsParams[ 'title_short' ] = $sTitleShort;
234
  return $aOptionsParams;
235
  }
48
  * @return array
49
  */
50
  protected function getSectionWarnings( $sSection ) {
51
+ $aWarnings = [];
52
 
53
  if ( !$this->isPremium() ) {
54
  $aWarnings[] = sprintf( _wpsf__( '%s is a Pro-only feature.' ), _wpsf__( 'Traffic Watch' ) );
75
  */
76
  protected function getExclusions() {
77
  $aEx = $this->getOpt( 'type_exclusions' );
78
+ return is_array( $aEx ) ? $aEx : [];
79
  }
80
 
81
  /**
83
  */
84
  public function getCustomExclusions() {
85
  $aEx = $this->getOpt( 'custom_exclusions' );
86
+ return is_array( $aEx ) ? $aEx : [];
87
  }
88
 
89
  /**
229
  throw new \Exception( sprintf( 'A section slug was defined but with no associated strings. Slug: "%s".', $sSectionSlug ) );
230
  }
231
  $aOptionsParams[ 'title' ] = $sTitle;
232
+ $aOptionsParams[ 'summary' ] = ( isset( $aSummary ) && is_array( $aSummary ) ) ? $aSummary : [];
233
  $aOptionsParams[ 'title_short' ] = $sTitleShort;
234
  return $aOptionsParams;
235
  }
src/features/user_management.php CHANGED
@@ -390,7 +390,7 @@ class ICWP_WPSF_FeatureHandler_UserManagement extends ICWP_WPSF_FeatureHandler_B
390
 
391
  $aNotices = array(
392
  'title' => _wpsf__( 'Users' ),
393
- 'messages' => array()
394
  );
395
 
396
  { //admin user
@@ -433,7 +433,7 @@ class ICWP_WPSF_FeatureHandler_UserManagement extends ICWP_WPSF_FeatureHandler_B
433
  'title' => _wpsf__( 'User Management' ),
434
  'sub' => _wpsf__( 'Sessions Control & Password Policies' ),
435
  ),
436
- 'key_opts' => array(),
437
  'href_options' => $this->getUrl_AdminPage()
438
  );
439
 
@@ -561,7 +561,7 @@ class ICWP_WPSF_FeatureHandler_UserManagement extends ICWP_WPSF_FeatureHandler_B
561
  throw new \Exception( sprintf( 'A section slug was defined but with no associated strings. Slug: "%s".', $sSectionSlug ) );
562
  }
563
  $aOptionsParams[ 'title' ] = $sTitle;
564
- $aOptionsParams[ 'summary' ] = ( isset( $aSummary ) && is_array( $aSummary ) ) ? $aSummary : array();
565
  $aOptionsParams[ 'title_short' ] = $sTitleShort;
566
  return $aOptionsParams;
567
  }
390
 
391
  $aNotices = array(
392
  'title' => _wpsf__( 'Users' ),
393
+ 'messages' => []
394
  );
395
 
396
  { //admin user
433
  'title' => _wpsf__( 'User Management' ),
434
  'sub' => _wpsf__( 'Sessions Control & Password Policies' ),
435
  ),
436
+ 'key_opts' => [],
437
  'href_options' => $this->getUrl_AdminPage()
438
  );
439
 
561
  throw new \Exception( sprintf( 'A section slug was defined but with no associated strings. Slug: "%s".', $sSectionSlug ) );
562
  }
563
  $aOptionsParams[ 'title' ] = $sTitle;
564
+ $aOptionsParams[ 'summary' ] = ( isset( $aSummary ) && is_array( $aSummary ) ) ? $aSummary : [];
565
  $aOptionsParams[ 'title_short' ] = $sTitleShort;
566
  return $aOptionsParams;
567
  }
src/lib/src/AuditTrail/Auditor.php CHANGED
@@ -19,16 +19,19 @@ trait Auditor {
19
  * @param array $aEventData
20
  * @return EntryVO
21
  */
22
- public function createNewAudit( $sContext, $sMsg, $nCategory = 1, $sEvent = '', $aEventData = array() ) {
23
  $oEntry = new EntryVO();
24
  $oEntry->context = $sContext;
25
  $oEntry->message = $sMsg;
26
  $oEntry->category = $nCategory;
27
  $oEntry->event = $sEvent;
28
  $oEntry->meta = $aEventData;
29
- if ( Services::WpGeneral()->getIsCron() ) {
30
  $oEntry->wp_username = 'WP Cron';
31
  }
 
 
 
32
  do_action( 'icwp-wpsf-add_new_audit_entry', $oEntry );
33
  return $oEntry;
34
  }
19
  * @param array $aEventData
20
  * @return EntryVO
21
  */
22
+ public function createNewAudit( $sContext, $sMsg, $nCategory = 1, $sEvent = '', $aEventData = [] ) {
23
  $oEntry = new EntryVO();
24
  $oEntry->context = $sContext;
25
  $oEntry->message = $sMsg;
26
  $oEntry->category = $nCategory;
27
  $oEntry->event = $sEvent;
28
  $oEntry->meta = $aEventData;
29
+ if ( Services::WpGeneral()->isCron() ) {
30
  $oEntry->wp_username = 'WP Cron';
31
  }
32
+ else if ( Services::WpGeneral()->isWpCli() ) {
33
+ $oEntry->wp_username = 'WP CLI';
34
+ }
35
  do_action( 'icwp-wpsf-add_new_audit_entry', $oEntry );
36
  return $oEntry;
37
  }
src/lib/src/Databases/Base/BaseQuery.php CHANGED
@@ -184,6 +184,18 @@ abstract class BaseQuery {
184
  );
185
  }
186
 
 
 
 
 
 
 
 
 
 
 
 
 
187
  /**
188
  * @return string
189
  */
@@ -227,7 +239,7 @@ abstract class BaseQuery {
227
  */
228
  public function getWheres() {
229
  if ( !is_array( $this->aWheres ) ) {
230
- $this->aWheres = array();
231
  }
232
  return $this->aWheres;
233
  }
@@ -272,7 +284,7 @@ abstract class BaseQuery {
272
  */
273
  public function reset() {
274
  return $this->setLimit( 0 )
275
- ->setWheres( array() )
276
  ->setPage( 1 )
277
  ->setOrderBy( '' );
278
  }
184
  );
185
  }
186
 
187
+ /**
188
+ * @param int $nTs
189
+ * @param string $sComparison
190
+ * @return $this
191
+ */
192
+ public function filterByCreatedAt( $nTs, $sComparison ) {
193
+ if ( !preg_match( '#[^=<>]#', $sComparison ) && is_numeric( $nTs ) ) {
194
+ $this->addWhere( 'created_at', (int)$nTs, $sComparison );
195
+ }
196
+ return $this;
197
+ }
198
+
199
  /**
200
  * @return string
201
  */
239
  */
240
  public function getWheres() {
241
  if ( !is_array( $this->aWheres ) ) {
242
+ $this->aWheres = [];
243
  }
244
  return $this->aWheres;
245
  }
284
  */
285
  public function reset() {
286
  return $this->setLimit( 0 )
287
+ ->setWheres( [] )
288
  ->setPage( 1 )
289
  ->setOrderBy( '' );
290
  }
src/lib/src/Databases/Base/EntryVO.php CHANGED
@@ -45,7 +45,7 @@ class EntryVO {
45
  }
46
 
47
  if ( !is_array( $mVal ) ) {
48
- $mVal = array();
49
  }
50
  break;
51
 
@@ -67,7 +67,7 @@ class EntryVO {
67
 
68
  case 'meta':
69
  if ( !is_array( $mValue ) ) {
70
- $mValue = array();
71
  }
72
  $mValue = base64_encode( json_encode( $mValue ) );
73
  break;
45
  }
46
 
47
  if ( !is_array( $mVal ) ) {
48
+ $mVal = [];
49
  }
50
  break;
51
 
67
 
68
  case 'meta':
69
  if ( !is_array( $mValue ) ) {
70
+ $mValue = [];
71
  }
72
  $mValue = base64_encode( json_encode( $mValue ) );
73
  break;
src/lib/src/Databases/Base/Handler.php CHANGED
@@ -69,14 +69,14 @@ class Handler {
69
  if ( empty( $this->aColActual ) ) {
70
  $this->aColActual = Services::WpDb()->getColumnsForTable( $this->getTable(), 'strtolower' );
71
  }
72
- return is_array( $this->aColActual ) ? $this->aColActual : array();
73
  }
74
 
75
  /**
76
  * @return string[]
77
  */
78
  public function getColumnsDefinition() {
79
- return is_array( $this->aColDef ) ? $this->aColDef : array();
80
  }
81
 
82
  /**
69
  if ( empty( $this->aColActual ) ) {
70
  $this->aColActual = Services::WpDb()->getColumnsForTable( $this->getTable(), 'strtolower' );
71
  }
72
+ return is_array( $this->aColActual ) ? $this->aColActual : [];
73
  }
74
 
75
  /**
76
  * @return string[]
77
  */
78
  public function getColumnsDefinition() {
79
+ return is_array( $this->aColDef ) ? $this->aColDef : [];
80
  }
81
 
82
  /**
src/lib/src/Databases/Base/Insert.php CHANGED
@@ -15,7 +15,7 @@ class Insert extends BaseQuery {
15
  * @return array
16
  */
17
  public function getInsertData() {
18
- $aD = is_array( $this->aInsertData ) ? $this->aInsertData : array();
19
  return array_intersect_key( $aD, array_flip( $this->getDbH()->getColumnsActual() ) );
20
  }
21
 
@@ -34,7 +34,7 @@ class Insert extends BaseQuery {
34
  */
35
  protected function setInsertData( $aData ) {
36
  if ( !is_array( $aData ) ) {
37
- $aData = array();
38
  }
39
  $this->aInsertData = array_intersect_key( $aData, array_flip( $this->getDbH()->getColumnsActual() ) );
40
  return $this;
@@ -48,7 +48,7 @@ class Insert extends BaseQuery {
48
  $aData = $this->getInsertData();
49
 
50
  if ( !is_array( $aData ) ) {
51
- $aData = array();
52
  }
53
  $aData = array_merge(
54
  array( 'created_at' => Services::Request()->ts(), ),
15
  * @return array
16
  */
17
  public function getInsertData() {
18
+ $aD = is_array( $this->aInsertData ) ? $this->aInsertData : [];
19
  return array_intersect_key( $aD, array_flip( $this->getDbH()->getColumnsActual() ) );
20
  }
21
 
34
  */
35
  protected function setInsertData( $aData ) {
36
  if ( !is_array( $aData ) ) {
37
+ $aData = [];
38
  }
39
  $this->aInsertData = array_intersect_key( $aData, array_flip( $this->getDbH()->getColumnsActual() ) );
40
  return $this;
48
  $aData = $this->getInsertData();
49
 
50
  if ( !is_array( $aData ) ) {
51
+ $aData = [];
52
  }
53
  $aData = array_merge(
54
  array( 'created_at' => Services::Request()->ts(), ),
src/lib/src/Databases/Base/Select.php CHANGED
@@ -115,7 +115,7 @@ class Select extends BaseQuery {
115
  * @return array
116
  */
117
  public function getColumnsToSelect() {
118
- return is_array( $this->aColumnsToSelect ) ? $this->aColumnsToSelect : array();
119
  }
120
 
121
  /**
@@ -182,7 +182,7 @@ class Select extends BaseQuery {
182
 
183
  /**
184
  * Handle COUNT, DISTINCT, & normal SELECT
185
- * @return int|string[]|array[]|EntryVO[]
186
  */
187
  public function query() {
188
  if ( $this->isCount() ) {
@@ -196,7 +196,7 @@ class Select extends BaseQuery {
196
  }, $mData );
197
  }
198
  else {
199
- $mData = array();
200
  }
201
  }
202
  else {
115
  * @return array
116
  */
117
  public function getColumnsToSelect() {
118
+ return is_array( $this->aColumnsToSelect ) ? $this->aColumnsToSelect : [];
119
  }
120
 
121
  /**
182
 
183
  /**
184
  * Handle COUNT, DISTINCT, & normal SELECT
185
+ * @return int|string[]|array[]|EntryVO[]|mixed
186
  */
187
  public function query() {
188
  if ( $this->isCount() ) {
196
  }, $mData );
197
  }
198
  else {
199
+ $mData = [];
200
  }
201
  }
202
  else {
src/lib/src/Databases/Base/Update.php CHANGED
@@ -22,7 +22,7 @@ class Update extends Insert {
22
  * @return array
23
  */
24
  public function getUpdateWheres() {
25
- return is_array( $this->aUpdateWheres ) ? $this->aUpdateWheres : array();
26
  }
27
 
28
  /**
@@ -56,7 +56,7 @@ class Update extends Insert {
56
  * @param array $aUpdateData
57
  * @return bool
58
  */
59
- public function updateEntry( $oEntry, $aUpdateData = array() ) {
60
  $bSuccess = false;
61
 
62
  if ( $oEntry instanceof EntryVO ) {
@@ -76,7 +76,7 @@ class Update extends Insert {
76
  * @param array $aUpdateData
77
  * @return bool true is success or no update necessary
78
  */
79
- public function updateById( $nId, $aUpdateData = array() ) {
80
  $bSuccess = true;
81
 
82
  if ( !empty( $aUpdateData ) ) {
22
  * @return array
23
  */
24
  public function getUpdateWheres() {
25
+ return is_array( $this->aUpdateWheres ) ? $this->aUpdateWheres : [];
26
  }
27
 
28
  /**
56
  * @param array $aUpdateData
57
  * @return bool
58
  */
59
+ public function updateEntry( $oEntry, $aUpdateData = [] ) {
60
  $bSuccess = false;
61
 
62
  if ( $oEntry instanceof EntryVO ) {
76
  * @param array $aUpdateData
77
  * @return bool true is success or no update necessary
78
  */
79
+ public function updateById( $nId, $aUpdateData = [] ) {
80
  $bSuccess = true;
81
 
82
  if ( !empty( $aUpdateData ) ) {
src/lib/src/Databases/Session/Update.php CHANGED
@@ -72,7 +72,7 @@ class Update extends Base\Update {
72
  * @param array $aUpdateData
73
  * @return bool
74
  */
75
- public function updateSession( $oSession, $aUpdateData = array() ) {
76
  return parent::updateEntry( $oSession, $aUpdateData );
77
  }
78
  }
72
  * @param array $aUpdateData
73
  * @return bool
74
  */
75
+ public function updateSession( $oSession, $aUpdateData = [] ) {
76
  return parent::updateEntry( $oSession, $aUpdateData );
77
  }
78
  }
src/lib/src/Databases/Tally/Update.php CHANGED
@@ -20,7 +20,7 @@ class Update extends Base\Update {
20
  * @param array $aUpdateData
21
  * @return bool
22
  */
23
- public function updateStat( $oStat, $aUpdateData = array() ) {
24
  return parent::updateEntry( $oStat, $aUpdateData );
25
  }
26
  }
20
  * @param array $aUpdateData
21
  * @return bool
22
  */
23
+ public function updateStat( $oStat, $aUpdateData = [] ) {
24
  return parent::updateEntry( $oStat, $aUpdateData );
25
  }
26
  }
src/lib/src/Modules/IPs/BotTrack/Base.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\BotTrack;
4
+
5
+ use FernleafSystems\Wordpress\Plugin\Shield;
6
+
7
+ abstract class Base {
8
+
9
+ use Shield\AuditTrail\Auditor,
10
+ Shield\Modules\ModConsumer;
11
+ const OPT_KEY = '';
12
+
13
+ public function run() {
14
+ $this->process();
15
+ }
16
+
17
+ protected function doTransgression() {
18
+ /** @var \ICWP_WPSF_FeatureHandler_Ips $oFO */
19
+ $oFO = $this->getMod();
20
+
21
+ if ( $oFO->isTrackOptImmediateBlock( static::OPT_KEY ) ) {
22
+ $oFO->setIpBlocked();
23
+ }
24
+ else if ( $oFO->isTrackOptTransgression( static::OPT_KEY ) ) {
25
+ $oFO->setIpTransgressed( $oFO->isTrackOptDoubleTransgression( static::OPT_KEY ) ? 2 : 1 );
26
+ }
27
+
28
+ $this->writeAudit();
29
+ }
30
+
31
+ /**
32
+ * @return $this
33
+ */
34
+ protected function writeAudit() {
35
+ $this->createNewAudit( 'wpsf', $this->getAuditMsg(), 2, 'bot'.static::OPT_KEY );
36
+ return $this;
37
+ }
38
+
39
+ abstract protected function process();
40
+
41
+ /**
42
+ * @return $this
43
+ */
44
+ abstract protected function getAuditMsg();
45
+ }
src/lib/src/Modules/IPs/BotTrack/Track404.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\BotTrack;
4
+
5
+ use FernleafSystems\Wordpress\Services\Services;
6
+
7
+ class Track404 extends Base {
8
+
9
+ const OPT_KEY = 'track_404';
10
+
11
+ protected function process() {
12
+ add_action( 'template_redirect', function () {
13
+ if ( is_404() ) {
14
+ $this->doTransgression();
15
+ }
16
+ } );
17
+ }
18
+
19
+ /**
20
+ * @return $this
21
+ */
22
+ protected function getAuditMsg() {
23
+ return sprintf( _wpsf__( '404 detected at "%s".' ), Services::Request()->getPath() );
24
+ }
25
+ }
src/lib/src/Modules/{MouseTrap/FakeWebCrawler.php → IPs/BotTrack/TrackFakeWebCrawler.php} RENAMED
@@ -1,14 +1,16 @@
1
  <?php
2
 
3
- namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\MouseTrap;
4
 
5
  use FernleafSystems\Wordpress\Services\Services;
6
 
7
  /**
8
- * Class FakeWebCrawler
9
- * @package FernleafSystems\Wordpress\Plugin\Shield\Modules\MouseTrap
10
  */
11
- class FakeWebCrawler extends Base {
 
 
12
 
13
  protected function process() {
14
  try {
@@ -19,25 +21,11 @@ class FakeWebCrawler extends Base {
19
  }
20
  }
21
 
22
- /**
23
- * @return bool
24
- */
25
- protected function isTransgression() {
26
- /** @var \ICWP_WPSF_FeatureHandler_Mousetrap $oFO */
27
- $oFO = $this->getMod();
28
- return $oFO->isTransgressionFakeWebCrawler();
29
- }
30
-
31
  /**
32
  * @return $this
33
  */
34
- protected function writeAudit() {
35
- $this->createNewAudit(
36
- 'wpsf',
37
- sprintf( _wpsf__( 'Fake Web Crawler detected "%s"' ), Services::Request()->getPath() ),
38
- 2, 'mousetrap_fakecrawler'
39
- );
40
- return $this;
41
  }
42
 
43
  /**
1
  <?php
2
 
3
+ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\BotTrack;
4
 
5
  use FernleafSystems\Wordpress\Services\Services;
6
 
7
  /**
8
+ * Class TrackFakeWebCrawler
9
+ * @package FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\BotTrack
10
  */
11
+ class TrackFakeWebCrawler extends Base {
12
+
13
+ const OPT_KEY = 'track_fakewebcrawler';
14
 
15
  protected function process() {
16
  try {
21
  }
22
  }
23
 
 
 
 
 
 
 
 
 
 
24
  /**
25
  * @return $this
26
  */
27
+ protected function getAuditMsg() {
28
+ return sprintf( _wpsf__( 'Fake Web Crawler detected at "%s".' ), Services::Request()->getPath() );
 
 
 
 
 
29
  }
30
 
31
  /**
src/lib/src/Modules/{MouseTrap/LinkCheese.php → IPs/BotTrack/TrackLinkCheese.php} RENAMED
@@ -1,6 +1,6 @@
1
  <?php
2
 
3
- namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\MouseTrap;
4
 
5
  use FernleafSystems\Wordpress\Plugin\Shield;
6
  use FernleafSystems\Wordpress\Services\Services;
@@ -8,16 +8,18 @@ use FernleafSystems\Wordpress\Services\Services;
8
  /**
9
  * Works by inserting a random, nofollow link to the footer of the page and appending to robots.txt
10
  * Class LinkCheese
11
- * @package FernleafSystems\Wordpress\Plugin\Shield\Modules\MouseTrap
12
  */
13
- class LinkCheese extends Base {
 
 
14
 
15
  protected function process() {
 
 
16
  if ( $this->isCheese() ) {
17
  $this->doTransgression();
18
  }
19
- add_filter( 'robots_txt', array( $this, 'appendRobotsTxt' ), 5 );
20
- add_action( 'wp_footer', array( $this, 'insertMouseTrap' ) );
21
  }
22
 
23
  /**
@@ -34,7 +36,7 @@ class LinkCheese extends Base {
34
  }
35
 
36
  private function isCheese() {
37
- /** @var \ICWP_WPSF_FeatureHandler_Mousetrap $oFO */
38
  $oFO = $this->getMod();
39
  $oReq = Services::Request();
40
 
@@ -60,11 +62,11 @@ class LinkCheese extends Base {
60
  }
61
 
62
  public function insertMouseTrap() {
63
- $sId = 'V'.rand();
64
  echo sprintf(
65
  '<style>#%s{display:none !important;}</style><a rel="nofollow" href="%s" title="%s" id="%s">%s</a>',
66
  $sId, $this->buildTrapHref(), 'Click here to see something fantastic',
67
- $sId, _wpsf__( 'Click to access the login or register cheese' )
68
  );
69
  }
70
 
@@ -72,12 +74,12 @@ class LinkCheese extends Base {
72
  * @return string
73
  */
74
  private function buildTrapHref() {
75
- /** @var \ICWP_WPSF_FeatureHandler_Mousetrap $oFO */
76
  $oFO = $this->getMod();
77
 
78
  $oWp = Services::WpGeneral();
79
  $sKey = substr( md5( wp_generate_password() ), 5, rand( 7, 9 ) );
80
- $sWord = $this->getPossibleWords()[ rand( 0, count( $this->getPossibleWords() ) ) ];
81
  if ( $oWp->isPermalinksEnabled() ) {
82
  $sLink = $oWp->getHomeUrl( sprintf( '/%s-%s/', $oFO->prefix( $sWord ), $sKey ) );
83
  }
@@ -87,25 +89,11 @@ class LinkCheese extends Base {
87
  return $sLink;
88
  }
89
 
90
- /**
91
- * @return bool
92
- */
93
- protected function isTransgression() {
94
- /** @var \ICWP_WPSF_FeatureHandler_Mousetrap $oFO */
95
- $oFO = $this->getMod();
96
- return $oFO->isTransgressionLinkCheese();
97
- }
98
-
99
  /**
100
  * @return $this
101
  */
102
- protected function writeAudit() {
103
- $this->createNewAudit(
104
- 'wpsf',
105
- sprintf( _wpsf__( 'Link cheese access detected at "%s"' ), Services::Request()->getPath() ),
106
- 2, 'mousetrap_linkcheese'
107
- );
108
- return $this;
109
  }
110
 
111
  /**
@@ -118,6 +106,7 @@ class LinkCheese extends Base {
118
  'venus',
119
  'stilton',
120
  'cheddar',
 
121
  ];
122
  }
123
  }
1
  <?php
2
 
3
+ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\BotTrack;
4
 
5
  use FernleafSystems\Wordpress\Plugin\Shield;
6
  use FernleafSystems\Wordpress\Services\Services;
8
  /**
9
  * Works by inserting a random, nofollow link to the footer of the page and appending to robots.txt
10
  * Class LinkCheese
11
+ * @package FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\BotTrack
12
  */
13
+ class TrackLinkCheese extends Base {
14
+
15
+ const OPT_KEY = 'track_linkcheese';
16
 
17
  protected function process() {
18
+ add_filter( 'robots_txt', array( $this, 'appendRobotsTxt' ), 5 );
19
+ add_action( 'wp_footer', array( $this, 'insertMouseTrap' ), 0 );
20
  if ( $this->isCheese() ) {
21
  $this->doTransgression();
22
  }
 
 
23
  }
24
 
25
  /**
36
  }
37
 
38
  private function isCheese() {
39
+ /** @var \ICWP_WPSF_FeatureHandler_Ips $oFO */
40
  $oFO = $this->getMod();
41
  $oReq = Services::Request();
42
 
62
  }
63
 
64
  public function insertMouseTrap() {
65
+ $sId = chr( rand( 97, 122 ) ).rand(1000,10000000);
66
  echo sprintf(
67
  '<style>#%s{display:none !important;}</style><a rel="nofollow" href="%s" title="%s" id="%s">%s</a>',
68
  $sId, $this->buildTrapHref(), 'Click here to see something fantastic',
69
+ $sId, 'Click to access the login or register cheese'
70
  );
71
  }
72
 
74
  * @return string
75
  */
76
  private function buildTrapHref() {
77
+ /** @var \ICWP_WPSF_FeatureHandler_Ips $oFO */
78
  $oFO = $this->getMod();
79
 
80
  $oWp = Services::WpGeneral();
81
  $sKey = substr( md5( wp_generate_password() ), 5, rand( 7, 9 ) );
82
+ $sWord = $this->getPossibleWords()[ rand( 1, count( $this->getPossibleWords() ) ) - 1 ];
83
  if ( $oWp->isPermalinksEnabled() ) {
84
  $sLink = $oWp->getHomeUrl( sprintf( '/%s-%s/', $oFO->prefix( $sWord ), $sKey ) );
85
  }
89
  return $sLink;
90
  }
91
 
 
 
 
 
 
 
 
 
 
92
  /**
93
  * @return $this
94
  */
95
+ protected function getAuditMsg() {
96
+ return sprintf( _wpsf__( 'Link cheese access detected at "%s".' ), Services::Request()->getPath() );
 
 
 
 
 
97
  }
98
 
99
  /**
106
  'venus',
107
  'stilton',
108
  'cheddar',
109
+ 'holey',
110
  ];
111
  }
112
  }
src/lib/src/Modules/IPs/BotTrack/TrackLoginFailed.php ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\BotTrack;
4
+
5
+ use FernleafSystems\Wordpress\Services\Services;
6
+
7
+ class TrackLoginFailed extends Base {
8
+
9
+ const OPT_KEY = 'track_loginfailed';
10
+
11
+ /**
12
+ * @var string
13
+ */
14
+ private $user_login;
15
+
16
+ protected function process() {
17
+ add_filter( 'authenticate',
18
+ /**
19
+ * @param null|\WP_User|\WP_Error $oUser
20
+ * @param string $sLogin
21
+ * @param string $sPass
22
+ * @return null|\WP_User|\WP_Error
23
+ */
24
+ function ( $oUser, $sLogin, $sPass ) {
25
+ if ( is_wp_error( $oUser ) && !empty( $sLogin )
26
+ && !empty( $sPass ) && Services::WpUsers()->exists( $sLogin ) ) {
27
+ $this->user_login = Services::Data()->validEmail( $sLogin ) ? $sLogin : sanitize_user( $sLogin );
28
+ $this->doTransgression();
29
+
30
+ // Adds an extra message to login failed
31
+ $oUser->add(
32
+ $this->getMod()->prefix( 'transgression-warning' ),
33
+ $this->getMod()->getTextOpt( 'text_loginfailed' )
34
+ );
35
+ }
36
+ return $oUser;
37
+ },
38
+ 21, 3 ); //right after username/password check
39
+ }
40
+
41
+ /**
42
+ * @return $this
43
+ */
44
+ protected function getAuditMsg() {
45
+ return sprintf( _wpsf__( 'Attempted login failed by user "%s".' ), $this->user_login );
46
+ }
47
+ }
src/lib/src/Modules/IPs/BotTrack/TrackLoginInvalid.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\BotTrack;
4
+
5
+ use FernleafSystems\Wordpress\Services\Services;
6
+
7
+ class TrackLoginInvalid extends Base {
8
+
9
+ const OPT_KEY = 'track_logininvalid';
10
+
11
+ /**
12
+ * @var string
13
+ */
14
+ private $user_login;
15
+
16
+ protected function process() {
17
+ add_filter( 'authenticate',
18
+ /**
19
+ * @param null|\WP_User|\WP_Error $oUser
20
+ * @param string $sLogin
21
+ * @return null|\WP_User|\WP_Error
22
+ */
23
+ function ( $oUser, $sLogin ) {
24
+ if ( !empty( $sLogin ) && !Services::WpUsers()->exists( $sLogin ) ) {
25
+ $this->user_login = Services::Data()->validEmail( $sLogin ) ? $sLogin : sanitize_user( $sLogin );
26
+ $this->doTransgression();
27
+ }
28
+ return $oUser;
29
+ },
30
+ 5, 2 );
31
+ }
32
+
33
+ /**
34
+ * @return $this
35
+ */
36
+ protected function getAuditMsg() {
37
+ return sprintf( _wpsf__( 'Attempted login with invalid user "%s".' ), $this->user_login );
38
+ }
39
+ }
src/lib/src/Modules/IPs/BotTrack/TrackUserAgent.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\BotTrack;
4
+
5
+ use FernleafSystems\Wordpress\Services\Services;
6
+
7
+ class TrackUserAgent extends Base {
8
+
9
+ const OPT_KEY = 'track_useragent';
10
+
11
+ protected function process() {
12
+ if ( strlen( Services::Request()->getUserAgent() ) === 0 ) {
13
+ $this->doTransgression();
14
+ }
15
+ }
16
+
17
+ /**
18
+ * @return $this
19
+ */
20
+ protected function getAuditMsg() {
21
+ return sprintf( _wpsf__( 'Empty user agent detected at "%s".' ), Services::Request()->getPath() );
22
+ }
23
+ }
src/lib/src/Modules/IPs/BotTrack/TrackXmlRpc.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\BotTrack;
4
+
5
+ use FernleafSystems\Wordpress\Services\Services;
6
+
7
+ class TrackXmlRpc extends Base {
8
+
9
+ const OPT_KEY = 'track_xmlrpc';
10
+
11
+ protected function process() {
12
+ if ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST
13
+ || preg_match( '#/xmlrpc\.php#', Services::Request()->getPath() ) ) {
14
+ $this->doTransgression();
15
+ }
16
+ }
17
+
18
+ /**
19
+ * @return $this
20
+ */
21
+ protected function getAuditMsg() {
22
+ return sprintf( _wpsf__( 'Access to XML-RPC detected at "%s".' ), Services::Request()->getPath() );
23
+ }
24
+ }
src/lib/src/Modules/MouseTrap/Base.php DELETED
@@ -1,44 +0,0 @@
1
- <?php
2
-
3
- namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\MouseTrap;
4
-
5
- use FernleafSystems\Wordpress\Plugin\Shield;
6
- use FernleafSystems\Wordpress\Services\Services;
7
-
8
- abstract class Base {
9
-
10
- use Shield\AuditTrail\Auditor,
11
- Shield\Modules\ModConsumer;
12
-
13
- public function run() {
14
- add_action( 'init', [ $this, 'onWpInit' ] );
15
- }
16
-
17
- public function onWpInit() {
18
- if ( !Services::WpUsers()->isUserLoggedIn() ) {
19
- $this->process();
20
- }
21
- }
22
-
23
- protected function process() {
24
- }
25
-
26
- protected function doTransgression() {
27
- /** @var \ICWP_WPSF_FeatureHandler_Mousetrap $oFO */
28
- $oFO = $this->getMod();
29
- if ( !$oFO->isVerifiedBot() ) {
30
- $this->isTransgression() ? $oFO->setIpTransgressed() : $oFO->setIpBlocked();
31
- $this->writeAudit();
32
- }
33
- }
34
-
35
- /**
36
- * @return bool
37
- */
38
- abstract protected function isTransgression();
39
-
40
- /**
41
- * @return $this
42
- */
43
- abstract protected function writeAudit();
44
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/src/Modules/MouseTrap/Detect404.php DELETED
@@ -1,34 +0,0 @@
1
- <?php
2
-
3
- namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\MouseTrap;
4
-
5
- use FernleafSystems\Wordpress\Services\Services;
6
-
7
- class Detect404 extends Base {
8
-
9
- protected function process() {
10
- add_action( 'template_redirect', function () {
11
- if ( is_404() ) {
12
- $this->doTransgression();
13
- }
14
- } );
15
- }
16
-
17
- protected function isTransgression() {
18
- /** @var \ICWP_WPSF_FeatureHandler_Mousetrap $oFO */
19
- $oFO = $this->getMod();
20
- return $oFO->isTransgression404();
21
- }
22
-
23
- /**
24
- * @return $this
25
- */
26
- protected function writeAudit() {
27
- $this->createNewAudit(
28
- 'wpsf',
29
- sprintf( _wpsf__( '404 detected at "%s"' ), Services::Request()->getPath() ),
30
- 2, 'mousetrap_404'
31
- );
32
- return $this;
33
- }
34
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/src/Modules/MouseTrap/DetectXmlRpc.php DELETED
@@ -1,36 +0,0 @@
1
- <?php
2
-
3
- namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\MouseTrap;
4
-
5
- use FernleafSystems\Wordpress\Services\Services;
6
-
7
- class DetectXmlRpc extends Base {
8
-
9
- protected function process() {
10
- if ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST
11
- || preg_match( '#/xmlrpc\.php#', Services::Request()->getPath() ) ) {
12
- $this->doTransgression();
13
- }
14
- }
15
-
16
- /**
17
- * @return bool
18
- */
19
- protected function isTransgression() {
20
- /** @var \ICWP_WPSF_FeatureHandler_Mousetrap $oFO */
21
- $oFO = $this->getMod();
22
- return $oFO->isTransgressionXmlRpc();
23
- }
24
-
25
- /**
26
- * @return $this
27
- */
28
- protected function writeAudit() {
29
- $this->createNewAudit(
30
- 'wpsf',
31
- sprintf( _wpsf__( 'Attempt to access XML-RPC detected at "%s"' ), Services::Request()->getPath() ),
32
- 2, 'mousetrap_xmlrpc'
33
- );
34
- return $this;
35
- }
36
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/src/Modules/MouseTrap/InvalidUsername.php DELETED
@@ -1,55 +0,0 @@
1
- <?php
2
-
3
- namespace FernleafSystems\Wordpress\Plugin\Shield\Modules\MouseTrap;
4
-
5
- use FernleafSystems\Wordpress\Services\Services;
6
-
7
- class InvalidUsername extends Base {
8
-
9
- protected function process() {
10
- add_filter( 'authenticate',
11
- /**
12
- * @param null|\WP_User|\WP_Error $oUser
13
- * @param $sUsernameEmail
14
- * @return null|\WP_User|\WP_Error
15
- */
16
- function ( $oUser, $sUsernameEmail ) {
17
- if ( !empty( $sUsernameEmail ) && !$this->userExists( $sUsernameEmail ) ) {
18
- $this->doTransgression();
19
- }
20
- return $oUser;
21
- },
22
- 5, 2 );
23
- }
24
-
25
- /**
26
- * @return bool
27
- */
28
- protected function isTransgression() {
29
- /** @var \ICWP_WPSF_FeatureHandler_Mousetrap $oFO */
30
- $oFO = $this->getMod();
31
- return $oFO->isTransgressionInvalidUsernames();
32
- }
33
-
34
- /**
35
- * @return $this
36
- */
37
- protected function writeAudit() {
38
- $this->createNewAudit(
39
- 'wpsf',
40
- sprintf( _wpsf__( 'Attempted login by invalid username "%s"' ), Services::Request()->getPath() ),
41
- 2, 'mousetrap_invaliduser'
42
- );
43
- return $this;
44
- }
45
-
46
- /**
47
- * @param string $sUsernameEmail
48
- * @return bool
49
- */
50
- private function userExists( $sUsernameEmail ) {
51
- $oWpUsers = Services::WpUsers();
52
- return ( $oWpUsers->getUserByEmail( $sUsernameEmail ) instanceof \WP_User )
53
- || ( $oWpUsers->getUserByUsername( $sUsernameEmail ) instanceof \WP_User );
54
- }
55
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/src/Scans/Apc/ResultsSet.php CHANGED
@@ -53,7 +53,7 @@ class ResultsSet extends Base\BaseResultsSet {
53
  * @return ResultsSet[]
54
  */
55
  public function getAllResultsSetsForContext( $sContext ) {
56
- $aCollection = array();
57
  foreach ( $this->getAllResultsSetsForUniqueSlugs() as $sSlug => $oRS ) {
58
  if ( $oRS->getItems()[ 0 ]->context == $sContext ) {
59
  $aCollection[ $sSlug ] = $oRS;
@@ -66,7 +66,7 @@ class ResultsSet extends Base\BaseResultsSet {
66
  * @return ResultsSet[]
67
  */
68
  public function getAllResultsSetsForUniqueSlugs() {
69
- $aCollection = array();
70
  foreach ( $this->getUniqueSlugs() as $sSlug ) {
71
  $oRS = $this->getResultsSetForSlug( $sSlug );
72
  if ( $oRS->hasItems() ) {
53
  * @return ResultsSet[]
54
  */
55
  public function getAllResultsSetsForContext( $sContext ) {
56
+ $aCollection = [];
57
  foreach ( $this->getAllResultsSetsForUniqueSlugs() as $sSlug => $oRS ) {
58
  if ( $oRS->getItems()[ 0 ]->context == $sContext ) {
59
  $aCollection[ $sSlug ] = $oRS;
66
  * @return ResultsSet[]
67
  */
68
  public function getAllResultsSetsForUniqueSlugs() {
69
+ $aCollection = [];
70
  foreach ( $this->getUniqueSlugs() as $sSlug ) {
71
  $oRS = $this->getResultsSetForSlug( $sSlug );
72
  if ( $oRS->hasItems() ) {
src/lib/src/Scans/Apc/Scanner.php CHANGED
@@ -90,7 +90,6 @@ class Scanner {
90
  $nLastUpdateAt = strtotime( $oApi->last_updated );
91
  if ( Services::Request()->ts() - $nLastUpdateAt > $this->getAbandonedLimit() ) {
92
  $nTime = $nLastUpdateAt;
93
- var_dump( $nTime );
94
  }
95
  }
96
 
@@ -102,7 +101,7 @@ class Scanner {
102
  * @return WpVulnVO[]
103
  */
104
  private function getThemeVulnerabilities( $sSlug ) {
105
- $aVulns = array();
106
  $oWpThemes = Services::WpThemes();
107
 
108
  try {
90
  $nLastUpdateAt = strtotime( $oApi->last_updated );
91
  if ( Services::Request()->ts() - $nLastUpdateAt > $this->getAbandonedLimit() ) {
92
  $nTime = $nLastUpdateAt;
 
93
  }
94
  }
95
 
101
  * @return WpVulnVO[]
102
  */
103
  private function getThemeVulnerabilities( $sSlug ) {
104
+ $aVulns = [];
105
  $oWpThemes = Services::WpThemes();
106
 
107
  try {
src/lib/src/Scans/Base/BaseConvertResultsToVos.php CHANGED
@@ -15,7 +15,7 @@ abstract class BaseConvertResultsToVos {
15
  * @return Scanner\EntryVO[]
16
  */
17
  public function convert( $oResults ) {
18
- $aVos = array();
19
  foreach ( $oResults->getAllItems() as $oIt ) {
20
  /** @var BaseResultItem $oIt */
21
  $aVos[ $oIt->generateHash() ] = $this->convertItem( $oIt );
15
  * @return Scanner\EntryVO[]
16
  */
17
  public function convert( $oResults ) {
18
+ $aVos = [];
19
  foreach ( $oResults->getAllItems() as $oIt ) {
20
  /** @var BaseResultItem $oIt */
21
  $aVos[ $oIt->generateHash() ] = $this->convertItem( $oIt );
src/lib/src/Scans/Base/BaseResultsSet.php CHANGED
@@ -54,7 +54,7 @@ class BaseResultsSet {
54
  */
55
  public function getAllItems() {
56
  if ( !is_array( $this->aItems ) ) {
57
- $this->aItems = array();
58
  }
59
  return $this->aItems;
60
  }
54
  */
55
  public function getAllItems() {
56
  if ( !is_array( $this->aItems ) ) {
57
+ $this->aItems = [];
58
  }
59
  return $this->aItems;
60
  }
src/lib/src/Scans/Helpers/BuildHashesFromDir.php CHANGED
@@ -16,7 +16,7 @@ class BuildHashesFromDir {
16
  /**
17
  * @var string[]
18
  */
19
- protected $aFileExts = array();
20
 
21
  /**
22
  * All file keys are their normalised file paths, with the ABSPATH stripped from it.
@@ -24,7 +24,7 @@ class BuildHashesFromDir {
24
  * @return string[]
25
  */
26
  public function build( $sDir ) {
27
- $aSnaps = array();
28
  try {
29
  $oDirIt = StandardDirectoryIterator::create( $sDir, $this->nDepth, $this->aFileExts );
30
  foreach ( $oDirIt as $oFile ) {
16
  /**
17
  * @var string[]
18
  */
19
+ protected $aFileExts = [];
20
 
21
  /**
22
  * All file keys are their normalised file paths, with the ABSPATH stripped from it.
24
  * @return string[]
25
  */
26
  public function build( $sDir ) {
27
+ $aSnaps = [];
28
  try {
29
  $oDirIt = StandardDirectoryIterator::create( $sDir, $this->nDepth, $this->aFileExts );
30
  foreach ( $oDirIt as $oFile ) {
src/lib/src/Scans/Helpers/ScannerRecursiveFilterIterator.php CHANGED
@@ -42,7 +42,7 @@ class ScannerRecursiveFilterIterator extends \RecursiveFilterIterator {
42
  * @return string[]
43
  */
44
  private function getFileExts() {
45
- return is_array( self::$aFileExts ) ? self::$aFileExts : array();
46
  }
47
 
48
  /**
42
  * @return string[]
43
  */
44
  private function getFileExts() {
45
+ return is_array( self::$aFileExts ) ? self::$aFileExts : [];
46
  }
47
 
48
  /**
src/lib/src/Scans/Helpers/StandardDirectoryIterator.php CHANGED
@@ -16,7 +16,7 @@ class StandardDirectoryIterator {
16
  * @return \RecursiveIteratorIterator
17
  * @throws \Exception
18
  */
19
- static public function create( $sDir, $nMaxDepth = 0, $aFileExts = array(), $bExcludeCoreFiles = false ) {
20
 
21
  $oDirIterator = new \RecursiveDirectoryIterator( $sDir );
22
  if ( method_exists( $oDirIterator, 'setFlags' ) ) {
16
  * @return \RecursiveIteratorIterator
17
  * @throws \Exception
18
  */
19
+ static public function create( $sDir, $nMaxDepth = 0, $aFileExts = [], $bExcludeCoreFiles = false ) {
20
 
21
  $oDirIterator = new \RecursiveDirectoryIterator( $sDir );
22
  if ( method_exists( $oDirIterator, 'setFlags' ) ) {
src/lib/src/Scans/Ptg/ResultsSet.php CHANGED
@@ -73,7 +73,7 @@ class ResultsSet extends Base\BaseResultsSet {
73
  * @return ResultsSet[]
74
  */
75
  public function getAllResultsSetsForUniqueSlugs() {
76
- $aCollection = array();
77
  foreach ( $this->getUniqueSlugs() as $sSlug ) {
78
  $oRS = $this->getResultsSetForSlug( $sSlug );
79
  if ( $oRS->hasItems() ) {
@@ -136,7 +136,7 @@ class ResultsSet extends Base\BaseResultsSet {
136
  * @return ResultsSet[]
137
  */
138
  public function getAllResultsSetsForContext( $sContext ) {
139
- $aCollection = array();
140
  foreach ( $this->getAllResultsSetsForUniqueSlugs() as $sSlug => $oRS ) {
141
  if ( $oRS->getItems()[ 0 ]->context == $sContext ) {
142
  $aCollection[ $sSlug ] = $oRS;
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() ) {
136
  * @return ResultsSet[]
137
  */
138
  public function getAllResultsSetsForContext( $sContext ) {
139
+ $aCollection = [];
140
  foreach ( $this->getAllResultsSetsForUniqueSlugs() as $sSlug => $oRS ) {
141
  if ( $oRS->getItems()[ 0 ]->context == $sContext ) {
142
  $aCollection[ $sSlug ] = $oRS;
src/lib/src/Scans/Ptg/ScanAssetDir.php CHANGED
@@ -18,7 +18,7 @@ class ScanAssetDir {
18
  /**
19
  * @var string[]
20
  */
21
- protected $aFileExts = array();
22
 
23
  /**
24
  * @param string $sRootDir
18
  /**
19
  * @var string[]
20
  */
21
+ protected $aFileExts = [];
22
 
23
  /**
24
  * @param string $sRootDir
src/lib/src/Scans/Ptg/ScannerBase.php CHANGED
@@ -20,7 +20,7 @@ abstract class ScannerBase {
20
  /**
21
  * @var string[]
22
  */
23
- protected $aFileExts = array();
24
 
25
  /**
26
  * @param array[] $aPreExistingHashes - key is the slug/base-file name and value is the file hashes
20
  /**
21
  * @var string[]
22
  */
23
+ protected $aFileExts = [];
24
 
25
  /**
26
  * @param array[] $aPreExistingHashes - key is the slug/base-file name and value is the file hashes
src/lib/src/Scans/Ptg/Snapshots/Store.php CHANGED
@@ -35,7 +35,7 @@ class Store {
35
  if ( !is_array( $this->aSnapData ) ) {
36
  $this->loadSnapDataIfExists();
37
  }
38
- return is_array( $this->aSnapData ) ? $this->aSnapData : array();
39
  }
40
 
41
  /**
@@ -64,7 +64,7 @@ class Store {
64
  * @return $this
65
  */
66
  public function clearSnapshots() {
67
- $this->aSnapData = array();
68
  return $this;
69
  }
70
 
@@ -132,7 +132,7 @@ class Store {
132
  $this->aSnapData = $this->readSnapData();
133
  }
134
  catch ( \Exception $oE ) {
135
- $this->aSnapData = array();
136
  }
137
  return $this;
138
  }
35
  if ( !is_array( $this->aSnapData ) ) {
36
  $this->loadSnapDataIfExists();
37
  }
38
+ return is_array( $this->aSnapData ) ? $this->aSnapData : [];
39
  }
40
 
41
  /**
64
  * @return $this
65
  */
66
  public function clearSnapshots() {
67
+ $this->aSnapData = [];
68
  return $this;
69
  }
70
 
132
  $this->aSnapData = $this->readSnapData();
133
  }
134
  catch ( \Exception $oE ) {
135
+ $this->aSnapData = [];
136
  }
137
  return $this;
138
  }
src/lib/src/Scans/Realtime/Files/Backup.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Realtime\Files;
4
+
5
+ use FernleafSystems\Wordpress\Services;
6
+
7
+ /**
8
+ * Class Backup
9
+ * @package FernleafSystems\Wordpress\Plugin\Shield\Scans\WpConfig
10
+ */
11
+ class Backup {
12
+
13
+ /**
14
+ * @param string $sOriginalPath
15
+ * @param string $sBackupPath
16
+ * @param string $sPubKey
17
+ * @return bool
18
+ * @throws \Exception
19
+ */
20
+ public function run( $sOriginalPath, $sBackupPath, $sPubKey ) {
21
+ $sCont = Services\Services::WpFs()->getFileContent( $sOriginalPath );
22
+ if ( empty( $sCont ) ) {
23
+ throw new \Exception( 'WP Config contents were empty' );
24
+ }
25
+ return ( new Services\Utilities\File\WriteDataToFileEncrypted() )->run( $sBackupPath, $sCont, $sPubKey );
26
+ }
27
+ }
src/lib/src/Scans/Realtime/Files/Process.php ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Realtime\Files;
4
+
5
+ use FernleafSystems\Utilities\Data\Adapter\StdClassAdapter;
6
+ use FernleafSystems\Wordpress\Services\Services;
7
+
8
+ /**
9
+ * Class Process
10
+ * @package FernleafSystems\Wordpress\Plugin\Shield\Scans\WpConfig
11
+ * @property string $priv_key
12
+ * @property string $backup_dir
13
+ * @property string $backup_file
14
+ * @property string $original_path
15
+ * @property string $original_path_hash
16
+ */
17
+ class Process {
18
+
19
+ use StdClassAdapter;
20
+
21
+ /**
22
+ * @return bool
23
+ * @throws \Exception
24
+ */
25
+ public function run() {
26
+ $oFs = Services::WpFs();
27
+
28
+ if ( empty( $this->backup_file ) ) {
29
+ // we haven't created a backup yet.
30
+ $this->createBackup();
31
+ }
32
+ else if ( !$oFs->isFile( $this->getFullBackupPath() ) ) {
33
+ throw new \Exception( 'Backup file is missing', 1 );
34
+ }
35
+ else if ( !( new Verify() )->run( $this->original_path, $this->original_path_hash ) ) {
36
+ ( new Revert() )->run( $this->original_path, $this->getFullBackupPath(), $this->priv_key );
37
+ }
38
+
39
+ return true;
40
+ }
41
+
42
+ /**
43
+ * @return bool
44
+ * @throws \Exception
45
+ */
46
+ protected function createBackup() {
47
+ $this->backup_file = '.shieldbak-'.wp_rand( 1000, 999999 );
48
+
49
+ if ( !( new TestWritable() )->run( $this->original_path ) ) {
50
+ throw new \Exception( 'Cannot write to path: '.$this->original_path, 2 );
51
+ }
52
+
53
+ try {
54
+ $bSuccess = ( new Backup() )->run(
55
+ Services::WpGeneral()->getPath_WpConfig(),
56
+ $this->getFullBackupPath(),
57
+ Services::Encrypt()->getPublicKeyFromPrivateKey( $this->priv_key )
58
+ );
59
+ if ( $bSuccess ) {
60
+ $this->original_path_hash = sha1_file( Services::WpGeneral()->getPath_WpConfig() );
61
+ }
62
+ }
63
+ catch ( \Exception $oE ) {
64
+ throw new \Exception( $oE->getMessage(), 3 );
65
+ }
66
+ return $bSuccess;
67
+ }
68
+
69
+ /**
70
+ * @return string
71
+ */
72
+ protected function getFullBackupPath() {
73
+ return path_join( $this->backup_dir, $this->backup_file );
74
+ }
75
+ }
src/lib/src/Scans/Realtime/Files/Revert.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Realtime\Files;
4
+
5
+ use FernleafSystems\Wordpress\Services\Services;
6
+ use FernleafSystems\Wordpress\Services\Utilities\File\ReadDataFromFileEncrypted;
7
+
8
+ /**
9
+ * Class Revert
10
+ * @package FernleafSystems\Wordpress\Plugin\Shield\Scans\WpConfig
11
+ */
12
+ class Revert {
13
+
14
+ /**
15
+ * @param string $sOriginalPath
16
+ * @param string $sBackupFilePath
17
+ * @param string $sPrivateKey
18
+ * @return bool
19
+ */
20
+ public function run( $sOriginalPath, $sBackupFilePath, $sPrivateKey ) {
21
+ $bSuccess = false;
22
+ try {
23
+ $sData = ( new ReadDataFromFileEncrypted() )->run( $sBackupFilePath, $sPrivateKey );
24
+ if ( !empty( $sData ) ) {
25
+ $bSuccess = Services::WpFs()->putFileContent( $sOriginalPath, $sData );
26
+ }
27
+ }
28
+ catch ( \Exception $oE ) {
29
+ }
30
+
31
+ return $bSuccess;
32
+ }
33
+ }
src/lib/src/Scans/Realtime/Files/TestWritable.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Realtime\Files;
4
+
5
+ use FernleafSystems\Wordpress\Services\Utilities\File\TestFileWritable;
6
+
7
+ /**
8
+ * Class TestWritable
9
+ * @package FernleafSystems\Wordpress\Plugin\Shield\Scans\WpConfig
10
+ */
11
+ class TestWritable {
12
+
13
+ /**
14
+ * @param string $sPath
15
+ * @return bool
16
+ */
17
+ public function run( $sPath ) {
18
+ try {
19
+ $bCan = ( new TestFileWritable() )->run( $sPath );
20
+ }
21
+ catch ( \Exception $oE ) {
22
+ $bCan = false;
23
+ }
24
+ return $bCan;
25
+ }
26
+ }
src/lib/src/Scans/Realtime/Files/Verify.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Realtime\Files;
4
+
5
+ /**
6
+ * Class Verify
7
+ * @package FernleafSystems\Wordpress\Plugin\Shield\Scans\WpConfig
8
+ */
9
+ class Verify {
10
+
11
+ /**
12
+ * @param string $sPath
13
+ * @param string $sHash
14
+ * @return bool
15
+ */
16
+ public function run( $sPath, $sHash ) {
17
+ return sha1_file( $sPath ) === $sHash;
18
+ }
19
+ }
src/lib/src/Scans/Ufc/Scanner.php CHANGED
@@ -121,7 +121,7 @@ class Scanner {
121
  */
122
  protected function getDirFileTypes() {
123
  if ( !is_array( $this->aDirFileTypes ) ) {
124
- $this->aDirFileTypes = array();
125
  }
126
  return $this->aDirFileTypes;
127
  }
@@ -130,7 +130,7 @@ class Scanner {
130
  * @return array
131
  */
132
  public function getExclusions() {
133
- return is_array( $this->aExclusions ) ? $this->aExclusions : array();
134
  }
135
 
136
  /**
@@ -139,7 +139,7 @@ class Scanner {
139
  */
140
  public function getFileTypesForDir( $sDir ) {
141
  $aEx = $this->getDirFileTypes();
142
- return isset( $aEx[ $sDir ] ) ? $aEx[ $sDir ] : array();
143
  }
144
 
145
  /**
121
  */
122
  protected function getDirFileTypes() {
123
  if ( !is_array( $this->aDirFileTypes ) ) {
124
+ $this->aDirFileTypes = [];
125
  }
126
  return $this->aDirFileTypes;
127
  }
130
  * @return array
131
  */
132
  public function getExclusions() {
133
+ return is_array( $this->aExclusions ) ? $this->aExclusions : [];
134
  }
135
 
136
  /**
139
  */
140
  public function getFileTypesForDir( $sDir ) {
141
  $aEx = $this->getDirFileTypes();
142
+ return isset( $aEx[ $sDir ] ) ? $aEx[ $sDir ] : [];
143
  }
144
 
145
  /**
src/lib/src/Scans/Wpv/ResultsSet.php CHANGED
@@ -53,7 +53,7 @@ class ResultsSet extends Base\BaseResultsSet {
53
  * @return ResultsSet[]
54
  */
55
  public function getAllResultsSetsForContext( $sContext ) {
56
- $aCollection = array();
57
  foreach ( $this->getAllResultsSetsForUniqueSlugs() as $sSlug => $oRS ) {
58
  if ( $oRS->getItems()[ 0 ]->context == $sContext ) {
59
  $aCollection[ $sSlug ] = $oRS;
@@ -66,7 +66,7 @@ class ResultsSet extends Base\BaseResultsSet {
66
  * @return ResultsSet[]
67
  */
68
  public function getAllResultsSetsForUniqueSlugs() {
69
- $aCollection = array();
70
  foreach ( $this->getUniqueSlugs() as $sSlug ) {
71
  $oRS = $this->getResultsSetForSlug( $sSlug );
72
  if ( $oRS->hasItems() ) {
53
  * @return ResultsSet[]
54
  */
55
  public function getAllResultsSetsForContext( $sContext ) {
56
+ $aCollection = [];
57
  foreach ( $this->getAllResultsSetsForUniqueSlugs() as $sSlug => $oRS ) {
58
  if ( $oRS->getItems()[ 0 ]->context == $sContext ) {
59
  $aCollection[ $sSlug ] = $oRS;
66
  * @return ResultsSet[]
67
  */
68
  public function getAllResultsSetsForUniqueSlugs() {
69
+ $aCollection = [];
70
  foreach ( $this->getUniqueSlugs() as $sSlug ) {
71
  $oRS = $this->getResultsSetForSlug( $sSlug );
72
  if ( $oRS->hasItems() ) {
src/lib/src/Scans/Wpv/Scanner.php CHANGED
@@ -47,7 +47,7 @@ class Scanner {
47
  * @return WpVulnVO[][]
48
  */
49
  protected function getAllPluginVulnerabilities() {
50
- $aVulns = array();
51
  foreach ( Services::WpPlugins()->getInstalledPluginFiles() as $sFile ) {
52
  $aVulns[ $sFile ] = $this->getPluginVulnerabilities( $sFile );
53
  }
@@ -58,7 +58,7 @@ class Scanner {
58
  * @return WpVulnVO[][]
59
  */
60
  protected function getAllThemeVulnerabilities() {
61
- $aVulns = array();
62
  $oWpThemes = Services::WpThemes();
63
 
64
  $oActiveTheme = $oWpThemes->getCurrent();
47
  * @return WpVulnVO[][]
48
  */
49
  protected function getAllPluginVulnerabilities() {
50
+ $aVulns = [];
51
  foreach ( Services::WpPlugins()->getInstalledPluginFiles() as $sFile ) {
52
  $aVulns[ $sFile ] = $this->getPluginVulnerabilities( $sFile );
53
  }
58
  * @return WpVulnVO[][]
59
  */
60
  protected function getAllThemeVulnerabilities() {
61
+ $aVulns = [];
62
  $oWpThemes = Services::WpThemes();
63
 
64
  $oActiveTheme = $oWpThemes->getCurrent();
src/lib/src/Scans/Wpv/WpVulnDb/RetrieveForItem.php CHANGED
@@ -37,12 +37,12 @@ class RetrieveForItem {
37
  if ( empty( $aD ) ) {
38
  $sRaw = Services::HttpRequest()->getContent( $this->buildApiUrl() );
39
  if ( empty( $sRaw ) ) {
40
- $aD = array();
41
  }
42
  else {
43
  $aD = @json_decode( trim( $sRaw ), true );
44
  if ( !is_array( $aD ) || !isset( $aD[ $sSlug ] ) || !is_array( $aD[ $sSlug ] ) ) {
45
- $aD = array();
46
  }
47
  else {
48
  $aD = $aD[ $sSlug ];
@@ -51,7 +51,7 @@ class RetrieveForItem {
51
 
52
  $aD[ 'slug' ] = $sSlug;
53
  if ( !isset( $aD[ 'vulnerabilities' ] ) || !is_array( $aD[ 'vulnerabilities' ] ) ) {
54
- $aD[ 'vulnerabilities' ] = array();
55
  }
56
  $this->setVoCache( $aD );
57
  }
@@ -79,7 +79,7 @@ class RetrieveForItem {
79
  $oWp = Services::WpGeneral();
80
  $aCacheData = $oWp->getTransient( $this->getVoCacheKey() );
81
  if ( !is_array( $aCacheData ) ) {
82
- $aCacheData = array();
83
  $this->setVoCache( $aCacheData );
84
  }
85
  return $aCacheData;
37
  if ( empty( $aD ) ) {
38
  $sRaw = Services::HttpRequest()->getContent( $this->buildApiUrl() );
39
  if ( empty( $sRaw ) ) {
40
+ $aD = [];
41
  }
42
  else {
43
  $aD = @json_decode( trim( $sRaw ), true );
44
  if ( !is_array( $aD ) || !isset( $aD[ $sSlug ] ) || !is_array( $aD[ $sSlug ] ) ) {
45
+ $aD = [];
46
  }
47
  else {
48
  $aD = $aD[ $sSlug ];
51
 
52
  $aD[ 'slug' ] = $sSlug;
53
  if ( !isset( $aD[ 'vulnerabilities' ] ) || !is_array( $aD[ 'vulnerabilities' ] ) ) {
54
+ $aD[ 'vulnerabilities' ] = [];
55
  }
56
  $this->setVoCache( $aD );
57
  }
79
  $oWp = Services::WpGeneral();
80
  $aCacheData = $oWp->getTransient( $this->getVoCacheKey() );
81
  if ( !is_array( $aCacheData ) ) {
82
+ $aCacheData = [];
83
  $this->setVoCache( $aCacheData );
84
  }
85
  return $aCacheData;
src/lib/src/Tables/Build/AdminNotes.php CHANGED
@@ -15,7 +15,7 @@ class AdminNotes extends BaseBuild {
15
  * @return array[]
16
  */
17
  protected function getEntriesFormatted() {
18
- $aEntries = array();
19
 
20
  foreach ( $this->getEntriesRaw() as $nKey => $oEntry ) {
21
  /** @var EntryVO $oEntry */
15
  * @return array[]
16
  */
17
  protected function getEntriesFormatted() {
18
+ $aEntries = [];
19
 
20
  foreach ( $this->getEntriesRaw() as $nKey => $oEntry ) {
21
  /** @var EntryVO $oEntry */
src/lib/src/Tables/Build/AuditTrail.php CHANGED
@@ -2,6 +2,7 @@
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Tables\Build;
4
 
 
5
  use FernleafSystems\Wordpress\Plugin\Shield\Databases;
6
  use FernleafSystems\Wordpress\Plugin\Shield\Tables;
7
  use FernleafSystems\Wordpress\Services\Services;
@@ -32,6 +33,28 @@ class AuditTrail extends BaseBuild {
32
  $oSelector->filterByNotIp( $oIp->getRequestIp() );
33
  }
34
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
  // if username is provided, this takes priority over "logged-in" (even if it's invalid)
36
  if ( !empty( $aParams[ 'fUsername' ] ) ) {
37
  $oSelector->filterByUsername( $aParams[ 'fUsername' ] );
@@ -48,36 +71,45 @@ class AuditTrail extends BaseBuild {
48
  * @return array
49
  */
50
  protected function getCustomParams() {
51
- return array(
52
  'fIp' => '',
53
  'fUsername' => '',
54
  'fContext' => '',
55
  'fLoggedIn' => -1,
56
  'fExludeYou' => '',
57
- );
 
 
58
  }
59
 
60
  /**
61
  * @return array[]
62
  */
63
  protected function getEntriesFormatted() {
64
- $aEntries = array();
65
 
66
  $sYou = Services::IP()->getRequestIp();
67
  foreach ( $this->getEntriesRaw() as $nKey => $oEntry ) {
68
  /** @var Databases\AuditTrail\EntryVO $oEntry */
69
- $aE = $oEntry->getRawDataAsArray();
70
- $aE[ 'meta' ] = $oEntry->meta;
71
- $aE[ 'event' ] = str_replace( '_', ' ', sanitize_text_field( $oEntry->event ) );
72
- $aE[ 'message' ] = stripslashes( sanitize_text_field( $oEntry->message ) );
73
- $aE[ 'created_at' ] = $this->formatTimestampField( $oEntry->created_at );
74
- if ( $oEntry->ip == $sYou ) {
75
- $aE[ 'your_ip' ] = '<small> ('._wpsf__( 'You' ).')</small>';
 
 
 
 
 
76
  }
77
  else {
78
- $aE[ 'your_ip' ] = '';
 
79
  }
80
- $aEntries[ $nKey ] = $aE;
 
81
  }
82
  return $aEntries;
83
  }
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Tables\Build;
4
 
5
+ use Carbon\Carbon;
6
  use FernleafSystems\Wordpress\Plugin\Shield\Databases;
7
  use FernleafSystems\Wordpress\Plugin\Shield\Tables;
8
  use FernleafSystems\Wordpress\Services\Services;
33
  $oSelector->filterByNotIp( $oIp->getRequestIp() );
34
  }
35
 
36
+ /**
37
+ * put this date stuff in the base so we can filter anything
38
+ */
39
+ if ( !empty( $aParams[ 'fDateFrom' ] ) && preg_match( '#^\d{4}-\d{2}-\d{2}$#', $aParams[ 'fDateFrom' ] ) ) {
40
+ $aParts = explode( '-', $aParams[ 'fDateFrom' ] );
41
+ $sTs = ( new Carbon() )
42
+ ->setDate( $aParts[ 0 ], $aParts[ 1 ], $aParts[ 2 ] )
43
+ ->setTime( 0, 0 )
44
+ ->timestamp;
45
+ $oSelector->filterByCreatedAt( $sTs, '>' );
46
+ }
47
+
48
+ if ( !empty( $aParams[ 'fDateTo' ] ) && preg_match( '#^\d{4}-\d{2}-\d{2}$#', $aParams[ 'fDateTo' ] ) ) {
49
+ $aParts = explode( '-', $aParams[ 'fDateTo' ] );
50
+ $sTs = ( new Carbon() )
51
+ ->setDate( $aParts[ 0 ], $aParts[ 1 ], $aParts[ 2 ] )
52
+ ->setTime( 0, 0 )
53
+ ->addDay()
54
+ ->timestamp;
55
+ $oSelector->filterByCreatedAt( $sTs, '<' );
56
+ }
57
+
58
  // if username is provided, this takes priority over "logged-in" (even if it's invalid)
59
  if ( !empty( $aParams[ 'fUsername' ] ) ) {
60
  $oSelector->filterByUsername( $aParams[ 'fUsername' ] );
71
  * @return array
72
  */
73
  protected function getCustomParams() {
74
+ return [
75
  'fIp' => '',
76
  'fUsername' => '',
77
  'fContext' => '',
78
  'fLoggedIn' => -1,
79
  'fExludeYou' => '',
80
+ 'fDateFrom' => '',
81
+ 'fDateTo' => '',
82
+ ];
83
  }
84
 
85
  /**
86
  * @return array[]
87
  */
88
  protected function getEntriesFormatted() {
89
+ $aEntries = [];
90
 
91
  $sYou = Services::IP()->getRequestIp();
92
  foreach ( $this->getEntriesRaw() as $nKey => $oEntry ) {
93
  /** @var Databases\AuditTrail\EntryVO $oEntry */
94
+ if ( !isset( $aEntries[ $oEntry->rid ] ) ) {
95
+ $aE = $oEntry->getRawDataAsArray();
96
+ $aE[ 'meta' ] = $oEntry->meta;
97
+ $aE[ 'event' ] = str_replace( '_', ' ', sanitize_text_field( $oEntry->event ) );
98
+ $aE[ 'message' ] = stripslashes( sanitize_textarea_field( $oEntry->message ) );
99
+ $aE[ 'created_at' ] = $this->formatTimestampField( $oEntry->created_at );
100
+ if ( $oEntry->ip == $sYou ) {
101
+ $aE[ 'your_ip' ] = '<small> ('._wpsf__( 'You' ).')</small>';
102
+ }
103
+ else {
104
+ $aE[ 'your_ip' ] = '';
105
+ }
106
  }
107
  else {
108
+ $aE = $aEntries[ $oEntry->rid ];
109
+ $aE[ 'message' ] .= "\n".stripslashes( sanitize_textarea_field( $oEntry->message ) );
110
  }
111
+
112
+ $aEntries[ $oEntry->rid ] = $aE;
113
  }
114
  return $aEntries;
115
  }
src/lib/src/Tables/Build/BaseBuild.php CHANGED
@@ -158,12 +158,12 @@ class BaseBuild {
158
  */
159
  protected function getParamDefaults() {
160
  return array_merge(
161
- array(
162
  'paged' => 1,
163
  'order' => 'DESC',
164
  'orderby' => 'created_at',
165
  'limit' => 25,
166
- ),
167
  $this->getCustomParams()
168
  );
169
  }
@@ -173,7 +173,7 @@ class BaseBuild {
173
  * @return array
174
  */
175
  protected function getCustomParams() {
176
- return array();
177
  }
178
 
179
  /**
158
  */
159
  protected function getParamDefaults() {
160
  return array_merge(
161
+ [
162
  'paged' => 1,
163
  'order' => 'DESC',
164
  'orderby' => 'created_at',
165
  'limit' => 25,
166
+ ],
167
  $this->getCustomParams()
168
  );
169
  }
173
  * @return array
174
  */
175
  protected function getCustomParams() {
176
+ return [];
177
  }
178
 
179
  /**
src/lib/src/Tables/Build/Ip.php CHANGED
@@ -39,7 +39,7 @@ class Ip extends BaseBuild {
39
  $oMod = $this->getMod();
40
  $nTransLimit = $oMod->getOptTransgressionLimit();
41
 
42
- $aEntries = array();
43
  foreach ( $this->getEntriesRaw() as $nKey => $oEntry ) {
44
  /** @var IPs\EntryVO $oEntry */
45
  $aE = $oEntry->getRawDataAsArray();
39
  $oMod = $this->getMod();
40
  $nTransLimit = $oMod->getOptTransgressionLimit();
41
 
42
+ $aEntries = [];
43
  foreach ( $this->getEntriesRaw() as $nKey => $oEntry ) {
44
  /** @var IPs\EntryVO $oEntry */
45
  $aE = $oEntry->getRawDataAsArray();
src/lib/src/Tables/Build/ScanApc.php CHANGED
@@ -16,7 +16,7 @@ class ScanApc extends ScanBase {
16
  * @return array[]
17
  */
18
  protected function getEntriesFormatted() {
19
- $aEntries = array();
20
 
21
  $oCarbon = new Carbon();
22
 
16
  * @return array[]
17
  */
18
  protected function getEntriesFormatted() {
19
+ $aEntries = [];
20
 
21
  $oCarbon = new Carbon();
22
 
src/lib/src/Tables/Build/ScanPtg.php CHANGED
@@ -15,7 +15,7 @@ class ScanPtg extends ScanBase {
15
  * @return array[]
16
  */
17
  protected function getEntriesFormatted() {
18
- $aEntries = array();
19
 
20
  /** @var \ICWP_WPSF_FeatureHandler_HackProtect $oMod */
21
  $oMod = $this->getMod();
15
  * @return array[]
16
  */
17
  protected function getEntriesFormatted() {
18
+ $aEntries = [];
19
 
20
  /** @var \ICWP_WPSF_FeatureHandler_HackProtect $oMod */
21
  $oMod = $this->getMod();
src/lib/src/Tables/Build/ScanUfc.php CHANGED
@@ -15,7 +15,7 @@ class ScanUfc extends ScanBase {
15
  * @return array[]
16
  */
17
  protected function getEntriesFormatted() {
18
- $aEntries = array();
19
 
20
  /** @var \ICWP_WPSF_FeatureHandler_HackProtect $oMod */
21
  $oMod = $this->getMod();
15
  * @return array[]
16
  */
17
  protected function getEntriesFormatted() {
18
+ $aEntries = [];
19
 
20
  /** @var \ICWP_WPSF_FeatureHandler_HackProtect $oMod */
21
  $oMod = $this->getMod();
src/lib/src/Tables/Build/ScanWcf.php CHANGED
@@ -15,7 +15,7 @@ class ScanWcf extends ScanBase {
15
  * @return array[]
16
  */
17
  protected function getEntriesFormatted() {
18
- $aEntries = array();
19
 
20
  /** @var \ICWP_WPSF_FeatureHandler_HackProtect $oMod */
21
  $oMod = $this->getMod();
15
  * @return array[]
16
  */
17
  protected function getEntriesFormatted() {
18
+ $aEntries = [];
19
 
20
  /** @var \ICWP_WPSF_FeatureHandler_HackProtect $oMod */
21
  $oMod = $this->getMod();
src/lib/src/Tables/Build/ScanWpv.php CHANGED
@@ -15,7 +15,7 @@ class ScanWpv extends ScanBase {
15
  * @return array[]
16
  */
17
  protected function getEntriesFormatted() {
18
- $aEntries = array();
19
 
20
  $oWpPlugins = Services::WpPlugins();
21
  $oWpThemes = Services::WpThemes();
15
  * @return array[]
16
  */
17
  protected function getEntriesFormatted() {
18
+ $aEntries = [];
19
 
20
  $oWpPlugins = Services::WpPlugins();
21
  $oWpThemes = Services::WpThemes();
src/lib/src/Tables/Build/Sessions.php CHANGED
@@ -59,7 +59,7 @@ class Sessions extends BaseBuild {
59
  * @return array[]
60
  */
61
  protected function getEntriesFormatted() {
62
- $aEntries = array();
63
 
64
  $sYou = Services::IP()->getRequestIp();
65
  foreach ( $this->getEntriesRaw() as $nKey => $oEntry ) {
59
  * @return array[]
60
  */
61
  protected function getEntriesFormatted() {
62
+ $aEntries = [];
63
 
64
  $sYou = Services::IP()->getRequestIp();
65
  foreach ( $this->getEntriesRaw() as $nKey => $oEntry ) {
src/lib/src/Tables/Build/Traffic.php CHANGED
@@ -76,14 +76,14 @@ class Traffic extends BaseBuild {
76
  * @return array[]
77
  */
78
  protected function getEntriesFormatted() {
79
- $aEntries = array();
80
 
81
  $oWpUsers = Services::WpUsers();
82
  $oGeo = Services::GeoIp()->setDbSource( $this->getGeoIpDbSource() );
83
  $oIp = Services::IP();
84
  $sYou = $oIp->getRequestIp();
85
 
86
- $aUsers = array( 0 => _wpsf__( 'No' ) );
87
  foreach ( $this->getEntriesRaw() as $nKey => $oEntry ) {
88
  /** @var Databases\Traffic\EntryVO $oEntry */
89
  $sIp = $oEntry->ip;
76
  * @return array[]
77
  */
78
  protected function getEntriesFormatted() {
79
+ $aEntries = [];
80
 
81
  $oWpUsers = Services::WpUsers();
82
  $oGeo = Services::GeoIp()->setDbSource( $this->getGeoIpDbSource() );
83
  $oIp = Services::IP();
84
  $sYou = $oIp->getRequestIp();
85
 
86
+ $aUsers = [ 0 => _wpsf__( 'No' ) ];
87
  foreach ( $this->getEntriesRaw() as $nKey => $oEntry ) {
88
  /** @var Databases\Traffic\EntryVO $oEntry */
89
  $sIp = $oEntry->ip;
src/lib/src/Tables/Render/Base.php CHANGED
@@ -33,7 +33,7 @@ class Base extends \WP_List_Table {
33
  * wp-admin/includes/class-wp-screen.php on line 209
34
  * @param array $aArgs
35
  */
36
- public function __construct( $aArgs = array() ) {
37
  parent::__construct( array_merge( [ 'screen' => 'odp-ajax' ], $aArgs ) );
38
  }
39
 
@@ -62,7 +62,7 @@ class Base extends \WP_List_Table {
62
  * @return array
63
  */
64
  public function get_sortable_columns() {
65
- return array();
66
  // $aCols = $this->get_columns();
67
  // foreach ( $aCols as $sCol => $sName ) {
68
  // $aCols[ $sCol ] = array( $sCol, false );
@@ -82,7 +82,7 @@ class Base extends \WP_List_Table {
82
  */
83
  public function prepare_items() {
84
  $aCols = $this->get_columns();
85
- $aHidden = array();
86
  $this->_column_headers = array( $aCols, $aHidden, $this->get_sortable_columns() );
87
  $this->items = $this->getItemEntries();
88
 
@@ -178,7 +178,7 @@ class Base extends \WP_List_Table {
178
  $aClasses[] = 'text-dark';
179
  }
180
 
181
- $aDataAttrs = array();
182
  foreach ( $aData as $sKey => $sValue ) {
183
  $aDataAttrs[] = sprintf( 'data-%s="%s"', $sKey, $sValue );
184
  }
33
  * wp-admin/includes/class-wp-screen.php on line 209
34
  * @param array $aArgs
35
  */
36
+ public function __construct( $aArgs = [] ) {
37
  parent::__construct( array_merge( [ 'screen' => 'odp-ajax' ], $aArgs ) );
38
  }
39
 
62
  * @return array
63
  */
64
  public function get_sortable_columns() {
65
+ return [];
66
  // $aCols = $this->get_columns();
67
  // foreach ( $aCols as $sCol => $sName ) {
68
  // $aCols[ $sCol ] = array( $sCol, false );
82
  */
83
  public function prepare_items() {
84
  $aCols = $this->get_columns();
85
+ $aHidden = [];
86
  $this->_column_headers = array( $aCols, $aHidden, $this->get_sortable_columns() );
87
  $this->items = $this->getItemEntries();
88
 
178
  $aClasses[] = 'text-dark';
179
  }
180
 
181
+ $aDataAttrs = [];
182
  foreach ( $aData as $sKey => $sValue ) {
183
  $aDataAttrs[] = sprintf( 'data-%s="%s"', $sKey, $sValue );
184
  }
src/lib/vendor/composer/ClassLoader.php CHANGED
@@ -279,7 +279,7 @@ class ClassLoader
279
  */
280
  public function setApcuPrefix($apcuPrefix)
281
  {
282
- $this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null;
283
  }
284
 
285
  /**
@@ -377,11 +377,11 @@ class ClassLoader
377
  $subPath = $class;
378
  while (false !== $lastPos = strrpos($subPath, '\\')) {
379
  $subPath = substr($subPath, 0, $lastPos);
380
- $search = $subPath.'\\';
381
  if (isset($this->prefixDirsPsr4[$search])) {
 
382
  foreach ($this->prefixDirsPsr4[$search] as $dir) {
383
- $length = $this->prefixLengthsPsr4[$first][$search];
384
- if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
385
  return $file;
386
  }
387
  }
279
  */
280
  public function setApcuPrefix($apcuPrefix)
281
  {
282
+ $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
283
  }
284
 
285
  /**
377
  $subPath = $class;
378
  while (false !== $lastPos = strrpos($subPath, '\\')) {
379
  $subPath = substr($subPath, 0, $lastPos);
380
+ $search = $subPath . '\\';
381
  if (isset($this->prefixDirsPsr4[$search])) {
382
+ $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
383
  foreach ($this->prefixDirsPsr4[$search] as $dir) {
384
+ if (file_exists($file = $dir . $pathEnd)) {
 
385
  return $file;
386
  }
387
  }
src/lib/vendor/composer/autoload_classmap.php CHANGED
@@ -13,6 +13,10 @@ return array(
13
  'Carbon\\Laravel\\ServiceProvider' => $vendorDir . '/nesbot/carbon/src/Carbon/Laravel/ServiceProvider.php',
14
  'Carbon\\Translator' => $vendorDir . '/nesbot/carbon/src/Carbon/Translator.php',
15
  'Composer\\CaBundle\\CaBundle' => $vendorDir . '/composer/ca-bundle/src/CaBundle.php',
 
 
 
 
16
  'FernleafSystems\\Utilities\\Data\\Adapter\\StdClassAdapter' => $vendorDir . '/fernleafsystems/utilities/src/Data/Adapter/StdClassAdapter.php',
17
  'FernleafSystems\\Utilities\\Response' => $vendorDir . '/fernleafsystems/utilities/src/Response.php',
18
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\AuditTrail\\Auditor' => $baseDir . '/src/AuditTrail/Auditor.php',
@@ -104,13 +108,15 @@ return array(
104
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Traffic\\Insert' => $baseDir . '/src/Databases/Traffic/Insert.php',
105
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Traffic\\Select' => $baseDir . '/src/Databases/Traffic/Select.php',
106
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\License\\EddLicenseVO' => $baseDir . '/src/License/EddLicenseVO.php',
 
 
 
 
 
 
 
 
107
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\ModConsumer' => $baseDir . '/src/Modules/ModConsumer.php',
108
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\MouseTrap\\Base' => $baseDir . '/src/Modules/MouseTrap/Base.php',
109
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\MouseTrap\\Detect404' => $baseDir . '/src/Modules/MouseTrap/Detect404.php',
110
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\MouseTrap\\DetectXmlRpc' => $baseDir . '/src/Modules/MouseTrap/DetectXmlRpc.php',
111
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\MouseTrap\\FakeWebCrawler' => $baseDir . '/src/Modules/MouseTrap/FakeWebCrawler.php',
112
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\MouseTrap\\InvalidUsername' => $baseDir . '/src/Modules/MouseTrap/InvalidUsername.php',
113
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\MouseTrap\\LinkCheese' => $baseDir . '/src/Modules/MouseTrap/LinkCheese.php',
114
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\OptsConsumer' => $baseDir . '/src/Modules/OptsConsumer.php',
115
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\PluginControllerConsumer' => $baseDir . '/src/Modules/PluginControllerConsumer.php',
116
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\UserManagement\\Suspend\\Base' => $baseDir . '/src/Modules/UserManagement/Suspend/Base.php',
@@ -151,6 +157,11 @@ return array(
151
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\ScannerThemes' => $baseDir . '/src/Scans/Ptg/ScannerThemes.php',
152
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\Snapshots\\Store' => $baseDir . '/src/Scans/Ptg/Snapshots/Store.php',
153
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\Snapshots\\StoreFormatUpgrade' => $baseDir . '/src/Scans/Ptg/Snapshots/StoreFormatUpgrade.php',
 
 
 
 
 
154
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ufc\\ConvertResultsToVos' => $baseDir . '/src/Scans/Ufc/ConvertResultsToVos.php',
155
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ufc\\ConvertVosToResults' => $baseDir . '/src/Scans/Ufc/ConvertVosToResults.php',
156
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ufc\\Repair' => $baseDir . '/src/Scans/Ufc/Repair.php',
@@ -238,6 +249,7 @@ return array(
238
  'FernleafSystems\\Wordpress\\Services\\Utilities\\GeoIp' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/GeoIp.php',
239
  'FernleafSystems\\Wordpress\\Services\\Utilities\\HttpRequest' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/HttpRequest.php',
240
  'FernleafSystems\\Wordpress\\Services\\Utilities\\IpUtils' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/IpUtils.php',
 
241
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Net\\VisitorIpDetection' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Net/VisitorIpDetection.php',
242
  'FernleafSystems\\Wordpress\\Services\\Utilities\\PluginUserMeta' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/PluginUserMeta.php',
243
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Render' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Render.php',
@@ -302,7 +314,6 @@ return array(
302
  'ICWP_WPSF_FeatureHandler_License' => $baseDir . '/../features/license.php',
303
  'ICWP_WPSF_FeatureHandler_Lockdown' => $baseDir . '/../features/lockdown.php',
304
  'ICWP_WPSF_FeatureHandler_LoginProtect' => $baseDir . '/../features/login_protect.php',
305
- 'ICWP_WPSF_FeatureHandler_Mousetrap' => $baseDir . '/../features/mousetrap.php',
306
  'ICWP_WPSF_FeatureHandler_Plugin' => $baseDir . '/../features/plugin.php',
307
  'ICWP_WPSF_FeatureHandler_Sessions' => $baseDir . '/../features/sessions.php',
308
  'ICWP_WPSF_FeatureHandler_Statistics' => $baseDir . '/../features/statistics.php',
@@ -341,6 +352,7 @@ return array(
341
  'ICWP_WPSF_Processor_HackProtect_Apc' => $baseDir . '/../processors/hackprotect_scan_apc.php',
342
  'ICWP_WPSF_Processor_HackProtect_Integrity' => $baseDir . '/../processors/hackprotect_integrity.php',
343
  'ICWP_WPSF_Processor_HackProtect_Ptg' => $baseDir . '/../processors/hackprotect_scan_ptg.php',
 
344
  'ICWP_WPSF_Processor_HackProtect_ScanAssetsBase' => $baseDir . '/../processors/hackprotect_scan_assets_base.php',
345
  'ICWP_WPSF_Processor_HackProtect_Scanner' => $baseDir . '/../processors/hackprotect_scanner.php',
346
  'ICWP_WPSF_Processor_HackProtect_Ufc' => $baseDir . '/../processors/hackprotect_scan_ufc.php',
@@ -364,7 +376,6 @@ return array(
364
  'ICWP_WPSF_Processor_LoginProtect_TwoFactorAuth' => $baseDir . '/../processors/loginprotect_intentprovider_email.php',
365
  'ICWP_WPSF_Processor_LoginProtect_WpLogin' => $baseDir . '/../processors/loginprotect_wplogin.php',
366
  'ICWP_WPSF_Processor_LoginProtect_Yubikey' => $baseDir . '/../processors/loginprotect_intentprovider_yubikey.php',
367
- 'ICWP_WPSF_Processor_Mousetrap' => $baseDir . '/../processors/mousetrap.php',
368
  'ICWP_WPSF_Processor_Plugin' => $baseDir . '/../processors/plugin.php',
369
  'ICWP_WPSF_Processor_Plugin_Badge' => $baseDir . '/../processors/plugin_badge.php',
370
  'ICWP_WPSF_Processor_Plugin_BadgeWidget' => $baseDir . '/../processors/plugin_badgewidget.php',
@@ -409,6 +420,12 @@ return array(
409
  'ICWP_WPSF_WpUsers' => $baseDir . '/../common/wp-users.php',
410
  'ICWP_WPSF_WpWidget' => $baseDir . '/../common/wp-widget.php',
411
  'JsonSerializable' => $vendorDir . '/nesbot/carbon/src/JsonSerializable.php',
 
 
 
 
 
 
412
  'MaxMind\\Db\\Reader' => $vendorDir . '/maxmind-db/reader/src/MaxMind/Db/Reader.php',
413
  'MaxMind\\Db\\Reader\\Decoder' => $vendorDir . '/maxmind-db/reader/src/MaxMind/Db/Reader/Decoder.php',
414
  'MaxMind\\Db\\Reader\\InvalidDatabaseException' => $vendorDir . '/maxmind-db/reader/src/MaxMind/Db/Reader/InvalidDatabaseException.php',
13
  'Carbon\\Laravel\\ServiceProvider' => $vendorDir . '/nesbot/carbon/src/Carbon/Laravel/ServiceProvider.php',
14
  'Carbon\\Translator' => $vendorDir . '/nesbot/carbon/src/Carbon/Translator.php',
15
  'Composer\\CaBundle\\CaBundle' => $vendorDir . '/composer/ca-bundle/src/CaBundle.php',
16
+ 'Elliotchance\\Iterator\\AbstractPagedIterator' => $vendorDir . '/elliotchance/iterator/src/Elliotchance/Iterator/AbstractPagedIterator.php',
17
+ 'Elliotchance\\Iterator\\PagedIterator1' => $vendorDir . '/elliotchance/iterator/tests/Elliotchance/Iterator/PagedIteratorTest.php',
18
+ 'Elliotchance\\Iterator\\PagedIterator2' => $vendorDir . '/elliotchance/iterator/tests/Elliotchance/Iterator/PagedIteratorTest.php',
19
+ 'Elliotchance\\Iterator\\PagedIteratorTest' => $vendorDir . '/elliotchance/iterator/tests/Elliotchance/Iterator/PagedIteratorTest.php',
20
  'FernleafSystems\\Utilities\\Data\\Adapter\\StdClassAdapter' => $vendorDir . '/fernleafsystems/utilities/src/Data/Adapter/StdClassAdapter.php',
21
  'FernleafSystems\\Utilities\\Response' => $vendorDir . '/fernleafsystems/utilities/src/Response.php',
22
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\AuditTrail\\Auditor' => $baseDir . '/src/AuditTrail/Auditor.php',
108
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Traffic\\Insert' => $baseDir . '/src/Databases/Traffic/Insert.php',
109
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Traffic\\Select' => $baseDir . '/src/Databases/Traffic/Select.php',
110
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\License\\EddLicenseVO' => $baseDir . '/src/License/EddLicenseVO.php',
111
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\BotTrack\\Base' => $baseDir . '/src/Modules/IPs/BotTrack/Base.php',
112
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\BotTrack\\Track404' => $baseDir . '/src/Modules/IPs/BotTrack/Track404.php',
113
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\BotTrack\\TrackFakeWebCrawler' => $baseDir . '/src/Modules/IPs/BotTrack/TrackFakeWebCrawler.php',
114
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\BotTrack\\TrackLinkCheese' => $baseDir . '/src/Modules/IPs/BotTrack/TrackLinkCheese.php',
115
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\BotTrack\\TrackLoginFailed' => $baseDir . '/src/Modules/IPs/BotTrack/TrackLoginFailed.php',
116
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\BotTrack\\TrackLoginInvalid' => $baseDir . '/src/Modules/IPs/BotTrack/TrackLoginInvalid.php',
117
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\BotTrack\\TrackUserAgent' => $baseDir . '/src/Modules/IPs/BotTrack/TrackUserAgent.php',
118
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\BotTrack\\TrackXmlRpc' => $baseDir . '/src/Modules/IPs/BotTrack/TrackXmlRpc.php',
119
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\ModConsumer' => $baseDir . '/src/Modules/ModConsumer.php',
 
 
 
 
 
 
120
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\OptsConsumer' => $baseDir . '/src/Modules/OptsConsumer.php',
121
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\PluginControllerConsumer' => $baseDir . '/src/Modules/PluginControllerConsumer.php',
122
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\UserManagement\\Suspend\\Base' => $baseDir . '/src/Modules/UserManagement/Suspend/Base.php',
157
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\ScannerThemes' => $baseDir . '/src/Scans/Ptg/ScannerThemes.php',
158
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\Snapshots\\Store' => $baseDir . '/src/Scans/Ptg/Snapshots/Store.php',
159
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\Snapshots\\StoreFormatUpgrade' => $baseDir . '/src/Scans/Ptg/Snapshots/StoreFormatUpgrade.php',
160
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Realtime\\Files\\Backup' => $baseDir . '/src/Scans/Realtime/Files/Backup.php',
161
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Realtime\\Files\\Process' => $baseDir . '/src/Scans/Realtime/Files/Process.php',
162
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Realtime\\Files\\Revert' => $baseDir . '/src/Scans/Realtime/Files/Revert.php',
163
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Realtime\\Files\\TestWritable' => $baseDir . '/src/Scans/Realtime/Files/TestWritable.php',
164
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Realtime\\Files\\Verify' => $baseDir . '/src/Scans/Realtime/Files/Verify.php',
165
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ufc\\ConvertResultsToVos' => $baseDir . '/src/Scans/Ufc/ConvertResultsToVos.php',
166
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ufc\\ConvertVosToResults' => $baseDir . '/src/Scans/Ufc/ConvertVosToResults.php',
167
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ufc\\Repair' => $baseDir . '/src/Scans/Ufc/Repair.php',
249
  'FernleafSystems\\Wordpress\\Services\\Utilities\\GeoIp' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/GeoIp.php',
250
  'FernleafSystems\\Wordpress\\Services\\Utilities\\HttpRequest' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/HttpRequest.php',
251
  'FernleafSystems\\Wordpress\\Services\\Utilities\\IpUtils' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/IpUtils.php',
252
+ 'FernleafSystems\\Wordpress\\Services\\Utilities\\Iterators\\WpUserIterator' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Iterators/WpUserIterator.php',
253
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Net\\VisitorIpDetection' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Net/VisitorIpDetection.php',
254
  'FernleafSystems\\Wordpress\\Services\\Utilities\\PluginUserMeta' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/PluginUserMeta.php',
255
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Render' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Render.php',
314
  'ICWP_WPSF_FeatureHandler_License' => $baseDir . '/../features/license.php',
315
  'ICWP_WPSF_FeatureHandler_Lockdown' => $baseDir . '/../features/lockdown.php',
316
  'ICWP_WPSF_FeatureHandler_LoginProtect' => $baseDir . '/../features/login_protect.php',
 
317
  'ICWP_WPSF_FeatureHandler_Plugin' => $baseDir . '/../features/plugin.php',
318
  'ICWP_WPSF_FeatureHandler_Sessions' => $baseDir . '/../features/sessions.php',
319
  'ICWP_WPSF_FeatureHandler_Statistics' => $baseDir . '/../features/statistics.php',
352
  'ICWP_WPSF_Processor_HackProtect_Apc' => $baseDir . '/../processors/hackprotect_scan_apc.php',
353
  'ICWP_WPSF_Processor_HackProtect_Integrity' => $baseDir . '/../processors/hackprotect_integrity.php',
354
  'ICWP_WPSF_Processor_HackProtect_Ptg' => $baseDir . '/../processors/hackprotect_scan_ptg.php',
355
+ 'ICWP_WPSF_Processor_HackProtect_Realtime' => $baseDir . '/../processors/hackprotect_realtime.php',
356
  'ICWP_WPSF_Processor_HackProtect_ScanAssetsBase' => $baseDir . '/../processors/hackprotect_scan_assets_base.php',
357
  'ICWP_WPSF_Processor_HackProtect_Scanner' => $baseDir . '/../processors/hackprotect_scanner.php',
358
  'ICWP_WPSF_Processor_HackProtect_Ufc' => $baseDir . '/../processors/hackprotect_scan_ufc.php',
376
  'ICWP_WPSF_Processor_LoginProtect_TwoFactorAuth' => $baseDir . '/../processors/loginprotect_intentprovider_email.php',
377
  'ICWP_WPSF_Processor_LoginProtect_WpLogin' => $baseDir . '/../processors/loginprotect_wplogin.php',
378
  'ICWP_WPSF_Processor_LoginProtect_Yubikey' => $baseDir . '/../processors/loginprotect_intentprovider_yubikey.php',
 
379
  'ICWP_WPSF_Processor_Plugin' => $baseDir . '/../processors/plugin.php',
380
  'ICWP_WPSF_Processor_Plugin_Badge' => $baseDir . '/../processors/plugin_badge.php',
381
  'ICWP_WPSF_Processor_Plugin_BadgeWidget' => $baseDir . '/../processors/plugin_badgewidget.php',
420
  'ICWP_WPSF_WpUsers' => $baseDir . '/../common/wp-users.php',
421
  'ICWP_WPSF_WpWidget' => $baseDir . '/../common/wp-widget.php',
422
  'JsonSerializable' => $vendorDir . '/nesbot/carbon/src/JsonSerializable.php',
423
+ 'LZCompressor\\LZContext' => $vendorDir . '/nullpunkt/lz-string-php/src/LZCompressor/LZContext.php',
424
+ 'LZCompressor\\LZData' => $vendorDir . '/nullpunkt/lz-string-php/src/LZCompressor/LZData.php',
425
+ 'LZCompressor\\LZReverseDictionary' => $vendorDir . '/nullpunkt/lz-string-php/src/LZCompressor/LZReverseDictionary.php',
426
+ 'LZCompressor\\LZString' => $vendorDir . '/nullpunkt/lz-string-php/src/LZCompressor/LZString.php',
427
+ 'LZCompressor\\LZUtil' => $vendorDir . '/nullpunkt/lz-string-php/src/LZCompressor/LZUtil.php',
428
+ 'LZCompressor\\LZUtil16' => $vendorDir . '/nullpunkt/lz-string-php/src/LZCompressor/LZUtil16.php',
429
  'MaxMind\\Db\\Reader' => $vendorDir . '/maxmind-db/reader/src/MaxMind/Db/Reader.php',
430
  'MaxMind\\Db\\Reader\\Decoder' => $vendorDir . '/maxmind-db/reader/src/MaxMind/Db/Reader/Decoder.php',
431
  'MaxMind\\Db\\Reader\\InvalidDatabaseException' => $vendorDir . '/maxmind-db/reader/src/MaxMind/Db/Reader/InvalidDatabaseException.php',
src/lib/vendor/composer/autoload_namespaces.php CHANGED
@@ -8,4 +8,5 @@ $baseDir = dirname($vendorDir);
8
  return array(
9
  'Twig_' => array($vendorDir . '/twig/twig/lib'),
10
  'Pimple' => array($vendorDir . '/pimple/pimple/src'),
 
11
  );
8
  return array(
9
  'Twig_' => array($vendorDir . '/twig/twig/lib'),
10
  'Pimple' => array($vendorDir . '/pimple/pimple/src'),
11
+ '' => array($vendorDir . '/elliotchance/iterator/tests', $vendorDir . '/elliotchance/iterator/src'),
12
  );
src/lib/vendor/composer/autoload_psr4.php CHANGED
@@ -17,6 +17,7 @@ return array(
17
  'MaxMind\\WebService\\' => array($vendorDir . '/maxmind/web-service-common/src/WebService'),
18
  'MaxMind\\Exception\\' => array($vendorDir . '/maxmind/web-service-common/src/Exception'),
19
  'MaxMind\\Db\\' => array($vendorDir . '/maxmind-db/reader/src/MaxMind/Db'),
 
20
  'Html2Text\\' => array($vendorDir . '/soundasleep/html2text/src'),
21
  'GeoIp2\\' => array($vendorDir . '/geoip2/geoip2/src'),
22
  'FernleafSystems\\Wordpress\\Services\\' => array($vendorDir . '/fernleafsystems/wordpress-services/src'),
17
  'MaxMind\\WebService\\' => array($vendorDir . '/maxmind/web-service-common/src/WebService'),
18
  'MaxMind\\Exception\\' => array($vendorDir . '/maxmind/web-service-common/src/Exception'),
19
  'MaxMind\\Db\\' => array($vendorDir . '/maxmind-db/reader/src/MaxMind/Db'),
20
+ 'LZCompressor\\' => array($vendorDir . '/nullpunkt/lz-string-php/src/LZCompressor'),
21
  'Html2Text\\' => array($vendorDir . '/soundasleep/html2text/src'),
22
  'GeoIp2\\' => array($vendorDir . '/geoip2/geoip2/src'),
23
  'FernleafSystems\\Wordpress\\Services\\' => array($vendorDir . '/fernleafsystems/wordpress-services/src'),
src/lib/vendor/composer/autoload_static.php CHANGED
@@ -41,6 +41,10 @@ class ComposerStaticInit18a31866e67f0a0bfffdc031786ecae1
41
  'MaxMind\\Exception\\' => 18,
42
  'MaxMind\\Db\\' => 11,
43
  ),
 
 
 
 
44
  'H' =>
45
  array (
46
  'Html2Text\\' => 10,
@@ -106,6 +110,10 @@ class ComposerStaticInit18a31866e67f0a0bfffdc031786ecae1
106
  array (
107
  0 => __DIR__ . '/..' . '/maxmind-db/reader/src/MaxMind/Db',
108
  ),
 
 
 
 
109
  'Html2Text\\' =>
110
  array (
111
  0 => __DIR__ . '/..' . '/soundasleep/html2text/src',
@@ -153,6 +161,11 @@ class ComposerStaticInit18a31866e67f0a0bfffdc031786ecae1
153
  ),
154
  );
155
 
 
 
 
 
 
156
  public static $classMap = array (
157
  'Carbon\\Carbon' => __DIR__ . '/..' . '/nesbot/carbon/src/Carbon/Carbon.php',
158
  'Carbon\\CarbonInterval' => __DIR__ . '/..' . '/nesbot/carbon/src/Carbon/CarbonInterval.php',
@@ -161,6 +174,10 @@ class ComposerStaticInit18a31866e67f0a0bfffdc031786ecae1
161
  'Carbon\\Laravel\\ServiceProvider' => __DIR__ . '/..' . '/nesbot/carbon/src/Carbon/Laravel/ServiceProvider.php',
162
  'Carbon\\Translator' => __DIR__ . '/..' . '/nesbot/carbon/src/Carbon/Translator.php',
163
  'Composer\\CaBundle\\CaBundle' => __DIR__ . '/..' . '/composer/ca-bundle/src/CaBundle.php',
 
 
 
 
164
  'FernleafSystems\\Utilities\\Data\\Adapter\\StdClassAdapter' => __DIR__ . '/..' . '/fernleafsystems/utilities/src/Data/Adapter/StdClassAdapter.php',
165
  'FernleafSystems\\Utilities\\Response' => __DIR__ . '/..' . '/fernleafsystems/utilities/src/Response.php',
166
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\AuditTrail\\Auditor' => __DIR__ . '/../..' . '/src/AuditTrail/Auditor.php',
@@ -252,13 +269,15 @@ class ComposerStaticInit18a31866e67f0a0bfffdc031786ecae1
252
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Traffic\\Insert' => __DIR__ . '/../..' . '/src/Databases/Traffic/Insert.php',
253
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Traffic\\Select' => __DIR__ . '/../..' . '/src/Databases/Traffic/Select.php',
254
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\License\\EddLicenseVO' => __DIR__ . '/../..' . '/src/License/EddLicenseVO.php',
 
 
 
 
 
 
 
 
255
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\ModConsumer' => __DIR__ . '/../..' . '/src/Modules/ModConsumer.php',
256
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\MouseTrap\\Base' => __DIR__ . '/../..' . '/src/Modules/MouseTrap/Base.php',
257
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\MouseTrap\\Detect404' => __DIR__ . '/../..' . '/src/Modules/MouseTrap/Detect404.php',
258
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\MouseTrap\\DetectXmlRpc' => __DIR__ . '/../..' . '/src/Modules/MouseTrap/DetectXmlRpc.php',
259
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\MouseTrap\\FakeWebCrawler' => __DIR__ . '/../..' . '/src/Modules/MouseTrap/FakeWebCrawler.php',
260
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\MouseTrap\\InvalidUsername' => __DIR__ . '/../..' . '/src/Modules/MouseTrap/InvalidUsername.php',
261
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\MouseTrap\\LinkCheese' => __DIR__ . '/../..' . '/src/Modules/MouseTrap/LinkCheese.php',
262
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\OptsConsumer' => __DIR__ . '/../..' . '/src/Modules/OptsConsumer.php',
263
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\PluginControllerConsumer' => __DIR__ . '/../..' . '/src/Modules/PluginControllerConsumer.php',
264
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\UserManagement\\Suspend\\Base' => __DIR__ . '/../..' . '/src/Modules/UserManagement/Suspend/Base.php',
@@ -299,6 +318,11 @@ class ComposerStaticInit18a31866e67f0a0bfffdc031786ecae1
299
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\ScannerThemes' => __DIR__ . '/../..' . '/src/Scans/Ptg/ScannerThemes.php',
300
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\Snapshots\\Store' => __DIR__ . '/../..' . '/src/Scans/Ptg/Snapshots/Store.php',
301
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\Snapshots\\StoreFormatUpgrade' => __DIR__ . '/../..' . '/src/Scans/Ptg/Snapshots/StoreFormatUpgrade.php',
 
 
 
 
 
302
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ufc\\ConvertResultsToVos' => __DIR__ . '/../..' . '/src/Scans/Ufc/ConvertResultsToVos.php',
303
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ufc\\ConvertVosToResults' => __DIR__ . '/../..' . '/src/Scans/Ufc/ConvertVosToResults.php',
304
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ufc\\Repair' => __DIR__ . '/../..' . '/src/Scans/Ufc/Repair.php',
@@ -386,6 +410,7 @@ class ComposerStaticInit18a31866e67f0a0bfffdc031786ecae1
386
  'FernleafSystems\\Wordpress\\Services\\Utilities\\GeoIp' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/GeoIp.php',
387
  'FernleafSystems\\Wordpress\\Services\\Utilities\\HttpRequest' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/HttpRequest.php',
388
  'FernleafSystems\\Wordpress\\Services\\Utilities\\IpUtils' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/IpUtils.php',
 
389
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Net\\VisitorIpDetection' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Net/VisitorIpDetection.php',
390
  'FernleafSystems\\Wordpress\\Services\\Utilities\\PluginUserMeta' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/PluginUserMeta.php',
391
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Render' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Render.php',
@@ -450,7 +475,6 @@ class ComposerStaticInit18a31866e67f0a0bfffdc031786ecae1
450
  'ICWP_WPSF_FeatureHandler_License' => __DIR__ . '/../..' . '/../features/license.php',
451
  'ICWP_WPSF_FeatureHandler_Lockdown' => __DIR__ . '/../..' . '/../features/lockdown.php',
452
  'ICWP_WPSF_FeatureHandler_LoginProtect' => __DIR__ . '/../..' . '/../features/login_protect.php',
453
- 'ICWP_WPSF_FeatureHandler_Mousetrap' => __DIR__ . '/../..' . '/../features/mousetrap.php',
454
  'ICWP_WPSF_FeatureHandler_Plugin' => __DIR__ . '/../..' . '/../features/plugin.php',
455
  'ICWP_WPSF_FeatureHandler_Sessions' => __DIR__ . '/../..' . '/../features/sessions.php',
456
  'ICWP_WPSF_FeatureHandler_Statistics' => __DIR__ . '/../..' . '/../features/statistics.php',
@@ -489,6 +513,7 @@ class ComposerStaticInit18a31866e67f0a0bfffdc031786ecae1
489
  'ICWP_WPSF_Processor_HackProtect_Apc' => __DIR__ . '/../..' . '/../processors/hackprotect_scan_apc.php',
490
  'ICWP_WPSF_Processor_HackProtect_Integrity' => __DIR__ . '/../..' . '/../processors/hackprotect_integrity.php',
491
  'ICWP_WPSF_Processor_HackProtect_Ptg' => __DIR__ . '/../..' . '/../processors/hackprotect_scan_ptg.php',
 
492
  'ICWP_WPSF_Processor_HackProtect_ScanAssetsBase' => __DIR__ . '/../..' . '/../processors/hackprotect_scan_assets_base.php',
493
  'ICWP_WPSF_Processor_HackProtect_Scanner' => __DIR__ . '/../..' . '/../processors/hackprotect_scanner.php',
494
  'ICWP_WPSF_Processor_HackProtect_Ufc' => __DIR__ . '/../..' . '/../processors/hackprotect_scan_ufc.php',
@@ -512,7 +537,6 @@ class ComposerStaticInit18a31866e67f0a0bfffdc031786ecae1
512
  'ICWP_WPSF_Processor_LoginProtect_TwoFactorAuth' => __DIR__ . '/../..' . '/../processors/loginprotect_intentprovider_email.php',
513
  'ICWP_WPSF_Processor_LoginProtect_WpLogin' => __DIR__ . '/../..' . '/../processors/loginprotect_wplogin.php',
514
  'ICWP_WPSF_Processor_LoginProtect_Yubikey' => __DIR__ . '/../..' . '/../processors/loginprotect_intentprovider_yubikey.php',
515
- 'ICWP_WPSF_Processor_Mousetrap' => __DIR__ . '/../..' . '/../processors/mousetrap.php',
516
  'ICWP_WPSF_Processor_Plugin' => __DIR__ . '/../..' . '/../processors/plugin.php',
517
  'ICWP_WPSF_Processor_Plugin_Badge' => __DIR__ . '/../..' . '/../processors/plugin_badge.php',
518
  'ICWP_WPSF_Processor_Plugin_BadgeWidget' => __DIR__ . '/../..' . '/../processors/plugin_badgewidget.php',
@@ -557,6 +581,12 @@ class ComposerStaticInit18a31866e67f0a0bfffdc031786ecae1
557
  'ICWP_WPSF_WpUsers' => __DIR__ . '/../..' . '/../common/wp-users.php',
558
  'ICWP_WPSF_WpWidget' => __DIR__ . '/../..' . '/../common/wp-widget.php',
559
  'JsonSerializable' => __DIR__ . '/..' . '/nesbot/carbon/src/JsonSerializable.php',
 
 
 
 
 
 
560
  'MaxMind\\Db\\Reader' => __DIR__ . '/..' . '/maxmind-db/reader/src/MaxMind/Db/Reader.php',
561
  'MaxMind\\Db\\Reader\\Decoder' => __DIR__ . '/..' . '/maxmind-db/reader/src/MaxMind/Db/Reader/Decoder.php',
562
  'MaxMind\\Db\\Reader\\InvalidDatabaseException' => __DIR__ . '/..' . '/maxmind-db/reader/src/MaxMind/Db/Reader/InvalidDatabaseException.php',
@@ -1070,6 +1100,7 @@ class ComposerStaticInit18a31866e67f0a0bfffdc031786ecae1
1070
  $loader->prefixDirsPsr4 = ComposerStaticInit18a31866e67f0a0bfffdc031786ecae1::$prefixDirsPsr4;
1071
  $loader->fallbackDirsPsr4 = ComposerStaticInit18a31866e67f0a0bfffdc031786ecae1::$fallbackDirsPsr4;
1072
  $loader->prefixesPsr0 = ComposerStaticInit18a31866e67f0a0bfffdc031786ecae1::$prefixesPsr0;
 
1073
  $loader->classMap = ComposerStaticInit18a31866e67f0a0bfffdc031786ecae1::$classMap;
1074
 
1075
  }, null, ClassLoader::class);
41
  'MaxMind\\Exception\\' => 18,
42
  'MaxMind\\Db\\' => 11,
43
  ),
44
+ 'L' =>
45
+ array (
46
+ 'LZCompressor\\' => 13,
47
+ ),
48
  'H' =>
49
  array (
50
  'Html2Text\\' => 10,
110
  array (
111
  0 => __DIR__ . '/..' . '/maxmind-db/reader/src/MaxMind/Db',
112
  ),
113
+ 'LZCompressor\\' =>
114
+ array (
115
+ 0 => __DIR__ . '/..' . '/nullpunkt/lz-string-php/src/LZCompressor',
116
+ ),
117
  'Html2Text\\' =>
118
  array (
119
  0 => __DIR__ . '/..' . '/soundasleep/html2text/src',
161
  ),
162
  );
163
 
164
+ public static $fallbackDirsPsr0 = array (
165
+ 0 => __DIR__ . '/..' . '/elliotchance/iterator/tests',
166
+ 1 => __DIR__ . '/..' . '/elliotchance/iterator/src',
167
+ );
168
+
169
  public static $classMap = array (
170
  'Carbon\\Carbon' => __DIR__ . '/..' . '/nesbot/carbon/src/Carbon/Carbon.php',
171
  'Carbon\\CarbonInterval' => __DIR__ . '/..' . '/nesbot/carbon/src/Carbon/CarbonInterval.php',
174
  'Carbon\\Laravel\\ServiceProvider' => __DIR__ . '/..' . '/nesbot/carbon/src/Carbon/Laravel/ServiceProvider.php',
175
  'Carbon\\Translator' => __DIR__ . '/..' . '/nesbot/carbon/src/Carbon/Translator.php',
176
  'Composer\\CaBundle\\CaBundle' => __DIR__ . '/..' . '/composer/ca-bundle/src/CaBundle.php',
177
+ 'Elliotchance\\Iterator\\AbstractPagedIterator' => __DIR__ . '/..' . '/elliotchance/iterator/src/Elliotchance/Iterator/AbstractPagedIterator.php',
178
+ 'Elliotchance\\Iterator\\PagedIterator1' => __DIR__ . '/..' . '/elliotchance/iterator/tests/Elliotchance/Iterator/PagedIteratorTest.php',
179
+ 'Elliotchance\\Iterator\\PagedIterator2' => __DIR__ . '/..' . '/elliotchance/iterator/tests/Elliotchance/Iterator/PagedIteratorTest.php',
180
+ 'Elliotchance\\Iterator\\PagedIteratorTest' => __DIR__ . '/..' . '/elliotchance/iterator/tests/Elliotchance/Iterator/PagedIteratorTest.php',
181
  'FernleafSystems\\Utilities\\Data\\Adapter\\StdClassAdapter' => __DIR__ . '/..' . '/fernleafsystems/utilities/src/Data/Adapter/StdClassAdapter.php',
182
  'FernleafSystems\\Utilities\\Response' => __DIR__ . '/..' . '/fernleafsystems/utilities/src/Response.php',
183
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\AuditTrail\\Auditor' => __DIR__ . '/../..' . '/src/AuditTrail/Auditor.php',
269
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Traffic\\Insert' => __DIR__ . '/../..' . '/src/Databases/Traffic/Insert.php',
270
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Databases\\Traffic\\Select' => __DIR__ . '/../..' . '/src/Databases/Traffic/Select.php',
271
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\License\\EddLicenseVO' => __DIR__ . '/../..' . '/src/License/EddLicenseVO.php',
272
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\BotTrack\\Base' => __DIR__ . '/../..' . '/src/Modules/IPs/BotTrack/Base.php',
273
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\BotTrack\\Track404' => __DIR__ . '/../..' . '/src/Modules/IPs/BotTrack/Track404.php',
274
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\BotTrack\\TrackFakeWebCrawler' => __DIR__ . '/../..' . '/src/Modules/IPs/BotTrack/TrackFakeWebCrawler.php',
275
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\BotTrack\\TrackLinkCheese' => __DIR__ . '/../..' . '/src/Modules/IPs/BotTrack/TrackLinkCheese.php',
276
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\BotTrack\\TrackLoginFailed' => __DIR__ . '/../..' . '/src/Modules/IPs/BotTrack/TrackLoginFailed.php',
277
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\BotTrack\\TrackLoginInvalid' => __DIR__ . '/../..' . '/src/Modules/IPs/BotTrack/TrackLoginInvalid.php',
278
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\BotTrack\\TrackUserAgent' => __DIR__ . '/../..' . '/src/Modules/IPs/BotTrack/TrackUserAgent.php',
279
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\IPs\\BotTrack\\TrackXmlRpc' => __DIR__ . '/../..' . '/src/Modules/IPs/BotTrack/TrackXmlRpc.php',
280
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\ModConsumer' => __DIR__ . '/../..' . '/src/Modules/ModConsumer.php',
 
 
 
 
 
 
281
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\OptsConsumer' => __DIR__ . '/../..' . '/src/Modules/OptsConsumer.php',
282
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\PluginControllerConsumer' => __DIR__ . '/../..' . '/src/Modules/PluginControllerConsumer.php',
283
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Modules\\UserManagement\\Suspend\\Base' => __DIR__ . '/../..' . '/src/Modules/UserManagement/Suspend/Base.php',
318
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\ScannerThemes' => __DIR__ . '/../..' . '/src/Scans/Ptg/ScannerThemes.php',
319
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\Snapshots\\Store' => __DIR__ . '/../..' . '/src/Scans/Ptg/Snapshots/Store.php',
320
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\Snapshots\\StoreFormatUpgrade' => __DIR__ . '/../..' . '/src/Scans/Ptg/Snapshots/StoreFormatUpgrade.php',
321
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Realtime\\Files\\Backup' => __DIR__ . '/../..' . '/src/Scans/Realtime/Files/Backup.php',
322
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Realtime\\Files\\Process' => __DIR__ . '/../..' . '/src/Scans/Realtime/Files/Process.php',
323
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Realtime\\Files\\Revert' => __DIR__ . '/../..' . '/src/Scans/Realtime/Files/Revert.php',
324
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Realtime\\Files\\TestWritable' => __DIR__ . '/../..' . '/src/Scans/Realtime/Files/TestWritable.php',
325
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Realtime\\Files\\Verify' => __DIR__ . '/../..' . '/src/Scans/Realtime/Files/Verify.php',
326
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ufc\\ConvertResultsToVos' => __DIR__ . '/../..' . '/src/Scans/Ufc/ConvertResultsToVos.php',
327
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ufc\\ConvertVosToResults' => __DIR__ . '/../..' . '/src/Scans/Ufc/ConvertVosToResults.php',
328
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ufc\\Repair' => __DIR__ . '/../..' . '/src/Scans/Ufc/Repair.php',
410
  'FernleafSystems\\Wordpress\\Services\\Utilities\\GeoIp' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/GeoIp.php',
411
  'FernleafSystems\\Wordpress\\Services\\Utilities\\HttpRequest' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/HttpRequest.php',
412
  'FernleafSystems\\Wordpress\\Services\\Utilities\\IpUtils' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/IpUtils.php',
413
+ 'FernleafSystems\\Wordpress\\Services\\Utilities\\Iterators\\WpUserIterator' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Iterators/WpUserIterator.php',
414
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Net\\VisitorIpDetection' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Net/VisitorIpDetection.php',
415
  'FernleafSystems\\Wordpress\\Services\\Utilities\\PluginUserMeta' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/PluginUserMeta.php',
416
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Render' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Render.php',
475
  'ICWP_WPSF_FeatureHandler_License' => __DIR__ . '/../..' . '/../features/license.php',
476
  'ICWP_WPSF_FeatureHandler_Lockdown' => __DIR__ . '/../..' . '/../features/lockdown.php',
477
  'ICWP_WPSF_FeatureHandler_LoginProtect' => __DIR__ . '/../..' . '/../features/login_protect.php',
 
478
  'ICWP_WPSF_FeatureHandler_Plugin' => __DIR__ . '/../..' . '/../features/plugin.php',
479
  'ICWP_WPSF_FeatureHandler_Sessions' => __DIR__ . '/../..' . '/../features/sessions.php',
480
  'ICWP_WPSF_FeatureHandler_Statistics' => __DIR__ . '/../..' . '/../features/statistics.php',
513
  'ICWP_WPSF_Processor_HackProtect_Apc' => __DIR__ . '/../..' . '/../processors/hackprotect_scan_apc.php',
514
  'ICWP_WPSF_Processor_HackProtect_Integrity' => __DIR__ . '/../..' . '/../processors/hackprotect_integrity.php',
515
  'ICWP_WPSF_Processor_HackProtect_Ptg' => __DIR__ . '/../..' . '/../processors/hackprotect_scan_ptg.php',
516
+ 'ICWP_WPSF_Processor_HackProtect_Realtime' => __DIR__ . '/../..' . '/../processors/hackprotect_realtime.php',
517
  'ICWP_WPSF_Processor_HackProtect_ScanAssetsBase' => __DIR__ . '/../..' . '/../processors/hackprotect_scan_assets_base.php',
518
  'ICWP_WPSF_Processor_HackProtect_Scanner' => __DIR__ . '/../..' . '/../processors/hackprotect_scanner.php',
519
  'ICWP_WPSF_Processor_HackProtect_Ufc' => __DIR__ . '/../..' . '/../processors/hackprotect_scan_ufc.php',
537
  'ICWP_WPSF_Processor_LoginProtect_TwoFactorAuth' => __DIR__ . '/../..' . '/../processors/loginprotect_intentprovider_email.php',
538
  'ICWP_WPSF_Processor_LoginProtect_WpLogin' => __DIR__ . '/../..' . '/../processors/loginprotect_wplogin.php',
539
  'ICWP_WPSF_Processor_LoginProtect_Yubikey' => __DIR__ . '/../..' . '/../processors/loginprotect_intentprovider_yubikey.php',
 
540
  'ICWP_WPSF_Processor_Plugin' => __DIR__ . '/../..' . '/../processors/plugin.php',
541
  'ICWP_WPSF_Processor_Plugin_Badge' => __DIR__ . '/../..' . '/../processors/plugin_badge.php',
542
  'ICWP_WPSF_Processor_Plugin_BadgeWidget' => __DIR__ . '/../..' . '/../processors/plugin_badgewidget.php',
581
  'ICWP_WPSF_WpUsers' => __DIR__ . '/../..' . '/../common/wp-users.php',
582
  'ICWP_WPSF_WpWidget' => __DIR__ . '/../..' . '/../common/wp-widget.php',
583
  'JsonSerializable' => __DIR__ . '/..' . '/nesbot/carbon/src/JsonSerializable.php',
584
+ 'LZCompressor\\LZContext' => __DIR__ . '/..' . '/nullpunkt/lz-string-php/src/LZCompressor/LZContext.php',
585
+ 'LZCompressor\\LZData' => __DIR__ . '/..' . '/nullpunkt/lz-string-php/src/LZCompressor/LZData.php',
586
+ 'LZCompressor\\LZReverseDictionary' => __DIR__ . '/..' . '/nullpunkt/lz-string-php/src/LZCompressor/LZReverseDictionary.php',
587
+ 'LZCompressor\\LZString' => __DIR__ . '/..' . '/nullpunkt/lz-string-php/src/LZCompressor/LZString.php',
588
+ 'LZCompressor\\LZUtil' => __DIR__ . '/..' . '/nullpunkt/lz-string-php/src/LZCompressor/LZUtil.php',
589
+ 'LZCompressor\\LZUtil16' => __DIR__ . '/..' . '/nullpunkt/lz-string-php/src/LZCompressor/LZUtil16.php',
590
  'MaxMind\\Db\\Reader' => __DIR__ . '/..' . '/maxmind-db/reader/src/MaxMind/Db/Reader.php',
591
  'MaxMind\\Db\\Reader\\Decoder' => __DIR__ . '/..' . '/maxmind-db/reader/src/MaxMind/Db/Reader/Decoder.php',
592
  'MaxMind\\Db\\Reader\\InvalidDatabaseException' => __DIR__ . '/..' . '/maxmind-db/reader/src/MaxMind/Db/Reader/InvalidDatabaseException.php',
1100
  $loader->prefixDirsPsr4 = ComposerStaticInit18a31866e67f0a0bfffdc031786ecae1::$prefixDirsPsr4;
1101
  $loader->fallbackDirsPsr4 = ComposerStaticInit18a31866e67f0a0bfffdc031786ecae1::$fallbackDirsPsr4;
1102
  $loader->prefixesPsr0 = ComposerStaticInit18a31866e67f0a0bfffdc031786ecae1::$prefixesPsr0;
1103
+ $loader->fallbackDirsPsr0 = ComposerStaticInit18a31866e67f0a0bfffdc031786ecae1::$fallbackDirsPsr0;
1104
  $loader->classMap = ComposerStaticInit18a31866e67f0a0bfffdc031786ecae1::$classMap;
1105
 
1106
  }, null, ClassLoader::class);
src/lib/vendor/composer/installed.json CHANGED
@@ -47,260 +47,236 @@
47
  ]
48
  },
49
  {
50
- "name": "maxmind/web-service-common",
51
- "version": "v0.5.0",
52
- "version_normalized": "0.5.0.0",
53
  "source": {
54
  "type": "git",
55
- "url": "https://github.com/maxmind/web-service-common-php.git",
56
- "reference": "61a9836fa3bb1743ab89752bae5005d71e78c73b"
57
  },
58
  "dist": {
59
  "type": "zip",
60
- "url": "https://api.github.com/repos/maxmind/web-service-common-php/zipball/61a9836fa3bb1743ab89752bae5005d71e78c73b",
61
- "reference": "61a9836fa3bb1743ab89752bae5005d71e78c73b",
62
  "shasum": ""
63
  },
64
  "require": {
65
- "composer/ca-bundle": "^1.0.3",
66
- "ext-curl": "*",
67
- "ext-json": "*",
68
- "php": ">=5.4"
69
  },
70
  "require-dev": {
71
- "friendsofphp/php-cs-fixer": "2.*",
72
- "phpunit/phpunit": "4.*",
73
- "squizlabs/php_codesniffer": "3.*"
74
  },
75
- "time": "2018-02-12T22:31:54+00:00",
76
  "type": "library",
 
 
 
 
 
77
  "installation-source": "dist",
78
  "autoload": {
79
  "psr-4": {
80
- "MaxMind\\Exception\\": "src/Exception",
81
- "MaxMind\\WebService\\": "src/WebService"
82
  }
83
  },
84
  "notification-url": "https://packagist.org/downloads/",
85
  "license": [
86
- "Apache-2.0"
87
  ],
88
  "authors": [
89
  {
90
- "name": "Gregory Oschwald",
91
- "email": "goschwald@maxmind.com"
 
92
  }
93
  ],
94
- "description": "Internal MaxMind Web Service API",
95
- "homepage": "https://github.com/maxmind/web-service-common-php"
 
 
 
 
 
 
96
  },
97
  {
98
- "name": "geoip2/geoip2",
99
- "version": "v2.9.0",
100
- "version_normalized": "2.9.0.0",
101
  "source": {
102
  "type": "git",
103
- "url": "https://github.com/maxmind/GeoIP2-php.git",
104
- "reference": "a807fbf65212eef5d8d2db1a1b31082b53633d77"
105
  },
106
  "dist": {
107
  "type": "zip",
108
- "url": "https://api.github.com/repos/maxmind/GeoIP2-php/zipball/a807fbf65212eef5d8d2db1a1b31082b53633d77",
109
- "reference": "a807fbf65212eef5d8d2db1a1b31082b53633d77",
110
  "shasum": ""
111
  },
112
- "require": {
113
- "maxmind-db/reader": "~1.0",
114
- "maxmind/web-service-common": "~0.5",
115
- "php": ">=5.4"
116
- },
117
  "require-dev": {
118
- "friendsofphp/php-cs-fixer": "2.*",
119
- "phpunit/phpunit": "4.*",
120
- "squizlabs/php_codesniffer": "3.*"
121
  },
122
- "time": "2018-04-10T15:32:59+00:00",
123
  "type": "library",
124
  "installation-source": "dist",
125
  "autoload": {
126
- "psr-4": {
127
- "GeoIp2\\": "src"
 
 
 
128
  }
129
  },
130
  "notification-url": "https://packagist.org/downloads/",
131
  "license": [
132
- "Apache-2.0"
133
  ],
134
  "authors": [
135
  {
136
- "name": "Gregory J. Oschwald",
137
- "email": "goschwald@maxmind.com",
138
- "homepage": "http://www.maxmind.com/"
139
  }
140
  ],
141
- "description": "MaxMind GeoIP2 PHP API",
142
- "homepage": "https://github.com/maxmind/GeoIP2-php",
143
- "keywords": [
144
- "IP",
145
- "geoip",
146
- "geoip2",
147
- "geolocation",
148
- "maxmind"
149
- ]
150
  },
151
  {
152
- "name": "soundasleep/html2text",
153
- "version": "0.5.0",
154
- "version_normalized": "0.5.0.0",
155
  "source": {
156
  "type": "git",
157
- "url": "https://github.com/soundasleep/html2text.git",
158
- "reference": "cdb89f6ffa2c4cc78f8ed9ea6ee0594a9133ccad"
159
  },
160
  "dist": {
161
  "type": "zip",
162
- "url": "https://api.github.com/repos/soundasleep/html2text/zipball/cdb89f6ffa2c4cc78f8ed9ea6ee0594a9133ccad",
163
- "reference": "cdb89f6ffa2c4cc78f8ed9ea6ee0594a9133ccad",
164
  "shasum": ""
165
  },
166
  "require": {
167
- "ext-dom": "*",
168
- "ext-libxml": "*",
169
- "php": ">=5.3.2"
170
- },
171
- "require-dev": {
172
- "phpunit/phpunit": ">=4.0",
173
- "soundasleep/component-tests": "dev-master"
174
  },
175
- "time": "2017-04-19T22:01:50+00:00",
176
  "type": "library",
177
  "installation-source": "dist",
178
  "autoload": {
179
  "psr-4": {
180
- "Html2Text\\": "src"
181
  }
182
  },
183
  "notification-url": "https://packagist.org/downloads/",
184
- "license": [
185
- "EPL-1.0"
186
- ],
187
  "authors": [
188
  {
189
- "name": "Jevon Wright",
190
- "homepage": "https://jevon.org",
191
- "role": "Developer"
192
  }
193
  ],
194
- "description": "A PHP script to convert HTML into a plain text format",
195
- "homepage": "https://github.com/soundasleep/html2text",
196
- "keywords": [
197
- "email",
198
- "html",
199
- "php",
200
- "text"
201
- ]
202
  },
203
  {
204
- "name": "psr/container",
205
- "version": "1.0.0",
206
- "version_normalized": "1.0.0.0",
207
  "source": {
208
  "type": "git",
209
- "url": "https://github.com/php-fig/container.git",
210
- "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f"
211
  },
212
  "dist": {
213
  "type": "zip",
214
- "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
215
- "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
216
  "shasum": ""
217
  },
218
  "require": {
219
- "php": ">=5.3.0"
 
 
 
 
 
 
 
220
  },
221
- "time": "2017-02-14T16:28:37+00:00",
222
  "type": "library",
223
- "extra": {
224
- "branch-alias": {
225
- "dev-master": "1.0.x-dev"
226
- }
227
- },
228
- "installation-source": "dist",
229
  "autoload": {
230
  "psr-4": {
231
- "Psr\\Container\\": "src/"
232
  }
233
  },
234
  "notification-url": "https://packagist.org/downloads/",
235
- "license": [
236
- "MIT"
237
- ],
238
  "authors": [
239
  {
240
- "name": "PHP-FIG",
241
- "homepage": "http://www.php-fig.org/"
242
  }
243
  ],
244
- "description": "Common Container Interface (PHP FIG PSR-11)",
245
- "homepage": "https://github.com/php-fig/container",
246
- "keywords": [
247
- "PSR-11",
248
- "container",
249
- "container-interface",
250
- "container-interop",
251
- "psr"
252
- ]
253
  },
254
  {
255
- "name": "pimple/pimple",
256
- "version": "v3.2.3",
257
- "version_normalized": "3.2.3.0",
258
  "source": {
259
  "type": "git",
260
- "url": "https://github.com/silexphp/Pimple.git",
261
- "reference": "9e403941ef9d65d20cba7d54e29fe906db42cf32"
262
  },
263
  "dist": {
264
  "type": "zip",
265
- "url": "https://api.github.com/repos/silexphp/Pimple/zipball/9e403941ef9d65d20cba7d54e29fe906db42cf32",
266
- "reference": "9e403941ef9d65d20cba7d54e29fe906db42cf32",
267
  "shasum": ""
268
  },
269
  "require": {
270
- "php": ">=5.3.0",
271
- "psr/container": "^1.0"
 
272
  },
273
  "require-dev": {
274
- "symfony/phpunit-bridge": "^3.2"
 
 
275
  },
276
- "time": "2018-01-21T07:42:36+00:00",
277
  "type": "library",
278
- "extra": {
279
- "branch-alias": {
280
- "dev-master": "3.2.x-dev"
281
- }
282
- },
283
  "installation-source": "dist",
284
  "autoload": {
285
- "psr-0": {
286
- "Pimple": "src/"
287
  }
288
  },
289
  "notification-url": "https://packagist.org/downloads/",
290
  "license": [
291
- "MIT"
292
  ],
293
  "authors": [
294
  {
295
- "name": "Fabien Potencier",
296
- "email": "fabien@symfony.com"
 
297
  }
298
  ],
299
- "description": "Pimple, a simple Dependency Injection Container",
300
- "homepage": "http://pimple.sensiolabs.org",
301
  "keywords": [
302
- "container",
303
- "dependency injection"
 
 
 
304
  ]
305
  },
306
  {
@@ -351,122 +327,110 @@
351
  ]
352
  },
353
  {
354
- "name": "symfony/yaml",
355
- "version": "v2.8.49",
356
- "version_normalized": "2.8.49.0",
357
  "source": {
358
  "type": "git",
359
- "url": "https://github.com/symfony/yaml.git",
360
- "reference": "02c1859112aa779d9ab394ae4f3381911d84052b"
361
  },
362
  "dist": {
363
  "type": "zip",
364
- "url": "https://api.github.com/repos/symfony/yaml/zipball/02c1859112aa779d9ab394ae4f3381911d84052b",
365
- "reference": "02c1859112aa779d9ab394ae4f3381911d84052b",
366
  "shasum": ""
367
  },
368
  "require": {
369
- "php": ">=5.3.9",
370
- "symfony/polyfill-ctype": "~1.8"
371
  },
372
- "time": "2018-11-11T11:18:13+00:00",
373
- "type": "library",
374
- "extra": {
375
- "branch-alias": {
376
- "dev-master": "2.8-dev"
377
- }
378
  },
 
 
 
 
 
 
 
379
  "installation-source": "dist",
380
  "autoload": {
381
  "psr-4": {
382
- "Symfony\\Component\\Yaml\\": ""
383
- },
384
- "exclude-from-classmap": [
385
- "/Tests/"
386
- ]
387
  },
388
  "notification-url": "https://packagist.org/downloads/",
389
  "license": [
390
- "MIT"
391
  ],
392
  "authors": [
393
  {
394
- "name": "Fabien Potencier",
395
- "email": "fabien@symfony.com"
396
- },
397
- {
398
- "name": "Symfony Community",
399
- "homepage": "https://symfony.com/contributors"
400
  }
401
  ],
402
- "description": "Symfony Yaml Component",
403
- "homepage": "https://symfony.com"
 
 
 
 
 
 
 
404
  },
405
  {
406
- "name": "symfony/translation",
407
- "version": "v2.8.49",
408
- "version_normalized": "2.8.49.0",
409
  "source": {
410
  "type": "git",
411
- "url": "https://github.com/symfony/translation.git",
412
- "reference": "fc58c2a19e56c29f5ba2736ec40d0119a0de2089"
413
  },
414
  "dist": {
415
  "type": "zip",
416
- "url": "https://api.github.com/repos/symfony/translation/zipball/fc58c2a19e56c29f5ba2736ec40d0119a0de2089",
417
- "reference": "fc58c2a19e56c29f5ba2736ec40d0119a0de2089",
418
  "shasum": ""
419
  },
420
  "require": {
421
- "php": ">=5.3.9",
422
- "symfony/polyfill-mbstring": "~1.0"
423
- },
424
- "conflict": {
425
- "symfony/config": "<2.7"
426
  },
427
  "require-dev": {
428
- "psr/log": "~1.0",
429
- "symfony/config": "~2.8",
430
- "symfony/intl": "~2.7.25|^2.8.18|~3.2.5",
431
- "symfony/yaml": "~2.2|~3.0.0"
432
- },
433
- "suggest": {
434
- "psr/log-implementation": "To use logging capability in translator",
435
- "symfony/config": "",
436
- "symfony/yaml": ""
437
  },
438
- "time": "2018-11-24T21:16:41+00:00",
439
  "type": "library",
440
- "extra": {
441
- "branch-alias": {
442
- "dev-master": "2.8-dev"
443
- }
444
- },
445
  "installation-source": "dist",
446
  "autoload": {
447
  "psr-4": {
448
- "Symfony\\Component\\Translation\\": ""
449
- },
450
- "exclude-from-classmap": [
451
- "/Tests/"
452
- ]
453
  },
454
  "notification-url": "https://packagist.org/downloads/",
455
  "license": [
456
- "MIT"
457
  ],
458
  "authors": [
459
  {
460
- "name": "Fabien Potencier",
461
- "email": "fabien@symfony.com"
462
- },
463
- {
464
- "name": "Symfony Community",
465
- "homepage": "https://symfony.com/contributors"
466
  }
467
  ],
468
- "description": "Symfony Translation Component",
469
- "homepage": "https://symfony.com"
470
  },
471
  {
472
  "name": "nesbot/carbon",
@@ -529,99 +493,131 @@
529
  ]
530
  },
531
  {
532
- "name": "maxmind-db/reader",
533
- "version": "v1.4.1",
534
- "version_normalized": "1.4.1.0",
535
  "source": {
536
  "type": "git",
537
- "url": "https://github.com/maxmind/MaxMind-DB-Reader-php.git",
538
- "reference": "eb83d0ee1c1f9b8a340206302136bc81ee02ae74"
539
  },
540
  "dist": {
541
  "type": "zip",
542
- "url": "https://api.github.com/repos/maxmind/MaxMind-DB-Reader-php/zipball/eb83d0ee1c1f9b8a340206302136bc81ee02ae74",
543
- "reference": "eb83d0ee1c1f9b8a340206302136bc81ee02ae74",
544
  "shasum": ""
545
  },
546
  "require": {
547
- "php": ">=5.4"
548
  },
549
  "require-dev": {
550
- "friendsofphp/php-cs-fixer": "2.*",
551
- "phpunit/phpunit": "4.* || 5.*",
552
- "satooshi/php-coveralls": "1.0.*",
553
- "squizlabs/php_codesniffer": "3.*"
554
  },
555
- "suggest": {
556
- "ext-bcmath": "bcmath or gmp is required for decoding larger integers with the pure PHP decoder",
557
- "ext-gmp": "bcmath or gmp is required for decoding larger integers with the pure PHP decoder",
558
- "ext-maxminddb": "A C-based database decoder that provides significantly faster lookups"
559
- },
560
- "time": "2019-01-04T19:55:56+00:00",
561
  "type": "library",
562
  "installation-source": "dist",
563
  "autoload": {
564
  "psr-4": {
565
- "MaxMind\\Db\\": "src/MaxMind/Db"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
566
  }
567
  },
568
  "notification-url": "https://packagist.org/downloads/",
569
  "license": [
570
- "Apache-2.0"
571
  ],
572
  "authors": [
573
  {
574
- "name": "Gregory J. Oschwald",
575
- "email": "goschwald@maxmind.com",
576
- "homepage": "http://www.maxmind.com/"
577
  }
578
  ],
579
- "description": "MaxMind DB Reader API",
580
- "homepage": "https://github.com/maxmind/MaxMind-DB-Reader-php",
581
  "keywords": [
582
- "database",
583
- "geoip",
584
- "geoip2",
585
- "geolocation",
586
- "maxmind"
587
  ]
588
  },
589
  {
590
- "name": "composer/ca-bundle",
591
- "version": "1.1.4",
592
- "version_normalized": "1.1.4.0",
593
  "source": {
594
  "type": "git",
595
- "url": "https://github.com/composer/ca-bundle.git",
596
- "reference": "558f321c52faeb4828c03e7dc0cfe39a09e09a2d"
597
  },
598
  "dist": {
599
  "type": "zip",
600
- "url": "https://api.github.com/repos/composer/ca-bundle/zipball/558f321c52faeb4828c03e7dc0cfe39a09e09a2d",
601
- "reference": "558f321c52faeb4828c03e7dc0cfe39a09e09a2d",
602
  "shasum": ""
603
  },
604
  "require": {
605
- "ext-openssl": "*",
606
- "ext-pcre": "*",
607
- "php": "^5.3.2 || ^7.0"
608
- },
609
- "require-dev": {
610
- "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5",
611
- "psr/log": "^1.0",
612
- "symfony/process": "^2.5 || ^3.0 || ^4.0"
613
  },
614
- "time": "2019-01-28T09:30:10+00:00",
615
  "type": "library",
616
  "extra": {
617
  "branch-alias": {
618
- "dev-master": "1.x-dev"
619
  }
620
  },
621
  "installation-source": "dist",
622
  "autoload": {
623
  "psr-4": {
624
- "Composer\\CaBundle\\": "src"
625
  }
626
  },
627
  "notification-url": "https://packagist.org/downloads/",
@@ -630,55 +626,71 @@
630
  ],
631
  "authors": [
632
  {
633
- "name": "Jordi Boggiano",
634
- "email": "j.boggiano@seld.be",
635
- "homepage": "http://seld.be"
636
  }
637
  ],
638
- "description": "Lets you find a path to the system CA bundle, and includes a fallback to the Mozilla CA bundle.",
 
639
  "keywords": [
640
- "cabundle",
641
- "cacert",
642
- "certificate",
643
- "ssl",
644
- "tls"
645
  ]
646
  },
647
  {
648
- "name": "fernleafsystems/utilities",
649
- "version": "1.3.1",
650
- "version_normalized": "1.3.1.0",
651
  "source": {
652
  "type": "git",
653
- "url": "https://github.com/FernleafSystems/Utilities.git",
654
- "reference": "9a96fb25d93c893edc08477e8e50d1e93a817bec"
655
  },
656
  "dist": {
657
  "type": "zip",
658
- "url": "https://api.github.com/repos/FernleafSystems/Utilities/zipball/9a96fb25d93c893edc08477e8e50d1e93a817bec",
659
- "reference": "9a96fb25d93c893edc08477e8e50d1e93a817bec",
660
  "shasum": ""
661
  },
662
  "require": {
663
- "php": ">=5.4"
 
 
664
  },
665
- "time": "2019-02-01T09:56:28+00:00",
 
 
 
 
666
  "type": "library",
667
  "installation-source": "dist",
668
  "autoload": {
669
  "psr-4": {
670
- "FernleafSystems\\Utilities\\": "src"
671
  }
672
  },
673
  "notification-url": "https://packagist.org/downloads/",
 
 
 
674
  "authors": [
675
  {
676
- "name": "Paul Goodchild",
677
- "email": "paul@paulgoodchild.me",
678
- "homepage": "https://paulgoodchild.me"
679
  }
680
  ],
681
- "description": "Collection of simple utilities and traits"
 
 
 
 
 
 
 
682
  },
683
  {
684
  "name": "symfony/polyfill-ctype",
@@ -801,6 +813,124 @@
801
  "shim"
802
  ]
803
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
804
  {
805
  "name": "twig/twig",
806
  "version": "v1.38.4",
@@ -868,47 +998,5 @@
868
  "keywords": [
869
  "templating"
870
  ]
871
- },
872
- {
873
- "name": "fernleafsystems/wordpress-services",
874
- "version": "dev-develop",
875
- "version_normalized": "dev-develop",
876
- "source": {
877
- "type": "git",
878
- "url": "https://bitbucket.org/FernleafSystems/wordpress-services.git",
879
- "reference": "1dfc3b46711bd27c0fcca6dbfda00307ae042beb"
880
- },
881
- "dist": {
882
- "type": "zip",
883
- "url": "https://bitbucket.org/FernleafSystems/wordpress-services/get/1dfc3b46711bd27c0fcca6dbfda00307ae042beb.zip",
884
- "reference": "1dfc3b46711bd27c0fcca6dbfda00307ae042beb",
885
- "shasum": ""
886
- },
887
- "require": {
888
- "fernleafsystems/utilities": "^1.3.1",
889
- "geoip2/geoip2": "^2.0",
890
- "google/recaptcha": "~1.1",
891
- "php": ">=5.4.0",
892
- "pimple/pimple": "~3.0",
893
- "soundasleep/html2text": "~0.5.0",
894
- "symfony/yaml": "~2.0||~3.0",
895
- "twig/twig": "^1.0"
896
- },
897
- "time": "2019-03-23T15:40:07+00:00",
898
- "type": "library",
899
- "installation-source": "source",
900
- "autoload": {
901
- "psr-4": {
902
- "FernleafSystems\\Wordpress\\Services\\": "src"
903
- }
904
- },
905
- "notification-url": "https://packagist.org/downloads/",
906
- "authors": [
907
- {
908
- "name": "Paul Goodchild",
909
- "email": "paul@icontrolwp.com"
910
- }
911
- ],
912
- "homepage": "https://bitbucket.org/FernleafSystems/wordpress-services"
913
  }
914
  ]
47
  ]
48
  },
49
  {
50
+ "name": "composer/ca-bundle",
51
+ "version": "1.1.4",
52
+ "version_normalized": "1.1.4.0",
53
  "source": {
54
  "type": "git",
55
+ "url": "https://github.com/composer/ca-bundle.git",
56
+ "reference": "558f321c52faeb4828c03e7dc0cfe39a09e09a2d"
57
  },
58
  "dist": {
59
  "type": "zip",
60
+ "url": "https://api.github.com/repos/composer/ca-bundle/zipball/558f321c52faeb4828c03e7dc0cfe39a09e09a2d",
61
+ "reference": "558f321c52faeb4828c03e7dc0cfe39a09e09a2d",
62
  "shasum": ""
63
  },
64
  "require": {
65
+ "ext-openssl": "*",
66
+ "ext-pcre": "*",
67
+ "php": "^5.3.2 || ^7.0"
 
68
  },
69
  "require-dev": {
70
+ "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5",
71
+ "psr/log": "^1.0",
72
+ "symfony/process": "^2.5 || ^3.0 || ^4.0"
73
  },
74
+ "time": "2019-01-28T09:30:10+00:00",
75
  "type": "library",
76
+ "extra": {
77
+ "branch-alias": {
78
+ "dev-master": "1.x-dev"
79
+ }
80
+ },
81
  "installation-source": "dist",
82
  "autoload": {
83
  "psr-4": {
84
+ "Composer\\CaBundle\\": "src"
 
85
  }
86
  },
87
  "notification-url": "https://packagist.org/downloads/",
88
  "license": [
89
+ "MIT"
90
  ],
91
  "authors": [
92
  {
93
+ "name": "Jordi Boggiano",
94
+ "email": "j.boggiano@seld.be",
95
+ "homepage": "http://seld.be"
96
  }
97
  ],
98
+ "description": "Lets you find a path to the system CA bundle, and includes a fallback to the Mozilla CA bundle.",
99
+ "keywords": [
100
+ "cabundle",
101
+ "cacert",
102
+ "certificate",
103
+ "ssl",
104
+ "tls"
105
+ ]
106
  },
107
  {
108
+ "name": "elliotchance/iterator",
109
+ "version": "v1.1.0",
110
+ "version_normalized": "1.1.0.0",
111
  "source": {
112
  "type": "git",
113
+ "url": "https://github.com/elliotchance/iterator.git",
114
+ "reference": "1167635743c394721b443fe8f81532c62a211a38"
115
  },
116
  "dist": {
117
  "type": "zip",
118
+ "url": "https://api.github.com/repos/elliotchance/iterator/zipball/1167635743c394721b443fe8f81532c62a211a38",
119
+ "reference": "1167635743c394721b443fe8f81532c62a211a38",
120
  "shasum": ""
121
  },
 
 
 
 
 
122
  "require-dev": {
123
+ "elliotchance/concise": "~1.7",
124
+ "phpunit/phpunit": "~4.0"
 
125
  },
126
+ "time": "2017-11-09T22:25:19+00:00",
127
  "type": "library",
128
  "installation-source": "dist",
129
  "autoload": {
130
+ "psr-0": {
131
+ "": [
132
+ "tests/",
133
+ "src/"
134
+ ]
135
  }
136
  },
137
  "notification-url": "https://packagist.org/downloads/",
138
  "license": [
139
+ "MIT"
140
  ],
141
  "authors": [
142
  {
143
+ "name": "Elliot Chance",
144
+ "email": "elliotchance@gmail.com"
 
145
  }
146
  ],
147
+ "description": "Iterator builders for PHP"
 
 
 
 
 
 
 
 
148
  },
149
  {
150
+ "name": "fernleafsystems/utilities",
151
+ "version": "1.3.3",
152
+ "version_normalized": "1.3.3.0",
153
  "source": {
154
  "type": "git",
155
+ "url": "https://github.com/FernleafSystems/Utilities.git",
156
+ "reference": "e405770bf8eab6a05a3203b8935dd38088f7a347"
157
  },
158
  "dist": {
159
  "type": "zip",
160
+ "url": "https://api.github.com/repos/FernleafSystems/Utilities/zipball/e405770bf8eab6a05a3203b8935dd38088f7a347",
161
+ "reference": "e405770bf8eab6a05a3203b8935dd38088f7a347",
162
  "shasum": ""
163
  },
164
  "require": {
165
+ "elliotchance/iterator": "^1.1.0",
166
+ "php": ">=5.4"
 
 
 
 
 
167
  },
168
+ "time": "2019-03-29T14:14:07+00:00",
169
  "type": "library",
170
  "installation-source": "dist",
171
  "autoload": {
172
  "psr-4": {
173
+ "FernleafSystems\\Utilities\\": "src"
174
  }
175
  },
176
  "notification-url": "https://packagist.org/downloads/",
 
 
 
177
  "authors": [
178
  {
179
+ "name": "Paul Goodchild",
180
+ "email": "paul@paulgoodchild.me",
181
+ "homepage": "https://paulgoodchild.me"
182
  }
183
  ],
184
+ "description": "Collection of simple utilities and traits"
 
 
 
 
 
 
 
185
  },
186
  {
187
+ "name": "fernleafsystems/wordpress-services",
188
+ "version": "dev-develop",
189
+ "version_normalized": "dev-develop",
190
  "source": {
191
  "type": "git",
192
+ "url": "https://bitbucket.org/FernleafSystems/wordpress-services.git",
193
+ "reference": "1aeb2d8c6f491f8520179077aaaae0000969a2c2"
194
  },
195
  "dist": {
196
  "type": "zip",
197
+ "url": "https://bitbucket.org/FernleafSystems/wordpress-services/get/1aeb2d8c6f491f8520179077aaaae0000969a2c2.zip",
198
+ "reference": "1aeb2d8c6f491f8520179077aaaae0000969a2c2",
199
  "shasum": ""
200
  },
201
  "require": {
202
+ "fernleafsystems/utilities": "^1.3.3",
203
+ "geoip2/geoip2": "^2.0",
204
+ "google/recaptcha": "~1.1",
205
+ "php": ">=5.4.0",
206
+ "pimple/pimple": "~3.0",
207
+ "soundasleep/html2text": "~0.5.0",
208
+ "symfony/yaml": "~2.0||~3.0",
209
+ "twig/twig": "^1.0"
210
  },
211
+ "time": "2019-04-15T16:02:49+00:00",
212
  "type": "library",
213
+ "installation-source": "source",
 
 
 
 
 
214
  "autoload": {
215
  "psr-4": {
216
+ "FernleafSystems\\Wordpress\\Services\\": "src"
217
  }
218
  },
219
  "notification-url": "https://packagist.org/downloads/",
 
 
 
220
  "authors": [
221
  {
222
+ "name": "Paul Goodchild",
223
+ "email": "paul@icontrolwp.com"
224
  }
225
  ],
226
+ "homepage": "https://bitbucket.org/FernleafSystems/wordpress-services"
 
 
 
 
 
 
 
 
227
  },
228
  {
229
+ "name": "geoip2/geoip2",
230
+ "version": "v2.9.0",
231
+ "version_normalized": "2.9.0.0",
232
  "source": {
233
  "type": "git",
234
+ "url": "https://github.com/maxmind/GeoIP2-php.git",
235
+ "reference": "a807fbf65212eef5d8d2db1a1b31082b53633d77"
236
  },
237
  "dist": {
238
  "type": "zip",
239
+ "url": "https://api.github.com/repos/maxmind/GeoIP2-php/zipball/a807fbf65212eef5d8d2db1a1b31082b53633d77",
240
+ "reference": "a807fbf65212eef5d8d2db1a1b31082b53633d77",
241
  "shasum": ""
242
  },
243
  "require": {
244
+ "maxmind-db/reader": "~1.0",
245
+ "maxmind/web-service-common": "~0.5",
246
+ "php": ">=5.4"
247
  },
248
  "require-dev": {
249
+ "friendsofphp/php-cs-fixer": "2.*",
250
+ "phpunit/phpunit": "4.*",
251
+ "squizlabs/php_codesniffer": "3.*"
252
  },
253
+ "time": "2018-04-10T15:32:59+00:00",
254
  "type": "library",
 
 
 
 
 
255
  "installation-source": "dist",
256
  "autoload": {
257
+ "psr-4": {
258
+ "GeoIp2\\": "src"
259
  }
260
  },
261
  "notification-url": "https://packagist.org/downloads/",
262
  "license": [
263
+ "Apache-2.0"
264
  ],
265
  "authors": [
266
  {
267
+ "name": "Gregory J. Oschwald",
268
+ "email": "goschwald@maxmind.com",
269
+ "homepage": "http://www.maxmind.com/"
270
  }
271
  ],
272
+ "description": "MaxMind GeoIP2 PHP API",
273
+ "homepage": "https://github.com/maxmind/GeoIP2-php",
274
  "keywords": [
275
+ "IP",
276
+ "geoip",
277
+ "geoip2",
278
+ "geolocation",
279
+ "maxmind"
280
  ]
281
  },
282
  {
327
  ]
328
  },
329
  {
330
+ "name": "maxmind-db/reader",
331
+ "version": "v1.4.1",
332
+ "version_normalized": "1.4.1.0",
333
  "source": {
334
  "type": "git",
335
+ "url": "https://github.com/maxmind/MaxMind-DB-Reader-php.git",
336
+ "reference": "eb83d0ee1c1f9b8a340206302136bc81ee02ae74"
337
  },
338
  "dist": {
339
  "type": "zip",
340
+ "url": "https://api.github.com/repos/maxmind/MaxMind-DB-Reader-php/zipball/eb83d0ee1c1f9b8a340206302136bc81ee02ae74",
341
+ "reference": "eb83d0ee1c1f9b8a340206302136bc81ee02ae74",
342
  "shasum": ""
343
  },
344
  "require": {
345
+ "php": ">=5.4"
 
346
  },
347
+ "require-dev": {
348
+ "friendsofphp/php-cs-fixer": "2.*",
349
+ "phpunit/phpunit": "4.* || 5.*",
350
+ "satooshi/php-coveralls": "1.0.*",
351
+ "squizlabs/php_codesniffer": "3.*"
 
352
  },
353
+ "suggest": {
354
+ "ext-bcmath": "bcmath or gmp is required for decoding larger integers with the pure PHP decoder",
355
+ "ext-gmp": "bcmath or gmp is required for decoding larger integers with the pure PHP decoder",
356
+ "ext-maxminddb": "A C-based database decoder that provides significantly faster lookups"
357
+ },
358
+ "time": "2019-01-04T19:55:56+00:00",
359
+ "type": "library",
360
  "installation-source": "dist",
361
  "autoload": {
362
  "psr-4": {
363
+ "MaxMind\\Db\\": "src/MaxMind/Db"
364
+ }
 
 
 
365
  },
366
  "notification-url": "https://packagist.org/downloads/",
367
  "license": [
368
+ "Apache-2.0"
369
  ],
370
  "authors": [
371
  {
372
+ "name": "Gregory J. Oschwald",
373
+ "email": "goschwald@maxmind.com",
374
+ "homepage": "http://www.maxmind.com/"
 
 
 
375
  }
376
  ],
377
+ "description": "MaxMind DB Reader API",
378
+ "homepage": "https://github.com/maxmind/MaxMind-DB-Reader-php",
379
+ "keywords": [
380
+ "database",
381
+ "geoip",
382
+ "geoip2",
383
+ "geolocation",
384
+ "maxmind"
385
+ ]
386
  },
387
  {
388
+ "name": "maxmind/web-service-common",
389
+ "version": "v0.5.0",
390
+ "version_normalized": "0.5.0.0",
391
  "source": {
392
  "type": "git",
393
+ "url": "https://github.com/maxmind/web-service-common-php.git",
394
+ "reference": "61a9836fa3bb1743ab89752bae5005d71e78c73b"
395
  },
396
  "dist": {
397
  "type": "zip",
398
+ "url": "https://api.github.com/repos/maxmind/web-service-common-php/zipball/61a9836fa3bb1743ab89752bae5005d71e78c73b",
399
+ "reference": "61a9836fa3bb1743ab89752bae5005d71e78c73b",
400
  "shasum": ""
401
  },
402
  "require": {
403
+ "composer/ca-bundle": "^1.0.3",
404
+ "ext-curl": "*",
405
+ "ext-json": "*",
406
+ "php": ">=5.4"
 
407
  },
408
  "require-dev": {
409
+ "friendsofphp/php-cs-fixer": "2.*",
410
+ "phpunit/phpunit": "4.*",
411
+ "squizlabs/php_codesniffer": "3.*"
 
 
 
 
 
 
412
  },
413
+ "time": "2018-02-12T22:31:54+00:00",
414
  "type": "library",
 
 
 
 
 
415
  "installation-source": "dist",
416
  "autoload": {
417
  "psr-4": {
418
+ "MaxMind\\Exception\\": "src/Exception",
419
+ "MaxMind\\WebService\\": "src/WebService"
420
+ }
 
 
421
  },
422
  "notification-url": "https://packagist.org/downloads/",
423
  "license": [
424
+ "Apache-2.0"
425
  ],
426
  "authors": [
427
  {
428
+ "name": "Gregory Oschwald",
429
+ "email": "goschwald@maxmind.com"
 
 
 
 
430
  }
431
  ],
432
+ "description": "Internal MaxMind Web Service API",
433
+ "homepage": "https://github.com/maxmind/web-service-common-php"
434
  },
435
  {
436
  "name": "nesbot/carbon",
493
  ]
494
  },
495
  {
496
+ "name": "nullpunkt/lz-string-php",
497
+ "version": "v1.2.0",
498
+ "version_normalized": "1.2.0.0",
499
  "source": {
500
  "type": "git",
501
+ "url": "https://github.com/nullpunkt/lz-string-php.git",
502
+ "reference": "b08fc07df528c7e3d05b47e6013dde63eebffb48"
503
  },
504
  "dist": {
505
  "type": "zip",
506
+ "url": "https://api.github.com/repos/nullpunkt/lz-string-php/zipball/b08fc07df528c7e3d05b47e6013dde63eebffb48",
507
+ "reference": "b08fc07df528c7e3d05b47e6013dde63eebffb48",
508
  "shasum": ""
509
  },
510
  "require": {
511
+ "php": ">=5.3.0"
512
  },
513
  "require-dev": {
514
+ "monolog/monolog": "^1.17",
515
+ "phpunit/phpunit": "~5.1"
 
 
516
  },
517
+ "time": "2016-03-23T09:49:56+00:00",
 
 
 
 
 
518
  "type": "library",
519
  "installation-source": "dist",
520
  "autoload": {
521
  "psr-4": {
522
+ "LZCompressor\\": "src/LZCompressor"
523
+ }
524
+ },
525
+ "notification-url": "https://packagist.org/downloads/",
526
+ "authors": [
527
+ {
528
+ "name": "Tobias Seipke",
529
+ "email": "tobias.seipke@gmail.com",
530
+ "homepage": "https://github.com/nullpunkt"
531
+ },
532
+ {
533
+ "name": "Juhász Ádám",
534
+ "email": "juhasz.adam@virgo.hu",
535
+ "homepage": "https://github.com/JuhaszAdam"
536
+ }
537
+ ],
538
+ "description": "PHP Class implementation of LZ-String javascript."
539
+ },
540
+ {
541
+ "name": "pimple/pimple",
542
+ "version": "v3.2.3",
543
+ "version_normalized": "3.2.3.0",
544
+ "source": {
545
+ "type": "git",
546
+ "url": "https://github.com/silexphp/Pimple.git",
547
+ "reference": "9e403941ef9d65d20cba7d54e29fe906db42cf32"
548
+ },
549
+ "dist": {
550
+ "type": "zip",
551
+ "url": "https://api.github.com/repos/silexphp/Pimple/zipball/9e403941ef9d65d20cba7d54e29fe906db42cf32",
552
+ "reference": "9e403941ef9d65d20cba7d54e29fe906db42cf32",
553
+ "shasum": ""
554
+ },
555
+ "require": {
556
+ "php": ">=5.3.0",
557
+ "psr/container": "^1.0"
558
+ },
559
+ "require-dev": {
560
+ "symfony/phpunit-bridge": "^3.2"
561
+ },
562
+ "time": "2018-01-21T07:42:36+00:00",
563
+ "type": "library",
564
+ "extra": {
565
+ "branch-alias": {
566
+ "dev-master": "3.2.x-dev"
567
+ }
568
+ },
569
+ "installation-source": "dist",
570
+ "autoload": {
571
+ "psr-0": {
572
+ "Pimple": "src/"
573
  }
574
  },
575
  "notification-url": "https://packagist.org/downloads/",
576
  "license": [
577
+ "MIT"
578
  ],
579
  "authors": [
580
  {
581
+ "name": "Fabien Potencier",
582
+ "email": "fabien@symfony.com"
 
583
  }
584
  ],
585
+ "description": "Pimple, a simple Dependency Injection Container",
586
+ "homepage": "http://pimple.sensiolabs.org",
587
  "keywords": [
588
+ "container",
589
+ "dependency injection"
 
 
 
590
  ]
591
  },
592
  {
593
+ "name": "psr/container",
594
+ "version": "1.0.0",
595
+ "version_normalized": "1.0.0.0",
596
  "source": {
597
  "type": "git",
598
+ "url": "https://github.com/php-fig/container.git",
599
+ "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f"
600
  },
601
  "dist": {
602
  "type": "zip",
603
+ "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
604
+ "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
605
  "shasum": ""
606
  },
607
  "require": {
608
+ "php": ">=5.3.0"
 
 
 
 
 
 
 
609
  },
610
+ "time": "2017-02-14T16:28:37+00:00",
611
  "type": "library",
612
  "extra": {
613
  "branch-alias": {
614
+ "dev-master": "1.0.x-dev"
615
  }
616
  },
617
  "installation-source": "dist",
618
  "autoload": {
619
  "psr-4": {
620
+ "Psr\\Container\\": "src/"
621
  }
622
  },
623
  "notification-url": "https://packagist.org/downloads/",
626
  ],
627
  "authors": [
628
  {
629
+ "name": "PHP-FIG",
630
+ "homepage": "http://www.php-fig.org/"
 
631
  }
632
  ],
633
+ "description": "Common Container Interface (PHP FIG PSR-11)",
634
+ "homepage": "https://github.com/php-fig/container",
635
  "keywords": [
636
+ "PSR-11",
637
+ "container",
638
+ "container-interface",
639
+ "container-interop",
640
+ "psr"
641
  ]
642
  },
643
  {
644
+ "name": "soundasleep/html2text",
645
+ "version": "0.5.0",
646
+ "version_normalized": "0.5.0.0",
647
  "source": {
648
  "type": "git",
649
+ "url": "https://github.com/soundasleep/html2text.git",
650
+ "reference": "cdb89f6ffa2c4cc78f8ed9ea6ee0594a9133ccad"
651
  },
652
  "dist": {
653
  "type": "zip",
654
+ "url": "https://api.github.com/repos/soundasleep/html2text/zipball/cdb89f6ffa2c4cc78f8ed9ea6ee0594a9133ccad",
655
+ "reference": "cdb89f6ffa2c4cc78f8ed9ea6ee0594a9133ccad",
656
  "shasum": ""
657
  },
658
  "require": {
659
+ "ext-dom": "*",
660
+ "ext-libxml": "*",
661
+ "php": ">=5.3.2"
662
  },
663
+ "require-dev": {
664
+ "phpunit/phpunit": ">=4.0",
665
+ "soundasleep/component-tests": "dev-master"
666
+ },
667
+ "time": "2017-04-19T22:01:50+00:00",
668
  "type": "library",
669
  "installation-source": "dist",
670
  "autoload": {
671
  "psr-4": {
672
+ "Html2Text\\": "src"
673
  }
674
  },
675
  "notification-url": "https://packagist.org/downloads/",
676
+ "license": [
677
+ "EPL-1.0"
678
+ ],
679
  "authors": [
680
  {
681
+ "name": "Jevon Wright",
682
+ "homepage": "https://jevon.org",
683
+ "role": "Developer"
684
  }
685
  ],
686
+ "description": "A PHP script to convert HTML into a plain text format",
687
+ "homepage": "https://github.com/soundasleep/html2text",
688
+ "keywords": [
689
+ "email",
690
+ "html",
691
+ "php",
692
+ "text"
693
+ ]
694
  },
695
  {
696
  "name": "symfony/polyfill-ctype",
813
  "shim"
814
  ]
815
  },
816
+ {
817
+ "name": "symfony/translation",
818
+ "version": "v2.8.50",
819
+ "version_normalized": "2.8.50.0",
820
+ "source": {
821
+ "type": "git",
822
+ "url": "https://github.com/symfony/translation.git",
823
+ "reference": "fc58c2a19e56c29f5ba2736ec40d0119a0de2089"
824
+ },
825
+ "dist": {
826
+ "type": "zip",
827
+ "url": "https://api.github.com/repos/symfony/translation/zipball/fc58c2a19e56c29f5ba2736ec40d0119a0de2089",
828
+ "reference": "fc58c2a19e56c29f5ba2736ec40d0119a0de2089",
829
+ "shasum": ""
830
+ },
831
+ "require": {
832
+ "php": ">=5.3.9",
833
+ "symfony/polyfill-mbstring": "~1.0"
834
+ },
835
+ "conflict": {
836
+ "symfony/config": "<2.7"
837
+ },
838
+ "require-dev": {
839
+ "psr/log": "~1.0",
840
+ "symfony/config": "~2.8",
841
+ "symfony/intl": "~2.7.25|^2.8.18|~3.2.5",
842
+ "symfony/yaml": "~2.2|~3.0.0"
843
+ },
844
+ "suggest": {
845
+ "psr/log-implementation": "To use logging capability in translator",
846
+ "symfony/config": "",
847
+ "symfony/yaml": ""
848
+ },
849
+ "time": "2018-11-24T21:16:41+00:00",
850
+ "type": "library",
851
+ "extra": {
852
+ "branch-alias": {
853
+ "dev-master": "2.8-dev"
854
+ }
855
+ },
856
+ "installation-source": "dist",
857
+ "autoload": {
858
+ "psr-4": {
859
+ "Symfony\\Component\\Translation\\": ""
860
+ },
861
+ "exclude-from-classmap": [
862
+ "/Tests/"
863
+ ]
864
+ },
865
+ "notification-url": "https://packagist.org/downloads/",
866
+ "license": [
867
+ "MIT"
868
+ ],
869
+ "authors": [
870
+ {
871
+ "name": "Fabien Potencier",
872
+ "email": "fabien@symfony.com"
873
+ },
874
+ {
875
+ "name": "Symfony Community",
876
+ "homepage": "https://symfony.com/contributors"
877
+ }
878
+ ],
879
+ "description": "Symfony Translation Component",
880
+ "homepage": "https://symfony.com"
881
+ },
882
+ {
883
+ "name": "symfony/yaml",
884
+ "version": "v2.8.50",
885
+ "version_normalized": "2.8.50.0",
886
+ "source": {
887
+ "type": "git",
888
+ "url": "https://github.com/symfony/yaml.git",
889
+ "reference": "02c1859112aa779d9ab394ae4f3381911d84052b"
890
+ },
891
+ "dist": {
892
+ "type": "zip",
893
+ "url": "https://api.github.com/repos/symfony/yaml/zipball/02c1859112aa779d9ab394ae4f3381911d84052b",
894
+ "reference": "02c1859112aa779d9ab394ae4f3381911d84052b",
895
+ "shasum": ""
896
+ },
897
+ "require": {
898
+ "php": ">=5.3.9",
899
+ "symfony/polyfill-ctype": "~1.8"
900
+ },
901
+ "time": "2018-11-11T11:18:13+00:00",
902
+ "type": "library",
903
+ "extra": {
904
+ "branch-alias": {
905
+ "dev-master": "2.8-dev"
906
+ }
907
+ },
908
+ "installation-source": "dist",
909
+ "autoload": {
910
+ "psr-4": {
911
+ "Symfony\\Component\\Yaml\\": ""
912
+ },
913
+ "exclude-from-classmap": [
914
+ "/Tests/"
915
+ ]
916
+ },
917
+ "notification-url": "https://packagist.org/downloads/",
918
+ "license": [
919
+ "MIT"
920
+ ],
921
+ "authors": [
922
+ {
923
+ "name": "Fabien Potencier",
924
+ "email": "fabien@symfony.com"
925
+ },
926
+ {
927
+ "name": "Symfony Community",
928
+ "homepage": "https://symfony.com/contributors"
929
+ }
930
+ ],
931
+ "description": "Symfony Yaml Component",
932
+ "homepage": "https://symfony.com"
933
+ },
934
  {
935
  "name": "twig/twig",
936
  "version": "v1.38.4",
998
  "keywords": [
999
  "templating"
1000
  ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1001
  }
1002
  ]
src/lib/vendor/elliotchance/iterator/src/Elliotchance/Iterator/AbstractPagedIterator.php ADDED
@@ -0,0 +1,144 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Elliotchance\Iterator;
4
+
5
+ use ArrayAccess;
6
+ use Countable;
7
+ use InvalidArgumentException;
8
+ use Iterator;
9
+ use LogicException;
10
+ use OutOfBoundsException;
11
+
12
+ abstract class AbstractPagedIterator implements Countable, ArrayAccess, Iterator
13
+ {
14
+ /**
15
+ * @var array
16
+ */
17
+ protected $cachedPages = [];
18
+
19
+ /**
20
+ * @var array
21
+ */
22
+ protected $currentPage;
23
+
24
+ /**
25
+ * @var int
26
+ */
27
+ protected $currentPageNumber;
28
+
29
+ /**
30
+ * @var bool
31
+ */
32
+ protected $useCache = true;
33
+
34
+ /**
35
+ * @var integer
36
+ */
37
+ protected $index = 0;
38
+
39
+ /**
40
+ * @return integer
41
+ */
42
+ abstract public function getPageSize();
43
+
44
+ /**
45
+ * @return integer
46
+ */
47
+ abstract public function getTotalSize();
48
+
49
+ /**
50
+ * @param integer $pageNumber
51
+ * @return array
52
+ */
53
+ abstract public function getPage($pageNumber);
54
+
55
+ /**
56
+ * @return integer
57
+ */
58
+ public function count()
59
+ {
60
+ return $this->getTotalSize();
61
+ }
62
+
63
+ /**
64
+ * @param integer $offset
65
+ * @return bool
66
+ */
67
+ public function offsetExists($offset)
68
+ {
69
+ return $offset >= 0 && $offset < $this->getTotalSize();
70
+ }
71
+
72
+ /**
73
+ * @param integer $offset
74
+ * @return mixed
75
+ * @throws InvalidArgumentException
76
+ * @throws OutOfBoundsException
77
+ */
78
+ public function offsetGet($offset)
79
+ {
80
+ if (!is_int($offset)) {
81
+ throw new InvalidArgumentException("Index must be a positive integer: $offset");
82
+ }
83
+ if (!$this->offsetExists($offset)) {
84
+ throw new OutOfBoundsException("Index out of bounds: $offset");
85
+ }
86
+
87
+ $page = (int) ($offset / $this->getPageSize());
88
+ if ($this->useCache) {
89
+ if (!array_key_exists($page, $this->cachedPages)) {
90
+ $this->cachedPages[$page] = $this->getPage($page);
91
+ }
92
+ return $this->cachedPages[$page][$offset % $this->getPageSize()];
93
+ }
94
+
95
+ if ($page !== $this->currentPageNumber) {
96
+ $this->currentPageNumber = $page;
97
+ $this->currentPage = $this->getPage($page);
98
+ }
99
+ return $this->currentPage[$offset % $this->getPageSize()];
100
+ }
101
+
102
+ /**
103
+ * @param integer $offset
104
+ * @param mixed $value
105
+ * @throws LogicException
106
+ */
107
+ public function offsetSet($offset, $value)
108
+ {
109
+ throw new LogicException("Setting values is not allowed.");
110
+ }
111
+
112
+ /**
113
+ * @param integer $offset
114
+ */
115
+ public function offsetUnset($offset)
116
+ {
117
+ throw new LogicException("Unsetting values is not allowed.");
118
+ }
119
+
120
+ public function current()
121
+ {
122
+ return $this->offsetGet($this->index);
123
+ }
124
+
125
+ public function key()
126
+ {
127
+ return $this->index;
128
+ }
129
+
130
+ public function next()
131
+ {
132
+ ++$this->index;
133
+ }
134
+
135
+ public function rewind()
136
+ {
137
+ $this->index = 0;
138
+ }
139
+
140
+ public function valid()
141
+ {
142
+ return $this->offsetExists($this->index);
143
+ }
144
+ }
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Iterators/WpUserIterator.php ADDED
@@ -0,0 +1,134 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace FernleafSystems\Wordpress\Services\Utilities\Iterators;
4
+
5
+ /**
6
+ * Class WpUserIterator
7
+ * @package FernleafSystems\Wordpress\Plugin\Shield\Users
8
+ */
9
+ class WpUserIterator extends \Elliotchance\Iterator\AbstractPagedIterator {
10
+
11
+ const PAGE_LIMIT = 50;
12
+
13
+ /**
14
+ * @var int
15
+ */
16
+ protected $nTotalSize;
17
+
18
+ /**
19
+ * @var array
20
+ */
21
+ private $aQueryFilters;
22
+
23
+ /**
24
+ * @return \WP_User
25
+ */
26
+ public function current() {
27
+ return parent::current();
28
+ }
29
+
30
+ /**
31
+ * @param string $sMetaKey
32
+ * @param mixed $sMetaValue
33
+ * @param string $sComparison
34
+ * @return $this
35
+ */
36
+ public function filterByMeta( $sMetaKey, $sMetaValue, $sComparison = '=' ) {
37
+ return $this->setCustomQueryFilter( 'meta_key', $sMetaKey )
38
+ ->setCustomQueryFilter( 'meta_value', $sMetaValue )
39
+ ->setCustomQueryFilter( 'meta_compare', $sComparison );
40
+ }
41
+
42
+ /**
43
+ * @return array
44
+ */
45
+ public function getCustomQueryFilters() {
46
+ return is_array( $this->aQueryFilters ) ? $this->aQueryFilters : [];
47
+ }
48
+
49
+ /**
50
+ * @return array
51
+ */
52
+ protected function getDefaultQueryFilters() {
53
+ return [
54
+ 'orderby' => 'ID',
55
+ 'order' => 'ASC',
56
+ 'paged' => 1,
57
+ 'number' => $this->getPageSize(),
58
+ ];
59
+ }
60
+
61
+ /**
62
+ * @return array
63
+ */
64
+ protected function getFinalQueryFilters() {
65
+ return array_merge( $this->getDefaultQueryFilters(), $this->getCustomQueryFilters() );
66
+ }
67
+
68
+ /**
69
+ * @param array $aQuery
70
+ * @return $this
71
+ */
72
+ public function setCustomQueryFilters( $aQuery ) {
73
+ if ( is_array( $aQuery ) ) {
74
+ if ( isset( $aQuery[ 'number' ] ) && (int)$aQuery[ 'number' ] < 0 ) {
75
+ unset( $aQuery[ 'number' ] );
76
+ }
77
+ $this->aQueryFilters = $aQuery;
78
+ }
79
+ return $this;
80
+ }
81
+
82
+ /**
83
+ * @param string $sKey
84
+ * @param mixed $mValue
85
+ * @return $this
86
+ */
87
+ public function setCustomQueryFilter( $sKey, $mValue ) {
88
+ $aQ = $this->getCustomQueryFilters();
89
+ $aQ[ $sKey ] = $mValue;
90
+ return $this->setCustomQueryFilters( $aQ );
91
+ }
92
+
93
+ /**
94
+ * @return int
95
+ */
96
+ public function getTotalSize() {
97
+ if ( !isset( $this->nTotalSize ) ) {
98
+ $this->nTotalSize = $this->setCustomQueryFilter( 'count_total', true )
99
+ ->runQuery()
100
+ ->get_total();
101
+ $this->setCustomQueryFilter( 'count_total', null );
102
+ }
103
+ return $this->nTotalSize;
104
+ }
105
+
106
+ /**
107
+ * @param int $nPage - starts at zero
108
+ * @return \WP_User[]
109
+ */
110
+ public function getPage( $nPage ) {
111
+ return $this->setCustomQueryFilter( 'paged', $nPage + 1 )
112
+ ->runQuery()
113
+ ->get_results();
114
+ }
115
+
116
+ /**
117
+ * @return \WP_User_Query
118
+ */
119
+ protected function runQuery() {
120
+ return new \WP_User_Query( $this->getFinalQueryFilters() );
121
+ }
122
+
123
+ /**
124
+ * @return int
125
+ */
126
+ public function getPageSize() {
127
+ return static::PAGE_LIMIT;
128
+ }
129
+
130
+ public function rewind() {
131
+ parent::rewind();
132
+ unset( $this->nTotalSize );
133
+ }
134
+ }
src/lib/vendor/nullpunkt/lz-string-php/src/LZCompressor/LZContext.php ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace LZCompressor;
3
+
4
+ class LZContext
5
+ {
6
+ /**
7
+ * @var array
8
+ */
9
+ public $dictionary = [];
10
+
11
+ /**
12
+ * @var array
13
+ */
14
+ public $dictionaryToCreate = [];
15
+
16
+ /**
17
+ * @var string
18
+ */
19
+ public $c = '';
20
+
21
+ /**
22
+ * @var string
23
+ */
24
+ public $wc = '';
25
+
26
+ /**
27
+ * @var string
28
+ */
29
+ public $w = '';
30
+
31
+ /**
32
+ * @var int
33
+ */
34
+ public $enlargeIn = 2;
35
+
36
+ /**
37
+ * @var int
38
+ */
39
+ public $dictSize = 3;
40
+
41
+ /**
42
+ * @var int
43
+ */
44
+ public $numBits = 2;
45
+
46
+ /**
47
+ * @var LZData
48
+ */
49
+ public $data;
50
+
51
+ function __construct()
52
+ {
53
+ $this->data = new LZData;
54
+ }
55
+
56
+ // Helper
57
+
58
+ /**
59
+ * @param string $val
60
+ * @return bool
61
+ */
62
+ public function dictionaryContains($val) {
63
+ return array_key_exists($val, $this->dictionary);
64
+ }
65
+
66
+ /**
67
+ * @param $val
68
+ */
69
+ public function addToDictionary($val) {
70
+ $this->dictionary[$val] = $this->dictSize++;
71
+ }
72
+
73
+ /**
74
+ * @param string $val
75
+ * @return bool
76
+ */
77
+ public function dictionaryToCreateContains($val) {
78
+ return array_key_exists($val, $this->dictionaryToCreate);
79
+ }
80
+
81
+ /**
82
+ * decrements enlargeIn and extends numbits in case enlargeIn drops to 0
83
+ */
84
+ public function enlargeIn() {
85
+ $this->enlargeIn--;
86
+ if($this->enlargeIn==0) {
87
+ $this->enlargeIn = pow(2, $this->numBits);
88
+ $this->numBits++;
89
+ }
90
+ }
91
+ }
src/lib/vendor/nullpunkt/lz-string-php/src/LZCompressor/LZData.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace LZCompressor;
3
+
4
+ class LZData
5
+ {
6
+ /**
7
+ * @var
8
+ */
9
+ public $str = '';
10
+
11
+ /**
12
+ * @var
13
+ */
14
+ public $val;
15
+
16
+ /**
17
+ * @var int
18
+ */
19
+ public $position = 0;
20
+
21
+ /**
22
+ * @var int
23
+ */
24
+ public $index = 1;
25
+
26
+ public function append($str) {
27
+ $this->str .= $str;
28
+ }
29
+ }
src/lib/vendor/nullpunkt/lz-string-php/src/LZCompressor/LZReverseDictionary.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Created by PhpStorm.
4
+ * User: sics
5
+ * Date: 28.02.2016
6
+ * Time: 12:53
7
+ */
8
+
9
+ namespace LZCompressor;
10
+
11
+
12
+ class LZReverseDictionary
13
+ {
14
+
15
+ public $entries = [0, 1 ,2];
16
+
17
+ public function size() {
18
+ return count($this->entries);
19
+ }
20
+
21
+ public function hasEntry($index) {
22
+ return array_key_exists($index, $this->entries);
23
+ }
24
+
25
+ public function getEntry($index) {
26
+ return $this->entries[$index];
27
+ }
28
+
29
+ public function addEntry($char) {
30
+ $this->entries[] = $char;
31
+ }
32
+
33
+ }
src/lib/vendor/nullpunkt/lz-string-php/src/LZCompressor/LZString.php ADDED
@@ -0,0 +1,298 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace LZCompressor;
3
+
4
+ class LZString
5
+ {
6
+
7
+ public static function compressToBase64($input)
8
+ {
9
+ $res = self::_compress($input, 6, function($a) {
10
+ return LZUtil::$keyStrBase64{$a};
11
+ });
12
+ switch (strlen($res) % 4) { // To produce valid Base64
13
+ default: // When could this happen ?
14
+ case 0 : return $res;
15
+ case 1 : return $res ."===";
16
+ case 2 : return $res ."==";
17
+ case 3 : return $res ."=";
18
+ }
19
+ }
20
+
21
+ public static function decompressFromBase64($input)
22
+ {
23
+ return self::_decompress($input, 32, function($feed, $index) {
24
+ return LZUtil::getBaseValue(LZUtil::$keyStrBase64, LZUtil::utf8_charAt($feed, $index));
25
+ });
26
+ }
27
+
28
+ public static function compressToUTF16($input) {
29
+ return self::_compress($input, 15, function($a) {
30
+ return LZUtil16::fromCharCode($a+32);
31
+ }) . LZUtil16::utf16_chr(32);
32
+ }
33
+
34
+ public static function decompressFromUTF16($input) {
35
+ return self::_decompress($input, 16384, function($feed, $index) {
36
+ return LZUtil16::charCodeAt($feed, $index)-32;
37
+ });
38
+ }
39
+
40
+ /**
41
+ * @param string $uncompressed
42
+ * @return string
43
+ */
44
+ public static function compress($uncompressed)
45
+ {
46
+ return self::_compress($uncompressed, 16, function($a) {
47
+ return LZUtil::fromCharCode($a);
48
+ });
49
+ }
50
+
51
+ /**
52
+ * @param string $compressed
53
+ * @return string
54
+ */
55
+ public static function decompress($compressed)
56
+ {
57
+ return self::_decompress($compressed, 32768, function($feed, $index) {
58
+ return LZUtil::charCodeAt($feed, $index);
59
+ });
60
+ }
61
+
62
+ /**
63
+ * @param string $uncompressed
64
+ * @param integer $bitsPerChar
65
+ * @param callable $getCharFromInt
66
+ * @return string
67
+ */
68
+ private static function _compress($uncompressed, $bitsPerChar, $getCharFromInt) {
69
+
70
+ if(!is_string($uncompressed) || strlen($uncompressed) === 0) {
71
+ return '';
72
+ }
73
+
74
+ $context = new LZContext();
75
+ $length = LZUtil::utf8_strlen($uncompressed);
76
+ for($ii=0; $ii<$length; $ii++) {
77
+ $context->c = LZUtil::utf8_charAt($uncompressed, $ii);
78
+ if(!$context->dictionaryContains($context->c)) {
79
+ $context->addToDictionary($context->c);
80
+ $context->dictionaryToCreate[$context->c] = true;
81
+ }
82
+ $context->wc = $context->w . $context->c;
83
+ if($context->dictionaryContains($context->wc)) {
84
+ $context->w = $context->wc;
85
+ } else {
86
+ self::produceW($context, $bitsPerChar, $getCharFromInt);
87
+ }
88
+ }
89
+ if($context->w !== '') {
90
+ self::produceW($context, $bitsPerChar, $getCharFromInt);
91
+ }
92
+
93
+ $value = 2;
94
+ for($i=0; $i<$context->numBits; $i++) {
95
+ self::writeBit($value&1, $context->data, $bitsPerChar, $getCharFromInt);
96
+ $value = $value >> 1;
97
+ }
98
+
99
+ while (true) {
100
+ $context->data->val = $context->data->val << 1;
101
+ if ($context->data->position == ($bitsPerChar-1)) {
102
+ $context->data->append($getCharFromInt($context->data->val));
103
+ break;
104
+ }
105
+ $context->data->position++;
106
+ }
107
+
108
+ return $context->data->str;
109
+ }
110
+
111
+ /**
112
+ * @param LZContext $context
113
+ * @param integer $bitsPerChar
114
+ * @param callable $getCharFromInt
115
+ *
116
+ * @return LZContext
117
+ */
118
+ private static function produceW(LZContext $context, $bitsPerChar, $getCharFromInt)
119
+ {
120
+ if($context->dictionaryToCreateContains($context->w)) {
121
+ if(LZUtil::charCodeAt($context->w)<256) {
122
+ for ($i=0; $i<$context->numBits; $i++) {
123
+ self::writeBit(null, $context->data, $bitsPerChar, $getCharFromInt);
124
+ }
125
+ $value = LZUtil::charCodeAt($context->w);
126
+ for ($i=0; $i<8; $i++) {
127
+ self::writeBit($value&1, $context->data, $bitsPerChar, $getCharFromInt);
128
+ $value = $value >> 1;
129
+ }
130
+ } else {
131
+ $value = 1;
132
+ for ($i=0; $i<$context->numBits; $i++) {
133
+ self::writeBit($value, $context->data, $bitsPerChar, $getCharFromInt);
134
+ $value = 0;
135
+ }
136
+ $value = LZUtil::charCodeAt($context->w);
137
+ for ($i=0; $i<16; $i++) {
138
+ self::writeBit($value&1, $context->data, $bitsPerChar, $getCharFromInt);
139
+ $value = $value >> 1;
140
+ }
141
+ }
142
+ $context->enlargeIn();
143
+ unset($context->dictionaryToCreate[$context->w]);
144
+ } else {
145
+ $value = $context->dictionary[$context->w];
146
+ for ($i=0; $i<$context->numBits; $i++) {
147
+ self::writeBit($value&1, $context->data, $bitsPerChar, $getCharFromInt);
148
+ $value = $value >> 1;
149
+ }
150
+ }
151
+ $context->enlargeIn();
152
+ $context->addToDictionary($context->wc);
153
+ $context->w = $context->c.'';
154
+ }
155
+
156
+ /**
157
+ * @param string $value
158
+ * @param LZData $data
159
+ * @param integer $bitsPerChar
160
+ * @param callable $getCharFromInt
161
+ */
162
+ private static function writeBit($value, LZData $data, $bitsPerChar, $getCharFromInt)
163
+ {
164
+ if(null !== $value) {
165
+ $data->val = ($data->val << 1) | $value;
166
+ } else {
167
+ $data->val = ($data->val << 1);
168
+ }
169
+ if ($data->position == ($bitsPerChar-1)) {
170
+ $data->position = 0;
171
+ $data->append($getCharFromInt($data->val));
172
+ $data->val = 0;
173
+ } else {
174
+ $data->position++;
175
+ }
176
+ }
177
+
178
+ /**
179
+ * @param LZData $data
180
+ * @param integer $resetValue
181
+ * @param callable $getNextValue
182
+ * @param integer $exponent
183
+ * @param string $feed
184
+ * @return integer
185
+ */
186
+ private static function readBits(LZData $data, $resetValue, $getNextValue, $feed, $exponent)
187
+ {
188
+ $bits = 0;
189
+ $maxPower = pow(2, $exponent);
190
+ $power=1;
191
+ while($power != $maxPower) {
192
+ $resb = $data->val & $data->position;
193
+ $data->position >>= 1;
194
+ if ($data->position == 0) {
195
+ $data->position = $resetValue;
196
+ $data->val = $getNextValue($feed, $data->index++);
197
+ }
198
+ $bits |= (($resb>0 ? 1 : 0) * $power);
199
+ $power <<= 1;
200
+ }
201
+ return $bits;
202
+ }
203
+
204
+ /**
205
+ * @param string $compressed
206
+ * @param integer $resetValue
207
+ * @param callable $getNextValue
208
+ * @return string
209
+ */
210
+ private static function _decompress($compressed, $resetValue, $getNextValue)
211
+ {
212
+ if(!is_string($compressed) || strlen($compressed) === 0) {
213
+ return '';
214
+ }
215
+
216
+ $length = LZUtil::utf8_strlen($compressed);
217
+ $entry = null;
218
+ $enlargeIn = 4;
219
+ $numBits = 3;
220
+ $result = '';
221
+
222
+ $dictionary = new LZReverseDictionary();
223
+
224
+ $data = new LZData();
225
+ $data->str = $compressed;
226
+ $data->val = $getNextValue($compressed, 0);
227
+ $data->position = $resetValue;
228
+ $data->index = 1;
229
+
230
+ $next = self::readBits($data, $resetValue, $getNextValue, $compressed, 2);
231
+
232
+ if($next < 0 || $next > 1) {
233
+ return '';
234
+ }
235
+
236
+ $exponent = ($next == 0) ? 8 : 16;
237
+ $bits = self::readBits($data, $resetValue, $getNextValue, $compressed, $exponent);
238
+
239
+ $c = LZUtil::fromCharCode($bits);
240
+ $dictionary->addEntry($c);
241
+ $w = $c;
242
+
243
+ $result .= $c;
244
+
245
+ while(true) {
246
+ if($data->index > $length) {
247
+ return '';
248
+ }
249
+ $bits = self::readBits($data, $resetValue, $getNextValue, $compressed, $numBits);
250
+
251
+ $c = $bits;
252
+
253
+ switch($c) {
254
+ case 0:
255
+ $bits = self::readBits($data, $resetValue, $getNextValue, $compressed, 8);
256
+ $c = $dictionary->size();
257
+ $dictionary->addEntry(LZUtil::fromCharCode($bits));
258
+ $enlargeIn--;
259
+ break;
260
+ case 1:
261
+ $bits = self::readBits($data, $resetValue, $getNextValue, $compressed, 16);
262
+ $c = $dictionary->size();
263
+ $dictionary->addEntry(LZUtil::fromCharCode($bits));
264
+ $enlargeIn--;
265
+ break;
266
+ case 2:
267
+ return $result;
268
+ break;
269
+ }
270
+
271
+ if($enlargeIn == 0) {
272
+ $enlargeIn = pow(2, $numBits);
273
+ $numBits++;
274
+ }
275
+
276
+ if($dictionary->hasEntry($c)) {
277
+ $entry = $dictionary->getEntry($c);
278
+ }
279
+ else {
280
+ if ($c == $dictionary->size()) {
281
+ $entry = $w . $w{0};
282
+ } else {
283
+ return null;
284
+ }
285
+ }
286
+
287
+ $result .= $entry;
288
+ $dictionary->addEntry($w . LZUtil::utf8_charAt($entry, 0));
289
+ $w = $entry;
290
+
291
+ $enlargeIn--;
292
+ if($enlargeIn == 0) {
293
+ $enlargeIn = pow(2, $numBits);
294
+ $numBits++;
295
+ }
296
+ }
297
+ }
298
+ }
src/lib/vendor/nullpunkt/lz-string-php/src/LZCompressor/LZUtil.php ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Created by PhpStorm.
4
+ * User: sics
5
+ * Date: 27.02.2016
6
+ * Time: 15:54
7
+ */
8
+
9
+ namespace LZCompressor;
10
+
11
+
12
+ class LZUtil
13
+ {
14
+ /**
15
+ * @var string
16
+ */
17
+ public static $keyStrBase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
18
+ public static $keyStrUriSafe = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-$";
19
+ private static $baseReverseDic = [];
20
+
21
+ /**
22
+ * @param string $alphabet
23
+ * @param integer $character
24
+ * @return string
25
+ */
26
+ public static function getBaseValue($alphabet, $character)
27
+ {
28
+ if(!array_key_exists($alphabet, self::$baseReverseDic)) {
29
+ self::$baseReverseDic[$alphabet] = [];
30
+ for($i=0; $i<strlen($alphabet); $i++) {
31
+ self::$baseReverseDic[$alphabet][$alphabet{$i}] = $i;
32
+ }
33
+ }
34
+ return self::$baseReverseDic[$alphabet][$character];
35
+ }
36
+
37
+ /**
38
+ * @return string
39
+ */
40
+ public static function fromCharCode()
41
+ {
42
+ return array_reduce(func_get_args(), function ($a, $b) {
43
+ $a .= self::utf8_chr($b);
44
+ return $a;
45
+ });
46
+ }
47
+
48
+ /**
49
+ * Phps chr() equivalent for UTF-8 encoding
50
+ *
51
+ * @param int|string $u
52
+ * @return string
53
+ */
54
+ public static function utf8_chr($u)
55
+ {
56
+ return mb_convert_encoding('&#' . intval($u) . ';', 'UTF-8', 'HTML-ENTITIES');
57
+ }
58
+
59
+ /**
60
+ * @param string $str
61
+ * @param int $num
62
+ *
63
+ * @return bool|integer
64
+ */
65
+ public static function charCodeAt($str, $num=0)
66
+ {
67
+ return self::utf8_ord(self::utf8_charAt($str, $num));
68
+ }
69
+
70
+ /**
71
+ * @param string $ch
72
+ *
73
+ * @return bool|integer
74
+ */
75
+ public static function utf8_ord($ch)
76
+ {
77
+ // must remain php's strlen
78
+ $len = strlen($ch);
79
+ if ($len <= 0) {
80
+ return -1;
81
+ }
82
+ $h = ord($ch{0});
83
+ if ($h <= 0x7F) return $h;
84
+ if ($h < 0xC2) return -3;
85
+ if ($h <= 0xDF && $len > 1) return ($h & 0x1F) << 6 | (ord($ch{1}) & 0x3F);
86
+ if ($h <= 0xEF && $len > 2) return ($h & 0x0F) << 12 | (ord($ch{1}) & 0x3F) << 6 | (ord($ch{2}) & 0x3F);
87
+ if ($h <= 0xF4 && $len > 3)
88
+ return ($h & 0x0F) << 18 | (ord($ch{1}) & 0x3F) << 12 | (ord($ch{2}) & 0x3F) << 6 | (ord($ch{3}) & 0x3F);
89
+ return -2;
90
+ }
91
+
92
+ /**
93
+ * @param string $str
94
+ * @param integer $num
95
+ *
96
+ * @return string
97
+ */
98
+ public static function utf8_charAt($str, $num)
99
+ {
100
+ return mb_substr($str, $num, 1, 'UTF-8');
101
+ }
102
+
103
+ /**
104
+ * @param string $str
105
+ * @return integer
106
+ */
107
+ public static function utf8_strlen($str) {
108
+ return mb_strlen($str, 'UTF-8');
109
+ }
110
+ }
src/lib/vendor/nullpunkt/lz-string-php/src/LZCompressor/LZUtil16.php ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Created by PhpStorm.
4
+ * User: sics
5
+ * Date: 27.02.2016
6
+ * Time: 15:54
7
+ */
8
+
9
+ namespace LZCompressor;
10
+
11
+
12
+ class LZUtil16
13
+ {
14
+
15
+ /**
16
+ * @return string
17
+ */
18
+ public static function fromCharCode()
19
+ {
20
+ return array_reduce(func_get_args(), function ($a, $b) {
21
+ $a .= self::utf16_chr($b);
22
+ return $a;
23
+ });
24
+ }
25
+
26
+ /**
27
+ * Phps chr() equivalent for UTF-16 encoding
28
+ *
29
+ * @param int|string $u
30
+ * @return string
31
+ */
32
+ public static function utf16_chr($u)
33
+ {
34
+ return mb_convert_encoding('&#' . intval($u) . ';', 'UTF-16', 'HTML-ENTITIES');
35
+ }
36
+
37
+ /**
38
+ * @param string $str
39
+ * @param int $num
40
+ *
41
+ * @return bool|integer
42
+ */
43
+ public static function charCodeAt($str, $num=0)
44
+ {
45
+ return self::utf16_ord(self::utf16_charAt($str, $num));
46
+ }
47
+
48
+ /**
49
+ * @source http://blog.sarabande.jp/post/35970262740
50
+ * @param string $ch
51
+ * @return bool|integer
52
+ */
53
+ function utf16_ord($ch) {
54
+ $length = strlen($ch);
55
+ if (2 === $length) {
56
+ return hexdec(bin2hex($ch));
57
+ } else if (4 === $length) {
58
+ $w1 = $ch[0].$ch[1];
59
+ $w2 = $ch[2].$ch[3];
60
+ if ($w1 < "\xD8\x00" || "\xDF\xFF" < $w1 || $w2 < "\xDC\x00" || "\xDF\xFF" < $w2) {
61
+ return false;
62
+ }
63
+ $w1 = (hexdec(bin2hex($w1)) & 0x3ff) << 10;
64
+ $w2 = hexdec(bin2hex($w2)) & 0x3ff;
65
+ return $w1 + $w2 + 0x10000;
66
+ }
67
+ return false;
68
+ }
69
+
70
+ /**
71
+ * @param string $str
72
+ * @param integer $num
73
+ *
74
+ * @return string
75
+ */
76
+ public static function utf16_charAt($str, $num)
77
+ {
78
+ return mb_substr($str, $num, 1, 'UTF-16');
79
+ }
80
+
81
+ /**
82
+ * @param string $str
83
+ * @return integer
84
+ */
85
+ public static function utf16_strlen($str)
86
+ {
87
+ return mb_strlen($str, 'UTF-16');
88
+ }
89
+
90
+ }
src/processors/admin_access_restriction.php CHANGED
@@ -130,12 +130,12 @@ class ICWP_WPSF_Processor_AdminAccessRestriction extends ICWP_WPSF_Processor_Bas
130
  * @param string $sRole
131
  * @param array $aOldRoles
132
  */
133
- public function restrictSetUserRole( $nUserId, $sRole, $aOldRoles = array() ) {
134
  $oWpUsers = $this->loadWpUsers();
135
 
136
  $sRole = strtolower( $sRole );
137
  if ( !is_array( $aOldRoles ) ) {
138
- $aOldRoles = array();
139
  }
140
 
141
  if ( $oWpUsers->getCurrentWpUserId() !== $nUserId ) {
130
  * @param string $sRole
131
  * @param array $aOldRoles
132
  */
133
+ public function restrictSetUserRole( $nUserId, $sRole, $aOldRoles = [] ) {
134
  $oWpUsers = $this->loadWpUsers();
135
 
136
  $sRole = strtolower( $sRole );
137
  if ( !is_array( $aOldRoles ) ) {
138
+ $aOldRoles = [];
139
  }
140
 
141
  if ( $oWpUsers->getCurrentWpUserId() !== $nUserId ) {
src/processors/audit_trail_auditor.php CHANGED
@@ -1,7 +1,6 @@
1
  <?php
2
 
3
  use FernleafSystems\Wordpress\Plugin\Shield\Databases\AuditTrail;
4
- use FernleafSystems\Wordpress\Services\Services;
5
 
6
  class ICWP_WPSF_Processor_AuditTrail_Auditor extends ICWP_WPSF_BaseDbProcessor {
7
 
@@ -148,7 +147,7 @@ class ICWP_WPSF_Processor_AuditTrail_Auditor extends ICWP_WPSF_BaseDbProcessor {
148
  */
149
  protected function getTableColumnsByDefinition() {
150
  $aDef = $this->getMod()->getDef( 'audit_trail_table_columns' );
151
- return ( is_array( $aDef ) ? $aDef : array() );
152
  }
153
 
154
  /**
1
  <?php
2
 
3
  use FernleafSystems\Wordpress\Plugin\Shield\Databases\AuditTrail;
 
4
 
5
  class ICWP_WPSF_Processor_AuditTrail_Auditor extends ICWP_WPSF_BaseDbProcessor {
6
 
147
  */
148
  protected function getTableColumnsByDefinition() {
149
  $aDef = $this->getMod()->getDef( 'audit_trail_table_columns' );
150
+ return ( is_array( $aDef ) ? $aDef : [] );
151
  }
152
 
153
  /**
src/processors/audit_trail_auditor_base.php CHANGED
@@ -11,7 +11,7 @@ class ICWP_WPSF_AuditTrail_Auditor_Base extends ICWP_WPSF_Foundation {
11
  * @param string $sMessage
12
  * @param array $aData
13
  */
14
- public function add( $sContext, $sEvent, $nCategory, $sMessage = '', $aData = array() ) {
15
  $this->createNewAudit( $sContext, $sMessage, $nCategory, $sEvent, $aData );
16
  }
17
  }
11
  * @param string $sMessage
12
  * @param array $aData
13
  */
14
+ public function add( $sContext, $sEvent, $nCategory, $sMessage = '', $aData = [] ) {
15
  $this->createNewAudit( $sContext, $sMessage, $nCategory, $sEvent, $aData );
16
  }
17
  }
src/processors/audit_trail_changetracking.php CHANGED
@@ -98,7 +98,7 @@ class ICWP_WPSF_Processor_AuditTrail_ChangeTracking extends ICWP_WPSF_BaseDbProc
98
  */
99
  protected function getTableColumnsByDefinition() {
100
  $aDef = $this->getMod()->getDef( 'table_columns_changetracking' );
101
- return ( is_array( $aDef ) ? $aDef : array() );
102
  }
103
 
104
  /**
98
  */
99
  protected function getTableColumnsByDefinition() {
100
  $aDef = $this->getMod()->getDef( 'table_columns_changetracking' );
101
+ return ( is_array( $aDef ) ? $aDef : [] );
102
  }
103
 
104
  /**
src/processors/audit_trail_emails.php CHANGED
@@ -91,7 +91,7 @@ class ICWP_WPSF_Processor_AuditTrail_Emails extends ICWP_WPSF_AuditTrail_Auditor
91
  $aCCs[ $sHead ],
92
  array_filter( $aEmails,
93
  function ( $sEmail ) {
94
- return \FernleafSystems\Wordpress\Services\Services::Data()->validEmail( $sEmail );
95
  } )
96
  ) );
97
  }
@@ -104,7 +104,7 @@ class ICWP_WPSF_Processor_AuditTrail_Emails extends ICWP_WPSF_AuditTrail_Auditor
104
  * @return array
105
  */
106
  private function findEmailSenderBacktrace() {
107
- $aBT = array();
108
  foreach ( debug_backtrace( false ) as $aItem ) {
109
  if ( isset( $aItem[ 'function' ] ) && 'wp_mail' === strtolower( $aItem[ 'function' ] ) ) {
110
  $aBT = $aItem;
91
  $aCCs[ $sHead ],
92
  array_filter( $aEmails,
93
  function ( $sEmail ) {
94
+ return Services::Data()->validEmail( $sEmail );
95
  } )
96
  ) );
97
  }
104
  * @return array
105
  */
106
  private function findEmailSenderBacktrace() {
107
+ $aBT = [];
108
  foreach ( debug_backtrace( false ) as $aItem ) {
109
  if ( isset( $aItem[ 'function' ] ) && 'wp_mail' === strtolower( $aItem[ 'function' ] ) ) {
110
  $aBT = $aItem;
src/processors/audit_trail_users.php CHANGED
@@ -5,7 +5,6 @@ class ICWP_WPSF_Processor_AuditTrail_Users extends ICWP_WPSF_AuditTrail_Auditor_
5
  /**
6
  */
7
  public function run() {
8
- add_action( 'wp_login_failed', array( $this, 'auditUserLoginFail' ) );
9
  add_action( 'wp_login', array( $this, 'auditUserLoginSuccess' ) );
10
  add_action( 'user_register', array( $this, 'auditNewUserRegistered' ) );
11
  add_action( 'delete_user', array( $this, 'auditDeleteUser' ), 30, 2 );
@@ -15,7 +14,6 @@ class ICWP_WPSF_Processor_AuditTrail_Users extends ICWP_WPSF_AuditTrail_Auditor_
15
  * @param string $sUsername
16
  */
17
  public function auditUserLoginSuccess( $sUsername ) {
18
-
19
  if ( !empty( $sUsername ) ) {
20
  $this->add( 'users', 'login_success', 1,
21
  sprintf( _wpsf__( 'Attempted user login by "%s" was successful.' ), $sUsername ),
@@ -24,18 +22,6 @@ class ICWP_WPSF_Processor_AuditTrail_Users extends ICWP_WPSF_AuditTrail_Auditor_
24
  }
25
  }
26
 
27
- /**
28
- * @param string $sUsername
29
- */
30
- public function auditUserLoginFail( $sUsername ) {
31
-
32
- if ( !empty( $sUsername ) ) {
33
- $this->add( 'users', 'login_failure', 2,
34
- sprintf( _wpsf__( 'Attempted user login by "%s" failed.' ), $sUsername )
35
- );
36
- }
37
- }
38
-
39
  /**
40
  * @param int $nUserId
41
  */
5
  /**
6
  */
7
  public function run() {
 
8
  add_action( 'wp_login', array( $this, 'auditUserLoginSuccess' ) );
9
  add_action( 'user_register', array( $this, 'auditNewUserRegistered' ) );
10
  add_action( 'delete_user', array( $this, 'auditDeleteUser' ), 30, 2 );
14
  * @param string $sUsername
15
  */
16
  public function auditUserLoginSuccess( $sUsername ) {
 
17
  if ( !empty( $sUsername ) ) {
18
  $this->add( 'users', 'login_success', 1,
19
  sprintf( _wpsf__( 'Attempted user login by "%s" was successful.' ), $sUsername ),
22
  }
23
  }
24
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  /**
26
  * @param int $nUserId
27
  */
src/processors/autoupdates.php CHANGED
@@ -12,7 +12,7 @@ class ICWP_WPSF_Processor_Autoupdates extends ICWP_WPSF_Processor_BaseWpsf {
12
  /**
13
  * @var array
14
  */
15
- private $aAssetsVersions = array();
16
 
17
  /**
18
  * @param boolean $bDoForceRun
@@ -95,11 +95,11 @@ class ICWP_WPSF_Processor_Autoupdates extends ICWP_WPSF_Processor_BaseWpsf {
95
  private function trackAssetsVersions() {
96
  $aAssVers = $this->getTrackedAssetsVersions();
97
 
98
- $oWpPlugins = \FernleafSystems\Wordpress\Services\Services::WpPlugins();
99
  foreach ( array_keys( $oWpPlugins->getUpdates() ) as $sFile ) {
100
  $aAssVers[ 'plugins' ][ $sFile ] = $oWpPlugins->getPluginAsVo( $sFile )->Version;
101
  }
102
- $oWpThemes = \FernleafSystems\Wordpress\Services\Services::WpThemes();
103
  foreach ( array_keys( $oWpThemes->getUpdates() ) as $sFile ) {
104
  $aAssVers[ 'themes' ][ $sFile ] = $oWpThemes->getTheme( $sFile )->get( 'Version' );
105
  }
@@ -112,8 +112,8 @@ class ICWP_WPSF_Processor_Autoupdates extends ICWP_WPSF_Processor_BaseWpsf {
112
  protected function getTrackedAssetsVersions() {
113
  if ( empty( $this->aAssetsVersions ) || !is_array( $this->aAssetsVersions ) ) {
114
  $this->aAssetsVersions = array(
115
- 'plugins' => array(),
116
- 'themes' => array(),
117
  );
118
  }
119
  return $this->aAssetsVersions;
@@ -129,7 +129,7 @@ class ICWP_WPSF_Processor_Autoupdates extends ICWP_WPSF_Processor_BaseWpsf {
129
  $oFO = $this->getMod();
130
 
131
  $aTk = $oFO->getDelayTracking();
132
- $aItemTk = isset( $aTk[ 'core' ][ 'wp' ] ) ? $aTk[ 'core' ][ 'wp' ] : array();
133
  foreach ( $oUpdates->updates as $oUpdate ) {
134
  if ( 'autoupdate' == $oUpdate->response ) {
135
  $sVersion = $oUpdate->current;
@@ -169,7 +169,7 @@ class ICWP_WPSF_Processor_Autoupdates extends ICWP_WPSF_Processor_BaseWpsf {
169
 
170
  $aTk = $oFO->getDelayTracking();
171
  foreach ( $oUpdates->response as $sSlug => $oUpdate ) {
172
- $aItemTk = isset( $aTk[ $sContext ][ $sSlug ] ) ? $aTk[ $sContext ][ $sSlug ] : array();
173
  if ( is_array( $oUpdate ) ) {
174
  $oUpdate = (object)$oUpdate;
175
  }
@@ -346,7 +346,7 @@ class ICWP_WPSF_Processor_Autoupdates extends ICWP_WPSF_Processor_BaseWpsf {
346
  return true;
347
  }
348
 
349
- $aAutoUpdates = apply_filters( 'icwp_wpsf_autoupdate_themes', array() );
350
  if ( !empty( $aAutoUpdates ) && is_array( $aAutoUpdates ) && in_array( $sFile, $aAutoUpdates ) ) {
351
  $bDoAutoUpdate = true;
352
  }
@@ -375,7 +375,7 @@ class ICWP_WPSF_Processor_Autoupdates extends ICWP_WPSF_Processor_BaseWpsf {
375
  $sSlug = 'wp';
376
  }
377
 
378
- $aItemTk = isset( $aTk[ $sContext ][ $sSlug ] ) ? $aTk[ $sContext ][ $sSlug ] : array();
379
 
380
  if ( $sContext == 'plugins' ) {
381
  $oPlugin = $this->loadWpPlugins()->getUpdateInfo( $sSlug );
12
  /**
13
  * @var array
14
  */
15
+ private $aAssetsVersions = [];
16
 
17
  /**
18
  * @param boolean $bDoForceRun
95
  private function trackAssetsVersions() {
96
  $aAssVers = $this->getTrackedAssetsVersions();
97
 
98
+ $oWpPlugins = Services::WpPlugins();
99
  foreach ( array_keys( $oWpPlugins->getUpdates() ) as $sFile ) {
100
  $aAssVers[ 'plugins' ][ $sFile ] = $oWpPlugins->getPluginAsVo( $sFile )->Version;
101
  }
102
+ $oWpThemes = Services::WpThemes();
103
  foreach ( array_keys( $oWpThemes->getUpdates() ) as $sFile ) {
104
  $aAssVers[ 'themes' ][ $sFile ] = $oWpThemes->getTheme( $sFile )->get( 'Version' );
105
  }
112
  protected function getTrackedAssetsVersions() {
113
  if ( empty( $this->aAssetsVersions ) || !is_array( $this->aAssetsVersions ) ) {
114
  $this->aAssetsVersions = array(
115
+ 'plugins' => [],
116
+ 'themes' => [],
117
  );
118
  }
119
  return $this->aAssetsVersions;
129
  $oFO = $this->getMod();
130
 
131
  $aTk = $oFO->getDelayTracking();
132
+ $aItemTk = isset( $aTk[ 'core' ][ 'wp' ] ) ? $aTk[ 'core' ][ 'wp' ] : [];
133
  foreach ( $oUpdates->updates as $oUpdate ) {
134
  if ( 'autoupdate' == $oUpdate->response ) {
135
  $sVersion = $oUpdate->current;
169
 
170
  $aTk = $oFO->getDelayTracking();
171
  foreach ( $oUpdates->response as $sSlug => $oUpdate ) {
172
+ $aItemTk = isset( $aTk[ $sContext ][ $sSlug ] ) ? $aTk[ $sContext ][ $sSlug ] : [];
173
  if ( is_array( $oUpdate ) ) {
174
  $oUpdate = (object)$oUpdate;
175
  }
346
  return true;
347
  }
348
 
349
+ $aAutoUpdates = apply_filters( 'icwp_wpsf_autoupdate_themes', [] );
350
  if ( !empty( $aAutoUpdates ) && is_array( $aAutoUpdates ) && in_array( $sFile, $aAutoUpdates ) ) {
351
  $bDoAutoUpdate = true;
352
  }
375
  $sSlug = 'wp';
376
  }
377
 
378
+ $aItemTk = isset( $aTk[ $sContext ][ $sSlug ] ) ? $aTk[ $sContext ][ $sSlug ] : [];
379
 
380
  if ( $sContext == 'plugins' ) {
381
  $oPlugin = $this->loadWpPlugins()->getUpdateInfo( $sSlug );
src/processors/base.php CHANGED
@@ -1,7 +1,7 @@
1
  <?php
2
 
3
- use \FernleafSystems\Wordpress\Plugin\Shield;
4
- use \FernleafSystems\Wordpress\Services\Services;
5
 
6
  abstract class ICWP_WPSF_Processor_Base extends ICWP_WPSF_Foundation {
7
 
@@ -41,12 +41,12 @@ abstract class ICWP_WPSF_Processor_Base extends ICWP_WPSF_Foundation {
41
  add_action( $oModCon->prefix( 'daily_cron' ), array( $this, 'runDailyCron' ) );
42
  add_action( $oModCon->prefix( 'hourly_cron' ), array( $this, 'runHourlyCron' ) );
43
  add_action( $oModCon->prefix( 'deactivate_plugin' ), array( $this, 'deactivatePlugin' ) );
 
44
 
45
  $this->init();
46
  }
47
 
48
  public function onWpInit() {
49
- add_action( $this->getMod()->prefix( 'generate_admin_notices' ), array( $this, 'autoAddToAdminNotices' ) );
50
  }
51
 
52
  public function onWpLoaded() {
@@ -240,7 +240,7 @@ abstract class ICWP_WPSF_Processor_Base extends ICWP_WPSF_Foundation {
240
 
241
  /**
242
  * @param string $sKey
243
- * @return ICWP_WPSF_Processor_Base|null
244
  */
245
  protected function getSubPro( $sKey ) {
246
  $aProcessors = $this->getSubProcessors();
@@ -266,7 +266,7 @@ abstract class ICWP_WPSF_Processor_Base extends ICWP_WPSF_Foundation {
266
  */
267
  protected function getSubProcessors() {
268
  if ( !isset( $this->aSubPros ) ) {
269
- $this->aSubPros = array();
270
  }
271
  return $this->aSubPros;
272
  }
1
  <?php
2
 
3
+ use FernleafSystems\Wordpress\Plugin\Shield;
4
+ use FernleafSystems\Wordpress\Services\Services;
5
 
6
  abstract class ICWP_WPSF_Processor_Base extends ICWP_WPSF_Foundation {
7
 
41
  add_action( $oModCon->prefix( 'daily_cron' ), array( $this, 'runDailyCron' ) );
42
  add_action( $oModCon->prefix( 'hourly_cron' ), array( $this, 'runHourlyCron' ) );
43
  add_action( $oModCon->prefix( 'deactivate_plugin' ), array( $this, 'deactivatePlugin' ) );
44
+ add_action( $oModCon->prefix( 'generate_admin_notices' ), array( $this, 'autoAddToAdminNotices' ) );
45
 
46
  $this->init();
47
  }
48
 
49
  public function onWpInit() {
 
50
  }
51
 
52
  public function onWpLoaded() {
240
 
241
  /**
242
  * @param string $sKey
243
+ * @return ICWP_WPSF_Processor_Base|mixed|null
244
  */
245
  protected function getSubPro( $sKey ) {
246
  $aProcessors = $this->getSubProcessors();
266
  */
267
  protected function getSubProcessors() {
268
  if ( !isset( $this->aSubPros ) ) {
269
+ $this->aSubPros = [];
270
  }
271
  return $this->aSubPros;
272
  }
src/processors/base_plugin.php CHANGED
@@ -91,7 +91,7 @@ class ICWP_WPSF_Processor_BasePlugin extends ICWP_WPSF_Processor_BaseWpsf {
91
  'hrefs' => array(
92
  'wizard' => $oFO->getUrl_Wizard( 'welcome' ),
93
  ),
94
- 'flags' => array()
95
  );
96
  $this->insertAdminNotice( $aRenderData );
97
  }
91
  'hrefs' => array(
92
  'wizard' => $oFO->getUrl_Wizard( 'welcome' ),
93
  ),
94
+ 'flags' => []
95
  );
96
  $this->insertAdminNotice( $aRenderData );
97
  }
src/processors/base_wpsf.php CHANGED
@@ -102,14 +102,6 @@ abstract class ICWP_WPSF_Processor_BaseWpsf extends ICWP_WPSF_Processor_Base {
102
  return true;
103
  }
104
 
105
- /**
106
- * @return bool
107
- */
108
- protected function getIfIpTransgressed() {
109
- return apply_filters( $this->getMod()->prefix( 'ip_black_mark' ), false )
110
- || apply_filters( $this->getMod()->prefix( 'ip_block_it' ), false );
111
- }
112
-
113
  /**
114
  * @return bool
115
  */
@@ -144,7 +136,7 @@ abstract class ICWP_WPSF_Processor_BaseWpsf extends ICWP_WPSF_Processor_Base {
144
  ),
145
  'https://www.google.com/recaptcha/api.js'
146
  );
147
- wp_register_script( self::RECAPTCHA_JS_HANDLE, $sJsUri, array(), false, true );
148
  wp_enqueue_script( self::RECAPTCHA_JS_HANDLE );
149
 
150
  // This also gives us the chance to remove recaptcha before it's printed, if it isn't needed
@@ -168,7 +160,7 @@ abstract class ICWP_WPSF_Processor_BaseWpsf extends ICWP_WPSF_Processor_Base {
168
  */
169
  public function stats_Collect( $aStats ) {
170
  if ( !is_array( $aStats ) ) {
171
- $aStats = array();
172
  }
173
  $aThisStats = $this->stats_Get();
174
  if ( !empty( $aThisStats ) && is_array( $aThisStats ) ) {
@@ -196,7 +188,7 @@ abstract class ICWP_WPSF_Processor_BaseWpsf extends ICWP_WPSF_Processor_Base {
196
  */
197
  public function stats_Get() {
198
  if ( !isset( $this->aStatistics ) || !is_array( $this->aStatistics ) ) {
199
- $this->aStatistics = array();
200
  }
201
  return $this->aStatistics;
202
  }
@@ -212,7 +204,7 @@ abstract class ICWP_WPSF_Processor_BaseWpsf extends ICWP_WPSF_Processor_Base {
212
  */
213
  public function tracking_DataCollect( $aData ) {
214
  if ( !is_array( $aData ) ) {
215
- $aData = array();
216
  }
217
  $oFO = $this->getMod();
218
  $aData[ $oFO->getSlug() ] = array( 'options' => $oFO->collectOptionsForTracking() );
@@ -240,7 +232,7 @@ abstract class ICWP_WPSF_Processor_BaseWpsf extends ICWP_WPSF_Processor_Base {
240
  * @param array $aData
241
  * @return $this
242
  */
243
- public function addToAuditEntry( $sMsg = '', $nCategory = 1, $sEvent = '', $aData = array() ) {
244
  $this->createNewAudit( 'wpsf', $sMsg, $nCategory, $sEvent, $aData );
245
  return $this;
246
  }
@@ -290,4 +282,14 @@ abstract class ICWP_WPSF_Processor_BaseWpsf extends ICWP_WPSF_Processor_Base {
290
  self::$bRecaptchaEnqueue = true;
291
  return $this;
292
  }
 
 
 
 
 
 
 
 
 
 
293
  }
102
  return true;
103
  }
104
 
 
 
 
 
 
 
 
 
105
  /**
106
  * @return bool
107
  */
136
  ),
137
  'https://www.google.com/recaptcha/api.js'
138
  );
139
+ wp_register_script( self::RECAPTCHA_JS_HANDLE, $sJsUri, [], false, true );
140
  wp_enqueue_script( self::RECAPTCHA_JS_HANDLE );
141
 
142
  // This also gives us the chance to remove recaptcha before it's printed, if it isn't needed
160
  */
161
  public function stats_Collect( $aStats ) {
162
  if ( !is_array( $aStats ) ) {
163
+ $aStats = [];
164
  }
165
  $aThisStats = $this->stats_Get();
166
  if ( !empty( $aThisStats ) && is_array( $aThisStats ) ) {
188
  */
189
  public function stats_Get() {
190
  if ( !isset( $this->aStatistics ) || !is_array( $this->aStatistics ) ) {
191
+ $this->aStatistics = [];
192
  }
193
  return $this->aStatistics;
194
  }
204
  */
205
  public function tracking_DataCollect( $aData ) {
206
  if ( !is_array( $aData ) ) {
207
+ $aData = [];
208
  }
209
  $oFO = $this->getMod();
210
  $aData[ $oFO->getSlug() ] = array( 'options' => $oFO->collectOptionsForTracking() );
232
  * @param array $aData
233
  * @return $this
234
  */
235
+ public function addToAuditEntry( $sMsg = '', $nCategory = 1, $sEvent = '', $aData = [] ) {
236
  $this->createNewAudit( 'wpsf', $sMsg, $nCategory, $sEvent, $aData );
237
  return $this;
238
  }
282
  self::$bRecaptchaEnqueue = true;
283
  return $this;
284
  }
285
+
286
+ /**
287
+ * @deprecated
288
+ * @return bool
289
+ */
290
+ protected function getIfIpTransgressed() {
291
+ /** @var ICWP_WPSF_FeatureHandler_BaseWpsf $oFO */
292
+ $oFO = $this->getMod();
293
+ return $oFO->getIfIpTransgressed();
294
+ }
295
  }
src/processors/comments_filter.php CHANGED
@@ -1,5 +1,7 @@
1
  <?php
2
 
 
 
3
  class ICWP_WPSF_Processor_CommentsFilter extends ICWP_WPSF_Processor_BaseWpsf {
4
 
5
  /**
@@ -10,31 +12,55 @@ class ICWP_WPSF_Processor_CommentsFilter extends ICWP_WPSF_Processor_BaseWpsf {
10
  public function onWpInit() {
11
  parent::onWpInit();
12
 
13
- if ( $this->loadWpUsers()->isUserLoggedIn() ) {
14
- return;
15
- }
16
-
17
- /** @var ICWP_WPSF_FeatureHandler_CommentsFilter $oFO */
18
- $oFO = $this->getMod();
 
 
 
 
 
 
19
 
20
- if ( $oFO->isEnabledGaspCheck() ) {
21
- $oBotSpamProcessor = new ICWP_WPSF_Processor_CommentsFilter_AntiBotSpam( $oFO );
22
- $oBotSpamProcessor->run();
23
  }
 
24
 
25
- if ( $oFO->isEnabledHumanCheck() && $this->loadWpComments()->isCommentPost() ) {
26
- $oHumanSpamProcessor = new ICWP_WPSF_Processor_CommentsFilter_HumanSpam( $oFO );
27
- $oHumanSpamProcessor->run();
28
- }
 
 
 
 
 
 
29
 
30
- if ( $oFO->isGoogleRecaptchaEnabled() ) {
31
- $oReCap = new ICWP_WPSF_Processor_CommentsFilter_GoogleRecaptcha( $oFO );
32
- $oReCap->run();
33
- }
 
 
34
 
35
- add_filter( 'pre_comment_approved', array( $this, 'doSetCommentStatus' ), 1 );
36
- add_filter( 'pre_comment_content', array( $this, 'doInsertCommentStatusExplanation' ), 1, 1 );
37
- add_filter( 'comment_notification_recipients', array( $this, 'clearCommentNotificationEmail' ), 100, 1 );
 
 
 
 
 
 
 
 
 
38
  }
39
 
40
  /**
@@ -47,7 +73,7 @@ class ICWP_WPSF_Processor_CommentsFilter extends ICWP_WPSF_Processor_BaseWpsf {
47
  // We only warn when the human spam filter is running
48
  if ( $oFO->isEnabledHumanCheck() ) {
49
 
50
- $oWpPlugins = $this->loadWpPlugins();
51
  $sPluginFile = $oWpPlugins->findPluginBy( 'Akismet', 'Name' );
52
  if ( $oWpPlugins->isActive( $sPluginFile ) ) {
53
  $aRenderData = array(
@@ -101,8 +127,8 @@ class ICWP_WPSF_Processor_CommentsFilter extends ICWP_WPSF_Processor_BaseWpsf {
101
  */
102
  public function clearCommentNotificationEmail( $aEmails ) {
103
  $sStatus = apply_filters( $this->getMod()->prefix( 'cf_status' ), '' );
104
- if ( in_array( $sStatus, array( 'reject', 'trash' ) ) ) {
105
- $aEmails = array();
106
  }
107
  return $aEmails;
108
  }
1
  <?php
2
 
3
+ use FernleafSystems\Wordpress\Services\Services;
4
+
5
  class ICWP_WPSF_Processor_CommentsFilter extends ICWP_WPSF_Processor_BaseWpsf {
6
 
7
  /**
12
  public function onWpInit() {
13
  parent::onWpInit();
14
 
15
+ if ( !Services::WpUsers()->isUserLoggedIn() ) {
16
+ /** @var ICWP_WPSF_FeatureHandler_CommentsFilter $oFO */
17
+ $oFO = $this->getMod();
18
+ if ( $oFO->isEnabledGaspCheck() ) {
19
+ $this->getSubProGasp()->run();
20
+ }
21
+ if ( $oFO->isEnabledHumanCheck() && $this->loadWpComments()->isCommentPost() ) {
22
+ $this->getSubProHuman()->run();
23
+ }
24
+ if ( $oFO->isGoogleRecaptchaEnabled() ) {
25
+ $this->getSubProRecaptcha()->run();
26
+ }
27
 
28
+ add_filter( 'pre_comment_approved', array( $this, 'doSetCommentStatus' ), 1 );
29
+ add_filter( 'pre_comment_content', array( $this, 'doInsertCommentStatusExplanation' ), 1, 1 );
30
+ add_filter( 'comment_notification_recipients', array( $this, 'clearCommentNotificationEmail' ), 100, 1 );
31
  }
32
+ }
33
 
34
+ /**
35
+ * @return array
36
+ */
37
+ protected function getSubProMap() {
38
+ return [
39
+ 'gasp' => 'ICWP_WPSF_Processor_CommentsFilter_AntiBotSpam',
40
+ 'human' => 'ICWP_WPSF_Processor_CommentsFilter_HumanSpam',
41
+ 'recaptcha' => 'ICWP_WPSF_Processor_CommentsFilter_GoogleRecaptcha',
42
+ ];
43
+ }
44
 
45
+ /**
46
+ * @return ICWP_WPSF_Processor_CommentsFilter_AntiBotSpam
47
+ */
48
+ private function getSubProGasp() {
49
+ return $this->getSubPro( 'gasp' );
50
+ }
51
 
52
+ /**
53
+ * @return ICWP_WPSF_Processor_CommentsFilter_AntiBotSpam
54
+ */
55
+ private function getSubProHuman() {
56
+ return $this->getSubPro( 'human' );
57
+ }
58
+
59
+ /**
60
+ * @return ICWP_WPSF_Processor_CommentsFilter_AntiBotSpam
61
+ */
62
+ private function getSubProRecaptcha() {
63
+ return $this->getSubPro( 'recaptcha' );
64
  }
65
 
66
  /**
73
  // We only warn when the human spam filter is running
74
  if ( $oFO->isEnabledHumanCheck() ) {
75
 
76
+ $oWpPlugins = Services::WpPlugins();
77
  $sPluginFile = $oWpPlugins->findPluginBy( 'Akismet', 'Name' );
78
  if ( $oWpPlugins->isActive( $sPluginFile ) ) {
79
  $aRenderData = array(
127
  */
128
  public function clearCommentNotificationEmail( $aEmails ) {
129
  $sStatus = apply_filters( $this->getMod()->prefix( 'cf_status' ), '' );
130
+ if ( in_array( $sStatus, [ 'reject', 'trash' ] ) ) {
131
+ $aEmails = [];
132
  }
133
  return $aEmails;
134
  }
src/processors/commentsfilter_antibotspam.php CHANGED
@@ -78,7 +78,7 @@ class ICWP_WPSF_Processor_CommentsFilter_AntiBotSpam extends ICWP_WPSF_BaseDbPro
78
  // Now we check whether comment status is to completely reject and then we simply redirect to "home"
79
  if ( $this->sCommentStatus == 'reject' ) {
80
  $oWp = $this->loadWp();
81
- $oWp->doRedirect( $oWp->getHomeUrl(), array(), true, false );
82
  }
83
  }
84
 
@@ -364,7 +364,7 @@ class ICWP_WPSF_Processor_CommentsFilter_AntiBotSpam extends ICWP_WPSF_BaseDbPro
364
  */
365
  protected function getTableColumnsByDefinition() {
366
  $aDef = $this->getMod()->getDef( 'spambot_comments_filter_table_columns' );
367
- return is_array( $aDef ) ? $aDef : array();
368
  }
369
 
370
  /**
78
  // Now we check whether comment status is to completely reject and then we simply redirect to "home"
79
  if ( $this->sCommentStatus == 'reject' ) {
80
  $oWp = $this->loadWp();
81
+ $oWp->doRedirect( $oWp->getHomeUrl(), [], true, false );
82
  }
83
  }
84
 
364
  */
365
  protected function getTableColumnsByDefinition() {
366
  $aDef = $this->getMod()->getDef( 'spambot_comments_filter_table_columns' );
367
+ return is_array( $aDef ) ? $aDef : [];
368
  }
369
 
370
  /**
src/processors/commentsfilter_googlerecaptcha.php CHANGED
@@ -67,7 +67,7 @@ class ICWP_WPSF_Processor_CommentsFilter_GoogleRecaptcha extends ICWP_WPSF_Proce
67
 
68
  if ( self::$sCommentStatus == 'reject' ) {
69
  $oWp = $this->loadWp();
70
- $oWp->doRedirect( $oWp->getHomeUrl(), array(), true, false );
71
  }
72
  }
73
  }
67
 
68
  if ( self::$sCommentStatus == 'reject' ) {
69
  $oWp = $this->loadWp();
70
+ $oWp->doRedirect( $oWp->getHomeUrl(), [], true, false );
71
  }
72
  }
73
  }
src/processors/commentsfilter_humanspam.php CHANGED
@@ -63,7 +63,7 @@ class ICWP_WPSF_Processor_CommentsFilter_HumanSpam extends ICWP_WPSF_Processor_C
63
  // Now we check whether comment status is to completely reject and then we simply redirect to "home"
64
  if ( self::$sCommentStatus == 'reject' ) {
65
  $oWp = $this->loadWp();
66
- $oWp->doRedirect( $oWp->getHomeUrl(), array(), true, false );
67
  }
68
  }
69
 
@@ -106,7 +106,7 @@ class ICWP_WPSF_Processor_CommentsFilter_HumanSpam extends ICWP_WPSF_Processor_C
106
  'user_agent' => $sUserAgent
107
  );
108
  $aDesiredItemsToCheck = $this->getOption( 'enable_comments_human_spam_filter_items' );
109
- $aItemsToCheck = array();
110
  foreach ( $aDesiredItemsToCheck as $sKey ) {
111
  $aItemsToCheck[ $sKey ] = $aItemsMap[ $sKey ];
112
  }
@@ -198,7 +198,7 @@ class ICWP_WPSF_Processor_CommentsFilter_HumanSpam extends ICWP_WPSF_Processor_C
198
  * @return string
199
  */
200
  protected function doSpamBlacklistDownload() {
201
- return \FernleafSystems\Wordpress\Services\Services::HttpRequest()->getContent( self::Spam_Blacklist_Source );
202
  }
203
 
204
  /**
63
  // Now we check whether comment status is to completely reject and then we simply redirect to "home"
64
  if ( self::$sCommentStatus == 'reject' ) {
65
  $oWp = $this->loadWp();
66
+ $oWp->doRedirect( $oWp->getHomeUrl(), [], true, false );
67
  }
68
  }
69
 
106
  'user_agent' => $sUserAgent
107
  );
108
  $aDesiredItemsToCheck = $this->getOption( 'enable_comments_human_spam_filter_items' );
109
+ $aItemsToCheck = [];
110
  foreach ( $aDesiredItemsToCheck as $sKey ) {
111
  $aItemsToCheck[ $sKey ] = $aItemsMap[ $sKey ];
112
  }
198
  * @return string
199
  */
200
  protected function doSpamBlacklistDownload() {
201
+ return Services::HttpRequest()->getContent( self::Spam_Blacklist_Source );
202
  }
203
 
204
  /**
src/processors/email.php CHANGED
@@ -84,7 +84,7 @@ class ICWP_WPSF_Processor_Email extends ICWP_WPSF_Processor_BaseWpsf {
84
  * @param array $aMessage
85
  * @return boolean
86
  */
87
- public function sendEmailWithWrap( $sAddress = '', $sSubject = '', $aMessage = array() ) {
88
  return $this->send(
89
  $sAddress,
90
  wp_specialchars_decode( sprintf( '[%s] %s', $this->loadWp()->getSiteName(), $sSubject ) ),
84
  * @param array $aMessage
85
  * @return boolean
86
  */
87
+ public function sendEmailWithWrap( $sAddress = '', $sSubject = '', $aMessage = [] ) {
88
  return $this->send(
89
  $sAddress,
90
  wp_specialchars_decode( sprintf( '[%s] %s', $this->loadWp()->getSiteName(), $sSubject ) ),
src/processors/firewall.php CHANGED
@@ -127,7 +127,7 @@ class ICWP_WPSF_Processor_Firewall extends ICWP_WPSF_Processor_BaseWpsf {
127
  $sKey = 'exefile';
128
  $bFAIL = false;
129
  if ( isset( $_FILES ) && !empty( $_FILES ) ) {
130
- $aFileNames = array();
131
  foreach ( $_FILES as $aFile ) {
132
  if ( !empty( $aFile[ 'name' ] ) ) {
133
  $aFileNames[] = $aFile[ 'name' ];
@@ -332,7 +332,7 @@ class ICWP_WPSF_Processor_Firewall extends ICWP_WPSF_Processor_BaseWpsf {
332
  $aMessages = apply_filters( $this->getMod()
333
  ->prefix( 'firewall_die_message' ), $this->getFirewallDieMessage() );
334
  if ( !is_array( $aMessages ) ) {
335
- $aMessages = array();
336
  }
337
  return implode( ' ', $aMessages );
338
  }
@@ -390,7 +390,7 @@ class ICWP_WPSF_Processor_Firewall extends ICWP_WPSF_Processor_BaseWpsf {
390
 
391
  // if the page has no particular parameters specified there is nothing to check since the whole page is white listed.
392
  if ( empty( $aWhitelistPageParams ) ) {
393
- $this->aPageParams = array();
394
  }
395
  else {
396
  // Otherwise we run through any whitelisted parameters and remove them.
127
  $sKey = 'exefile';
128
  $bFAIL = false;
129
  if ( isset( $_FILES ) && !empty( $_FILES ) ) {
130
+ $aFileNames = [];
131
  foreach ( $_FILES as $aFile ) {
132
  if ( !empty( $aFile[ 'name' ] ) ) {
133
  $aFileNames[] = $aFile[ 'name' ];
332
  $aMessages = apply_filters( $this->getMod()
333
  ->prefix( 'firewall_die_message' ), $this->getFirewallDieMessage() );
334
  if ( !is_array( $aMessages ) ) {
335
+ $aMessages = [];
336
  }
337
  return implode( ' ', $aMessages );
338
  }
390
 
391
  // if the page has no particular parameters specified there is nothing to check since the whole page is white listed.
392
  if ( empty( $aWhitelistPageParams ) ) {
393
+ $this->aPageParams = [];
394
  }
395
  else {
396
  // Otherwise we run through any whitelisted parameters and remove them.
src/processors/hack_protect.php CHANGED
@@ -8,6 +8,8 @@ class ICWP_WPSF_Processor_HackProtect extends ICWP_WPSF_Processor_BaseWpsf {
8
  * Override to set what this processor does when it's "run"
9
  */
10
  public function run() {
 
 
11
 
12
  $sPath = Services::Request()->getPath();
13
  if ( !empty( $sPath ) && ( strpos( $sPath, '/wp-admin/admin-ajax.php' ) !== false ) ) {
@@ -18,6 +20,16 @@ class ICWP_WPSF_Processor_HackProtect extends ICWP_WPSF_Processor_BaseWpsf {
18
  add_filter( 'pre_comment_content', array( $this, 'secXss64kb' ), 0, 1 );
19
 
20
  $this->getSubProScanner()->run();
 
 
 
 
 
 
 
 
 
 
21
  }
22
 
23
  /**
@@ -32,7 +44,8 @@ class ICWP_WPSF_Processor_HackProtect extends ICWP_WPSF_Processor_BaseWpsf {
32
  */
33
  protected function getSubProMap() {
34
  return [
35
- 'scanner' => 'ICWP_WPSF_Processor_HackProtect_Scanner',
 
36
  ];
37
  }
38
 
8
  * Override to set what this processor does when it's "run"
9
  */
10
  public function run() {
11
+ /** @var ICWP_WPSF_FeatureHandler_HackProtect $oMod */
12
+ $oMod = $this->getMod();
13
 
14
  $sPath = Services::Request()->getPath();
15
  if ( !empty( $sPath ) && ( strpos( $sPath, '/wp-admin/admin-ajax.php' ) !== false ) ) {
20
  add_filter( 'pre_comment_content', array( $this, 'secXss64kb' ), 0, 1 );
21
 
22
  $this->getSubProScanner()->run();
23
+ if ( $oMod->isRtEnabledWpConfig() ) {
24
+ $this->getSubProRealtime()->run();
25
+ }
26
+ }
27
+
28
+ /**
29
+ * @return ICWP_WPSF_Processor_HackProtect_Realtime|mixed
30
+ */
31
+ public function getSubProRealtime() {
32
+ return $this->getSubPro( 'realtime' );
33
  }
34
 
35
  /**
44
  */
45
  protected function getSubProMap() {
46
  return [
47
+ 'scanner' => 'ICWP_WPSF_Processor_HackProtect_Scanner',
48
+ 'realtime' => 'ICWP_WPSF_Processor_HackProtect_Realtime',
49
  ];
50
  }
51
 
src/processors/hackprotect_integrity.php CHANGED
@@ -23,7 +23,7 @@ class ICWP_WPSF_Processor_HackProtect_Integrity extends ICWP_WPSF_Processor_Base
23
  * @return array[] - associative arrays where keys are $this->getStandardUserFields()
24
  */
25
  public function getSnapshotUsers() {
26
- return is_array( $this->getOption( 'snapshot_users' ) ) ? $this->getOption( 'snapshot_users' ) : array();
27
  }
28
 
29
  /**
@@ -117,11 +117,11 @@ class ICWP_WPSF_Processor_HackProtect_Integrity extends ICWP_WPSF_Processor_Base
117
 
118
  if ( $oFO->isIcUsersEnabled() && ( $bUpdate || !$this->hasSnapshotUsers() ) ) {
119
 
120
- $aUsersToStore = array();
121
  $aFields = $this->getStandardUserFields();
122
  foreach ( $this->loadWpUsers()->getAllUsers() as $oUser ) {
123
 
124
- $aUserData = array();
125
  foreach ( $aFields as $sField ) {
126
  $aUserData[ $sField ] = $oUser->get( $sField );
127
  }
23
  * @return array[] - associative arrays where keys are $this->getStandardUserFields()
24
  */
25
  public function getSnapshotUsers() {
26
+ return is_array( $this->getOption( 'snapshot_users' ) ) ? $this->getOption( 'snapshot_users' ) : [];
27
  }
28
 
29
  /**
117
 
118
  if ( $oFO->isIcUsersEnabled() && ( $bUpdate || !$this->hasSnapshotUsers() ) ) {
119
 
120
+ $aUsersToStore = [];
121
  $aFields = $this->getStandardUserFields();
122
  foreach ( $this->loadWpUsers()->getAllUsers() as $oUser ) {
123
 
124
+ $aUserData = [];
125
  foreach ( $aFields as $sField ) {
126
  $aUserData[ $sField ] = $oUser->get( $sField );
127
  }
src/processors/hackprotect_realtime.php ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ use FernleafSystems\Wordpress\Plugin\Shield;
4
+ use FernleafSystems\Wordpress\Services\Services;
5
+
6
+ class ICWP_WPSF_Processor_HackProtect_Realtime extends ICWP_WPSF_Processor_BaseWpsf {
7
+
8
+ /**
9
+ */
10
+ public function run() {
11
+ parent::run();
12
+ /** @var ICWP_WPSF_FeatureHandler_HackProtect $oMod */
13
+ $oMod = $this->getMod();
14
+
15
+ if ( $oMod->isRtEnabledWpConfig() ) {
16
+ $this->runWpConfig();
17
+ }
18
+ }
19
+
20
+ private function runWpConfig() {
21
+ /** @var ICWP_WPSF_FeatureHandler_HackProtect $oMod */
22
+ $oMod = $this->getMod();
23
+ $oProc = new Shield\Scans\Realtime\Files\Process();
24
+
25
+ /** @var ICWP_WPSF_FeatureHandler_Plugin $oModPlugin */
26
+ $oModPlugin = $this->getCon()->getModule( 'plugin' );
27
+ $oProc->priv_key = $oModPlugin->getOpenSslPrivateKey();
28
+ $oProc->original_path = Services::WpGeneral()->getPath_WpConfig();
29
+ $oProc->original_path_hash = $oMod->getRtFileHash( $oProc->original_path );
30
+ $oProc->backup_file = $oMod->getRtFileBackupName( $oProc->original_path );
31
+ $oProc->backup_dir = $this->getCon()->getPath_PluginCache();
32
+
33
+ // This is going to create the new backup file
34
+ $bNeedStoreHashAndPath = empty( $oProc->backup_file );
35
+ try {
36
+ if ( $oProc->run() && $bNeedStoreHashAndPath ) {
37
+ $oProc->backup_file = $oMod->setRtFileBackupName( $oProc->original_path, $oProc->backup_file );
38
+ $oProc->original_path_hash = $oMod->setRtFileHash( $oProc->original_path, $oProc->original_path_hash );
39
+ }
40
+ }
41
+ catch ( \Exception $oE ) {
42
+ $this->handleErrorCode( $oE->getCode() );
43
+ }
44
+ }
45
+
46
+ private function handleErrorCode( $nCode ) {
47
+ switch ( $nCode ) {
48
+
49
+ case 1:
50
+ break;
51
+
52
+ case 2:
53
+ break;
54
+
55
+ default:
56
+ break;
57
+ }
58
+ }
59
+ }
src/processors/hackprotect_scan_apc.php CHANGED
@@ -164,7 +164,7 @@ class ICWP_WPSF_Processor_HackProtect_Apc extends ICWP_WPSF_Processor_ScanBase {
164
  /**
165
  * @return bool
166
  */
167
- protected function countVulnerablePlugins() {
168
  return $this->getAllAbandoned()->countUniqueSlugsForPluginsContext();
169
  }
170
  }
164
  /**
165
  * @return bool
166
  */
167
+ protected function countAbandonedPlugins() {
168
  return $this->getAllAbandoned()->countUniqueSlugsForPluginsContext();
169
  }
170
  }
src/processors/hackprotect_scan_ptg.php CHANGED
@@ -176,7 +176,7 @@ class ICWP_WPSF_Processor_HackProtect_Ptg extends ICWP_WPSF_Processor_HackProtec
176
  'strings' => array(
177
  'editing_restricted' => _wpsf__( 'Editing this option is currently restricted.' ),
178
  ),
179
- 'js_snippets' => array()
180
  );
181
  echo $this->getMod()
182
  ->renderTemplate( 'snippets/hg-plugins-reinstall-dialogs.php', $aRenderData );
@@ -218,7 +218,7 @@ class ICWP_WPSF_Processor_HackProtect_Ptg extends ICWP_WPSF_Processor_HackProtec
218
  public function updateSnapshotAfterUpgrade( $oUpgrader, $aInfo ) {
219
 
220
  $sContext = '';
221
- $aSlugs = array();
222
 
223
  // Need to account for single and bulk updates. First bulk
224
  if ( !empty( $aInfo[ self::CONTEXT_PLUGINS ] ) ) {
@@ -568,7 +568,7 @@ class ICWP_WPSF_Processor_HackProtect_Ptg extends ICWP_WPSF_Processor_HackProtec
568
  $oWpPlugins = Services\Services::WpPlugins();
569
  $oWpThemes = Services\Services::WpThemes();
570
 
571
- $aAllPlugins = array();
572
  foreach ( $oRes->getResultsForPluginsContext()->getUniqueSlugs() as $sBaseFile ) {
573
  $oP = $oWpPlugins->getPluginAsVo( $sBaseFile );
574
  if ( !empty( $oP ) ) {
@@ -577,7 +577,7 @@ class ICWP_WPSF_Processor_HackProtect_Ptg extends ICWP_WPSF_Processor_HackProtec
577
  }
578
  }
579
 
580
- $aAllThemes = array();
581
  foreach ( $oRes->getResultsForThemesContext()->getUniqueSlugs() as $sBaseFile ) {
582
  $oTheme = $oWpThemes->getTheme( $sBaseFile );
583
  if ( !empty( $oTheme ) ) {
@@ -661,7 +661,7 @@ class ICWP_WPSF_Processor_HackProtect_Ptg extends ICWP_WPSF_Processor_HackProtec
661
  * @param array $aData
662
  * @return $this
663
  */
664
- public function addToAuditEntry( $sMsg = '', $nCategory = 1, $sEvent = '', $aData = array() ) {
665
  $sMsg = sprintf( '[%s]: %s', _wpsf__( 'Plugin/Theme Guard' ), $sMsg );
666
  $this->createNewAudit( 'wpsf', $sMsg, $nCategory, $sEvent, $aData );
667
  return $this;
176
  'strings' => array(
177
  'editing_restricted' => _wpsf__( 'Editing this option is currently restricted.' ),
178
  ),
179
+ 'js_snippets' => []
180
  );
181
  echo $this->getMod()
182
  ->renderTemplate( 'snippets/hg-plugins-reinstall-dialogs.php', $aRenderData );
218
  public function updateSnapshotAfterUpgrade( $oUpgrader, $aInfo ) {
219
 
220
  $sContext = '';
221
+ $aSlugs = [];
222
 
223
  // Need to account for single and bulk updates. First bulk
224
  if ( !empty( $aInfo[ self::CONTEXT_PLUGINS ] ) ) {
568
  $oWpPlugins = Services\Services::WpPlugins();
569
  $oWpThemes = Services\Services::WpThemes();
570
 
571
+ $aAllPlugins = [];
572
  foreach ( $oRes->getResultsForPluginsContext()->getUniqueSlugs() as $sBaseFile ) {
573
  $oP = $oWpPlugins->getPluginAsVo( $sBaseFile );
574
  if ( !empty( $oP ) ) {
577
  }
578
  }
579
 
580
+ $aAllThemes = [];
581
  foreach ( $oRes->getResultsForThemesContext()->getUniqueSlugs() as $sBaseFile ) {
582
  $oTheme = $oWpThemes->getTheme( $sBaseFile );
583
  if ( !empty( $oTheme ) ) {
661
  * @param array $aData
662
  * @return $this
663
  */
664
+ public function addToAuditEntry( $sMsg = '', $nCategory = 1, $sEvent = '', $aData = [] ) {
665
  $sMsg = sprintf( '[%s]: %s', _wpsf__( 'Plugin/Theme Guard' ), $sMsg );
666
  $this->createNewAudit( 'wpsf', $sMsg, $nCategory, $sEvent, $aData );
667
  return $this;
src/processors/hackprotect_scan_wcf.php CHANGED
@@ -50,7 +50,7 @@ class ICWP_WPSF_Processor_HackProtect_Wcf extends ICWP_WPSF_Processor_ScanBase {
50
  * TODO:
51
  * $aAutoFixIndexFiles = $this->getMod()->getDef( 'corechecksum_autofix' );
52
  * if ( empty( $aAutoFixIndexFiles ) ) {
53
- * $aAutoFixIndexFiles = array();
54
  */
55
 
56
  /**
@@ -67,7 +67,7 @@ class ICWP_WPSF_Processor_HackProtect_Wcf extends ICWP_WPSF_Processor_ScanBase {
67
  */
68
  protected function getFullExclusions() {
69
  $aExclusions = $this->getMod()->getDef( 'corechecksum_exclusions' );
70
- $aExclusions = is_array( $aExclusions ) ? $aExclusions : array();
71
 
72
  // Flywheel specific mods
73
  if ( defined( 'FLYWHEEL_PLUGIN_DIR' ) ) {
@@ -82,7 +82,7 @@ class ICWP_WPSF_Processor_HackProtect_Wcf extends ICWP_WPSF_Processor_ScanBase {
82
  */
83
  protected function getMissingOnlyExclusions() {
84
  $aExclusions = $this->getMod()->getDef( 'corechecksum_exclusions_missing_only' );
85
- return is_array( $aExclusions ) ? $aExclusions : array();
86
  }
87
 
88
  /**
@@ -183,7 +183,7 @@ class ICWP_WPSF_Processor_HackProtect_Wcf extends ICWP_WPSF_Processor_ScanBase {
183
  * @return array
184
  */
185
  private function buildListOfFilesForEmail( $oResult ) {
186
- $aContent = array();
187
 
188
  if ( $oResult->hasChecksumFailed() ) {
189
  $aContent[] = '';
50
  * TODO:
51
  * $aAutoFixIndexFiles = $this->getMod()->getDef( 'corechecksum_autofix' );
52
  * if ( empty( $aAutoFixIndexFiles ) ) {
53
+ * $aAutoFixIndexFiles = [];
54
  */
55
 
56
  /**
67
  */
68
  protected function getFullExclusions() {
69
  $aExclusions = $this->getMod()->getDef( 'corechecksum_exclusions' );
70
+ $aExclusions = is_array( $aExclusions ) ? $aExclusions : [];
71
 
72
  // Flywheel specific mods
73
  if ( defined( 'FLYWHEEL_PLUGIN_DIR' ) ) {
82
  */
83
  protected function getMissingOnlyExclusions() {
84
  $aExclusions = $this->getMod()->getDef( 'corechecksum_exclusions_missing_only' );
85
+ return is_array( $aExclusions ) ? $aExclusions : [];
86
  }
87
 
88
  /**
183
  * @return array
184
  */
185
  private function buildListOfFilesForEmail( $oResult ) {
186
+ $aContent = [];
187
 
188
  if ( $oResult->hasChecksumFailed() ) {
189
  $aContent[] = '';
src/processors/hackprotect_scanner.php CHANGED
@@ -106,10 +106,10 @@ class ICWP_WPSF_Processor_HackProtect_Scanner extends ICWP_WPSF_BaseDbProcessor
106
  }
107
 
108
  /**
109
- * @return \FernleafSystems\Wordpress\Plugin\Shield\Databases\Scanner\Handler
110
  */
111
  protected function createDbHandler() {
112
- return new \FernleafSystems\Wordpress\Plugin\Shield\Databases\Scanner\Handler();
113
  }
114
 
115
  /**
@@ -117,7 +117,7 @@ class ICWP_WPSF_Processor_HackProtect_Scanner extends ICWP_WPSF_BaseDbProcessor
117
  * @param string $sItemId
118
  */
119
  public function downloadItemFile( $sItemId ) {
120
- /** @var \FernleafSystems\Wordpress\Plugin\Shield\Databases\Scanner\EntryVO $oEntry */
121
  $oEntry = $this->getDbHandler()
122
  ->getQuerySelector()
123
  ->byId( (int)$sItemId );
@@ -157,6 +157,6 @@ class ICWP_WPSF_Processor_HackProtect_Scanner extends ICWP_WPSF_BaseDbProcessor
157
  */
158
  protected function getTableColumnsByDefinition() {
159
  $aDef = $this->getMod()->getDef( 'table_columns_scanner' );
160
- return ( is_array( $aDef ) ? $aDef : array() );
161
  }
162
  }
106
  }
107
 
108
  /**
109
+ * @return Scanner\Handler
110
  */
111
  protected function createDbHandler() {
112
+ return new Scanner\Handler();
113
  }
114
 
115
  /**
117
  * @param string $sItemId
118
  */
119
  public function downloadItemFile( $sItemId ) {
120
+ /** @var Scanner\EntryVO $oEntry */
121
  $oEntry = $this->getDbHandler()
122
  ->getQuerySelector()
123
  ->byId( (int)$sItemId );
157
  */
158
  protected function getTableColumnsByDefinition() {
159
  $aDef = $this->getMod()->getDef( 'table_columns_scanner' );
160
+ return ( is_array( $aDef ) ? $aDef : [] );
161
  }
162
  }
src/processors/headers.php CHANGED
@@ -106,7 +106,7 @@ class ICWP_WPSF_Processor_Headers extends ICWP_WPSF_Processor_BaseWpsf {
106
 
107
  $sTemplate = 'default-src %s;';
108
 
109
- $aDefaultSrcDirectives = array();
110
 
111
  if ( $oFO->isOpt( 'xcsp_self', 'Y' ) ) {
112
  $aDefaultSrcDirectives[] = "'self'";
@@ -161,7 +161,7 @@ class ICWP_WPSF_Processor_Headers extends ICWP_WPSF_Processor_BaseWpsf {
161
  */
162
  private function getHeaders() {
163
  if ( !isset( $this->aHeaders ) || !is_array( $this->aHeaders ) ) {
164
- $this->aHeaders = array();
165
  }
166
  return $this->aHeaders;
167
  }
106
 
107
  $sTemplate = 'default-src %s;';
108
 
109
+ $aDefaultSrcDirectives = [];
110
 
111
  if ( $oFO->isOpt( 'xcsp_self', 'Y' ) ) {
112
  $aDefaultSrcDirectives[] = "'self'";
161
  */
162
  private function getHeaders() {
163
  if ( !isset( $this->aHeaders ) || !is_array( $this->aHeaders ) ) {
164
+ $this->aHeaders = [];
165
  }
166
  return $this->aHeaders;
167
  }
src/processors/ips.php CHANGED
@@ -1,6 +1,7 @@
1
  <?php
2
 
3
  use FernleafSystems\Wordpress\Plugin\Shield\Databases\IPs;
 
4
  use FernleafSystems\Wordpress\Services\Services;
5
 
6
  class ICWP_WPSF_Processor_Ips extends ICWP_WPSF_BaseDbProcessor {
@@ -33,42 +34,54 @@ class ICWP_WPSF_Processor_Ips extends ICWP_WPSF_BaseDbProcessor {
33
 
34
  /** @var ICWP_WPSF_FeatureHandler_Ips $oFO */
35
  $oFO = $this->getMod();
36
- if ( $oFO->isAutoBlackListFeatureEnabled() ) {
37
  add_filter( $oFO->prefix( 'firewall_die_message' ), array( $this, 'fAugmentFirewallDieMessage' ) );
38
  add_action( $oFO->prefix( 'pre_plugin_shutdown' ), array( $this, 'doBlackMarkCurrentVisitor' ) );
39
- add_action( 'wp_login_failed', array( $oFO, 'setIpTransgressed' ), 10, 0 );
40
  }
41
-
42
- add_filter( 'authenticate', array( $this, 'addLoginFailedWarningMessage' ), 10000, 1 );
43
- add_action( 'template_redirect', array( $this, 'doTrack404' ) );
44
  }
45
 
46
- public function doTrack404() {
 
47
  /** @var ICWP_WPSF_FeatureHandler_Ips $oFO */
48
  $oFO = $this->getMod();
49
- if ( $oFO->is404Tracking() && is_404() && !$oFO->isVerifiedBot() ) {
50
- if ( $oFO->getOptTracking404() == 'assign-transgression' ) {
51
- $oFO->setIpTransgressed(); // We now black mark this IP
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  }
53
- $this->addToAuditEntry(
54
- sprintf( _wpsf__( '404 detected at "%s"' ), $this->loadRequest()->getPath() ),
55
- 2, 'request_tracking_404'
56
- );
57
- }
58
- }
59
 
60
- /**
61
- * @param WP_User|WP_Error $oUserOrError
62
- * @return WP_User|WP_Error
63
- */
64
- public function addLoginFailedWarningMessage( $oUserOrError ) {
65
- if ( $this->loadWp()->isRequestUserLogin() && is_wp_error( $oUserOrError ) ) {
66
- $oUserOrError->add(
67
- $this->getMod()->prefix( 'transgression-warning' ),
68
- $this->getMod()->getTextOpt( 'text_loginfailed' )
69
- );
70
  }
71
- return $oUserOrError;
72
  }
73
 
74
  /**
@@ -92,80 +105,18 @@ class ICWP_WPSF_Processor_Ips extends ICWP_WPSF_BaseDbProcessor {
92
  }
93
  }
94
 
95
- /**
96
- * @return array
97
- */
98
- public function getAllValidLists() {
99
- return array(
100
- ICWP_WPSF_FeatureHandler_Ips::LIST_AUTO_BLACK,
101
- ICWP_WPSF_FeatureHandler_Ips::LIST_MANUAL_WHITE,
102
- ICWP_WPSF_FeatureHandler_Ips::LIST_MANUAL_BLACK
103
- );
104
- }
105
-
106
- /**
107
- * @param string $sIp
108
- * @return boolean
109
- */
110
- protected function isValidIpOrRange( $sIp ) {
111
- $oIP = Services::IP();
112
- return $oIP->isValidIp_PublicRemote( $sIp ) || $oIP->isValidIpRange( $sIp );
113
- }
114
-
115
  /**
116
  * @param array $aMessages
117
  * @return array
118
  */
119
  public function fAugmentFirewallDieMessage( $aMessages ) {
120
  if ( !is_array( $aMessages ) ) {
121
- $aMessages = array();
122
  }
123
  $aMessages[] = sprintf( '<p>%s</p>', $this->getTextOfRemainingTransgressions() );
124
  return $aMessages;
125
  }
126
 
127
- /**
128
- * @param WP_User|WP_Error $oUserOrError
129
- * @param string $sUsername
130
- * @return WP_User|WP_Error
131
- */
132
- public function verifyIfAuthenticationValid( $oUserOrError, $sUsername ) {
133
- // Don't concern yourself if visitor is whitelisted
134
- if ( $this->isCurrentIpWhitelisted() ) {
135
- return $oUserOrError;
136
- }
137
-
138
- $bBlackMark = false;
139
- $oWp = $this->loadWp();
140
- if ( $oWp->isRequestUserLogin() ) {
141
-
142
- // If there's an attempt to login with a non-existent username
143
- if ( !empty( $sUsername ) && !in_array( $sUsername, $oWp->getAllUserLoginUsernames() ) ) {
144
- $bBlackMark = true;
145
- }
146
- else {
147
- // If the login failed.
148
- $bUserLoginSuccess = is_object( $oUserOrError ) && ( $oUserOrError instanceof WP_User );
149
- if ( !$bUserLoginSuccess ) {
150
- $bBlackMark = true;
151
- }
152
- }
153
- }
154
-
155
- if ( $bBlackMark ) {
156
- /** @var ICWP_WPSF_FeatureHandler_Ips $oFO */
157
- $oFO = $this->getMod();
158
- $oFO->setIpTransgressed(); // We now black mark this IP
159
-
160
- if ( !is_wp_error( $oUserOrError ) ) {
161
- $oUserOrError = new WP_Error();
162
- }
163
- $oUserOrError->add( 'wpsf-autoblacklist', $this->getTextOfRemainingTransgressions() );
164
- }
165
-
166
- return $oUserOrError;
167
- }
168
-
169
  /**
170
  * @return string
171
  */
@@ -212,7 +163,7 @@ class ICWP_WPSF_Processor_Ips extends ICWP_WPSF_BaseDbProcessor {
212
  // TODO: *Maybe* Have a manual black list process first.
213
 
214
  // now try auto black list
215
- if ( !$bKill && $oFO->isAutoBlackListFeatureEnabled() ) {
216
  $bKill = $this->isIpToBeBlocked( $sIp );
217
  }
218
 
@@ -275,7 +226,7 @@ class ICWP_WPSF_Processor_Ips extends ICWP_WPSF_BaseDbProcessor {
275
  /** @var IPs\Delete $oDel */
276
  $oDel = $this->getDbHandler()->getQueryDeleter();
277
  $oDel->deleteIpFromBlacklists( $sIp );
278
- Services::WpGeneral()->redirectToHome();
279
  }
280
 
281
  return false;
@@ -350,8 +301,8 @@ class ICWP_WPSF_Processor_Ips extends ICWP_WPSF_BaseDbProcessor {
350
  /** @var ICWP_WPSF_FeatureHandler_Ips $oFO */
351
  $oFO = $this->getMod();
352
 
353
- if ( $oFO->isAutoBlackListFeatureEnabled() && !$this->getCon()->isPluginDeleting()
354
- && $this->getIfIpTransgressed() && !$oFO->isVerifiedBot() && !$this->isCurrentIpWhitelisted() ) {
355
 
356
  $this->processTransgression();
357
  }
@@ -372,8 +323,8 @@ class ICWP_WPSF_Processor_Ips extends ICWP_WPSF_BaseDbProcessor {
372
  $nLimit = $oFO->getOptTransgressionLimit();
373
  $nCurrentTrans = $oBlackIp->transgressions;
374
  // At this stage we know it's a transgression. But is it an outright block?
375
- $bBlock = apply_filters( $oFO->prefix( 'ip_block_it' ), false ) || ( $nLimit - $nCurrentTrans == 1 );
376
- $nToIncrement = $bBlock ? ( $nLimit - $nCurrentTrans ) : 1;
377
 
378
  /** @var IPs\Update $oUp */
379
  $oUp = $this->getDbHandler()->getQueryUpdater();
@@ -412,35 +363,6 @@ class ICWP_WPSF_Processor_Ips extends ICWP_WPSF_BaseDbProcessor {
412
  return $this->bVisitorIsWhitelisted;
413
  }
414
 
415
- /**
416
- * @return IPs\EntryVO[]
417
- */
418
- public function getAutoBlacklistIpsData() {
419
- /** @var IPs\Select $oSelect */
420
- $oSelect = $this->getDbHandler()->getQuerySelector();
421
- return $oSelect->allFromList( ICWP_WPSF_FeatureHandler_Ips::LIST_AUTO_BLACK );
422
- }
423
-
424
- /**
425
- * @return IPs\EntryVO[]
426
- */
427
- public function getBlacklistIpData( $sIpAddress ) {
428
- /** @var IPs\Select $oSelect */
429
- $oSelect = $this->getDbHandler()->getQuerySelector();
430
- return $oSelect->allFromList( ICWP_WPSF_FeatureHandler_Ips::LIST_AUTO_BLACK );
431
- }
432
-
433
- /**
434
- * @return string[]
435
- */
436
- public function getAutoBlacklistIps() {
437
- $aIps = array();
438
- foreach ( $this->getAutoBlacklistIpsData() as $oIp ) {
439
- $aIps[] = $oIp->ip;
440
- }
441
- return $aIps;
442
- }
443
-
444
  /**
445
  * @return IPs\EntryVO[]
446
  */
@@ -454,7 +376,7 @@ class ICWP_WPSF_Processor_Ips extends ICWP_WPSF_BaseDbProcessor {
454
  * @return string[]
455
  */
456
  public function getWhitelistIps() {
457
- $aIps = array();
458
  foreach ( $this->getWhitelistIpsData() as $oIp ) {
459
  $aIps[] = $oIp->ip;
460
  }
@@ -678,7 +600,7 @@ class ICWP_WPSF_Processor_Ips extends ICWP_WPSF_BaseDbProcessor {
678
  */
679
  protected function getTableColumnsByDefinition() {
680
  $aDef = $this->getMod()->getDef( 'ip_list_table_columns' );
681
- return is_array( $aDef ) ? $aDef : array();
682
  }
683
 
684
  /**
1
  <?php
2
 
3
  use FernleafSystems\Wordpress\Plugin\Shield\Databases\IPs;
4
+ use FernleafSystems\Wordpress\Plugin\Shield\Modules\IPs\BotTrack;
5
  use FernleafSystems\Wordpress\Services\Services;
6
 
7
  class ICWP_WPSF_Processor_Ips extends ICWP_WPSF_BaseDbProcessor {
34
 
35
  /** @var ICWP_WPSF_FeatureHandler_Ips $oFO */
36
  $oFO = $this->getMod();
37
+ if ( $oFO->isAutoBlackListEnabled() ) {
38
  add_filter( $oFO->prefix( 'firewall_die_message' ), array( $this, 'fAugmentFirewallDieMessage' ) );
39
  add_action( $oFO->prefix( 'pre_plugin_shutdown' ), array( $this, 'doBlackMarkCurrentVisitor' ) );
 
40
  }
 
 
 
41
  }
42
 
43
+ public function onWpInit() {
44
+ parent::onWpInit();
45
  /** @var ICWP_WPSF_FeatureHandler_Ips $oFO */
46
  $oFO = $this->getMod();
47
+
48
+ if ( $this->isReadyToRun() && $oFO->isAutoBlackListEnabled() && !Services::WpUsers()->isUserLoggedIn() ) {
49
+
50
+ if ( !$oFO->isVerifiedBot() ) {
51
+ if ( $oFO->isEnabledTrackXmlRpc() ) {
52
+ ( new BotTrack\TrackXmlRpc() )
53
+ ->setMod( $oFO )
54
+ ->run();
55
+ }
56
+ if ( $oFO->isEnabledTrack404() ) {
57
+ ( new BotTrack\Track404() )
58
+ ->setMod( $oFO )
59
+ ->run();
60
+ }
61
+ if ( $oFO->isEnabledTrackLoginFailed() ) {
62
+ ( new BotTrack\TrackLoginFailed() )
63
+ ->setMod( $oFO )
64
+ ->run();
65
+ }
66
+ if ( $oFO->isEnabledTrackLoginInvalid() ) {
67
+ ( new BotTrack\TrackLoginInvalid() )
68
+ ->setMod( $oFO )
69
+ ->run();
70
+ }
71
+ if ( $oFO->isEnabledTrackFakeWebCrawler() ) {
72
+ ( new BotTrack\TrackFakeWebCrawler() )
73
+ ->setMod( $oFO )
74
+ ->run();
75
+ }
76
  }
 
 
 
 
 
 
77
 
78
+ /** Always run link cheese regardless of the verified bot or not */
79
+ if ( $oFO->isEnabledTrackLinkCheese() ) {
80
+ ( new BotTrack\TrackLinkCheese() )
81
+ ->setMod( $oFO )
82
+ ->run();
83
+ }
 
 
 
 
84
  }
 
85
  }
86
 
87
  /**
105
  }
106
  }
107
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
108
  /**
109
  * @param array $aMessages
110
  * @return array
111
  */
112
  public function fAugmentFirewallDieMessage( $aMessages ) {
113
  if ( !is_array( $aMessages ) ) {
114
+ $aMessages = [];
115
  }
116
  $aMessages[] = sprintf( '<p>%s</p>', $this->getTextOfRemainingTransgressions() );
117
  return $aMessages;
118
  }
119
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
120
  /**
121
  * @return string
122
  */
163
  // TODO: *Maybe* Have a manual black list process first.
164
 
165
  // now try auto black list
166
+ if ( !$bKill && $oFO->isAutoBlackListEnabled() ) {
167
  $bKill = $this->isIpToBeBlocked( $sIp );
168
  }
169
 
226
  /** @var IPs\Delete $oDel */
227
  $oDel = $this->getDbHandler()->getQueryDeleter();
228
  $oDel->deleteIpFromBlacklists( $sIp );
229
+ Services::Response()->redirectToHome();
230
  }
231
 
232
  return false;
301
  /** @var ICWP_WPSF_FeatureHandler_Ips $oFO */
302
  $oFO = $this->getMod();
303
 
304
+ if ( $oFO->isAutoBlackListEnabled() && !$this->getCon()->isPluginDeleting()
305
+ && $oFO->getIfIpTransgressed() && !$oFO->isVerifiedBot() && !$this->isCurrentIpWhitelisted() ) {
306
 
307
  $this->processTransgression();
308
  }
323
  $nLimit = $oFO->getOptTransgressionLimit();
324
  $nCurrentTrans = $oBlackIp->transgressions;
325
  // At this stage we know it's a transgression. But is it an outright block?
326
+ $bBlock = ( $oFO->getIpAction() == 'block' ) || ( $nLimit - $nCurrentTrans == 1 );
327
+ $nToIncrement = $bBlock ? ( $nLimit - $nCurrentTrans ) : $oFO->getIpAction();
328
 
329
  /** @var IPs\Update $oUp */
330
  $oUp = $this->getDbHandler()->getQueryUpdater();
363
  return $this->bVisitorIsWhitelisted;
364
  }
365
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
366
  /**
367
  * @return IPs\EntryVO[]
368
  */
376
  * @return string[]
377
  */
378
  public function getWhitelistIps() {
379
+ $aIps = [];
380
  foreach ( $this->getWhitelistIpsData() as $oIp ) {
381
  $aIps[] = $oIp->ip;
382
  }
600
  */
601
  protected function getTableColumnsByDefinition() {
602
  $aDef = $this->getMod()->getDef( 'ip_list_table_columns' );
603
+ return is_array( $aDef ) ? $aDef : [];
604
  }
605
 
606
  /**
src/processors/lockdown.php CHANGED
@@ -4,8 +4,6 @@ use FernleafSystems\Wordpress\Services\Services;
4
 
5
  class ICWP_WPSF_Processor_Lockdown extends ICWP_WPSF_Processor_BaseWpsf {
6
 
7
- /**
8
- */
9
  public function run() {
10
  /** @var ICWP_WPSF_FeatureHandler_Lockdown $oFO */
11
  $oFO = $this->getMod();
@@ -22,10 +20,6 @@ class ICWP_WPSF_Processor_Lockdown extends ICWP_WPSF_Processor_BaseWpsf {
22
  // add_filter( 'bloginfo_url', array( $this, 'maskWordpressVersion' ), 1, 2 );
23
  }
24
 
25
- if ( false && $this->getOption( 'action_reset_auth_salts' ) == 'Y' ) {
26
- add_action( 'init', array( $this, 'resetAuthKeysSalts' ), 1 );
27
- }
28
-
29
  if ( $oFO->isOpt( 'force_ssl_admin', 'Y' ) && function_exists( 'force_ssl_admin' ) ) {
30
  if ( !defined( 'FORCE_SSL_ADMIN' ) ) {
31
  define( 'FORCE_SSL_ADMIN', true );
@@ -87,7 +81,7 @@ class ICWP_WPSF_Processor_Lockdown extends ICWP_WPSF_Processor_BaseWpsf {
87
  $oFO = $this->getMod();
88
  $oFO->setOptInsightsAt( 'xml_block_at' )
89
  ->setIpTransgressed();
90
- return ( current_filter() == 'xmlrpc_enabled' ) ? false : array();
91
  }
92
 
93
  /**
@@ -165,77 +159,4 @@ class ICWP_WPSF_Processor_Lockdown extends ICWP_WPSF_Processor_BaseWpsf {
165
  = empty( $aData[ $sSlug ][ 'options' ][ 'mask_wordpress_version' ] ) ? 0 : 1;
166
  return $aData;
167
  }
168
-
169
- /**
170
- * @param $sOutput
171
- * @param $sShow
172
- * @return string
173
- */
174
- public function maskWordpressVersion( $sOutput, $sShow ) {
175
- // if ( $sShow === 'version' ) {
176
- // $sOutput = $this->aOptions['mask_wordpress_version'];
177
- // }
178
- // return $sOutput;
179
- }
180
-
181
- /**
182
- */
183
- public function resetAuthKeysSalts() {
184
- $oWpFs = Services::WpFs();
185
-
186
- // Get the new Salts
187
- $sSaltsUrl = 'https://api.wordpress.org/secret-key/1.1/salt/';
188
- $sSalts = Services::HttpRequest()->getContent( $sSaltsUrl );
189
-
190
- $sWpConfigContent = $oWpFs->getContent_WpConfig();
191
- if ( is_null( $sWpConfigContent ) ) {
192
- return;
193
- }
194
-
195
- $aKeys = array(
196
- 'AUTH_KEY',
197
- 'SECURE_AUTH_KEY',
198
- 'LOGGED_IN_KEY',
199
- 'NONCE_KEY',
200
- 'AUTH_SALT',
201
- 'SECURE_AUTH_SALT',
202
- 'LOGGED_IN_SALT',
203
- 'NONCE_SALT'
204
- );
205
-
206
- $aContent = explode( PHP_EOL, $sWpConfigContent );
207
- $fKeyFound = false;
208
- $nStartLine = 0;
209
- foreach ( $aContent as $nLineNumber => $sLine ) {
210
- foreach ( $aKeys as $nPosition => $sKey ) {
211
- if ( strpos( $sLine, $sKey ) === false ) {
212
- continue;
213
- }
214
- if ( $nStartLine == 0 ) {
215
- $nStartLine = $nLineNumber;
216
- }
217
- else {
218
- unset( $aContent[ $nLineNumber ] );
219
- }
220
- $fKeyFound = true;
221
- }
222
- }
223
- $aContent[ $nStartLine ] = $sSalts;
224
- $oWpFs->putContent_WpConfig( implode( PHP_EOL, $aContent ) );
225
- }
226
-
227
- /**
228
- * @deprecated
229
- * @param array $aAllCaps
230
- * @param $cap
231
- * @param array $aArgs
232
- * @return array
233
- */
234
- public function disableFileEditing( $aAllCaps, $cap, $aArgs ) {
235
- $sRequestedCapability = $aArgs[ 0 ];
236
- if ( in_array( $sRequestedCapability, [ 'edit_themes', 'edit_plugins', 'edit_files' ] ) ) {
237
- $aAllCaps[ $sRequestedCapability ] = false;
238
- }
239
- return $aAllCaps;
240
- }
241
  }
4
 
5
  class ICWP_WPSF_Processor_Lockdown extends ICWP_WPSF_Processor_BaseWpsf {
6
 
 
 
7
  public function run() {
8
  /** @var ICWP_WPSF_FeatureHandler_Lockdown $oFO */
9
  $oFO = $this->getMod();
20
  // add_filter( 'bloginfo_url', array( $this, 'maskWordpressVersion' ), 1, 2 );
21
  }
22
 
 
 
 
 
23
  if ( $oFO->isOpt( 'force_ssl_admin', 'Y' ) && function_exists( 'force_ssl_admin' ) ) {
24
  if ( !defined( 'FORCE_SSL_ADMIN' ) ) {
25
  define( 'FORCE_SSL_ADMIN', true );
81
  $oFO = $this->getMod();
82
  $oFO->setOptInsightsAt( 'xml_block_at' )
83
  ->setIpTransgressed();
84
+ return ( current_filter() == 'xmlrpc_enabled' ) ? false : [];
85
  }
86
 
87
  /**
159
  = empty( $aData[ $sSlug ][ 'options' ][ 'mask_wordpress_version' ] ) ? 0 : 1;
160
  return $aData;
161
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
162
  }
src/processors/login_protect.php CHANGED
@@ -16,23 +16,23 @@ class ICWP_WPSF_Processor_LoginProtect extends ICWP_WPSF_Processor_BaseWpsf {
16
  }
17
 
18
  if ( $oFO->isCustomLoginPathEnabled() ) {
19
- $this->getProcessorWpLogin()->run();
20
  }
21
 
22
  // Add GASP checking to the login form.
23
  if ( $oFO->isEnabledGaspCheck() ) {
24
- $this->getProcessorGasp()->run();
25
  }
26
 
27
  if ( $oFO->isCooldownEnabled() && Services::Request()->isPost() ) {
28
- $this->getProcessorCooldown()->run();
29
  }
30
 
31
  if ( $oFO->isGoogleRecaptchaEnabled() ) {
32
- $this->getProcessorGoogleRecaptcha()->run();
33
  }
34
 
35
- $this->getProcessorLoginIntent()->run();
36
  }
37
 
38
  /**
@@ -80,37 +80,50 @@ class ICWP_WPSF_Processor_LoginProtect extends ICWP_WPSF_Processor_BaseWpsf {
80
  }
81
 
82
  /**
83
- * @return ICWP_WPSF_Processor_LoginProtect_Intent
84
  */
85
- public function getProcessorLoginIntent() {
86
- return new ICWP_WPSF_Processor_LoginProtect_Intent( $this->getMod() );
 
 
 
 
 
 
87
  }
88
 
89
  /**
90
  * @return ICWP_WPSF_Processor_LoginProtect_Cooldown
91
  */
92
- protected function getProcessorCooldown() {
93
- return new ICWP_WPSF_Processor_LoginProtect_Cooldown( $this->getMod() );
94
  }
95
 
96
  /**
97
  * @return ICWP_WPSF_Processor_LoginProtect_Gasp
98
  */
99
- protected function getProcessorGasp() {
100
- return new ICWP_WPSF_Processor_LoginProtect_Gasp( $this->getMod() );
101
  }
102
 
103
  /**
104
- * @return ICWP_WPSF_Processor_LoginProtect_WpLogin
105
  */
106
- protected function getProcessorWpLogin() {
107
- return new ICWP_WPSF_Processor_LoginProtect_WpLogin( $this->getMod() );
108
  }
109
 
110
  /**
111
  * @return ICWP_WPSF_Processor_LoginProtect_GoogleRecaptcha
112
  */
113
- protected function getProcessorGoogleRecaptcha() {
114
- return new ICWP_WPSF_Processor_LoginProtect_GoogleRecaptcha( $this->getMod() );
 
 
 
 
 
 
 
115
  }
116
  }
16
  }
17
 
18
  if ( $oFO->isCustomLoginPathEnabled() ) {
19
+ $this->getSubProRename()->run();
20
  }
21
 
22
  // Add GASP checking to the login form.
23
  if ( $oFO->isEnabledGaspCheck() ) {
24
+ $this->getSubProGasp()->run();
25
  }
26
 
27
  if ( $oFO->isCooldownEnabled() && Services::Request()->isPost() ) {
28
+ $this->getSubProCooldown()->run();
29
  }
30
 
31
  if ( $oFO->isGoogleRecaptchaEnabled() ) {
32
+ $this->getSubProRecaptcha()->run();
33
  }
34
 
35
+ $this->getSubProIntent()->run();
36
  }
37
 
38
  /**
80
  }
81
 
82
  /**
83
+ * @return array
84
  */
85
+ protected function getSubProMap() {
86
+ return [
87
+ 'cooldown' => 'ICWP_WPSF_Processor_LoginProtect_Cooldown',
88
+ 'gasp' => 'ICWP_WPSF_Processor_LoginProtect_Gasp',
89
+ 'intent' => 'ICWP_WPSF_Processor_LoginProtect_Intent',
90
+ 'recaptcha' => 'ICWP_WPSF_Processor_LoginProtect_GoogleRecaptcha',
91
+ 'rename' => 'ICWP_WPSF_Processor_LoginProtect_WpLogin',
92
+ ];
93
  }
94
 
95
  /**
96
  * @return ICWP_WPSF_Processor_LoginProtect_Cooldown
97
  */
98
+ private function getSubProCooldown() {
99
+ return $this->getSubPro( 'cooldown' );
100
  }
101
 
102
  /**
103
  * @return ICWP_WPSF_Processor_LoginProtect_Gasp
104
  */
105
+ private function getSubProGasp() {
106
+ return $this->getSubPro( 'gasp' );
107
  }
108
 
109
  /**
110
+ * @return ICWP_WPSF_Processor_LoginProtect_Intent
111
  */
112
+ public function getSubProIntent() {
113
+ return $this->getSubPro( 'intent' );
114
  }
115
 
116
  /**
117
  * @return ICWP_WPSF_Processor_LoginProtect_GoogleRecaptcha
118
  */
119
+ private function getSubProRecaptcha() {
120
+ return $this->getSubPro( 'recaptcha' );
121
+ }
122
+
123
+ /**
124
+ * @return ICWP_WPSF_Processor_LoginProtect_WpLogin
125
+ */
126
+ private function getSubProRename() {
127
+ return $this->getSubPro( 'rename' );
128
  }
129
  }
src/processors/loginprotect_cooldown.php CHANGED
@@ -8,15 +8,16 @@ class ICWP_WPSF_Processor_LoginProtect_Cooldown extends ICWP_WPSF_Processor_Logi
8
  * @throws \Exception
9
  */
10
  protected function performCheckWithException() {
 
 
11
 
12
  if ( !$this->isFactorTested() ) {
13
 
14
  // At this point someone has attempted to login within the previous login wait interval
15
  // So we remove WordPress's authentication filter and our own user check authentication
16
  // And finally return a WP_Error which will be reflected back to the user.
17
- if ( $this->isWithinCooldownPeriod() ) {
18
-
19
- $nRemaining = $this->getCooldownInterval() - $this->getSecondsSinceLastLogin();
20
  $sErrorString = _wpsf__( "Request Cooldown in effect." ).' '
21
  .sprintf(
22
  _wpsf__( "You must wait %s seconds before attempting this action again." ),
@@ -38,50 +39,25 @@ class ICWP_WPSF_Processor_LoginProtect_Cooldown extends ICWP_WPSF_Processor_Logi
38
  /**
39
  * @return int
40
  */
41
- protected function getCooldownInterval() {
42
- return (int)$this->getOption( 'login_limit_interval' );
43
- }
44
-
45
- /**
46
- * @return int
47
- */
48
- protected function getLastLoginTime() {
49
  $sFile = $this->getLastLoginTimeFilePath();
50
- return Services::WpFs()->exists( $sFile ) ? filemtime( $sFile ) : 0;
 
51
  }
52
 
53
  /**
54
  * @return string
55
  */
56
- protected function getLastLoginTimeFilePath() {
57
  return path_join( $this->getCon()->getRootDir(), 'mode.login_throttled' );
58
  }
59
 
60
  /**
61
  * @return $this
62
  */
63
- protected function updateLastLoginTime() {
64
  Services::WpFs()->deleteFile( $this->getLastLoginTimeFilePath() );
65
  Services::WpFs()->touch( $this->getLastLoginTimeFilePath(), $this->time() );
66
  return $this;
67
  }
68
-
69
- /**
70
- * @return bool
71
- */
72
- private function isWithinCooldownPeriod() {
73
- // Is there an interval set?
74
- $nCooldown = $this->getCooldownInterval();
75
- if ( empty( $nCooldown ) || $nCooldown <= 0 ) {
76
- return false;
77
- }
78
- return ( $this->getSecondsSinceLastLogin() < $nCooldown );
79
- }
80
-
81
- /**
82
- * @return int
83
- */
84
- protected function getSecondsSinceLastLogin() {
85
- return ( $this->time() - $this->getLastLoginTime() );
86
- }
87
  }
8
  * @throws \Exception
9
  */
10
  protected function performCheckWithException() {
11
+ /** @var ICWP_WPSF_FeatureHandler_LoginProtect $oFO */
12
+ $oFO = $this->getMod();
13
 
14
  if ( !$this->isFactorTested() ) {
15
 
16
  // At this point someone has attempted to login within the previous login wait interval
17
  // So we remove WordPress's authentication filter and our own user check authentication
18
  // And finally return a WP_Error which will be reflected back to the user.
19
+ $nRemaining = $oFO->getCooldownInterval() - $this->getSecondsSinceLastLogin();
20
+ if ( $nRemaining > 0 ) {
 
21
  $sErrorString = _wpsf__( "Request Cooldown in effect." ).' '
22
  .sprintf(
23
  _wpsf__( "You must wait %s seconds before attempting this action again." ),
39
  /**
40
  * @return int
41
  */
42
+ private function getSecondsSinceLastLogin() {
 
 
 
 
 
 
 
43
  $sFile = $this->getLastLoginTimeFilePath();
44
+ $nLastLogin = Services::WpFs()->exists( $sFile ) ? filemtime( $sFile ) : 0;
45
+ return ( Services::Request()->ts() - $nLastLogin );
46
  }
47
 
48
  /**
49
  * @return string
50
  */
51
+ private function getLastLoginTimeFilePath() {
52
  return path_join( $this->getCon()->getRootDir(), 'mode.login_throttled' );
53
  }
54
 
55
  /**
56
  * @return $this
57
  */
58
+ private function updateLastLoginTime() {
59
  Services::WpFs()->deleteFile( $this->getLastLoginTimeFilePath() );
60
  Services::WpFs()->touch( $this->getLastLoginTimeFilePath(), $this->time() );
61
  return $this;
62
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
  }
src/processors/loginprotect_intent.php CHANGED
@@ -250,7 +250,7 @@ class ICWP_WPSF_Processor_LoginProtect_Intent extends ICWP_WPSF_Processor_BaseWp
250
  $oFO = $this->getMod();
251
  $oCon = $this->getCon();
252
  $oReq = Services::Request();
253
- $aLoginIntentFields = apply_filters( $oFO->prefix( 'login-intent-form-fields' ), array() );
254
 
255
  if ( empty( $aLoginIntentFields ) ) {
256
  return false; // a final guard against displaying an empty form.
250
  $oFO = $this->getMod();
251
  $oCon = $this->getCon();
252
  $oReq = Services::Request();
253
+ $aLoginIntentFields = apply_filters( $oFO->prefix( 'login-intent-form-fields' ), [] );
254
 
255
  if ( empty( $aLoginIntentFields ) ) {
256
  return false; // a final guard against displaying an empty form.
src/processors/loginprotect_intent_tracker.php CHANGED
@@ -49,7 +49,7 @@ class ICWP_WPSF_Processor_LoginProtect_Track {
49
  */
50
  public function getAuthFactorsTracked() {
51
  if ( !isset( $this->aFactorsTracked ) ) {
52
- $this->aFactorsTracked = array();
53
  }
54
  return $this->aFactorsTracked;
55
  }
@@ -59,7 +59,7 @@ class ICWP_WPSF_Processor_LoginProtect_Track {
59
  */
60
  public function getAuthFactorsToTrack() {
61
  if ( !is_array( $this->aFactorsToTrack ) ) {
62
- $this->aFactorsToTrack = array();
63
  }
64
  return array_unique( $this->aFactorsToTrack );
65
  }
49
  */
50
  public function getAuthFactorsTracked() {
51
  if ( !isset( $this->aFactorsTracked ) ) {
52
+ $this->aFactorsTracked = [];
53
  }
54
  return $this->aFactorsTracked;
55
  }
59
  */
60
  public function getAuthFactorsToTrack() {
61
  if ( !is_array( $this->aFactorsToTrack ) ) {
62
+ $this->aFactorsToTrack = [];
63
  }
64
  return array_unique( $this->aFactorsToTrack );
65
  }
src/processors/loginprotect_intentprovider_ga.php CHANGED
@@ -216,7 +216,7 @@ class ICWP_WPSF_Processor_LoginProtect_GoogleAuthenticator extends ICWP_WPSF_Pro
216
  protected function sendEmailConfirmationGaRemoval( $oUser ) {
217
  $bSendSuccess = false;
218
 
219
- $aEmailContent = array();
220
  $aEmailContent[] = _wpsf__( 'You have requested the removal of Google Authenticator from your WordPress account.' )
221
  ._wpsf__( 'Please click the link below to confirm.' );
222
  $aEmailContent[] = $this->generateGaRemovalConfirmationLink();
216
  protected function sendEmailConfirmationGaRemoval( $oUser ) {
217
  $bSendSuccess = false;
218
 
219
+ $aEmailContent = [];
220
  $aEmailContent[] = _wpsf__( 'You have requested the removal of Google Authenticator from your WordPress account.' )
221
  ._wpsf__( 'Please click the link below to confirm.' );
222
  $aEmailContent[] = $this->generateGaRemovalConfirmationLink();
src/processors/loginprotect_intentprovider_yubikey.php CHANGED
@@ -181,7 +181,7 @@ class ICWP_WPSF_Processor_LoginProtect_Yubikey extends ICWP_WPSF_Processor_Login
181
  ];
182
 
183
  $sReqUrl = add_query_arg( $aParts, self::URL_YUBIKEY_VERIFY );
184
- $sYubiResponse = \FernleafSystems\Wordpress\Services\Services::HttpRequest()->getContent( $sReqUrl );
185
 
186
  unset( $aParts[ 'id' ] );
187
  $aParts[ 'status' ] = 'OK';
181
  ];
182
 
183
  $sReqUrl = add_query_arg( $aParts, self::URL_YUBIKEY_VERIFY );
184
+ $sYubiResponse = Services::HttpRequest()->getContent( $sReqUrl );
185
 
186
  unset( $aParts[ 'id' ] );
187
  $aParts[ 'status' ] = 'OK';
src/processors/loginprotect_wplogin.php CHANGED
@@ -118,8 +118,6 @@ class ICWP_WPSF_Processor_LoginProtect_WpLogin extends ICWP_WPSF_Processor_BaseW
118
  }
119
 
120
  if ( $bDoBlock ) {
121
- // We now black mark this IP
122
- // add_filter( $this->getMod()->prefix( 'ip_black_mark' ), '__return_true' );
123
  $this->doWpLoginFailedRedirect404();
124
  }
125
  }
@@ -196,8 +194,6 @@ class ICWP_WPSF_Processor_LoginProtect_WpLogin extends ICWP_WPSF_Processor_BaseW
196
 
197
  public function aLoginFormAction() {
198
  if ( !$this->loadWp()->isRequestLoginUrl() ) {
199
- // We now black mark this IP
200
- // add_filter( $this->getMod()->prefix( 'ip_black_mark' ), '__return_true' );
201
  $this->doWpLoginFailedRedirect404();
202
  die();
203
  }
@@ -224,7 +220,7 @@ class ICWP_WPSF_Processor_LoginProtect_WpLogin extends ICWP_WPSF_Processor_BaseW
224
  if ( !empty( $sRedirectUrl ) ) {
225
  $sRedirectUrl = esc_url( $sRedirectUrl );
226
  if ( @parse_url( $sRedirectUrl ) !== false ) {
227
- Services::WpGeneral()->doRedirect( $sRedirectUrl, array(), false );
228
  }
229
  }
230
 
118
  }
119
 
120
  if ( $bDoBlock ) {
 
 
121
  $this->doWpLoginFailedRedirect404();
122
  }
123
  }
194
 
195
  public function aLoginFormAction() {
196
  if ( !$this->loadWp()->isRequestLoginUrl() ) {
 
 
197
  $this->doWpLoginFailedRedirect404();
198
  die();
199
  }
220
  if ( !empty( $sRedirectUrl ) ) {
221
  $sRedirectUrl = esc_url( $sRedirectUrl );
222
  if ( @parse_url( $sRedirectUrl ) !== false ) {
223
+ Services::WpGeneral()->doRedirect( $sRedirectUrl, [], false );
224
  }
225
  }
226
 
src/processors/mousetrap.php DELETED
@@ -1,51 +0,0 @@
1
- <?php
2
-
3
- use FernleafSystems\Wordpress\Services\Services;
4
- use FernleafSystems\Wordpress\Plugin\Shield\Modules\MouseTrap;
5
-
6
- class ICWP_WPSF_Processor_Mousetrap extends ICWP_WPSF_Processor_BaseWpsf {
7
-
8
- /**
9
- * Resets the object values to be re-used anew
10
- */
11
- public function init() {
12
- parent::init();
13
- }
14
-
15
- /**
16
- */
17
- public function run() {
18
- /** @var ICWP_WPSF_FeatureHandler_Mousetrap $oFO */
19
- $oFO = $this->getMod();
20
-
21
- if ( $oFO->isEnabled404() ) {
22
- ( new MouseTrap\Detect404() )
23
- ->setMod( $oFO )
24
- ->run();
25
- }
26
-
27
- if ( $oFO->isEnabledInvalidUsernames() ) {
28
- ( new MouseTrap\InvalidUsername() )
29
- ->setMod( $oFO )
30
- ->run();
31
- }
32
-
33
- if ( $oFO->isEnabledFakeWebCrawler() ) {
34
- ( new MouseTrap\FakeWebCrawler() )
35
- ->setMod( $oFO )
36
- ->run();
37
- }
38
-
39
- if ( $oFO->isEnabledLinkCheese() ) {
40
- ( new MouseTrap\LinkCheese() )
41
- ->setMod( $oFO )
42
- ->run();
43
- }
44
-
45
- if ( $oFO->isEnabledXmlRpcDetect() ) {
46
- ( new MouseTrap\DetectXmlRpc() )
47
- ->setMod( $oFO )
48
- ->run();
49
- }
50
- }
51
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/processors/plugin.php CHANGED
@@ -123,7 +123,7 @@ class ICWP_WPSF_Processor_Plugin extends ICWP_WPSF_Processor_BasePlugin {
123
  'strings' => array(
124
  'title' => $this->getCon()->getHumanName(),
125
  ),
126
- 'js_snippets' => array()
127
  );
128
  echo $this->getMod()
129
  ->renderTemplate( 'snippets/toaster.twig', $aRenderData, true );
@@ -150,7 +150,7 @@ class ICWP_WPSF_Processor_Plugin extends ICWP_WPSF_Processor_BasePlugin {
150
  'inputs' => array(
151
  'checkboxes' => $this->loadDP()->shuffleArray( $aOpts )
152
  ),
153
- 'js_snippets' => array()
154
  );
155
  echo $this->getMod()
156
  ->renderTemplate( 'snippets/plugin-deactivate-survey.php', $aRenderData );
@@ -227,13 +227,13 @@ class ICWP_WPSF_Processor_Plugin extends ICWP_WPSF_Processor_BasePlugin {
227
  $aRenderData = array(
228
  'notice_attributes' => $aNoticeAttributes,
229
  'strings' => array(
230
- 'title' => 'Come and Join Us!',
231
- 'yes' => "Yes please! I'd love to join in and learn more",
232
- 'no' => "No thanks, I'm not interested in such groups",
233
- 'your_name' => _wpsf__( 'Your Name' ),
234
- 'your_email' => _wpsf__( 'Your Email' ),
235
- 'dismiss' => "No thanks, I'm not interested in such informative groups",
236
- 'summary' => sprintf( 'The %s security team is running an initiative to raise awareness of WordPress Security
237
  and to provide further help with the %s security plugin. Get Involved here:', $sName, $sName ),
238
  'privacy_policy' => sprintf(
239
  'I certify that I have read and agree to the <a href="%s" target="_blank">Privacy Policy</a>',
@@ -244,7 +244,7 @@ class ICWP_WPSF_Processor_Plugin extends ICWP_WPSF_Processor_BasePlugin {
244
  'privacy_policy' => $oModCon->getDef( 'href_privacy_policy' )
245
  ),
246
  'install_days' => $nDays,
247
- 'vars' => [
248
  'name' => $oUser->first_name,
249
  'user_email' => $oUser->user_email
250
  ]
123
  'strings' => array(
124
  'title' => $this->getCon()->getHumanName(),
125
  ),
126
+ 'js_snippets' => []
127
  );
128
  echo $this->getMod()
129
  ->renderTemplate( 'snippets/toaster.twig', $aRenderData, true );
150
  'inputs' => array(
151
  'checkboxes' => $this->loadDP()->shuffleArray( $aOpts )
152
  ),
153
+ 'js_snippets' => []
154
  );
155
  echo $this->getMod()
156
  ->renderTemplate( 'snippets/plugin-deactivate-survey.php', $aRenderData );
227
  $aRenderData = array(
228
  'notice_attributes' => $aNoticeAttributes,
229
  'strings' => array(
230
+ 'title' => 'Come and Join Us!',
231
+ 'yes' => "Yes please! I'd love to join in and learn more",
232
+ 'no' => "No thanks, I'm not interested in such groups",
233
+ 'your_name' => _wpsf__( 'Your Name' ),
234
+ 'your_email' => _wpsf__( 'Your Email' ),
235
+ 'dismiss' => "No thanks, I'm not interested in such informative groups",
236
+ 'summary' => sprintf( 'The %s security team is running an initiative to raise awareness of WordPress Security
237
  and to provide further help with the %s security plugin. Get Involved here:', $sName, $sName ),
238
  'privacy_policy' => sprintf(
239
  'I certify that I have read and agree to the <a href="%s" target="_blank">Privacy Policy</a>',
244
  'privacy_policy' => $oModCon->getDef( 'href_privacy_policy' )
245
  ),
246
  'install_days' => $nDays,
247
+ 'vars' => [
248
  'name' => $oUser->first_name,
249
  'user_email' => $oUser->user_email
250
  ]
src/processors/plugin_badge.php CHANGED
@@ -20,7 +20,7 @@ class ICWP_WPSF_Processor_Plugin_Badge extends ICWP_WPSF_Processor_BaseWpsf {
20
  }
21
 
22
  public function includeJquery() {
23
- wp_enqueue_script( 'jquery', null, array(), false, true );
24
  }
25
 
26
  /**
@@ -44,7 +44,7 @@ class ICWP_WPSF_Processor_Plugin_Badge extends ICWP_WPSF_Processor_BaseWpsf {
44
  );
45
 
46
  if ( !is_array( $aContent ) ) {
47
- $aContent = array();
48
  }
49
  $aContent[] = $oFO->renderTemplate( 'snippets/widget_dashboard_plugin.php', $aDisplayData );
50
  return $aContent;
20
  }
21
 
22
  public function includeJquery() {
23
+ wp_enqueue_script( 'jquery', null, [], false, true );
24
  }
25
 
26
  /**
44
  );
45
 
46
  if ( !is_array( $aContent ) ) {
47
+ $aContent = [];
48
  }
49
  $aContent[] = $oFO->renderTemplate( 'snippets/widget_dashboard_plugin.php', $aDisplayData );
50
  return $aContent;
src/processors/plugin_importexport.php CHANGED
@@ -233,7 +233,7 @@ class ICWP_WPSF_Processor_Plugin_ImportExport extends ICWP_WPSF_Processor_BaseWp
233
  * @return array
234
  */
235
  private function getExportData() {
236
- $aD = apply_filters( $this->getMod()->prefix( 'gather_options_for_export' ), array() );
237
  return is_array( $aD ) ? $aD : [];
238
  }
239
 
@@ -329,7 +329,7 @@ class ICWP_WPSF_Processor_Plugin_ImportExport extends ICWP_WPSF_Processor_BaseWp
329
  }
330
 
331
  $bSuccess = false;
332
- $aData = array();
333
 
334
  if ( !$oFO->isPremium() ) {
335
  $nCode = 1;
233
  * @return array
234
  */
235
  private function getExportData() {
236
+ $aD = apply_filters( $this->getMod()->prefix( 'gather_options_for_export' ), [] );
237
  return is_array( $aD ) ? $aD : [];
238
  }
239
 
329
  }
330
 
331
  $bSuccess = false;
332
+ $aData = [];
333
 
334
  if ( !$oFO->isPremium() ) {
335
  $nCode = 1;
src/processors/plugin_notes.php CHANGED
@@ -31,7 +31,7 @@ class ICWP_WPSF_Processor_Plugin_Notes extends ICWP_WPSF_BaseDbProcessor {
31
  */
32
  protected function getTableColumnsByDefinition() {
33
  $aDef = $this->getMod()->getDef( 'db_notes_table_columns' );
34
- return ( is_array( $aDef ) ? $aDef : array() );
35
  }
36
 
37
  /**
31
  */
32
  protected function getTableColumnsByDefinition() {
33
  $aDef = $this->getMod()->getDef( 'db_notes_table_columns' );
34
+ return ( is_array( $aDef ) ? $aDef : [] );
35
  }
36
 
37
  /**
src/processors/plugin_tracking.php CHANGED
@@ -79,7 +79,7 @@ class ICWP_WPSF_Processor_Plugin_Tracking extends ICWP_WPSF_Processor_BasePlugin
79
  $this->getMod()->prefix( 'collect_tracking_data' ),
80
  $this->getBaseTrackingData()
81
  );
82
- return is_array( $aData ) ? $aData : array();
83
  }
84
 
85
  /**
79
  $this->getMod()->prefix( 'collect_tracking_data' ),
80
  $this->getBaseTrackingData()
81
  );
82
+ return is_array( $aData ) ? $aData : [];
83
  }
84
 
85
  /**
src/processors/sessions.php CHANGED
@@ -258,7 +258,7 @@ class ICWP_WPSF_Processor_Sessions extends ICWP_WPSF_BaseDbProcessor {
258
  */
259
  protected function getTableColumnsByDefinition() {
260
  $aDef = $this->getMod()->getDef( 'sessions_table_columns' );
261
- return ( is_array( $aDef ) ? $aDef : array() );
262
  }
263
 
264
  /**
258
  */
259
  protected function getTableColumnsByDefinition() {
260
  $aDef = $this->getMod()->getDef( 'sessions_table_columns' );
261
+ return ( is_array( $aDef ) ? $aDef : [] );
262
  }
263
 
264
  /**
src/processors/statistics.php CHANGED
@@ -27,7 +27,7 @@ class ICWP_WPSF_Processor_Statistics extends ICWP_WPSF_Processor_BaseWpsf {
27
  public function tracking_DataCollect( $aData ) {
28
  $aData = parent::tracking_DataCollect( $aData );
29
  $aTallys = $this->getAllTallys();
30
- $aTallyTracking = array();
31
  foreach ( $aTallys as $oTally ) {
32
  $sKey = preg_replace( '#[^_a-z]#', '', str_replace( '.', '_', $oTally->stat_key ) );
33
  if ( strpos( $sKey, '_' ) ) {
@@ -43,7 +43,7 @@ class ICWP_WPSF_Processor_Statistics extends ICWP_WPSF_Processor_BaseWpsf {
43
  */
44
  public function getInsightsStats() {
45
  $aAllTallys = $this->getAllTallys();
46
- $aAllStats = array();
47
 
48
  $aSpamCommentKeys = array(
49
  'spam.gasp.checkbox',
@@ -209,7 +209,7 @@ class ICWP_WPSF_Processor_Statistics extends ICWP_WPSF_Processor_BaseWpsf {
209
  );
210
 
211
  if ( !is_array( $aContent ) ) {
212
- $aContent = array();
213
  }
214
  $aContent[] = $oFO->renderTemplate( 'snippets/widget_dashboard_statistics.php', $aDisplayData );
215
  return $aContent;
27
  public function tracking_DataCollect( $aData ) {
28
  $aData = parent::tracking_DataCollect( $aData );
29
  $aTallys = $this->getAllTallys();
30
+ $aTallyTracking = [];
31
  foreach ( $aTallys as $oTally ) {
32
  $sKey = preg_replace( '#[^_a-z]#', '', str_replace( '.', '_', $oTally->stat_key ) );
33
  if ( strpos( $sKey, '_' ) ) {
43
  */
44
  public function getInsightsStats() {
45
  $aAllTallys = $this->getAllTallys();
46
+ $aAllStats = [];
47
 
48
  $aSpamCommentKeys = array(
49
  'spam.gasp.checkbox',
209
  );
210
 
211
  if ( !is_array( $aContent ) ) {
212
+ $aContent = [];
213
  }
214
  $aContent[] = $oFO->renderTemplate( 'snippets/widget_dashboard_statistics.php', $aDisplayData );
215
  return $aContent;
src/processors/statistics_reporting.php CHANGED
@@ -99,7 +99,7 @@ class ICWP_WPSF_Processor_Statistics_Reporting extends ICWP_WPSF_BaseDbProcessor
99
  */
100
  protected function getTableColumnsByDefinition() {
101
  $aDef = $this->getMod()->getDef( 'reporting_table_columns' );
102
- return ( is_array( $aDef ) ? $aDef : array() );
103
  }
104
 
105
  /**
@@ -119,7 +119,7 @@ class ICWP_WPSF_Processor_Statistics_Reporting extends ICWP_WPSF_BaseDbProcessor
119
  /**
120
  */
121
  protected function commit() {
122
- $aEntries = apply_filters( $this->getMod()->prefix( 'collect_stats' ), array() );
123
  if ( !empty( $aEntries ) && is_array( $aEntries ) ) {
124
  foreach ( $aEntries as $aCollection ) {
125
  foreach ( $aCollection as $sStatKey => $nTally ) {
99
  */
100
  protected function getTableColumnsByDefinition() {
101
  $aDef = $this->getMod()->getDef( 'reporting_table_columns' );
102
+ return ( is_array( $aDef ) ? $aDef : [] );
103
  }
104
 
105
  /**
119
  /**
120
  */
121
  protected function commit() {
122
+ $aEntries = apply_filters( $this->getMod()->prefix( 'collect_stats' ), [] );
123
  if ( !empty( $aEntries ) && is_array( $aEntries ) ) {
124
  foreach ( $aEntries as $aCollection ) {
125
  foreach ( $aCollection as $sStatKey => $nTally ) {
src/processors/statistics_tally.php CHANGED
@@ -33,13 +33,13 @@ class ICWP_WPSF_Processor_Statistics_Tally extends ICWP_WPSF_BaseDbProcessor {
33
  */
34
  protected function getTableColumnsByDefinition() {
35
  $aDef = $this->getMod()->getDef( 'statistics_table_columns' );
36
- return ( is_array( $aDef ) ? $aDef : array() );
37
  }
38
 
39
  /**
40
  */
41
  protected function commit() {
42
- $aEntries = apply_filters( $this->getMod()->prefix( 'collect_stats' ), array() );
43
  if ( empty( $aEntries ) || !is_array( $aEntries ) ) {
44
  return;
45
  }
@@ -103,7 +103,7 @@ class ICWP_WPSF_Processor_Statistics_Tally extends ICWP_WPSF_BaseDbProcessor {
103
  /** @var Tally\EntryVO[] $aAll */
104
  $aAll = $this->getDbHandler()->getQuerySelector()->all();
105
 
106
- $aKeys = array();
107
  foreach ( $aAll as $oTally ) {
108
  if ( !isset( $aKeys[ $oTally->stat_key ] ) ) {
109
  $aKeys[ $oTally->stat_key ] = 0;
33
  */
34
  protected function getTableColumnsByDefinition() {
35
  $aDef = $this->getMod()->getDef( 'statistics_table_columns' );
36
+ return ( is_array( $aDef ) ? $aDef : [] );
37
  }
38
 
39
  /**
40
  */
41
  protected function commit() {
42
+ $aEntries = apply_filters( $this->getMod()->prefix( 'collect_stats' ), [] );
43
  if ( empty( $aEntries ) || !is_array( $aEntries ) ) {
44
  return;
45
  }
103
  /** @var Tally\EntryVO[] $aAll */
104
  $aAll = $this->getDbHandler()->getQuerySelector()->all();
105
 
106
+ $aKeys = [];
107
  foreach ( $aAll as $oTally ) {
108
  if ( !isset( $aKeys[ $oTally->stat_key ] ) ) {
109
  $aKeys[ $oTally->stat_key ] = 0;
src/processors/traffic_logger.php CHANGED
@@ -42,7 +42,7 @@ class ICWP_WPSF_Processor_TrafficLogger extends ICWP_WPSF_BaseDbProcessor {
42
  protected function getIfLogRequest() {
43
  /** @var ICWP_WPSF_FeatureHandler_Traffic $oFO */
44
  $oFO = $this->getMod();
45
- $oWp = $this->loadWp();
46
  $bLoggedIn = Services::WpUsers()->isUserLoggedIn();
47
  return parent::getIfLogRequest()
48
  && !$this->getCon()->isPluginDeleting()
@@ -96,7 +96,7 @@ class ICWP_WPSF_Processor_TrafficLogger extends ICWP_WPSF_BaseDbProcessor {
96
  $oSP = $this->loadServiceProviders();
97
 
98
  $sIp = $this->ip();
99
- $sAgent = (string)$this->loadRequest()->server( 'HTTP_USER_AGENT' );
100
  return $oSP->isIp_GoogleBot( $sIp, $sAgent )
101
  || $oSP->isIp_BingBot( $sIp, $sAgent )
102
  || $oSP->isIp_DuckDuckGoBot( $sIp, $sAgent )
@@ -113,14 +113,16 @@ class ICWP_WPSF_Processor_TrafficLogger extends ICWP_WPSF_BaseDbProcessor {
113
  $oSP = $this->loadServiceProviders();
114
 
115
  $sIp = $this->ip();
116
- $sAgent = (string)$this->loadRequest()->server( 'HTTP_USER_AGENT' );
117
  return $oSP->isIp_Statuscake( $sIp, $sAgent )
118
  || $oSP->isIp_UptimeRobot( $sIp, $sAgent )
119
  || $oSP->isIp_Pingdom( $sIp, $sAgent );
120
  }
121
 
122
  protected function logTraffic() {
123
- $oReq = $this->loadRequest();
 
 
124
 
125
  // For multisites that are separated by sub-domains we also show the host.
126
  $sLeadingPath = $this->loadWp()->isMultisite_SubdomainInstall() ? $oReq->getHost() : '';
@@ -129,13 +131,13 @@ class ICWP_WPSF_Processor_TrafficLogger extends ICWP_WPSF_BaseDbProcessor {
129
  $oEntry = $this->getDbHandler()->getVo();
130
 
131
  $oEntry->rid = $this->getCon()->getShortRequestId();
132
- $oEntry->uid = $this->loadWpUsers()->getCurrentWpUserId();
133
  $oEntry->ip = inet_pton( $this->ip() );
134
  $oEntry->verb = $oReq->getMethod();
135
  $oEntry->path = $sLeadingPath.$oReq->getPath().( empty( $_GET ) ? '' : '?'.http_build_query( $_GET ) );
136
  $oEntry->code = http_response_code();
137
  $oEntry->ua = $oReq->getUserAgent();
138
- $oEntry->trans = $this->getIfIpTransgressed() ? 1 : 0;
139
 
140
  $this->getDbHandler()
141
  ->getQueryInserter()
@@ -183,6 +185,6 @@ class ICWP_WPSF_Processor_TrafficLogger extends ICWP_WPSF_BaseDbProcessor {
183
  */
184
  protected function getTableColumnsByDefinition() {
185
  $aDef = $this->getMod()->getDef( 'traffic_table_columns' );
186
- return is_array( $aDef ) ? $aDef : array();
187
  }
188
  }
42
  protected function getIfLogRequest() {
43
  /** @var ICWP_WPSF_FeatureHandler_Traffic $oFO */
44
  $oFO = $this->getMod();
45
+ $oWp = Services::WpGeneral();
46
  $bLoggedIn = Services::WpUsers()->isUserLoggedIn();
47
  return parent::getIfLogRequest()
48
  && !$this->getCon()->isPluginDeleting()
96
  $oSP = $this->loadServiceProviders();
97
 
98
  $sIp = $this->ip();
99
+ $sAgent = (string)Services::Request()->getUserAgent();
100
  return $oSP->isIp_GoogleBot( $sIp, $sAgent )
101
  || $oSP->isIp_BingBot( $sIp, $sAgent )
102
  || $oSP->isIp_DuckDuckGoBot( $sIp, $sAgent )
113
  $oSP = $this->loadServiceProviders();
114
 
115
  $sIp = $this->ip();
116
+ $sAgent = (string)Services::Request()->getUserAgent();
117
  return $oSP->isIp_Statuscake( $sIp, $sAgent )
118
  || $oSP->isIp_UptimeRobot( $sIp, $sAgent )
119
  || $oSP->isIp_Pingdom( $sIp, $sAgent );
120
  }
121
 
122
  protected function logTraffic() {
123
+ /** @var ICWP_WPSF_FeatureHandler_Traffic $oFO */
124
+ $oFO = $this->getMod();
125
+ $oReq = Services::Request();
126
 
127
  // For multisites that are separated by sub-domains we also show the host.
128
  $sLeadingPath = $this->loadWp()->isMultisite_SubdomainInstall() ? $oReq->getHost() : '';
131
  $oEntry = $this->getDbHandler()->getVo();
132
 
133
  $oEntry->rid = $this->getCon()->getShortRequestId();
134
+ $oEntry->uid = Services::WpUsers()->getCurrentWpUserId();
135
  $oEntry->ip = inet_pton( $this->ip() );
136
  $oEntry->verb = $oReq->getMethod();
137
  $oEntry->path = $sLeadingPath.$oReq->getPath().( empty( $_GET ) ? '' : '?'.http_build_query( $_GET ) );
138
  $oEntry->code = http_response_code();
139
  $oEntry->ua = $oReq->getUserAgent();
140
+ $oEntry->trans = $oFO->getIfIpTransgressed() ? 1 : 0;
141
 
142
  $this->getDbHandler()
143
  ->getQueryInserter()
185
  */
186
  protected function getTableColumnsByDefinition() {
187
  $aDef = $this->getMod()->getDef( 'traffic_table_columns' );
188
+ return is_array( $aDef ) ? $aDef : [];
189
  }
190
  }
src/wizards/login_protect.php CHANGED
@@ -118,7 +118,7 @@ class ICWP_WPSF_Wizard_LoginProtect extends ICWP_WPSF_Wizard_BaseWpsf {
118
  $oUser = $this->loadWpUsers()->getCurrentWpUser();
119
  /** @var ICWP_WPSF_Processor_LoginProtect $oProc */
120
  $oProc = $oFO->getProcessor();
121
- $oProcGa = $oProc->getProcessorLoginIntent()
122
  ->getProcessorGoogleAuthenticator();
123
  $bValidated = $oProcGa->validateGaCode( $oUser, $sCode );
124
 
@@ -228,7 +228,7 @@ class ICWP_WPSF_Wizard_LoginProtect extends ICWP_WPSF_Wizard_BaseWpsf {
228
  $oUser = $this->loadWpUsers()->getCurrentWpUser();
229
  /** @var ICWP_WPSF_Processor_LoginProtect $oProc */
230
  $oProc = $oFO->getProcessor();
231
- $oProcGa = $oProc->getProcessorLoginIntent()
232
  ->getProcessorGoogleAuthenticator();
233
  $sGaUrl = $oProcGa->getGaRegisterChartUrl( $oUser );
234
  $aAdditional = array(
118
  $oUser = $this->loadWpUsers()->getCurrentWpUser();
119
  /** @var ICWP_WPSF_Processor_LoginProtect $oProc */
120
  $oProc = $oFO->getProcessor();
121
+ $oProcGa = $oProc->getSubProIntent()
122
  ->getProcessorGoogleAuthenticator();
123
  $bValidated = $oProcGa->validateGaCode( $oUser, $sCode );
124
 
228
  $oUser = $this->loadWpUsers()->getCurrentWpUser();
229
  /** @var ICWP_WPSF_Processor_LoginProtect $oProc */
230
  $oProc = $oFO->getProcessor();
231
+ $oProcGa = $oProc->getSubProIntent()
232
  ->getProcessorGoogleAuthenticator();
233
  $sGaUrl = $oProcGa->getGaRegisterChartUrl( $oUser );
234
  $aAdditional = array(
src/wizards/plugin.php CHANGED
@@ -333,7 +333,7 @@ class ICWP_WPSF_Wizard_Plugin extends ICWP_WPSF_Wizard_BaseWpsf {
333
  * @return \FernleafSystems\Utilities\Response
334
  */
335
  private function wizardIpDetect() {
336
- $oIps = \FernleafSystems\Wordpress\Services\Services::IP();
337
  $sIp = Services::Request()->post( 'ip' );
338
 
339
  $oResponse = new \FernleafSystems\Utilities\Response();
333
  * @return \FernleafSystems\Utilities\Response
334
  */
335
  private function wizardIpDetect() {
336
+ $oIps = Services::IP();
337
  $sIp = Services::Request()->post( 'ip' );
338
 
339
  $oResponse = new \FernleafSystems\Utilities\Response();
templates/php/admin_bootstrap.php ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
1
+ <?php
2
+ ?>
3
+
4
+ <div id="ContentHolder">
5
+ <h6 style="margin: 30px">Loading options ...</h6>
6
+ </div>
templates/twig/wpadmin_pages/insights_new/audit/audit_table.twig CHANGED
@@ -29,6 +29,7 @@
29
  {% endfor %}
30
  </select>
31
  </div>
 
32
  <div class="form-group">
33
  <label for="_fIp">IP Address</label>
34
  <select id="_fIp" name="fIp" class="form-control">
@@ -38,6 +39,13 @@
38
  {% endfor %}
39
  </select>
40
  </div>
 
 
 
 
 
 
 
41
  <div class="form-group">
42
  <label for="_fUsername">Username (ignores 'Logged-In' filter)</label>
43
  <select id="_fUsername" name="fUsername" class="form-control">
@@ -50,6 +58,7 @@
50
  Providing a username will cause the 'logged-in' filter to be ignored.
51
  </small>
52
  </div>
 
53
  <div class="form-group">
54
  <label for="_fLoggedIn">Logged-In?</label>
55
  <select id="_fLoggedIn" name="fLoggedIn" class="form-control">
@@ -58,14 +67,20 @@
58
  <option value="0">No</option>
59
  </select>
60
  </div>
61
- <div class="form-group">
62
- <label class="form-check-label" for="_fExludeYou" title="<?php echo $sYourIp; ?>">
63
- Exclude Your Current IP?</label>
64
- <input type="checkbox" id="_fExludeYou" name="fExludeYou" value="Y"
65
- class="form-control" />
 
 
 
 
66
  </div>
 
67
  <div class="form-group text-right">
68
- <input id="SubmitForm" href="#" class="btn btn-info" type="submit" value="Apply Filters" />
 
69
  <a id="ClearForm" href="#" class="btn btn-link">Clear Filters</a>
70
  </div>
71
 
@@ -96,4 +111,17 @@
96
  }
97
  }
98
  );
 
 
 
 
 
 
 
 
 
 
 
 
 
99
  </script>
29
  {% endfor %}
30
  </select>
31
  </div>
32
+
33
  <div class="form-group">
34
  <label for="_fIp">IP Address</label>
35
  <select id="_fIp" name="fIp" class="form-control">
39
  {% endfor %}
40
  </select>
41
  </div>
42
+ <div class="form-group">
43
+ <label class="form-check-label" for="_fExludeYou" title="Exclude Your IP From Results">
44
+ Exclude Your Current IP?</label>
45
+ <input type="checkbox" id="_fExludeYou" name="fExludeYou" value="Y"
46
+ class="form-control" />
47
+ </div>
48
+
49
  <div class="form-group">
50
  <label for="_fUsername">Username (ignores 'Logged-In' filter)</label>
51
  <select id="_fUsername" name="fUsername" class="form-control">
58
  Providing a username will cause the 'logged-in' filter to be ignored.
59
  </small>
60
  </div>
61
+
62
  <div class="form-group">
63
  <label for="_fLoggedIn">Logged-In?</label>
64
  <select id="_fLoggedIn" name="fLoggedIn" class="form-control">
67
  <option value="0">No</option>
68
  </select>
69
  </div>
70
+
71
+ <div class="form-group input-daterange">
72
+ <label class="form-label" for="_fFromDate" title="Show results since...">
73
+ From:</label>
74
+ <input type="text" class="form-control date-picker" id="_fDateFrom"
75
+ name="fDateFrom" value="" placeholder="YYYY-MM-DD">
76
+ <div class="input-group-addon">To:</div>
77
+ <input type="text" class="form-control date-picker" id="_fDateTo"
78
+ name="fDateTo" value="" placeholder="YYYY-MM-DD">
79
  </div>
80
+
81
  <div class="form-group text-right">
82
+ <input id="SubmitForm" href="#" class="btn btn-info" type="submit"
83
+ value="Apply Filters" />
84
  <a id="ClearForm" href="#" class="btn btn-link">Clear Filters</a>
85
  </div>
86
 
111
  }
112
  }
113
  );
114
+
115
+ var $oDataPickers = jQuery( '.date-picker' );
116
+ $oDataPickers.datepicker(
117
+ {
118
+ autoclose: true,
119
+ clearBtn: true,
120
+ format: "yyyy-mm-dd",
121
+ language: "az",
122
+ maxViewMode: 2
123
+ }
124
+ );
125
+
126
+
127
  </script>
templates/twig/wpadmin_pages/insights_new/insights/index.twig CHANGED
@@ -49,12 +49,25 @@
49
  </div>
50
  </div>
51
  </div>
 
 
 
 
 
 
 
 
52
  </div>
53
  <script>
54
  jQuery( '#collapseConfigSummary' ).on( 'shown.bs.collapse', function () {
55
  jQuery( 'html, body' ).animate( {
56
  scrollTop: jQuery( "#collapseConfigSummaryTitle" ).offset().top - 115
57
  }, 750 );
58
- } )
 
 
 
 
 
59
  </script>
60
  {% endblock %}
49
  </div>
50
  </div>
51
  </div>
52
+ {% if flags.show_guided_tour %}
53
+ <a style="display: none;" class="btn btn-default"
54
+ id="IntroVideo"
55
+ href="https://player.vimeo.com/video/326357543"
56
+ data-featherlight="iframe" data-featherlight-iframe-allowfullscreen="true"
57
+ data-featherlight-iframe-width="1200"
58
+ data-featherlight-iframe-height="675">&nbsp;</a>
59
+ {% endif %}
60
  </div>
61
  <script>
62
  jQuery( '#collapseConfigSummary' ).on( 'shown.bs.collapse', function () {
63
  jQuery( 'html, body' ).animate( {
64
  scrollTop: jQuery( "#collapseConfigSummaryTitle" ).offset().top - 115
65
  }, 750 );
66
+ } );
67
+ {% if flags.show_guided_tour %}
68
+ window.onload = function () {
69
+ jQuery( '#IntroVideo' ).click();
70
+ };
71
+ {% endif %}
72
  </script>
73
  {% endblock %}