Issues (9)

src/Middleware/SubFolder.php (1 issue)

Labels
Severity
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Yii\Web\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\Web\Exception\BadUriPrefixException;
14
15
use function strlen;
16
17
/**
18
 * This middleware supports routing when webroot is not the same folder as public
19
 */
20
final class SubFolder implements MiddlewareInterface
21
{
22
    private UrlGeneratorInterface $uriGenerator;
23
    private Aliases $aliases;
24
    private ?string $prefix;
25
    private ?string $alias;
26
27 12
    public function __construct(
28
        UrlGeneratorInterface $uriGenerator,
29
        Aliases $aliases,
30
        ?string $prefix = null,
31
        ?string $alias = null
32
    ) {
33 12
        $this->uriGenerator = $uriGenerator;
34 12
        $this->aliases = $aliases;
35 12
        $this->prefix = $prefix;
36 12
        $this->alias = $alias;
37 12
    }
38
39 12
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
40
    {
41 12
        $uri = $request->getUri();
42 12
        $path = $uri->getPath();
43 12
        $prefix = $this->prefix;
44 12
        $auto = $prefix === null;
45 12
        $length = $auto ? 0 : strlen($prefix);
46
47 12
        if ($auto) {
48
            // automatically checks that the project is in a subfolder
49
            // and URI contains a prefix
50 7
            $scriptName = $request->getServerParams()['SCRIPT_NAME'];
51 7
            if (strpos($scriptName, '/', 1) !== false) {
52 6
                $tmpPrefix = substr($scriptName, 0, strrpos($scriptName, '/'));
53 6
                if (strpos($path, $tmpPrefix) === 0) {
54 5
                    $prefix = $tmpPrefix;
55 7
                    $length = strlen($prefix);
56
                }
57
            }
58 5
        } elseif ($length > 0) {
59 5
            if ($prefix[-1] === '/') {
60 1
                throw new BadUriPrefixException('Wrong URI prefix value');
61
            }
62 4
            if (strpos($path, $prefix) !== 0) {
63 2
                throw new BadUriPrefixException('URI prefix does not match');
64
            }
65
        }
66
67 9
        if ($length > 0) {
68 7
            $newPath = substr($path, $length);
69 7
            if ($newPath === '') {
70 1
                $newPath = '/';
71
            }
72 7
            if ($newPath[0] !== '/') {
73 2
                if (!$auto) {
74 2
                    throw new BadUriPrefixException('URI prefix does not match completely');
75
                }
76
            } else {
77 5
                $request = $request->withUri($uri->withPath($newPath));
78 5
                $this->uriGenerator->setUriPrefix($prefix);
0 ignored issues
show
It seems like $prefix can also be of type null; however, parameter $name of Yiisoft\Router\UrlGenera...terface::setUriPrefix() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

78
                $this->uriGenerator->setUriPrefix(/** @scrutinizer ignore-type */ $prefix);
Loading history...
79
80 5
                if ($this->alias !== null) {
81 5
                    $this->aliases->set($this->alias, $prefix . '/');
82
                }
83
            }
84
        }
85
86 8
        return $handler->handle($request);
87
    }
88
}
89