Passed
Push — master ( 9328af...ecfde0 )
by Alexander
06:46
created

Group::hasContainer()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
cc 1
nc 1
nop 0
crap 1
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
final 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 10
    private function __construct(?string $prefix = null, ?callable $callback = null, ContainerInterface $container = null)
23
    {
24 10
        $this->container = $container;
25 10
        $this->prefix = $prefix;
26
27 10
        if ($callback !== null) {
28 10
            $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 10
    final public static function create(?string $prefix = null, $routes = [], ContainerInterface $container = null): self
42
    {
43 10
        if (\is_callable($routes)) {
44 4
            $callback = $routes;
45 9
        } elseif (is_array($routes)) {
46
            $callback = static function (Group $group) use (&$routes) {
47 9
                foreach ($routes as $route) {
48 3
                    if ($route instanceof Route) {
49 3
                        $group->addRoute($route);
50 3
                    } elseif ($route instanceof Group) {
51 3
                        $group->addGroup($route);
52
                    } else {
53
                        throw new InvalidArgumentException('Route should be either instance of Route or Group.');
54
                    }
55
                }
56 9
            };
57
        } else {
58
            $callback = null;
59
        }
60
61 10
        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 9
    final public function hasContainer(): bool
79
    {
80 9
        return $this->container !== null;
81
    }
82
83 9
    final public function addRoute(Route $route): self
84
    {
85 9
        if (!$route->hasContainer() && $this->hasContainer()) {
86 2
            $route = $route->withContainer($this->container);
87
        }
88 9
        $this->items[] = $route;
89 9
        return $this;
90
    }
91
92 7
    final public function addGroup(Group $group): self
93
    {
94 7
        if (!$group->hasContainer() && $this->hasContainer()) {
95 2
            $group = $group->withContainer($this->container);
96
        }
97 7
        $this->items[] = $group;
98 7
        return $this;
99
    }
100
101
    /**
102
     * @param MiddlewareInterface|callable|string|array $middleware
103
     */
104 6
    private function validateMiddleware($middleware): void
105
    {
106
        if (
107 6
            is_string($middleware) && is_subclass_of($middleware, MiddlewareInterface::class)
108
        ) {
109
            return;
110
        }
111
112 6
        if (is_callable($middleware)) {
113
            return;
114
        }
115
116 6
        if (!$middleware instanceof MiddlewareInterface) {
117
            throw new InvalidArgumentException('Parameter should be either PSR middleware instance, PSR middleware class name, handler action or a callable.');
118
        }
119
    }
120
121
    /**
122
     * @param callable|MiddlewareInterface $middleware
123
     * @return $this
124
     */
125 6
    final public function addMiddleware($middleware): self
126
    {
127 6
        $this->validateMiddleware($middleware);
128 6
        $this->middlewares[] = $middleware;
129
130 6
        return $this;
131
    }
132
133
    /**
134
     * @return Route|Group[]
135
     */
136 9
    final public function getItems(): array
137
    {
138 9
        return $this->items;
139
    }
140
141 5
    final public function getPrefix(): ?string
142
    {
143 5
        return $this->prefix;
144
    }
145
146 7
    final public function getMiddlewares(): array
147
    {
148 7
        return $this->middlewares;
149
    }
150
}
151