Passed
Pull Request — master (#63)
by Anatoly
04:52 queued 02:47
created

Route::getPath()   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 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
3
/**
4
 * It's free open-source software released under the MIT License.
5
 *
6
 * @author Anatoly Fenric <[email protected]>
7
 * @copyright Copyright (c) 2018, Anatoly Fenric
8
 * @license https://github.com/sunrise-php/http-router/blob/master/LICENSE
9
 * @link https://github.com/sunrise-php/http-router
10
 */
11
12
namespace Sunrise\Http\Router\Annotation;
13
14
/**
15
 * Import classes
16
 */
17
use Psr\Http\Server\MiddlewareInterface;
18
use Sunrise\Http\Router\Exception\InvalidDescriptorArgumentException;
19
use Sunrise\Http\Router\RouteDescriptorInterface;
20
21
/**
22
 * Import functions
23
 */
24
use function is_array;
25
use function is_int;
26
use function is_null;
27
use function is_string;
28
use function is_subclass_of;
29
use function implode;
30
31
/**
32
 * Annotation for a route description
33
 *
34
 * @Annotation
35
 *
36
 * @Target({"CLASS"})
37
 */
38
final class Route implements RouteDescriptorInterface
39
{
40
41
    /**
42
     * A route name
43
     *
44
     * @var string
45
     */
46
    private $name;
47
48
    /**
49
     * A route host
50
     *
51
     * @var null|string
52
     *
53
     * @since 2.6.0
54
     */
55
    private $host;
56
57
    /**
58
     * A route path
59
     *
60
     * @var string
61
     */
62
    private $path;
63
64
    /**
65
     * A route methods
66
     *
67
     * @var string[]
68
     */
69
    private $methods;
70
71
    /**
72
     * A route middlewares
73
     *
74
     * @var string[]
75
     */
76
    private $middlewares;
77
78
    /**
79
     * A route attributes
80
     *
81
     * @var array
82
     */
83
    private $attributes;
84
85
    /**
86
     * A route summary
87
     *
88
     * @var string
89
     *
90
     * @since 2.4.0
91
     */
92
    private $summary;
93
94
    /**
95
     * A route description
96
     *
97
     * @var string
98
     *
99
     * @since 2.4.0
100
     */
101
    private $description;
102
103
    /**
104
     * A route tags
105
     *
106
     * @var string[]
107
     *
108
     * @since 2.4.0
109
     */
110
    private $tags;
111
112
    /**
113
     * A route priority
114
     *
115
     * @var int
116
     */
117
    private $priority;
118
119
    /**
120
     * Constructor of the annotation
121
     *
122
     * @param array $params
123
     *
124
     * @throws InvalidDescriptorArgumentException
125
     */
126 148
    public function __construct(array $params)
127
    {
128
        $params += [
129 148
            'host' => null,
130
            'middlewares' => [],
131
            'attributes' => [],
132
            'summary' => '',
133
            'description' => '',
134
            'tags' => [],
135
            'priority' => 0,
136
        ];
137
138 148
        $this->assertParamsContainValidName($params);
139 134
        $this->assertParamsContainValidHost($params);
140 125
        $this->assertParamsContainValidPath($params);
141 111
        $this->assertParamsContainValidMethods($params);
142 87
        $this->assertParamsContainValidMiddlewares($params);
143 63
        $this->assertParamsContainValidAttributes($params);
144 53
        $this->assertParamsContainValidSummary($params);
145 44
        $this->assertParamsContainValidDescription($params);
146 36
        $this->assertParamsContainValidTags($params);
147 18
        $this->assertParamsContainValidPriority($params);
148
149
        // Opportunity for concatenation...
150 8
        if (is_array($params['description'])) {
151 1
            $params['description'] = implode($params['description']);
152
        }
153
154 8
        $this->name = $params['name'];
155 8
        $this->host = $params['host'];
156 8
        $this->path = $params['path'];
157 8
        $this->methods = $params['methods'];
158 8
        $this->middlewares = $params['middlewares'];
159 8
        $this->attributes = $params['attributes'];
160 8
        $this->summary = $params['summary'];
161 8
        $this->description = $params['description'];
162 8
        $this->tags = $params['tags'];
163 8
        $this->priority = $params['priority'];
164 8
    }
165
166
    /**
167
     * {@inheritDoc}
168
     *
169
     * @since 2.6.0
170
     */
171 7
    public function getName() : string
172
    {
173 7
        return $this->name;
174
    }
175
176
    /**
177
     * {@inheritDoc}
178
     *
179
     * @since 2.6.0
180
     */
181 7
    public function getHost() : ?string
182
    {
183 7
        return $this->host;
184
    }
185
186
    /**
187
     * {@inheritDoc}
188
     *
189
     * @since 2.6.0
190
     */
191 7
    public function getPath() : string
192
    {
193 7
        return $this->path;
194
    }
195
196
    /**
197
     * {@inheritDoc}
198
     *
199
     * @since 2.6.0
200
     */
201 7
    public function getMethods() : array
202
    {
203 7
        return $this->methods;
204
    }
205
206
    /**
207
     * {@inheritDoc}
208
     *
209
     * @since 2.6.0
210
     */
211 6
    public function getMiddlewares() : array
212
    {
213 6
        return $this->middlewares;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->middlewares returns the type string[] which is incompatible with the return type mandated by Sunrise\Http\Router\Rout...rface::getMiddlewares() of Psr\Http\Server\MiddlewareInterface[].

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
214
    }
215
216
    /**
217
     * {@inheritDoc}
218
     *
219
     * @since 2.6.0
220
     */
221 6
    public function getAttributes() : array
222
    {
223 6
        return $this->attributes;
224
    }
225
226
    /**
227
     * {@inheritDoc}
228
     *
229
     * @since 2.6.0
230
     */
231 6
    public function getSummary() : string
232
    {
233 6
        return $this->summary;
234
    }
235
236
    /**
237
     * {@inheritDoc}
238
     *
239
     * @since 2.6.0
240
     */
241 7
    public function getDescription() : string
242
    {
243 7
        return $this->description;
244
    }
245
246
    /**
247
     * {@inheritDoc}
248
     *
249
     * @since 2.6.0
250
     */
251 6
    public function getTags() : array
252
    {
253 6
        return $this->tags;
254
    }
255
256
    /**
257
     * {@inheritDoc}
258
     *
259
     * @since 2.6.0
260
     */
261 4
    public function getPriority() : int
262
    {
263 4
        return $this->priority;
264
    }
265
266
    /**
267
     * @param array $params
268
     *
269
     * @return void
270
     *
271
     * @throws InvalidDescriptorArgumentException
272
     */
273 148
    private function assertParamsContainValidName(array $params) : void
274
    {
275 148
        if (empty($params['name']) || !is_string($params['name'])) {
276 14
            throw new InvalidDescriptorArgumentException(
277 14
                '@Route.name must be not an empty string.'
278
            );
279
        }
280 134
    }
281
282
    /**
283
     * @param array $params
284
     *
285
     * @return void
286
     *
287
     * @throws InvalidDescriptorArgumentException
288
     */
289 134
    private function assertParamsContainValidHost(array $params) : void
290
    {
291 134
        if (!is_null($params['host']) && !is_string($params['host'])) {
292 9
            throw new InvalidDescriptorArgumentException(
293 9
                '@Route.host must be null or string.'
294
            );
295
        }
296 125
    }
297
298
    /**
299
     * @param array $params
300
     *
301
     * @return void
302
     *
303
     * @throws InvalidDescriptorArgumentException
304
     */
305 125
    private function assertParamsContainValidPath(array $params) : void
306
    {
307 125
        if (empty($params['path']) || !is_string($params['path'])) {
308 14
            throw new InvalidDescriptorArgumentException(
309 14
                '@Route.path must be not an empty string.'
310
            );
311
        }
312 111
    }
313
314
    /**
315
     * @param array $params
316
     *
317
     * @return void
318
     *
319
     * @throws InvalidDescriptorArgumentException
320
     */
321 111
    private function assertParamsContainValidMethods(array $params) : void
322
    {
323 111
        if (empty($params['methods']) || !is_array($params['methods'])) {
324 14
            throw new InvalidDescriptorArgumentException(
325 14
                '@Route.methods must be not an empty array.'
326
            );
327
        }
328
329 97
        foreach ($params['methods'] as $method) {
330 97
            if (!is_string($method)) {
331 10
                throw new InvalidDescriptorArgumentException(
332 10
                    '@Route.methods must contain only strings.'
333
                );
334
            }
335
        }
336 87
    }
337
338
    /**
339
     * @param array $params
340
     *
341
     * @return void
342
     *
343
     * @throws InvalidDescriptorArgumentException
344
     */
345 87
    private function assertParamsContainValidMiddlewares(array $params) : void
346
    {
347 87
        if (!is_array($params['middlewares'])) {
348 10
            throw new InvalidDescriptorArgumentException(
349 10
                '@Route.middlewares must be an array.'
350
            );
351
        }
352
353 77
        foreach ($params['middlewares'] as $middleware) {
354 18
            if (!is_string($middleware)) {
355 10
                throw new InvalidDescriptorArgumentException(
356 10
                    '@Route.middlewares must contain only strings.'
357
                );
358
            }
359
360 9
            if (!is_subclass_of($middleware, MiddlewareInterface::class)) {
361 4
                throw new InvalidDescriptorArgumentException(
362 4
                    '@Route.middlewares contains a nonexistent or non-middleware class.'
363
                );
364
            }
365
        }
366 63
    }
367
368
    /**
369
     * @param array $params
370
     *
371
     * @return void
372
     *
373
     * @throws InvalidDescriptorArgumentException
374
     */
375 63
    private function assertParamsContainValidAttributes(array $params) : void
376
    {
377 63
        if (!is_array($params['attributes'])) {
378 10
            throw new InvalidDescriptorArgumentException(
379 10
                '@Route.attributes must be an array.'
380
            );
381
        }
382 53
    }
383
384
    /**
385
     * @param array $params
386
     *
387
     * @return void
388
     *
389
     * @throws InvalidDescriptorArgumentException
390
     */
391 53
    private function assertParamsContainValidSummary(array $params) : void
392
    {
393 53
        if (!is_string($params['summary'])) {
394 9
            throw new InvalidDescriptorArgumentException(
395 9
                '@Route.summary must be a string.'
396
            );
397
        }
398 44
    }
399
400
    /**
401
     * @param array $params
402
     *
403
     * @return void
404
     *
405
     * @throws InvalidDescriptorArgumentException
406
     */
407 44
    private function assertParamsContainValidDescription(array $params) : void
408
    {
409 44
        if (!is_array($params['description']) && !is_string($params['description'])) {
410 8
            throw new InvalidDescriptorArgumentException(
411 8
                '@Route.description must be an array or a string.'
412
            );
413
        }
414 36
    }
415
416
    /**
417
     * @param array $params
418
     *
419
     * @return void
420
     *
421
     * @throws InvalidDescriptorArgumentException
422
     */
423 36
    private function assertParamsContainValidTags(array $params) : void
424
    {
425 36
        if (!is_array($params['tags'])) {
426 9
            throw new InvalidDescriptorArgumentException(
427 9
                '@Route.tags must be an array.'
428
            );
429
        }
430
431 27
        foreach ($params['tags'] as $middleware) {
432 12
            if (!is_string($middleware)) {
433 9
                throw new InvalidDescriptorArgumentException(
434 9
                    '@Route.tags must contain only strings.'
435
                );
436
            }
437
        }
438 18
    }
439
440
    /**
441
     * @param array $params
442
     *
443
     * @return void
444
     *
445
     * @throws InvalidDescriptorArgumentException
446
     */
447 18
    private function assertParamsContainValidPriority(array $params) : void
448
    {
449 18
        if (!is_int($params['priority'])) {
450 10
            throw new InvalidDescriptorArgumentException(
451 10
                '@Route.priority must be an integer.'
452
            );
453
        }
454 8
    }
455
}
456