Last active
August 10, 2017 10:21
-
-
Save felixarntz/9b3bed66099641a45ce437b067fea547 to your computer and use it in GitHub Desktop.
WP Scoped MU Plugin Loader
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
Plugin Name: WP Scoped MU Plugin Loader | |
Plugin URI: https://gist.github.com/felixarntz/9b3bed66099641a45ce437b067fea547 | |
Description: Loads scoped MU plugins for specific sites or networks for an improved organization of those more specific tweaks. | |
Version: 1.0.0 | |
Author: Felix Arntz | |
Author URI: https://leaves-and-love.net | |
License: GNU General Public License v2 | |
License URI: http://www.gnu.org/licenses/gpl-2.0.html | |
*/ | |
/** | |
* Class used for loading scoped MU plugins | |
* | |
* @since 1.0.0 | |
*/ | |
class WP_Scoped_MU_Plugin_Loader { | |
/** | |
* Directory name for network-wide MU plugins. | |
* | |
* @since 1.0.0 | |
* @var string | |
*/ | |
const NETWORKWIDE_DIR = 'network-wide'; | |
/** | |
* Directory name for site-wide MU plugins. | |
* | |
* @since 1.0.0 | |
* @var string | |
*/ | |
const SITEWIDE_DIR = 'site-wide'; | |
/** | |
* Base directory to look for scoped MU plugins. | |
* | |
* @since 1.0.0 | |
* @var string | |
*/ | |
private $basedir; | |
/** | |
* Constructor. | |
* | |
* Sets the base directory property. | |
* | |
* @since 1.0.0 | |
* | |
* @param string $basedir Base directory to look for scoped MU plugins. | |
*/ | |
public function __construct( $basedir ) { | |
$this->basedir = trailingslashit( $basedir ); | |
} | |
/** | |
* Loads all scoped MU plugins for the current network and site. | |
* | |
* @since 1.0.0 | |
*/ | |
public function load() { | |
$network = $this->get_current_network(); | |
$site = $this->get_current_site(); | |
$this->load_networkwide( $network ); | |
$this->load_sitewide( $site ); | |
} | |
/** | |
* Loads network-wide MU plugins for a given network. | |
* | |
* @since 1.0.0 | |
* | |
* @param WP_Network $network Network object. | |
*/ | |
public function load_networkwide( $network ) { | |
$dirs = $this->get_search_directories( $this->basedir . self::NETWORKWIDE_DIR, $network ); | |
foreach ( $dirs as $dir ) { | |
foreach ( $this->get_mu_plugins( $dir ) as $mu_plugin ) { | |
require_once $mu_plugin; | |
} | |
} | |
} | |
/** | |
* Loads site-wide MU plugins for a given site. | |
* | |
* @since 1.0.0 | |
* | |
* @param WP_Site $site Site object. | |
*/ | |
public function load_sitewide( $site ) { | |
$dirs = $this->get_search_directories( $this->basedir . self::SITEWIDE_DIR, $site ); | |
foreach ( $dirs as $dir ) { | |
foreach ( $this->get_mu_plugins( $dir ) as $mu_plugin ) { | |
require_once $mu_plugin; | |
} | |
} | |
} | |
/** | |
* Returns the current network. | |
* | |
* @since 1.0.0 | |
* | |
* @return WP_Network Current network object. | |
*/ | |
private function get_current_network() { | |
return get_network(); | |
} | |
/** | |
* Returns the current site. | |
* | |
* @since 1.0.0 | |
* | |
* @return WP_Site Current site object. | |
*/ | |
private function get_current_site() { | |
return get_site(); | |
} | |
/** | |
* Returns directories to search for MU plugins for a given site or network. | |
* | |
* @since 1.0.0 | |
* | |
* @param string $basedir Basedir to look in for the respective kind of object. | |
* @param WP_Network|WP_Site $obj Network or site object. | |
* @return array Array of directories. | |
*/ | |
private function get_search_directories( $basedir, $obj ) { | |
$basedir = trailingslashit( $basedir ); | |
return array( | |
$basedir . $obj->id, | |
$basedir . str_replace( '/', '+', $obj->domain . $obj->path ), | |
); | |
} | |
/** | |
* Returns MU plugin file names found in a given directory. | |
* | |
* @since 1.0.0 | |
* | |
* @param string $dir Directory to look for MU plugins. | |
* @return array MU plugin files in that directory. | |
*/ | |
private function get_mu_plugins( $dir ) { | |
$mu_plugins = array(); | |
if ( ! is_dir( $dir ) ) { | |
return $mu_plugins; | |
} | |
$handle = opendir( $dir ); | |
if ( ! $handle ) { | |
return $mu_plugins; | |
} | |
$dir = trailingslashit( $dir ); | |
while ( ( $mu_plugin = readdir( $handle ) ) !== false ) { | |
if ( substr( $mu_plugin, -4 ) === '.php' ) { | |
$mu_plugins[] = $dir . $mu_plugin; | |
} | |
} | |
closedir( $handle ); | |
sort( $mu_plugins ); | |
return $mu_plugins; | |
} | |
} | |
/** | |
* Initializes the loader to load scoped MU plugins. | |
* | |
* @since 1.0.0 | |
*/ | |
function wp_scoped_mu_plugin_loader_run() { | |
$loader = new WP_Scoped_MU_Plugin_Loader( plugin_dir_path( __FILE__ ) ); | |
$loader->load(); | |
} | |
// Load all scoped MU plugins. | |
wp_scoped_mu_plugin_loader_run(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
WP Scoped MU Plugin Loader
Loads scoped MU plugins for specific sites or networks for an improved organization of those more specific tweaks.
Background Info
We usually use MU plugins for small tweaks in our WordPress setups. Sometimes more, sometimes less. In a multisite or multinetwork setup, some of these tweaks however should not be applied globally as they only affect a specific site or network. Of course this can be achieved with a regular MU plugin already, but as you get more and more of those tweaks in place, overview might get lost as you may have a hard time figuring out to which site you applied which tweaks and where to find them. This simple loader aims at solving this problem by allowing you to create site- or network-specific MU plugins.
Of course you could also use regular plugins for that and activate them per site or network, but in some cases MU plugins are easier to maintain since they usually are only plain PHP files and, more importantly, cannot be deactivated through WP Admin in any way.
Requirements
Setup
wp-content/mu-plugins
directory. Create the directory if it does not exist.wp-content/mu-plugins/site-wide/{$site_id}
(where{$site_id}
is the ID of the site) orwp-content/mu-plugins/site-wide/{$site_domain_and_path}
(where{$site_domain_and_path}
is the concatenated site domain and path with slashes replaced with+
characters).wp-content/mu-plugins/network-wide/{$network_id}
(where{$network_id}
is the ID of the network) orwp-content/mu-plugins/network-wide/{$network_domain_and_path}
(where{$network_domain_and_path}
is the concatenated network domain and path with slashes replaced with+
characters).That's it! You're all set. It may seem weird to replace the slashes in the domain and path combinations with
+
characters, however this needs to happen in order not to conflict with the directory separators of the server.Happy coding!