Test Failed
Pull Request — master (#63)
by Anatoly
10:52
created

Route::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 29
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 16
nc 1
nop 10
dl 0
loc 29
rs 9.7333
c 1
b 0
f 0

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 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\Attribute;
13
14
/**
15
 * Import classes
16
 */
17
use Attribute;
18
use Psr\Http\Server\MiddlewareInterface;
19
use Sunrise\Http\Router\Exception\InvalidDescriptorArgumentException;
20
use Sunrise\Http\Router\RouteDescriptorInterface;
21
22
/**
23
 * Import functions
24
 */
25
use function is_string;
26
use function is_subclass_of;
27
28
/**
29
 * Attribute for a route description
30
 *
31
 * @since 2.6.0
32
 */
33
#[Attribute(Attribute::TARGET_CLASS)]
34
final class Route implements RouteDescriptorInterface
35
{
36
37
    /**
38
     * A route name
39
     *
40
     * @var string
41
     */
42
    private $name;
43
44
    /**
45
     * A route host
46
     *
47
     * @var null|string
48
     */
49
    private $host;
50
51
    /**
52
     * A route path
53
     *
54
     * @var string
55
     */
56
    private $path;
57
58
    /**
59
     * A route methods
60
     *
61
     * @var string[]
62
     */
63
    private $methods;
64
65
    /**
66
     * A route middlewares
67
     *
68
     * @var string[]
69
     */
70
    private $middlewares;
71
72
    /**
73
     * A route attributes
74
     *
75
     * @var array
76
     */
77
    private $attributes;
78
79
    /**
80
     * A route summary
81
     *
82
     * @var string
83
     */
84
    private $summary;
85
86
    /**
87
     * A route description
88
     *
89
     * @var string
90
     */
91
    private $description;
92
93
    /**
94
     * A route tags
95
     *
96
     * @var string[]
97
     */
98
    private $tags;
99
100
    /**
101
     * A route priority
102
     *
103
     * @var int
104
     */
105
    private $priority;
106
107
    /**
108
     * Constructor of the attribute
109
     *
110
     * @param  string       $name         A route name
111
     * @param  null|string  $host         A route host
112
     * @param  string       $path         A route path
113
     * @param  string[]     $methods      A route methods
114
     * @param  string[]     $middlewares  A route middlewares
115
     * @param  array        $attributes   A route attributes
116
     * @param  string       $summary      A route summary
117
     * @param  string       $description  A route description
118
     * @param  string[]     $tags         A route tags
119
     * @param  int          $priority     A route priority
120
     *
121
     * @throws InvalidDescriptorArgumentException
122
     */
123
    public function __construct(
124
        string $name,
125
        string $host = null,
126
        string $path,
127
        array $methods,
128
        array $middlewares = [],
129
        array $attributes = [],
130
        string $summary = '',
131
        string $description = '',
132
        array $tags = [],
133
        int $priority = 0
134
    ) {
135
        $this->name = $name;
136
        $this->host = $host;
137
        $this->path = $path;
138
        $this->methods = $methods;
139
        $this->middlewares = $middlewares;
140
        $this->attributes = $attributes;
141
        $this->summary = $summary;
142
        $this->description = $description;
143
        $this->tags = $tags;
144
        $this->priority = $priority;
145
146
        $this->assertValidName();
147
        $this->assertValidHost();
148
        $this->assertValidPath();
149
        $this->assertValidMethods();
150
        $this->assertValidMiddlewares();
151
        $this->assertValidTags();
152
    }
153
154
    /**
155
     * {@inheritDoc}
156
     */
157
    public function getName() : string
158
    {
159
        return $this->name;
160
    }
161
162
    /**
163
     * {@inheritDoc}
164
     */
165
    public function getHost() : ?string
166
    {
167
        return $this->host;
168
    }
169
170
    /**
171
     * {@inheritDoc}
172
     */
173
    public function getPath() : string
174
    {
175
        return $this->path;
176
    }
177
178
    /**
179
     * {@inheritDoc}
180
     */
181
    public function getMethods() : array
182
    {
183
        return $this->methods;
184
    }
185
186
    /**
187
     * {@inheritDoc}
188
     */
189
    public function getMiddlewares() : array
190
    {
191
        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...
192
    }
193
194
    /**
195
     * {@inheritDoc}
196
     */
197
    public function getAttributes() : array
198
    {
199
        return $this->attributes;
200
    }
201
202
    /**
203
     * {@inheritDoc}
204
     */
205
    public function getSummary() : string
206
    {
207
        return $this->summary;
208
    }
209
210
    /**
211
     * {@inheritDoc}
212
     */
213
    public function getDescription() : string
214
    {
215
        return $this->description;
216
    }
217
218
    /**
219
     * {@inheritDoc}
220
     */
221
    public function getTags() : array
222
    {
223
        return $this->tags;
224
    }
225
226
    /**
227
     * {@inheritDoc}
228
     */
229
    public function getPriority() : int
230
    {
231
        return $this->priority;
232
    }
233
234
    /**
235
     * Throws an exception if the attribute contains invalid a route name
236
     *
237
     * @return void
238
     *
239
     * @throws InvalidDescriptorArgumentException
240
     */
241
    private function assertValidName() : void
242
    {
243
        if ('' === $this->name) {
244
            throw new InvalidDescriptorArgumentException('#[Route.name] must contain a non-empty string.');
245
        }
246
    }
247
248
    /**
249
     * Throws an exception if the attribute contains invalid a route host
250
     *
251
     * @return void
252
     *
253
     * @throws InvalidDescriptorArgumentException
254
     */
255
    private function assertValidHost() : void
256
    {
257
        if ('' === $this->host) {
258
            throw new InvalidDescriptorArgumentException('#[Route.host] must contain a non-empty string or null.');
259
        }
260
    }
261
262
    /**
263
     * Throws an exception if the attribute contains invalid a route path
264
     *
265
     * @return void
266
     *
267
     * @throws InvalidDescriptorArgumentException
268
     */
269
    private function assertValidPath() : void
270
    {
271
        if ('' === $this->path) {
272
            throw new InvalidDescriptorArgumentException('#[Route.path] must contain a non-empty string.');
273
        }
274
    }
275
276
    /**
277
     * Throws an exception if the attribute contains invalid a route methods
278
     *
279
     * @return void
280
     *
281
     * @throws InvalidDescriptorArgumentException
282
     */
283
    private function assertValidMethods() : void
284
    {
285
        if ([] === $this->methods) {
286
            throw new InvalidDescriptorArgumentException('#[Route.methods] must contain at least one element.');
287
        }
288
289
        foreach ($this->methods as $method) {
290
            if ('' === $method || !is_string($method)) {
291
                throw new InvalidDescriptorArgumentException('#[Route.methods] must contain non-empty strings.');
292
            }
293
        }
294
    }
295
296
    /**
297
     * Throws an exception if the attribute contains invalid a route middlewares
298
     *
299
     * @return void
300
     *
301
     * @throws InvalidDescriptorArgumentException
302
     */
303
    private function assertValidMiddlewares() : void
304
    {
305
        if ([] === $this->middlewares) {
306
            return;
307
        }
308
309
        foreach ($this->middlewares as $middleware) {
310
            if ('' === $middleware || !is_string($middleware)) {
311
                throw new InvalidDescriptorArgumentException('#[Route.middlewares] must contain non-empty strings.');
312
            }
313
314
            if (!is_subclass_of($middleware, MiddlewareInterface::class)) {
315
                throw new InvalidDescriptorArgumentException('#[Route.middlewares] must contain existing middlewares.');
316
            }
317
        }
318
    }
319
320
    /**
321
     * Throws an exception if the attribute contains invalid a route tags
322
     *
323
     * @return void
324
     *
325
     * @throws InvalidDescriptorArgumentException
326
     */
327
    private function assertValidTags() : void
328
    {
329
        if ([] === $this->tags) {
330
            return;
331
        }
332
333
        foreach ($this->tags as $tag) {
334
            if ('' === $tag || !is_string($tag)) {
335
                throw new InvalidDescriptorArgumentException('#[Route.tags] must contain non-empty strings.');
336
            }
337
        }
338
    }
339
}
340