Passed
Push — master ( 412c5f...ce13c3 )
by Divine Niiquaye
02:22
created

Route::getDomain()   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 2
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 2
b 0
f 0
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of Flight Routing.
7
 *
8
 * PHP version 7.1 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\Annotation;
19
20
use Biurad\Annotations\InvalidAnnotationException;
21
22
/**
23
 * Annotation class for @Route().
24
 *
25
 * @Annotation
26
 *
27
 * ```php
28
 * <?php
29
 *  /**
30
 *   * @Route("/blog" name="blog", methods={"GET", "HEAD"}, defaults={"_locale" = "en"})
31
 *   * /
32
 *  class Blog
33
 *  {
34
 *     /**
35
 *      * @Route("/{_locale}", name="index", methods={"GET", "HEAD"})
36
 *      * /
37
 *     public function index()
38
 *     {
39
 *     }
40
 *     /**
41
 *      * @Route("/{_locale}/{id}", name="post", methods={"GET", "HEAD"}, patterns={"id" = "[0-9]+"})
42
 *      * /
43
 *     public function show($id)
44
 *     {
45
 *     }
46
 *  }
47
 * ```
48
 *
49
 * On PHP 8, the annotation class can be used as an attribute as well:
50
 * ```php
51
 *     #[Route('/Blog', methods: ['GET', 'POST'])]
52
 *     class Blog
53
 *     {
54
 *         #[Route('/', name: 'blog_index')]
55
 *         public function index()
56
 *         {
57
 *         }
58
 *         #[Route('/{id}', name: 'blog_post', patterns: ["id" => '\d+'])]
59
 *         public function show()
60
 *         {
61
 *         }
62
 *     }
63
 * ```
64
 *
65
 * @Target({"CLASS", "METHOD"})
66
 */
67
#[\Attribute(\Attribute::IS_REPEATABLE | \Attribute::TARGET_CLASS | \Attribute::TARGET_METHOD)]
68
final class Route
69
{
70
    /** @var null|string @Required */
71
    private $path;
72
73
    /** @var null|string @Required */
74
    private $name;
75
76
    /** @var string[] @Required */
77
    private $methods;
78
79
    /** @var null|string */
80
    private $domain;
81
82
    /** @var string[] */
83
    private $schemes;
84
85
    /** @var string[] */
86
    private $middlewares;
87
88
    /** @var array<string,string> */
89
    private $patterns;
90
91
    /** @var array<string,mixed> */
92
    private $defaults;
93
94
    /**
95
     * @param array<string,mixed>|string $params      data array managed by the Doctrine Annotations library or the path
96
     * @param null|string                $path
97
     * @param string                     $name
98
     * @param string[]                   $methods
99
     * @param string[]                   $patterns
100
     * @param string[]                   $defaults
101
     * @param string                     $domain
102
     * @param string[]                   $schemes
103
     * @param string[]                   $middlewares
104
     */
105 121
    public function __construct(
106
        $params = [],
107
        ?string $path = null,
108
        string $name = null,
109
        array $methods = [],
110
        array $patterns = [],
111
        array $defaults = [],
112
        string $domain = null,
113
        array $schemes = [],
114
        array $middlewares = []
115
    ) {
116 121
        if (is_array($params) && isset($params['value'])) {
117 5
            $params['path'] = $params['value'];
118 5
            unset($params['value']);
119 120
        } elseif (\is_string($params)) {
120 1
            $params = ['path' => $params];
121
        }
122
123 121
        $params = \array_merge([
124 121
            'middlewares' => $middlewares,
125 121
            'patterns'    => $patterns,
126 121
            'defaults'    => $defaults,
127 121
            'schemes'     => $schemes,
128 121
            'methods'     => $methods,
129 121
            'domain'      => $domain,
130 121
            'name'        => $name,
131 121
            'path'        => $path,
132 121
        ], $params);
133
134 121
        $this->assertParamsContainValidName($params);
135 108
        $this->assertParamsContainValidPath($params);
136 96
        $this->assertParamsContainValidMethods($params);
137 75
        $this->assertParamsContainValidSchemes($params);
138 57
        $this->assertParamsContainValidMiddlewares($params);
139 37
        $this->assertParamsContainValidPatterns($params);
140 19
        $this->assertParamsContainValidDefaults($params);
141
142 9
        $this->name        = $params['name'];
143 9
        $this->path        = $params['path'];
144 9
        $this->methods     = $params['methods'];
145 9
        $this->domain      = $params['domain'];
146 9
        $this->middlewares = $params['middlewares'];
147 9
        $this->schemes     = $params['schemes'];
148 9
        $this->patterns    = $params['patterns'];
149 9
        $this->defaults    = $params['defaults'];
150 9
    }
151
152
    /**
153
     * @return null|string
154
     */
155 8
    public function getPath(): ?string
156
    {
157 8
        return $this->path;
158
    }
159
160
    /**
161
     * @return null|string
162
     */
163 7
    public function getDomain(): ?string
164
    {
165 7
        return $this->domain;
166
    }
167
168
    /**
169
     * @return null|string
170
     */
171 8
    public function getName(): ?string
172
    {
173 8
        return $this->name;
174
    }
175
176
    /**
177
     * @return array<string,string>
178
     */
179 7
    public function getPatterns(): array
180
    {
181 7
        return $this->patterns;
182
    }
183
184
    /**
185
     * @return string[]
186
     */
187 7
    public function getMethods(): array
188
    {
189 7
        return $this->methods;
190
    }
191
192
    /**
193
     * @return string[]
194
     */
195 7
    public function getMiddlewares(): array
196
    {
197 7
        return $this->middlewares;
198
    }
199
200
    /**
201
     * @return string[]
202
     */
203 7
    public function getSchemes(): array
204
    {
205 7
        return $this->schemes;
206
    }
207
208
    /**
209
     * @return array<string,mixed>
210
     */
211 7
    public function getDefaults(): array
212
    {
213 7
        return $this->defaults;
214
    }
215
216
    /**
217
     * @param array<string,mixed> $params
218
     *
219
     * @throws InvalidAnnotationException
220
     */
221 121
    private function assertParamsContainValidName(array $params): void
222
    {
223 121
        if (null === $params['name']) {
224 6
            return;
225
        }
226
227 119
        if (empty($params['name']) || !\is_string($params['name'])) {
228 13
            throw new InvalidAnnotationException(\sprintf(
229 13
                '@Route.name must %s.',
230 13
                empty($params['name']) ? 'be not an empty string' : 'contain only a string'
231
            ));
232
        }
233 106
    }
234
235
    /**
236
     * @param array<string,mixed> $params
237
     *
238
     * @throws InvalidAnnotationException
239
     */
240 108
    private function assertParamsContainValidPath(array $params): void
241
    {
242 108
        if (null === $params['path']) {
243 4
            return;
244
        }
245
246 107
        if (empty($params['path']) || !\is_string($params['path'])) {
247 12
            throw new InvalidAnnotationException('@Route.path must be not an empty string.');
248
        }
249 95
    }
250
251
    /**
252
     * @param array<string,mixed> $params
253
     *
254
     * @throws InvalidAnnotationException
255
     */
256 96
    private function assertParamsContainValidMethods(array $params): void
257
    {
258 96
        if (!\is_array($params['methods'])) {
259 11
            throw new InvalidAnnotationException('@Route.methods must contain only an array.');
260
        }
261
262 85
        foreach ($params['methods'] as $method) {
263 84
            if (!\is_string($method)) {
264 10
                throw new InvalidAnnotationException('@Route.methods must contain only strings.');
265
            }
266
        }
267 75
    }
268
269
    /**
270
     * @param array<string,mixed> $params
271
     *
272
     * @throws InvalidAnnotationException
273
     */
274 57
    private function assertParamsContainValidMiddlewares(array $params): void
275
    {
276 57
        if (!\is_array($params['middlewares'])) {
277 10
            throw new InvalidAnnotationException('@Route.middlewares must be an array.');
278
        }
279
280 47
        foreach ($params['middlewares'] as $middleware) {
281 14
            if (!\is_string($middleware)) {
282 10
                throw new InvalidAnnotationException('@Route.middlewares must contain only strings.');
283
            }
284
        }
285 37
    }
286
287
    /**
288
     * @param array<string,mixed> $params
289
     *
290
     * @throws InvalidAnnotationException
291
     */
292 37
    private function assertParamsContainValidPatterns(array $params): void
293
    {
294 37
        if (!\is_array($params['patterns'])) {
295 9
            throw new InvalidAnnotationException('@Route.patterns must be an array.');
296
        }
297
298 28
        foreach ($params['patterns'] as $pattern) {
299 13
            if (!\is_string($pattern)) {
300 9
                throw new InvalidAnnotationException('@Route.patterns must contain only strings.');
301
            }
302
        }
303 19
    }
304
305
    /**
306
     * @param array<string,mixed> $params
307
     *
308
     * @throws InvalidAnnotationException
309
     */
310 75
    private function assertParamsContainValidSchemes(array $params): void
311
    {
312 75
        if (!\is_array($params['schemes'])) {
313 9
            throw new InvalidAnnotationException('@Route.schemes must be an array.');
314
        }
315
316 66
        foreach ($params['schemes'] as $scheme) {
317 13
            if (!\is_string($scheme)) {
318 9
                throw new InvalidAnnotationException('@Route.schemes must contain only strings.');
319
            }
320
        }
321 57
    }
322
323
    /**
324
     * @param array<string,mixed> $params
325
     *
326
     * @throws InvalidAnnotationException
327
     */
328 19
    private function assertParamsContainValidDefaults(array $params): void
329
    {
330 19
        if (!\is_array($params['defaults'])) {
331 10
            throw new InvalidAnnotationException('@Route.defaults must be an array.');
332
        }
333 9
    }
334
}
335