Test Failed
Push — master ( 08de7a...d45f24 )
by Divine Niiquaye
11:57
created

FastRoute::default()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 2
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of Flight Routing.
7
 *
8
 * PHP version 7.4 and above required
9
 *
10
 * @author    Divine Niiquaye Ibok <[email protected]>
11
 * @copyright 2019 Biurad Group (https://biurad.com/)
12
 * @license   https://opensource.org/licenses/BSD-3-Clause License
13
 *
14
 * For the full copyright and license information, please view the LICENSE
15
 * file that was distributed with this source code.
16
 */
17
18
namespace Flight\Routing\Routes;
19
20
use Flight\Routing\Exceptions\InvalidControllerException;
21
use Flight\Routing\Handlers\ResourceHandler;
22
23
/**
24
 * Value object representing a single route.
25
 *
26
 * Route path and prefixing a path are not casted. This class is meant to be
27
 * extendable for addition support on route(s).
28
 *
29
 * The default support for this route class:
30
 * - name binding
31
 * - methods binding
32
 * - handler & namespacing
33
 * - arguments binding to handler
34
 * - pattern placeholders assert binding
35
 * - add defaults binding
36
 *
37
 * @author Divine Niiquaye Ibok <[email protected]>
38
 */
39
class FastRoute extends AbstractRoute
40
{
41
    /**
42
     * Sets the route path prefix.
43
     *
44
     * @return static
45
     */
46
    public function prefix(string $path)
47
    {
48
        $this->data['path'] = $path . $this->data['path'] ?? '';
49
50
        return $this;
51
    }
52
53
    /**
54
     * Sets the route path pattern.
55
     *
56
     * @return static
57
     */
58
    public function path(string $pattern)
59
    {
60
        $this->data['path'] = $pattern;
61
62
        return $this;
63
    }
64
65
    /**
66
     * Sets the requirement for the HTTP method.
67
     *
68
     * @param string $methods the HTTP method(s) name
69
     *
70
     * @return static
71
     */
72
    public function method(string ...$methods)
73
    {
74
        foreach ($methods as $method) {
75
            $this->data['methods'][\strtoupper($method)] = true;
76
        }
77
78
        return $this;
79
    }
80
81
    /**
82
     * Sets the route name.
83
     *
84
     * @return static
85
     */
86
    public function bind(string $routeName)
87
    {
88
        $this->data['name'] = $routeName;
89
90
        return $this;
91
    }
92
93
    /**
94
     * Sets the parameter value for a route handler.
95
     *
96
     * @param mixed $value The parameter value
97
     *
98
     * @return static
99
     */
100
    public function argument(string $parameter, $value)
101
    {
102
        if (\is_numeric($value)) {
103
            $value = (int) $value;
104
        } elseif (\is_string($value)) {
105
            $value = \rawurldecode($value);
106
        }
107
108
        $this->data['arguments'][$parameter] = $value;
109
110
        return $this;
111
    }
112
113
    /**
114
     * Sets the parameter values for a route handler.
115
     *
116
     * @param array<int|string> $parameters The route handler parameters
117
     *
118
     * @return static
119
     */
120
    public function arguments(array $parameters)
121
    {
122
        foreach ($parameters as $variable => $value) {
123
            $this->argument($variable, $value);
124
        }
125
126
        return $this;
127
    }
128
129
    /**
130
     * Sets the route code that should be executed when matched.
131
     *
132
     * @param mixed $to PHP class, object or callable that returns the response when matched
133
     *
134
     * @return static
135
     */
136
    public function run($to)
137
    {
138
        $this->data['handler'] = $to;
139
140
        return $this;
141
    }
142
143
    /**
144
     * Sets the missing namespace on route's handler.
145
     *
146
     * @throws InvalidControllerException if $namespace is invalid
147
     *
148
     * @return static
149
     */
150
    public function namespace(string $namespace)
151
    {
152
        if ('' !== $namespace) {
153
            if ('\\' === $namespace[-1]) {
154
                throw new InvalidControllerException(\sprintf('Namespace "%s" provided for routes must not end with a "\\".', $namespace));
155
            }
156
157
            if (isset($this->data['handler'])) {
158
                $this->data['handler'] = self::resolveNamespace($namespace, $this->data['handler']);
159
            }
160
        }
161
162
        return $this;
163
    }
164
165
    /**
166
     * Attach a named middleware group(s) to route.
167
     *
168
     * @return static
169
     */
170
    public function piped(string ...$to)
171
    {
172
        foreach ($to as $namedMiddleware) {
173
            $this->middlewares[] = $namedMiddleware;
174
        }
175
176
        return $this;
177
    }
178
179
    /**
180
     * Sets the requirement for a route variable.
181
     *
182
     * @param string|string[] $regexp The regexp to apply
183
     *
184
     * @return static
185
     */
186
    public function assert(string $variable, $regexp)
187
    {
188
        $this->data['patterns'][$variable] = $regexp;
189
190
        return $this;
191
    }
192
193
    /**
194
     * Sets the requirements for a route variable.
195
     *
196
     * @param array<string,string|string[]> $regexps The regexps to apply
197
     *
198
     * @return static
199
     */
200
    public function asserts(array $regexps)
201
    {
202
        foreach ($regexps as $variable => $regexp) {
203
            $this->assert($variable, $regexp);
204
        }
205
206
        return $this;
207
    }
208
209
    /**
210
     * Sets the default value for a route variable.
211
     *
212
     * @param mixed $default The default value
213
     *
214
     * @return static
215
     */
216
    public function default(string $variable, $default)
217
    {
218
        $this->data['defaults'][$variable] = $default;
219
220
        return $this;
221
    }
222
223
    /**
224
     * Sets the default values for a route variables.
225
     *
226
     * @param array<string,mixed> $values
227
     *
228
     * @return static
229
     */
230
    public function defaults(array $values)
231
    {
232
        foreach ($values as $variable => $default) {
233
            $this->default($variable, $default);
234
        }
235
236
        return $this;
237
    }
238
239
    /**
240
     * @internal skip throwing an exception and return existing $controller
241
     *
242
     * @param callable|object|string|string[] $controller
243
     *
244
     * @return mixed
245
     */
246
    private static function resolveNamespace(string $namespace, $controller)
247
    {
248
        if ($controller instanceof ResourceHandler) {
249
            return $controller->namespace($namespace);
250
        }
251
252
        if (\is_string($controller) && (!\str_starts_with($controller, $namespace) && '\\' === $controller[0])) {
253
            return $namespace . $controller;
254
        }
255
256
        if ((\is_array($controller) && \array_keys($controller) === [0, 1]) && \is_string($controller[0])) {
257
            $controller[0] = self::resolveNamespace($namespace, $controller[0]);
258
        }
259
260
        return $controller;
261
    }
262
}
263