Advertisement
Guest User

Untitled

a guest
May 24th, 2016
46
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.68 KB | None | 0 0
  1. <?php
  2. use ISV\Service\Cache\CacheInterface;
  3. use ISV\Service\Cache\FileCache;
  4. use Symfony\Component\DependencyInjection\ContainerInterface;
  5. use Symfony\Component\EventDispatcher\Event;
  6. use Symfony\Component\EventDispatcher\EventDispatcher;
  7.  
  8. /**
  9. * Overrides the symfony event dispatcher so that we don't call addListener() 400 times for every request when 90%
  10. * of requests never dispatch an event.
  11. *
  12. * When dispatch() is called, we addListener() first and then dispatch().
  13. *
  14. * Stole some ideas from ContainerAwareEventDispatcher
  15. */
  16. class LazyEventDispatcher extends EventDispatcher
  17. {
  18. const CACHE_KEY = 'LazyEventDispatcher';
  19.  
  20. // array index in $listeners
  21. const SERVICE = 0;
  22. const METHOD = 1;
  23. const PRIORITY = 2;
  24.  
  25. /** @var CacheInterface */
  26. private $cache;
  27.  
  28. /** @var array eventName => array of ['service', 'method', 'priority'] one per listener */
  29. private $listeners = [];
  30.  
  31. /** @var ContainerInterface */
  32. private $container;
  33.  
  34. /**
  35. * LazyEventDispatcher constructor.
  36. * @param ContainerInterface $container
  37. * @param CacheInterface $cache for unit testing: so we can inject a different cache if needed
  38. */
  39. public function __construct(ContainerInterface $container, CacheInterface $cache = null)
  40. {
  41. $this->container = $container;
  42. $this->cache = $cache;
  43. }
  44.  
  45. /**
  46. * @return array
  47. */
  48. public function getLazyListeners()
  49. {
  50. if (empty($this->listeners)) {
  51. $this->listeners = $this->getCache()->get(self::CACHE_KEY);
  52. if (empty($this->listeners)) {
  53. $this->listeners = [];
  54. }
  55. }
  56. return $this->listeners;
  57. }
  58.  
  59. /**
  60. * save them to cache so we can load them later.
  61. * called at compile time.
  62. */
  63. public function saveLazyListeners()
  64. {
  65. ksort($this->listeners);
  66. $this->getCache()->set(self::CACHE_KEY, $this->listeners);
  67. }
  68.  
  69. /**
  70. * Adds an event listener that listens on the specified events. Called by a container compiler class at build time.
  71. *
  72. * @param string $eventName The event to listen for
  73. * @param string $serviceName usually a class name
  74. * @param string $methodName eg onPersonDelete
  75. * @param int $priority The higher this value, the earlier an event
  76. * listener will be triggered in the chain (defaults to 0)
  77. */
  78. public function addLazyListener($eventName, $serviceName, $methodName, $priority = 0)
  79. {
  80. $this->listeners[$eventName][] = [
  81. self::SERVICE => $serviceName,
  82. self::METHOD => $methodName,
  83. self::PRIORITY => $priority,
  84. ];
  85. }
  86.  
  87. /**
  88. * {@inheritdoc}
  89. */
  90. public function dispatch($eventName, Event $event = null)
  91. {
  92. if ($this->hasListeners($eventName)) {
  93. return parent::dispatch($eventName, $event);
  94. }
  95.  
  96. $allListeners = $this->getLazyListeners();
  97. if (!isset($allListeners[$eventName])) {
  98. return parent::dispatch($eventName, $event);
  99. }
  100.  
  101. // add them then dispatch
  102. foreach ($allListeners[$eventName] as $handler) {
  103. $service = $this->container->get($handler[self::SERVICE]);
  104. $this->addListener($eventName, [$service, $handler[self::METHOD]], $handler[self::PRIORITY]);
  105. }
  106. return parent::dispatch($eventName, $event);
  107. }
  108.  
  109. /**
  110. * no need to clear the cache explicitly: it will be automatically rebuilt when the container is rebuilt
  111. * @return CacheInterface
  112. */
  113. private function getCache()
  114. {
  115. if (empty($this->cache)) {
  116. $this->cache = new FileCache(CACHE_PATH);
  117. }
  118. return $this->cache;
  119. }
  120. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement