Passed
Push — master ( 6ed31c...3efa89 )
by Enjoys
08:45
created

ReplaceRelative::getContent()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 25
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 3.0884

Importance

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

110
            /** @scrutinizer ignore-type */ pathinfo($filePath, PATHINFO_DIRNAME) . DIRECTORY_SEPARATOR
Loading history...
111 6
            . parse_url($relativePath, PHP_URL_PATH)
112
        );
113
114 6
        if ($realpath === false) {
115 2
            return false;
116
        }
117
118 5
        $relativeFullPath = \str_replace(
119
            '\\',
120
            '/',
121 5
            \str_replace(
122
                [
123 5
                    $this->environment->getCompileDir(),
124 5
                    $this->environment->getProjectDir()
125
                ],
126
                '',
127
                $realpath
128
            )
129
        );
130
131 5
        Helpers::createSymlink($this->environment->getCompileDir() . $relativeFullPath, $realpath, $this->logger);
132
133 5
        return $this->environment->getBaseUrl() . $relativeFullPath;
134
    }
135
}
136