Bus::addHandler()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
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 4
    private function getNameOfClass($command): string
70
    {
71 4
        $reflectionCommand = new \ReflectionObject($command);
72
73 4
        return $reflectionCommand->getNamespaceName() . '\\' . $reflectionCommand->getShortName();
74
    }
75
76
    /**
77
     * Add the Command Handler
78
     *
79
     * @param  string $command Class name of the command
80
     * @param  string $handler Class name of the handler to be resolved from the Laravel Container
81
     * @return mixed
82
     */
83 3
    public function addHandler($command, $handler)
84
    {
85 3
        $this->handlerLocator->addHandler($handler, $command);
86 3
    }
87
88
    /**
89
     * Handle the command
90
     *
91
     * @param  $command
92
     * @param  $middleware
93
     * @return mixed
94
     */
95 3
    protected function handleTheCommand($command, array $middleware)
96
    {
97 3
        $this->bus = new CommandBus(
98 3
            array_merge(
99 3
                [new LockingMiddleware()],
100 3
                $this->resolveMiddleware($middleware),
101 3
                [new CommandHandlerMiddleware($this->commandNameExtractor, $this->handlerLocator, $this->methodNameInflector)]
102
            )
103
        );
104 3
        return $this->bus->handle($command);
105
    }
106
107
    /**
108
     * Resolve the middleware stack from the laravel container
109
     *
110
     * @param  $middleware
111
     * @return array
112
     */
113 3
    protected function resolveMiddleware(array $middleware)
114
    {
115 3
        $m = [];
116 3
        foreach ($middleware as $class) {
117 1
            $m[] = app($class);
118
        }
119
120 3
        return $m;
121
    }
122
123
}
124