WordPress plugin development: Versions and updates

It is with some humility that I write this post. A recent update to EPS 301 Redirects has shed a lot of light on how to properly code your update functions, and handle version control. Because this update had some very significant updates (it’s almost a complete rewrite) it was important that the plugin update seamlessly, however… It didn’t. And here’s what I learned.

1. Activation Hooks

First, good practice is to create a constant for your current plugin version, and create an activation and deactivation hook for your plugin. This allows you to check things like version numbers, and do some general initialization.

define ( 'MY_PLUGIN_VERSION', '2.0.0');

register_activation_hook(__FILE__, 'my_plugin_activation'));
register_deactivation_hook(__FILE__, 'my_plugin_deactivation'));
function my_plugin_activation() {
// Initialize some stuff for my_plugin
}
function my_plugin_deactivation() {
// Welp, I've been deactivated - are there some things I should clean up?
}

Here is an example of a typical update function:

function my_plugin_activation() {
$version = get_option( 'my_plugin_version' );

if( version_compare($version, '2.0.0', '<')) {
    // Do some special things when we update to 2.0.0.
}

update_option( 'my_plugin_version', MY_PLUGIN_VERSION );
return MY_PLUGIN_VERSION;
}

Notice that we are storing our plugin version in the WordPress options table. We retrieve that, and use a special php function version_compare to compare our stored version and the current version. You can write any conditionals you need at this point. Afterwards, we update the stored version to the current version, and we are essentially done the update process.

However, my first mistake was expecting the WordPress function register_activation_hook to fire when a plugin is updated. IT DOES NOT. It is only called when a plugin is activated through the Plugins page in the WordPress admin – and at no other time.

2. So how do we Update our plugin?

There is no hook for when your plugin is updated. You, as a plugin author, have to manually check the plugin version. First, you want to create a simple function which will tell you if your plugin is up to date:

function my_plugin_is_current_version(){
    $version = get_option( 'my_plugin_version' );
    return version_compare($version, MY_PLUGIN_VERSION, '=') ? true : false;
}

Then, test if your plugin is up to date, and call your update function (or in this case we call the same function as we would if the plugin was updated!):

   if ( !my_plugin_is_current_version() ) my_plugin_activation();

The big lesson here is understanding that plugins are not deactivated and reactivated when updated, therefore register_activation_hook is not called on updates. You must manually check your versions and handle them.

3. Testing updates and activations

Testing the update process from one version to the next is not all that complicated, though it is kinda cumbersome. Maybe someone has a better way, if so please tell me!

You can’t really see any errors when you activate a plugin, so the first step is to create a very simple hook to store plugin activation errors. In this case, we store these errors in error_activation.html in the plugin folder:

add_action('activated_plugin', 'my_plugin_activation_error');
my_plugin_activation_error() {
    file_put_contents( plugin_dir_path(__FILE__) . '/error_activation.html', ob_get_contents());
}

1. Testing Activation
For when a user Activates your plugin from the Plugins page in the WordPress admin:

  1. Have both versions of your plugin (old and current) readily available.
  2. Start with your old version activated, and deactivate it.
  3. Replace your old plugin with your new plugin version.
  4. Reactivate.
  5. Review any errors in error_activation.html
  6. Ensure that any update processes have successfully ran, and that the activation was a success.

2. Testing Updates
For when a user Updates your plugin.

  1. Have both versions of your plugin (old and current) readily available.
  2. Start with your old version activated.
  3. Replace your old plugin with your new plugin version.
  4. Ensure that any update processes have successfully ran, and that the activation was a success.

Once you have tested extensively, and you’re 100% confident your update process is error-free, launch your plugin to the world!