Completed
Push — master ( 113bf8...019067 )
by Neomerx
04:28
created

BaseGroup::clearName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 1
cts 1
cp 1
rs 9.4285
c 0
b 0
f 0
nc 1
cc 1
eloc 3
nop 0
crap 1
1
<?php namespace Limoncello\Core\Routing;
2
3
/**
4
 * Copyright 2015-2017 [email protected]
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\Contracts\Routing\GroupInterface;
21
use Limoncello\Contracts\Routing\RouteInterface;
22
use Limoncello\Core\Reflection\CheckCallableTrait;
23
use Limoncello\Core\Routing\Traits\CallableTrait;
24
use Limoncello\Core\Routing\Traits\HasConfiguratorsTrait;
25
use Limoncello\Core\Routing\Traits\HasMiddlewareTrait;
26
use Limoncello\Core\Routing\Traits\HasRequestFactoryTrait;
27
use Limoncello\Core\Routing\Traits\UriTrait;
28
29
/**
30
 * @package Limoncello\Core
31
 */
32
abstract class BaseGroup implements GroupInterface
33
{
34
    use CallableTrait, UriTrait, HasRequestFactoryTrait, CheckCallableTrait;
35
36
    use HasMiddlewareTrait {
37
        addMiddleware as private addMiddlewareImpl;
38
    }
39
40
    use HasConfiguratorsTrait {
41
        addConfigurators as private addConfiguratorsImpl;
42
    }
43
44
    /** Default value if routes should use request factory from its group */
45
    const USE_FACTORY_FROM_GROUP_DEFAULT = true;
46
47
    /**
48
     * @var null|GroupInterface
49
     */
50
    private $parent;
51
52
    /**
53
     * @var string
54
     */
55
    private $uriPrefix = '';
56
57
    /**
58
     * @var string|null
59
     */
60
    private $name = null;
61
62
    /**
63
     * @var array
64
     */
65
    private $items = [];
66
67
    /**
68
     * @var bool
69
     */
70
    private $trailSlashes = false;
71
72
    /**
73
     * @return self
0 ignored issues
show
Documentation introduced by
Should the return type not be \self?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
74
     */
75 17
    abstract protected function createGroup(): self;
76
77 17
    /**
78
     * @param GroupInterface $parent
79 17
     *
80
     * @return $this
81
     */
82
    public function setParentGroup(GroupInterface $parent)
83
    {
84
        $this->parent = $parent;
85
86
        return $this;
87 17
    }
88
89 17
    /**
90
     * @param string $uriPrefix
91 17
     *
92
     * @return self
93
     */
94
    public function setUriPrefix(string $uriPrefix): self
95
    {
96
        $this->uriPrefix = $uriPrefix;
97
98
        return $this;
99 17
    }
100
101 17
    /**
102
     * @param string $name
103 17
     *
104
     * @return self
105
     */
106
    public function setName(string $name): self
107
    {
108
        $this->name = $name;
109
110
        return $this;
111 17
    }
112
113 17
    /**
114
     * @return self
115 17
     */
116
    public function clearName(): self
117
    {
118
        $this->name = null;
119
120
        return $this;
121 18
    }
122
123 18
    /**
124
     * @param bool $trailSlashes
125
     *
126
     * @return self
127
     */
128
    public function setHasTrailSlash(bool $trailSlashes): self
129 18
    {
130
        $this->trailSlashes = $trailSlashes;
131 18
132 18
        return $this;
133 17
    }
134
135
    /**
136 18
     * @inheritdoc
137
     */
138
    public function parentGroup(): ?GroupInterface
139
    {
140
        return $this->parent;
141
    }
142 8
143
    /**
144 8
     * @inheritdoc
145
     */
146
    public function getUriPrefix(): string
147
    {
148
        $parentPrefix = $this->getParentUriPrefix();
149
        if ($parentPrefix !== null) {
150 17
            return $this->normalizeUri($this->concatUri($parentPrefix, $this->uriPrefix), $this->hasTrailSlash());
151
        }
152 17
153
        return $this->normalizeUri($this->uriPrefix, $this->hasTrailSlash());
154 17
    }
155
156
    /**
157
     * @inheritdoc
158
     */
159
    public function getName(): ?string
160 17
    {
161
        return $this->name;
162 17
    }
163
164 17
    /**
165
     * @inheritdoc
166
     */
167
    public function getMiddleware(): array
168
    {
169
        $result = array_merge($this->getParentMiddleware(), $this->middleware);
170 17
171
        return $result;
172 17
    }
173 9
174
    /**
175
     * @inheritdoc
176 15
     */
177 15
    public function addMiddleware(array $middleware): GroupInterface
178
    {
179 15
        return $this->addMiddlewareImpl($middleware);
180
    }
181
182
    /**
183
     * @inheritdoc
184
     */
185 18
    public function getContainerConfigurators(): array
186
    {
187 18
        $result = array_merge($this->getParentConfigurators(), $this->configurators);
188 18
189
        return $result;
190 18
    }
191 18
192
    /**
193
     * @inheritdoc
194
     */
195 17
    public function addContainerConfigurators(array $configurators): GroupInterface
196 17
    {
197
        return $this->addConfiguratorsImpl($configurators);
198
    }
199
200
    /**
201
     * @inheritdoc
202
     */
203
    public function getRequestFactory(): ?callable
204 17
    {
205
        if ($this->isRequestFactorySet() === true) {
206
            return $this->requestFactory;
207 17
        }
208
209 17
        $parent = $this->parentGroup();
210 17
        $result = $parent === null ? $this->getDefaultRequestFactory() : $parent->getRequestFactory();
211 17
212 17
        return $result;
213 17
    }
214
215 17
    /**
216
     * @inheritdoc
217 17
     */
218
    public function getRoutes(): iterable
219
    {
220
        foreach ($this->items as $routeOrGroup) {
221
            if ($routeOrGroup instanceof RouteInterface) {
222
                /** @var RouteInterface $routeOrGroup */
223 17
                yield $routeOrGroup;
224
                continue;
225 17
            }
226
227 17
            /** @var GroupInterface $routeOrGroup */
228
            foreach ($routeOrGroup->getRoutes() as $route) {
229 17
                yield $route;
230
            }
231
        }
232
    }
233
234
    /**
235 18
     * @inheritdoc
236
     */
237 18
    public function group(string $prefix, Closure $closure, array $parameters = []): GroupInterface
238
    {
239 18
        list($middleware, $configurators, $factoryWasGiven, $requestFactory, $name) =
240
            $this->normalizeGroupParameters($parameters);
241
242
        $group = $this->createGroup()
243
            ->setUriPrefix($prefix)
244
            ->setMiddleware($middleware)
245 22
            ->setConfigurators($configurators);
246
        $name === null ? $group->clearName() : $group->setName($name);
247
248 22
        $factoryWasGiven === false ?: $group->setRequestFactory($requestFactory);
249
250 22
        return $this->addGroup($closure, $group);
251
    }
252 22
253 21
    /**
254 21
     * @inheritdoc
255 20
     */
256 19
    public function addGroup(Closure $closure, GroupInterface $group): GroupInterface
257 18
    {
258
        $closure($group);
259 18
260
        $this->items[] = $group;
261
262
        return $this;
263
    }
264
265 22
    /**
266
     * @inheritdoc
267 22
     */
268
    public function addRoute(RouteInterface $route): GroupInterface
269
    {
270
        $this->items[] = $route;
271
272
        return $this;
273 16
    }
274
275 16
    /**
276
     * @inheritdoc
277
     */
278
    public function method(string $method, string $uriPath, callable $handler, array $parameters = []): GroupInterface
279
    {
280
        list($middleware, $configurators, $requestFactory, $useGroupFactory, $name) =
281 1
            $this->normalizeRouteParameters($parameters);
282
283 1
        $uriPath = $this->normalizeUri($uriPath, $this->hasTrailSlash());
284
285
        $route = $this->createRoute($this, $method, $uriPath, $handler)
286
            ->setUseGroupRequestFactory($useGroupFactory)
287
            ->setRequestFactory($requestFactory)
288
            ->setConfigurators($configurators)
289 2
            ->setMiddleware($middleware)
290
            ->setName($name);
291 2
292
        return $this->addRoute($route);
293
    }
294
295
    /**
296
     * @inheritdoc
297 10
     */
298
    public function get(string $uriPath, callable $handler, array $parameters = []): GroupInterface
299 10
    {
300
        return $this->method('GET', $uriPath, $handler, $parameters);
301
    }
302
303
    /**
304
     * @inheritdoc
305 22
     */
306
    public function post(string $uriPath, callable $handler, array $parameters = []): GroupInterface
307 22
    {
308
        return $this->method('POST', $uriPath, $handler, $parameters);
309
    }
310
311
    /**
312
     * @inheritdoc
313
     */
314
    public function put(string $uriPath, callable $handler, array $parameters = []): GroupInterface
315
    {
316
        return $this->method('PUT', $uriPath, $handler, $parameters);
317
    }
318 22
319
    /**
320 22
     * @inheritdoc
321
     */
322 21
    public function patch(string $uriPath, callable $handler, array $parameters = []): GroupInterface
323
    {
324
        return $this->method('PATCH', $uriPath, $handler, $parameters);
325
    }
326
327
    /**
328
     * @inheritdoc
329
     */
330 22
    public function delete(string $uriPath, callable $handler, array $parameters = []): GroupInterface
331
    {
332
        return $this->method('DELETE', $uriPath, $handler, $parameters);
333 22
    }
334 22
335 22
    /**
336 22
     * @inheritdoc
337 22
     */
338
    public function hasTrailSlash(): bool
339
    {
340 22
        return $this->trailSlashes;
341
    }
342 22
343
    /**
344
     * @param GroupInterface $group
345 22
     * @param string         $method
346 22
     * @param string         $uriPath
347 22
     * @param callable       $handler
348 22
     *
349 22
     * @return Route
350
     */
351
    protected function createRoute(GroupInterface $group, string $method, string $uriPath, callable $handler): Route
352
    {
353
        $route = (new Route($group, $method, $uriPath, $handler));
354
355
        return $route;
356
    }
357
358 25
    /**
359
     * @param array $parameters
360
     *
361 25
     * @return array
362 25
     */
363 25
    protected function normalizeRouteParameters(array $parameters): array
364 25
    {
365
        $factoryWasGiven = array_key_exists(RouteInterface::PARAM_REQUEST_FACTORY, $parameters);
366
        $useGroupFactory =
367 25
            $parameters[RouteInterface::PARAM_FACTORY_FROM_GROUP] ?? self::USE_FACTORY_FROM_GROUP_DEFAULT;
368
369 25
        return [
370
            $parameters[RouteInterface::PARAM_MIDDLEWARE_LIST] ?? [],
371
            $parameters[RouteInterface::PARAM_CONTAINER_CONFIGURATORS] ?? [],
372 25
            $parameters[RouteInterface::PARAM_REQUEST_FACTORY] ?? null,
373 25
            $factoryWasGiven === true ? false : $useGroupFactory,
374 25
            $parameters[RouteInterface::PARAM_NAME] ?? null,
375 25
        ];
376 25
    }
377
378
    /**
379
     * @param array $parameters
380
     *
381
     * @return array
382
     */
383 18
    protected function normalizeGroupParameters(array $parameters): array
384
    {
385 18
        $factoryWasGiven = array_key_exists(GroupInterface::PARAM_REQUEST_FACTORY, $parameters);
386 18
387
        return [
388 18
            $parameters[GroupInterface::PARAM_MIDDLEWARE_LIST] ?? [],
389
            $parameters[GroupInterface::PARAM_CONTAINER_CONFIGURATORS] ?? [],
390
            $factoryWasGiven,
391
            $parameters[GroupInterface::PARAM_REQUEST_FACTORY] ?? null,
392
            $parameters[GroupInterface::PARAM_NAME_PREFIX] ?? null,
393
        ];
394 17
    }
395
396 17
    /**
397 17
     * @return null|string
398
     */
399 17
    private function getParentUriPrefix(): ?string
400
    {
401
        $parent = $this->parentGroup();
402
        $result = $parent === null ? null : $parent->getUriPrefix();
403
404
        return $result;
405 17
    }
406
407 17
    /**
408 17
     * @return array
409
     */
410 17
    private function getParentMiddleware(): array
411
    {
412
        $parent = $this->parentGroup();
413
        $result = $parent === null ? [] : $parent->getMiddleware();
414
415
        return $result;
416
    }
417
418
    /**
419
     * @return array
420
     */
421
    private function getParentConfigurators(): array
422
    {
423
        $parent = $this->parentGroup();
424
        $result = $parent === null ? [] : $parent->getContainerConfigurators();
425
426
        return $result;
427
    }
428
}
429