Support loading mu_plugins from subdirectories
|Reported by:||benward||Owned by:||benward|
|Severity:||normal||Keywords:||plugins, mu_plugins, subdirectory|
Aim: Enhance the load_mu_plugins mechanism to support loading plugins from inside subdirectories in WPMU_PLUGIN_DIR, in both initialization and plugins administration interface.
Why: We (Yahoo, hello) are making substantial use of the mu-plugins mechanism to extend WordPress functionality at a deployment level, adding core product/instance functionality to a as part of the code deployment, rather than features that are enabled through the GUI. (e.g. Authentication, custom input filtering, integration with low level options configuration systems we have.) Each such enhancement is modular, and some wrap additional libraries, so all of our ‘must-use’ plugins are packaged in separate directories. WordPress, as of now, does not load must-use plugins from subdirectories.
Thus, we have one root must-use plugin that recursively loads plugins from subdirectories. This has the disadvantage that those sub-directory plugins then aren't listed in the Plugins UI, and it's all a bit of a hack.
I'm working on a patch to improve the mu-plugin loading to support single-subdirectory loading, _similar_ to regular plugins. The components of this are:
- Patch wp-admin/includes/plugin.php:get_plugins() to accept $plugin_root as a parameter—either WP_PLUGIN_DIR or WPMU_PLUGIN_DIR—and build a cache key using that path rather than fixed plugins key.
- Patch wp-admin/includes/plugin.php:get_mu_plugins() to call get_plugins() specifying WPMU_PLUGIN_DIR as the $plugin_root. This loads subdirectory plugins with details into the admin UI.
- From wp-admin/includes/plugin.php:get_plugins() refactor the recursive directory listing code into a non-admin get_plugins() method in wp-includes/load.php, since it is needed to load the mu-plugins.
- Patch load.php:wp_get_mu_plugins() to grab plugin files from WPMU_PLUGINS_DIR and subdirectories, using refactoring file-listing function from \#3.
In writing this I quickly hit on why WordPress treats mu-plugins so simply already: Regular plugins are examined for metadata to check their validity, regardless of filename, and then active plugins are stored as an option and cached. Since must-use plugins are not stored in an option, and since caching is not a default feature of WordPress, mu-plugin loading cannot require calling /wp-admin/includes/plugin.php:get_plugin_data() on every load. As such, I'm currently working with a new, but I think more reasonable structure limitation for mu-plugins: That the main file for a subdirectory-based mu-plugin must be named the same as its containing directory: That is, the ./yahoo_example plugin must be initialized by ./yahoo_example/yahoo_example.php. This pattern seems to match how many plugins already package themselves anyway.
That said, I am interested to hear other suggestions on how to load from mu_plugins without introducing a performance hit.
I'm posting this bug to describe my fix. I'm testing the patch at present and will attach it for review/comment after a couple of immediate kinks are ironed out.