Completed
Push — master ( af3c22...fbabbd )
by Douglas
01:45
created

AbstractBus::findHandler()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 15
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 3.3332

Importance

Changes 0
Metric Value
dl 0
loc 15
ccs 4
cts 6
cp 0.6667
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 6
nc 3
nop 1
crap 3.3332
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, ?callable $callback = null): 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
        $result = call_user_func($messageHandler, $message);
69
70 1
        if ($callback) {
71
            call_user_func($callback, $result);
72
        }
73 1
    }
74
75
    /**
76
     * @param string $msg
77
     */
78 1
    private function log(string $msg): void
79
    {
80 1
        if (!$this->logger) {
81 1
            return;
82
        }
83
84
        $this->logger->info($msg);
85
    }
86
87
    /**
88
     * @return callable
89
     *
90
     * @throws \RuntimeException
91
     */
92 1
    private function findHandler($message): callable
93
    {
94
        // In this implementation the first handler wins but
95
        // actually we would want to fail if there is more than
96
        // one for Commands and Queries
97 1
        foreach ($this->handlers as $handler) {
98 1
            if ($callable = $handler->getCallable($message)) {
99 1
                return $callable;
100
            }
101
        }
102
103
        throw new \RuntimeException(
104
            sprintf('No handler was found for message [%s]', get_class($message))
105
        );
106
    }
107
}
108