Skip to content

Instantly share code, notes, and snippets.

@crstauf
Last active September 13, 2019 23:39
Show Gist options
  • Save crstauf/67de8505ae628d9589c14e62e6ef69eb to your computer and use it in GitHub Desktop.
Save crstauf/67de8505ae628d9589c14e62e6ef69eb to your computer and use it in GitHub Desktop.
WordPress drop-in (mu-plugin or include) to help manage features in certain server load conditions.
<?php
/**
* Plugin name: Server Load
* Plugin URI: https://gist.github.com/crstauf/67de8505ae628d9589c14e62e6ef69eb
* Author: Caleb Stauffer
* Author URI: https://develop.calebstauffer.com
* Version: 1.0
*/
class ServerLoad {
/**
* @var string Version number.
*/
const VERSION = '1.0';
/**
* @var string $load
*/
protected $load = 'normal';
/**
* @var string[] $loads
*/
protected $loads = array(
'normal',
'high',
'extreme',
);
/**
* @var array $constants
*/
protected $constants = array(
'EXTREME_SERVER_LOAD' => 'extreme',
'HIGH_SERVER_LOAD' => 'high',
);
/**
* Get instance.
*
* @return self
*/
static function instance() {
static $_instance = null;
if ( is_null( $_instance ) )
$_instance = new self;
return $_instance;
}
/**
* Construct.
*
* @uses $this::check_constants()
*/
protected function __construct() {
$this->check_constants();
add_action( 'plugins_loaded', array( $this, 'action__plugins_loaded' ) );
}
/**
* Getter.
*
* @param string $key
*/
function __get( $key ) {
if ( 'load' !== $key )
return null;
return $this->load;
}
/**
* Setter.
*
* @param string $key
* @param mixed $value
* @uses $this::set()
*/
function __set( $key, $value ) {
if ( 'load' !== $key )
return null;
$this->set( $value );
}
static function load() {
return static::instance()->load;
}
/**
* Check constants.
*/
protected function check_constants() {
foreach ( $this->constants as $constant => $load ) {
# If constant not defined, define false.
if ( !defined( $constant ) )
define( $constant, false );
# If constant is defined, set load.
else if ( constant( $constant ) )
$this->load = $load;
}
}
/**
* Set load.
*
* @param string $load
* @uses $this::is_valid_load()
*/
protected function set( string $load ) {
if ( !$this->is_valid_load( $load ) ) {
trigger_error( sprintf( '<code>%s</code> is not a valid load level.', $load ) );
return;
}
$this->load = $load;
}
/**
* Check if load is valid.
*
* @param string $load
* @return bool
*/
protected function is_valid_load( string $load ) {
return in_array( $load, $this->loads );
}
/**
* Check if is specified load.
*
* @param string|array $loads
* @return bool
*/
static function is( $loads ) {
$loads = ( array ) $loads;
if ( in_array( 'high', $loads ) )
$loads[] = 'extreme';
return in_array( static::instance()->load, $loads );
}
/**
* Action: plugins_loaded
*
* - add warning to Query Monitor if server load isn't normal
*/
function action__plugins_loaded() {
if ( static::is( 'normal' ) )
return;
do_action( 'qm/warning', sprintf( 'Server load: %s', $this->load ) );
}
}
if ( !function_exists( 'add_action_if_load' ) ) {
/**
* Add action if specified load.
*
* @see add_action()
* @param string|array $loads
* @uses ServerLoad::is()
* @uses add_action()
*/
function add_action_if_load( $loads, string $hook, callable $callback, int $priority = 10, int $accepted_args = 1 ) {
if ( !ServerLoad::is( $loads ) )
return;
add_action( $hook, $callback, $priority, $accepted_args );
}
}
if ( !function_exists( 'add_filter_if_load' ) ) {
/**
* Add filter if specified load.
*
* @see add_filter()
* @param string|array $loads
* @uses ServerLoad::is()
* @uses add_filter()
*/
function add_filter_if_load( $loads, string $hook, callable $callback, int $priority = 10, int $accepted_args = 1 ) {
if ( !ServerLoad::is( $loads ) )
return;
add_filter( $hook, $callback, $priority, $accepted_args );
}
}
if ( !function_exists( 'remove_action_if_load' ) ) {
/**
* Remove action if specified load.
*
* @see add_action()
* @param string|array $loads
* @uses ServerLoad::is()
* @uses remove_action()
*/
function remove_action_if_load( $loads, string $hook, callable $callback, int $priority = 10, int $accepted_args = 1 ) {
if ( !ServerLoad::is( $loads ) )
return;
if ( class_exists( 'QM_Util' ) )
do_action( 'qm/info', sprintf( '<code>%s</code> on <code>%s</code> action prevented due to %s server load.', QM_Util::populate_callback( array( 'function' => $callback ) )['function'], $hook, ServerLoad::load() ) );
remove_action( $hook, $callback, $priority, $accepted_args );
}
}
if ( !function_exists( 'remove_filter_if_load' ) ) {
/**
* Remove filter if specified load.
*
* @see add_filter()
* @param string|array $loads
* @uses ServerLoad::is()
* @uses add_filter()
*/
function remove_filter_if_load( $loads, string $hook, callable $callback, int $priority = 10, int $accepted_args = 1 ) {
if ( !ServerLoad::is( $loads ) )
return;
if ( class_exists( 'QM_Util' ) )
do_action( 'qm/info', sprintf( '<code>%s</code> on <code>%s</code> filter prevented due to %s server load.', QM_Util::populate_callback( array( 'function' => $callback ) )['function'], $hook, ServerLoad::load() ) );
remove_filter( $hook, $callback, $priority, $accepted_args );
}
}
ServerLoad::instance();
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment