Completed
Push — master ( 7d6afc...af3c22 )
by Douglas
02:06
created

AbstractBus   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 87
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 86.21%

Importance

Changes 0
Metric Value
wmc 8
lcom 1
cbo 3
dl 0
loc 87
ccs 25
cts 29
cp 0.8621
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A registerHandler() 0 9 1
A post() 0 20 1
A log() 0 8 2
A findHandler() 0 15 3
1
<?php
2
3
/**
4
 * (c) 2018 Douglas Reith.
5
 *
6
 * For the full copyright and license information, please view the LICENSE
7
 * file that was distributed with this source code.
8
 */
9
declare(strict_types=1);
10
11
namespace Reith\ToyRobot\Infrastructure\Bus;
12
13
use Psr\Log\LoggerInterface;
14
use Assert\Assertion;
15
use Reith\ToyRobot\Messaging\BusInterface;
16
17
abstract class AbstractBus implements BusInterface
18
{
19
    // Message handlers
20
    private $handlers;
21
22
    private $logger;
23
24
    /**
25
     * @param LoggerInterface|null $logger
26
     */
27 8
    public function __construct(?LoggerInterface $logger = null)
28
    {
29 8
        $this->logger = $logger;
30 8
    }
31
32
    /**
33
     * @param mixed $handler
34
     */
35 2
    public function registerHandler($handler): AbstractBus
36
    {
37
        // Expect the handler to be an object
38 2
        Assertion::isObject($handler);
39
40 2
        $this->handlers[] = new HandlerWrapper($handler);
41
42 2
        return $this;
43
    }
44
45
    /**
46
     * @param mixed $message
47
     *
48
     * @throws \Assert\AssertionFailedException
49
     */
50 1
    public function post($message): void
51
    {
52
        // Expect the message to be an object to use reflection
53
        // and match the handler method
54 1
        Assertion::isObject($message);
55
56 1
        $messageHandler = $this->findHandler($message);
57
58 1
        $this->log(
59 1
            sprintf(
60 1
                'Sending message [%s] to handler [%s::%s()]', 
61 1
                get_class($message),
62 1
                get_class($messageHandler[0]),
63 1
                $messageHandler[1]
64
            )
65
        );
66
67
        // Run the command
68 1
        call_user_func($messageHandler, $message);
69 1
    }
70
71
    /**
72
     * @param string $msg
73
     */
74 1
    private function log(string $msg): void
75
    {
76 1
        if (!$this->logger) {
77 1
            return;
78
        }
79
80
        $this->logger->info($msg);
81
    }
82
83
    /**
84
     * @return callable
85
     *
86
     * @throws \RuntimeException
87
     */
88 1
    private function findHandler($message): callable
89
    {
90
        // In this implementation the first handler wins but
91
        // actually we would want to fail if there is more than
92
        // one for Commands and Queries
93 1
        foreach ($this->handlers as $handler) {
94 1
            if ($callable = $handler->getCallable($message)) {
95 1
                return $callable;
96
            }
97
        }
98
99
        throw new \RuntimeException(
100
            sprintf('No handler was found for message [%s]', get_class($message))
101
        );
102
    }
103
}
104