Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
23 / 23
100.00% covered (success)
100.00%
3 / 3
CRAP
100.00% covered (success)
100.00%
1 / 1
SyncCommandBus
100.00% covered (success)
100.00%
23 / 23
100.00% covered (success)
100.00%
3 / 3
5
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 dispatch
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 resolveHandler
100.00% covered (success)
100.00%
16 / 16
100.00% covered (success)
100.00%
1 / 1
3
1<?php
2
3// ╔════════════════════════════════════════════════════════════╗
4// ║ MIT Licence (#Expat) - https://opensource.org/licenses/MIT ║
5// ║ Copyright 2026 Frederic Poeydomenge <dyno@phexium.com>     ║
6// ╚════════════════════════════════════════════════════════════╝
7
8declare(strict_types=1);
9
10namespace Phexium\Plugin\CommandBus\Adapter;
11
12use InvalidArgumentException;
13use Override;
14use Phexium\Application\Command\CommandHandlerInterface;
15use Phexium\Application\Command\CommandInterface;
16use Phexium\Plugin\CommandBus\Internal\CommandHandlerNamingConvention;
17use Phexium\Plugin\CommandBus\Port\CommandBusInterface;
18use Phexium\Plugin\Logger\Port\LoggerInterface;
19use Psr\Container\ContainerInterface;
20
21final readonly class SyncCommandBus implements CommandBusInterface
22{
23    public function __construct(
24        private ContainerInterface $container,
25        private LoggerInterface $logger
26    ) {}
27
28    #[Override]
29    public function dispatch(CommandInterface $command): void
30    {
31        $commandClass = $command::class;
32
33        $this->logger->debug('CommandBus: Dispatching command', [
34            'command' => $commandClass,
35        ]);
36
37        $handler = $this->resolveHandler($commandClass);
38        $handler->handle($command);
39    }
40
41    private function resolveHandler(string $commandClass): CommandHandlerInterface
42    {
43        $handlerClass = CommandHandlerNamingConvention::resolveHandlerClass($commandClass);
44
45        if (!class_exists($handlerClass)) {
46            throw new InvalidArgumentException(
47                sprintf(
48                    'Handler not found for command %s. Expected class: %s',
49                    $commandClass,
50                    $handlerClass
51                )
52            );
53        }
54
55        $handler = $this->container->get($handlerClass);
56
57        if (!$handler instanceof CommandHandlerInterface) {
58            throw new InvalidArgumentException(sprintf(
59                'Handler must implement %s.',
60                CommandHandlerInterface::class
61            ));
62        }
63
64        return $handler;
65    }
66}