Passed
Push — master ( 2ec48f...8844b9 )
by
unknown
01:42
created

Group::create()   A

Complexity

Conditions 6
Paths 3

Size

Total Lines 21
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 6.1308

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 6
eloc 14
c 1
b 0
f 0
nc 3
nop 3
dl 0
loc 21
ccs 11
cts 13
cp 0.8462
crap 6.1308
rs 9.2222
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Router;
6
7
use InvalidArgumentException;
8
use Psr\Container\ContainerInterface;
9
use Psr\Http\Server\MiddlewareInterface;
10
use Yiisoft\Router\Middleware\Callback;
11
12
class Group implements RouteCollectorInterface
13
{
14
    /**
15
     * @var Group[]|Route[]
16
     */
17
    protected array $items = [];
18
    protected ?string $prefix;
19
    protected array $middlewares = [];
20
    private ?ContainerInterface $container = null;
21
22 9
    private function __construct(?string $prefix = null, ?callable $callback = null, ContainerInterface $container = null)
23
    {
24 9
        $this->container = $container;
25 9
        $this->prefix = $prefix;
26
27 9
        if ($callback !== null) {
28 9
            $callback($this);
29
        }
30
    }
31
32
    /**
33
     * Create a new instance
34
     *
35
     * @param string $prefix
36
     * @param callable|array $routes
37
     * @param ContainerInterface $container
38
     *
39
     * @return self
40
     */
41 9
    final public static function create(?string $prefix = null, $routes = [], ContainerInterface $container = null): self
42
    {
43 9
        if (\is_callable($routes)) {
44 4
            $callback = $routes;
45 8
        } elseif (is_array($routes)) {
46
            $callback = static function (Group $group) use (&$routes) {
47 8
                foreach ($routes as $route) {
48 2
                    if ($route instanceof Route) {
49 2
                        $group->addRoute($route);
50 2
                    } elseif ($route instanceof Group) {
51 2
                        $group->addGroup($route);
52
                    } else {
53
                        throw new InvalidArgumentException('Route should be either instance of Route or Group.');
54
                    }
55
                }
56 8
            };
57
        } else {
58
            $callback = null;
59
        }
60
61 9
        return new self($prefix, $callback, $container);
62
    }
63
64 2
    final public function withContainer(ContainerInterface $container): self
65
    {
66 2
        $group = clone $this;
67 2
        $group->container = $container;
68 2
        foreach ($group->items as $index => $item) {
69 2
            if (!$item->hasContainer()) {
70 2
                $item = $item->withContainer($container);
71 2
                $group->items[$index] = $item;
72
            }
73
        }
74
75 2
        return $group;
76
    }
77
78 8
    final public function hasContainer(): bool
79
    {
80 8
        return $this->container !== null;
81
    }
82
83 8
    final public function addRoute(Route $route): self
84
    {
85 8
        if (!$route->hasContainer() && $this->hasContainer()) {
86 2
            $route = $route->withContainer($this->container);
87
        }
88 8
        $this->items[] = $route;
89 8
        return $this;
90
    }
91
92 6
    final public function addGroup(Group $group): self
93
    {
94 6
        if (!$group->hasContainer() && $this->hasContainer()) {
95 2
            $group = $group->withContainer($this->container);
96
        }
97 6
        $this->items[] = $group;
98 6
        return $this;
99
    }
100
101
    /**
102
     * @param callable|MiddlewareInterface $middleware
103
     * @return $this
104
     */
105 5
    final public function addMiddleware($middleware): self
106
    {
107 5
        if (is_callable($middleware)) {
108
            $middleware = new Callback($middleware, $this->container);
0 ignored issues
show
Bug introduced by
It seems like $this->container can also be of type null; however, parameter $container of Yiisoft\Router\Middleware\Callback::__construct() does only seem to accept Psr\Container\ContainerInterface, 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

108
            $middleware = new Callback($middleware, /** @scrutinizer ignore-type */ $this->container);
Loading history...
Bug introduced by
It seems like $middleware can also be of type Psr\Http\Server\MiddlewareInterface; however, parameter $callback of Yiisoft\Router\Middleware\Callback::__construct() does only seem to accept callable, 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

108
            $middleware = new Callback(/** @scrutinizer ignore-type */ $middleware, $this->container);
Loading history...
109
        }
110
111 5
        if (!$middleware instanceof MiddlewareInterface) {
112
            throw new InvalidArgumentException('Parameter should be either a PSR middleware or a callable.');
113
        }
114
115 5
        array_unshift($this->middlewares, $middleware);
116
117 5
        return $this;
118
    }
119
120
    /**
121
     * @return Route|Group[]
122
     */
123 8
    final public function getItems(): array
124
    {
125 8
        return $this->items;
126
    }
127
128 4
    final public function getPrefix(): ?string
129
    {
130 4
        return $this->prefix;
131
    }
132
133 6
    final public function getMiddlewares(): array
134
    {
135 6
        return $this->middlewares;
136
    }
137
}
138