Test Failed
Pull Request — master (#34)
by Anatoly
02:07
created

Route::assertParamsContainValidMethods()   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 7
c 1
b 0
f 0
dl 0
loc 12
rs 9.6111
cc 5
nc 4
nop 1
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
    public function __construct(array $params)
71
    {
72
        $params += [
73
            'middlewares' => [],
74
            'attributes' => [],
75
            'priority' => 0,
76
        ];
77
78
        $this->assertParamsContainValidName($params);
79
        $this->assertParamsContainValidPath($params);
80
        $this->assertParamsContainValidMethods($params);
81
        $this->assertParamsContainValidMiddlewares($params);
82
        $this->assertParamsContainValidAttributes($params);
83
        $this->assertParamsContainValidPriority($params);
84
85
        $this->name = $params['name'];
86
        $this->path = $params['path'];
87
        $this->methods = $params['methods'];
88
        $this->middlewares = $params['middlewares'];
89
        $this->attributes = $params['attributes'];
90
        $this->priority = $params['priority'];
91
    }
92
93
    /**
94
     * @param string $source
95
     *
96
     * @return void
97
     *
98
     * @throws InvalidAnnotationSourceException
99
     */
100
    public static function assertValidSource(string $source) : void
101
    {
102
        if (!is_subclass_of($source, RequestHandlerInterface::class)) {
103
            throw new InvalidAnnotationSourceException(
104
                sprintf('@Route annotation source %s is not a request handler.', $source)
105
            );
106
        }
107
    }
108
109
    /**
110
     * @param array $params
111
     *
112
     * @return void
113
     *
114
     * @throws InvalidAnnotationParameterException
115
     */
116
    private function assertParamsContainValidName(array $params) : void
117
    {
118
        if (empty($params['name']) || !is_string($params['name'])) {
119
            throw new InvalidAnnotationParameterException(
120
                '@Route.name must be not an empty string.'
121
            );
122
        }
123
    }
124
125
    /**
126
     * @param array $params
127
     *
128
     * @return void
129
     *
130
     * @throws InvalidAnnotationParameterException
131
     */
132
    private function assertParamsContainValidPath(array $params) : void
133
    {
134
        if (empty($params['path']) || !is_string($params['path'])) {
135
            throw new InvalidAnnotationParameterException(
136
                '@Route.path must be not an empty string.'
137
            );
138
        }
139
    }
140
141
    /**
142
     * @param array $params
143
     *
144
     * @return void
145
     *
146
     * @throws InvalidAnnotationParameterException
147
     */
148
    private function assertParamsContainValidMethods(array $params) : void
149
    {
150
        if (empty($params['methods']) || !is_array($params['methods'])) {
151
            throw new InvalidAnnotationParameterException(
152
                '@Route.methods must be not an empty array.'
153
            );
154
        }
155
156
        foreach ($params['methods'] as $method) {
157
            if (!is_string($method)) {
158
                throw new InvalidAnnotationParameterException(
159
                    '@Route.methods must contain only strings.'
160
                );
161
            }
162
        }
163
    }
164
165
    /**
166
     * @param array $params
167
     *
168
     * @return void
169
     *
170
     * @throws InvalidAnnotationParameterException
171
     */
172
    private function assertParamsContainValidMiddlewares(array $params) : void
173
    {
174
        if (!is_array($params['middlewares'])) {
175
            throw new InvalidAnnotationParameterException(
176
                '@Route.middlewares must be an array.'
177
            );
178
        }
179
180
        foreach ($params['middlewares'] as $middleware) {
181
            if (!is_string($middleware)) {
182
                throw new InvalidAnnotationParameterException(
183
                    '@Route.middlewares must contain only strings.'
184
                );
185
            }
186
187
            if (!is_subclass_of($middleware, MiddlewareInterface::class)) {
188
                throw new InvalidAnnotationParameterException(
189
                    '@Route.middlewares contains a nonexistent or non-middleware class.'
190
                );
191
            }
192
        }
193
    }
194
195
    /**
196
     * @param array $params
197
     *
198
     * @return void
199
     *
200
     * @throws InvalidAnnotationParameterException
201
     */
202
    private function assertParamsContainValidAttributes(array $params) : void
203
    {
204
        if (!is_array($params['attributes'])) {
205
            throw new InvalidAnnotationParameterException(
206
                '@Route.attributes must be an array.'
207
            );
208
        }
209
    }
210
211
    /**
212
     * @param array $params
213
     *
214
     * @return void
215
     *
216
     * @throws InvalidAnnotationParameterException
217
     */
218
    private function assertParamsContainValidPriority(array $params) : void
219
    {
220
        if (!is_int($params['priority'])) {
221
            throw new InvalidAnnotationParameterException(
222
                '@Route.priority must be an integer.'
223
            );
224
        }
225
    }
226
}
227