Extensible configuration system

Add object registration for hooks.

refs #4300
This commit is contained in:
Marius Hein 2013-06-27 13:42:48 +02:00
parent eaf6314efe
commit b403721c11
2 changed files with 150 additions and 33 deletions

View File

@ -7,6 +7,13 @@ namespace Icinga\Web;
use Icinga\Application\Logger as Log;
use Icinga\Exception\ProgrammingError;
/**
* Class Hook
*
* Register and use hook classes
*
* @package Icinga\Web
*/
class Hook
{
/**
@ -35,7 +42,8 @@ class Hook
}
/**
* @param $name
* Test hook names or keys
* @param string $name
* @param null $key
* @return bool
*/
@ -49,9 +57,10 @@ class Hook
}
/**
* @param $name
* @param $key
* @return null
* Create or return an instance of the hook
* @param string $name
* @param string $key
* @return \stdClass
*/
public static function createInstance($name, $key)
{
@ -81,8 +90,9 @@ class Hook
}
/**
* @param $instance
* @param $name
* Test for a valid class name
* @param \stdClass $instance
* @param string $name
* @throws \Icinga\Exception\ProgrammingError
*/
private static function assertValidHook(&$instance, $name)
@ -100,7 +110,8 @@ class Hook
}
/**
* @param $name
* Return all instances of a specific name
* @param string $name
* @return array
*/
public static function all($name)
@ -117,8 +128,8 @@ class Hook
}
/**
* @param $name
* @return null
* @param string $name
* @return \stdClass
*/
public static function first($name)
{
@ -126,12 +137,51 @@ class Hook
}
/**
* @param $name
* @param $key
* @param $class
* 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);
}
/**
* Register a class
*
* @param string $name
* @param string $key
* @param string $class
*/
public static function registerClass($name, $key, $class)
{
if (!isset(self::$hooks[$name])) {
self::$hooks[$name] = array();
}
self::$hooks[$name][$key] = $class;
}
/**
* Register an object
* @param string $name
* @param string $key
* @param object $object
* @throws \Icinga\Exception\ProgrammingError
*/
public static function registerObject($name, $key, $object)
{
if (!is_object($object)) {
throw new ProgrammingError('object is not an instantiated class');
}
if (!isset(self::$instances[$name])) {
self::$instances[$name] = array();
}
self::$instances[$name][$key] =& $object;
self::registerClass($name, $key, get_class($object));
}
}

View File

@ -14,6 +14,7 @@ require_once("Zend/Log.php");
require_once("../../library/Icinga/Application/Logger.php");
use Icinga\Web\Hook as Hook;
class Base
{
}
@ -34,8 +35,47 @@ class ErrorProneHookImplementation
}
}
class ObjectHookImplementation
{
private $test;
/**
* @param mixed $test
*/
public function setTest($test)
{
$this->test = $test;
}
/**
* @return mixed
*/
public function getTest()
{
return $this->test;
}
public function __toString()
{
return $this->getTest();
}
}
class HookTest extends \PHPUnit_Framework_TestCase
{
protected function setUp()
{
parent::setUp();
Hook::clean();
}
protected function tearDown()
{
parent::tearDown();
Hook::clean();
}
/**
* Test for Hook::Has()
@ -44,14 +84,12 @@ class HookTest extends \PHPUnit_Framework_TestCase
**/
public function testHas()
{
Hook::clean();
$this->assertFalse(Hook::has("a"));
$this->assertFalse(Hook::has("a","b"));
Hook::register("a","b","c");
Hook::registerClass("a","b","c");
$this->assertTrue(Hook::has("a"));
$this->assertTrue(Hook::has("a","b"));
Hook::clean();
}
/**
@ -61,9 +99,8 @@ class HookTest extends \PHPUnit_Framework_TestCase
**/
public function testCreateInstance()
{
Hook::clean();
Hook::$BASE_NS = "Tests\\Icinga\\Web\\";
Hook::register("Base","b","Tests\\Icinga\\Web\\TestHookImplementation");
Hook::registerClass("Base","b","Tests\\Icinga\\Web\\TestHookImplementation");
$this->assertInstanceOf("Tests\\Icinga\\Web\\TestHookImplementation",Hook::createInstance("Base","b"));
Hook::clean();
}
@ -77,30 +114,25 @@ class HookTest extends \PHPUnit_Framework_TestCase
public function testCreateInvalidInstance1()
{
$this->setExpectedException('\Icinga\Exception\ProgrammingError');
Hook::clean();
Hook::$BASE_NS = "Tests\\Icinga\\Web\\";
Hook::register("Base","b","Tests\\Icinga\\Web\\TestBadHookImplementation");
Hook::registerClass("Base","b","Tests\\Icinga\\Web\\TestBadHookImplementation");
Hook::createInstance("Base","b");
Hook::clean();
}
public function testCreateInvalidInstance2()
{
Hook::clean();
Hook::$BASE_NS = "Tests\\Icinga\\Web\\";
$test = Hook::createInstance("Base","NOTEXIST");
$this->assertNull($test);
Hook::clean();
}
public function testCreateInvalidInstance3()
{
Hook::clean();
Hook::$BASE_NS = "Tests\\Icinga\\Web\\";
Hook::register("Base","ErrorProne","Tests\\Icinga\\Web\\ErrorProneHookImplementation");
$test = Hook::createInstance("Base","ErrorProne");
$this->assertNull($test);
Hook::clean();
}
/**
@ -110,16 +142,15 @@ class HookTest extends \PHPUnit_Framework_TestCase
**/
public function testAll()
{
Hook::clean();
Hook::$BASE_NS = "Tests\\Icinga\\Web\\";
Hook::register("Base","a","Tests\\Icinga\\Web\\TestHookImplementation");
Hook::register("Base","b","Tests\\Icinga\\Web\\TestHookImplementation");
Hook::register("Base","c","Tests\\Icinga\\Web\\TestHookImplementation");
Hook::registerClass("Base","a","Tests\\Icinga\\Web\\TestHookImplementation");
Hook::registerClass("Base","b","Tests\\Icinga\\Web\\TestHookImplementation");
Hook::registerClass("Base","c","Tests\\Icinga\\Web\\TestHookImplementation");
$this->assertCount(3,Hook::all("Base"));
foreach(Hook::all("Base") as $instance) {
$this->assertInstanceOf("Tests\\Icinga\\Web\\TestHookImplementation",$instance);
}
Hook::clean();
}
/**
@ -129,13 +160,49 @@ class HookTest extends \PHPUnit_Framework_TestCase
**/
public function testFirst()
{
Hook::clean();
Hook::$BASE_NS = "Tests\\Icinga\\Web\\";
Hook::register("Base","a","Tests\\Icinga\\Web\\TestHookImplementation");
Hook::register("Base","b","Tests\\Icinga\\Web\\TestHookImplementation");
Hook::register("Base","c","Tests\\Icinga\\Web\\TestHookImplementation");
Hook::registerClass("Base","a","Tests\\Icinga\\Web\\TestHookImplementation");
Hook::registerClass("Base","b","Tests\\Icinga\\Web\\TestHookImplementation");
Hook::registerClass("Base","c","Tests\\Icinga\\Web\\TestHookImplementation");
$this->assertInstanceOf("Tests\\Icinga\\Web\\TestHookImplementation",Hook::first("Base"));
Hook::clean();
}
public function testRegisterObject()
{
$o1 = new ObjectHookImplementation();
$o1->setTest('$123123');
Hook::registerObject('Test', 'o1', $o1);
$o2 = new ObjectHookImplementation();
$o2->setTest('#456456');
Hook::registerObject('Test', 'o2', $o2);
$this->assertInstanceOf('Tests\\Icinga\\Web\\ObjectHookImplementation', Hook::createInstance('Test', 'o1'));
$this->assertInstanceOf('Tests\\Icinga\\Web\\ObjectHookImplementation', Hook::createInstance('Test', 'o2'));
$string = "";
foreach (Hook::all('Test') as $hook) {
$string .= (string)$hook;
}
$this->assertEquals('$123123#456456', $string);
}
/**
* @expectedException Icinga\Exception\ProgrammingError
* @expectedExceptionMessage object is not an instantiated class
*/
public function testErrorObjectRegistration()
{
Hook::registerObject('Test', 'e1', 'STRING');
}
public function testGetNullHooks()
{
$nh = Hook::all('DOES_NOT_EXIST');
$this->assertInternalType('array', $nh);
$this->assertCount(0, $nh);
}
}