Shield Security for WordPress - Version 7.4.2

Version Description

  • Current Release = Released: 30th May, 2019 - Release Notes

  • (v.2) NEW: Options finder/jumper menu lets you find and jump to any option in the plugin instantly.

  • (v.2) NEW: Help/explainer videos for a few sections - more to come.

  • (v.2) FIXES: Fixes for a few problems introduced with the recent UI changes.

  • (v.2) FIXED: Welcome wizard launching was broken.

Download this release

Release Info

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

Code changes from version 7.4.1 to 7.4.2

Files changed (88) hide show
  1. filesnotfound.php +32 -0
  2. icwp-plugin-controller.php +12 -22
  3. icwp-wpsf.php +6 -1
  4. plugin-spec.php +4 -2
  5. readme.txt +15 -5
  6. resources/css/bootstrap-select.min.css +6 -0
  7. resources/css/plugin.css +8 -27
  8. resources/js/bootstrap-select.min.js +9 -0
  9. src/common/easydigitaldownloads/ICWP_EDD_LicenseVO.php +0 -212
  10. src/common/googleauthenticator/googleauthenticator.php +0 -252
  11. src/common/googlerecaptcha/ReCaptcha/RequestMethod/WordpressPost.php +0 -60
  12. src/common/icwp-data.php +23 -23
  13. src/common/icwp-edd.php +12 -12
  14. src/common/icwp-foundation.php +7 -36
  15. src/common/icwp-googlearecaptcha.php +0 -35
  16. src/common/icwp-googleauthenticator.php +0 -59
  17. src/common/icwp-ip.php +0 -499
  18. src/common/icwp-optionsvo.php +54 -52
  19. src/common/icwp-render.php +6 -5
  20. src/common/icwp-request.php +3 -3
  21. src/common/icwp-serviceproviders.php +17 -17
  22. src/common/icwp-ssl.php +7 -7
  23. src/common/icwp-usermeta.php +0 -118
  24. src/common/icwp-wpcron.php +4 -4
  25. src/common/icwp-wpfilesystem.php +8 -8
  26. src/common/icwp-wpfunctions-plugins.php +25 -30
  27. src/common/icwp-wpfunctions-themes.php +18 -16
  28. src/common/icwp-wpfunctions.php +14 -14
  29. src/common/icwp-wpincludes.php +16 -45
  30. src/common/icwp-wpupgrades.php +28 -28
  31. src/common/wp-admin-notices.php +13 -13
  32. src/common/wp-comments.php +4 -8
  33. src/common/wp-users.php +10 -67
  34. src/config/feature-admin_access_restriction.php +7 -7
  35. src/config/feature-plugin.php +21 -18
  36. src/features/autoupdates.php +6 -7
  37. src/features/base.php +22 -6
  38. src/features/base_wpsf.php +16 -15
  39. src/features/comments_filter.php +1 -1
  40. src/features/hack_protect.php +4 -4
  41. src/features/insights.php +14 -10
  42. src/features/plugin.php +10 -11
  43. src/features/statistics.php +3 -1
  44. src/lib/src/Utilities/ReCaptcha/WordpressPost.php +40 -0
  45. src/lib/vendor/composer/autoload_classmap.php +3 -7
  46. src/lib/vendor/composer/autoload_static.php +3 -7
  47. src/lib/vendor/composer/installed.json +49 -4
  48. src/lib/vendor/fernleafsystems/wordpress-services/src/Core/Comments.php +29 -41
  49. src/lib/vendor/fernleafsystems/wordpress-services/src/Core/Db.php +7 -0
  50. src/lib/vendor/fernleafsystems/wordpress-services/src/Core/Fs.php +17 -17
  51. src/lib/vendor/fernleafsystems/wordpress-services/src/Core/General.php +68 -16
  52. src/lib/vendor/fernleafsystems/wordpress-services/src/Core/Includes.php +19 -0
  53. src/lib/vendor/fernleafsystems/wordpress-services/src/Core/Plugins.php +48 -10
  54. src/lib/vendor/fernleafsystems/wordpress-services/src/Core/Response.php +34 -1
  55. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Data.php +32 -43
  56. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Licenses/EddLicenseVO.php +79 -0
  57. src/lib/vendor/phpgangsta/googleauthenticator/PHPGangsta/GoogleAuthenticator.php +252 -0
  58. src/processors/admin_access_restriction.php +12 -13
  59. src/processors/adminaccess_whitelabel.php +5 -5
  60. src/processors/audit_trail_auditor.php +1 -1
  61. src/processors/audit_trail_plugins.php +2 -2
  62. src/processors/audit_trail_users.php +4 -2
  63. src/processors/audit_trail_wordpress.php +6 -2
  64. src/processors/autoupdates.php +6 -6
  65. src/processors/base.php +2 -2
  66. src/processors/base_wpsf.php +18 -13
  67. src/processors/basedb.php +2 -2
  68. src/processors/commentsfilter_googlerecaptcha.php +1 -1
  69. src/processors/email.php +5 -2
  70. src/processors/hackprotect_integrity.php +6 -5
  71. src/processors/hackprotect_scan_assets_base.php +1 -1
  72. src/processors/hackprotect_scan_mal.php +1 -1
  73. src/processors/hackprotect_scan_ptg.php +4 -4
  74. src/processors/hackprotect_scan_ufc.php +4 -3
  75. src/processors/hackprotect_scan_wcf.php +2 -10
  76. src/processors/hackprotect_scan_wpv.php +3 -3
  77. src/processors/hackprotect_scanner.php +2 -3
  78. src/processors/ips.php +4 -4
  79. src/processors/loginprotect_intentprovider_ga.php +10 -10
  80. src/processors/plugin_importexport.php +6 -7
  81. src/processors/usermanagement_passwords.php +32 -48
  82. src/wizards/base.php +56 -57
  83. src/wizards/hack_protect.php +4 -4
  84. src/wizards/login_protect.php +3 -3
  85. src/wizards/plugin.php +64 -65
  86. templates/twig/snippets/options_form.twig +41 -4
  87. templates/twig/wpadmin_pages/insights_new/base.twig +24 -1
  88. templates/twig/wpadmin_pages/insights_new/settings/index.twig +4 -0
filesnotfound.php ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ foreach (
4
+ [
5
+ 'ICWP_WPSF_Foundation',
6
+ 'ICWP_WPSF_OptionsVO',
7
+ 'ICWP_WPSF_Plugin_Controller',
8
+ 'ICWP_WPSF_FeatureHandler_Base',
9
+ 'ICWP_WPSF_FeatureHandler_BaseWpsf',
10
+ 'ICWP_WPSF_Processor_Base',
11
+ 'ICWP_WPSF_Processor_BaseWpsf',
12
+ ] as $sClass
13
+ ) {
14
+ if ( !@class_exists( $sClass ) ) {
15
+ add_action( 'admin_notices', 'icwp_wpsf_checkfilesnotfound' );
16
+ add_action( 'network_admin_notices', 'icwp_wpsf_checkfilesnotfound' );
17
+ return false;
18
+ }
19
+ }
20
+
21
+ function icwp_wpsf_checkfilesnotfound() {
22
+ echo sprintf( '<div class="error"><h4>%s</h4><p>%s</p></div>',
23
+ 'Shield Security Plugin - Broken Installation',
24
+ implode( '<br/>', [
25
+ 'It appears the Shield Security plugin was not upgraded/installed correctly.',
26
+ "We run a quick check to make sure certain important files are present in-case a faulty installation breaks your site.",
27
+ 'Try refreshing this page, and if you continue to see this notice, we recommend that you reinstall the Shield Security plugin.'
28
+ ] )
29
+ );
30
+ }
31
+
32
+ return true;
icwp-plugin-controller.php CHANGED
@@ -420,14 +420,6 @@ class ICWP_WPSF_Plugin_Controller extends ICWP_WPSF_Foundation {
420
  );
421
  }
422
 
423
- /**
424
- * @return string
425
- */
426
- public function getOptionsEncoding() {
427
- $sEncoding = $this->getPluginSpec_Property( 'options_encoding' );
428
- return in_array( $sEncoding, [ 'yaml', 'json' ] ) ? $sEncoding : 'yaml';
429
- }
430
-
431
  /**
432
  * @return bool
433
  */
@@ -743,7 +735,7 @@ class ICWP_WPSF_Plugin_Controller extends ICWP_WPSF_Foundation {
743
  * @return boolean
744
  */
745
  public function onWpAutoUpdate( $bDoAutoUpdate, $mItem ) {
746
- $oWp = $this->loadWp();
747
  $oWpPlugins = Services::WpPlugins();
748
 
749
  $sFile = $oWp->getFileFromAutomaticUpdateItem( $mItem );
@@ -1148,7 +1140,7 @@ class ICWP_WPSF_Plugin_Controller extends ICWP_WPSF_Foundation {
1148
  $oConOptions = $this->getPluginControllerOptions();
1149
  $sSpecPath = $this->getPathPluginSpec();
1150
  $sCurrentHash = @md5_file( $sSpecPath );
1151
- $sModifiedTime = $this->loadFS()->getModifiedTime( $sSpecPath );
1152
 
1153
  $this->bRebuildOptions = true;
1154
 
@@ -1176,7 +1168,7 @@ class ICWP_WPSF_Plugin_Controller extends ICWP_WPSF_Foundation {
1176
  */
1177
  public function getIsResetPlugin() {
1178
  if ( !isset( $this->bResetPlugin ) ) {
1179
- $bExists = $this->loadFS()->isFile( $this->getPath_Flags( 'reset' ) );
1180
  $this->bResetPlugin = (bool)$bExists;
1181
  }
1182
  return $this->bResetPlugin;
@@ -1229,9 +1221,9 @@ class ICWP_WPSF_Plugin_Controller extends ICWP_WPSF_Foundation {
1229
  public function getPluginUrl_Asset( $sAsset ) {
1230
  $sUrl = '';
1231
  $sAssetPath = $this->getPath_Assets( $sAsset );
1232
- if ( $this->loadFS()->exists( $sAssetPath ) ) {
1233
  $sUrl = $this->getPluginUrl( $this->getPluginSpec_Path( 'assets' ).'/'.$sAsset );
1234
- return $this->loadWpIncludes()->addIncludeModifiedParam( $sUrl, $sAssetPath );
1235
  }
1236
  return $sUrl;
1237
  }
@@ -1291,10 +1283,9 @@ class ICWP_WPSF_Plugin_Controller extends ICWP_WPSF_Foundation {
1291
  */
1292
  public function getPath_Temp( $sTmpFile = '' ) {
1293
  $sTempPath = null;
1294
- $oFs = $this->loadFS();
1295
 
1296
  $sBase = path_join( $this->getRootDir(), $this->getPluginSpec_Path( 'temp' ) );
1297
- if ( $oFs->mkdir( $sBase ) ) {
1298
  $sTempPath = $sBase;
1299
  }
1300
  return empty( $sTmpFile ) ? $sTempPath : path_join( $sTempPath, $sTmpFile );
@@ -1564,7 +1555,7 @@ class ICWP_WPSF_Plugin_Controller extends ICWP_WPSF_Foundation {
1564
  /**
1565
  */
1566
  public function clearSession() {
1567
- $this->loadRequest()->setDeleteCookie( $this->getPluginPrefix() );
1568
  self::$sSessionId = null;
1569
  }
1570
 
@@ -1592,9 +1583,9 @@ class ICWP_WPSF_Plugin_Controller extends ICWP_WPSF_Foundation {
1592
  */
1593
  protected function getForceOffFilePath() {
1594
  if ( !isset( $this->sForceOffFile ) ) {
1595
- $oFs = $this->loadFS();
1596
- $sFile = $oFs->fileExistsInDir( 'forceOff', $this->getRootDir(), false );
1597
- $this->sForceOffFile = ( !is_null( $sFile ) && $oFs->isFile( $sFile ) ) ? $sFile : false;
1598
  }
1599
  return $this->sForceOffFile;
1600
  }
@@ -1645,11 +1636,10 @@ class ICWP_WPSF_Plugin_Controller extends ICWP_WPSF_Foundation {
1645
  /**
1646
  */
1647
  protected function setSessionCookie() {
1648
- $oReq = $this->loadRequest();
1649
- $oReq->setCookie(
1650
  $this->getPluginPrefix(),
1651
  $this->getSessionId(),
1652
- $oReq->ts() + DAY_IN_SECONDS*30,
1653
  Services::WpGeneral()->getCookiePath(),
1654
  Services::WpGeneral()->getCookieDomain(),
1655
  false
420
  );
421
  }
422
 
 
 
 
 
 
 
 
 
423
  /**
424
  * @return bool
425
  */
735
  * @return boolean
736
  */
737
  public function onWpAutoUpdate( $bDoAutoUpdate, $mItem ) {
738
+ $oWp = Services::WpGeneral();
739
  $oWpPlugins = Services::WpPlugins();
740
 
741
  $sFile = $oWp->getFileFromAutomaticUpdateItem( $mItem );
1140
  $oConOptions = $this->getPluginControllerOptions();
1141
  $sSpecPath = $this->getPathPluginSpec();
1142
  $sCurrentHash = @md5_file( $sSpecPath );
1143
+ $sModifiedTime = Services::WpFs()->getModifiedTime( $sSpecPath );
1144
 
1145
  $this->bRebuildOptions = true;
1146
 
1168
  */
1169
  public function getIsResetPlugin() {
1170
  if ( !isset( $this->bResetPlugin ) ) {
1171
+ $bExists = Services::WpFs()->isFile( $this->getPath_Flags( 'reset' ) );
1172
  $this->bResetPlugin = (bool)$bExists;
1173
  }
1174
  return $this->bResetPlugin;
1221
  public function getPluginUrl_Asset( $sAsset ) {
1222
  $sUrl = '';
1223
  $sAssetPath = $this->getPath_Assets( $sAsset );
1224
+ if ( Services::WpFs()->exists( $sAssetPath ) ) {
1225
  $sUrl = $this->getPluginUrl( $this->getPluginSpec_Path( 'assets' ).'/'.$sAsset );
1226
+ return Services::Includes()->addIncludeModifiedParam( $sUrl, $sAssetPath );
1227
  }
1228
  return $sUrl;
1229
  }
1283
  */
1284
  public function getPath_Temp( $sTmpFile = '' ) {
1285
  $sTempPath = null;
 
1286
 
1287
  $sBase = path_join( $this->getRootDir(), $this->getPluginSpec_Path( 'temp' ) );
1288
+ if ( Services::WpFs()->mkdir( $sBase ) ) {
1289
  $sTempPath = $sBase;
1290
  }
1291
  return empty( $sTmpFile ) ? $sTempPath : path_join( $sTempPath, $sTmpFile );
1555
  /**
1556
  */
1557
  public function clearSession() {
1558
+ Services::Response()->cookieDelete( $this->getPluginPrefix() );
1559
  self::$sSessionId = null;
1560
  }
1561
 
1583
  */
1584
  protected function getForceOffFilePath() {
1585
  if ( !isset( $this->sForceOffFile ) ) {
1586
+ $oFs = Services::WpFs();
1587
+ $sFile = $oFs->findFileInDir( 'forceOff', $this->getRootDir(), false, false );
1588
+ $this->sForceOffFile = ( !empty( $sFile ) && $oFs->isFile( $sFile ) ) ? $sFile : false;
1589
  }
1590
  return $this->sForceOffFile;
1591
  }
1636
  /**
1637
  */
1638
  protected function setSessionCookie() {
1639
+ Services::Response()->cookieSet(
 
1640
  $this->getPluginPrefix(),
1641
  $this->getSessionId(),
1642
+ Services::Request()->ts() + DAY_IN_SECONDS*30,
1643
  Services::WpGeneral()->getCookiePath(),
1644
  Services::WpGeneral()->getCookieDomain(),
1645
  false
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.4.1
7
  * Text Domain: wp-simple-firewall
8
  * Domain Path: /languages
9
  * Author: One Dollar Plugin
@@ -48,6 +48,10 @@ if ( !function_exists( '_wpsf__' ) ) {
48
 
49
  require_once( dirname( __FILE__ ).'/src/lib/vendor/autoload.php' );
50
 
 
 
 
 
51
  add_action( 'plugins_loaded', 'icwp_wpsf_init', 1 ); // use 0 for extensions to ensure hooks have been added.
52
  function icwp_wpsf_init() {
53
  $sRootFile = __FILE__;
@@ -64,4 +68,5 @@ function icwp_wpsf_onactivate() {
64
  }
65
  }
66
  }
 
67
  register_activation_hook( __FILE__, 'icwp_wpsf_onactivate' );
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.4.2
7
  * Text Domain: wp-simple-firewall
8
  * Domain Path: /languages
9
  * Author: One Dollar Plugin
48
 
49
  require_once( dirname( __FILE__ ).'/src/lib/vendor/autoload.php' );
50
 
51
+ if ( !include_once( dirname( __FILE__ ).'/filesnotfound.php' ) ) {
52
+ return;
53
+ }
54
+
55
  add_action( 'plugins_loaded', 'icwp_wpsf_init', 1 ); // use 0 for extensions to ensure hooks have been added.
56
  function icwp_wpsf_init() {
57
  $sRootFile = __FILE__;
68
  }
69
  }
70
  }
71
+
72
  register_activation_hook( __FILE__, 'icwp_wpsf_onactivate' );
plugin-spec.php CHANGED
@@ -1,7 +1,7 @@
1
  {
2
  "properties": {
3
- "version": "7.4.1",
4
- "release_timestamp": 1558340680,
5
  "slug_parent": "icwp",
6
  "slug_plugin": "wpsf",
7
  "human_name": "Shield",
@@ -42,11 +42,13 @@
42
  "plugin_admin": {
43
  "css": [
44
  "bootstrap4",
 
45
  "plugin",
46
  "featherlight"
47
  ],
48
  "js": [
49
  "bootstrap4.bundle.min",
 
50
  "jquery",
51
  "plugin",
52
  "base64.min",
1
  {
2
  "properties": {
3
+ "version": "7.4.2",
4
+ "release_timestamp": 1559221200,
5
  "slug_parent": "icwp",
6
  "slug_plugin": "wpsf",
7
  "human_name": "Shield",
42
  "plugin_admin": {
43
  "css": [
44
  "bootstrap4",
45
+ "bootstrap-select.min",
46
  "plugin",
47
  "featherlight"
48
  ],
49
  "js": [
50
  "bootstrap4.bundle.min",
51
+ "bootstrap-select.min",
52
  "jquery",
53
  "plugin",
54
  "base64.min",
readme.txt CHANGED
@@ -8,7 +8,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.4.1
12
 
13
  Security protection from hackers through smarter automation. Powerful scanners, 2-Factor Auth, limit logins, auto IP blocks & more.
14
 
@@ -355,6 +355,12 @@ Possible options are: network_admin, administrator, editor, author, contributor,
355
 
356
  == Screenshots ==
357
 
 
 
 
 
 
 
358
  == Changelog ==
359
 
360
  Shield Pro brings exclusive features to the serious webmaster to maximise site security.
@@ -364,15 +370,19 @@ You will always be able to use Shield Security and its free features in-full.
364
 
365
  [Go Pro for just $1/month](https://icwp.io/aa).
366
 
367
- = 7.4.1 - Current Release =
368
- *Released: 20th May, 2019* - [Release Notes](https://icwp.io/fc)
369
 
370
- * **(v.1)** NEW: Adjustments and redesign of Shield options pages.
371
- * **(v.1)** IMPROVED: Further prep for better internationalization.
 
 
372
 
373
  = 7.4 - Series =
374
  *Released: 13th May, 2019* - [Release Notes](https://icwp.io/fc)
375
 
 
 
376
  * **(v.0)** NEW: [**PRO**] [Manual/Automatic User Suspension](https://icwp.io/fa)
377
  * **(v.0)** NEW: Comment SPAM - Increase minimum number of approved comments before scanning is skipped
378
  * **(v.0)** NEW: [**PRO**] Comment SPAM - Trusted user roles where comments scanning is skipped
8
  Requires PHP: 5.4.0
9
  Recommended PHP: 7.0
10
  Tested up to: 5.2
11
+ Stable tag: 7.4.2
12
 
13
  Security protection from hackers through smarter automation. Powerful scanners, 2-Factor Auth, limit logins, auto IP blocks & more.
14
 
355
 
356
  == Screenshots ==
357
 
358
+ 1. A top-level dashboard that shows all the important things you need to know at-a-glance.
359
+ 2. IP Whitelist and Blacklists lets you manage access and blocks on your site with ease.
360
+ 3. A full audit log lets you see everything that happens on your site and why, and by whom.
361
+ 4. Track user sessions and monitor who is logged-into your site and what they're doing.
362
+ 5. Simple, clean options pages that let you configure Shield Security and all its options easily.
363
+
364
  == Changelog ==
365
 
366
  Shield Pro brings exclusive features to the serious webmaster to maximise site security.
370
 
371
  [Go Pro for just $1/month](https://icwp.io/aa).
372
 
373
+ = 7.4.2 - Current Release =
374
+ *Released: 30th May, 2019* - [Release Notes](https://icwp.io/fc)
375
 
376
+ * **(v.2)** NEW: Options finder/jumper menu lets you find and jump to any option in the plugin instantly.
377
+ * **(v.2)** NEW: Help/explainer videos for a few sections - more to come.
378
+ * **(v.2)** FIXES: Fixes for a few problems introduced with the recent UI changes.
379
+ * **(v.2)** FIXED: Welcome wizard launching was broken.
380
 
381
  = 7.4 - Series =
382
  *Released: 13th May, 2019* - [Release Notes](https://icwp.io/fc)
383
 
384
+ * **(v.1)** NEW: Adjustments and redesign of Shield options pages.
385
+ * **(v.1)** IMPROVED: Further prep for better internationalization.
386
  * **(v.0)** NEW: [**PRO**] [Manual/Automatic User Suspension](https://icwp.io/fa)
387
  * **(v.0)** NEW: Comment SPAM - Increase minimum number of approved comments before scanning is skipped
388
  * **(v.0)** NEW: [**PRO**] Comment SPAM - Trusted user roles where comments scanning is skipped
resources/css/bootstrap-select.min.css ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
1
+ /*!
2
+ * Bootstrap-select v1.13.10 (https://developer.snapappointments.com/bootstrap-select)
3
+ *
4
+ * Copyright 2012-2019 SnapAppointments, LLC
5
+ * Licensed under MIT (https://github.com/snapappointments/bootstrap-select/blob/master/LICENSE)
6
+ */.bootstrap-select>select.bs-select-hidden,select.bs-select-hidden,select.selectpicker{display:none!important}.bootstrap-select{width:220px\0;vertical-align:middle}.bootstrap-select>.dropdown-toggle{position:relative;width:100%;text-align:right;white-space:nowrap;display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between}.bootstrap-select>.dropdown-toggle:after{margin-top:-1px}.bootstrap-select>.dropdown-toggle.bs-placeholder,.bootstrap-select>.dropdown-toggle.bs-placeholder:active,.bootstrap-select>.dropdown-toggle.bs-placeholder:focus,.bootstrap-select>.dropdown-toggle.bs-placeholder:hover{color:#999}.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-danger,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-danger:active,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-danger:focus,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-danger:hover,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-dark,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-dark:active,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-dark:focus,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-dark:hover,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-info,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-info:active,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-info:focus,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-info:hover,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-primary,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-primary:active,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-primary:focus,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-primary:hover,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-secondary,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-secondary:active,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-secondary:focus,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-secondary:hover,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-success,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-success:active,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-success:focus,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-success:hover{color:rgba(255,255,255,.5)}.bootstrap-select>select{position:absolute!important;bottom:0;left:50%;display:block!important;width:.5px!important;height:100%!important;padding:0!important;opacity:0!important;border:none;z-index:0!important}.bootstrap-select>select.mobile-device{top:0;left:0;display:block!important;width:100%!important;z-index:2!important}.bootstrap-select.is-invalid .dropdown-toggle,.error .bootstrap-select .dropdown-toggle,.has-error .bootstrap-select .dropdown-toggle,.was-validated .bootstrap-select .selectpicker:invalid+.dropdown-toggle{border-color:#b94a48}.bootstrap-select.is-valid .dropdown-toggle,.was-validated .bootstrap-select .selectpicker:valid+.dropdown-toggle{border-color:#28a745}.bootstrap-select.fit-width{width:auto!important}.bootstrap-select:not([class*=col-]):not([class*=form-control]):not(.input-group-btn){width:220px}.bootstrap-select .dropdown-toggle:focus,.bootstrap-select>select.mobile-device:focus+.dropdown-toggle{outline:thin dotted #333!important;outline:5px auto -webkit-focus-ring-color!important;outline-offset:-2px}.bootstrap-select.form-control{margin-bottom:0;padding:0;border:none;height:auto}:not(.input-group)>.bootstrap-select.form-control:not([class*=col-]){width:100%}.bootstrap-select.form-control.input-group-btn{float:none;z-index:auto}.form-inline .bootstrap-select,.form-inline .bootstrap-select.form-control:not([class*=col-]){width:auto}.bootstrap-select:not(.input-group-btn),.bootstrap-select[class*=col-]{float:none;display:inline-block;margin-left:0}.bootstrap-select.dropdown-menu-right,.bootstrap-select[class*=col-].dropdown-menu-right,.row .bootstrap-select[class*=col-].dropdown-menu-right{float:right}.form-group .bootstrap-select,.form-horizontal .bootstrap-select,.form-inline .bootstrap-select{margin-bottom:0}.form-group-lg .bootstrap-select.form-control,.form-group-sm .bootstrap-select.form-control{padding:0}.form-group-lg .bootstrap-select.form-control .dropdown-toggle,.form-group-sm .bootstrap-select.form-control .dropdown-toggle{height:100%;font-size:inherit;line-height:inherit;border-radius:inherit}.bootstrap-select.form-control-lg .dropdown-toggle,.bootstrap-select.form-control-sm .dropdown-toggle{font-size:inherit;line-height:inherit;border-radius:inherit}.bootstrap-select.form-control-sm .dropdown-toggle{padding:.25rem .5rem}.bootstrap-select.form-control-lg .dropdown-toggle{padding:.5rem 1rem}.form-inline .bootstrap-select .form-control{width:100%}.bootstrap-select.disabled,.bootstrap-select>.disabled{cursor:not-allowed}.bootstrap-select.disabled:focus,.bootstrap-select>.disabled:focus{outline:0!important}.bootstrap-select.bs-container{position:absolute;top:0;left:0;height:0!important;padding:0!important}.bootstrap-select.bs-container .dropdown-menu{z-index:1060}.bootstrap-select .dropdown-toggle .filter-option{position:static;top:0;left:0;float:left;height:100%;width:100%;text-align:left;overflow:hidden;-webkit-box-flex:0;-webkit-flex:0 1 auto;-ms-flex:0 1 auto;flex:0 1 auto}.bs3.bootstrap-select .dropdown-toggle .filter-option{padding-right:inherit}.input-group .bs3-has-addon.bootstrap-select .dropdown-toggle .filter-option{position:absolute;padding-top:inherit;padding-bottom:inherit;padding-left:inherit;float:none}.input-group .bs3-has-addon.bootstrap-select .dropdown-toggle .filter-option .filter-option-inner{padding-right:inherit}.bootstrap-select .dropdown-toggle .filter-option-inner-inner{overflow:hidden}.bootstrap-select .dropdown-toggle .filter-expand{width:0!important;float:left;opacity:0!important;overflow:hidden}.bootstrap-select .dropdown-toggle .caret{position:absolute;top:50%;right:12px;margin-top:-2px;vertical-align:middle}.input-group .bootstrap-select.form-control .dropdown-toggle{border-radius:inherit}.bootstrap-select[class*=col-] .dropdown-toggle{width:100%}.bootstrap-select .dropdown-menu{min-width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.bootstrap-select .dropdown-menu>.inner:focus{outline:0!important}.bootstrap-select .dropdown-menu.inner{position:static;float:none;border:0;padding:0;margin:0;border-radius:0;-webkit-box-shadow:none;box-shadow:none}.bootstrap-select .dropdown-menu li{position:relative}.bootstrap-select .dropdown-menu li.active small{color:rgba(255,255,255,.5)!important}.bootstrap-select .dropdown-menu li.disabled a{cursor:not-allowed}.bootstrap-select .dropdown-menu li a{cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.bootstrap-select .dropdown-menu li a.opt{position:relative;padding-left:2.25em}.bootstrap-select .dropdown-menu li a span.check-mark{display:none}.bootstrap-select .dropdown-menu li a span.text{display:inline-block}.bootstrap-select .dropdown-menu li small{padding-left:.5em}.bootstrap-select .dropdown-menu .notify{position:absolute;bottom:5px;width:96%;margin:0 2%;min-height:26px;padding:3px 5px;background:#f5f5f5;border:1px solid #e3e3e3;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05);pointer-events:none;opacity:.9;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.bootstrap-select .no-results{padding:3px;background:#f5f5f5;margin:0 5px;white-space:nowrap}.bootstrap-select.fit-width .dropdown-toggle .filter-option{position:static;display:inline;padding:0}.bootstrap-select.fit-width .dropdown-toggle .filter-option-inner,.bootstrap-select.fit-width .dropdown-toggle .filter-option-inner-inner{display:inline}.bootstrap-select.fit-width .dropdown-toggle .bs-caret:before{content:'\00a0'}.bootstrap-select.fit-width .dropdown-toggle .caret{position:static;top:auto;margin-top:-1px}.bootstrap-select.show-tick .dropdown-menu .selected span.check-mark{position:absolute;display:inline-block;right:15px;top:5px}.bootstrap-select.show-tick .dropdown-menu li a span.text{margin-right:34px}.bootstrap-select .bs-ok-default:after{content:'';display:block;width:.5em;height:1em;border-style:solid;border-width:0 .26em .26em 0;-webkit-transform:rotate(45deg);-ms-transform:rotate(45deg);-o-transform:rotate(45deg);transform:rotate(45deg)}.bootstrap-select.show-menu-arrow.open>.dropdown-toggle,.bootstrap-select.show-menu-arrow.show>.dropdown-toggle{z-index:1061}.bootstrap-select.show-menu-arrow .dropdown-toggle .filter-option:before{content:'';border-left:7px solid transparent;border-right:7px solid transparent;border-bottom:7px solid rgba(204,204,204,.2);position:absolute;bottom:-4px;left:9px;display:none}.bootstrap-select.show-menu-arrow .dropdown-toggle .filter-option:after{content:'';border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid #fff;position:absolute;bottom:-4px;left:10px;display:none}.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle .filter-option:before{bottom:auto;top:-4px;border-top:7px solid rgba(204,204,204,.2);border-bottom:0}.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle .filter-option:after{bottom:auto;top:-4px;border-top:6px solid #fff;border-bottom:0}.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle .filter-option:before{right:12px;left:auto}.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle .filter-option:after{right:13px;left:auto}.bootstrap-select.show-menu-arrow.open>.dropdown-toggle .filter-option:after,.bootstrap-select.show-menu-arrow.open>.dropdown-toggle .filter-option:before,.bootstrap-select.show-menu-arrow.show>.dropdown-toggle .filter-option:after,.bootstrap-select.show-menu-arrow.show>.dropdown-toggle .filter-option:before{display:block}.bs-actionsbox,.bs-donebutton,.bs-searchbox{padding:4px 8px}.bs-actionsbox{width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.bs-actionsbox .btn-group button{width:50%}.bs-donebutton{float:left;width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.bs-donebutton .btn-group button{width:100%}.bs-searchbox+.bs-actionsbox{padding:0 8px 4px}.bs-searchbox .form-control{margin-bottom:0;width:100%;float:none}
resources/css/plugin.css CHANGED
@@ -172,34 +172,13 @@ p.code-description {
172
  padding-left: 200px;
173
  }
174
  /** Section summaries **/
175
- .row_section_summary {
176
- background-color: rgba(0, 0, 0, 0.02);
177
- border: 1px solid rgb(240, 240, 240);
178
- margin: 10px 20px 20px;
179
- }
180
- .row_section_summary div {
181
- }
182
- .row_section_summary p {
183
- margin: 12px 0;
184
- }
185
- .row_section_summary p.noselect {
186
- -webkit-touch-callout: none;
187
- -webkit-user-select: none;
188
- -moz-user-select: none;
189
- -ms-user-select: none;
190
- user-select: none;
191
- }
192
- .row_section_summary button.section_help_video {
193
- position: relative;
194
- top: 25%;
195
- }
196
- .row_section_summary button.section_help_video .dashicons {
197
- font-size: 33px;
198
- width: 30px;
199
  }
200
- .row_section_summary .section_video > div {
201
- box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
202
- margin-bottom: 20px;
 
203
  }
204
  /** End-Section summaries **/
205
 
@@ -1190,6 +1169,7 @@ table.odp-table.scan-table td.column-path code {
1190
  .form-check .form-check-label {
1191
  margin-left: 8px;
1192
  }
 
1193
  input[type=checkbox].form-check-input {
1194
  margin-top: 5px;
1195
  margin-left: -20px;
@@ -1200,6 +1180,7 @@ input[type=checkbox].form-check-input {
1200
  margin: 0;
1201
  border-width: 10px 20px;
1202
  }
 
1203
  /** copied from bootstrap to override WP admin styles */
1204
  .wp-admin select.custom-select {
1205
  height: calc(1.5em + 0.75rem + 2px);
172
  padding-left: 200px;
173
  }
174
  /** Section summaries **/
175
+ a.section-help-video {
176
+ text-decoration: none;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
177
  }
178
+ a.section-help-video > span {
179
+ font-size: 28px;
180
+ margin-left: 6px;
181
+ color: red;
182
  }
183
  /** End-Section summaries **/
184
 
1169
  .form-check .form-check-label {
1170
  margin-left: 8px;
1171
  }
1172
+ input[type=radio].form-check-input,
1173
  input[type=checkbox].form-check-input {
1174
  margin-top: 5px;
1175
  margin-left: -20px;
1180
  margin: 0;
1181
  border-width: 10px 20px;
1182
  }
1183
+
1184
  /** copied from bootstrap to override WP admin styles */
1185
  .wp-admin select.custom-select {
1186
  height: calc(1.5em + 0.75rem + 2px);
resources/js/bootstrap-select.min.js ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ * Bootstrap-select v1.13.10 (https://developer.snapappointments.com/bootstrap-select)
3
+ *
4
+ * Copyright 2012-2019 SnapAppointments, LLC
5
+ * Licensed under MIT (https://github.com/snapappointments/bootstrap-select/blob/master/LICENSE)
6
+ */
7
+
8
+ !function(e,t){void 0===e&&void 0!==window&&(e=window),"function"==typeof define&&define.amd?define(["jquery"],function(e){return t(e)}):"object"==typeof module&&module.exports?module.exports=t(require("jquery")):t(e.jQuery)}(this,function(e){!function(z){"use strict";var d=["sanitize","whiteList","sanitizeFn"],r=["background","cite","href","itemtype","longdesc","poster","src","xlink:href"],e={"*":["class","dir","id","lang","role","tabindex","style",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},l=/^(?:(?:https?|mailto|ftp|tel|file):|[^&:/?#]*(?:[/?#]|$))/gi,a=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[a-z0-9+/]+=*$/i;function v(e,t){var i=e.nodeName.toLowerCase();if(-1!==z.inArray(i,t))return-1===z.inArray(i,r)||Boolean(e.nodeValue.match(l)||e.nodeValue.match(a));for(var s=z(t).filter(function(e,t){return t instanceof RegExp}),n=0,o=s.length;n<o;n++)if(i.match(s[n]))return!0;return!1}function P(e,t,i){if(i&&"function"==typeof i)return i(e);for(var s=Object.keys(t),n=0,o=e.length;n<o;n++)for(var r=e[n].querySelectorAll("*"),l=0,a=r.length;l<a;l++){var c=r[l],d=c.nodeName.toLowerCase();if(-1!==s.indexOf(d))for(var h=[].slice.call(c.attributes),p=[].concat(t["*"]||[],t[d]||[]),u=0,f=h.length;u<f;u++){var m=h[u];v(m,p)||c.removeAttribute(m.nodeName)}else c.parentNode.removeChild(c)}}"classList"in document.createElement("_")||function(e){if("Element"in e){var t="classList",i="prototype",s=e.Element[i],n=Object,o=function(){var i=z(this);return{add:function(e){return e=Array.prototype.slice.call(arguments).join(" "),i.addClass(e)},remove:function(e){return e=Array.prototype.slice.call(arguments).join(" "),i.removeClass(e)},toggle:function(e,t){return i.toggleClass(e,t)},contains:function(e){return i.hasClass(e)}}};if(n.defineProperty){var r={get:o,enumerable:!0,configurable:!0};try{n.defineProperty(s,t,r)}catch(e){void 0!==e.number&&-2146823252!==e.number||(r.enumerable=!1,n.defineProperty(s,t,r))}}else n[i].__defineGetter__&&s.__defineGetter__(t,o)}}(window);var t,c,i,s=document.createElement("_");if(s.classList.add("c1","c2"),!s.classList.contains("c2")){var n=DOMTokenList.prototype.add,o=DOMTokenList.prototype.remove;DOMTokenList.prototype.add=function(){Array.prototype.forEach.call(arguments,n.bind(this))},DOMTokenList.prototype.remove=function(){Array.prototype.forEach.call(arguments,o.bind(this))}}if(s.classList.toggle("c3",!1),s.classList.contains("c3")){var h=DOMTokenList.prototype.toggle;DOMTokenList.prototype.toggle=function(e,t){return 1 in arguments&&!this.contains(e)==!t?t:h.call(this,e)}}function O(e,t){for(var i,s=[],n=t||e.selectedOptions,o=0,r=n.length;o<r;o++)(i=n[o]).disabled||"OPTGROUP"===i.parentNode.tagName&&i.parentNode.disabled||s.push(i.value||i.text);return e.multiple?s:s.length?s[0]:null}s=null,String.prototype.startsWith||(t=function(){try{var e={},t=Object.defineProperty,i=t(e,e,e)&&t}catch(e){}return i}(),c={}.toString,i=function(e){if(null==this)throw new TypeError;var t=String(this);if(e&&"[object RegExp]"==c.call(e))throw new TypeError;var i=t.length,s=String(e),n=s.length,o=1<arguments.length?arguments[1]:void 0,r=o?Number(o):0;r!=r&&(r=0);var l=Math.min(Math.max(r,0),i);if(i<n+l)return!1;for(var a=-1;++a<n;)if(t.charCodeAt(l+a)!=s.charCodeAt(a))return!1;return!0},t?t(String.prototype,"startsWith",{value:i,configurable:!0,writable:!0}):String.prototype.startsWith=i),Object.keys||(Object.keys=function(e,t,i){for(t in i=[],e)i.hasOwnProperty.call(e,t)&&i.push(t);return i}),HTMLSelectElement&&!HTMLSelectElement.prototype.hasOwnProperty("selectedOptions")&&Object.defineProperty(HTMLSelectElement.prototype,"selectedOptions",{get:function(){return this.querySelectorAll(":checked")}});var p={useDefault:!1,_set:z.valHooks.select.set};z.valHooks.select.set=function(e,t){return t&&!p.useDefault&&z(e).data("selected",!0),p._set.apply(this,arguments)};var T=null,u=function(){try{return new Event("change"),!0}catch(e){return!1}}();function k(e,t,i,s){for(var n=["display","subtext","tokens"],o=!1,r=0;r<n.length;r++){var l=n[r],a=e[l];if(a&&(a=a.toString(),"display"===l&&(a=a.replace(/<[^>]+>/g,"")),s&&(a=w(a)),a=a.toUpperCase(),o="contains"===i?0<=a.indexOf(t):a.startsWith(t)))break}return o}function A(e){return parseInt(e,10)||0}z.fn.triggerNative=function(e){var t,i=this[0];i.dispatchEvent?(u?t=new Event(e,{bubbles:!0}):(t=document.createEvent("Event")).initEvent(e,!0,!1),i.dispatchEvent(t)):i.fireEvent?((t=document.createEventObject()).eventType=e,i.fireEvent("on"+e,t)):this.trigger(e)};var f={"\xc0":"A","\xc1":"A","\xc2":"A","\xc3":"A","\xc4":"A","\xc5":"A","\xe0":"a","\xe1":"a","\xe2":"a","\xe3":"a","\xe4":"a","\xe5":"a","\xc7":"C","\xe7":"c","\xd0":"D","\xf0":"d","\xc8":"E","\xc9":"E","\xca":"E","\xcb":"E","\xe8":"e","\xe9":"e","\xea":"e","\xeb":"e","\xcc":"I","\xcd":"I","\xce":"I","\xcf":"I","\xec":"i","\xed":"i","\xee":"i","\xef":"i","\xd1":"N","\xf1":"n","\xd2":"O","\xd3":"O","\xd4":"O","\xd5":"O","\xd6":"O","\xd8":"O","\xf2":"o","\xf3":"o","\xf4":"o","\xf5":"o","\xf6":"o","\xf8":"o","\xd9":"U","\xda":"U","\xdb":"U","\xdc":"U","\xf9":"u","\xfa":"u","\xfb":"u","\xfc":"u","\xdd":"Y","\xfd":"y","\xff":"y","\xc6":"Ae","\xe6":"ae","\xde":"Th","\xfe":"th","\xdf":"ss","\u0100":"A","\u0102":"A","\u0104":"A","\u0101":"a","\u0103":"a","\u0105":"a","\u0106":"C","\u0108":"C","\u010a":"C","\u010c":"C","\u0107":"c","\u0109":"c","\u010b":"c","\u010d":"c","\u010e":"D","\u0110":"D","\u010f":"d","\u0111":"d","\u0112":"E","\u0114":"E","\u0116":"E","\u0118":"E","\u011a":"E","\u0113":"e","\u0115":"e","\u0117":"e","\u0119":"e","\u011b":"e","\u011c":"G","\u011e":"G","\u0120":"G","\u0122":"G","\u011d":"g","\u011f":"g","\u0121":"g","\u0123":"g","\u0124":"H","\u0126":"H","\u0125":"h","\u0127":"h","\u0128":"I","\u012a":"I","\u012c":"I","\u012e":"I","\u0130":"I","\u0129":"i","\u012b":"i","\u012d":"i","\u012f":"i","\u0131":"i","\u0134":"J","\u0135":"j","\u0136":"K","\u0137":"k","\u0138":"k","\u0139":"L","\u013b":"L","\u013d":"L","\u013f":"L","\u0141":"L","\u013a":"l","\u013c":"l","\u013e":"l","\u0140":"l","\u0142":"l","\u0143":"N","\u0145":"N","\u0147":"N","\u014a":"N","\u0144":"n","\u0146":"n","\u0148":"n","\u014b":"n","\u014c":"O","\u014e":"O","\u0150":"O","\u014d":"o","\u014f":"o","\u0151":"o","\u0154":"R","\u0156":"R","\u0158":"R","\u0155":"r","\u0157":"r","\u0159":"r","\u015a":"S","\u015c":"S","\u015e":"S","\u0160":"S","\u015b":"s","\u015d":"s","\u015f":"s","\u0161":"s","\u0162":"T","\u0164":"T","\u0166":"T","\u0163":"t","\u0165":"t","\u0167":"t","\u0168":"U","\u016a":"U","\u016c":"U","\u016e":"U","\u0170":"U","\u0172":"U","\u0169":"u","\u016b":"u","\u016d":"u","\u016f":"u","\u0171":"u","\u0173":"u","\u0174":"W","\u0175":"w","\u0176":"Y","\u0177":"y","\u0178":"Y","\u0179":"Z","\u017b":"Z","\u017d":"Z","\u017a":"z","\u017c":"z","\u017e":"z","\u0132":"IJ","\u0133":"ij","\u0152":"Oe","\u0153":"oe","\u0149":"'n","\u017f":"s"},m=/[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g,g=RegExp("[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff\\u1ab0-\\u1aff\\u1dc0-\\u1dff]","g");function b(e){return f[e]}function w(e){return(e=e.toString())&&e.replace(m,b).replace(g,"")}var I,x,$,y,S,E=(I={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;","`":"&#x60;"},x=function(e){return I[e]},$="(?:"+Object.keys(I).join("|")+")",y=RegExp($),S=RegExp($,"g"),function(e){return e=null==e?"":""+e,y.test(e)?e.replace(S,x):e}),C={32:" ",48:"0",49:"1",50:"2",51:"3",52:"4",53:"5",54:"6",55:"7",56:"8",57:"9",59:";",65:"A",66:"B",67:"C",68:"D",69:"E",70:"F",71:"G",72:"H",73:"I",74:"J",75:"K",76:"L",77:"M",78:"N",79:"O",80:"P",81:"Q",82:"R",83:"S",84:"T",85:"U",86:"V",87:"W",88:"X",89:"Y",90:"Z",96:"0",97:"1",98:"2",99:"3",100:"4",101:"5",102:"6",103:"7",104:"8",105:"9"},L=27,N=13,D=32,H=9,B=38,W=40,M={success:!1,major:"3"};try{M.full=(z.fn.dropdown.Constructor.VERSION||"").split(" ")[0].split("."),M.major=M.full[0],M.success=!0}catch(e){}var R=0,U=".bs.select",j={DISABLED:"disabled",DIVIDER:"divider",SHOW:"open",DROPUP:"dropup",MENU:"dropdown-menu",MENURIGHT:"dropdown-menu-right",MENULEFT:"dropdown-menu-left",BUTTONCLASS:"btn-default",POPOVERHEADER:"popover-title",ICONBASE:"glyphicon",TICKICON:"glyphicon-ok"},V={MENU:"."+j.MENU},F={span:document.createElement("span"),i:document.createElement("i"),subtext:document.createElement("small"),a:document.createElement("a"),li:document.createElement("li"),whitespace:document.createTextNode("\xa0"),fragment:document.createDocumentFragment()};F.a.setAttribute("role","option"),F.subtext.className="text-muted",F.text=F.span.cloneNode(!1),F.text.className="text",F.checkMark=F.span.cloneNode(!1);var _=new RegExp(B+"|"+W),G=new RegExp("^"+H+"$|"+L),q=function(e,t,i){var s=F.li.cloneNode(!1);return e&&(1===e.nodeType||11===e.nodeType?s.appendChild(e):s.innerHTML=e),void 0!==t&&""!==t&&(s.className=t),null!=i&&s.classList.add("optgroup-"+i),s},K=function(e,t,i){var s=F.a.cloneNode(!0);return e&&(11===e.nodeType?s.appendChild(e):s.insertAdjacentHTML("beforeend",e)),void 0!==t&&""!==t&&(s.className=t),"4"===M.major&&s.classList.add("dropdown-item"),i&&s.setAttribute("style",i),s},Y=function(e,t){var i,s,n=F.text.cloneNode(!1);if(e.content)n.innerHTML=e.content;else{if(n.textContent=e.text,e.icon){var o=F.whitespace.cloneNode(!1);(s=(!0===t?F.i:F.span).cloneNode(!1)).className=e.iconBase+" "+e.icon,F.fragment.appendChild(s),F.fragment.appendChild(o)}e.subtext&&((i=F.subtext.cloneNode(!1)).textContent=e.subtext,n.appendChild(i))}if(!0===t)for(;0<n.childNodes.length;)F.fragment.appendChild(n.childNodes[0]);else F.fragment.appendChild(n);return F.fragment},Z=function(e){var t,i,s=F.text.cloneNode(!1);if(s.innerHTML=e.label,e.icon){var n=F.whitespace.cloneNode(!1);(i=F.span.cloneNode(!1)).className=e.iconBase+" "+e.icon,F.fragment.appendChild(i),F.fragment.appendChild(n)}return e.subtext&&((t=F.subtext.cloneNode(!1)).textContent=e.subtext,s.appendChild(t)),F.fragment.appendChild(s),F.fragment},J=function(e,t){var i=this;p.useDefault||(z.valHooks.select.set=p._set,p.useDefault=!0),this.$element=z(e),this.$newElement=null,this.$button=null,this.$menu=null,this.options=t,this.selectpicker={main:{},search:{},current:{},view:{},keydown:{keyHistory:"",resetKeyHistory:{start:function(){return setTimeout(function(){i.selectpicker.keydown.keyHistory=""},800)}}}},null===this.options.title&&(this.options.title=this.$element.attr("title"));var s=this.options.windowPadding;"number"==typeof s&&(this.options.windowPadding=[s,s,s,s]),this.val=J.prototype.val,this.render=J.prototype.render,this.refresh=J.prototype.refresh,this.setStyle=J.prototype.setStyle,this.selectAll=J.prototype.selectAll,this.deselectAll=J.prototype.deselectAll,this.destroy=J.prototype.destroy,this.remove=J.prototype.remove,this.show=J.prototype.show,this.hide=J.prototype.hide,this.init()};function Q(e){var l,a=arguments,c=e;if([].shift.apply(a),!M.success){try{M.full=(z.fn.dropdown.Constructor.VERSION||"").split(" ")[0].split(".")}catch(e){J.BootstrapVersion?M.full=J.BootstrapVersion.split(" ")[0].split("."):(M.full=[M.major,"0","0"],console.warn("There was an issue retrieving Bootstrap's version. Ensure Bootstrap is being loaded before bootstrap-select and there is no namespace collision. If loading Bootstrap asynchronously, the version may need to be manually specified via $.fn.selectpicker.Constructor.BootstrapVersion.",e))}M.major=M.full[0],M.success=!0}if("4"===M.major){var t=[];J.DEFAULTS.style===j.BUTTONCLASS&&t.push({name:"style",className:"BUTTONCLASS"}),J.DEFAULTS.iconBase===j.ICONBASE&&t.push({name:"iconBase",className:"ICONBASE"}),J.DEFAULTS.tickIcon===j.TICKICON&&t.push({name:"tickIcon",className:"TICKICON"}),j.DIVIDER="dropdown-divider",j.SHOW="show",j.BUTTONCLASS="btn-light",j.POPOVERHEADER="popover-header",j.ICONBASE="",j.TICKICON="bs-ok-default";for(var i=0;i<t.length;i++){e=t[i];J.DEFAULTS[e.name]=j[e.className]}}var s=this.each(function(){var e=z(this);if(e.is("select")){var t=e.data("selectpicker"),i="object"==typeof c&&c;if(t){if(i)for(var s in i)i.hasOwnProperty(s)&&(t.options[s]=i[s])}else{var n=e.data();for(var o in n)n.hasOwnProperty(o)&&-1!==z.inArray(o,d)&&delete n[o];var r=z.extend({},J.DEFAULTS,z.fn.selectpicker.defaults||{},n,i);r.template=z.extend({},J.DEFAULTS.template,z.fn.selectpicker.defaults?z.fn.selectpicker.defaults.template:{},n.template,i.template),e.data("selectpicker",t=new J(this,r))}"string"==typeof c&&(l=t[c]instanceof Function?t[c].apply(t,a):t.options[c])}});return void 0!==l?l:s}J.VERSION="1.13.10",J.DEFAULTS={noneSelectedText:"Nothing selected",noneResultsText:"No results matched {0}",countSelectedText:function(e,t){return 1==e?"{0} item selected":"{0} items selected"},maxOptionsText:function(e,t){return[1==e?"Limit reached ({n} item max)":"Limit reached ({n} items max)",1==t?"Group limit reached ({n} item max)":"Group limit reached ({n} items max)"]},selectAllText:"Select All",deselectAllText:"Deselect All",doneButton:!1,doneButtonText:"Close",multipleSeparator:", ",styleBase:"btn",style:j.BUTTONCLASS,size:"auto",title:null,selectedTextFormat:"values",width:!1,container:!1,hideDisabled:!1,showSubtext:!1,showIcon:!0,showContent:!0,dropupAuto:!0,header:!1,liveSearch:!1,liveSearchPlaceholder:null,liveSearchNormalize:!1,liveSearchStyle:"contains",actionsBox:!1,iconBase:j.ICONBASE,tickIcon:j.TICKICON,showTick:!1,template:{caret:'<span class="caret"></span>'},maxOptions:!1,mobile:!1,selectOnTab:!1,dropdownAlignRight:!1,windowPadding:0,virtualScroll:600,display:!1,sanitize:!0,sanitizeFn:null,whiteList:e},J.prototype={constructor:J,init:function(){var i=this,e=this.$element.attr("id");R++,this.selectId="bs-select-"+R,this.$element[0].classList.add("bs-select-hidden"),this.multiple=this.$element.prop("multiple"),this.autofocus=this.$element.prop("autofocus"),this.$element[0].classList.contains("show-tick")&&(this.options.showTick=!0),this.$newElement=this.createDropdown(),this.$element.after(this.$newElement).prependTo(this.$newElement),this.$button=this.$newElement.children("button"),this.$menu=this.$newElement.children(V.MENU),this.$menuInner=this.$menu.children(".inner"),this.$searchbox=this.$menu.find("input"),this.$element[0].classList.remove("bs-select-hidden"),!0===this.options.dropdownAlignRight&&this.$menu[0].classList.add(j.MENURIGHT),void 0!==e&&this.$button.attr("data-id",e),this.checkDisabled(),this.clickListener(),this.options.liveSearch?(this.liveSearchListener(),this.focusedParent=this.$searchbox[0]):this.focusedParent=this.$menuInner[0],this.setStyle(),this.render(),this.setWidth(),this.options.container?this.selectPosition():this.$element.on("hide"+U,function(){if(i.isVirtual()){var e=i.$menuInner[0],t=e.firstChild.cloneNode(!1);e.replaceChild(t,e.firstChild),e.scrollTop=0}}),this.$menu.data("this",this),this.$newElement.data("this",this),this.options.mobile&&this.mobile(),this.$newElement.on({"hide.bs.dropdown":function(e){i.$element.trigger("hide"+U,e)},"hidden.bs.dropdown":function(e){i.$element.trigger("hidden"+U,e)},"show.bs.dropdown":function(e){i.$element.trigger("show"+U,e)},"shown.bs.dropdown":function(e){i.$element.trigger("shown"+U,e)}}),i.$element[0].hasAttribute("required")&&this.$element.on("invalid"+U,function(){i.$button[0].classList.add("bs-invalid"),i.$element.on("shown"+U+".invalid",function(){i.$element.val(i.$element.val()).off("shown"+U+".invalid")}).on("rendered"+U,function(){this.validity.valid&&i.$button[0].classList.remove("bs-invalid"),i.$element.off("rendered"+U)}),i.$button.on("blur"+U,function(){i.$element.trigger("focus").trigger("blur"),i.$button.off("blur"+U)})}),setTimeout(function(){i.createLi(),i.$element.trigger("loaded"+U)})},createDropdown:function(){var e=this.multiple||this.options.showTick?" show-tick":"",t=this.multiple?' aria-multiselectable="true"':"",i="",s=this.autofocus?" autofocus":"";M.major<4&&this.$element.parent().hasClass("input-group")&&(i=" input-group-btn");var n,o="",r="",l="",a="";return this.options.header&&(o='<div class="'+j.POPOVERHEADER+'"><button type="button" class="close" aria-hidden="true">&times;</button>'+this.options.header+"</div>"),this.options.liveSearch&&(r='<div class="bs-searchbox"><input type="text" class="form-control" autocomplete="off"'+(null===this.options.liveSearchPlaceholder?"":' placeholder="'+E(this.options.liveSearchPlaceholder)+'"')+' role="combobox" aria-label="Search" aria-controls="'+this.selectId+'" aria-autocomplete="list"></div>'),this.multiple&&this.options.actionsBox&&(l='<div class="bs-actionsbox"><div class="btn-group btn-group-sm btn-block"><button type="button" class="actions-btn bs-select-all btn '+j.BUTTONCLASS+'">'+this.options.selectAllText+'</button><button type="button" class="actions-btn bs-deselect-all btn '+j.BUTTONCLASS+'">'+this.options.deselectAllText+"</button></div></div>"),this.multiple&&this.options.doneButton&&(a='<div class="bs-donebutton"><div class="btn-group btn-block"><button type="button" class="btn btn-sm '+j.BUTTONCLASS+'">'+this.options.doneButtonText+"</button></div></div>"),n='<div class="dropdown bootstrap-select'+e+i+'"><button type="button" class="'+this.options.styleBase+' dropdown-toggle" '+("static"===this.options.display?'data-display="static"':"")+'data-toggle="dropdown"'+s+' role="combobox" aria-owns="'+this.selectId+'" aria-haspopup="listbox" aria-expanded="false"><div class="filter-option"><div class="filter-option-inner"><div class="filter-option-inner-inner"></div></div> </div>'+("4"===M.major?"":'<span class="bs-caret">'+this.options.template.caret+"</span>")+'</button><div class="'+j.MENU+" "+("4"===M.major?"":j.SHOW)+'">'+o+r+l+'<div class="inner '+j.SHOW+'" role="listbox" id="'+this.selectId+'" tabindex="-1" '+t+'><ul class="'+j.MENU+" inner "+("4"===M.major?j.SHOW:"")+'" role="presentation"></ul></div>'+a+"</div></div>",z(n)},setPositionData:function(){this.selectpicker.view.canHighlight=[];for(var e=this.selectpicker.view.size=0;e<this.selectpicker.current.data.length;e++){var t=this.selectpicker.current.data[e],i=!0;"divider"===t.type?(i=!1,t.height=this.sizeInfo.dividerHeight):"optgroup-label"===t.type?(i=!1,t.height=this.sizeInfo.dropdownHeaderHeight):t.height=this.sizeInfo.liHeight,t.disabled&&(i=!1),this.selectpicker.view.canHighlight.push(i),i&&(this.selectpicker.view.size++,t.posinset=this.selectpicker.view.size),t.position=(0===e?0:this.selectpicker.current.data[e-1].position)+t.height}},isVirtual:function(){return!1!==this.options.virtualScroll&&this.selectpicker.main.elements.length>=this.options.virtualScroll||!0===this.options.virtualScroll},createView:function(A,e,t){var L,N,D=this,i=0,H=[];if(this.selectpicker.current=A?this.selectpicker.search:this.selectpicker.main,this.setPositionData(),e)if(t)i=this.$menuInner[0].scrollTop;else if(!D.multiple){var s=D.$element[0],n=(s.options[s.selectedIndex]||{}).liIndex;if("number"==typeof n&&!1!==D.options.size){var o=D.selectpicker.main.data[n],r=o&&o.position;r&&(i=r-(D.sizeInfo.menuInnerHeight+D.sizeInfo.liHeight)/2)}}function l(e,t){var i,s,n,o,r,l,a,c,d,h,p=D.selectpicker.current.elements.length,u=[],f=!0,m=D.isVirtual();D.selectpicker.view.scrollTop=e,!0===m&&D.sizeInfo.hasScrollBar&&D.$menu[0].offsetWidth>D.sizeInfo.totalMenuWidth&&(D.sizeInfo.menuWidth=D.$menu[0].offsetWidth,D.sizeInfo.totalMenuWidth=D.sizeInfo.menuWidth+D.sizeInfo.scrollBarWidth,D.$menu.css("min-width",D.sizeInfo.menuWidth)),i=Math.ceil(D.sizeInfo.menuInnerHeight/D.sizeInfo.liHeight*1.5),s=Math.round(p/i)||1;for(var v=0;v<s;v++){var g=(v+1)*i;if(v===s-1&&(g=p),u[v]=[v*i+(v?1:0),g],!p)break;void 0===r&&e<=D.selectpicker.current.data[g-1].position-D.sizeInfo.menuInnerHeight&&(r=v)}if(void 0===r&&(r=0),l=[D.selectpicker.view.position0,D.selectpicker.view.position1],n=Math.max(0,r-1),o=Math.min(s-1,r+1),D.selectpicker.view.position0=!1===m?0:Math.max(0,u[n][0])||0,D.selectpicker.view.position1=!1===m?p:Math.min(p,u[o][1])||0,a=l[0]!==D.selectpicker.view.position0||l[1]!==D.selectpicker.view.position1,void 0!==D.activeIndex&&(N=D.selectpicker.main.elements[D.prevActiveIndex],H=D.selectpicker.main.elements[D.activeIndex],L=D.selectpicker.main.elements[D.selectedIndex],t&&(D.activeIndex!==D.selectedIndex&&D.defocusItem(H),D.activeIndex=void 0),D.activeIndex&&D.activeIndex!==D.selectedIndex&&D.defocusItem(L)),void 0!==D.prevActiveIndex&&D.prevActiveIndex!==D.activeIndex&&D.prevActiveIndex!==D.selectedIndex&&D.defocusItem(N),(t||a)&&(c=D.selectpicker.view.visibleElements?D.selectpicker.view.visibleElements.slice():[],D.selectpicker.view.visibleElements=!1===m?D.selectpicker.current.elements:D.selectpicker.current.elements.slice(D.selectpicker.view.position0,D.selectpicker.view.position1),D.setOptionStatus(),(A||!1===m&&t)&&(d=c,h=D.selectpicker.view.visibleElements,f=!(d.length===h.length&&d.every(function(e,t){return e===h[t]}))),(t||!0===m)&&f)){var b,w,I=D.$menuInner[0],x=document.createDocumentFragment(),k=I.firstChild.cloneNode(!1),$=D.selectpicker.view.visibleElements,y=[];I.replaceChild(k,I.firstChild);v=0;for(var S=$.length;v<S;v++){var E,C,O=$[v];D.options.sanitize&&(E=O.lastChild)&&(C=D.selectpicker.current.data[v+D.selectpicker.view.position0])&&C.content&&!C.sanitized&&(y.push(E),C.sanitized=!0),x.appendChild(O)}D.options.sanitize&&y.length&&P(y,D.options.whiteList,D.options.sanitizeFn),I.firstChild.style.marginBottom=!0===m?(b=0===D.selectpicker.view.position0?0:D.selectpicker.current.data[D.selectpicker.view.position0-1].position,w=D.selectpicker.view.position1>p-1?0:D.selectpicker.current.data[p-1].position-D.selectpicker.current.data[D.selectpicker.view.position1-1].position,I.firstChild.style.marginTop=b+"px",w+"px"):I.firstChild.style.marginTop=0,I.firstChild.appendChild(x)}if(D.prevActiveIndex=D.activeIndex,D.options.liveSearch){if(A&&t){var z,T=0;D.selectpicker.view.canHighlight[T]||(T=1+D.selectpicker.view.canHighlight.slice(1).indexOf(!0)),z=D.selectpicker.view.visibleElements[T],D.defocusItem(D.selectpicker.view.currentActive),D.activeIndex=(D.selectpicker.current.data[T]||{}).index,D.focusItem(z)}}else D.$menuInner.trigger("focus")}l(i,!0),this.$menuInner.off("scroll.createView").on("scroll.createView",function(e,t){D.noScroll||l(this.scrollTop,t),D.noScroll=!1}),z(window).off("resize"+U+"."+this.selectId+".createView").on("resize"+U+"."+this.selectId+".createView",function(){D.$newElement.hasClass(j.SHOW)&&l(D.$menuInner[0].scrollTop)})},focusItem:function(e,t,i){if(e){t=t||this.selectpicker.main.data[this.activeIndex];var s=e.firstChild;s&&(s.setAttribute("aria-setsize",this.selectpicker.view.size),s.setAttribute("aria-posinset",t.posinset),!0!==i&&(this.focusedParent.setAttribute("aria-activedescendant",s.id),e.classList.add("active"),s.classList.add("active")))}},defocusItem:function(e){e&&(e.classList.remove("active"),e.firstChild&&e.firstChild.classList.remove("active"))},setPlaceholder:function(){var e=!1;if(this.options.title&&!this.multiple){this.selectpicker.view.titleOption||(this.selectpicker.view.titleOption=document.createElement("option")),e=!0;var t=this.$element[0],i=!1,s=!this.selectpicker.view.titleOption.parentNode;if(s)this.selectpicker.view.titleOption.className="bs-title-option",this.selectpicker.view.titleOption.value="",i=void 0===z(t.options[t.selectedIndex]).attr("selected")&&void 0===this.$element.data("selected");(s||0!==this.selectpicker.view.titleOption.index)&&t.insertBefore(this.selectpicker.view.titleOption,t.firstChild),i&&(t.selectedIndex=0)}return e},createLi:function(){var c=this,f=this.options.iconBase,m=':not([hidden]):not([data-hidden="true"])',v=[],g=[],d=0,b=0,e=this.setPlaceholder()?1:0;this.options.hideDisabled&&(m+=":not(:disabled)"),!c.options.showTick&&!c.multiple||F.checkMark.parentNode||(F.checkMark.className=f+" "+c.options.tickIcon+" check-mark",F.a.appendChild(F.checkMark));var t=this.$element[0].querySelectorAll("select > *"+m);function w(e){var t=g[g.length-1];t&&"divider"===t.type&&(t.optID||e.optID)||((e=e||{}).type="divider",v.push(q(!1,j.DIVIDER,e.optID?e.optID+"div":void 0)),g.push(e))}function I(e,t){if((t=t||{}).divider="true"===e.getAttribute("data-divider"),t.divider)w({optID:t.optID});else{var i=g.length,s=e.style.cssText,n=s?E(s):"",o=(e.className||"")+(t.optgroupClass||"");t.optID&&(o="opt "+o),t.text=e.textContent,t.content=e.getAttribute("data-content"),t.tokens=e.getAttribute("data-tokens"),t.subtext=e.getAttribute("data-subtext"),t.icon=e.getAttribute("data-icon"),t.iconBase=f;var r=Y(t),l=q(K(r,o,n),"",t.optID);l.firstChild&&(l.firstChild.id=c.selectId+"-"+i),v.push(l),e.liIndex=i,t.display=t.content||t.text,t.type="option",t.index=i,t.option=e,t.disabled=t.disabled||e.disabled,g.push(t);var a=0;t.display&&(a+=t.display.length),t.subtext&&(a+=t.subtext.length),t.icon&&(a+=1),d<a&&(d=a,c.selectpicker.view.widestOption=v[v.length-1])}}function i(e,t){var i=t[e],s=t[e-1],n=t[e+1],o=i.querySelectorAll("option"+m);if(o.length){var r,l,a={label:E(i.label),subtext:i.getAttribute("data-subtext"),icon:i.getAttribute("data-icon"),iconBase:f},c=" "+(i.className||"");b++,s&&w({optID:b});var d=Z(a);v.push(q(d,"dropdown-header"+c,b)),g.push({display:a.label,subtext:a.subtext,type:"optgroup-label",optID:b});for(var h=0,p=o.length;h<p;h++){var u=o[h];0===h&&(l=(r=g.length-1)+p),I(u,{headerIndex:r,lastIndex:l,optID:b,optgroupClass:c,disabled:i.disabled})}n&&w({optID:b})}}for(var s=t.length;e<s;e++){var n=t[e];"OPTGROUP"!==n.tagName?I(n,{}):i(e,t)}this.selectpicker.main.elements=v,this.selectpicker.main.data=g,this.selectpicker.current=this.selectpicker.main},findLis:function(){return this.$menuInner.find(".inner > li")},render:function(){this.setPlaceholder();var e,t,i=this,s=this.$element[0],n=function(e,t){var i,s=e.selectedOptions,n=[];if(t){for(var o=0,r=s.length;o<r;o++)(i=s[o]).disabled||"OPTGROUP"===i.parentNode.tagName&&i.parentNode.disabled||n.push(i);return n}return s}(s,this.options.hideDisabled),o=n.length,r=this.$button[0],l=r.querySelector(".filter-option-inner-inner"),a=document.createTextNode(this.options.multipleSeparator),c=F.fragment.cloneNode(!1),d=!1;if(r.classList.toggle("bs-placeholder",i.multiple?!o:!O(s,n)),this.tabIndex(),"static"===this.options.selectedTextFormat)c=Y({text:this.options.title},!0);else if((e=this.multiple&&-1!==this.options.selectedTextFormat.indexOf("count")&&1<o)&&(e=1<(t=this.options.selectedTextFormat.split(">")).length&&o>t[1]||1===t.length&&2<=o),!1===e){for(var h=0;h<o&&h<50;h++){var p=n[h],u={},f={content:p.getAttribute("data-content"),subtext:p.getAttribute("data-subtext"),icon:p.getAttribute("data-icon")};this.multiple&&0<h&&c.appendChild(a.cloneNode(!1)),p.title?u.text=p.title:f.content&&i.options.showContent?(u.content=f.content.toString(),d=!0):(i.options.showIcon&&(u.icon=f.icon,u.iconBase=this.options.iconBase),i.options.showSubtext&&!i.multiple&&f.subtext&&(u.subtext=" "+f.subtext),u.text=p.textContent.trim()),c.appendChild(Y(u,!0))}49<o&&c.appendChild(document.createTextNode("..."))}else{var m=':not([hidden]):not([data-hidden="true"]):not([data-divider="true"])';this.options.hideDisabled&&(m+=":not(:disabled)");var v=this.$element[0].querySelectorAll("select > option"+m+", optgroup"+m+" option"+m).length,g="function"==typeof this.options.countSelectedText?this.options.countSelectedText(o,v):this.options.countSelectedText;c=Y({text:g.replace("{0}",o.toString()).replace("{1}",v.toString())},!0)}if(null==this.options.title&&(this.options.title=this.$element.attr("title")),c.childNodes.length||(c=Y({text:void 0!==this.options.title?this.options.title:this.options.noneSelectedText},!0)),r.title=c.textContent.replace(/<[^>]*>?/g,"").trim(),this.options.sanitize&&d&&P([c],i.options.whiteList,i.options.sanitizeFn),l.innerHTML="",l.appendChild(c),M.major<4&&this.$newElement[0].classList.contains("bs3-has-addon")){var b=r.querySelector(".filter-expand"),w=l.cloneNode(!0);w.className="filter-expand",b?r.replaceChild(w,b):r.appendChild(w)}this.$element.trigger("rendered"+U)},setStyle:function(e,t){var i,s=this.$button[0],n=this.$newElement[0],o=this.options.style.trim();this.$element.attr("class")&&this.$newElement.addClass(this.$element.attr("class").replace(/selectpicker|mobile-device|bs-select-hidden|validate\[.*\]/gi,"")),M.major<4&&(n.classList.add("bs3"),n.parentNode.classList.contains("input-group")&&(n.previousElementSibling||n.nextElementSibling)&&(n.previousElementSibling||n.nextElementSibling).classList.contains("input-group-addon")&&n.classList.add("bs3-has-addon")),i=e?e.trim():o,"add"==t?i&&s.classList.add.apply(s.classList,i.split(" ")):"remove"==t?i&&s.classList.remove.apply(s.classList,i.split(" ")):(o&&s.classList.remove.apply(s.classList,o.split(" ")),i&&s.classList.add.apply(s.classList,i.split(" ")))},liHeight:function(e){if(e||!1!==this.options.size&&!this.sizeInfo){this.sizeInfo||(this.sizeInfo={});var t=document.createElement("div"),i=document.createElement("div"),s=document.createElement("div"),n=document.createElement("ul"),o=document.createElement("li"),r=document.createElement("li"),l=document.createElement("li"),a=document.createElement("a"),c=document.createElement("span"),d=this.options.header&&0<this.$menu.find("."+j.POPOVERHEADER).length?this.$menu.find("."+j.POPOVERHEADER)[0].cloneNode(!0):null,h=this.options.liveSearch?document.createElement("div"):null,p=this.options.actionsBox&&this.multiple&&0<this.$menu.find(".bs-actionsbox").length?this.$menu.find(".bs-actionsbox")[0].cloneNode(!0):null,u=this.options.doneButton&&this.multiple&&0<this.$menu.find(".bs-donebutton").length?this.$menu.find(".bs-donebutton")[0].cloneNode(!0):null,f=this.$element.find("option")[0];if(this.sizeInfo.selectWidth=this.$newElement[0].offsetWidth,c.className="text",a.className="dropdown-item "+(f?f.className:""),t.className=this.$menu[0].parentNode.className+" "+j.SHOW,t.style.width=this.sizeInfo.selectWidth+"px","auto"===this.options.width&&(i.style.minWidth=0),i.className=j.MENU+" "+j.SHOW,s.className="inner "+j.SHOW,n.className=j.MENU+" inner "+("4"===M.major?j.SHOW:""),o.className=j.DIVIDER,r.className="dropdown-header",c.appendChild(document.createTextNode("\u200b")),a.appendChild(c),l.appendChild(a),r.appendChild(c.cloneNode(!0)),this.selectpicker.view.widestOption&&n.appendChild(this.selectpicker.view.widestOption.cloneNode(!0)),n.appendChild(l),n.appendChild(o),n.appendChild(r),d&&i.appendChild(d),h){var m=document.createElement("input");h.className="bs-searchbox",m.className="form-control",h.appendChild(m),i.appendChild(h)}p&&i.appendChild(p),s.appendChild(n),i.appendChild(s),u&&i.appendChild(u),t.appendChild(i),document.body.appendChild(t);var v,g=l.offsetHeight,b=r?r.offsetHeight:0,w=d?d.offsetHeight:0,I=h?h.offsetHeight:0,x=p?p.offsetHeight:0,k=u?u.offsetHeight:0,$=z(o).outerHeight(!0),y=!!window.getComputedStyle&&window.getComputedStyle(i),S=i.offsetWidth,E=y?null:z(i),C={vert:A(y?y.paddingTop:E.css("paddingTop"))+A(y?y.paddingBottom:E.css("paddingBottom"))+A(y?y.borderTopWidth:E.css("borderTopWidth"))+A(y?y.borderBottomWidth:E.css("borderBottomWidth")),horiz:A(y?y.paddingLeft:E.css("paddingLeft"))+A(y?y.paddingRight:E.css("paddingRight"))+A(y?y.borderLeftWidth:E.css("borderLeftWidth"))+A(y?y.borderRightWidth:E.css("borderRightWidth"))},O={vert:C.vert+A(y?y.marginTop:E.css("marginTop"))+A(y?y.marginBottom:E.css("marginBottom"))+2,horiz:C.horiz+A(y?y.marginLeft:E.css("marginLeft"))+A(y?y.marginRight:E.css("marginRight"))+2};s.style.overflowY="scroll",v=i.offsetWidth-S,document.body.removeChild(t),this.sizeInfo.liHeight=g,this.sizeInfo.dropdownHeaderHeight=b,this.sizeInfo.headerHeight=w,this.sizeInfo.searchHeight=I,this.sizeInfo.actionsHeight=x,this.sizeInfo.doneButtonHeight=k,this.sizeInfo.dividerHeight=$,this.sizeInfo.menuPadding=C,this.sizeInfo.menuExtras=O,this.sizeInfo.menuWidth=S,this.sizeInfo.totalMenuWidth=this.sizeInfo.menuWidth,this.sizeInfo.scrollBarWidth=v,this.sizeInfo.selectHeight=this.$newElement[0].offsetHeight,this.setPositionData()}},getSelectPosition:function(){var e,t=z(window),i=this.$newElement.offset(),s=z(this.options.container);this.options.container&&s.length&&!s.is("body")?((e=s.offset()).top+=parseInt(s.css("borderTopWidth")),e.left+=parseInt(s.css("borderLeftWidth"))):e={top:0,left:0};var n=this.options.windowPadding;this.sizeInfo.selectOffsetTop=i.top-e.top-t.scrollTop(),this.sizeInfo.selectOffsetBot=t.height()-this.sizeInfo.selectOffsetTop-this.sizeInfo.selectHeight-e.top-n[2],this.sizeInfo.selectOffsetLeft=i.left-e.left-t.scrollLeft(),this.sizeInfo.selectOffsetRight=t.width()-this.sizeInfo.selectOffsetLeft-this.sizeInfo.selectWidth-e.left-n[1],this.sizeInfo.selectOffsetTop-=n[0],this.sizeInfo.selectOffsetLeft-=n[3]},setMenuSize:function(e){this.getSelectPosition();var t,i,s,n,o,r,l,a=this.sizeInfo.selectWidth,c=this.sizeInfo.liHeight,d=this.sizeInfo.headerHeight,h=this.sizeInfo.searchHeight,p=this.sizeInfo.actionsHeight,u=this.sizeInfo.doneButtonHeight,f=this.sizeInfo.dividerHeight,m=this.sizeInfo.menuPadding,v=0;if(this.options.dropupAuto&&(l=c*this.selectpicker.current.elements.length+m.vert,this.$newElement.toggleClass(j.DROPUP,this.sizeInfo.selectOffsetTop-this.sizeInfo.selectOffsetBot>this.sizeInfo.menuExtras.vert&&l+this.sizeInfo.menuExtras.vert+50>this.sizeInfo.selectOffsetBot)),"auto"===this.options.size)n=3<this.selectpicker.current.elements.length?3*this.sizeInfo.liHeight+this.sizeInfo.menuExtras.vert-2:0,i=this.sizeInfo.selectOffsetBot-this.sizeInfo.menuExtras.vert,s=n+d+h+p+u,r=Math.max(n-m.vert,0),this.$newElement.hasClass(j.DROPUP)&&(i=this.sizeInfo.selectOffsetTop-this.sizeInfo.menuExtras.vert),t=(o=i)-d-h-p-u-m.vert;else if(this.options.size&&"auto"!=this.options.size&&this.selectpicker.current.elements.length>this.options.size){for(var g=0;g<this.options.size;g++)"divider"===this.selectpicker.current.data[g].type&&v++;t=(i=c*this.options.size+v*f+m.vert)-m.vert,o=i+d+h+p+u,s=r=""}"auto"===this.options.dropdownAlignRight&&this.$menu.toggleClass(j.MENURIGHT,this.sizeInfo.selectOffsetLeft>this.sizeInfo.selectOffsetRight&&this.sizeInfo.selectOffsetRight<this.sizeInfo.totalMenuWidth-a),this.$menu.css({"max-height":o+"px",overflow:"hidden","min-height":s+"px"}),this.$menuInner.css({"max-height":t+"px","overflow-y":"auto","min-height":r+"px"}),this.sizeInfo.menuInnerHeight=Math.max(t,1),this.selectpicker.current.data.length&&this.selectpicker.current.data[this.selectpicker.current.data.length-1].position>this.sizeInfo.menuInnerHeight&&(this.sizeInfo.hasScrollBar=!0,this.sizeInfo.totalMenuWidth=this.sizeInfo.menuWidth+this.sizeInfo.scrollBarWidth,this.$menu.css("min-width",this.sizeInfo.totalMenuWidth)),this.dropdown&&this.dropdown._popper&&this.dropdown._popper.update()},setSize:function(e){if(this.liHeight(e),this.options.header&&this.$menu.css("padding-top",0),!1!==this.options.size){var t=this,i=z(window);this.setMenuSize(),this.options.liveSearch&&this.$searchbox.off("input.setMenuSize propertychange.setMenuSize").on("input.setMenuSize propertychange.setMenuSize",function(){return t.setMenuSize()}),"auto"===this.options.size?i.off("resize"+U+"."+this.selectId+".setMenuSize scroll"+U+"."+this.selectId+".setMenuSize").on("resize"+U+"."+this.selectId+".setMenuSize scroll"+U+"."+this.selectId+".setMenuSize",function(){return t.setMenuSize()}):this.options.size&&"auto"!=this.options.size&&this.selectpicker.current.elements.length>this.options.size&&i.off("resize"+U+"."+this.selectId+".setMenuSize scroll"+U+"."+this.selectId+".setMenuSize"),t.createView(!1,!0,e)}},setWidth:function(){var i=this;"auto"===this.options.width?requestAnimationFrame(function(){i.$menu.css("min-width","0"),i.$element.on("loaded"+U,function(){i.liHeight(),i.setMenuSize();var e=i.$newElement.clone().appendTo("body"),t=e.css("width","auto").children("button").outerWidth();e.remove(),i.sizeInfo.selectWidth=Math.max(i.sizeInfo.totalMenuWidth,t),i.$newElement.css("width",i.sizeInfo.selectWidth+"px")})}):"fit"===this.options.width?(this.$menu.css("min-width",""),this.$newElement.css("width","").addClass("fit-width")):this.options.width?(this.$menu.css("min-width",""),this.$newElement.css("width",this.options.width)):(this.$menu.css("min-width",""),this.$newElement.css("width","")),this.$newElement.hasClass("fit-width")&&"fit"!==this.options.width&&this.$newElement[0].classList.remove("fit-width")},selectPosition:function(){this.$bsContainer=z('<div class="bs-container" />');var s,n,o,r=this,l=z(this.options.container),e=function(e){var t={},i=r.options.display||!!z.fn.dropdown.Constructor.Default&&z.fn.dropdown.Constructor.Default.display;r.$bsContainer.addClass(e.attr("class").replace(/form-control|fit-width/gi,"")).toggleClass(j.DROPUP,e.hasClass(j.DROPUP)),s=e.offset(),l.is("body")?n={top:0,left:0}:((n=l.offset()).top+=parseInt(l.css("borderTopWidth"))-l.scrollTop(),n.left+=parseInt(l.css("borderLeftWidth"))-l.scrollLeft()),o=e.hasClass(j.DROPUP)?0:e[0].offsetHeight,(M.major<4||"static"===i)&&(t.top=s.top-n.top+o,t.left=s.left-n.left),t.width=e[0].offsetWidth,r.$bsContainer.css(t)};this.$button.on("click.bs.dropdown.data-api",function(){r.isDisabled()||(e(r.$newElement),r.$bsContainer.appendTo(r.options.container).toggleClass(j.SHOW,!r.$button.hasClass(j.SHOW)).append(r.$menu))}),z(window).off("resize"+U+"."+this.selectId+" scroll"+U+"."+this.selectId).on("resize"+U+"."+this.selectId+" scroll"+U+"."+this.selectId,function(){r.$newElement.hasClass(j.SHOW)&&e(r.$newElement)}),this.$element.on("hide"+U,function(){r.$menu.data("height",r.$menu.height()),r.$bsContainer.detach()})},setOptionStatus:function(e){var t=this;if(t.noScroll=!1,t.selectpicker.view.visibleElements&&t.selectpicker.view.visibleElements.length)for(var i=0;i<t.selectpicker.view.visibleElements.length;i++){var s=t.selectpicker.current.data[i+t.selectpicker.view.position0],n=s.option;n&&(!0!==e&&t.setDisabled(s.index,s.disabled),t.setSelected(s.index,n.selected))}},setSelected:function(e,t){var i,s,n=this.selectpicker.main.elements[e],o=this.selectpicker.main.data[e],r=void 0!==this.activeIndex,l=this.activeIndex===e||t&&!this.multiple&&!r;o.selected=t,s=n.firstChild,t&&(this.selectedIndex=e),n.classList.toggle("selected",t),l?(this.focusItem(n,o),this.selectpicker.view.currentActive=n,this.activeIndex=e):this.defocusItem(n),s&&(s.classList.toggle("selected",t),t?s.setAttribute("aria-selected",!0):this.multiple?s.setAttribute("aria-selected",!1):s.removeAttribute("aria-selected")),l||r||!t||void 0===this.prevActiveIndex||(i=this.selectpicker.main.elements[this.prevActiveIndex],this.defocusItem(i))},setDisabled:function(e,t){var i,s=this.selectpicker.main.elements[e];this.selectpicker.main.data[e].disabled=t,i=s.firstChild,s.classList.toggle(j.DISABLED,t),i&&("4"===M.major&&i.classList.toggle(j.DISABLED,t),t?(i.setAttribute("aria-disabled",t),i.setAttribute("tabindex",-1)):(i.removeAttribute("aria-disabled"),i.setAttribute("tabindex",0)))},isDisabled:function(){return this.$element[0].disabled},checkDisabled:function(){var e=this;this.isDisabled()?(this.$newElement[0].classList.add(j.DISABLED),this.$button.addClass(j.DISABLED).attr("tabindex",-1).attr("aria-disabled",!0)):(this.$button[0].classList.contains(j.DISABLED)&&(this.$newElement[0].classList.remove(j.DISABLED),this.$button.removeClass(j.DISABLED).attr("aria-disabled",!1)),-1!=this.$button.attr("tabindex")||this.$element.data("tabindex")||this.$button.removeAttr("tabindex")),this.$button.on("click",function(){return!e.isDisabled()})},tabIndex:function(){this.$element.data("tabindex")!==this.$element.attr("tabindex")&&-98!==this.$element.attr("tabindex")&&"-98"!==this.$element.attr("tabindex")&&(this.$element.data("tabindex",this.$element.attr("tabindex")),this.$button.attr("tabindex",this.$element.data("tabindex"))),this.$element.attr("tabindex",-98)},clickListener:function(){var C=this,t=z(document);function e(){C.options.liveSearch?C.$searchbox.trigger("focus"):C.$menuInner.trigger("focus")}function i(){C.dropdown&&C.dropdown._popper&&C.dropdown._popper.state.isCreated?e():requestAnimationFrame(i)}t.data("spaceSelect",!1),this.$button.on("keyup",function(e){/(32)/.test(e.keyCode.toString(10))&&t.data("spaceSelect")&&(e.preventDefault(),t.data("spaceSelect",!1))}),this.$newElement.on("show.bs.dropdown",function(){3<M.major&&!C.dropdown&&(C.dropdown=C.$button.data("bs.dropdown"),C.dropdown._menu=C.$menu[0])}),this.$button.on("click.bs.dropdown.data-api",function(){C.$newElement.hasClass(j.SHOW)||C.setSize()}),this.$element.on("shown"+U,function(){C.$menuInner[0].scrollTop!==C.selectpicker.view.scrollTop&&(C.$menuInner[0].scrollTop=C.selectpicker.view.scrollTop),3<M.major?requestAnimationFrame(i):e()}),this.$menuInner.on("mouseenter","li a",function(e){var t=this.parentElement,i=C.isVirtual()?C.selectpicker.view.position0:0,s=Array.prototype.indexOf.call(t.parentElement.children,t),n=C.selectpicker.current.data[s+i];C.focusItem(t,n,!0)}),this.$menuInner.on("click","li a",function(e,t){var i=z(this),s=C.$element[0],n=C.isVirtual()?C.selectpicker.view.position0:0,o=C.selectpicker.current.data[i.parent().index()+n],r=o.index,l=O(s),a=s.selectedIndex,c=s.options[a],d=!0;if(C.multiple&&1!==C.options.maxOptions&&e.stopPropagation(),e.preventDefault(),!C.isDisabled()&&!i.parent().hasClass(j.DISABLED)){var h=C.$element.find("option"),p=o.option,u=z(p),f=p.selected,m=u.parent("optgroup"),v=m.find("option"),g=C.options.maxOptions,b=m.data("maxOptions")||!1;if(r===C.activeIndex&&(t=!0),t||(C.prevActiveIndex=C.activeIndex,C.activeIndex=void 0),C.multiple){if(p.selected=!f,C.setSelected(r,!f),i.trigger("blur"),!1!==g||!1!==b){var w=g<h.filter(":selected").length,I=b<m.find("option:selected").length;if(g&&w||b&&I)if(g&&1==g){h.prop("selected",!1),u.prop("selected",!0);for(var x=0;x<h.length;x++)C.setSelected(x,!1);C.setSelected(r,!0)}else if(b&&1==b){m.find("option:selected").prop("selected",!1),u.prop("selected",!0);for(x=0;x<v.length;x++){p=v[x];C.setSelected(h.index(p),!1)}C.setSelected(r,!0)}else{var k="string"==typeof C.options.maxOptionsText?[C.options.maxOptionsText,C.options.maxOptionsText]:C.options.maxOptionsText,$="function"==typeof k?k(g,b):k,y=$[0].replace("{n}",g),S=$[1].replace("{n}",b),E=z('<div class="notify"></div>');$[2]&&(y=y.replace("{var}",$[2][1<g?0:1]),S=S.replace("{var}",$[2][1<b?0:1])),u.prop("selected",!1),C.$menu.append(E),g&&w&&(E.append(z("<div>"+y+"</div>")),d=!1,C.$element.trigger("maxReached"+U)),b&&I&&(E.append(z("<div>"+S+"</div>")),d=!1,C.$element.trigger("maxReachedGrp"+U)),setTimeout(function(){C.setSelected(r,!1)},10),E.delay(750).fadeOut(300,function(){z(this).remove()})}}}else c.selected=!1,p.selected=!0,C.setSelected(r,!0);!C.multiple||C.multiple&&1===C.options.maxOptions?C.$button.trigger("focus"):C.options.liveSearch&&C.$searchbox.trigger("focus"),d&&(C.multiple||a!==s.selectedIndex)&&(T=[p.index,u.prop("selected"),l],C.$element.triggerNative("change"))}}),this.$menu.on("click","li."+j.DISABLED+" a, ."+j.POPOVERHEADER+", ."+j.POPOVERHEADER+" :not(.close)",function(e){e.currentTarget==this&&(e.preventDefault(),e.stopPropagation(),C.options.liveSearch&&!z(e.target).hasClass("close")?C.$searchbox.trigger("focus"):C.$button.trigger("focus"))}),this.$menuInner.on("click",".divider, .dropdown-header",function(e){e.preventDefault(),e.stopPropagation(),C.options.liveSearch?C.$searchbox.trigger("focus"):C.$button.trigger("focus")}),this.$menu.on("click","."+j.POPOVERHEADER+" .close",function(){C.$button.trigger("click")}),this.$searchbox.on("click",function(e){e.stopPropagation()}),this.$menu.on("click",".actions-btn",function(e){C.options.liveSearch?C.$searchbox.trigger("focus"):C.$button.trigger("focus"),e.preventDefault(),e.stopPropagation(),z(this).hasClass("bs-select-all")?C.selectAll():C.deselectAll()}),this.$element.on("change"+U,function(){C.render(),C.$element.trigger("changed"+U,T),T=null}).on("focus"+U,function(){C.options.mobile||C.$button.trigger("focus")})},liveSearchListener:function(){var u=this,f=document.createElement("li");this.$button.on("click.bs.dropdown.data-api",function(){u.$searchbox.val()&&u.$searchbox.val("")}),this.$searchbox.on("click.bs.dropdown.data-api focus.bs.dropdown.data-api touchend.bs.dropdown.data-api",function(e){e.stopPropagation()}),this.$searchbox.on("input propertychange",function(){var e=u.$searchbox.val();if(u.selectpicker.search.elements=[],u.selectpicker.search.data=[],e){var t=[],i=e.toUpperCase(),s={},n=[],o=u._searchStyle(),r=u.options.liveSearchNormalize;r&&(i=w(i)),u._$lisSelected=u.$menuInner.find(".selected");for(var l=0;l<u.selectpicker.main.data.length;l++){var a=u.selectpicker.main.data[l];s[l]||(s[l]=k(a,i,o,r)),s[l]&&void 0!==a.headerIndex&&-1===n.indexOf(a.headerIndex)&&(0<a.headerIndex&&(s[a.headerIndex-1]=!0,n.push(a.headerIndex-1)),s[a.headerIndex]=!0,n.push(a.headerIndex),s[a.lastIndex+1]=!0),s[l]&&"optgroup-label"!==a.type&&n.push(l)}l=0;for(var c=n.length;l<c;l++){var d=n[l],h=n[l-1],p=(a=u.selectpicker.main.data[d],u.selectpicker.main.data[h]);("divider"!==a.type||"divider"===a.type&&p&&"divider"!==p.type&&c-1!==l)&&(u.selectpicker.search.data.push(a),t.push(u.selectpicker.main.elements[d]))}u.activeIndex=void 0,u.noScroll=!0,u.$menuInner.scrollTop(0),u.selectpicker.search.elements=t,u.createView(!0),t.length||(f.className="no-results",f.innerHTML=u.options.noneResultsText.replace("{0}",'"'+E(e)+'"'),u.$menuInner[0].firstChild.appendChild(f))}else u.$menuInner.scrollTop(0),u.createView(!1)})},_searchStyle:function(){return this.options.liveSearchStyle||"contains"},val:function(e){var t=this.$element[0];if(void 0===e)return this.$element.val();var i=O(t);if(T=[null,null,i],this.$element.val(e).trigger("changed"+U,T),this.$newElement.hasClass(j.SHOW))if(this.multiple)this.setOptionStatus(!0);else{var s=(t.options[t.selectedIndex]||{}).liIndex;"number"==typeof s&&(this.setSelected(this.selectedIndex,!1),this.setSelected(s,!0))}return this.render(),T=null,this.$element},changeAll:function(e){if(this.multiple){void 0===e&&(e=!0);var t=this.$element[0],i=0,s=0,n=O(t);t.classList.add("bs-select-hidden");for(var o=0,r=this.selectpicker.current.elements.length;o<r;o++){var l=this.selectpicker.current.data[o],a=l.option;a&&!l.disabled&&"divider"!==l.type&&(l.selected&&i++,(a.selected=e)&&s++)}t.classList.remove("bs-select-hidden"),i!==s&&(this.setOptionStatus(),T=[null,null,n],this.$element.triggerNative("change"))}},selectAll:function(){return this.changeAll(!0)},deselectAll:function(){return this.changeAll(!1)},toggle:function(e){(e=e||window.event)&&e.stopPropagation(),this.$button.trigger("click.bs.dropdown.data-api")},keydown:function(e){var t,i,s,n,o,r=z(this),l=r.hasClass("dropdown-toggle"),a=(l?r.closest(".dropdown"):r.closest(V.MENU)).data("this"),c=a.findLis(),d=!1,h=e.which===H&&!l&&!a.options.selectOnTab,p=_.test(e.which)||h,u=a.$menuInner[0].scrollTop,f=!0===a.isVirtual()?a.selectpicker.view.position0:0;if(!(i=a.$newElement.hasClass(j.SHOW))&&(p||48<=e.which&&e.which<=57||96<=e.which&&e.which<=105||65<=e.which&&e.which<=90)&&(a.$button.trigger("click.bs.dropdown.data-api"),a.options.liveSearch))a.$searchbox.trigger("focus");else{if(e.which===L&&i&&(e.preventDefault(),a.$button.trigger("click.bs.dropdown.data-api").trigger("focus")),p){if(!c.length)return;-1!==(t=(s=a.selectpicker.main.elements[a.activeIndex])?Array.prototype.indexOf.call(s.parentElement.children,s):-1)&&a.defocusItem(s),e.which===B?(-1!==t&&t--,t+f<0&&(t+=c.length),a.selectpicker.view.canHighlight[t+f]||-1===(t=a.selectpicker.view.canHighlight.slice(0,t+f).lastIndexOf(!0)-f)&&(t=c.length-1)):(e.which===W||h)&&(++t+f>=a.selectpicker.view.canHighlight.length&&(t=0),a.selectpicker.view.canHighlight[t+f]||(t=t+1+a.selectpicker.view.canHighlight.slice(t+f+1).indexOf(!0))),e.preventDefault();var m=f+t;e.which===B?0===f&&t===c.length-1?(a.$menuInner[0].scrollTop=a.$menuInner[0].scrollHeight,m=a.selectpicker.current.elements.length-1):d=(o=(n=a.selectpicker.current.data[m]).position-n.height)<u:(e.which===W||h)&&(0===t?m=a.$menuInner[0].scrollTop=0:d=u<(o=(n=a.selectpicker.current.data[m]).position-a.sizeInfo.menuInnerHeight)),s=a.selectpicker.current.elements[m],a.activeIndex=a.selectpicker.current.data[m].index,a.focusItem(s),a.selectpicker.view.currentActive=s,d&&(a.$menuInner[0].scrollTop=o),a.options.liveSearch?a.$searchbox.trigger("focus"):r.trigger("focus")}else if(!r.is("input")&&!G.test(e.which)||e.which===D&&a.selectpicker.keydown.keyHistory){var v,g,b=[];e.preventDefault(),a.selectpicker.keydown.keyHistory+=C[e.which],a.selectpicker.keydown.resetKeyHistory.cancel&&clearTimeout(a.selectpicker.keydown.resetKeyHistory.cancel),a.selectpicker.keydown.resetKeyHistory.cancel=a.selectpicker.keydown.resetKeyHistory.start(),g=a.selectpicker.keydown.keyHistory,/^(.)\1+$/.test(g)&&(g=g.charAt(0));for(var w=0;w<a.selectpicker.current.data.length;w++){var I=a.selectpicker.current.data[w];k(I,g,"startsWith",!0)&&a.selectpicker.view.canHighlight[w]&&b.push(I.index)}if(b.length){var x=0;c.removeClass("active").find("a").removeClass("active"),1===g.length&&(-1===(x=b.indexOf(a.activeIndex))||x===b.length-1?x=0:x++),v=b[x],d=0<u-(n=a.selectpicker.main.data[v]).position?(o=n.position-n.height,!0):(o=n.position-a.sizeInfo.menuInnerHeight,n.position>u+a.sizeInfo.menuInnerHeight),s=a.selectpicker.main.elements[v],a.activeIndex=b[x],a.focusItem(s),s&&s.firstChild.focus(),d&&(a.$menuInner[0].scrollTop=o),r.trigger("focus")}}i&&(e.which===D&&!a.selectpicker.keydown.keyHistory||e.which===N||e.which===H&&a.options.selectOnTab)&&(e.which!==D&&e.preventDefault(),a.options.liveSearch&&e.which===D||(a.$menuInner.find(".active a").trigger("click",!0),r.trigger("focus"),a.options.liveSearch||(e.preventDefault(),z(document).data("spaceSelect",!0))))}},mobile:function(){this.$element[0].classList.add("mobile-device")},refresh:function(){var e=z.extend({},this.options,this.$element.data());this.options=e,this.checkDisabled(),this.setStyle(),this.render(),this.createLi(),this.setWidth(),this.setSize(!0),this.$element.trigger("refreshed"+U)},hide:function(){this.$newElement.hide()},show:function(){this.$newElement.show()},remove:function(){this.$newElement.remove(),this.$element.remove()},destroy:function(){this.$newElement.before(this.$element).remove(),this.$bsContainer?this.$bsContainer.remove():this.$menu.remove(),this.$element.off(U).removeData("selectpicker").removeClass("bs-select-hidden selectpicker"),z(window).off(U+"."+this.selectId)}};var X=z.fn.selectpicker;z.fn.selectpicker=Q,z.fn.selectpicker.Constructor=J,z.fn.selectpicker.noConflict=function(){return z.fn.selectpicker=X,this},z(document).off("keydown.bs.dropdown.data-api").on("keydown"+U,'.bootstrap-select [data-toggle="dropdown"], .bootstrap-select [role="listbox"], .bootstrap-select .bs-searchbox input',J.prototype.keydown).on("focusin.modal",'.bootstrap-select [data-toggle="dropdown"], .bootstrap-select [role="listbox"], .bootstrap-select .bs-searchbox input',function(e){e.stopPropagation()}),z(window).on("load"+U+".data-api",function(){z(".selectpicker").each(function(){var e=z(this);Q.call(e,e.data())})})}(e)});
9
+ //# sourceMappingURL=bootstrap-select.min.js.map
src/common/easydigitaldownloads/ICWP_EDD_LicenseVO.php DELETED
@@ -1,212 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * @deprecated v7.0.0
5
- * Class ICWP_EDD_LicenseVO
6
- */
7
- class ICWP_EDD_LicenseVO {
8
-
9
- /**
10
- * @var stdClass
11
- */
12
- private $oRaw;
13
-
14
- /**
15
- * ICWP_EDD_LicenseVO constructor.
16
- * @param stdClass $oData
17
- */
18
- public function __construct( $oData ) {
19
- $this->oRaw = $oData;
20
- }
21
-
22
- /**
23
- * @return int
24
- */
25
- public function getActivationsLeft() {
26
- return $this->getRawKey( 'activations_left' );
27
- }
28
-
29
- /**
30
- * @return string
31
- */
32
- public function getCustomerEmail() {
33
- return $this->getRawKey( 'customer_email' );
34
- }
35
-
36
- /**
37
- * @return string
38
- */
39
- public function getChecksum() {
40
- return $this->getRawKey( 'checksum' );
41
- }
42
-
43
- /**
44
- * @return string
45
- */
46
- public function getCustomerName() {
47
- return $this->getRawKey( 'customer_name' );
48
- }
49
-
50
- /**
51
- * @return int
52
- */
53
- public function getExpiresAt() {
54
- $sTime = $this->getRawKey( 'expires' );
55
- return ( $sTime == 'lifetime' ) ? PHP_INT_MAX : strtotime( $sTime );
56
- }
57
-
58
- /**
59
- * @return string
60
- */
61
- public function getItemName() {
62
- return $this->raw()->item_name;
63
- }
64
-
65
- /**
66
- * @return int
67
- */
68
- public function getLastRequestAt() {
69
- return (int)$this->getRawKey( 'last_request_at', 0 );
70
- }
71
-
72
- /**
73
- * @return int
74
- */
75
- public function getLastVerifiedAt() {
76
- return (int)$this->getRawKey( 'last_verified_at', 0 );
77
- }
78
-
79
- /**
80
- * @return int
81
- */
82
- public function getLicenseLimit() {
83
- return $this->getRawKey( 'license_limit' );
84
- }
85
-
86
- /**
87
- * @return string
88
- */
89
- public function getLicenseStatus() {
90
- return $this->getRawKey( 'license' );
91
- }
92
-
93
- /**
94
- * @return int
95
- */
96
- public function getPaymentId() {
97
- return $this->getRawKey( 'payment_id' );
98
- }
99
-
100
- /**
101
- * @return int
102
- */
103
- public function getSiteCount() {
104
- return $this->getRawKey( 'site_count' );
105
- }
106
-
107
- /**
108
- * @return bool
109
- */
110
- public function isCentral() {
111
- return (bool)$this->getRawKey( 'is_central' );
112
- }
113
-
114
- /**
115
- * @return bool
116
- */
117
- public function isSuccess() {
118
- return (bool)$this->getRawKey( 'success' );
119
- }
120
-
121
- /**
122
- * @return bool
123
- */
124
- public function isExpired() {
125
- return ( $this->getExpiresAt() < time() );
126
- }
127
-
128
- /**
129
- * @return bool
130
- */
131
- public function isValid() {
132
- return ( $this->isReady() && $this->isSuccess() && !$this->isExpired() && $this->getLicenseStatus() == 'valid' );
133
- }
134
-
135
- /**
136
- * @param string $sKey
137
- * @param mixed $mDefault
138
- * @return mixed
139
- */
140
- protected function getRawKey( $sKey, $mDefault = null ) {
141
- $oRaw = $this->raw();
142
- return isset( $oRaw->{$sKey} ) ? $oRaw->{$sKey} : $mDefault;
143
- }
144
-
145
- /**
146
- * IMPORTANT: uses clone
147
- * @return stdClass
148
- */
149
- public function getRaw() {
150
- return ( clone $this->raw() );
151
- }
152
-
153
- /**
154
- * @return stdClass
155
- */
156
- private function raw() {
157
- if ( !is_object( $this->oRaw ) ) {
158
- $this->oRaw = new stdClass();
159
- }
160
- return $this->oRaw;
161
- }
162
-
163
- /**
164
- * @return bool
165
- */
166
- public function hasError() {
167
- $sE = $this->getRawKey( 'error' );
168
- return !empty( $sE );
169
- }
170
-
171
- /**
172
- * @return bool
173
- */
174
- public function hasChecksum() {
175
- $sC = $this->getChecksum();
176
- return !empty( $sC );
177
- }
178
-
179
- /**
180
- * @return bool
181
- */
182
- public function isReady() {
183
- return $this->hasChecksum();
184
- }
185
-
186
- /**
187
- * @param int $nAt
188
- * @return $this
189
- */
190
- public function setLastRequestAt( $nAt ) {
191
- return $this->setRawKey( 'last_request_at', $nAt );
192
- }
193
-
194
- /**
195
- * @param bool $bAddRandom
196
- * @return $this
197
- */
198
- public function updateLastVerifiedAt( $bAddRandom = false ) {
199
- $nRandom = $bAddRandom ? rand( -12, 12 )*HOUR_IN_SECONDS : 0;
200
- return $this->setRawKey( 'last_verified_at', $this->getLastRequestAt() + $nRandom );
201
- }
202
-
203
- /**
204
- * @param string $sKey
205
- * @param mixed $mValue
206
- * @return $this
207
- */
208
- protected function setRawKey( $sKey, $mValue ) {
209
- $this->raw()->{$sKey} = $mValue;
210
- return $this;
211
- }
212
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/common/googleauthenticator/googleauthenticator.php DELETED
@@ -1,252 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * PHP Class for handling Google Authenticator 2-factor authentication.
5
- *
6
- * @author Michael Kliewe
7
- * @copyright 2012 Michael Kliewe
8
- * @license http://www.opensource.org/licenses/bsd-license.php BSD License
9
- *
10
- * @link http://www.phpgangsta.de/
11
- */
12
- class PHPGangsta_GoogleAuthenticator
13
- {
14
- protected $_codeLength = 6;
15
-
16
- /**
17
- * Create new secret.
18
- * 16 characters, randomly chosen from the allowed base32 characters.
19
- *
20
- * @param int $secretLength
21
- *
22
- * @return string
23
- */
24
- public function createSecret($secretLength = 16)
25
- {
26
- $validChars = $this->_getBase32LookupTable();
27
-
28
- // Valid secret lengths are 80 to 640 bits
29
- if ($secretLength < 16 || $secretLength > 128) {
30
- throw new Exception('Bad secret length');
31
- }
32
- $secret = '';
33
- $rnd = false;
34
- if (function_exists('random_bytes')) {
35
- $rnd = random_bytes($secretLength);
36
- } elseif (function_exists('mcrypt_create_iv')) {
37
- $rnd = mcrypt_create_iv($secretLength, MCRYPT_DEV_URANDOM);
38
- } elseif (function_exists('openssl_random_pseudo_bytes')) {
39
- $rnd = openssl_random_pseudo_bytes($secretLength, $cryptoStrong);
40
- if (!$cryptoStrong) {
41
- $rnd = false;
42
- }
43
- }
44
- if ($rnd !== false) {
45
- for ($i = 0; $i < $secretLength; ++$i) {
46
- $secret .= $validChars[ord($rnd[$i]) & 31];
47
- }
48
- } else {
49
- throw new Exception('No source of secure random');
50
- }
51
-
52
- return $secret;
53
- }
54
-
55
- /**
56
- * Calculate the code, with given secret and point in time.
57
- *
58
- * @param string $secret
59
- * @param int|null $timeSlice
60
- *
61
- * @return string
62
- */
63
- public function getCode($secret, $timeSlice = null)
64
- {
65
- if ($timeSlice === null) {
66
- $timeSlice = floor(time() / 30);
67
- }
68
-
69
- $secretkey = $this->_base32Decode($secret);
70
-
71
- // Pack time into binary string
72
- $time = chr(0).chr(0).chr(0).chr(0).pack('N*', $timeSlice);
73
- // Hash it with users secret key
74
- $hm = hash_hmac('SHA1', $time, $secretkey, true);
75
- // Use last nipple of result as index/offset
76
- $offset = ord(substr($hm, -1)) & 0x0F;
77
- // grab 4 bytes of the result
78
- $hashpart = substr($hm, $offset, 4);
79
-
80
- // Unpak binary value
81
- $value = unpack('N', $hashpart);
82
- $value = $value[1];
83
- // Only 32 bits
84
- $value = $value & 0x7FFFFFFF;
85
-
86
- $modulo = pow(10, $this->_codeLength);
87
-
88
- return str_pad($value % $modulo, $this->_codeLength, '0', STR_PAD_LEFT);
89
- }
90
-
91
- /**
92
- * Get QR-Code URL for image, from google charts.
93
- *
94
- * @param string $name
95
- * @param string $secret
96
- * @param string $title
97
- * @param array $params
98
- *
99
- * @return string
100
- */
101
- public function getQRCodeGoogleUrl($name, $secret, $title = null, $params = array())
102
- {
103
- $width = !empty($params['width']) && (int) $params['width'] > 0 ? (int) $params['width'] : 200;
104
- $height = !empty($params['height']) && (int) $params['height'] > 0 ? (int) $params['height'] : 200;
105
- $level = !empty($params['level']) && array_search($params['level'], array('L', 'M', 'Q', 'H')) !== false ? $params['level'] : 'M';
106
-
107
- $urlencoded = urlencode('otpauth://totp/'.$name.'?secret='.$secret.'');
108
- if (isset($title)) {
109
- $urlencoded .= urlencode('&issuer='.urlencode($title));
110
- }
111
-
112
- return 'https://chart.googleapis.com/chart?chs='.$width.'x'.$height.'&chld='.$level.'|0&cht=qr&chl='.$urlencoded.'';
113
- }
114
-
115
- /**
116
- * Check if the code is correct. This will accept codes starting from $discrepancy*30sec ago to $discrepancy*30sec from now.
117
- *
118
- * @param string $secret
119
- * @param string $code
120
- * @param int $discrepancy This is the allowed time drift in 30 second units (8 means 4 minutes before or after)
121
- * @param int|null $currentTimeSlice time slice if we want use other that time()
122
- *
123
- * @return bool
124
- */
125
- public function verifyCode($secret, $code, $discrepancy = 1, $currentTimeSlice = null)
126
- {
127
- if ($currentTimeSlice === null) {
128
- $currentTimeSlice = floor(time() / 30);
129
- }
130
-
131
- if (strlen($code) != 6) {
132
- return false;
133
- }
134
-
135
- for ($i = -$discrepancy; $i <= $discrepancy; ++$i) {
136
- $calculatedCode = $this->getCode($secret, $currentTimeSlice + $i);
137
- if ($this->timingSafeEquals($calculatedCode, $code)) {
138
- return true;
139
- }
140
- }
141
-
142
- return false;
143
- }
144
-
145
- /**
146
- * Set the code length, should be >=6.
147
- *
148
- * @param int $length
149
- *
150
- * @return PHPGangsta_GoogleAuthenticator
151
- */
152
- public function setCodeLength($length)
153
- {
154
- $this->_codeLength = $length;
155
-
156
- return $this;
157
- }
158
-
159
- /**
160
- * Helper class to decode base32.
161
- *
162
- * @param $secret
163
- *
164
- * @return bool|string
165
- */
166
- protected function _base32Decode($secret)
167
- {
168
- if (empty($secret)) {
169
- return '';
170
- }
171
-
172
- $base32chars = $this->_getBase32LookupTable();
173
- $base32charsFlipped = array_flip($base32chars);
174
-
175
- $paddingCharCount = substr_count($secret, $base32chars[32]);
176
- $allowedValues = array(6, 4, 3, 1, 0);
177
- if (!in_array($paddingCharCount, $allowedValues)) {
178
- return false;
179
- }
180
- for ($i = 0; $i < 4; ++$i) {
181
- if ($paddingCharCount == $allowedValues[$i] &&
182
- substr($secret, -($allowedValues[$i])) != str_repeat($base32chars[32], $allowedValues[$i])) {
183
- return false;
184
- }
185
- }
186
- $secret = str_replace('=', '', $secret);
187
- $secret = str_split($secret);
188
- $binaryString = '';
189
- for ($i = 0; $i < count($secret); $i = $i + 8) {
190
- $x = '';
191
- if (!in_array($secret[$i], $base32chars)) {
192
- return false;
193
- }
194
- for ($j = 0; $j < 8; ++$j) {
195
- $x .= str_pad(base_convert(@$base32charsFlipped[@$secret[$i + $j]], 10, 2), 5, '0', STR_PAD_LEFT);
196
- }
197
- $eightBits = str_split($x, 8);
198
- for ($z = 0; $z < count($eightBits); ++$z) {
199
- $binaryString .= (($y = chr(base_convert($eightBits[$z], 2, 10))) || ord($y) == 48) ? $y : '';
200
- }
201
- }
202
-
203
- return $binaryString;
204
- }
205
-
206
- /**
207
- * Get array with all 32 characters for decoding from/encoding to base32.
208
- *
209
- * @return array
210
- */
211
- protected function _getBase32LookupTable()
212
- {
213
- return array(
214
- 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', // 7
215
- 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', // 15
216
- 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', // 23
217
- 'Y', 'Z', '2', '3', '4', '5', '6', '7', // 31
218
- '=', // padding char
219
- );
220
- }
221
-
222
- /**
223
- * A timing safe equals comparison
224
- * more info here: http://blog.ircmaxell.com/2014/11/its-all-about-time.html.
225
- *
226
- * @param string $safeString The internal (safe) value to be checked
227
- * @param string $userString The user submitted (unsafe) value
228
- *
229
- * @return bool True if the two strings are identical
230
- */
231
- private function timingSafeEquals($safeString, $userString)
232
- {
233
- if (function_exists('hash_equals')) {
234
- return hash_equals($safeString, $userString);
235
- }
236
- $safeLen = strlen($safeString);
237
- $userLen = strlen($userString);
238
-
239
- if ($userLen != $safeLen) {
240
- return false;
241
- }
242
-
243
- $result = 0;
244
-
245
- for ($i = 0; $i < $userLen; ++$i) {
246
- $result |= (ord($safeString[$i]) ^ ord($userString[$i]));
247
- }
248
-
249
- // They are only identical strings if $result is exactly 0...
250
- return $result === 0;
251
- }
252
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/common/googlerecaptcha/ReCaptcha/RequestMethod/WordpressPost.php DELETED
@@ -1,60 +0,0 @@
1
- <?php
2
- /**
3
- * This is a PHP library that handles calling reCAPTCHA.
4
- * @copyright Copyright (c) 2015, Google Inc.
5
- * @link http://www.google.com/recaptcha
6
- * Permission is hereby granted, free of charge, to any person obtaining a copy
7
- * of this software and associated documentation files (the "Software"), to deal
8
- * in the Software without restriction, including without limitation the rights
9
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
- * copies of the Software, and to permit persons to whom the Software is
11
- * furnished to do so, subject to the following conditions:
12
- * The above copyright notice and this permission notice shall be included in
13
- * all copies or substantial portions of the Software.
14
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
- * THE SOFTWARE.
21
- */
22
-
23
- namespace ReCaptcha\RequestMethod;
24
-
25
- use ReCaptcha\RequestMethod;
26
- use ReCaptcha\RequestParameters;
27
-
28
- /**
29
- * Class WordpressPost
30
- * @package ReCaptcha\RequestMethod
31
- */
32
- class WordpressPost implements RequestMethod {
33
-
34
- /**
35
- * URL to which requests are sent via wp_remote_post.
36
- * @const string
37
- */
38
- const SITE_VERIFY_URL = 'https://www.google.com/recaptcha/api/siteverify';
39
-
40
- /**
41
- * Submit the wp_remote_post request with the specified parameters.
42
- * @param RequestParameters $params Request parameters
43
- * @return string Body of the reCAPTCHA response
44
- */
45
- public function submit( RequestParameters $params ) {
46
- $aResponse = wp_remote_post(
47
- self::SITE_VERIFY_URL,
48
- array(
49
- 'headers' => array( 'Content-Type' => 'application/x-www-form-urlencoded' ),
50
- 'body' => $params->toArray()
51
- )
52
- );
53
-
54
- $sResponseBody = '';
55
- if ( !is_wp_error( $aResponse ) && is_array( $aResponse ) && isset( $aResponse[ 'body' ] ) ) {
56
- $sResponseBody = $aResponse[ 'body' ];
57
- }
58
- return $sResponseBody;
59
- }
60
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/common/icwp-data.php CHANGED
@@ -147,7 +147,7 @@ class ICWP_WPSF_DataProcessor extends ICWP_WPSF_Foundation {
147
 
148
  $sUrl = trim( $this->urlStripQueryPart( $sUrl ) );
149
  if ( filter_var( $sUrl, FILTER_VALIDATE_URL ) ) { // we have a scheme+host
150
- if ( in_array( parse_url( $sUrl, PHP_URL_SCHEME ), array( 'http', 'https' ) ) ) {
151
  $sValidatedUrl = rtrim( $sUrl, '/' );
152
  }
153
  }
@@ -187,13 +187,13 @@ class ICWP_WPSF_DataProcessor extends ICWP_WPSF_Foundation {
187
  */
188
  public function extractCommaSeparatedList( $sRawList = '' ) {
189
 
190
- $aRawList = array();
191
  if ( empty( $sRawList ) ) {
192
  return $aRawList;
193
  }
194
 
195
  $aRawList = array_map( 'trim', preg_split( '/\r\n|\r|\n/', $sRawList ) );
196
- $aNewList = array();
197
  $bHadStar = false;
198
  foreach ( $aRawList as $sKey => $sRawLine ) {
199
 
@@ -217,7 +217,7 @@ class ICWP_WPSF_DataProcessor extends ICWP_WPSF_Foundation {
217
  }
218
  }
219
 
220
- $aParams = empty( $aParts[ 1 ] ) ? array() : explode( ',', $aParts[ 1 ] );
221
  $aNewList[ $aParts[ 0 ] ] = $aParams;
222
  }
223
  return $aNewList;
@@ -231,7 +231,7 @@ class ICWP_WPSF_DataProcessor extends ICWP_WPSF_Foundation {
231
  * @return string
232
  */
233
  public function generateRandomString( $nLength = 10, $nStrength = 7, $bIgnoreAmb = true ) {
234
- $aChars = array( 'abcdefghijkmnopqrstuvwxyz' );
235
 
236
  if ( $nStrength & 2 ) {
237
  $aChars[] = '023456789';
@@ -411,7 +411,7 @@ class ICWP_WPSF_DataProcessor extends ICWP_WPSF_Foundation {
411
  * @return array
412
  */
413
  public function removeFromArrayByValue( $aArray, $mValue, $bFirstOnly = false ) {
414
- $aKeys = array();
415
 
416
  if ( $bFirstOnly ) {
417
  $mKey = array_search( $mValue, $aArray, true );
@@ -443,146 +443,145 @@ class ICWP_WPSF_DataProcessor extends ICWP_WPSF_Foundation {
443
  }
444
 
445
  /**
446
- * @deprecated
447
  * @return int
 
448
  */
449
  public function time() {
450
  return $this->loadRequest()->ts();
451
  }
452
 
453
  /**
454
- * @deprecated
455
  * @param string $sKey
456
  * @param string $mDefault
457
  * @param bool $bTrim -automatically trim whitespace
458
  * @return mixed|null
 
459
  */
460
  public function cookie( $sKey, $mDefault = null, $bTrim = true ) {
461
  return $this->loadRequest()->cookie( $sKey, $mDefault, $bTrim );
462
  }
463
 
464
  /**
465
- * @deprecated
466
  * @param string $sKey
467
  * @param mixed $mDefault
468
  * @return mixed|null
 
469
  */
470
  public function env( $sKey, $mDefault = null ) {
471
  return $this->loadRequest()->env( $sKey, $mDefault );
472
  }
473
 
474
  /**
475
- * @deprecated
476
  * @param string $sKey
477
  * @param null $mDefault
478
  * @param bool $bTrim -automatically trim whitespace
479
  * @return mixed|null
 
480
  */
481
  public function post( $sKey, $mDefault = null, $bTrim = true ) {
482
  return $this->loadRequest()->post( $sKey, $mDefault, $bTrim );
483
  }
484
 
485
  /**
486
- * @deprecated
487
  * @param string $sKey
488
  * @param null $mDefault
489
  * @param bool $bTrim -automatically trim whitespace
490
  * @return mixed|null
 
491
  */
492
  public function query( $sKey, $mDefault = null, $bTrim = true ) {
493
  return $this->loadRequest()->query( $sKey, $mDefault, $bTrim );
494
  }
495
 
496
  /**
497
- * @deprecated
498
  * @param string $sKey
499
  * @param null $mDefault
500
  * @param bool $bTrim -automatically trim whitespace
501
  * @return mixed|null
 
502
  */
503
  public function server( $sKey, $mDefault = null, $bTrim = true ) {
504
  return $this->loadRequest()->server( $sKey, $mDefault, $bTrim );
505
  }
506
 
507
  /**
508
- * @deprecated
509
  * @param string $sKey
510
  * @param null $mDefault
511
  * @param bool $bIncludeCookie
512
  * @param bool $bTrim -automatically trim whitespace
513
  * @return mixed|null
 
514
  */
515
  public function request( $sKey, $bIncludeCookie = false, $mDefault = null, $bTrim = true ) {
516
  return $this->loadRequest()->request( $sKey, $bIncludeCookie, $mDefault, $bTrim );
517
  }
518
 
519
  /**
520
- * @deprecated
521
  * @return string URI Path in lowercase
 
522
  */
523
  public function getRequestPath() {
524
  return $this->loadRequest()->getPath();
525
  }
526
 
527
  /**
528
- * @deprecated
529
  * @return string
 
530
  */
531
  public function getRequestUri() {
532
  return $this->loadRequest()->getUri();
533
  }
534
 
535
  /**
536
- * @deprecated
537
  * @return string
 
538
  */
539
  public function getUserAgent() {
540
  return $this->loadRequest()->getUserAgent();
541
  }
542
 
543
  /**
544
- * @deprecated
545
  * @param bool $bIncludeCookie
546
  * @return array
 
547
  */
548
  public function getRequestParams( $bIncludeCookie = true ) {
549
  return $this->loadRequest()->getParams( $bIncludeCookie );
550
  }
551
 
552
  /**
553
- * @deprecated
554
  * @return array
 
555
  */
556
  public function getRequestUriParts() {
557
  return $this->loadRequest()->getUriParts();
558
  }
559
 
560
  /**
561
- * @deprecated
562
  * @return string
 
563
  */
564
  public function getRequestMethod() {
565
  return $this->loadRequest()->getMethod();
566
  }
567
 
568
  /**
569
- * @deprecated
570
  * @return bool
 
571
  */
572
  public function isMethodPost() {
573
  return $this->loadRequest()->isMethodPost();
574
  }
575
 
576
  /**
577
- * @deprecated
578
  * @return string|null
 
579
  */
580
  public function getScriptName() {
581
  return $this->loadRequest()->getScriptName();
582
  }
583
 
584
  /**
585
- * @deprecated
586
  * @param $sKey
587
  * @param $mValue
588
  * @param int $nExpireLength
@@ -590,15 +589,16 @@ class ICWP_WPSF_DataProcessor extends ICWP_WPSF_Foundation {
590
  * @param null $sDomain
591
  * @param bool $bSsl
592
  * @return bool
 
593
  */
594
  public function setCookie( $sKey, $mValue, $nExpireLength = 3600, $sPath = null, $sDomain = null, $bSsl = true ) {
595
  return $this->loadRequest()->setCookie( $sKey, $mValue, $nExpireLength, $sPath, $sDomain, $bSsl );
596
  }
597
 
598
  /**
599
- * @deprecated
600
  * @param string $sKey
601
  * @return bool
 
602
  */
603
  public function setDeleteCookie( $sKey ) {
604
  return $this->loadRequest()->setDeleteCookie( $sKey );
147
 
148
  $sUrl = trim( $this->urlStripQueryPart( $sUrl ) );
149
  if ( filter_var( $sUrl, FILTER_VALIDATE_URL ) ) { // we have a scheme+host
150
+ if ( in_array( parse_url( $sUrl, PHP_URL_SCHEME ), [ 'http', 'https' ] ) ) {
151
  $sValidatedUrl = rtrim( $sUrl, '/' );
152
  }
153
  }
187
  */
188
  public function extractCommaSeparatedList( $sRawList = '' ) {
189
 
190
+ $aRawList = [];
191
  if ( empty( $sRawList ) ) {
192
  return $aRawList;
193
  }
194
 
195
  $aRawList = array_map( 'trim', preg_split( '/\r\n|\r|\n/', $sRawList ) );
196
+ $aNewList = [];
197
  $bHadStar = false;
198
  foreach ( $aRawList as $sKey => $sRawLine ) {
199
 
217
  }
218
  }
219
 
220
+ $aParams = empty( $aParts[ 1 ] ) ? [] : explode( ',', $aParts[ 1 ] );
221
  $aNewList[ $aParts[ 0 ] ] = $aParams;
222
  }
223
  return $aNewList;
231
  * @return string
232
  */
233
  public function generateRandomString( $nLength = 10, $nStrength = 7, $bIgnoreAmb = true ) {
234
+ $aChars = [ 'abcdefghijkmnopqrstuvwxyz' ];
235
 
236
  if ( $nStrength & 2 ) {
237
  $aChars[] = '023456789';
411
  * @return array
412
  */
413
  public function removeFromArrayByValue( $aArray, $mValue, $bFirstOnly = false ) {
414
+ $aKeys = [];
415
 
416
  if ( $bFirstOnly ) {
417
  $mKey = array_search( $mValue, $aArray, true );
443
  }
444
 
445
  /**
 
446
  * @return int
447
+ * @deprecated
448
  */
449
  public function time() {
450
  return $this->loadRequest()->ts();
451
  }
452
 
453
  /**
 
454
  * @param string $sKey
455
  * @param string $mDefault
456
  * @param bool $bTrim -automatically trim whitespace
457
  * @return mixed|null
458
+ * @deprecated
459
  */
460
  public function cookie( $sKey, $mDefault = null, $bTrim = true ) {
461
  return $this->loadRequest()->cookie( $sKey, $mDefault, $bTrim );
462
  }
463
 
464
  /**
 
465
  * @param string $sKey
466
  * @param mixed $mDefault
467
  * @return mixed|null
468
+ * @deprecated
469
  */
470
  public function env( $sKey, $mDefault = null ) {
471
  return $this->loadRequest()->env( $sKey, $mDefault );
472
  }
473
 
474
  /**
 
475
  * @param string $sKey
476
  * @param null $mDefault
477
  * @param bool $bTrim -automatically trim whitespace
478
  * @return mixed|null
479
+ * @deprecated
480
  */
481
  public function post( $sKey, $mDefault = null, $bTrim = true ) {
482
  return $this->loadRequest()->post( $sKey, $mDefault, $bTrim );
483
  }
484
 
485
  /**
 
486
  * @param string $sKey
487
  * @param null $mDefault
488
  * @param bool $bTrim -automatically trim whitespace
489
  * @return mixed|null
490
+ * @deprecated
491
  */
492
  public function query( $sKey, $mDefault = null, $bTrim = true ) {
493
  return $this->loadRequest()->query( $sKey, $mDefault, $bTrim );
494
  }
495
 
496
  /**
 
497
  * @param string $sKey
498
  * @param null $mDefault
499
  * @param bool $bTrim -automatically trim whitespace
500
  * @return mixed|null
501
+ * @deprecated
502
  */
503
  public function server( $sKey, $mDefault = null, $bTrim = true ) {
504
  return $this->loadRequest()->server( $sKey, $mDefault, $bTrim );
505
  }
506
 
507
  /**
 
508
  * @param string $sKey
509
  * @param null $mDefault
510
  * @param bool $bIncludeCookie
511
  * @param bool $bTrim -automatically trim whitespace
512
  * @return mixed|null
513
+ * @deprecated
514
  */
515
  public function request( $sKey, $bIncludeCookie = false, $mDefault = null, $bTrim = true ) {
516
  return $this->loadRequest()->request( $sKey, $bIncludeCookie, $mDefault, $bTrim );
517
  }
518
 
519
  /**
 
520
  * @return string URI Path in lowercase
521
+ * @deprecated
522
  */
523
  public function getRequestPath() {
524
  return $this->loadRequest()->getPath();
525
  }
526
 
527
  /**
 
528
  * @return string
529
+ * @deprecated
530
  */
531
  public function getRequestUri() {
532
  return $this->loadRequest()->getUri();
533
  }
534
 
535
  /**
 
536
  * @return string
537
+ * @deprecated
538
  */
539
  public function getUserAgent() {
540
  return $this->loadRequest()->getUserAgent();
541
  }
542
 
543
  /**
 
544
  * @param bool $bIncludeCookie
545
  * @return array
546
+ * @deprecated
547
  */
548
  public function getRequestParams( $bIncludeCookie = true ) {
549
  return $this->loadRequest()->getParams( $bIncludeCookie );
550
  }
551
 
552
  /**
 
553
  * @return array
554
+ * @deprecated
555
  */
556
  public function getRequestUriParts() {
557
  return $this->loadRequest()->getUriParts();
558
  }
559
 
560
  /**
 
561
  * @return string
562
+ * @deprecated
563
  */
564
  public function getRequestMethod() {
565
  return $this->loadRequest()->getMethod();
566
  }
567
 
568
  /**
 
569
  * @return bool
570
+ * @deprecated
571
  */
572
  public function isMethodPost() {
573
  return $this->loadRequest()->isMethodPost();
574
  }
575
 
576
  /**
 
577
  * @return string|null
578
+ * @deprecated
579
  */
580
  public function getScriptName() {
581
  return $this->loadRequest()->getScriptName();
582
  }
583
 
584
  /**
 
585
  * @param $sKey
586
  * @param $mValue
587
  * @param int $nExpireLength
589
  * @param null $sDomain
590
  * @param bool $bSsl
591
  * @return bool
592
+ * @deprecated
593
  */
594
  public function setCookie( $sKey, $mValue, $nExpireLength = 3600, $sPath = null, $sDomain = null, $bSsl = true ) {
595
  return $this->loadRequest()->setCookie( $sKey, $mValue, $nExpireLength, $sPath, $sDomain, $bSsl );
596
  }
597
 
598
  /**
 
599
  * @param string $sKey
600
  * @return bool
601
+ * @deprecated
602
  */
603
  public function setDeleteCookie( $sKey ) {
604
  return $this->loadRequest()->setDeleteCookie( $sKey );
src/common/icwp-edd.php CHANGED
@@ -32,14 +32,14 @@ class ICWP_WPSF_Edd {
32
  */
33
  public function ping( $sStoreUrl ) {
34
  $sStoreUrl = add_query_arg( [ 'license_ping' => 'Y' ], $sStoreUrl );
35
- $aParams = array(
36
- 'body' => array(
37
  'ping' => 'pong',
38
  'license' => 'abcdefghi',
39
  'item_id' => '123',
40
  'url' => Services::WpGeneral()->getWpUrl()
41
- )
42
- );
43
 
44
  $oHttpReq = Services::HttpRequest();
45
  if ( $oHttpReq->post( $sStoreUrl, $aParams ) ) {
@@ -100,19 +100,19 @@ class ICWP_WPSF_Edd {
100
  */
101
  private function commonLicenseAction( $sAction, $sStoreUrl, $sKey, $sItemId ) {
102
  $oWp = Services::WpGeneral();
103
- $aLicenseLookupParams = array(
104
  'timeout' => 60,
105
  'body' => array_merge(
106
- array(
107
  'edd_action' => $sAction,
108
  'license' => $sKey,
109
  'item_id' => $sItemId,
110
  'url' => $oWp->getHomeUrl(),
111
  'alt_url' => $oWp->getWpUrl()
112
- ),
113
  $this->getRequestParams()
114
  )
115
- );
116
 
117
  return ( new EddLicenseVO() )
118
  ->applyFromArray( $this->sendReq( $sStoreUrl, $aLicenseLookupParams, false ) )
@@ -127,7 +127,7 @@ class ICWP_WPSF_Edd {
127
  * @return array
128
  */
129
  private function sendReq( $sUrl, $aArgs, $bAsPost = false ) {
130
- $aResponse = array();
131
  $oHttpReq = Services::HttpRequest();
132
 
133
  if ( $bAsPost ) {
@@ -158,15 +158,15 @@ class ICWP_WPSF_Edd {
158
  * @return array
159
  */
160
  public function getRequestParams() {
161
- return is_array( $this->aAdditionalRequestParams ) ? $this->aAdditionalRequestParams : array();
162
  }
163
 
164
  /**
165
  * @param array $aParams
166
  * @return $this
167
  */
168
- public function setRequestParams( $aParams = array() ) {
169
- $this->aAdditionalRequestParams = is_array( $aParams ) ? $aParams : array();
170
  return $this;
171
  }
172
  }
32
  */
33
  public function ping( $sStoreUrl ) {
34
  $sStoreUrl = add_query_arg( [ 'license_ping' => 'Y' ], $sStoreUrl );
35
+ $aParams = [
36
+ 'body' => [
37
  'ping' => 'pong',
38
  'license' => 'abcdefghi',
39
  'item_id' => '123',
40
  'url' => Services::WpGeneral()->getWpUrl()
41
+ ]
42
+ ];
43
 
44
  $oHttpReq = Services::HttpRequest();
45
  if ( $oHttpReq->post( $sStoreUrl, $aParams ) ) {
100
  */
101
  private function commonLicenseAction( $sAction, $sStoreUrl, $sKey, $sItemId ) {
102
  $oWp = Services::WpGeneral();
103
+ $aLicenseLookupParams = [
104
  'timeout' => 60,
105
  'body' => array_merge(
106
+ [
107
  'edd_action' => $sAction,
108
  'license' => $sKey,
109
  'item_id' => $sItemId,
110
  'url' => $oWp->getHomeUrl(),
111
  'alt_url' => $oWp->getWpUrl()
112
+ ],
113
  $this->getRequestParams()
114
  )
115
+ ];
116
 
117
  return ( new EddLicenseVO() )
118
  ->applyFromArray( $this->sendReq( $sStoreUrl, $aLicenseLookupParams, false ) )
127
  * @return array
128
  */
129
  private function sendReq( $sUrl, $aArgs, $bAsPost = false ) {
130
+ $aResponse = [];
131
  $oHttpReq = Services::HttpRequest();
132
 
133
  if ( $bAsPost ) {
158
  * @return array
159
  */
160
  public function getRequestParams() {
161
+ return is_array( $this->aAdditionalRequestParams ) ? $this->aAdditionalRequestParams : [];
162
  }
163
 
164
  /**
165
  * @param array $aParams
166
  * @return $this
167
  */
168
+ public function setRequestParams( $aParams = [] ) {
169
+ $this->aAdditionalRequestParams = is_array( $aParams ) ? $aParams : [];
170
  return $this;
171
  }
172
  }
src/common/icwp-foundation.php CHANGED
@@ -52,6 +52,7 @@ class ICWP_WPSF_Foundation {
52
 
53
  /**
54
  * @return ICWP_WPSF_WpFunctions_Plugins
 
55
  */
56
  public function loadWpPlugins() {
57
  $sKey = 'icwp-wpfunctions-plugins';
@@ -63,6 +64,7 @@ class ICWP_WPSF_Foundation {
63
 
64
  /**
65
  * @return ICWP_WPSF_WpFunctions_Themes
 
66
  */
67
  public function loadWpThemes() {
68
  $sKey = 'icwp-wpfunctions-themes';
@@ -74,6 +76,7 @@ class ICWP_WPSF_Foundation {
74
 
75
  /**
76
  * @return ICWP_WPSF_WpCron
 
77
  */
78
  static public function loadWpCronProcessor() {
79
  $sKey = 'icwp-wpcron';
@@ -85,6 +88,7 @@ class ICWP_WPSF_Foundation {
85
 
86
  /**
87
  * @return ICWP_WPSF_WpUpgrades
 
88
  */
89
  static public function loadWpUpgrades() {
90
  $sKey = 'icwp-wpupgrades';
@@ -105,18 +109,6 @@ class ICWP_WPSF_Foundation {
105
  return self::getService( $sKey );
106
  }
107
 
108
- /**
109
- * @deprecated
110
- * @return ICWP_WPSF_Ip
111
- */
112
- static public function loadIpService() {
113
- $sKey = 'icwp-ip';
114
- if ( !self::isServiceReady( $sKey ) ) {
115
- self::setService( $sKey, ICWP_WPSF_Ip::GetInstance() );
116
- }
117
- return self::getService( $sKey );
118
- }
119
-
120
  /**
121
  * @return ICWP_WPSF_Request
122
  */
@@ -150,30 +142,9 @@ class ICWP_WPSF_Foundation {
150
  return self::getService( $sKey );
151
  }
152
 
153
- /**
154
- * @return ICWP_WPSF_GoogleAuthenticator
155
- */
156
- static public function loadGoogleAuthenticatorProcessor() {
157
- $sKey = 'icwp-googleauthenticator';
158
- if ( !self::isServiceReady( $sKey ) ) {
159
- self::setService( $sKey, ICWP_WPSF_GoogleAuthenticator::GetInstance() );
160
- }
161
- return self::getService( $sKey );
162
- }
163
-
164
- /**
165
- * @return ICWP_WPSF_GoogleRecaptcha
166
- */
167
- static public function loadGoogleRecaptcha() {
168
- $sKey = 'icwp-googlearecaptcha';
169
- if ( !self::isServiceReady( $sKey ) ) {
170
- self::setService( $sKey, ICWP_WPSF_GoogleRecaptcha::GetInstance() );
171
- }
172
- return self::getService( $sKey );
173
- }
174
-
175
  /**
176
  * @return ICWP_WPSF_WpIncludes
 
177
  */
178
  static public function loadWpIncludes() {
179
  $sKey = 'icwp-wpincludes';
@@ -250,7 +221,7 @@ class ICWP_WPSF_Foundation {
250
  */
251
  static private function getDic() {
252
  if ( !is_array( self::$aDic ) ) {
253
- self::$aDic = array();
254
  }
255
  return self::$aDic;
256
  }
@@ -284,8 +255,8 @@ class ICWP_WPSF_Foundation {
284
  }
285
 
286
  /**
287
- * @deprecated
288
  * @return ICWP_WPSF_WpAdminNotices
 
289
  */
290
  static public function loadAdminNoticesProcessor() {
291
  return self::loadWpNotices();
52
 
53
  /**
54
  * @return ICWP_WPSF_WpFunctions_Plugins
55
+ * @deprecated
56
  */
57
  public function loadWpPlugins() {
58
  $sKey = 'icwp-wpfunctions-plugins';
64
 
65
  /**
66
  * @return ICWP_WPSF_WpFunctions_Themes
67
+ * @deprecated
68
  */
69
  public function loadWpThemes() {
70
  $sKey = 'icwp-wpfunctions-themes';
76
 
77
  /**
78
  * @return ICWP_WPSF_WpCron
79
+ * @deprecated
80
  */
81
  static public function loadWpCronProcessor() {
82
  $sKey = 'icwp-wpcron';
88
 
89
  /**
90
  * @return ICWP_WPSF_WpUpgrades
91
+ * @deprecated
92
  */
93
  static public function loadWpUpgrades() {
94
  $sKey = 'icwp-wpupgrades';
109
  return self::getService( $sKey );
110
  }
111
 
 
 
 
 
 
 
 
 
 
 
 
 
112
  /**
113
  * @return ICWP_WPSF_Request
114
  */
142
  return self::getService( $sKey );
143
  }
144
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
145
  /**
146
  * @return ICWP_WPSF_WpIncludes
147
+ * @deprecated
148
  */
149
  static public function loadWpIncludes() {
150
  $sKey = 'icwp-wpincludes';
221
  */
222
  static private function getDic() {
223
  if ( !is_array( self::$aDic ) ) {
224
+ self::$aDic = [];
225
  }
226
  return self::$aDic;
227
  }
255
  }
256
 
257
  /**
 
258
  * @return ICWP_WPSF_WpAdminNotices
259
+ * @deprecated
260
  */
261
  static public function loadAdminNoticesProcessor() {
262
  return self::loadWpNotices();
src/common/icwp-googlearecaptcha.php DELETED
@@ -1,35 +0,0 @@
1
- <?php
2
-
3
- class ICWP_WPSF_GoogleRecaptcha {
4
-
5
- /**
6
- * @var ICWP_WPSF_GoogleRecaptcha
7
- */
8
- protected static $oInstance = null;
9
-
10
- /**
11
- * @var \ReCaptcha\ReCaptcha
12
- */
13
- protected static $oGR;
14
-
15
- /**
16
- * @return ICWP_WPSF_GoogleRecaptcha
17
- */
18
- public static function GetInstance() {
19
- if ( is_null( self::$oInstance ) ) {
20
- self::$oInstance = new self();
21
- }
22
- return self::$oInstance;
23
- }
24
-
25
- /**
26
- * @param string $sSecret
27
- * @return \ReCaptcha\ReCaptcha
28
- */
29
- public function getGoogleRecaptchaLib( $sSecret ) {
30
- if ( !isset( self::$oGR ) ) {
31
- self::$oGR = new \ReCaptcha\ReCaptcha( $sSecret, new \ReCaptcha\RequestMethod\WordpressPost() );
32
- }
33
- return self::$oGR;
34
- }
35
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/common/icwp-googleauthenticator.php DELETED
@@ -1,59 +0,0 @@
1
- <?php
2
-
3
- class ICWP_WPSF_GoogleAuthenticator {
4
-
5
- /**
6
- * @var ICWP_WPSF_GoogleAuthenticator
7
- */
8
- protected static $oInstance = null;
9
-
10
- /**
11
- * @var PHPGangsta_GoogleAuthenticator
12
- */
13
- protected static $oGA;
14
-
15
- /**
16
- * @return ICWP_WPSF_GoogleAuthenticator
17
- */
18
- public static function GetInstance() {
19
- if ( is_null( self::$oInstance ) ) {
20
- self::$oInstance = new self();
21
- }
22
- return self::$oInstance;
23
- }
24
-
25
- /**
26
- * @return string
27
- */
28
- public function generateNewSecret() {
29
- return $this->getGoogleAuthenticatorLib()->createSecret();
30
- }
31
-
32
- /**
33
- * @param string $sSecret
34
- * @param string $sName
35
- * @return string
36
- */
37
- public function getGoogleQrChartUrl( $sSecret, $sName = 'icwp' ) {
38
- return $this->getGoogleAuthenticatorLib()->getQRCodeGoogleUrl( $sName, $sSecret );
39
- }
40
-
41
- /**
42
- * @param string $sSecret
43
- * @param string $sPassword
44
- * @return bool
45
- */
46
- public function verifyOtp( $sSecret, $sPassword ) {
47
- return $this->getGoogleAuthenticatorLib()->verifyCode( $sSecret, $sPassword );
48
- }
49
-
50
- /**
51
- * @return PHPGangsta_GoogleAuthenticator
52
- */
53
- protected function getGoogleAuthenticatorLib() {
54
- if ( !isset( self::$oGA ) ) {
55
- self::$oGA = new PHPGangsta_GoogleAuthenticator();
56
- }
57
- return self::$oGA;
58
- }
59
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/common/icwp-ip.php DELETED
@@ -1,499 +0,0 @@
1
- <?php
2
-
3
- use FernleafSystems\Wordpress\Services\Services;
4
-
5
- /**
6
- * This is taken straight out of https://github.com/symfony/HttpFoundation/blob/master/IpUtils.php
7
- */
8
- class ICWP_WPSF_Ip extends ICWP_WPSF_Foundation {
9
-
10
- const IpifyEndpoint = 'https://api.ipify.org';
11
-
12
- /**
13
- * @var string
14
- */
15
- private $sIp;
16
-
17
- /**
18
- * @var string
19
- */
20
- private $sMyIp;
21
-
22
- /**
23
- * @var ICWP_WPSF_Ip
24
- */
25
- protected static $oInstance = null;
26
-
27
- /**
28
- * @return ICWP_WPSF_Ip
29
- */
30
- public static function GetInstance() {
31
- if ( is_null( self::$oInstance ) ) {
32
- self::$oInstance = new self();
33
- }
34
- return self::$oInstance;
35
- }
36
-
37
- /**
38
- * Checks if an IPv4 or IPv6 address is contained in the list of given IPs or subnets.
39
- * @param string $requestIp IP to check
40
- * @param string|array $ips List of IPs or subnets (can be a string if only a single one)
41
- * @return bool Whether the IP is valid
42
- * @throws Exception When IPV6 support is not enabled
43
- */
44
- public static function checkIp( $requestIp, $ips ) {
45
- if ( !is_array( $ips ) ) {
46
- $ips = array( $ips );
47
- }
48
- $method = substr_count( $requestIp, ':' ) > 1 ? 'checkIp6' : 'checkIp4';
49
- foreach ( $ips as $ip ) {
50
- if ( self::$method( $requestIp, $ip ) ) {
51
- return true;
52
- }
53
- }
54
- return false;
55
- }
56
-
57
- /**
58
- * Compares two IPv4 addresses.
59
- * In case a subnet is given, it checks if it contains the request IP.
60
- * @param string $requestIp IPv4 address to check
61
- * @param string $ip IPv4 address or subnet in CIDR notation
62
- * @return bool Whether the IP is valid
63
- */
64
- public static function checkIp4( $requestIp, $ip ) {
65
- if ( false !== strpos( $ip, '/' ) ) {
66
- if ( '0.0.0.0/0' === $ip ) {
67
- return true;
68
- }
69
- list( $address, $netmask ) = explode( '/', $ip, 2 );
70
- if ( $netmask < 1 || $netmask > 32 ) {
71
- return false;
72
- }
73
- }
74
- else {
75
- $address = $ip;
76
- $netmask = 32;
77
- }
78
- return 0 === substr_compare( sprintf( '%032b', ip2long( $requestIp ) ), sprintf( '%032b', ip2long( $address ) ), 0, $netmask );
79
- }
80
-
81
- /**
82
- * Compares two IPv6 addresses.
83
- * In case a subnet is given, it checks if it contains the request IP.
84
- * @author David Soria Parra <dsp at php dot net>
85
- * @see https://github.com/dsp/v6tools
86
- * @param string $requestIp IPv6 address to check
87
- * @param string $ip IPv6 address or subnet in CIDR notation
88
- * @return bool Whether the IP is valid
89
- * @throws Exception When IPV6 support is not enabled
90
- */
91
- public static function checkIp6( $requestIp, $ip ) {
92
- if ( !( ( extension_loaded( 'sockets' ) && defined( 'AF_INET6' ) ) || @inet_pton( '::1' ) ) ) {
93
- throw new Exception( 'Unable to check Ipv6. Check that PHP was not compiled with option "disable-ipv6".' );
94
- }
95
- if ( false !== strpos( $ip, '/' ) ) {
96
- list( $address, $netmask ) = explode( '/', $ip, 2 );
97
- if ( $netmask < 1 || $netmask > 128 ) {
98
- return false;
99
- }
100
- }
101
- else {
102
- $address = $ip;
103
- $netmask = 128;
104
- }
105
- $bytesAddr = unpack( 'n*', inet_pton( $address ) );
106
- $bytesTest = unpack( 'n*', inet_pton( $requestIp ) );
107
- for ( $i = 1, $ceil = ceil( $netmask/16 ) ; $i <= $ceil ; ++$i ) {
108
- $left = $netmask - 16*( $i - 1 );
109
- $left = ( $left <= 16 ) ? $left : 16;
110
- $mask = ~( 0xffff >> $left ) & 0xffff;
111
- if ( ( $bytesAddr[ $i ] & $mask ) != ( $bytesTest[ $i ] & $mask ) ) {
112
- return false;
113
- }
114
- }
115
- return true;
116
- }
117
-
118
- /**
119
- * @param string $sIp
120
- * @return bool|int
121
- */
122
- public function getIpVersion( $sIp ) {
123
- if ( filter_var( $sIp, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 ) ) {
124
- return 4;
125
- }
126
- if ( filter_var( $sIp, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 ) ) {
127
- return 6;
128
- }
129
- return false;
130
- }
131
-
132
- /**
133
- * @param string $sIp
134
- * @return string
135
- */
136
- public function getIpWhoisLookup( $sIp ) {
137
- return sprintf( 'https://apps.db.ripe.net/db-web-ui/#/query?bflag&searchtext=%s#resultsSection', $sIp );
138
- }
139
-
140
- /**
141
- * @deprecated
142
- * @param boolean $bAsHuman
143
- * @return int|string|bool - visitor IP Address as IP2Long
144
- */
145
- public function getRequestIp( $bAsHuman = true ) {
146
- return Services::IP()->getRequestIp( $bAsHuman );
147
- }
148
-
149
- /**
150
- * @param string $sIp
151
- * @return bool
152
- */
153
- public function isCloudFlareIp( $sIp ) {
154
- if ( $this->getIpVersion( $sIp ) == 4 ) {
155
- return $this->checkIp( $sIp, $this->getCloudFlareIpsV4() );
156
- }
157
- else {
158
- return $this->checkIp( $sIp, $this->getCloudFlareIpsV6() );
159
- }
160
- }
161
-
162
- /**
163
- * @return bool
164
- */
165
- public function isSupportedIpv6() {
166
- return ( extension_loaded( 'sockets' ) && defined( 'AF_INET6' ) ) || @inet_pton( '::1' );
167
- }
168
-
169
- /**
170
- * @param string $sIp
171
- * @param bool $flags
172
- * @return boolean
173
- */
174
- public function isValidIp( $sIp, $flags = null ) {
175
- /*preg_replace( '#[^a-f0-9:.]#i', '', $sIp )*/
176
- return filter_var( trim( $sIp ), FILTER_VALIDATE_IP, $flags );
177
- }
178
-
179
- /**
180
- * @param string $sIp
181
- * @return boolean
182
- */
183
- public function isValidIp4Range( $sIp ) {
184
- $bIsRange = false;
185
- if ( strpos( $sIp, '/' ) ) {
186
- list( $sIp, $sCIDR ) = explode( '/', $sIp );
187
- $bIsRange = $this->isValidIp( $sIp ) && ( (int)$sCIDR >= 0 && (int)$sCIDR <= 32 );
188
- }
189
- return $bIsRange;
190
- }
191
-
192
- /**
193
- * @param string $sIp
194
- * @return boolean
195
- */
196
- public function isValidIpOrRange( $sIp ) {
197
- return $this->isValidIp_PublicRemote( $sIp ) || $this->isValidIpRange( $sIp );
198
- }
199
-
200
- /**
201
- * Assumes a valid IPv4 address is provided as we're only testing for a whether the IP is public or not.
202
- * @param string $sIp
203
- * @return boolean
204
- */
205
- public function isValidIp_PublicRange( $sIp ) {
206
- return $this->isValidIp( $sIp, FILTER_FLAG_NO_PRIV_RANGE );
207
- }
208
-
209
- /**
210
- * @param string $sIp
211
- * @return boolean
212
- */
213
- public function isValidIp_PublicRemote( $sIp ) {
214
- return $this->isValidIp( $sIp, ( FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE ) );
215
- }
216
-
217
- /**
218
- * @param string $sIp
219
- * @return boolean
220
- */
221
- public function isValidIpRange( $sIp ) {
222
- if ( strpos( $sIp, '/' ) == false ) {
223
- return false;
224
- }
225
- $aParts = explode( '/', $sIp );
226
- return filter_var( $aParts[ 0 ], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 ) && ( 0 < $aParts[ 1 ] && $aParts[ 1 ] < 33 );
227
- }
228
-
229
- /**
230
- * Checks:
231
- * - valid public remote IP
232
- * - Not CloudFlare
233
- * - Not the IP of the currently running server if this is provided
234
- * @param string $sIp
235
- * @param string $sHostIp
236
- * @return bool
237
- */
238
- public function isViablePublicVisitorIp( $sIp, $sHostIp = '' ) {
239
- return !empty( $sIp ) && $this->isValidIp_PublicRemote( $sIp ) && !$this->isCloudFlareIp( $sIp )
240
- && ( empty( $sHostIp ) || !$this->checkIp( $sIp, $sHostIp ) );
241
- }
242
-
243
- /**
244
- * @param string $sIp
245
- * @return $this
246
- */
247
- public function setRequestIpAddress( $sIp ) {
248
- $this->sIp = $sIp;
249
- return $this;
250
- }
251
-
252
- /**
253
- * @param string $sIp
254
- * @return $this
255
- */
256
- public function setServerIpAddress( $sIp ) {
257
- $this->sMyIp = $sIp;
258
- return $this;
259
- }
260
-
261
- /**
262
- * @deprecated
263
- * @return string|false
264
- */
265
- public function whatIsMyIp() {
266
- return Services::IP()->whatIsMyIp();
267
- }
268
-
269
- /**
270
- * @param string $sVisitorIp
271
- * @return string
272
- */
273
- public function determineSourceFromIp( $sVisitorIp ) {
274
- $oReq = Services::Request();
275
-
276
- $sBestSource = null;
277
- foreach ( $this->getIpSourceOptions() as $sSource ) {
278
-
279
- $sIpToTest = $oReq->server( $sSource );
280
- if ( empty( $sIpToTest ) ) {
281
- continue;
282
- }
283
-
284
- // sometimes a comma-separated list is returned
285
- $aIpAddresses = array_map( 'trim', explode( ',', $sIpToTest ) );
286
- foreach ( $aIpAddresses as $sIp ) {
287
-
288
- if ( $sVisitorIp == $sIp ) {
289
- $sBestSource = $sSource;
290
- break( 2 );
291
- }
292
- }
293
- }
294
-
295
- return $sBestSource;
296
- }
297
-
298
- /**
299
- * @return array
300
- */
301
- public function discoverViableRequestIpSource() {
302
- return $this->findViableVisitorIp( true );
303
- }
304
-
305
- /**
306
- * Cloudflare compatible.
307
- * @param bool $bRemoteVerify
308
- * @return array
309
- */
310
- protected function findViableVisitorIp( $bRemoteVerify = false ) {
311
-
312
- $sMyIp = $bRemoteVerify ? $this->whatIsMyIp() : null;
313
-
314
- $sIpToReturn = false;
315
- $sSource = false;
316
- $oReq = Services::Request();
317
- foreach ( $this->getIpSourceOptions() as $sMaybeSource ) {
318
-
319
- $sIpToTest = $oReq->server( $sMaybeSource );
320
- if ( empty( $sIpToTest ) ) {
321
- continue;
322
- }
323
-
324
- // sometimes a comma-separated list is returned
325
- $aIpAddresses = array_map( 'trim', explode( ',', $sIpToTest ) );
326
- foreach ( $aIpAddresses as $sIp ) {
327
-
328
- if ( $this->isViablePublicVisitorIp( $sIp ) ) {
329
- $sIpToReturn = $sIp;
330
- $sSource = $sMaybeSource;
331
- break( 2 );
332
- }
333
- }
334
- }
335
-
336
- return array(
337
- 'source' => $sSource,
338
- 'ip' => $sIpToReturn
339
- );
340
- }
341
-
342
- /**
343
- * @return string[]
344
- */
345
- protected function getIpSourceOptions() {
346
- return array(
347
- 'REMOTE_ADDR',
348
- 'HTTP_CF_CONNECTING_IP',
349
- 'HTTP_X_FORWARDED_FOR',
350
- 'HTTP_X_FORWARDED',
351
- 'HTTP_X_REAL_IP',
352
- 'HTTP_X_SUCURI_CLIENTIP',
353
- 'HTTP_INCAP_CLIENT_IP',
354
- 'HTTP_X_SP_FORWARDED_IP',
355
- 'HTTP_FORWARDED',
356
- 'HTTP_CLIENT_IP'
357
- );
358
- }
359
-
360
- /**
361
- * @return string[]
362
- */
363
- protected function getCloudFlareIpsV4() {
364
- return array(
365
- '103.21.244.0/22',
366
- '103.22.200.0/22',
367
- '103.31.4.0/22',
368
- '104.16.0.0/12',
369
- '108.162.192.0/18',
370
- '131.0.72.0/22',
371
- '141.101.64.0/18',
372
- '162.158.0.0/15',
373
- '172.64.0.0/13',
374
- '173.245.48.0/20',
375
- '188.114.96.0/20',
376
- '190.93.240.0/20',
377
- '197.234.240.0/22',
378
- '198.41.128.0/17'
379
- );
380
- }
381
-
382
- /**
383
- * @return string[]
384
- */
385
- protected function getCloudFlareIpsV6() {
386
- return array(
387
- '2400:cb00::/32',
388
- '2405:8100::/32',
389
- '2405:b500::/32',
390
- '2606:4700::/32',
391
- '2803:f800::/32',
392
- '2c0f:f248::/32',
393
- '2a06:98c0::/29'
394
- );
395
- }
396
-
397
- /**
398
- * @deprecated
399
- * @param int $sIpVersion
400
- * @return string[]
401
- */
402
- public function getServiceIps_Pingdom( $sIpVersion = 4 ) {
403
- return $this->loadServiceProviders()->getIps_Pingdom()[ $sIpVersion ];
404
- }
405
-
406
- /**
407
- * @deprecated
408
- * @return string[]
409
- */
410
- public function getServiceIps_StatusCake() {
411
- return $this->loadServiceProviders()->getIps_Statuscake();
412
- }
413
-
414
- /**
415
- * @deprecated
416
- * @param int $sIpVersion
417
- * @return string[]
418
- */
419
- public function getServiceIps_UptimeRobot( $sIpVersion = 4 ) {
420
- return $this->loadServiceProviders()->getIps_UptimeRobot()[ $sIpVersion ];
421
- }
422
-
423
- /**
424
- * @param string $sIp
425
- * @param string $sUserAgent
426
- * @return bool
427
- */
428
- public function isIpBingBot( $sIp, $sUserAgent = '' ) {
429
- return $this->isIpOfBot( 'bingbot', '#.*\.search\.msn\.com\.?$#i', $sIp, $sUserAgent );
430
- }
431
-
432
- /**
433
- * https://duckduckgo.com/duckduckbot
434
- * @param string $sIp
435
- * @param string $sUserAgent
436
- * @return bool
437
- */
438
- public function isIpDuckDuckGoBot( $sIp, $sUserAgent = '' ) {
439
- $bIsBot = false;
440
-
441
- // We check the useragent if available
442
- if ( is_null( $sUserAgent ) || stripos( $sUserAgent, 'DuckDuckBot' ) !== false ) {
443
- $bIsBot = in_array( $sIp, array( '107.20.237.51', '23.21.226.191', '107.21.1.8', '54.208.102.37' ) );
444
- }
445
- return $bIsBot;
446
- }
447
-
448
- /**
449
- * @param string $sIp
450
- * @param string $sUserAgent
451
- * @return bool
452
- */
453
- public function isIpGoogleBot( $sIp, $sUserAgent = '' ) {
454
- return $this->isIpOfBot( 'Googlebot', '#.*\.google(bot)?\.com\.?$#i', $sIp, $sUserAgent );
455
- }
456
-
457
- /**
458
- * @param string $sIp
459
- * @param string $sUserAgent
460
- * @return bool
461
- */
462
- public function isIpYandexBot( $sIp, $sUserAgent = '' ) {
463
- return $this->isIpOfBot( 'yandex.com/bots', '#.*\.yandex?\.(com|ru|net)\.?$#i', $sIp, $sUserAgent );
464
- }
465
-
466
- /**
467
- * https://support.apple.com/en-gb/HT204683
468
- * https://discussions.apple.com/thread/7090135
469
- * Apple IPs start with '17.'
470
- * @param string $sIp
471
- * @param string $sUserAgent
472
- * @return bool
473
- */
474
- public function isIpAppleBot( $sIp, $sUserAgent = '' ) {
475
- return ( $this->getIpVersion( $sIp ) != 4 || strpos( $sIp, '17.' ) === 0 )
476
- && $this->isIpOfBot( 'Applebot/', '#.*\.applebot.apple.com\.?$#i', $sIp, $sUserAgent );
477
- }
478
-
479
- /**
480
- * @param string $sBotUserAgent
481
- * @param string $sBotHostPattern
482
- * @param string $sReqIp
483
- * @param string $sReqUserAgent
484
- * @return bool
485
- */
486
- protected function isIpOfBot( $sBotUserAgent, $sBotHostPattern, $sReqIp, $sReqUserAgent = '' ) {
487
- $bIsBot = false;
488
-
489
- // We check the useragent if available
490
- if ( is_null( $sReqUserAgent ) || stripos( $sReqUserAgent, $sBotUserAgent ) !== false ) {
491
- $sHost = @gethostbyaddr( $sReqIp ); // returns the ip on failure
492
- if ( !empty( $sHost ) && ( $sHost != $sReqIp )
493
- && preg_match( $sBotHostPattern, $sHost ) && gethostbyname( $sHost ) === $sReqIp ) {
494
- $bIsBot = true;
495
- }
496
- }
497
- return $bIsBot;
498
- }
499
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/common/icwp-optionsvo.php CHANGED
@@ -1,5 +1,7 @@
1
  <?php
2
 
 
 
3
  class ICWP_WPSF_OptionsVO extends ICWP_WPSF_Foundation {
4
 
5
  /**
@@ -43,11 +45,6 @@ class ICWP_WPSF_OptionsVO extends ICWP_WPSF_Foundation {
43
  */
44
  protected $bLoadFromSaved = true;
45
 
46
- /**
47
- * @var string
48
- */
49
- protected $sOptionsEncoding;
50
-
51
  /**
52
  * @var string
53
  */
@@ -113,7 +110,7 @@ class ICWP_WPSF_OptionsVO extends ICWP_WPSF_Foundation {
113
  * @return array
114
  */
115
  public function getTransferableOptions() {
116
- $aTransferable = array();
117
 
118
  foreach ( $this->getRawData_AllOptions() as $nKey => $aOptionData ) {
119
  if ( !isset( $aOptionData[ 'transferable' ] ) || $aOptionData[ 'transferable' ] === true ) {
@@ -175,7 +172,7 @@ class ICWP_WPSF_OptionsVO extends ICWP_WPSF_Foundation {
175
  */
176
  public function getAdminNotices() {
177
  $aRawConfig = $this->getRawData_FullFeatureConfig();
178
- return ( isset( $aRawConfig[ 'admin_notices' ] ) && is_array( $aRawConfig[ 'admin_notices' ] ) ) ? $aRawConfig[ 'admin_notices' ] : array();
179
  }
180
 
181
  /**
@@ -206,7 +203,7 @@ class ICWP_WPSF_OptionsVO extends ICWP_WPSF_Foundation {
206
  */
207
  public function getHiddenOptions() {
208
 
209
- $aOptionsData = array();
210
 
211
  foreach ( $this->getRawData_OptionsSections() as $nPosition => $aRawSection ) {
212
 
@@ -239,7 +236,7 @@ class ICWP_WPSF_OptionsVO extends ICWP_WPSF_Foundation {
239
  * @return array[]
240
  */
241
  public function getSections( $bIncludeHidden = false ) {
242
- $aSections = array();
243
  foreach ( $this->getRawData_OptionsSections() as $aRawSection ) {
244
  if ( $bIncludeHidden || !isset( $aRawSection[ 'hidden' ] ) || !$aRawSection[ 'hidden' ] ) {
245
  $aSections[ $aRawSection[ 'slug' ] ] = $aRawSection;
@@ -252,7 +249,7 @@ class ICWP_WPSF_OptionsVO extends ICWP_WPSF_Foundation {
252
  * @return array
253
  */
254
  public function getPrimarySection() {
255
- $aSec = array();
256
  foreach ( $this->getSections() as $aS ) {
257
  if ( isset( $aS[ 'primary' ] ) && $aS[ 'primary' ] ) {
258
  $aSec = $aS;
@@ -268,12 +265,12 @@ class ICWP_WPSF_OptionsVO extends ICWP_WPSF_Foundation {
268
  */
269
  public function getSection_Requirements( $sSlug ) {
270
  $aSection = $this->getSection( $sSlug );
271
- $aReqs = ( is_array( $aSection ) && isset( $aSection[ 'reqs' ] ) ) ? $aSection[ 'reqs' ] : array();
272
  return array_merge(
273
- array(
274
  'php_min' => '5.2.4',
275
  'wp_min' => '3.5.0',
276
- ),
277
  $aReqs
278
  );
279
  }
@@ -306,12 +303,33 @@ class ICWP_WPSF_OptionsVO extends ICWP_WPSF_Foundation {
306
  return $this->isSectionReqsMet( $this->getOptProperty( $sOptKey, 'section' ) );
307
  }
308
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
309
  /**
310
  * @return array
311
  */
312
  public function getOptionsForPluginUse() {
313
 
314
- $aOptionsData = array();
315
 
316
  foreach ( $this->getRawData_OptionsSections() as $aRawSection ) {
317
 
@@ -320,11 +338,11 @@ class ICWP_WPSF_OptionsVO extends ICWP_WPSF_Foundation {
320
  }
321
 
322
  $aRawSection = array_merge(
323
- array(
324
  'primary' => false,
325
  'options' => $this->getOptionsForSection( $aRawSection[ 'slug' ] ),
326
  'help_video_id' => ''
327
- ),
328
  $aRawSection
329
  );
330
 
@@ -342,7 +360,7 @@ class ICWP_WPSF_OptionsVO extends ICWP_WPSF_Foundation {
342
  */
343
  protected function getOptionsForSection( $sSectionSlug ) {
344
 
345
- $aAllOptions = array();
346
  foreach ( $this->getRawData_AllOptions() as $aOptionDef ) {
347
 
348
  if ( ( $aOptionDef[ 'section' ] != $sSectionSlug ) || ( isset( $aOptionDef[ 'hidden' ] ) && $aOptionDef[ 'hidden' ] ) ) {
@@ -354,18 +372,18 @@ class ICWP_WPSF_OptionsVO extends ICWP_WPSF_Foundation {
354
  }
355
 
356
  $aOptionDef = array_merge(
357
- array(
358
  'link_info' => '',
359
  'link_blog' => '',
360
  'help_video_id' => '',
361
- 'value_options' => array()
362
- ),
363
  $aOptionDef
364
  );
365
  $aOptionDef[ 'value' ] = $this->getOpt( $aOptionDef[ 'key' ] );
366
 
367
- if ( in_array( $aOptionDef[ 'type' ], array( 'select', 'multiple_select' ) ) ) {
368
- $aNewValueOptions = array();
369
  foreach ( $aOptionDef[ 'value_options' ] as $aValueOptions ) {
370
  $aNewValueOptions[ $aValueOptions[ 'value_key' ] ] = $aValueOptions[ 'text' ];
371
  }
@@ -438,7 +456,7 @@ class ICWP_WPSF_OptionsVO extends ICWP_WPSF_Foundation {
438
  * @return array
439
  */
440
  public function getOptDefinition( $sOptionKey ) {
441
- $aDef = array();
442
  foreach ( $this->getRawData_AllOptions() as $aOption ) {
443
  if ( $aOption[ 'key' ] == $sOptionKey ) {
444
  $aDef = $aOption;
@@ -471,19 +489,12 @@ class ICWP_WPSF_OptionsVO extends ICWP_WPSF_Foundation {
471
  return null;
472
  }
473
 
474
- /**
475
- * @return string
476
- */
477
- public function getOptionsEncoding() {
478
- return empty( $this->sOptionsEncoding ) ? 'json' : $this->sOptionsEncoding;
479
- }
480
-
481
  /**
482
  * @return array
483
  */
484
  public function getOptionsKeys() {
485
  if ( !isset( $this->aOptionsKeys ) ) {
486
- $this->aOptionsKeys = array();
487
  foreach ( $this->getRawData_AllOptions() as $aOption ) {
488
  $this->aOptionsKeys[] = $aOption[ 'key' ];
489
  }
@@ -503,7 +514,7 @@ class ICWP_WPSF_OptionsVO extends ICWP_WPSF_Foundation {
503
  * @return string
504
  */
505
  protected function getConfigModTime() {
506
- return $this->loadFS()->getModifiedTime( $this->getPathToConfig() );
507
  }
508
 
509
  /**
@@ -531,7 +542,7 @@ class ICWP_WPSF_OptionsVO extends ICWP_WPSF_Foundation {
531
  return $this->loadOptionsValuesFromStorage();
532
  }
533
  catch ( Exception $oE ) {
534
- return array();
535
  }
536
  }
537
 
@@ -551,7 +562,7 @@ class ICWP_WPSF_OptionsVO extends ICWP_WPSF_Foundation {
551
  */
552
  protected function getRawData_AllOptions() {
553
  $aRaw = $this->getRawData_FullFeatureConfig();
554
- return ( isset( $aRaw[ 'options' ] ) && is_array( $aRaw[ 'options' ] ) ) ? $aRaw[ 'options' ] : array();
555
  }
556
 
557
  /**
@@ -560,7 +571,7 @@ class ICWP_WPSF_OptionsVO extends ICWP_WPSF_Foundation {
560
  */
561
  protected function getRawData_OptionsSections() {
562
  $aAllRawOptions = $this->getRawData_FullFeatureConfig();
563
- return isset( $aAllRawOptions[ 'sections' ] ) ? $aAllRawOptions[ 'sections' ] : array();
564
  }
565
 
566
  /**
@@ -569,7 +580,7 @@ class ICWP_WPSF_OptionsVO extends ICWP_WPSF_Foundation {
569
  */
570
  protected function getRawData_Requirements() {
571
  $aAllRawOptions = $this->getRawData_FullFeatureConfig();
572
- return isset( $aAllRawOptions[ 'requirements' ] ) ? $aAllRawOptions[ 'requirements' ] : array();
573
  }
574
 
575
  /**
@@ -578,7 +589,7 @@ class ICWP_WPSF_OptionsVO extends ICWP_WPSF_Foundation {
578
  */
579
  protected function getRawData_MenuItems() {
580
  $aAllRawOptions = $this->getRawData_FullFeatureConfig();
581
- return isset( $aAllRawOptions[ 'menu_items' ] ) ? $aAllRawOptions[ 'menu_items' ] : array();
582
  }
583
 
584
  /**
@@ -715,15 +726,6 @@ class ICWP_WPSF_OptionsVO extends ICWP_WPSF_Foundation {
715
  $this->bNeedSave = $bNeed;
716
  }
717
 
718
- /**
719
- * @param string $sOptionsEncoding
720
- * @return $this
721
- */
722
- public function setOptionsEncoding( $sOptionsEncoding ) {
723
- $this->sOptionsEncoding = $sOptionsEncoding;
724
- return $this;
725
- }
726
-
727
  /**
728
  * @param boolean $bRebuild
729
  * @return $this
@@ -840,7 +842,7 @@ class ICWP_WPSF_OptionsVO extends ICWP_WPSF_Foundation {
840
  */
841
  private function setOldOptValue( $sOptionKey, $mValue ) {
842
  if ( !is_array( $this->aOld ) ) {
843
- $this->aOld = array();
844
  }
845
  if ( !isset( $this->aOld[ $sOptionKey ] ) ) {
846
  $this->aOld[ $sOptionKey ] = $mValue;
@@ -865,7 +867,7 @@ class ICWP_WPSF_OptionsVO extends ICWP_WPSF_Foundation {
865
  * @return array
866
  */
867
  protected function getCommonStandardOptions() {
868
- return array( 'help_video_options' );
869
  }
870
 
871
  /**
@@ -894,11 +896,11 @@ class ICWP_WPSF_OptionsVO extends ICWP_WPSF_Foundation {
894
  if ( empty( $sStorageKey ) ) {
895
  throw new Exception( 'Options Storage Key Is Empty' );
896
  }
897
- $this->aOptionsValues = $this->loadWp()->getOption( $sStorageKey, array() );
898
  }
899
  }
900
  if ( !is_array( $this->aOptionsValues ) ) {
901
- $this->aOptionsValues = array();
902
  $this->setNeedSave( true );
903
  }
904
  return $this->aOptionsValues;
@@ -930,7 +932,7 @@ class ICWP_WPSF_OptionsVO extends ICWP_WPSF_Foundation {
930
  if ( WP_DEBUG ) {
931
  trigger_error( $oE->getMessage() );
932
  }
933
- $aConfig = array();
934
  }
935
  $aConfig[ 'meta_modts' ] = $this->getConfigModTime();
936
  $oWp->setTransient( $sTransientKey, $aConfig, DAY_IN_SECONDS );
@@ -975,7 +977,7 @@ class ICWP_WPSF_OptionsVO extends ICWP_WPSF_Foundation {
975
  */
976
  private function getConfigFileExists() {
977
  $sPath = $this->getPathToConfig();
978
- return !empty( $sPath ) && $this->loadFS()->isFile( $sPath );
979
  }
980
 
981
  /**
1
  <?php
2
 
3
+ use FernleafSystems\Wordpress\Services\Services; // TODO: use after 7.5
4
+
5
  class ICWP_WPSF_OptionsVO extends ICWP_WPSF_Foundation {
6
 
7
  /**
45
  */
46
  protected $bLoadFromSaved = true;
47
 
 
 
 
 
 
48
  /**
49
  * @var string
50
  */
110
  * @return array
111
  */
112
  public function getTransferableOptions() {
113
+ $aTransferable = [];
114
 
115
  foreach ( $this->getRawData_AllOptions() as $nKey => $aOptionData ) {
116
  if ( !isset( $aOptionData[ 'transferable' ] ) || $aOptionData[ 'transferable' ] === true ) {
172
  */
173
  public function getAdminNotices() {
174
  $aRawConfig = $this->getRawData_FullFeatureConfig();
175
+ return ( isset( $aRawConfig[ 'admin_notices' ] ) && is_array( $aRawConfig[ 'admin_notices' ] ) ) ? $aRawConfig[ 'admin_notices' ] : [];
176
  }
177
 
178
  /**
203
  */
204
  public function getHiddenOptions() {
205
 
206
+ $aOptionsData = [];
207
 
208
  foreach ( $this->getRawData_OptionsSections() as $nPosition => $aRawSection ) {
209
 
236
  * @return array[]
237
  */
238
  public function getSections( $bIncludeHidden = false ) {
239
+ $aSections = [];
240
  foreach ( $this->getRawData_OptionsSections() as $aRawSection ) {
241
  if ( $bIncludeHidden || !isset( $aRawSection[ 'hidden' ] ) || !$aRawSection[ 'hidden' ] ) {
242
  $aSections[ $aRawSection[ 'slug' ] ] = $aRawSection;
249
  * @return array
250
  */
251
  public function getPrimarySection() {
252
+ $aSec = [];
253
  foreach ( $this->getSections() as $aS ) {
254
  if ( isset( $aS[ 'primary' ] ) && $aS[ 'primary' ] ) {
255
  $aSec = $aS;
265
  */
266
  public function getSection_Requirements( $sSlug ) {
267
  $aSection = $this->getSection( $sSlug );
268
+ $aReqs = ( is_array( $aSection ) && isset( $aSection[ 'reqs' ] ) ) ? $aSection[ 'reqs' ] : [];
269
  return array_merge(
270
+ [
271
  'php_min' => '5.2.4',
272
  'wp_min' => '3.5.0',
273
+ ],
274
  $aReqs
275
  );
276
  }
303
  return $this->isSectionReqsMet( $this->getOptProperty( $sOptKey, 'section' ) );
304
  }
305
 
306
+ /**
307
+ * @return string[]
308
+ */
309
+ public function getVisibleOptionsKeys() {
310
+ $aKeys = [];
311
+
312
+ foreach ( $this->getRawData_AllOptions() as $aOptionDef ) {
313
+ if ( isset( $aOptionDef[ 'hidden' ] ) && $aOptionDef[ 'hidden' ] ) {
314
+ continue;
315
+ }
316
+ $aSection = $this->getSection( $aOptionDef[ 'section' ] );
317
+ if ( isset( $aSection[ 'hidden' ] ) && $aSection[ 'hidden' ] ) {
318
+ continue;
319
+ }
320
+
321
+ $aKeys[] = $aOptionDef[ 'key' ];
322
+ }
323
+
324
+ return $aKeys;
325
+ }
326
+
327
  /**
328
  * @return array
329
  */
330
  public function getOptionsForPluginUse() {
331
 
332
+ $aOptionsData = [];
333
 
334
  foreach ( $this->getRawData_OptionsSections() as $aRawSection ) {
335
 
338
  }
339
 
340
  $aRawSection = array_merge(
341
+ [
342
  'primary' => false,
343
  'options' => $this->getOptionsForSection( $aRawSection[ 'slug' ] ),
344
  'help_video_id' => ''
345
+ ],
346
  $aRawSection
347
  );
348
 
360
  */
361
  protected function getOptionsForSection( $sSectionSlug ) {
362
 
363
+ $aAllOptions = [];
364
  foreach ( $this->getRawData_AllOptions() as $aOptionDef ) {
365
 
366
  if ( ( $aOptionDef[ 'section' ] != $sSectionSlug ) || ( isset( $aOptionDef[ 'hidden' ] ) && $aOptionDef[ 'hidden' ] ) ) {
372
  }
373
 
374
  $aOptionDef = array_merge(
375
+ [
376
  'link_info' => '',
377
  'link_blog' => '',
378
  'help_video_id' => '',
379
+ 'value_options' => []
380
+ ],
381
  $aOptionDef
382
  );
383
  $aOptionDef[ 'value' ] = $this->getOpt( $aOptionDef[ 'key' ] );
384
 
385
+ if ( in_array( $aOptionDef[ 'type' ], [ 'select', 'multiple_select' ] ) ) {
386
+ $aNewValueOptions = [];
387
  foreach ( $aOptionDef[ 'value_options' ] as $aValueOptions ) {
388
  $aNewValueOptions[ $aValueOptions[ 'value_key' ] ] = $aValueOptions[ 'text' ];
389
  }
456
  * @return array
457
  */
458
  public function getOptDefinition( $sOptionKey ) {
459
+ $aDef = [];
460
  foreach ( $this->getRawData_AllOptions() as $aOption ) {
461
  if ( $aOption[ 'key' ] == $sOptionKey ) {
462
  $aDef = $aOption;
489
  return null;
490
  }
491
 
 
 
 
 
 
 
 
492
  /**
493
  * @return array
494
  */
495
  public function getOptionsKeys() {
496
  if ( !isset( $this->aOptionsKeys ) ) {
497
+ $this->aOptionsKeys = [];
498
  foreach ( $this->getRawData_AllOptions() as $aOption ) {
499
  $this->aOptionsKeys[] = $aOption[ 'key' ];
500
  }
514
  * @return string
515
  */
516
  protected function getConfigModTime() {
517
+ return \FernleafSystems\Wordpress\Services\Services::WpFs()->getModifiedTime( $this->getPathToConfig() );
518
  }
519
 
520
  /**
542
  return $this->loadOptionsValuesFromStorage();
543
  }
544
  catch ( Exception $oE ) {
545
+ return [];
546
  }
547
  }
548
 
562
  */
563
  protected function getRawData_AllOptions() {
564
  $aRaw = $this->getRawData_FullFeatureConfig();
565
+ return ( isset( $aRaw[ 'options' ] ) && is_array( $aRaw[ 'options' ] ) ) ? $aRaw[ 'options' ] : [];
566
  }
567
 
568
  /**
571
  */
572
  protected function getRawData_OptionsSections() {
573
  $aAllRawOptions = $this->getRawData_FullFeatureConfig();
574
+ return isset( $aAllRawOptions[ 'sections' ] ) ? $aAllRawOptions[ 'sections' ] : [];
575
  }
576
 
577
  /**
580
  */
581
  protected function getRawData_Requirements() {
582
  $aAllRawOptions = $this->getRawData_FullFeatureConfig();
583
+ return isset( $aAllRawOptions[ 'requirements' ] ) ? $aAllRawOptions[ 'requirements' ] : [];
584
  }
585
 
586
  /**
589
  */
590
  protected function getRawData_MenuItems() {
591
  $aAllRawOptions = $this->getRawData_FullFeatureConfig();
592
+ return isset( $aAllRawOptions[ 'menu_items' ] ) ? $aAllRawOptions[ 'menu_items' ] : [];
593
  }
594
 
595
  /**
726
  $this->bNeedSave = $bNeed;
727
  }
728
 
 
 
 
 
 
 
 
 
 
729
  /**
730
  * @param boolean $bRebuild
731
  * @return $this
842
  */
843
  private function setOldOptValue( $sOptionKey, $mValue ) {
844
  if ( !is_array( $this->aOld ) ) {
845
+ $this->aOld = [];
846
  }
847
  if ( !isset( $this->aOld[ $sOptionKey ] ) ) {
848
  $this->aOld[ $sOptionKey ] = $mValue;
867
  * @return array
868
  */
869
  protected function getCommonStandardOptions() {
870
+ return [ 'help_video_options' ];
871
  }
872
 
873
  /**
896
  if ( empty( $sStorageKey ) ) {
897
  throw new Exception( 'Options Storage Key Is Empty' );
898
  }
899
+ $this->aOptionsValues = $this->loadWp()->getOption( $sStorageKey, [] );
900
  }
901
  }
902
  if ( !is_array( $this->aOptionsValues ) ) {
903
+ $this->aOptionsValues = [];
904
  $this->setNeedSave( true );
905
  }
906
  return $this->aOptionsValues;
932
  if ( WP_DEBUG ) {
933
  trigger_error( $oE->getMessage() );
934
  }
935
+ $aConfig = [];
936
  }
937
  $aConfig[ 'meta_modts' ] = $this->getConfigModTime();
938
  $oWp->setTransient( $sTransientKey, $aConfig, DAY_IN_SECONDS );
977
  */
978
  private function getConfigFileExists() {
979
  $sPath = $this->getPathToConfig();
980
+ return !empty( $sPath ) && \FernleafSystems\Wordpress\Services\Services::WpFs()->isFile( $sPath );
981
  }
982
 
983
  /**
src/common/icwp-render.php CHANGED
@@ -11,7 +11,8 @@ class ICWP_WPSF_Render extends ICWP_WPSF_Foundation {
11
  */
12
  protected static $oInstance = null;
13
 
14
- private function __construct() {}
 
15
 
16
  /**
17
  * @return ICWP_WPSF_Render
@@ -135,7 +136,7 @@ class ICWP_WPSF_Render extends ICWP_WPSF_Foundation {
135
  * @return $this
136
  */
137
  public function clearRenderVars() {
138
- return $this->setRenderVars( array() );
139
  }
140
 
141
  /**
@@ -169,11 +170,11 @@ class ICWP_WPSF_Render extends ICWP_WPSF_Foundation {
169
  */
170
  public function getTemplateEngine() {
171
  if ( !isset( $this->nTemplateEngine )
172
- || !in_array( $this->nTemplateEngine, array(
173
  self::TEMPLATE_ENGINE_TWIG,
174
  self::TEMPLATE_ENGINE_PHP,
175
  self::TEMPLATE_ENGINE_HTML
176
- ) ) ) {
177
  $this->nTemplateEngine = self::TEMPLATE_ENGINE_PHP;
178
  }
179
  return $this->nTemplateEngine;
@@ -218,7 +219,7 @@ class ICWP_WPSF_Render extends ICWP_WPSF_Foundation {
218
  */
219
  public function getTemplateRoots() {
220
  if ( !is_array( $this->aTemplateRoots ) ) {
221
- $this->aTemplateRoots = array();
222
  }
223
  array_unshift( $this->aTemplateRoots, $this->getTemplateRootMain() );
224
  return array_unique( array_filter( $this->aTemplateRoots ) );
11
  */
12
  protected static $oInstance = null;
13
 
14
+ private function __construct() {
15
+ }
16
 
17
  /**
18
  * @return ICWP_WPSF_Render
136
  * @return $this
137
  */
138
  public function clearRenderVars() {
139
+ return $this->setRenderVars( [] );
140
  }
141
 
142
  /**
170
  */
171
  public function getTemplateEngine() {
172
  if ( !isset( $this->nTemplateEngine )
173
+ || !in_array( $this->nTemplateEngine, [
174
  self::TEMPLATE_ENGINE_TWIG,
175
  self::TEMPLATE_ENGINE_PHP,
176
  self::TEMPLATE_ENGINE_HTML
177
+ ] ) ) {
178
  $this->nTemplateEngine = self::TEMPLATE_ENGINE_PHP;
179
  }
180
  return $this->nTemplateEngine;
219
  */
220
  public function getTemplateRoots() {
221
  if ( !is_array( $this->aTemplateRoots ) ) {
222
+ $this->aTemplateRoots = [];
223
  }
224
  array_unshift( $this->aTemplateRoots, $this->getTemplateRootMain() );
225
  return array_unique( array_filter( $this->aTemplateRoots ) );
src/common/icwp-request.php CHANGED
@@ -150,10 +150,10 @@ class ICWP_WPSF_Request extends ICWP_WPSF_Foundation {
150
  public function getUriParts() {
151
  if ( !isset( $this->aRequestUriParts ) ) {
152
  $aExploded = explode( '?', $this->getUri(), 2 );
153
- $this->aRequestUriParts = array(
154
  'path' => empty( $aExploded[ 0 ] ) ? '' : $aExploded[ 0 ],
155
  'query' => empty( $aExploded[ 1 ] ) ? '' : $aExploded[ 1 ],
156
- );
157
  }
158
  return $this->aRequestUriParts;
159
  }
@@ -300,8 +300,8 @@ class ICWP_WPSF_Request extends ICWP_WPSF_Foundation {
300
 
301
  /**
302
  * alias
303
- * @deprecated
304
  * @return int
 
305
  */
306
  public function time() {
307
  return $this->ts();
150
  public function getUriParts() {
151
  if ( !isset( $this->aRequestUriParts ) ) {
152
  $aExploded = explode( '?', $this->getUri(), 2 );
153
+ $this->aRequestUriParts = [
154
  'path' => empty( $aExploded[ 0 ] ) ? '' : $aExploded[ 0 ],
155
  'query' => empty( $aExploded[ 1 ] ) ? '' : $aExploded[ 1 ],
156
+ ];
157
  }
158
  return $this->aRequestUriParts;
159
  }
300
 
301
  /**
302
  * alias
 
303
  * @return int
304
+ * @deprecated
305
  */
306
  public function time() {
307
  return $this->ts();
src/common/icwp-serviceproviders.php CHANGED
@@ -39,10 +39,10 @@ class ICWP_WPSF_ServiceProviders extends ICWP_WPSF_Foundation {
39
  $sStoreKey = $this->prefix( 'serviceips_cloudflare' );
40
  $aIps = $oWp->getTransient( $sStoreKey );
41
  if ( empty( $aIps ) ) {
42
- $aIps = array(
43
  4 => $this->downloadServiceIps_Cloudflare( 4 ),
44
  6 => $this->downloadServiceIps_Cloudflare( 6 )
45
- );
46
  $oWp->setTransient( $sStoreKey, $aIps, WEEK_IN_SECONDS*4 );
47
  }
48
  return $aIps;
@@ -68,7 +68,7 @@ class ICWP_WPSF_ServiceProviders extends ICWP_WPSF_Foundation {
68
  * @return string[]
69
  */
70
  public function getIps_DuckDuckGo() {
71
- return array( '107.20.237.51', '23.21.226.191', '107.21.1.8', '54.208.102.37' );
72
  }
73
 
74
  /**
@@ -112,10 +112,10 @@ class ICWP_WPSF_ServiceProviders extends ICWP_WPSF_Foundation {
112
  $sStoreKey = $this->prefix( 'serviceips_pingdom' );
113
  $aIps = $oWp->getTransient( $sStoreKey );
114
  if ( empty( $aIps ) ) {
115
- $aIps = array(
116
  4 => $this->downloadServiceIps_Pingdom( 4 ),
117
  6 => $this->downloadServiceIps_Pingdom( 6 )
118
- );
119
  $oWp->setTransient( $sStoreKey, $aIps, WEEK_IN_SECONDS*4 );
120
  }
121
  return $aIps;
@@ -145,10 +145,10 @@ class ICWP_WPSF_ServiceProviders extends ICWP_WPSF_Foundation {
145
  $sStoreKey = $this->prefix( 'serviceips_uptimerobot' );
146
  $aIps = $oWp->getTransient( $sStoreKey );
147
  if ( empty( $aIps ) ) {
148
- $aIps = array(
149
  4 => $this->downloadServiceIps_UptimeRobot( 4 ),
150
  6 => $this->downloadServiceIps_UptimeRobot( 6 )
151
- );
152
  $oWp->setTransient( $sStoreKey, $aIps, WEEK_IN_SECONDS*4 );
153
  }
154
  return $aIps;
@@ -165,7 +165,7 @@ class ICWP_WPSF_ServiceProviders extends ICWP_WPSF_Foundation {
165
  $sStoreKey = $this->prefix( 'serviceips_applebot' );
166
  $aIps = $oWp->getTransient( $sStoreKey );
167
  if ( !is_array( $aIps ) ) {
168
- $aIps = array();
169
  }
170
 
171
  if ( !in_array( $sIp, $aIps ) && $this->verifyIp_AppleBot( $sIp, $sUserAgent ) ) {
@@ -187,7 +187,7 @@ class ICWP_WPSF_ServiceProviders extends ICWP_WPSF_Foundation {
187
  $sStoreKey = $this->prefix( 'serviceips_baidubot' );
188
  $aIps = $oWp->getTransient( $sStoreKey );
189
  if ( !is_array( $aIps ) ) {
190
- $aIps = array();
191
  }
192
 
193
  if ( !in_array( $sIp, $aIps ) && $this->verifyIp_BaiduBot( $sIp, $sUserAgent ) ) {
@@ -204,12 +204,12 @@ class ICWP_WPSF_ServiceProviders extends ICWP_WPSF_Foundation {
204
  * @return bool
205
  */
206
  public function isIp_BingBot( $sIp, $sUserAgent ) {
207
- $oWp = $this->loadWp();
208
 
209
  $sStoreKey = $this->prefix( 'serviceips_bingbot' );
210
  $aIps = $oWp->getTransient( $sStoreKey );
211
  if ( !is_array( $aIps ) ) {
212
- $aIps = array();
213
  }
214
 
215
  if ( !in_array( $sIp, $aIps ) && $this->verifyIp_BingBot( $sIp, $sUserAgent ) ) {
@@ -280,7 +280,7 @@ class ICWP_WPSF_ServiceProviders extends ICWP_WPSF_Foundation {
280
  $sStoreKey = $this->prefix( 'serviceips_googlebot' );
281
  $aIps = $oWp->getTransient( $sStoreKey );
282
  if ( !is_array( $aIps ) ) {
283
- $aIps = array();
284
  }
285
 
286
  if ( !in_array( $sIp, $aIps ) && $this->verifyIp_GoogleBot( $sIp, $sUserAgent ) ) {
@@ -345,7 +345,7 @@ class ICWP_WPSF_ServiceProviders extends ICWP_WPSF_Foundation {
345
  $sStoreKey = $this->prefix( 'serviceips_yandexbot' );
346
  $aIps = $oWp->getTransient( $sStoreKey );
347
  if ( !is_array( $aIps ) ) {
348
- $aIps = array();
349
  }
350
 
351
  if ( !in_array( $sIp, $aIps ) && $this->verifyIp_YandexBot( $sIp, $sUserAgent ) ) {
@@ -368,7 +368,7 @@ class ICWP_WPSF_ServiceProviders extends ICWP_WPSF_Foundation {
368
  $sStoreKey = $this->prefix( 'serviceips_yahoobot' );
369
  $aIps = $oWp->getTransient( $sStoreKey );
370
  if ( !is_array( $aIps ) ) {
371
- $aIps = array();
372
  }
373
 
374
  if ( !in_array( $sIp, $aIps ) && $this->verifyIp_YahooBot( $sIp, $sUserAgent ) ) {
@@ -507,7 +507,7 @@ class ICWP_WPSF_ServiceProviders extends ICWP_WPSF_Foundation {
507
  * @return string[]
508
  */
509
  private function downloadServiceIps_StatusCake() {
510
- $aIps = array();
511
  $aData = @json_decode( Services::HttpRequest()->getContent( self::URL_STATUS_CAKE_IPS ), true );
512
  if ( is_array( $aData ) ) {
513
  foreach ( $aData as $aItem ) {
@@ -534,13 +534,13 @@ class ICWP_WPSF_ServiceProviders extends ICWP_WPSF_Foundation {
534
  */
535
  private function downloadServiceIps_Standard( $sSourceUrl, $sIpVersion = null ) {
536
  if ( !is_null( $sIpVersion ) ) {
537
- if ( !in_array( (int)$sIpVersion, array( 4, 6 ) ) ) {
538
  $sIpVersion = 4;
539
  }
540
  $sSourceUrl = Services::HttpRequest()->getContent( sprintf( $sSourceUrl, $sIpVersion ) );
541
  }
542
  $sRaw = Services::HttpRequest()->getContent( $sSourceUrl );
543
- $aIps = empty( $sRaw ) ? array() : explode( "\n", $sRaw );
544
  return array_filter( array_map( 'trim', $aIps ) );
545
  }
546
  }
39
  $sStoreKey = $this->prefix( 'serviceips_cloudflare' );
40
  $aIps = $oWp->getTransient( $sStoreKey );
41
  if ( empty( $aIps ) ) {
42
+ $aIps = [
43
  4 => $this->downloadServiceIps_Cloudflare( 4 ),
44
  6 => $this->downloadServiceIps_Cloudflare( 6 )
45
+ ];
46
  $oWp->setTransient( $sStoreKey, $aIps, WEEK_IN_SECONDS*4 );
47
  }
48
  return $aIps;
68
  * @return string[]
69
  */
70
  public function getIps_DuckDuckGo() {
71
+ return [ '107.20.237.51', '23.21.226.191', '107.21.1.8', '54.208.102.37' ];
72
  }
73
 
74
  /**
112
  $sStoreKey = $this->prefix( 'serviceips_pingdom' );
113
  $aIps = $oWp->getTransient( $sStoreKey );
114
  if ( empty( $aIps ) ) {
115
+ $aIps = [
116
  4 => $this->downloadServiceIps_Pingdom( 4 ),
117
  6 => $this->downloadServiceIps_Pingdom( 6 )
118
+ ];
119
  $oWp->setTransient( $sStoreKey, $aIps, WEEK_IN_SECONDS*4 );
120
  }
121
  return $aIps;
145
  $sStoreKey = $this->prefix( 'serviceips_uptimerobot' );
146
  $aIps = $oWp->getTransient( $sStoreKey );
147
  if ( empty( $aIps ) ) {
148
+ $aIps = [
149
  4 => $this->downloadServiceIps_UptimeRobot( 4 ),
150
  6 => $this->downloadServiceIps_UptimeRobot( 6 )
151
+ ];
152
  $oWp->setTransient( $sStoreKey, $aIps, WEEK_IN_SECONDS*4 );
153
  }
154
  return $aIps;
165
  $sStoreKey = $this->prefix( 'serviceips_applebot' );
166
  $aIps = $oWp->getTransient( $sStoreKey );
167
  if ( !is_array( $aIps ) ) {
168
+ $aIps = [];
169
  }
170
 
171
  if ( !in_array( $sIp, $aIps ) && $this->verifyIp_AppleBot( $sIp, $sUserAgent ) ) {
187
  $sStoreKey = $this->prefix( 'serviceips_baidubot' );
188
  $aIps = $oWp->getTransient( $sStoreKey );
189
  if ( !is_array( $aIps ) ) {
190
+ $aIps = [];
191
  }
192
 
193
  if ( !in_array( $sIp, $aIps ) && $this->verifyIp_BaiduBot( $sIp, $sUserAgent ) ) {
204
  * @return bool
205
  */
206
  public function isIp_BingBot( $sIp, $sUserAgent ) {
207
+ $oWp = Services::WpGeneral();
208
 
209
  $sStoreKey = $this->prefix( 'serviceips_bingbot' );
210
  $aIps = $oWp->getTransient( $sStoreKey );
211
  if ( !is_array( $aIps ) ) {
212
+ $aIps = [];
213
  }
214
 
215
  if ( !in_array( $sIp, $aIps ) && $this->verifyIp_BingBot( $sIp, $sUserAgent ) ) {
280
  $sStoreKey = $this->prefix( 'serviceips_googlebot' );
281
  $aIps = $oWp->getTransient( $sStoreKey );
282
  if ( !is_array( $aIps ) ) {
283
+ $aIps = [];
284
  }
285
 
286
  if ( !in_array( $sIp, $aIps ) && $this->verifyIp_GoogleBot( $sIp, $sUserAgent ) ) {
345
  $sStoreKey = $this->prefix( 'serviceips_yandexbot' );
346
  $aIps = $oWp->getTransient( $sStoreKey );
347
  if ( !is_array( $aIps ) ) {
348
+ $aIps = [];
349
  }
350
 
351
  if ( !in_array( $sIp, $aIps ) && $this->verifyIp_YandexBot( $sIp, $sUserAgent ) ) {
368
  $sStoreKey = $this->prefix( 'serviceips_yahoobot' );
369
  $aIps = $oWp->getTransient( $sStoreKey );
370
  if ( !is_array( $aIps ) ) {
371
+ $aIps = [];
372
  }
373
 
374
  if ( !in_array( $sIp, $aIps ) && $this->verifyIp_YahooBot( $sIp, $sUserAgent ) ) {
507
  * @return string[]
508
  */
509
  private function downloadServiceIps_StatusCake() {
510
+ $aIps = [];
511
  $aData = @json_decode( Services::HttpRequest()->getContent( self::URL_STATUS_CAKE_IPS ), true );
512
  if ( is_array( $aData ) ) {
513
  foreach ( $aData as $aItem ) {
534
  */
535
  private function downloadServiceIps_Standard( $sSourceUrl, $sIpVersion = null ) {
536
  if ( !is_null( $sIpVersion ) ) {
537
+ if ( !in_array( (int)$sIpVersion, [ 4, 6 ] ) ) {
538
  $sIpVersion = 4;
539
  }
540
  $sSourceUrl = Services::HttpRequest()->getContent( sprintf( $sSourceUrl, $sIpVersion ) );
541
  }
542
  $sRaw = Services::HttpRequest()->getContent( $sSourceUrl );
543
+ $aIps = empty( $sRaw ) ? [] : explode( "\n", $sRaw );
544
  return array_filter( array_map( 'trim', $aIps ) );
545
  }
546
  }
src/common/icwp-ssl.php CHANGED
@@ -15,7 +15,7 @@ class ICWP_WPSF_Ssl extends ICWP_WPSF_Foundation {
15
  protected static $oInstance = null;
16
 
17
  private function __construct() {
18
- $this->aCache = array();
19
  }
20
 
21
  /**
@@ -32,12 +32,12 @@ class ICWP_WPSF_Ssl extends ICWP_WPSF_Foundation {
32
  * @return bool
33
  */
34
  public function isEnvSupported() {
35
- $aFunctions = array(
36
  'stream_context_create',
37
  'stream_socket_client',
38
  'stream_context_get_params',
39
  'openssl_x509_parse',
40
- );
41
 
42
  $bFunctionsAvailable = true;
43
  foreach ( $aFunctions as $sFunction ) {
@@ -65,13 +65,13 @@ class ICWP_WPSF_Ssl extends ICWP_WPSF_Foundation {
65
  if ( empty( $this->aCache[ $sHost ] ) ) {
66
 
67
  $oContext = stream_context_create(
68
- array(
69
- 'ssl' => array(
70
  'capture_peer_cert' => true,
71
  'verify_peer' => true,
72
  'verify_peer_name' => true,
73
- )
74
- )
75
  );
76
 
77
  $rSocketClient = @stream_socket_client(
15
  protected static $oInstance = null;
16
 
17
  private function __construct() {
18
+ $this->aCache = [];
19
  }
20
 
21
  /**
32
  * @return bool
33
  */
34
  public function isEnvSupported() {
35
+ $aFunctions = [
36
  'stream_context_create',
37
  'stream_socket_client',
38
  'stream_context_get_params',
39
  'openssl_x509_parse',
40
+ ];
41
 
42
  $bFunctionsAvailable = true;
43
  foreach ( $aFunctions as $sFunction ) {
65
  if ( empty( $this->aCache[ $sHost ] ) ) {
66
 
67
  $oContext = stream_context_create(
68
+ [
69
+ 'ssl' => [
70
  'capture_peer_cert' => true,
71
  'verify_peer' => true,
72
  'verify_peer_name' => true,
73
+ ]
74
+ ]
75
  );
76
 
77
  $rSocketClient = @stream_socket_client(
src/common/icwp-usermeta.php DELETED
@@ -1,118 +0,0 @@
1
- <?php
2
-
3
- use FernleafSystems\Wordpress\Services\Services;
4
-
5
- /**
6
- * @property string $email_secret
7
- * @property bool $email_validated
8
- * @property string $backupcode_secret
9
- * @property string $backupcode_validated
10
- * @property string $ga_secret
11
- * @property bool $ga_validated
12
- * @property array $hash_loginmfa
13
- * @property string $pass_hash
14
- * @property int $pass_started_at
15
- * @property int $pass_reset_last_redirect_at
16
- * @property int $pass_check_failed_at
17
- * @property string $yubi_secret
18
- * @property bool $yubi_validated
19
- * @property int $last_login_at
20
- * @property string $prefix
21
- * @property int $user_id
22
- * @property bool $wc_social_login_valid
23
- * @property string $flash_msg
24
- * Class ICWP_UserMeta
25
- */
26
- class ICWP_UserMeta extends ICWP_WPSF_Foundation {
27
-
28
- /**
29
- * @var array
30
- */
31
- protected $aData;
32
-
33
- /**
34
- * @param string $sPrefix
35
- * @param int $nUserId
36
- */
37
- public function __construct( $sPrefix, $nUserId = 0 ) {
38
- $this->load( $sPrefix, $nUserId );
39
- add_action( 'shutdown', array( $this, 'save' ) );
40
- }
41
-
42
- /**
43
- * Cannot use Data store (__get()) yet
44
- * @param int $sPrefix
45
- * @param int $nUserId
46
- * @return $this
47
- */
48
- private function load( $sPrefix, $nUserId ) {
49
- $aStore = $this->loadWpUsers()->getUserMeta( $sPrefix.'-meta', $nUserId );
50
- if ( !is_array( $aStore ) ) {
51
- $aStore = array();
52
- }
53
- $this->aData = $aStore;
54
- $this->prefix = $sPrefix;
55
- $this->user_id = $nUserId;
56
- return $this;
57
- }
58
-
59
- /**
60
- * @return $this
61
- */
62
- public function delete() {
63
- if ( $this->user_id > 0 ) {
64
- $this->loadWpUsers()->deleteUserMeta( $this->getStorageKey(), $this->user_id );
65
- }
66
- return $this;
67
- }
68
-
69
- /**
70
- * @return $this
71
- */
72
- public function save() {
73
- if ( $this->user_id > 0 ) {
74
- $this->loadWpUsers()->updateUserMeta( $this->getStorageKey(), $this->aData, $this->user_id );
75
- }
76
- return $this;
77
- }
78
-
79
- /**
80
- * @param string $sKey
81
- * @return mixed|null
82
- */
83
- public function __get( $sKey ) {
84
- return isset( $this->aData[ $sKey ] ) ? $this->aData[ $sKey ] : null;
85
- }
86
-
87
- /**
88
- * @param string $sKey
89
- * @return bool
90
- */
91
- public function __isset( $sKey ) {
92
- return isset( $this->aData[ $sKey ] );
93
- }
94
-
95
- /**
96
- * @param string $sKey
97
- * @param $mValue
98
- */
99
- public function __set( $sKey, $mValue ) {
100
- $this->aData[ $sKey ] = $mValue;
101
- $this->save();
102
- }
103
-
104
- /**
105
- * @param string $sKey
106
- */
107
- public function __unset( $sKey ) {
108
- unset( $this->aData[ $sKey ] );
109
- $this->save();
110
- }
111
-
112
- /**
113
- * @return string
114
- */
115
- private function getStorageKey() {
116
- return $this->prefix.'-meta';
117
- }
118
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/common/icwp-wpcron.php CHANGED
@@ -33,7 +33,7 @@ class ICWP_WPSF_WpCron {
33
  }
34
 
35
  private function __construct() {
36
- add_filter( 'cron_schedules', array( $this, 'addSchedules' ) );
37
  }
38
 
39
  /**
@@ -59,11 +59,11 @@ class ICWP_WPSF_WpCron {
59
  }
60
 
61
  /**
62
- * @deprecated uses undocumented private WP function
63
  * @return array
 
64
  */
65
  public function getCrons() {
66
- return function_exists( '_get_cron_array' ) && is_array( _get_cron_array() ) ? _get_cron_array() : array();
67
  }
68
 
69
  /**
@@ -71,7 +71,7 @@ class ICWP_WPSF_WpCron {
71
  */
72
  protected function getSchedules() {
73
  if ( !is_array( $this->aSchedules ) ) {
74
- $this->aSchedules = array();
75
  }
76
  return $this->aSchedules;
77
  }
33
  }
34
 
35
  private function __construct() {
36
+ add_filter( 'cron_schedules', [ $this, 'addSchedules' ] );
37
  }
38
 
39
  /**
59
  }
60
 
61
  /**
 
62
  * @return array
63
+ * @deprecated uses undocumented private WP function
64
  */
65
  public function getCrons() {
66
+ return function_exists( '_get_cron_array' ) && is_array( _get_cron_array() ) ? _get_cron_array() : [];
67
  }
68
 
69
  /**
71
  */
72
  protected function getSchedules() {
73
  if ( !is_array( $this->aSchedules ) ) {
74
+ $this->aSchedules = [];
75
  }
76
  return $this->aSchedules;
77
  }
src/common/icwp-wpfilesystem.php CHANGED
@@ -106,7 +106,7 @@ class ICWP_WPSF_WpFilesystem {
106
  * @return SplFileInfo[]
107
  */
108
  public function getFilesInDir( $sDir, $nMaxDepth = 1, $oDirIterator = null ) {
109
- $aList = array();
110
 
111
  try {
112
  if ( empty( $oDirIterator ) ) {
@@ -185,7 +185,7 @@ class ICWP_WPSF_WpFilesystem {
185
  * @param bool $bAlwaysRawResponse
186
  * @return array|WP_Error|bool
187
  */
188
- public function requestUrl( $sUrl, $aRequestArgs = array(), $bAlwaysRawResponse = false ) {
189
 
190
  $mResult = wp_remote_request( $sUrl, $aRequestArgs );
191
  if ( $bAlwaysRawResponse ) {
@@ -202,7 +202,7 @@ class ICWP_WPSF_WpFilesystem {
202
  * @param array $aRequestArgs
203
  * @return array|bool
204
  */
205
- public function getUrl( $sUrl, $aRequestArgs = array() ) {
206
  $aRequestArgs[ 'method' ] = 'GET';
207
  return $this->requestUrl( $sUrl, $aRequestArgs );
208
  }
@@ -212,7 +212,7 @@ class ICWP_WPSF_WpFilesystem {
212
  * @param array $aRequestArgs
213
  * @return false|string
214
  */
215
- public function getUrlContent( $sUrl, $aRequestArgs = array() ) {
216
  $aResponse = $this->getUrl( $sUrl, $aRequestArgs );
217
  if ( !$aResponse || !isset( $aResponse[ 'body' ] ) ) {
218
  return false;
@@ -221,22 +221,22 @@ class ICWP_WPSF_WpFilesystem {
221
  }
222
 
223
  /**
224
- * @deprecated
225
  * @param string $sUrl
226
  * @param array $aRequestArgs
227
  * @return array|false
 
228
  */
229
- public function postUrl( $sUrl, $aRequestArgs = array() ) {
230
  $aRequestArgs[ 'method' ] = 'POST';
231
  return $this->requestUrl( $sUrl, $aRequestArgs );
232
  }
233
 
234
  public function getCanWpRemoteGet() {
235
- $aUrlsToTest = array(
236
  'https://www.microsoft.com',
237
  'https://www.google.com',
238
  'https://www.facebook.com'
239
- );
240
  foreach ( $aUrlsToTest as $sUrl ) {
241
  if ( $this->getUrl( $sUrl ) !== false ) {
242
  return true;
106
  * @return SplFileInfo[]
107
  */
108
  public function getFilesInDir( $sDir, $nMaxDepth = 1, $oDirIterator = null ) {
109
+ $aList = [];
110
 
111
  try {
112
  if ( empty( $oDirIterator ) ) {
185
  * @param bool $bAlwaysRawResponse
186
  * @return array|WP_Error|bool
187
  */
188
+ public function requestUrl( $sUrl, $aRequestArgs = [], $bAlwaysRawResponse = false ) {
189
 
190
  $mResult = wp_remote_request( $sUrl, $aRequestArgs );
191
  if ( $bAlwaysRawResponse ) {
202
  * @param array $aRequestArgs
203
  * @return array|bool
204
  */
205
+ public function getUrl( $sUrl, $aRequestArgs = [] ) {
206
  $aRequestArgs[ 'method' ] = 'GET';
207
  return $this->requestUrl( $sUrl, $aRequestArgs );
208
  }
212
  * @param array $aRequestArgs
213
  * @return false|string
214
  */
215
+ public function getUrlContent( $sUrl, $aRequestArgs = [] ) {
216
  $aResponse = $this->getUrl( $sUrl, $aRequestArgs );
217
  if ( !$aResponse || !isset( $aResponse[ 'body' ] ) ) {
218
  return false;
221
  }
222
 
223
  /**
 
224
  * @param string $sUrl
225
  * @param array $aRequestArgs
226
  * @return array|false
227
+ * @deprecated
228
  */
229
+ public function postUrl( $sUrl, $aRequestArgs = [] ) {
230
  $aRequestArgs[ 'method' ] = 'POST';
231
  return $this->requestUrl( $sUrl, $aRequestArgs );
232
  }
233
 
234
  public function getCanWpRemoteGet() {
235
+ $aUrlsToTest = [
236
  'https://www.microsoft.com',
237
  'https://www.google.com',
238
  'https://www.facebook.com'
239
+ ];
240
  foreach ( $aUrlsToTest as $sUrl ) {
241
  if ( $this->getUrl( $sUrl ) !== false ) {
242
  return true;
src/common/icwp-wpfunctions-plugins.php CHANGED
@@ -87,11 +87,11 @@ class ICWP_WPSF_WpFunctions_Plugins extends ICWP_WPSF_Foundation {
87
  public function install( $sUrlToInstall, $bOverwrite = true, $bMaintenanceMode = false ) {
88
  $this->loadWpUpgrades();
89
 
90
- $aResult = array(
91
  'successful' => true,
92
  'plugin_info' => '',
93
- 'errors' => array()
94
- );
95
 
96
  $oUpgraderSkin = new ICWP_Upgrader_Skin();
97
  $oUpgrader = new ICWP_Plugin_Upgrader( $oUpgraderSkin );
@@ -128,12 +128,12 @@ class ICWP_WPSF_WpFunctions_Plugins extends ICWP_WPSF_Foundation {
128
  public function installFromWpOrg( $sSlug ) {
129
  include_once( ABSPATH.'wp-admin/includes/plugin-install.php' );
130
 
131
- $api = plugins_api( 'plugin_information', array(
132
  'slug' => $sSlug,
133
- 'fields' => array(
134
  'sections' => false,
135
- ),
136
- ) );
137
 
138
  if ( !is_wp_error( $api ) ) {
139
  return $this->install( $api->download_link, true, true );
@@ -187,15 +187,15 @@ class ICWP_WPSF_WpFunctions_Plugins extends ICWP_WPSF_Foundation {
187
  public function update( $sFile ) {
188
  $this->loadWpUpgrades();
189
 
190
- $aResult = array(
191
  'successful' => 1,
192
- 'errors' => array()
193
- );
194
 
195
  $oUpgraderSkin = new ICWP_Bulk_Plugin_Upgrader_Skin();
196
  $oUpgrader = new Plugin_Upgrader( $oUpgraderSkin );
197
  ob_start();
198
- $oUpgrader->bulk_upgrade( array( $sFile ) );
199
  ob_end_clean();
200
 
201
  if ( isset( $oUpgraderSkin->m_aErrors[ 0 ] ) ) {
@@ -274,12 +274,7 @@ class ICWP_WPSF_WpFunctions_Plugins extends ICWP_WPSF_Foundation {
274
  * @return array|null
275
  */
276
  public function getPlugin( $sPluginFile ) {
277
- $aPlugin = null;
278
- if ( $this->isInstalled( $sPluginFile ) ) {
279
- $aPlugins = $this->getPlugins();
280
- $aPlugin = $aPlugins[ $sPluginFile ];
281
- }
282
- return $aPlugin;
283
  }
284
 
285
  /**
@@ -323,7 +318,7 @@ class ICWP_WPSF_WpFunctions_Plugins extends ICWP_WPSF_Foundation {
323
  public function getActivePlugins() {
324
  $oWp = $this->loadWp();
325
  $aActive = $oWp->getOption( ( $oWp->isMultisite() ? 'active_sitewide_plugins' : 'active_plugins' ) );
326
- return is_array( $aActive ) ? $aActive : array();
327
  }
328
 
329
  /**
@@ -340,8 +335,8 @@ class ICWP_WPSF_WpFunctions_Plugins extends ICWP_WPSF_Foundation {
340
  if ( !function_exists( 'get_plugins' ) ) {
341
  require_once( ABSPATH.'wp-admin/includes/plugin.php' );
342
  }
343
- $aP = function_exists( 'get_plugins' ) ? get_plugins() : array();
344
- return is_array( $aP ) ? $aP : array();
345
  }
346
 
347
  /**
@@ -350,8 +345,8 @@ class ICWP_WPSF_WpFunctions_Plugins extends ICWP_WPSF_Foundation {
350
  public function getAllExtendedData() {
351
  $oData = $this->loadWp()->getTransient( 'update_plugins' );
352
  return array_merge(
353
- isset( $oData->no_update ) ? $oData->no_update : array(),
354
- isset( $oData->response ) ? $oData->response : array()
355
  );
356
  }
357
 
@@ -368,7 +363,7 @@ class ICWP_WPSF_WpFunctions_Plugins extends ICWP_WPSF_Foundation {
368
  * @return array
369
  */
370
  public function getAllSlugs() {
371
- $aSlugs = array();
372
 
373
  foreach ( $this->getAllExtendedData() as $sBaseName => $oPlugData ) {
374
  if ( isset( $oPlugData->slug ) ) {
@@ -416,7 +411,7 @@ class ICWP_WPSF_WpFunctions_Plugins extends ICWP_WPSF_Foundation {
416
  $this->checkForUpdates();
417
  }
418
  $aUpdates = $this->loadWp()->getWordpressUpdates( 'plugins' );
419
- return is_array( $aUpdates ) ? $aUpdates : array();
420
  }
421
 
422
  /**
@@ -440,11 +435,11 @@ class ICWP_WPSF_WpFunctions_Plugins extends ICWP_WPSF_Foundation {
440
  * @return string
441
  */
442
  public function getUrl_Upgrade( $sPluginFile ) {
443
- $aQueryArgs = array(
444
  'action' => 'upgrade-plugin',
445
  'plugin' => urlencode( $sPluginFile ),
446
  '_wpnonce' => wp_create_nonce( 'upgrade-plugin_'.$sPluginFile )
447
- );
448
  return add_query_arg( $aQueryArgs, self_admin_url( 'update.php' ) );
449
  }
450
 
@@ -455,11 +450,11 @@ class ICWP_WPSF_WpFunctions_Plugins extends ICWP_WPSF_Foundation {
455
  */
456
  protected function getUrl_Action( $sPluginFile, $sAction ) {
457
  return add_query_arg(
458
- array(
459
  'action' => $sAction,
460
  'plugin' => urlencode( $sPluginFile ),
461
  '_wpnonce' => wp_create_nonce( $sAction.'-plugin_'.$sPluginFile )
462
- ),
463
  self_admin_url( 'plugins.php' )
464
  );
465
  }
@@ -534,17 +529,17 @@ class ICWP_WPSF_WpFunctions_Plugins extends ICWP_WPSF_Foundation {
534
  }
535
 
536
  /**
537
- * @deprecated
538
  * @param string $sPluginFile
539
  * @return string
 
540
  */
541
  public function getLinkPluginUpgrade( $sPluginFile ) {
542
  return $this->getUrl_Upgrade( $sPluginFile );
543
  }
544
 
545
  /**
546
- * @deprecated
547
  * @return array
 
548
  */
549
  public function getInstalledPluginFiles() {
550
  return $this->getInstalledBaseFiles();
87
  public function install( $sUrlToInstall, $bOverwrite = true, $bMaintenanceMode = false ) {
88
  $this->loadWpUpgrades();
89
 
90
+ $aResult = [
91
  'successful' => true,
92
  'plugin_info' => '',
93
+ 'errors' => []
94
+ ];
95
 
96
  $oUpgraderSkin = new ICWP_Upgrader_Skin();
97
  $oUpgrader = new ICWP_Plugin_Upgrader( $oUpgraderSkin );
128
  public function installFromWpOrg( $sSlug ) {
129
  include_once( ABSPATH.'wp-admin/includes/plugin-install.php' );
130
 
131
+ $api = plugins_api( 'plugin_information', [
132
  'slug' => $sSlug,
133
+ 'fields' => [
134
  'sections' => false,
135
+ ],
136
+ ] );
137
 
138
  if ( !is_wp_error( $api ) ) {
139
  return $this->install( $api->download_link, true, true );
187
  public function update( $sFile ) {
188
  $this->loadWpUpgrades();
189
 
190
+ $aResult = [
191
  'successful' => 1,
192
+ 'errors' => []
193
+ ];
194
 
195
  $oUpgraderSkin = new ICWP_Bulk_Plugin_Upgrader_Skin();
196
  $oUpgrader = new Plugin_Upgrader( $oUpgraderSkin );
197
  ob_start();
198
+ $oUpgrader->bulk_upgrade( [ $sFile ] );
199
  ob_end_clean();
200
 
201
  if ( isset( $oUpgraderSkin->m_aErrors[ 0 ] ) ) {
274
  * @return array|null
275
  */
276
  public function getPlugin( $sPluginFile ) {
277
+ return $this->isInstalled( $sPluginFile ) ? $this->getPlugins()[ $sPluginFile ] : null;
 
 
 
 
 
278
  }
279
 
280
  /**
318
  public function getActivePlugins() {
319
  $oWp = $this->loadWp();
320
  $aActive = $oWp->getOption( ( $oWp->isMultisite() ? 'active_sitewide_plugins' : 'active_plugins' ) );
321
+ return is_array( $aActive ) ? $aActive : [];
322
  }
323
 
324
  /**
335
  if ( !function_exists( 'get_plugins' ) ) {
336
  require_once( ABSPATH.'wp-admin/includes/plugin.php' );
337
  }
338
+ $aP = function_exists( 'get_plugins' ) ? get_plugins() : [];
339
+ return is_array( $aP ) ? $aP : [];
340
  }
341
 
342
  /**
345
  public function getAllExtendedData() {
346
  $oData = $this->loadWp()->getTransient( 'update_plugins' );
347
  return array_merge(
348
+ isset( $oData->no_update ) ? $oData->no_update : [],
349
+ isset( $oData->response ) ? $oData->response : []
350
  );
351
  }
352
 
363
  * @return array
364
  */
365
  public function getAllSlugs() {
366
+ $aSlugs = [];
367
 
368
  foreach ( $this->getAllExtendedData() as $sBaseName => $oPlugData ) {
369
  if ( isset( $oPlugData->slug ) ) {
411
  $this->checkForUpdates();
412
  }
413
  $aUpdates = $this->loadWp()->getWordpressUpdates( 'plugins' );
414
+ return is_array( $aUpdates ) ? $aUpdates : [];
415
  }
416
 
417
  /**
435
  * @return string
436
  */
437
  public function getUrl_Upgrade( $sPluginFile ) {
438
+ $aQueryArgs = [
439
  'action' => 'upgrade-plugin',
440
  'plugin' => urlencode( $sPluginFile ),
441
  '_wpnonce' => wp_create_nonce( 'upgrade-plugin_'.$sPluginFile )
442
+ ];
443
  return add_query_arg( $aQueryArgs, self_admin_url( 'update.php' ) );
444
  }
445
 
450
  */
451
  protected function getUrl_Action( $sPluginFile, $sAction ) {
452
  return add_query_arg(
453
+ [
454
  'action' => $sAction,
455
  'plugin' => urlencode( $sPluginFile ),
456
  '_wpnonce' => wp_create_nonce( $sAction.'-plugin_'.$sPluginFile )
457
+ ],
458
  self_admin_url( 'plugins.php' )
459
  );
460
  }
529
  }
530
 
531
  /**
 
532
  * @param string $sPluginFile
533
  * @return string
534
+ * @deprecated
535
  */
536
  public function getLinkPluginUpgrade( $sPluginFile ) {
537
  return $this->getUrl_Upgrade( $sPluginFile );
538
  }
539
 
540
  /**
 
541
  * @return array
542
+ * @deprecated
543
  */
544
  public function getInstalledPluginFiles() {
545
  return $this->getInstalledBaseFiles();
src/common/icwp-wpfunctions-themes.php CHANGED
@@ -7,7 +7,8 @@ class ICWP_WPSF_WpFunctions_Themes extends ICWP_WPSF_Foundation {
7
  */
8
  protected static $oInstance = null;
9
 
10
- private function __construct() {}
 
11
 
12
  /**
13
  * @return ICWP_WPSF_WpFunctions_Themes
@@ -79,11 +80,11 @@ class ICWP_WPSF_WpFunctions_Themes extends ICWP_WPSF_Foundation {
79
  public function install( $sUrlToInstall, $bOverwrite = true, $bMaintenanceMode = false ) {
80
  $this->loadWpUpgrades();
81
 
82
- $aResult = array(
83
  'successful' => true,
84
  'plugin_info' => '',
85
- 'errors' => array()
86
- );
87
 
88
  $oUpgraderSkin = new ICWP_Upgrader_Skin();
89
  $oUpgrader = new ICWP_Theme_Upgrader( $oUpgraderSkin );
@@ -156,15 +157,15 @@ class ICWP_WPSF_WpFunctions_Themes extends ICWP_WPSF_Foundation {
156
  public function update( $sFile ) {
157
  $this->loadWpUpgrades();
158
 
159
- $aResult = array(
160
  'successful' => 1,
161
- 'errors' => array()
162
- );
163
 
164
  $oUpgraderSkin = new ICWP_Bulk_Theme_Upgrader_Skin();
165
  $oUpgrader = new Theme_Upgrader( $oUpgraderSkin );
166
  ob_start();
167
- $oUpgrader->bulk_upgrade( array( $sFile ) );
168
  ob_end_clean();
169
 
170
  if ( isset( $oUpgraderSkin->m_aErrors[ 0 ] ) ) {
@@ -181,7 +182,8 @@ class ICWP_WPSF_WpFunctions_Themes extends ICWP_WPSF_Foundation {
181
  * @return string|WP_Theme
182
  */
183
  public function getCurrentThemeName() {
184
- return $this->loadWp()->getWordpressIsAtLeastVersion( '3.4.0' ) ? $this->getCurrent()->get( 'Name' ) : get_current_theme();
 
185
  }
186
 
187
  /**
@@ -245,7 +247,7 @@ class ICWP_WPSF_WpFunctions_Themes extends ICWP_WPSF_Foundation {
245
  $this->checkForUpdates();
246
  }
247
  $aUpdates = $this->loadWp()->getWordpressUpdates( 'themes' );
248
- return is_array( $aUpdates ) ? $aUpdates : array();
249
  }
250
 
251
  /**
@@ -263,18 +265,18 @@ class ICWP_WPSF_WpFunctions_Themes extends ICWP_WPSF_Foundation {
263
  public function getExtendedData( $sBase ) {
264
  include_once( ABSPATH.'wp-admin/includes/theme.php' );
265
 
266
- $oApi = themes_api( 'theme_information', array(
267
  'slug' => $sBase,
268
- 'fields' => array(
269
  'sections' => false,
270
- ),
271
- ) );
272
  return $oApi;
273
  }
274
 
275
  /**
276
  * @param string $sSlug
277
- * @param bool $bCheckIsActiveParent
278
  * @return bool
279
  */
280
  public function isActive( $sSlug, $bCheckIsActiveParent = false ) {
@@ -358,6 +360,6 @@ class ICWP_WPSF_WpFunctions_Themes extends ICWP_WPSF_Foundation {
358
  * @return array
359
  */
360
  public function wpmsGetSiteAllowedThemes() {
361
- return ( function_exists( 'get_site_allowed_themes' ) ? get_site_allowed_themes() : array() );
362
  }
363
  }
7
  */
8
  protected static $oInstance = null;
9
 
10
+ private function __construct() {
11
+ }
12
 
13
  /**
14
  * @return ICWP_WPSF_WpFunctions_Themes
80
  public function install( $sUrlToInstall, $bOverwrite = true, $bMaintenanceMode = false ) {
81
  $this->loadWpUpgrades();
82
 
83
+ $aResult = [
84
  'successful' => true,
85
  'plugin_info' => '',
86
+ 'errors' => []
87
+ ];
88
 
89
  $oUpgraderSkin = new ICWP_Upgrader_Skin();
90
  $oUpgrader = new ICWP_Theme_Upgrader( $oUpgraderSkin );
157
  public function update( $sFile ) {
158
  $this->loadWpUpgrades();
159
 
160
+ $aResult = [
161
  'successful' => 1,
162
+ 'errors' => []
163
+ ];
164
 
165
  $oUpgraderSkin = new ICWP_Bulk_Theme_Upgrader_Skin();
166
  $oUpgrader = new Theme_Upgrader( $oUpgraderSkin );
167
  ob_start();
168
+ $oUpgrader->bulk_upgrade( [ $sFile ] );
169
  ob_end_clean();
170
 
171
  if ( isset( $oUpgraderSkin->m_aErrors[ 0 ] ) ) {
182
  * @return string|WP_Theme
183
  */
184
  public function getCurrentThemeName() {
185
+ return $this->loadWp()->getWordpressIsAtLeastVersion( '3.4.0' ) ? $this->getCurrent()
186
+ ->get( 'Name' ) : get_current_theme();
187
  }
188
 
189
  /**
247
  $this->checkForUpdates();
248
  }
249
  $aUpdates = $this->loadWp()->getWordpressUpdates( 'themes' );
250
+ return is_array( $aUpdates ) ? $aUpdates : [];
251
  }
252
 
253
  /**
265
  public function getExtendedData( $sBase ) {
266
  include_once( ABSPATH.'wp-admin/includes/theme.php' );
267
 
268
+ $oApi = themes_api( 'theme_information', [
269
  'slug' => $sBase,
270
+ 'fields' => [
271
  'sections' => false,
272
+ ],
273
+ ] );
274
  return $oApi;
275
  }
276
 
277
  /**
278
  * @param string $sSlug
279
+ * @param bool $bCheckIsActiveParent
280
  * @return bool
281
  */
282
  public function isActive( $sSlug, $bCheckIsActiveParent = false ) {
360
  * @return array
361
  */
362
  public function wpmsGetSiteAllowedThemes() {
363
+ return ( function_exists( 'get_site_allowed_themes' ) ? get_site_allowed_themes() : [] );
364
  }
365
  }
src/common/icwp-wpfunctions.php CHANGED
@@ -121,11 +121,11 @@ class ICWP_WPSF_WpFunctions extends ICWP_WPSF_Foundation {
121
  }
122
 
123
  /**
124
- * @see wp_redirect_admin_locations()
125
  * @return array
 
126
  */
127
  public function getAutoRedirectLocations() {
128
- return array( 'wp-admin', 'dashboard', 'admin', 'login', 'wp-login.php' );
129
  }
130
 
131
  /**
@@ -222,7 +222,7 @@ class ICWP_WPSF_WpFunctions extends ICWP_WPSF_Foundation {
222
  if ( !function_exists( 'wp_get_themes' ) ) {
223
  require_once( ABSPATH.'wp-admin/includes/theme.php' );
224
  }
225
- return function_exists( 'wp_get_themes' ) ? wp_get_themes() : array();
226
  }
227
 
228
  /**
@@ -231,7 +231,7 @@ class ICWP_WPSF_WpFunctions extends ICWP_WPSF_Foundation {
231
  */
232
  public function getWordpressUpdates( $sType = 'plugins' ) {
233
  $oCurrent = $this->getTransient( 'update_'.$sType );
234
- return ( isset( $oCurrent->response ) && is_array( $oCurrent->response ) ) ? $oCurrent->response : array();
235
  }
236
 
237
  /**
@@ -353,12 +353,12 @@ class ICWP_WPSF_WpFunctions extends ICWP_WPSF_Foundation {
353
  */
354
  public function canCoreUpdateAutomatically() {
355
  global $required_php_version, $required_mysql_version;
356
- $future_minor_update = (object)array(
357
  'current' => $this->getVersion().'.1.next.minor',
358
  'version' => $this->getVersion().'.1.next.minor',
359
  'php_version' => $required_php_version,
360
  'mysql_version' => $required_mysql_version,
361
- );
362
  return $this->getWpAutomaticUpdater()
363
  ->should_update( 'core', $future_minor_update, ABSPATH );
364
  }
@@ -379,21 +379,21 @@ class ICWP_WPSF_WpFunctions extends ICWP_WPSF_Foundation {
379
  /**
380
  * @param array $aQueryParams
381
  */
382
- public function redirectToLogin( $aQueryParams = array() ) {
383
  $this->doRedirect( wp_login_url(), $aQueryParams );
384
  }
385
 
386
  /**
387
  * @param array $aQueryParams
388
  */
389
- public function redirectToAdmin( $aQueryParams = array() ) {
390
  $this->doRedirect( is_multisite() ? get_admin_url() : admin_url(), $aQueryParams );
391
  }
392
 
393
  /**
394
  * @param array $aQueryParams
395
  */
396
- public function redirectToHome( $aQueryParams = array() ) {
397
  $this->doRedirect( home_url(), $aQueryParams );
398
  }
399
 
@@ -403,7 +403,7 @@ class ICWP_WPSF_WpFunctions extends ICWP_WPSF_Foundation {
403
  * @param bool $bSafe
404
  * @param bool $bProtectAgainstInfiniteLoops - if false, ignores the redirect loop protection
405
  */
406
- public function doRedirect( $sUrl, $aQueryParams = array(), $bSafe = true, $bProtectAgainstInfiniteLoops = true ) {
407
  $sUrl = empty( $aQueryParams ) ? $sUrl : add_query_arg( $aQueryParams, $sUrl );
408
 
409
  $oReq = $this->loadRequest();
@@ -511,9 +511,9 @@ class ICWP_WPSF_WpFunctions extends ICWP_WPSF_Foundation {
511
  if ( $sPage == 'admin.php' ) {
512
  $sSubPage = $this->loadRequest()->query( 'page' );
513
  if ( !empty( $sSubPage ) ) {
514
- $aQueryArgs = array(
515
  'page' => $sSubPage,
516
- );
517
  $sUrl = add_query_arg( $aQueryArgs, $sUrl );
518
  }
519
  }
@@ -673,8 +673,8 @@ class ICWP_WPSF_WpFunctions extends ICWP_WPSF_Foundation {
673
  * @return array
674
  */
675
  public function getAllUserLoginUsernames() {
676
- $aUsers = get_users( array( 'fields' => array( 'user_login' ) ) );
677
- $aLogins = array();
678
  foreach ( $aUsers as $oUser ) {
679
  $aLogins[] = $oUser->user_login;
680
  }
121
  }
122
 
123
  /**
 
124
  * @return array
125
+ * @see wp_redirect_admin_locations()
126
  */
127
  public function getAutoRedirectLocations() {
128
+ return [ 'wp-admin', 'dashboard', 'admin', 'login', 'wp-login.php' ];
129
  }
130
 
131
  /**
222
  if ( !function_exists( 'wp_get_themes' ) ) {
223
  require_once( ABSPATH.'wp-admin/includes/theme.php' );
224
  }
225
+ return function_exists( 'wp_get_themes' ) ? wp_get_themes() : [];
226
  }
227
 
228
  /**
231
  */
232
  public function getWordpressUpdates( $sType = 'plugins' ) {
233
  $oCurrent = $this->getTransient( 'update_'.$sType );
234
+ return ( isset( $oCurrent->response ) && is_array( $oCurrent->response ) ) ? $oCurrent->response : [];
235
  }
236
 
237
  /**
353
  */
354
  public function canCoreUpdateAutomatically() {
355
  global $required_php_version, $required_mysql_version;
356
+ $future_minor_update = (object)[
357
  'current' => $this->getVersion().'.1.next.minor',
358
  'version' => $this->getVersion().'.1.next.minor',
359
  'php_version' => $required_php_version,
360
  'mysql_version' => $required_mysql_version,
361
+ ];
362
  return $this->getWpAutomaticUpdater()
363
  ->should_update( 'core', $future_minor_update, ABSPATH );
364
  }
379
  /**
380
  * @param array $aQueryParams
381
  */
382
+ public function redirectToLogin( $aQueryParams = [] ) {
383
  $this->doRedirect( wp_login_url(), $aQueryParams );
384
  }
385
 
386
  /**
387
  * @param array $aQueryParams
388
  */
389
+ public function redirectToAdmin( $aQueryParams = [] ) {
390
  $this->doRedirect( is_multisite() ? get_admin_url() : admin_url(), $aQueryParams );
391
  }
392
 
393
  /**
394
  * @param array $aQueryParams
395
  */
396
+ public function redirectToHome( $aQueryParams = [] ) {
397
  $this->doRedirect( home_url(), $aQueryParams );
398
  }
399
 
403
  * @param bool $bSafe
404
  * @param bool $bProtectAgainstInfiniteLoops - if false, ignores the redirect loop protection
405
  */
406
+ public function doRedirect( $sUrl, $aQueryParams = [], $bSafe = true, $bProtectAgainstInfiniteLoops = true ) {
407
  $sUrl = empty( $aQueryParams ) ? $sUrl : add_query_arg( $aQueryParams, $sUrl );
408
 
409
  $oReq = $this->loadRequest();
511
  if ( $sPage == 'admin.php' ) {
512
  $sSubPage = $this->loadRequest()->query( 'page' );
513
  if ( !empty( $sSubPage ) ) {
514
+ $aQueryArgs = [
515
  'page' => $sSubPage,
516
+ ];
517
  $sUrl = add_query_arg( $aQueryArgs, $sUrl );
518
  }
519
  }
673
  * @return array
674
  */
675
  public function getAllUserLoginUsernames() {
676
+ $aUsers = get_users( [ 'fields' => [ 'user_login' ] ] );
677
+ $aLogins = [];
678
  foreach ( $aUsers as $oUser ) {
679
  $aLogins[] = $oUser->user_login;
680
  }
src/common/icwp-wpincludes.php CHANGED
@@ -1,5 +1,7 @@
1
  <?php
2
 
 
 
3
  class ICWP_WPSF_WpIncludes extends ICWP_WPSF_Foundation {
4
 
5
  /**
@@ -7,11 +9,6 @@ class ICWP_WPSF_WpIncludes extends ICWP_WPSF_Foundation {
7
  */
8
  protected static $oInstance = null;
9
 
10
- /**
11
- * @var array
12
- */
13
- private $aScriptTags;
14
-
15
  /**
16
  * @return ICWP_WPSF_WpIncludes
17
  */
@@ -50,13 +47,14 @@ class ICWP_WPSF_WpIncludes extends ICWP_WPSF_Foundation {
50
  }
51
 
52
  /**
53
- * @param $sUrl
54
- * @param $sInclude
55
  * @return string
56
  */
57
  public function addIncludeModifiedParam( $sUrl, $sInclude ) {
58
- $nTime = $this->loadFS()->getModifiedTime( path_join( ABSPATH, $sInclude ) );
59
- return add_query_arg( array( 'mtime' => $nTime ), $sUrl );
 
60
  }
61
 
62
  /**
@@ -67,42 +65,15 @@ class ICWP_WPSF_WpIncludes extends ICWP_WPSF_Foundation {
67
  * @return $this
68
  */
69
  public function addIncludeAttribute( $sIncludeHandle, $sAttribute, $sValue ) {
70
- if ( empty( $this->aScriptTags ) ) {
71
- $this->aScriptTags = array();
72
- }
73
-
74
- $this->aScriptTags[ $sIncludeHandle ] = $sAttribute.'::'.$sValue;
75
-
76
- // adjusted to use php5.2 compatible
77
- add_filter( 'script_loader_tag', array( $this, 'filterScriptTags' ), 10, 2 );
78
- // if ( $this->loadDP()->getPhpVersionIsAtLeast( '5.3' ) ) {
79
- //
80
- // add_filter( 'script_loader_tag',
81
- // function ( $sTag, $sHandle ) use ( $sIncludeHandle, $sAttribute, $sValue ) {
82
- // if ( $sHandle == $sIncludeHandle && strpos( $sTag, $sAttribute.'=' ) === false ) {
83
- // $sTag = str_replace( ' src', sprintf( ' %s="%s" src', $sAttribute, $sValue ), $sTag );
84
- // }
85
- // return $sTag;
86
- // },
87
- // 10, 2
88
- // );
89
- // }
90
  return $this;
91
  }
92
-
93
- /**
94
- * This is the crappy php 5.2 method of script_loader_tag because anon functions aren't supported.
95
- * @param $sTag
96
- * @param $sHandle
97
- * @return mixed
98
- */
99
- public function filterScriptTags( $sTag, $sHandle ) {
100
- if ( isset( $this->aScriptTags[ $sHandle ] ) ) {
101
- list( $sAttribute, $sValue ) = explode( '::', $this->aScriptTags[ $sHandle ] );
102
- if ( strpos( $sTag, $sAttribute.'=' ) === false ) {
103
- $sTag = str_replace( ' src', sprintf( ' %s="%s" src', $sAttribute, $sValue ), $sTag );
104
- }
105
- }
106
- return $sTag;
107
- }
108
  }
1
  <?php
2
 
3
+ use FernleafSystems\Wordpress\Services\Services;
4
+
5
  class ICWP_WPSF_WpIncludes extends ICWP_WPSF_Foundation {
6
 
7
  /**
9
  */
10
  protected static $oInstance = null;
11
 
 
 
 
 
 
12
  /**
13
  * @return ICWP_WPSF_WpIncludes
14
  */
47
  }
48
 
49
  /**
50
+ * @param string $sUrl
51
+ * @param string $sInclude
52
  * @return string
53
  */
54
  public function addIncludeModifiedParam( $sUrl, $sInclude ) {
55
+ $nTime = \FernleafSystems\Wordpress\Services\Services::WpFs()
56
+ ->getModifiedTime( path_join( ABSPATH, $sInclude ) );
57
+ return add_query_arg( [ 'mtime' => $nTime ], $sUrl );
58
  }
59
 
60
  /**
65
  * @return $this
66
  */
67
  public function addIncludeAttribute( $sIncludeHandle, $sAttribute, $sValue ) {
68
+ add_filter( 'script_loader_tag',
69
+ function ( $sTag, $sHandle ) use ( $sIncludeHandle, $sAttribute, $sValue ) {
70
+ if ( $sHandle == $sIncludeHandle && strpos( $sTag, $sAttribute.'=' ) === false ) {
71
+ $sTag = str_replace( ' src', sprintf( ' %s="%s" src', $sAttribute, $sValue ), $sTag );
72
+ }
73
+ return $sTag;
74
+ },
75
+ 10, 2
76
+ );
 
 
 
 
 
 
 
 
 
 
 
77
  return $this;
78
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
  }
src/common/icwp-wpupgrades.php CHANGED
@@ -57,33 +57,33 @@ if ( class_exists( 'Plugin_Upgrader' ) ) {
57
 
58
  protected $fModeOverwrite = true;
59
 
60
- public function install( $package, $args = array() ) {
61
 
62
- $defaults = array(
63
  'clear_update_cache' => true,
64
- );
65
  $parsed_args = wp_parse_args( $args, $defaults );
66
 
67
  $this->init();
68
  $this->install_strings();
69
 
70
- add_filter( 'upgrader_source_selection', array( $this, 'check_package' ) );
71
- add_filter( 'upgrader_clear_destination', array( $this, 'clearStatCache' ) );
72
 
73
- $oResult = $this->run( array(
74
  'package' => $package,
75
  'destination' => WP_PLUGIN_DIR,
76
  'clear_destination' => $this->getOverwriteMode(),
77
  // key to overwrite and why we're extending the native wordpress class
78
  'clear_working' => true,
79
- 'hook_extra' => array(
80
  'type' => 'plugin',
81
  'action' => 'install',
82
- )
83
- ) );
84
 
85
- remove_filter( 'upgrader_source_selection', array( $this, 'check_package' ) );
86
- remove_filter( 'upgrader_clear_destination', array( $this, 'clearStatCache' ) );
87
 
88
  if ( !$this->result || is_wp_error( $this->result ) ) {
89
  return $this->result;
@@ -136,8 +136,8 @@ if ( class_exists( 'Bulk_Plugin_Upgrader_Skin', false ) ) {
136
  */
137
  public function __construct() {
138
  parent::__construct( compact( 'nonce', 'url' ) );
139
- $this->m_aErrors = array();
140
- $this->aFeedback = array();
141
  }
142
 
143
  /**
@@ -213,34 +213,34 @@ if ( class_exists( 'Theme_Upgrader' ) ) {
213
 
214
  protected $fModeOverwrite = true;
215
 
216
- public function install( $package, $args = array() ) {
217
 
218
- $defaults = array(
219
  'clear_update_cache' => true,
220
- );
221
  $parsed_args = wp_parse_args( $args, $defaults );
222
 
223
  $this->init();
224
  $this->install_strings();
225
 
226
- add_filter( 'upgrader_source_selection', array( $this, 'check_package' ) );
227
- add_filter( 'upgrader_post_install', array( $this, 'check_parent_theme_filter' ), 10, 3 );
228
- add_filter( 'upgrader_clear_destination', array( $this, 'clearStatCache' ) );
229
 
230
- $this->run( array(
231
  'package' => $package,
232
  'destination' => get_theme_root(),
233
  'clear_destination' => $this->getOverwriteMode(),
234
  'clear_working' => true,
235
- 'hook_extra' => array(
236
  'type' => 'theme',
237
  'action' => 'install',
238
- ),
239
- ) );
240
 
241
- remove_filter( 'upgrader_source_selection', array( $this, 'check_package' ) );
242
- remove_filter( 'upgrader_post_install', array( $this, 'check_parent_theme_filter' ) );
243
- remove_filter( 'upgrader_clear_destination', array( $this, 'clearStatCache' ) );
244
 
245
  if ( !$this->result || is_wp_error( $this->result ) ) {
246
  return $this->result;
@@ -293,8 +293,8 @@ if ( class_exists( 'Bulk_Theme_Upgrader_Skin', false ) ) {
293
  */
294
  public function __construct() {
295
  parent::__construct( compact( 'title', 'nonce', 'url', 'theme' ) );
296
- $this->m_aErrors = array();
297
- $this->aFeedback = array();
298
  }
299
 
300
  /**
57
 
58
  protected $fModeOverwrite = true;
59
 
60
+ public function install( $package, $args = [] ) {
61
 
62
+ $defaults = [
63
  'clear_update_cache' => true,
64
+ ];
65
  $parsed_args = wp_parse_args( $args, $defaults );
66
 
67
  $this->init();
68
  $this->install_strings();
69
 
70
+ add_filter( 'upgrader_source_selection', [ $this, 'check_package' ] );
71
+ add_filter( 'upgrader_clear_destination', [ $this, 'clearStatCache' ] );
72
 
73
+ $oResult = $this->run( [
74
  'package' => $package,
75
  'destination' => WP_PLUGIN_DIR,
76
  'clear_destination' => $this->getOverwriteMode(),
77
  // key to overwrite and why we're extending the native wordpress class
78
  'clear_working' => true,
79
+ 'hook_extra' => [
80
  'type' => 'plugin',
81
  'action' => 'install',
82
+ ]
83
+ ] );
84
 
85
+ remove_filter( 'upgrader_source_selection', [ $this, 'check_package' ] );
86
+ remove_filter( 'upgrader_clear_destination', [ $this, 'clearStatCache' ] );
87
 
88
  if ( !$this->result || is_wp_error( $this->result ) ) {
89
  return $this->result;
136
  */
137
  public function __construct() {
138
  parent::__construct( compact( 'nonce', 'url' ) );
139
+ $this->m_aErrors = [];
140
+ $this->aFeedback = [];
141
  }
142
 
143
  /**
213
 
214
  protected $fModeOverwrite = true;
215
 
216
+ public function install( $package, $args = [] ) {
217
 
218
+ $defaults = [
219
  'clear_update_cache' => true,
220
+ ];
221
  $parsed_args = wp_parse_args( $args, $defaults );
222
 
223
  $this->init();
224
  $this->install_strings();
225
 
226
+ add_filter( 'upgrader_source_selection', [ $this, 'check_package' ] );
227
+ add_filter( 'upgrader_post_install', [ $this, 'check_parent_theme_filter' ], 10, 3 );
228
+ add_filter( 'upgrader_clear_destination', [ $this, 'clearStatCache' ] );
229
 
230
+ $this->run( [
231
  'package' => $package,
232
  'destination' => get_theme_root(),
233
  'clear_destination' => $this->getOverwriteMode(),
234
  'clear_working' => true,
235
+ 'hook_extra' => [
236
  'type' => 'theme',
237
  'action' => 'install',
238
+ ],
239
+ ] );
240
 
241
+ remove_filter( 'upgrader_source_selection', [ $this, 'check_package' ] );
242
+ remove_filter( 'upgrader_post_install', [ $this, 'check_parent_theme_filter' ] );
243
+ remove_filter( 'upgrader_clear_destination', [ $this, 'clearStatCache' ] );
244
 
245
  if ( !$this->result || is_wp_error( $this->result ) ) {
246
  return $this->result;
293
  */
294
  public function __construct() {
295
  parent::__construct( compact( 'title', 'nonce', 'url', 'theme' ) );
296
+ $this->m_aErrors = [];
297
+ $this->aFeedback = [];
298
  }
299
 
300
  /**
src/common/wp-admin-notices.php CHANGED
@@ -36,8 +36,8 @@ class ICWP_WPSF_WpAdminNotices extends ICWP_WPSF_Foundation {
36
 
37
  protected function __construct() {
38
  $this->sFlashMessage = '';
39
- add_action( 'admin_notices', array( $this, 'onWpAdminNotices' ) );
40
- add_action( 'network_admin_notices', array( $this, 'onWpAdminNotices' ) );
41
  }
42
 
43
  /**
@@ -57,11 +57,11 @@ class ICWP_WPSF_WpAdminNotices extends ICWP_WPSF_Foundation {
57
  protected function ajaxExec_DismissAdminNotice() {
58
  // Get all notices and if this notice exists, we set it to "hidden"
59
  $sNoticeId = sanitize_key( $this->loadRequest()->query( 'notice_id', '' ) );
60
- $aNotices = apply_filters( $this->getPrefix().'register_admin_notices', array() );
61
  if ( !empty( $sNoticeId ) && array_key_exists( $sNoticeId, $aNotices ) ) {
62
  $this->setMeta( $aNotices[ $sNoticeId ][ 'id' ] );
63
  }
64
- return array( 'success' => true );
65
  }
66
 
67
  public function onWpAdminNotices() {
@@ -86,11 +86,11 @@ class ICWP_WPSF_WpAdminNotices extends ICWP_WPSF_Foundation {
86
  * @return false|string
87
  */
88
  public function getMeta( $sNoticeId ) {
89
- $mValue = array();
90
 
91
  $oMeta = $this->getCurrentUserMeta();
92
 
93
- $sCleanNotice = 'notice_'.str_replace( array( '-', '_' ), '', $sNoticeId );
94
  if ( isset( $oMeta->{$sCleanNotice} ) && is_array( $oMeta->{$sCleanNotice} ) ) {
95
  $mValue = $oMeta->{$sCleanNotice};
96
  }
@@ -110,14 +110,14 @@ class ICWP_WPSF_WpAdminNotices extends ICWP_WPSF_Foundation {
110
  * @param string $sNoticeId
111
  * @param array $aMeta
112
  */
113
- public function setMeta( $sNoticeId, $aMeta = array() ) {
114
  if ( !is_array( $aMeta ) ) {
115
- $aMeta = array();
116
  }
117
 
118
  $oMeta = $this->getCurrentUserMeta();
119
- $sCleanNotice = 'notice_'.str_replace( array( '-', '_' ), '', $sNoticeId );
120
- $oMeta->{$sCleanNotice} = array_merge( array( 'time' => $this->loadRequest()->ts() ), $aMeta );
121
  return;
122
  }
123
 
@@ -142,7 +142,7 @@ class ICWP_WPSF_WpAdminNotices extends ICWP_WPSF_Foundation {
142
  */
143
  protected function getNotices() {
144
  if ( !isset( $this->aAdminNotices ) || !is_array( $this->aAdminNotices ) ) {
145
- $this->aAdminNotices = array();
146
  }
147
  return $this->aAdminNotices;
148
  }
@@ -209,7 +209,7 @@ class ICWP_WPSF_WpAdminNotices extends ICWP_WPSF_Foundation {
209
  * @return $this
210
  */
211
  public function addFlashUserMessage( $sMessage, $bError = false ) {
212
- if ( $this->loadWpUsers()->isUserLoggedIn() ) {
213
  $this->getCurrentUserMeta()->flash_msg = ( $bError ? 'error' : 'updated' )
214
  .'::'.sanitize_text_field( $sMessage )
215
  .'::'.( $this->loadRequest()->ts() + 300 );
@@ -262,7 +262,7 @@ class ICWP_WPSF_WpAdminNotices extends ICWP_WPSF_Foundation {
262
  * @return $this
263
  */
264
  public function flushFlash() {
265
- if ( $this->loadWpUsers()->isUserLoggedIn() ) {
266
  $oMeta = $this->getCurrentUserMeta();
267
  if ( isset( $oMeta->flash_msg ) ) {
268
  $this->sFlashMessage = (string)$oMeta->flash_msg;
36
 
37
  protected function __construct() {
38
  $this->sFlashMessage = '';
39
+ add_action( 'admin_notices', [ $this, 'onWpAdminNotices' ] );
40
+ add_action( 'network_admin_notices', [ $this, 'onWpAdminNotices' ] );
41
  }
42
 
43
  /**
57
  protected function ajaxExec_DismissAdminNotice() {
58
  // Get all notices and if this notice exists, we set it to "hidden"
59
  $sNoticeId = sanitize_key( $this->loadRequest()->query( 'notice_id', '' ) );
60
+ $aNotices = apply_filters( $this->getPrefix().'register_admin_notices', [] );
61
  if ( !empty( $sNoticeId ) && array_key_exists( $sNoticeId, $aNotices ) ) {
62
  $this->setMeta( $aNotices[ $sNoticeId ][ 'id' ] );
63
  }
64
+ return [ 'success' => true ];
65
  }
66
 
67
  public function onWpAdminNotices() {
86
  * @return false|string
87
  */
88
  public function getMeta( $sNoticeId ) {
89
+ $mValue = [];
90
 
91
  $oMeta = $this->getCurrentUserMeta();
92
 
93
+ $sCleanNotice = 'notice_'.str_replace( [ '-', '_' ], '', $sNoticeId );
94
  if ( isset( $oMeta->{$sCleanNotice} ) && is_array( $oMeta->{$sCleanNotice} ) ) {
95
  $mValue = $oMeta->{$sCleanNotice};
96
  }
110
  * @param string $sNoticeId
111
  * @param array $aMeta
112
  */
113
+ public function setMeta( $sNoticeId, $aMeta = [] ) {
114
  if ( !is_array( $aMeta ) ) {
115
+ $aMeta = [];
116
  }
117
 
118
  $oMeta = $this->getCurrentUserMeta();
119
+ $sCleanNotice = 'notice_'.str_replace( [ '-', '_' ], '', $sNoticeId );
120
+ $oMeta->{$sCleanNotice} = array_merge( [ 'time' => $this->loadRequest()->ts() ], $aMeta );
121
  return;
122
  }
123
 
142
  */
143
  protected function getNotices() {
144
  if ( !isset( $this->aAdminNotices ) || !is_array( $this->aAdminNotices ) ) {
145
+ $this->aAdminNotices = [];
146
  }
147
  return $this->aAdminNotices;
148
  }
209
  * @return $this
210
  */
211
  public function addFlashUserMessage( $sMessage, $bError = false ) {
212
+ if ( Services::WpUsers()->isUserLoggedIn() ) {
213
  $this->getCurrentUserMeta()->flash_msg = ( $bError ? 'error' : 'updated' )
214
  .'::'.sanitize_text_field( $sMessage )
215
  .'::'.( $this->loadRequest()->ts() + 300 );
262
  * @return $this
263
  */
264
  public function flushFlash() {
265
+ if ( Services::WpUsers()->isUserLoggedIn() ) {
266
  $oMeta = $this->getCurrentUserMeta();
267
  if ( isset( $oMeta->flash_msg ) ) {
268
  $this->sFlashMessage = (string)$oMeta->flash_msg;
src/common/wp-comments.php CHANGED
@@ -1,5 +1,7 @@
1
  <?php
2
 
 
 
3
  class ICWP_WPSF_WpComments extends ICWP_WPSF_Foundation {
4
 
5
  /**
@@ -7,7 +9,8 @@ class ICWP_WPSF_WpComments extends ICWP_WPSF_Foundation {
7
  */
8
  protected static $oInstance = null;
9
 
10
- private function __construct() {}
 
11
 
12
  /**
13
  * @return ICWP_WPSF_WpComments
@@ -19,13 +22,6 @@ class ICWP_WPSF_WpComments extends ICWP_WPSF_Foundation {
19
  return self::$oInstance;
20
  }
21
 
22
- /**
23
- * @return bool
24
- */
25
- public function getIfAllowCommentsByPreviouslyApproved() {
26
- return ( $this->loadWp()->getOption( 'comment_whitelist' ) == 1 );
27
- }
28
-
29
  /**
30
  * @param WP_Post|null $oPost - queries the current post if null
31
  * @return bool
1
  <?php
2
 
3
+ use FernleafSystems\Wordpress\Services\Services;
4
+
5
  class ICWP_WPSF_WpComments extends ICWP_WPSF_Foundation {
6
 
7
  /**
9
  */
10
  protected static $oInstance = null;
11
 
12
+ private function __construct() {
13
+ }
14
 
15
  /**
16
  * @return ICWP_WPSF_WpComments
22
  return self::$oInstance;
23
  }
24
 
 
 
 
 
 
 
 
25
  /**
26
  * @param WP_Post|null $oPost - queries the current post if null
27
  * @return bool
src/common/wp-users.php CHANGED
@@ -1,14 +1,7 @@
1
  <?php
2
 
3
- use FernleafSystems\Wordpress\Services\Services;
4
-
5
  class ICWP_WPSF_WpUsers extends ICWP_WPSF_Foundation {
6
 
7
- /**
8
- * @var ICWP_UserMeta[]
9
- */
10
- private $aMetas;
11
-
12
  /**
13
  * @var ICWP_WPSF_WpUsers
14
  */
@@ -50,7 +43,7 @@ class ICWP_WPSF_WpUsers extends ICWP_WPSF_Foundation {
50
  /**
51
  * @param array $aLoginUrlParams
52
  */
53
- public function forceUserRelogin( $aLoginUrlParams = array() ) {
54
  $this->logoutUser();
55
  $this->loadWp()->redirectToLogin( $aLoginUrlParams );
56
  }
@@ -59,10 +52,10 @@ class ICWP_WPSF_WpUsers extends ICWP_WPSF_Foundation {
59
  * @param array $aArgs
60
  * @return WP_User[]
61
  */
62
- public function getAllUsers( $aArgs = array() ) {
63
  $aArgs = wp_parse_args(
64
  $aArgs,
65
- array(
66
  'blog_id' => 0,
67
  // 'fields' => array(
68
  // 'ID',
@@ -70,9 +63,9 @@ class ICWP_WPSF_WpUsers extends ICWP_WPSF_Foundation {
70
  // 'user_email',
71
  // 'user_pass',
72
  // )
73
- )
74
  );
75
- return function_exists( 'get_users' ) ? get_users( $aArgs ) : array();
76
  }
77
 
78
  /**
@@ -87,13 +80,13 @@ class ICWP_WPSF_WpUsers extends ICWP_WPSF_Foundation {
87
  * @return array
88
  */
89
  public function getLevelToRoleMap() {
90
- return array(
91
  0 => 'subscriber',
92
  1 => 'contributor',
93
  2 => 'author',
94
  3 => 'editor',
95
  8 => 'administrator'
96
- );
97
  }
98
 
99
  /**
@@ -105,28 +98,6 @@ class ICWP_WPSF_WpUsers extends ICWP_WPSF_Foundation {
105
  return $bSlugsOnly ? array_keys( get_editable_roles() ) : get_editable_roles();
106
  }
107
 
108
- /**
109
- * @return bool
110
- */
111
- public function canSaveMeta() {
112
- $bCanMeta = false;
113
- try {
114
- if ( $this->isUserLoggedIn() ) {
115
- $sKey = 'icwp-flag-can-store-user-meta';
116
- $sMeta = $this->getUserMeta( $sKey );
117
- if ( $sMeta == 'icwp' ) {
118
- $bCanMeta = true;
119
- }
120
- else {
121
- $bCanMeta = $this->updateUserMeta( $sKey, 'icwp' );
122
- }
123
- }
124
- }
125
- catch ( Exception $oE ) {
126
- }
127
- return $bCanMeta;
128
- }
129
-
130
  /**
131
  * @return null|WP_User
132
  */
@@ -219,9 +190,9 @@ class ICWP_WPSF_WpUsers extends ICWP_WPSF_Foundation {
219
  }
220
 
221
  /**
222
- * @see wp-login.php
223
  * @param WP_User $oUser
224
  * @return string|null
 
225
  */
226
  public function getPasswordResetUrl( $oUser ) {
227
  $sUrl = null;
@@ -229,11 +200,11 @@ class ICWP_WPSF_WpUsers extends ICWP_WPSF_Foundation {
229
  $sResetKey = get_password_reset_key( $oUser );
230
  if ( !is_wp_error( $sResetKey ) ) {
231
  $sUrl = add_query_arg(
232
- array(
233
  'action' => 'rp',
234
  'key' => $sResetKey,
235
  'login' => $oUser->user_login,
236
- ),
237
  wp_login_url()
238
  );
239
  }
@@ -262,34 +233,6 @@ class ICWP_WPSF_WpUsers extends ICWP_WPSF_Foundation {
262
  return function_exists( 'is_user_logged_in' ) && is_user_logged_in();
263
  }
264
 
265
- /**
266
- * @param string $sPrefix
267
- * @param int $nUserId
268
- * @return ICWP_UserMeta
269
- */
270
- public function metaVoForUser( $sPrefix, $nUserId = null ) {
271
- if ( is_null( $nUserId ) ) {
272
- $nUserId = $this->getCurrentWpUserId();
273
- }
274
-
275
- $aMetas = $this->getMetas();
276
- if ( !isset( $aMetas[ $nUserId ] ) ) {
277
- $aMetas[ $nUserId ] = new ICWP_UserMeta( $sPrefix, $nUserId );
278
- $this->aMetas = $aMetas;
279
- }
280
- return $this->aMetas[ $nUserId ];
281
- }
282
-
283
- /**
284
- * @return ICWP_UserMeta[]
285
- */
286
- protected function getMetas() {
287
- if ( empty( $this->aMetas ) ) {
288
- $this->aMetas = array();
289
- }
290
- return $this->aMetas;
291
- }
292
-
293
  /**
294
  * Fires the WordPress logout functions. If $bQuiet is true, it'll manually
295
  * call the WordPress logout code, so as not to fire any other logout actions
1
  <?php
2
 
 
 
3
  class ICWP_WPSF_WpUsers extends ICWP_WPSF_Foundation {
4
 
 
 
 
 
 
5
  /**
6
  * @var ICWP_WPSF_WpUsers
7
  */
43
  /**
44
  * @param array $aLoginUrlParams
45
  */
46
+ public function forceUserRelogin( $aLoginUrlParams = [] ) {
47
  $this->logoutUser();
48
  $this->loadWp()->redirectToLogin( $aLoginUrlParams );
49
  }
52
  * @param array $aArgs
53
  * @return WP_User[]
54
  */
55
+ public function getAllUsers( $aArgs = [] ) {
56
  $aArgs = wp_parse_args(
57
  $aArgs,
58
+ [
59
  'blog_id' => 0,
60
  // 'fields' => array(
61
  // 'ID',
63
  // 'user_email',
64
  // 'user_pass',
65
  // )
66
+ ]
67
  );
68
+ return function_exists( 'get_users' ) ? get_users( $aArgs ) : [];
69
  }
70
 
71
  /**
80
  * @return array
81
  */
82
  public function getLevelToRoleMap() {
83
+ return [
84
  0 => 'subscriber',
85
  1 => 'contributor',
86
  2 => 'author',
87
  3 => 'editor',
88
  8 => 'administrator'
89
+ ];
90
  }
91
 
92
  /**
98
  return $bSlugsOnly ? array_keys( get_editable_roles() ) : get_editable_roles();
99
  }
100
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
  /**
102
  * @return null|WP_User
103
  */
190
  }
191
 
192
  /**
 
193
  * @param WP_User $oUser
194
  * @return string|null
195
+ * @see wp-login.php
196
  */
197
  public function getPasswordResetUrl( $oUser ) {
198
  $sUrl = null;
200
  $sResetKey = get_password_reset_key( $oUser );
201
  if ( !is_wp_error( $sResetKey ) ) {
202
  $sUrl = add_query_arg(
203
+ [
204
  'action' => 'rp',
205
  'key' => $sResetKey,
206
  'login' => $oUser->user_login,
207
+ ],
208
  wp_login_url()
209
  );
210
  }
233
  return function_exists( 'is_user_logged_in' ) && is_user_logged_in();
234
  }
235
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
236
  /**
237
  * Fires the WordPress logout functions. If $bQuiet is true, it'll manually
238
  * call the WordPress logout code, so as not to fire any other logout actions
src/config/feature-admin_access_restriction.php CHANGED
@@ -32,14 +32,15 @@
32
  },
33
  "sections": [
34
  {
35
- "slug": "section_admin_access_restriction_settings",
36
- "primary": true,
37
- "title": "Security Admin Restriction Settings",
38
- "title_short": "Security Admin Settings",
39
- "summary": [
40
  "Purpose - Restrict access using a simple Access Key.",
41
  "Recommendation - Use of this feature is highly recommend."
42
- ]
 
43
  },
44
  {
45
  "slug": "section_admin_access_restriction_areas",
@@ -349,7 +350,6 @@
349
  }
350
  ],
351
  "definitions": {
352
- "help_video_id": "214855538",
353
  "admin_access_options_to_restrict": {
354
  "wpms_options": [
355
  "admin_email",
32
  },
33
  "sections": [
34
  {
35
+ "slug": "section_admin_access_restriction_settings",
36
+ "primary": true,
37
+ "title": "Security Admin Restriction Settings",
38
+ "title_short": "Security Admin Settings",
39
+ "summary": [
40
  "Purpose - Restrict access using a simple Access Key.",
41
  "Recommendation - Use of this feature is highly recommend."
42
+ ],
43
+ "help_video_id": "338551188"
44
  },
45
  {
46
  "slug": "section_admin_access_restriction_areas",
350
  }
351
  ],
352
  "definitions": {
 
353
  "admin_access_options_to_restrict": {
354
  "wpms_options": [
355
  "admin_email",
src/config/feature-plugin.php CHANGED
@@ -47,12 +47,12 @@
47
  "type": "promo"
48
  },
49
  "plugin-mailing-list-signup": {
50
- "id": "plugin-mailing-list-signup",
51
- "schedule": "once",
52
- "valid_admin": true,
53
- "delay_days": 15,
54
- "type": "promo",
55
- "twig": true,
56
  "drip_form_id": "250437573"
57
  },
58
  "rate-plugin": {
@@ -65,26 +65,29 @@
65
  },
66
  "sections": [
67
  {
68
- "slug": "section_defaults",
69
- "primary": true,
70
- "title": "Plugin Defaults",
71
- "title_short": "Plugin Defaults"
 
 
 
 
 
 
 
72
  },
73
  {
74
- "slug": "section_general_plugin_options",
75
- "title": "General Plugin Options",
76
- "title_short": "General Options"
 
77
  },
78
  {
79
  "slug": "section_importexport",
80
  "title": "Import / Export",
81
  "title_short": "Import / Export"
82
  },
83
- {
84
- "slug": "section_third_party_google",
85
- "title": "Google",
86
- "title_short": "Google"
87
- },
88
  {
89
  "slug": "section_global_security_options",
90
  "title": "Global Plugin Security Options",
47
  "type": "promo"
48
  },
49
  "plugin-mailing-list-signup": {
50
+ "id": "plugin-mailing-list-signup",
51
+ "schedule": "once",
52
+ "valid_admin": true,
53
+ "delay_days": 15,
54
+ "type": "promo",
55
+ "twig": true,
56
  "drip_form_id": "250437573"
57
  },
58
  "rate-plugin": {
65
  },
66
  "sections": [
67
  {
68
+ "slug": "section_defaults",
69
+ "primary": true,
70
+ "title": "Plugin Defaults",
71
+ "title_short": "Plugin Defaults",
72
+ "help_video_id": "338533495"
73
+ },
74
+ {
75
+ "slug": "section_general_plugin_options",
76
+ "title": "General Plugin Options",
77
+ "title_short": "General Options",
78
+ "help_video_id": "338540386"
79
  },
80
  {
81
+ "slug": "section_third_party_google",
82
+ "title": "Google reCAPTCHA",
83
+ "title_short": "Google reCAPTCHA",
84
+ "help_video_id": "338546796"
85
  },
86
  {
87
  "slug": "section_importexport",
88
  "title": "Import / Export",
89
  "title_short": "Import / Export"
90
  },
 
 
 
 
 
91
  {
92
  "slug": "section_global_security_options",
93
  "title": "Global Plugin Security Options",
src/features/autoupdates.php CHANGED
@@ -135,16 +135,16 @@ class ICWP_WPSF_FeatureHandler_Autoupdates extends ICWP_WPSF_FeatureHandler_Base
135
  $sMessage = __( 'You do not have permissions to perform this action.', 'wp-simple-firewall' );
136
 
137
  if ( $this->isAutoupdateIndividualPlugins() && $this->getCon()->isPluginAdmin() ) {
138
- $oWpPlugins = $this->loadWpPlugins();
139
  $sFile = Services::Request()->post( 'pluginfile' );
140
  if ( $oWpPlugins->isInstalled( $sFile ) ) {
141
  $this->setPluginToAutoUpdate( $sFile );
142
 
143
- $aPlugin = $oWpPlugins->getPlugin( $sFile );
144
  $sMessage = sprintf( __( 'Plugin "%s" will %s.', 'wp-simple-firewall' ),
145
- $aPlugin[ 'Name' ],
146
- $this->loadWp()
147
- ->isPluginAutomaticallyUpdated( $sFile ) ? __( 'update automatically', 'wp-simple-firewall' ) : __( 'not update automatically', 'wp-simple-firewall' )
 
148
  );
149
  $bSuccess = true;
150
  }
@@ -261,8 +261,7 @@ class ICWP_WPSF_FeatureHandler_Autoupdates extends ICWP_WPSF_FeatureHandler_Base
261
  ];
262
  }
263
  else {
264
- $oWp = $this->loadWp();
265
- $bCanCore = $oWp->canCoreUpdateAutomatically();
266
  $aThis[ 'key_opts' ][ 'core_minor' ] = [
267
  'name' => __( 'Core Updates', 'wp-simple-firewall' ),
268
  'enabled' => $bCanCore,
135
  $sMessage = __( 'You do not have permissions to perform this action.', 'wp-simple-firewall' );
136
 
137
  if ( $this->isAutoupdateIndividualPlugins() && $this->getCon()->isPluginAdmin() ) {
138
+ $oWpPlugins = Services::WpPlugins();
139
  $sFile = Services::Request()->post( 'pluginfile' );
140
  if ( $oWpPlugins->isInstalled( $sFile ) ) {
141
  $this->setPluginToAutoUpdate( $sFile );
142
 
 
143
  $sMessage = sprintf( __( 'Plugin "%s" will %s.', 'wp-simple-firewall' ),
144
+ $oWpPlugins->getPluginAsVo( $sFile )->Name,
145
+ Services::WpPlugins()->isPluginAutomaticallyUpdated( $sFile ) ?
146
+ __( 'update automatically', 'wp-simple-firewall' )
147
+ : __( 'not update automatically', 'wp-simple-firewall' )
148
  );
149
  $bSuccess = true;
150
  }
261
  ];
262
  }
263
  else {
264
+ $bCanCore = Services::WpGeneral()->canCoreUpdateAutomatically();
 
265
  $aThis[ 'key_opts' ][ 'core_minor' ] = [
266
  'name' => __( 'Core Updates', 'wp-simple-firewall' ),
267
  'enabled' => $bCanCore,
src/features/base.php CHANGED
@@ -404,7 +404,6 @@ abstract class ICWP_WPSF_FeatureHandler_Base extends ICWP_WPSF_Foundation {
404
  $oCon = $this->getCon();
405
  $this->oOptions = ( new ICWP_WPSF_OptionsVO )
406
  ->setPathToConfig( $oCon->getPath_ConfigFile( $this->getSlug() ) )
407
- ->setOptionsEncoding( $oCon->getOptionsEncoding() )
408
  ->setRebuildFromFile( $oCon->getIsRebuildOptionsFromFile() )
409
  ->setOptionsStorageKey( $this->getOptionsStorageKey() )
410
  ->setIfLoadOptionsFromStorage( !$oCon->getIsResetPlugin() );
@@ -684,8 +683,20 @@ abstract class ICWP_WPSF_FeatureHandler_Base extends ICWP_WPSF_Foundation {
684
  'name' => $this->getMainFeatureName(),
685
  'menu_title' => empty( $sMenuTitle ) ? $this->getMainFeatureName() : $sMenuTitle,
686
  'href' => network_admin_url( 'admin.php?page='.$this->getModSlug() ),
687
- // 'sections' => $aSections,
 
688
  ];
 
 
 
 
 
 
 
 
 
 
 
689
  // $aSum[ 'content' ] = $this->renderTemplate( 'snippets/summary_single', $aSum );
690
  $aSum[ 'tooltip' ] = sprintf(
691
  '%s: %s',
@@ -969,6 +980,7 @@ abstract class ICWP_WPSF_FeatureHandler_Base extends ICWP_WPSF_Foundation {
969
 
970
  $oOptsVo = $this->getOptionsVo();
971
  $aOptions = $oOptsVo->getOptionsForPluginUse();
 
972
  foreach ( $aOptions as $nSectionKey => $aSection ) {
973
 
974
  if ( !empty( $aSection[ 'options' ] ) ) {
@@ -984,10 +996,6 @@ abstract class ICWP_WPSF_FeatureHandler_Base extends ICWP_WPSF_Foundation {
984
  }
985
  }
986
 
987
- if ( !empty( $aSection[ 'help_video_id' ] ) ) {
988
- $aSection[ 'help_video_url' ] = $this->getHelpVideoUrl( $aSection[ 'help_video_id' ] );
989
- }
990
-
991
  if ( empty( $aSection[ 'options' ] ) ) {
992
  unset( $aOptions[ $nSectionKey ] );
993
  }
@@ -1004,6 +1012,14 @@ abstract class ICWP_WPSF_FeatureHandler_Base extends ICWP_WPSF_Foundation {
1004
  $this->getSectionWarnings( $aSection[ 'slug' ] )
1005
  );
1006
  $aOptions[ $nSectionKey ][ 'notices' ] = $this->getSectionNotices( $aSection[ 'slug' ] );
 
 
 
 
 
 
 
 
1007
  }
1008
  }
1009
 
404
  $oCon = $this->getCon();
405
  $this->oOptions = ( new ICWP_WPSF_OptionsVO )
406
  ->setPathToConfig( $oCon->getPath_ConfigFile( $this->getSlug() ) )
 
407
  ->setRebuildFromFile( $oCon->getIsRebuildOptionsFromFile() )
408
  ->setOptionsStorageKey( $this->getOptionsStorageKey() )
409
  ->setIfLoadOptionsFromStorage( !$oCon->getIsResetPlugin() );
683
  'name' => $this->getMainFeatureName(),
684
  'menu_title' => empty( $sMenuTitle ) ? $this->getMainFeatureName() : $sMenuTitle,
685
  'href' => network_admin_url( 'admin.php?page='.$this->getModSlug() ),
686
+ 'sections' => $aSections,
687
+ 'options' => [],
688
  ];
689
+
690
+ foreach ( $this->getOptionsVo()->getVisibleOptionsKeys() as $sOptKey ) {
691
+ try {
692
+ $aOptData = $this->loadStrings_Options( [ 'key' => $sOptKey ] );
693
+ $aOptData[ 'href' ] = $this->getUrl_DirectLinkToOption( $sOptKey );
694
+ $aSum[ 'options' ][ $sOptKey ] = $aOptData;
695
+ }
696
+ catch ( Exception $oE ) {
697
+ }
698
+ }
699
+
700
  // $aSum[ 'content' ] = $this->renderTemplate( 'snippets/summary_single', $aSum );
701
  $aSum[ 'tooltip' ] = sprintf(
702
  '%s: %s',
980
 
981
  $oOptsVo = $this->getOptionsVo();
982
  $aOptions = $oOptsVo->getOptionsForPluginUse();
983
+
984
  foreach ( $aOptions as $nSectionKey => $aSection ) {
985
 
986
  if ( !empty( $aSection[ 'options' ] ) ) {
996
  }
997
  }
998
 
 
 
 
 
999
  if ( empty( $aSection[ 'options' ] ) ) {
1000
  unset( $aOptions[ $nSectionKey ] );
1001
  }
1012
  $this->getSectionWarnings( $aSection[ 'slug' ] )
1013
  );
1014
  $aOptions[ $nSectionKey ][ 'notices' ] = $this->getSectionNotices( $aSection[ 'slug' ] );
1015
+
1016
+ if ( !empty( $aSection[ 'help_video_id' ] ) ) {
1017
+ $sHelpVideoUrl = $this->getHelpVideoUrl( $aSection[ 'help_video_id' ] );
1018
+ }
1019
+ else {
1020
+ $sHelpVideoUrl = '';
1021
+ }
1022
+ $aOptions[ $nSectionKey ][ 'help_video_url' ] = $sHelpVideoUrl;
1023
  }
1024
  }
1025
 
src/features/base_wpsf.php CHANGED
@@ -47,7 +47,7 @@ class ICWP_WPSF_FeatureHandler_BaseWpsf extends ICWP_WPSF_FeatureHandler_Base {
47
  */
48
  public function onWpInit() {
49
  parent::onWpInit();
50
- if ( $this->isThisModulePage() && ( $this->getSlug() != 'insights' ) ) {
51
  $this->redirectToInsightsSubPage();
52
  }
53
  }
@@ -179,20 +179,21 @@ class ICWP_WPSF_FeatureHandler_BaseWpsf extends ICWP_WPSF_FeatureHandler_Base {
179
  'sec_admin_login' => $this->getSecAdminLoginAjaxData(),
180
  ],
181
  'strings' => [
182
- 'go_to_settings' => __( 'Settings', 'wp-simple-firewall' ),
183
- 'on' => __( 'On', 'wp-simple-firewall' ),
184
- 'off' => __( 'Off', 'wp-simple-firewall' ),
185
- 'more_info' => __( 'Info', 'wp-simple-firewall' ),
186
- 'blog' => __( 'Blog', 'wp-simple-firewall' ),
187
- 'save_all_settings' => __( 'Save All Settings', 'wp-simple-firewall' ),
188
- 'options_title' => __( 'Options', 'wp-simple-firewall' ),
189
- 'options_summary' => __( 'Configure Module', 'wp-simple-firewall' ),
190
- 'actions_title' => __( 'Actions and Info', 'wp-simple-firewall' ),
191
- 'actions_summary' => __( 'Perform actions for this module', 'wp-simple-firewall' ),
192
- 'help_title' => __( 'Help', 'wp-simple-firewall' ),
193
- 'help_summary' => __( 'Learn More', 'wp-simple-firewall' ),
194
- 'supply_password' => __( 'Supply Password', 'wp-simple-firewall' ),
195
- 'confirm_password' => __( 'Confirm Password', 'wp-simple-firewall' ),
 
196
 
197
  'aar_title' => __( 'Plugin Access Restricted', 'wp-simple-firewall' ),
198
  'aar_what_should_you_enter' => __( 'This security plugin is restricted to administrators with the Security Access Key.', 'wp-simple-firewall' ),
47
  */
48
  public function onWpInit() {
49
  parent::onWpInit();
50
+ if ( $this->isThisModulePage() && !$this->isWizardPage() && ( $this->getSlug() != 'insights' ) ) {
51
  $this->redirectToInsightsSubPage();
52
  }
53
  }
179
  'sec_admin_login' => $this->getSecAdminLoginAjaxData(),
180
  ],
181
  'strings' => [
182
+ 'go_to_settings' => __( 'Settings', 'wp-simple-firewall' ),
183
+ 'on' => __( 'On', 'wp-simple-firewall' ),
184
+ 'off' => __( 'Off', 'wp-simple-firewall' ),
185
+ 'more_info' => __( 'Info', 'wp-simple-firewall' ),
186
+ 'blog' => __( 'Blog', 'wp-simple-firewall' ),
187
+ 'save_all_settings' => __( 'Save All Settings', 'wp-simple-firewall' ),
188
+ 'options_title' => __( 'Options', 'wp-simple-firewall' ),
189
+ 'options_summary' => __( 'Configure Module', 'wp-simple-firewall' ),
190
+ 'actions_title' => __( 'Actions and Info', 'wp-simple-firewall' ),
191
+ 'actions_summary' => __( 'Perform actions for this module', 'wp-simple-firewall' ),
192
+ 'help_title' => __( 'Help', 'wp-simple-firewall' ),
193
+ 'help_summary' => __( 'Learn More', 'wp-simple-firewall' ),
194
+ 'supply_password' => __( 'Supply Password', 'wp-simple-firewall' ),
195
+ 'confirm_password' => __( 'Confirm Password', 'wp-simple-firewall' ),
196
+ 'show_help_video_section' => __( 'Show help video for this section', 'wp-simple-firewall' ),
197
 
198
  'aar_title' => __( 'Plugin Access Restricted', 'wp-simple-firewall' ),
199
  'aar_what_should_you_enter' => __( 'This security plugin is restricted to administrators with the Security Access Key.', 'wp-simple-firewall' ),
src/features/comments_filter.php CHANGED
@@ -10,7 +10,7 @@ class ICWP_WPSF_FeatureHandler_CommentsFilter extends ICWP_WPSF_FeatureHandler_B
10
  * @return bool
11
  */
12
  public function getIfDoCommentsCheck( $nPostId, $sCommentEmail ) {
13
- $oWpComm = $this->loadWpComments();
14
 
15
  $oPost = Services::WpPost()->getById( $nPostId );
16
  return ( $oPost instanceof WP_Post ) && $oWpComm->isCommentsOpen( $oPost )
10
  * @return bool
11
  */
12
  public function getIfDoCommentsCheck( $nPostId, $sCommentEmail ) {
13
+ $oWpComm = Services::WpComments();
14
 
15
  $oPost = Services::WpPost()->getById( $nPostId );
16
  return ( $oPost instanceof WP_Post ) && $oWpComm->isCommentsOpen( $oPost )
src/features/hack_protect.php CHANGED
@@ -285,9 +285,8 @@ class ICWP_WPSF_FeatureHandler_HackProtect extends ICWP_WPSF_FeatureHandler_Base
285
  protected function cleanFileExclusions() {
286
  $aExclusions = [];
287
 
288
- $oFS = $this->loadFS();
289
  foreach ( $this->getUfcFileExclusions() as $nKey => $sExclusion ) {
290
- $sExclusion = $oFS->normalizeFilePathDS( trim( $sExclusion ) );
291
 
292
  if ( preg_match( '/^#(.+)#$/', $sExclusion, $aMatches ) ) { // it's regex
293
  // ignore it
@@ -412,7 +411,7 @@ class ICWP_WPSF_FeatureHandler_HackProtect extends ICWP_WPSF_FeatureHandler_Base
412
  $nNow = Services::Request()->ts();
413
  $bLastCheckExpired = ( $nNow - $this->getOpt( 'ptg_candiskwrite_at', 0 ) ) > DAY_IN_SECONDS;
414
 
415
- $bCanWrite = (bool)$this->getOpt( 'ptg_candiskwrite' ) && !$bLastCheckExpired;
416
  if ( !$bCanWrite ) {
417
  $oFS = Services::WpFs();
418
  $sDir = $this->getPtgSnapsBaseDir();
@@ -423,7 +422,8 @@ class ICWP_WPSF_FeatureHandler_HackProtect extends ICWP_WPSF_FeatureHandler_Base
423
  $sContents = $oFS->exists( $sTestFile ) ? $oFS->getFileContent( $sTestFile ) : '';
424
  if ( $sContents === 'test-'.$nNow ) {
425
  $oFS->deleteFile( $sTestFile );
426
- $this->setOpt( 'ptg_candiskwrite', !$oFS->exists( $sTestFile ) );
 
427
  }
428
  $this->setOpt( 'ptg_candiskwrite_at', $nNow );
429
  }
285
  protected function cleanFileExclusions() {
286
  $aExclusions = [];
287
 
 
288
  foreach ( $this->getUfcFileExclusions() as $nKey => $sExclusion ) {
289
+ $sExclusion = wp_normalize_path( trim( $sExclusion ) );
290
 
291
  if ( preg_match( '/^#(.+)#$/', $sExclusion, $aMatches ) ) { // it's regex
292
  // ignore it
411
  $nNow = Services::Request()->ts();
412
  $bLastCheckExpired = ( $nNow - $this->getOpt( 'ptg_candiskwrite_at', 0 ) ) > DAY_IN_SECONDS;
413
 
414
+ $bCanWrite = $this->getOpt( 'ptg_candiskwrite' ) && !$bLastCheckExpired;
415
  if ( !$bCanWrite ) {
416
  $oFS = Services::WpFs();
417
  $sDir = $this->getPtgSnapsBaseDir();
422
  $sContents = $oFS->exists( $sTestFile ) ? $oFS->getFileContent( $sTestFile ) : '';
423
  if ( $sContents === 'test-'.$nNow ) {
424
  $oFS->deleteFile( $sTestFile );
425
+ $bCanWrite = !$oFS->exists( $sTestFile );
426
+ $this->setOpt( 'ptg_candiskwrite', $bCanWrite );
427
  }
428
  $this->setOpt( 'ptg_candiskwrite_at', $nNow );
429
  }
src/features/insights.php CHANGED
@@ -263,6 +263,7 @@ class ICWP_WPSF_FeatureHandler_Insights extends ICWP_WPSF_FeatureHandler_BaseWps
263
  ];
264
  } );
265
 
 
266
  $aSettingsSubNav = [];
267
  foreach ( $this->getModulesSummaryData() as $sSlug => $aSubMod ) {
268
  $aSettingsSubNav[ $sSlug ] = [
@@ -271,6 +272,8 @@ class ICWP_WPSF_FeatureHandler_Insights extends ICWP_WPSF_FeatureHandler_BaseWps
271
  'active' => $sSlug === $sSubNavSection,
272
  'slug' => $sSlug
273
  ];
 
 
274
  }
275
  $aTopNav[ 'settings' ][ 'subnavs' ] = $aSettingsSubNav;
276
 
@@ -299,7 +302,8 @@ class ICWP_WPSF_FeatureHandler_Insights extends ICWP_WPSF_FeatureHandler_BaseWps
299
  ],
300
  'strings' => $this->getDisplayStrings(),
301
  'vars' => [
302
- 'changelog_id' => $oCon->getPluginSpec()[ 'meta' ][ 'headway_changelog_id' ],
 
303
  ],
304
  ],
305
  $aData
@@ -478,7 +482,7 @@ class ICWP_WPSF_FeatureHandler_Insights extends ICWP_WPSF_FeatureHandler_BaseWps
478
  ];
479
 
480
  // SSL Expires
481
- $sHomeUrl = $this->loadWp()->getHomeUrl();
482
  $bHomeSsl = strpos( $sHomeUrl, 'https://' ) === 0;
483
 
484
  if ( $bHomeSsl && $oSslService->isEnvSupported() ) {
@@ -545,7 +549,7 @@ class ICWP_WPSF_FeatureHandler_Insights extends ICWP_WPSF_FeatureHandler_BaseWps
545
  * @return array
546
  */
547
  protected function getNoticesPlugins() {
548
- $oWpPlugins = $this->loadWpPlugins();
549
  $aNotices = [
550
  'title' => __( 'Plugins', 'wp-simple-firewall' ),
551
  'messages' => []
@@ -557,7 +561,7 @@ class ICWP_WPSF_FeatureHandler_Insights extends ICWP_WPSF_FeatureHandler_BaseWps
557
  $aNotices[ 'messages' ][ 'inactive' ] = [
558
  'title' => 'Inactive',
559
  'message' => sprintf( __( '%s inactive plugin(s)', 'wp-simple-firewall' ), $nCount ),
560
- 'href' => $this->loadWp()->getAdminUrl_Plugins( true ),
561
  'action' => sprintf( 'Go To %s', __( 'Plugins', 'wp-simple-firewall' ) ),
562
  'rec' => __( 'Unused plugins should be removed.', 'wp-simple-firewall' )
563
  ];
@@ -570,7 +574,7 @@ class ICWP_WPSF_FeatureHandler_Insights extends ICWP_WPSF_FeatureHandler_BaseWps
570
  $aNotices[ 'messages' ][ 'updates' ] = [
571
  'title' => 'Updates',
572
  'message' => sprintf( __( '%s plugin update(s)', 'wp-simple-firewall' ), $nCount ),
573
- 'href' => $this->loadWp()->getAdminUrl_Updates( true ),
574
  'action' => sprintf( 'Go To %s', __( 'Updates', 'wp-simple-firewall' ) ),
575
  'rec' => __( 'Updates should be applied as early as possible.', 'wp-simple-firewall' )
576
  ];
@@ -585,7 +589,7 @@ class ICWP_WPSF_FeatureHandler_Insights extends ICWP_WPSF_FeatureHandler_BaseWps
585
  * @return array
586
  */
587
  protected function getNoticesThemes() {
588
- $oWpT = $this->loadWpThemes();
589
  $aNotices = [
590
  'title' => __( 'Themes', 'wp-simple-firewall' ),
591
  'messages' => []
@@ -597,7 +601,7 @@ class ICWP_WPSF_FeatureHandler_Insights extends ICWP_WPSF_FeatureHandler_BaseWps
597
  $aNotices[ 'messages' ][ 'inactive' ] = [
598
  'title' => 'Inactive',
599
  'message' => sprintf( __( '%s inactive themes(s)', 'wp-simple-firewall' ), $nInactive ),
600
- 'href' => $this->loadWp()->getAdminUrl_Themes( true ),
601
  'action' => sprintf( 'Go To %s', __( 'Themes', 'wp-simple-firewall' ) ),
602
  'rec' => __( 'Unused themes should be removed.', 'wp-simple-firewall' )
603
  ];
@@ -610,7 +614,7 @@ class ICWP_WPSF_FeatureHandler_Insights extends ICWP_WPSF_FeatureHandler_BaseWps
610
  $aNotices[ 'messages' ][ 'updates' ] = [
611
  'title' => 'Updates',
612
  'message' => sprintf( __( '%s theme update(s)', 'wp-simple-firewall' ), $nCount ),
613
- 'href' => $this->loadWp()->getAdminUrl_Updates( true ),
614
  'action' => sprintf( 'Go To %s', __( 'Updates', 'wp-simple-firewall' ) ),
615
  'rec' => __( 'Updates should be applied as early as possible.', 'wp-simple-firewall' )
616
  ];
@@ -625,7 +629,7 @@ class ICWP_WPSF_FeatureHandler_Insights extends ICWP_WPSF_FeatureHandler_BaseWps
625
  * @return array
626
  */
627
  protected function getNoticesCore() {
628
- $oWp = $this->loadWp();
629
  $aNotices = [
630
  'title' => __( 'WordPress Core', 'wp-simple-firewall' ),
631
  'messages' => []
@@ -636,7 +640,7 @@ class ICWP_WPSF_FeatureHandler_Insights extends ICWP_WPSF_FeatureHandler_BaseWps
636
  $aNotices[ 'messages' ][ 'updates' ] = [
637
  'title' => 'Updates',
638
  'message' => __( 'WordPress Core has an update available.', 'wp-simple-firewall' ),
639
- 'href' => $this->loadWp()->getAdminUrl_Updates( true ),
640
  'action' => sprintf( 'Go To %s', __( 'Updates', 'wp-simple-firewall' ) ),
641
  'rec' => __( 'Updates should be applied as early as possible.', 'wp-simple-firewall' )
642
  ];
263
  ];
264
  } );
265
 
266
+ $aSearchSelect = [];
267
  $aSettingsSubNav = [];
268
  foreach ( $this->getModulesSummaryData() as $sSlug => $aSubMod ) {
269
  $aSettingsSubNav[ $sSlug ] = [
272
  'active' => $sSlug === $sSubNavSection,
273
  'slug' => $sSlug
274
  ];
275
+
276
+ $aSearchSelect[ $aSubMod[ 'name' ] ] = $aSubMod[ 'options' ];
277
  }
278
  $aTopNav[ 'settings' ][ 'subnavs' ] = $aSettingsSubNav;
279
 
302
  ],
303
  'strings' => $this->getDisplayStrings(),
304
  'vars' => [
305
+ 'changelog_id' => $oCon->getPluginSpec()[ 'meta' ][ 'headway_changelog_id' ],
306
+ 'search_select' => $aSearchSelect
307
  ],
308
  ],
309
  $aData
482
  ];
483
 
484
  // SSL Expires
485
+ $sHomeUrl = Services::WpGeneral()->getHomeUrl();
486
  $bHomeSsl = strpos( $sHomeUrl, 'https://' ) === 0;
487
 
488
  if ( $bHomeSsl && $oSslService->isEnvSupported() ) {
549
  * @return array
550
  */
551
  protected function getNoticesPlugins() {
552
+ $oWpPlugins = Services::WpPlugins();
553
  $aNotices = [
554
  'title' => __( 'Plugins', 'wp-simple-firewall' ),
555
  'messages' => []
561
  $aNotices[ 'messages' ][ 'inactive' ] = [
562
  'title' => 'Inactive',
563
  'message' => sprintf( __( '%s inactive plugin(s)', 'wp-simple-firewall' ), $nCount ),
564
+ 'href' => Services::WpGeneral()->getAdminUrl_Plugins( true ),
565
  'action' => sprintf( 'Go To %s', __( 'Plugins', 'wp-simple-firewall' ) ),
566
  'rec' => __( 'Unused plugins should be removed.', 'wp-simple-firewall' )
567
  ];
574
  $aNotices[ 'messages' ][ 'updates' ] = [
575
  'title' => 'Updates',
576
  'message' => sprintf( __( '%s plugin update(s)', 'wp-simple-firewall' ), $nCount ),
577
+ 'href' => Services::WpGeneral()->getAdminUrl_Updates( true ),
578
  'action' => sprintf( 'Go To %s', __( 'Updates', 'wp-simple-firewall' ) ),
579
  'rec' => __( 'Updates should be applied as early as possible.', 'wp-simple-firewall' )
580
  ];
589
  * @return array
590
  */
591
  protected function getNoticesThemes() {
592
+ $oWpT = Services::WpThemes();
593
  $aNotices = [
594
  'title' => __( 'Themes', 'wp-simple-firewall' ),
595
  'messages' => []
601
  $aNotices[ 'messages' ][ 'inactive' ] = [
602
  'title' => 'Inactive',
603
  'message' => sprintf( __( '%s inactive themes(s)', 'wp-simple-firewall' ), $nInactive ),
604
+ 'href' => Services::WpGeneral()->getAdminUrl_Themes( true ),
605
  'action' => sprintf( 'Go To %s', __( 'Themes', 'wp-simple-firewall' ) ),
606
  'rec' => __( 'Unused themes should be removed.', 'wp-simple-firewall' )
607
  ];
614
  $aNotices[ 'messages' ][ 'updates' ] = [
615
  'title' => 'Updates',
616
  'message' => sprintf( __( '%s theme update(s)', 'wp-simple-firewall' ), $nCount ),
617
+ 'href' => Services::WpGeneral()->getAdminUrl_Updates( true ),
618
  'action' => sprintf( 'Go To %s', __( 'Updates', 'wp-simple-firewall' ) ),
619
  'rec' => __( 'Updates should be applied as early as possible.', 'wp-simple-firewall' )
620
  ];
629
  * @return array
630
  */
631
  protected function getNoticesCore() {
632
+ $oWp = Services::WpGeneral();
633
  $aNotices = [
634
  'title' => __( 'WordPress Core', 'wp-simple-firewall' ),
635
  'messages' => []
640
  $aNotices[ 'messages' ][ 'updates' ] = [
641
  'title' => 'Updates',
642
  'message' => __( 'WordPress Core has an update available.', 'wp-simple-firewall' ),
643
+ 'href' => $oWp->getAdminUrl_Updates( true ),
644
  'action' => sprintf( 'Go To %s', __( 'Updates', 'wp-simple-firewall' ) ),
645
  'rec' => __( 'Updates should be applied as early as possible.', 'wp-simple-firewall' )
646
  ];
src/features/plugin.php CHANGED
@@ -21,7 +21,7 @@ class ICWP_WPSF_FeatureHandler_Plugin extends ICWP_WPSF_FeatureHandler_BaseWpsf
21
  }
22
 
23
  private function deleteAllPluginCrons() {
24
- $oWpCron = $this->loadWpCronProcessor();
25
 
26
  foreach ( $oWpCron->getCrons() as $nKey => $aCronArgs ) {
27
  foreach ( $aCronArgs as $sHook => $aCron ) {
@@ -291,16 +291,15 @@ class ICWP_WPSF_FeatureHandler_Plugin extends ICWP_WPSF_FeatureHandler_BaseWpsf
291
  * @return array
292
  */
293
  public function ajaxExec_PluginBadgeClose() {
294
- $bSuccess = $this->loadRequest()
295
- ->setCookie(
296
- $this->getCookieIdBadgeState(),
297
- 'closed',
298
- DAY_IN_SECONDS
299
- );
300
- $sMessage = $bSuccess ? 'Badge Closed' : 'Badge Not Closed';
301
  return [
302
  'success' => $bSuccess,
303
- 'message' => $sMessage
304
  ];
305
  }
306
 
@@ -1161,8 +1160,8 @@ class ICWP_WPSF_FeatureHandler_Plugin extends ICWP_WPSF_FeatureHandler_BaseWpsf
1161
  break;
1162
 
1163
  case 'section_third_party_google' :
1164
- $sTitle = __( 'Google', 'wp-simple-firewall' );
1165
- $sTitleShort = __( 'Google', 'wp-simple-firewall' );
1166
  $aSummary = [
1167
  sprintf( '%s - %s', __( 'Purpose', 'wp-simple-firewall' ), sprintf( __( 'Setup Google reCAPTCHA for use across %s.', 'wp-simple-firewall' ), $sName ) ),
1168
  sprintf( '%s - %s',
21
  }
22
 
23
  private function deleteAllPluginCrons() {
24
+ $oWpCron = Services::WpCron();
25
 
26
  foreach ( $oWpCron->getCrons() as $nKey => $aCronArgs ) {
27
  foreach ( $aCronArgs as $sHook => $aCron ) {
291
  * @return array
292
  */
293
  public function ajaxExec_PluginBadgeClose() {
294
+ $bSuccess = Services::Response()
295
+ ->cookieSet(
296
+ $this->getCookieIdBadgeState(),
297
+ 'closed',
298
+ DAY_IN_SECONDS
299
+ );
 
300
  return [
301
  'success' => $bSuccess,
302
+ 'message' => $bSuccess ? 'Badge Closed' : 'Badge Not Closed'
303
  ];
304
  }
305
 
1160
  break;
1161
 
1162
  case 'section_third_party_google' :
1163
+ $sTitle = __( 'Google reCAPTCHA', 'wp-simple-firewall' );
1164
+ $sTitleShort = __( 'Google reCAPTCHA', 'wp-simple-firewall' );
1165
  $aSummary = [
1166
  sprintf( '%s - %s', __( 'Purpose', 'wp-simple-firewall' ), sprintf( __( 'Setup Google reCAPTCHA for use across %s.', 'wp-simple-firewall' ), $sName ) ),
1167
  sprintf( '%s - %s',
src/features/statistics.php CHANGED
@@ -1,5 +1,7 @@
1
  <?php
2
 
 
 
3
  class ICWP_WPSF_FeatureHandler_Statistics extends ICWP_WPSF_FeatureHandler_BaseWpsf {
4
 
5
  /**
@@ -13,7 +15,7 @@ class ICWP_WPSF_FeatureHandler_Statistics extends ICWP_WPSF_FeatureHandler_BaseW
13
  * @return string
14
  */
15
  public function getFullReportingTableName() {
16
- return $this->loadDbProcessor()->getPrefix().$this->getReportingTableName();
17
  }
18
 
19
  /**
1
  <?php
2
 
3
+ use FernleafSystems\Wordpress\Services\Services; // TODO: use after 7.5
4
+
5
  class ICWP_WPSF_FeatureHandler_Statistics extends ICWP_WPSF_FeatureHandler_BaseWpsf {
6
 
7
  /**
15
  * @return string
16
  */
17
  public function getFullReportingTableName() {
18
+ return \FernleafSystems\Wordpress\Services\Services::WpDb()->getPrefix().$this->getReportingTableName();
19
  }
20
 
21
  /**
src/lib/src/Utilities/ReCaptcha/WordpressPost.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace FernleafSystems\Wordpress\Plugin\Shield\Utilities;
4
+
5
+ use ReCaptcha\RequestMethod;
6
+ use ReCaptcha\RequestParameters;
7
+
8
+ /**
9
+ * Class WordpressPost
10
+ * @package ReCaptcha\RequestMethod
11
+ */
12
+ class WordpressPost implements RequestMethod {
13
+
14
+ /**
15
+ * URL to which requests are sent via wp_remote_post.
16
+ * @const string
17
+ */
18
+ const SITE_VERIFY_URL = 'https://www.google.com/recaptcha/api/siteverify';
19
+
20
+ /**
21
+ * Submit the wp_remote_post request with the specified parameters.
22
+ * @param RequestParameters $params Request parameters
23
+ * @return string Body of the reCAPTCHA response
24
+ */
25
+ public function submit( RequestParameters $params ) {
26
+ $aResponse = wp_remote_post(
27
+ self::SITE_VERIFY_URL,
28
+ [
29
+ 'headers' => [ 'Content-Type' => 'application/x-www-form-urlencoded' ],
30
+ 'body' => $params->toArray()
31
+ ]
32
+ );
33
+
34
+ $sResponseBody = '';
35
+ if ( !is_wp_error( $aResponse ) && is_array( $aResponse ) && isset( $aResponse[ 'body' ] ) ) {
36
+ $sResponseBody = $aResponse[ 'body' ];
37
+ }
38
+ return $sResponseBody;
39
+ }
40
+ }
src/lib/vendor/composer/autoload_classmap.php CHANGED
@@ -225,6 +225,7 @@ return array(
225
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tests\\VerifyConfig' => $baseDir . '/src/Tests/VerifyConfig.php',
226
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Users\\ShieldUserMeta' => $baseDir . '/src/Users/ShieldUserMeta.php',
227
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\VisitorIpDetection' => $baseDir . '/src/Utilities/VisitorIpDetection.php',
 
228
  'FernleafSystems\\Wordpress\\Services\\Core\\AdminNotices' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/AdminNotices.php',
229
  'FernleafSystems\\Wordpress\\Services\\Core\\Comments' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/Comments.php',
230
  'FernleafSystems\\Wordpress\\Services\\Core\\CoreFileHashes' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/CoreFileHashes.php',
@@ -266,6 +267,7 @@ return array(
266
  'FernleafSystems\\Wordpress\\Services\\Utilities\\HttpUtil' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/HttpUtil.php',
267
  'FernleafSystems\\Wordpress\\Services\\Utilities\\IpUtils' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/IpUtils.php',
268
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Iterators\\WpUserIterator' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Iterators/WpUserIterator.php',
 
269
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Net\\VisitorIpDetection' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Net/VisitorIpDetection.php',
270
  'FernleafSystems\\Wordpress\\Services\\Utilities\\PluginUserMeta' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/PluginUserMeta.php',
271
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Render' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Render.php',
@@ -322,11 +324,9 @@ return array(
322
  'Html2Text\\Html2TextException' => $vendorDir . '/soundasleep/html2text/src/Html2TextException.php',
323
  'ICWP_Bulk_Plugin_Upgrader_Skin' => $baseDir . '/../common/icwp-wpupgrades.php',
324
  'ICWP_Bulk_Theme_Upgrader_Skin' => $baseDir . '/../common/icwp-wpupgrades.php',
325
- 'ICWP_EDD_LicenseVO' => $baseDir . '/../common/easydigitaldownloads/ICWP_EDD_LicenseVO.php',
326
  'ICWP_Plugin_Upgrader' => $baseDir . '/../common/icwp-wpupgrades.php',
327
  'ICWP_Theme_Upgrader' => $baseDir . '/../common/icwp-wpupgrades.php',
328
  'ICWP_Upgrader_Skin' => $baseDir . '/../common/icwp-wpupgrades.php',
329
- 'ICWP_UserMeta' => $baseDir . '/../common/icwp-usermeta.php',
330
  'ICWP_WPSF_AuditTrail_Auditor_Base' => $baseDir . '/../processors/audit_trail_auditor_base.php',
331
  'ICWP_WPSF_BaseDbProcessor' => $baseDir . '/../processors/basedb.php',
332
  'ICWP_WPSF_DataProcessor' => $baseDir . '/../common/icwp-data.php',
@@ -352,9 +352,6 @@ return array(
352
  'ICWP_WPSF_FeatureHandler_Traffic' => $baseDir . '/../features/traffic.php',
353
  'ICWP_WPSF_FeatureHandler_UserManagement' => $baseDir . '/../features/user_management.php',
354
  'ICWP_WPSF_Foundation' => $baseDir . '/../common/icwp-foundation.php',
355
- 'ICWP_WPSF_GoogleAuthenticator' => $baseDir . '/../common/icwp-googleauthenticator.php',
356
- 'ICWP_WPSF_GoogleRecaptcha' => $baseDir . '/../common/icwp-googlearecaptcha.php',
357
- 'ICWP_WPSF_Ip' => $baseDir . '/../common/icwp-ip.php',
358
  'ICWP_WPSF_OptionsVO' => $baseDir . '/../common/icwp-optionsvo.php',
359
  'ICWP_WPSF_Plugin_Controller' => $baseDir . '/../../icwp-plugin-controller.php',
360
  'ICWP_WPSF_Processor_AdminAccessRestriction' => $baseDir . '/../processors/admin_access_restriction.php',
@@ -477,7 +474,7 @@ return array(
477
  'MaxMind\\WebService\\Http\\CurlRequest' => $vendorDir . '/maxmind/web-service-common/src/WebService/Http/CurlRequest.php',
478
  'MaxMind\\WebService\\Http\\Request' => $vendorDir . '/maxmind/web-service-common/src/WebService/Http/Request.php',
479
  'MaxMind\\WebService\\Http\\RequestFactory' => $vendorDir . '/maxmind/web-service-common/src/WebService/Http/RequestFactory.php',
480
- 'PHPGangsta_GoogleAuthenticator' => $baseDir . '/../common/googleauthenticator/googleauthenticator.php',
481
  'Pimple\\Container' => $vendorDir . '/pimple/pimple/src/Pimple/Container.php',
482
  'Pimple\\Exception\\ExpectedInvokableException' => $vendorDir . '/pimple/pimple/src/Pimple/Exception/ExpectedInvokableException.php',
483
  'Pimple\\Exception\\FrozenServiceException' => $vendorDir . '/pimple/pimple/src/Pimple/Exception/FrozenServiceException.php',
@@ -506,7 +503,6 @@ return array(
506
  'ReCaptcha\\RequestMethod\\Post' => $vendorDir . '/google/recaptcha/src/ReCaptcha/RequestMethod/Post.php',
507
  'ReCaptcha\\RequestMethod\\Socket' => $vendorDir . '/google/recaptcha/src/ReCaptcha/RequestMethod/Socket.php',
508
  'ReCaptcha\\RequestMethod\\SocketPost' => $vendorDir . '/google/recaptcha/src/ReCaptcha/RequestMethod/SocketPost.php',
509
- 'ReCaptcha\\RequestMethod\\WordpressPost' => $baseDir . '/../common/googlerecaptcha/ReCaptcha/RequestMethod/WordpressPost.php',
510
  'ReCaptcha\\RequestParameters' => $vendorDir . '/google/recaptcha/src/ReCaptcha/RequestParameters.php',
511
  'ReCaptcha\\Response' => $vendorDir . '/google/recaptcha/src/ReCaptcha/Response.php',
512
  'StatisticsReportingVO' => $baseDir . '/../query/VOs/StatisticsReportingVO.php',
225
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tests\\VerifyConfig' => $baseDir . '/src/Tests/VerifyConfig.php',
226
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Users\\ShieldUserMeta' => $baseDir . '/src/Users/ShieldUserMeta.php',
227
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\VisitorIpDetection' => $baseDir . '/src/Utilities/VisitorIpDetection.php',
228
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\WordpressPost' => $baseDir . '/src/Utilities/ReCaptcha/WordpressPost.php',
229
  'FernleafSystems\\Wordpress\\Services\\Core\\AdminNotices' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/AdminNotices.php',
230
  'FernleafSystems\\Wordpress\\Services\\Core\\Comments' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/Comments.php',
231
  'FernleafSystems\\Wordpress\\Services\\Core\\CoreFileHashes' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/CoreFileHashes.php',
267
  'FernleafSystems\\Wordpress\\Services\\Utilities\\HttpUtil' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/HttpUtil.php',
268
  'FernleafSystems\\Wordpress\\Services\\Utilities\\IpUtils' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/IpUtils.php',
269
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Iterators\\WpUserIterator' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Iterators/WpUserIterator.php',
270
+ 'FernleafSystems\\Wordpress\\Services\\Utilities\\Licenses\\EddLicenseVO' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Licenses/EddLicenseVO.php',
271
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Net\\VisitorIpDetection' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Net/VisitorIpDetection.php',
272
  'FernleafSystems\\Wordpress\\Services\\Utilities\\PluginUserMeta' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/PluginUserMeta.php',
273
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Render' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Render.php',
324
  'Html2Text\\Html2TextException' => $vendorDir . '/soundasleep/html2text/src/Html2TextException.php',
325
  'ICWP_Bulk_Plugin_Upgrader_Skin' => $baseDir . '/../common/icwp-wpupgrades.php',
326
  'ICWP_Bulk_Theme_Upgrader_Skin' => $baseDir . '/../common/icwp-wpupgrades.php',
 
327
  'ICWP_Plugin_Upgrader' => $baseDir . '/../common/icwp-wpupgrades.php',
328
  'ICWP_Theme_Upgrader' => $baseDir . '/../common/icwp-wpupgrades.php',
329
  'ICWP_Upgrader_Skin' => $baseDir . '/../common/icwp-wpupgrades.php',
 
330
  'ICWP_WPSF_AuditTrail_Auditor_Base' => $baseDir . '/../processors/audit_trail_auditor_base.php',
331
  'ICWP_WPSF_BaseDbProcessor' => $baseDir . '/../processors/basedb.php',
332
  'ICWP_WPSF_DataProcessor' => $baseDir . '/../common/icwp-data.php',
352
  'ICWP_WPSF_FeatureHandler_Traffic' => $baseDir . '/../features/traffic.php',
353
  'ICWP_WPSF_FeatureHandler_UserManagement' => $baseDir . '/../features/user_management.php',
354
  'ICWP_WPSF_Foundation' => $baseDir . '/../common/icwp-foundation.php',
 
 
 
355
  'ICWP_WPSF_OptionsVO' => $baseDir . '/../common/icwp-optionsvo.php',
356
  'ICWP_WPSF_Plugin_Controller' => $baseDir . '/../../icwp-plugin-controller.php',
357
  'ICWP_WPSF_Processor_AdminAccessRestriction' => $baseDir . '/../processors/admin_access_restriction.php',
474
  'MaxMind\\WebService\\Http\\CurlRequest' => $vendorDir . '/maxmind/web-service-common/src/WebService/Http/CurlRequest.php',
475
  'MaxMind\\WebService\\Http\\Request' => $vendorDir . '/maxmind/web-service-common/src/WebService/Http/Request.php',
476
  'MaxMind\\WebService\\Http\\RequestFactory' => $vendorDir . '/maxmind/web-service-common/src/WebService/Http/RequestFactory.php',
477
+ 'PHPGangsta_GoogleAuthenticator' => $vendorDir . '/phpgangsta/googleauthenticator/PHPGangsta/GoogleAuthenticator.php',
478
  'Pimple\\Container' => $vendorDir . '/pimple/pimple/src/Pimple/Container.php',
479
  'Pimple\\Exception\\ExpectedInvokableException' => $vendorDir . '/pimple/pimple/src/Pimple/Exception/ExpectedInvokableException.php',
480
  'Pimple\\Exception\\FrozenServiceException' => $vendorDir . '/pimple/pimple/src/Pimple/Exception/FrozenServiceException.php',
503
  'ReCaptcha\\RequestMethod\\Post' => $vendorDir . '/google/recaptcha/src/ReCaptcha/RequestMethod/Post.php',
504
  'ReCaptcha\\RequestMethod\\Socket' => $vendorDir . '/google/recaptcha/src/ReCaptcha/RequestMethod/Socket.php',
505
  'ReCaptcha\\RequestMethod\\SocketPost' => $vendorDir . '/google/recaptcha/src/ReCaptcha/RequestMethod/SocketPost.php',
 
506
  'ReCaptcha\\RequestParameters' => $vendorDir . '/google/recaptcha/src/ReCaptcha/RequestParameters.php',
507
  'ReCaptcha\\Response' => $vendorDir . '/google/recaptcha/src/ReCaptcha/Response.php',
508
  'StatisticsReportingVO' => $baseDir . '/../query/VOs/StatisticsReportingVO.php',
src/lib/vendor/composer/autoload_static.php CHANGED
@@ -386,6 +386,7 @@ class ComposerStaticInit18a31866e67f0a0bfffdc031786ecae1
386
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tests\\VerifyConfig' => __DIR__ . '/../..' . '/src/Tests/VerifyConfig.php',
387
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Users\\ShieldUserMeta' => __DIR__ . '/../..' . '/src/Users/ShieldUserMeta.php',
388
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\VisitorIpDetection' => __DIR__ . '/../..' . '/src/Utilities/VisitorIpDetection.php',
 
389
  'FernleafSystems\\Wordpress\\Services\\Core\\AdminNotices' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/AdminNotices.php',
390
  'FernleafSystems\\Wordpress\\Services\\Core\\Comments' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/Comments.php',
391
  'FernleafSystems\\Wordpress\\Services\\Core\\CoreFileHashes' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/CoreFileHashes.php',
@@ -427,6 +428,7 @@ class ComposerStaticInit18a31866e67f0a0bfffdc031786ecae1
427
  'FernleafSystems\\Wordpress\\Services\\Utilities\\HttpUtil' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/HttpUtil.php',
428
  'FernleafSystems\\Wordpress\\Services\\Utilities\\IpUtils' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/IpUtils.php',
429
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Iterators\\WpUserIterator' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Iterators/WpUserIterator.php',
 
430
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Net\\VisitorIpDetection' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Net/VisitorIpDetection.php',
431
  'FernleafSystems\\Wordpress\\Services\\Utilities\\PluginUserMeta' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/PluginUserMeta.php',
432
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Render' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Render.php',
@@ -483,11 +485,9 @@ class ComposerStaticInit18a31866e67f0a0bfffdc031786ecae1
483
  'Html2Text\\Html2TextException' => __DIR__ . '/..' . '/soundasleep/html2text/src/Html2TextException.php',
484
  'ICWP_Bulk_Plugin_Upgrader_Skin' => __DIR__ . '/../..' . '/../common/icwp-wpupgrades.php',
485
  'ICWP_Bulk_Theme_Upgrader_Skin' => __DIR__ . '/../..' . '/../common/icwp-wpupgrades.php',
486
- 'ICWP_EDD_LicenseVO' => __DIR__ . '/../..' . '/../common/easydigitaldownloads/ICWP_EDD_LicenseVO.php',
487
  'ICWP_Plugin_Upgrader' => __DIR__ . '/../..' . '/../common/icwp-wpupgrades.php',
488
  'ICWP_Theme_Upgrader' => __DIR__ . '/../..' . '/../common/icwp-wpupgrades.php',
489
  'ICWP_Upgrader_Skin' => __DIR__ . '/../..' . '/../common/icwp-wpupgrades.php',
490
- 'ICWP_UserMeta' => __DIR__ . '/../..' . '/../common/icwp-usermeta.php',
491
  'ICWP_WPSF_AuditTrail_Auditor_Base' => __DIR__ . '/../..' . '/../processors/audit_trail_auditor_base.php',
492
  'ICWP_WPSF_BaseDbProcessor' => __DIR__ . '/../..' . '/../processors/basedb.php',
493
  'ICWP_WPSF_DataProcessor' => __DIR__ . '/../..' . '/../common/icwp-data.php',
@@ -513,9 +513,6 @@ class ComposerStaticInit18a31866e67f0a0bfffdc031786ecae1
513
  'ICWP_WPSF_FeatureHandler_Traffic' => __DIR__ . '/../..' . '/../features/traffic.php',
514
  'ICWP_WPSF_FeatureHandler_UserManagement' => __DIR__ . '/../..' . '/../features/user_management.php',
515
  'ICWP_WPSF_Foundation' => __DIR__ . '/../..' . '/../common/icwp-foundation.php',
516
- 'ICWP_WPSF_GoogleAuthenticator' => __DIR__ . '/../..' . '/../common/icwp-googleauthenticator.php',
517
- 'ICWP_WPSF_GoogleRecaptcha' => __DIR__ . '/../..' . '/../common/icwp-googlearecaptcha.php',
518
- 'ICWP_WPSF_Ip' => __DIR__ . '/../..' . '/../common/icwp-ip.php',
519
  'ICWP_WPSF_OptionsVO' => __DIR__ . '/../..' . '/../common/icwp-optionsvo.php',
520
  'ICWP_WPSF_Plugin_Controller' => __DIR__ . '/../..' . '/../../icwp-plugin-controller.php',
521
  'ICWP_WPSF_Processor_AdminAccessRestriction' => __DIR__ . '/../..' . '/../processors/admin_access_restriction.php',
@@ -638,7 +635,7 @@ class ComposerStaticInit18a31866e67f0a0bfffdc031786ecae1
638
  'MaxMind\\WebService\\Http\\CurlRequest' => __DIR__ . '/..' . '/maxmind/web-service-common/src/WebService/Http/CurlRequest.php',
639
  'MaxMind\\WebService\\Http\\Request' => __DIR__ . '/..' . '/maxmind/web-service-common/src/WebService/Http/Request.php',
640
  'MaxMind\\WebService\\Http\\RequestFactory' => __DIR__ . '/..' . '/maxmind/web-service-common/src/WebService/Http/RequestFactory.php',
641
- 'PHPGangsta_GoogleAuthenticator' => __DIR__ . '/../..' . '/../common/googleauthenticator/googleauthenticator.php',
642
  'Pimple\\Container' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Container.php',
643
  'Pimple\\Exception\\ExpectedInvokableException' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Exception/ExpectedInvokableException.php',
644
  'Pimple\\Exception\\FrozenServiceException' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Exception/FrozenServiceException.php',
@@ -667,7 +664,6 @@ class ComposerStaticInit18a31866e67f0a0bfffdc031786ecae1
667
  'ReCaptcha\\RequestMethod\\Post' => __DIR__ . '/..' . '/google/recaptcha/src/ReCaptcha/RequestMethod/Post.php',
668
  'ReCaptcha\\RequestMethod\\Socket' => __DIR__ . '/..' . '/google/recaptcha/src/ReCaptcha/RequestMethod/Socket.php',
669
  'ReCaptcha\\RequestMethod\\SocketPost' => __DIR__ . '/..' . '/google/recaptcha/src/ReCaptcha/RequestMethod/SocketPost.php',
670
- 'ReCaptcha\\RequestMethod\\WordpressPost' => __DIR__ . '/../..' . '/../common/googlerecaptcha/ReCaptcha/RequestMethod/WordpressPost.php',
671
  'ReCaptcha\\RequestParameters' => __DIR__ . '/..' . '/google/recaptcha/src/ReCaptcha/RequestParameters.php',
672
  'ReCaptcha\\Response' => __DIR__ . '/..' . '/google/recaptcha/src/ReCaptcha/Response.php',
673
  'StatisticsReportingVO' => __DIR__ . '/../..' . '/../query/VOs/StatisticsReportingVO.php',
386
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Tests\\VerifyConfig' => __DIR__ . '/../..' . '/src/Tests/VerifyConfig.php',
387
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Users\\ShieldUserMeta' => __DIR__ . '/../..' . '/src/Users/ShieldUserMeta.php',
388
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\VisitorIpDetection' => __DIR__ . '/../..' . '/src/Utilities/VisitorIpDetection.php',
389
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Utilities\\WordpressPost' => __DIR__ . '/../..' . '/src/Utilities/ReCaptcha/WordpressPost.php',
390
  'FernleafSystems\\Wordpress\\Services\\Core\\AdminNotices' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/AdminNotices.php',
391
  'FernleafSystems\\Wordpress\\Services\\Core\\Comments' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/Comments.php',
392
  'FernleafSystems\\Wordpress\\Services\\Core\\CoreFileHashes' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/CoreFileHashes.php',
428
  'FernleafSystems\\Wordpress\\Services\\Utilities\\HttpUtil' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/HttpUtil.php',
429
  'FernleafSystems\\Wordpress\\Services\\Utilities\\IpUtils' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/IpUtils.php',
430
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Iterators\\WpUserIterator' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Iterators/WpUserIterator.php',
431
+ 'FernleafSystems\\Wordpress\\Services\\Utilities\\Licenses\\EddLicenseVO' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Licenses/EddLicenseVO.php',
432
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Net\\VisitorIpDetection' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Net/VisitorIpDetection.php',
433
  'FernleafSystems\\Wordpress\\Services\\Utilities\\PluginUserMeta' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/PluginUserMeta.php',
434
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Render' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Render.php',
485
  'Html2Text\\Html2TextException' => __DIR__ . '/..' . '/soundasleep/html2text/src/Html2TextException.php',
486
  'ICWP_Bulk_Plugin_Upgrader_Skin' => __DIR__ . '/../..' . '/../common/icwp-wpupgrades.php',
487
  'ICWP_Bulk_Theme_Upgrader_Skin' => __DIR__ . '/../..' . '/../common/icwp-wpupgrades.php',
 
488
  'ICWP_Plugin_Upgrader' => __DIR__ . '/../..' . '/../common/icwp-wpupgrades.php',
489
  'ICWP_Theme_Upgrader' => __DIR__ . '/../..' . '/../common/icwp-wpupgrades.php',
490
  'ICWP_Upgrader_Skin' => __DIR__ . '/../..' . '/../common/icwp-wpupgrades.php',
 
491
  'ICWP_WPSF_AuditTrail_Auditor_Base' => __DIR__ . '/../..' . '/../processors/audit_trail_auditor_base.php',
492
  'ICWP_WPSF_BaseDbProcessor' => __DIR__ . '/../..' . '/../processors/basedb.php',
493
  'ICWP_WPSF_DataProcessor' => __DIR__ . '/../..' . '/../common/icwp-data.php',
513
  'ICWP_WPSF_FeatureHandler_Traffic' => __DIR__ . '/../..' . '/../features/traffic.php',
514
  'ICWP_WPSF_FeatureHandler_UserManagement' => __DIR__ . '/../..' . '/../features/user_management.php',
515
  'ICWP_WPSF_Foundation' => __DIR__ . '/../..' . '/../common/icwp-foundation.php',
 
 
 
516
  'ICWP_WPSF_OptionsVO' => __DIR__ . '/../..' . '/../common/icwp-optionsvo.php',
517
  'ICWP_WPSF_Plugin_Controller' => __DIR__ . '/../..' . '/../../icwp-plugin-controller.php',
518
  'ICWP_WPSF_Processor_AdminAccessRestriction' => __DIR__ . '/../..' . '/../processors/admin_access_restriction.php',
635
  'MaxMind\\WebService\\Http\\CurlRequest' => __DIR__ . '/..' . '/maxmind/web-service-common/src/WebService/Http/CurlRequest.php',
636
  'MaxMind\\WebService\\Http\\Request' => __DIR__ . '/..' . '/maxmind/web-service-common/src/WebService/Http/Request.php',
637
  'MaxMind\\WebService\\Http\\RequestFactory' => __DIR__ . '/..' . '/maxmind/web-service-common/src/WebService/Http/RequestFactory.php',
638
+ 'PHPGangsta_GoogleAuthenticator' => __DIR__ . '/..' . '/phpgangsta/googleauthenticator/PHPGangsta/GoogleAuthenticator.php',
639
  'Pimple\\Container' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Container.php',
640
  'Pimple\\Exception\\ExpectedInvokableException' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Exception/ExpectedInvokableException.php',
641
  'Pimple\\Exception\\FrozenServiceException' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Exception/FrozenServiceException.php',
664
  'ReCaptcha\\RequestMethod\\Post' => __DIR__ . '/..' . '/google/recaptcha/src/ReCaptcha/RequestMethod/Post.php',
665
  'ReCaptcha\\RequestMethod\\Socket' => __DIR__ . '/..' . '/google/recaptcha/src/ReCaptcha/RequestMethod/Socket.php',
666
  'ReCaptcha\\RequestMethod\\SocketPost' => __DIR__ . '/..' . '/google/recaptcha/src/ReCaptcha/RequestMethod/SocketPost.php',
 
667
  'ReCaptcha\\RequestParameters' => __DIR__ . '/..' . '/google/recaptcha/src/ReCaptcha/RequestParameters.php',
668
  'ReCaptcha\\Response' => __DIR__ . '/..' . '/google/recaptcha/src/ReCaptcha/Response.php',
669
  'StatisticsReportingVO' => __DIR__ . '/../..' . '/../query/VOs/StatisticsReportingVO.php',
src/lib/vendor/composer/installed.json CHANGED
@@ -190,12 +190,12 @@
190
  "source": {
191
  "type": "git",
192
  "url": "https://bitbucket.org/FernleafSystems/wordpress-services.git",
193
- "reference": "9cb818f7abd9406b1d231090b21c98d887de64cf"
194
  },
195
  "dist": {
196
  "type": "zip",
197
- "url": "https://bitbucket.org/FernleafSystems/wordpress-services/get/9cb818f7abd9406b1d231090b21c98d887de64cf.zip",
198
- "reference": "9cb818f7abd9406b1d231090b21c98d887de64cf",
199
  "shasum": ""
200
  },
201
  "require": {
@@ -208,7 +208,7 @@
208
  "symfony/yaml": "~2.0||~3.0",
209
  "twig/twig": "^1.0"
210
  },
211
- "time": "2019-05-12T14:53:47+00:00",
212
  "type": "library",
213
  "installation-source": "source",
214
  "autoload": {
@@ -537,6 +537,51 @@
537
  ],
538
  "description": "PHP Class implementation of LZ-String javascript."
539
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
540
  {
541
  "name": "pimple/pimple",
542
  "version": "v3.2.3",
190
  "source": {
191
  "type": "git",
192
  "url": "https://bitbucket.org/FernleafSystems/wordpress-services.git",
193
+ "reference": "38a133acf075f45fe47d43208b6df7af6382cfb2"
194
  },
195
  "dist": {
196
  "type": "zip",
197
+ "url": "https://bitbucket.org/FernleafSystems/wordpress-services/get/38a133acf075f45fe47d43208b6df7af6382cfb2.zip",
198
+ "reference": "38a133acf075f45fe47d43208b6df7af6382cfb2",
199
  "shasum": ""
200
  },
201
  "require": {
208
  "symfony/yaml": "~2.0||~3.0",
209
  "twig/twig": "^1.0"
210
  },
211
+ "time": "2019-05-27T17:15:53+00:00",
212
  "type": "library",
213
  "installation-source": "source",
214
  "autoload": {
537
  ],
538
  "description": "PHP Class implementation of LZ-String javascript."
539
  },
540
+ {
541
+ "name": "phpgangsta/googleauthenticator",
542
+ "version": "dev-master",
543
+ "version_normalized": "9999999-dev",
544
+ "source": {
545
+ "type": "git",
546
+ "url": "https://github.com/PHPGangsta/GoogleAuthenticator.git",
547
+ "reference": "505c2af8337b559b33557f37cda38e5f843f3768"
548
+ },
549
+ "dist": {
550
+ "type": "zip",
551
+ "url": "https://api.github.com/repos/PHPGangsta/GoogleAuthenticator/zipball/505c2af8337b559b33557f37cda38e5f843f3768",
552
+ "reference": "505c2af8337b559b33557f37cda38e5f843f3768",
553
+ "shasum": ""
554
+ },
555
+ "require": {
556
+ "php": ">=5.3"
557
+ },
558
+ "time": "2019-03-20T00:55:58+00:00",
559
+ "type": "library",
560
+ "installation-source": "source",
561
+ "autoload": {
562
+ "classmap": [
563
+ "PHPGangsta/GoogleAuthenticator.php"
564
+ ]
565
+ },
566
+ "notification-url": "https://packagist.org/downloads/",
567
+ "license": [
568
+ "BSD-4-Clause"
569
+ ],
570
+ "authors": [
571
+ {
572
+ "name": "Michael Kliewe",
573
+ "email": "info@phpgangsta.de",
574
+ "homepage": "http://www.phpgangsta.de/",
575
+ "role": "Developer"
576
+ }
577
+ ],
578
+ "description": "Google Authenticator 2-factor authentication",
579
+ "keywords": [
580
+ "googleauthenticator",
581
+ "rfc6238",
582
+ "totp"
583
+ ]
584
+ },
585
  {
586
  "name": "pimple/pimple",
587
  "version": "v3.2.3",
src/lib/vendor/fernleafsystems/wordpress-services/src/Core/Comments.php CHANGED
@@ -11,9 +11,27 @@ use FernleafSystems\Wordpress\Services\Services;
11
  class Comments {
12
 
13
  /**
14
- * @var bool
 
15
  */
16
- protected $bIsCommentSubmission;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
 
18
  /**
19
  * @param int $nId
@@ -41,8 +59,7 @@ class Comments {
41
  }
42
  $bOpen = is_a( $oPost, '\WP_Post' )
43
  && comments_open( $oPost->ID )
44
- && get_post_status( $oPost ) != 'trash'
45
- && !post_password_required( $oPost->ID );
46
  return $bOpen;
47
  }
48
 
@@ -50,7 +67,7 @@ class Comments {
50
  * @return bool
51
  */
52
  public function isCommentsOpenByDefault() {
53
- return ( Services::WpGeneral()->getOption( 'default_comment_status' ) == 'open' );
54
  }
55
 
56
  /**
@@ -58,54 +75,25 @@ class Comments {
58
  * @return bool
59
  */
60
  public function isCommentAuthorPreviouslyApproved( $sAuthorEmail ) {
61
-
62
- if ( empty( $sAuthorEmail ) || !is_email( $sAuthorEmail ) ) {
63
- return false;
64
- }
65
-
66
- $oDb = Services::WpDb();
67
- $sQuery = "
68
- SELECT comment_approved
69
- FROM %s
70
- WHERE
71
- comment_author_email = '%s'
72
- AND comment_approved = '1'
73
- LIMIT 1
74
- ";
75
-
76
- $sQuery = sprintf(
77
- $sQuery,
78
- $oDb->getTable_Comments(),
79
- esc_sql( $sAuthorEmail )
80
- );
81
- return $oDb->getVar( $sQuery ) == 1;
82
  }
83
 
84
  /**
85
  * @return bool
86
  */
87
  public function isCommentSubmission() {
88
- if ( !isset( $this->bIsCommentSubmission ) ) {
89
- $this->bIsCommentSubmission = Services::Request()->isPost()
90
- && Services::WpPost()->getIsCurrentPage( 'wp-comments-post.php' );
91
- if ( $this->bIsCommentSubmission ) {
92
- $nPostId = Services::Request()->post( 'comment_post_ID' );
93
- $this->bIsCommentSubmission = !empty( $nPostId ) && is_numeric( $nPostId );
94
- }
95
- }
96
- return $this->bIsCommentSubmission;
97
  }
98
 
99
  /**
100
  * @return bool
101
  */
102
  public function getCommentSubmissionEmail() {
103
- $sData = null;
104
- if ( $this->isCommentSubmission() ) {
105
- $sData = Services::Request()->query( 'email' );
106
- $sData = is_string( $sData ) ? trim( $sData ) : null;
107
- }
108
- return $sData;
109
  }
110
 
111
  /**
11
  class Comments {
12
 
13
  /**
14
+ * @param string $sAuthorEmail
15
+ * @return bool
16
  */
17
+ public function countApproved( $sAuthorEmail ) {
18
+ $nCount = 0;
19
+
20
+ if ( Services::Data()->validEmail( $sAuthorEmail ) ) {
21
+ $oDb = Services::WpDb();
22
+ $sQuery = sprintf(
23
+ "SELECT COUNT(*) FROM %s
24
+ WHERE
25
+ comment_author_email = '%s'
26
+ AND comment_approved = 1 ",
27
+ $oDb->getTable_Comments(),
28
+ esc_sql( $sAuthorEmail )
29
+ );
30
+ $nCount = (int)$oDb->getVar( $sQuery );
31
+ }
32
+
33
+ return $nCount;
34
+ }
35
 
36
  /**
37
  * @param int $nId
59
  }
60
  $bOpen = is_a( $oPost, '\WP_Post' )
61
  && comments_open( $oPost->ID )
62
+ && get_post_status( $oPost ) != 'trash';
 
63
  return $bOpen;
64
  }
65
 
67
  * @return bool
68
  */
69
  public function isCommentsOpenByDefault() {
70
+ return Services::WpGeneral()->getOption( 'default_comment_status' ) === 'open';
71
  }
72
 
73
  /**
75
  * @return bool
76
  */
77
  public function isCommentAuthorPreviouslyApproved( $sAuthorEmail ) {
78
+ return $this->countApproved( $sAuthorEmail ) > 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
  }
80
 
81
  /**
82
  * @return bool
83
  */
84
  public function isCommentSubmission() {
85
+ $oReq = Services::Request();
86
+ $nPostId = $oReq->post( 'comment_post_ID' );
87
+ return $oReq->isPost() && !empty( $nPostId ) && is_numeric( $nPostId )
88
+ && Services::WpPost()->isCurrentPage( 'wp-comments-post.php' );
 
 
 
 
 
89
  }
90
 
91
  /**
92
  * @return bool
93
  */
94
  public function getCommentSubmissionEmail() {
95
+ $sEmail = $this->isCommentSubmission() ? trim( (string)Services::Request()->query( 'email', '' ) ) : '';
96
+ return Services::Data()->validEmail( $sEmail ) ? $sEmail : null;
 
 
 
 
97
  }
98
 
99
  /**
src/lib/vendor/fernleafsystems/wordpress-services/src/Core/Db.php CHANGED
@@ -132,6 +132,13 @@ class Db {
132
  return $this->loadWpdb()->posts;
133
  }
134
 
 
 
 
 
 
 
 
135
  /**
136
  * @param $sSql
137
  *
132
  return $this->loadWpdb()->posts;
133
  }
134
 
135
+ /**
136
+ * @return string
137
+ */
138
+ public function getTable_Users() {
139
+ return $this->loadWpdb()->users;
140
+ }
141
+
142
  /**
143
  * @param $sSql
144
  *
src/lib/vendor/fernleafsystems/wordpress-services/src/Core/Fs.php CHANGED
@@ -37,25 +37,22 @@ class Fs {
37
  }
38
 
39
  /**
40
- * @param string $sOriginalNeedle
41
  * @param string $sDir
42
  * @param boolean $bIncludeExtension
43
  * @param boolean $bCaseSensitive
44
- * @return bool
45
  */
46
- public function fileExistsInDir( $sOriginalNeedle, $sDir, $bIncludeExtension = true, $bCaseSensitive = false ) {
47
  if ( empty( $sNeedle ) || empty( $sDir ) || !$this->canAccessDirectory( $sDir ) ) {
48
  return false;
49
  }
50
 
51
  $aAllFiles = $this->getAllFilesInDir( $sDir, false );
52
  if ( !$bCaseSensitive ) {
53
- $sNeedle = strtolower( $sOriginalNeedle );
54
  $aAllFiles = array_map( 'strtolower', $aAllFiles );
55
  }
56
- else {
57
- $sNeedle = $sOriginalNeedle;
58
- }
59
 
60
  //if the file you're searching for doesn't have an extension, then we don't include extensions in search
61
  $nDotPosition = strpos( $sNeedle, '.' );
@@ -63,23 +60,26 @@ class Fs {
63
  $bIncludeExtension = $bIncludeExtension && $bHasExtension;
64
  $sNeedlePreExtension = $bHasExtension ? substr( $sNeedle, 0, $nDotPosition ) : $sNeedle;
65
 
66
- $bFound = false;
67
  foreach ( $aAllFiles as $sFilename ) {
68
 
 
69
  if ( $bIncludeExtension ) {
70
- $bFound = ( $sFilename == $sNeedle );
 
 
 
71
  }
72
  else {
73
  // This is not entirely accurate as it only finds whether a file "starts" with needle, ignoring subsequent characters
74
- $bFound = ( strpos( $sFilename, $sNeedlePreExtension ) === 0 );
75
- }
76
-
77
- if ( $bFound ) {
78
- break;
79
  }
80
  }
81
 
82
- return $bFound;
83
  }
84
 
85
  /**
@@ -100,11 +100,11 @@ class Fs {
100
  if ( $this->canAccessDirectory( $sDir ) ) {
101
  foreach ( $this->getDirIterator( $sDir ) as $oFileItem ) {
102
  if ( !$oFileItem->isDot() && ( $oFileItem->isFile() || $bIncludeDirs ) ) {
103
- $aFiles[] = $oFileItem->getFilename();
104
  }
105
  }
106
  }
107
- return ( empty( $aFiles ) ? [] : $aFiles );
108
  }
109
 
110
  /**
37
  }
38
 
39
  /**
40
+ * @param string $sNeedle
41
  * @param string $sDir
42
  * @param boolean $bIncludeExtension
43
  * @param boolean $bCaseSensitive
44
+ * @return string|null
45
  */
46
+ public function findFileInDir( $sNeedle, $sDir, $bIncludeExtension = true, $bCaseSensitive = false ) {
47
  if ( empty( $sNeedle ) || empty( $sDir ) || !$this->canAccessDirectory( $sDir ) ) {
48
  return false;
49
  }
50
 
51
  $aAllFiles = $this->getAllFilesInDir( $sDir, false );
52
  if ( !$bCaseSensitive ) {
53
+ $sNeedle = strtolower( $sNeedle );
54
  $aAllFiles = array_map( 'strtolower', $aAllFiles );
55
  }
 
 
 
56
 
57
  //if the file you're searching for doesn't have an extension, then we don't include extensions in search
58
  $nDotPosition = strpos( $sNeedle, '.' );
60
  $bIncludeExtension = $bIncludeExtension && $bHasExtension;
61
  $sNeedlePreExtension = $bHasExtension ? substr( $sNeedle, 0, $nDotPosition ) : $sNeedle;
62
 
63
+ $sTheFile = null;
64
  foreach ( $aAllFiles as $sFilename ) {
65
 
66
+ $sFilePart = basename( $sFilename );
67
  if ( $bIncludeExtension ) {
68
+ if ( $sFilePart == $sNeedle ) {
69
+ $sTheFile = $sFilename;
70
+ break;
71
+ }
72
  }
73
  else {
74
  // This is not entirely accurate as it only finds whether a file "starts" with needle, ignoring subsequent characters
75
+ if ( strpos( $sFilePart, $sNeedlePreExtension ) === 0 ) {
76
+ $sTheFile = $sFilename;
77
+ break;
78
+ }
 
79
  }
80
  }
81
 
82
+ return $sTheFile;
83
  }
84
 
85
  /**
100
  if ( $this->canAccessDirectory( $sDir ) ) {
101
  foreach ( $this->getDirIterator( $sDir ) as $oFileItem ) {
102
  if ( !$oFileItem->isDot() && ( $oFileItem->isFile() || $bIncludeDirs ) ) {
103
+ $aFiles[] = $oFileItem->getPathname();
104
  }
105
  }
106
  }
107
+ return empty( $aFiles ) ? [] : $aFiles;
108
  }
109
 
110
  /**
src/lib/vendor/fernleafsystems/wordpress-services/src/Core/General.php CHANGED
@@ -62,10 +62,25 @@ class General {
62
  return true;
63
  }
64
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
  /**
66
  * @return bool
67
  */
68
- public function getIsRunningAutomaticUpdates() {
69
  return ( get_option( 'auto_updater.lock' ) ? true : false );
70
  }
71
 
@@ -358,6 +373,16 @@ class General {
358
  return $bResult;
359
  }
360
 
 
 
 
 
 
 
 
 
 
 
361
  /**
362
  * TODO: Create ClassicPress override class for this stuff
363
  * @param bool $bIgnoreClassicpress if true returns the $wp_version regardless of ClassicPress or not
@@ -391,23 +416,10 @@ class General {
391
  /**
392
  * @param string $sPluginBaseFilename
393
  * @return boolean
 
394
  */
395
  public function getIsPluginAutomaticallyUpdated( $sPluginBaseFilename ) {
396
- $oUpdater = $this->getWpAutomaticUpdater();
397
- if ( !$oUpdater ) {
398
- return false;
399
- }
400
-
401
- // This is due to a change in the filter introduced in version 3.8.2
402
- if ( $this->getWordpressIsAtLeastVersion( '3.8.2' ) ) {
403
- $mPluginItem = new \stdClass();
404
- $mPluginItem->plugin = $sPluginBaseFilename;
405
- }
406
- else {
407
- $mPluginItem = $sPluginBaseFilename;
408
- }
409
-
410
- return $oUpdater->should_update( 'plugin', $mPluginItem, WP_PLUGIN_DIR );
411
  }
412
 
413
  /**
@@ -702,6 +714,38 @@ class General {
702
  return (int)did_action( 'automatic_updates_complete' ) > 0;
703
  }
704
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
705
  /**
706
  * Flushes the Rewrite rules and forces a re-commit to the .htaccess where applicable
707
  */
@@ -1090,4 +1134,12 @@ class General {
1090
  public function redirectToHome( $aQueryParams = [] ) {
1091
  Services::Response()->redirectToHome( $aQueryParams );
1092
  }
 
 
 
 
 
 
 
 
1093
  }
62
  return true;
63
  }
64
 
65
+ /**
66
+ * @param \stdClass|string $mItem
67
+ * @param string $sContext from plugin|theme
68
+ * @return string
69
+ */
70
+ public function getFileFromAutomaticUpdateItem( $mItem, $sContext = 'plugin' ) {
71
+ if ( is_object( $mItem ) && isset( $mItem->{$sContext} ) ) { // WP 3.8.2+
72
+ $mItem = $mItem->{$sContext};
73
+ }
74
+ else if ( !is_string( $mItem ) ) { // WP pre-3.8.2
75
+ $mItem = '';
76
+ }
77
+ return $mItem;
78
+ }
79
+
80
  /**
81
  * @return bool
82
  */
83
+ public function isRunningAutomaticUpdates() {
84
  return ( get_option( 'auto_updater.lock' ) ? true : false );
85
  }
86
 
373
  return $bResult;
374
  }
375
 
376
+ /**
377
+ * @return string
378
+ */
379
+ public function getDirUploads() {
380
+ $aDirParts = wp_get_upload_dir();
381
+ $bHasUploads = is_array( $aDirParts ) && !empty( $aDirParts[ 'basedir' ] )
382
+ && Services::WpFs()->exists( $aDirParts[ 'basedir' ] );
383
+ return $bHasUploads ? $aDirParts[ 'basedir' ] : '';
384
+ }
385
+
386
  /**
387
  * TODO: Create ClassicPress override class for this stuff
388
  * @param bool $bIgnoreClassicpress if true returns the $wp_version regardless of ClassicPress or not
416
  /**
417
  * @param string $sPluginBaseFilename
418
  * @return boolean
419
+ * @deprecated
420
  */
421
  public function getIsPluginAutomaticallyUpdated( $sPluginBaseFilename ) {
422
+ return Services::WpPlugins()->isPluginAutomaticallyUpdated( $sPluginBaseFilename );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
423
  }
424
 
425
  /**
714
  return (int)did_action( 'automatic_updates_complete' ) > 0;
715
  }
716
 
717
+ /**
718
+ * @return bool
719
+ */
720
+ public function canCoreUpdateAutomatically() {
721
+ global $required_php_version, $required_mysql_version;
722
+ $future_minor_update = (object)[
723
+ 'current' => $this->getVersion().'.1.next.minor',
724
+ 'version' => $this->getVersion().'.1.next.minor',
725
+ 'php_version' => $required_php_version,
726
+ 'mysql_version' => $required_mysql_version,
727
+ ];
728
+ return $this->getWpAutomaticUpdater()
729
+ ->should_update( 'core', $future_minor_update, ABSPATH );
730
+ }
731
+
732
+ /**
733
+ * @return array|false
734
+ */
735
+ public function getCoreUpdates() {
736
+ include_once( ABSPATH.'wp-admin/includes/update.php' );
737
+ return get_core_updates();
738
+ }
739
+
740
+ /**
741
+ * See: /wp-admin/update-core.php core_upgrade_preamble()
742
+ * @return bool
743
+ */
744
+ public function hasCoreUpdate() {
745
+ $aUpdates = $this->getCoreUpdates();
746
+ return ( isset( $aUpdates[ 0 ]->response ) && 'latest' != $aUpdates[ 0 ]->response );
747
+ }
748
+
749
  /**
750
  * Flushes the Rewrite rules and forces a re-commit to the .htaccess where applicable
751
  */
1134
  public function redirectToHome( $aQueryParams = [] ) {
1135
  Services::Response()->redirectToHome( $aQueryParams );
1136
  }
1137
+
1138
+ /**
1139
+ * @return bool
1140
+ * @deprecated
1141
+ */
1142
+ public function getIsRunningAutomaticUpdates() {
1143
+ return $this->isRunningAutomaticUpdates();
1144
+ }
1145
  }
src/lib/vendor/fernleafsystems/wordpress-services/src/Core/Includes.php CHANGED
@@ -34,6 +34,25 @@ class Includes {
34
  return $this->addIncludeModifiedParam( path_join( Services::WpGeneral()->getWpUrl(), $sInclude ), $sInclude );
35
  }
36
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  /**
38
  * @param $sUrl
39
  * @param $sInclude
34
  return $this->addIncludeModifiedParam( path_join( Services::WpGeneral()->getWpUrl(), $sInclude ), $sInclude );
35
  }
36
 
37
+ /**
38
+ * @param string $sIncludeHandle
39
+ * @param string $sAttribute
40
+ * @param string $sValue
41
+ * @return $this
42
+ */
43
+ public function addIncludeAttribute( $sIncludeHandle, $sAttribute, $sValue ) {
44
+ add_filter( 'script_loader_tag',
45
+ function ( $sTag, $sHandle ) use ( $sIncludeHandle, $sAttribute, $sValue ) {
46
+ if ( $sHandle == $sIncludeHandle && strpos( $sTag, $sAttribute.'=' ) === false ) {
47
+ $sTag = str_replace( ' src', sprintf( ' %s="%s" src', $sAttribute, $sValue ), $sTag );
48
+ }
49
+ return $sTag;
50
+ },
51
+ 10, 2
52
+ );
53
+ return $this;
54
+ }
55
+
56
  /**
57
  * @param $sUrl
58
  * @param $sInclude
src/lib/vendor/fernleafsystems/wordpress-services/src/Core/Plugins.php CHANGED
@@ -259,6 +259,22 @@ class Plugins {
259
 
260
  return $sFilename;
261
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
262
 
263
  /**
264
  * @param string $sFile - plugin base file, e.g. wp-folder/wp-plugin.php
@@ -315,14 +331,7 @@ class Plugins {
315
  * @return array|null
316
  */
317
  public function getPlugin( $sPluginFile ) {
318
- $aPlugin = null;
319
-
320
- $aPlugins = $this->getPlugins();
321
- if ( !empty( $sPluginFile ) && !empty( $aPlugins )
322
- && is_array( $aPlugins ) && array_key_exists( $sPluginFile, $aPlugins ) ) {
323
- $aPlugin = $aPlugins[ $sPluginFile ];
324
- }
325
- return $aPlugin;
326
  }
327
 
328
  /**
@@ -366,6 +375,13 @@ class Plugins {
366
  return $oWp->getOption( $sOptionKey );
367
  }
368
 
 
 
 
 
 
 
 
369
  /**
370
  * @return string[]
371
  */
@@ -551,12 +567,34 @@ class Plugins {
551
  * @return bool
552
  */
553
  public function isInstalled( $sFile ) {
554
- return !empty( $sFile ) && !is_null( $this->getPlugin( $sFile ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
555
  }
556
 
557
  /**
558
  * @param string $sFile
559
- * @return boolean|\stdClass
560
  */
561
  public function isUpdateAvailable( $sFile ) {
562
  return !is_null( $this->getUpdateInfo( $sFile ) );
259
 
260
  return $sFilename;
261
  }
262
+ /**
263
+ * @param string $sDirName
264
+ * @return string|null
265
+ */
266
+ public function findPluginFileFromDirName( $sDirName ) {
267
+ $sFile = null;
268
+ if ( !empty( $sDirName ) ) {
269
+ foreach ( $this->getInstalledBaseFiles() as $sF ) {
270
+ if ( strpos( $sFile, $sDirName.'/' ) === 0 ) {
271
+ $sFile = $sF;
272
+ break;
273
+ }
274
+ }
275
+ }
276
+ return $sFile;
277
+ }
278
 
279
  /**
280
  * @param string $sFile - plugin base file, e.g. wp-folder/wp-plugin.php
331
  * @return array|null
332
  */
333
  public function getPlugin( $sPluginFile ) {
334
+ return $this->isInstalled( $sPluginFile ) ? $this->getPlugins()[ $sPluginFile ] : null;
 
 
 
 
 
 
 
335
  }
336
 
337
  /**
375
  return $oWp->getOption( $sOptionKey );
376
  }
377
 
378
+ /**
379
+ * @return array
380
+ */
381
+ public function getInstalledBaseFiles() {
382
+ return array_keys( $this->getPlugins() );
383
+ }
384
+
385
  /**
386
  * @return string[]
387
  */
567
  * @return bool
568
  */
569
  public function isInstalled( $sFile ) {
570
+ return !empty( $sFile ) && in_array( $sFile, $this->getInstalledBaseFiles() );
571
+ }
572
+
573
+ /**
574
+ * @param string $sBaseFile
575
+ * @return bool
576
+ */
577
+ public function isPluginAutomaticallyUpdated( $sBaseFile ) {
578
+ $oUpdater = Services::WpGeneral()->getWpAutomaticUpdater();
579
+ if ( !$oUpdater ) {
580
+ return false;
581
+ }
582
+
583
+ // Due to a change in the filter introduced in version 3.8.2
584
+ if ( Services::WpGeneral()->getWordpressIsAtLeastVersion( '3.8.2' ) ) {
585
+ $mPluginItem = new \stdClass();
586
+ $mPluginItem->plugin = $sBaseFile;
587
+ }
588
+ else {
589
+ $mPluginItem = $sBaseFile;
590
+ }
591
+
592
+ return $oUpdater->should_update( 'plugin', $mPluginItem, WP_PLUGIN_DIR );
593
  }
594
 
595
  /**
596
  * @param string $sFile
597
+ * @return bool
598
  */
599
  public function isUpdateAvailable( $sFile ) {
600
  return !is_null( $this->getUpdateInfo( $sFile ) );
src/lib/vendor/fernleafsystems/wordpress-services/src/Core/Response.php CHANGED
@@ -16,6 +16,39 @@ class Response {
16
  public function __construct() {
17
  }
18
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  /**
20
  * @param string $sStringContent
21
  * @param string $sFilename
@@ -45,7 +78,7 @@ class Response {
45
  return;
46
  }
47
  else {
48
- Services::Data()->setCookie( 'icwp-isredirect', 'yes', 7 );
49
  }
50
  }
51
 
16
  public function __construct() {
17
  }
18
 
19
+ /**
20
+ * @param string $sKey
21
+ * @return bool
22
+ */
23
+ public function cookieDelete( $sKey ) {
24
+ unset( $_COOKIE[ $sKey ] );
25
+ return $this->cookieSet( $sKey, '', -1000000 );
26
+ }
27
+
28
+ /**
29
+ * @param string $sKey
30
+ * @param string $mValue
31
+ * @param int $nExpireLength
32
+ * @param null $sPath
33
+ * @param null $sDomain
34
+ * @param bool $bSsl
35
+ * @return bool
36
+ */
37
+ public function cookieSet( $sKey, $mValue, $nExpireLength = 3600, $sPath = null, $sDomain = null, $bSsl = null ) {
38
+ if ( function_exists( 'headers_sent' ) && headers_sent() ) {
39
+ return false;
40
+ }
41
+ $_COOKIE[ $sKey ] = $mValue;
42
+ return setcookie(
43
+ $sKey,
44
+ $mValue,
45
+ (int)( Services::Request()->ts() + $nExpireLength ),
46
+ ( is_null( $sPath ) && defined( 'COOKIEPATH' ) ) ? COOKIEPATH : $sPath,
47
+ ( is_null( $sDomain ) && defined( 'COOKIE_DOMAIN' ) ) ? COOKIE_DOMAIN : $sDomain,
48
+ is_null( $bSsl ) ? ( is_ssl() ? true : false ) : $bSsl
49
+ );
50
+ }
51
+
52
  /**
53
  * @param string $sStringContent
54
  * @param string $sFilename
78
  return;
79
  }
80
  else {
81
+ Services::Request()->cookie( 'icwp-isredirect', 'yes', 7 );
82
  }
83
  }
84
 
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Data.php CHANGED
@@ -335,49 +335,6 @@ class Data {
335
  return $aArray[ $sKey ];
336
  }
337
 
338
- /**
339
- * @param string $sRequestedUrl
340
- * @param string $sBaseUrl
341
- * @deprecated
342
- */
343
- public function doSendApache404( $sRequestedUrl, $sBaseUrl ) {
344
- Services::Response()->sendApache404();
345
- }
346
-
347
- /**
348
- * @param $sKey
349
- * @param $mValue
350
- * @param int $nExpireLength
351
- * @param null $sPath
352
- * @param null $sDomain
353
- * @param bool $bSsl
354
- *
355
- * @return bool
356
- */
357
- public function setCookie( $sKey, $mValue, $nExpireLength = 3600, $sPath = null, $sDomain = null, $bSsl = null ) {
358
- if ( function_exists( 'headers_sent' ) && headers_sent() ) {
359
- return false;
360
- }
361
- $_COOKIE[ $sKey ] = $mValue;
362
- return setcookie(
363
- $sKey,
364
- $mValue,
365
- (int)( Services::Request()->ts() + $nExpireLength ),
366
- ( is_null( $sPath ) && defined( 'COOKIEPATH' ) ) ? COOKIEPATH : $sPath,
367
- ( is_null( $sDomain ) && defined( 'COOKIE_DOMAIN' ) ) ? COOKIE_DOMAIN : $sDomain,
368
- is_null( $bSsl ) ? ( is_ssl() ? true : false ) : $bSsl
369
- );
370
- }
371
-
372
- /**
373
- * @param string $sKey
374
- * @return bool
375
- */
376
- public function setDeleteCookie( $sKey ) {
377
- unset( $_COOKIE[ $sKey ] );
378
- return $this->setCookie( $sKey, '', -3600 );
379
- }
380
-
381
  /**
382
  * Effectively validates and IP Address.
383
  *
@@ -509,4 +466,36 @@ class Data {
509
  public function downloadStringAsFile( $sStringContent, $sFilename ) {
510
  Services::Response()->downloadStringAsFile( $sStringContent, $sFilename );
511
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
512
  }
335
  return $aArray[ $sKey ];
336
  }
337
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
338
  /**
339
  * Effectively validates and IP Address.
340
  *
466
  public function downloadStringAsFile( $sStringContent, $sFilename ) {
467
  Services::Response()->downloadStringAsFile( $sStringContent, $sFilename );
468
  }
469
+
470
+ /**
471
+ * @param string $sRequestedUrl
472
+ * @param string $sBaseUrl
473
+ * @deprecated
474
+ */
475
+ public function doSendApache404( $sRequestedUrl, $sBaseUrl ) {
476
+ Services::Response()->sendApache404( $sRequestedUrl, $sBaseUrl );
477
+ }
478
+
479
+ /**
480
+ * @param $sKey
481
+ * @param $mValue
482
+ * @param int $nExpireLength
483
+ * @param null $sPath
484
+ * @param null $sDomain
485
+ * @param bool $bSsl
486
+ * @return bool
487
+ * @deprecated
488
+ */
489
+ public function setCookie( $sKey, $mValue, $nExpireLength = 3600, $sPath = null, $sDomain = null, $bSsl = null ) {
490
+ return Services::Response()->cookieSet( $sKey, $mValue, $nExpireLength, $sPath, $sDomain, $bSsl );
491
+ }
492
+
493
+ /**
494
+ * @param string $sKey
495
+ * @return bool
496
+ * @deprecated
497
+ */
498
+ public function setDeleteCookie( $sKey ) {
499
+ return Services::Response()->cookieDelete( $sKey );
500
+ }
501
  }
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Licenses/EddLicenseVO.php ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace FernleafSystems\Wordpress\Services\Utilities\Licenses;
4
+
5
+ use FernleafSystems\Wordpress\Services\Services;
6
+
7
+ /**
8
+ * Class EddLicenseVO
9
+ * @package FernleafSystems\Wordpress\Services\Utilities\Licenses
10
+ * @property int $activations_left
11
+ * @property string $customer_email
12
+ * @property string $checksum
13
+ * @property string $customer_name
14
+ * @property string $item_name
15
+ * @property int $last_request_at
16
+ * @property int $last_verified_at
17
+ * @property int $license_limit
18
+ * @property int $site_count
19
+ * @property string $license
20
+ * @property string $payment_id
21
+ * @property bool $success
22
+ * @property string $error
23
+ */
24
+ class EddLicenseVO {
25
+
26
+ use \FernleafSystems\Utilities\Data\Adapter\StdClassAdapter;
27
+
28
+ /**
29
+ * @return int
30
+ */
31
+ public function getExpiresAt() {
32
+ $sTime = $this->getParam( 'expires' );
33
+ return ( $sTime == 'lifetime' ) ? PHP_INT_MAX : strtotime( $sTime );
34
+ }
35
+
36
+ /**
37
+ * @return bool
38
+ */
39
+ public function isExpired() {
40
+ return ( $this->getExpiresAt() < Services::Request()->ts() );
41
+ }
42
+
43
+ /**
44
+ * @return bool
45
+ */
46
+ public function isValid() {
47
+ return ( $this->isReady() && $this->success && !$this->isExpired() && $this->license == 'valid' );
48
+ }
49
+
50
+ /**
51
+ * @return bool
52
+ */
53
+ public function hasError() {
54
+ return !empty( $this->error );
55
+ }
56
+
57
+ /**
58
+ * @return bool
59
+ */
60
+ public function hasChecksum() {
61
+ return !empty( $this->checksum );
62
+ }
63
+
64
+ /**
65
+ * @return bool
66
+ */
67
+ public function isReady() {
68
+ return $this->hasChecksum();
69
+ }
70
+
71
+ /**
72
+ * @param bool $bAddRandom
73
+ * @return $this
74
+ */
75
+ public function updateLastVerifiedAt( $bAddRandom = false ) {
76
+ $nRandom = $bAddRandom ? rand( -12, 12 )*HOUR_IN_SECONDS : 0;
77
+ return $this->setParam( 'last_verified_at', $this->last_request_at + $nRandom );
78
+ }
79
+ }
src/lib/vendor/phpgangsta/googleauthenticator/PHPGangsta/GoogleAuthenticator.php ADDED
@@ -0,0 +1,252 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * PHP Class for handling Google Authenticator 2-factor authentication.
5
+ *
6
+ * @author Michael Kliewe
7
+ * @copyright 2012 Michael Kliewe
8
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
9
+ *
10
+ * @link http://www.phpgangsta.de/
11
+ */
12
+ class PHPGangsta_GoogleAuthenticator
13
+ {
14
+ protected $_codeLength = 6;
15
+
16
+ /**
17
+ * Create new secret.
18
+ * 16 characters, randomly chosen from the allowed base32 characters.
19
+ *
20
+ * @param int $secretLength
21
+ *
22
+ * @return string
23
+ */
24
+ public function createSecret($secretLength = 16)
25
+ {
26
+ $validChars = $this->_getBase32LookupTable();
27
+
28
+ // Valid secret lengths are 80 to 640 bits
29
+ if ($secretLength < 16 || $secretLength > 128) {
30
+ throw new Exception('Bad secret length');
31
+ }
32
+ $secret = '';
33
+ $rnd = false;
34
+ if (function_exists('random_bytes')) {
35
+ $rnd = random_bytes($secretLength);
36
+ } elseif (function_exists('mcrypt_create_iv')) {
37
+ $rnd = mcrypt_create_iv($secretLength, MCRYPT_DEV_URANDOM);
38
+ } elseif (function_exists('openssl_random_pseudo_bytes')) {
39
+ $rnd = openssl_random_pseudo_bytes($secretLength, $cryptoStrong);
40
+ if (!$cryptoStrong) {
41
+ $rnd = false;
42
+ }
43
+ }
44
+ if ($rnd !== false) {
45
+ for ($i = 0; $i < $secretLength; ++$i) {
46
+ $secret .= $validChars[ord($rnd[$i]) & 31];
47
+ }
48
+ } else {
49
+ throw new Exception('No source of secure random');
50
+ }
51
+
52
+ return $secret;
53
+ }
54
+
55
+ /**
56
+ * Calculate the code, with given secret and point in time.
57
+ *
58
+ * @param string $secret
59
+ * @param int|null $timeSlice
60
+ *
61
+ * @return string
62
+ */
63
+ public function getCode($secret, $timeSlice = null)
64
+ {
65
+ if ($timeSlice === null) {
66
+ $timeSlice = floor(time() / 30);
67
+ }
68
+
69
+ $secretkey = $this->_base32Decode($secret);
70
+
71
+ // Pack time into binary string
72
+ $time = chr(0).chr(0).chr(0).chr(0).pack('N*', $timeSlice);
73
+ // Hash it with users secret key
74
+ $hm = hash_hmac('SHA1', $time, $secretkey, true);
75
+ // Use last nipple of result as index/offset
76
+ $offset = ord(substr($hm, -1)) & 0x0F;
77
+ // grab 4 bytes of the result
78
+ $hashpart = substr($hm, $offset, 4);
79
+
80
+ // Unpak binary value
81
+ $value = unpack('N', $hashpart);
82
+ $value = $value[1];
83
+ // Only 32 bits
84
+ $value = $value & 0x7FFFFFFF;
85
+
86
+ $modulo = pow(10, $this->_codeLength);
87
+
88
+ return str_pad($value % $modulo, $this->_codeLength, '0', STR_PAD_LEFT);
89
+ }
90
+
91
+ /**
92
+ * Get QR-Code URL for image, from google charts.
93
+ *
94
+ * @param string $name
95
+ * @param string $secret
96
+ * @param string $title
97
+ * @param array $params
98
+ *
99
+ * @return string
100
+ */
101
+ public function getQRCodeGoogleUrl($name, $secret, $title = null, $params = array())
102
+ {
103
+ $width = !empty($params['width']) && (int) $params['width'] > 0 ? (int) $params['width'] : 200;
104
+ $height = !empty($params['height']) && (int) $params['height'] > 0 ? (int) $params['height'] : 200;
105
+ $level = !empty($params['level']) && array_search($params['level'], array('L', 'M', 'Q', 'H')) !== false ? $params['level'] : 'M';
106
+
107
+ $urlencoded = urlencode('otpauth://totp/'.$name.'?secret='.$secret.'');
108
+ if (isset($title)) {
109
+ $urlencoded .= urlencode('&issuer='.urlencode($title));
110
+ }
111
+
112
+ return "https://api.qrserver.com/v1/create-qr-code/?data=$urlencoded&size=${width}x${height}&ecc=$level";
113
+ }
114
+
115
+ /**
116
+ * Check if the code is correct. This will accept codes starting from $discrepancy*30sec ago to $discrepancy*30sec from now.
117
+ *
118
+ * @param string $secret
119
+ * @param string $code
120
+ * @param int $discrepancy This is the allowed time drift in 30 second units (8 means 4 minutes before or after)
121
+ * @param int|null $currentTimeSlice time slice if we want use other that time()
122
+ *
123
+ * @return bool
124
+ */
125
+ public function verifyCode($secret, $code, $discrepancy = 1, $currentTimeSlice = null)
126
+ {
127
+ if ($currentTimeSlice === null) {
128
+ $currentTimeSlice = floor(time() / 30);
129
+ }
130
+
131
+ if (strlen($code) != 6) {
132
+ return false;
133
+ }
134
+
135
+ for ($i = -$discrepancy; $i <= $discrepancy; ++$i) {
136
+ $calculatedCode = $this->getCode($secret, $currentTimeSlice + $i);
137
+ if ($this->timingSafeEquals($calculatedCode, $code)) {
138
+ return true;
139
+ }
140
+ }
141
+
142
+ return false;
143
+ }
144
+
145
+ /**
146
+ * Set the code length, should be >=6.
147
+ *
148
+ * @param int $length
149
+ *
150
+ * @return PHPGangsta_GoogleAuthenticator
151
+ */
152
+ public function setCodeLength($length)
153
+ {
154
+ $this->_codeLength = $length;
155
+
156
+ return $this;
157
+ }
158
+
159
+ /**
160
+ * Helper class to decode base32.
161
+ *
162
+ * @param $secret
163
+ *
164
+ * @return bool|string
165
+ */
166
+ protected function _base32Decode($secret)
167
+ {
168
+ if (empty($secret)) {
169
+ return '';
170
+ }
171
+
172
+ $base32chars = $this->_getBase32LookupTable();
173
+ $base32charsFlipped = array_flip($base32chars);
174
+
175
+ $paddingCharCount = substr_count($secret, $base32chars[32]);
176
+ $allowedValues = array(6, 4, 3, 1, 0);
177
+ if (!in_array($paddingCharCount, $allowedValues)) {
178
+ return false;
179
+ }
180
+ for ($i = 0; $i < 4; ++$i) {
181
+ if ($paddingCharCount == $allowedValues[$i] &&
182
+ substr($secret, -($allowedValues[$i])) != str_repeat($base32chars[32], $allowedValues[$i])) {
183
+ return false;
184
+ }
185
+ }
186
+ $secret = str_replace('=', '', $secret);
187
+ $secret = str_split($secret);
188
+ $binaryString = '';
189
+ for ($i = 0; $i < count($secret); $i = $i + 8) {
190
+ $x = '';
191
+ if (!in_array($secret[$i], $base32chars)) {
192
+ return false;
193
+ }
194
+ for ($j = 0; $j < 8; ++$j) {
195
+ $x .= str_pad(base_convert(@$base32charsFlipped[@$secret[$i + $j]], 10, 2), 5, '0', STR_PAD_LEFT);
196
+ }
197
+ $eightBits = str_split($x, 8);
198
+ for ($z = 0; $z < count($eightBits); ++$z) {
199
+ $binaryString .= (($y = chr(base_convert($eightBits[$z], 2, 10))) || ord($y) == 48) ? $y : '';
200
+ }
201
+ }
202
+
203
+ return $binaryString;
204
+ }
205
+
206
+ /**
207
+ * Get array with all 32 characters for decoding from/encoding to base32.
208
+ *
209
+ * @return array
210
+ */
211
+ protected function _getBase32LookupTable()
212
+ {
213
+ return array(
214
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', // 7
215
+ 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', // 15
216
+ 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', // 23
217
+ 'Y', 'Z', '2', '3', '4', '5', '6', '7', // 31
218
+ '=', // padding char
219
+ );
220
+ }
221
+
222
+ /**
223
+ * A timing safe equals comparison
224
+ * more info here: http://blog.ircmaxell.com/2014/11/its-all-about-time.html.
225
+ *
226
+ * @param string $safeString The internal (safe) value to be checked
227
+ * @param string $userString The user submitted (unsafe) value
228
+ *
229
+ * @return bool True if the two strings are identical
230
+ */
231
+ private function timingSafeEquals($safeString, $userString)
232
+ {
233
+ if (function_exists('hash_equals')) {
234
+ return hash_equals($safeString, $userString);
235
+ }
236
+ $safeLen = strlen($safeString);
237
+ $userLen = strlen($userString);
238
+
239
+ if ($userLen != $safeLen) {
240
+ return false;
241
+ }
242
+
243
+ $result = 0;
244
+
245
+ for ($i = 0; $i < $userLen; ++$i) {
246
+ $result |= (ord($safeString[$i]) ^ ord($userString[$i]));
247
+ }
248
+
249
+ // They are only identical strings if $result is exactly 0...
250
+ return $result === 0;
251
+ }
252
+ }
src/processors/admin_access_restriction.php CHANGED
@@ -115,7 +115,7 @@ class ICWP_WPSF_Processor_AdminAccessRestriction extends ICWP_WPSF_Processor_Bas
115
  * @param string $sRole
116
  */
117
  public function restrictAddUserRole( $nUserId, $sRole ) {
118
- $oWpUsers = $this->loadWpUsers();
119
 
120
  if ( $oWpUsers->getCurrentWpUserId() !== $nUserId && strtolower( $sRole ) === 'administrator' ) {
121
  $oModUser = $oWpUsers->getUserById( $nUserId );
@@ -131,7 +131,7 @@ class ICWP_WPSF_Processor_AdminAccessRestriction extends ICWP_WPSF_Processor_Bas
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 ) ) {
@@ -172,7 +172,7 @@ class ICWP_WPSF_Processor_AdminAccessRestriction extends ICWP_WPSF_Processor_Bas
172
  * @param string $sRole
173
  */
174
  public function restrictRemoveUserRole( $nUserId, $sRole ) {
175
- $oWpUsers = $this->loadWpUsers();
176
 
177
  if ( $oWpUsers->getCurrentWpUserId() !== $nUserId && strtolower( $sRole ) === 'administrator' ) {
178
  $oModUser = $oWpUsers->getUserById( $nUserId );
@@ -186,11 +186,11 @@ class ICWP_WPSF_Processor_AdminAccessRestriction extends ICWP_WPSF_Processor_Bas
186
  * @param int $nId
187
  */
188
  public function restrictAdminUserDelete( $nId ) {
189
- $oWpUsers = $this->loadWpUsers();
190
  $oUserToDelete = $oWpUsers->getUserById( $nId );
191
  if ( $oUserToDelete && $oWpUsers->isUserAdmin( $oUserToDelete ) ) {
192
- $this->loadWp()
193
- ->wpDie( 'Sorry, deleting administrators is currently restricted to your Security Admin' );
194
  }
195
  }
196
 
@@ -224,8 +224,8 @@ class ICWP_WPSF_Processor_AdminAccessRestriction extends ICWP_WPSF_Processor_Bas
224
  if ( in_array( $sUserCap, $aReleventCaps ) ) {
225
  $bBlockCapability = false;
226
 
227
- $oReq = $this->loadRequest();
228
- $oWpUsers = $this->loadWpUsers();
229
 
230
  // Find the WP_User for the POST
231
  $oPostUser = false;
@@ -276,8 +276,8 @@ class ICWP_WPSF_Processor_AdminAccessRestriction extends ICWP_WPSF_Processor_Bas
276
  return;
277
  }
278
 
279
- $sCurrentPage = $this->loadWp()->getCurrentPage();
280
- $sCurrentGetPage = $this->loadRequest()->query( 'page' );
281
  if ( !in_array( $sCurrentPage, $oFO->getOptionsPagesToRestrict() ) || !empty( $sCurrentGetPage ) ) {
282
  return;
283
  }
@@ -316,8 +316,7 @@ class ICWP_WPSF_Processor_AdminAccessRestriction extends ICWP_WPSF_Processor_Bas
316
  /** @var ICWP_WPSF_FeatureHandler_AdminAccessRestriction $oFO */
317
  $oFO = $this->getMod();
318
 
319
- $sCurrentPage = $this->loadWp()->getCurrentPage();
320
- if ( !in_array( $sCurrentPage, $this->getUserPagesToRestrict() ) ) {
321
  return;
322
  }
323
 
@@ -409,7 +408,7 @@ class ICWP_WPSF_Processor_AdminAccessRestriction extends ICWP_WPSF_Processor_Bas
409
  public function disablePluginManipulation( $aAllCaps, $cap, $aArgs ) {
410
  /** @var ICWP_WPSF_FeatureHandler_AdminAccessRestriction $oFO */
411
  $oFO = $this->getMod();
412
- $oReq = $this->loadRequest();
413
 
414
  /** @var string $sRequestedCapability */
415
  $sRequestedCapability = $aArgs[ 0 ];
115
  * @param string $sRole
116
  */
117
  public function restrictAddUserRole( $nUserId, $sRole ) {
118
+ $oWpUsers = Services::WpUsers();
119
 
120
  if ( $oWpUsers->getCurrentWpUserId() !== $nUserId && strtolower( $sRole ) === 'administrator' ) {
121
  $oModUser = $oWpUsers->getUserById( $nUserId );
131
  * @param array $aOldRoles
132
  */
133
  public function restrictSetUserRole( $nUserId, $sRole, $aOldRoles = [] ) {
134
+ $oWpUsers = Services::WpUsers();
135
 
136
  $sRole = strtolower( $sRole );
137
  if ( !is_array( $aOldRoles ) ) {
172
  * @param string $sRole
173
  */
174
  public function restrictRemoveUserRole( $nUserId, $sRole ) {
175
+ $oWpUsers = Services::WpUsers();
176
 
177
  if ( $oWpUsers->getCurrentWpUserId() !== $nUserId && strtolower( $sRole ) === 'administrator' ) {
178
  $oModUser = $oWpUsers->getUserById( $nUserId );
186
  * @param int $nId
187
  */
188
  public function restrictAdminUserDelete( $nId ) {
189
+ $oWpUsers = Services::WpUsers();
190
  $oUserToDelete = $oWpUsers->getUserById( $nId );
191
  if ( $oUserToDelete && $oWpUsers->isUserAdmin( $oUserToDelete ) ) {
192
+ Services::WpGeneral()
193
+ ->wpDie( __( 'Sorry, deleting administrators is currently restricted to your Security Admin', 'wp-simple-firewall' ) );
194
  }
195
  }
196
 
224
  if ( in_array( $sUserCap, $aReleventCaps ) ) {
225
  $bBlockCapability = false;
226
 
227
+ $oReq = Services::Request();
228
+ $oWpUsers = Services::WpUsers();
229
 
230
  // Find the WP_User for the POST
231
  $oPostUser = false;
276
  return;
277
  }
278
 
279
+ $sCurrentPage = Services::WpPost()->getCurrentPage();
280
+ $sCurrentGetPage = Services::Request()->query( 'page' );
281
  if ( !in_array( $sCurrentPage, $oFO->getOptionsPagesToRestrict() ) || !empty( $sCurrentGetPage ) ) {
282
  return;
283
  }
316
  /** @var ICWP_WPSF_FeatureHandler_AdminAccessRestriction $oFO */
317
  $oFO = $this->getMod();
318
 
319
+ if ( !in_array( Services::WpPost()->getCurrentPage(), $this->getUserPagesToRestrict() ) ) {
 
320
  return;
321
  }
322
 
408
  public function disablePluginManipulation( $aAllCaps, $cap, $aArgs ) {
409
  /** @var ICWP_WPSF_FeatureHandler_AdminAccessRestriction $oFO */
410
  $oFO = $this->getMod();
411
+ $oReq = Services::Request();
412
 
413
  /** @var string $sRequestedCapability */
414
  $sRequestedCapability = $aArgs[ 0 ];
src/processors/adminaccess_whitelabel.php CHANGED
@@ -1,5 +1,7 @@
1
  <?php
2
 
 
 
3
  class ICWP_WPSF_Processor_AdminAccess_Whitelabel extends ICWP_WPSF_Processor_BaseWpsf {
4
 
5
  /**
@@ -30,8 +32,7 @@ class ICWP_WPSF_Processor_AdminAccess_Whitelabel extends ICWP_WPSF_Processor_Bas
30
  * or we adjust the number of displayed updates counts
31
  */
32
  protected function hideUpdates() {
33
- $sCurrent = $this->loadWp()->getCurrentPage();
34
- if ( in_array( $sCurrent, [ 'plugins.php', 'update-core.php' ] ) ) {
35
  add_filter( 'site_transient_update_plugins', [ $this, 'hidePluginUpdatesFromUI' ] );
36
  }
37
  else {
@@ -47,7 +48,7 @@ class ICWP_WPSF_Processor_AdminAccess_Whitelabel extends ICWP_WPSF_Processor_Bas
47
  public function adjustUpdateDataCount( $aUpdateData ) {
48
 
49
  $sFile = $this->getCon()->getPluginBaseFile();
50
- if ( $this->loadWpPlugins()->isUpdateAvailable( $sFile ) ) {
51
  $aUpdateData[ 'counts' ][ 'total' ]--;
52
  $aUpdateData[ 'counts' ][ 'plugins' ]--;
53
  }
@@ -135,7 +136,6 @@ class ICWP_WPSF_Processor_AdminAccess_Whitelabel extends ICWP_WPSF_Processor_Bas
135
  * @return bool
136
  */
137
  private function isNeedToHideUpdates() {
138
- $oWp = $this->loadWp();
139
- return is_admin() && !$oWp->isCron();
140
  }
141
  }
1
  <?php
2
 
3
+ use FernleafSystems\Wordpress\Services\Services; //TODO: Use after 7.5
4
+
5
  class ICWP_WPSF_Processor_AdminAccess_Whitelabel extends ICWP_WPSF_Processor_BaseWpsf {
6
 
7
  /**
32
  * or we adjust the number of displayed updates counts
33
  */
34
  protected function hideUpdates() {
35
+ if ( in_array( Services::WpPost()->getCurrentPage(), [ 'plugins.php', 'update-core.php' ] ) ) {
 
36
  add_filter( 'site_transient_update_plugins', [ $this, 'hidePluginUpdatesFromUI' ] );
37
  }
38
  else {
48
  public function adjustUpdateDataCount( $aUpdateData ) {
49
 
50
  $sFile = $this->getCon()->getPluginBaseFile();
51
+ if ( \FernleafSystems\Wordpress\Services\Services::WpPlugins()->isUpdateAvailable( $sFile ) ) {
52
  $aUpdateData[ 'counts' ][ 'total' ]--;
53
  $aUpdateData[ 'counts' ][ 'plugins' ]--;
54
  }
136
  * @return bool
137
  */
138
  private function isNeedToHideUpdates() {
139
+ return is_admin() && !Services::WpGeneral()->isCron();
 
140
  }
141
  }
src/processors/audit_trail_auditor.php CHANGED
@@ -16,7 +16,7 @@ class ICWP_WPSF_Processor_AuditTrail_Auditor extends ICWP_WPSF_BaseDbProcessor {
16
  */
17
  public function init() {
18
  parent::init();
19
- add_action( $this->getMod()->prefix( 'add_new_audit_entry' ), [ $this, 'addAuditTrialEntry' ] );
20
  }
21
 
22
  public function cleanupDatabase() {
16
  */
17
  public function init() {
18
  parent::init();
19
+ add_action( $this->getCon()->prefix( 'add_new_audit_entry' ), [ $this, 'addAuditTrialEntry' ] );
20
  }
21
 
22
  public function cleanupDatabase() {
src/processors/audit_trail_plugins.php CHANGED
@@ -37,8 +37,8 @@ class ICWP_WPSF_Processor_AuditTrail_Plugins extends ICWP_WPSF_AuditTrail_Audito
37
  }
38
 
39
  /**
40
- * @param string $sAction
41
- * @param boolean $bResult
42
  */
43
  public function auditEditedPluginFile( $sAction, $bResult ) {
44
 
37
  }
38
 
39
  /**
40
+ * @param string $sAction
41
+ * @param bool $bResult
42
  */
43
  public function auditEditedPluginFile( $sAction, $bResult ) {
44
 
src/processors/audit_trail_users.php CHANGED
@@ -1,5 +1,7 @@
1
  <?php
2
 
 
 
3
  class ICWP_WPSF_Processor_AuditTrail_Users extends ICWP_WPSF_AuditTrail_Auditor_Base {
4
 
5
  /**
@@ -27,7 +29,7 @@ class ICWP_WPSF_Processor_AuditTrail_Users extends ICWP_WPSF_AuditTrail_Auditor_
27
  */
28
  public function auditNewUserRegistered( $nUserId ) {
29
 
30
- $oNewUser = empty( $nUserId ) ? null : $this->loadWpUsers()->getUserById( $nUserId );
31
  if ( !empty( $oNewUser ) ) {
32
  $this->add( 'users', 'user_registered', 1,
33
  __( 'New WordPress user registered.', 'wp-simple-firewall' ).' '
@@ -44,7 +46,7 @@ class ICWP_WPSF_Processor_AuditTrail_Users extends ICWP_WPSF_AuditTrail_Auditor_
44
  * @param int $nReassigned
45
  */
46
  public function auditDeleteUser( $nUserId, $nReassigned ) {
47
- $oWpUsers = $this->loadWpUsers();
48
 
49
  $aAuditMessage = [ __( 'WordPress user deleted.', 'wp-simple-firewall' ) ];
50
 
1
  <?php
2
 
3
+ use FernleafSystems\Wordpress\Services\Services;
4
+
5
  class ICWP_WPSF_Processor_AuditTrail_Users extends ICWP_WPSF_AuditTrail_Auditor_Base {
6
 
7
  /**
29
  */
30
  public function auditNewUserRegistered( $nUserId ) {
31
 
32
+ $oNewUser = empty( $nUserId ) ? null : Services::WpUsers()->getUserById( $nUserId );
33
  if ( !empty( $oNewUser ) ) {
34
  $this->add( 'users', 'user_registered', 1,
35
  __( 'New WordPress user registered.', 'wp-simple-firewall' ).' '
46
  * @param int $nReassigned
47
  */
48
  public function auditDeleteUser( $nUserId, $nReassigned ) {
49
+ $oWpUsers = Services::WpUsers();
50
 
51
  $aAuditMessage = [ __( 'WordPress user deleted.', 'wp-simple-firewall' ) ];
52
 
src/processors/audit_trail_wordpress.php CHANGED
@@ -1,5 +1,7 @@
1
  <?php
2
 
 
 
3
  class ICWP_WPSF_Processor_AuditTrail_Wordpress extends ICWP_WPSF_AuditTrail_Auditor_Base {
4
 
5
  /**
@@ -13,9 +15,11 @@ class ICWP_WPSF_Processor_AuditTrail_Wordpress extends ICWP_WPSF_AuditTrail_Audi
13
  * @param string $sNewCoreVersion
14
  */
15
  public function auditCoreUpdated( $sNewCoreVersion ) {
16
- global $wp_version;
17
  $this->add( 'wordpress', 'core_updated', 1,
18
- sprintf( __( 'WordPress Core was updated from "v%s" to "v%s".', 'wp-simple-firewall' ), $wp_version, $sNewCoreVersion )
 
 
 
19
  );
20
  }
21
 
1
  <?php
2
 
3
+ use FernleafSystems\Wordpress\Services\Services;
4
+
5
  class ICWP_WPSF_Processor_AuditTrail_Wordpress extends ICWP_WPSF_AuditTrail_Auditor_Base {
6
 
7
  /**
15
  * @param string $sNewCoreVersion
16
  */
17
  public function auditCoreUpdated( $sNewCoreVersion ) {
 
18
  $this->add( 'wordpress', 'core_updated', 1,
19
+ sprintf( __( 'WordPress Core was updated from "v%s" to "v%s".', 'wp-simple-firewall' ),
20
+ Services::WpGeneral()->getVersion(),
21
+ $sNewCoreVersion
22
+ )
23
  );
24
  }
25
 
src/processors/autoupdates.php CHANGED
@@ -293,7 +293,7 @@ class ICWP_WPSF_Processor_Autoupdates extends ICWP_WPSF_Processor_BaseWpsf {
293
  $bDoAutoUpdate = false;
294
  }
295
  else {
296
- $sFile = $this->loadWp()->getFileFromAutomaticUpdateItem( $mItem );
297
 
298
  if ( $this->isDelayed( $sFile, 'plugins' ) ) {
299
  return false;
@@ -334,7 +334,7 @@ class ICWP_WPSF_Processor_Autoupdates extends ICWP_WPSF_Processor_BaseWpsf {
334
  $bDoAutoUpdate = false;
335
  }
336
  else {
337
- $sFile = $this->loadWp()->getFileFromAutomaticUpdateItem( $mItem, 'theme' );
338
 
339
  if ( $this->isDelayed( $sFile, 'themes' ) ) {
340
  return false;
@@ -378,11 +378,11 @@ class ICWP_WPSF_Processor_Autoupdates extends ICWP_WPSF_Processor_BaseWpsf {
378
  $aItemTk = isset( $aTk[ $sContext ][ $sSlug ] ) ? $aTk[ $sContext ][ $sSlug ] : [];
379
 
380
  if ( $sContext == 'plugins' ) {
381
- $oPlugin = $this->loadWpPlugins()->getUpdateInfo( $sSlug );
382
  $sVersion = isset( $oPlugin->new_version ) ? $oPlugin->new_version : '';
383
  }
384
  else if ( $sContext == 'themes' ) {
385
- $aThemeInfo = $this->loadWpThemes()->getUpdateInfo( $sSlug );
386
  $sVersion = isset( $aThemeInfo[ 'new_version' ] ) ? $aThemeInfo[ 'new_version' ] : '';
387
  }
388
 
@@ -432,7 +432,7 @@ class ICWP_WPSF_Processor_Autoupdates extends ICWP_WPSF_Processor_BaseWpsf {
432
  return $aPluginMeta;
433
  }
434
  }
435
- $bUpdate = $this->loadWp()->isPluginAutomaticallyUpdated( $sPluginBaseFileName );
436
  $sHtml = $this->getPluginAutoupdateIconHtml( $bUpdate );
437
  array_unshift( $aPluginMeta, sprintf( '%s', $sHtml ) );
438
  return $aPluginMeta;
@@ -464,7 +464,7 @@ class ICWP_WPSF_Processor_Autoupdates extends ICWP_WPSF_Processor_BaseWpsf {
464
  }
465
  /** @var ICWP_WPSF_FeatureHandler_Autoupdates $oFO */
466
  $oFO = $this->getMod();
467
- $bUpdate = $this->loadWp()->isPluginAutomaticallyUpdated( $sPluginBaseFileName );
468
  // $bUpdate = in_array( $sPluginBaseFileName, $oFO->getAutoupdatePlugins() );
469
  $bDisabled = $bUpdate && !in_array( $sPluginBaseFileName, $oFO->getAutoupdatePlugins() );
470
  echo $this->getPluginAutoupdateIconHtml( $sPluginBaseFileName, $bUpdate, $bDisabled );
293
  $bDoAutoUpdate = false;
294
  }
295
  else {
296
+ $sFile = Services::WpGeneral()->getFileFromAutomaticUpdateItem( $mItem );
297
 
298
  if ( $this->isDelayed( $sFile, 'plugins' ) ) {
299
  return false;
334
  $bDoAutoUpdate = false;
335
  }
336
  else {
337
+ $sFile = Services::WpGeneral()->getFileFromAutomaticUpdateItem( $mItem, 'theme' );
338
 
339
  if ( $this->isDelayed( $sFile, 'themes' ) ) {
340
  return false;
378
  $aItemTk = isset( $aTk[ $sContext ][ $sSlug ] ) ? $aTk[ $sContext ][ $sSlug ] : [];
379
 
380
  if ( $sContext == 'plugins' ) {
381
+ $oPlugin = Services::WpPlugins()->getUpdateInfo( $sSlug );
382
  $sVersion = isset( $oPlugin->new_version ) ? $oPlugin->new_version : '';
383
  }
384
  else if ( $sContext == 'themes' ) {
385
+ $aThemeInfo = Services::WpThemes()->getUpdateInfo( $sSlug );
386
  $sVersion = isset( $aThemeInfo[ 'new_version' ] ) ? $aThemeInfo[ 'new_version' ] : '';
387
  }
388
 
432
  return $aPluginMeta;
433
  }
434
  }
435
+ $bUpdate = Services::WpPlugins()->isPluginAutomaticallyUpdated( $sPluginBaseFileName );
436
  $sHtml = $this->getPluginAutoupdateIconHtml( $bUpdate );
437
  array_unshift( $aPluginMeta, sprintf( '%s', $sHtml ) );
438
  return $aPluginMeta;
464
  }
465
  /** @var ICWP_WPSF_FeatureHandler_Autoupdates $oFO */
466
  $oFO = $this->getMod();
467
+ $bUpdate = Services::WpPlugins()->isPluginAutomaticallyUpdated( $sPluginBaseFileName );
468
  // $bUpdate = in_array( $sPluginBaseFileName, $oFO->getAutoupdatePlugins() );
469
  $bDisabled = $bUpdate && !in_array( $sPluginBaseFileName, $oFO->getAutoupdatePlugins() );
470
  echo $this->getPluginAutoupdateIconHtml( $sPluginBaseFileName, $bUpdate, $bDisabled );
src/processors/base.php CHANGED
@@ -167,7 +167,7 @@ abstract class ICWP_WPSF_Processor_Base extends ICWP_WPSF_Foundation {
167
  $bDisplay = false;
168
  }
169
  else if ( $aAttrs[ 'schedule' ] == 'once'
170
- && ( !$this->loadWpUsers()->canSaveMeta() || $oWpNotices->isDismissed( $aAttrs[ 'id' ] ) ) ) {
171
  $bDisplay = false;
172
  }
173
  else if ( $aAttrs[ 'type' ] == 'promo' && Services::WpGeneral()->isMobile() ) {
@@ -242,7 +242,7 @@ abstract class ICWP_WPSF_Processor_Base extends ICWP_WPSF_Foundation {
242
  * @return string
243
  */
244
  protected function getGoogleRecaptchaLocale() {
245
- return $this->loadWp()->getLocale( '-' );
246
  }
247
 
248
  /**
167
  $bDisplay = false;
168
  }
169
  else if ( $aAttrs[ 'schedule' ] == 'once'
170
+ && ( !Services::WpUsers()->canSaveMeta() || $oWpNotices->isDismissed( $aAttrs[ 'id' ] ) ) ) {
171
  $bDisplay = false;
172
  }
173
  else if ( $aAttrs[ 'type' ] == 'promo' && Services::WpGeneral()->isMobile() ) {
242
  * @return string
243
  */
244
  protected function getGoogleRecaptchaLocale() {
245
+ return Services::WpGeneral()->getLocale( '-' );
246
  }
247
 
248
  /**
src/processors/base_wpsf.php CHANGED
@@ -1,5 +1,7 @@
1
  <?php
2
 
 
 
3
  abstract class ICWP_WPSF_Processor_BaseWpsf extends ICWP_WPSF_Processor_Base {
4
 
5
  const RECAPTCHA_JS_HANDLE = 'icwp-google-recaptcha';
@@ -50,7 +52,7 @@ abstract class ICWP_WPSF_Processor_BaseWpsf extends ICWP_WPSF_Processor_Base {
50
  $bIsSubject = false;
51
 
52
  if ( !$oUser instanceof WP_User ) {
53
- $oUser = $this->loadWpUsers()->getCurrentWpUser();
54
  }
55
  if ( $oUser instanceof WP_User ) {
56
  $bIsSubject = apply_filters( $this->prefix( 'user_subject_to_login_intent' ), false, $oUser );
@@ -89,15 +91,16 @@ abstract class ICWP_WPSF_Processor_BaseWpsf extends ICWP_WPSF_Processor_Base {
89
  throw new \Exception( __( 'Whoops.', 'wp-simple-firewall' ).' '.__( 'Google reCAPTCHA was not submitted.', 'wp-simple-firewall' ), 1 );
90
  }
91
  else {
92
- $oResponse = $this->loadGoogleRecaptcha()
93
- ->getGoogleRecaptchaLib( $oFO->getGoogleRecaptchaSecretKey() )
94
- ->verify( $sCaptchaResponse, $this->ip() );
95
  if ( empty( $oResponse ) || !$oResponse->isSuccess() ) {
96
- throw new \Exception(
97
- __( 'Whoops.', 'wp-simple-firewall' ).' '.__( 'Google reCAPTCHA verification failed.', 'wp-simple-firewall' )
98
- .( $this->loadWp()
99
- ->isAjax() ? ' '.__( 'Maybe refresh the page and try again.', 'wp-simple-firewall' ) : '' ),
100
- 2 );
 
 
101
  }
102
  }
103
  return true;
@@ -107,7 +110,9 @@ abstract class ICWP_WPSF_Processor_BaseWpsf extends ICWP_WPSF_Processor_Base {
107
  * @return bool
108
  */
109
  protected function getIfLogRequest() {
110
- return isset( $this->bLogRequest ) ? (bool)$this->bLogRequest : !$this->loadWp()->isCron();
 
 
111
  }
112
 
113
  /**
@@ -144,9 +149,9 @@ abstract class ICWP_WPSF_Processor_BaseWpsf extends ICWP_WPSF_Processor_Base {
144
  add_action( 'wp_footer', [ $this, 'maybeDequeueRecaptcha' ], -100 );
145
  add_action( 'login_footer', [ $this, 'maybeDequeueRecaptcha' ], -100 );
146
 
147
- $this->loadWpIncludes()
148
- ->addIncludeAttribute( self::RECAPTCHA_JS_HANDLE, 'async', 'async' )
149
- ->addIncludeAttribute( self::RECAPTCHA_JS_HANDLE, 'defer', 'defer' );
150
  /**
151
  * Change to recaptcha implementation now means
152
  * 1 - the form will not submit unless the recaptcha has been executed (either invisible or manual)
1
  <?php
2
 
3
+ use FernleafSystems\Wordpress\Services\Services; // TODO: use after Shield 7.5
4
+
5
  abstract class ICWP_WPSF_Processor_BaseWpsf extends ICWP_WPSF_Processor_Base {
6
 
7
  const RECAPTCHA_JS_HANDLE = 'icwp-google-recaptcha';
52
  $bIsSubject = false;
53
 
54
  if ( !$oUser instanceof WP_User ) {
55
+ $oUser = Services::WpUsers()->getCurrentWpUser();
56
  }
57
  if ( $oUser instanceof WP_User ) {
58
  $bIsSubject = apply_filters( $this->prefix( 'user_subject_to_login_intent' ), false, $oUser );
91
  throw new \Exception( __( 'Whoops.', 'wp-simple-firewall' ).' '.__( 'Google reCAPTCHA was not submitted.', 'wp-simple-firewall' ), 1 );
92
  }
93
  else {
94
+ $oResponse = ( new \ReCaptcha\ReCaptcha( $oFO->getGoogleRecaptchaSecretKey(), new \FernleafSystems\Wordpress\Plugin\Shield\Utilities\WordpressPost() ) )
95
+ ->verify( $sCaptchaResponse, $this->ip() );
 
96
  if ( empty( $oResponse ) || !$oResponse->isSuccess() ) {
97
+ $aMsg = [
98
+ __( 'Whoops.', 'wp-simple-firewall' ),
99
+ __( 'Google reCAPTCHA verification failed.', 'wp-simple-firewall' ),
100
+ Services::WpGeneral()->isAjax() ?
101
+ __( 'Maybe refresh the page and try again.', 'wp-simple-firewall' ) : ''
102
+ ];
103
+ throw new \Exception( implode( ' ', $aMsg ), 2 );
104
  }
105
  }
106
  return true;
110
  * @return bool
111
  */
112
  protected function getIfLogRequest() {
113
+ return isset( $this->bLogRequest ) ?
114
+ (bool)$this->bLogRequest
115
+ : !\FernleafSystems\Wordpress\Services\Services::WpGeneral()->isCron();
116
  }
117
 
118
  /**
149
  add_action( 'wp_footer', [ $this, 'maybeDequeueRecaptcha' ], -100 );
150
  add_action( 'login_footer', [ $this, 'maybeDequeueRecaptcha' ], -100 );
151
 
152
+ \FernleafSystems\Wordpress\Services\Services::Includes()
153
+ ->addIncludeAttribute( self::RECAPTCHA_JS_HANDLE, 'async', 'async' )
154
+ ->addIncludeAttribute( self::RECAPTCHA_JS_HANDLE, 'defer', 'defer' );
155
  /**
156
  * Change to recaptcha implementation now means
157
  * 1 - the form will not submit unless the recaptcha has been executed (either invisible or manual)
src/processors/basedb.php CHANGED
@@ -34,12 +34,12 @@ abstract class ICWP_WPSF_BaseDbProcessor extends ICWP_WPSF_Processor_BaseWpsf {
34
  throw new \Exception( 'Table name is empty' );
35
  }
36
  $this->getDbHandler()
37
- ->setTable( $this->getMod()->prefixOptionKey( $sTableName ) )
38
  ->setColumnsDefinition( $this->getTableColumnsByDefinition() )
39
  ->setSqlCreate( $this->getCreateTableSql() )
40
  ->tableInit();
41
 
42
- add_action( $this->getMod()->prefix( 'delete_plugin' ), [ $this->getDbHandler(), 'deleteTable' ] );
43
  }
44
 
45
  /**
34
  throw new \Exception( 'Table name is empty' );
35
  }
36
  $this->getDbHandler()
37
+ ->setTable( $this->getCon()->prefixOption( $sTableName ) )
38
  ->setColumnsDefinition( $this->getTableColumnsByDefinition() )
39
  ->setSqlCreate( $this->getCreateTableSql() )
40
  ->tableInit();
41
 
42
+ add_action( $this->getCon()->prefix( 'delete_plugin' ), [ $this->getDbHandler(), 'deleteTable' ] );
43
  }
44
 
45
  /**
src/processors/commentsfilter_googlerecaptcha.php CHANGED
@@ -15,7 +15,7 @@ class ICWP_WPSF_Processor_CommentsFilter_GoogleRecaptcha extends ICWP_WPSF_Proce
15
  * The WP Query is alive and well at this stage so we can assume certain data is available.
16
  */
17
  public function setup() {
18
- if ( $this->loadWpComments()->isCommentsOpen() ) {
19
  add_action( 'wp_enqueue_scripts', [ $this, 'registerGoogleRecaptchaJs' ], 99 );
20
  add_action( 'comment_form_after_fields', [ $this, 'printGoogleRecaptchaCheck' ] );
21
  }
15
  * The WP Query is alive and well at this stage so we can assume certain data is available.
16
  */
17
  public function setup() {
18
+ if ( Services::WpComments()->isCommentsOpen() ) {
19
  add_action( 'wp_enqueue_scripts', [ $this, 'registerGoogleRecaptchaJs' ], 99 );
20
  add_action( 'comment_form_after_fields', [ $this, 'printGoogleRecaptchaCheck' ] );
21
  }
src/processors/email.php CHANGED
@@ -1,5 +1,7 @@
1
  <?php
2
 
 
 
3
  class ICWP_WPSF_Processor_Email extends ICWP_WPSF_Processor_BaseWpsf {
4
 
5
  const Slug = 'email';
@@ -63,15 +65,16 @@ class ICWP_WPSF_Processor_Email extends ICWP_WPSF_Processor_BaseWpsf {
63
  * @return array
64
  */
65
  protected function getEmailFooter() {
 
66
  $sUrl = [
67
  '',
68
  sprintf( __( 'Email sent from the %s Plugin v%s, on %s.', 'wp-simple-firewall' ),
69
  $this->getCon()->getHumanName(),
70
  $this->getCon()->getVersion(),
71
- $this->loadWp()->getHomeUrl()
72
  ),
73
  __( 'Note: Email delays are caused by website hosting and email providers.', 'wp-simple-firewall' ),
74
- sprintf( __( 'Time Sent: %s', 'wp-simple-firewall' ), $this->loadWp()->getTimeStampForDisplay() )
75
  ];
76
 
77
  return apply_filters( 'icwp_shield_email_footer', $sUrl );
1
  <?php
2
 
3
+ use FernleafSystems\Wordpress\Services\Services; // TODO: use after 7.5
4
+
5
  class ICWP_WPSF_Processor_Email extends ICWP_WPSF_Processor_BaseWpsf {
6
 
7
  const Slug = 'email';
65
  * @return array
66
  */
67
  protected function getEmailFooter() {
68
+ $oWp = \FernleafSystems\Wordpress\Services\Services::WpGeneral();
69
  $sUrl = [
70
  '',
71
  sprintf( __( 'Email sent from the %s Plugin v%s, on %s.', 'wp-simple-firewall' ),
72
  $this->getCon()->getHumanName(),
73
  $this->getCon()->getVersion(),
74
+ $oWp->getHomeUrl()
75
  ),
76
  __( 'Note: Email delays are caused by website hosting and email providers.', 'wp-simple-firewall' ),
77
+ sprintf( __( 'Time Sent: %s', 'wp-simple-firewall' ),$oWp->getTimeStampForDisplay() )
78
  ];
79
 
80
  return apply_filters( 'icwp_shield_email_footer', $sUrl );
src/processors/hackprotect_integrity.php CHANGED
@@ -1,5 +1,7 @@
1
  <?php
2
 
 
 
3
  class ICWP_WPSF_Processor_HackProtect_Integrity extends ICWP_WPSF_Processor_BaseWpsf {
4
 
5
  /**
@@ -52,8 +54,7 @@ class ICWP_WPSF_Processor_HackProtect_Integrity extends ICWP_WPSF_Processor_Base
52
  $aSnapshot = $this->getSnapshotUsers();
53
  $aFieldsToCheck = $this->getStandardUserFields();
54
 
55
- $aUsers = $this->loadWpUsers()->getAllUsers();
56
- foreach ( $aUsers as $oUser ) {
57
 
58
  if ( !array_key_exists( $oUser->ID, $aSnapshot ) ) {
59
  // Unrecognised user ID exists.
@@ -80,7 +81,7 @@ class ICWP_WPSF_Processor_HackProtect_Integrity extends ICWP_WPSF_Processor_Base
80
  * @return bool
81
  */
82
  public function deleteUserById( $nId ) {
83
- $oDb = $this->loadDbProcessor();
84
  return $oDb->deleteRowsFromTableWhere(
85
  $oDb->getTable_Users(),
86
  [ 'ID' => $nId ]
@@ -95,7 +96,7 @@ class ICWP_WPSF_Processor_HackProtect_Integrity extends ICWP_WPSF_Processor_Base
95
  $aSnapshot = $this->getSnapshotUsers();
96
  $aUser = $aSnapshot[ $nId ];
97
 
98
- $oDb = $this->loadDbProcessor();
99
  return $oDb->updateRowsFromTableWhere(
100
  $oDb->getTable_Users(),
101
  $aUser,
@@ -117,7 +118,7 @@ class ICWP_WPSF_Processor_HackProtect_Integrity extends ICWP_WPSF_Processor_Base
117
 
118
  $aUsersToStore = [];
119
  $aFields = $this->getStandardUserFields();
120
- foreach ( $this->loadWpUsers()->getAllUsers() as $oUser ) {
121
 
122
  $aUserData = [];
123
  foreach ( $aFields as $sField ) {
1
  <?php
2
 
3
+ use FernleafSystems\Wordpress\Services\Services;
4
+
5
  class ICWP_WPSF_Processor_HackProtect_Integrity extends ICWP_WPSF_Processor_BaseWpsf {
6
 
7
  /**
54
  $aSnapshot = $this->getSnapshotUsers();
55
  $aFieldsToCheck = $this->getStandardUserFields();
56
 
57
+ foreach ( Services::WpUsers()->getAllUsers() as $oUser ) {
 
58
 
59
  if ( !array_key_exists( $oUser->ID, $aSnapshot ) ) {
60
  // Unrecognised user ID exists.
81
  * @return bool
82
  */
83
  public function deleteUserById( $nId ) {
84
+ $oDb = Services::WpDb();
85
  return $oDb->deleteRowsFromTableWhere(
86
  $oDb->getTable_Users(),
87
  [ 'ID' => $nId ]
96
  $aSnapshot = $this->getSnapshotUsers();
97
  $aUser = $aSnapshot[ $nId ];
98
 
99
+ $oDb = Services::WpDb();
100
  return $oDb->updateRowsFromTableWhere(
101
  $oDb->getTable_Users(),
102
  $aUser,
118
 
119
  $aUsersToStore = [];
120
  $aFields = $this->getStandardUserFields();
121
+ foreach ( Services::WpUsers()->getAllUsers() as $oUser ) {
122
 
123
  $aUserData = [];
124
  foreach ( $aFields as $sField ) {
src/processors/hackprotect_scan_assets_base.php CHANGED
@@ -15,7 +15,7 @@ abstract class ICWP_WPSF_Processor_HackProtect_ScanAssetsBase extends ICWP_WPSF_
15
  * @throws \Exception
16
  */
17
  protected function assetDeactivate( $oItem ) {
18
- $oWpPlugins = $this->loadWpPlugins();
19
  if ( !$oWpPlugins->isInstalled( $oItem->slug ) ) {
20
  throw new \Exception( 'Items is not currently installed.' );
21
  }
15
  * @throws \Exception
16
  */
17
  protected function assetDeactivate( $oItem ) {
18
+ $oWpPlugins = Services\Services::WpPlugins();
19
  if ( !$oWpPlugins->isInstalled( $oItem->slug ) ) {
20
  throw new \Exception( 'Items is not currently installed.' );
21
  }
src/processors/hackprotect_scan_mal.php CHANGED
@@ -137,7 +137,7 @@ class ICWP_WPSF_Processor_HackProtect_Mal extends ICWP_WPSF_Processor_ScanBase {
137
  /** @var ICWP_WPSF_FeatureHandler_HackProtect $oFO */
138
  $oFO = $this->getMod();
139
  $sName = $this->getCon()->getHumanName();
140
- $sHomeUrl = $this->loadWp()->getHomeUrl();
141
 
142
  $aContent = [
143
  sprintf( __( "The %s Core File Scanner found files with potential problems.", 'wp-simple-firewall' ), $sName ),
137
  /** @var ICWP_WPSF_FeatureHandler_HackProtect $oFO */
138
  $oFO = $this->getMod();
139
  $sName = $this->getCon()->getHumanName();
140
+ $sHomeUrl = Services::WpGeneral()->getHomeUrl();
141
 
142
  $aContent = [
143
  sprintf( __( "The %s Core File Scanner found files with potential problems.", 'wp-simple-firewall' ), $sName ),
src/processors/hackprotect_scan_ptg.php CHANGED
@@ -241,11 +241,11 @@ class ICWP_WPSF_Processor_HackProtect_Ptg extends ICWP_WPSF_Processor_HackProtec
241
  && !empty( $oUpgrader->result[ 'destination_name' ] ) ) {
242
 
243
  if ( $aInfo[ 'type' ] == 'plugin' ) {
244
- $oWpPlugins = $this->loadWpPlugins();
245
- $sDir = $oWpPlugins->getFileFromDirName( $oUpgrader->result[ 'destination_name' ] );
246
- if ( $sDir && $oWpPlugins->isActive( $sDir ) ) {
247
  $sContext = self::CONTEXT_PLUGINS;
248
- $aSlugs = [ $sDir ];
249
  }
250
  }
251
  else if ( $aInfo[ 'type' ] == 'theme' ) {
241
  && !empty( $oUpgrader->result[ 'destination_name' ] ) ) {
242
 
243
  if ( $aInfo[ 'type' ] == 'plugin' ) {
244
+ $oWpPlugins = Services\Services::WpPlugins();
245
+ $sPluginFile = $oWpPlugins->findPluginFileFromDirName( $oUpgrader->result[ 'destination_name' ] );
246
+ if ( !empty( $sPluginFile ) && $oWpPlugins->isActive( $sPluginFile ) ) {
247
  $sContext = self::CONTEXT_PLUGINS;
248
+ $aSlugs = [ $sPluginFile ];
249
  }
250
  }
251
  else if ( $aInfo[ 'type' ] == 'theme' ) {
src/processors/hackprotect_scan_ufc.php CHANGED
@@ -1,6 +1,7 @@
1
  <?php
2
 
3
- use \FernleafSystems\Wordpress\Plugin\Shield;
 
4
 
5
  class ICWP_WPSF_Processor_HackProtect_Ufc extends ICWP_WPSF_Processor_ScanBase {
6
 
@@ -57,7 +58,7 @@ class ICWP_WPSF_Processor_HackProtect_Ufc extends ICWP_WPSF_Processor_ScanBase {
57
  ->setExclusions( $oFO->getUfcFileExclusions() );
58
 
59
  if ( $oFO->isUfsScanUploads() ) {
60
- $sUploadsDir = $this->loadWp()->getDirUploads();
61
  if ( !empty( $sUploadsDir ) ) {
62
  $oScanner->addScanDirector( $sUploadsDir )
63
  ->addDirSpecificFileTypes(
@@ -148,7 +149,7 @@ class ICWP_WPSF_Processor_HackProtect_Ufc extends ICWP_WPSF_Processor_ScanBase {
148
  $oFO = $this->getMod();
149
  $oCon = $this->getCon();
150
  $sName = $oCon->getHumanName();
151
- $sHomeUrl = $this->loadWp()->getHomeUrl();
152
 
153
  $aContent = [
154
  sprintf( __( 'The %s Unrecognised File Scanner found files which you need to review.', 'wp-simple-firewall' ), $sName ),
1
  <?php
2
 
3
+ use FernleafSystems\Wordpress\Plugin\Shield;
4
+ use FernleafSystems\Wordpress\Services\Services;
5
 
6
  class ICWP_WPSF_Processor_HackProtect_Ufc extends ICWP_WPSF_Processor_ScanBase {
7
 
58
  ->setExclusions( $oFO->getUfcFileExclusions() );
59
 
60
  if ( $oFO->isUfsScanUploads() ) {
61
+ $sUploadsDir = Services::WpGeneral()->getDirUploads();
62
  if ( !empty( $sUploadsDir ) ) {
63
  $oScanner->addScanDirector( $sUploadsDir )
64
  ->addDirSpecificFileTypes(
149
  $oFO = $this->getMod();
150
  $oCon = $this->getCon();
151
  $sName = $oCon->getHumanName();
152
+ $sHomeUrl = Services::WpGeneral()->getHomeUrl();
153
 
154
  $aContent = [
155
  sprintf( __( 'The %s Unrecognised File Scanner found files which you need to review.', 'wp-simple-firewall' ), $sName ),
src/processors/hackprotect_scan_wcf.php CHANGED
@@ -1,6 +1,7 @@
1
  <?php
2
 
3
  use \FernleafSystems\Wordpress\Plugin\Shield;
 
4
 
5
  class ICWP_WPSF_Processor_HackProtect_Wcf extends ICWP_WPSF_Processor_ScanBase {
6
 
@@ -144,7 +145,7 @@ class ICWP_WPSF_Processor_HackProtect_Wcf extends ICWP_WPSF_Processor_ScanBase {
144
  /** @var ICWP_WPSF_FeatureHandler_HackProtect $oFO */
145
  $oFO = $this->getMod();
146
  $sName = $this->getCon()->getHumanName();
147
- $sHomeUrl = $this->loadWp()->getHomeUrl();
148
 
149
  $aContent = [
150
  sprintf( __( "The %s Core File Scanner found files with potential problems.", 'wp-simple-firewall' ), $sName ),
@@ -201,13 +202,4 @@ class ICWP_WPSF_Processor_HackProtect_Wcf extends ICWP_WPSF_Processor_ScanBase {
201
  }
202
  return $aContent;
203
  }
204
-
205
- /**
206
- * @param string $sFile
207
- * @return string
208
- */
209
- private function getWpFileDownloadUrl( $sFile ) {
210
- return $this->getMod()->getDef( 'url_wordress_core_svn' )
211
- .'tags/'.$this->loadWp()->getVersion().'/'.$sFile;
212
- }
213
  }
1
  <?php
2
 
3
  use \FernleafSystems\Wordpress\Plugin\Shield;
4
+ use FernleafSystems\Wordpress\Services\Services;
5
 
6
  class ICWP_WPSF_Processor_HackProtect_Wcf extends ICWP_WPSF_Processor_ScanBase {
7
 
145
  /** @var ICWP_WPSF_FeatureHandler_HackProtect $oFO */
146
  $oFO = $this->getMod();
147
  $sName = $this->getCon()->getHumanName();
148
+ $sHomeUrl = Services::WpGeneral()->getHomeUrl();
149
 
150
  $aContent = [
151
  sprintf( __( "The %s Core File Scanner found files with potential problems.", 'wp-simple-firewall' ), $sName ),
202
  }
203
  return $aContent;
204
  }
 
 
 
 
 
 
 
 
 
205
  }
src/processors/hackprotect_scan_wpv.php CHANGED
@@ -116,7 +116,7 @@ class ICWP_WPSF_Processor_HackProtect_Wpv extends ICWP_WPSF_Processor_HackProtec
116
  * @return boolean
117
  */
118
  public function autoupdateVulnerablePlugins( $bDoAutoUpdate, $mItem ) {
119
- $sItemFile = $this->loadWp()->getFileFromAutomaticUpdateItem( $mItem );
120
  // TODO Audit.
121
  return $bDoAutoUpdate || ( $this->getPluginVulnerabilities( $sItemFile ) > 0 );
122
  }
@@ -231,8 +231,8 @@ class ICWP_WPSF_Processor_HackProtect_Wpv extends ICWP_WPSF_Processor_HackProtec
231
  protected function emailResults( $oRes ) {
232
  /** @var ICWP_WPSF_FeatureHandler_HackProtect $oFO */
233
  $oFO = $this->getMod();
234
- $oWpPlugins = $this->loadWpPlugins();
235
- $oWpThemes = $this->loadWpThemes();
236
  $oCon = $this->getCon();
237
 
238
  $aContent = [
116
  * @return boolean
117
  */
118
  public function autoupdateVulnerablePlugins( $bDoAutoUpdate, $mItem ) {
119
+ $sItemFile = Services::WpGeneral()->getFileFromAutomaticUpdateItem( $mItem );
120
  // TODO Audit.
121
  return $bDoAutoUpdate || ( $this->getPluginVulnerabilities( $sItemFile ) > 0 );
122
  }
231
  protected function emailResults( $oRes ) {
232
  /** @var ICWP_WPSF_FeatureHandler_HackProtect $oFO */
233
  $oFO = $this->getMod();
234
+ $oWpPlugins = Services::WpPlugins();
235
+ $oWpThemes = Services::WpThemes();
236
  $oCon = $this->getCon();
237
 
238
  $aContent = [
src/processors/hackprotect_scanner.php CHANGED
@@ -134,11 +134,10 @@ class ICWP_WPSF_Processor_HackProtect_Scanner extends ICWP_WPSF_BaseDbProcessor
134
  ->byId( (int)$sItemId );
135
  if ( !empty( $oEntry ) ) {
136
  $sPath = $oEntry->meta[ 'path_full' ];
137
- $oFs = $this->loadFS();
138
  if ( $oFs->isFile( $sPath ) ) {
139
  header( 'Set-Cookie: fileDownload=true; path=/' );
140
- $this->loadRequest()
141
- ->downloadStringAsFile( $oFs->getFileContent( $sPath ), basename( $sPath ) );
142
  }
143
  }
144
 
134
  ->byId( (int)$sItemId );
135
  if ( !empty( $oEntry ) ) {
136
  $sPath = $oEntry->meta[ 'path_full' ];
137
+ $oFs = Services::WpFs();
138
  if ( $oFs->isFile( $sPath ) ) {
139
  header( 'Set-Cookie: fileDownload=true; path=/' );
140
+ Services::Response()->downloadStringAsFile( $oFs->getFileContent( $sPath ), basename( $sPath ) );
 
141
  }
142
  }
143
 
src/processors/ips.php CHANGED
@@ -289,10 +289,10 @@ class ICWP_WPSF_Processor_Ips extends ICWP_WPSF_BaseDbProcessor {
289
  'is_uau_permitted' => $oFO->getCanIpRequestAutoUnblock( $sIp ),
290
  ],
291
  ];
292
- $this->loadWp()
293
- ->wpDie(
294
- $oFO->renderTemplate( '/snippets/blacklist_die.twig', $aData, true )
295
- );
296
  }
297
 
298
  /**
289
  'is_uau_permitted' => $oFO->getCanIpRequestAutoUnblock( $sIp ),
290
  ],
291
  ];
292
+ Services::WpGeneral()
293
+ ->wpDie(
294
+ $oFO->renderTemplate( '/snippets/blacklist_die.twig', $aData, true )
295
+ );
296
  }
297
 
298
  /**
src/processors/loginprotect_intentprovider_ga.php CHANGED
@@ -58,7 +58,7 @@ class ICWP_WPSF_Processor_LoginProtect_GoogleAuthenticator extends ICWP_WPSF_Pro
58
  }
59
 
60
  /**
61
- * @param WP_User $oUser
62
  * @return string
63
  */
64
  public function getGaRegisterChartUrl( $oUser ) {
@@ -66,12 +66,12 @@ class ICWP_WPSF_Processor_LoginProtect_GoogleAuthenticator extends ICWP_WPSF_Pro
66
  $sUrl = '';
67
  }
68
  else {
69
- $sUrl = $this->loadGoogleAuthenticatorProcessor()
70
- ->getGoogleQrChartUrl(
71
- $this->getSecret( $oUser ),
72
- preg_replace( '#[^0-9a-z]#i', '', $oUser->user_login )
73
- .'@'.preg_replace( '#[^0-9a-z]#i', '', Services::WpGeneral()->getSiteName() )
74
- );
75
  }
76
  return $sUrl;
77
  }
@@ -268,8 +268,8 @@ class ICWP_WPSF_Processor_LoginProtect_GoogleAuthenticator extends ICWP_WPSF_Pro
268
  public function validateGaCode( $oUser, $sOtpCode ) {
269
  $bValidOtp = false;
270
  if ( !empty( $sOtpCode ) && preg_match( '#^[0-9]{6}$#', $sOtpCode ) ) {
271
- $bValidOtp = $this->loadGoogleAuthenticatorProcessor()
272
- ->verifyOtp( $this->getSecret( $oUser ), $sOtpCode );
273
  }
274
  return $bValidOtp;
275
  }
@@ -312,7 +312,7 @@ class ICWP_WPSF_Processor_LoginProtect_GoogleAuthenticator extends ICWP_WPSF_Pro
312
  * @return string
313
  */
314
  protected function genNewSecret() {
315
- return $this->loadGoogleAuthenticatorProcessor()->generateNewSecret();
316
  }
317
 
318
  /**
58
  }
59
 
60
  /**
61
+ * @param \WP_User $oUser
62
  * @return string
63
  */
64
  public function getGaRegisterChartUrl( $oUser ) {
66
  $sUrl = '';
67
  }
68
  else {
69
+ $sUrl = ( new PHPGangsta_GoogleAuthenticator() )
70
+ ->getQRCodeGoogleUrl(
71
+ preg_replace( '#[^0-9a-z]#i', '', $oUser->user_login )
72
+ .'@'.preg_replace( '#[^0-9a-z]#i', '', Services::WpGeneral()->getSiteName() ),
73
+ $this->getSecret( $oUser )
74
+ );
75
  }
76
  return $sUrl;
77
  }
268
  public function validateGaCode( $oUser, $sOtpCode ) {
269
  $bValidOtp = false;
270
  if ( !empty( $sOtpCode ) && preg_match( '#^[0-9]{6}$#', $sOtpCode ) ) {
271
+ $bValidOtp = ( new PHPGangsta_GoogleAuthenticator() )
272
+ ->verifyCode( $this->getSecret( $oUser ), $sOtpCode );
273
  }
274
  return $bValidOtp;
275
  }
312
  * @return string
313
  */
314
  protected function genNewSecret() {
315
+ return ( new PHPGangsta_GoogleAuthenticator() )->createSecret();
316
  }
317
 
318
  /**
src/processors/plugin_importexport.php CHANGED
@@ -55,17 +55,16 @@ class ICWP_WPSF_Processor_Plugin_ImportExport extends ICWP_WPSF_Processor_BaseWp
55
  public function runWhitelistNotify() {
56
  /** @var ICWP_WPSF_FeatureHandler_Plugin $oFO */
57
  $oFO = $this->getMod();
 
58
 
59
  if ( $oFO->hasImportExportWhitelistSites() ) {
60
 
 
 
 
 
61
  foreach ( $oFO->getImportExportWhitelist() as $sUrl ) {
62
- $this->loadFS()->getUrl(
63
- $sUrl,
64
- [
65
- 'blocking' => false,
66
- 'body' => [ 'shield_action' => 'importexport_updatenotified' ]
67
- ]
68
- );
69
  }
70
 
71
  $this->addToAuditEntry(
55
  public function runWhitelistNotify() {
56
  /** @var ICWP_WPSF_FeatureHandler_Plugin $oFO */
57
  $oFO = $this->getMod();
58
+ $oHttpReq = Services::HttpRequest();
59
 
60
  if ( $oFO->hasImportExportWhitelistSites() ) {
61
 
62
+ $aQuery = [
63
+ 'blocking' => false,
64
+ 'body' => [ 'shield_action' => 'importexport_updatenotified' ]
65
+ ];
66
  foreach ( $oFO->getImportExportWhitelist() as $sUrl ) {
67
+ $oHttpReq->get( $sUrl, $aQuery );
 
 
 
 
 
 
68
  }
69
 
70
  $this->addToAuditEntry(
src/processors/usermanagement_passwords.php CHANGED
@@ -134,17 +134,16 @@ class ICWP_WPSF_Processor_UserManagement_Passwords extends ICWP_WPSF_Processor_B
134
 
135
  $oMeta->pass_reset_last_redirect_at = $this->time();
136
 
137
- $oWp = $this->loadWp();
138
  $oWpUsers = Services::WpUsers();
139
  $sAction = Services::Request()->query( 'action' );
140
  $oUser = $oWpUsers->getCurrentWpUser();
141
- if ( $oUser && ( !$oWp->isRequestLoginUrl() || !in_array( $sAction, [ 'rp', 'resetpass' ] ) ) ) {
142
 
143
  $sMessage .= ' '.__( 'For your security, please use the password section below to update your password.', 'wp-simple-firewall' );
144
  $this->getMod()
145
  ->setFlashAdminNotice( $sMessage );
146
 
147
- $oWp->doRedirect( $oWpUsers->getPasswordResetUrl( $oUser ) );
148
  }
149
  }
150
  }
@@ -254,40 +253,32 @@ class ICWP_WPSF_Processor_UserManagement_Passwords extends ICWP_WPSF_Processor_B
254
  * @throws \Exception
255
  */
256
  protected function sendRequestToPwned( $sPass ) {
257
- /** @var ICWP_WPSF_FeatureHandler_UserManagement $oFO */
258
- $oFO = $this->getMod();
259
- $oCon = $this->getCon();
260
-
261
- $aResponse = $this->loadFS()->requestUrl(
262
- sprintf( '%s/%s', $oFO->getDef( 'pwned_api_url_password_single' ), hash( 'sha1', $sPass ) ),
263
  [
264
- 'headers' => [
265
- 'user-agent' => sprintf( '%s WP Plugin-v%s', $oCon->getHumanName(), $oCon->getVersion() )
266
- ]
267
- ],
268
- true
269
  );
270
 
271
  $sError = '';
272
- if ( is_wp_error( $aResponse ) ) {
273
- $sError = $aResponse->get_error_message();
274
- }
275
- else if ( empty( $aResponse ) ) {
276
- $sError = 'Response was empty';
277
  }
278
- else if ( is_array( $aResponse ) ) {
279
- if ( empty( $aResponse[ 'response' ][ 'code' ] ) ) {
280
- $sError = 'Unexpected Error: No response code available from the API';
 
281
  }
282
- else if ( $aResponse[ 'response' ][ 'code' ] == 404 ) {
283
  // means that the password isn't on the pwned list. It's acceptable.
284
  }
285
- else if ( empty( $aResponse[ 'body' ] ) ) {
286
- $sError = 'Unexpected Error: The response from the API was empty';
287
  }
288
  else {
289
  // password pwned
290
- $nCount = intval( $aResponse[ 'body' ] );
291
  if ( $nCount == 0 ) {
292
  $sError = 'Unexpected Error: The API response could not be properly parsed.';
293
  }
@@ -304,7 +295,7 @@ class ICWP_WPSF_Processor_UserManagement_Passwords extends ICWP_WPSF_Processor_B
304
  }
305
 
306
  if ( !empty( $sError ) ) {
307
- throw new \Exception( $sError );
308
  }
309
 
310
  return true;
@@ -316,43 +307,36 @@ class ICWP_WPSF_Processor_UserManagement_Passwords extends ICWP_WPSF_Processor_B
316
  * @throws \Exception
317
  */
318
  protected function sendRequestToPwnedRange( $sPass ) {
319
- /** @var ICWP_WPSF_FeatureHandler_UserManagement $oFO */
320
- $oFO = $this->getMod();
321
- $oCon = $this->getCon();
322
 
323
  $sPassHash = strtoupper( hash( 'sha1', $sPass ) );
324
  $sSubHash = substr( $sPassHash, 0, 5 );
325
 
326
- $aResponse = $this->loadFS()->requestUrl(
327
- sprintf( '%s/%s', $oFO->getDef( 'pwned_api_url_password_range' ), $sSubHash ),
328
  [
329
- 'headers' => [
330
- 'user-agent' => sprintf( '%s WP Plugin-v%s', $oCon->getHumanName(), $oCon->getVersion() )
331
- ]
332
- ],
333
- true
334
  );
335
 
336
  $sError = '';
337
- if ( is_wp_error( $aResponse ) ) {
338
- $sError = $aResponse->get_error_message();
339
- }
340
- else if ( empty( $aResponse ) ) {
341
- $sError = 'Response was empty';
342
  }
343
- else if ( is_array( $aResponse ) ) {
344
- if ( empty( $aResponse[ 'response' ][ 'code' ] ) ) {
 
345
  $sError = 'Unexpected Error: No response code available from the Pwned API';
346
  }
347
- else if ( $aResponse[ 'response' ][ 'code' ] != 200 ) {
348
  $sError = 'Unexpected Error: The response from the Pwned API was unexpected';
349
  }
350
- else if ( empty( $aResponse[ 'body' ] ) ) {
351
  $sError = 'Unexpected Error: The response from the Pwned API was empty';
352
  }
353
  else {
354
  $nCount = 0;
355
- foreach ( array_map( 'trim', explode( "\n", trim( $aResponse[ 'body' ] ) ) ) as $sRow ) {
356
  if ( $sSubHash.substr( strtoupper( $sRow ), 0, 35 ) == $sPassHash ) {
357
  $nCount = substr( $sRow, 36 );
358
  break;
@@ -371,7 +355,7 @@ class ICWP_WPSF_Processor_UserManagement_Passwords extends ICWP_WPSF_Processor_B
371
  }
372
 
373
  if ( !empty( $sError ) ) {
374
- throw new \Exception( $sError );
375
  }
376
 
377
  return true;
134
 
135
  $oMeta->pass_reset_last_redirect_at = $this->time();
136
 
 
137
  $oWpUsers = Services::WpUsers();
138
  $sAction = Services::Request()->query( 'action' );
139
  $oUser = $oWpUsers->getCurrentWpUser();
140
+ if ( $oUser && ( !$this->loadWp()->isRequestLoginUrl() || !in_array( $sAction, [ 'rp', 'resetpass' ] ) ) ) {
141
 
142
  $sMessage .= ' '.__( 'For your security, please use the password section below to update your password.', 'wp-simple-firewall' );
143
  $this->getMod()
144
  ->setFlashAdminNotice( $sMessage );
145
 
146
+ Services::Response()->redirect( $oWpUsers->getPasswordResetUrl( $oUser ) );
147
  }
148
  }
149
  }
253
  * @throws \Exception
254
  */
255
  protected function sendRequestToPwned( $sPass ) {
256
+ $oHttpReq = Services::HttpRequest();
257
+ $bSuccess = $oHttpReq->get(
258
+ sprintf( '%s/%s', $this->getMod()->getDef( 'pwned_api_url_password_single' ), hash( 'sha1', $sPass ) ),
 
 
 
259
  [
260
+ 'headers' => [ 'user-agent' => sprintf( '%s WP Plugin-v%s', 'Shield', $this->getCon()->getVersion() ) ]
261
+ ]
 
 
 
262
  );
263
 
264
  $sError = '';
265
+ if ( !$bSuccess ) {
266
+ $sError = 'API request failed';
 
 
 
267
  }
268
+ else {
269
+ $nCode = $oHttpReq->lastResponse->getCode();
270
+ if ( empty( $nCode ) ) {
271
+ $sError = 'Unexpected Error: No response code available from the Response';
272
  }
273
+ else if ( $nCode == 404 ) {
274
  // means that the password isn't on the pwned list. It's acceptable.
275
  }
276
+ else if ( empty( $oHttpReq->lastResponse->body ) ) {
277
+ $sError = 'Unexpected Error: The response from the Pwned API was empty';
278
  }
279
  else {
280
  // password pwned
281
+ $nCount = intval( $oHttpReq->lastResponse[ 'body' ] );
282
  if ( $nCount == 0 ) {
283
  $sError = 'Unexpected Error: The API response could not be properly parsed.';
284
  }
295
  }
296
 
297
  if ( !empty( $sError ) ) {
298
+ throw new \Exception( '[Pwned Request] '.$sError );
299
  }
300
 
301
  return true;
307
  * @throws \Exception
308
  */
309
  protected function sendRequestToPwnedRange( $sPass ) {
310
+ $oHttpReq = Services::HttpRequest();
 
 
311
 
312
  $sPassHash = strtoupper( hash( 'sha1', $sPass ) );
313
  $sSubHash = substr( $sPassHash, 0, 5 );
314
 
315
+ $bSuccess = $oHttpReq->get(
316
+ sprintf( '%s/%s', $this->getMod()->getDef( 'pwned_api_url_password_range' ), $sSubHash ),
317
  [
318
+ 'headers' => [ 'user-agent' => sprintf( '%s WP Plugin-v%s', 'Shield', $this->getCon()->getVersion() ) ]
319
+ ]
 
 
 
320
  );
321
 
322
  $sError = '';
323
+ if ( !$bSuccess ) {
324
+ $sError = 'API request failed';
 
 
 
325
  }
326
+ else {
327
+ $nCode = $oHttpReq->lastResponse->getCode();
328
+ if ( empty( $nCode ) ) {
329
  $sError = 'Unexpected Error: No response code available from the Pwned API';
330
  }
331
+ else if ( $nCode != 200 ) {
332
  $sError = 'Unexpected Error: The response from the Pwned API was unexpected';
333
  }
334
+ else if ( empty( $oHttpReq->lastResponse->body ) ) {
335
  $sError = 'Unexpected Error: The response from the Pwned API was empty';
336
  }
337
  else {
338
  $nCount = 0;
339
+ foreach ( array_map( 'trim', explode( "\n", trim( $oHttpReq->lastResponse->body ) ) ) as $sRow ) {
340
  if ( $sSubHash.substr( strtoupper( $sRow ), 0, 35 ) == $sPassHash ) {
341
  $nCount = substr( $sRow, 36 );
342
  break;
355
  }
356
 
357
  if ( !empty( $sError ) ) {
358
+ throw new \Exception( '[Pwned Request] '.$sError );
359
  }
360
 
361
  return true;
src/wizards/base.php CHANGED
@@ -28,7 +28,7 @@ abstract class ICWP_WPSF_Wizard_Base extends ICWP_WPSF_Foundation {
28
  /**
29
  */
30
  public function init() {
31
- add_action( 'wp_loaded', array( $this, 'onWpLoaded' ), 0 );
32
  }
33
 
34
  /**
@@ -37,10 +37,10 @@ abstract class ICWP_WPSF_Wizard_Base extends ICWP_WPSF_Foundation {
37
  public function ajaxExec_WizRenderStep() {
38
  $oReq = Services::Request();
39
 
40
- $aResponse = array(
41
  'success' => false,
42
- 'next_step' => array(),
43
- );
44
 
45
  try {
46
  $this->setCurrentWizard( $oReq->post( 'wizard_slug' ) );
@@ -66,7 +66,7 @@ abstract class ICWP_WPSF_Wizard_Base extends ICWP_WPSF_Foundation {
66
  * TODO: does not honour 'min_user_permissions' from the wizard definition
67
  */
68
  public function onWpLoaded() {
69
- $sWizard = $this->loadRequest()->query( 'wizard' );
70
  try {
71
  $this->setCurrentWizard( $sWizard );
72
 
@@ -78,8 +78,7 @@ abstract class ICWP_WPSF_Wizard_Base extends ICWP_WPSF_Foundation {
78
  $sDieMessage = 'Please login to run this wizard';
79
  }
80
 
81
- $this->loadWp()
82
- ->wpDie( $sDieMessage );
83
  }
84
  catch ( Exception $oE ) {
85
  if ( $sWizard == 'landing' ) {
@@ -182,7 +181,7 @@ abstract class ICWP_WPSF_Wizard_Base extends ICWP_WPSF_Foundation {
182
  * @return array
183
  */
184
  public function ajaxExec_WizProcessStep() {
185
- $oResponse = $this->processWizardStep( $this->loadRequest()->post( 'wizard-step' ) );
186
  if ( !empty( $oResponse ) ) {
187
  $this->buildWizardResponse( $oResponse );
188
  }
@@ -274,25 +273,25 @@ abstract class ICWP_WPSF_Wizard_Base extends ICWP_WPSF_Foundation {
274
 
275
  return $this->loadDP()->mergeArraysRecursive(
276
  $this->getRenderData_TwigPageBase(),
277
- array(
278
- 'strings' => array(
279
  'page_title' => 'Select Your Wizard',
280
  'premium_note' => 'Note: This uses features only available to Pro-licensed installations.'
281
- ),
282
- 'data' => array(
283
  'mod_wizards_count' => count( $aWizards ),
284
  'mod_wizards' => $aWizards
285
- ),
286
- 'hrefs' => array(
287
  'dashboard' => $oFO->getUrl_AdminPage(),
288
  'goprofooter' => 'https://icwp.io/goprofooter',
289
- ),
290
- 'ajax' => array(
291
  'content' => $oFO->getAjaxActionData( 'wiz_process_step' ),
292
  'steps' => $oFO->getAjaxActionData( 'wiz_render_step' ),
293
  'steps_as_json' => $oFO->getAjaxActionData( 'wiz_render_step', true ),
294
- )
295
- )
296
  );
297
  }
298
 
@@ -302,21 +301,21 @@ abstract class ICWP_WPSF_Wizard_Base extends ICWP_WPSF_Foundation {
302
  */
303
  protected function getRenderData_TwigPageBase() {
304
  $oCon = $this->getModCon()->getCon();
305
- return array(
306
- 'strings' => array(
307
  'page_title' => 'Twig Page',
308
  'plugin_name' => $oCon->getHumanName()
309
- ),
310
- 'data' => array(),
311
- 'hrefs' => array(
312
- 'form_action' => $this->loadRequest()->getUri(),
313
  'css_bootstrap' => $oCon->getPluginUrl_Css( 'bootstrap4.min.css' ),
314
  'css_pages' => $oCon->getPluginUrl_Css( 'pages.css' ),
315
  'css_steps' => $oCon->getPluginUrl_Css( 'jquery.steps.css' ),
316
  'css_fancybox' => $oCon->getPluginUrl_Css( 'jquery.fancybox.min.css' ),
317
  'css_globalplugin' => $oCon->getPluginUrl_Css( 'global-plugin.css' ),
318
  'css_wizard' => $oCon->getPluginUrl_Css( 'wizard.css' ),
319
- 'js_jquery' => $this->loadWpIncludes()->getUrl_Jquery(),
320
  'js_bootstrap' => $oCon->getPluginUrl_Js( 'bootstrap4.bundle.min.js' ),
321
  'js_fancybox' => $oCon->getPluginUrl_Js( 'jquery.fancybox.min.js' ),
322
  'js_globalplugin' => $oCon->getPluginUrl_Js( 'global-plugin.js' ),
@@ -324,12 +323,12 @@ abstract class ICWP_WPSF_Wizard_Base extends ICWP_WPSF_Foundation {
324
  'js_wizard' => $oCon->getPluginUrl_Js( 'wizard.js' ),
325
  'plugin_banner' => $oCon->getPluginUrl_Image( 'banner-1500x500-transparent.png' ),
326
  'favicon' => $oCon->getPluginUrl_Image( 'pluginlogo_24x24.png' ),
327
- ),
328
- 'ajax' => array(),
329
- 'flags' => array(
330
  'is_premium' => $this->getModCon()->isPremium(),
331
- )
332
- );
333
  }
334
 
335
  /**
@@ -341,26 +340,26 @@ abstract class ICWP_WPSF_Wizard_Base extends ICWP_WPSF_Foundation {
341
  $oFO = $this->getModCon();
342
  return $this->loadDP()->mergeArraysRecursive(
343
  $this->getRenderData_TwigPageBase(),
344
- array(
345
- 'strings' => array(
346
  'page_title' => $this->getPageTitle(),
347
  'plugin_name' => $oCon->getHumanName()
348
- ),
349
- 'data' => array(
350
  'wizard_slug' => $this->getWizardSlug(),
351
  'wizard_steps' => json_encode( $this->buildSteps() ),
352
  'wizard_first_step' => json_encode( $this->getWizardFirstStep() ),
353
- ),
354
- 'hrefs' => array(
355
  'dashboard' => $oFO->getUrl_AdminPage(),
356
  'goprofooter' => 'https://icwp.io/goprofooter',
357
- ),
358
- 'ajax' => array(
359
  'content' => $oFO->getAjaxActionData( 'wiz_process_step' ),
360
  'steps' => $oFO->getAjaxActionData( 'wiz_render_step' ),
361
  'steps_as_json' => $oFO->getAjaxActionData( 'wiz_render_step', true ),
362
- )
363
- )
364
  );
365
  }
366
 
@@ -375,7 +374,7 @@ abstract class ICWP_WPSF_Wizard_Base extends ICWP_WPSF_Foundation {
375
  * @return string[]
376
  */
377
  protected function buildSteps() {
378
- return $this->getUserCan() ? $this->determineWizardSteps() : array( 'no_access' );
379
  }
380
 
381
  /**
@@ -442,24 +441,24 @@ abstract class ICWP_WPSF_Wizard_Base extends ICWP_WPSF_Foundation {
442
  $oFO = $this->getModCon();
443
  $oCon = $this->getModCon()->getCon();
444
  $aWizards = $this->getModuleWizardsForRender();
445
- return array(
446
- 'strings' => array(
447
  'plugin_name' => $oCon->getHumanName()
448
- ),
449
- 'flags' => array(
450
  'is_premium' => $oFO->isPremium(),
451
  'has_other_wizards' => false
452
- ),
453
- 'hrefs' => array(
454
  'dashboard' => $oFO->getUrl_AdminPage(),
455
  'gopro' => 'https://icwp.io/ap',
456
- ),
457
- 'imgs' => array(),
458
- 'data' => array(
459
  'mod_wizards_count' => count( $aWizards ),
460
  'mod_wizards' => $aWizards
461
- ),
462
- );
463
  }
464
 
465
  /**
@@ -467,7 +466,7 @@ abstract class ICWP_WPSF_Wizard_Base extends ICWP_WPSF_Foundation {
467
  * @return array
468
  */
469
  protected function getRenderData_SlideExtra( $sStep ) {
470
- return array();
471
  }
472
 
473
  /**
@@ -509,11 +508,11 @@ abstract class ICWP_WPSF_Wizard_Base extends ICWP_WPSF_Foundation {
509
  * @return array[]
510
  */
511
  protected function getStepsDefinition() {
512
- $aNoAccess = array(
513
- 'no_access' => array(
514
  'title' => __( 'No Access', 'wp-simple-firewall' ),
515
- )
516
- );
517
  $aSteps = array_merge( $this->getAllDefinedSteps(), $aNoAccess );
518
  foreach ( $aSteps as $sSlug => $aStep ) {
519
  $aSteps[ $sSlug ][ 'slug' ] = $sSlug;
28
  /**
29
  */
30
  public function init() {
31
+ add_action( 'wp_loaded', [ $this, 'onWpLoaded' ], 0 );
32
  }
33
 
34
  /**
37
  public function ajaxExec_WizRenderStep() {
38
  $oReq = Services::Request();
39
 
40
+ $aResponse = [
41
  'success' => false,
42
+ 'next_step' => [],
43
+ ];
44
 
45
  try {
46
  $this->setCurrentWizard( $oReq->post( 'wizard_slug' ) );
66
  * TODO: does not honour 'min_user_permissions' from the wizard definition
67
  */
68
  public function onWpLoaded() {
69
+ $sWizard = Services::Request()->query( 'wizard' );
70
  try {
71
  $this->setCurrentWizard( $sWizard );
72
 
78
  $sDieMessage = 'Please login to run this wizard';
79
  }
80
 
81
+ Services::WpGeneral()->wpDie( $sDieMessage );
 
82
  }
83
  catch ( Exception $oE ) {
84
  if ( $sWizard == 'landing' ) {
181
  * @return array
182
  */
183
  public function ajaxExec_WizProcessStep() {
184
+ $oResponse = $this->processWizardStep( Services::Request()->post( 'wizard-step' ) );
185
  if ( !empty( $oResponse ) ) {
186
  $this->buildWizardResponse( $oResponse );
187
  }
273
 
274
  return $this->loadDP()->mergeArraysRecursive(
275
  $this->getRenderData_TwigPageBase(),
276
+ [
277
+ 'strings' => [
278
  'page_title' => 'Select Your Wizard',
279
  'premium_note' => 'Note: This uses features only available to Pro-licensed installations.'
280
+ ],
281
+ 'data' => [
282
  'mod_wizards_count' => count( $aWizards ),
283
  'mod_wizards' => $aWizards
284
+ ],
285
+ 'hrefs' => [
286
  'dashboard' => $oFO->getUrl_AdminPage(),
287
  'goprofooter' => 'https://icwp.io/goprofooter',
288
+ ],
289
+ 'ajax' => [
290
  'content' => $oFO->getAjaxActionData( 'wiz_process_step' ),
291
  'steps' => $oFO->getAjaxActionData( 'wiz_render_step' ),
292
  'steps_as_json' => $oFO->getAjaxActionData( 'wiz_render_step', true ),
293
+ ]
294
+ ]
295
  );
296
  }
297
 
301
  */
302
  protected function getRenderData_TwigPageBase() {
303
  $oCon = $this->getModCon()->getCon();
304
+ return [
305
+ 'strings' => [
306
  'page_title' => 'Twig Page',
307
  'plugin_name' => $oCon->getHumanName()
308
+ ],
309
+ 'data' => [],
310
+ 'hrefs' => [
311
+ 'form_action' => Services::Request()->getUri(),
312
  'css_bootstrap' => $oCon->getPluginUrl_Css( 'bootstrap4.min.css' ),
313
  'css_pages' => $oCon->getPluginUrl_Css( 'pages.css' ),
314
  'css_steps' => $oCon->getPluginUrl_Css( 'jquery.steps.css' ),
315
  'css_fancybox' => $oCon->getPluginUrl_Css( 'jquery.fancybox.min.css' ),
316
  'css_globalplugin' => $oCon->getPluginUrl_Css( 'global-plugin.css' ),
317
  'css_wizard' => $oCon->getPluginUrl_Css( 'wizard.css' ),
318
+ 'js_jquery' => Services::Includes()->getUrl_Jquery(),
319
  'js_bootstrap' => $oCon->getPluginUrl_Js( 'bootstrap4.bundle.min.js' ),
320
  'js_fancybox' => $oCon->getPluginUrl_Js( 'jquery.fancybox.min.js' ),
321
  'js_globalplugin' => $oCon->getPluginUrl_Js( 'global-plugin.js' ),
323
  'js_wizard' => $oCon->getPluginUrl_Js( 'wizard.js' ),
324
  'plugin_banner' => $oCon->getPluginUrl_Image( 'banner-1500x500-transparent.png' ),
325
  'favicon' => $oCon->getPluginUrl_Image( 'pluginlogo_24x24.png' ),
326
+ ],
327
+ 'ajax' => [],
328
+ 'flags' => [
329
  'is_premium' => $this->getModCon()->isPremium(),
330
+ ]
331
+ ];
332
  }
333
 
334
  /**
340
  $oFO = $this->getModCon();
341
  return $this->loadDP()->mergeArraysRecursive(
342
  $this->getRenderData_TwigPageBase(),
343
+ [
344
+ 'strings' => [
345
  'page_title' => $this->getPageTitle(),
346
  'plugin_name' => $oCon->getHumanName()
347
+ ],
348
+ 'data' => [
349
  'wizard_slug' => $this->getWizardSlug(),
350
  'wizard_steps' => json_encode( $this->buildSteps() ),
351
  'wizard_first_step' => json_encode( $this->getWizardFirstStep() ),
352
+ ],
353
+ 'hrefs' => [
354
  'dashboard' => $oFO->getUrl_AdminPage(),
355
  'goprofooter' => 'https://icwp.io/goprofooter',
356
+ ],
357
+ 'ajax' => [
358
  'content' => $oFO->getAjaxActionData( 'wiz_process_step' ),
359
  'steps' => $oFO->getAjaxActionData( 'wiz_render_step' ),
360
  'steps_as_json' => $oFO->getAjaxActionData( 'wiz_render_step', true ),
361
+ ]
362
+ ]
363
  );
364
  }
365
 
374
  * @return string[]
375
  */
376
  protected function buildSteps() {
377
+ return $this->getUserCan() ? $this->determineWizardSteps() : [ 'no_access' ];
378
  }
379
 
380
  /**
441
  $oFO = $this->getModCon();
442
  $oCon = $this->getModCon()->getCon();
443
  $aWizards = $this->getModuleWizardsForRender();
444
+ return [
445
+ 'strings' => [
446
  'plugin_name' => $oCon->getHumanName()
447
+ ],
448
+ 'flags' => [
449
  'is_premium' => $oFO->isPremium(),
450
  'has_other_wizards' => false
451
+ ],
452
+ 'hrefs' => [
453
  'dashboard' => $oFO->getUrl_AdminPage(),
454
  'gopro' => 'https://icwp.io/ap',
455
+ ],
456
+ 'imgs' => [],
457
+ 'data' => [
458
  'mod_wizards_count' => count( $aWizards ),
459
  'mod_wizards' => $aWizards
460
+ ],
461
+ ];
462
  }
463
 
464
  /**
466
  * @return array
467
  */
468
  protected function getRenderData_SlideExtra( $sStep ) {
469
+ return [];
470
  }
471
 
472
  /**
508
  * @return array[]
509
  */
510
  protected function getStepsDefinition() {
511
+ $aNoAccess = [
512
+ 'no_access' => [
513
  'title' => __( 'No Access', 'wp-simple-firewall' ),
514
+ ]
515
+ ];
516
  $aSteps = array_merge( $this->getAllDefinedSteps(), $aNoAccess );
517
  foreach ( $aSteps as $sSlug => $aStep ) {
518
  $aSteps[ $sSlug ][ 'slug' ] = $sSlug;
src/wizards/hack_protect.php CHANGED
@@ -251,8 +251,8 @@ class ICWP_WPSF_Wizard_HackProtect extends ICWP_WPSF_Wizard_BaseWpsf {
251
  $sContext = $oReq->post( 'context' );
252
  $sItemAction = $oReq->post( 'ptgaction' );
253
 
254
- $oWpPlugins = $this->loadWpPlugins();
255
- $oWpThemes = $this->loadWpThemes();
256
 
257
  // 1. load the asset
258
  if ( $sContext == 'plugins' ) {
@@ -498,8 +498,8 @@ class ICWP_WPSF_Wizard_HackProtect extends ICWP_WPSF_Wizard_BaseWpsf {
498
  $oResults = $oP->scanThemes();
499
  }
500
 
501
- $oWpPlugins = $this->loadWpPlugins();
502
- $oWpThemes = $this->loadWpThemes();
503
  foreach ( $oResults->getUniqueSlugs() as $sSlug ) {
504
 
505
  if ( $sContext == 'plugins' ) {
251
  $sContext = $oReq->post( 'context' );
252
  $sItemAction = $oReq->post( 'ptgaction' );
253
 
254
+ $oWpPlugins = Services::WpPlugins();
255
+ $oWpThemes = Services::WpThemes();
256
 
257
  // 1. load the asset
258
  if ( $sContext == 'plugins' ) {
498
  $oResults = $oP->scanThemes();
499
  }
500
 
501
+ $oWpPlugins = Services::WpPlugins();
502
+ $oWpThemes = Services::WpThemes();
503
  foreach ( $oResults->getUniqueSlugs() as $sSlug ) {
504
 
505
  if ( $sContext == 'plugins' ) {
src/wizards/login_protect.php CHANGED
@@ -116,7 +116,7 @@ class ICWP_WPSF_Wizard_LoginProtect extends ICWP_WPSF_Wizard_BaseWpsf {
116
  $sMessage = __( 'Code was empty.', 'wp-simple-firewall' );
117
  }
118
  else {
119
- $oUser = $this->loadWpUsers()->getCurrentWpUser();
120
  /** @var ICWP_WPSF_Processor_LoginProtect $oProc */
121
  $oProc = $oFO->getProcessor();
122
  $oProcGa = $oProc->getSubProIntent()
@@ -216,7 +216,7 @@ class ICWP_WPSF_Wizard_LoginProtect extends ICWP_WPSF_Wizard_BaseWpsf {
216
  switch ( $sStep ) {
217
 
218
  case 'authemail':
219
- $oUser = $this->loadWpUsers()->getCurrentWpUser();
220
  $aAdditional = array(
221
  'data' => array(
222
  'name' => $oUser->first_name,
@@ -226,7 +226,7 @@ class ICWP_WPSF_Wizard_LoginProtect extends ICWP_WPSF_Wizard_BaseWpsf {
226
  break;
227
 
228
  case 'authga':
229
- $oUser = $this->loadWpUsers()->getCurrentWpUser();
230
  /** @var ICWP_WPSF_Processor_LoginProtect $oProc */
231
  $oProc = $oFO->getProcessor();
232
  $oProcGa = $oProc->getSubProIntent()
116
  $sMessage = __( 'Code was empty.', 'wp-simple-firewall' );
117
  }
118
  else {
119
+ $oUser = Services::WpUsers()->getCurrentWpUser();
120
  /** @var ICWP_WPSF_Processor_LoginProtect $oProc */
121
  $oProc = $oFO->getProcessor();
122
  $oProcGa = $oProc->getSubProIntent()
216
  switch ( $sStep ) {
217
 
218
  case 'authemail':
219
+ $oUser = Services::WpUsers()->getCurrentWpUser();
220
  $aAdditional = array(
221
  'data' => array(
222
  'name' => $oUser->first_name,
226
  break;
227
 
228
  case 'authga':
229
+ $oUser = Services::WpUsers()->getCurrentWpUser();
230
  /** @var ICWP_WPSF_Processor_LoginProtect $oProc */
231
  $oProc = $oFO->getProcessor();
232
  $oProcGa = $oProc->getSubProIntent()
src/wizards/plugin.php CHANGED
@@ -100,23 +100,23 @@ class ICWP_WPSF_Wizard_Plugin extends ICWP_WPSF_Wizard_BaseWpsf {
100
  * @return string[]
101
  */
102
  private function determineWizardSteps_Gdpr() {
103
- return array(
104
  'start',
105
  'search',
106
  'results',
107
  'finished',
108
- );
109
  }
110
 
111
  /**
112
  * @return string[]
113
  */
114
  private function determineWizardSteps_Import() {
115
- return array(
116
  'start',
117
  'import',
118
  'finished',
119
- );
120
  }
121
 
122
  /**
@@ -127,10 +127,10 @@ class ICWP_WPSF_Wizard_Plugin extends ICWP_WPSF_Wizard_BaseWpsf {
127
  $oFO = $this->getModCon();
128
  $oConn = $this->getPluginCon();
129
 
130
- $aStepsSlugs = array(
131
  'welcome',
132
  'ip_detect'
133
- );
134
  // if ( !$oFO->isPremium() ) {
135
  // $aStepsSlugs[] = 'license'; not showing it for now
136
  // }
@@ -183,7 +183,7 @@ class ICWP_WPSF_Wizard_Plugin extends ICWP_WPSF_Wizard_BaseWpsf {
183
  protected function getRenderData_SlideExtra( $sStep ) {
184
  $oConn = $this->getPluginCon();
185
 
186
- $aAdditional = array();
187
 
188
  $sCurrentWiz = $this->getWizardSlug();
189
 
@@ -191,50 +191,50 @@ class ICWP_WPSF_Wizard_Plugin extends ICWP_WPSF_Wizard_BaseWpsf {
191
 
192
  switch ( $sStep ) {
193
  case 'ip_detect':
194
- $aAdditional = array(
195
- 'hrefs' => array(
196
  'visitor_ip' => 'https://icwp.io/visitorip',
197
- )
198
- );
199
  break;
200
  case 'license':
201
  break;
202
  case 'import':
203
- $aAdditional = array(
204
- 'hrefs' => array(
205
  'blog_importexport' => 'https://icwp.io/av'
206
- ),
207
- 'imgs' => array(
208
  'shieldnetworkmini' => $oConn->getPluginUrl_Image( 'shield/shieldnetworkmini.png' ),
209
- )
210
- );
211
  break;
212
 
213
  case 'optin':
214
  $oUser = Services::WpUsers()->getCurrentWpUser();
215
- $aAdditional = array(
216
- 'vars' => array(
217
  'name' => $oUser->first_name,
218
  'user_email' => $oUser->user_email
219
- ),
220
- 'hrefs' => array(
221
  'privacy_policy' => $this->getModCon()->getDef( 'href_privacy_policy' )
222
- ),
223
- 'strings' => array(
224
  'privacy_policy' => sprintf(
225
  'I certify that I have read and agree to the <a href="%s" target="_blank">Privacy Policy</a>',
226
  $this->getModCon()->getDef( 'href_privacy_policy' )
227
  ),
228
- )
229
- );
230
  break;
231
 
232
  case 'thankyou':
233
  break;
234
 
235
  case 'how_shield_works':
236
- $aAdditional = array(
237
- 'imgs' => array(
238
  'how_shield_works' => $oConn->getPluginUrl_Image( 'wizard/general-shield_where.png' ),
239
  'modules' => $oConn->getPluginUrl_Image( 'wizard/general-shield_modules.png' ),
240
  'options' => $oConn->getPluginUrl_Image( 'wizard/general-shield_options.png' ),
@@ -243,8 +243,8 @@ class ICWP_WPSF_Wizard_Plugin extends ICWP_WPSF_Wizard_BaseWpsf {
243
  'actions' => $oConn->getPluginUrl_Image( 'wizard/general-shield_actions.png' ),
244
  'option_help' => $oConn->getPluginUrl_Image( 'wizard/general-option_help.png' ),
245
  'module_onoff' => $oConn->getPluginUrl_Image( 'wizard/general-module_onoff.png' ),
246
- ),
247
- 'headings' => array(
248
  'how_shield_works' => __( 'Where to find Shield', 'wp-simple-firewall' ),
249
  'modules' => __( 'Accessing Each Module', 'wp-simple-firewall' ),
250
  'options' => __( 'Accessing Options', 'wp-simple-firewall' ),
@@ -253,8 +253,8 @@ class ICWP_WPSF_Wizard_Plugin extends ICWP_WPSF_Wizard_BaseWpsf {
253
  'actions' => __( 'Actions (not Options)', 'wp-simple-firewall' ),
254
  'option_help' => __( 'Help For Each Option', 'wp-simple-firewall' ),
255
  'module_onoff' => __( 'Module On/Off Switch', 'wp-simple-firewall' ),
256
- ),
257
- 'captions' => array(
258
  'how_shield_works' => sprintf( __( "You'll find the main %s settings in the left-hand WordPress menu.", 'wp-simple-firewall' ), $oConn->getHumanName() ),
259
  'modules' => __( 'Shield is split up into independent modules for accessing the options of each feature.', 'wp-simple-firewall' ),
260
  'options' => __( 'When you load a module, you can access the options by clicking on the Options Panel link.', 'wp-simple-firewall' ),
@@ -264,8 +264,8 @@ class ICWP_WPSF_Wizard_Plugin extends ICWP_WPSF_Wizard_BaseWpsf {
264
  .' '.__( 'Note: Not all modules have the actions section', 'wp-simple-firewall' ),
265
  'module_onoff' => __( 'Each module has an Enable/Disable checkbox to turn on/off all processing for that module', 'wp-simple-firewall' ),
266
  'option_help' => __( 'To help you understand each option, most of them have a more info link, and/or a blog link, to read more', 'wp-simple-firewall' ),
267
- ),
268
- );
269
  break;
270
 
271
  default:
@@ -275,18 +275,18 @@ class ICWP_WPSF_Wizard_Plugin extends ICWP_WPSF_Wizard_BaseWpsf {
275
  else if ( $sCurrentWiz == 'importexport' ) {
276
  switch ( $sStep ) {
277
  case 'import':
278
- $aAdditional = array(
279
- 'hrefs' => array(
280
  'blog_importexport' => 'https://icwp.io/av'
281
- ),
282
- 'imgs' => array(
283
  'shieldnetworkmini' => $oConn->getPluginUrl_Image( 'shield/shieldnetworkmini.png' ),
284
- )
285
- );
286
  break;
287
  case 'results': //gdpr results
288
 
289
- $aAdditional = array();
290
  break;
291
 
292
  default:
@@ -306,16 +306,16 @@ class ICWP_WPSF_Wizard_Plugin extends ICWP_WPSF_Wizard_BaseWpsf {
306
  $nTotal += $aResult[ 'count' ];
307
  }
308
 
309
- $aAdditional = array(
310
- 'flags' => array(
311
  'has_search_items' => $bHasSearchItems
312
- ),
313
- 'data' => array(
314
  'result' => $this->runGdprSearch(),
315
  'count_total' => $nTotal,
316
  'has_results' => $nTotal > 0,
317
- )
318
- );
319
  break;
320
 
321
  default:
@@ -411,7 +411,7 @@ class ICWP_WPSF_Wizard_Plugin extends ICWP_WPSF_Wizard_BaseWpsf {
411
  $nCode = $oProc->getSubProImportExport()
412
  ->runImport( $sMasterSiteUrl, $sSecretKey, $bEnabledNetwork, $sSiteResponse );
413
 
414
- $aErrors = array(
415
  __( 'Options imported successfully to your site.', 'wp-simple-firewall' ), // success
416
  __( 'Secret key was empty.', 'wp-simple-firewall' ),
417
  __( 'Secret key was not 40 characters long.', 'wp-simple-firewall' ),
@@ -422,7 +422,7 @@ class ICWP_WPSF_Wizard_Plugin extends ICWP_WPSF_Wizard_BaseWpsf {
422
  __( 'Failure response returned from the site.', 'wp-simple-firewall' ),
423
  sprintf( __( 'Remote site responded with - %s', 'wp-simple-firewall' ), $sSiteResponse ),
424
  __( 'Data returned from the site was empty.', 'wp-simple-firewall' )
425
- );
426
 
427
  $sMessage = isset( $aErrors[ $nCode ] ) ? $aErrors[ $nCode ] : 'Unknown Error';
428
 
@@ -615,12 +615,12 @@ class ICWP_WPSF_Wizard_Plugin extends ICWP_WPSF_Wizard_BaseWpsf {
615
 
616
  if ( !empty( $sInput ) ) {
617
  if ( $sInput === 'CLEAR' ) {
618
- $aItems = array();
619
  }
620
  else {
621
  $aItems[] = $sInput;
622
  if ( $this->loadDP()->validEmail( $sInput ) ) {
623
- $oUser = $this->loadWpUsers()->getUserByEmail( $sInput );
624
  if ( !is_null( $oUser ) ) {
625
  $aItems[] = $oUser->user_login;
626
  }
@@ -628,7 +628,7 @@ class ICWP_WPSF_Wizard_Plugin extends ICWP_WPSF_Wizard_BaseWpsf {
628
  else {
629
  $sUsername = sanitize_user( $sInput );
630
  if ( !empty( $sUsername ) ) {
631
- $oUser = $this->loadWpUsers()->getUserByUsername( $sUsername );
632
  if ( $oUser instanceof WP_User ) {
633
  $aItems[] = $oUser->user_email;
634
  }
@@ -718,10 +718,9 @@ class ICWP_WPSF_Wizard_Plugin extends ICWP_WPSF_Wizard_BaseWpsf {
718
  * @return array
719
  */
720
  private function getGdprSearchItems() {
721
- $aItems = $this->loadWp()
722
- ->getTransient( $this->getPluginCon()->prefix( 'gdpr-items' ) );
723
  if ( !is_array( $aItems ) ) {
724
- $aItems = array();
725
  }
726
  return $aItems;
727
  }
@@ -732,15 +731,15 @@ class ICWP_WPSF_Wizard_Plugin extends ICWP_WPSF_Wizard_BaseWpsf {
732
  */
733
  private function setGdprSearchItems( $aItems ) {
734
  if ( !is_array( $aItems ) ) {
735
- $aItems = array();
736
  }
737
  $aItems = array_filter( array_unique( $aItems ) );
738
- $this->loadWp()
739
- ->setTransient(
740
- $this->getPluginCon()->prefix( 'gdpr-items' ),
741
- $aItems,
742
- MINUTE_IN_SECONDS*10
743
- );
744
  return $aItems;
745
  }
746
 
@@ -755,7 +754,7 @@ class ICWP_WPSF_Wizard_Plugin extends ICWP_WPSF_Wizard_BaseWpsf {
755
  ->getQuerySelector()
756
  ->setResultsAsVo( false );
757
 
758
- $aItems = array();
759
  foreach ( $this->getGdprSearchItems() as $sItem ) {
760
  try {
761
  $aResults = $oFinder->reset()
@@ -767,14 +766,14 @@ class ICWP_WPSF_Wizard_Plugin extends ICWP_WPSF_Wizard_BaseWpsf {
767
  ->query();
768
  }
769
  catch ( \Exception $oE ) {
770
- $aResults = array();
771
  }
772
  // $aResults = array_intersect_key( $aResults, array_flip( [ 'wp_username', 'message' ] ) );
773
- $aItems[ $sItem ] = array(
774
  'entries' => $aResults,
775
  'count' => count( $aResults ),
776
  'has' => count( $aResults ) > 0,
777
- );
778
  }
779
  return $aItems;
780
  }
100
  * @return string[]
101
  */
102
  private function determineWizardSteps_Gdpr() {
103
+ return [
104
  'start',
105
  'search',
106
  'results',
107
  'finished',
108
+ ];
109
  }
110
 
111
  /**
112
  * @return string[]
113
  */
114
  private function determineWizardSteps_Import() {
115
+ return [
116
  'start',
117
  'import',
118
  'finished',
119
+ ];
120
  }
121
 
122
  /**
127
  $oFO = $this->getModCon();
128
  $oConn = $this->getPluginCon();
129
 
130
+ $aStepsSlugs = [
131
  'welcome',
132
  'ip_detect'
133
+ ];
134
  // if ( !$oFO->isPremium() ) {
135
  // $aStepsSlugs[] = 'license'; not showing it for now
136
  // }
183
  protected function getRenderData_SlideExtra( $sStep ) {
184
  $oConn = $this->getPluginCon();
185
 
186
+ $aAdditional = [];
187
 
188
  $sCurrentWiz = $this->getWizardSlug();
189
 
191
 
192
  switch ( $sStep ) {
193
  case 'ip_detect':
194
+ $aAdditional = [
195
+ 'hrefs' => [
196
  'visitor_ip' => 'https://icwp.io/visitorip',
197
+ ]
198
+ ];
199
  break;
200
  case 'license':
201
  break;
202
  case 'import':
203
+ $aAdditional = [
204
+ 'hrefs' => [
205
  'blog_importexport' => 'https://icwp.io/av'
206
+ ],
207
+ 'imgs' => [
208
  'shieldnetworkmini' => $oConn->getPluginUrl_Image( 'shield/shieldnetworkmini.png' ),
209
+ ]
210
+ ];
211
  break;
212
 
213
  case 'optin':
214
  $oUser = Services::WpUsers()->getCurrentWpUser();
215
+ $aAdditional = [
216
+ 'vars' => [
217
  'name' => $oUser->first_name,
218
  'user_email' => $oUser->user_email
219
+ ],
220
+ 'hrefs' => [
221
  'privacy_policy' => $this->getModCon()->getDef( 'href_privacy_policy' )
222
+ ],
223
+ 'strings' => [
224
  'privacy_policy' => sprintf(
225
  'I certify that I have read and agree to the <a href="%s" target="_blank">Privacy Policy</a>',
226
  $this->getModCon()->getDef( 'href_privacy_policy' )
227
  ),
228
+ ]
229
+ ];
230
  break;
231
 
232
  case 'thankyou':
233
  break;
234
 
235
  case 'how_shield_works':
236
+ $aAdditional = [
237
+ 'imgs' => [
238
  'how_shield_works' => $oConn->getPluginUrl_Image( 'wizard/general-shield_where.png' ),
239
  'modules' => $oConn->getPluginUrl_Image( 'wizard/general-shield_modules.png' ),
240
  'options' => $oConn->getPluginUrl_Image( 'wizard/general-shield_options.png' ),
243
  'actions' => $oConn->getPluginUrl_Image( 'wizard/general-shield_actions.png' ),
244
  'option_help' => $oConn->getPluginUrl_Image( 'wizard/general-option_help.png' ),
245
  'module_onoff' => $oConn->getPluginUrl_Image( 'wizard/general-module_onoff.png' ),
246
+ ],
247
+ 'headings' => [
248
  'how_shield_works' => __( 'Where to find Shield', 'wp-simple-firewall' ),
249
  'modules' => __( 'Accessing Each Module', 'wp-simple-firewall' ),
250
  'options' => __( 'Accessing Options', 'wp-simple-firewall' ),
253
  'actions' => __( 'Actions (not Options)', 'wp-simple-firewall' ),
254
  'option_help' => __( 'Help For Each Option', 'wp-simple-firewall' ),
255
  'module_onoff' => __( 'Module On/Off Switch', 'wp-simple-firewall' ),
256
+ ],
257
+ 'captions' => [
258
  'how_shield_works' => sprintf( __( "You'll find the main %s settings in the left-hand WordPress menu.", 'wp-simple-firewall' ), $oConn->getHumanName() ),
259
  'modules' => __( 'Shield is split up into independent modules for accessing the options of each feature.', 'wp-simple-firewall' ),
260
  'options' => __( 'When you load a module, you can access the options by clicking on the Options Panel link.', 'wp-simple-firewall' ),
264
  .' '.__( 'Note: Not all modules have the actions section', 'wp-simple-firewall' ),
265
  'module_onoff' => __( 'Each module has an Enable/Disable checkbox to turn on/off all processing for that module', 'wp-simple-firewall' ),
266
  'option_help' => __( 'To help you understand each option, most of them have a more info link, and/or a blog link, to read more', 'wp-simple-firewall' ),
267
+ ],
268
+ ];
269
  break;
270
 
271
  default:
275
  else if ( $sCurrentWiz == 'importexport' ) {
276
  switch ( $sStep ) {
277
  case 'import':
278
+ $aAdditional = [
279
+ 'hrefs' => [
280
  'blog_importexport' => 'https://icwp.io/av'
281
+ ],
282
+ 'imgs' => [
283
  'shieldnetworkmini' => $oConn->getPluginUrl_Image( 'shield/shieldnetworkmini.png' ),
284
+ ]
285
+ ];
286
  break;
287
  case 'results': //gdpr results
288
 
289
+ $aAdditional = [];
290
  break;
291
 
292
  default:
306
  $nTotal += $aResult[ 'count' ];
307
  }
308
 
309
+ $aAdditional = [
310
+ 'flags' => [
311
  'has_search_items' => $bHasSearchItems
312
+ ],
313
+ 'data' => [
314
  'result' => $this->runGdprSearch(),
315
  'count_total' => $nTotal,
316
  'has_results' => $nTotal > 0,
317
+ ]
318
+ ];
319
  break;
320
 
321
  default:
411
  $nCode = $oProc->getSubProImportExport()
412
  ->runImport( $sMasterSiteUrl, $sSecretKey, $bEnabledNetwork, $sSiteResponse );
413
 
414
+ $aErrors = [
415
  __( 'Options imported successfully to your site.', 'wp-simple-firewall' ), // success
416
  __( 'Secret key was empty.', 'wp-simple-firewall' ),
417
  __( 'Secret key was not 40 characters long.', 'wp-simple-firewall' ),
422
  __( 'Failure response returned from the site.', 'wp-simple-firewall' ),
423
  sprintf( __( 'Remote site responded with - %s', 'wp-simple-firewall' ), $sSiteResponse ),
424
  __( 'Data returned from the site was empty.', 'wp-simple-firewall' )
425
+ ];
426
 
427
  $sMessage = isset( $aErrors[ $nCode ] ) ? $aErrors[ $nCode ] : 'Unknown Error';
428
 
615
 
616
  if ( !empty( $sInput ) ) {
617
  if ( $sInput === 'CLEAR' ) {
618
+ $aItems = [];
619
  }
620
  else {
621
  $aItems[] = $sInput;
622
  if ( $this->loadDP()->validEmail( $sInput ) ) {
623
+ $oUser = Services::WpUsers()->getUserByEmail( $sInput );
624
  if ( !is_null( $oUser ) ) {
625
  $aItems[] = $oUser->user_login;
626
  }
628
  else {
629
  $sUsername = sanitize_user( $sInput );
630
  if ( !empty( $sUsername ) ) {
631
+ $oUser = Services::WpUsers()->getUserByUsername( $sUsername );
632
  if ( $oUser instanceof WP_User ) {
633
  $aItems[] = $oUser->user_email;
634
  }
718
  * @return array
719
  */
720
  private function getGdprSearchItems() {
721
+ $aItems = Services::WpGeneral()->getTransient( $this->getPluginCon()->prefix( 'gdpr-items' ) );
 
722
  if ( !is_array( $aItems ) ) {
723
+ $aItems = [];
724
  }
725
  return $aItems;
726
  }
731
  */
732
  private function setGdprSearchItems( $aItems ) {
733
  if ( !is_array( $aItems ) ) {
734
+ $aItems = [];
735
  }
736
  $aItems = array_filter( array_unique( $aItems ) );
737
+ Services::WpGeneral()
738
+ ->setTransient(
739
+ $this->getPluginCon()->prefix( 'gdpr-items' ),
740
+ $aItems,
741
+ MINUTE_IN_SECONDS*10
742
+ );
743
  return $aItems;
744
  }
745
 
754
  ->getQuerySelector()
755
  ->setResultsAsVo( false );
756
 
757
+ $aItems = [];
758
  foreach ( $this->getGdprSearchItems() as $sItem ) {
759
  try {
760
  $aResults = $oFinder->reset()
766
  ->query();
767
  }
768
  catch ( \Exception $oE ) {
769
+ $aResults = [];
770
  }
771
  // $aResults = array_intersect_key( $aResults, array_flip( [ 'wp_username', 'message' ] ) );
772
+ $aItems[ $sItem ] = [
773
  'entries' => $aResults,
774
  'count' => count( $aResults ),
775
  'has' => count( $aResults ) > 0,
776
+ ];
777
  }
778
  return $aItems;
779
  }
templates/twig/snippets/options_form.twig CHANGED
@@ -19,7 +19,23 @@
19
  role="tabpanel" id="tab-{{ opt_section.slug }}">
20
 
21
  <div class="row">
22
- <div class="col-12"><h5 class="mb-3 mt-3">{{ opt_section.title }}</h5></div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  <div class="col-12">
24
  {% if ( opt_section.summary is defined ) and opt_section.summary|length %}
25
  <div class="row">
@@ -37,6 +53,26 @@
37
  </div>
38
  </div>
39
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
  {% for key, aOption in opt_section.options %}
41
  <div class="form-group row">
42
  <label for="Opt-{{ aOption.key }}"
@@ -44,9 +80,10 @@
44
  class="col-sm-1 col-md-2 col-lg-3 col-xl-2 col-form-label">
45
  {{ aOption.name }}
46
  {% if aOption.disabled %}
47
- <br/>
48
  <div class="badge badge-warning">
49
- <a href="{{ hrefs.go_pro }}" target="_blank" class="text-dark">{{ strings.pro_only_option }}</a>
 
50
  </div>
51
  {% endif %}
52
  </label>
@@ -111,7 +148,7 @@
111
  class="custom-select">
112
  {% for option_value, option_value_name in aOption.value_options %}
113
  <option value="{{ option_value }}"
114
- {% if aOption.value is sameas( option_value ) %}
115
  selected="selected"
116
  {% endif %}
117
  id="Opt-{{ aOption.key }}_{{ option_value }}">
19
  role="tabpanel" id="tab-{{ opt_section.slug }}">
20
 
21
  <div class="row">
22
+ <div class="col-12">
23
+ <h5 class="mb-3 mt-3">
24
+ {{ opt_section.title }}
25
+ <small>
26
+ {% if opt_section.help_video_url is not empty %}
27
+ <a class="section-help-video"
28
+ title="{{ strings.show_help_video_section }}"
29
+ href="{{ opt_section.help_video_url }}"
30
+ data-featherlight="iframe" data-featherlight-iframe-allowfullscreen="true"
31
+ data-featherlight-iframe-width="1200"
32
+ data-featherlight-iframe-height="675">
33
+ <span class="dashicons dashicons-video-alt3"></span>
34
+ </a>
35
+ {% endif %}
36
+ </small>
37
+ </h5>
38
+ </div>
39
  <div class="col-12">
40
  {% if ( opt_section.summary is defined ) and opt_section.summary|length %}
41
  <div class="row">
53
  </div>
54
  </div>
55
 
56
+ {% if opt_section.warnings|length %}
57
+ {% for section_warning in opt_section.warnings %}
58
+ <div class="row">
59
+ <div class="col">
60
+ <div class="alert alert-warning text-center">{{ section_warning|raw }}</div>
61
+ </div>
62
+ </div>
63
+ {% endfor %}
64
+ {% endif %}
65
+
66
+ {% if opt_section.notices|length %}
67
+ {% for section_notice in opt_section.notices %}
68
+ <div class="row">
69
+ <div class="col">
70
+ <div class="alert alert-info text-center">{{ section_notice|raw }}</div>
71
+ </div>
72
+ </div>
73
+ {% endfor %}
74
+ {% endif %}
75
+
76
  {% for key, aOption in opt_section.options %}
77
  <div class="form-group row">
78
  <label for="Opt-{{ aOption.key }}"
80
  class="col-sm-1 col-md-2 col-lg-3 col-xl-2 col-form-label">
81
  {{ aOption.name }}
82
  {% if aOption.disabled %}
83
+ <br />
84
  <div class="badge badge-warning">
85
+ <a href="{{ hrefs.go_pro }}" target="_blank"
86
+ class="text-dark">{{ strings.pro_only_option }}</a>
87
  </div>
88
  {% endif %}
89
  </label>
148
  class="custom-select">
149
  {% for option_value, option_value_name in aOption.value_options %}
150
  <option value="{{ option_value }}"
151
+ {% if aOption.value == option_value %}
152
  selected="selected"
153
  {% endif %}
154
  id="Opt-{{ aOption.key }}_{{ option_value }}">
templates/twig/wpadmin_pages/insights_new/base.twig CHANGED
@@ -41,6 +41,23 @@
41
  {% endif %}
42
  {% endfor %}
43
  <div class="nav-item" id="PluginHeadwayChangelog"></div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
  </ul>
45
  </div>
46
  {#<form class="form-inline">#}
@@ -55,7 +72,13 @@
55
  var HW_config = {
56
  selector: "#PluginHeadwayChangelog", // CSS selector where to inject the badge
57
  account: "{{ vars.changelog_id }}"
58
- }
 
 
 
 
 
 
59
  </script>
60
  <script async src="https://cdn.headwayapp.co/widget.js"></script>
61
  {% endblock %}
41
  {% endif %}
42
  {% endfor %}
43
  <div class="nav-item" id="PluginHeadwayChangelog"></div>
44
+
45
+ <select class="selectpicker" data-live-search="true"
46
+ title="Jump to plugin option"
47
+ data-size="10" multiple
48
+ data-header="Type below to search all plugin options ..."
49
+ onchange="location = this.value;">
50
+ {% for select_section_name,select_section_opts in vars.search_select %}
51
+ <optgroup label="{{ select_section_name }}">
52
+ {% for select_opt_key,select_opt_data in select_section_opts %}
53
+ <option value="{{ select_opt_data.href }}" aria-selected="false"
54
+ data-tokens="{{ select_opt_data.summary }}"
55
+ >{{ select_opt_data.name }}
56
+ </option>
57
+ {% endfor %}
58
+ </optgroup>
59
+ {% endfor %}
60
+ </select>
61
  </ul>
62
  </div>
63
  {#<form class="form-inline">#}
72
  var HW_config = {
73
  selector: "#PluginHeadwayChangelog", // CSS selector where to inject the badge
74
  account: "{{ vars.changelog_id }}"
75
+ };
76
+ jQuery( document ).ready( function () {
77
+ jQuery.fn.selectpicker.Constructor.BootstrapVersion = '4';
78
+
79
+ jQuery( '.selectpicker' ).selectpicker()
80
+ .removeAttr("selected");
81
+ } );
82
  </script>
83
  <script async src="https://cdn.headwayapp.co/widget.js"></script>
84
  {% endblock %}
templates/twig/wpadmin_pages/insights_new/settings/index.twig CHANGED
@@ -26,5 +26,9 @@
26
  iCWP_WPSF_OptsPageRender.renderForm( {{ ajax.mod_opts_form_render|raw }} );
27
  iCWP_WPSF_OptionsFormSubmit.updateAjaxReqParams( {{ ajax.mod_options|raw }} );
28
  jQuery( 'a.nav-link.module' ).tooltip();
 
 
 
 
29
  </script>
30
  {% endblock %}
26
  iCWP_WPSF_OptsPageRender.renderForm( {{ ajax.mod_opts_form_render|raw }} );
27
  iCWP_WPSF_OptionsFormSubmit.updateAjaxReqParams( {{ ajax.mod_options|raw }} );
28
  jQuery( 'a.nav-link.module' ).tooltip();
29
+ jQuery( 'a.section-help-video' ).tooltip({
30
+ placement: 'right',
31
+ trigger: 'hover'
32
+ } );
33
  </script>
34
  {% endblock %}