Passed
Pull Request — master (#97)
by Dmitriy
07:54
created

Group::disableMiddleware()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 1
dl 0
loc 5
ccs 0
cts 4
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Router;
6
7
use InvalidArgumentException;
8
use Psr\Http\Server\MiddlewareInterface;
9
use Yiisoft\Middleware\Dispatcher\MiddlewareDispatcher;
10
use function get_class;
11
use function in_array;
12
use function is_array;
13
use function is_callable;
14
use function is_object;
15
use function is_string;
16
17
final class Group implements RouteCollectorInterface
18
{
19
    /**
20
     * @var Group[]|Route[]
21
     */
22
    protected array $items = [];
23
    protected ?string $prefix;
24
25
    protected array $middlewareDefinitions = [];
26
    private array $disabledMiddlewareDefinitions = [];
27
    private ?MiddlewareDispatcher $dispatcher = null;
28
29 10
    private function __construct(?string $prefix = null, ?callable $callback = null, MiddlewareDispatcher $dispatcher = null)
30
    {
31 10
        $this->dispatcher = $dispatcher;
32 10
        $this->prefix = $prefix;
33
34 10
        if ($callback !== null) {
35 10
            $callback($this);
36
        }
37 10
    }
38
39
    /**
40
     * Create a new instance
41
     *
42
     * @param string|null $prefix
43
     * @param array|callable $routes
44
     * @param MiddlewareDispatcher|null $dispatcher
45
     *
46
     * @return self
47
     */
48 10
    public static function create(?string $prefix = null, $routes = [], MiddlewareDispatcher $dispatcher = null): self
49
    {
50 10
        if (is_callable($routes)) {
51 4
            $callback = $routes;
52 9
        } elseif (is_array($routes)) {
53 9
            $callback = static function (self $group) use (&$routes) {
54 9
                foreach ($routes as $route) {
55 2
                    if ($route instanceof Route) {
56 2
                        $group->addRoute($route);
57 2
                    } elseif ($route instanceof self) {
58 2
                        $group->addGroup($route);
59
                    } else {
60
                        $type = is_object($route) ? get_class($route) : gettype($route);
61
                        throw new InvalidArgumentException(sprintf('Route should be either instance of Route or Group, %s given.', $type));
62
                    }
63
                }
64 9
            };
65
        } else {
66
            $callback = null;
67
        }
68
69 10
        return new self($prefix, $callback, $dispatcher);
70
    }
71
72 2
    public function withDispatcher(MiddlewareDispatcher $dispatcher): self
73
    {
74 2
        $group = clone $this;
75 2
        $group->dispatcher = $dispatcher;
76 2
        foreach ($group->items as $index => $item) {
77 2
            if (!$item->hasDispatcher()) {
78 2
                $item = $item->withDispatcher($dispatcher);
79 2
                $group->items[$index] = $item;
80
            }
81
        }
82
83 2
        return $group;
84
    }
85
86 9
    public function hasDispatcher(): bool
87
    {
88 9
        return $this->dispatcher !== null;
89
    }
90
91 9
    public function addRoute(Route $route): self
92
    {
93 9
        if (!$route->hasDispatcher() && $this->hasDispatcher()) {
94 3
            $route->injectDispatcher($this->dispatcher);
95
        }
96 9
        $this->items[] = $route;
97 9
        return $this;
98
    }
99
100 6
    public function addGroup(self $group): self
101
    {
102 6
        if (!$group->hasDispatcher() && $this->hasDispatcher()) {
103 2
            $group = $group->withDispatcher($this->dispatcher);
104
        }
105 6
        $this->items[] = $group;
106 6
        return $this;
107
    }
108
109
    /**
110
     * Adds a handler middleware definition that should be invoked for a matched route.
111
     * Last added handler will be executed first.
112
     *
113
     * @param $middlewareDefinition mixed
114
     * @return self
115
     */
116 6
    public function addMiddleware($middlewareDefinition): self
117
    {
118 6
        $this->middlewareDefinitions[] = $middlewareDefinition;
119 6
        return $this;
120
    }
121
122
    public function disableMiddleware($middlewareDefinition): self
123
    {
124
        $route = clone $this;
125
        $route->disabledMiddlewareDefinitions[] = $middlewareDefinition;
126
        return $route;
127
    }
128
129
    /**
130
     * @return Group[]|Route[]
131
     */
132 9
    public function getItems(): array
133
    {
134 9
        return $this->items;
135
    }
136
137 7
    public function getPrefix(): ?string
138
    {
139 7
        return $this->prefix;
140
    }
141
142 8
    public function getMiddlewareDefinitions(): array
143
    {
144 8
        foreach ($this->middlewareDefinitions as $index => $definition) {
145 6
            if (in_array($definition, $this->disabledMiddlewareDefinitions)) {
146
                unset($this->middlewareDefinitions[$index]);
147
            }
148
        }
149
150 8
        return $this->middlewareDefinitions;
151
    }
152
}
153