Passed
Pull Request — master (#68)
by Alexander
14:32
created

Route::defaults()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 3
c 2
b 0
f 0
dl 0
loc 5
ccs 3
cts 3
cp 1
rs 10
cc 1
nc 1
nop 1
crap 1
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
    private function __construct(?MiddlewareDispatcher $dispatcher = null)
28
    {
29
        $this->dispatcher = $dispatcher;
30
    }
31
32
    public function injectDispatcher(MiddlewareDispatcher $dispatcher): void
33
    {
34
        $this->dispatcher = $dispatcher;
35
    }
36
37
    public function withDispatcher(MiddlewareDispatcher $dispatcher): self
38 44
    {
39
        $route = clone $this;
40 44
        $route->dispatcher = $dispatcher;
41 44
        return $route;
42
    }
43 7
44
    public function getDispatcherWithMiddlewares(): MiddlewareDispatcher
45 7
    {
46 7
        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 7
            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 10
        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 10
53
    public function hasDispatcher(): bool
54
    {
55
        return $this->dispatcher !== null;
56
    }
57
58
    /**
59
     * @param string $pattern
60
     * @param callable|string|array|null $middlewareDefinition primary route handler {@see addMiddleware()}
61 34
     * @param MiddlewareDispatcher|null $dispatcher
62
     * @return self
63 34
     */
64
    public static function get(string $pattern, $middlewareDefinition = null, ?MiddlewareDispatcher $dispatcher = null): self
65
    {
66
        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 4
     * @param MiddlewareDispatcher|null $dispatcher
73
     * @return self
74 4
     */
75
    public static function post(string $pattern, $middlewareDefinition = null, ?MiddlewareDispatcher $dispatcher = null): self
76
    {
77
        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 1
     * @param MiddlewareDispatcher|null $dispatcher
84
     * @return self
85 1
     */
86
    public static function put(string $pattern, $middlewareDefinition = null, ?MiddlewareDispatcher $dispatcher = null): self
87
    {
88
        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 1
     * @param MiddlewareDispatcher|null $dispatcher
95
     * @return self
96 1
     */
97
    public static function delete(string $pattern, $middlewareDefinition = null, ?MiddlewareDispatcher $dispatcher = null): self
98
    {
99
        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 1
     * @param MiddlewareDispatcher|null $dispatcher
106
     * @return self
107 1
     */
108
    public static function patch(string $pattern, $middlewareDefinition = null, ?MiddlewareDispatcher $dispatcher = null): self
109
    {
110
        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 1
     * @param MiddlewareDispatcher|null $dispatcher
117
     * @return self
118 1
     */
119
    public static function head(string $pattern, $middlewareDefinition = null, ?MiddlewareDispatcher $dispatcher = null): self
120
    {
121
        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 1
     * @param MiddlewareDispatcher|null $dispatcher
128
     * @return self
129 1
     */
130
    public static function options(string $pattern, $middlewareDefinition = null, ?MiddlewareDispatcher $dispatcher = null): self
131
    {
132
        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 44
     * @param MiddlewareDispatcher|null $dispatcher
140
     * @return self
141
     */
142
    public static function methods(
143
        array $methods,
144
        string $pattern,
145 44
        $middlewareDefinition = null,
146 44
        ?MiddlewareDispatcher $dispatcher = null
147 44
    ): self {
148 44
        $route = new self($dispatcher);
149 10
        $route->methods = $methods;
150 4
        $route->pattern = $pattern;
151
        if ($middlewareDefinition !== null) {
152 38
            $route->middlewareDefinitions[] = $middlewareDefinition;
153
        }
154
        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 1
     * @return self
162
     */
163 1
    public static function anyMethod(string $pattern, $middlewareDefinition = null, ?MiddlewareDispatcher $dispatcher = null): self
164
    {
165
        return self::methods(Method::ANY, $pattern, $middlewareDefinition, $dispatcher);
166 8
    }
167
168 8
    public function name(string $name): self
169 8
    {
170 8
        $route = clone $this;
171
        $route->name = $name;
172
        return $route;
173 4
    }
174
175 4
    public function pattern(string $pattern): self
176 4
    {
177 4
        $new = clone $this;
178
        $new->pattern = $pattern;
179
        return $new;
180 2
    }
181
182 2
    public function host(string $host): self
183 2
    {
184 2
        $route = clone $this;
185
        $route->host = rtrim($host, '/');
186
        return $route;
187
    }
188
189
    /**
190
     * Parameter default values indexed by parameter names
191
     *
192
     * @param array $defaults
193 1
     * @return self
194
     */
195 1
    public function defaults(array $defaults): self
196 1
    {
197 1
        $route = clone $this;
198
        $route->defaults = $defaults;
199
        return $route;
200
    }
201
202
    /**
203 21
     * Prepends a handler that should be invoked for a matching route.
204
     * Last added handler will be invoked first.
205
     *
206 21
     * Parameter can be a PSR middleware class name, handler action
207
     * (an array of [handlerClass, handlerMethod]) or a callable.
208 1
     *
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 20
     * type-hinting for ServerRequestInterface and RequestHandlerInterface.
212 13
     *
213
     * @param callable|string|array $middlewareDefinition
214
     * @return Route
215 7
     */
216
    public function addMiddleware($middlewareDefinition): self
217
    {
218
        $route = clone $this;
219
        $route->middlewareDefinitions[] = $middlewareDefinition;
220
        return $route;
221
    }
222 12
223
    public function __toString(): string
224 12
    {
225
        $result = '';
226
227
        if ($this->name !== null) {
228
            $result .= '[' . $this->name . '] ';
229
        }
230
231 12
        if ($this->methods !== []) {
232 3
            $result .= implode(',', $this->methods) . ' ';
233
        }
234
        if ($this->host !== null && strrpos($this->pattern, $this->host) === false) {
235 3
            $result .= $this->host;
236
        }
237
        $result .= $this->pattern;
238 9
239 9
        return $result;
240
    }
241
242 9
    public function getName(): string
243
    {
244
        return $this->name ?? (implode(', ', $this->methods) . ' ' . $this->host . $this->pattern);
245
    }
246
247
    public function getMethods(): array
248 20
    {
249
        return $this->methods;
250 20
    }
251 13
252
    public function getPattern(): string
253
    {
254 7
        return $this->pattern;
255
    }
256
257
    public function getHost(): ?string
258
    {
259
        return $this->host;
260
    }
261
262
    public function getDefaults(): array
263
    {
264
        return $this->defaults;
265
    }
266
}
267