Must-use plugins autoloader: How to use get_plugins() correctly?

My autoloader class is responsible for loading must-use plugins that do not sit in the root of the mu-plugins folder. To locate them, I need to use the get_plugins() function. According to Codex, the function accepts one parameter:

$plugin_folder (string) (optional): Relative path to single plugin folder.

My file hierarchy looks like this:

|-- /mu-plugins
|   |-- autoload.php                    // only includes wpmu/autoload.php
|   |-- /wpmu
|   |   |-- autoload.php                // uses **get_plugins()** and autoloads other MU plugins
|   |-- /mu-plugin-to-autoload-A
|   |   |-- plugin-file-to-autoload.php // this plugin file should be autoloaded
|   |-- /mu-plugin-to-autoload-B
|   |   |-- plugin-file-to-autoload.php // this plugin file should be autoloaded

I thought I should go at it this way:

// array to store plugins
$plugins = [];
// get mu-plugin folders
$plugin_dirs = glob(WPMU_PLUGIN_DIR . '/*' , GLOB_ONLYDIR);
// loop through mu-plugin folders
foreach ($plugin_dirs as $plugin_dir) {
    $plugins[] = get_plugins($plugin_dir);
}

However get_plugins() function returns an empty array.

I want to achieve similar functionality as SĂ©bastien Lavoie did in his Gist on GitHub. Its script should sit on the root of WPMU folder, as it uses get_plugins('/../mu-plugins'), which I do not understand at all (does it move back and forth to wpmu plugins folder?).

$plugins = array();
foreach (get_plugins('/../mu-plugins') as $plugin_file => $data) {
    if (dirname($plugin_file) != '.') { // skip files directly at root
        $plugins[] = $plugin_file;
    }
}

Nevertheless, it works (as I’ve tested it).

I hope all makes sense. 🙂

1 Answer
1

‘get_plugins’ is intended to be used only with regular plugins, and also it looks at plugin headers, and return only plugins that have valid one, like

/* Plugin Name: A plugin */

However mu-plugins can work even without that headers.

Also consider that with WP 3.9 was introduced the function wp_register_plugin_realpath that should be used to ensure compatibility with symbolink linked folders.

According to a post of Ryan McCue on make.wordpress.org a sinple, but working mu plugins loader should be something like this:

<?php
$plugins = array(
    'my-mu-plugin/my-mu-plugin.php'
);
foreach ( $plugins as $plugin ) {
    $path = dirname( __FILE__ ) . "https://wordpress.stackexchange.com/" . $plugin;
    // Add this line to ensure mu-plugins subdirectories can be symlinked
    wp_register_plugin_realpath( $path );
    include $path;
}

The $plugins array here is hardcoded. Sincerly I found this approach more functional than the glob + get_plugins

because:

  • it’s faster
  • it works for mu plugins that does not have any plugins header

Sure it need to manually add a line on the array every time you install a new plugin, but imho this is not a great issue, and also gives ability to easily deactivate a mu plugin.

Leave a Comment