ContainerAwareEventManager.php 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Bridge\Doctrine;
  11. use Doctrine\Common\EventArgs;
  12. use Doctrine\Common\EventManager;
  13. use Symfony\Component\DependencyInjection\ContainerInterface;
  14. /**
  15. * Allows lazy loading of listener services.
  16. *
  17. * @author Johannes M. Schmitt <schmittjoh@gmail.com>
  18. */
  19. class ContainerAwareEventManager extends EventManager
  20. {
  21. /**
  22. * Map of registered listeners.
  23. *
  24. * <event> => <listeners>
  25. */
  26. private $listeners = array();
  27. private $initialized = array();
  28. private $container;
  29. public function __construct(ContainerInterface $container)
  30. {
  31. $this->container = $container;
  32. }
  33. /**
  34. * Dispatches an event to all registered listeners.
  35. *
  36. * @param string $eventName The name of the event to dispatch. The name of the event is
  37. * the name of the method that is invoked on listeners.
  38. * @param EventArgs $eventArgs The event arguments to pass to the event handlers/listeners.
  39. * If not supplied, the single empty EventArgs instance is used.
  40. *
  41. * @return bool
  42. */
  43. public function dispatchEvent($eventName, EventArgs $eventArgs = null)
  44. {
  45. if (isset($this->listeners[$eventName])) {
  46. $eventArgs = null === $eventArgs ? EventArgs::getEmptyInstance() : $eventArgs;
  47. $initialized = isset($this->initialized[$eventName]);
  48. foreach ($this->listeners[$eventName] as $hash => $listener) {
  49. if (!$initialized && \is_string($listener)) {
  50. $this->listeners[$eventName][$hash] = $listener = $this->container->get($listener);
  51. }
  52. $listener->$eventName($eventArgs);
  53. }
  54. $this->initialized[$eventName] = true;
  55. }
  56. }
  57. /**
  58. * Gets the listeners of a specific event or all listeners.
  59. *
  60. * @param string $event The name of the event
  61. *
  62. * @return array The event listeners for the specified event, or all event listeners
  63. */
  64. public function getListeners($event = null)
  65. {
  66. return $event ? $this->listeners[$event] : $this->listeners;
  67. }
  68. /**
  69. * Checks whether an event has any registered listeners.
  70. *
  71. * @param string $event
  72. *
  73. * @return bool TRUE if the specified event has any listeners, FALSE otherwise
  74. */
  75. public function hasListeners($event)
  76. {
  77. return isset($this->listeners[$event]) && $this->listeners[$event];
  78. }
  79. /**
  80. * Adds an event listener that listens on the specified events.
  81. *
  82. * @param string|array $events The event(s) to listen on
  83. * @param object|string $listener The listener object
  84. *
  85. * @throws \RuntimeException
  86. */
  87. public function addEventListener($events, $listener)
  88. {
  89. if (\is_string($listener)) {
  90. if ($this->initialized) {
  91. throw new \RuntimeException('Adding lazy-loading listeners after construction is not supported.');
  92. }
  93. $hash = '_service_'.$listener;
  94. } else {
  95. // Picks the hash code related to that listener
  96. $hash = spl_object_hash($listener);
  97. }
  98. foreach ((array) $events as $event) {
  99. // Overrides listener if a previous one was associated already
  100. // Prevents duplicate listeners on same event (same instance only)
  101. $this->listeners[$event][$hash] = $listener;
  102. }
  103. }
  104. /**
  105. * Removes an event listener from the specified events.
  106. *
  107. * @param string|array $events
  108. * @param object|string $listener
  109. */
  110. public function removeEventListener($events, $listener)
  111. {
  112. if (\is_string($listener)) {
  113. $hash = '_service_'.$listener;
  114. } else {
  115. // Picks the hash code related to that listener
  116. $hash = spl_object_hash($listener);
  117. }
  118. foreach ((array) $events as $event) {
  119. // Check if actually have this listener associated
  120. if (isset($this->listeners[$event][$hash])) {
  121. unset($this->listeners[$event][$hash]);
  122. }
  123. }
  124. }
  125. }