Completed
Push — master ( 163fd9...314ef3 )
by Neomerx
02:36
created

BaseGroup   B

Complexity

Total Complexity 38

Size/Duplication

Total Lines 380
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 7

Test Coverage

Coverage 100%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 38
c 2
b 0
f 0
lcom 1
cbo 7
dl 0
loc 380
ccs 126
cts 126
cp 1
rs 8.3999

28 Methods

Rating   Name   Duplication   Size   Complexity  
A hasTrailSlash() 0 4 1
createGroup() 0 1 ?
A setParentGroup() 0 6 1
A setUriPrefix() 0 6 1
A setName() 0 6 1
A setHasTrailSlash() 0 6 1
A parentGroup() 0 4 1
A getUriPrefix() 0 9 2
A getName() 0 4 1
A getMiddleware() 0 6 1
A getContainerConfigurators() 0 6 1
A getRequestFactory() 0 11 3
A getRoutes() 0 15 4
A group() 0 15 2
A addGroup() 0 8 1
A addRoute() 0 6 1
A method() 0 17 1
A get() 0 4 1
A post() 0 4 1
A put() 0 4 1
A patch() 0 4 1
A delete() 0 4 1
A createRoute() 0 6 1
A normalizeRouteParameters() 0 22 2
A normalizeGroupParameters() 0 21 1
A getParentUriPrefix() 0 7 2
A getParentMiddleware() 0 7 2
A getParentConfigurators() 0 7 2
1
<?php namespace Limoncello\Core\Routing;
2
3
/**
4
 * Copyright 2015-2016 [email protected] (www.neomerx.com)
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License");
7
 * you may not use this file except in compliance with the License.
8
 * You may obtain a copy of the License at
9
 *
10
 * http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS,
14
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 * See the License for the specific language governing permissions and
16
 * limitations under the License.
17
 */
18
19
use Closure;
20
use Limoncello\Core\Contracts\Routing\GroupInterface;
21
use Limoncello\Core\Contracts\Routing\RouteInterface;
22
use Limoncello\Core\Routing\Traits\CallableTrait;
23
use Limoncello\Core\Routing\Traits\HasConfiguratorsTrait;
24
use Limoncello\Core\Routing\Traits\HasMiddlewareTrait;
25
use Limoncello\Core\Routing\Traits\HasRequestFactoryTrait;
26
use Limoncello\Core\Routing\Traits\UriTrait;
27
28
/**
29
 * @package Limoncello\Core
30
 */
31
abstract class BaseGroup implements GroupInterface
32
{
33
    use CallableTrait, UriTrait, HasConfiguratorsTrait, HasMiddlewareTrait, HasRequestFactoryTrait;
34
35
    /** Default value if routes should use request factory from its group */
36
    const USE_FACTORY_FROM_GROUP_DEFAULT = true;
37
38
    /**
39
     * @var null|GroupInterface
40
     */
41
    private $parent;
42
43
    /**
44
     * @var string
45
     */
46
    private $uriPrefix = '';
47
48
    /**
49
     * @var string|null
50
     */
51
    private $name = null;
52
53
    /**
54
     * @var array
55
     */
56
    private $items = [];
57
58
    /**
59
     * @var bool
60
     */
61
    private $trailSlashes = false;
62
63
    /**
64
     * @return BaseGroup
65
     */
66
    abstract protected function createGroup();
67
68
    /**
69
     * @param GroupInterface $parent
70
     *
71
     * @return $this
72
     */
73 12
    public function setParentGroup(GroupInterface $parent)
74
    {
75 12
        $this->parent = $parent;
76
77 12
        return $this;
78
    }
79
80
    /**
81
     * @param string $uriPrefix
82
     *
83
     * @return $this
84
     */
85 12
    public function setUriPrefix($uriPrefix)
86
    {
87 12
        $this->uriPrefix = $uriPrefix;
88
89 12
        return $this;
90
    }
91
92
    /**
93
     * @param string $name
94
     *
95
     * @return $this
96
     */
97 12
    public function setName($name)
98
    {
99 12
        $this->name = $name;
100
101 12
        return $this;
102
    }
103
104
    /**
105
     * @param bool $trailSlashes
106
     *
107
     * @return $this
108
     */
109 12
    public function setHasTrailSlash($trailSlashes)
110
    {
111 12
        $this->trailSlashes = $trailSlashes;
112
113 12
        return $this;
114
    }
115
116
    /**
117
     * @return null|GroupInterface
118
     */
119 13
    public function parentGroup()
120
    {
121 13
        return $this->parent;
122
    }
123
124
    /**
125
     * @inheritdoc
126
     */
127 13
    public function getUriPrefix()
128
    {
129 13
        $parentPrefix = $this->getParentUriPrefix();
130 13
        if ($parentPrefix !== null) {
131 12
            return $this->normalizeUri($this->concatUri($parentPrefix, $this->uriPrefix), $this->hasTrailSlash());
132
        }
133
134 13
        return $this->normalizeUri($this->uriPrefix, $this->hasTrailSlash());
135
    }
136
137
    /**
138
     * @inheritdoc
139
     */
140 6
    public function getName()
141
    {
142 6
        return $this->name;
143
    }
144
145
    /**
146
     * @inheritdoc
147
     */
148 12
    public function getMiddleware()
149
    {
150 12
        $result = array_merge($this->getParentMiddleware(), $this->middleware);
151
152 12
        return $result;
153
    }
154
155
    /**
156
     * @inheritdoc
157
     */
158 12
    public function getContainerConfigurators()
159
    {
160 12
        $result = array_merge($this->getParentConfigurators(), $this->configurators);
161
162 12
        return $result;
163
    }
164
165
    /**
166
     * @inheritdoc
167
     */
168 12
    public function getRequestFactory()
169
    {
170 12
        if ($this->isRequestFactorySet() === true) {
171 7
            return $this->requestFactory;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The expression $this->requestFactory; of type callable|false|null adds false to the return on line 171 which is incompatible with the return type declared by the interface Limoncello\Core\Contract...face::getRequestFactory of type callable|null. It seems like you forgot to handle an error condition.
Loading history...
172
        }
173
174 10
        $parent = $this->parentGroup();
175 10
        $result = $parent === null ? $this->getDefaultRequestFactory() : $parent->getRequestFactory();
176
177 10
        return $result;
178
    }
179
180
    /**
181
     * @inheritdoc
182
     */
183 13
    public function getRoutes()
184
    {
185 13
        foreach ($this->items as $routeOrGroup) {
186 13
            if ($routeOrGroup instanceof RouteInterface) {
187
                /** @var RouteInterface $routeOrGroup */
188 13
                yield $routeOrGroup;
189 13
                continue;
190
            }
191
192
            /** @var GroupInterface $routeOrGroup */
193 12
            foreach ($routeOrGroup->getRoutes() as $route) {
194 12
                yield $route;
195 12
            }
196 13
        }
197 13
    }
198
199
    /**
200
     * @inheritdoc
201
     */
202 12
    public function group($prefix, Closure $closure, array $parameters = [])
203
    {
204
        list($middleware, $configurators, $factoryWasGiven, $requestFactory, $name) =
205 12
            $this->normalizeGroupParameters($parameters);
206
207 12
        $group = $this->createGroup()
208 12
            ->setUriPrefix($prefix)
209 12
            ->setMiddleware($middleware)
210 12
            ->setConfigurators($configurators)
211 12
            ->setName($name);
212
213 12
        $factoryWasGiven === false ?: $group->setRequestFactory($requestFactory);
214
215 12
        return $this->addGroup($closure, $group);
216
    }
217
218
    /**
219
     * @inheritdoc
220
     */
221 12
    public function addGroup(Closure $closure, GroupInterface $group)
222
    {
223 12
        $closure($group);
224
225 12
        $this->items[] = $group;
226
227 12
        return $this;
228
    }
229
230
    /**
231
     * @inheritdoc
232
     */
233 13
    public function addRoute(RouteInterface $route)
234
    {
235 13
        $this->items[] = $route;
236
237 13
        return $this;
238
    }
239
240
    /**
241
     * @inheritdoc
242
     */
243 17
    public function method($method, $uriPath, callable $handler, array $parameters = [])
244
    {
245
        list($middleware, $configurators, $requestFactory, $useGroupFactory, $name) =
246 17
            $this->normalizeRouteParameters($parameters);
247
248 17
        $uriPath = $this->normalizeUri($uriPath, $this->hasTrailSlash());
249
250 17
        $route = $this->createRoute($this, $method, $uriPath)
251 17
            ->setUseGroupRequestFactory($useGroupFactory)
252 17
            ->setRequestFactory($requestFactory)
253 16
            ->setConfigurators($configurators)
254 15
            ->setMiddleware($middleware)
255 14
            ->setHandler($handler)
256 13
            ->setName($name);
257
258 13
        return $this->addRoute($route);
259
    }
260
261
    /**
262
     * @inheritdoc
263
     */
264 17
    public function get($uriPath, callable $handler, array $parameters = [])
265
    {
266 17
        return $this->method('GET', $uriPath, $handler, $parameters);
267
    }
268
269
    /**
270
     * @inheritdoc
271
     */
272 12
    public function post($uriPath, callable $handler, array $parameters = [])
273
    {
274 12
        return $this->method('POST', $uriPath, $handler, $parameters);
275
    }
276
277
    /**
278
     * @inheritdoc
279
     */
280 1
    public function put($uriPath, callable $handler, array $parameters = [])
281
    {
282 1
        return $this->method('PUT', $uriPath, $handler, $parameters);
283
    }
284
285
    /**
286
     * @inheritdoc
287
     */
288 2
    public function patch($uriPath, callable $handler, array $parameters = [])
289
    {
290 2
        return $this->method('PATCH', $uriPath, $handler, $parameters);
291
    }
292
293
    /**
294
     * @inheritdoc
295
     */
296 8
    public function delete($uriPath, callable $handler, array $parameters = [])
297
    {
298 8
        return $this->method('DELETE', $uriPath, $handler, $parameters);
299
    }
300
301
    /**
302
     * @inheritdoc
303
     */
304 17
    public function hasTrailSlash()
305
    {
306 17
        return $this->trailSlashes;
307
    }
308
309
    /**
310
     * @param GroupInterface $group
311
     * @param string         $method
312
     * @param string         $uriPath
313
     *
314
     * @return Route
315
     */
316 17
    protected function createRoute(GroupInterface $group, $method, $uriPath)
317
    {
318 17
        $route = (new Route($group, $method, $uriPath));
319
320 17
        return $route;
321
    }
322
323
    /**
324
     * @param array $parameters
325
     *
326
     * @return array
327
     */
328 17
    protected function normalizeRouteParameters(array $parameters)
329
    {
330
        $defaults = [
331 17
            RouteInterface::PARAM_NAME                    => null,
332 17
            RouteInterface::PARAM_REQUEST_FACTORY         => null,
333 17
            RouteInterface::PARAM_FACTORY_FROM_GROUP      => self::USE_FACTORY_FROM_GROUP_DEFAULT,
334 17
            RouteInterface::PARAM_MIDDLEWARE_LIST         => [],
335 17
            RouteInterface::PARAM_CONTAINER_CONFIGURATORS => [],
336 17
        ];
337
338 17
        $result = array_merge($defaults, $parameters);
339
340 17
        $factoryWasGiven = array_key_exists(RouteInterface::PARAM_REQUEST_FACTORY, $parameters);
341
342
        return [
343 17
            $result[RouteInterface::PARAM_MIDDLEWARE_LIST],
344 17
            $result[RouteInterface::PARAM_CONTAINER_CONFIGURATORS],
345 17
            $result[RouteInterface::PARAM_REQUEST_FACTORY],
346 17
            $factoryWasGiven === true ? false : $result[RouteInterface::PARAM_FACTORY_FROM_GROUP],
347 17
            $result[RouteInterface::PARAM_NAME],
348 17
        ];
349
    }
350
351
    /**
352
     * @param array $parameters
353
     *
354
     * @return array
355
     */
356 20
    protected function normalizeGroupParameters(array $parameters)
357
    {
358
        $defaults = [
359 20
            GroupInterface::PARAM_NAME_PREFIX             => null,
360 20
            GroupInterface::PARAM_REQUEST_FACTORY         => null,
361 20
            GroupInterface::PARAM_MIDDLEWARE_LIST         => [],
362 20
            GroupInterface::PARAM_CONTAINER_CONFIGURATORS => [],
363 20
        ];
364
365 20
        $result = array_merge($defaults, $parameters);
366
367 20
        $factoryWasGiven = array_key_exists(GroupInterface::PARAM_REQUEST_FACTORY, $parameters);
368
369
        return [
370 20
            $result[GroupInterface::PARAM_MIDDLEWARE_LIST],
371 20
            $result[GroupInterface::PARAM_CONTAINER_CONFIGURATORS],
372 20
            $factoryWasGiven,
373 20
            $result[GroupInterface::PARAM_REQUEST_FACTORY],
374 20
            $result[GroupInterface::PARAM_NAME_PREFIX],
375 20
        ];
376
    }
377
378
    /**
379
     * @return null|string
380
     */
381 13
    private function getParentUriPrefix()
382
    {
383 13
        $parent = $this->parentGroup();
384 13
        $result = $parent === null ? null : $parent->getUriPrefix();
385
386 13
        return $result;
387
    }
388
389
    /**
390
     * @return array
391
     */
392 12
    private function getParentMiddleware()
393
    {
394 12
        $parent = $this->parentGroup();
395 12
        $result = $parent === null ? [] : $parent->getMiddleware();
396
397 12
        return $result;
398
    }
399
400
    /**
401
     * @return array
402
     */
403 12
    private function getParentConfigurators()
404
    {
405 12
        $parent = $this->parentGroup();
406 12
        $result = $parent === null ? [] : $parent->getContainerConfigurators();
407
408 12
        return $result;
409
    }
410
}
411