Passed
Pull Request — master (#36)
by Rustam
02:59
created

SubFolder::process()   A

Complexity

Conditions 6
Paths 10

Size

Total Lines 24
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 6
eloc 14
c 1
b 0
f 0
nc 10
nop 2
dl 0
loc 24
ccs 15
cts 15
cp 1
crap 6
rs 9.2222
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
14
use function basename;
15
use function dirname;
16
use function rtrim;
17
use function str_replace;
18
use function str_starts_with;
19
use function strlen;
20
use function strpos;
21
use function substr;
22
23
/**
24
 * This middleware supports routing when webroot is not the same folder as public.
25
 */
26
final class SubFolder implements MiddlewareInterface
27
{
28
    /**
29
     * @param UrlGeneratorInterface $uriGenerator The URI generator instance.
30
     * @param Aliases $aliases The aliases instance.
31
     * @param string $baseUrlAlias The base url alias {@see Aliases::get()}. Default "@baseUrl".
32
     */
33 7
    public function __construct(
34
        private UrlGeneratorInterface $uriGenerator,
35
        private Aliases $aliases,
36
        private string $baseUrlAlias = '@baseUrl',
37
    ) {
38 7
    }
39
40
    /**
41
     * @inheritDoc
42
     */
43 7
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
44
    {
45 7
        $uri = $request->getUri();
46 7
        $path = $uri->getPath();
47 7
        $baseUrl = $this->getBaseUrl($request);
48 7
        $length = strlen($baseUrl);
49
50 7
        if ($length > 0 && str_starts_with($path, $baseUrl)) {
51 5
            $newPath = substr($path, $length);
52
53 5
            if ($newPath === '') {
54 1
                $newPath = '/';
55
            }
56 5
            if ($newPath[0] === '/') {
57 4
                $request = $request->withUri($uri->withPath($newPath));
58
            }
59
        }
60
61 7
        if ($length !== 0) {
62 6
            $this->uriGenerator->setUriPrefix($baseUrl);
63 6
            $this->aliases->set($this->baseUrlAlias, $baseUrl);
64
        }
65
66 7
        return $handler->handle($request);
67
    }
68
69 7
    public function getBaseUrl(ServerRequestInterface $request): string
70
    {
71 7
        $serverParams = $request->getServerParams();
72 7
        $scriptUrl = $serverParams['SCRIPT_FILENAME'];
73 7
        $scriptName = basename($scriptUrl);
74
75 7
        if (isset($serverParams['PHP_SELF']) && basename($serverParams['PHP_SELF']) === $scriptName) {
76
            $scriptUrl = $serverParams['PHP_SELF'];
77
        } elseif (
78 7
            isset($serverParams['ORIG_SCRIPT_NAME']) &&
79 7
            basename($serverParams['ORIG_SCRIPT_NAME']) === $scriptName
80
        ) {
81
            $scriptUrl = $serverParams['ORIG_SCRIPT_NAME'];
82
        } elseif (
83 7
            isset($serverParams['PHP_SELF']) &&
84 7
            ($pos = strpos($serverParams['PHP_SELF'], '/' . $scriptName)) !== false
85
        ) {
86
            $scriptUrl = substr($serverParams['PHP_SELF'], 0, $pos) . '/' . $scriptName;
87
        } elseif (
88 7
            !empty($serverParams['DOCUMENT_ROOT']) &&
89 7
            str_starts_with($scriptUrl, $serverParams['DOCUMENT_ROOT'])
90
        ) {
91
            $scriptUrl = str_replace([$serverParams['DOCUMENT_ROOT'], '\\'], ['', '/'], $scriptUrl);
92
        }
93
94 7
        return rtrim(dirname($scriptUrl), '\\/');
95
    }
96
}
97