Move most GitHub and BitBucket stuff to a general "VCS checker" class and put service-specific logic in API classes that follow a common interface.
Rationale: Upon further reflection, there's no need to have different theme & plugin checker implementations for each Git hosting service. The overall update detection algorithm stays the same. Only the API and authentication are different.
Not entirely happy with the code duplication in Vcs_PluginUpdateChecker and Vcs_ThemeUpdateChecker. Traits would be one solution, but can't use that in PHP 5.2. There's probably a "good enough" way to achieve the same thing through composition, but I haven't figured it out yet.
For private GH repositories, use setAuthentication('access_token_here') instead of setAccessToken().
We don't need two different implementation for GitHub and BitBucket, they use the same property name. But lets make the property configurable anyway in case other APIs do differ.
Refactor requestUpdate() filtering.
Rename getFilterName to getUniqueName because it's used for more than just filter names.
Added a couple of utility methods.
- Refactor the scheduler so that it can be used in themes.
- Add state storage to the base update checker.
- Move the "allow metadata host" workaround to the base class.
- Rename cron hook from "check_plugin_updates-$slug" to "puc_cron_check_updates-$slug" and "tuc_cron_check_updates-$slug".
The readme.txt format that's used by WordPress is not quite standard Markdown. It includes a couple of features that are not directly supported by popular Markdown parsers. One of those features is parsing "= string =" as "<h4>string</h4>" (the opening "=" must be at the start of the line). Leading whitespace is allowed. This syntax is typically for plugin version numbers in the changelog section.
The problem: the readme parser discards leading whitespace when parsing these headers. This means it can also discard the previous line break character(s). As a result, this markup:
* abc
= 1.2.3 =
* def
Becomes this:
* abc
<h4>1.2.3</h4>
* def
The way that Parsedown handles this markup is to make the H4 a part of the preceding list item. And that's a bug.
Fixed by keeping leading whitespace instead of throwing it away.
Closes#68
While most PUC class names use version number suffixes to avoid conflicts with older versions of the library, the classes responsible for Debug Bar integration did not (until now). This is because those classes are fairly simple and they have stayed mostly unchanged since version 1.0. Mostly, but not completely. For example, the debug bar panel depends on the getCronHookName() function, and that function was recently moved to the new PucScheduler class.
This is a problem because when your site has two plugins using two different versions of this library (e.g. 3.0 and 1.3), you can end up in a situation where PluginUpdateChecker_3_0 unintentionally instantiates the old version of PluginUpdateCheckerPanel (1.3). Then the panel then tries to access a non-existent field or method of PluginUpdateChecker_3_0 and crashes. It produces errors like this:
[26-Apr-2016 13:34:14 UTC] PHP Fatal error: Call to undefined method PluginUpdateChecker_3_0::getCronHookName() in [redacted]\wp-content\plugins\plugin-name-here\inc\plugin-updates\debug-bar-panel.php on line 58
Fixed by versioning debug bar panel class names.
In theory, $state and $state->update should always be either NULL or objects. That means isset() fully covers the possibilities and we don't need the additional empty() checks.
Support both PHP 7 and PHP <5.3
Load different versions of the Parsedown library depending on the PHP version. This will only affect plugins that use the GitHub update checker because the usual checker doesn't need to parse Markdown.
It appears that WordPress core developers are planning to add the `tested` and `compatibility` fields to the bulk update check API. Previously WordPress had to make a separate API request for each plugin to retrieve this information. See this Trac ticket for details:
https://core.trac.wordpress.org/ticket/35301
The `tested` field is used to generate the "Compatibility with WordPress X.Y: 100% (according to its author)" message on the "Dashboard -> Updates" page.
Note: This library doesn't support the `compatibility` field, so that's not included.