123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209 |
- <?php
- /*
- * This file is part of the Symfony package.
- *
- * (c) Fabien Potencier <fabien@symfony.com>
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
- namespace Symfony\Bridge\Doctrine;
- use Doctrine\Common\EventArgs;
- use Doctrine\Common\EventManager;
- use Psr\Container\ContainerInterface;
- /**
- * Allows lazy loading of listener and subscriber services.
- *
- * @author Johannes M. Schmitt <schmittjoh@gmail.com>
- */
- class ContainerAwareEventManager extends EventManager
- {
- /**
- * Map of registered listeners.
- *
- * <event> => <listeners>
- */
- private $listeners = [];
- private $subscribers;
- private $initialized = [];
- private $initializedSubscribers = false;
- private $methods = [];
- private $container;
- public function __construct(ContainerInterface $container, array $subscriberIds = [])
- {
- $this->container = $container;
- $this->subscribers = $subscriberIds;
- }
- /**
- * {@inheritdoc}
- *
- * @return void
- */
- public function dispatchEvent($eventName, EventArgs $eventArgs = null)
- {
- if (!$this->initializedSubscribers) {
- $this->initializeSubscribers();
- }
- if (!isset($this->listeners[$eventName])) {
- return;
- }
- $eventArgs = null === $eventArgs ? EventArgs::getEmptyInstance() : $eventArgs;
- if (!isset($this->initialized[$eventName])) {
- $this->initializeListeners($eventName);
- }
- foreach ($this->listeners[$eventName] as $hash => $listener) {
- $listener->{$this->methods[$eventName][$hash]}($eventArgs);
- }
- }
- /**
- * {@inheritdoc}
- *
- * @return object[][]
- */
- public function getListeners($event = null)
- {
- if (!$this->initializedSubscribers) {
- $this->initializeSubscribers();
- }
- if (null !== $event) {
- if (!isset($this->initialized[$event])) {
- $this->initializeListeners($event);
- }
- return $this->listeners[$event];
- }
- foreach ($this->listeners as $event => $listeners) {
- if (!isset($this->initialized[$event])) {
- $this->initializeListeners($event);
- }
- }
- return $this->listeners;
- }
- /**
- * {@inheritdoc}
- *
- * @return bool
- */
- public function hasListeners($event)
- {
- if (!$this->initializedSubscribers) {
- $this->initializeSubscribers();
- }
- return isset($this->listeners[$event]) && $this->listeners[$event];
- }
- /**
- * {@inheritdoc}
- *
- * @return void
- */
- public function addEventListener($events, $listener)
- {
- $hash = $this->getHash($listener);
- foreach ((array) $events as $event) {
- // Overrides listener if a previous one was associated already
- // Prevents duplicate listeners on same event (same instance only)
- $this->listeners[$event][$hash] = $listener;
- if (\is_string($listener)) {
- unset($this->initialized[$event]);
- } else {
- $this->methods[$event][$hash] = $this->getMethod($listener, $event);
- }
- }
- }
- /**
- * {@inheritdoc}
- *
- * @return void
- */
- public function removeEventListener($events, $listener)
- {
- $hash = $this->getHash($listener);
- foreach ((array) $events as $event) {
- // Check if we actually have this listener associated
- if (isset($this->listeners[$event][$hash])) {
- unset($this->listeners[$event][$hash]);
- }
- if (isset($this->methods[$event][$hash])) {
- unset($this->methods[$event][$hash]);
- }
- }
- }
- private function initializeListeners(string $eventName)
- {
- $this->initialized[$eventName] = true;
- foreach ($this->listeners[$eventName] as $hash => $listener) {
- if (\is_string($listener)) {
- $this->listeners[$eventName][$hash] = $listener = $this->container->get($listener);
- $this->methods[$eventName][$hash] = $this->getMethod($listener, $eventName);
- }
- }
- }
- private function initializeSubscribers()
- {
- $this->initializedSubscribers = true;
- $eventListeners = $this->listeners;
- // reset eventListener to respect priority: EventSubscribers have a higher priority
- $this->listeners = [];
- foreach ($this->subscribers as $id => $subscriber) {
- if (\is_string($subscriber)) {
- parent::addEventSubscriber($this->subscribers[$id] = $this->container->get($subscriber));
- }
- }
- foreach ($eventListeners as $event => $listeners) {
- if (!isset($this->listeners[$event])) {
- $this->listeners[$event] = [];
- }
- unset($this->initialized[$event]);
- $this->listeners[$event] += $listeners;
- }
- $this->subscribers = [];
- }
- /**
- * @param string|object $listener
- */
- private function getHash($listener): string
- {
- if (\is_string($listener)) {
- return '_service_'.$listener;
- }
- return spl_object_hash($listener);
- }
- /**
- * @param object $listener
- */
- private function getMethod($listener, string $event): string
- {
- if (!method_exists($listener, $event) && method_exists($listener, '__invoke')) {
- return '__invoke';
- }
- return $event;
- }
- }
|