Changing Plugin Load Order

I’m writing a plugin, bar, which is dependent on another plugin, foo, being activated, and I need the functions from foo to be available when bar loads. Normally plugins are loaded in alphabetical order based on the directory name, so bar is loaded before foo. If I rename the bar directory to zbar then it gets loaded last and works fine, but I’m looking for a more elegant and correct solution.

I’ve followed jsdalton’s method of altering the active_plugins option, and it is reordering the array to place bar at the end, but bar still can’t access foo‘s functions when it instantiates. I’ve read through the relevant core code — basically wp-settings.php and wp_get_active_and_valid_plugins() in wp-includesload.php — and it seems like plugins should be loaded in the order they’re indexed inside active_plugins, so I can’t figure out what’s going wrong.

Read More

This is on a MultiSite installation. bar is a class and foo is procedural.

Here’s a stripped-down version of foo/foo.php

function foo()
{
    // stuff
}

And here’s a stripped-down version of bar/bar.php

class bar
{
    public function __construct()
    {
        // ...

        $active_plugins = get_option('active_plugins');
        print_r($active_plugins);

        if( function_exists('foo') )
            wp_die("foo exists");
        else
            wp_die("foo doesn't exist yet");
        }
    }
}

function this_plugin_last() 
{
    $wp_path_to_this_file = preg_replace('/(.*)plugins/(.*)$/', WP_PLUGIN_DIR."/$2", __FILE__);
    $this_plugin = plugin_basename(trim($wp_path_to_this_file));
    $active_plugins = get_option('active_plugins');
    $this_plugin_key = array_search($this_plugin, $active_plugins);

    if ($this_plugin_key) 
    {
        array_splice($active_plugins, $this_plugin_key, 1);
        array_push($active_plugins, $this_plugin);
        update_option('active_plugins', $active_plugins);
    }
}
add_action("plugins_loaded", "this_plugin_last");

$bar = new bar();

This is the output from bar‘s constructor:

Array
(
    [0] => foo/foo.php
    [1] => bar/bar.php
)

foo doesn't exist yet

Related posts

Leave a Reply

3 comments

  1. No matter what, your constructor of bar will always run before the action is called in your code.

    I ran into this scenario a while back, and you’re mostly there for how I did it.

    Simply put – comment out everything inside this_plugin_last function, and put your $bar = new bar(); inside there. and just do all of the logic and whatnot that you needed to in that function as well. this ensures that foo will be loaded before you run your code (the plugin itself doesn’t necessarily need to be loaded before hand, just what you use that relies on foo).

  2. Add the following at the top of the dependent plugin code, below the plugin name, description, etc:

    require_once( WP_PLUGIN_DIR . '/foo/foo.php' );
    

    The “foo” plugin won’t even need to be activated for “bar” to find the code.