Shield Security for WordPress - Version 8.2.1

Version Description

  • Current Release = Released: 7th October, 2019 - Release Notes

  • (v.1) IMPROVED: Further reduce Malware false positives by also using SVN trunk data when verifying files for plugins and themes.

  • (v.1) ADDED: Initial support for repairing Themes that have been installed from WordPress.org.

  • (v.1) ADDED: Support for using WP Hashes.com for WordPress.org themes (already done for plugins).

  • (v.1) FIXED: PHP notices in the logs.

Download this release

Release Info

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

Code changes from version 8.2.0 to 8.2.1

Files changed (50) hide show
  1. icwp-wpsf.php +1 -1
  2. languages/wp-simple-firewall-bs_BA.mo +0 -0
  3. languages/wp-simple-firewall-ja.mo +0 -0
  4. languages/wp-simple-firewall-nl_NL.mo +0 -0
  5. languages/wp-simple-firewall-sr_RS.mo +0 -0
  6. plugin-spec.php +3 -3
  7. readme.txt +10 -2
  8. src/config/feature-hack_protect.php +2 -1
  9. src/features/insights.php +0 -5
  10. src/lib/src/Modules/Base/Options.php +6 -6
  11. src/lib/src/Modules/HackGuard/Options.php +10 -2
  12. src/lib/src/Modules/HackGuard/Strings.php +8 -0
  13. src/lib/src/Scans/Base/BaseScanActionVO.php +0 -1
  14. src/lib/src/Scans/Base/Files/BaseFileMapScan.php +2 -2
  15. src/lib/src/Scans/Helpers/BuildHashesFromApi.php +24 -8
  16. src/lib/src/Scans/Helpers/StandardDirectoryIterator.php +2 -4
  17. src/lib/src/Scans/Mal/BuildFileMap.php +1 -1
  18. src/lib/src/Scans/Mal/FileScanner.php +26 -39
  19. src/lib/src/Scans/Mal/Repair.php +68 -9
  20. src/lib/src/Scans/Mal/Utilities/Whitelist.php +1 -1
  21. src/lib/src/Scans/Ptg/ItemScanner.php +5 -0
  22. src/lib/src/Scans/Ptg/Scan.php +35 -24
  23. src/lib/src/Scans/Ptg/{PluginWporgScanner.php → WporgAssetScanner.php} +61 -15
  24. src/lib/vendor/composer/autoload_classmap.php +12 -1
  25. src/lib/vendor/composer/autoload_static.php +12 -1
  26. src/lib/vendor/fernleafsystems/wordpress-services/src/Core/Plugins.php +24 -10
  27. src/lib/vendor/fernleafsystems/wordpress-services/src/Core/Themes.php +86 -29
  28. src/lib/vendor/fernleafsystems/wordpress-services/src/Core/VOs/WpPluginVo.php +67 -25
  29. src/lib/vendor/fernleafsystems/wordpress-services/src/Core/VOs/WpThemeVo.php +106 -0
  30. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/File/Cache/LoadFromCache.php +3 -1
  31. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/Plugin.php +1 -15
  32. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/PluginThemeBase.php +24 -0
  33. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/Theme.php +22 -0
  34. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Base/PluginThemeFilesBase.php +56 -0
  35. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Base/RepoBase.php +0 -45
  36. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Plugin/Api.php +10 -1
  37. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Plugin/Base.php +1 -1
  38. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Plugin/Download.php +21 -24
  39. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Plugin/Files.php +14 -44
  40. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Plugin/Repo.php +7 -2
  41. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Plugin/VOs/PluginInfoVO.php +23 -23
  42. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Plugin/Versions.php +9 -37
  43. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Theme/Api.php +71 -0
  44. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Theme/Base.php +61 -0
  45. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Theme/Download.php +46 -0
  46. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Theme/Files.php +128 -0
  47. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Theme/Repo.php +63 -0
  48. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Theme/VOs/ThemeInfoVO.php +40 -0
  49. src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Theme/Versions.php +64 -0
  50. src/processors/loginprotect_intent.php +0 -1
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: 8.2.0
7
  * Text Domain: wp-simple-firewall
8
  * Domain Path: /languages
9
  * Author: One Dollar Plugin
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: 8.2.1
7
  * Text Domain: wp-simple-firewall
8
  * Domain Path: /languages
9
  * Author: One Dollar Plugin
languages/wp-simple-firewall-bs_BA.mo CHANGED
Binary file
languages/wp-simple-firewall-ja.mo CHANGED
Binary file
languages/wp-simple-firewall-nl_NL.mo CHANGED
Binary file
languages/wp-simple-firewall-sr_RS.mo CHANGED
Binary file
plugin-spec.php CHANGED
@@ -1,8 +1,8 @@
1
  {
2
  "properties": {
3
- "version": "8.2.0",
4
- "release_timestamp": 1569918000,
5
- "build": "201910.0101",
6
  "slug_parent": "icwp",
7
  "slug_plugin": "wpsf",
8
  "human_name": "Shield",
1
  {
2
  "properties": {
3
+ "version": "8.2.1",
4
+ "release_timestamp": 1570444789,
5
+ "build": "201910.0701",
6
  "slug_parent": "icwp",
7
  "slug_plugin": "wpsf",
8
  "human_name": "Shield",
readme.txt CHANGED
@@ -8,7 +8,7 @@ Requires at least: 3.5.2
8
  Requires PHP: 5.4.0
9
  Recommended PHP: 7.0
10
  Tested up to: 5.3
11
- Stable tag: 8.2.0
12
 
13
  Security protection from hackers through smarter automation. Powerful scanners, 2-Factor Auth, limit logins, auto IP blocks & more.
14
 
@@ -370,7 +370,15 @@ You will always be able to use Shield Security and its free features in-full.
370
 
371
  [Go Pro for just $1/month](https://icwp.io/aa).
372
 
373
- = 8.2.0 - Current Release =
 
 
 
 
 
 
 
 
374
  *Released: 1st October, 2019* - [Release Notes](https://icwp.io/g0)
375
 
376
  * **(v.0)** IMPROVED: [**PRO**] Malware scanner now uses network intelligence to the gather information on malware results.
8
  Requires PHP: 5.4.0
9
  Recommended PHP: 7.0
10
  Tested up to: 5.3
11
+ Stable tag: 8.2.1
12
 
13
  Security protection from hackers through smarter automation. Powerful scanners, 2-Factor Auth, limit logins, auto IP blocks & more.
14
 
370
 
371
  [Go Pro for just $1/month](https://icwp.io/aa).
372
 
373
+ = 8.2.1 - Current Release =
374
+ *Released: 7th October, 2019* - [Release Notes](https://icwp.io/g0)
375
+
376
+ * **(v.1)** IMPROVED: Further reduce Malware false positives by also using SVN trunk data when verifying files for plugins and themes.
377
+ * **(v.1)** ADDED: Initial support for repairing Themes that have been installed from WordPress.org.
378
+ * **(v.1)** ADDED: Support for using [WP Hashes.com](https://wphashes.com) for WordPress.org themes (already done for plugins).
379
+ * **(v.1)** FIXED: PHP notices in the logs.
380
+
381
+ = 8.2 - Series =
382
  *Released: 1st October, 2019* - [Release Notes](https://icwp.io/g0)
383
 
384
  * **(v.0)** IMPROVED: [**PRO**] Malware scanner now uses network intelligence to the gather information on malware results.
src/config/feature-hack_protect.php CHANGED
@@ -739,7 +739,8 @@
739
  "url_mal_sigs_regex": "https://raw.githubusercontent.com/scr34m/php-malware-scanner/master/definitions/patterns_re.txt",
740
  "malware_whitelist_paths": [
741
  "wp-content/wflogs/",
742
- "wp-content/cache/"
 
743
  ],
744
  "cron_all_scans": "all-scans",
745
  "url_checksum_api": "https://api.wordpress.org/core/checksums/1.0/",
739
  "url_mal_sigs_regex": "https://raw.githubusercontent.com/scr34m/php-malware-scanner/master/definitions/patterns_re.txt",
740
  "malware_whitelist_paths": [
741
  "wp-content/wflogs/",
742
+ "wp-content/cache/",
743
+ "wp-content/icwp/rollback/"
744
  ],
745
  "cron_all_scans": "all-scans",
746
  "url_checksum_api": "https://api.wordpress.org/core/checksums/1.0/",
src/features/insights.php CHANGED
@@ -816,11 +816,6 @@ class ICWP_WPSF_FeatureHandler_Insights extends ICWP_WPSF_FeatureHandler_BaseWps
816
  )->count(),
817
  'tooltip' => __( 'Current IP addresses with offenses against the site.', 'wp-simple-firewall' )
818
  ],
819
- // 'pro' => array(
820
- // 'title' => _wpsf__( 'Pro' ),
821
- // 'val' => $this->isPremium() ? _wpsf__( 'Yes' ) : _wpsf__( 'No' ),
822
- // 'tooltip' => sprintf( _wpsf__( 'Is this site running %s Pro' ), $oConn->getHumanName() )
823
- // ),
824
  ];
825
  }
826
 
816
  )->count(),
817
  'tooltip' => __( 'Current IP addresses with offenses against the site.', 'wp-simple-firewall' )
818
  ],
 
 
 
 
 
819
  ];
820
  }
821
 
src/lib/src/Modules/Base/Options.php CHANGED
@@ -85,7 +85,7 @@ class Options {
85
  */
86
  public function deleteStorage() {
87
  $oWp = Services::WpGeneral();
88
- $oWp->deleteTransient( $this->getSpecTransientStorageKey() );
89
  return $oWp->deleteOption( $this->getOptionsStorageKey() );
90
  }
91
 
@@ -945,8 +945,8 @@ class Options {
945
  private function readConfiguration() {
946
  $oWp = Services::WpGeneral();
947
 
948
- $sTransientKey = $this->getSpecTransientStorageKey();
949
- $aConfig = $oWp->getTransient( $sTransientKey );
950
 
951
  $bRebuild = $this->getRebuildFromFile() || empty( $aConfig );
952
  if ( !$bRebuild && !empty( $aConfig ) && is_array( $aConfig ) ) {
@@ -968,7 +968,7 @@ class Options {
968
  $aConfig = [];
969
  }
970
  $aConfig[ 'meta_modts' ] = $this->getConfigModTime();
971
- $oWp->setTransient( $sTransientKey, $aConfig, DAY_IN_SECONDS );
972
  }
973
 
974
  $this->setRebuildFromFile( $bRebuild );
@@ -1001,8 +1001,8 @@ class Options {
1001
  /**
1002
  * @return string
1003
  */
1004
- private function getSpecTransientStorageKey() {
1005
- return 'icwp_'.md5( $this->getPathToConfig() );
1006
  }
1007
 
1008
  /**
85
  */
86
  public function deleteStorage() {
87
  $oWp = Services::WpGeneral();
88
+ $oWp->deleteOption( $this->getConfigStorageKey() );
89
  return $oWp->deleteOption( $this->getOptionsStorageKey() );
90
  }
91
 
945
  private function readConfiguration() {
946
  $oWp = Services::WpGeneral();
947
 
948
+ $sStorageKey = $this->getConfigStorageKey();
949
+ $aConfig = $oWp->getOption( $sStorageKey );
950
 
951
  $bRebuild = $this->getRebuildFromFile() || empty( $aConfig );
952
  if ( !$bRebuild && !empty( $aConfig ) && is_array( $aConfig ) ) {
968
  $aConfig = [];
969
  }
970
  $aConfig[ 'meta_modts' ] = $this->getConfigModTime();
971
+ $oWp->updateOption( $sStorageKey, $aConfig );
972
  }
973
 
974
  $this->setRebuildFromFile( $bRebuild );
1001
  /**
1002
  * @return string
1003
  */
1004
+ private function getConfigStorageKey() {
1005
+ return 'shield_mod_config_'.md5( $this->getPathToConfig() );
1006
  }
1007
 
1008
  /**
src/lib/src/Modules/HackGuard/Options.php CHANGED
@@ -115,11 +115,19 @@ class Options extends Base\ShieldOptions {
115
  return $this->isOpt( 'mal_autorepair_plugins', 'Y' );
116
  }
117
 
 
 
 
 
 
 
 
118
  /**
119
  * @return bool
120
  */
121
  public function isMalAutoRepair() {
122
- return $this->isMalAutoRepairCore() || $this->isMalAutoRepairPlugins() || $this->isMalAutoRepairSurgical();
 
123
  }
124
 
125
  /**
@@ -243,7 +251,7 @@ class Options extends Base\ShieldOptions {
243
  if ( $this->isUfcScanUploads() ) {
244
  $sUploadsDir = Services::WpGeneral()->getDirUploads();
245
  if ( !empty( $sUploadsDir ) ) {
246
- $aDirs[] = [
247
  'php',
248
  'php5',
249
  'js',
115
  return $this->isOpt( 'mal_autorepair_plugins', 'Y' );
116
  }
117
 
118
+ /**
119
+ * @return bool
120
+ */
121
+ public function isMalAutoRepairThemes() {
122
+ return $this->isOpt( 'mal_autorepair_themes', 'Y' );
123
+ }
124
+
125
  /**
126
  * @return bool
127
  */
128
  public function isMalAutoRepair() {
129
+ return $this->isMalAutoRepairCore() || $this->isMalAutoRepairPlugins() || $this->isMalAutoRepairThemes()
130
+ || $this->isMalAutoRepairSurgical();
131
  }
132
 
133
  /**
251
  if ( $this->isUfcScanUploads() ) {
252
  $sUploadsDir = Services::WpGeneral()->getDirUploads();
253
  if ( !empty( $sUploadsDir ) ) {
254
+ $aDirs[ $sUploadsDir ] = [
255
  'php',
256
  'php5',
257
  'js',
src/lib/src/Modules/HackGuard/Strings.php CHANGED
@@ -343,6 +343,14 @@ class Strings extends Base\Strings {
343
  .'<br />'.sprintf( '%s: %s', __( 'Important', 'wp-simple-firewall' ), __( "Also deletes suspected files if they weren't originally distributed with the plugin.", 'wp-simple-firewall' ) );
344
  break;
345
 
 
 
 
 
 
 
 
 
346
  case 'mal_fp_confidence' :
347
  $sName = __( 'Ignore False Positives Threshold', 'wp-simple-firewall' );
348
  $sSummary = __( 'Ignore False Positives In Scan Results Automatically', 'wp-simple-firewall' );
343
  .'<br />'.sprintf( '%s: %s', __( 'Important', 'wp-simple-firewall' ), __( "Also deletes suspected files if they weren't originally distributed with the plugin.", 'wp-simple-firewall' ) );
344
  break;
345
 
346
+ case 'mal_autorepair_themes' :
347
+ $sName = __( 'Auto-Repair WP Themes', 'wp-simple-firewall' );
348
+ $sSummary = __( 'Automatically Repair WordPress.org Themes', 'wp-simple-firewall' );
349
+ $sDescription = __( "Automatically repair any theme files found to have potential malware.", 'wp-simple-firewall' )
350
+ .'<br />'.sprintf( '%s: %s', __( 'Important', 'wp-simple-firewall' ), __( 'Only compatible with themes installed from WordPress.org.', 'wp-simple-firewall' ) )
351
+ .'<br />'.sprintf( '%s: %s', __( 'Important', 'wp-simple-firewall' ), __( "Also deletes suspected files if they weren't originally distributed with the theme.", 'wp-simple-firewall' ) );
352
+ break;
353
+
354
  case 'mal_fp_confidence' :
355
  $sName = __( 'Ignore False Positives Threshold', 'wp-simple-firewall' );
356
  $sSummary = __( 'Ignore False Positives In Scan Results Automatically', 'wp-simple-firewall' );
src/lib/src/Scans/Base/BaseScanActionVO.php CHANGED
@@ -19,7 +19,6 @@ use FernleafSystems\Utilities\Data\Adapter\StdClassAdapter;
19
  class BaseScanActionVO {
20
 
21
  use StdClassAdapter;
22
-
23
  const ITEM_STORAGE_LIMIT = 1;
24
 
25
  /**
19
  class BaseScanActionVO {
20
 
21
  use StdClassAdapter;
 
22
  const ITEM_STORAGE_LIMIT = 1;
23
 
24
  /**
src/lib/src/Scans/Base/Files/BaseFileMapScan.php CHANGED
@@ -18,8 +18,8 @@ abstract class BaseFileMapScan extends Base\BaseScan {
18
  $oAction = $this->getScanActionVO();
19
 
20
  $oTempRs = $this->getScanFromFileMap()
21
- ->setScanActionVO( $oAction )
22
- ->run();
23
 
24
  $aNewItems = [];
25
  if ( $oTempRs->hasItems() ) {
18
  $oAction = $this->getScanActionVO();
19
 
20
  $oTempRs = $this->getScanFromFileMap()
21
+ ->setScanActionVO( $oAction )
22
+ ->run();
23
 
24
  $aNewItems = [];
25
  if ( $oTempRs->hasItems() ) {
src/lib/src/Scans/Helpers/BuildHashesFromApi.php CHANGED
@@ -2,6 +2,7 @@
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Helpers;
4
 
 
5
  use FernleafSystems\Wordpress\Services\Services;
6
  use FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\Hashes;
7
 
@@ -23,20 +24,35 @@ class BuildHashesFromApi {
23
 
24
  /**
25
  * All file keys are their normalised file paths, with the ABSPATH stripped from it.
26
- * @param string $sPluginFile
27
  * @return string[] - keys are file paths relative to ABSPATH
28
  * @throws \Exception
29
  */
30
- public function build( $sPluginFile ) {
31
- $oWpPlugins = Services::WpPlugins();
32
- $oPluginVo = $oWpPlugins->getPluginAsVo( $sPluginFile );
33
 
34
- $sInstallDir = $oWpPlugins->getInstallationDir( $sPluginFile );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
 
36
- $aHashes = ( new Hashes\Plugin() )
37
- ->getHashes( $oPluginVo->slug, $oPluginVo->Version, 'md5' );
38
  if ( empty( $aHashes ) ) {
39
- throw new \Exception( 'Could not retrieve live hashes.' );
40
  }
41
 
42
  $aSnaps = [];
2
 
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Helpers;
4
 
5
+ use FernleafSystems\Wordpress\Services\Core\VOs;
6
  use FernleafSystems\Wordpress\Services\Services;
7
  use FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\Hashes;
8
 
24
 
25
  /**
26
  * All file keys are their normalised file paths, with the ABSPATH stripped from it.
27
+ * @param VOs\WpPluginVo|VOs\WpThemeVo $oAsset
28
  * @return string[] - keys are file paths relative to ABSPATH
29
  * @throws \Exception
30
  */
31
+ public function build( $oAsset ) {
 
 
32
 
33
+ if ( !$oAsset->isWpOrg() ) {
34
+ throw new \Exception( 'Not a WordPress.org asset.' );
35
+ }
36
+
37
+ if ( $oAsset instanceof VOs\WpPluginVo ) {
38
+ $sInstallDir = Services::WpPlugins()->getInstallationDir( $oAsset->file );
39
+ $aHashes = ( new Hashes\Plugin() )
40
+ ->getHashes( $oAsset->slug, $oAsset->Version, 'md5' );
41
+ }
42
+ else if ( $oAsset instanceof VOs\WpThemeVo ) {
43
+ if ( $oAsset->is_child ) {
44
+ throw new \Exception( 'Live hashes are not supported for child themes.' );
45
+ }
46
+ $sInstallDir = $oAsset->wp_theme->get_stylesheet_directory();
47
+ $aHashes = ( new Hashes\Theme() )
48
+ ->getHashes( $oAsset->stylesheet, $oAsset->version, 'md5' );
49
+ }
50
+ else {
51
+ throw new \Exception( 'Not a supported asset type' );
52
+ }
53
 
 
 
54
  if ( empty( $aHashes ) ) {
55
+ throw new \Exception( 'Could not retrieve live hashes for: '.$sInstallDir );
56
  }
57
 
58
  $aSnaps = [];
src/lib/src/Scans/Helpers/StandardDirectoryIterator.php CHANGED
@@ -19,11 +19,9 @@ class StandardDirectoryIterator {
19
  static public function create( $sDir, $nMaxDepth = 0, $aFileExts = [], $bExcludeCoreFiles = false ) {
20
 
21
  $oDirIterator = new \RecursiveDirectoryIterator( $sDir );
22
- if ( method_exists( $oDirIterator, 'setFlags' ) ) {
23
- $oDirIterator->setFlags( \RecursiveDirectoryIterator::SKIP_DOTS );
24
- }
25
 
26
- $oFilter = new ScannerRecursiveFilterIterator( new \RecursiveDirectoryIterator( $sDir ) );
27
  $oFilter->setFileExts( $aFileExts )
28
  ->setIsFilterOutWpCoreFiles( $bExcludeCoreFiles );
29
  $oRecurIter = new \RecursiveIteratorIterator( $oFilter );
19
  static public function create( $sDir, $nMaxDepth = 0, $aFileExts = [], $bExcludeCoreFiles = false ) {
20
 
21
  $oDirIterator = new \RecursiveDirectoryIterator( $sDir );
22
+ $oDirIterator->setFlags( \RecursiveDirectoryIterator::SKIP_DOTS );
 
 
23
 
24
+ $oFilter = new ScannerRecursiveFilterIterator( $oDirIterator );
25
  $oFilter->setFileExts( $aFileExts )
26
  ->setIsFilterOutWpCoreFiles( $bExcludeCoreFiles );
27
  $oRecurIter = new \RecursiveIteratorIterator( $oFilter );
src/lib/src/Scans/Mal/BuildFileMap.php CHANGED
@@ -37,7 +37,7 @@ class BuildFileMap {
37
  }
38
  catch ( \Exception $oE ) {
39
  error_log(
40
- sprintf( 'Shield file scanner attempted to read directory but there was error: "%s".', $oE->getMessage() )
41
  );
42
  }
43
  }
37
  }
38
  catch ( \Exception $oE ) {
39
  error_log(
40
+ sprintf( 'Shield file scanner attempted to read directory (%s) but there was error: "%s".', $sScanDir, $oE->getMessage() )
41
  );
42
  }
43
  }
src/lib/src/Scans/Mal/FileScanner.php CHANGED
@@ -3,7 +3,6 @@
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Mal;
4
 
5
  use FernleafSystems\Wordpress\Plugin\Shield;
6
- use FernleafSystems\Wordpress\Services\Core\VOs\WpPluginVo;
7
  use FernleafSystems\Wordpress\Services\Services;
8
  use FernleafSystems\Wordpress\Services\Utilities;
9
 
@@ -106,15 +105,13 @@ class FileScanner extends Shield\Scans\Base\Files\BaseFileScanner {
106
  * @return bool
107
  */
108
  private function canExcludeFile( $sFullPath ) {
109
- $bExclude = $this->isValidCoreFile( $sFullPath );
110
-
111
- if ( !$bExclude ) {
112
- if ( $this->isPluginFileValid( $sFullPath ) ) {
113
- $bExclude = true;
114
- ( new Shield\Scans\Mal\Utilities\FalsePositiveReporter() )
115
- ->setMod( $this->getMod() )
116
- ->report( $sFullPath, 'sha1', true );
117
- }
118
  }
119
  return $bExclude;
120
  }
@@ -150,37 +147,27 @@ class FileScanner extends Shield\Scans\Base\Files\BaseFileScanner {
150
  * @return bool
151
  */
152
  private function isPluginFileValid( $sFullPath ) {
153
- $bCanExclude = false;
154
-
155
- if ( strpos( $sFullPath, wp_normalize_path( WP_PLUGIN_DIR ) ) === 0 ) {
156
-
157
- $oPluginFiles = new Utilities\WpOrg\Plugin\Files();
158
- $oThePlugin = $oPluginFiles->findPluginFromFile( $sFullPath );
159
- if ( $oThePlugin instanceof WpPluginVo ) {
160
-
161
- $oPlugVersion = ( new Utilities\WpOrg\Plugin\Versions() )
162
- ->setWorkingSlug( $oThePlugin->slug )
163
- ->setWorkingVersion( $oThePlugin->Version );
164
-
165
- // Only try to download load a file if the plugin actually uses SVN Tags for this version.
166
- if ( $oPlugVersion->exists( $oThePlugin->Version, true ) ) {
167
- try {
168
- $sTmpFile = $oPluginFiles
169
- ->setWorkingSlug( $oThePlugin->slug )
170
- ->setWorkingVersion( $oThePlugin->Version )
171
- ->getOriginalFileFromVcs( $sFullPath );
172
- if ( Services::WpFs()->exists( $sTmpFile )
173
- && ( new Utilities\File\Compare\CompareHash() )->isEqualFilesMd5( $sTmpFile, $sFullPath ) ) {
174
- $bCanExclude = true;
175
- }
176
- }
177
- catch ( \Exception $oE ) {
178
- }
179
- }
180
- }
181
  }
 
 
182
 
183
- return $bCanExclude;
 
 
 
 
 
 
 
 
 
 
 
184
  }
185
 
186
  /**
3
  namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Mal;
4
 
5
  use FernleafSystems\Wordpress\Plugin\Shield;
 
6
  use FernleafSystems\Wordpress\Services\Services;
7
  use FernleafSystems\Wordpress\Services\Utilities;
8
 
105
  * @return bool
106
  */
107
  private function canExcludeFile( $sFullPath ) {
108
+ $bExclude = $this->isValidCoreFile( $sFullPath )
109
+ || $this->isPluginFileValid( $sFullPath ) || $this->isThemeFileValid( $sFullPath );
110
+
111
+ if ( $bExclude ) {
112
+ ( new Shield\Scans\Mal\Utilities\FalsePositiveReporter() )
113
+ ->setMod( $this->getMod() )
114
+ ->report( $sFullPath, 'sha1', true );
 
 
115
  }
116
  return $bExclude;
117
  }
147
  * @return bool
148
  */
149
  private function isPluginFileValid( $sFullPath ) {
150
+ try {
151
+ $bIsValidFile = ( new Utilities\WpOrg\Plugin\Files() )->verifyFileContents( $sFullPath );
152
+ }
153
+ catch ( \Exception $oE ) {
154
+ $bIsValidFile = false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
155
  }
156
+ return $bIsValidFile;
157
+ }
158
 
159
+ /**
160
+ * @param string $sFullPath - normalized
161
+ * @return bool
162
+ */
163
+ private function isThemeFileValid( $sFullPath ) {
164
+ try {
165
+ $bIsValidFile = ( new Utilities\WpOrg\Theme\Files() )->verifyFileContents( $sFullPath );
166
+ }
167
+ catch ( \Exception $oE ) {
168
+ $bIsValidFile = false;
169
+ }
170
+ return $bIsValidFile;
171
  }
172
 
173
  /**
src/lib/src/Scans/Mal/Repair.php CHANGED
@@ -44,11 +44,6 @@ class Repair extends Shield\Scans\Base\BaseRepair {
44
  $oOpts = $this->getOptions();
45
  $bSuccess = false;
46
 
47
- // 1) Report the file as being malware.
48
- ( new Shield\Scans\Mal\Utilities\FalsePositiveReporter() )
49
- ->setMod( $this->getMod() )
50
- ->report( $oItem->path_full, 'sha1', false );
51
-
52
  // 2). Repair
53
  try {
54
  $bCanAutoRepair = $this->canAutoRepairFromSource( $oItem );
@@ -57,6 +52,13 @@ class Repair extends Shield\Scans\Base\BaseRepair {
57
  $bCanAutoRepair = false;
58
  }
59
 
 
 
 
 
 
 
 
60
  if ( $bCanAutoRepair ) {
61
 
62
  if ( Services\Services::CoreFileHashes()->isCoreFile( $oItem->path_fragment ) ) {
@@ -70,8 +72,17 @@ class Repair extends Shield\Scans\Base\BaseRepair {
70
  $bSuccess = $this->repairItemInPlugin( $oItem );
71
  }
72
  }
73
- else if ( $oOpts->isMalAutoRepairSurgical() ) {
74
- $bSuccess = $this->repairSurgicalItem( $oItem );
 
 
 
 
 
 
 
 
 
75
  }
76
  }
77
  }
@@ -100,9 +111,9 @@ class Repair extends Shield\Scans\Base\BaseRepair {
100
  public function canAutoRepairFromSource( $oItem ) {
101
  $bCanRepair = Services\Services::CoreFileHashes()->isCoreFile( $oItem->path_fragment );
102
  if ( !$bCanRepair ) {
 
103
  $oPlugin = ( new WpOrg\Plugin\Files() )->findPluginFromFile( $oItem->path_full );
104
- $bCanRepair = ( $oPlugin instanceof Services\Core\VOs\WpPluginVo );
105
- if ( $bCanRepair ) {
106
  if ( !$oPlugin->isWpOrg() ) {
107
  throw new \Exception( sprintf(
108
  __( "%s not installed from WordPress.org.", 'wp-simple-firewall' ),
@@ -115,6 +126,34 @@ class Repair extends Shield\Scans\Base\BaseRepair {
115
  ->exists( $oPlugin->Version, true ) ) {
116
  throw new \Exception( __( "Plugin developer doesn't use SVN tags for official releases.", 'wp-simple-firewall' ) );
117
  };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
118
  }
119
  }
120
  return $bCanRepair;
@@ -173,4 +212,24 @@ class Repair extends Shield\Scans\Base\BaseRepair {
173
  }
174
  return (bool)$bSuccess;
175
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
176
  }
44
  $oOpts = $this->getOptions();
45
  $bSuccess = false;
46
 
 
 
 
 
 
47
  // 2). Repair
48
  try {
49
  $bCanAutoRepair = $this->canAutoRepairFromSource( $oItem );
52
  $bCanAutoRepair = false;
53
  }
54
 
55
+ if ( $bCanAutoRepair || $this->isManualAction() ) {
56
+ // 1) Report the file as being malware.
57
+ ( new Shield\Scans\Mal\Utilities\FalsePositiveReporter() )
58
+ ->setMod( $this->getMod() )
59
+ ->report( $oItem->path_full, 'sha1', false );
60
+ }
61
+
62
  if ( $bCanAutoRepair ) {
63
 
64
  if ( Services\Services::CoreFileHashes()->isCoreFile( $oItem->path_fragment ) ) {
72
  $bSuccess = $this->repairItemInPlugin( $oItem );
73
  }
74
  }
75
+ else {
76
+ $oTheme = ( new WpOrg\Theme\Files() )->findThemeFromFile( $oItem->path_full );
77
+ if ( $oTheme instanceof Services\Core\VOs\WpThemeVo && $oTheme->isWpOrg() ) {
78
+
79
+ if ( $this->isManualAction() || $oOpts->isMalAutoRepairThemes() ) {
80
+ $bSuccess = $this->repairItemInTheme( $oItem );
81
+ }
82
+ }
83
+ else if ( $oOpts->isMalAutoRepairSurgical() ) {
84
+ $bSuccess = $this->repairSurgicalItem( $oItem );
85
+ }
86
  }
87
  }
88
  }
111
  public function canAutoRepairFromSource( $oItem ) {
112
  $bCanRepair = Services\Services::CoreFileHashes()->isCoreFile( $oItem->path_fragment );
113
  if ( !$bCanRepair ) {
114
+
115
  $oPlugin = ( new WpOrg\Plugin\Files() )->findPluginFromFile( $oItem->path_full );
116
+ if ( $oPlugin instanceof Services\Core\VOs\WpPluginVo ) {
 
117
  if ( !$oPlugin->isWpOrg() ) {
118
  throw new \Exception( sprintf(
119
  __( "%s not installed from WordPress.org.", 'wp-simple-firewall' ),
126
  ->exists( $oPlugin->Version, true ) ) {
127
  throw new \Exception( __( "Plugin developer doesn't use SVN tags for official releases.", 'wp-simple-firewall' ) );
128
  };
129
+
130
+ $bCanRepair = true;
131
+ }
132
+ else {
133
+ $oTheme = ( new WpOrg\Theme\Files() )->findThemeFromFile( $oItem->path_full );
134
+ if ( $oTheme instanceof Services\Core\VOs\WpThemeVo ) {
135
+ if ( $oTheme->is_child ) {
136
+ throw new \Exception( sprintf(
137
+ __( "%s is a child of another theme.", 'wp-simple-firewall' ),
138
+ __( 'Theme', 'wp-simple-firewall' )
139
+ )
140
+ );
141
+ };
142
+ if ( !$oTheme->isWpOrg() ) {
143
+ throw new \Exception( sprintf(
144
+ __( "%s not installed from WordPress.org.", 'wp-simple-firewall' ),
145
+ __( 'Theme', 'wp-simple-firewall' )
146
+ )
147
+ );
148
+ };
149
+ if ( !( new WpOrg\Theme\Versions() )
150
+ ->setWorkingSlug( $oTheme->stylesheet )
151
+ ->exists( $oTheme->version, true ) ) {
152
+ throw new \Exception( __( "Theme version doesn't appear to exist.", 'wp-simple-firewall' ) );
153
+ };
154
+
155
+ $bCanRepair = true;
156
+ }
157
  }
158
  }
159
  return $bCanRepair;
212
  }
213
  return (bool)$bSuccess;
214
  }
215
+
216
+ /**
217
+ * @param ResultItem $oItem
218
+ * @return bool
219
+ */
220
+ private function repairItemInTheme( $oItem ) {
221
+ $oFiles = new WpOrg\Theme\Files();
222
+ try {
223
+ if ( $oFiles->isValidFileFromTheme( $oItem->path_full ) ) {
224
+ $bSuccess = $oFiles->replaceFileFromVcs( $oItem->path_full );
225
+ }
226
+ else {
227
+ $bSuccess = Services\Services::WpFs()->deleteFile( $oItem->path_full );
228
+ }
229
+ }
230
+ catch ( \InvalidArgumentException $oE ) {
231
+ $bSuccess = false;
232
+ }
233
+ return (bool)$bSuccess;
234
+ }
235
  }
src/lib/src/Scans/Mal/Utilities/Whitelist.php CHANGED
@@ -27,7 +27,7 @@ class Whitelist {
27
  }
28
  else {
29
  $oCacheDef->file_fragment = 'cache_whitelist_confidence.txt';
30
- $oCacheDef->expiration = HOUR_IN_SECONDS; // Prevent lots of unnecessary HTTP requests out.
31
  ( new Cache\LoadFromCache() )
32
  ->setCacheDef( $oCacheDef )
33
  ->load();
27
  }
28
  else {
29
  $oCacheDef->file_fragment = 'cache_whitelist_confidence.txt';
30
+ $oCacheDef->expiration = MINUTE_IN_SECONDS*10;
31
  ( new Cache\LoadFromCache() )
32
  ->setCacheDef( $oCacheDef )
33
  ->load();
src/lib/src/Scans/Ptg/ItemScanner.php CHANGED
@@ -17,8 +17,13 @@ class ItemScanner {
17
  * @param string $sRootDir
18
  * @param array $aExistingHashes
19
  * @return ResultsSet
 
20
  */
21
  public function scan( $sRootDir, $aExistingHashes ) {
 
 
 
 
22
  /** @var ScanActionVO $oAction */
23
  $oAction = $this->getScanActionVO();
24
 
17
  * @param string $sRootDir
18
  * @param array $aExistingHashes
19
  * @return ResultsSet
20
+ * @throws \Exception
21
  */
22
  public function scan( $sRootDir, $aExistingHashes ) {
23
+ if ( empty( $aExistingHashes ) ) {
24
+ throw new \Exception( 'Existing Hashes are empty' );
25
+ }
26
+
27
  /** @var ScanActionVO $oAction */
28
  $oAction = $this->getScanActionVO();
29
 
src/lib/src/Scans/Ptg/Scan.php CHANGED
@@ -18,6 +18,8 @@ class Scan extends Shield\Scans\Base\BaseScan {
18
  */
19
  private $oThemeHashes;
20
 
 
 
21
  protected function scanSlice() {
22
  /** @var ScanActionVO $oAction */
23
  $oAction = $this->getScanActionVO();
@@ -26,22 +28,34 @@ class Scan extends Shield\Scans\Base\BaseScan {
26
 
27
  $oWpPlugins = Services::WpPlugins();
28
  $oWpThemes = Services::WpThemes();
29
- $oItemScanner = $this->getItemScanner();
30
  $oCopier = new Shield\Scans\Helpers\CopyResultsSets();
31
 
32
  // check we can even ping the WP Hashes API.
33
- $bLiveHashesPing = ( new WpHashes\ApiPing() )->ping();
34
- foreach ( $oAction->items as $sSlug => $sContext ) {
35
  $oNewRes = null;
36
 
37
  $bUseStaticHashes = true;
38
 
39
- // use live hashes if it's a WP.org plugin
40
- if ( $bLiveHashesPing && $oWpPlugins->isWpOrg( $sSlug ) ) {
 
 
 
 
 
 
 
 
 
 
 
 
41
  try {
42
- $oNewRes = ( new PluginWporgScanner() )
43
  ->setScanActionVO( $oAction )
44
- ->scan( $sSlug );
 
45
  $bUseStaticHashes = false;
46
  }
47
  catch ( \Exception $oE ) {
@@ -49,29 +63,26 @@ class Scan extends Shield\Scans\Base\BaseScan {
49
  }
50
  }
51
 
52
- if ( $bUseStaticHashes ) {
53
  if ( $sContext == 'plugins' ) {
54
- $aHashes = $this->getPluginHashes()->getSnapItem( $sSlug )[ 'hashes' ];
55
- if ( !empty( $aHashes ) ) {
56
- $oNewRes = $oItemScanner->scan(
57
- $oWpPlugins->getInstallationDir( $sSlug ),
58
- $this->getPluginHashes()->getSnapItem( $sSlug )[ 'hashes' ]
59
- );
60
- }
 
 
 
 
61
  }
62
- else {
63
- $aHashes = $this->getThemeHashes()->getSnapItem( $sSlug )[ 'hashes' ];
64
- if ( !empty( $aHashes ) ) {
65
- $oNewRes = $oItemScanner->scan(
66
- $oWpThemes->getInstallationDir( $sSlug ),
67
- $this->getThemeHashes()->getSnapItem( $sSlug )[ 'hashes' ]
68
- );
69
- }
70
  }
71
  }
72
 
73
  if ( $oNewRes instanceof ResultsSet ) {
74
- $oNewRes->setSlugOnAllItems( $sSlug )
75
  ->setContextOnAllItems( $sContext );
76
  $oCopier->copyTo( $oNewRes, $oTempRs );
77
  }
18
  */
19
  private $oThemeHashes;
20
 
21
+ /**
22
+ */
23
  protected function scanSlice() {
24
  /** @var ScanActionVO $oAction */
25
  $oAction = $this->getScanActionVO();
28
 
29
  $oWpPlugins = Services::WpPlugins();
30
  $oWpThemes = Services::WpThemes();
 
31
  $oCopier = new Shield\Scans\Helpers\CopyResultsSets();
32
 
33
  // check we can even ping the WP Hashes API.
34
+ $bUseLiveHashes = ( new WpHashes\ApiPing() )->ping();
35
+ foreach ( $oAction->items as $sFileOrStylesheet => $sContext ) {
36
  $oNewRes = null;
37
 
38
  $bUseStaticHashes = true;
39
 
40
+ if ( $sContext == 'plugins' ) {
41
+ $oAsset = $oWpPlugins->getPluginAsVo( $sFileOrStylesheet );
42
+ }
43
+ else {
44
+ $oAsset = $oWpThemes->getThemeAsVo( $sFileOrStylesheet );
45
+ }
46
+ if ( empty( $oAsset ) ) {
47
+ error_log( sprintf( '"%s" Asset "%s" cannot be loaded', $sContext, $sFileOrStylesheet ) );
48
+ continue;
49
+ }
50
+
51
+ // use live hashes if it's a WP.org plugin/theme
52
+ if ( $bUseLiveHashes ) {
53
+
54
  try {
55
+ $oNewRes = ( new WporgAssetScanner() )
56
  ->setScanActionVO( $oAction )
57
+ ->setAsset( $oAsset )
58
+ ->scan();
59
  $bUseStaticHashes = false;
60
  }
61
  catch ( \Exception $oE ) {
63
  }
64
  }
65
 
66
+ if ( $bUseStaticHashes ) { // Live hashes didn't work.
67
  if ( $sContext == 'plugins' ) {
68
+ $sAssetDir = $oWpPlugins->getInstallationDir( $oAsset->file );
69
+ $aSnapHashes = $this->getPluginHashes()->getSnapItem( $sFileOrStylesheet )[ 'hashes' ];
70
+ }
71
+ else { // THEMES:
72
+ $sAssetDir = $oAsset->wp_theme->get_stylesheet_directory();
73
+ $aSnapHashes = $this->getThemeHashes()->getSnapItem( $sFileOrStylesheet )[ 'hashes' ];
74
+ }
75
+
76
+ try {
77
+ $oNewRes = $this->getItemScanner()
78
+ ->scan( $sAssetDir, $aSnapHashes );
79
  }
80
+ catch ( \Exception $oE ) {
 
 
 
 
 
 
 
81
  }
82
  }
83
 
84
  if ( $oNewRes instanceof ResultsSet ) {
85
+ $oNewRes->setSlugOnAllItems( $sFileOrStylesheet )
86
  ->setContextOnAllItems( $sContext );
87
  $oCopier->copyTo( $oNewRes, $oTempRs );
88
  }
src/lib/src/Scans/Ptg/{PluginWporgScanner.php → WporgAssetScanner.php} RENAMED
@@ -5,40 +5,54 @@ namespace FernleafSystems\Wordpress\Plugin\Shield\Scans\Ptg;
5
  use FernleafSystems\Wordpress\Plugin\Shield\Scans\Common\ScanActionConsumer;
6
  use FernleafSystems\Wordpress\Plugin\Shield\Scans\Helpers\BuildHashesFromApi;
7
  use FernleafSystems\Wordpress\Plugin\Shield\Scans\Helpers\StandardDirectoryIterator;
 
 
8
  use FernleafSystems\Wordpress\Services\Services;
9
  use FernleafSystems\Wordpress\Services\Utilities\File\Compare\CompareHash;
10
 
11
  /**
12
- * Class PluginWporgScanner
13
  * @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Ptg
14
  */
15
- class PluginWporgScanner {
16
 
17
  use ScanActionConsumer;
18
 
19
  /**
20
- * @param string $sSlug - plugin base file
 
 
 
 
21
  * @return ResultsSet
22
  * @throws \Exception
23
  */
24
- public function scan( $sSlug ) {
25
  $oResults = new ResultsSet();
26
 
27
- /** @var ScanActionVO $oAction */
28
- $oAction = $this->getScanActionVO();
29
 
30
- $aLive = ( new BuildHashesFromApi() )
31
- ->setDepth( $oAction->scan_depth )
32
- ->setFileExts( $oAction->file_exts )
33
- ->build( $sSlug );
 
 
 
 
 
34
 
35
- $oWpPlugins = Services::WpPlugins();
36
- $sAssetDir = trailingslashit( $oWpPlugins->getInstallationDir( $sSlug ) );
 
 
 
37
  $oCompare = new CompareHash();
 
38
  try {
 
 
39
 
40
- $oDirIt = StandardDirectoryIterator::create(
41
- $sAssetDir, $oAction->scan_depth, $oAction->file_exts );
42
  foreach ( $oDirIt as $oFile ) {
43
  /** @var \SplFileInfo $oFile */
44
  if ( !$oFile->isFile() ) {
@@ -46,7 +60,7 @@ class PluginWporgScanner {
46
  }
47
 
48
  $sFullPath = wp_normalize_path( $oFile->getPathname() );
49
- $sRelAbsPath = str_replace( wp_normalize_path( ABSPATH ), '', $sFullPath );
50
  $sPathFragment = str_replace( $sAssetDir, '', $sFullPath );
51
 
52
  if ( array_key_exists( $sRelAbsPath, $aLive ) ) {
@@ -81,17 +95,49 @@ class PluginWporgScanner {
81
  return $oResults;
82
  }
83
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
  /**
85
  * @param string $sFile
86
  * @return ResultItem
87
  */
88
  private function getNewItem( $sFile ) {
 
89
  $oItem = new ResultItem();
90
  $oItem->path_full = $sFile;
91
  $oItem->path_fragment = $sFile; // will eventually be overwritten
92
  $oItem->is_unrecognised = false;
93
  $oItem->is_different = false;
94
  $oItem->is_missing = false;
 
 
95
  return $oItem;
96
  }
97
  }
5
  use FernleafSystems\Wordpress\Plugin\Shield\Scans\Common\ScanActionConsumer;
6
  use FernleafSystems\Wordpress\Plugin\Shield\Scans\Helpers\BuildHashesFromApi;
7
  use FernleafSystems\Wordpress\Plugin\Shield\Scans\Helpers\StandardDirectoryIterator;
8
+ use FernleafSystems\Wordpress\Services\Core\VOs\WpPluginVo;
9
+ use FernleafSystems\Wordpress\Services\Core\VOs\WpThemeVo;
10
  use FernleafSystems\Wordpress\Services\Services;
11
  use FernleafSystems\Wordpress\Services\Utilities\File\Compare\CompareHash;
12
 
13
  /**
14
+ * Class WporgAssetScanner
15
  * @package FernleafSystems\Wordpress\Plugin\Shield\Scans\Ptg
16
  */
17
+ class WporgAssetScanner {
18
 
19
  use ScanActionConsumer;
20
 
21
  /**
22
+ * @var WpPluginVo|WpThemeVo
23
+ */
24
+ private $oAsset;
25
+
26
+ /**
27
  * @return ResultsSet
28
  * @throws \Exception
29
  */
30
+ public function scan() {
31
  $oResults = new ResultsSet();
32
 
33
+ $oAsset = $this->getAsset();
 
34
 
35
+ if ( $oAsset instanceof WpPluginVo ) {
36
+ $sAssetDir = Services::WpPlugins()->getInstallationDir( $oAsset->file );
37
+ }
38
+ else if ( $oAsset instanceof WpThemeVo ) {
39
+ $sAssetDir = $oAsset->wp_theme->get_stylesheet_directory();
40
+ }
41
+ else {
42
+ throw new \Exception( 'Unsupported Asset Type' );
43
+ }
44
 
45
+ // Get live hashes if it's possible.
46
+ $aLive = $this->getLiveHashes();
47
+
48
+ /** @var ScanActionVO $oAction */
49
+ $oAction = $this->getScanActionVO();
50
  $oCompare = new CompareHash();
51
+ $sAssetDir = trailingslashit( wp_normalize_path( $sAssetDir ) );
52
  try {
53
+ $oDirIt = StandardDirectoryIterator::create( $sAssetDir, $oAction->scan_depth, $oAction->file_exts );
54
+ $sAbsPath = wp_normalize_path( ABSPATH );
55
 
 
 
56
  foreach ( $oDirIt as $oFile ) {
57
  /** @var \SplFileInfo $oFile */
58
  if ( !$oFile->isFile() ) {
60
  }
61
 
62
  $sFullPath = wp_normalize_path( $oFile->getPathname() );
63
+ $sRelAbsPath = str_replace( $sAbsPath, '', $sFullPath );
64
  $sPathFragment = str_replace( $sAssetDir, '', $sFullPath );
65
 
66
  if ( array_key_exists( $sRelAbsPath, $aLive ) ) {
95
  return $oResults;
96
  }
97
 
98
+ /**
99
+ * @return WpPluginVo|WpThemeVo
100
+ */
101
+ public function getAsset() {
102
+ return $this->oAsset;
103
+ }
104
+
105
+ /**
106
+ * @param WpPluginVo|WpThemeVo $oAsset
107
+ * @return $this
108
+ */
109
+ public function setAsset( $oAsset ) {
110
+ $this->oAsset = $oAsset;
111
+ return $this;
112
+ }
113
+
114
+ /**
115
+ * @return string[]
116
+ * @throws \Exception
117
+ */
118
+ private function getLiveHashes() {
119
+ /** @var ScanActionVO $oAction */
120
+ $oAction = $this->getScanActionVO();
121
+ return ( new BuildHashesFromApi() )
122
+ ->setDepth( $oAction->scan_depth )
123
+ ->setFileExts( $oAction->file_exts )
124
+ ->build( $this->getAsset() );
125
+ }
126
+
127
  /**
128
  * @param string $sFile
129
  * @return ResultItem
130
  */
131
  private function getNewItem( $sFile ) {
132
+ $oAsset = $this->getAsset();
133
  $oItem = new ResultItem();
134
  $oItem->path_full = $sFile;
135
  $oItem->path_fragment = $sFile; // will eventually be overwritten
136
  $oItem->is_unrecognised = false;
137
  $oItem->is_different = false;
138
  $oItem->is_missing = false;
139
+ $oItem->context = ( $oAsset instanceof WpPluginVo ) ? 'plugins' : 'themes';
140
+ $oItem->slug = ( $oAsset instanceof WpPluginVo ) ? $oAsset->file : $oAsset->stylesheet;
141
  return $oItem;
142
  }
143
  }
src/lib/vendor/composer/autoload_classmap.php CHANGED
@@ -297,7 +297,6 @@ return array(
297
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\BuildScanAction' => $baseDir . '/src/Scans/Ptg/BuildScanAction.php',
298
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\DiffHashes' => $baseDir . '/src/Scans/Ptg/DiffHashes.php',
299
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\ItemScanner' => $baseDir . '/src/Scans/Ptg/ItemScanner.php',
300
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\PluginWporgScanner' => $baseDir . '/src/Scans/Ptg/PluginWporgScanner.php',
301
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\Repair' => $baseDir . '/src/Scans/Ptg/Repair.php',
302
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\ResultItem' => $baseDir . '/src/Scans/Ptg/ResultItem.php',
303
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\ResultsSet' => $baseDir . '/src/Scans/Ptg/ResultsSet.php',
@@ -310,6 +309,7 @@ return array(
310
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\ScannerThemes' => $baseDir . '/src/Scans/Ptg/ScannerThemes.php',
311
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\Snapshots\\Store' => $baseDir . '/src/Scans/Ptg/Snapshots/Store.php',
312
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\Snapshots\\StoreFormatUpgrade' => $baseDir . '/src/Scans/Ptg/Snapshots/StoreFormatUpgrade.php',
 
313
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Realtime\\Files\\Backup' => $baseDir . '/src/Scans/Realtime/Files/Backup.php',
314
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Realtime\\Files\\Process' => $baseDir . '/src/Scans/Realtime/Files/Process.php',
315
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Realtime\\Files\\Revert' => $baseDir . '/src/Scans/Realtime/Files/Revert.php',
@@ -404,6 +404,7 @@ return array(
404
  'FernleafSystems\\Wordpress\\Services\\Core\\Users' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/Users.php',
405
  'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpHttpResponseVo' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/VOs/WpHttpResponseVo.php',
406
  'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpPluginVo' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/VOs/WpPluginVo.php',
 
407
  'FernleafSystems\\Wordpress\\Services\\Services' => $vendorDir . '/fernleafsystems/wordpress-services/src/Services.php',
408
  'FernleafSystems\\Wordpress\\Services\\Utilities\\BackgroundProcessing\\BackgroundProcess' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/BackgroundProcessing/BackgroundProcess.php',
409
  'FernleafSystems\\Wordpress\\Services\\Utilities\\ClassicPress\\Checksums' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/ClassicPress/Checksums.php',
@@ -434,7 +435,9 @@ return array(
434
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\Hashes\\Base' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/Base.php',
435
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\Hashes\\ClassicPress' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/ClassicPress.php',
436
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\Hashes\\Plugin' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/Plugin.php',
 
437
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\Hashes\\RequestVO' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/RequestVO.php',
 
438
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\Hashes\\WordPress' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/WordPress.php',
439
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\Malware\\Patterns\\Base' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Malware/Patterns/Base.php',
440
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\Malware\\Patterns\\Retrieve' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Malware/Patterns/Retrieve.php',
@@ -458,6 +461,7 @@ return array(
458
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Render' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Render.php',
459
  'FernleafSystems\\Wordpress\\Services\\Utilities\\ServiceProviders' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/ServiceProviders.php',
460
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Ssl' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Ssl.php',
 
461
  'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Base\\RepoBase' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Base/RepoBase.php',
462
  'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Base\\VersionsBase' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Base/VersionsBase.php',
463
  'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Core' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Core.php',
@@ -473,6 +477,13 @@ return array(
473
  'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Plugin\\VOs\\PluginInfoVO' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Plugin/VOs/PluginInfoVO.php',
474
  'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Plugin\\Versions' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Plugin/Versions.php',
475
  'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Plugins' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Plugins.php',
 
 
 
 
 
 
 
476
  'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Wp\\Base' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Wp/Base.php',
477
  'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Wp\\Download' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Wp/Download.php',
478
  'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Wp\\Files' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Wp/Files.php',
297
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\BuildScanAction' => $baseDir . '/src/Scans/Ptg/BuildScanAction.php',
298
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\DiffHashes' => $baseDir . '/src/Scans/Ptg/DiffHashes.php',
299
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\ItemScanner' => $baseDir . '/src/Scans/Ptg/ItemScanner.php',
 
300
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\Repair' => $baseDir . '/src/Scans/Ptg/Repair.php',
301
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\ResultItem' => $baseDir . '/src/Scans/Ptg/ResultItem.php',
302
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\ResultsSet' => $baseDir . '/src/Scans/Ptg/ResultsSet.php',
309
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\ScannerThemes' => $baseDir . '/src/Scans/Ptg/ScannerThemes.php',
310
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\Snapshots\\Store' => $baseDir . '/src/Scans/Ptg/Snapshots/Store.php',
311
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\Snapshots\\StoreFormatUpgrade' => $baseDir . '/src/Scans/Ptg/Snapshots/StoreFormatUpgrade.php',
312
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\WporgAssetScanner' => $baseDir . '/src/Scans/Ptg/WporgAssetScanner.php',
313
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Realtime\\Files\\Backup' => $baseDir . '/src/Scans/Realtime/Files/Backup.php',
314
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Realtime\\Files\\Process' => $baseDir . '/src/Scans/Realtime/Files/Process.php',
315
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Realtime\\Files\\Revert' => $baseDir . '/src/Scans/Realtime/Files/Revert.php',
404
  'FernleafSystems\\Wordpress\\Services\\Core\\Users' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/Users.php',
405
  'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpHttpResponseVo' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/VOs/WpHttpResponseVo.php',
406
  'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpPluginVo' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/VOs/WpPluginVo.php',
407
+ 'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpThemeVo' => $vendorDir . '/fernleafsystems/wordpress-services/src/Core/VOs/WpThemeVo.php',
408
  'FernleafSystems\\Wordpress\\Services\\Services' => $vendorDir . '/fernleafsystems/wordpress-services/src/Services.php',
409
  'FernleafSystems\\Wordpress\\Services\\Utilities\\BackgroundProcessing\\BackgroundProcess' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/BackgroundProcessing/BackgroundProcess.php',
410
  'FernleafSystems\\Wordpress\\Services\\Utilities\\ClassicPress\\Checksums' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/ClassicPress/Checksums.php',
435
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\Hashes\\Base' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/Base.php',
436
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\Hashes\\ClassicPress' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/ClassicPress.php',
437
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\Hashes\\Plugin' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/Plugin.php',
438
+ 'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\Hashes\\PluginThemeBase' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/PluginThemeBase.php',
439
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\Hashes\\RequestVO' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/RequestVO.php',
440
+ 'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\Hashes\\Theme' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/Theme.php',
441
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\Hashes\\WordPress' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/WordPress.php',
442
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\Malware\\Patterns\\Base' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Malware/Patterns/Base.php',
443
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\Malware\\Patterns\\Retrieve' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Malware/Patterns/Retrieve.php',
461
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Render' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Render.php',
462
  'FernleafSystems\\Wordpress\\Services\\Utilities\\ServiceProviders' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/ServiceProviders.php',
463
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Ssl' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/Ssl.php',
464
+ 'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Base\\PluginThemeFilesBase' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Base/PluginThemeFilesBase.php',
465
  'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Base\\RepoBase' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Base/RepoBase.php',
466
  'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Base\\VersionsBase' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Base/VersionsBase.php',
467
  'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Core' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Core.php',
477
  'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Plugin\\VOs\\PluginInfoVO' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Plugin/VOs/PluginInfoVO.php',
478
  'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Plugin\\Versions' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Plugin/Versions.php',
479
  'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Plugins' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Plugins.php',
480
+ 'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Theme\\Api' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Theme/Api.php',
481
+ 'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Theme\\Base' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Theme/Base.php',
482
+ 'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Theme\\Download' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Theme/Download.php',
483
+ 'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Theme\\Files' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Theme/Files.php',
484
+ 'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Theme\\Repo' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Theme/Repo.php',
485
+ 'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Theme\\VOs\\ThemeInfoVO' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Theme/VOs/ThemeInfoVO.php',
486
+ 'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Theme\\Versions' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Theme/Versions.php',
487
  'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Wp\\Base' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Wp/Base.php',
488
  'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Wp\\Download' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Wp/Download.php',
489
  'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Wp\\Files' => $vendorDir . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Wp/Files.php',
src/lib/vendor/composer/autoload_static.php CHANGED
@@ -446,7 +446,6 @@ class ComposerStaticInitfcf2fe1888f1f5fc092770cdc8ef3cf4
446
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\BuildScanAction' => __DIR__ . '/../..' . '/src/Scans/Ptg/BuildScanAction.php',
447
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\DiffHashes' => __DIR__ . '/../..' . '/src/Scans/Ptg/DiffHashes.php',
448
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\ItemScanner' => __DIR__ . '/../..' . '/src/Scans/Ptg/ItemScanner.php',
449
- 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\PluginWporgScanner' => __DIR__ . '/../..' . '/src/Scans/Ptg/PluginWporgScanner.php',
450
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\Repair' => __DIR__ . '/../..' . '/src/Scans/Ptg/Repair.php',
451
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\ResultItem' => __DIR__ . '/../..' . '/src/Scans/Ptg/ResultItem.php',
452
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\ResultsSet' => __DIR__ . '/../..' . '/src/Scans/Ptg/ResultsSet.php',
@@ -459,6 +458,7 @@ class ComposerStaticInitfcf2fe1888f1f5fc092770cdc8ef3cf4
459
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\ScannerThemes' => __DIR__ . '/../..' . '/src/Scans/Ptg/ScannerThemes.php',
460
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\Snapshots\\Store' => __DIR__ . '/../..' . '/src/Scans/Ptg/Snapshots/Store.php',
461
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\Snapshots\\StoreFormatUpgrade' => __DIR__ . '/../..' . '/src/Scans/Ptg/Snapshots/StoreFormatUpgrade.php',
 
462
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Realtime\\Files\\Backup' => __DIR__ . '/../..' . '/src/Scans/Realtime/Files/Backup.php',
463
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Realtime\\Files\\Process' => __DIR__ . '/../..' . '/src/Scans/Realtime/Files/Process.php',
464
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Realtime\\Files\\Revert' => __DIR__ . '/../..' . '/src/Scans/Realtime/Files/Revert.php',
@@ -553,6 +553,7 @@ class ComposerStaticInitfcf2fe1888f1f5fc092770cdc8ef3cf4
553
  'FernleafSystems\\Wordpress\\Services\\Core\\Users' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/Users.php',
554
  'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpHttpResponseVo' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/VOs/WpHttpResponseVo.php',
555
  'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpPluginVo' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/VOs/WpPluginVo.php',
 
556
  'FernleafSystems\\Wordpress\\Services\\Services' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Services.php',
557
  'FernleafSystems\\Wordpress\\Services\\Utilities\\BackgroundProcessing\\BackgroundProcess' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/BackgroundProcessing/BackgroundProcess.php',
558
  'FernleafSystems\\Wordpress\\Services\\Utilities\\ClassicPress\\Checksums' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/ClassicPress/Checksums.php',
@@ -583,7 +584,9 @@ class ComposerStaticInitfcf2fe1888f1f5fc092770cdc8ef3cf4
583
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\Hashes\\Base' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/Base.php',
584
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\Hashes\\ClassicPress' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/ClassicPress.php',
585
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\Hashes\\Plugin' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/Plugin.php',
 
586
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\Hashes\\RequestVO' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/RequestVO.php',
 
587
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\Hashes\\WordPress' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/WordPress.php',
588
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\Malware\\Patterns\\Base' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Malware/Patterns/Base.php',
589
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\Malware\\Patterns\\Retrieve' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Malware/Patterns/Retrieve.php',
@@ -607,6 +610,7 @@ class ComposerStaticInitfcf2fe1888f1f5fc092770cdc8ef3cf4
607
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Render' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Render.php',
608
  'FernleafSystems\\Wordpress\\Services\\Utilities\\ServiceProviders' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/ServiceProviders.php',
609
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Ssl' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Ssl.php',
 
610
  'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Base\\RepoBase' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Base/RepoBase.php',
611
  'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Base\\VersionsBase' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Base/VersionsBase.php',
612
  'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Core' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Core.php',
@@ -622,6 +626,13 @@ class ComposerStaticInitfcf2fe1888f1f5fc092770cdc8ef3cf4
622
  'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Plugin\\VOs\\PluginInfoVO' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Plugin/VOs/PluginInfoVO.php',
623
  'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Plugin\\Versions' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Plugin/Versions.php',
624
  'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Plugins' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Plugins.php',
 
 
 
 
 
 
 
625
  'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Wp\\Base' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Wp/Base.php',
626
  'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Wp\\Download' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Wp/Download.php',
627
  'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Wp\\Files' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Wp/Files.php',
446
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\BuildScanAction' => __DIR__ . '/../..' . '/src/Scans/Ptg/BuildScanAction.php',
447
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\DiffHashes' => __DIR__ . '/../..' . '/src/Scans/Ptg/DiffHashes.php',
448
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\ItemScanner' => __DIR__ . '/../..' . '/src/Scans/Ptg/ItemScanner.php',
 
449
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\Repair' => __DIR__ . '/../..' . '/src/Scans/Ptg/Repair.php',
450
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\ResultItem' => __DIR__ . '/../..' . '/src/Scans/Ptg/ResultItem.php',
451
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\ResultsSet' => __DIR__ . '/../..' . '/src/Scans/Ptg/ResultsSet.php',
458
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\ScannerThemes' => __DIR__ . '/../..' . '/src/Scans/Ptg/ScannerThemes.php',
459
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\Snapshots\\Store' => __DIR__ . '/../..' . '/src/Scans/Ptg/Snapshots/Store.php',
460
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\Snapshots\\StoreFormatUpgrade' => __DIR__ . '/../..' . '/src/Scans/Ptg/Snapshots/StoreFormatUpgrade.php',
461
+ 'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Ptg\\WporgAssetScanner' => __DIR__ . '/../..' . '/src/Scans/Ptg/WporgAssetScanner.php',
462
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Realtime\\Files\\Backup' => __DIR__ . '/../..' . '/src/Scans/Realtime/Files/Backup.php',
463
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Realtime\\Files\\Process' => __DIR__ . '/../..' . '/src/Scans/Realtime/Files/Process.php',
464
  'FernleafSystems\\Wordpress\\Plugin\\Shield\\Scans\\Realtime\\Files\\Revert' => __DIR__ . '/../..' . '/src/Scans/Realtime/Files/Revert.php',
553
  'FernleafSystems\\Wordpress\\Services\\Core\\Users' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/Users.php',
554
  'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpHttpResponseVo' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/VOs/WpHttpResponseVo.php',
555
  'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpPluginVo' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/VOs/WpPluginVo.php',
556
+ 'FernleafSystems\\Wordpress\\Services\\Core\\VOs\\WpThemeVo' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Core/VOs/WpThemeVo.php',
557
  'FernleafSystems\\Wordpress\\Services\\Services' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Services.php',
558
  'FernleafSystems\\Wordpress\\Services\\Utilities\\BackgroundProcessing\\BackgroundProcess' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/BackgroundProcessing/BackgroundProcess.php',
559
  'FernleafSystems\\Wordpress\\Services\\Utilities\\ClassicPress\\Checksums' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/ClassicPress/Checksums.php',
584
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\Hashes\\Base' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/Base.php',
585
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\Hashes\\ClassicPress' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/ClassicPress.php',
586
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\Hashes\\Plugin' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/Plugin.php',
587
+ 'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\Hashes\\PluginThemeBase' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/PluginThemeBase.php',
588
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\Hashes\\RequestVO' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/RequestVO.php',
589
+ 'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\Hashes\\Theme' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/Theme.php',
590
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\Hashes\\WordPress' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/WordPress.php',
591
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\Malware\\Patterns\\Base' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Malware/Patterns/Base.php',
592
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Integrations\\WpHashes\\Malware\\Patterns\\Retrieve' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Malware/Patterns/Retrieve.php',
610
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Render' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Render.php',
611
  'FernleafSystems\\Wordpress\\Services\\Utilities\\ServiceProviders' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/ServiceProviders.php',
612
  'FernleafSystems\\Wordpress\\Services\\Utilities\\Ssl' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/Ssl.php',
613
+ 'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Base\\PluginThemeFilesBase' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Base/PluginThemeFilesBase.php',
614
  'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Base\\RepoBase' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Base/RepoBase.php',
615
  'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Base\\VersionsBase' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Base/VersionsBase.php',
616
  'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Core' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Core.php',
626
  'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Plugin\\VOs\\PluginInfoVO' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Plugin/VOs/PluginInfoVO.php',
627
  'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Plugin\\Versions' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Plugin/Versions.php',
628
  'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Plugins' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Plugins.php',
629
+ 'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Theme\\Api' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Theme/Api.php',
630
+ 'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Theme\\Base' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Theme/Base.php',
631
+ 'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Theme\\Download' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Theme/Download.php',
632
+ 'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Theme\\Files' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Theme/Files.php',
633
+ 'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Theme\\Repo' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Theme/Repo.php',
634
+ 'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Theme\\VOs\\ThemeInfoVO' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Theme/VOs/ThemeInfoVO.php',
635
+ 'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Theme\\Versions' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Theme/Versions.php',
636
  'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Wp\\Base' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Wp/Base.php',
637
  'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Wp\\Download' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Wp/Download.php',
638
  'FernleafSystems\\Wordpress\\Services\\Utilities\\WpOrg\\Wp\\Files' => __DIR__ . '/..' . '/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Wp/Files.php',
src/lib/vendor/fernleafsystems/wordpress-services/src/Core/Plugins.php CHANGED
@@ -12,6 +12,11 @@ use FernleafSystems\Wordpress\Services\Services;
12
  */
13
  class Plugins {
14
 
 
 
 
 
 
15
  /**
16
  * @param string $sPluginFile
17
  * @param bool $bNetworkWide
@@ -337,16 +342,23 @@ class Plugins {
337
 
338
  /**
339
  * @param string $sPluginFile
 
340
  * @return WpPluginVo|null
341
  */
342
- public function getPluginAsVo( $sPluginFile ) {
343
- $oPlug = null;
344
  try {
345
- $oPlug = new WpPluginVo( $sPluginFile );
 
 
 
 
 
 
346
  }
347
  catch ( \Exception $oE ) {
 
348
  }
349
- return $oPlug;
350
  }
351
 
352
  /**
@@ -427,7 +439,7 @@ class Plugins {
427
  }
428
 
429
  /**
430
- * @return array - keys are plugin base files
431
  */
432
  public function getAllExtendedData() {
433
  $oData = Services::WpGeneral()->getTransient( 'update_plugins' );
@@ -443,7 +455,9 @@ class Plugins {
443
  */
444
  public function getExtendedData( $sBaseFile ) {
445
  $aData = $this->getAllExtendedData();
446
- return isset( $aData[ $sBaseFile ] ) ? $aData[ $sBaseFile ] : [];
 
 
447
  }
448
 
449
  /**
@@ -466,17 +480,17 @@ class Plugins {
466
  * @return string
467
  */
468
  public function getSlug( $sBaseName ) {
469
- $oPluginInfo = $this->getExtendedData( $sBaseName );
470
- return isset( $oPluginInfo->slug ) ? $oPluginInfo->slug : '';
471
  }
472
 
473
  /**
474
  * @param string $sBaseName
475
  * @return bool
 
476
  */
477
  public function isWpOrg( $sBaseName ) {
478
- $oPluginInfo = $this->getExtendedData( $sBaseName );
479
- return isset( $oPluginInfo->id ) ? strpos( $oPluginInfo->id, 'w.org/' ) === 0 : false;
480
  }
481
 
482
  /**
12
  */
13
  class Plugins {
14
 
15
+ /**
16
+ * @var WpPluginVo[]
17
+ */
18
+ private $aLoadedVOs;
19
+
20
  /**
21
  * @param string $sPluginFile
22
  * @param bool $bNetworkWide
342
 
343
  /**
344
  * @param string $sPluginFile
345
+ * @param bool $bReload
346
  * @return WpPluginVo|null
347
  */
348
+ public function getPluginAsVo( $sPluginFile, $bReload = false ) {
 
349
  try {
350
+ if ( !is_array( $this->aLoadedVOs ) ) {
351
+ $this->aLoadedVOs = [];
352
+ }
353
+ if ( $bReload || !isset( $this->aLoadedVOs[ $sPluginFile ] ) ) {
354
+ $this->aLoadedVOs[ $sPluginFile ] = new WpPluginVo( $sPluginFile );
355
+ }
356
+ $oAsset = $this->aLoadedVOs[ $sPluginFile ];
357
  }
358
  catch ( \Exception $oE ) {
359
+ $oAsset = null;
360
  }
361
+ return $oAsset;
362
  }
363
 
364
  /**
439
  }
440
 
441
  /**
442
+ * @return \stdClass[] - keys are plugin base files
443
  */
444
  public function getAllExtendedData() {
445
  $oData = Services::WpGeneral()->getTransient( 'update_plugins' );
455
  */
456
  public function getExtendedData( $sBaseFile ) {
457
  $aData = $this->getAllExtendedData();
458
+ return isset( $aData[ $sBaseFile ] ) ?
459
+ Services::DataManipulation()->convertStdClassToArray( $aData[ $sBaseFile ] )
460
+ : [];
461
  }
462
 
463
  /**
480
  * @return string
481
  */
482
  public function getSlug( $sBaseName ) {
483
+ $aInfo = $this->getExtendedData( $sBaseName );
484
+ return isset( $aInfo[ 'slug' ] ) ? $aInfo[ 'slug' ] : '';
485
  }
486
 
487
  /**
488
  * @param string $sBaseName
489
  * @return bool
490
+ * @deprecated 1.1.17
491
  */
492
  public function isWpOrg( $sBaseName ) {
493
+ return $this->getPluginAsVo( $sBaseName )->isWpOrg();
 
494
  }
495
 
496
  /**
src/lib/vendor/fernleafsystems/wordpress-services/src/Core/Themes.php CHANGED
@@ -3,7 +3,9 @@
3
  namespace FernleafSystems\Wordpress\Services\Core;
4
 
5
  use FernleafSystems\Wordpress\Services\Core\Upgrades;
 
6
  use FernleafSystems\Wordpress\Services\Services;
 
7
 
8
  /**
9
  * Class Themes
@@ -11,6 +13,11 @@ use FernleafSystems\Wordpress\Services\Services;
11
  */
12
  class Themes {
13
 
 
 
 
 
 
14
  /**
15
  * @param string $sThemeStylesheet
16
  * @return bool
@@ -48,18 +55,22 @@ class Themes {
48
  }
49
 
50
  /**
51
- * @param $sSlug
52
- * @return array|bool
53
  */
54
  public function installFromWpOrg( $sSlug ) {
55
- include_once( ABSPATH.'wp-admin/includes/plugin-install.php' );
56
-
57
- $oApi = $this->getExtendedData( $sSlug );
58
-
59
- if ( !is_wp_error( $oApi ) ) {
60
- return $this->install( $oApi->download_link, true, true );
 
 
61
  }
62
- return false;
 
 
63
  }
64
 
65
  /**
@@ -125,8 +136,7 @@ class Themes {
125
  rename( $sDir, $sBackupDir );
126
  }
127
 
128
- $aResult = $this->installFromWpOrg( $sSlug );
129
- $bSuccess = $aResult[ 'successful' ];
130
  if ( $bSuccess ) {
131
  wp_update_themes(); //refreshes our update information
132
  if ( $bUseBackup ) {
@@ -214,6 +224,54 @@ class Themes {
214
  return function_exists( 'wp_get_theme' ) ? wp_get_theme( $sStylesheet ) : null;
215
  }
216
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
217
  /**
218
  * Supports only WP > 3.4.0
219
  * Abstracts the WordPress wp_get_themes()
@@ -254,19 +312,23 @@ class Themes {
254
  }
255
 
256
  /**
257
- * @param string $sBase
258
- * @return object|\WP_Error
 
 
 
 
 
 
 
 
 
 
 
259
  */
260
- public function getExtendedData( $sBase ) {
261
- include_once( ABSPATH.'wp-admin/includes/theme.php' );
262
-
263
- $oApi = themes_api( 'theme_information', [
264
- 'slug' => $sBase,
265
- 'fields' => [
266
- 'sections' => false,
267
- ],
268
- ] );
269
- return $oApi;
270
  }
271
 
272
  /**
@@ -316,12 +378,7 @@ class Themes {
316
  * @return bool
317
  */
318
  public function isWpOrg( $sBaseName ) {
319
- $bIsWpOrg = false;
320
- $oInfo = $this->getExtendedData( $sBaseName );
321
- if ( !empty( $oInfo ) && !is_wp_error( $oInfo ) && isset( $oInfo->download_link ) ) {
322
- $bIsWpOrg = strpos( $oInfo->download_link, 'https://downloads.wordpress.org' ) === 0;
323
- }
324
- return $bIsWpOrg;
325
  }
326
 
327
  /**
3
  namespace FernleafSystems\Wordpress\Services\Core;
4
 
5
  use FernleafSystems\Wordpress\Services\Core\Upgrades;
6
+ use FernleafSystems\Wordpress\Services\Core\VOs\WpThemeVo;
7
  use FernleafSystems\Wordpress\Services\Services;
8
+ use FernleafSystems\Wordpress\Services\Utilities\WpOrg\Theme\Api;
9
 
10
  /**
11
  * Class Themes
13
  */
14
  class Themes {
15
 
16
+ /**
17
+ * @var WpThemeVo[]
18
+ */
19
+ private $aLoadedVOs;
20
+
21
  /**
22
  * @param string $sThemeStylesheet
23
  * @return bool
55
  }
56
 
57
  /**
58
+ * @param string $sSlug
59
+ * @return bool
60
  */
61
  public function installFromWpOrg( $sSlug ) {
62
+ $bSuccess = false;
63
+ try {
64
+ $oTheme = ( new Api() )
65
+ ->setWorkingSlug( $sSlug )
66
+ ->getInfo();
67
+ if ( !empty( $oTheme->download_link ) ) {
68
+ $bSuccess = $this->install( $oTheme->download_link, true, true )[ 'successful' ];
69
+ }
70
  }
71
+ catch ( \Exception $oE ) {
72
+ }
73
+ return $bSuccess;
74
  }
75
 
76
  /**
136
  rename( $sDir, $sBackupDir );
137
  }
138
 
139
+ $bSuccess = $this->installFromWpOrg( $sSlug );
 
140
  if ( $bSuccess ) {
141
  wp_update_themes(); //refreshes our update information
142
  if ( $bUseBackup ) {
224
  return function_exists( 'wp_get_theme' ) ? wp_get_theme( $sStylesheet ) : null;
225
  }
226
 
227
+ /**
228
+ * @param string $sStylesheet
229
+ * @param bool $bReload
230
+ * @return WpThemeVo|null
231
+ */
232
+ public function getThemeAsVo( $sStylesheet, $bReload = false ) {
233
+ try {
234
+ if ( !is_array( $this->aLoadedVOs ) ) {
235
+ $this->aLoadedVOs = [];
236
+ }
237
+ if ( $bReload || !isset( $this->aLoadedVOs[ $sStylesheet ] ) ) {
238
+ $this->aLoadedVOs[ $sStylesheet ] = new WpThemeVo( $sStylesheet );
239
+ }
240
+ $oAsset = $this->aLoadedVOs[ $sStylesheet ];
241
+ }
242
+ catch ( \Exception $oE ) {
243
+ $oAsset = null;
244
+ }
245
+ return $oAsset;
246
+ }
247
+
248
+ /**
249
+ * @return WpThemeVo[]
250
+ */
251
+ public function getThemesAsVo() {
252
+ return array_filter(
253
+ array_map(
254
+ function ( $sStyleSheet ) {
255
+ return $this->getThemeAsVo( $sStyleSheet );
256
+ },
257
+ $this->getInstalledStylesheets()
258
+ )
259
+ );
260
+ }
261
+
262
+ /**
263
+ * @return string[]
264
+ */
265
+ public function getInstalledStylesheets() {
266
+ return array_map(
267
+ function ( $oTheme ) {
268
+ /** @var \WP_Theme $oTheme */
269
+ return $oTheme->get_stylesheet();
270
+ },
271
+ $this->getThemes()
272
+ );
273
+ }
274
+
275
  /**
276
  * Supports only WP > 3.4.0
277
  * Abstracts the WordPress wp_get_themes()
312
  }
313
 
314
  /**
315
+ * @return array[] - keys are theme stylesheets
316
+ */
317
+ public function getAllExtendedData() {
318
+ $oData = Services::WpGeneral()->getTransient( 'update_themes' );
319
+ return array_merge(
320
+ isset( $oData->no_update ) ? $oData->no_update : [],
321
+ isset( $oData->response ) ? $oData->response : []
322
+ );
323
+ }
324
+
325
+ /**
326
+ * @param string $sSlug
327
+ * @return array
328
  */
329
+ public function getExtendedData( $sSlug ) {
330
+ $aData = $this->getAllExtendedData();
331
+ return isset( $aData[ $sSlug ] ) ? $aData[ $sSlug ] : [];
 
 
 
 
 
 
 
332
  }
333
 
334
  /**
378
  * @return bool
379
  */
380
  public function isWpOrg( $sBaseName ) {
381
+ return $this->getThemeAsVo( $sBaseName )->isWpOrg();
 
 
 
 
 
382
  }
383
 
384
  /**
src/lib/vendor/fernleafsystems/wordpress-services/src/Core/VOs/WpPluginVo.php CHANGED
@@ -4,35 +4,41 @@ namespace FernleafSystems\Wordpress\Services\Core\VOs;
4
 
5
  use FernleafSystems\Utilities\Data\Adapter\StdClassAdapter;
6
  use FernleafSystems\Wordpress\Services\Services;
 
7
 
8
  /**
9
  * Class WpPluginVo
10
  * @package FernleafSystems\Wordpress\Services\Core\VOs
11
- * @property string Name
12
- * @property string Version
13
- * @property string Description
14
- * @property string PluginURI
15
- * @property string Author
16
- * @property string AuthorURI
17
- * @property string TextDomain
18
- * @property string DomainPath
19
- * @property bool Network
20
- * @property string Title
21
- * @property string AuthorName
22
  * Extended Properties:
23
- * @property string id
24
- * @property string slug
25
- * @property string plugin
26
- * @property string new_version
27
- * @property string url
28
- * @property string package the update package URL
29
  * Custom Properties:
30
- * @property string file
31
- * @property string active
 
 
32
  */
33
  class WpPluginVo {
34
 
35
- use StdClassAdapter;
 
 
 
36
 
37
  /**
38
  * WpPluginVo constructor.
@@ -45,15 +51,51 @@ class WpPluginVo {
45
  if ( empty( $aPlug ) ) {
46
  throw new \Exception( sprintf( 'Plugin file %s does not exist', $sBaseFile ) );
47
  }
48
- $aPlug = array_merge(
49
- $aPlug,
50
- Services::DataManipulation()->convertStdClassToArray( $oWpPlugins->getExtendedData( $sBaseFile ) )
51
- );
52
- $this->applyFromArray( $aPlug );
53
  $this->file = $sBaseFile;
54
  $this->active = $oWpPlugins->isActive( $sBaseFile );
55
  }
56
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
  /**
58
  * @return bool
59
  */
4
 
5
  use FernleafSystems\Utilities\Data\Adapter\StdClassAdapter;
6
  use FernleafSystems\Wordpress\Services\Services;
7
+ use FernleafSystems\Wordpress\Services\Utilities\WpOrg\Plugin;
8
 
9
  /**
10
  * Class WpPluginVo
11
  * @package FernleafSystems\Wordpress\Services\Core\VOs
12
+ * @property string Name
13
+ * @property string Version
14
+ * @property string Description
15
+ * @property string PluginURI
16
+ * @property string Author
17
+ * @property string AuthorURI
18
+ * @property string TextDomain
19
+ * @property string DomainPath
20
+ * @property bool Network
21
+ * @property string Title
22
+ * @property string AuthorName
23
  * Extended Properties:
24
+ * @property string $id
25
+ * @property string $slug
26
+ * @property string $plugin
27
+ * @property string $new_version
28
+ * @property string $url
29
+ * @property string $package the update package URL
30
  * Custom Properties:
31
+ * @property string $file
32
+ * @property bool $active
33
+ * @property bool $svn_uses_tags
34
+ * @property Plugin\VOs\PluginInfoVO $wp_info
35
  */
36
  class WpPluginVo {
37
 
38
+ use StdClassAdapter {
39
+ __get as __adapterGet;
40
+ __set as __adapterSet;
41
+ }
42
 
43
  /**
44
  * WpPluginVo constructor.
51
  if ( empty( $aPlug ) ) {
52
  throw new \Exception( sprintf( 'Plugin file %s does not exist', $sBaseFile ) );
53
  }
54
+ $this->applyFromArray( array_merge( $aPlug, $oWpPlugins->getExtendedData( $sBaseFile ) ) );
 
 
 
 
55
  $this->file = $sBaseFile;
56
  $this->active = $oWpPlugins->isActive( $sBaseFile );
57
  }
58
 
59
+ /**
60
+ * @param string $sProperty
61
+ * @return mixed
62
+ */
63
+ public function __get( $sProperty ) {
64
+
65
+ $mVal = $this->__adapterGet( $sProperty );
66
+
67
+ switch ( $sProperty ) {
68
+
69
+ case 'svn_uses_tags':
70
+ if ( is_null( $mVal ) ) {
71
+ $mVal = ( new Plugin\Versions() )
72
+ ->setWorkingSlug( $this->slug )
73
+ ->exists( $this->Version, true );
74
+ $this->svn_uses_tags = $mVal;
75
+ }
76
+ break;
77
+
78
+ case 'wp_info':
79
+ if ( is_null( $mVal ) ) {
80
+ try {
81
+ $mVal = ( new Plugin\Api() )
82
+ ->setWorkingSlug( $this->slug )
83
+ ->getInfo();
84
+ }
85
+ catch ( \Exception $oE ) {
86
+ $mVal = false;
87
+ }
88
+ $this->wp_info = $mVal;
89
+ }
90
+ break;
91
+
92
+ default:
93
+ break;
94
+ }
95
+
96
+ return $mVal;
97
+ }
98
+
99
  /**
100
  * @return bool
101
  */
src/lib/vendor/fernleafsystems/wordpress-services/src/Core/VOs/WpThemeVo.php ADDED
@@ -0,0 +1,106 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace FernleafSystems\Wordpress\Services\Core\VOs;
4
+
5
+ use FernleafSystems\Utilities\Data\Adapter\StdClassAdapter;
6
+ use FernleafSystems\Wordpress\Services\Services;
7
+ use FernleafSystems\Wordpress\Services\Utilities\WpOrg\Theme;
8
+
9
+ /**
10
+ * Class WpThemeVo
11
+ * @package FernleafSystems\Wordpress\Services\Core\VOs
12
+ * @property string $theme - the stylesheet
13
+ * @property string $stylesheet - the stylesheet
14
+ * @property \WP_Theme $wp_theme
15
+ * @property Theme\VOs\ThemeInfoVO|false $wp_info - wp.org theme info
16
+ * @property string $new_version
17
+ * @property string $url
18
+ * @property string $package
19
+ * @property string $requires
20
+ * @property string $requires_php
21
+ * @property string $version
22
+ * @property bool $active
23
+ * @property bool $is_child
24
+ * @property bool $is_parent
25
+ */
26
+ class WpThemeVo {
27
+
28
+ use StdClassAdapter {
29
+ __get as __adapterGet;
30
+ __set as __adapterSet;
31
+ }
32
+
33
+ /**
34
+ * WpPluginVo constructor.
35
+ * @param string $sStylesheet - the name of the theme folder.
36
+ * @throws \Exception
37
+ */
38
+ public function __construct( $sStylesheet ) {
39
+ $oWpTheme = Services::WpThemes();
40
+ $oT = $oWpTheme->getTheme( $sStylesheet );
41
+ if ( empty( $oT ) ) {
42
+ throw new \Exception( sprintf( 'Theme file %s does not exist', $sStylesheet ) );
43
+ }
44
+
45
+ $this->applyFromArray( $oWpTheme->getExtendedData( $sStylesheet ) );
46
+ $this->wp_theme = $oT;
47
+ $this->stylesheet = $sStylesheet;
48
+ $this->active = $oWpTheme->isActive( $sStylesheet );
49
+ $this->is_child = $this->active && $oWpTheme->isActiveThemeAChild();
50
+ $this->is_parent = !$this->active && $oWpTheme->isActiveParent( $sStylesheet );
51
+ }
52
+
53
+ /**
54
+ * @param string $sProperty
55
+ * @return mixed
56
+ */
57
+ public function __get( $sProperty ) {
58
+
59
+ $mVal = $this->__adapterGet( $sProperty );
60
+
61
+ switch ( $sProperty ) {
62
+
63
+ case 'version':
64
+ if ( is_null( $mVal ) ) {
65
+ $mVal = $this->wp_theme->get( 'Version' );
66
+ $this->version = $mVal;
67
+ }
68
+ break;
69
+
70
+ case 'wp_info':
71
+ if ( is_null( $mVal ) ) {
72
+ try {
73
+ $mVal = ( new Theme\Api() )
74
+ ->setWorkingSlug( $this->stylesheet )
75
+ ->getInfo();
76
+ }
77
+ catch ( \Exception $oE ) {
78
+ $mVal = false;
79
+ }
80
+ $this->wp_info = $mVal;
81
+ }
82
+ break;
83
+
84
+ default:
85
+ break;
86
+ }
87
+
88
+ return $mVal;
89
+ }
90
+
91
+ /**
92
+ * @return bool
93
+ */
94
+ public function hasUpdate() {
95
+ return !empty( $this->new_version )
96
+ && version_compare( $this->new_version, $this->version, '>' );
97
+ }
98
+
99
+ /**
100
+ * @return bool
101
+ */
102
+ public function isWpOrg() {
103
+ $this->wp_info;
104
+ return !empty( $this->wp_info );
105
+ }
106
+ }
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/File/Cache/LoadFromCache.php CHANGED
@@ -19,7 +19,9 @@ class LoadFromCache extends Base {
19
 
20
  $oDef = $this->getCacheDef();
21
  $sFile = $this->getCacheFile();
22
- $nExpireBoundary = Services::Request()->carbon()->subSeconds( $oDef->expiration );
 
 
23
  if ( $oFS->exists( $sFile ) && $oFS->getModifiedTime( $sFile ) > $nExpireBoundary ) {
24
  $sJson = $oFS->getFileContent( $sFile, true );
25
  if ( !empty( $sJson ) ) {
19
 
20
  $oDef = $this->getCacheDef();
21
  $sFile = $this->getCacheFile();
22
+ $nExpireBoundary = Services::Request()
23
+ ->carbon()
24
+ ->subSeconds( $oDef->expiration )->timestamp;
25
  if ( $oFS->exists( $sFile ) && $oFS->getModifiedTime( $sFile ) > $nExpireBoundary ) {
26
  $sJson = $oFS->getFileContent( $sFile, true );
27
  if ( !empty( $sJson ) ) {
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/Plugin.php CHANGED
@@ -8,24 +8,10 @@ use FernleafSystems\Wordpress\Services;
8
  * Class Plugin
9
  * @package FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\Hashes
10
  */
11
- class Plugin extends Base {
12
 
13
  const TYPE = 'plugin';
14
 
15
- /**
16
- * @param string $sSlug
17
- * @param string $sVersion
18
- * @param string $sHashAlgo
19
- * @return array|null
20
- */
21
- public function getHashes( $sSlug, $sVersion, $sHashAlgo = null ) {
22
- $oReq = $this->getRequestVO();
23
- $oReq->version = $sVersion;
24
- $oReq->hash = $sHashAlgo;
25
- $oReq->slug = $sSlug;
26
- return $this->query();
27
- }
28
-
29
  /**
30
  * @param Services\Core\VOs\WpPluginVo $oPluginVO
31
  * @return array|null
8
  * Class Plugin
9
  * @package FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\Hashes
10
  */
11
+ class Plugin extends PluginThemeBase {
12
 
13
  const TYPE = 'plugin';
14
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  /**
16
  * @param Services\Core\VOs\WpPluginVo $oPluginVO
17
  * @return array|null
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/PluginThemeBase.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\Hashes;
4
+
5
+ /**
6
+ * Class PluginThemeBase
7
+ * @package FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\Hashes
8
+ */
9
+ abstract class PluginThemeBase extends Base {
10
+
11
+ /**
12
+ * @param string $sSlug
13
+ * @param string $sVersion
14
+ * @param string $sHashAlgo
15
+ * @return array|null
16
+ */
17
+ public function getHashes( $sSlug, $sVersion, $sHashAlgo = null ) {
18
+ $oReq = $this->getRequestVO();
19
+ $oReq->version = $sVersion;
20
+ $oReq->hash = $sHashAlgo;
21
+ $oReq->slug = $sSlug;
22
+ return $this->query();
23
+ }
24
+ }
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/Integrations/WpHashes/Hashes/Theme.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\Hashes;
4
+
5
+ use FernleafSystems\Wordpress\Services;
6
+
7
+ /**
8
+ * Class Theme
9
+ * @package FernleafSystems\Wordpress\Services\Utilities\Integrations\WpHashes\Hashes
10
+ */
11
+ class Theme extends PluginThemeBase {
12
+
13
+ const TYPE = 'theme';
14
+
15
+ /**
16
+ * @param Services\Core\VOs\WpThemeVo $oVO
17
+ * @return array|null
18
+ */
19
+ public function getHashesFromVO( Services\Core\VOs\WpThemeVo $oVO ) {
20
+ return $this->getHashes( $oVO->stylesheet, $oVO->version );
21
+ }
22
+ }
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Base/PluginThemeFilesBase.php ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace FernleafSystems\Wordpress\Services\Utilities\WpOrg\Base;
4
+
5
+ use FernleafSystems\Wordpress\Services;
6
+
7
+ /**
8
+ * Class PluginThemeFilesBase
9
+ * @package FernleafSystems\Wordpress\Services\Utilities\WpOrg\Base
10
+ */
11
+ abstract class PluginThemeFilesBase {
12
+
13
+ /**
14
+ * @param string $sFullFilePath
15
+ * @return bool
16
+ */
17
+ public function replaceFileFromVcs( $sFullFilePath ) {
18
+ $sTmpFile = $this->getOriginalFileFromVcs( $sFullFilePath );
19
+ return !empty( $sTmpFile ) && Services\Services::WpFs()->move( $sTmpFile, $sFullFilePath );
20
+ }
21
+
22
+ /**
23
+ * Verifies the file exists on the SVN repository for the particular version that's installed.
24
+ * @param string $sFullFilePath
25
+ * @return bool
26
+ * @throws \InvalidArgumentException
27
+ */
28
+ public function verifyFileContents( $sFullFilePath ) {
29
+ $sTmpFile = $this->getOriginalFileFromVcs( $sFullFilePath );
30
+ return !empty( $sTmpFile )
31
+ && ( new Services\Utilities\File\Compare\CompareHash() )
32
+ ->isEqualFilesMd5( $sTmpFile, $sFullFilePath );
33
+ }
34
+
35
+ /**
36
+ * @param string $sFullFilePath
37
+ * @return string
38
+ */
39
+ public function getOriginalFileMd5FromVcs( $sFullFilePath ) {
40
+ $sFile = $this->getOriginalFileFromVcs( $sFullFilePath );
41
+ return empty( $sFile ) ? null : md5_file( $sFile );
42
+ }
43
+
44
+ /**
45
+ * @param string $sFullFilePath
46
+ * @return string|null
47
+ */
48
+ abstract public function getOriginalFileFromVcs( $sFullFilePath );
49
+
50
+ /**
51
+ * Gets the path of the plugin file relative to its own home plugin dir. (not wp-content/plugins/)
52
+ * @param string $sFile
53
+ * @return string
54
+ */
55
+ abstract protected function getRelativeFilePathFromItsInstallDir( $sFile );
56
+ }
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Base/RepoBase.php CHANGED
@@ -10,29 +10,6 @@ use FernleafSystems\Wordpress\Services;
10
  */
11
  abstract class RepoBase {
12
 
13
- /**
14
- * @var string[]
15
- */
16
- private $aDownloadedFiles;
17
-
18
- public function __construct() {
19
- $this->autoDelete();
20
- }
21
-
22
- /**
23
- * Must be setup when the object is instantiated ie constructor
24
- */
25
- protected function autoDelete() {
26
- add_action( 'shutdown', function () {
27
- $oFs = Services\Services::WpFs();
28
- foreach ( $this->getDownloadedFiles() as $sFile ) {
29
- if ( $oFs->exists( $sFile ) ) {
30
- $oFs->deleteFile( $sFile );
31
- }
32
- }
33
- } );
34
- }
35
-
36
  /**
37
  * @param string $sFileFragment
38
  * @param string $sVersion
@@ -45,7 +22,6 @@ abstract class RepoBase {
45
  $sTmpFile = ( new Services\Utilities\HttpUtil() )
46
  ->checkUrl( $sUrl )
47
  ->downloadUrl( $sUrl );
48
- $this->addToDownloadedFiles( $sTmpFile );
49
  }
50
  catch ( \Exception $oE ) {
51
  $sTmpFile = null;
@@ -79,25 +55,4 @@ abstract class RepoBase {
79
  * @return string
80
  */
81
  abstract protected function getVcsUrlForFileAndVersion( $sFileFragment, $sVersion, $bUseSiteLocale = true );
82
-
83
- /**
84
- * @param string $sFile
85
- * @return $this
86
- */
87
- private function addToDownloadedFiles( $sFile ) {
88
- $aFiles = $this->getDownloadedFiles();
89
- $aFiles[] = $sFile;
90
- $this->aDownloadedFiles = $aFiles;
91
- return $this;
92
- }
93
-
94
- /**
95
- * @return string[]
96
- */
97
- private function getDownloadedFiles() {
98
- if ( !is_array( $this->aDownloadedFiles ) ) {
99
- $this->aDownloadedFiles = [];
100
- }
101
- return array_filter( $this->aDownloadedFiles );
102
- }
103
  }
10
  */
11
  abstract class RepoBase {
12
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  /**
14
  * @param string $sFileFragment
15
  * @param string $sVersion
22
  $sTmpFile = ( new Services\Utilities\HttpUtil() )
23
  ->checkUrl( $sUrl )
24
  ->downloadUrl( $sUrl );
 
25
  }
26
  catch ( \Exception $oE ) {
27
  $sTmpFile = null;
55
  * @return string
56
  */
57
  abstract protected function getVcsUrlForFileAndVersion( $sFileFragment, $sVersion, $bUseSiteLocale = true );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
  }
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Plugin/Api.php CHANGED
@@ -19,10 +19,19 @@ class Api {
19
  * @return PluginInfoVO
20
  * @throws \Exception
21
  */
22
- public function getPluginInfo() {
23
  return $this->run( 'plugin_information' );
24
  }
25
 
 
 
 
 
 
 
 
 
 
26
  /**
27
  * @param string $sCmd
28
  * @return PluginInfoVO
19
  * @return PluginInfoVO
20
  * @throws \Exception
21
  */
22
+ public function getInfo() {
23
  return $this->run( 'plugin_information' );
24
  }
25
 
26
+ /**
27
+ * @return PluginInfoVO
28
+ * @throws \Exception
29
+ * @deprecated 0.1.19
30
+ */
31
+ public function getPluginInfo() {
32
+ return $this->getInfo();
33
+ }
34
+
35
  /**
36
  * @param string $sCmd
37
  * @return PluginInfoVO
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Plugin/Base.php CHANGED
@@ -6,7 +6,7 @@ use FernleafSystems\Wordpress\Services\Core\VOs\WpPluginVo;
6
  use FernleafSystems\Wordpress\Services\Services;
7
 
8
  /**
9
- * Class Base
10
  * @package FernleafSystems\Wordpress\Services\Utilities\WpOrg\Plugin
11
  */
12
  trait Base {
6
  use FernleafSystems\Wordpress\Services\Services;
7
 
8
  /**
9
+ * Trait Base
10
  * @package FernleafSystems\Wordpress\Services\Utilities\WpOrg\Plugin
11
  */
12
  trait Base {
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Plugin/Download.php CHANGED
@@ -4,26 +4,34 @@ namespace FernleafSystems\Wordpress\Services\Utilities\WpOrg\Plugin;
4
 
5
  use FernleafSystems\Wordpress\Services\Utilities\HttpUtil;
6
 
 
 
 
 
7
  class Download {
8
 
9
  use Base;
10
 
 
 
 
 
 
 
 
 
 
 
 
11
  /**
12
  * @return string|null
13
  * @throws \Exception
14
  */
15
  public function latest() {
16
- try {
17
- $sUrl = ( new Api() )
18
- ->setWorkingSlug( $this->getWorkingSlug() )
19
- ->getPluginInfo()
20
- ->download_link;
21
- $sTmpFile = ( new HttpUtil() )->downloadUrl( $sUrl );
22
- }
23
- catch ( \Exception $oE ) {
24
- $sTmpFile = null;
25
- }
26
- return $sTmpFile;
27
  }
28
 
29
  /**
@@ -32,18 +40,7 @@ class Download {
32
  * @throws \Exception
33
  */
34
  public function version( $sVersion ) {
35
- $sTmpFile = null;
36
- try {
37
- $aVersions = ( new Api() )
38
- ->setWorkingSlug( $this->getWorkingSlug() )
39
- ->getPluginInfo()
40
- ->versions;
41
- if ( !empty( $aVersions[ $sVersion ] ) ) {
42
- $sTmpFile = ( new HttpUtil() )->downloadUrl( $aVersions[ $sVersion ] );
43
- }
44
- }
45
- catch ( \Exception $oE ) {
46
- }
47
- return $sTmpFile;
48
  }
49
  }
4
 
5
  use FernleafSystems\Wordpress\Services\Utilities\HttpUtil;
6
 
7
+ /**
8
+ * Class Download
9
+ * @package FernleafSystems\Wordpress\Services\Utilities\WpOrg\Plugin
10
+ */
11
  class Download {
12
 
13
  use Base;
14
 
15
+ /**
16
+ * @param string $sVersion
17
+ * @return string|null
18
+ */
19
+ public function getDownloadUrlForVersion( $sVersion ) {
20
+ $aAll = ( new Versions() )
21
+ ->setWorkingSlug( $this->getWorkingSlug() )
22
+ ->allVersionsUrls();
23
+ return empty( $aAll[ $sVersion ] ) ? null : $aAll[ $sVersion ];
24
+ }
25
+
26
  /**
27
  * @return string|null
28
  * @throws \Exception
29
  */
30
  public function latest() {
31
+ $sUrl = ( new Versions() )
32
+ ->setWorkingSlug( $this->getWorkingSlug() )
33
+ ->latest();
34
+ return empty( $sUrl ) ? null : ( new HttpUtil() )->downloadUrl( $sUrl );
 
 
 
 
 
 
 
35
  }
36
 
37
  /**
40
  * @throws \Exception
41
  */
42
  public function version( $sVersion ) {
43
+ $sUrl = $this->getDownloadUrlForVersion( $sVersion );
44
+ return empty( $sUrl ) ? null : ( new HttpUtil() )->downloadUrl( $sUrl );
 
 
 
 
 
 
 
 
 
 
 
45
  }
46
  }
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Plugin/Files.php CHANGED
@@ -8,7 +8,7 @@ use FernleafSystems\Wordpress\Services;
8
  * Class Files
9
  * @package FernleafSystems\Wordpress\Services\Utilities\WpOrg\Plugin
10
  */
11
- class Files {
12
 
13
  use Base;
14
 
@@ -21,12 +21,12 @@ class Files {
21
  $oThePlugin = null;
22
 
23
  $sFragment = $this->getPluginPathFragmentFromPath( $sFullFilePath );
24
- $oWpPlugins = Services\Services::WpPlugins();
25
 
26
  if ( !empty( $sFragment ) && strpos( $sFragment, '/' ) > 0 ) {
27
- list( $sThisPluginDir, $sPluginPathFragment ) = explode( '/', $sFragment, 2 );
 
28
  foreach ( $oWpPlugins->getInstalledPluginFiles() as $sPluginFile ) {
29
- if ( $sThisPluginDir == dirname( $sPluginFile ) ) {
30
  $oThePlugin = $oWpPlugins->getPluginAsVo( $sPluginFile );
31
  break;
32
  }
@@ -51,67 +51,38 @@ class Files {
51
  throw new \InvalidArgumentException( 'Not a WordPress.org plugin.', 2 );
52
  }
53
 
 
54
  return ( new Repo() )
55
  ->setWorkingSlug( $oThePlugin->slug )
56
- ->setWorkingVersion( $oThePlugin->Version )
57
- ->existsInVcs( $this->getRelativeFilePathFromItsPluginDir( $sFullFilePath ) );
58
  }
59
 
60
  /**
61
  * @param string $sFullFilePath
62
  * @return bool
63
- * @throws \InvalidArgumentException
64
  */
65
  public function replaceFileFromVcs( $sFullFilePath ) {
66
  $sTmpFile = $this->getOriginalFileFromVcs( $sFullFilePath );
67
  return !empty( $sTmpFile ) && Services\Services::WpFs()->move( $sTmpFile, $sFullFilePath );
68
  }
69
 
70
- /**
71
- * Verifies the file exists on the SVN repository for the particular version that's installed.
72
- * @param string $sFullFilePath
73
- * @return bool
74
- * @throws \InvalidArgumentException - not actually a plugin file / not a WordPress.org plugin
75
- */
76
- public function verifyFileContents( $sFullFilePath ) {
77
- $bVerified = false;
78
- if ( $this->isValidFileFromPlugin( $sFullFilePath ) ) {
79
- $sTmpFile = $this->getOriginalFileFromVcs( $sFullFilePath );
80
- if ( !empty( $sTmpFile ) ) {
81
- $bVerified = ( new Services\Utilities\File\Compare\CompareHash() )
82
- ->isEqualFilesMd5( $sTmpFile, $sFullFilePath );
83
- }
84
- }
85
- return $bVerified;
86
- }
87
-
88
  /**
89
  * @param string $sFullFilePath
90
  * @return string|null
91
- * @throws \InvalidArgumentException
92
  */
93
  public function getOriginalFileFromVcs( $sFullFilePath ) {
94
  $sTmpFile = null;
95
- if ( $this->isValidFileFromPlugin( $sFullFilePath ) ) {
96
- $oThePlugin = $this->findPluginFromFile( $sFullFilePath );
97
  $sTmpFile = ( new Repo() )
98
  ->setWorkingSlug( $oThePlugin->slug )
99
- ->setWorkingVersion( $oThePlugin->Version )
100
- ->downloadFromVcs( $this->getRelativeFilePathFromItsPluginDir( $sFullFilePath ) );
101
  }
102
  return $sTmpFile;
103
  }
104
 
105
- /**
106
- * @param string $sFullFilePath
107
- * @return string
108
- * @throws \InvalidArgumentException
109
- */
110
- public function getOriginalFileMd5FromVcs( $sFullFilePath ) {
111
- $sFile = $this->getOriginalFileFromVcs( $sFullFilePath );
112
- return empty( $sFile ) ? null : md5_file( $sFile );
113
- }
114
-
115
  /**
116
  * @param string $sFile - can either be absolute, or relative to ABSPATH
117
  * @return string|null - the path to the file relative to Plugins Dir.
@@ -137,9 +108,8 @@ class Files {
137
  * @param string $sFile
138
  * @return string
139
  */
140
- private function getRelativeFilePathFromItsPluginDir( $sFile ) {
141
- $sPluginsDirFragment = $this->getPluginPathFragmentFromPath( $sFile );
142
- list( $sThisPluginDir, $sPluginPathFragment ) = explode( '/', $sPluginsDirFragment, 2 );
143
- return $sPluginPathFragment;
144
  }
145
  }
8
  * Class Files
9
  * @package FernleafSystems\Wordpress\Services\Utilities\WpOrg\Plugin
10
  */
11
+ class Files extends Services\Utilities\WpOrg\Base\PluginThemeFilesBase {
12
 
13
  use Base;
14
 
21
  $oThePlugin = null;
22
 
23
  $sFragment = $this->getPluginPathFragmentFromPath( $sFullFilePath );
 
24
 
25
  if ( !empty( $sFragment ) && strpos( $sFragment, '/' ) > 0 ) {
26
+ $oWpPlugins = Services\Services::WpPlugins();
27
+ $sDir = substr( $sFragment, 0, strpos( $sFragment, '/' ) );
28
  foreach ( $oWpPlugins->getInstalledPluginFiles() as $sPluginFile ) {
29
+ if ( $sDir == dirname( $sPluginFile ) ) {
30
  $oThePlugin = $oWpPlugins->getPluginAsVo( $sPluginFile );
31
  break;
32
  }
51
  throw new \InvalidArgumentException( 'Not a WordPress.org plugin.', 2 );
52
  }
53
 
54
+ // if uses SVN tags, use that version. Otherwise trunk.
55
  return ( new Repo() )
56
  ->setWorkingSlug( $oThePlugin->slug )
57
+ ->setWorkingVersion( ( $oThePlugin->svn_uses_tags ? $oThePlugin->Version : 'trunk' ) )
58
+ ->existsInVcs( $this->getRelativeFilePathFromItsInstallDir( $sFullFilePath ) );
59
  }
60
 
61
  /**
62
  * @param string $sFullFilePath
63
  * @return bool
 
64
  */
65
  public function replaceFileFromVcs( $sFullFilePath ) {
66
  $sTmpFile = $this->getOriginalFileFromVcs( $sFullFilePath );
67
  return !empty( $sTmpFile ) && Services\Services::WpFs()->move( $sTmpFile, $sFullFilePath );
68
  }
69
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
  /**
71
  * @param string $sFullFilePath
72
  * @return string|null
 
73
  */
74
  public function getOriginalFileFromVcs( $sFullFilePath ) {
75
  $sTmpFile = null;
76
+ $oThePlugin = $this->findPluginFromFile( $sFullFilePath );
77
+ if ( $oThePlugin instanceof Services\Core\VOs\WpPluginVo ) {
78
  $sTmpFile = ( new Repo() )
79
  ->setWorkingSlug( $oThePlugin->slug )
80
+ ->setWorkingVersion( ( $oThePlugin->svn_uses_tags ? $oThePlugin->Version : 'trunk' ) )
81
+ ->downloadFromVcs( $this->getRelativeFilePathFromItsInstallDir( $sFullFilePath ) );
82
  }
83
  return $sTmpFile;
84
  }
85
 
 
 
 
 
 
 
 
 
 
 
86
  /**
87
  * @param string $sFile - can either be absolute, or relative to ABSPATH
88
  * @return string|null - the path to the file relative to Plugins Dir.
108
  * @param string $sFile
109
  * @return string
110
  */
111
+ protected function getRelativeFilePathFromItsInstallDir( $sFile ) {
112
+ $sRelDirFragment = $this->getPluginPathFragmentFromPath( $sFile );
113
+ return substr( $sRelDirFragment, strpos( $sRelDirFragment, '/' ) + 1 );
 
114
  }
115
  }
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Plugin/Repo.php CHANGED
@@ -29,7 +29,10 @@ class Repo extends Services\Utilities\WpOrg\Base\RepoBase {
29
  * @return string
30
  */
31
  static public function GetUrlForPluginVersion( $sSlug, $sVersion ) {
32
- return sprintf( '%s/tags/%s', static::GetUrlForPlugin( $sSlug ), $sVersion );
 
 
 
33
  }
34
 
35
  /**
@@ -60,6 +63,8 @@ class Repo extends Services\Utilities\WpOrg\Base\RepoBase {
60
  ->latest();
61
  }
62
  return sprintf( '%s/%s',
63
- static::GetUrlForPluginVersion( $this->getWorkingSlug(), $sVersion ), ltrim( $sFileFragment, '/' ) );
 
 
64
  }
65
  }
29
  * @return string
30
  */
31
  static public function GetUrlForPluginVersion( $sSlug, $sVersion ) {
32
+ if ( $sVersion != 'trunk' ) {
33
+ $sVersion = sprintf( 'tags/%s', $sVersion );
34
+ }
35
+ return sprintf( '%s/%s', static::GetUrlForPlugin( $sSlug ), $sVersion );
36
  }
37
 
38
  /**
63
  ->latest();
64
  }
65
  return sprintf( '%s/%s',
66
+ rtrim( static::GetUrlForPluginVersion( $this->getWorkingSlug(), $sVersion ), '/' ),
67
+ ltrim( $sFileFragment, '/' )
68
+ );
69
  }
70
  }
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Plugin/VOs/PluginInfoVO.php CHANGED
@@ -7,29 +7,29 @@ use FernleafSystems\Utilities\Data\Adapter\StdClassAdapter;
7
  /**
8
  * Class PluginInfoVO
9
  * @package FernleafSystems\Wordpress\Services\Utilities\WpOrg\Plugin\VOs
10
- * @property string name
11
- * @property string slug
12
- * @property string version
13
- * @property string author - a href link
14
- * @property string author_profile - URL
15
- * @property array contributors
16
- * @property string requires
17
- * @property string tested
18
- * @property string requires_php
19
- * @property int rating
20
- * @property array ratings
21
- * @property int num_ratings
22
- * @property int support_threads
23
- * @property int support_threads_resolved
24
- * @property int active_installs
25
- * @property string last_updated
26
- * @property string added - YYYY-MM-DD
27
- * @property string homepage - URL
28
- * @property array sections
29
- * @property string download_link
30
- * @property array screenshots
31
- * @property array tags
32
- * @property array versions - key: versions; value: URL to ZIP
33
  */
34
  class PluginInfoVO {
35
 
7
  /**
8
  * Class PluginInfoVO
9
  * @package FernleafSystems\Wordpress\Services\Utilities\WpOrg\Plugin\VOs
10
+ * @property string name
11
+ * @property string slug
12
+ * @property string version
13
+ * @property string author - a href link
14
+ * @property string author_profile - URL
15
+ * @property array contributors
16
+ * @property string requires
17
+ * @property string tested
18
+ * @property string requires_php
19
+ * @property int rating
20
+ * @property array ratings
21
+ * @property int num_ratings
22
+ * @property int support_threads
23
+ * @property int support_threads_resolved
24
+ * @property int active_installs
25
+ * @property string last_updated
26
+ * @property string added - YYYY-MM-DD
27
+ * @property string homepage - URL
28
+ * @property array sections
29
+ * @property string download_link
30
+ * @property array screenshots
31
+ * @property array tags
32
+ * @property string[] versions - key: versions; value: URL to ZIP
33
  */
34
  class PluginInfoVO {
35
 
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Plugin/Versions.php CHANGED
@@ -2,7 +2,6 @@
2
 
3
  namespace FernleafSystems\Wordpress\Services\Utilities\WpOrg\Plugin;
4
 
5
- use FernleafSystems\Wordpress\Services\Services;
6
  use FernleafSystems\Wordpress\Services\Utilities\HttpUtil;
7
 
8
  class Versions {
@@ -12,52 +11,25 @@ class Versions {
12
  /**
13
  * @return string[]
14
  */
15
- public function allFallback() {
16
- $aV = [];
17
- $sSvnVersionsContent = Services::HttpRequest()
18
- ->getContent( Repo::GetUrlForPluginVersions( $this->getWorkingSlug() ) );
19
-
20
- if ( !empty( $sSvnVersionsContent ) ) {
21
- $oSvnDom = new \DOMDocument();
22
- $oSvnDom->loadHTML( $sSvnVersionsContent );
23
-
24
- foreach ( $oSvnDom->getElementsByTagName( 'a' ) as $oElem ) {
25
- /** @var \DOMElement $oElem */
26
- $sHref = $oElem->getAttribute( 'href' );
27
- if ( $sHref != '../' && !filter_var( $sHref, FILTER_VALIDATE_URL ) ) {
28
- $aV[] = trim( $sHref, '/' );
29
- }
30
- }
31
- }
32
- return $aV;
33
  }
34
 
35
  /**
36
  * @return string[]
37
  */
38
- public function all() {
39
  try {
40
- $oInfo = ( new Api() )
41
  ->setWorkingSlug( $this->getWorkingSlug() )
42
- ->getPluginInfo();
43
-
44
- if ( !empty( $oInfo->versions ) ) {
45
- $aVersions = array_filter(
46
- array_keys( $oInfo->versions ),
47
- function ( $sVersion ) {
48
- return strpos( $sVersion, '.' );
49
- }
50
- );
51
- }
52
- else {
53
- $aVersions = $this->allFallback();
54
- }
55
  }
56
  catch ( \Exception $oE ) {
57
  $aVersions = [];
58
  }
59
-
60
- usort( $aVersions, 'version_compare' );
61
  return $aVersions;
62
  }
63
 
@@ -68,7 +40,7 @@ class Versions {
68
  public function latest() {
69
  return ( new Api() )
70
  ->setWorkingSlug( $this->getWorkingSlug() )
71
- ->getPluginInfo()
72
  ->version;
73
  }
74
 
2
 
3
  namespace FernleafSystems\Wordpress\Services\Utilities\WpOrg\Plugin;
4
 
 
5
  use FernleafSystems\Wordpress\Services\Utilities\HttpUtil;
6
 
7
  class Versions {
11
  /**
12
  * @return string[]
13
  */
14
+ public function all() {
15
+ $aVersions = array_filter( array_keys( $this->allVersionsUrls() ) );
16
+ usort( $aVersions, 'version_compare' );
17
+ return $aVersions;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  }
19
 
20
  /**
21
  * @return string[]
22
  */
23
+ public function allVersionsUrls() {
24
  try {
25
+ $aVersions = ( new Api() )
26
  ->setWorkingSlug( $this->getWorkingSlug() )
27
+ ->getInfo()
28
+ ->versions;
 
 
 
 
 
 
 
 
 
 
 
29
  }
30
  catch ( \Exception $oE ) {
31
  $aVersions = [];
32
  }
 
 
33
  return $aVersions;
34
  }
35
 
40
  public function latest() {
41
  return ( new Api() )
42
  ->setWorkingSlug( $this->getWorkingSlug() )
43
+ ->getInfo()
44
  ->version;
45
  }
46
 
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Theme/Api.php ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace FernleafSystems\Wordpress\Services\Utilities\WpOrg\Theme;
4
+
5
+ use FernleafSystems\Utilities\Data\Adapter\StdClassAdapter;
6
+ use FernleafSystems\Wordpress\Services\Services;
7
+ use FernleafSystems\Wordpress\Services\Utilities\WpOrg\Theme\VOs\ThemeInfoVO;
8
+
9
+ /**
10
+ * Class Api
11
+ * @package FernleafSystems\Wordpress\Services\Utilities\WpOrg\Theme
12
+ * @property array $fields
13
+ */
14
+ class Api {
15
+
16
+ use Base,
17
+ StdClassAdapter;
18
+
19
+ /**
20
+ * @return ThemeInfoVO
21
+ * @throws \Exception
22
+ */
23
+ public function getInfo() {
24
+ return $this->run( 'theme_information' );
25
+ }
26
+
27
+ /**
28
+ * @return ThemeInfoVO
29
+ * @throws \Exception
30
+ * @deprecated 0.1.19
31
+ */
32
+ public function getThemeInfo() {
33
+ return $this->getInfo();
34
+ }
35
+
36
+ /**
37
+ * @param string $sCmd
38
+ * @return ThemeInfoVO
39
+ * @throws \Exception
40
+ */
41
+ public function run( $sCmd ) {
42
+ include_once( ABSPATH.'wp-admin/includes/theme.php' );
43
+
44
+ $aParams = $this->getRawDataAsArray();
45
+ $aParams[ 'slug' ] = $this->getWorkingSlug();
46
+ $oResponse = \themes_api( $sCmd,
47
+ Services::DataManipulation()->mergeArraysRecursive( $this->defaultParams(), $aParams ) );
48
+
49
+ if ( \is_wp_error( $oResponse ) ) {
50
+ throw new \Exception( sprintf( '[ThemesApi Error] %s', $oResponse->get_error_message() ) );
51
+ }
52
+ else if ( !\is_object( $oResponse ) ) {
53
+ throw new \Exception( sprintf( '[ThemesApi Error] %s', 'Did not return an expected Object' ) );
54
+ }
55
+
56
+ return ( new ThemeInfoVO() )->applyFromArray( (array)$oResponse );
57
+ }
58
+
59
+ /**
60
+ * @return array[]
61
+ */
62
+ protected function defaultParams() {
63
+ return [
64
+ 'fields' => [
65
+ 'rating' => true,
66
+ 'ratings' => true,
67
+ 'versions' => true,
68
+ ]
69
+ ];
70
+ }
71
+ }
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Theme/Base.php ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace FernleafSystems\Wordpress\Services\Utilities\WpOrg\Theme;
4
+
5
+ use FernleafSystems\Wordpress\Services\Services;
6
+
7
+ /**
8
+ * Trait Base
9
+ * @package FernleafSystems\Wordpress\Services\Utilities\WpOrg\Theme
10
+ */
11
+ trait Base {
12
+
13
+ /**
14
+ * @var string
15
+ */
16
+ private $sWorkingSlug;
17
+
18
+ /**
19
+ * @var string
20
+ */
21
+ private $sWorkingVersion;
22
+
23
+ /**
24
+ * @return string
25
+ */
26
+ public function getWorkingSlug() {
27
+ return $this->sWorkingSlug;
28
+ }
29
+
30
+ /**
31
+ * @return string
32
+ */
33
+ public function getWorkingVersion() {
34
+ $sVersion = $this->sWorkingVersion;
35
+ if ( empty( $sVersion ) ) {
36
+ $oT = Services::WpThemes()->getTheme( $this->getWorkingSlug() );
37
+ if ( $oT instanceof \WP_Theme ) {
38
+ $sVersion = $oT->get( 'Version' );
39
+ }
40
+ }
41
+ return $sVersion;
42
+ }
43
+
44
+ /**
45
+ * @param string $sSlug
46
+ * @return $this
47
+ */
48
+ public function setWorkingSlug( $sSlug ) {
49
+ $this->sWorkingSlug = $sSlug;
50
+ return $this;
51
+ }
52
+
53
+ /**
54
+ * @param string $sV
55
+ * @return $this
56
+ */
57
+ public function setWorkingVersion( $sV ) {
58
+ $this->sWorkingVersion = $sV;
59
+ return $this;
60
+ }
61
+ }
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Theme/Download.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace FernleafSystems\Wordpress\Services\Utilities\WpOrg\Theme;
4
+
5
+ use FernleafSystems\Wordpress\Services\Utilities\HttpUtil;
6
+
7
+ /**
8
+ * Class Download
9
+ * @package FernleafSystems\Wordpress\Services\Utilities\WpOrg\Theme
10
+ */
11
+ class Download {
12
+
13
+ use Base;
14
+
15
+ /**
16
+ * @param string $sVersion
17
+ * @return string|null
18
+ */
19
+ public function getDownloadUrlForVersion( $sVersion ) {
20
+ $aAll = ( new Versions() )
21
+ ->setWorkingSlug( $this->getWorkingSlug() )
22
+ ->allVersionsUrls();
23
+ return empty( $aAll[ $sVersion ] ) ? null : $aAll[ $sVersion ];
24
+ }
25
+
26
+ /**
27
+ * @return string|null
28
+ * @throws \Exception
29
+ */
30
+ public function latest() {
31
+ $sUrl = ( new Versions() )
32
+ ->setWorkingSlug( $this->getWorkingSlug() )
33
+ ->latest();
34
+ return empty( $sUrl ) ? null : ( new HttpUtil() )->downloadUrl( $sUrl );
35
+ }
36
+
37
+ /**
38
+ * @param string $sVersion
39
+ * @return string
40
+ * @throws \Exception
41
+ */
42
+ public function version( $sVersion ) {
43
+ $sUrl = $this->getDownloadUrlForVersion( $sVersion );
44
+ return empty( $sUrl ) ? null : ( new HttpUtil() )->downloadUrl( $sUrl );
45
+ }
46
+ }
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Theme/Files.php ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace FernleafSystems\Wordpress\Services\Utilities\WpOrg\Theme;
4
+
5
+ use FernleafSystems\Wordpress\Services;
6
+
7
+ /**
8
+ * Class Files
9
+ * @package FernleafSystems\Wordpress\Services\Utilities\WpOrg\Theme
10
+ */
11
+ class Files extends Services\Utilities\WpOrg\Base\PluginThemeFilesBase {
12
+
13
+ use Base;
14
+
15
+ /**
16
+ * Given a full root path on the file system for a file, locate the plugin to which this file belongs.
17
+ * @param string $sFullFilePath
18
+ * @return Services\Core\VOs\WpThemeVo|null
19
+ */
20
+ public function findThemeFromFile( $sFullFilePath ) {
21
+ $oTheTheme = null;
22
+
23
+ $sFragment = $this->getThemePathFragmentFromPath( $sFullFilePath );
24
+
25
+ if ( !empty( $sFragment ) && strpos( $sFragment, '/' ) > 0 ) {
26
+ $oWpThemes = Services\Services::WpThemes();
27
+ $sDir = substr( $sFragment, 0, strpos( $sFragment, '/' ) );
28
+ foreach ( $oWpThemes->getThemes() as $oTheme ) {
29
+ if ( $sDir == $oTheme->get_stylesheet() ) {
30
+ $oTheTheme = $oWpThemes->getThemeAsVo( $sDir );
31
+ break;
32
+ }
33
+ }
34
+ }
35
+ return $oTheTheme;
36
+ }
37
+
38
+ /**
39
+ * Verifies the file exists on the SVN repository for the particular version that's installed.
40
+ * @param string $sFullFilePath
41
+ * @return bool
42
+ * @throws \InvalidArgumentException
43
+ */
44
+ public function isValidFileFromTheme( $sFullFilePath ) {
45
+
46
+ $oTheTheme = $this->findThemeFromFile( $sFullFilePath );
47
+ if ( !$oTheTheme instanceof Services\Core\VOs\WpThemeVo ) {
48
+ throw new \InvalidArgumentException( 'Not actually a theme file.', 1 );
49
+ }
50
+ if ( !$oTheTheme->isWpOrg() ) {
51
+ throw new \InvalidArgumentException( 'Not a WordPress.org theme.', 2 );
52
+ }
53
+
54
+ // if uses SVN tags, use that version. Otherwise trunk.
55
+ return ( new Repo() )
56
+ ->setWorkingSlug( $oTheTheme->stylesheet )
57
+ ->setWorkingVersion( $oTheTheme->version )
58
+ ->existsInVcs( $this->getRelativeFilePathFromItsInstallDir( $sFullFilePath ) );
59
+ }
60
+
61
+ /**
62
+ * @param string $sFullFilePath
63
+ * @return bool
64
+ */
65
+ public function replaceFileFromVcs( $sFullFilePath ) {
66
+ $sTmpFile = $this->getOriginalFileFromVcs( $sFullFilePath );
67
+ return !empty( $sTmpFile ) && Services\Services::WpFs()->move( $sTmpFile, $sFullFilePath );
68
+ }
69
+
70
+ /**
71
+ * Verifies the file exists on the SVN repository for the particular version that's installed.
72
+ * @param string $sFullFilePath
73
+ * @return bool
74
+ * @throws \InvalidArgumentException
75
+ */
76
+ public function verifyFileContents( $sFullFilePath ) {
77
+ $sTmpFile = $this->getOriginalFileFromVcs( $sFullFilePath );
78
+ return !empty( $sTmpFile )
79
+ && ( new Services\Utilities\File\Compare\CompareHash() )
80
+ ->isEqualFilesMd5( $sTmpFile, $sFullFilePath );
81
+ }
82
+
83
+ /**
84
+ * @param string $sFullFilePath
85
+ * @return string|null
86
+ */
87
+ public function getOriginalFileFromVcs( $sFullFilePath ) {
88
+ $sTmpFile = null;
89
+ $oTheTheme = $this->findThemeFromFile( $sFullFilePath );
90
+ if ( $oTheTheme instanceof Services\Core\VOs\WpThemeVo ) {
91
+ $sTmpFile = ( new Repo() )
92
+ ->setWorkingSlug( $oTheTheme->stylesheet )
93
+ ->setWorkingVersion( $oTheTheme->version )
94
+ ->downloadFromVcs( $this->getRelativeFilePathFromItsInstallDir( $sFullFilePath ) );
95
+ }
96
+ return $sTmpFile;
97
+ }
98
+
99
+ /**
100
+ * @param string $sFile - can either be absolute, or relative to ABSPATH
101
+ * @return string|null - the path to the file relative to Plugins Dir.
102
+ */
103
+ public function getThemePathFragmentFromPath( $sFile ) {
104
+ $sFragment = null;
105
+
106
+ if ( !path_is_absolute( $sFile ) ) { // assume it's relative to ABSPATH
107
+ $sFile = path_join( ABSPATH, $sFile );
108
+ }
109
+ $sFile = wp_normalize_path( $sFile );
110
+ $sThemesDir = wp_normalize_path( get_theme_root() );
111
+
112
+ if ( strpos( $sFile, $sThemesDir ) === 0 ) {
113
+ $sFragment = ltrim( str_replace( $sThemesDir, '', $sFile ), '/' );
114
+ }
115
+
116
+ return $sFragment;
117
+ }
118
+
119
+ /**
120
+ * Gets the path of the plugin file relative to its own home plugin dir. (not wp-content/plugins/)
121
+ * @param string $sFile
122
+ * @return string
123
+ */
124
+ protected function getRelativeFilePathFromItsInstallDir( $sFile ) {
125
+ $sRelDirFragment = $this->getThemePathFragmentFromPath( $sFile );
126
+ return substr( $sRelDirFragment, strpos( $sRelDirFragment, '/' ) + 1 );
127
+ }
128
+ }
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Theme/Repo.php ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace FernleafSystems\Wordpress\Services\Utilities\WpOrg\Theme;
4
+
5
+ use FernleafSystems\Wordpress\Services;
6
+
7
+ /**
8
+ * Class Repo
9
+ * @package FernleafSystems\Wordpress\Services\Utilities\WpOrg\Theme
10
+ */
11
+ class Repo extends Services\Utilities\WpOrg\Base\RepoBase {
12
+
13
+ use Base;
14
+ const URL_VCS_ROOT = 'https://themes.svn.wordpress.org';
15
+
16
+ /**
17
+ * @param string $sSlug
18
+ * @return string
19
+ */
20
+ static public function GetUrlForTheme( $sSlug ) {
21
+ return sprintf( '%s/%s', static::URL_VCS_ROOT, $sSlug );
22
+ }
23
+
24
+ /**
25
+ * @param string $sSlug
26
+ * @param string $sVersion
27
+ * @return string
28
+ */
29
+ static public function GetUrlForThemeVersion( $sSlug, $sVersion ) {
30
+ return sprintf( '%s/%s', static::GetUrlForTheme( $sSlug ), $sVersion );
31
+ }
32
+
33
+ /**
34
+ * @param string $sSlug
35
+ * @return string
36
+ */
37
+ static public function GetUrlForThemeVersions( $sSlug ) {
38
+ return static::GetUrlForThemeVersion( $sSlug, '' );
39
+ }
40
+
41
+ /**
42
+ * @param string $sFileFragment - relative to the working plugin directory
43
+ * @param string $sVersion
44
+ * @param bool $bUseSiteLocale - unused
45
+ * @return string
46
+ * @throws \Exception
47
+ */
48
+ protected function getVcsUrlForFileAndVersion( $sFileFragment, $sVersion = null, $bUseSiteLocale = true ) {
49
+ if ( empty( $sFileFragment ) ) {
50
+ throw new \InvalidArgumentException( 'Theme file fragment path provided is empty' );
51
+ }
52
+ if ( empty( $sVersion ) ) {
53
+ $sVersion = $this->getWorkingVersion();
54
+ }
55
+ if ( empty( $sVersion ) ) {
56
+ $sVersion = ( new Versions() )
57
+ ->setWorkingSlug( $this->getWorkingSlug() )
58
+ ->latest();
59
+ }
60
+ return sprintf( '%s/%s',
61
+ static::GetUrlForThemeVersion( $this->getWorkingSlug(), $sVersion ), ltrim( $sFileFragment, '/' ) );
62
+ }
63
+ }
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Theme/VOs/ThemeInfoVO.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace FernleafSystems\Wordpress\Services\Utilities\WpOrg\Theme\VOs;
4
+
5
+ use FernleafSystems\Utilities\Data\Adapter\StdClassAdapter;
6
+
7
+ /**
8
+ * Class ThemeInfoVO
9
+ * @package FernleafSystems\Wordpress\Services\Utilities\WpOrg\Theme\VOs
10
+ * @property string name
11
+ * @property string slug
12
+ * @property string version
13
+ * @property string preview_url
14
+ * @property string[] author - user_nicename / profile / avatar / display_name
15
+ * @property string screenshot_url - URL
16
+ * @property string[] versions - key is version, value is ZIP URL
17
+ * @property string requires
18
+ * @property string requires_php
19
+ * @property int rating
20
+ * @property int[] ratings - 1, 2, 3, 4, 5
21
+ * @property int num_ratings
22
+ * @property int downloaded
23
+ * @property string last_updated
24
+ * @property string homepage - URL
25
+ * @property array sections - description /
26
+ * @property string download_link
27
+ * @property string[] tags - theme tags, not versions
28
+ */
29
+ class ThemeInfoVO {
30
+
31
+ use StdClassAdapter;
32
+
33
+ /**
34
+ * @return float
35
+ */
36
+ public function getNetPromoterScore() {
37
+ $aRs = $this->ratings;
38
+ return ( $aRs[ 5 ] - ( $aRs[ 1 ] + $aRs[ 2 ] + $aRs[ 3 ] ) )/array_sum( $aRs );
39
+ }
40
+ }
src/lib/vendor/fernleafsystems/wordpress-services/src/Utilities/WpOrg/Theme/Versions.php ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace FernleafSystems\Wordpress\Services\Utilities\WpOrg\Theme;
4
+
5
+ use FernleafSystems\Wordpress\Services\Utilities\HttpUtil;
6
+
7
+ class Versions {
8
+
9
+ use Base;
10
+
11
+ /**
12
+ * @return string[]
13
+ */
14
+ public function all() {
15
+ $aVersions = array_filter( array_keys( $this->allVersionsUrls() ) );
16
+ usort( $aVersions, 'version_compare' );
17
+ return $aVersions;
18
+ }
19
+
20
+ /**
21
+ * @return string[]
22
+ */
23
+ public function allVersionsUrls() {
24
+ try {
25
+ $aVersions = ( new Api() )
26
+ ->setWorkingSlug( $this->getWorkingSlug() )
27
+ ->getInfo()
28
+ ->versions;
29
+ }
30
+ catch ( \Exception $oE ) {
31
+ $aVersions = [];
32
+ }
33
+ return $aVersions;
34
+ }
35
+
36
+ /**
37
+ * @return string
38
+ * @throws \Exception
39
+ */
40
+ public function latest() {
41
+ return ( new Api() )
42
+ ->setWorkingSlug( $this->getWorkingSlug() )
43
+ ->getInfo()
44
+ ->version;
45
+ }
46
+
47
+ /**
48
+ * @param string $sVersion
49
+ * @param bool $bVerifyUrl
50
+ * @return bool
51
+ */
52
+ public function exists( $sVersion, $bVerifyUrl = false ) {
53
+ $bExists = in_array( $sVersion, $this->all() );
54
+ if ( $bExists && $bVerifyUrl ) {
55
+ try {
56
+ ( new HttpUtil() )->checkUrl( Repo::GetUrlForThemeVersion( $this->getWorkingSlug(), $sVersion ) );
57
+ }
58
+ catch ( \Exception $oE ) {
59
+ $bExists = false;
60
+ };
61
+ }
62
+ return $bExists;
63
+ }
64
+ }
src/processors/loginprotect_intent.php CHANGED
@@ -152,7 +152,6 @@ class ICWP_WPSF_Processor_LoginProtect_Intent extends Shield\Modules\BaseShield\
152
  $sFlash = __( 'Success', 'wp-simple-firewall' ).'! '.__( 'Thank you for authenticating your login.', 'wp-simple-firewall' );
153
  if ( $oFO->isEnabledBackupCodes() ) {
154
  $sFlash .= ' '.__( 'If you used your Backup Code, you will need to reset it.', 'wp-simple-firewall' ); //TODO::
155
- // .' '.sprintf( '<a href="%s">%s</a>', $oWpUsers->getAdminUrl_ProfileEdit(), _wpsf__( 'Go' ) );
156
  }
157
 
158
  $this->getCon()->fireEvent( '2fa_success' );
152
  $sFlash = __( 'Success', 'wp-simple-firewall' ).'! '.__( 'Thank you for authenticating your login.', 'wp-simple-firewall' );
153
  if ( $oFO->isEnabledBackupCodes() ) {
154
  $sFlash .= ' '.__( 'If you used your Backup Code, you will need to reset it.', 'wp-simple-firewall' ); //TODO::
 
155
  }
156
 
157
  $this->getCon()->fireEvent( '2fa_success' );