* $sharedEventManager = new SharedEventManager(); * foreach (['My\Resource\AbstractResource', 'My\Resource\EntityResource'] as $identifier) { * $sharedEventManager->attach( * $identifier, * 'getAll', * function ($e) use ($cache) { * if (!$id = $e->getParam('id', false)) { * return; * } * if (!$data = $cache->load(get_class($resource) . '::getOne::' . $id )) { * return; * } * return $data; * } * ); * } * * * @param string $identifier Identifier for event emitting component. * @param string $event * @param callable $listener Listener that will handle the event. * @param int $priority Priority at which listener should execute * @return void * @throws Exception\InvalidArgumentException For invalid identifier arguments. * @throws Exception\InvalidArgumentException For invalid event arguments. */ public function attach($identifier, $event, callable $listener, $priority = 1) { if (! is_string($identifier) || empty($identifier)) { throw new Exception\InvalidArgumentException(sprintf( 'Invalid identifier provided; must be a string; received "%s"', get_debug_type($identifier), )); } if (! is_string($event) || empty($event)) { throw new Exception\InvalidArgumentException(sprintf( 'Invalid event provided; must be a non-empty string; received "%s"', get_debug_type($event), )); } $this->identifiers[$identifier][$event][(int) $priority][] = $listener; } /** * @inheritDoc */ public function detach(callable $listener, $identifier = null, $eventName = null, $force = false) { // No identifier or wildcard identifier: loop through all identifiers and detach if (null === $identifier || ('*' === $identifier && ! $force)) { foreach (array_keys($this->identifiers) as $identifier) { $this->detach($listener, $identifier, $eventName, true); } return; } if (! is_string($identifier) || empty($identifier)) { throw new Exception\InvalidArgumentException(sprintf( 'Invalid identifier provided; must be a string, received %s', get_debug_type($identifier), )); } // Do we have any listeners on the provided identifier? if (! isset($this->identifiers[$identifier])) { return; } if (null === $eventName || ('*' === $eventName && ! $force)) { foreach (array_keys($this->identifiers[$identifier]) as $eventName) { $this->detach($listener, $identifier, $eventName, true); } return; } if (! is_string($eventName) || empty($eventName)) { throw new Exception\InvalidArgumentException(sprintf( 'Invalid event name provided; must be a string, received %s', get_debug_type($eventName), )); } if (! isset($this->identifiers[$identifier][$eventName])) { return; } foreach ($this->identifiers[$identifier][$eventName] as $priority => $listeners) { foreach ($listeners as $index => $evaluatedListener) { if ($evaluatedListener !== $listener) { continue; } // Found the listener; remove it. unset($this->identifiers[$identifier][$eventName][$priority][$index]); // Is the priority queue empty? if (empty($this->identifiers[$identifier][$eventName][$priority])) { unset($this->identifiers[$identifier][$eventName][$priority]); break; } } // Is the event queue empty? if (empty($this->identifiers[$identifier][$eventName])) { unset($this->identifiers[$identifier][$eventName]); break; } } // Is the identifier queue now empty? Remove it. if (empty($this->identifiers[$identifier])) { unset($this->identifiers[$identifier]); } } /** * Retrieve all listeners for a given identifier and event * * @param string[] $identifiers * @param string $eventName * @return array[] * @throws Exception\InvalidArgumentException */ public function getListeners(array $identifiers, $eventName) { if ('*' === $eventName || ! is_string($eventName) || empty($eventName)) { throw new Exception\InvalidArgumentException(sprintf( 'Event name passed to %s must be a non-empty, non-wildcard string', __METHOD__ )); } $returnListeners = []; foreach ($identifiers as $identifier) { if ('*' === $identifier || ! is_string($identifier) || empty($identifier)) { throw new Exception\InvalidArgumentException(sprintf( 'Identifier names passed to %s must be non-empty, non-wildcard strings', __METHOD__ )); } if (isset($this->identifiers[$identifier])) { $listenersByIdentifier = $this->identifiers[$identifier]; if (isset($listenersByIdentifier[$eventName])) { foreach ($listenersByIdentifier[$eventName] as $priority => $listeners) { $returnListeners[$priority][] = $listeners; } } if (isset($listenersByIdentifier['*'])) { foreach ($listenersByIdentifier['*'] as $priority => $listeners) { $returnListeners[$priority][] = $listeners; } } } } if (isset($this->identifiers['*'])) { $wildcardIdentifier = $this->identifiers['*']; if (isset($wildcardIdentifier[$eventName])) { foreach ($wildcardIdentifier[$eventName] as $priority => $listeners) { $returnListeners[$priority][] = $listeners; } } if (isset($wildcardIdentifier['*'])) { foreach ($wildcardIdentifier['*'] as $priority => $listeners) { $returnListeners[$priority][] = $listeners; } } } foreach ($returnListeners as $priority => $listOfListeners) { $returnListeners[$priority] = array_merge(...$listOfListeners); } return $returnListeners; } /** * @inheritDoc */ public function clearListeners($identifier, $eventName = null) { if (! isset($this->identifiers[$identifier])) { return false; } if (null === $eventName) { unset($this->identifiers[$identifier]); return; } if (! isset($this->identifiers[$identifier][$eventName])) { return; } unset($this->identifiers[$identifier][$eventName]); } }