Issues (7)

src/Content/ReplaceRelative.php (1 issue)

Labels
Severity
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Enjoys\AssetsCollector\Content;
6
7
use Enjoys\AssetsCollector\Asset;
8
use Enjoys\AssetsCollector\AssetOption;
9
use Enjoys\AssetsCollector\Environment;
10
use Enjoys\UrlConverter;
11
use Exception;
12
use Psr\Log\LoggerInterface;
13
14
use function str_replace;
15
16
17
final class ReplaceRelative
18
{
19
    private LoggerInterface $logger;
20
21 20
    public function __construct(
22
        private readonly string $content,
23 20
        private readonly Asset $asset,
24 20
        private readonly Environment $environment
25 20
    ) {
26 20
        $this->logger = $environment->getLogger();
27 20
    }
28
29
30
    /**
31
     * @throws Exception
32
     */
33
    public function getContent(): string
34
    {
35 20
        $result = preg_replace_callback(
36
            '/(url\([\'"]?)(?!["\'a-z]+:|[\'"]?\/{2})(.+?[^\'"])([\'"]?\))/i',
37 20
            function (array $m) {
38 20
                $normalizedPath = $this->getNormalizedPath($m[2]);
39 20
                if ($normalizedPath === false) {
40 11
                    return $m[1] . $m[2] . $m[3];
41 11
                }
42 4
43
                return $m[1] . $normalizedPath . $m[3];
44
            },
45 10
            $this->content
46 20
        );
47 20
48 20
        $this->logger->info(sprintf('ReplaceRelativeUrls: %s', $this->asset->getPath()));
49
        return $result ?? '';
50 20
    }
51
52
    /**
53
     * @throws Exception
54
     */
55
    private function getNormalizedPath(string $relativePath): false|string
56 20
    {
57 20
        if ($this->asset->isUrl()) {
58
            return $this->replaceUrls($this->asset->getPath(), $relativePath);
59
        }
60
        return $this->replacePath($this->asset->getPath(), $relativePath);
61
    }
62
63 12
64
    private function replaceUrls(string $baseUrl, string $relativeUrl): false|string
65 12
    {
66
        $urlConverter = new UrlConverter();
67
        return $urlConverter->relativeToAbsolute($baseUrl, $relativeUrl);
68
    }
69
70
    /**
71
     * @throws Exception
72
     * @psalm-suppress PossiblyFalseOperand
73 11
     */
74
    private function replacePath(string $filePath, string $relativePath): false|string
75 11
    {
76 3
        $realpath = realpath(
77
            pathinfo($filePath, PATHINFO_DIRNAME) . DIRECTORY_SEPARATOR
0 ignored issues
show
Are you sure pathinfo($filePath, Enjo...ntent\PATHINFO_DIRNAME) of type array|string can be used in concatenation? ( Ignorable by Annotation )

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

77
            /** @scrutinizer ignore-type */ pathinfo($filePath, PATHINFO_DIRNAME) . DIRECTORY_SEPARATOR
Loading history...
78 8
            . (parse_url($relativePath, PHP_URL_PATH) ?? '')
79
        );
80
81
        if ($realpath === false) {
82
            return false;
83
        }
84
85
        $relativeFullPath = str_replace(
86 3
            '\\',
87
            '/',
88 3
            str_replace(
89 3
                [
90
                    $this->environment->getCompileDir(),
91
                    $this->environment->getProjectDir()
92
                ],
93
                '',
94
                $realpath
95
            )
96
        );
97
98 8
        /** @infection-ignore-all */
99
        $this->asset->getOptions()->setOption(
100 8
            AssetOption::SYMLINKS,
101 8
            array_merge(
102 8
                [$this->environment->getCompileDir() . $relativeFullPath => $realpath],
103 8
                $this->asset->getOptions()->getSymlinks()
104
            )
105 8
        );
106 4
107
        return $this->environment->getBaseUrl() . $relativeFullPath;
108
    }
109
}
110