92 lines
3.0 KiB
PHP
92 lines
3.0 KiB
PHP
<?php
|
|
/**
|
|
* Hookable objects automatically bind Wordpress filters and actions instance methods.
|
|
* - Filter methods take the form `public function filter_{hook}()`
|
|
* - Actions methods take the form `public function on_{hook}`
|
|
*/
|
|
abstract class Loco_hooks_Hookable {
|
|
|
|
/**
|
|
* Registry of tags to be deregistered when object removed from memory
|
|
* @var array
|
|
*/
|
|
private $hooks;
|
|
|
|
|
|
/**
|
|
* Constructor register hooks immediately
|
|
*/
|
|
public function __construct(){
|
|
|
|
$ref = new ReflectionClass( $this );
|
|
$this->hooks = [];
|
|
foreach( $ref->getMethods( ReflectionMethod::IS_PUBLIC ) as $method ){
|
|
$func = $method->name;
|
|
// support filter_{filter_hook} methods
|
|
if( 'filter_' === substr($func,0,7) ) {
|
|
$hook = substr( $func, 7 );
|
|
}
|
|
// support on_{action_hook} methods
|
|
else if( 'on_' === substr($func,0,3) ) {
|
|
$hook = substr( $func, 3 );
|
|
}
|
|
// support debug_{filter|action_hook} methods only in debug mode
|
|
else if( 'debug_' === substr($func,0,6) && loco_debugging() ) {
|
|
$hook = substr( $func, 6 );
|
|
}
|
|
else {
|
|
continue;
|
|
}
|
|
// this goes to 11 so we run after system defaults
|
|
$priority = 11;
|
|
// support @priority tag in comment block (uncomment if needed)
|
|
/*if( ( $docblock = $method->getDocComment() ) && ( $offset = strpos($docblock,'@priority ') ) ){
|
|
preg_match( '/^\d+/', substr($docblock,$offset+10), $r ) and
|
|
$priority = (int) $r[0];
|
|
}*/
|
|
$num_args = $method->getNumberOfParameters();
|
|
$this->addHook( $hook, $func, $num_args, $priority );
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Manually append a hook, regardless of whether it's added already
|
|
*/
|
|
protected function addHook( $hook, $func, $num_args = 0, $priority = 11 ){
|
|
// call add_action or add_filter with required arguments and hook is registered
|
|
add_filter( $hook, [ $this, $func ], $priority, $num_args );
|
|
$this->hooks[] = [ $hook, $func, $priority, $num_args ];
|
|
}
|
|
|
|
|
|
/**
|
|
* Ensure all hooks in memory are re-attached if they've been removed
|
|
*/
|
|
protected function reHook(){
|
|
if( is_array($this->hooks) ){
|
|
foreach( $this->hooks as $r ){
|
|
list( $hook, $func, $priority, $num_args ) = $r;
|
|
if( ! has_filter($hook,[$this,$func]) ){
|
|
add_filter( $hook, [$this,$func], $priority, $num_args );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Deregister active hooks.
|
|
* We can't use __destruct because instances persist in WordPress hook registry
|
|
*/
|
|
public function unhook(){
|
|
if( is_array($this->hooks) ){
|
|
foreach( $this->hooks as $r ){
|
|
remove_filter( $r[0], [$this,$r[1]], $r[2] );
|
|
}
|
|
}
|
|
$this->hooks = null;
|
|
}
|
|
|
|
} |