Currently WordPress doesn’t offer an easy way for plugins which are not hosted on wordpress.org to use its built-in automatic update feature.
Fortunately, I have found a quick and simple way to add this functionality to any plugin and allow plugin authors to take a complete control over when and how the updates are released.
The solution consist of two parts:
- filtering the contents of
get_transient('update_plugins')
underwp_update_plugins()
in/wp-includes/update.php
, and - providing your own update API.
Examples
Updates Hosted on GitHub
See https://github.com/kasparsd/git-update
Envato CodeCanyon Hosted Plugins
Note: this functionality is now provided by the Envato Market Plugin by default!
See https://github.com/kasparsd/envato-automatic-plugin-update
Custom Update Endpoint
Here is a working (and a very basic) example of an update API endpoint:
<?php
// Set this to TRUE while editing and testing this file
$disable_update = false;
$allowed_clients = array(
'111' => 'note for self',
'222' => 'like the URL of the user'
);
// Strip away comments
$allowed_clients = array_keys($allowed_clients);
$versions['check'] = array(
array(
'version' => '0.5',
'package' => 'http://api.example.com/plugin-0.5.zip'
)
);
// Check if the request is valid
if (!isset($_POST['name']) || $disable_update || !is_array($versions[$_POST['name']]))
return;
// Check if client can receive updates
if (!in_array($_POST['api-key'], $allowed_clients))
return;
$latest_version = array_shift($versions[$_POST['name']]);
if (version_compare($_POST['version'], $latest_version['version'], '<'))
print serialize($latest_version);
if ($disable_update && !isset($_POST))
print_r($versions);
and a plugin using that endpoint:
<?php
/*
Plugin Name: Check Updates
Description: Plugins hosted outside wordpress.org should also enjoy the automatic updates.
Version: 0.1
Author: Kaspars Dambis
*/
add_filter('transient_update_plugins', 'check_for_update');
function check_for_update($checked_data) {
global $wp_version;
$api_url = 'http://api.example.com/';
$plugin_base = plugin_basename(dirname(__FILE__));
// Check for updates ONLY ONCE per hour
if ($checked_data->last_checked) {
if ((time() - $checked_data->last_checked) < 3600) {
// uncomment this to avoid checking for updates on every page load
// return $checked_data;
}
}
// Start checking for an update
$send_for_check = array(
'body' => array(
'name' => $plugin_base,
'version' => $checked_data->checked[$plugin_base .'/'. $plugin_base .'.php'],
'api-key' => '111'
),
'user-agent' => 'WordPress/' . $wp_version . '; ' . get_bloginfo('url')
);
$raw_response = wp_remote_post($api_url, $send_for_check);
if (!is_wp_error($raw_response) && ($raw_response['response']['code'] == 200))
$response = unserialize($raw_response['body']);
if (!empty($response['package'])) {
$update_data = new stdClass;
$update_data->slug = $plugin_base;
$update_data->new_version = $response['version'];
$update_data->url = 'http://konstruktors.com/blog/';
$update_data->package = $response['package'];
// Feed the update data into WP updater
$checked_data->response[$plugin_base .'/'. $plugin_base .'.php'] = $update_data;
}
return $checked_data;
}
These solutions enable developers to sell their plugins and still retain the convenience of automatic updates for their users.
So, are you going to produce a plugin for WPers to set up their own API on their WP blog then sell it through the store?
Andrew, no, not really.
I am just thinking of ways to monetize plugins while still offering them as a free download to those who want to study and improve them.
One could provide a basic version hosted on WP.org and another full feature version to those who purchase an API key. Updates for the basic version would still go through WP.org, while I would control the full feature version.
Ideally I would imagine users making a donation right from their admin panel and receiving an API key upon PayPal confirmation.
p.s. I just realized that this works also for themes.
Kaspars, I’ve been thinking of similar ways as well. Perhaps a basic plugin for free and then something that plugs into that which can be purchased.
I’m also wondering how long until premiummod gets extended to plugins.
Jeffro made an interesting point on Twitter when he said that people were assuming that plugins for sale would be higher quality. They certainly could be, but being paid for doesn’t guarantee it.
Andrew, interesting that you bring up premiummod, because if they implemented this update API, they could provide automatic updates for those modified themes too :)
Re: higher quality of premium plugins & themes — I think that the main feature users are interested in is the continued development. Some might need the support, but regular updates are what people would be more than willing to pay for.
Thanks for this post. The timing is just about perfect. I’m working on a Premium Plugin and had just written some custom code to implement update notifications, but wasn’t happy with it. It shows up on the plugin page, but not at the top or in the counter.
I’ll have a look at your implementation.
Regarding the Free in the repository and premium for sale, the folks at WordPress recently made announcements to discourage this. Encouraging more high quality free plugins and less using the repository as a place to advertise your for-sale products.
Only part about this that bugs me is when the paid version comes into conversation. Other then that though, this is cool information, so thanks for sharing it.
Long as you realize folks could buy your plugin and still turn around and give it away to others for free …
Wow, I think it’s awesome. What do WP core guys think of it?
Thanks a million for this :) I thought this was going to be horridly complex but it seems to be fairly straightforward by the looks of your example.
@Dave – I doubt the core guys will have any qualms with this. There are many, many different reasons people will need to use a non-official repository, particularly for non-distributed plugins.
I’m stumped. How on earth do we get this to work?
Is there any chance you could roll this into a plugin which actually works? I must be doing something stupid with the file as it looks like it SHOULD work, but all my attempts keep creating a plugin which never says it needs updated :(
Ryan, you should uncomment the last two lines in the plugin file in order to initiate the
transient_update_plugins
filter call.You must also specify your own
$api_url
.hey kaspars-
first of all, thanks for this. it already helped me a lot. I had some difficulty getting this to work, though (wordpress 2.9.2)
whenever I enabled the get_transient(‘update_plugins’) line, the plugin refused to work. without it, everything seemed fine. so I did not investigate further. but one thing happened every time I updated my plugin through this mechanism: wordpress did not replace the existing plugin file, but disabled it, created a new folder with .tmp appended and put the new plugin version there, then enabled the new one.
still half of what I wanted, but I guess it’d be great if people didn’t have to delete their old plugin files afterwards.
do you have an idea what this could be related to? my “official” plugins all work fine and updating them does too.
I’d be thrilled if you shared your thoughts on this. I realize this post is already some months old, but I’m hoping you will still get my message.
best regards,
arno
Arno, in several hours (or days) I’ll publish a new article that gives examples of automatic updates both for themes and plugins. So stay tuned.
wow, this is very good news! thank you for your effort.
Good news, Arno — I got it all working just five minutes ago. I have working examples of both plugin and theme that use custom API. I’ll send you the files right now, as it will take a while to write an article that explains it all.
that’s great, thank you so much!
Kaspars, I noticed that you removed the .txt files this post refers to. Any chance you are willing to share this code still?
Jeff, there is a new post coming that will showcase code examples for both plugin and theme automatic updates which work with WordPress 3.0 (that posts is already in Drafts).
Nice work here, any idea when the article this will be published, or is there any way to get the working sample!
Thanks for the time man!
Here is the code for WordPress 3.0.
Thanks a Mil!!!
Shawn