Passed
Pull Request — master (#15)
by Enjoys
02:34
created

ReplaceRelative::getContent()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 23
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 3.0987

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 14
c 1
b 0
f 0
nc 2
nop 0
dl 0
loc 23
ccs 14
cts 18
cp 0.7778
crap 3.0987
rs 9.7998
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 Psr\Log\LoggerInterface;
12
13
class ReplaceRelative
14
{
15
    private string $content;
16
    private LoggerInterface $logger;
17
    private Asset $asset;
18
    private Environment $environment;
19
    private string $path;
20
21 14
    public function __construct(string $content, string $path, Asset $asset, Environment $environment)
22
    {
23 14
        $this->content = $content;
24 14
        $this->asset = $asset;
25 14
        $this->environment = $environment;
26 14
        $this->path = $path;
27 14
        $this->logger = $environment->getLogger();
28
    }
29
30
31
    /**
32
     * @return string
33
     * @throws \Exception
34
     */
35 14
    public function getContent(): string
36
    {
37 14
        $result = preg_replace_callback(
38 14
            '/(url\([\'"]?)(?!["\'a-z]+:|[\'"]?\/{2})(.+?[^\'"])([\'"]?\))/i',
39 14
            function (array $m) {
40 10
                $normalizedPath = $this->getNormalizedPath($m[2]);
41 10
                if ($normalizedPath === false) {
42 3
                    return $m[1] . $m[2] . $m[3];
43
                }
44
45 9
                return $m[1] . $normalizedPath . $m[3];
46 14
            },
47 14
            $this->content
48 14
        );
49
50 14
        if ($result === null) {
51
            $this->logger->notice(
52
                sprintf('Regex return null value. Returned empty string: %s', $this->path)
53
            );
54
            return '';
55
        }
56 14
        $this->logger->info(sprintf('ReplaceRelativeUrls: %s', $this->path));
57 14
        return $result;
58
    }
59
60
    /**
61
     * @param LoggerInterface $logger
62
     */
63 6
    public function setLogger(LoggerInterface $logger): void
64
    {
65 6
        $this->logger = $logger;
66
    }
67
68
    /**
69
     * @param string $relativePath
70
     * @return false|string
71
     * @throws \Exception
72
     */
73 10
    private function getNormalizedPath(string $relativePath)
74
    {
75 10
        if ($this->asset->isUrl()) {
76 3
            return $this->replaceUrls($this->path, $relativePath);
77
        }
78 7
        return $this->replacePath($this->path, $relativePath);
79
    }
80
81
    /**
82
     * @param string $baseUrl
83
     * @param string $relativeUrl
84
     * @return false|string
85
     */
86 3
    private function replaceUrls(string $baseUrl, string $relativeUrl)
87
    {
88 3
        $urlConverter = new UrlConverter();
89 3
        return $urlConverter->relativeToAbsolute($baseUrl, $relativeUrl);
90
    }
91
92
    /**
93
     * @param string $filePath
94
     * @param string $relativePath
95
     * @return false|string
96
     * @throws \Exception
97
     */
98 7
    private function replacePath(string $filePath, string $relativePath)
99
    {
100 7
        $realpath = realpath(
101 7
            pathinfo($filePath, PATHINFO_DIRNAME) . DIRECTORY_SEPARATOR
0 ignored issues
show
Bug introduced by
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

101
            /** @scrutinizer ignore-type */ pathinfo($filePath, PATHINFO_DIRNAME) . DIRECTORY_SEPARATOR
Loading history...
102 7
            . parse_url($relativePath, PHP_URL_PATH)
103 7
        );
104
105 7
        if ($realpath === false) {
106 3
            return false;
107
        }
108
109 6
        $relativeFullPath = \str_replace(
110 6
            '\\',
111 6
            '/',
112 6
            \str_replace(
113 6
                [
114 6
                    $this->environment->getCompileDir(),
115 6
                    $this->environment->getProjectDir()
116 6
                ],
117 6
                '',
118 6
                $realpath
119 6
            )
120 6
        );
121
122 6
        $this->asset->getOptions()->setOption(
123 6
            AssetOption::SYMLINKS,
124 6
            array_merge(
125 6
                [$this->environment->getCompileDir() . $relativeFullPath => $realpath],
126 6
                $this->asset->getOptions()->getSymlinks()
127 6
            )
128 6
        );
129
130 6
        return $this->environment->getBaseUrl() . $relativeFullPath;
131
    }
132
}
133