Test Failed
Push — master ( fd3819...5bc6ef )
by Divine Niiquaye
13:04
created

GroupingTrait   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 103
Duplicated Lines 0 %

Importance

Changes 15
Bugs 0 Features 0
Metric Value
eloc 40
c 15
b 0
f 0
dl 0
loc 103
rs 10
wmc 17

4 Methods

Rating   Name   Duplication   Size   Complexity  
A populate() 0 20 5
B injectGroups() 0 25 7
A group() 0 15 3
A injectGroup() 0 10 2
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of Flight Routing.
7
 *
8
 * PHP version 7.4 and above required
9
 *
10
 * @author    Divine Niiquaye Ibok <[email protected]>
11
 * @copyright 2019 Biurad Group (https://biurad.com/)
12
 * @license   https://opensource.org/licenses/BSD-3-Clause License
13
 *
14
 * For the full copyright and license information, please view the LICENSE
15
 * file that was distributed with this source code.
16
 */
17
18
namespace Flight\Routing\Traits;
19
20
use Flight\Routing\{Route, RouteCollection};
21
22
/**
23
 * A trait providing route collection grouping functionality.
24
 *
25
 * @author Divine Niiquaye Ibok <[email protected]>
26
 */
27
trait GroupingTrait
28
{
29
    /** @var self[] */
30
    private array $groups = [];
31
32
    private string $namedPrefix;
33
34
    /**
35
     * Mounts controllers under the given route prefix.
36
     *
37
     * @param string                   $name        The route group prefixed name
38
     * @param callable|RouteCollection $controllers A RouteCollection instance or a callable for defining routes
39
     *
40
     * @throws \TypeError        if $controllers not instance of route collection's class
41
     * @throws \RuntimeException if locked
42
     *
43
     * @return $this
44
     */
45
    public function group(string $name, $controllers = null)
46
    {
47
        if (null === $this->uniqueId) {
48
            throw new \RuntimeException('Grouping index invalid or out of range, add group before calling the getRoutes() method.');
49
        }
50
51
        if (\is_callable($controllers)) {
52
            $routes = new static($name);
0 ignored issues
show
Unused Code introduced by
The call to Flight\Routing\Traits\GroupingTrait::__construct() has too many arguments starting with $name. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

52
            $routes = /** @scrutinizer ignore-call */ new static($name);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
53
            $routes->prototypes = $this->prototypes ?? [];
0 ignored issues
show
Bug Best Practice introduced by
The property prototypes does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
54
            $controllers($routes);
55
56
            return $this->groups[] = $routes;
57
        }
58
59
        return $this->groups[] = $this->injectGroup($name, $controllers ?? new static($name));
0 ignored issues
show
Bug introduced by
It seems like $controllers ?? new static($name) can also be of type callable and null; however, parameter $controllers of Flight\Routing\Traits\GroupingTrait::injectGroup() does only seem to accept Flight\Routing\Traits\GroupingTrait, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

59
        return $this->groups[] = $this->injectGroup($name, /** @scrutinizer ignore-type */ $controllers ?? new static($name));
Loading history...
60
    }
61
62
    /**
63
     * Merge a collection into base.
64
     *
65
     * @throws \RuntimeException if locked
66
     */
67
    public function populate(self $collection, bool $asGroup = false): void
68
    {
69
        if ($asGroup) {
70
            if (null === $this->uniqueId) {
71
                throw new \RuntimeException('Populating a route collection as group must be done before calling the getRoutes() method.');
72
            }
73
74
            $this->groups[] = $collection;
75
        } else {
76
            $routes = $collection->routes;
77
78
            if (!empty($collection->groups)) {
79
                $collection->injectGroups($collection->namedPrefix, $routes);
80
            }
81
82
            foreach ($routes as $route) {
83
                $this->routes[] = $this->injectRoute($route);
0 ignored issues
show
Bug Best Practice introduced by
The property routes does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
Bug introduced by
The method injectRoute() does not exist on Flight\Routing\Traits\GroupingTrait. Did you maybe mean injectGroup()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

83
                /** @scrutinizer ignore-call */ 
84
                $this->routes[] = $this->injectRoute($route);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
84
            }
85
86
            $collection->routes = $collection->prototypes = [];
0 ignored issues
show
Bug Best Practice introduced by
The property prototypes does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
87
        }
88
    }
89
90
    protected function injectGroup(string $prefix, self $controllers): self
91
    {
92
        $controllers->prototypes = $this->prototypes ?? [];
0 ignored issues
show
Bug Best Practice introduced by
The property prototypes does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
93
        $controllers->parent = $this;
0 ignored issues
show
Bug Best Practice introduced by
The property parent does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
94
95
        if (empty($controllers->namedPrefix)) {
96
            $controllers->namedPrefix = $prefix;
97
        }
98
99
        return $controllers;
100
    }
101
102
    /**
103
     * @param array<int,Route> $collection
104
     */
105
    private function injectGroups(string $prefix, array &$collection): void
106
    {
107
        $unnamedRoutes = [];
108
109
        foreach ($this->groups as $group) {
110
            foreach ($group->routes as $route) {
111
                if (empty($name = $route->getName())) {
112
                    $name = $route->generateRouteName('');
113
114
                    if (isset($unnamedRoutes[$name])) {
115
                        $name .= ('_' !== $name[-1] ? '_' : '') . ++$unnamedRoutes[$name];
116
                    } else {
117
                        $unnamedRoutes[$name] = 0;
118
                    }
119
                }
120
121
                $collection[] = $route->bind($prefix . $group->namedPrefix . $name);
122
            }
123
124
            if (!empty($group->groups)) {
125
                $group->injectGroups($prefix . $group->namedPrefix, $collection);
126
            }
127
        }
128
129
        $this->groups = [];
130
    }
131
}
132