TacticianServiceProvider::resolveMiddleware()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 15
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 15
rs 9.2
cc 4
eloc 8
nc 4
nop 1
1
<?php
2
3
namespace Silex\Provider;
4
5
use League\Tactician\CommandBus;
6
use League\Tactician\Handler\CommandHandlerMiddleware;
7
use League\Tactician\Handler\CommandNameExtractor\CommandNameExtractor;
8
use League\Tactician\Handler\Locator\HandlerLocator;
9
use League\Tactician\Handler\MethodNameInflector\HandleClassNameInflector;
10
use League\Tactician\Handler\MethodNameInflector\HandleClassNameWithoutSuffixInflector;
11
use League\Tactician\Handler\MethodNameInflector\HandleInflector;
12
use League\Tactician\Handler\MethodNameInflector\InvokeInflector;
13
use League\Tactician\Handler\MethodNameInflector\MethodNameInflector;
14
use League\Tactician\Middleware;
15
use Pimple\Container;
16
use Pimple\ServiceProviderInterface;
17
use Silex\Component\Tactician\CommandNameExtractor\Silex as SilexCommandExtractor;
18
use Silex\Component\Tactician\Locator\Silex as SilexLocator;
19
20
/**
21
 * Class TacticianServiceProvider
22
 * @package Silex\Provider
23
 */
24
class TacticianServiceProvider implements ServiceProviderInterface
25
{
26
    /**
27
     * @var Container
28
     */
29
    private $app;
30
31
    /**
32
     * @var array
33
     */
34
    private $config;
35
    /**
36
     * @param array $config
37
     */
38
    public function __construct(array $config)
39
    {
40
        $this->config = $config;
41
    }
42
    /**
43
     * @param Container $app
44
     */
45
    public function register(Container $app)
46
    {
47
        $this->app = $app;
48
49
        foreach ($this->config as $key => $value) {
50
            $this->app[$key] = $value;
51
        }
52
53
        // register default locator if haven't defined yet
54
        if (! $app->offsetExists('tactician.locator')) {
55
            $app['tactician.locator'] = function () use ($app) {
56
                return new SilexLocator($app);
57
            };
58
        }
59
60
        // register default command extractor if haven't defined yet
61
        if (! $app->offsetExists('tactician.command_extractor')) {
62
            $app['tactician.command_extractor'] = function () {
63
                return new SilexCommandExtractor();
64
            };
65
        }
66
67
        // if inflector is string then resolve it
68
        if (is_string($app['tactician.inflector'])) {
69
            $app['tactician.inflector'] = $this->resolveStringBaseMethodInflector($app['tactician.inflector']);
70
        }
71
72
        $app['tactician.command_bus'] = function () use ($app) {
73
            // type checking, make sure all command bus component are valid
74
            if (! $app['tactician.command_extractor'] instanceof CommandNameExtractor) {
75
                throw new \InvalidArgumentException(sprintf(
76
                    'Tactician command extractor must implement %s',
77
                    CommandNameExtractor::class
78
                ));
79
            }
80
81
            if (! $app['tactician.locator'] instanceof HandlerLocator) {
82
                throw new \InvalidArgumentException(sprintf(
83
                    'Tactician locator must implement %s',
84
                    HandlerLocator::class
85
                ));
86
            }
87
88
            if (! $app['tactician.inflector'] instanceof MethodNameInflector) {
89
                throw new \InvalidArgumentException(sprintf(
90
                    'Tactician inflector must implement %s',
91
                    MethodNameInflector::class
92
                ));
93
            }
94
95
            $handler_middleware = new CommandHandlerMiddleware(
96
                $app['tactician.command_extractor'],
97
                $app['tactician.locator'],
98
                $app['tactician.inflector']
99
            );
100
101
            // combine middleware together
102
            $middleware = $app['tactician.middleware'];
103
            array_walk($middleware, function (&$value) {
104
                $value = $this->resolveMiddleware($value);
105
            });
106
            array_push($middleware, $handler_middleware);
107
108
            return new CommandBus($middleware);
109
        };
110
    }
111
112
    /**
113
     * @param string $string
114
     * @return MethodNameInflector
115
     */
116
    private function resolveStringBaseMethodInflector($string)
117
    {
118
        switch ($string) {
119
            case 'class_name':
120
                $inflector = function () {
121
                    return new HandleClassNameInflector();
122
                };
123
                break;
124
            case 'class_name_without_suffix':
125
                $inflector = function () {
126
                    return new HandleClassNameWithoutSuffixInflector();
127
                };
128
                break;
129
            case 'handle':
130
                $inflector = function () {
131
                    return new HandleInflector();
132
                };
133
                break;
134
            case 'invoke':
135
                $inflector = function () {
136
                    return new InvokeInflector();
137
                };
138
                break;
139
            default:
140
                $inflector = function () {
141
                    return new HandleClassNameInflector();
142
                };
143
                break;
144
        }
145
146
        return $inflector;
147
    }
148
149
    /**
150
     * @param string|Middleware $middleware
151
     * @return Middleware
152
     */
153
    public function resolveMiddleware($middleware)
154
    {
155
        if ($middleware instanceof Middleware) {
156
            return $middleware;
157
        }
158
159
        if ($this->app->offsetExists($middleware)) {
160
            $middleware = $this->app[$middleware];
161
            if ($middleware instanceof Middleware) {
162
                return $middleware;
163
            }
164
        }
165
166
        throw new \InvalidArgumentException(sprintf('Tactician middleware must implement %s', Middleware::class));
167
    }
168
}
169