Changing WordPress Plugin Load Order

The Problem

You need a plugin to load before other plugins, but, by default, WordPress loads plugins alphabetically.

Breakdown

There are essentially two parts to this:

  • Plugin Load Order
  • The firing of any events related to that plugin

Plugin Load Order

The order plugins are loaded is dictated by an array stored in the wp_options table.
The option name is called ‘active_plugins‘.
When a plugin is activated:

  • It is added to the array.
  • The array is sorted alphabetically.
  • Then saved to the options table.

This all happens in /wp-admin/includes/plugin.php (lines 594-603):

	if ( $network_wide ) {
		$current = get_site_option( 'active_sitewide_plugins', array() );
		$current[$plugin] = time();
		update_site_option( 'active_sitewide_plugins', $current );
	} else {
		$current = get_option( 'active_plugins', array() );
		$current[] = $plugin;
		sort($current);
		update_option('active_plugins', $current);
	}

Immediately after this block of code a hook is fired.

/**
 * Fires after a plugin has been activated.
 *
 * If a plugin is silently activated (such as during an update),
 * this hook does not fire.
 *
 * @since 2.9.0
 *
 * @param string $plugin       Plugin path to main plugin file with plugin data.
 * @param bool   $network_wide Whether to enable the plugin for all sites in the network
 *                             or just the current site. Multisite only. Default is false.
 */
do_action( 'activated_plugin', $plugin, $network_wide );

Note: This hook will not fire if silently activated. See comment above hook.

With this knowledge it should be pretty easy to set an action to override the alpha sort.

Here’s a quick and dirty (and untested) override example.
Lets say we want to change the order so the WP Super Cache plugin loads first.
Here is the untested code to make that happen:

/**
 * Action callback to reprioritize plugin load order.
 *
 * @return void
 */
function boost_plugin_load_priority() {
	// Set plugin names we want to load first.
	$priority_plugins = [ 'wp-super-cache' ];
	// Get active plugin array.
	$active_plugins = (array) get_option( 'active_plugins', array() );
	// Get the priority plugins that are actually active.
	$active_priority = array_intersect( $priority_plugins, $active_plugins );
	// Perform an array union to merge the two lists.
	$prioritized_active_plugins = array_unique( array_merge( $active_priority, $active_plugins ) );
	// Save newly minted list of active plugins in proper load order.
	update_option( 'active_plugins', $prioritized_active_plugins );
}
add_action( 'activated_plugin', 'boost_plugin_load_priority' );

Change the $priority_plugins array to whatever plugins you want loaded first. You should use the plugin’s slug value as the array entry’s value.

Event Firing Order

If you want a certain plugin’s action or filter callbacks to fire before any other plugin’s callbacks on the same hook, you just need to change the priority in the add_action()/add_filter() call, which is the third parameter for both those functions.

add_action( string $tag, callable $function_to_add, int $priority = 10, int $accepted_args = 1 )

The default priority for an action or filter call is 10. The lower the number, the higher the priority and the earlier the execution. Callbacks that have the same priority are executed in the order they were added to the action hook.

In this case:

add_action( 'my_hook', 'my_callback', 5, 1 )

The priority value of 5 being higher than the default value of 10 will generally boost the action to be run earlier than the other callbacks assigned to the my_hook hook.

Hope this was helpful!


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *