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

Route::__construct()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 45
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 31
CRAP Score 4

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 4
eloc 30
c 2
b 0
f 0
nc 3
nop 9
dl 0
loc 45
ccs 31
cts 31
cp 1
crap 4
rs 9.44

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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