I have been writing WordPress plugins for a long time, and across these years, I’ve had a few users comment that I push out updates too often on occasion, sometimes almost every day of the week. While this puzzled me at first (why would someone complain about getting too many updates?), I started thinking from their point of view, and quickly saw that it is valid concern.
Whether the person is running a single site or is an integrator maintaining a number of sites for their clients, every update that pops up requires a certain amount of work. Some people will install updates automatically while others will read through the changelog to see decide if an update is worth installing. Most users will look around the site after any updates to make sure that things are still working correctly. All of this takes time.
On the flip side, as a plugin developers, when I get requests from users, I typically want to push out an update to them very quickly, so that they can keep working on their project, especially if what they are asking is a very quick fix. This brought me to think of ways to be able to allow users to choose how often they want updates, similar to how browser like Chrome or Firefox have stable and beta channels, or to how WordPress can be updated more frequently with the WordPress Beta Tester plugin.
Since I recently started using github for my initial plugin code commits, which are later pushed to the wordpress svn, my first thoughts were to push frequent updates to github and have my plugin look there for updates if the user opted in to get all of the updates. However, this goes against the rules of the WordPress.org plugin repository.
The actual solution was suggested by George Stephanis in a facebook discussion: just filter out unwanted updates from the http response that WordPress receives back from the plugin repository.
Here is code showing how I implemented this mechanism in my Link Library plugin:
if ( is_admin() ) { /* Determine update method selected by user under General Settings or under Network Settings */ $updatechannel = 'standard'; if ( !is_multisite() ) { $genoptions = get_option( 'LinkLibraryGeneral' ); if ( !empty( $genoptions['updatechannel'] ) ) { $updatechannel = $genoptions['updatechannel']; } } else if ( is_multisite() ) { $networkoptions = get_site_option( 'LinkLibraryNetworkOptions' ); if ( isset( $networkoptions ) && !empty( $networkoptions['updatechannel'] ) ) { $updatechannel = $networkoptions['updatechannel']; } } /* Install filter is user selected monthly updates to filter out dot dot dot minor releases (e.g. 5.8.8.x) */ if ( 'monthly' == $updatechannel ) { add_filter( 'http_response', 'link_library_tweak_plugins_http_filter', 10, 3 ); } } function link_library_tweak_plugins_http_filter( $response, $r, $url ) { if ( stristr( $url, 'api.wordpress.org/plugins/update-check/1.1' ) ) { $wpapi_response = json_decode( $response['body'] ); $wpapi_response->plugins = link_library_modify_http_response( $wpapi_response->plugins ); $response['body'] = json_encode( $wpapi_response ); } return $response; } function link_library_modify_http_response( $plugins_response ) { foreach ( $plugins_response as $response_key => $plugin_response ) { if ( plugin_basename(__FILE__) == $plugin_response->plugin ) { if ( 3 <= substr_count( $plugin_response->new_version, '.' ) ) { unset( $plugins_response->$response_key ); } } } return $plugins_response; }
In short, this code checks to see what update frequency the user selected. This check is different depending on whether the site is running a single site installation or a network installation. If the user selected only to receive monthly updates, a filter is added to modify http responses received by WordPress.
Then, when a response is received, the link_library_tweak_plugins_http_filter function checks to see if function was called after querying the Plugin Check API from WordPress.org. If that is the case, it decodes the json response and sends the plugins data to another function, link_library_modify_http_response. That function cycles through each plugin response object, checking if the plugin is the same as its name. If it is, it checks if the version number contains 3 or more periods. If so, it removes that data from the response. Of course, you could check for more or less periods depending on the depth of updates that you are looking at filtering out. Once all entries are processed, the resulting object is sent back to be json encoded and passed back to WordPress.
I did not put the admin panel code that was used to set the LinkLibraryGeneral options array. For users running network sites, I placed the option to select the update frequency under a small settings panel that is only visible in the network admin as a site option.
I hope you will find this code sample helpful in your plugin development.