ContainerAwareQueryHandlerLocator::getHandlers()   A
last analyzed

Complexity

Conditions 6
Paths 5

Size

Total Lines 24
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 14
nc 5
nop 1
dl 0
loc 24
rs 9.2222
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * cqrs-symfony-messenger (https://github.com/phpgears/cqrs-symfony-messenger).
5
 * CQRS implementation with Symfony's Messenger.
6
 *
7
 * @license MIT
8
 * @link https://github.com/phpgears/cqrs-symfony-messenger
9
 * @author Julián Gutiérrez <[email protected]>
10
 */
11
12
declare(strict_types=1);
13
14
namespace Gears\CQRS\Symfony\Messenger;
15
16
use Gears\CQRS\Exception\InvalidQueryHandlerException;
17
use Gears\CQRS\Query;
18
use Gears\CQRS\QueryHandler;
19
use Gears\DTO\DTO;
20
use Psr\Container\ContainerInterface;
21
use Symfony\Component\Messenger\Envelope;
22
use Symfony\Component\Messenger\Handler\HandlerDescriptor;
23
24
class ContainerAwareQueryHandlerLocator extends QueryHandlerLocator
25
{
26
    /**
27
     * PSR container.
28
     *
29
     * @var ContainerInterface
30
     */
31
    private $container;
32
33
    /**
34
     * ContainerAwareCommandHandlerLocator constructor.
35
     *
36
     * @param ContainerInterface $container
37
     * @param mixed[]            $handlers
38
     */
39
    public function __construct(ContainerInterface $container, array $handlers)
40
    {
41
        $this->container = $container;
42
43
        parent::__construct($handlers);
44
    }
45
46
    /**
47
     * {@inheritdoc}
48
     *
49
     * @throws InvalidQueryHandlerException
50
     */
51
    public function getHandlers(Envelope $envelope): iterable
52
    {
53
        $seen = [];
54
55
        foreach ($this->getQueryMap($envelope) as $type) {
56
            foreach ($this->handlersMap[$type] ?? [] as $alias => $handler) {
57
                $handler = $this->container->get($handler);
58
59
                if (!$handler instanceof QueryHandler) {
60
                    throw new InvalidQueryHandlerException(\sprintf(
61
                        'Query handler must implement %s interface, %s given.',
62
                        QueryHandler::class,
63
                        \is_object($handler) ? \get_class($handler) : \gettype($handler)
64
                    ));
65
                }
66
67
                $handlerCallable = function (Query $query) use ($handler): DTO {
68
                    return $handler->handle($query);
69
                };
70
71
                if (!\in_array($handlerCallable, $seen, true)) {
72
                    $seen[] = $handlerCallable;
73
74
                    yield $alias => new HandlerDescriptor($handlerCallable);
75
                }
76
            }
77
        }
78
    }
79
}
80