Commit Graph

587 Commits

Author SHA1 Message Date
Yahnis Elsts 155eff7964 Bump version number to 2.2 2015-07-28 13:43:46 +03:00
Yahnis Elsts 70011dbb52 Improve compatibility with plugins that use custom upgrader skins. 2015-07-28 11:55:44 +03:00
Yahnis Elsts 81bbb6775b Fix automatic directory renaming not working with inline/AJAX updates. 2015-06-28 01:30:03 +03:00
Yahnis Elsts fd5feddfef Bump all version numbers to 2.1 2015-06-26 16:37:25 +03:00
Yahnis Elsts f4b013c77a Add an optional "active_installs" field. This should be an positive integer that indicates how many sites use your plugin. WordPress will show it in the "view version 1.2.3 details" pop-up. For example, if you set it to 10000, users will see "Active Installs: 10,000+".
Note that wordpress.org itself reports approximate install stats - e.g. 10000 instead of 11450. It's up to you whether you want to do the same, show the exact number of installs, or omit this field entirely.
2015-06-26 16:32:46 +03:00
Yahnis Elsts 317a45dc45 Prevent class_exists() from calling autoloaders.
The update checker uses class_exists in several ways:

- As a guard clause around `class Whatever` definitions. This ensures we don't try to define a class that has already been loaded by a different plugin. In this case, autoloading is not necessary because we already know how to load the class. Also, we *want to* load our version of that class if possible - the version that gets loaded by somebody else's autoloader might be different and incompatible.
- As a guard clause before `require` statements that include a class. This is conceptually the same as the previous example. 
- To enable optional features if Debug Bar is active. The latest compatible version of Debug Bar doesn't use autoloading, so it would again be unnecessary in this case.
2015-06-17 12:30:05 +03:00
Yahnis Elsts acb8476be2 Validate the directory structure of the update
As noted in the docs, the update ZIP file needs to have a specific directory structure. All plugin files should be inside a directory named "plugin-slug-here" and not at the root of the ZIP file. The update checker can fix the directory name if necessary, but it can't deal with the files being at the wrong level - at least not yet.

The reason this is necessary is that WordPress decides which directory to copy to /wp-content/plugins based on the contents of the update. If the ZIP contains just a single directory, WP will copy that directory. In any other case, it will copy the entire working directory where it extracted the ZIP file. This directory usually has a name like "zip-file-name.tmp". As a result, the directory name of the update won't match the directory where the old version was installed, which means WordPress will fail to reactivate the plugin.

The update checker can't rename the working directory because that would prevent WP from cleaning up temporary files in that directory (that part of the core is not hook-able and doesn't check for errors).

A potential solution would be to automatically create the requisite subdirectory and copy all update files to it. However, that would be a bit too much "magic", as well as another edge case to worry about and test. It seems better to notify the developer and let them fix their mistake.
2015-02-22 12:03:27 +02:00
Yahnis Elsts 323e80fa19 Fix fenced code blocks in lists 2015-02-10 12:00:06 +02:00
Yahnis Elsts d8a3d26b1c Indented code blocks in Markdown, arrgh. 2015-02-10 11:54:53 +02:00
Yahnis Elsts 03dd38fd71 Add support for updating plugins hosted on GitHub.
- Added experimental GitHub support. The new PucGitHubChecker subclass can check a GitHub repository for plugin updates. Depending on configuration, it will use either the latest release, the latest tag, or the specified branch. It can also automagically extract version details (description, changelog, etc) from a number of different locations - release names, plugin headers, readme.txt, changelog.md and more.
- The "slug" field of the metadata file is no longer used. The update checker will now use the slug passed to the class constructor, or generate a slug based on the plugin file name.
- Other minor changes to slug handling.
- Version bump to 2.0.
2015-02-10 11:46:46 +02:00
Yahnis Elsts 037ab7d2a4 Automatically rename update to match existing installation
Preamble:
When WordPress installs a plugin update, it assumes that the update ZIP will contain a directory that has the same name as the currently installed plugin. For example, if the plugin is installed in `/wp-content/plugins/awesome-plugin/`, WP expects that there'll be an "awesome-plugin" directory in the ZIP archive. If the update doesn't contain that directory, the installation process will either fail with a cryptic error message or produce unexpected results.
   
 The problem:
  - Some developers are either unaware of the above, or unable to format their updates accordingly. For example, they might be using GitHub to serve updates. GitHub typically names the directory in the release/branch downloads "repo-branchname" or "repo-tag-hash". WP needs it to be just "repo".
- Users can rename the plugin directory. It's very rare, but I've seen it happen.
 
Solution:
The `upgrader_source_selection` filter lets you specify the directory that will be used as the "new" version. Using it is a bit tricky because WordPress doesn't actually tell you *which* plugin or theme it's currently upgrading, but with some analysis and heuristics it's possible to figure it out (most of the time). Then you can rename the directory from the update package to match the existing plugin directory.
2015-02-06 18:01:00 +02:00
Yahnis Elsts a0ee8ca0a7 Added support for plugin banners
Usage: 
Add a new key named "banners" to the metadata file. It should be a JSON object with two string properties: "low" and "high". "low" must be a fully qualified URL pointing to a 772x250 image (PNG or JPG). "high" must point to a 1544x500 image. Only one of "low" or "high" is required. 

Example:
{
    "banners" : {
        "low" : "//example.com/assets/banner-772x250.png",
        "high" : "//example.com/assets/banner-1544x500.png"
    }
}

Banners are entirely optional.
2015-02-05 17:28:16 +02:00
Yahnis Elsts b8102edc06 Minor: Operator spacing and naming consistency
By convention, there should be a space before and after a string concatenation operator.
Also, both submit buttons should use a dash to separate the static and variable parts of the element ID.
2015-01-14 16:51:26 +02:00
Yahnis Elsts 8e7fb4a373 Merge pull request #26 from jrfnl/Less-HTML-errors
Prevent some html errors for duplicate ids
2015-01-14 16:47:08 +02:00
jrfnl 07366fff49 Prevent some html errors for duplicate ids 2015-01-14 12:51:12 +01:00
Yahnis Elsts 14466ae1bc Update copyright header 2014-12-17 12:38:48 +02:00
Yahnis Elsts a4d023e0c3 Change license to MIT/Expat 2014-12-17 12:22:29 +02:00
Yahnis Elsts 3f75005b3b Check for updates more often when the user visits the "Plugins" page, updates/installs/activates anything, or does a bulk update. This is to be more consistent with how/when WordPress checks updates in wp_update_plugins. 2014-12-09 15:09:49 +02:00
Yahnis Elsts dac23e9601 Merge pull request #23 from doublesharp/patch-1
Fix version number in library header
2014-10-27 14:00:30 +02:00
doublesharp 3564a4b045 Update plugin-update-checker.php
Fixed plugin version in header to 1.6
2014-10-26 21:10:15 -07:00
Yahnis Elsts 954aa4a192 Fixed automatic background updates not working for plugins that use this library.
Background (i.e. unattended) plugin updates require an additional $update->plugin field to be set to plugin file name relative to the /wp-content/plugins directory. Fixed by adding a $filename property to the PluginInfo and PluginUpdate classes and updating toWpFormat() to return it as "plugin". Apparently WordPress update API introduced the field a couple of minor versions back, but I didn't notice because it's used *only* by the background updater and ignored otherwise. 

I named the internal variable "filename" instead of "plugin" because "plugin" is very vague. It doesn't really tell you if the variable contains a plugin slug, plugin name, the full plugin filename, a partial filename, basename or something else. "filename" is a bit less ambiguous, though not perfect.

Bumped version to 1.6.
2014-10-24 15:53:16 +03:00
Yahnis Elsts dbe109557b Add a Composer manifest 2014-09-10 18:41:18 +03:00
Yahnis Elsts c43301056e Minor: Fix typo. 2014-05-17 11:29:33 +03:00
Yahnis Elsts 102a7b2e05 Added limited support for mu-plugins.
You can explicitly specify the MU-plugin basename (relative to "/wp-content/mu-plugins") as the last argument to PucFactory:buildUpdateChecker(). If you do, the "Check for updates" link and update notifications will show up in "Plugins -> Installed -> Must-Use". However, automatic update installation still won't  work because WordPress does not support it for mu-plugins.
2014-03-10 20:49:35 +02:00
Yahnis Elsts 8f1b7006ba Merge pull request #17 from YahnisElsts/pull_15
Pull 15
2014-02-15 13:37:19 +02:00
Yahnis Elsts b40ad4eb0b Replace isset() with property_exists() 2014-02-14 17:12:43 +02:00
David Anderson ebdf86863a Prevent PHP warnings
Edit with both changes, and braces, as requested.

Apologies for my limited understanding of Git + Github.
2014-02-14 09:54:09 +00:00
Yahnis Elsts 88ddc53b3b Minor: Update file header with the current year and the correct version number. 2014-02-05 14:40:30 -08:00
Yahnis Elsts 6d0a1ef2e5 Merge pull request #11 from DavidAnderson684/patch-1
Allow the consumer to receive customised information from the server.
2014-02-04 03:39:45 -08:00
David Anderson c873f4c53d Add a filter to allow the consumer to receive customised information from the server
I have a need to receive extra information back from the server. In particular, I want to receive information that says "updates entitlement soon expires" or "updates entitlement already expired".

Currently, the functions in the class PluginUpdate_1_3 strip out anything not in the private $fields.

This change adds a filter to allow the consumer to retain any extra fields they wish.
2014-01-14 19:28:32 +00:00
Yahnis Elsts 6d4372feaf Add a "puc_check_now-$slug" filter that lets plugin authors to override the automatic check behaviour. 2013-12-03 02:23:48 -08:00
Yahnis Elsts 89da7ab52d Enforce update frequency settings ($checkPeriod) even when triggered by a cron event.
The WordPress cron implementation does not guarantee that a cron hook will only be run once, or run exactly on schedule. For example, it's possible for an event to be triggered two or three times in quick succession due to race conditions. If we check for updates each time our hook is run, we could end up sending redundant update requests that waste bandwidth and server resources.

Instead, make sure at least $checkPeriod hours have elapsed since the last check before checking again. Allow for a small fuzz-factor (currently 20 minutes) to account for the inherent inaccuracy of WP cron.
2013-12-03 01:40:44 -08:00
Yahnis Elsts d921ed91e8 Added an option to check updates less frequently if there's an update already available.
This feature is disabled by default. Turn it on by setting `$checker->throttleRedundantChecks` to `true` and use `$checker->throttledCheckPeriod` to set the alternate check period (default = every 72 hours).
2013-11-29 04:13:32 -08:00
Yahnis Elsts 3adbcdeee9 Slightly improved performance by reading the current version number directly from the plugin file instead of asking WordPress to fetch all installed plugins. The version number is cached for the current page load.
Caution: There might be some issues in how/when the cache is cleared. It looks fine in theory, but I may have missed something (bulk upgrades? Multisite side-effects?).

Also removed two unused parameters from addCheckForUpdatesLink(). We can always add them back later if needed.

Version bump: 1.3.2
2013-10-29 03:16:02 -07:00
Yahnis Elsts c3a8325c2d Check for updates once per minute when the user visits Dashboard -> Updates.
This was suggested in #8 as a way to make the custom update checker more consistent with how WP handles plugin updates. Arguably, visiting "Dashboard -> Updates" means that the user wants to check for updates, so it's okay to ignore the configured check interval in this case.

You can still disable automatic checks by setting $checkPeriod to 0, which will also disable this additional check.
2013-09-27 04:24:14 -07:00
Yahnis Elsts 2edd17e0a5 Fix a conflict with WordPress' "quick edit" feature.
Explanation:
WordPress includes a "quick edit" function that lets users edit certain post properties (title, categories, etc) from the "All Posts" list. WP calculates the width (colspan attribute) of the inline editor based on the number of <th>'s in the header of the first .widefat table on the page. When PUC and Debug Bar are both active, that first table happens to be the debug info table in our Debug Bar panel. This table does not have a <thead>. As a result, WordPress sets the colspan to zero, making the inline editor unusable.

Fixed by removing the "widefat" class from our debug info tables and adding a bunch of new CSS to emulate WordPress table style.
2013-09-27 03:08:51 -07:00
Yahnis Elsts 9f7c8f74ba Fix: Display the Debug Bar panel even if the update checker is loaded during or after the "plugins_loaded" action.
Bumped version to 1.3.1.
2013-07-18 02:34:54 -07:00
Yahnis Elsts f757517434 Use default cron schedules when possible.
This makes the library more resilient and less likely to break due to cron-related bugs in other plugins. See this commit for an analysis of one such bug: YahnisElsts/plugin-update-checker@5aee0d7b8b
2013-06-26 06:07:48 -07:00
Yahnis Elsts 5aee0d7b8b Add a workaround for a bug in BackupBuddy that would cause this library to run a new update check every few seconds. This affects BackupBuddy 3.2.0.2 and possibly multiple other versions.
Analysis:
- PluginUpdateChecker creates a custom cron schedule by using the cron_schedules filter. This schedule is used to run periodic update checks.
- BackupBuddy also creates a number of custom schedules using the same filter. However, its filter callback throws away any schedules defined by other filters/plugins and re-initializes $schedules with an empty array().
- As a result, if the filter that was added by BackupBuddy runs *after* the filter added by PluginUpdateChecker, our custom schedule is destroyed.
- When WordPress tries to re-schedule our event after a successful Cron run, it discovers that the required schedule no longer exists, and fails. On the next page load, the library detects that the event is not scheduled and schedules it again. Hence infinite loop.
- Fixed by moving our cron_schedules filter to a later priority.

Notes:
This is the *second* time I have to add a workaround for some arrogant oversight perpetrated by BackupBuddy developers. (The first one was the "plugins_api" thing, IIRC).
2013-02-22 09:40:15 -08:00
Yahnis Elsts 1fa27700a8 Fix: Make the "Check for updates" link work properly in Multisite.
Essentially, the library just switches to using /wp-admin/network/plugins.php instead of /wp-admin/plugins.php as necessary. Also, the "all_admin_notices" action runs in both normal and Network admin, so it's a better choice for displaying the update check result than either "admin_notices" or "network_admin_notices".
2013-01-07 03:04:16 -08:00
Yahnis Elsts e2ddd78cce Prevent the update checker from throwing a warning if the update state is not an object, yet is non-empty.
Technically it shouldn't be possible for this to happen, but at least one user has reported that it does.
2012-11-21 11:16:05 -08:00
Yahnis Elsts 93601c897d Fix the update check status message showing up twice when two plugins are using the library.
Pass the plugin slug in a separate "puc_slug" query parameter when doing a manual update check. This way displayManualCheckResult() can verify that the current "puc_update_check_result" value applies to the right plugin.
2012-11-08 02:33:29 -08:00
Yahnis Elsts 0132961c42 Add a readme for GitHub. This is just a stub; people who want to use the library should read the relevant blog post. 2012-11-06 00:42:20 -08:00
Yahnis Elsts bbd128d0e1 Add a factory class that should be used when creating instances of PluginUpdateChecker.
If several active plugins include the update checker library we might end up with a bunch of different versions being loaded. In the previous implementation, whichever version was loaded first would take precedence. This is obviously a problem if an old version gets loaded and one of the plugins relies on features that are only available in the latest version. 
   
The best way to fix this would be to delay library loading until all plugins have been loaded, then only load the latest available version. Unfortunately this approach would not be backwards-compatible  with previous versions that just load the library right away. Another good way to fix the problem would be to put the entire library in a versioned namespace. Alas, namespaces are only available in PHP 5.3 and WordPress only requires PHP 5.2.
 
 So what I've done is to put the version number in the class name and create a factory that will keep track of available versions and let you instantiate the latest one. Note that internal classes like PluginUpdate and PluginInfo still refer to specific implementations for internal consistency and backwards-compatibility.
2012-11-04 12:40:44 +00:00
Yahnis Elsts a0c1dfa732 Add the update checker class name to the Debug Bar output. Useful when trying to figure out which library version was loaded. 2012-11-04 11:46:55 +00:00
Yahnis Elsts 0c5f9863f0 Ensure the internal WP update structure is initialized before trying to modify it. For example, it can be `false` if WordPress has just cleared its update cache. 2012-10-31 14:57:14 +00:00
Yahnis Elsts a793bb1906 * get_submit_button() is only available in the WP admin, so make sure it exists before trying to output a button.
* HOUR_IN_SECONDS is only defined in WP 3.5+. Use the literal value instead.
2012-10-31 14:34:24 +00:00
Yahnis Elsts dd309a7310 Rename debug-bar-support.php to debug-bar-plugin.php 2012-10-29 09:13:23 +00:00
Yahnis Elsts 4a24752fce Encode special HTML characters when dumping plugin or update info to the debug bar. 2012-10-27 12:39:30 +00:00
Yahnis Elsts ae084bd3be Actually, lets prefix our custom Debug Bar IDs with "puc" to be completely sure we'll avoid name collisions. 2012-10-27 12:30:35 +00:00