WordPress Plugin Updates the Right Way

Share this article

Some weeks ago, I received an email about WP Photo Sphere, a WordPress plugin I developed. There was a big problem: updating the plugin broke it on some installations. After some investigation, I discovered that the problem came from the options used by the plugin: these installations hadn’t any default values for the new options I added.

WordPress Plugin Updates

These values were important, so I needed a way to create the default values. But, contrary to what I thought, WordPress doesn’t provide any native way to handle an update process.

That’s why I thought of writing this tutorial. First, we’ll see exactly why we need an update process and why WordPress doesn’t provide such a process. Then I’ll show you how to properly create your own process to update your options.

Why an Update Process for Your Plugin Is Important

Often, changing files is not enough to properly update something. For example, when you manually update the WordPress files to a new version, the platform will ask you to hit a button to update the database too.

Assume that you use options in your plugin. As your plugin evolves, you’ll need more options in new versions. Creating new options when a user activates your plugin for the first time is easy, you just have to use the activation hook.

For example, let’s look at the following code.

function my_awesome_plugin_activation() {
    update_option('my_awesome_plugin_option', 'default value');
}
register_activation_hook(__FILE__, 'my_awesome_plugin_activation');

If you’re unfamiliar with using update_option() instead of add_option(), don’t worry, we’ll explain it later, when we’ll look at how to handle our update process.

If you want a new option, or if you update the value of an existing option in a new version, you need to update the database of users who already use your plugin, so we need a function called right after the update.

The activation hook can seem a bit confusing. After all, when you automatically update a plugin, it is deactivated and reactivated, so we could expect this hook to be called. But it’s not the case.

To be more precise, it was, but WordPress stopped this behavior in version 3.1. The development team explained this choice, and you can read the entire explanation on the Make WordPress Core blog. The main reason is that it wasn’t called every time is that if a user manually updates a plugin, the activation hook can be skipped.

So WordPress doesn’t provide a default way to automatically call a function right after a plugin update. That’s why you’ll need to build your own process.

How To Handle an Update Process

In this part of the tutorial I’ll show you how to automatically call a given function right after an update of your plugin. We’ll see in the next part how to properly handle the updates of existing options, and the creation of new ones (in the same function).

The Principle of this Method

The global principle of our method will be that we’ll store the version number of our plugin in two places: in a constant in the main file of the plugin, and in an option in the database.

The number in the database will store the version currently installed by the user, while the number in the constant is the current version. If these two numbers are different, then the database options have not been updated since the last plugin update, so we’ll need to do it.

In this case, we call a function that updates all the necessary options. This function also updates the version number stored in the database: that way, we won’t call this function more than necessary.

The Constant

Now that we’ve covered what we’ll do, it’s time to code! First, add a constant definition in the main file of your plugin, with your current version number as a value. In order to prevent any problems, we test if it does not exit yet.

if (!defined('MY_AWESOME_PLUGIN_VERSION'))
    define('MY_AWESOME_PLUGIN_VERSION', '3.4.1');

Usually, plugin versions are identified with numbers but, if you use another system, feel free to use it. The only constraint here is to have a unique identifier for each version or, at least, for each version which requires changes in the database (new options, new default values, etc.).

The Checking Function

We need now to write a function that will check if the database needs to be updated. This function will compare the previously defined constant with the value currently stored in the database. To do that, we’ll make sure that our function is called everywhere, with the action plugins_loaded, triggered once all the plugins are loaded.

function my_awesome_plugin_check_version() {
}

add_action('plugins_loaded', 'my_awesome_plugin_check_version');

This function will be simple. We retrieve the version number stored in the database, as any other option, and we compare it to the constant. If these values are different, we call the my_awesome_plugin_activation() function.

if (MY_AWESOME_PLUGIN_VERSION !== get_option('my_awesome_plugin_version'))
    my_awesome_plugin_activation();

Now, there are some questions we need to clarify. First, what if the option doesn’t exist in the database yet? If the option doesn’t exist, get_option() returns false, which is different from your version number, so the function will be called.

So why do we call the activation function? To be clear, we could create a new function, dedicated to the update process. But, if you do this, you’ll see that this new function will be very similar to activation, as updating an option can be achieved the same way we create one.

Updating the Version Number in the Database

You can do whatever you want in the activation function called above. However, there is one thing needed, updating the version number stored in the database. That way, we won’t call our function every time a page is loaded.

update_option('my_awesome_plugin_version', MY_AWESOME_PLUGIN_VERSION);

Note the trick: we don’t use add_option(), just update_option(). In fact, if the option does not exist yet, update_option() will create it. If it exists, it will update its value to the indicated one. That’s why we can use our activation function as an update function without any problem.

Updating Options

Don’t Override Users’ Choices!

Updating any option can be done the same way we updated the version number: you call update_option(), and you’re done, even if it’s the first time WordPress sees the option.

However, we don’t always want to update the options values. In fact, if you use options, it’s often for letting your users personalize settings. By using update_option() you’ll override the users’ choices every time you update the plugin, which is not what we want to do.

Above, we saw that get_option() returns false if the option doesn’t exist. We’ll use this behavior to test if the option we want to update exists in the database. If this is the case, we don’t do anything. Otherwise, we create the option.

if (get_option('my_awesome_option') === false)
    update_option('my_awesome_option', 'my_value');

Note that this test is necessary for options you don’t want to override. In some cases, we might want to do this, think about the version number, where we surely don’t want to keep the old value!

A Special Case – Arrays

You should know that WordPress allows arrays to store values for our options, and creating them is not any more difficult that creating other options. For example:

update_option('my_awesome_plugin_settings', array(
    'awesome_titles' => true,
    'any_number' => 7
));

Using arrays is a good idea if you need several settings. That way, you don’t use a lot of entries in the database, and you limit the chances to have an option with the same name used by another plugin. However, this can cause issues when we think about the update process.

To understand why, assume that you have an array as an option, with some keys. Your users will surely personalize these values. With the test we did above, we can create the option only if it does not exist, and these choices won’t be overridden. It seems straightforward, but what if you want to create a new key in your array?

If the option exists in the database, the previous code won’t create it, so your new key won’t exist. But if we erase the condition, the array will retrieve its default values with each new update. Not ideal. Fortunately, there’s a solution!

First, we define an array containing the default values of our options (with the new keys if they exist).

$default = array(
    'awesome_title' => true,
    'any_number' => 7,
    'new_option' => 'default'
)

Then, we retrieve the array currently stored in the database.

$option = get_option('my_awesome_plugin_settings');

Now we can use the PHP function array_merge(), with our default values array as the first parameter, and the user’s values array as the second one. That way, we’ll get an array containing all of the keys defined in the $default array and we won’t have any non-existing options. If the user has changed one of the old options, their values will be kept. With array_merge() we always keep the latest definition.

$option_to_store = array_merge($default, $option);

Finally, we store the result in the database with update_option().

update_option('my_awesome_plugin_settings', $option_to_store);

We’re close to the end, but we now need to fix a bug that you can run into if the function is executed for the very first time.

This function is called when the plugin is activated, that’s what we want. But, in this case, the option does not exist yet, so get_option() returns false. The problem is that using false as a parameter for array_merge() will cause an error.

What we want is simple, if the option doesn’t exist, we want $option to be an empty array. For that, we can use the second parameter of get_option() which represents the default value to get (in order to not return false).

$option = get_option('my_awesome_plugin_settings', array());

Conclusion

Once you’ve gone over it, handling the update process for a WordPress plugin is not overly complicated. However, it’s important if you use options, since not initializing options can cause some problems.

Currently, WordPress doesn’t provide a native way to handling plugin updates. The fact is, considering the problems we listed above, if we see this type of feature introduced one day, it should be implemented in a similar way to this tutorial.

You can get the code for my example plugin here. Treat this code as a skeleton for you to implement your own WordPress plugin update process. If you have any feedback, please let me know in the comments below.

Frequently Asked Questions (FAQs) about WordPress Plugin Updates

What is the importance of updating WordPress plugins regularly?

Regularly updating WordPress plugins is crucial for several reasons. Firstly, updates often include new features and functionalities that can enhance your website’s performance. Secondly, updates often fix bugs and vulnerabilities that could potentially compromise your website’s security. Lastly, updates ensure compatibility with the latest version of WordPress, ensuring your website runs smoothly and efficiently.

How can I ensure a safe update of my WordPress plugins?

To ensure a safe update, always backup your website before initiating the update process. This way, if anything goes wrong during the update, you can easily restore your website to its previous state. Additionally, it’s advisable to test the update on a staging site before applying it to your live site.

What should I do if a plugin update fails?

If a plugin update fails, the first step is to restore your website from a backup. Then, try to identify the cause of the failure. It could be due to a conflict with another plugin or theme, or a compatibility issue with your version of WordPress. Once you’ve identified the issue, you can either fix it yourself or contact the plugin developer for assistance.

How can I automate the process of updating WordPress plugins?

WordPress has a built-in feature that allows you to automatically update your plugins. You can enable this feature by going to the ‘Plugins’ section in your WordPress dashboard, selecting the plugins you want to auto-update, and clicking on ‘Enable auto-updates’.

Can I rollback a plugin update if it causes issues on my website?

Yes, you can rollback a plugin update if it causes issues on your website. There are several plugins available, such as WP Rollback, that allow you to easily revert to a previous version of a plugin.

How can I update a premium WordPress plugin?

Premium WordPress plugins can be updated in a similar way to free plugins. However, you’ll need to have a valid license key to access the updates. Once you’ve entered your license key, you can update the plugin from your WordPress dashboard.

What is the best way to manage updates for multiple WordPress websites?

If you’re managing multiple WordPress websites, it can be time-consuming to update plugins individually for each site. A more efficient approach is to use a WordPress management tool, such as ManageWP or MainWP, which allows you to manage updates for all your sites from a single dashboard.

How can I disable automatic updates for specific WordPress plugins?

If you want to disable automatic updates for specific plugins, you can do so by using a plugin like Easy Updates Manager. This plugin allows you to control automatic updates for each individual plugin on your site.

How can I check the compatibility of a plugin update with my version of WordPress?

Before updating a plugin, you can check its compatibility with your version of WordPress by visiting the plugin’s page on the WordPress Plugin Directory. Here, you’ll find information about the plugin’s compatibility with different versions of WordPress.

What should I do if a plugin update breaks my website?

If a plugin update breaks your website, the first step is to restore your website from a backup. Then, deactivate the plugin that caused the issue. If you can’t access your WordPress dashboard, you can deactivate the plugin via FTP by renaming the plugin’s folder in the wp-content/plugins directory. Once the plugin is deactivated, you can troubleshoot the issue or contact the plugin developer for assistance.

Jérémy HeleineJérémy Heleine
View Author

Currently a math student, Jérémy is a passionate guy who is interested in many fields, particularly in the high tech world for which he covers the news everyday on some blogs, and web development which takes much of his free time. He loves learning new things and sharing his knowledge with others.

ChrisBplugin developmentplugin updateplugin upgradeupdatingWordPresswordpress development
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week