Passed
Push — master ( 69906d...00f66f )
by Alexander
01:16
created

Route::to()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 7
c 2
b 0
f 0
dl 0
loc 13
ccs 0
cts 0
cp 0
rs 10
cc 3
nc 4
nop 1
crap 12
1
<?php
2
3
namespace Yiisoft\Router;
4
5
use Psr\Http\Message\ResponseInterface;
6
use Psr\Http\Message\ServerRequestInterface;
7
use Psr\Http\Server\MiddlewareInterface;
8
use Psr\Http\Server\RequestHandlerInterface;
9
10
/**
11
 * Route defines a mapping from URL to callback / name and vice versa
12
 */
13
class Route implements MiddlewareInterface
14
{
15
    /**
16
     * @var string
17
     */
18
    private $name;
19
20
    /**
21
     * @var array
22
     */
23
    private $methods;
24
25
    /**
26
     * @var string
27
     */
28
    private $pattern;
29
30
    /**
31
     * @var string
32
     */
33
    private $host;
34
35
    /**
36
     * @var MiddlewareInterface
37
     */
38
    private $middleware;
39
40
    /**
41
     * @var array
42
     */
43
    private $parameters = [];
44
45
    /**
46
     * @var array
47
     */
48
    private $defaults = [];
49
50
    private function __construct()
51
    {
52
    }
53
54
    public static function get(string $pattern): self
55
    {
56
        $route = new static();
57
        $route->methods = [Method::GET];
58
        $route->pattern = $pattern;
59
        return $route;
60
    }
61
62
    public static function post(string $pattern): self
63
    {
64
        $route = new static();
65
        $route->methods = [Method::POST];
66
        $route->pattern = $pattern;
67
        return $route;
68
    }
69
70
    public static function put(string $pattern): self
71
    {
72
        $route = new static();
73
        $route->methods = [Method::PUT];
74
        $route->pattern = $pattern;
75
        return $route;
76
    }
77
78
    public static function delete(string $pattern): self
79
    {
80
        $route = new static();
81
        $route->methods = [Method::DELETE];
82
        $route->pattern = $pattern;
83
        return $route;
84
    }
85
86
    public static function patch(string $pattern): self
87
    {
88
        $route = new static();
89
        $route->methods = [Method::PATCH];
90
        $route->pattern = $pattern;
91
        return $route;
92
    }
93
94
    public static function head(string $pattern): self
95
    {
96
        $route = new static();
97
        $route->methods = [Method::HEAD];
98
        $route->pattern = $pattern;
99
        return $route;
100
    }
101
102
    public static function options(string $pattern): self
103
    {
104
        $route = new static();
105
        $route->methods = [Method::OPTIONS];
106
        $route->pattern = $pattern;
107
        return $route;
108
    }
109
110
    public static function methods(array $methods, string $pattern): self
111
    {
112
        $route = new static();
113
        $route->methods = $methods;
114
        $route->pattern = $pattern;
115
        return $route;
116
    }
117
118
    public static function anyMethod(string $pattern): self
119
    {
120
        $route = new static();
121
        $route->methods = Method::ANY;
122
        $route->pattern = $pattern;
123
        return $route;
124
    }
125
126
    public function name(string $name): self
127
    {
128
        $route = clone $this;
129
        $route->name = $name;
130
        return $route;
131
    }
132
133
    public function pattern(string $pattern): self
134
    {
135
        $new = clone $this;
136
        $new->pattern = $pattern;
137
        return $new;
138
    }
139
140
    public function host(string $host): self
141
    {
142
        $route = clone $this;
143
        $route->host = rtrim($host, '/');
144
        return $route;
145
    }
146
147
    /**
148
     * Parameter validation rules indexed by parameter names
149
     *
150
     * @param array $parameters
151
     * @return Route
152
     */
153
    public function parameters(array $parameters): self
154
    {
155
        $route = clone $this;
156
        $route->parameters = $parameters;
157
        return $route;
158
    }
159
160
    /**
161
     * Parameter default values indexed by parameter names
162
     *
163
     * @param array $defaults
164
     * @return Route
165
     */
166
    public function defaults(array $defaults): self
167
    {
168
        $route = clone $this;
169
        $route->defaults = $defaults;
170
        return $route;
171
    }
172
173
    /**
174
     * Speicifes a handler that should be invoked for a matching route.
175
     * It can be either a PSR middleware or a callable with the following signature:
176
     *
177
     * ```
178
     * function (ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface {
179
     * ```
180
     *
181
     * @param MiddlewareInterface|callable $middleware
182
     * @return Route
183
     */
184
    public function to($middleware): self
185
    {
186
        $route = clone $this;
187
        if (\is_callable($middleware)) {
188
            $middleware = $this->wrapCallable($middleware);
0 ignored issues
show
Bug introduced by
It seems like $middleware can also be of type Psr\Http\Server\MiddlewareInterface; however, parameter $callback of Yiisoft\Router\Route::wrapCallable() does only seem to accept callable, maybe add an additional type check? ( Ignorable by Annotation )

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

188
            $middleware = $this->wrapCallable(/** @scrutinizer ignore-type */ $middleware);
Loading history...
189
        }
190
191
        if (!$middleware instanceof MiddlewareInterface) {
192
            throw new \InvalidArgumentException('Parameter should be either a PSR middleware or a callable.');
193
        }
194
195
        $route->middleware = $middleware;
196
        return $route;
197
    }
198
199 1
    private function wrapCallable(callable $callback): MiddlewareInterface
200
    {
201
        return new class($callback) implements MiddlewareInterface {
202
            private $callback;
203
204
            public function __construct(callable $callback)
205
            {
206 1
                $this->callback = $callback;
207
            }
208
209
            public function process(
210
                ServerRequestInterface $request,
211
                RequestHandlerInterface $handler
212
            ): ResponseInterface {
213 1
                return \call_user_func($this->callback, $request, $handler);
214
            }
215
        };
216
    }
217
218 1
    public function __toString()
219
    {
220 1
        $result = '';
221
222 1
        if ($this->name !== null) {
223 1
            $result .= '[' . $this->name . '] ';
224
        }
225
226 1
        if ($this->methods !== null) {
227 1
            $result .= implode(',', $this->methods) . ' ';
228
        }
229 1
        if ($this->host !== null && strrpos($this->pattern, $this->host) === false) {
230 1
            $result .= $this->host;
231
        }
232 1
        $result .= $this->pattern;
233
234 1
        return $result;
235
    }
236
237 2
    public function getName(): string
238
    {
239 2
        return $this->name ?? implode(', ', $this->methods) . ' ' . $this->pattern;
240
    }
241
242 9
    public function getMethods(): array
243
    {
244 9
        return $this->methods;
245
    }
246
247 1
    public function getPattern(): string
248
    {
249 1
        return $this->pattern;
250
    }
251
252 1
    public function getHost(): ?string
253
    {
254 1
        return $this->host;
255
    }
256
257 1
    public function getParameters(): array
258
    {
259 1
        return $this->parameters;
260
    }
261
262 1
    public function getDefaults(): array
263
    {
264 1
        return $this->defaults;
265
    }
266
267
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
268
    {
269
        return $this->middleware->process($request, $handler);
270
    }
271
}
272