Passed
Pull Request — master (#36)
by Rustam
12:29
created

SubFolder::process()   B

Complexity

Conditions 10
Paths 24

Size

Total Lines 37
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 11.1743

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 10
eloc 21
c 2
b 0
f 0
nc 24
nop 2
dl 0
loc 37
ccs 17
cts 22
cp 0.7727
crap 11.1743
rs 7.6666

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Yii\Middleware;
6
7
use Psr\Http\Message\ResponseInterface;
8
use Psr\Http\Message\ServerRequestInterface;
9
use Psr\Http\Server\MiddlewareInterface;
10
use Psr\Http\Server\RequestHandlerInterface;
11
use Yiisoft\Aliases\Aliases;
12
use Yiisoft\Router\UrlGeneratorInterface;
13
use Yiisoft\Yii\Middleware\Exception\BadUriPrefixException;
14
15
use function basename;
16
use function dirname;
17
use function rtrim;
18
use function str_replace;
19
use function str_starts_with;
20
use function strlen;
21
use function strpos;
22
use function substr;
23
24
/**
25
 * This middleware supports routing when webroot is not the same folder as public.
26
 */
27
final class SubFolder implements MiddlewareInterface
28
{
29
    /**
30
     * @param UrlGeneratorInterface $uriGenerator The URI generator instance.
31
     * @param Aliases $aliases The aliases instance.
32
     * @param string|null $prefix URI prefix the specified immediately after the domain part.
33
     * The prefix value usually begins with a slash and must not end with a slash.
34
     * @param string|null $baseUrlAlias The base url alias {@see Aliases::get()}. Default "@baseUrl".
35
     */
36 7
    public function __construct(
37
        private UrlGeneratorInterface $uriGenerator,
38
        private Aliases $aliases,
39
        private ?string $prefix = null,
40
        private ?string $baseUrlAlias = '@baseUrl',
41
    ) {
42 7
    }
43
44
    /**
45
     * @inheritDoc
46
     */
47 7
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
48
    {
49 7
        $uri = $request->getUri();
50 7
        $path = $uri->getPath();
51 7
        $baseUrl = $this->prefix ?? $this->getBaseUrl($request);
52 7
        $length = strlen($baseUrl);
53
54 7
        if ($this->prefix !== null) {
55
            if ($baseUrl[-1] === '/') {
56
                throw new BadUriPrefixException('Wrong URI prefix value.');
57
            }
58
59
            if (!str_starts_with($path, $baseUrl)) {
60
                throw new BadUriPrefixException('URI prefix does not match.');
61
            }
62
        }
63
64 7
        if ($length > 0) {
65 6
            $newPath = substr($path, $length);
66
67 6
            if ($newPath === '') {
68 1
                $newPath = '/';
69
            }
70
71 6
            if ($newPath[0] === '/') {
72 4
                $request = $request->withUri($uri->withPath($newPath));
73 2
            } elseif ($this->prefix !== null) {
74
                throw new BadUriPrefixException('URI prefix does not match completely.');
75
            }
76
77 6
            $this->uriGenerator->setUriPrefix($baseUrl);
78 6
            if ($this->baseUrlAlias !== null && $this->prefix === null) {
79 6
                $this->aliases->set($this->baseUrlAlias, $baseUrl);
80
            }
81
        }
82
83 7
        return $handler->handle($request);
84
    }
85
86 7
    public function getBaseUrl(ServerRequestInterface $request): string
87
    {
88 7
        $serverParams = $request->getServerParams();
89 7
        $scriptUrl = $serverParams['SCRIPT_FILENAME'];
90 7
        $scriptName = basename($scriptUrl);
91
92 7
        if (isset($serverParams['PHP_SELF']) && basename($serverParams['PHP_SELF']) === $scriptName) {
93
            $scriptUrl = $serverParams['PHP_SELF'];
94
        } elseif (
95 7
            isset($serverParams['ORIG_SCRIPT_NAME']) &&
96 7
            basename($serverParams['ORIG_SCRIPT_NAME']) === $scriptName
97
        ) {
98
            $scriptUrl = $serverParams['ORIG_SCRIPT_NAME'];
99
        } elseif (
100 7
            isset($serverParams['PHP_SELF']) &&
101 7
            ($pos = strpos($serverParams['PHP_SELF'], '/' . $scriptName)) !== false
102
        ) {
103
            $scriptUrl = substr($serverParams['PHP_SELF'], 0, $pos) . '/' . $scriptName;
104
        } elseif (
105 7
            !empty($serverParams['DOCUMENT_ROOT']) &&
106 7
            str_starts_with($scriptUrl, $serverParams['DOCUMENT_ROOT'])
107
        ) {
108
            $scriptUrl = str_replace([$serverParams['DOCUMENT_ROOT'], '\\'], ['', '/'], $scriptUrl);
109
        }
110
111 7
        return rtrim(dirname($scriptUrl), '\\/');
112
    }
113
}
114