90 lines
2.2 KiB
PHP
90 lines
2.2 KiB
PHP
|
<?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\Component\Messenger\Handler;
|
||
|
|
||
|
use Symfony\Component\Messenger\Envelope;
|
||
|
use Symfony\Component\Messenger\Stamp\ReceivedStamp;
|
||
|
|
||
|
/**
|
||
|
* Maps a message to a list of handlers.
|
||
|
*
|
||
|
* @author Nicolas Grekas <p@tchwork.com>
|
||
|
* @author Samuel Roze <samuel.roze@gmail.com>
|
||
|
*/
|
||
|
class HandlersLocator implements HandlersLocatorInterface
|
||
|
{
|
||
|
private $handlers;
|
||
|
|
||
|
/**
|
||
|
* @param HandlerDescriptor[][]|callable[][] $handlers
|
||
|
*/
|
||
|
public function __construct(array $handlers)
|
||
|
{
|
||
|
$this->handlers = $handlers;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* {@inheritdoc}
|
||
|
*/
|
||
|
public function getHandlers(Envelope $envelope): iterable
|
||
|
{
|
||
|
$seen = [];
|
||
|
|
||
|
foreach (self::listTypes($envelope) as $type) {
|
||
|
foreach ($this->handlers[$type] ?? [] as $handlerDescriptor) {
|
||
|
if (\is_callable($handlerDescriptor)) {
|
||
|
$handlerDescriptor = new HandlerDescriptor($handlerDescriptor);
|
||
|
}
|
||
|
|
||
|
if (!$this->shouldHandle($envelope, $handlerDescriptor)) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
$name = $handlerDescriptor->getName();
|
||
|
if (\in_array($name, $seen)) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
$seen[] = $name;
|
||
|
|
||
|
yield $handlerDescriptor;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @internal
|
||
|
*/
|
||
|
public static function listTypes(Envelope $envelope): array
|
||
|
{
|
||
|
$class = \get_class($envelope->getMessage());
|
||
|
|
||
|
return [$class => $class]
|
||
|
+ class_parents($class)
|
||
|
+ class_implements($class)
|
||
|
+ ['*' => '*'];
|
||
|
}
|
||
|
|
||
|
private function shouldHandle(Envelope $envelope, HandlerDescriptor $handlerDescriptor): bool
|
||
|
{
|
||
|
if (null === $received = $envelope->last(ReceivedStamp::class)) {
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
if (null === $expectedTransport = $handlerDescriptor->getOption('from_transport')) {
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
return $received->getTransportName() === $expectedTransport;
|
||
|
}
|
||
|
}
|