diff --git a/Puc/v4p13/Vcs/Api.php b/Puc/v4p13/Vcs/Api.php index 1e28b65..018ded4 100644 --- a/Puc/v4p13/Vcs/Api.php +++ b/Puc/v4p13/Vcs/Api.php @@ -2,6 +2,11 @@ if ( !class_exists('Puc_v4p13_Vcs_Api') ): abstract class Puc_v4p13_Vcs_Api { + const STRATEGY_LATEST_RELEASE = 'latest_release'; + const STRATEGY_LATEST_TAG = 'latest_tag'; + const STRATEGY_STABLE_TAG = 'stable_tag'; + const STRATEGY_BRANCH = 'branch'; + protected $tagNameProperty = 'name'; protected $slug = ''; @@ -21,6 +26,12 @@ if ( !class_exists('Puc_v4p13_Vcs_Api') ): */ protected $httpFilterName = ''; + /** + * @var string The filter applied to the list of update detection strategies that + * are used to find the latest version. + */ + protected $strategyFilterName = ''; + /** * @var string|null */ @@ -45,12 +56,41 @@ if ( !class_exists('Puc_v4p13_Vcs_Api') ): } /** - * Figure out which reference (i.e tag or branch) contains the latest version. + * Figure out which reference (i.e. tag or branch) contains the latest version. * * @param string $configBranch Start looking in this branch. * @return null|Puc_v4p13_Vcs_Reference */ - abstract public function chooseReference($configBranch); + public function chooseReference($configBranch) { + $strategies = $this->getUpdateDetectionStrategies($configBranch); + + if ( !empty($this->strategyFilterName) ) { + $strategies = apply_filters( + $this->strategyFilterName, + $strategies, + $this->slug + ); + } + + foreach ($strategies as $strategy) { + $reference = call_user_func($strategy); + if ( !empty($reference) ) { + return $reference; + } + } + return null; + } + + /** + * Get an ordered list of strategies that can be used to find the latest version. + * + * The update checker will try each strategy in order until one of them + * returns a valid reference. + * + * @param string $configBranch + * @return array Array of callables that return Vcs_Reference objects. + */ + abstract protected function getUpdateDetectionStrategies($configBranch); /** * Get the readme.txt file from the remote repository and parse it @@ -280,6 +320,13 @@ if ( !class_exists('Puc_v4p13_Vcs_Api') ): $this->httpFilterName = $filterName; } + /** + * @param string $filterName + */ + public function setStrategyFilterName($filterName) { + $this->strategyFilterName = $filterName; + } + /** * @param string $directory */ diff --git a/Puc/v4p13/Vcs/BitBucketApi.php b/Puc/v4p13/Vcs/BitBucketApi.php index 1092b40..93f0996 100644 --- a/Puc/v4p13/Vcs/BitBucketApi.php +++ b/Puc/v4p13/Vcs/BitBucketApi.php @@ -29,28 +29,21 @@ if ( !class_exists('Puc_v4p13_Vcs_BitBucketApi', false) ): parent::__construct($repositoryUrl, $credentials); } - /** - * Figure out which reference (i.e tag or branch) contains the latest version. - * - * @param string $configBranch Start looking in this branch. - * @return null|Puc_v4p13_Vcs_Reference - */ - public function chooseReference($configBranch) { - $updateSource = null; + protected function getUpdateDetectionStrategies($configBranch) { + $strategies = array( + self::STRATEGY_STABLE_TAG => function () use ($configBranch) { + return $this->getStableTag($configBranch); + }, + ); - //Check if there's a "Stable tag: 1.2.3" header that points to a valid tag. - $updateSource = $this->getStableTag($configBranch); - - //Look for version-like tags. - if ( !$updateSource && ($configBranch === 'master' || $configBranch === 'main') ) { - $updateSource = $this->getLatestTag(); - } - //If all else fails, use the specified branch itself. - if ( !$updateSource ) { - $updateSource = $this->getBranch($configBranch); + if ( ($configBranch === 'master' || $configBranch === 'main') ) { + $strategies[self::STRATEGY_LATEST_TAG] = array($this, 'getLatestTag'); } - return $updateSource; + $strategies[self::STRATEGY_BRANCH] = function () use ($configBranch) { + return $this->getBranch($configBranch); + }; + return $strategies; } public function getBranch($branchName) { @@ -261,7 +254,7 @@ if ( !class_exists('Puc_v4p13_Vcs_BitBucketApi', false) ): public function signDownloadUrl($url) { //Add authentication data to download URLs. Since OAuth signatures incorporate - //timestamps, we have to do this immediately before inserting the update. Otherwise + //timestamps, we have to do this immediately before inserting the update. Otherwise, //authentication could fail due to a stale timestamp. if ( $this->oauth ) { $url = $this->oauth->sign($url); diff --git a/Puc/v4p13/Vcs/GitHubApi.php b/Puc/v4p13/Vcs/GitHubApi.php index 0fb0b05..ba9ee2b 100644 --- a/Puc/v4p13/Vcs/GitHubApi.php +++ b/Puc/v4p13/Vcs/GitHubApi.php @@ -310,29 +310,22 @@ if ( !class_exists('Puc_v4p13_Vcs_GitHubApi', false) ): add_filter('upgrader_pre_download', array($this, 'addHttpRequestFilter'), 10, 1); //WP 3.7+ } - /** - * Figure out which reference (i.e tag or branch) contains the latest version. - * - * @param string $configBranch Start looking in this branch. - * @return null|Puc_v4p13_Vcs_Reference - */ - public function chooseReference($configBranch) { - $updateSource = null; + protected function getUpdateDetectionStrategies($configBranch) { + $strategies = array(); if ( $configBranch === 'master' ) { //Use the latest release. - $updateSource = $this->getLatestRelease(); - if ( $updateSource === null ) { - //Failing that, use the tag with the highest version number. - $updateSource = $this->getLatestTag(); - } - } - //Alternatively, just use the branch itself. - if ( empty($updateSource) ) { - $updateSource = $this->getBranch($configBranch); + $strategies[self::STRATEGY_LATEST_RELEASE] = array($this, 'getLatestRelease'); + //Failing that, use the tag with the highest version number. + $strategies[self::STRATEGY_LATEST_TAG] = array($this, 'getLatestTag'); } - return $updateSource; + //Alternatively, just use the branch itself. + $strategies[self::STRATEGY_BRANCH] = function() use ($configBranch) { + return $this->getBranch($configBranch); + }; + + return $strategies; } /** diff --git a/Puc/v4p13/Vcs/GitLabApi.php b/Puc/v4p13/Vcs/GitLabApi.php index cd90ec2..cb42797 100644 --- a/Puc/v4p13/Vcs/GitLabApi.php +++ b/Puc/v4p13/Vcs/GitLabApi.php @@ -356,28 +356,19 @@ if ( !class_exists('Puc_v4p13_Vcs_GitLabApi', false) ): throw new LogicException('The ' . __METHOD__ . ' method is not implemented and should not be used.'); } - /** - * Figure out which reference (i.e tag or branch) contains the latest version. - * - * @param string $configBranch Start looking in this branch. - * @return null|Puc_v4p13_Vcs_Reference - */ - public function chooseReference($configBranch) { + protected function getUpdateDetectionStrategies($configBranch) { + $strategies = array(); - if ( $configBranch === 'main' || $configBranch === 'master' ) { - //Use the latest release. - $updateSource = $this->getLatestRelease(); - if ( $updateSource === null ) { - //Failing that, use the tag with the highest version number. - $updateSource = $this->getLatestTag(); - } - } - //Alternatively, just use the branch itself. - if ( empty($updateSource) ) { - $updateSource = $this->getBranch($configBranch); + if ( ($configBranch === 'main') || ($configBranch === 'master') ) { + $strategies[self::STRATEGY_LATEST_RELEASE] = array($this, 'getLatestRelease'); + $strategies[self::STRATEGY_LATEST_TAG] = array($this, 'getLatestTag'); } - return $updateSource; + $strategies[self::STRATEGY_BRANCH] = function() use ($configBranch) { + return $this->getBranch($configBranch); + }; + + return $strategies; } public function setAuthentication($credentials) { diff --git a/Puc/v4p13/Vcs/PluginUpdateChecker.php b/Puc/v4p13/Vcs/PluginUpdateChecker.php index 33d9142..8bdaa7a 100644 --- a/Puc/v4p13/Vcs/PluginUpdateChecker.php +++ b/Puc/v4p13/Vcs/PluginUpdateChecker.php @@ -24,10 +24,11 @@ if ( !class_exists('Puc_v4p13_Vcs_PluginUpdateChecker') ): */ public function __construct($api, $pluginFile, $slug = '', $checkPeriod = 12, $optionName = '', $muPluginFile = '') { $this->api = $api; - $this->api->setHttpFilterName($this->getUniqueName('request_info_options')); parent::__construct($api->getRepositoryUrl(), $pluginFile, $slug, $checkPeriod, $optionName, $muPluginFile); + $this->api->setHttpFilterName($this->getUniqueName('request_info_options')); + $this->api->setStrategyFilterName($this->getUniqueName('vcs_update_detection_strategies')); $this->api->setSlug($this->slug); } diff --git a/Puc/v4p13/Vcs/ThemeUpdateChecker.php b/Puc/v4p13/Vcs/ThemeUpdateChecker.php index c463b8e..07efbe7 100644 --- a/Puc/v4p13/Vcs/ThemeUpdateChecker.php +++ b/Puc/v4p13/Vcs/ThemeUpdateChecker.php @@ -24,10 +24,11 @@ if ( !class_exists('Puc_v4p13_Vcs_ThemeUpdateChecker', false) ): */ public function __construct($api, $stylesheet = null, $customSlug = null, $checkPeriod = 12, $optionName = '') { $this->api = $api; - $this->api->setHttpFilterName($this->getUniqueName('request_update_options')); parent::__construct($api->getRepositoryUrl(), $stylesheet, $customSlug, $checkPeriod, $optionName); + $this->api->setHttpFilterName($this->getUniqueName('request_update_options')); + $this->api->setStrategyFilterName($this->getUniqueName('vcs_update_detection_strategies')); $this->api->setSlug($this->slug); } diff --git a/composer.json b/composer.json index 7f97a49..0b1c37b 100644 --- a/composer.json +++ b/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": ">=5.2.0", + "php": ">=5.4.0", "ext-json": "*" }, "autoload": {