GenerateRouteMiddleware::generateRoute()   A
last analyzed

Complexity

Conditions 3
Paths 4

Size

Total Lines 15
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 7
c 1
b 0
f 0
nc 4
nop 3
dl 0
loc 15
ccs 8
cts 8
cp 1
crap 3
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Jasny\SwitchRoute\Generator;
6
7
use Jasny\SwitchRoute\Endpoint;
8
use Jasny\SwitchRoute\InvalidRouteException;
9
10
/**
11
 * Generate a route middleware that sets server request attributes.
12
 */
13
class GenerateRouteMiddleware extends AbstractGenerate
14
{
15
    /**
16
     * Invoke code generation.
17
     *
18
     * @param string $name      Class name
19
     * @param array  $routes    Ignored
20
     * @param array  $structure
21
     * @return string
22
     */
23 3
    public function __invoke(string $name, array $routes, array $structure): string
24
    {
25 3
        $default = $structure["\e"] ?? null;
26 3
        unset($structure["\e"]);
27
28 3
        $applyRoutingCode = self::indent($this->generateSwitch($structure), 8) . "\n\n"
29 3
            . self::indent($this->generateDefault($default), 8);
30
31 3
        [$namespace, $class] = $this->generateNs($name);
32
33 3
        return <<<CODE
34 3
<?php
35
36
declare(strict_types=1);
37 3
{$namespace}
38
use Psr\Http\Message\ResponseInterface;
39
use Psr\Http\Message\ServerRequestInterface;
40
use Psr\Http\Server\MiddlewareInterface;
41
use Psr\Http\Server\RequestHandlerInterface;
42
43
/**
44
 * PSR-15 compatible middleware that add route attributes to the server request.
45
 *
46
 * This file is generated by SwitchRoute.
47
 * Do not modify it manually. Any changes will be overwritten.
48
 */
49 3
class {$class} implements MiddlewareInterface
50
{
51
    /**
52
     * Add routing attributes to the server request
53
     */
54
    protected function applyRouting(ServerRequestInterface \$request): ServerRequestInterface
55
    {
56
        \$method = \$request->getMethod();
57
        \$path = \$request->getUri()->getPath();
58
        \$segments = \$path === "/" ? [] : explode("/", trim(\$path, "/"));
59
60 3
{$applyRoutingCode}
61
    }
62
63
    /**
64
     * Process an incoming server request.
65
     */
66
    public function process(ServerRequestInterface \$request, RequestHandlerInterface \$handler): ResponseInterface
67
    {
68
        return \$handler->handle(\$this->applyRouting(\$request));
69
    }
70
}
71 3
CODE;
72
    }
73
74
    /**
75
     * Generate code for an endpoint
76
     *
77
     * @param Endpoint $endpoint
78
     * @return string
79
     */
80 4
    protected function generateEndpoint(Endpoint $endpoint): string
81
    {
82 4
        $exportValue = function ($var): string {
83 3
            return var_export($var, true);
84 4
        };
85 4
        $methods = join(', ', array_map($exportValue, $endpoint->getAllowedMethods()));
86
87 4
        return "\$request = \$request->withAttribute('route:allowed_methods', [{$methods}]);\n"
88 4
            . parent::generateEndpoint($endpoint);
89
    }
90
91
    /**
92
     * Generate routing code for an endpoint.
93
     *
94
     * @throws InvalidRouteException
95
     */
96 4
    protected function generateRoute(string $key, array $route, array $vars): string
97
    {
98 4
        $code = ['return $request'];
99
100 4
        foreach ($route as $k => $v) {
101 4
            $code[] = "    ->withAttribute('route:" . addslashes($k) . "', " . var_export($v, true) . ")";
102
        }
103
104 4
        foreach ($vars as $k => $index) {
105 1
            $code[] = "    ->withAttribute('route:{" . addslashes($k) . "}', \$segments[{$index}])";
106
        }
107
108 4
        $code[array_key_last($code)] .= ';';
109
110 4
        return join("\n", $code);
111
    }
112
113
    /**
114
     * Generate code for when no route matches.
115
     *
116
     * @param Endpoint|null $endpoint
117
     * @return string
118
     * @throws InvalidRouteException
119
     */
120 4
    protected function generateDefault(?Endpoint $endpoint): string
121
    {
122 4
        return $endpoint === null
123 3
            ? 'return $request;'
124 4
            : $this->generateRoute('default', $endpoint->getRoutes()[''], []);
125
    }
126
}
127