Test Failed
Pull Request — master (#831)
by Maxim
13:01
created

RouteGroup::setNamePrefix()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 8
ccs 4
cts 4
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Spiral\Router;
6
7
use Psr\Container\ContainerInterface;
8
use Psr\Http\Server\MiddlewareInterface;
9
use Spiral\Core\Container\Autowire;
10
use Spiral\Core\CoreInterface;
11
use Spiral\Router\Target\AbstractTarget;
12
13
/**
14
 * RouteGroup provides the ability to configure multiple routes to controller/actions using same presets.
15
 */
16
final class RouteGroup
17
{
18
    private string $prefix = '';
19
    private string $namePrefix = '';
20
21
    /** @var string[] */
22
    private array $routes = [];
23
24
    /** @var array<class-string<MiddlewareInterface>|MiddlewareInterface|Autowire> */
0 ignored issues
show
Documentation Bug introduced by
The doc comment array<class-string<Middl...wareInterface|Autowire> at position 2 could not be parsed: Unknown type name 'class-string' at position 2 in array<class-string<MiddlewareInterface>|MiddlewareInterface|Autowire>.
Loading history...
25
    private array $middleware = [];
26
27
    private ?CoreInterface $core = null;
28
29 280
    public function __construct(
30
        private readonly ContainerInterface $container,
31
        private readonly RouterInterface $router,
32
        private readonly UriHandler $handler
33
    ) {
34
    }
35
36
    /**
37
     * Check if group has a route with given name
38
     */
39 2
    public function hasRoute(string $name): bool
40
    {
41 2
        return \in_array($name, $this->routes);
42
    }
43
44
    /**
45
     * Prefix added to all the routes.
46
     */
47
    public function setPrefix(string $prefix): self
48
    {
49
        $this->prefix = $prefix;
50
51
        // update routes
52
        $this->flushRoutes();
53
54
        return $this;
55
    }
56
57 2
    /**
58
     * Route name prefix added to all routes.
59 2
     */
60 1
    public function setNamePrefix(string $prefix): self
61
    {
62 2
        $this->namePrefix = $prefix;
63
64
        // update routes
65 2
        $this->flushRoutes();
66
67 2
        return $this;
68
    }
69
70
    public function setCore(Autowire|CoreInterface|string $core): self
71
    {
72
        if (!$core instanceof CoreInterface) {
73 270
            $core = $this->container->get($core);
0 ignored issues
show
Bug introduced by
It seems like $core can also be of type Spiral\Core\Container\Autowire; however, parameter $id of Psr\Container\ContainerInterface::get() does only seem to accept string, 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

73
            $core = $this->container->get(/** @scrutinizer ignore-type */ $core);
Loading history...
74
        }
75 270
        $this->core = $core;
76
77
        // update routes
78 270
        $this->flushRoutes();
79
80 270
        return $this;
81
    }
82
83
    /**
84
     * @param MiddlewareInterface|Autowire|class-string<MiddlewareInterface>|non-empty-string $middleware
0 ignored issues
show
Documentation Bug introduced by
The doc comment MiddlewareInterface|Auto...rface>|non-empty-string at position 4 could not be parsed: Unknown type name 'class-string' at position 4 in MiddlewareInterface|Autowire|class-string<MiddlewareInterface>|non-empty-string.
Loading history...
85
     */
86
    public function addMiddleware(MiddlewareInterface|Autowire|string $middleware): self
87
    {
88 272
        $this->middleware[] = $middleware;
89
90 272
        // update routes
91
        $this->flushRoutes();
92
93
        return $this;
94
    }
95
96
    /**
97
     * Push routes to router.
98 279
     *
99
     * @internal
100 279
     */
101
    public function flushRoutes(): void
102 279
    {
103
        foreach ($this->routes as $name) {
104 279
            $this->router->setRoute($name, $this->applyGroupParams($this->router->getRoute($name)));
105
        }
106
    }
107 279
108
    /**
109 279
     * Add a route to a route group.
110 2
     */
111
    public function addRoute(string $name, Route $route): self
112 2
    {
113 2
        $this->routes[] = $this->namePrefix . $name;
114
115
        $this->router->setRoute($this->namePrefix . $name, $this->applyGroupParams($route));
116
117
        return $this;
118 279
    }
119 279
120
    private function applyGroupParams(Route $route): Route
121
    {
122
        if ($this->core !== null) {
123
            $target = $route->getTarget();
124
125
            if ($target instanceof AbstractTarget) {
126
                $route = $route->withTarget($target->withCore($this->core));
127
            }
128
        }
129
130
        try {
131
            $uriHandler = $route->getUriHandler();
132
        } catch (\Throwable) {
133
            $uriHandler = $this->handler;
134
        }
135
136
        return $route
137
            ->withUriHandler($uriHandler->withPrefix($this->prefix))
138
            ->withMiddleware(...$this->middleware);
139
    }
140
}
141