Passed
Push — 6.x ( 08953e...092dd0 )
by Phil
13:02
created

Route   A

Complexity

Total Complexity 28

Size/Duplication

Total Lines 127
Duplicated Lines 0 %

Test Coverage

Coverage 98%

Importance

Changes 5
Bugs 0 Features 1
Metric Value
wmc 28
eloc 49
c 5
b 0
f 1
dl 0
loc 127
ccs 49
cts 50
cp 0.98
rs 10

10 Methods

Rating   Name   Duplication   Size   Complexity  
C getCallable() 0 29 12
A __construct() 0 8 2
A getParentGroup() 0 3 1
A setVars() 0 4 1
A getVars() 0 3 1
A getMethod() 0 3 1
A setParentGroup() 0 12 2
A resolve() 0 11 4
A getPath() 0 9 2
A process() 0 11 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace League\Route;
6
7
use League\Route\Middleware\{MiddlewareAwareInterface, MiddlewareAwareTrait};
8
use Psr\Container\ContainerExceptionInterface;
9
use Psr\Container\NotFoundExceptionInterface;
10
use League\Route\Strategy\{StrategyAwareInterface, StrategyAwareTrait, StrategyInterface};
11
use Psr\Container\ContainerInterface;
12
use Psr\Http\Message\{ResponseInterface, ServerRequestInterface};
13
use Psr\Http\Server\{MiddlewareInterface, RequestHandlerInterface};
14
use RuntimeException;
15
16
class Route implements
17
    MiddlewareInterface,
18
    MiddlewareAwareInterface,
19
    RouteConditionHandlerInterface,
20
    StrategyAwareInterface
21
{
22
    use MiddlewareAwareTrait;
23
    use RouteConditionHandlerTrait;
24
    use StrategyAwareTrait;
25
26
    protected $handler;
27
28 84
    public function __construct(
29
        protected array|string $method,
30
        protected string $path,
31
        callable|string|RequestHandlerInterface $handler,
32
        protected ?RouteGroup $group = null,
33
        protected array $vars = []
34
    ) {
35 84
        $this->handler = ($handler instanceof RequestHandlerInterface) ? [$handler, 'handle'] : $handler;
36
    }
37
38 51
    public function getCallable(?ContainerInterface $container = null): callable
39
    {
40 51
        $callable = $this->handler;
41
42 51
        if (is_string($callable) && str_contains($callable, '::')) {
43 6
            $callable = explode('::', $callable);
44
        }
45
46 51
        if (is_array($callable) && isset($callable[0]) && is_object($callable[0])) {
47 3
            $callable = [$callable[0], $callable[1]];
48
        }
49
50 51
        if (is_array($callable) && isset($callable[0]) && is_string($callable[0])) {
51 6
            $callable = [$this->resolve($callable[0], $container), $callable[1]];
52
        }
53
54 51
        if (is_string($callable)) {
55 6
            $callable = $this->resolve($callable, $container);
56
        }
57
58 51
        if ($callable instanceof RequestHandlerInterface) {
59 3
            $callable = [$callable, 'handle'];
60
        }
61
62 51
        if (!is_callable($callable)) {
63
            throw new RuntimeException('Could not resolve a callable for this route');
64
        }
65
66 51
        return $callable;
67
    }
68
69 45
    public function getMethod(): array|string
70
    {
71 45
        return $this->method;
72
    }
73
74 33
    public function getParentGroup(): ?RouteGroup
75
    {
76 33
        return $this->group;
77
    }
78
79 51
    public function getPath(array $replacements = []): string
80
    {
81 51
        $toReplace = [];
82
83 51
        foreach ($replacements as $wildcard => $actual) {
84 3
            $toReplace['/{' . preg_quote($wildcard, '/') . '(:.*?)?}/'] = $actual;
85
        }
86
87 51
        return preg_replace(array_keys($toReplace), array_values($toReplace), $this->path);
88
    }
89
90 33
    public function getVars(): array
91
    {
92 33
        return $this->vars;
93
    }
94
95 33
    public function process(
96
        ServerRequestInterface $request,
97
        RequestHandlerInterface $handler
98
    ): ResponseInterface {
99 33
        $strategy = $this->getStrategy();
100
101 33
        if (!($strategy instanceof StrategyInterface)) {
102 3
            throw new RuntimeException('A strategy must be set to process a route');
103
        }
104
105 30
        return $strategy->invokeRouteCallable($this, $request);
106
    }
107
108 15
    public function setParentGroup(RouteGroup $group): self
109
    {
110 15
        $this->group = $group;
111 15
        $prefix = $this->group->getPrefix();
112 15
        $path = $this->getPath();
113
114 15
        if (strcmp($prefix, substr($path, 0, strlen($prefix))) !== 0) {
115 3
            $path = $prefix . $path;
116 3
            $this->path = $path;
117
        }
118
119 15
        return $this;
120
    }
121
122 33
    public function setVars(array $vars): self
123
    {
124 33
        $this->vars = $vars;
125 33
        return $this;
126
    }
127
128
    /**
129
     * @throws ContainerExceptionInterface
130
     * @throws NotFoundExceptionInterface
131
     */
132 12
    protected function resolve(string $class, ?ContainerInterface $container = null): mixed
133
    {
134 12
        if ($container instanceof ContainerInterface && $container->has($class)) {
135 6
            return $container->get($class);
136
        }
137
138 6
        if (class_exists($class)) {
139 3
            return new $class();
140
        }
141
142 3
        return $class;
143
    }
144
}
145