A Guide to the WordPress HTTP API: Automatic Plugin Updates

As you probably already know, WordPress has a mechanism that detects plugins, themes and the WordPress core updates, makes a notification when they are available, pulls information about these updates and enables you to automatically install these updates. This third (and final) part of the WordPress HTTP API series will teach you how to create your own plugin repository to distribute automatic updates for your users.


A Glimpse at Auto-Updates

WordPress has a magnificent auto-update system that notifies you when new versions of the WordPress core, installed plugins or themes are available. The notifications are displayed in the Admin Bar and also on the plugins page where you can get more details about the new version.

To install the new version, you simply hit the "Update automatically" button. WordPress will automatically download the new package, extract it and replace the old files. No FTP, removing old files, and uploading is required.

There is also a dedicated page for updates which can be reached from the dashboard menu. It's helpful when you want to do bulk updates of multiple plugins instead of updating each one separately. It also has a "Check Again" button which checks for new updates. By default, WordPress does this check every 12 hours.

Under the Hood

Auto-updates are like magic; you are just a click away from getting the latest version. The good news is that the process itself is not complicated or at least understanding it and customizing it for your own use isn't. There can be many reasons why you want to run your own server to distribute updates for your plugins; the only one I'm thinking of is premium plugins. If your plugin is free and open to the public, you should publish it on the WordPress plugins repository.

Every 12 hours, your WordPress blog will check for new plugin versions and store the request sent and response received in a site transient called 'update_plugins'. The following code will display the content of this transient:

After 12 hours or so, refresh your blog plugins page and you should get a similar output to the following:

The output will certainly differ from one blog to another, but the contained information is essentially the same:

  • last_checked (int) – The last time the auto-updates check was run (in seconds)
  • checked (array) – The list of checked plugins and their version
  • response (array) – The returned response from the API server

Disabling the 12 Hours Latency

If you are like me, you probably won't enjoy waiting 12 hours for WordPress to check for new updates when you are doing related debugging and development. For this, you can simply press the "Check Again" button in the updates page. The 12 hour waiting period is defined in WordPress core on Line 147 of the wp-includes/update.php file, it's the $timeout variable.

Hooking to the "update_plugins" Transient

Since your plugin is not hosted in the WordPress plugin repository, there will be no response from the traditional API. The solution is to build your own API, check for updates; and when a new update is available add the response to the "update_plugins" transient. WordPress will download the new version from a 'download_url' that you specify in the response.

To check for new versions, we need an API server. It's not really required that your server has PHP or even a server side language, but it'll help for finer control of the update process. This tutorial assumes you have a remote PHP server but you can convert the code (which is pretty basic) to your favorite language.

To get a better understanding of how the filter works, pick up any plugin from the "checked" list that gets displayed on your blog. For example, the 'access/access.php' plugin, and put the following code in a new or already running WordPress plugin.

Now when you refresh your plugins page, you should see a notification that a new version of the plugin is available (version 2.0) and you can get more information or install it. None of that will work yet, obviously, but you get the idea. WordPress relies on this transient to know about the new updates.

In summary, our solution needs to do the following:

  1. Check for new updates from your server.
  2. When a new update exists, add it to the response property of the 'update_plugins' transient.
  3. Hook with the "plugins_api" in a similar fashion to provide the new version information.
  4. An API Server which provide the version, details and package of the latest release.

The Auto-Update Class

To standardize and streamline things, I have built a PHP class which can work with any plugin. It's quite simple to use, you just need to provide 3 parameters: the plugin's current version, the update path, and the plugin's slug. I'll explain in detail later what each one does.

Our class will be able to perform 3 HTTP requests, 2 required and a third optional:

  1. The first request will check for the latest version on the remote server. To make things simpler and faster the API server will only return the latest version as a string (e.g. "1.0" or "1.1")
  2. The second request will return the latest version information as a serialized PHP object.

The class has 3 public functions which you can use in your plugin:

  • getRemote_version – Returns the latest remote version as a string.
  • getRemote_description – Returns the latest remote version details as a PHP object.
  • getRemote_license – Returns the license status of the plugin. It is optional, and there is no implementation of licensing in this tutorial.

Using the Class

The class can be initiated in the "init" action. It has 3 parameters:

  1. Current version – A string with the current installed version of the plugin.
  2. Update path – The path of the update server. In our case, it's a PHP file in my localhost root directory.
  3. Plugin slug – This is required to get the plugin slug and name. For that, the class should be initiated in the same file that has the WordPress plugin header.

That's all! Now your plugin is ready for getting updates from the specified remote path.


The Class Code

Step 1 The Class, Properties, and Methods

We start off with a class skeleton defining the properties, the constructor and the different methods. Each property and method is preceded with a comment section that has a description, the accepted parameters and the returned variable. The comments follow the PhpDoc guidelines.

Step 2 The Constructor

The constructor initiates a new instance of our class. It accepts three parameters which we already defined in the previous section. The constructor sets the "current_version", "update_path", "plugin_slug" and "slug" (which it extracts from the "plugin_slug") public properties. It also hooks to the "pre_set_site_transient_update_plugins" and "plugins_api" filters.

Step 3 Remote Call Functions

There are 3 functions which make remote requests to our self-hosted repository. They are public functions which can be used independently and each of them either return the response value or false.

getRemote_version – Returns the latest plugin version from our self-hosted repository as a string.

getRemote_information – Returns information on the plugin's latest version from our self-hosted repository as a PHP object.

getRemote_license – Returns the licensing status. This function is optional and there is no licensing implementation in this tutorial.

Step 4 Filter Hooks

The class hooks to the "pre_set_site_transient_update_plugins" and "plugins_api" filters. A deeper explanation of each filter and the hook is available in the first section in case you skipped it.

The Full Class Code


Setting Up Your Server

Now that we have made our plugin ready for self-hosted auto-updates, it's time to setup the server which will serve the notification, the description and the update package. In our case, we are using PHP with a single file called "update.php" in my local server root directory. The plugin update is "update.zip" in the same directory.

If you did read the auto-update class code, you'll find that it does 3 requests which should be handled by our API server.

  1. Plugin Version
    • Request Type: POST
    • Parameter/value: "action"/"version"
    • Return value: String ("1.0", "1.5", "2.0"...)
  2. Plugin Details
    • Request Type: POST
    • Parameter/value: "action"/"info"
    • Return value: String. A serialized PHP objected
  3. Plugin License
    • Request Type: POST
    • Parameter/value: "action"/"license"
    • Return value: Feel free to implement it :)
  4. Plugin Package
    • Request Type: GET
    • Parameter/value: none
    • Return value: Zip Package

Code for the update.php File

Customizing the Plugin Information Box

It's possible to customize the plugin information box. The box has:

  1. Information about the plugin (description, last update, downloads count)
  2. Sections which will add tabs to the information box

Sections can be added to the sections array property. The description tab is itself a section.


Summary

I have tried to cover most of the update process in this tutorial. The source code for the Auto-update class can be found in this GitHub repository. Feel free to fork and push your improvements. Suggestions, questions and critiques are certainly welcome.

Tags:

Comments

Related Articles