Passed
Push — master ( d17b70...413065 )
by Divine Niiquaye
03:12
created

Route::__construct()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 45
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 30
CRAP Score 3.0003

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 30
c 1
b 0
f 0
nc 3
nop 9
dl 0
loc 45
ccs 30
cts 31
cp 0.9677
crap 3.0003
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 Flight\Routing\Exceptions\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 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> $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
        array $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 (isset($params['value'])) {
117 5
            $params['path'] = $params['value'];
118 5
            unset($params['value']);
119 120
        } elseif (\is_string($params)) {
120
            $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 94
        $this->assertParamsContainValidMethods($params);
137 73
        $this->assertParamsContainValidSchemes($params);
138 55
        $this->assertParamsContainValidMiddlewares($params);
139 35
        $this->assertParamsContainValidPatterns($params);
140 17
        $this->assertParamsContainValidDefaults($params);
141
142 7
        $this->name        = $params['name'];
143 7
        $this->path        = $params['path'];
144 7
        $this->methods     = $params['methods'];
145 7
        $this->domain      = $params['domain'];
146 7
        $this->middlewares = $params['middlewares'];
147 7
        $this->schemes     = $params['schemes'];
148 7
        $this->patterns    = $params['patterns'];
149 7
        $this->defaults    = $params['defaults'];
150 7
    }
151
152
    /**
153
     * @return string
154
     */
155 6
    public function getPath(): string
156
    {
157 6
        return $this->path;
158
    }
159
160
    /**
161
     * @return null|string
162
     */
163 6
    public function getDomain(): ?string
164
    {
165 6
        return $this->domain;
166
    }
167
168
    /**
169
     * @return null|string
170
     */
171 7
    public function getName(): ?string
172
    {
173 7
        return $this->name;
174
    }
175
176
    /**
177
     * @return array<string,string>
178
     */
179 6
    public function getPatterns(): array
180
    {
181 6
        return $this->patterns;
182
    }
183
184
    /**
185
     * @return string[]
186
     */
187 6
    public function getMethods(): array
188
    {
189 6
        return $this->methods;
190
    }
191
192
    /**
193
     * @return string[]
194
     */
195 6
    public function getMiddlewares(): array
196
    {
197 6
        return $this->middlewares;
198
    }
199
200
    /**
201
     * @return string[]
202
     */
203 6
    public function getSchemes(): array
204
    {
205 6
        return $this->schemes;
206
    }
207
208
    /**
209
     * @return array<string,mixed>
210
     */
211 6
    public function getDefaults(): array
212
    {
213 6
        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 5
            return;
225
        }
226
227 120
        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 107
    }
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 (empty($params['path']) || !\is_string($params['path'])) {
243 14
            throw new InvalidAnnotationException('@Route.path must be not an empty string.');
244
        }
245 94
    }
246
247
    /**
248
     * @param array<string,mixed> $params
249
     *
250
     * @throws InvalidAnnotationException
251
     */
252 94
    private function assertParamsContainValidMethods(array $params): void
253
    {
254 94
        if (!\is_array($params['methods'])) {
255 11
            throw new InvalidAnnotationException('@Route.methods must contain only an array.');
256
        }
257
258 83
        foreach ($params['methods'] as $method) {
259 83
            if (!\is_string($method)) {
260 10
                throw new InvalidAnnotationException('@Route.methods must contain only strings.');
261
            }
262
        }
263 73
    }
264
265
    /**
266
     * @param array<string,mixed> $params
267
     *
268
     * @throws InvalidAnnotationException
269
     */
270 55
    private function assertParamsContainValidMiddlewares(array $params): void
271
    {
272 55
        if (!\is_array($params['middlewares'])) {
273 10
            throw new InvalidAnnotationException('@Route.middlewares must be an array.');
274
        }
275
276 45
        foreach ($params['middlewares'] as $middleware) {
277 15
            if (!\is_string($middleware)) {
278 10
                throw new InvalidAnnotationException('@Route.middlewares must contain only strings.');
279
            }
280
        }
281 35
    }
282
283
    /**
284
     * @param array<string,mixed> $params
285
     *
286
     * @throws InvalidAnnotationException
287
     */
288 35
    private function assertParamsContainValidPatterns(array $params): void
289
    {
290 35
        if (!\is_array($params['patterns'])) {
291 9
            throw new InvalidAnnotationException('@Route.patterns must be an array.');
292
        }
293
294 26
        foreach ($params['patterns'] as $pattern) {
295 14
            if (!\is_string($pattern)) {
296 9
                throw new InvalidAnnotationException('@Route.patterns must contain only strings.');
297
            }
298
        }
299 17
    }
300
301
    /**
302
     * @param array<string,mixed> $params
303
     *
304
     * @throws InvalidAnnotationException
305
     */
306 73
    private function assertParamsContainValidSchemes(array $params): void
307
    {
308 73
        if (!\is_array($params['schemes'])) {
309 9
            throw new InvalidAnnotationException('@Route.schemes must be an array.');
310
        }
311
312 64
        foreach ($params['schemes'] as $scheme) {
313 14
            if (!\is_string($scheme)) {
314 9
                throw new InvalidAnnotationException('@Route.schemes must contain only strings.');
315
            }
316
        }
317 55
    }
318
319
    /**
320
     * @param array<string,mixed> $params
321
     *
322
     * @throws InvalidAnnotationException
323
     */
324 17
    private function assertParamsContainValidDefaults(array $params): void
325
    {
326 17
        if (!\is_array($params['defaults'])) {
327 10
            throw new InvalidAnnotationException('@Route.defaults must be an array.');
328
        }
329 7
    }
330
}
331