WordPress fires and activation action when a plugin is activated. Or at least it should. To be notified of its activation, a plugin can register itself to that even, using the register_activation_hook() function.

There are some background concept that must be clear before start to use that action. It is not always as natural as it seems.

How WordPress Activates a Plugin

When you press the “activate” button on one fo the installed plugin, WordPress runs a sequance like that:

  • invoke a special administration page with the request to activate a specific plugin
  • that page loads completely WordPress so each active plugin is loaded
  • WordPress fires the init event which is usually hooked by plugin to initialize them self
  • The plugin to be activated is loaded (its main file is included)
  • The activation action for that plugin is fired

There are some other steps, checks and actions but their are not relevant for us in this moment.

The plugin which is going to be activated is late-loaded and every action fired before it is loaded cannot be hooked by that plugin. For example, for that plugin the init action is not fired while activating.

That brings to the necessity to register the activation hook function at load time. So it can be registered in the main file as a single direct PHP line of code, or added inside a class construction, state that the class is instantiated when the main file id loaded.

Check out those code examples:

register_activation_hook(__FILE__, [function name]);
class MyPlugin {
  function __constructor() {
    register_activation_hook(__FILE__, [method callback]); 
  }
}

new MyPlugin();

(the examples even if working are simplified, a singleton pattern could be used and the function mane in the first example could be a static method of a class, and so on…)

The activation action is not fired on every activation

The activation can be silent: the plugin could be activated (for example during an automatic upgrade) without having the activation even fired for that plugin.

That is, just my opinion, a bad behavior, since the activation event should be used to communicate to the plugin a status change letting the plugin to act, if required.

If you rely on the activation event to run upgrade code, you should not. It’s much better to save the last plugin version and compare it to the current version on administration context (you can use is_admin()) to avoid that check on every blog visit.

I would add that check even during the cron execution (you can use the is_doing_cron() function) to condition the version check.

Version check tips

To verify a version change you need to store somewhere the “latest version”. For example I use an entry in the options table named myprefix_version.

You plugin has a current version, the number written in the plugin main file headers. You can get it in many ways, for example reading it with plugin_data() or getting the list of active plugins and so on. Probably the less expensive way is to check the main plugin file modification date and use that as version.

$old_version = get_option('myprefix_version', 0);
$current_version = filemtime(__FILE__);
if ($old_version != $current_version) {
  // run upgrade code
}
update_option('myprefix_version', $current_version, false);  

This technique grant to sun the update code even when the plugin is changed by a direct upload via FTP (you should know how many time users updated my plugin via FTP, hence without activating the activation process) and they stopped to work because the database was not updated or other one-time code never executed.

Optimization ideas

Register the activation hook for a plugin on every page load (public or administrative) is a waste of time and resources. And, as said, you cannot be sure the activation is ran every time the plugin is activated.

Looking the the WP code (version 5.3) there are not safe ways to late-register that hook under a condition (like a defined constant).

A good solution would be to move to OOP even the plugins area of WP, providing a base class to declare a plugin with some predefined method (for example “activate”) to be called by WP only when needed.

Being an old time Java coder, I really miss that! :-)

Similar Posts

Leave a Reply