Have a plugin that can’t be submitted to the official repository?
Code is now on GitHub please see here for updated version.
Many reasons exist but the biggest is that the plugin/support is sold therefore can’t be downloaded for free. But why should the end user be punished after all they bought the plugin and updates should be just as seamless as from the official repo. With this script this can be accomplished. Examples and a package of sample code can be downloaded below.
The original idea and code came from konstruktors.com, but I’ve modified it to add more info and fixed a couple of errors with it. The package containing all the sample code can be downloaded here from GitHub.
First I’ll explain the code that goes onto the update server, this code is found in the api folder of the zip file. Basically you’ll just need to edit and upload the api/index.php file to your server somewhere and then in the update files of your theme/plugin point to that directory.
Theme Update
The theme in $packages[‘theme’] will need to replaced with your theme’s slug most likely it’s theme folder name. This is what is sent to the update server to check for updates. Next you have a versions array. You’ll need to change the 1.0 both places to match the version of the update that is available. Next is the date that the update was published. Not really used in theme updates but still handy to have. Next is the important part the url to the zip file for the update that will be pulled down by WordPress and installed. The info array below this is where you can specifiy a url that will display the theme and some info about it. Normally for themes from the offical repo this will display the page from the extend section.
[php]
// Theme with update info
$packages[‘theme’] = array(
‘versions’ => array(
‘1.0’ => array(
‘version’ => ‘1.0’,
‘date’ => ‘2010-04-10’,
‘package’ => ‘http://url_to_your_site/theme.zip’ // The zip file of the theme update
)
),
‘info’ => array(
‘url’ => ‘http://url_to_your_theme_site’ // Website devoted to theme if available
)
);
[/php]
Plugin Update
Now onto the plugin section of the api/index.php file. The plugin in $packages[‘plugin’] will need to be replaced with the plugin’s slug, usually the folder name of the plugin itself. Next is the versions array where 1.0 will need to replaced both time with the version that is in the zip file for the update.
- version: version of the update
- date: date the update was published this is used in the plugin details section.
- author: full name of the author or company publishing the plugin.
- requires: minimum version of WordPress needed for the plugin to function properly.
- tested: the version of WordPress the plugin has been tested with.
- homepage: authors homepage.
- downloaded: download counter used by wordpress.org but not by the self update api, can be any number.
- external: link to the page devoted to plugin.
- package: url to the zip file for the update.
- sections: is an array to hold the extra info for the plugin details page generated by WordPress.
- description: Description of Plugin.
- installation: Install Info
- …
- Any section can be added not just the ones listed. The first field in the array ie before the => is used as the title of the tab in the plugin info page. The next section is used in the body of the tab.
[php]
// Plugin with update info
$packages[‘plugin’] = array(
‘versions’ => array(
‘1.0’ => array(
‘version’ => ‘1.0’,
‘date’ => ‘2010-04-10’,
‘author’ => ‘Author Name’,
‘requires’ => ‘2.8’, // WP version required for plugin
‘tested’ => ‘3.0.1’, // WP version tested with
‘homepage’ => ‘http://your_author_website’, // Your personal website
‘downloaded’=> ‘1000’, // Number of times downloaded
‘external’ => ‘http://your_plugin_website’, // Site devoted to your plugin if available
‘package’ => ‘http://url_to_your_site/plugin.zip’, // The zip file of the plugin update
‘sections’ => array(
‘description’ => ‘Description of Plugin’,
‘installation’ => ‘Install Info’,
‘screen shots’ => ‘Screen Shots’,
‘change log’ => ‘Change log’,
‘faq’ => ‘FAQ’,
‘other notes’ => ‘Other Notes’
)
)
),
‘info’ => array(
‘url’ => ‘http://your_plugin_webiste’ // Site devoted to your plugin if available
)
);
[/php]
Theme Update script
Now for the script that will need to be added to your theme for the theme to be able to check back to your server for updates. There is a folder called theme/theme-update/ that has a update.php file that is all that is needed. It need to be edited and included from your functions.php file. The value that needs to be edited is $api_url. $api_url is the url to the api/index.php file that you’ve uploaded to your server somewhere. There is also a debug function at the top to reset the transient used for theme updates so that WordPress will check every page load for updates. The should only be used for testing, and should be removed from actual production code, as it would cause massive amounts of traffic to your site.
[php]/**/
// TEMP: Enable update check on every request. Normally you don’t need this! This is for testing only!
//set_site_transient(‘update_themes’, null);
add_filter(‘pre_set_site_transient_update_themes’, ‘check_for_update’);
function check_for_update($checked_data) {
global $wp_version;
/******************Change this*******************/
$api_url = ‘http://UPDATE SERVER.com/’;
/************************************************/
[/php]
Plugin Update script
In the zip package there is a folder test-plugin-update which contains a file called test-plugin-update.php Which is a full plugin but doesn’t do anything except check for updates to itself. The code can just be placed into existing plugin files or into a new file and included from the main plugin file. The plugin update only require one variable be changed $api_url which is the path to the api/index.php file on your update server. This also has the function to check for updates every page load and should be removed from production code. Basically the plugin update has two main functions. One checks for the update the other takes the info from the update check and places it into the plugin update details screen.

By Thomas Nagels January 5, 2011 - 2:38 pm
Great plugin, but there was one problem with the implementation for me:
It would not work unless I added another version (like ‘0.2’) to the packages >plugin > version array. Before I did this, it gave an “argument must be array” error on the array_shift function in the code. Took me quite a while to figure that out.
Btw. We use the code in a plugin that is installed in all WordPress-enabled accounts in our hosting packages. That plugin is so specific that we don’t want to distribute it on wordpress.org, and now we can finally update it easily!
By Mark Jones January 17, 2011 - 12:04 pm
Awesome. Exactly what I was looking for.
By The Frosty January 17, 2011 - 9:50 pm
Looks promising, am going to give this a try. Thanks.
By alex chousmith February 10, 2011 - 3:31 pm
this was exactly what i was looking for. just needed a couple tweaks to get it working 100% for the Theme Update check.
mainly, in your /theme-update/update.php , you look for the current version of the theme via
‘version’ => $checked_data->checked[$theme_base .’/’. $theme_base .’.php’]
which was the same as for the Plugins. This works for Plugins but for Themes, seems like WP just sets up that $checked_data array with just the Theme slug, so the code should just be
‘version’ => $checked_data->checked[$theme_base]
also another quick comment, in the api/index.php file, where it says
“$packages[‘theme’] = array( ” and “$packages[‘plugin’] = array( ”
the ‘theme’ should be replaced with the actual value of the $theme_base, so they match, and the ‘plugin’ also (i believe) should be that $plugin_base/$plugin_base.php
thanks!
By Ryan April 2, 2011 - 4:56 pm
I have been fighting with this for a day and maybe someone here can give me some advice….(for theme updates)
My $checked_data object only seems to contain a $last_checked key and that’s it. It looks like everyone above has a ‘checked’ array that is part of the $checked_data object.
Anyone know of any reason that a theme would not have a complete $checked_data object? It looks to me that this is simply passed by wordpress when it calls the filter function ‘check_for_update’.
Any help here would be greatly appreciated.
By Jeremy Clark April 2, 2011 - 5:13 pm
@Ryan I’ve struggled with this problem myself and come to find out that the problem was with my code and if everything else on the blog is updated and not saying a new version is available then the code quits before checking your update site. If you’d like to use my contact form I’d be glad to help you get it going, when I get time I’m also going to update this page with the new code that I’ve found works.
By Ryan April 2, 2011 - 5:31 pm
@Jeremy Thanks Jeremy, I am going to keep struggling with this and hopefully come up with a solution as well. In the WordPress update.php there is a function called wp_update_themes() that I am working threw that might be of some use. I will shoot you an e-mail via your contact form shortly and update here if I find any more info.
All the best.
By Rod April 29, 2011 - 10:17 am
Very interesting article and would be great if it worked. I hope you have a chance to post another code update Jeremy. Many thanks for doing this!
By Jeremy Clark April 30, 2011 - 7:40 pm
@rod please check my github page as I’ve updated the script now and will be working on it more soon.
By jay April 30, 2011 - 4:58 pm
I have not been able to get this working for a plugin… is there any live examples that can be seen?
By jay April 30, 2011 - 6:31 pm
How do you include the screenshots?
By Jeremy Clark April 30, 2011 - 7:38 pm
@Jay
I haven’t actually tried including screenshots but I’m pretty sure you would need to format the screenshots section code as html and just use an img tag to insert the image from you server or perhaps a cdn of some sort. I’ve been working on updating the script so I will try include better examples of how to use each section.
Keep checking my github page for updates and if you have any suggestions please let me know.
By Tyler May 25, 2011 - 1:48 pm
I seem to be getting an Notice: unserialize() [function.unserialize]: Error at offset 0 of 2146 bytes on line 36 of the update.php, any thoughts?
By link(salt) June 4, 2011 - 6:56 am
OMG .. just downloaded the zip. Gonna spend my weekend on it !
I so hope this will work as all our plugins were recently banned from wordpress.org (after having been on there for over 2 yrs.). (autoposting plugins no longer allowed !). Our entire userbase went from one-click update to : ….’finding / learning about obscure download place elsewhere on the internet -> downloading our latest plugin version -> uploading into wordpress -> reactivating plugin’ …..
Needless to say a lot of casual users don’t even know how to initiate the regular updates, let alone doing it semi-manually.
Will keep you posted, but thanks ahead of time for all the legwork !
Pete
By Ariel Bustillos June 9, 2011 - 1:17 pm
cant make it work, what can I do?
I dont get any error, I have even tried to echo some text to see if function is called or the filter is working, but nothing show up ๐
Please help
By Jeremy Clark June 11, 2011 - 3:24 pm
I’ve updated the code on github, most likely the problem was the url masking if you didn’t have it setup it would still try to connect to a no existent db and error out.
By Cristian June 12, 2011 - 1:19 pm
First of all, THANKS for making this available!
I ran into a (most probably stupid) problem… The plugin shows up, the update information is retrieved correctly but when I click on “View version details” it comes up with an “An unknown error occurred” error message. Any idea what might cause that? I see no way to provide this information, actually…
Many thanks in advance for any advice you might give!
By tonli.eu June 13, 2011 - 8:30 am
If you cannot host your plugin on wordpress.org because of censorship, license issues, or want to host plugins outside of wordpress for any other reason you can now also use the free services by http://tonli.eu .
tonli.eu is running a lot of the code mentioned here at it’s core but was slightly adapted for public use.
We’ve managed to condense the code so you only need to upload 1 zip file and the code will do the rest. The bells and whistles are a work in progress.
(b.t.w. tonli.eu comes from the french : ton lieu -> freely translated “your place”).
thanks to people like Jeremy and the many hours they spent coding we are now no longer dependent on the whims of big companies and random acts of vague “wordpress censorship boards”.
By Frankie Jarrett June 22, 2011 - 9:20 pm
Thanks Jeremy! Just got the latest version from github.
I’m testing on a wp multisite blog and having problems. Not receiving any update notification for themes or plugins. Have you by chance tested on a multisite installation? Thanks.
Running WordPress 3.1.3 Multisite
//Frankie
By Trevor Mills June 24, 2011 - 11:06 pm
I was looking for a solution to host my own plugins and came across this and other pages that gave examples and an API. But what I was looking for was a plugin to manage my own self-hosted plugins. I couldn’t find one.
So I built one.
It’s now hosted at http://wordpress.org/extend/plugins/self-hosted-plugins.
Basically you write a plugin as you normally would without worrying about managing updates. Then upload the .zip file to your WordPress admin area. The tool will manage the updates and can parse the readme.txt and plugin.php files to generates a page with the same look and feel as the WordPress repository. You can see it in action on my own site – http://topquark.com.
@topquarky
Hope other people find it useful, and if any developers want to contribute, drop me a line.
By djbokka July 7, 2011 - 1:32 pm
I’ve been able to get your script working (as well as a similar script from the book “Professional WordPress Plugin Development”) but in both cases, it always shows there’s a new update available. Even with the current version is the most recent.
Info request works fine. Plugin update works fine. Just always thinks there’s a new version. Anyone else run into this?
By timg19 July 8, 2011 - 1:23 pm
That piece is working fine for me (I’m only working on theme updates though). In themes there are 3 places to make sure version numbers are updated. 2 in the index.php file (in the api folder) and 1 in the style.css file in the new theme. If the style.css file in the new theme is not updated it will keep tell you a new theme is available. I’m assuming there is a similar file for a plugin.
By djbokka July 8, 2011 - 1:25 pm
Thanks timg19. I’ve double-checked the version numbers – all appears to be right. In fact, when I go to the Plugins page within WP, I see the correct version of my plugin, then beneath it, it’ll say “A new version of your plugin is available” and will list the same version number.
I’ll keep toying with it and see what I come up with.
By timg19 July 8, 2011 - 1:15 pm
Thanks a lot of posting this. I am running into an issue with how files are being copied over to the site being updated. Steps taken:
1) Update api index.php to note there is a new version (will be retrieving mytheme.zip file from api folder)
2) Notification shows up that theme has a new update. *** This only happens when I activate my theme, it will not display that an update is available if the theme being updated a child theme. Is this correct?***
3) Click to update the theme
4) Update is successful, but all new files are in folder called “mytheme.tmp”
Does anyone know what i’m doing to cause the updated theme to get the “tmp” extension?
Thanks!
By Tim July 19, 2011 - 7:41 am
I’m seeing the same problem: following an update, the new files are in /mytheme.tmp instead of /mytheme, causing WP to revert to the TwentyTen theme.
Really hope we can get to the bottom of this.
By timg19 August 2, 2011 - 10:59 am
Tim: I confirmed that the “.tmp” extension is a result of updating WordPress to 3.2+. Any help with this would be greatly appreciated.
By Tim September 7, 2011 - 12:01 pm
Apologies for the slow response. I’ve just checked, and I get the same issue on a 3.1.4 installation. As an experiment, I tried reducing the size of the zip file by omitting all of the images, making it 159k, and the problem is still there. Theme folder permissions are 755. Not quite sure what to try next. Any suggestions?
By Tim September 13, 2011 - 9:21 am
For me at least, the problem was the folder structure within the zip file. It seems that the theme files need to be contained within a folder within the zip file, and the folder name needs to match that of the theme being upgraded.
By Tim September 14, 2011 - 2:47 pm
So, unsecured downloads are working, which is brilliant.
But when I switch url masking on, I get an error during the update: “Incompatible Archive. PCLZIP_ERR_BAD_FORMAT (-10) : Unable to find End of Central Dir Record signature”.
Any suggestions?
By Jeremy Clark August 3, 2011 - 6:43 am
The way it sounds is that WordPress is running out of memory before being able to complete the installation. Have you tried renaming your old mytheme folder in the wp-content/themes folder and then manually uploading the new version’s zip file under the install theme tab. You might also want to see if your host can increase your php memory. One other thing to test is the permissions on the mytheme folder in the wp-content/themes folder, if the server can’t delete the old folder the install wouldn’t finish. If you’d like to contact me I’d be glad to help you further: http://clark-technet.com/contact-me
By timg19 August 10, 2011 - 4:06 pm
Thanks Jeremy. I had to turn my attention to another project, but when I come back to this I will post what I find.
By Nathaniel Schweinberg June 11, 2012 - 6:53 pm
Or are we to manually create the keys that they use? I’m a little confused and could use some help =]
By Nathaniel Schweinberg June 11, 2012 - 6:49 pm
Hey man!
I’m LOVING this. I’m encountering the same issue as our friend here, and I think I may have found the reason… The function createKey doesn’t actually insert the key it’s created into the database, so the database is constantly empty, returning an error to WordPress because the key doesn’t exist. Any thoughts on how to properly go about this?
By Jeremy Clark June 11, 2012 - 8:19 pm
Did you fill out the database info at the top of the index.php file and the download.php. Also you need to uncomment the section for the database functions to work. If you’d like to contact me here: http://clark-technet.com/contact I’d be glad to look over the code and find the problem.
By Frankie Jarrett September 13, 2011 - 9:26 am
Jeremy, just wanted to say thank you. I’ve been running this script on my themes over that last two months and it’s been working flawlessly.
It’s a big value to be able to provide my customers with automatic updates. Thank you for your hard work and giving back!
//Frankie
By Ryan Hellyer September 30, 2011 - 11:58 am
Thanks for all the hard work!
I’m toying with the idea of turning this into a WordPress plugin so that people can just install it directly onto their own WordPress install, then just dump the URL for the download link into an admin page and have it all sorted automagically. Could even have it spit out the PHP required to be added into the theme/plugin perhaps. It’s just an idea at this stage but something I’m toying with a bit as it seems like it would be useful.
One change I would make is to move away from global variables and use constants instead. Constants are generally a better option for static strings that need to be used globally.
By Daniel October 3, 2011 - 5:05 pm
That’s really great. I got it working but I have a question:
I would like to protect the package url. Now it is a direct link to a zip file but I would like to point to a download.php file. So, my question is, how the file content (of the zip file) has to be served from the download.php file that wordpress can install it?
Best regards,
Daniel
By Jeremy Clark October 3, 2011 - 7:03 pm
The download has a readme for basic instructions. The files are commented pretty thourghly as well. Basically you’ll need to add a table to your mysql database then enter some config in the api/index.php and api/download.php. You’ll also need to uncomment the database sections. If you’d like I’m always available to help you setup and customize http://clark-technet.com/consulting
By Frankie Jarrett October 28, 2011 - 8:25 pm
Jeremy, just to update you. I’ve been using your solution for a while now with great results! I’ve noticed while testing WP 3.3 Beta-2 this strange scenario:
1. I have an old theme (that there’s an update available for) activated
2. It will not show there is an update available
3. If I delete another non-active theme the “update available” is then suddenly appearing for the active theme
Catch my drift? BTW, I’ve overheard some conversations in the Trac about changes for the update check which may be beneficial for this project: http://core.trac.wordpress.org/ticket/18876
//Frankie
By Jeremy Clark October 29, 2011 - 6:36 pm
Thanks for the report Frankie, I’ll defenitely be testing 3.3 soon and I’ll look for this, and see if I can figure out the problem and update the code.
By Riyo8 October 29, 2011 - 9:59 am
I have been unable to set this up on local machine with mamp+WordPress. Need a more details description for the above api. Can someone help me?
By Jeremy Clark October 29, 2011 - 6:38 pm
I’ve tried to document the file thoroughly, if you’d like to contact me http://clark-technet.com/contact-me I’d be glad to give you a hand.
By Riyo8 December 3, 2011 - 12:36 pm
Got it working! great script! Awesome work. Thanks a ton!
By Adi November 6, 2011 - 12:42 pm
Everything works well, but after update theme folder is renamed to *.tmp – do you know why?
By Adi November 6, 2011 - 3:48 pm
I’ve managed to fix it, I was not properly archiving the theme folder.
By Mark January 3, 2012 - 9:53 pm
This is a great post. I managed to make it work in a plugin.
But I am encountering a problem in plugin information when applying it to multiple plugins. Only one plugin displays the information, the other plugin that uses this feature are empty page. When I am changing the “10” in add_filter(‘plugins_api’, ‘plugin_name_api_call’, 10, 3); the other plugin displays the plugin information, and the previous one turns empty page. When I var_dump the $api variable in install_plugin_information() function of wp-admin/includes/plugin-install.php, it is null. Can you help me? Did you managed to apply it in multiple plugins? Your help is highly appreciated. Thanks!
By Jason January 18, 2012 - 6:19 pm
Not sure what I’mdoing wrong but I cannot get this to work with my WordPress plugin. . .I’m on WP 3.3 if that makes a dfference. . .
Thanks,
Jason
By Adi January 23, 2012 - 7:18 pm
One more question, I’m wondering if it’s possible to manually generate a download link? Thank you very much for this awesome plugin.
By timg19 January 31, 2012 - 4:40 pm
I’m back to looking at this after almost a year of other projects. Its running great now that I’ve updated my WordPress versions, so no longer a problem extracting the zip file on the server.
I run over 10 blogs and have a parent theme which all of them use. The other problem I was running into was the child theme is always active, so to get the update alert that a new parent theme is available, I had to active it (the parent theme).
To have the update look for the parent theme, rather then the child theme, I did the following:
1) Open the theme update.php file
2) Change: $theme_base = get_option(‘stylesheet’);
3) To: $theme_base = get_option(‘template’);
That keeps me from having to activate the parent theme. Again, great plugin, thanks!
Just a note that your original script could cause a problem if you want to update the child theme.
This will get the parent theme info.
$theme_data = get_theme_data( TEMPLATEPATH . ‘/style.css’);
While the one will get the child theme info.
$theme_base = get_option(‘stylesheet’);
So the the original script will get the wrong version number for the child theme. Not sure how to fix that yet.
By Frankie Jarrett April 20, 2012 - 11:13 pm
Hey Jeremy! Just wanted to give you a heads up that get_theme_data() is deprecated in 3.4 and has been replaced with wp_get_theme()
By Jeremy Clark April 23, 2012 - 10:27 am
Thanks Frankie for the heads up, I’m implementing the new function in my theme, and I’ll update the api to use the new version as well. The data available is still the same just in a different format.
By Jeremy Clark May 18, 2012 - 1:32 pm
The new version with this fixed and a few other improvements has been pushed to the github repo: https://github.com/jeremyclark13/automatic-theme-plugin-update
By Marcus May 22, 2012 - 1:49 pm
Just tried this out and there is a call to a function called “prepare_request()” in the check_for_plugin_update() function within test-plugin-update.php that doesn’t seem to be defined anywhere – am I missing something?
By Jeremy Clark May 23, 2012 - 7:39 pm
Fixed the error in version 1.6.2, available now on github. Thanks for the report.
By JohnG May 27, 2012 - 11:55 am
Thanks for this. I have it working but with a problem. Whenever there’s an update available the updates page displays a lot of HTTP header information as arrays, followed by the regular page contents. This doesn’t happen if there is no update available.
It appears to me as if something is either missing or being stripped out of the HTTP headers, although I’ve yet to determine what. Each of the displayed arrays is wrapped in “” tags and has a class of “xdebug-var-dump”, if that’s any help.
Using WordPress 3.3.2 and tested with Camino and Chrome browsers, both on a Mac.
By JohnG May 27, 2012 - 11:57 am
Oops, the tag got stripped out of my previous post. They are “pre” tags.
By JohnG May 28, 2012 - 10:42 am
Never mind, I found the problem. There were a couple of var_dump() statements that needed to be commented out. Works perfectly. Thanks again.
By Jeremy Clark May 31, 2012 - 11:39 am
I must have missed removing some of the debugging code. I’ve removed it now and push it to the github repo. Thanks for letting me know about this problem.
By Mitchell Wischmann June 4, 2012 - 4:58 pm
I am seeing a lot of code printed on the plugin update information screen. How can I fix this? Here’s a screenshot:
https://skitch.com/e-mwischmann/86174/screen-shot-2012-06-04-at-3.53.44-pm
By Jeremy Clark June 5, 2012 - 6:56 am
I had left some debugging code on with one version, but the latest version shouldn’t have the problem: https://github.com/jeremyclark13/automatic-theme-plugin-update
By Scott Hack June 28, 2012 - 8:09 pm
Anyone been able to get this to work with 3.4.1? I can’t get it to work with the latest version of WordPress.
By JohnG June 28, 2012 - 8:14 pm
I just tested it here with 3.4.1 and it worked perfectly.
By Jeremy Clark June 28, 2012 - 8:18 pm
Yes I’ve tested this with 3.4.1 as well and it is working. Are you using the latest version from the github page? Also if you still haven’t got it working feel free to contact me and I’ll see what I can figure out. http://clark-technet.com/consulting
By Scott Hack June 29, 2012 - 12:25 am
Thanks Jeremy, I’m going to keep at it for a little while. I’m sure I’m just doing something wrong that is really simple. What is the plugin slug?
By Plugin Licenses, Upsells, and Add-ons | Half-Elf on Tech July 6, 2012 - 1:16 pm
[…] an update too.Probably not the most efficient or effective way about it, but the other option is a self hosted plugin update API.Bear in mind, because of GPL, all these hoops and ladders can be circumvented. Your plugin can and […]
By Dave Spencer July 18, 2012 - 2:28 am
Hi Jeremy, hoping for a clue,as I’ve struggling with this for a few hours… :).
The update process works! If I update my version on the server, the plugin update-checking function sees the change and the Plugins screen shows “Update Available (1)”.
The problem is that there is NO change to my plugin row in the Plugins table (except, curiously, the separator line between it and the one below disappears, as if about to give me my “update” line, but stopping short …).
If I click the Updates Available (1), it correctly lists only my plugin and if I tick the checkbox and select Update from the bulk actions, the update works flawlessly.
I just don’t understand why I am not getting the “There is a new version of available . View version 1.1.1 details or update now.”.
The $checked_data being returned in the first function appears to be nicely populated (to me, at least), so I can’t see where the issue might be. This is 3.4.1.
Hoping to get a cuff over the back of the head with something stupidly simple
Dave
By Dave Spencer July 18, 2012 - 5:36 am
PS: just a note to let you know that I found an old 3.0.1 site – loaded ‘er up and everything worked perfectly, so now (tomorrow), I’ll try 3.3 and 3.4 and see where it stops (I know there is a comment above that says 3.4.1 works – but not for me, thus far)
By Dave Spencer July 18, 2012 - 5:47 am
PPS: The plot thickens: If I deactivate my plugin, the offer to update appears (yay). If I activate it again is disappears (along with the separator line).
Clues?
By Dave Spencer July 18, 2012 - 6:11 am
PPPS: I Commented out
//if (empty($checked_data->checked))
//return $checked_data;
And it works …
By Jeremy Clark July 18, 2012 - 8:47 am
Yes I had just discovered this myself, I made some additional notes in the repo here: https://github.com/jeremyclark13/automatic-theme-plugin-update/blob/9774186067c3903ad31a7f5b8d1a38ddf8ec8ff4/plugin/test-plugin-update/test-plugin-update.php
By Dave Spencer July 18, 2012 - 7:02 pm
OK – I’m sure you had those lines in there for a good reason (yeah?). Anyway, it works – and is an excellent piece of code, appreciate your work.
Dave
By Jeremy Clark July 18, 2012 - 7:17 pm
Yes since the plugin version is pulled from the checked_data variable this just checks if it is set and if not skip the rest of the code.
By Eric Schwarz August 17, 2012 - 11:44 am
I noticed that you were posting hear a lot more with help so I thought to just post here too.
I could use your help getting the auto update feature to work with a theme I’m developing. Here’s a link to the theme with the update file placed in it http://semper-fi.schwarttzy.com/files/2012/08/SemperFi.zip and here is the index.php file I’m using http://semper-fi.schwarttzy.com/files/2012/08/index.zip
Would love to hear what I’m doing wrong, and possibly donate if it starts working for me.
By Dietmar October 8, 2012 - 4:18 am
Hi,
first of all Thanx for this great script!!! Unfortunally I can’t get it to work with WordPress 3.4.2. I thought, it was a problem because of the webspace config I have. But I tried it out on a different server with different setup and it doesn’t work there as well. Maybe it is a problem with the newest version of WP?
By Jeremy Clark October 8, 2012 - 8:05 am
I have confirmed that the api does work on 3.4.2, if you’d like to contact me I’d be glad to help you get this going.
By Dietmar November 16, 2012 - 4:41 am
Thanx for the quick reply! I guess it is a problem on my site, not your script… Maybe misconfiguration. But anyway and again: Awesome script!
By gustao November 27, 2012 - 1:05 pm
hello Jeremy, thanks for the great work!
today I turned the debug mode in one site, and I noticed this message error for my plugin (that have the code for the update functions – the last one available on github).
Notice: Undefined variable: wp_version
reading the code, i saw that this variable isn’t declared before.. You had seen it?
cheers!
By Jeremy Clark November 27, 2012 - 9:05 pm
Yes I’ve had another report of this. I’m guessing that earlier versions of WordPress had this as a global and didn’t need to declare it. I’ll be testing both the theme and plugin version for compatiblity with 3.5 so I’ll fix it then and release a new version after that.
By gustao November 27, 2012 - 9:19 pm
Thanks for your attention, Jeremy!
By gustao December 5, 2012 - 8:18 am
Hello Jeremy,
just to you indicate a thing you probably know: calling the $wp_version in the global calls solve the problem.. I changed it and its ok.
eg: global $api_url, $plugin_slug, $wp_version;
another thing: I tried to put the plugin auto-update code in a separate file that is “required once” in the main plugin file, but the auto update didn’t work.. any recommendation for this case?
thanks!
By Jeremy Clark December 5, 2012 - 8:26 am
Yes that’s what I figured would fix the problem, evidently older versions of WP must have declared it global when setting it.
As far as the require_once that should work fine, as long as it isn’t included in another action like plugin init or something like that. I think the filter that is used to catch the update process runs well before plugin init.
By gustao December 5, 2012 - 12:12 pm
I don’t know.. If the problem can be the time that the filter runs, I think that could be necessary choose another one.. Here, with my tests, the updates didn’t work until i put the codes back in the main file..
By Jeremy Clark December 5, 2012 - 12:20 pm
So far I’ve only found the one filter that contains the everything that’s needed for the update check to work. If you’d like to contact me you can send me a copy of you plugin and I can see if I have any more luck with it.
By gustao December 5, 2012 - 9:41 pm
Hello Jeremy,
I’ve replied you via contact form! I used the same email that I used here.
Thanks!
By Josh Lobe December 4, 2012 - 10:18 pm
Hi Jeremy,
I haven’t met you… but wanted to thank you for your wonderful “template” to use. It is, by far, the best one I have found.
I almost have it working… except for one small issue. The plugin always says there is an update… even if the current update is installed. I mean, you could just keep going from updating… back to the plugin page… to a new update message… an endless cycle.
I tried experimenting with different numbers in the versions of the packages.php file… but was unsuccessful.
Have you experienced this before?? And can you provide any guidance??
Thanks again!! It truly is lovely ๐
Btw.. I’m the developer of a plugin called Ultimate Tinymce. I have a pro version.. and this is what I’m trying to implement your code into.
By Jeremy Clark December 5, 2012 - 8:28 am
I’ve replied via your contact form request.
By smedsrud January 4, 2013 - 3:51 am
wonderful stuff! however, can’t get themes to update…
do I have to activate the theme for the update.php to run?
By Jeremy Clark January 4, 2013 - 8:59 pm
Depending on the site setup. On a multisite WordPress install if the theme is activated on at least one site then it will run properly. On a single WordPress install yes the theme has to be active for the update to run properly.
By From Development to Deployment, My WordPress Dev Workflow - Shellcreeper.com January 28, 2013 - 7:48 am
[…] Automatic Theme Plugin Update Script – @GitHub (need fixing, several error, maybe i’ll publish my mod) […]
By mommaroodles February 10, 2013 - 9:33 am
Hello Jeremy, this is truly awesome, just what I have been looking for, many many thanks. I’ve followed your instructions as per the read me file included in the package, I left most of the info as is except for the urls that needed to change and everything is working except for one thing.
In wp admin, plugins where I get the notification that a new version is available – this link – View version 1.0 details – if I click on that link – I get the following which appears just above the tabs
—-
stdClass Object ( [slug] => test-plugin-update [version] => 1.0 [last_updated] => 2010-05-10 [download_link] => http://my-domain.com/extends/download.php?key=6fe789755689171e98174a90de514490 [author] => Melanie [external] => 1 [requires] => 2.8 [tested] => 3.5.1 [homepage] => http://my-domain.com[downloaded] => 1000 [sections] => Array ( [description] => Description of Plugin [installation] => Install Info [screen shots] => Screen Shots [change log] => Change log [faq] => FAQ [other notes] => Other Notes ) )
—–
Have you any idea why that is happening and do you perhaps have a solution? I’d be most greatful to hear from you ๐
By Jeremy Clark February 10, 2013 - 10:02 am
This block of code is what is outputting that to the top of the plugin info screen.
add_filter(‘plugins_api_result’, ‘aaa_result’, 10, 3); function aaa_result($res, $action, $args) { print_r($res); return $res; }
You should be able to just comment that out.
By Vinny February 24, 2013 - 1:26 pm
Hi Jeremy,
Thanks for the awesome API. Here’s a little change I made to `api/index.php` to ensure that the latest version is shown to the user:
if ( is_array( $args ) )
$args = array_to_object( $args );
// Make sure we get the latest version
$versions = $packages[$args->slug]['versions'];
uksort($versions,'version_compare');
$versions = array_reverse($versions);
$latest_package = array_shift( $versions );
Cheers,
Vinny
By Jeremy Clark February 25, 2013 - 8:52 am
Good idea. I had a question about maintaining all the releases in the packages file, this seems like a good solution.
By Vinny February 25, 2013 - 8:59 am
I further modified my copy so that I could store the packages in the DB. That way I only load the plugin versions having the slug passed. The key gets generated when the first call to ‘basic_check’ is made, so that when the time to download comes, I can query by the key. I’m still not sure why you had 2 keys being created in the download section and if just fetching the existing key will cause any issues. Perhaps I could simply change the ‘basic_check’ reply to have slug/version instead of a key.
Do you see any issues that may come from my changes?
Thanks,
Vinny
By Jeremy Clark February 25, 2013 - 9:04 am
I’ve changed how the urls are secured in the latest version. The db was not a good option since every time a check was made a new key was generated. The newest version uses a md5 hash that will only be valid for 2 days. I’m by now means a security expert but this seems to working fine. Because in the end once it’s downloaded one time they have the files and repackage them anyway and distribute them. This just keeps them from using your url to distribute it.
By Vinny February 26, 2013 - 10:18 am
I see your point. Perhaps then the best option in my case would be to add the slug (and perhaps latest version) along with the key to the download URL so that we can query the db for the file and re-generate the key on the fly. I simply don’t want to have to maintain a huge file with all the packages ๐
By Tyson Brooks February 24, 2013 - 3:28 pm
Does anyone have an example of the changes that need to be made in update.php for each theme?
I am developing multiple themes and I can not seem to get all themes to pick up update notifications from my server. It only seems to want to pick up the update for the theme that is currently active, and never touches the other themes.
I have no tried using this setup with multiple plugins as I am more focused on theme development.
By Jeremy Clark February 25, 2013 - 8:49 am
Unfortunately this is the way that it works. WordPress doesn’t load any php files for inactive themes. It only loads the style.css to get the headers from the file. The only time this is different is in a WordPress Multisite install. If the theme is activated on any site of course it’s loaded and the update will show in the network admin screen.
By smedsrud March 20, 2013 - 12:08 pm
hi
im using the theme update and loving it. cannot get the code to notify updates when using on a network install, it only notifies when used on the main blog. any ideas?
By Jeremy Clark March 20, 2013 - 7:27 pm
This is just the way WP multisite works. Updates can only be applied in the network admin which is usually the main site, so the update will only show there.
By smedsrud May 10, 2013 - 3:35 am
oh, didnt mean to see the update notification at the sub site, but it seems to me the theme has to be active at the main site to get notified of updates. ie when the theme is active on a sub site, the main (admin) site does not check for updates. Am I wrong?
By Vinny February 26, 2013 - 11:46 pm
Hi Jeremy,
I might have found a bug in
function plugin_api_call($def, $action, $args) {
global $plugin_slug, $api_url, $wp_version;
if (!isset($args->slug) || ($args->slug != $plugin_slug))
return false;
I’m using classes so I don’t have function name conflicts, and when I tested with 2 plugins having updates, the second plugin to be added to the filters would raise an error when checking the update info.
The fix was to replace $def with $res
function plugin_api_call($res, $action, $args) {
global $plugin_slug, $api_url, $wp_version;
if (!isset($args->slug) || ($args->slug != $plugin_slug))
return $res;
Cheers,
Vinny
By Jeremy Clark February 28, 2013 - 10:57 am
I’ll have to investigate this a little further. Thanks for the report.
By Kishan February 28, 2013 - 7:41 am
I have just used this plugin and its working fine in my local but when i have uploaded it to live server. wp_remote_post returns 500 internal server error in response in the function check_for_plugin_update. I don’t understand why it is giving this error. Please help
By Jeremy Clark February 28, 2013 - 10:24 am
Have you looked in the apache error logs for the api server. This should give you a clue as to what’s going on. I’ve personally tested the api on at least 5 different hosting providers, and I’ve seen a few problems but not 500 errors.
By Kishan February 28, 2013 - 2:31 pm
Yes i have just looked at error log but it haven’t got any idea for this. Here is whats in that file.
[28-Feb-2013 19:14:46] PHP Warning: session_start() [function.session-start]: Cannot send session cookie – headers already sent by (output started at /home/wpsales/public_html/test/wp-content/plugins/test-plugin-update/test-plugin-update.php:31) in /home/wpsales/public_html/test/wp-content/plugins/wp-salesautomator/php/wp-sa-core-function.php on line 10
[28-Feb-2013 19:14:46] PHP Warning: session_start() [function.session-start]: Cannot send session cache limiter – headers already sent (output started at /home/wpsales/public_html/test/wp-content/plugins/test-plugin-update/test-plugin-update.php:31) in /home/wpsales/public_html/test/wp-content/plugins/wp-salesautomator/php/wp-sa-core-function.php on line 10
[28-Feb-2013 19:14:46] PHP Warning: Cannot modify header information – headers already sent by (output started at /home/wpsales/public_html/test/wp-content/plugins/test-plugin-update/test-plugin-update.php:31) in /home/wpsales/public_html/test/wp-content/plugins/wp-salesautomator/php/wp-sa-core-function.php on line 1185
Also here is what i get in update page when i have used print_r($raw_response);
Array ( [headers] => Array ( [date] => Thu, 28 Feb 2013 19:21:25 GMT [server] => Apache/2.2.23 (Unix) mod_ssl/2.2.23 OpenSSL/0.9.8e-fips-rhel5 mod_auth_passthrough/2.1 mod_bwlimited/1.4 FrontPage/5.0.2.2635 mod_qos/10.10 mod_perl/2.0.6 Perl/v5.8.8 [x-powered-by] => PHP/5.2.17 [content-length] => 0 [connection] => close [content-type] => text/html ) [body] => [response] => Array ( [code][/code] => 500 [message] => Internal Server Error ) [cookies] => Array ( ) [filename] => ) Array ( [headers] => Array ( [date] => Thu, 28 Feb 2013 19:21:26 GMT [server] => Apache/2.2.23 (Unix) mod_ssl/2.2.23 OpenSSL/0.9.8e-fips-rhel5 mod_auth_passthrough/2.1 mod_bwlimited/1.4 FrontPage/5.0.2.2635 mod_qos/10.10 mod_perl/2.0.6 Perl/v5.8.8 [x-powered-by] => PHP/5.2.17 [content-length] => 0 [connection] => close [content-type] => text/html ) [body] => [response] => Array ( [code][/code] => 500 [message] => Internal Server Error ) [cookies] => Array ( ) [filename] => )
By Jeremy Clark March 1, 2013 - 7:01 am
What about on the server where the API files are. It’s giving the 500 error so there’s a problem on there somewhere.
By Kishan March 1, 2013 - 10:11 am
Hi,
I got the problem. I have used get_bloginfo() in packages.php which is causing problem.
Thanks for your response.
Regards,
Kishan
By Jeremy Clark March 2, 2013 - 4:00 pm
Glad you figured it out. Since the API is a standalone script package, WordPress functions aren’t defined. I’ve thought about a premium version that uses WordPress to power it.
By Daniel March 2, 2013 - 7:32 pm
Hi there, I’m just wondering if anyone got any tips on getting the wordpress theme updater working? I was able to get the plugin bit going but not for themes.
Thankyou
By Jeremy Clark March 2, 2013 - 8:29 pm
There are a couple places in the theme update file that have some debugging code. Specifically the code about the theme slug. This must match the slug in the packages.php. Also if the theme is a child theme there is a different set of code that has to be uncommented for the update to work. If your still having problems, please feel free to contact me. You can use the link in the footer.
By Daniel March 3, 2013 - 6:54 pm
Hello Jeremy,
Thankyou for the tip, after several attempts to get it going, I finaily made it ๐
By Jeremy Clark March 4, 2013 - 6:34 am
What was the problem, maybe its something I could improve or document better.
By Examining the WordPress Core, Plugin and Theme Update Procedure April 19, 2013 - 3:56 pm
[…] GitHub repository to provide updates for themes and plugins that can’t be submitted to official WordPress repository, ie … commercial themes/plugins/, non-gpl licensed, written for one client. Based on this guide. […]
By Michael April 23, 2013 - 11:22 pm
Found a little gotcha with the new code.
In the packages.php, if you don’t have the timezone specifically set you host env might give you a bunch of warnings because of the date function in the md5 string not knowing which timezone to use (and its best guess).
The update.php will then fail to find an update.
I just added a specific timezone to the top of the packages.php file and everything worked.
Just a heads up and thanks for a cool script!
By ssd cloud servers April 27, 2013 - 3:54 am
I will be truly satisfied with all your way with words-at all plus while using the structure to the website. Is the a new settled topic as well as can you customize the item your self? In any case keep up the excellent quality crafting, it truly is strange to see an awesome weblog such as this one as of late.
By mattib May 12, 2013 - 12:37 pm
Notice: unserialize(): Error at offset 0 of 193 bytes in update.php on line 61 .. what could be the problem?
By Jeremy Clark May 12, 2013 - 5:14 pm
This is caused by the server not returning the expected values. It’s easiest to tell what the problem is if you add this.
after this line
By mos June 4, 2013 - 5:03 am
still havent gotten the theme update on MU site working without activating the theme on the main blog. any pointers to what may cause this?
By Roger MacRae July 4, 2013 - 1:47 am
Hey Jeremy,
I thank you so much for creating this. It works really well and now I can have all my self hosted plugins show they have updates. Awesome, truly awesome.
There is one part that I can’t for the life of me figure out why it doesn’t work. Like I said, I see that there is a new update available and I can even do the update but when I click on View version 3.1.3 details all I get is the following error:
An unexpected error occurred. Something may be wrong with WordPress.org or this serverโs configuration. If you continue to have problems, please try the support forums.
From the error it would seem to me that wordpress.org is being check for the version details even though the update comes from my server. The problem is I don’t know where to change this.
Can you help me please.
By Todd Lahman July 15, 2013 - 4:11 am
There is this commercial Plugin and Theme Update API manager for WooCommerce for those who don’t want to write it yourself, and need a lot of features, plus working examples for plugins and themes that are being sold.
http://www.toddlahman.com/shop/wordpress-automatic-update-api-manager/
By Jeremy Clark July 17, 2013 - 10:13 am
Nice looking solution. Obviously my solution is intended for developers looking for a quick solution, but your solution seems very easy to manage.
By Richard August 20, 2013 - 10:39 am
Hi, the updater creates a directory download.tmp and puts the new theme in their, then links to the stylesheet in there. What am I doing wrong?
Thanks
By Jeremy Clark August 29, 2013 - 12:14 am
This is usually caused by an incorrectly packaged zip file. There should be a folder inside the zip file with the same name as the theme folder. So in essence you’ll have something like this.
theme-name.zip
– theme-name (folder)
– – theme files
By Monirul Hemal August 23, 2013 - 3:41 pm
Hello,
First of all thanks for such a nice solution to make commercial plugins/themes update so easy. I am trying it for my theme. But I am facing a problem. When I include the update.php in my themes functions.php it gives no result. But I take the update.php and use it as a plugin it works. Can you please suggest me how can I make it work by including from functions.php?
By Jeremy Clark August 29, 2013 - 12:16 am
The theme will have to be activated or else the code isn’t ran.
By GregBlack August 28, 2013 - 6:11 pm
I can see the prompt for the update, but when I try and update the download can not be found.
In your example for a theme update, you have:
“package’ => ‘http://url_to_your_site/theme.zip'”.
And in the files from GitHub there is something quite different:
“‘package’ => ‘http://url_to_your_site/download.php?key=’ . md5(‘theme.zip’ . mktime(0,0,0,date(“m”),date(“d”),date(“Y”))),
//file_name is the name of the file in the update folder.
‘file_name’ => ‘theme.zip’, //File name of theme zip file ”
Not sure if this has anything to do with it not being able to find the download. I also tried pointing it to the “plugin.zip” included with the files (there is no theme.zip even though you reference it).
-Greg
By Jeremy Clark August 29, 2013 - 12:21 am
The code that was added was to help secure the download url from being distributed, and abused. In the download.php file there is a variable at the top of the file that needs to be updated to point to the correct location where the zip files are stored. It can even be a location out of the document root of the server for even more security.
By Luba September 8, 2013 - 7:00 am
Hi!
Thank you for a great article and very useful code.
Everything seems to be working. But after downloading package I’m getting this message:
“The package could not be installed. The package contains no files.
Plugin update failed.”
Any idea what can be the problem?
By Jeremy Clark September 8, 2013 - 1:56 pm
This sounds like the zip file is packaged improperly. The zip file should contain a folder with the theme files. The files should not be in the root of the zip file.
By Richard September 8, 2013 - 2:24 pm
Can you tell me why I’m getting this error, please?
Backtrace from warning ‘Undefined property: stdClass::$slug’ at /home/g…/public_html/…… update.php 76:
By Richard September 8, 2013 - 2:47 pm
Solved it. I used get_template_part instead of require_once. I have no idea why that affected it, but there we go.
By Suzanne September 16, 2013 - 11:49 pm
Hey Jeremy – props for this awesome tool. I have it working for my theme and now I’m getting my plugins read. The only thing I can’t figure out is how to better format my plugin tab content. For example, how do you specify a line break? I tried ‘blah blah ‘ . “\n” . ‘more blah’, but that didn’t work. I also tried using tags. That doesn’t work either. I also tried to insert my screenshot using an image tag, it display in the array print, but not on the Screenshots tab of the pop-up window.
By Suzanne September 17, 2013 - 12:05 am
Wait I figured out the visibility issue… in your $package template for plugins, there are spaces in the array variables for screen shots and change log. I had to change those to screen_shots and change_log and then the content for those tabs appeared.
Second looks like p tags work but br tags don’t so we’ll go with p. Thanks again for writing this. Very cool to be able to host your own stuff.
By Jeremy Clark September 17, 2013 - 7:49 pm
Glad you figured it out I’ll definitely make a note on the github page about your findings.
By Roger MacRae September 17, 2013 - 8:21 pm
Suzanne, thanks for noticing the _ thing and posting it here. That one just slipped right by me. Now everything finally works as expected.
By Todd Lahman October 1, 2013 - 4:29 am
Hi Jeremy,
My WooCommerce API Manager just got a big update, and it will be offered in the WooThemes store. I thought you might be interested to see how it’s changed since I last posted here.
http://www.toddlahman.com/shop/wordpress-automatic-update-api-manager/
By Christian Johannesen February 23, 2015 - 9:05 am
Hey Jeremy,
Found this on Github, and it is working wonderfully! I have an issue, I think you can cast some light on. When I update a theme, it deletes the whole file structure and then copies everything from the zip. This is a bit problematic in my case, because every theme has custom code in specific files. That could be front-page.php for an example. Can I somehow tell it to only update/overwrite certain files or the files available in the zip?
Thanks in advance and for some awesome code!
By How to make alert for new version on theme options? | DL-UAT April 18, 2015 - 12:47 pm
[…] http://clark-technet.com/2010/12/wordpress-self-hosted-plugin-update-api […]
By Tejas May 7, 2015 - 5:11 am
Hi Jeremy,
I have tried the code from Github and after running this, it updates the theme.
But after the theme, it is renamed the theme folder to download.tmp
any idea on this issue?
Thanks for the great contribution.
Tejas
By Dave Spencer September 6, 2015 - 5:45 am
Hi Jeremy, I’m not sure if you are still touching up this wonderful code (that I have been using for a few years now – for both plugins and themes), but since about 4.2 we’ve lost the “There is a new version of YourPlugin available” row.
The Plugin row is highlighted to suggest there is an update and it it possible to do the update through the Dashboard updates page, but the row (with a class of .plugin-update-tr) doesn’t get printed (or even called) for some reason.
I’ve located where that row is generated in wp-admin/includes.update.php – there’s a few functions in there that seem to do the work, but we are not getting sent through them at all (whereas conventional plugins, needing updates, are).
This is all a bit beyond me, so I was hoping you could spare some time to take a look and shed some light
Dave
By Dave Spencer September 6, 2015 - 6:31 am
Sadly, your test plugin works perfectly, so the problem lies in my implementation somewhere.
Sob
Dave
By JC November 16, 2016 - 3:30 am
Hi,
Is someone have the list of parameters to add in packages.php to have an image banner (and more custom) in the plugin info iframe ?
Thanks for the job