Test Failed
Pull Request — master (#16)
by Divine Niiquaye
14:00
created

PathMiddleware   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 59
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 24
dl 0
loc 59
ccs 23
cts 23
cp 1
rs 10
c 2
b 0
f 0
wmc 14

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
C process() 0 38 13
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of Flight Routing.
7
 *
8
 * PHP version 7.1 and above required
9
 *
10
 * @author    Divine Niiquaye Ibok <[email protected]>
11
 * @copyright 2019 Biurad Group (https://biurad.com/)
12
 * @license   https://opensource.org/licenses/BSD-3-Clause License
13
 *
14
 * For the full copyright and license information, please view the LICENSE
15
 * file that was distributed with this source code.
16
 */
17
18
namespace Flight\Routing\Middlewares;
19
20
use Flight\Routing\Route;
21
use Psr\Http\Message\ResponseInterface;
22
use Psr\Http\Message\ServerRequestInterface;
23
use Psr\Http\Server\MiddlewareInterface;
24
use Psr\Http\Server\RequestHandlerInterface;
25
26
/**
27
 * Resolves request uri path, route path, and response status.
28
 *
29
 * The response status code is 302 if the permanent parameter is false (default),
30
 * and 301 if the redirection is permanent on redirection.
31
 *
32
 * @author Divine Niiquaye Ibok <[email protected]>
33
 */
34 3
class PathMiddleware implements MiddlewareInterface
35
{
36 3
    /** @var bool */
37 3
    private $permanent;
38
39
    /** @var bool */
40
    private $keepRequestMethod;
41
42 3
    /**
43
     * @param bool $permanent         Whether the redirection is permanent
44 3
     * @param bool $keepRequestMethod Whether redirect action should keep HTTP request method
45 3
     */
46
    public function __construct(bool $permanent = false, bool $keepRequestMethod = false)
47 3
    {
48 3
        $this->permanent = $permanent;
49
        $this->keepRequestMethod = $keepRequestMethod;
50
    }
51 3
52 2
    /**
53 2
     * {@inheritdoc}
54
     */
55
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
56
    {
57 1
        // Supported prefix for uri paths ...
58
        $prefixRegex = '#(?|\\' . \implode('|\\', Route::URL_PREFIX_SLASHES) . ')+$#';
59
60
        $requestUri = $request->getUri();
61
        $response = $handler->handle($request);
62
        $requestPath = \preg_replace($prefixRegex, $requestUri->getPath()[-1], $requestUri->getPath());
63
64
        // Determine the response code should keep HTTP request method ...
65
        $statusCode = $this->keepRequestMethod ? ($this->permanent ? 308 : 307) : ($this->permanent ? 301 : 302);
66
67
        if ($requestUri->getPath() !== $requestPath) {
68
            return $response->withHeader('Location', (string) $requestUri->withPath($requestPath))->withStatus($statusCode);
69 3
        }
70
71
        $route = $request->getAttribute(Route::class);
72 3
73 3
        if ($route instanceof Route) {
74
            $routeEndTail = Route::URL_PREFIX_SLASHES[$route->get('path')[-1]] ?? null;
75 3
            $requestEndTail = Route::URL_PREFIX_SLASHES[$requestPath[-1]] ?? null;
76 3
77 3
            if ($routeEndTail === $requestEndTail) {
78
                return $response;
79
            }
80 3
81 1
            // Resolve request tail end to avoid conflicts and infinite redirection looping ...
82
            if (null === $routeEndTail && null !== $requestEndTail || (isset($routeEndTail, $requestEndTail) && $routeEndTail !== $requestEndTail)) {
0 ignored issues
show
introduced by
Consider adding parentheses for clarity. Current Interpretation: (null === $routeEndTail ...ail !== $requestEndTail, Probably Intended Meaning: null === $routeEndTail &...il !== $requestEndTail)
Loading history...
83
                $requestPath = \substr($requestPath, 0, -1);
84 2
            } elseif (null !== $routeEndTail && null === $requestEndTail) {
85 1
                $requestPath .= $routeEndTail;
86
            }
87
88 1
            // Allow Redirection if exists and avoid static request.
89
            return $response->withAddedHeader('Location', (string) $requestUri->withPath($requestPath))->withStatus($statusCode);
90
        }
91
92
        return $response;
93
    }
94
}
95