aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/hooks/basicemitter.php2
-rw-r--r--lib/hooks/forwardingemitter.php50
-rw-r--r--tests/lib/hooks/forwardingemitter.php74
3 files changed, 125 insertions, 1 deletions
diff --git a/lib/hooks/basicemitter.php b/lib/hooks/basicemitter.php
index e615a58cfe8..9ffe1af2314 100644
--- a/lib/hooks/basicemitter.php
+++ b/lib/hooks/basicemitter.php
@@ -13,7 +13,7 @@ abstract class BasicEmitter implements Emitter {
/**
* @var (callable[])[] $listeners
*/
- private $listeners = array();
+ protected $listeners = array();
/**
* @param string $scope
diff --git a/lib/hooks/forwardingemitter.php b/lib/hooks/forwardingemitter.php
new file mode 100644
index 00000000000..1aacc4012e0
--- /dev/null
+++ b/lib/hooks/forwardingemitter.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OC\Hooks;
+
+/**
+ * Class ForwardingEmitter
+ *
+ * allows forwarding all listen calls to other emitters
+ *
+ * @package OC\Hooks
+ */
+abstract class ForwardingEmitter extends BasicEmitter {
+ /**
+ * @var \OC\Hooks\Emitter[] array
+ */
+ private $forwardEmitters = array();
+
+ /**
+ * @param string $scope
+ * @param string $method
+ * @param callable $callback
+ */
+ public function listen($scope, $method, $callback) {
+ parent::listen($scope, $method, $callback);
+ foreach ($this->forwardEmitters as $emitter) {
+ $emitter->listen($scope, $method, $callback);
+ }
+ }
+
+ /**
+ * @param \OC\Hooks\Emitter $emitter
+ */
+ protected function forward($emitter) {
+ $this->forwardEmitters[] = $emitter;
+
+ //forward all previously connected hooks
+ foreach ($this->listeners as $key => $listeners) {
+ list($scope, $method) = explode('::', $key, 2);
+ foreach ($listeners as $listener) {
+ $emitter->listen($scope, $method, $listener);
+ }
+ }
+ }
+}
diff --git a/tests/lib/hooks/forwardingemitter.php b/tests/lib/hooks/forwardingemitter.php
new file mode 100644
index 00000000000..decf6bb354c
--- /dev/null
+++ b/tests/lib/hooks/forwardingemitter.php
@@ -0,0 +1,74 @@
+<?php
+/**
+ * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace Test\Hooks;
+use OC\Hooks\PublicEmitter;
+
+class DummyForwardingEmitter extends \OC\Hooks\ForwardingEmitter {
+ public function emitEvent($scope, $method, $arguments = array()) {
+ $this->emit($scope, $method, $arguments);
+ }
+
+ /**
+ * @param \OC\Hooks\Emitter $emitter
+ */
+ public function forward($emitter) {
+ parent::forward($emitter);
+ }
+}
+
+/**
+ * Class ForwardingEmitter
+ *
+ * allows forwarding all listen calls to other emitters
+ *
+ * @package OC\Hooks
+ */
+class ForwardingEmitter extends BasicEmitter {
+ public function testSingleForward() {
+ $baseEmitter = new PublicEmitter();
+ $forwardingEmitter = new DummyForwardingEmitter();
+ $forwardingEmitter->forward($baseEmitter);
+ $hookCalled = false;
+ $forwardingEmitter->listen('Test', 'test', function () use (&$hookCalled) {
+ $hookCalled = true;
+ });
+ $baseEmitter->emit('Test', 'test');
+ $this->assertTrue($hookCalled);
+ }
+
+ public function testMultipleForwards() {
+ $baseEmitter1 = new PublicEmitter();
+ $baseEmitter2 = new PublicEmitter();
+ $forwardingEmitter = new DummyForwardingEmitter();
+ $forwardingEmitter->forward($baseEmitter1);
+ $forwardingEmitter->forward($baseEmitter2);
+ $hookCalled = 0;
+ $forwardingEmitter->listen('Test', 'test1', function () use (&$hookCalled) {
+ $hookCalled++;
+ });
+ $forwardingEmitter->listen('Test', 'test2', function () use (&$hookCalled) {
+ $hookCalled++;
+ });
+ $baseEmitter1->emit('Test', 'test1');
+ $baseEmitter1->emit('Test', 'test2');
+ $this->assertEquals(2, $hookCalled);
+ }
+
+ public function testForwardExistingHooks() {
+ $baseEmitter = new PublicEmitter();
+ $forwardingEmitter = new DummyForwardingEmitter();
+ $hookCalled = false;
+ $forwardingEmitter->listen('Test', 'test', function () use (&$hookCalled) {
+ $hookCalled = true;
+ });
+ $forwardingEmitter->forward($baseEmitter);
+ $baseEmitter->emit('Test', 'test');
+ $this->assertTrue($hookCalled);
+ }
+}