Skip to content

Instantly share code, notes, and snippets.

@geminorum
Forked from chrisguitarguy/Hooks.php
Created November 12, 2013 03:05
Show Gist options
  • Save geminorum/7424805 to your computer and use it in GitHub Desktop.
Save geminorum/7424805 to your computer and use it in GitHub Desktop.
<?php
/**
* Implementation of WordPress style hooks.
*
* @author Christopher Davis <chris [AT] classicalguitar.org>
* @copyright Christopher Davis 2012
* @license MIT
*/
class Hooks
{
protected $hooks = array();
protected $done = array();
public function act($hook)
{
return $this->perform($hook, array_slice(func_get_args(), 1));
}
public function filter($hook)
{
return $this->perform($hook, array_slice(func_get_args(), 1));
}
public function add_action($hook, $callable, $prio=10)
{
return $this->add($hook, $callable, $prio);
}
public function remove_action($hook, $callable, $prio=10)
{
return $this->remove($hook, $callable, $prio);
}
public function add_filter($hook, $callable, $prio=10)
{
return $this->add($hook, $callable, $prio);
}
public function remove_filter($hook, $callable, $prio=10)
{
return $this->remove($hook, $callable, $prio);
}
public function has_action($hook, $callable, $prio=10)
{
return $this->has_hook($hook, $callable, $prio);
}
public function has_filter($hook, $callable, $prio=10)
{
return $this->has_hook($hook, $callable, $prio);
}
public function did_filter($hook)
{
return $this->did_hook($hook);
}
public function did_action($hook)
{
return $this->did_hook($hook);
}
/********** Internals **********/
protected function build_id($func)
{
if(is_scalar($func))
return $func;
if(is_object($func))
$func = array($func, ''); // closures are objects
$id = is_object($func[0]) ? spl_object_hash($func[0]) : $func[0];
$id .= !empty($func[1]) ? $func[1] : '';
return $id;
}
protected function perform($hook, $args)
{
if(isset($args[0]))
$value = $args[0];
else
$value = null;
if(!isset($this->hooks[$hook]))
return $value; // bail, nothing set for this hook.
ksort($this->hooks[$hook], SORT_NUMERIC);
reset($this->hooks[$hook]);
do {
foreach(current($this->hooks[$hook]) as $idx => $func)
{
if(!is_callable($func))
continue; // maybe this shouldn't get checked?
$args[0] = $value;
$value = call_user_func_array($func, $args);
}
} while(next($this->hooks[$hook]) !== false);
$this->done[$hook] = true;
return $value;
}
protected function add($hook, $func, $prio)
{
$prio = intval($prio);
!isset($this->hooks[$hook]) && $this->hooks[$hook] = array();
!isset($this->hooks[$hook][$prio]) && $this->hooks[$hook][$prio] = array();
$this->hooks[$hook][$prio][$this->build_id($func)] = $func;
}
protected function remove($hook, $func, $prio)
{
if($this->has_hook($hook, $func, $prio))
{
unset($this->hooks[$hook][$prio][$this->build_id($func)]);
return true;
}
return false;
}
protected function has_hook($hook, $func, $prio)
{
return isset($this->hooks[$hook][intval($prio)][$this->build_id($func)]);
}
protected function did_hook($hook)
{
return isset($this->done[$hook]);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment