diff --git a/update/.editorconfig b/update/.editorconfig deleted file mode 100644 index 1b51cad..0000000 --- a/update/.editorconfig +++ /dev/null @@ -1,15 +0,0 @@ -[*] -charset=utf-8 -end_of_line=lf -insert_final_newline=false -indent_style=tab -tab_width=4 - -[{phpunit.xml.dist,*.jhm,*.xslt,*.xul,*.rng,*.xsl,*.xsd,*.ant,*.tld,*.fxml,*.jrxml,*.xml,*.jnlp,*.wsdl}] -indent_style=space -indent_size=4 - -[*.svg] -indent_style=space -indent_size=4 - diff --git a/update/.gitattributes b/update/.gitattributes deleted file mode 100644 index ba74e78..0000000 --- a/update/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -/build export-ignore diff --git a/update/.gitignore b/update/.gitignore deleted file mode 100644 index 7126070..0000000 --- a/update/.gitignore +++ /dev/null @@ -1,40 +0,0 @@ -# Created by .ignore support plugin (hsz.mobi) -### JetBrains template -# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider -# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 - -# The entire IDEA/PhpStorm directory -.idea/ - -# CMake -cmake-build-*/ - -# Mongo Explorer plugin -.idea/**/mongoSettings.xml - -# File-based project format -*.iws - -# IntelliJ -out/ - -# mpeltonen/sbt-idea plugin -.idea_modules/ - -# JIRA plugin -atlassian-ide-plugin.xml - -# Cursive Clojure plugin -.idea/replstate.xml - -# Crashlytics plugin (for Android Studio and IntelliJ) -com_crashlytics_export_strings.xml -crashlytics.properties -crashlytics-build.properties -fabric.properties - -# Editor-based Rest Client -.idea/httpRequests - -# Android studio 3.1+ serialized cache file -.idea/caches/build_file_checksums.ser diff --git a/update/Puc/v5/PucFactory.php b/update/Puc/v5/PucFactory.php index a2ec2d2..0bc62ce 100644 --- a/update/Puc/v5/PucFactory.php +++ b/update/Puc/v5/PucFactory.php @@ -4,7 +4,7 @@ if ( !class_exists(PucFactory::class, false) ): - class PucFactory extends \YahnisElsts\PluginUpdateChecker\v5p3\PucFactory { + class PucFactory extends \YahnisElsts\PluginUpdateChecker\v5p4\PucFactory { } endif; diff --git a/update/Puc/v5p3/Autoloader.php b/update/Puc/v5p4/Autoloader.php similarity index 98% rename from update/Puc/v5p3/Autoloader.php rename to update/Puc/v5p4/Autoloader.php index 5074ab2..5a98133 100644 --- a/update/Puc/v5p3/Autoloader.php +++ b/update/Puc/v5p4/Autoloader.php @@ -1,6 +1,6 @@ removeHooks(); + $this->updateChecker->removeHooks(); + } + } + /** * Runs upon the WP action upgrader_process_complete. * @@ -108,16 +125,6 @@ public function upgraderProcessComplete( /** @noinspection PhpUnusedParameterInspection */ $upgrader, $upgradeInfo ) { - //Cancel all further actions if the current version of PUC has been deleted or overwritten - //by a different version during the upgrade. If we try to do anything more in that situation, - //we could trigger a fatal error by trying to autoload a deleted class. - clearstatcache(); - if ( !file_exists(__FILE__) ) { - $this->removeHooks(); - $this->updateChecker->removeHooks(); - return; - } - //Sanity check and limitation to relevant types. if ( !is_array($upgradeInfo) || !isset($upgradeInfo['type'], $upgradeInfo['action']) @@ -180,6 +187,21 @@ public function maybeCheckForUpdates() { $state = $this->updateChecker->getUpdateState(); $shouldCheck = ($state->timeSinceLastCheck() >= $this->getEffectiveCheckPeriod()); + if ( $shouldCheck ) { + //Sanity check: Do not proceed if one of the critical classes is missing. + //That can happen - theoretically and extremely rarely - if maybeCheckForUpdates() + //is called before the old version of our plugin has been fully deleted, or + //called from an independent AJAX request during deletion. + if ( !( + class_exists(Utils::class) + && class_exists(Metadata::class) + && class_exists(Plugin\Update::class) + && class_exists(Theme\Update::class) + ) ) { + return; + } + } + //Let plugin authors substitute their own algorithm. $shouldCheck = apply_filters( $this->updateChecker->getUniqueName('check_now'), diff --git a/update/Puc/v5p3/StateStore.php b/update/Puc/v5p4/StateStore.php similarity index 93% rename from update/Puc/v5p3/StateStore.php rename to update/Puc/v5p4/StateStore.php index f182787..3828c1c 100644 --- a/update/Puc/v5p3/StateStore.php +++ b/update/Puc/v5p4/StateStore.php @@ -1,5 +1,5 @@ optionName, null); - if ( !is_object($state) ) { + if ( + !is_object($state) + //Sanity check: If the Utils class is missing, the plugin is probably in the process + //of being deleted (e.g. the old version gets deleted during an update). + || !class_exists(Utils::class) + ) { $this->lastCheck = 0; $this->checkedVersion = ''; $this->update = null; diff --git a/update/Puc/v5p3/Theme/Package.php b/update/Puc/v5p4/Theme/Package.php similarity index 93% rename from update/Puc/v5p3/Theme/Package.php rename to update/Puc/v5p4/Theme/Package.php index 8a83f66..0b20702 100644 --- a/update/Puc/v5p3/Theme/Package.php +++ b/update/Puc/v5p4/Theme/Package.php @@ -1,7 +1,7 @@ debugMode = (bool)(constant('WP_DEBUG')); $this->metadataUrl = $metadataUrl; @@ -91,6 +105,10 @@ public function __construct($metadataUrl, $directoryName, $slug = null, $checkPe } } + if ( empty($this->translationType) ) { + $this->translationType = $this->componentType; + } + $this->package = $this->createInstalledPackage(); $this->scheduler = $this->createScheduler($checkPeriod); $this->upgraderStatus = new UpgraderStatus(); @@ -103,6 +121,10 @@ public function __construct($metadataUrl, $directoryName, $slug = null, $checkPe } $this->installHooks(); + + if ( ($this->wpCliCheckTrigger === null) && defined('WP_CLI') ) { + $this->wpCliCheckTrigger = new WpCliCheckTrigger($this->componentType, $this->scheduler); + } } /** diff --git a/update/Puc/v5p3/UpgraderStatus.php b/update/Puc/v5p4/UpgraderStatus.php similarity index 99% rename from update/Puc/v5p3/UpgraderStatus.php rename to update/Puc/v5p4/UpgraderStatus.php index 81b1f4c..e8340fd 100644 --- a/update/Puc/v5p3/UpgraderStatus.php +++ b/update/Puc/v5p4/UpgraderStatus.php @@ -1,5 +1,5 @@ componentType = $componentType; + $this->scheduler = $scheduler; + + if ( !defined('WP_CLI') || !class_exists(WP_CLI::class, false) ) { + return; //Nothing to do if WP-CLI is not available. + } + + /* + * We can't hook directly into wp_update_plugins(), but we can hook into the WP-CLI + * commands that call it. We'll use the "before_invoke:xyz" hook to trigger update checks. + */ + foreach ($this->getRelevantCommands() as $command) { + WP_CLI::add_hook('before_invoke:' . $command, [$this, 'triggerUpdateCheckOnce']); + } + } + + private function getRelevantCommands() { + $result = []; + foreach (['status', 'list', 'update'] as $subcommand) { + $result[] = $this->componentType . ' ' . $subcommand; + } + return $result; + } + + /** + * Trigger a potential update check once. + * + * @param mixed $input + * @return mixed The input value, unchanged. + * @internal This method is public so that it can be used as a WP-CLI hook callback. + * It should not be called directly. + * + */ + public function triggerUpdateCheckOnce($input = null) { + if ( $this->wasCheckTriggered ) { + return $input; + } + + $this->wasCheckTriggered = true; + $this->scheduler->maybeCheckForUpdates(); + + return $input; + } +} \ No newline at end of file diff --git a/update/README.md b/update/README.md index 1af16f0..4c1c197 100644 --- a/update/README.md +++ b/update/README.md @@ -252,8 +252,8 @@ BitBucket doesn't have an equivalent to GitHub's releases, so the process is sli Alternatively, if you're using a self-hosted GitLab instance, initialize the update checker like this: ```php - use YahnisElsts\PluginUpdateChecker\v5p3\Vcs\PluginUpdateChecker; - use YahnisElsts\PluginUpdateChecker\v5p3\Vcs\GitLabApi; + use YahnisElsts\PluginUpdateChecker\v5p4\Vcs\PluginUpdateChecker; + use YahnisElsts\PluginUpdateChecker\v5p4\Vcs\GitLabApi; $myUpdateChecker = new PluginUpdateChecker( new GitLabApi('https://myserver.com/user-name/repo-name/'), @@ -264,8 +264,8 @@ BitBucket doesn't have an equivalent to GitHub's releases, so the process is sli ``` If you're using a self-hosted GitLab instance and [subgroups or nested groups](https://docs.gitlab.com/ce/user/group/subgroups/index.html), you have to tell the update checker which parts of the URL are subgroups: ```php - use YahnisElsts\PluginUpdateChecker\v5p3\Vcs\PluginUpdateChecker; - use YahnisElsts\PluginUpdateChecker\v5p3\Vcs\GitLabApi; + use YahnisElsts\PluginUpdateChecker\v5p4\Vcs\PluginUpdateChecker; + use YahnisElsts\PluginUpdateChecker\v5p4\Vcs\GitLabApi; $myUpdateChecker = new PluginUpdateChecker( new GitLabApi( @@ -347,14 +347,14 @@ Other classes have also been renamed, usually by simply removing the `Puc_vXpY_` | Old class name | New class name | |-------------------------------------|----------------------------------------------------------------| | `Puc_v4_Factory` | `YahnisElsts\PluginUpdateChecker\v5\PucFactory` | -| `Puc_v4p13_Factory` | `YahnisElsts\PluginUpdateChecker\v5p3\PucFactory` | -| `Puc_v4p13_Plugin_UpdateChecker` | `YahnisElsts\PluginUpdateChecker\v5p3\Plugin\UpdateChecker` | -| `Puc_v4p13_Theme_UpdateChecker` | `YahnisElsts\PluginUpdateChecker\v5p3\Theme\UpdateChecker` | -| `Puc_v4p13_Vcs_PluginUpdateChecker` | `YahnisElsts\PluginUpdateChecker\v5p3\Vcs\PluginUpdateChecker` | -| `Puc_v4p13_Vcs_ThemeUpdateChecker` | `YahnisElsts\PluginUpdateChecker\v5p3\Vcs\ThemeUpdateChecker` | -| `Puc_v4p13_Vcs_GitHubApi` | `YahnisElsts\PluginUpdateChecker\v5p3\Vcs\GitHubApi` | -| `Puc_v4p13_Vcs_GitLabApi` | `YahnisElsts\PluginUpdateChecker\v5p3\Vcs\GitLabApi` | -| `Puc_v4p13_Vcs_BitBucketApi` | `YahnisElsts\PluginUpdateChecker\v5p3\Vcs\BitBucketApi` | +| `Puc_v4p13_Factory` | `YahnisElsts\PluginUpdateChecker\v5p4\PucFactory` | +| `Puc_v4p13_Plugin_UpdateChecker` | `YahnisElsts\PluginUpdateChecker\v5p4\Plugin\UpdateChecker` | +| `Puc_v4p13_Theme_UpdateChecker` | `YahnisElsts\PluginUpdateChecker\v5p4\Theme\UpdateChecker` | +| `Puc_v4p13_Vcs_PluginUpdateChecker` | `YahnisElsts\PluginUpdateChecker\v5p4\Vcs\PluginUpdateChecker` | +| `Puc_v4p13_Vcs_ThemeUpdateChecker` | `YahnisElsts\PluginUpdateChecker\v5p4\Vcs\ThemeUpdateChecker` | +| `Puc_v4p13_Vcs_GitHubApi` | `YahnisElsts\PluginUpdateChecker\v5p4\Vcs\GitHubApi` | +| `Puc_v4p13_Vcs_GitLabApi` | `YahnisElsts\PluginUpdateChecker\v5p4\Vcs\GitLabApi` | +| `Puc_v4p13_Vcs_BitBucketApi` | `YahnisElsts\PluginUpdateChecker\v5p4\Vcs\BitBucketApi` | License Management ------------------ diff --git a/update/composer.json b/update/composer.json index 27b65b0..f7af7eb 100644 --- a/update/composer.json +++ b/update/composer.json @@ -18,6 +18,6 @@ "ext-json": "*" }, "autoload": { - "files": ["load-v5p3.php"] + "files": ["load-v5p4.php"] } } diff --git a/update/examples/plugin.json b/update/examples/plugin.json deleted file mode 100644 index 946b730..0000000 --- a/update/examples/plugin.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "name": "My Example Plugin", - "version": "2.0", - "download_url": "http://example.com/updates/example-plugin.zip", - - "homepage": "http://example.com/", - "requires": "4.5", - "tested": "4.8", - "last_updated": "2017-01-01 16:17:00", - "upgrade_notice": "Here's why you should upgrade...", - - "author": "Janis Elsts", - "author_homepage": "http://example.com/", - - "sections": { - "description": "(Required) Plugin description. Basic HTML can be used in all sections.", - "installation": "(Recommended) Installation instructions.", - "changelog": "(Recommended) Changelog.
This section will be displayed by default when the user clicks 'View version x.y.z details'.
", - "custom_section": "This is a custom section labeled 'Custom Section'." - }, - - "icons" : { - "1x" : "http://w-shadow.com/files/external-update-example/assets/icon-128x128.png", - "2x" : "http://w-shadow.com/files/external-update-example/assets/icon-256x256.png" - }, - - "banners": { - "low": "http://w-shadow.com/files/external-update-example/assets/banner-772x250.png", - "high": "http://w-shadow.com/files/external-update-example/assets/banner-1544x500.png" - }, - - "translations": [ - { - "language": "fr_FR", - "version": "4.0", - "updated": "2016-04-22 23:22:42", - "package": "http://example.com/updates/translations/french-language-pack.zip" - }, - { - "language": "de_DE", - "version": "5.0", - "updated": "2016-04-22 23:22:42", - "package": "http://example.com/updates/translations/german-language-pack.zip" - } - ], - - "rating": 90, - "num_ratings": 123, - - "downloaded": 1234, - "active_installs": 12345 -} \ No newline at end of file diff --git a/update/examples/theme.json b/update/examples/theme.json deleted file mode 100644 index 0e08072..0000000 --- a/update/examples/theme.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "version": "2.0", - "details_url": "http://example.com/version-2.0-details.html", - "download_url": "http://example.com/example-theme-2.0.zip" -} \ No newline at end of file diff --git a/update/languages/plugin-update-checker.pot b/update/languages/plugin-update-checker.pot index 4985307..5b6319c 100644 --- a/update/languages/plugin-update-checker.pot +++ b/update/languages/plugin-update-checker.pot @@ -17,33 +17,33 @@ msgstr "" "X-Poedit-KeywordsList: __;_e;_x:1,2c;_x\n" "X-Poedit-SearchPath-0: .\n" -#: Puc/v5p3/Plugin/Ui.php:128 +#: Puc/v5p4/Plugin/Ui.php:128 msgid "Check for updates" msgstr "" -#: Puc/v5p3/Plugin/Ui.php:214 +#: Puc/v5p4/Plugin/Ui.php:214 #, php-format msgctxt "the plugin title" msgid "The %s plugin is up to date." msgstr "" -#: Puc/v5p3/Plugin/Ui.php:216 +#: Puc/v5p4/Plugin/Ui.php:216 #, php-format msgctxt "the plugin title" msgid "A new version of the %s plugin is available." msgstr "" -#: Puc/v5p3/Plugin/Ui.php:218 +#: Puc/v5p4/Plugin/Ui.php:218 #, php-format msgctxt "the plugin title" msgid "Could not determine if updates are available for %s." msgstr "" -#: Puc/v5p3/Plugin/Ui.php:224 +#: Puc/v5p4/Plugin/Ui.php:224 #, php-format msgid "Unknown update checker status \"%s\"" msgstr "" -#: Puc/v5p3/Vcs/PluginUpdateChecker.php:100 +#: Puc/v5p4/Vcs/PluginUpdateChecker.php:100 msgid "There is no changelog available." msgstr "" diff --git a/update/load-v5p3.php b/update/load-v5p4.php similarity index 80% rename from update/load-v5p3.php rename to update/load-v5p4.php index 1de3d58..2cd9580 100644 --- a/update/load-v5p3.php +++ b/update/load-v5p4.php @@ -1,14 +1,14 @@ $pucVersionedClass ) { - MajorFactory::addVersion($pucGeneralClass, $pucVersionedClass, '5.3'); + MajorFactory::addVersion($pucGeneralClass, $pucVersionedClass, '5.4'); //Also add it to the minor-version factory in case the major-version factory //was already defined by another, older version of the update checker. - MinorFactory::addVersion($pucGeneralClass, $pucVersionedClass, '5.3'); + MinorFactory::addVersion($pucGeneralClass, $pucVersionedClass, '5.4'); } diff --git a/update/phpcs.xml b/update/phpcs.xml deleted file mode 100644 index e8260b9..0000000 --- a/update/phpcs.xml +++ /dev/null @@ -1,21 +0,0 @@ - -