HandlersLocator.php 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  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\Component\Messenger\Handler;
  11. use Symfony\Component\Messenger\Envelope;
  12. use Symfony\Component\Messenger\Stamp\ReceivedStamp;
  13. /**
  14. * Maps a message to a list of handlers.
  15. *
  16. * @author Nicolas Grekas <p@tchwork.com>
  17. * @author Samuel Roze <samuel.roze@gmail.com>
  18. */
  19. class HandlersLocator implements HandlersLocatorInterface
  20. {
  21. private $handlers;
  22. /**
  23. * @param HandlerDescriptor[][]|callable[][] $handlers
  24. */
  25. public function __construct(array $handlers)
  26. {
  27. $this->handlers = $handlers;
  28. }
  29. /**
  30. * {@inheritdoc}
  31. */
  32. public function getHandlers(Envelope $envelope): iterable
  33. {
  34. $seen = [];
  35. foreach (self::listTypes($envelope) as $type) {
  36. foreach ($this->handlers[$type] ?? [] as $handlerDescriptor) {
  37. if (\is_callable($handlerDescriptor)) {
  38. $handlerDescriptor = new HandlerDescriptor($handlerDescriptor);
  39. }
  40. if (!$this->shouldHandle($envelope, $handlerDescriptor)) {
  41. continue;
  42. }
  43. $name = $handlerDescriptor->getName();
  44. if (\in_array($name, $seen)) {
  45. continue;
  46. }
  47. $seen[] = $name;
  48. yield $handlerDescriptor;
  49. }
  50. }
  51. }
  52. /**
  53. * @internal
  54. */
  55. public static function listTypes(Envelope $envelope): array
  56. {
  57. $class = \get_class($envelope->getMessage());
  58. return [$class => $class]
  59. + class_parents($class)
  60. + class_implements($class)
  61. + ['*' => '*'];
  62. }
  63. private function shouldHandle(Envelope $envelope, HandlerDescriptor $handlerDescriptor): bool
  64. {
  65. if (null === $received = $envelope->last(ReceivedStamp::class)) {
  66. return true;
  67. }
  68. if (null === $expectedTransport = $handlerDescriptor->getOption('from_transport')) {
  69. return true;
  70. }
  71. return $received->getTransportName() === $expectedTransport;
  72. }
  73. }