Passed
Push — master ( 1da3d9...4f22f8 )
by Alexander
23:29 queued 21:59
created

Route::injectDispatcher()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Router;
6
7
use Yiisoft\Http\Method;
8
9
/**
10
 * Route defines a mapping from URL to callback / name and vice versa
11
 */
12
final class Route
13
{
14
    private ?string $name = null;
15
    /** @var string[] */
16
    private array $methods;
17
    private string $pattern;
18
    private ?string $host = null;
19
    private ?MiddlewareDispatcher $dispatcher = null;
20
21
    /**
22
     * @var callable[]|string[]|array[]
23
     */
24
    private array $middlewareDefinitions = [];
25
    private array $defaults = [];
26
27 28
    private function __construct(?MiddlewareDispatcher $dispatcher = null)
28
    {
29 28
        $this->dispatcher = $dispatcher;
30 28
    }
31
32 5
    public function injectDispatcher(MiddlewareDispatcher $dispatcher): void
33
    {
34 5
        $this->dispatcher = $dispatcher;
35 5
    }
36
37 2
    public function withDispatcher(MiddlewareDispatcher $dispatcher): self
38
    {
39 2
        $route = clone $this;
40 2
        $route->dispatcher = $dispatcher;
41 2
        return $route;
42
    }
43
44 6
    public function getDispatcherWithMiddlewares(): MiddlewareDispatcher
45
    {
46 6
        if ($this->dispatcher->hasMiddlewares()) {
0 ignored issues
show
Bug introduced by
The method hasMiddlewares() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

46
        if ($this->dispatcher->/** @scrutinizer ignore-call */ hasMiddlewares()) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
47
            return $this->dispatcher;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->dispatcher could return the type null which is incompatible with the type-hinted return Yiisoft\Router\MiddlewareDispatcher. Consider adding an additional type-check to rule them out.
Loading history...
48
        }
49
50 6
        return $this->dispatcher = $this->dispatcher->withMiddlewares($this->middlewareDefinitions);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->dispatcher...>middlewareDefinitions) could return the type null which is incompatible with the type-hinted return Yiisoft\Router\MiddlewareDispatcher. Consider adding an additional type-check to rule them out.
Loading history...
51
    }
52
53 9
    public function hasDispatcher(): bool
54
    {
55 9
        return $this->dispatcher !== null;
56
    }
57
58
    /**
59
     * @param string $pattern
60
     * @param callable|string|array|null $middlewareDefinition primary route handler {@see addMiddleware()}
61
     * @param MiddlewareDispatcher|null $dispatcher
62
     * @return self
63
     */
64 18
    public static function get(string $pattern, $middlewareDefinition = null, ?MiddlewareDispatcher $dispatcher = null): self
65
    {
66 18
        return self::methods([Method::GET], $pattern, $middlewareDefinition, $dispatcher);
67
    }
68
69
    /**
70
     * @param string $pattern
71
     * @param callable|string|array|null $middlewareDefinition primary route handler {@see addMiddleware()}
72
     * @param MiddlewareDispatcher|null $dispatcher
73
     * @return self
74
     */
75 4
    public static function post(string $pattern, $middlewareDefinition = null, ?MiddlewareDispatcher $dispatcher = null): self
76
    {
77 4
        return self::methods([Method::POST], $pattern, $middlewareDefinition, $dispatcher);
78
    }
79
80
    /**
81
     * @param string $pattern
82
     * @param callable|string|array|null $middlewareDefinition primary route handler {@see addMiddleware()}
83
     * @param MiddlewareDispatcher|null $dispatcher
84
     * @return self
85
     */
86 1
    public static function put(string $pattern, $middlewareDefinition = null, ?MiddlewareDispatcher $dispatcher = null): self
87
    {
88 1
        return self::methods([Method::PUT], $pattern, $middlewareDefinition, $dispatcher);
89
    }
90
91
    /**
92
     * @param string $pattern
93
     * @param callable|string|array|null $middlewareDefinition primary route handler {@see addMiddleware()}
94
     * @param MiddlewareDispatcher|null $dispatcher
95
     * @return self
96
     */
97 1
    public static function delete(string $pattern, $middlewareDefinition = null, ?MiddlewareDispatcher $dispatcher = null): self
98
    {
99 1
        return self::methods([Method::DELETE], $pattern, $middlewareDefinition, $dispatcher);
100
    }
101
102
    /**
103
     * @param string $pattern
104
     * @param callable|string|array|null $middlewareDefinition primary route handler {@see addMiddleware()}
105
     * @param MiddlewareDispatcher|null $dispatcher
106
     * @return self
107
     */
108 1
    public static function patch(string $pattern, $middlewareDefinition = null, ?MiddlewareDispatcher $dispatcher = null): self
109
    {
110 1
        return self::methods([Method::PATCH], $pattern, $middlewareDefinition, $dispatcher);
111
    }
112
113
    /**
114
     * @param string $pattern
115
     * @param callable|string|array|null $middlewareDefinition primary route handler {@see addMiddleware()}
116
     * @param MiddlewareDispatcher|null $dispatcher
117
     * @return self
118
     */
119 1
    public static function head(string $pattern, $middlewareDefinition = null, ?MiddlewareDispatcher $dispatcher = null): self
120
    {
121 1
        return self::methods([Method::HEAD], $pattern, $middlewareDefinition, $dispatcher);
122
    }
123
124
    /**
125
     * @param string $pattern
126
     * @param callable|string|array|null $middlewareDefinition primary route handler {@see addMiddleware()}
127
     * @param MiddlewareDispatcher|null $dispatcher
128
     * @return self
129
     */
130 1
    public static function options(string $pattern, $middlewareDefinition = null, ?MiddlewareDispatcher $dispatcher = null): self
131
    {
132 1
        return self::methods([Method::OPTIONS], $pattern, $middlewareDefinition, $dispatcher);
133
    }
134
135
    /**
136
     * @param array $methods
137
     * @param string $pattern
138
     * @param callable|string|array|null $middlewareDefinition primary route handler {@see addMiddleware()}
139
     * @param MiddlewareDispatcher|null $dispatcher
140
     * @return self
141
     */
142 28
    public static function methods(
143
        array $methods,
144
        string $pattern,
145
        $middlewareDefinition = null,
146
        ?MiddlewareDispatcher $dispatcher = null
147
    ): self {
148 28
        $route = new self($dispatcher);
149 28
        $route->methods = $methods;
150 28
        $route->pattern = $pattern;
151 28
        if ($middlewareDefinition !== null) {
152 1
            $route->middlewareDefinitions[] = $middlewareDefinition;
153
        }
154 28
        return $route;
155
    }
156
157
    /**
158
     * @param string $pattern
159
     * @param callable|string|array|null $middlewareDefinition primary route handler {@see addMiddleware()}
160
     * @param MiddlewareDispatcher|null $dispatcher
161
     * @return self
162
     */
163 1
    public static function anyMethod(string $pattern, $middlewareDefinition = null, ?MiddlewareDispatcher $dispatcher = null): self
164
    {
165 1
        return self::methods(Method::ANY, $pattern, $middlewareDefinition, $dispatcher);
166
    }
167
168 7
    public function name(string $name): self
169
    {
170 7
        $route = clone $this;
171 7
        $route->name = $name;
172 7
        return $route;
173
    }
174
175 4
    public function pattern(string $pattern): self
176
    {
177 4
        $new = clone $this;
178 4
        $new->pattern = $pattern;
179 4
        return $new;
180
    }
181
182 2
    public function host(string $host): self
183
    {
184 2
        $route = clone $this;
185 2
        $route->host = rtrim($host, '/');
186 2
        return $route;
187
    }
188
189
    /**
190
     * Parameter default values indexed by parameter names
191
     *
192
     * @param array $defaults
193
     * @return self
194
     */
195 1
    public function defaults(array $defaults): self
196
    {
197 1
        $route = clone $this;
198 1
        $route->defaults = $defaults;
199 1
        return $route;
200
    }
201
202
    /**
203
     * Prepends a handler that should be invoked for a matching route.
204
     * Last added handler will be invoked first.
205
     *
206
     * Parameter can be a PSR middleware class name, handler action
207
     * (an array of [handlerClass, handlerMethod]) or a callable.
208
     *
209
     * For handler action and callable typed parameters are automatically injected using dependency
210
     * injection container passed to the route. Current request and handler could be obtained by
211
     * type-hinting for ServerRequestInterface and RequestHandlerInterface.
212
     *
213
     * @param callable|string|array $middlewareDefinition
214
     * @return Route
215
     */
216 5
    public function addMiddleware($middlewareDefinition): self
217
    {
218 5
        $route = clone $this;
219 5
        $route->middlewareDefinitions[] = $middlewareDefinition;
220 5
        return $route;
221
    }
222
223 2
    public function __toString(): string
224
    {
225 2
        $result = '';
226
227 2
        if ($this->name !== null) {
228 1
            $result .= '[' . $this->name . '] ';
229
        }
230
231 2
        if ($this->methods !== []) {
232 2
            $result .= implode(',', $this->methods) . ' ';
233
        }
234 2
        if ($this->host !== null && strrpos($this->pattern, $this->host) === false) {
235 1
            $result .= $this->host;
236
        }
237 2
        $result .= $this->pattern;
238
239 2
        return $result;
240
    }
241
242 6
    public function getName(): string
243
    {
244 6
        return $this->name ?? (implode(', ', $this->methods) . ' ' . $this->host . $this->pattern);
245
    }
246
247 9
    public function getMethods(): array
248
    {
249 9
        return $this->methods;
250
    }
251
252 4
    public function getPattern(): string
253
    {
254 4
        return $this->pattern;
255
    }
256
257 1
    public function getHost(): ?string
258
    {
259 1
        return $this->host;
260
    }
261
262 1
    public function getDefaults(): array
263
    {
264 1
        return $this->defaults;
265
    }
266
}
267