-
-
Save ooksanen/20743a1e25f42614c88521ed7535f0a9 to your computer and use it in GitHub Desktop.
MU plugin to enable/disable other plugins during local development.
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 // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName | |
/** | |
* Plugin Name: RA Local Dev Plugin | |
* Description: Install as an mu-plugin to enable and disable other plugins during local development. | |
* Version: 0.1.0 | |
* License: GPL version 2 or any later version | |
* Author: Mark Jaquith, Andrey Savchenko, Paul Biron, Richard Aber | |
* | |
* Inspired by Paul Biron https://gist.github.com/pbiron/52bb63042cf220256ece89bc07fb57b0, | |
* who was inspired by Andrey Savchenko https://gist.github.com/Rarst/4402927, | |
* who was inspired by Mark Jaquith https://gist.github.com/markjaquith/1044546. | |
* | |
* @package RA\LocalDev | |
*/ | |
namespace RA\LocalDev; | |
// phpcs:disable Generic.Arrays.DisallowShortArraySyntax | |
// phpcs:disable Generic.Files.OneObjectStructurePerFile | |
// phpcs:disable PSR1.Classes.ClassDeclaration.MultipleClasses | |
/** | |
* Class Config | |
* | |
* Config object containing plugins to enable and disable. | |
* | |
* @package RA\LocalDev | |
*/ | |
class Config | |
{ | |
/** | |
* Array of plugins to disable in local development. | |
* | |
* This is for plugins that could be hazardous in local development, | |
* such as plugins that send emails through a third-party service | |
* or interface with an external email server. | |
* | |
* These typically follow the format of directory name, | |
* followed by a slash /, followed by the main plugin file name. | |
* | |
* @var array | |
*/ | |
public static $disable = [ | |
'wp-mail-smtp/wp_mail_smtp.php', | |
]; | |
/** | |
* Array of plugins to enable in local development. | |
* | |
* This is for plugins that are useful in local development, | |
* such as plugins that display debug information. | |
* | |
* 'network' is used for network activation in multisite, | |
* 'non-network' for standard activation. | |
* | |
* These typically follow the format of directory name, | |
* followed by a slash /, followed by the main plugin file name. | |
* | |
* @var array | |
*/ | |
public static $enable = [ | |
'network' => [], | |
'non-network' => [ | |
'admin-bar-user-switching/admin-bar-user-switching.php', | |
'query-monitor/query-monitor.php', | |
'rewrite-rules-inspector/rewrite-rules-inspector.php', | |
'user-switching/user-switching.php', | |
'wp-crontrol/wp-crontrol.php', | |
], | |
]; | |
/** | |
* Get the array of plugins to disable in local development. | |
* | |
* @return array | |
*/ | |
public static function getPluginsToDisable(): array | |
{ | |
return (array)self::$disable; | |
} | |
/** | |
* Get the array of plugins to enable in local development. | |
* | |
* @return array | |
*/ | |
public static function getPluginsToEnable(): array | |
{ | |
return (array)self::$enable; | |
} | |
} | |
/** | |
* Class Plugin | |
* | |
* The plugin class that handles enabling and disabling. | |
* | |
* @package RA\LocalDev | |
*/ | |
class Plugin | |
{ | |
/** | |
* The config used to create this instance. | |
* | |
* @var null|Config | |
*/ | |
protected $config = null; | |
/** | |
* The array of disabled plugins. | |
* | |
* @var array | |
*/ | |
protected $disabled = []; | |
/** | |
* The array of enabled plugins. | |
* | |
* @var array | |
*/ | |
protected $enabled = [ | |
'network' => [], | |
'non-network' => [], | |
]; | |
/** | |
* Sets up the filters, and handles arrays of plugins to enable and disable. | |
* | |
* @param Config $config Config object. | |
*/ | |
public function __construct(Config $config) | |
{ | |
$this->config = $config; | |
foreach ($this->config::getPluginsToDisable() as $disable) { | |
$this->disable($disable); | |
} | |
foreach ($this->config::getPluginsToEnable() as $where => $_enables) { | |
if (is_array($_enables)) { | |
foreach ($_enables as $enable) { | |
$this->enable($enable, $where); | |
} | |
} | |
} | |
add_filter( | |
'option_active_plugins', | |
[$this, 'doDisabling'] | |
); | |
add_filter( | |
'option_active_plugins', | |
[$this, 'doEnabling'] | |
); | |
add_filter( | |
'site_option_active_sitewide_plugins', | |
[$this, 'doNetworkDisabling'] | |
); | |
add_filter( | |
'site_option_active_sitewide_plugins', | |
[$this, 'doNetworkEnabling'] | |
); | |
} | |
/** | |
* Adds a filename to the list of plugins to disable. | |
* | |
* @param string $file The plugin filename to disable. | |
*/ | |
public function disable($file) | |
{ | |
$this->disabled[] = $file; | |
} | |
/** | |
* Adds a filename to the list of plugins to enable. | |
* | |
* @param string $file The plugin filename to enable. | |
* @param null|string $where Network or non-network. | |
* | |
* @return void | |
*/ | |
public function enable(string $file, $where = 'non-network') | |
{ | |
if ( | |
! is_multisite() | |
|| ! in_array($where, ['non-network', 'network'], true) | |
) { | |
$where = 'non-network'; | |
} | |
$this->enabled[$where][] = $file; | |
} | |
/** | |
* Hooks in to the option_active_plugins filter and does the disabling. | |
* | |
* @param array $plugins The plugin filenames to disable. | |
* | |
* @return array The filtered array of plugin filenames. | |
*/ | |
public function doDisabling($plugins) | |
{ | |
if (count($this->disabled)) { | |
foreach ((array)$this->disabled as $plugin) { | |
$key = array_search($plugin, $plugins, true); | |
if (false !== $key) { | |
unset($plugins[$key]); | |
} | |
} | |
} | |
return $plugins; | |
} | |
/** | |
* Hooks in to the site_option_active_sitewide_plugins filter and does the disabling. | |
* | |
* @param array $plugins The plugin filenames to network disable. | |
* | |
* @return array The filtered array of plugin filenames. | |
*/ | |
public function doNetworkDisabling(array $plugins) | |
{ | |
if (count($this->disabled)) { | |
foreach ((array)$this->disabled as $plugin) { | |
if (isset($plugins[$plugin])) { | |
unset($plugins[$plugin]); | |
} | |
} | |
} | |
return $plugins; | |
} | |
/** | |
* Hooks in to the option_active_plugins filter and does the enabling. | |
* | |
* @param array $plugins List of plugin filenames. | |
* | |
* @return array The filtered array of plugin filenames | |
*/ | |
public function doEnabling($plugins) | |
{ | |
return array_merge($plugins, $this->enabled['non-network']); | |
} | |
/** | |
* Hooks in to the site_option_active_sitewide_plugins filter and does the enabling. | |
* | |
* @param array $plugins List of plugin filenames. | |
* | |
* @return array | |
*/ | |
public function doNetworkEnabling($plugins) | |
{ | |
foreach ($this->enabled['network'] as $file) { | |
$plugins[$file] = time(); | |
} | |
return $plugins; | |
} | |
} | |
/** | |
* Class Factory | |
* | |
* The factory responsible for instantiating and returning the single Plugin instance. | |
* | |
* @package RA\LocalDev | |
*/ | |
class Factory | |
{ | |
/** | |
* Create and return an instance of Plugin. | |
* | |
* This always returns a shared instance. | |
* This way, outside code can always get access to the instance of the plugin. | |
* | |
* @return Plugin The plugin instance. | |
*/ | |
public static function create(): Plugin | |
{ | |
static $plugin = null; | |
if (null === $plugin) { | |
$plugin = new Plugin( | |
new Config() | |
); | |
} | |
return $plugin; | |
} | |
} | |
if ( | |
(defined('WP_LOCAL_DEV') && WP_LOCAL_DEV) | |
|| (defined('WP_ENVIRONMENT_TYPE') && 'local' === WP_ENVIRONMENT_TYPE) | |
) { | |
Factory::create(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment