File: /var/www/html/wp-content/plugins/wp-external-links/libs/wprun/class-wprun-base.php
<?php
/**
* Class WPRun_Base_1x0x0
*
* Base abstract class can be extended for easy WP Plugin and Theme development.
* All subclasses are singletons and can be instantiated with the static
* "create()" factory method.
*
* @package WPRun
* @category WordPress Library
* @version 1.0.0
* @author WebFactory Ltd
* @link https://www.webfactoryltd.com/
*/
abstract class WPRun_Base_1x0x0
{
const RETURN_VOID = '__VOID__';
/**
* Page hook
* Page hook can be set by subclasses, in that case filter and action methods
* will only be set if page hook is the current screen id
* @var string
*/
protected $page_hook = null;
/**
* Automatically set action and filter methods
* @var boolean
*/
protected $autoset_hook_methods = true;
/**
* @var string
*/
protected $action_prefix = 'action_';
/**
* @var string
*/
protected $filter_prefix = 'filter_';
/**
* Only for internal use (to recognize a callback call)
* @var string
*/
private $internal_callback_prefix = '_cb_';
/**
* List of (singleton) instances
* Only for internal use
* @var array
*/
private static $instances = array();
/**
* @var array
*/
private $arguments = array();
/**
* Factory method
* @param mixed $param1 Optional, will be passed on to the constructor and init() method
* @param mixed $paramN Optional, will be passed on to the constructor and init() method
* @return WPRun_Base_1x0x0
* @triggers E_USER_NOTICE Class already created
*/
final public static function create()
{
$class_name = get_called_class();
$arguments = func_get_args();
// check if instance of this class already exists
if ( key_exists( $class_name, self::$instances ) ) {
return;
}
// pass all arguments to constructor
$instance = new $class_name( $arguments );
return $instance;
}
/**
* Constructor
* @triggers E_USER_NOTICE
*/
private function __construct( array $arguments )
{
$class_name = get_called_class();
self::$instances[ $class_name ] = $this;
$this->arguments = $arguments;
// call init method
$method_name = 'init';
if ( method_exists( $this, $method_name ) ) {
$method_reflection = new ReflectionMethod( get_called_class(), $method_name );
if ( $method_reflection->isProtected() ) {
call_user_func_array( array( $this, $method_name ), $this->arguments );
}
}
// automatically set methods as callback for WP hooks
if ( true === $this->autoset_hook_methods ) {
$this->set_hook_methods();
}
}
/**
* @return WPRun_Base_1x0x0
* @triggers E_USER_NOTICE Instance not yet created
*/
final public static function get_instance()
{
$class_name = get_called_class();
if ( ! isset( self::$instances[ $class_name ] ) ) {
return false;
}
return self::$instances[ $class_name ];
}
/**
* Get argument passed on to the constructor
* @param integer $index Optional, when null return all arguments
* @return mixed|null
*/
final protected function get_argument( $index = null )
{
// return all arguments when no index given
if ( null === $index ) {
return $this->arguments;
}
if ( !isset( $this->arguments[ $index ] ) ) {
return null;
}
return $this->arguments[ $index ];
}
/**
* @param string $template_file_path
* @param array $vars Optional
* @triggers E_USER_NOTICE Template file not readable
*/
final public static function show_template( $template_file_path, array $vars = array() )
{
if ( is_readable( $template_file_path ) && 0 === strpos($template_file_path, WPEL_Plugin::get_plugin_dir())) {
// show file
include $template_file_path;
}
}
/**
* @param string $template_file_path
* @param array $vars Optional
* @triggers E_USER_NOTICE Template file not readable
*/
final public static function render_template( $template_file_path, array $vars = array() )
{
// start output buffer
ob_start();
// output template
self::show_template( $template_file_path, $vars );
// get the view content
$content = ob_get_contents();
// clean output buffer
ob_end_clean();
return $content;
}
/**
* Get a callable to a method in current instance, when called will be
* caught by __callStatic(), were the magic happens
* @param string $method_name
* @return callable
*/
final protected function get_callback( $method_name )
{
return array( get_called_class(), $this->internal_callback_prefix . $method_name );
}
/**
* @param string $method_name
* @param array $arguments
* @return mixed|void
* @triggers E_USER_NOTICE Method name not exists/callable
*/
public function __call( $method_name, $arguments )
{
$return_value = self::magic_call( $method_name, $arguments );
if ( self::RETURN_VOID === $return_value ) {
return false;
}
return $return_value;
}
/**
* @param string $method_name
* @param array $arguments
* @return mixed|void
* @triggers E_USER_NOTICE Method name not exists/callable
*/
public static function __callStatic( $method_name, $arguments )
{
$return_value = self::magic_call( $method_name, $arguments );
if ( self::RETURN_VOID === $return_value ) {
return false;
}
return $return_value;
}
/**
* @param string $method_name
* @param array $arguments
* @return mixed|void
*/
final protected static function magic_call( $method_name, $arguments )
{
$class_name = get_called_class();
$instance = self::$instances[ $class_name ];
// catch callbacks set by get_callback() method
// this way callbacks can also be implemented as protected
$given_callback_name = self::fetch_name_containing_prefix( $instance->internal_callback_prefix, $method_name );
// normal callback
if ( null !== $given_callback_name ) {
$real_args = $arguments;
$given_method_name = $given_callback_name;
$callable = array( $instance, $given_method_name );
if ( is_callable( $callable ) ) {
return call_user_func_array( $callable, $real_args );
}
}
return self::RETURN_VOID;
}
/**
* Check and auto-initialize methods for hooks
*/
final protected function set_hook_methods()
{
$methods = get_class_methods( $this );
foreach ( $methods as $method_name ) {
$action_name = self::fetch_name_containing_prefix( $this->action_prefix, $method_name );
if ( null !== $action_name ) {
$this->add_to_hook( 'action', $action_name, $method_name );
continue;
}
$filter_name = self::fetch_name_containing_prefix( $this->filter_prefix, $method_name );
if ( null !== $filter_name ) {
$this->add_to_hook( 'filter', $filter_name, $method_name );
continue;
}
}
}
/**
* @param string $hook_type "action" or "filter"
* @param string $hook_name
* @param string $method_name
* @triggers E_USER_NOTICE
*/
private function add_to_hook( $hook_type, $hook_name, $method_name )
{
// fetch priority outof method name
$split_method_Name = explode( '_', $method_name );
$last = end( $split_method_Name );
if ( is_numeric( $last ) ) {
$priority = (int) $last;
$wp_hook_name = str_replace( '_' . $last, '', $hook_name );
} else {
$priority = 10;
$wp_hook_name = $hook_name;
}
// get the method's number of params
$method_reflection = new ReflectionMethod( get_called_class(), $method_name );
$accepted_args = $method_reflection->getNumberOfParameters();
// set internal wp hook action or filter callback
$method_callback = $this->get_callback( $method_name );
$check_call_hook = $this->get_callback( 'check_call_hook' );
$callback = function () use ( $method_callback, $check_call_hook ) {
$call_hook = call_user_func( $check_call_hook );
if ( false === $call_hook ) {
return;
}
return call_user_func_array( $method_callback, func_get_args() );
};
if ( 'action' === $hook_type ) {
add_action( $wp_hook_name, $callback, $priority, $accepted_args );
} elseif ('filter' === $hook_type) {
add_filter( $wp_hook_name, $callback, $priority, $accepted_args );
} else {
return false;
}
}
/**
* Check if an action or filter hook should be called (correct page hook)
* @return boolean
*/
final protected function check_call_hook()
{
if ( null === $this->page_hook ) {
return true;
}
if ( is_network_admin() ) {
$page_hook = $this->page_hook .'-network';
} else {
$page_hook = $this->page_hook;
}
if ( get_current_screen()->id === $page_hook ) {
return true;
}
return false;
}
/**
* @param string $prefix
* @param string $name
* @return string|null
*/
private static function fetch_name_containing_prefix( $prefix, $name )
{
$prefix_length = strlen( $prefix );
if ( $prefix !== substr( $name, 0, $prefix_length) ) {
return null;
}
$fetchedName = substr( $name, $prefix_length );
return $fetchedName;
}
}