Route::variables()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 0
cts 4
cp 0
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
crap 2
1
<?php declare(strict_types = 1);
2
3
namespace Venta\Routing;
4
5
use InvalidArgumentException;
6
use Venta\Contracts\Routing\Route as RouteContract;
7
8
/**
9
 * Class Route
10
 *
11
 * @package Venta\Routing
12
 */
13
class Route implements RouteContract
14
{
15
    /**
16
     * @var string
17
     */
18
    private $domain = '';
19
20
    /**
21
     * Host to apply route to.
22
     *
23
     * @var string
24
     */
25
    private $host = '';
26
27
    /**
28
     * @var string
29
     */
30
    private $input = '';
31
32
    /**
33
     * Route allowed methods.
34
     *
35
     * @var string[]
36
     */
37
    private $methods = [];
38
39
    /**
40
     * List of middleware class names.
41
     *
42
     * @var string[]
43
     */
44
    private $middlewares = [];
45
46
    /**
47
     * Route name.
48
     *
49
     * @var string
50
     */
51
    private $name = '';
52
53
    /**
54
     * Route path
55
     *
56
     * @var string
57
     */
58
    private $path = '';
59
60
    /**
61
     * @var string
62
     */
63
    private $responder;
64
65
    /**
66
     * Scheme to apply route to.
67
     *
68
     * @var string
69
     */
70
    private $scheme = '';
71
72
    /**
73
     * Route variables.
74
     *
75
     * @var string[]
76
     */
77
    private $variables = [];
78
79
    /**
80
     * Route constructor.
81
     *
82
     * @param string[] $methods
83
     * @param string $path
84
     * @param string $responder
85
     */
86 17
    public function __construct(array $methods, string $path, string $responder)
87
    {
88 17
        $this->methods = $methods;
89 17
        $this->path = '/' . ltrim($path, '/');
90 17
        $this->responder = $responder;
91 17
    }
92
93
    /**
94
     * @param string $path
95
     * @param callable|string $responder
96
     * @return Route
97
     */
98
    public static function any(string $path, $responder): Route
99
    {
100
        return new static(['HEAD', 'GET', 'POST', 'PUT', 'PATCH', 'OPTIONS', 'DELETE'], $path, $responder);
0 ignored issues
show
Documentation introduced by
$responder is of type callable, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
101
    }
102
103
    /**
104
     * @param string $path
105
     * @param callable|string $responder
106
     * @return Route
107
     */
108
    public static function delete(string $path, $responder): Route
109
    {
110
        return new static(['DELETE'], $path, $responder);
0 ignored issues
show
Documentation introduced by
$responder is of type callable, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
111
    }
112
113
    /**
114
     * @param string $path
115
     * @param callable|string $responder
116
     * @return Route
117
     */
118
    public static function get(string $path, $responder): Route
119
    {
120
        return new static(['GET'], $path, $responder);
0 ignored issues
show
Documentation introduced by
$responder is of type callable, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
121
    }
122
123
    /**
124
     * @param string $path
125
     * @param callable|string $responder
126
     * @return Route
127
     */
128
    public static function head(string $path, $responder): Route
129
    {
130
        return new static(['HEAD'], $path, $responder);
0 ignored issues
show
Documentation introduced by
$responder is of type callable, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
131
    }
132
133
    /**
134
     * @param string $path
135
     * @param callable|string $responder
136
     * @return Route
137
     */
138
    public static function options(string $path, $responder): Route
139
    {
140
        return new static(['OPTIONS'], $path, $responder);
0 ignored issues
show
Documentation introduced by
$responder is of type callable, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
141
    }
142
143
    /**
144
     * @param string $path
145
     * @param callable|string $responder
146
     * @return Route
147
     */
148
    public static function patch(string $path, $responder): Route
149
    {
150
        return new static(['PATCH'], $path, $responder);
0 ignored issues
show
Documentation introduced by
$responder is of type callable, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
151
    }
152
153
    /**
154
     * @param string $path
155
     * @param callable|string $responder
156
     * @return Route
157
     */
158
    public static function post(string $path, $responder): Route
159
    {
160
        return new static(['POST'], $path, $responder);
0 ignored issues
show
Documentation introduced by
$responder is of type callable, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
161
    }
162
163
    /**
164
     * @param string $path
165
     * @param callable|string $responder
166
     * @return Route
167
     */
168
    public static function put(string $path, $responder): Route
169
    {
170
        return new static(['PUT'], $path, $responder);
0 ignored issues
show
Documentation introduced by
$responder is of type callable, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
171
    }
172
173
    /**
174
     * @inheritDoc
175
     */
176 3
    public function compilePath(array $variables = []): string
177
    {
178 3
        $path = $this->path();
179 3
        foreach ($variables as $key => $value) {
180 3
            $pattern = sprintf('~%s~x', sprintf('\{\s*%s\s*(?::\s*([^{}]*(?:\{(?-1)\}[^{}]*)*))?\}', preg_quote($key)));
181 3
            preg_match($pattern, $path, $matches);
182 3
            if (isset($matches[1]) && !preg_match('/' . $matches[1] . '/', (string)$value)) {
183 1
                throw new InvalidArgumentException(
184 1
                    sprintf('Substitution value "%s" does not match "%s" parameter "%s" pattern.',
185
                        $value,
186
                        $key,
187 1
                        $matches[1]
188
                    )
189
                );
190
            }
191 3
            $path = preg_replace($pattern, $value, $path);
192
        }
193
        // 1. remove patterns for named prameters
194
        // 2. remove optional segments' ending delimiters
195
        // 3. split path into an array of optional segments and remove those
196
        //    containing unsubstituted parameters starting from the last segment
197 3
        $path = preg_replace('/{(\w+):(.+?)}/', '{$1}', $path);
198 3
        $path = str_replace(']', '', $path);
199 3
        $segments = array_reverse(explode('[', $path));
200 3
        foreach ($segments as $n => $segment) {
201 3
            if (strpos($segment, '{') !== false) {
202 2
                if (isset($segments[$n - 1])) {
203
                    throw new InvalidArgumentException(
204
                        'Optional segments with unsubstituted parameters cannot '
205
                        . 'contain segments with substituted parameters when using FastRoute'
206
                    );
207
                }
208 2
                unset($segments[$n]);
209 2
                if (count($segments) == 0) {
210 2
                    preg_match('/{.+}/', $segment, $params);
211 2
                    throw new InvalidArgumentException(
212 3
                        sprintf('Parameter "%s" is mandatory', $params[0] ?? $segment)
213
                    );
214
                }
215
            }
216
        }
217 3
        $path = implode('', array_reverse($segments));
218
219 3
        return $path;
220
    }
221
222
    /**
223
     * @inheritDoc
224
     */
225 2
    public function domain(): string
226
    {
227 2
        return $this->domain;
228
    }
229
230
    /**
231
     * @inheritDoc
232
     */
233 7
    public function host(): string
234
    {
235 7
        return $this->host;
236
    }
237
238
    /**
239
     * @inheritDoc
240
     */
241 2
    public function input(): string
242
    {
243 2
        return $this->input;
244
    }
245
246
    /**
247
     * @inheritDoc
248
     */
249 1
    public function methods(): array
250
    {
251 1
        return $this->methods;
252
    }
253
254
    /**
255
     * @inheritDoc
256
     */
257 1
    public function middlewares(): array
258
    {
259 1
        return $this->middlewares;
260
    }
261
262
    /**
263
     * @inheritDoc
264
     */
265 2
    public function name(): string
266
    {
267 2
        return $this->name;
268
    }
269
270
    /**
271
     * @inheritDoc
272
     */
273 9
    public function path(): string
274
    {
275 9
        return $this->path;
276
    }
277
278
    /**
279
     * @inheritDoc
280
     */
281 1
    public function responder(): string
282
    {
283 1
        return $this->responder;
284
    }
285
286
    /**
287
     * @inheritDoc
288
     */
289 7
    public function scheme(): string
290
    {
291 7
        return $this->scheme;
292
    }
293
294
    /**
295
     * @inheritDoc
296
     */
297
    public function variables(): array
298
    {
299
        return $this->variables;
300
    }
301
302
    /**
303
     * @inheritDoc
304
     */
305 3
    public function secure(): RouteContract
306
    {
307 3
        $route = clone $this;
308 3
        $route->scheme = 'https';
309
310 3
        return $route;
311
    }
312
313
    /**
314
     * @inheritDoc
315
     */
316 1
    public function withDomain(string $domainClass): RouteContract
317
    {
318 1
        $route = clone $this;
319 1
        $route->domain = $domainClass;
320
321 1
        return $route;
322
    }
323
324
    /**
325
     * @inheritDoc
326
     */
327 3
    public function withHost(string $host): RouteContract
328
    {
329 3
        $route = clone $this;
330 3
        $route->host = $host;
331
332 3
        return $route;
333
    }
334
335
    /**
336
     * @inheritDoc
337
     */
338 1
    public function withInput(string $inputClass): RouteContract
339
    {
340 1
        $route = clone $this;
341 1
        $route->input = $inputClass;
342
343 1
        return $route;
344
    }
345
346
    /**
347
     * @inheritDoc
348
     */
349 1
    public function withMiddleware(string $middleware): RouteContract
350
    {
351 1
        $route = clone $this;
352 1
        $route->middlewares[] = $middleware;
353
354 1
        return $route;
355
    }
356
357
    /**
358
     * @inheritDoc
359
     */
360 1
    public function withName(string $name): RouteContract
361
    {
362 1
        $route = clone $this;
363 1
        $route->name = $name;
364
365 1
        return $route;
366
    }
367
368
    /**
369
     * @inheritDoc
370
     */
371 5
    public function withPath(string $path): RouteContract
372
    {
373 5
        $route = clone $this;
374 5
        $route->path = $path;
375
376 5
        return $route;
377
    }
378
379
    /**
380
     * @inheritDoc
381
     */
382
    public function withVariables(array $variables): RouteContract
383
    {
384
        $route = clone $this;
385
        $route->variables = $variables;
386
387
        return $route;
388
    }
389
390
}