Passed
Branch release/v2.0.0 (bebdea)
by Anatoly
04:02
created

Route::assertValidMethod()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 2
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 4
ccs 3
cts 3
cp 1
crap 2
rs 10
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 Psr\Http\Server\RequestHandlerInterface;
19
use Sunrise\Http\Router\Exception\InvalidAnnotationParameterException;
20
use Sunrise\Http\Router\Exception\InvalidAnnotationSourceException;
21
22
/**
23
 * Import functions
24
 */
25
use function class_exists;
26
use function is_array;
27
use function is_int;
28
use function is_string;
29
use function is_subclass_of;
30
31
/**
32
 * @Annotation
33
 * @Target({"CLASS"})
34
 */
35
final class Route
36
{
37
38
    /**
39
     * @var string
40
     */
41
    public $name;
42
43
    /**
44
     * @var string
45
     */
46
    public $path;
47
48
    /**
49
     * @var array
50
     */
51
    public $methods;
52
53
    /**
54
     * @var array
55
     */
56
    public $middlewares;
57
58
    /**
59
     * @var array
60
     */
61
    public $attributes;
62
63
    /**
64
     * @var int
65
     */
66
    public $priority;
67
68
    /**
69
     * @param array $params
70
     */
71 101
    public function __construct(array $params)
72
    {
73
        $params += [
74 101
            'middlewares' => [],
75
            'attributes' => [],
76
            'priority' => 0,
77
        ];
78
79 101
        $this->assertParamsContainValidName($params);
80 87
        $this->assertParamsContainValidPath($params);
81 73
        $this->assertParamsContainValidMethods($params);
82 49
        $this->assertParamsContainValidMiddlewares($params);
83 25
        $this->assertParamsContainValidAttributes($params);
84 15
        $this->assertParamsContainValidPriority($params);
85
86 5
        $this->name = $params['name'];
87 5
        $this->path = $params['path'];
88 5
        $this->methods = $params['methods'];
89 5
        $this->middlewares = $params['middlewares'];
90 5
        $this->attributes = $params['attributes'];
91 5
        $this->priority = $params['priority'];
92 5
    }
93
94
    /**
95
     * @param string $source
96
     * @return void
97
     * @throws InvalidAnnotationSourceException
98
     */
99 3
    public static function assertValidSource(string $source) : void
100
    {
101 3
        if (!is_subclass_of($source, RequestHandlerInterface::class)) {
102 2
            throw new InvalidAnnotationSourceException(
103 2
                sprintf('@Route annotation source %s is not a request handler.', $source)
104
            );
105
        }
106 2
    }
107
108
    /**
109
     * @param array $params
110
     * @return void
111
     * @throws InvalidAnnotationParameterException
112
     */
113 101
    private function assertParamsContainValidName(array $params) : void
114
    {
115 101
        if (empty($params['name']) || !is_string($params['name'])) {
116 14
            throw new InvalidAnnotationParameterException('@Route.name must be not an empty string.');
117
        }
118 87
    }
119
120
    /**
121
     * @param array $params
122
     * @return void
123
     * @throws InvalidAnnotationParameterException
124
     */
125 87
    private function assertParamsContainValidPath(array $params) : void
126
    {
127 87
        if (empty($params['path']) || !is_string($params['path'])) {
128 14
            throw new InvalidAnnotationParameterException('@Route.path must be not an empty string.');
129
        }
130 73
    }
131
132
    /**
133
     * @param array $params
134
     * @return void
135
     * @throws InvalidAnnotationParameterException
136
     */
137 73
    private function assertParamsContainValidMethods(array $params) : void
138
    {
139 73
        if (empty($params['methods']) || !is_array($params['methods'])) {
140 14
            throw new InvalidAnnotationParameterException('@Route.methods must be not an empty array.');
141
        }
142
143 59
        foreach ($params['methods'] as $method) {
144 59
            if (!is_string($method)) {
145 59
                throw new InvalidAnnotationParameterException('@Route.methods must contain only strings.');
146
            }
147
        }
148 49
    }
149
150
    /**
151
     * @param array $params
152
     * @return void
153
     * @throws InvalidAnnotationParameterException
154
     */
155 49
    private function assertParamsContainValidMiddlewares(array $params) : void
156
    {
157 49
        if (!is_array($params['middlewares'])) {
158 10
            throw new InvalidAnnotationParameterException('@Route.middlewares must be an array.');
159
        }
160
161 39
        foreach ($params['middlewares'] as $middleware) {
162 16
            if (!is_string($middleware)) {
163 10
                throw new InvalidAnnotationParameterException('@Route.middlewares must contain only strings.');
164
            }
165
166 7
            if (!class_exists($middleware)) {
167 2
                throw new InvalidAnnotationParameterException('@Route.middlewares contains nonexistent class.');
168
            }
169
170 5
            if (!is_subclass_of($middleware, MiddlewareInterface::class)) {
171 5
                throw new InvalidAnnotationParameterException('@Route.middlewares contains non middleware class.');
172
            }
173
        }
174 25
    }
175
176
    /**
177
     * @param array $params
178
     * @return void
179
     * @throws InvalidAnnotationParameterException
180
     */
181 25
    private function assertParamsContainValidAttributes(array $params) : void
182
    {
183 25
        if (!is_array($params['attributes'])) {
184 10
            throw new InvalidAnnotationParameterException('@Route.attributes must be an array.');
185
        }
186 15
    }
187
188
    /**
189
     * @param array $params
190
     * @return void
191
     * @throws InvalidAnnotationParameterException
192
     */
193 15
    private function assertParamsContainValidPriority(array $params) : void
194
    {
195 15
        if (!is_int($params['priority'])) {
196 10
            throw new InvalidAnnotationParameterException('@Route.priority must be an integer.');
197
        }
198 5
    }
199
}
200