WordPress Plugin Update and Install Functions

On the page where they explain how to create tables for your plugin, there’s a link to the register_activation_hook function, which is run when the plugin is activated. However, right in the first section, it says:

Note: Don’t use activation hooks (especially for multisite). Do this instead:

It’s far better to use an upgrade routine fired on admin_init, and handle that per-site, basing it on a stored option.

That links to another page, which repeats the information, but doesn’t tell you how to do this. Here’s one way.

This is how I did it:

    add_action('admin_init', 'update');
    function update() {
        $revision = 3;
        $opt = get_option('dmpm_revision');
        if ( $opt == false ) {
            add_option( 'dmpm_revision', $revision, null, 'no' );
        } 
        if (intval($opt) < $revision or $opt == false) {
            create_tables();
            update_option('dmpm_revision', $revision);
        }
    }

You store the code revision number in the Options, and then retrieve it to see if the revision has changed. If it has, run the installation function.

Of course, this isn’t enough. You need to manage each upgrade separately, so if you go from revision 3 to 4, there’s a revision function, like update_3_to_4() that will perform all the work required to move from 3 to 4. These need to be stored in an internal database (stored in an array) that looks like this:

| from | to |      function |
|------+----+---------------|
|  3   |  4 | update_3_to_4 |
|  4   |  9 | update_4_to_9 |

Then, to perform updates, you first scan down the “from” column to find your old revision, or, if there isn’t an exact match, a revision that’s older than your revision. Then, execute all the functions after that.

The “to” column is basically superfluous, but I think it’s good to record that information for completeness.

Other Techniques

Sitepoint has a slightly different way. I don’t really like the idea of using version numbers, because they look like “1.2.3” and you need a semver library to read those things. Also, the semantics don’t actually have any meaning to the developers: things like bugfixes can cause changes to the database state, and require running update code.

Even if we somehow manage to never change the tables on a revision that changes only the third number, you may need to change the contents in the tables. IMNSHO it’s a moot point – the odds are, at some point, you will alter the table structure on a bugfix. Data tables have a lot of settings, and you may forget to set one.

So, I prefer integer revision numbers that always increase, and are not coupled to the semver. The semver is really for the application administrator and package manager software.

Sitepoint’s function runs on all page loads. The version I used only runs when someone logs into the admin. With this latter technique, it’s possible that the plugin’s code will be updated, but the tables or data in them aren’t updated. I feel this is an outlier scenario; most WordPress installations don’t use FTP to load plugins.

Auto Updates

This technique should work with auto updates, but if you don’t have your code in the WP Plugins directory, here’s an article showing how to enable auto updating for code not in the WP Plugin directory.

Leave a Reply