EventDispatcher.php 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. <?php
  2. namespace JMS\SerializerBundle\EventDispatcher;
  3. use JMS\SerializerBundle\EventDispatcher\EventDispatcherInterface;
  4. use JMS\SerializerBundle\EventDispatcher\EventSubscriberInterface;
  5. /**
  6. * Light-weight event dispatcher.
  7. *
  8. * This implementation focuses primarily on performance, and dispatching
  9. * events for certain classes. It is not a general purpose event dispatcher.
  10. *
  11. * @author Johannes M. Schmitt <schmittjoh@gmail.com>
  12. */
  13. class EventDispatcher implements EventDispatcherInterface
  14. {
  15. private $listeners = array();
  16. private $classListeners = array();
  17. public static function getDefaultMethodName($eventName)
  18. {
  19. return 'on'.str_replace(array('_', '.'), '', $eventName);
  20. }
  21. /**
  22. * Sets the listeners.
  23. *
  24. * @param array $listeners
  25. */
  26. public function setListeners(array $listeners)
  27. {
  28. $this->listeners = $listeners;
  29. $this->classListeners = array();
  30. }
  31. public function addListener($eventName, $callable, $class = null, $format = null)
  32. {
  33. $this->listeners[$eventName][] = array($callable, null === $class ? null : strtolower($class), $format);
  34. unset($this->classListeners[$eventName]);
  35. }
  36. public function addSubscriber(EventSubscriberInterface $subscriber)
  37. {
  38. foreach ($subscriber->getSubscribedEvents() as $eventData) {
  39. if ( ! isset($eventData['event'])) {
  40. throw new \InvalidArgumentException(sprintf('Each event must have a "event" key.'));
  41. }
  42. $method = isset($eventData['method']) ? $eventData['method'] : self::getDefaultMethodName($eventData['event']);
  43. $class = isset($eventData['class']) ? strtolower($eventData['class']) : null;
  44. $format = isset($eventData['format']) ? $eventData['format'] : null;
  45. $this->listeners[$eventData['event']][] = array(array($subscriber, $method), $class, $format);
  46. unset($this->classListeners[$eventData['event']]);
  47. }
  48. }
  49. public function hasListeners($eventName, $class, $format)
  50. {
  51. if ( ! isset($this->listeners[$eventName])) {
  52. return false;
  53. }
  54. $loweredClass = strtolower($class);
  55. if ( ! isset($this->classListeners[$eventName][$loweredClass][$format])) {
  56. $this->classListeners[$eventName][$loweredClass][$format] = $this->initializeListeners($eventName, $loweredClass, $format);
  57. }
  58. return !!$this->classListeners[$eventName][$loweredClass][$format];
  59. }
  60. public function dispatch($eventName, $class, $format, Event $event)
  61. {
  62. if ( ! isset($this->listeners[$eventName])) {
  63. return;
  64. }
  65. $loweredClass = strtolower($class);
  66. if ( ! isset($this->classListeners[$eventName][$loweredClass][$format])) {
  67. $this->classListeners[$eventName][$loweredClass][$format] = $this->initializeListeners($eventName, $loweredClass, $format);
  68. }
  69. foreach ($this->classListeners[$eventName][$loweredClass][$format] as $listener) {
  70. call_user_func($listener, $event);
  71. }
  72. }
  73. protected function initializeListeners($eventName, $loweredClass, $format)
  74. {
  75. $listeners = array();
  76. foreach ($this->listeners[$eventName] as $listener) {
  77. if (null !== $listener[1] && $loweredClass !== $listener[1]) {
  78. continue;
  79. }
  80. if (null !== $listener[2] && $format !== $listener[2]) {
  81. continue;
  82. }
  83. $listeners[] = $listener[0];
  84. }
  85. return $listeners;
  86. }
  87. }