storage = new SplObjectStorage(); } public function __clone() { $storage = $this->storage; $this->storage = new SplObjectStorage(); $this->storage->addAll($storage); } /** * Registers a listener, pass the listener events to the target. * * @param ListenerInterface $listener * @param null|EventEmitter $target * * @return ListenersInterface */ public function register(ListenerInterface $listener, EventEmitter $target = null) { $EElisteners = array(); if (null !== $target) { $EElisteners = $this->forwardEvents($listener, $target, $listener->forwardedEvents()); } $this->storage->attach($listener, $EElisteners); return $this; } /** * Unregisters a listener, removes the listener events from the target. * * @param ListenerInterface $listener * * @return ListenersInterface * * @throws InvalidArgumentException In case the listener is not registered */ public function unregister(ListenerInterface $listener) { if (!isset($this->storage[$listener])) { throw new InvalidArgumentException('Listener is not registered.'); } foreach ($this->storage[$listener] as $event => $EElistener) { $listener->removeListener($event, $EElistener); } $this->storage->detach($listener); return $this; } private function forwardEvents($source, $target, array $events) { $EElisteners = array(); foreach ($events as $event) { $listener = $this->createListener($event, $target); $source->on($event, $EElisteners[$event] = $listener); } return $EElisteners; } private function createListener($event, $target) { return function () use ($event, $target) { $target->emit($event, func_get_args()); }; } }