Completed
Push — master ( b9e56f...62a774 )
by Víctor
04:28
created

Bus::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 9
ccs 5
cts 5
cp 1
rs 9.9666
c 0
b 0
f 0
cc 1
nc 1
nop 3
crap 1
1
<?php
2
3
namespace Victormln\LaravelTactician;
4
5
use League\Tactician\CommandBus;
6
use League\Tactician\Plugins\LockingMiddleware;
7
use League\Tactician\Handler\CommandHandlerMiddleware;
8
use Victormln\LaravelTactician\Exceptions\CommandHandlerNotExists;
9
use Victormln\LaravelTactician\Locator\LocatorInterface;
10
use League\Tactician\Handler\MethodNameInflector\MethodNameInflector;
11
use League\Tactician\Handler\CommandNameExtractor\CommandNameExtractor;
12
13
/**
14
 * The default Command bus Using Tactician, this is an implementation to dispatch commands to their handlers trough a middleware stack, every class is resolved from the laravel's service container.
15
 *
16
 * @package Victormln\LaravelTactician
17
 */
18
class Bus implements CommandBusInterface
19
{
20
21
    /** @var CommandBus */
22
    protected $bus;
23
24
    /** @var CommandNameExtractor */
25
    protected $commandNameExtractor;
26
27
    /** @var MethodNameInflector */
28
    protected $methodNameInflector;
29
30
    /** @var LocatorInterface */
31
    protected $handlerLocator;
32
33 4
    public function __construct(
34
        MethodNameInflector $methodNameInflector,
35
        CommandNameExtractor $commandNameExtractor,
36
        LocatorInterface $handlerLocator
37
    ) {
38 4
        $this->methodNameInflector = $methodNameInflector;
39 4
        $this->commandNameExtractor = $commandNameExtractor;
40 4
        $this->handlerLocator = $handlerLocator;
41 4
    }
42
43
    /**
44
     * Dispatch a command
45
     *
46
     * @param  object $command    Command to be dispatched
47
     * @param  array  $middleware Array of middleware class name to add to the stack, they are resolved from the laravel container
48
     * @throws CommandHandlerNotExists
49
     * @return mixed
50
     */
51 4
    public function dispatch($command, array $middleware = [])
52
    {
53 4
        $this->bindCommandWitHisCommandHandler($command);
54
55 3
        return $this->handleTheCommand($command, $middleware);
56
    }
57
58 4
    private function bindCommandWitHisCommandHandler($command)
59
    {
60 4
        $commandFullName = $this->getNameOfClass($command);
61 4
        $commandHandlerFullName = $commandFullName . 'Handler';
62 4
        if (!class_exists($commandHandlerFullName)) {
63 1
            throw CommandHandlerNotExists::with($commandHandlerFullName);
64
        }
65
66 3
        $this->addHandler($commandFullName, $commandHandlerFullName);
67 3
    }
68
69
    /**
70
     * @param $command
71
     * @return string
72
     */
73 4
    private function getNameOfClass($command): string
74
    {
75 4
        if (\is_string($command)) {
76
            return $command;
77
        }
78
79 4
        $reflectionCommand = new \ReflectionObject($command);
80
81 4
        return $reflectionCommand->getNamespaceName() . '\\' . $reflectionCommand->getShortName();
82
    }
83
84
    /**
85
     * Add the Command Handler
86
     *
87
     * @param  string $command Class name of the command
88
     * @param  string $handler Class name of the handler to be resolved from the Laravel Container
89
     * @return mixed
90
     */
91 3
    public function addHandler($command, $handler)
92
    {
93 3
        $this->handlerLocator->addHandler($handler, $command);
94 3
    }
95
96
    /**
97
     * Handle the command
98
     *
99
     * @param  $command
100
     * @param  $middleware
101
     * @return mixed
102
     */
103 3
    protected function handleTheCommand($command, array $middleware)
104
    {
105 3
        $this->bus = new CommandBus(
106 3
            array_merge(
107 3
                [new LockingMiddleware()],
108 3
                $this->resolveMiddleware($middleware),
109 3
                [new CommandHandlerMiddleware($this->commandNameExtractor, $this->handlerLocator, $this->methodNameInflector)]
110
            )
111
        );
112 3
        return $this->bus->handle($command);
113
    }
114
115
    /**
116
     * Resolve the middleware stack from the laravel container
117
     *
118
     * @param  $middleware
119
     * @return array
120
     */
121 3
    protected function resolveMiddleware(array $middleware)
122
    {
123 3
        $m = [];
124 3
        foreach ($middleware as $class) {
125 1
            $m[] = app($class);
126
        }
127
128 3
        return $m;
129
    }
130
131
}
132