-
-
Save leepeterson/5a81c104d13f58b753240a16c0188fe5 to your computer and use it in GitHub Desktop.
Proof of concept of a WordPress mu-plugin to automatically disable plugins that start throwing errors.
This file contains hidden or 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: Plugin Debugging Tool | |
Description: Proof of concept of a WordPress mu-plugin to automatically disable plugins that start throwing errors. Must be installed as mu-plugin. The first time a plugin errors, it will white screen or show an error. Next page load, it is disabled. There has not been any functionality to remove plugins from the black list. If you'd like to see it developed more, please email [email protected] Only tested on Apache running PHP7. | |
Author: Chase C. Miller | |
Author Email: [email protected] | |
Version: 1.0 | |
Author URI: http://crumbls.com | |
*/ | |
namespace Crumbls\Debug\Plugins; | |
class Plugin | |
{ | |
protected static $errHandler = false; | |
protected static $errLog = []; | |
public function __construct() | |
{ | |
} | |
public static function getInstance() | |
{ | |
static $instance; | |
$class = get_called_class(); | |
if (!$instance instanceof $class) { | |
$instance = new $class; | |
add_action('admin_enqueue_scripts', [get_called_class(), 'adminEnqueue'], 10, 1); | |
self::$errHandler = set_error_handler([get_called_class(), 'errorHandler']); | |
set_exception_handler([get_called_class(), 'errorHandler']); | |
error_reporting(E_ALL); | |
add_filter('option_active_plugins', [get_called_class(), 'filterActivePlugins'], PHP_INT_MAX, 1); | |
add_action('shutdown', [get_called_class(), 'wordpressShutdown'], PHP_INT_MAX); | |
register_shutdown_function([get_called_class(), 'systemShutdown']); | |
} | |
return $instance; | |
} | |
/** | |
* Tied to filter "option_active_plugins" | |
* @param array $plugins | |
* @return array | |
*/ | |
public static function filterActivePlugins($plugins = []) | |
{ | |
global $wp_object_cache; | |
if (!$dis = get_option('disabled_plugins', [])) { | |
return $plugins; | |
} | |
// TODO: If you want to re-enable plugins, this is the spot. | |
// Return plugins, with disabled not activated. | |
$plugins = array_diff($plugins, array_column($dis, 2)); | |
return $plugins; | |
} | |
public static function wordpressShutdown() | |
{ | |
// The following plugins gave a horrible error. | |
if (!self::$errLog) { | |
return true; | |
} | |
$option = get_option('disabled_plugins', []); | |
$option = array_column($option, null, 'f'); | |
foreach (self::$errLog as $err) { | |
if (array_key_exists($err[2], $option)) { | |
continue; | |
} | |
$option[$err[2]] = $err; | |
} | |
update_option('disabled_plugins', $option, true); | |
return true; | |
} | |
/** | |
* Tied to register_shutdown_function | |
* Not currently used. | |
*/ | |
public static function systemShutdown() | |
{ | |
// echo __METHOD__; | |
} | |
/** | |
* Error handling. | |
*/ | |
public static function errorHandler($n = null, $s = null, $f = null, $ln = null) | |
{ | |
if (is_object($n) && get_class($n) == 'Exception') { | |
$s = $n->getMessage(); | |
$f = $n->getFile(); | |
$ln = $n->getLine(); | |
$n = $n->getCode(); | |
} | |
if ( | |
strpos($f, WP_CONTENT_DIR) !== 0 | |
|| | |
strpos($f, WP_CONTENT_DIR . '/plugins/') !== 0 | |
) { | |
// Send to default error handler. | |
$func = self::$errHandler; | |
return call_user_func($func, $n, $s, $f, $ln); | |
} | |
$f = substr($f, strlen(WP_CONTENT_DIR . '/plugins/')); | |
self::$errLog[] = [$n, $s, $f, $ln]; | |
return true; | |
} | |
/** | |
* Enqueue special CSS | |
* @param null $hook | |
*/ | |
public static function adminEnqueue($hook = null) | |
{ | |
if ($hook != 'plugins.php') { | |
return; | |
} | |
if (!$option = get_option('disabled_plugins', [])) { | |
return; | |
} | |
echo '<style>'; | |
foreach ($option as $e) { | |
printf('.plugins tr[data-plugin="%s"] { background-color: rgba(255,0,0,0.5) !important; }', $e[2]); | |
} | |
echo '</style>'; | |
} | |
} | |
Plugin::getInstance(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment