Passed
Pull Request — master (#34)
by Anatoly
02:09
created

Route::assertParamsContainValidMethods()   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 5

Importance

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