Automatic Updates For Private And Commercial Themes

Update 2017-06-20: This library has been deprecated. Please use PUC instead. It’s more current and it supports both themes and plugins.


This is a PHP library that lets you add automatic update notifications and single-click updates to any WordPress theme. It’s purpose is to be easy to integrate for developers and to provide a familiar experience to theme users. From the users’ point of view, update notifications generated by this library will look and function just like those displayed by WP itself.

Dashboard screenshot

An update notification for a theme not hosted on wordpress.org

Download

License

This library is licensed under the GPL and is distributed free of charge. If you find it useful, consider making a donation. Commercial licensing (e.g. for projects that can’t use an open-source license) is available upon request.

Quick-Start Guide

There are two things you will need to do:

  1. Create a publicly accessible “metadata file” that describes the latest version of your theme.
  2. Add the update checker to your theme and tell it where to find that file.

First, the metadata file. Open your favourite text editor and copy the following JSON code into a new file:

{
  "version" : "2.0",
  "details_url" : "http://example.com/example-theme/details.html",
  "download_url" : "http://examle.com/example-theme/example-theme.zip"
}

Replace the placeholder values with your own data. As you can probably guess, version is the version number of your theme. details_url specifies the page that the user will see if they click the “View version 1.2.3 details” link in an update notification. Set this field to your “What’s New In Version 1.2.3” page or the theme homepage (tip: if you notice that your page looks strange when viewed from the WP dashboard, see this comment).

Finally, download_url is the URL where the latest version of the theme can be downloaded. This field is optional. If you leave it out, the user will still get an update notification when a new version comes out, but there will be no “update automatically” link. They’ll have to download and install the update manually.

Upload the metadata file to your website. You can use any directory and file name you like; just remember that the file URL should be accessible from wherever someone might install your theme.

Next, lets add the update checker library to you theme. Copy the “theme-updates” directory from the client library to your theme. Then add the following to your functions.php:

//Initialize the update checker.
require 'theme-updates/theme-update-checker.php';
$example_update_checker = new ThemeUpdateChecker(
    'example-theme',
    'http://example.com/example-theme/info.json'
);

Again, replace the placeholders with your own settings. The first argument should be the name of your theme’s directory. For example, if your theme lives in /wp-content/themes/my-theme/, use “my-theme” here. The second argument should be the URL of the metadata file you just created.

Congratulations, your theme now supports automatic updates 🙂 The update checker will automatically query the metadata file every 12 hours, checking to see if a new version is available. If it finds one, it will display a standard theme update notification on the Dashboard. Your users will be able to install the new version with a single click.

The ThemeUpdateChecker class

Class constructor
The library is configured by passing a number of arguments to the ThemeUpdateChecker constructor. They are, in order :

  • $theme –  The theme directory name, sometimes called the “slug”.
  • $metadataUrl – The URL of the theme metadata file.
  • $enableAutomaticChecking – Enable/disable automatic update checking. If set to FALSE, you’ll need to explicitly call the checkForUpdates method to, err, check for updates. Defaults to TRUE.

checkForUpdates()
Manually trigger an update check. This is useful if you want to do update checks on your own schedule. checkForUpdates has no parameters and does not return anything. If you want to actually retrieve the latest update, use requestUpdate instead.

requestUpdate()
Retrieve update information from the configured metadata URL. Returns either an instance of ThemeUpdate, or NULL if there is no newer version available or if there’s an error.

deleteStoredData()
The update checker stores various update-related bookkeeping data in a DB option. Call this method to delete that data. This is can be useful is your theme provides some kind of “uninstall” feature.

addQueryArgFilter($callback)
Register a callback for filtering query arguments. Whenever the update checker needs to retrieve the metadata file, it will first run each filter callback and attach the query arguments that they return to the metadata URL. This lets you pass arbitrary data to the server hosting the metadata. For example, commercial themes could use it to implement some kind of authorization scheme where only paying users get automatic updates.

The callback function will be passed an associative array of query arguments and should return a modified array. By default, the update checker will append the following query arguments to the URL:

  • installed_version – the currently installed version of the theme.

This method takes one parameter – the callback function.

addHttpRequestArgFilter($callback)
Register a callback for filtering arguments passed to wp_remote_get. The callback function should take one argument – an associative array of arguments – and return a modified array or arguments. See the WP documentation for details about what arguments are available and how they work. This method takes one parameter – the callback function.

addResultFilter($callback)
Register a callback for filtering theme info retrieved from the metadata URL. The callback function should take two arguments. If a theme update was retrieved successfully, the first argument will be an instance of ThemeUpdate. Otherwise, it will be NULL. The second argument will be the corresponding return value of wp_remote_get (see WP docs for details). The callback function should return an instance of ThemeUpdate, or NULL. This method takes one parameter – the callback function.

Related posts :

306 Responses to “Automatic Updates For Private And Commercial Themes”

  1. paul says:

    Much appreciated! I’m emailing you now. Thanks so much for your help with this sir! 🙂

  2. Karl Brown says:

    I am attempting to use your library but it is not functioning as desired. The library does not seem to be detecting the current version of my theme, coded into its Style.css. This is seen by the fact I can update to the latest version of my theme and I am still prompted to update my theme after the update completes, and also by the fact that the current version is not listed on the update screen. Here is a picture of what I am seeing: http://i.imgur.com/avvBW8M.png
    Do you have any idea what might be wrong?

  3. Jānis Elsts says:

    The update screen is displayed by WordPress and not this library, so this might not be related to the library as such. What does your style.css header look like?

    Also, is the file really named “Style.css” with an uppercase S? The file name should be all lowercase.

  4. Karl Brown says:

    /*
    Theme Name: Capitol Connect Classic Responsive
    Theme URI:
    Author: TODO
    Author URI: TODO same as above
    Description:
    Version: 1.3.103.0
    License: TODO
    License URI: TODO same as above
    Tags: TODO
    Text Domain: capitolconnect
    */
    It is in lower case.

  5. Jānis Elsts says:

    Try filling in the “Description:” field (with anything, e.g. another TODO). If that doesn’t work, see if changing the version to something simpler like “1.0” helps.

  6. Karl Brown says:

    I am already using your plugin library with a similarly complicated version number so I doubt that is the issue. I tried filling in the description field to no avail.

  7. Jānis Elsts says:

    The plugin library is significantly more advanced, however.

    Hmm, I’m not sure what else it could be. Have you tried the example theme? Does the library work correctly with that?

  8. Karl Brown says:

    By updating the directory I referenced in ThemeUpdateChecker and changing what was visible to my user, I succeeded in getting farther along in the process. However, now I am stuck with the following error after successfully initiating an update:
    http://i.imgur.com/7hY10Gu.png
    I believe it has to do with a permissions issue

  9. Jānis Elsts says:

    Yes, it could be a permissions issue. I’ve also had that error happen when one of the files in the theme directory is open, which prevents WP from removing that file and the directory itself. If you have a .svn or .git subdirectory in there, that could also cause problems since the VCS client might have some of the files open.

  10. Julien says:

    Hi !
    I have a small problem and maybe someone could help me.
    When I made an update of my theme I find myself with a really strange file name.

    The name of my theme is starter
    and the result is: actiondownloadslugstarter-GsrfKn

    I do not find a solution.
    Thank you !!!

  11. Jānis Elsts says:

    I’ve heard of that, but I’m not sure what causes it.

    Maybe it’s related to the structure of the ZIP file? Normally, all theme files should be inside a directory, not at the top of the archive. If the files are not in a directory or the directory name doesn’t match the theme name, that can cause all kinds of weird problems.

  12. […] 详情可以参看作者文章:Automatic Updates For Private And Commercial Themes […]

  13. Sinan Atici says:

    Hi !
    I have a small problem and maybe someone could help me.
    When I made an update of my theme I find myself with a really strange file name.

    The name of my theme is starter
    and the result is: actiondownloadslugstarter-GsrfKn

    I do not find a solution.
    Thank you !!!

    I got the same problem. Don’t add theme files directly in theme.zip file. Theme files must be a folder in theme.zip file. theme.zip>theme-folder>(All other things)

    I wish I helped you.

  14. Chris says:

    I’ve setup the update server and when I go to update my custom theme I get this message.

    Download failed. Forbidden

    If anyone could point me in the right direction for fixing this please let me know.

    Thanks

  15. Jānis Elsts says:

    This may sound obvious, but does the download URL work if you open it manually?

  16. Chris says:

    Actually no its seems my api folder can’t be opened in the browser.

    I’ll contact my hosting thanks.

  17. Mike says:

    I’ve got the same problem as Rasmus where the theme directory gets renamed after it updates.

    My update zip file is not hosted on github though, it’s just hosted on my website and it is publicly accessible. As mentioned it updates just fine, but the theme folder gets renamed to the theme name with a hyphen followed by some random characters, for example:

    mytheme-A8I2Sr

    Does anyone know how to solve this issue?

  18. Jānis Elsts says:

    As I mentioned before, check the ZIP file structure. The theme files must be inside a directory, not at the top of the ZIP. If they’re not in a directory, you will get an incorrect folder name like you described.

  19. Is it possible to update a theme while excluding a user configured file from being changed? For example, I make it possible for the user to edit certain styles which gets published to its own stylesheet. Can I still do the autoupdate while keeping this file intact?

  20. Jānis Elsts says:

    No, I don’t think WordPress supports that. It always overwrites all files.

Leave a Reply