UriRedirectMiddleware   A
last analyzed

Complexity

Total Complexity 9

Size/Duplication

Total Lines 41
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 16
c 2
b 0
f 0
dl 0
loc 41
ccs 17
cts 17
cp 1
rs 10
wmc 9

2 Methods

Rating   Name   Duplication   Size   Complexity  
B process() 0 25 8
A __construct() 0 4 1
1
<?php declare(strict_types=1);
2
3
/*
4
 * This file is part of Flight Routing.
5
 *
6
 * PHP version 8.0 and above required
7
 *
8
 * @author    Divine Niiquaye Ibok <[email protected]>
9
 * @copyright 2019 Divine Niiquaye Ibok (https://divinenii.com/)
10
 * @license   https://opensource.org/licenses/BSD-3-Clause License
11
 *
12
 * For the full copyright and license information, please view the LICENSE
13
 * file that was distributed with this source code.
14
 */
15
16
namespace Flight\Routing\Middlewares;
17
18
use Flight\Routing\Handlers\RouteHandler;
19
use Psr\Http\Message\{ResponseInterface, ServerRequestInterface, UriInterface};
20
use Psr\Http\Server\{MiddlewareInterface, RequestHandlerInterface};
21
22
/**
23
 * The importance of this middleware is to slowly migrate users from old routes
24
 * to new route paths, with or without maintaining route attributes.
25
 *
26
 * Eg:
27
 * 1. Redirect from `/users/\d+` to `/account`
28
 * 2. Redirect from `/sign-up` tp `/register`
29
 * 3. Redirect from `/admin-page` to `#/admin`. The `#` before means, all existing slashes and/or queries are maintained.
30
 *
31
 * NB: Old route paths as treated as regex otherwise actual path redirecting to new paths.
32
 *
33
 * @author Divine Niiquaye Ibok <[email protected]>
34
 */
35
class UriRedirectMiddleware implements MiddlewareInterface
36
{
37
    /**
38
     * @param array<string,string|UriInterface> $redirects         [from previous => to new]
39
     * @param bool                              $keepRequestMethod Whether redirect action should keep HTTP request method
40
     */
41 13
    public function __construct(protected array $redirects = [], private bool $keepRequestMethod = false)
42
    {
43 13
        $this->redirects = $redirects;
44 13
        $this->keepRequestMethod = $keepRequestMethod;
45
    }
46
47
    /**
48
     * Process a request and return a response.
49
     * {@inheritdoc}
50
     */
51 13
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
52
    {
53 13
        $requestPath = ($uri = $request->getUri())->getPath();
54
55 13
        if ('' === $redirectedUri = (string) ($this->redirects[$requestPath] ?? '')) {
56 5
            foreach ($this->redirects as $oldPath => $newPath) {
57 5
                if (1 === \preg_match('#^'.$oldPath.'$#u', $requestPath)) {
58 1
                    $redirectedUri = $newPath;
59
60 1
                    break;
61
                }
62
            }
63
64 5
            if (empty($redirectedUri)) {
65 4
                return $handler->handle($request);
66
            }
67
        }
68
69 9
        if (\is_string($redirectedUri) && '#' === $redirectedUri[0]) {
70 1
            $redirectedUri = $uri->withPath(\substr($redirectedUri, 1));
71
        }
72
73 9
        return $handler->handle($request->withAttribute(RouteHandler::OVERRIDE_NULL_ROUTE, true))
74 9
            ->withStatus($this->keepRequestMethod ? 308 : 301)
75 9
            ->withHeader('Location', (string) $redirectedUri)
76
        ;
77
    }
78
}
79