Skip to content

Instantly share code, notes, and snippets.

@joshuaadickerson
Created December 17, 2013 20:59
Show Gist options
  • Select an option

  • Save joshuaadickerson/8012506 to your computer and use it in GitHub Desktop.

Select an option

Save joshuaadickerson/8012506 to your computer and use it in GitHub Desktop.
<?php
class ElkArte_Hook
{
protected $_hooks = array();
protected $_files = array();
protected $_path_replacements;
protected $_debug = false;
public function __construct($settings)
{
// Get the replacements for the paths
$this->_path_replacements = array(
'BOARDDIR' => BOARDDIR,
'SOURCEDIR' => SOURCEDIR,
'EXTDIR' => EXTDIR,
'LANGUAGEDIR' => LANGUAGEDIR,
'ADMINDIR' => ADMINDIR,
'CONTROLLERDIR' => CONTROLLERDIR,
'SUBSDIR' => SUBSDIR,
);
// @todo I think this is legacy
if (!empty($GLOBALS['settings']['theme_dir']))
$this->path_replacements['$themedir'] = $GLOBALS['settings']['theme_dir'];
}
public function setDebug($debug)
{
$this->debug = (bool) $debug;
}
public function __call($name, $arguments)
{
// Track that it was called
if ($this->debug)
{
$GLOBALS['context']['debug']['hooks'][] = $name;
}
$results = array();
if ($this->offsetExists($name))
{
// Load any files
if (isset($this->_files[$name]))
{
foreach ($this->_files[$name] as $file)
{
require_once($this->getFileName($file));
}
}
// Call the callables
foreach ($this->offsetGet($name) as $function => $callable)
{
if (is_callable($callable))
$results[$function] = call_user_func_array($callable, $arguments);
}
}
}
protected function getFileName($file)
{
return strtr($file, $this->_path_replacements);
}
/**
* When passed the $modSettings, register all settings starting with "integrate_"
* @deprecated
* @param array $settings
*/
public function registerFromModSettings($settings)
{
foreach ($settings as $hook_name => $hook)
{
// Pass anything that doesn't start with 'integrate_'
if (strpos($hook_name, 'integrate_') !== 0)
continue;
$functions = explode(',', $hook);
// Loop through each function.
foreach ($functions as $function)
{
$file = false;
$function = trim($function);
// OOP static method
if (strpos($function, '::') !== false)
{
$call = explode('::', $function);
if (strpos($call[1], ':') !== false)
{
list ($func, $file) = explode(':', $call[1]);
$call = array($call[0], $func);
}
}
// Normal plain function
else
{
$call = $function;
if (strpos($function, ':') !== false)
{
list ($func, $file) = explode(':', $function);
$call = $func;
}
}
$this->registerHook($hook_name, $call, $file);
}
}
}
public function registerHook($hook, $callable, $file = false)
{
$function = is_array($callable) ? implode($callable, '::') : $callable;
$this->_hooks[$hook][$function] = $callable;
if (!empty($file))
$this->registerIncludeHook($hook, $file);
return $this;
}
public function registerIncludeHook($hook, $file)
{
//if (!file_exists($file))
// throw new Exception('The file "' . $file . '" could not be loaded. Hook: ' . $hook);
$this->_files[$hook][] = $file;
return $this;
}
public function __sleep()
{
/**
* The format is array(
* '{hook name}' => array(
* [[{class name}, {function name}]],
* [{file name}]
* )
* )
*
* Then we json_encode() that to save space
*/
return json_encode($this->__toArray());
}
/**
* Not actually a magic method, but it should be
*/
public function __toArray()
{
$array = array();
foreach ($this->_hooks as $hook => $callable)
{
$array[$hook] = array($callable);
if (isset($this->_files[$hook]))
$array[$hook][] = $this->_files[$hook];
}
return $array;
}
public function __toString()
{
return $this->__sleep();
}
public function registerFromSettings($settings)
{
$settings = json_decode($settings);
foreach ($settings as $name => $array)
{
if (count($array) == 2)
{
list($callables, $files) = $array;
}
else
{
$callables = $array[0];
$files = array();
}
if (!is_array($callables))
$callables = array($callables);
if (!is_array($files))
$files = array($files);
foreach ($callables as $callable)
{
$this->registerHook($name, $callable);
}
foreach ($files as $file)
{
$this->registerIncludeHook($name, $file);
}
}
}
public function __isset($name)
{
return isset($this->_hooks[$name]) || isset($this->_files[$name]);
}
public function __unset($name)
{
unset($this->_hooks[$name], $this->_files[$name]);
}
public function __set($name, $value)
{
return $this->registerHook($name, $value, false);
}
public function save()
{
return updateSettings('integration_hooks', $this->__sleep());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment