Completed
Push — master ( 4ed40a...f1e4e0 )
by Prasetyo
02:16
created

TacticianServiceProvider::resolveMiddleware()   A

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('Tactician command extractor must implement %s', CommandNameExtractor::class));
76
            }
77
78
            if ( ! $app['tactician.locator'] instanceof HandlerLocator) {
79
                throw new \InvaludArgumentException(sprintf('tactician locator must implement %s', HandlerLocator::class));
80
            }
81
82
            if ( ! $app['tactician.inflector'] instanceof MethodNameInflector) {
83
                throw new \InvalidArgumentException(sprintf(
84
                    'Tactician inflector must implement %s',
85
                    MethodNameInflector::class
86
                ));
87
            }
88
89
            $handler_middleware = new CommandHandlerMiddleware(
90
                $app['tactician.command_extractor'],
91
                $app['tactician.locator'],
92
                $app['tactician.inflector']
93
            );
94
95
            // combine middleware toggether
96
            $middleware = $app['tactician.middleware'];
97
            array_walk($middleware, function (&$value) {
98
                $value = $this->resolveMiddleware($value);
99
            });
100
            array_push($middleware, $handler_middleware);
101
102
            return new CommandBus($middleware);
103
        };
104
    }
105
106
    /**
107
     * @param string $string
108
     * @return MethodNameInflector
109
     */
110
    private function resolveStringBaseMethodInflector($string)
111
    {
112
        switch ($string) {
113
            case 'class_name':
114
                $inflector = function () {
115
                    return new HandleClassNameInflector();
116
                };
117
                break;
118
            case 'class_name_without_suffix':
119
                $inflector = function () {
120
                    return new HandleClassNameWithoutSuffixInflector();
121
                };
122
                break;
123
            case 'handle':
124
                $inflector = function () {
125
                    return new HandleInflector();
126
                };
127
                break;
128
            case 'invoke':
129
                $inflector = function () {
130
                    return new InvokeInflector();
131
                };
132
                break;
133
            default:
134
                $inflector = function () {
135
                    return new HandleClassNameInflector();
136
                };
137
                break;
138
        }
139
140
        return $inflector;
141
    }
142
143
    /**
144
     * @param string|Middleware $middleware
145
     * @return Middleware
146
     */
147
    public function resolveMiddleware($middleware)
148
    {
149
        if ($middleware instanceof Middleware) {
150
            return $middleware;
151
        }
152
153
        if ($this->app->offsetExists($middleware)) {
154
            $middleware = $this->app[$middleware];
155
            if ($middleware instanceof Middleware) {
156
                return $middleware;
157
            }
158
        }
159
160
        throw new \InvalidArgumentException(sprintf('Tactician middleware must implement %s', Middleware::class));
161
    }
162
}
163