Add static function get to class Hook

refs #4301
This commit is contained in:
Eric Lippmann 2013-06-27 13:33:46 +02:00
parent 771cfbf4eb
commit d1253f8136

View File

@ -1,149 +1,114 @@
<?php <?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
/**
* Icinga Web Hook registry
*/
namespace Icinga\Web; namespace Icinga\Web;
use Icinga\Application\Logger as Log; use Icinga\Application\Logger as Log;
use Icinga\Exception\ProgrammingError; use Icinga\Exception\ProgrammingError;
use Icinga\Exception\NotImplementedError;
/** /**
* Class Hook * Icinga Web Hook registry
* *
* Register and use hook classes * Modules making use of predefined hooks have to use this registry
* *
* @package Icinga\Web * Usage:
* <code>
* Hook::register('grapher', 'My\\Grapher\\Class');
* </code>
*
* @copyright Copyright (c) 2013 Icinga-Web Team <info@icinga.org>
* @author Icinga-Web Team <info@icinga.org>
* @license http://www.gnu.org/copyleft/gpl.html GNU General Public License
*/ */
class Hook class Hook
{ {
/** /**
* Our hook name registry
*
* @var array * @var array
*/ */
protected static $hooks = array(); protected static $hooks = array();
/** /**
* Hooks that have already been instantiated
*
* @var array * @var array
*/ */
protected static $instances = array(); protected static $instances = array();
/** /**
* @var string * Whether someone registered itself for the given hook name
*/ *
public static $BASE_NS = 'Icinga\\Web\\Hook\\'; * @param string $name One of the predefined hook names
/**
* *
*/
public static function clean()
{
self::$hooks = array();
self::$instances = array();
self::$BASE_NS = 'Icinga\\Web\\Hook\\';
}
/**
* Test hook names or keys
* @param string $name
* @param null $key
* @return bool * @return bool
*/ */
public static function has($name, $key = null) public static function has($name)
{ {
if ($key !== null) { return array_key_exists($name, self::$hooks);
return isset(self::$hooks[$name][$key]);
} else {
return isset(self::$hooks[$name]);
}
} }
/** /**
* Create or return an instance of the hook * Get the first registered instance for the given hook name
* @param string $name *
* @param string $key * TODO: Multiple instances are not handled yet
* @return \stdClass * TODO: Should return some kind of a hook interface
*
* @param string $name One of the predefined hook names
*
* @return mixed
*/ */
public static function createInstance($name, $key) public static function get($name)
{ {
if (!self::has($name, $key)) { if (! self::has($name)) {
return null; return null;
} }
if (isset(self::$instances[$name][$key])) { if (! array_key_exists($name, self::$instances)) {
return self::$instances[$name][$key]; $class = self::$hooks[$name];
} try {
$class = self::$hooks[$name][$key]; $obj = new $class();
try { } catch (\Exception $e) {
$instance = new $class(); // TODO: Persist unloading for "some time" or "current session"
} catch (\Exception $e) { Log::debug(
Log::debug( 'Hook "%s" (%s) failed, will be unloaded: %s',
'Hook "%s" (%s) (%s) failed, will be unloaded: %s', $name,
$name, $class,
$key, $e->getMessage()
$class, );
$e->getMessage() unset(self::$hooks[$name]);
); return null;
unset(self::$hooks[$name][$key]);
return null;
}
self::assertValidHook($instance, $name);
self::$instances[$name][$key] = $instance;
return $instance;
}
/**
* Test for a valid class name
* @param \stdClass $instance
* @param string $name
* @throws \Icinga\Exception\ProgrammingError
*/
private static function assertValidHook(&$instance, $name)
{
$base_class = self::$BASE_NS . ucfirst($name);
if (!$instance instanceof $base_class) {
throw new ProgrammingError(
sprintf(
'%s is not an instance of %s',
get_class($instance),
$base_class
)
);
}
}
/**
* Return all instances of a specific name
* @param string $name
* @return array
*/
public static function all($name)
{
if (!self::has($name)) {
return array();
}
foreach (self::$hooks[$name] as $key => $hook) {
if (self::createInstance($name, $key) === null) {
return array();
} }
$base_class = 'Icinga\\Web\\Hook\\' . ucfirst($name);
if (! $obj instanceof $base_class) {
throw new ProgrammingError(
sprintf(
'%s is not an instance of %s',
get_class($obj),
$base_class
)
);
}
self::$instances[$name] = $obj;
} }
return self::$instances[$name]; return self::$instances[$name];
} }
/** /**
* @param string $name * Register your hook
* @return \stdClass *
* @param string $name One of the predefined hook names
* @param string $class Your class name, must inherit one of the classes
* in the Icinga/Web/Hook folder
*
* @throws NotImplementedError unless we support multiple instances
*
* @return void
*/ */
public static function first($name) public static function register($name, $class)
{
return self::createInstance($name, key(self::$hooks[$name]));
}
/**
* Registers a class
* @deprecated Too generic, throw away
* @param string $name
* @param string $key
* @param string $class
*/
public static function register($name, $key, $class)
{ {
self::registerClass($name, $key, $class); self::registerClass($name, $key, $class);
} }
@ -184,4 +149,5 @@ class Hook
self::$instances[$name][$key] =& $object; self::$instances[$name][$key] =& $object;
self::registerClass($name, $key, get_class($object)); self::registerClass($name, $key, get_class($object));
} }
} }