diff --git a/src/messenger/tests/webim/libs/classes/EventDispatcherTest.php b/src/messenger/tests/webim/libs/classes/EventDispatcherTest.php new file mode 100644 index 00000000..cb66c78a --- /dev/null +++ b/src/messenger/tests/webim/libs/classes/EventDispatcherTest.php @@ -0,0 +1,157 @@ +assertSame($dispatcher, $another_dispatcher); + unset($another_dispatcher); + return $dispatcher; + } + + /** + * @depends testGetInstance + */ + public function testRegisterEvent($dispatcher) { + // Try to register new event + $this->assertTrue($dispatcher->registerEvent('some_test_event')); + $this->assertTrue($dispatcher->registerEvent('some_another_test_event')); + + // Try to register already registered event + // Following code wait for trigger user error, which converts by PHPUnit to an + // Exception + try{ + $dispatcher->registerEvent('some_test_event'); + $this->fail("Error expected!"); + } catch(Exception $e) {} + return $dispatcher; + } + + /** + * @depends testRegisterEvent + */ + public function testAttachListener($dispatcher) { + // Try to attach listener to unregistered event + // Following code wait for trigger user error, which converts by PHPUnit to an + // Exception + try{ + $dispatcher->attachListener( + 'unreginstered_event', + self::$plugin, + 'testEventListener' + ); + $this->fail("Error expected!"); + } catch(Exception $e) {} + + // Try to Attach wrong method as listener to event + // Following code wait for trigger user error, which converts by PHPUnit to an + // Exception + try{ + $dispatcher->attachListener( + 'some_test_event', + self::$plugin, + 'wrongEventListener' + ); + $this->fail("Error expected!"); + } catch(Exception $e) {} + + // Try to attach listener to registered event + $this->assertTrue( + $dispatcher->attachListener( + 'some_test_event', + self::$plugin, + 'testEventListener' + ) + ); + + // Try to attach listener to registered event + $this->assertTrue( + $dispatcher->attachListener( + 'some_another_test_event', + self::$plugin, + 'testEventListener' + ) + ); + + return $dispatcher; + } + + /** + * @depends testAttachListener + */ + public function testDetachListener($dispatcher) { + // Try to detach listener for unregistered event. + // Following code wait for trigger user error, which converts by PHPUnit to an + // Exception + try{ + $dispatcher->detachListener( + 'unreginstered_event', + self::$plugin, + 'testEventListener' + ); + $this->fail("Error expected!"); + } catch(Exception $e) {} + + // Try to detach listner that was not attached to registerd event + $this->assertFalse( + $dispatcher->detachListener( + 'some_test_event', + self::$plugin, + 'wrongEventListener' + ) + ); + + // Try to detach listener that was attached to registered + $this->assertTrue( + $dispatcher->detachListener( + 'some_test_event', + self::$plugin, + 'testEventListener' + ) + ); + return $dispatcher; + } + + /** + * @depends testDetachListener + */ + public function testTriggerEvent($dispatcher) { + // Try to trigger unregistered event + // Following code wait for trigger user error, which converts by PHPUnit to an + // Exception + try{ + $dispatcher->triggerEvent('unregistered_event', array()); + $this->fail("Error expected!"); + } catch(Exception $e) {} + + // Try to thrigger registered event + // Wait for exception thrown by + // Phpunit_autotest_plugin_managerPlugin::testEventListener() + try{ + $dispatcher->triggerEvent('some_another_test_event', array()); + $this->fail("Exception excpected!"); + } catch(Exception $e) {} + } + +} + +?> diff --git a/src/messenger/tests/webim/libs/classes/PluginManagerTest.php b/src/messenger/tests/webim/libs/classes/PluginManagerTest.php new file mode 100644 index 00000000..1eaf8d5e --- /dev/null +++ b/src/messenger/tests/webim/libs/classes/PluginManagerTest.php @@ -0,0 +1,28 @@ + 'phpunit_autotest_plugin_manager' + ) + ) + ); + if(empty($GLOBALS['phpunit_autotest_plugin_manager'])) { + $this->fail('Plugin not loaded and initialize correctly'); + } + } + +} + +?> diff --git a/src/messenger/tests/webim/libs/classes/phpunit_autotest_plugin_manager/plugin.mibew.inc.php b/src/messenger/tests/webim/libs/classes/phpunit_autotest_plugin_manager/plugin.mibew.inc.php new file mode 100644 index 00000000..f125560f --- /dev/null +++ b/src/messenger/tests/webim/libs/classes/phpunit_autotest_plugin_manager/plugin.mibew.inc.php @@ -0,0 +1,37 @@ +eventsRegistered = true; + $this->checkRegistration(); + } + + public function registerListeners() { + $this->listenersRegistered = true; + $this->checkRegistration(); + } + + public function checkRegistration() { + if ($this->eventsRegistered && $this->listenersRegistered) { + $GLOBALS['phpunit_autotest_plugin_manager'] = true; + } + } + + public function testEventListener($vars) { + throw new Exception(); + } + +} + +?> \ No newline at end of file diff --git a/src/messenger/webim/libs/classes/.htaccess b/src/messenger/webim/libs/classes/.htaccess new file mode 100644 index 00000000..14249c50 --- /dev/null +++ b/src/messenger/webim/libs/classes/.htaccess @@ -0,0 +1 @@ +Deny from all \ No newline at end of file diff --git a/src/messenger/webim/libs/classes/event_dispatcher.php b/src/messenger/webim/libs/classes/event_dispatcher.php new file mode 100644 index 00000000..324f23bf --- /dev/null +++ b/src/messenger/webim/libs/classes/event_dispatcher.php @@ -0,0 +1,163 @@ +events)) { + trigger_error("Event '{$event_name}' does not exists!", E_USER_WARNING); + return false; + } + // Check method is callable + if (! is_callable(array($plugin, $listener))) { + trigger_error("Method '{$listener}' is not callable!", E_USER_WARNING); + return false; + } + // Check priority + if (is_null($priority)) { + $priority = $plugin->getWeight(); + } + // Attach listener + $this->events[$event_name][$priority . "_" . $this->offset] = array( + 'plugin' => $plugin, + 'listener' => $listener + ); + $this->offset++; + return true; + } + + /** + * Detach listener function from event + * + * @param string $event_name Event's name + * @param Plugin $plugin Plugin object, that handles the event + * @param string $listener Plugins method, that handles the event + * @return boolean true on success or false on failure. + */ + public function detachListener($event_name, Plugin $plugin, $listener){ + // Check event exists + if (! array_key_exists($event_name, $this->events)) { + trigger_error("Event '{$event_name}' does not exists!", E_USER_WARNING); + return false; + } + // Search event and $plugin->$listener + foreach ($this->events[$event_name] as $index => $event) { + if ($event['plugin'] === $plugin && $event['listener'] == $listener) { + // Detach listener + unset($this->events[$event_name][$index]); + return true; + } + } + return false; + } + + /** + * Registers new event + * + * @param string $event_name Event's name + * @return boolean true on success or false on failure + */ + public function registerEvent($event_name){ + // Check event exists + if (array_key_exists($event_name, $this->events)) { + trigger_error("Event '{$event_name}' already exists!", E_USER_WARNING); + return false; + } + // register event + $this->events[$event_name] = array(); + return true; + } + + /** + * Triggers the event + * + * @param string $event_name Event's name + * @param array $arguments Arguments passed to listener + * @return boolean true on success or false on failure + */ + public function triggerEvent($event_name, $arguments = array()){ + // Check event exists + if (! array_key_exists($event_name, $this->events)) { + trigger_error("Event '{$event_name}' does not exists!", E_USER_WARNING); + return false; + } + // Sorting listeners by priority + uksort($this->events[$event_name], 'strnatcmp'); + // Invoke listeners + foreach ($this->events[$event_name] as $event) { + $plugin = $event['plugin']; + $listener = $event['listener']; + $plugin->$listener($arguments); + } + } + +} + +?> \ No newline at end of file diff --git a/src/messenger/webim/libs/classes/plugin.php b/src/messenger/webim/libs/classes/plugin.php new file mode 100644 index 00000000..62b7e9ac --- /dev/null +++ b/src/messenger/webim/libs/classes/plugin.php @@ -0,0 +1,43 @@ + \ No newline at end of file diff --git a/src/messenger/webim/libs/classes/plugin_manager.php b/src/messenger/webim/libs/classes/plugin_manager.php new file mode 100644 index 00000000..bc3cbd47 --- /dev/null +++ b/src/messenger/webim/libs/classes/plugin_manager.php @@ -0,0 +1,94 @@ + + * $plugins_list = array(); + * $plugins_list[] = array( + * 'name' => 'plugin_name', // Obligatory value + * 'config' => array( // Pass to plugin constructor + * 'weight' => 100, + * 'some_configurable_value' => 'value' + * ) + * ) + * + * + * @see Plugin::registerEvents() + * @see Plugin::registerListeners() + */ + public static function loadPlugins($plugins_list){ + // Add include path + $include_path = get_include_path(); + $include_path .= empty($include_path) ? '' : PATH_SEPARATOR ; + set_include_path($include_path . realpath(dirname(__FILE__) . "/../../plugins/")); + + // Load plugins + $loading_queue = array(); + $offset = 0; + foreach ($plugins_list as $plugin) { + if (empty($plugin['name'])) { + trigger_error("Plugin name undefined!", E_USER_WARNING); + continue; + } + $plugin_name = $plugin['name']; + $plugin_config = isset($plugin['config']) ? $plugin['config'] : array(); + $plugin_classname = ucfirst($plugin_name) . "Plugin"; + // Try to load plugin file + if (! (include_once $plugin_name."/plugin.mibew.inc.php")) { + trigger_error("Cannot load plugin file!", E_USER_ERROR); + } + // Check plugin class name + if (! class_exists($plugin_classname)) { + trigger_error( + "Plugin class '{$plugin_classname}' does not defined!", + E_USER_WARNING + ); + continue; + } + // Check if plugin implements 'Plugin' interface + if (! in_array('Plugin', class_implements($plugin_classname))) { + trigger_error( + "Plugin class '{$plugin_classname}' does not implement " . + "'Plugin' interface!", + E_USER_WARNING + ); + continue; + } + // Add plugin to loading queue + $plugin_instance = new $plugin_classname($plugin_config); + $loading_queue[$plugin_instance->getWeight() . "_" . $offset] = $plugin_instance; + $offset++; + } + // Sort queue in order to plugins' weights + uksort($loading_queue, 'strnatcmp'); + // Add events and listeners + foreach ($loading_queue as $plugin) { + $plugin->registerEvents(); + $plugin->registerListeners(); + } + } +} + +?> \ No newline at end of file diff --git a/src/messenger/webim/plugins/.htaccess b/src/messenger/webim/plugins/.htaccess new file mode 100644 index 00000000..14249c50 --- /dev/null +++ b/src/messenger/webim/plugins/.htaccess @@ -0,0 +1 @@ +Deny from all \ No newline at end of file