Passed
Push — master ( 59589b...c79df9 )
by Enjoys
05:41 queued 03:11
created

Reader::readWithPhpFileGetContents()   A

Complexity

Conditions 3
Paths 5

Size

Total Lines 15
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 10
c 0
b 0
f 0
nc 5
nop 1
dl 0
loc 15
ccs 10
cts 10
cp 1
crap 3
rs 9.9332
1
<?php
2
3
namespace Enjoys\AssetsCollector\Content;
4
5
use Enjoys\AssetsCollector\Asset;
6
use Enjoys\AssetsCollector\Content\Minify\MinifyFactory;
7
use Enjoys\AssetsCollector\Environment;
8
use Psr\Http\Client\ClientInterface;
9
use Psr\Http\Message\RequestFactoryInterface;
10
use Psr\Log\LoggerInterface;
11
use Psr\Log\NullLogger;
12
13
/**
14
 * Class Reader
15
 * @package Enjoys\AssetsCollector\Content
16
 */
17
class Reader
18
{
19
    /**
20
     * @var Asset
21
     */
22
    private Asset $asset;
23
24
    /**
25
     * @var false|string
26
     */
27
    private $content;
28
    /**
29
     * @var false|string
30
     */
31
    private $path;
32
33
    private Environment $environment;
34
    /**
35
     * @var LoggerInterface|NullLogger
36
     */
37
    private LoggerInterface $logger;
38
39
    /**
40
     * Reader constructor.
41
     * @param Asset $asset
42
     * @param Environment $environment
43
     * @param LoggerInterface|null $logger
44
     */
45 13
    public function __construct(
46
        Asset $asset,
47
        Environment $environment,
48
        LoggerInterface $logger = null
49
    ) {
50 13
        $this->environment = $environment;
51 13
        $this->asset = $asset;
52 13
        $this->logger = $logger ?? $this->environment->getLogger();
53 13
        $this->path = $this->asset->getPath();
54 13
        $this->content = $this->getContent();
55
    }
56
57
    /**
58
     * @throws \Exception
59
     */
60 13
    public function getContents(): string
61
    {
62 13
        if ($this->content === false || $this->path === false) {
63 4
            $this->logger->notice(sprintf('Nothing return: path is `%s`', $this->asset->getOrigPath()));
64 4
            return '';
65
        }
66
67 9
        if ($this->asset->getOptions()->isReplaceRelativeUrls()) {
68 6
            $replaceRelativeUrls = new ReplaceRelative($this->content, $this->path, $this->asset, $this->environment);
0 ignored issues
show
Bug introduced by
It seems like $this->content can also be of type true; however, parameter $content of Enjoys\AssetsCollector\C...Relative::__construct() 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

68
            $replaceRelativeUrls = new ReplaceRelative(/** @scrutinizer ignore-type */ $this->content, $this->path, $this->asset, $this->environment);
Loading history...
Bug introduced by
It seems like $this->path can also be of type true; however, parameter $path of Enjoys\AssetsCollector\C...Relative::__construct() 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

68
            $replaceRelativeUrls = new ReplaceRelative($this->content, /** @scrutinizer ignore-type */ $this->path, $this->asset, $this->environment);
Loading history...
69 6
            $replaceRelativeUrls->setLogger($this->logger);
70 6
            $this->content = $replaceRelativeUrls->getContent();
71
        }
72
73 9
        if ($this->asset->getOptions()->isMinify()) {
74 4
            $this->content = MinifyFactory::minify(
75 4
                    $this->content,
0 ignored issues
show
Bug introduced by
It seems like $this->content can also be of type true; however, parameter $content of Enjoys\AssetsCollector\C...MinifyFactory::minify() 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

75
                    /** @scrutinizer ignore-type */ $this->content,
Loading history...
76 4
                    $this->asset->getType(),
77 4
                    $this->environment
78 4
                )->getContent() . "\n";
79 4
            $this->logger->info(sprintf('Minify: %s', $this->path));
0 ignored issues
show
Bug introduced by
It seems like $this->path can also be of type true; however, parameter $values of sprintf() does only seem to accept double|integer|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

79
            $this->logger->info(sprintf('Minify: %s', /** @scrutinizer ignore-type */ $this->path));
Loading history...
80
        }
81 9
        return $this->content;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->content could return the type true which is incompatible with the type-hinted return string. Consider adding an additional type-check to rule them out.
Loading history...
82
    }
83
84
85
    /**
86
     * @return false|string
87
     */
88 13
    private function getContent()
89
    {
90 13
        if ($this->path === false) {
91 1
            return false;
92
        }
93
94 12
        if ($this->asset->isUrl()) {
95 4
            return $this->readUrl($this->path);
0 ignored issues
show
Bug introduced by
It seems like $this->path can also be of type true; however, parameter $url of Enjoys\AssetsCollector\Content\Reader::readUrl() 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

95
            return $this->readUrl(/** @scrutinizer ignore-type */ $this->path);
Loading history...
96
        }
97 8
        return $this->readFile($this->path);
0 ignored issues
show
Bug introduced by
It seems like $this->path can also be of type true; however, parameter $filename of Enjoys\AssetsCollector\Content\Reader::readFile() 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

97
        return $this->readFile(/** @scrutinizer ignore-type */ $this->path);
Loading history...
98
    }
99
100
    /**
101
     * @return false|string
102
     */
103 4
    private function readUrl(string $url)
104
    {
105
        if (
106 4
            null !== ($httpClient = $this->environment->getHttpClient())
107 4
            && null !== ($requestFactory = $this->environment->getRequestFactory())
108
        ) {
109 2
            return $this->readWithPsrHttpClient($url, $httpClient, $requestFactory);
110
        }
111
112 2
        return $this->readWithPhpFileGetContents($url);
113
    }
114
115
    /**
116
     * @return false|string
117
     * @throws \RuntimeException
118
     */
119 10
    private function readWithPhpFileGetContents(string $url)
120
    {
121
        try {
122
            //Clear the most recent error
123 10
            error_clear_last();
124 10
            $content = @file_get_contents($url);
125
            /** @var null|string[] $error */
126 10
            $error = error_get_last();
127 10
            if ($error !== null) {
128 2
                throw new \RuntimeException(sprintf("%s", $error['message']));
129
            }
130 8
            return $content;
131 2
        } catch (\Throwable $e) {
132 2
            $this->logger->notice($e->getMessage());
133 2
            return false;
134
        }
135
    }
136
137
    /**
138
     * @return false|string
139
     */
140 2
    private function readWithPsrHttpClient(
141
        string $url,
142
        ClientInterface $client,
143
        RequestFactoryInterface $requestFactory
144
    ) {
145
        try {
146 2
            $response = $client->sendRequest(
147 2
                $requestFactory->createRequest('get', $url)
148 2
            );
149
150 2
            if ($response->getStatusCode() !== 200) {
151 1
                throw new \RuntimeException(
152 1
                    sprintf('HTTP error: %s - %s', $response->getStatusCode(), $response->getReasonPhrase())
153 1
                );
154
            }
155
156 1
            $this->logger->info(sprintf('Read: %s', $url));
157 1
            return $response->getBody()->getContents();
158 1
        } catch (\Throwable $e) {
159 1
            $this->logger->notice($e->getMessage());
160 1
            return false;
161
        }
162
    }
163
164
    /**
165
     * @param string $filename
166
     * @return false|string
167
     */
168 8
    private function readFile(string $filename)
169
    {
170 8
        if (!file_exists($filename)) {
171
            $this->logger->notice(sprintf("Файла по указанному пути нет: %s", $filename));
172
            return false;
173
        }
174
175
        try {
176 8
            $content = $this->readWithPhpFileGetContents($filename);
177
        } catch (\RuntimeException $e) {
178
            $this->logger->notice(sprintf("Ошибка чтения содержимого файла: %s", $e->getMessage()));
179
            return false;
180
        }
181
182 8
        $this->logger->info(sprintf('Read: %s', $filename));
183 8
        return $content;
184
    }
185
186
    /**
187
     * @param LoggerInterface|NullLogger $logger
188
     */
189
    public function setLogger($logger): void
190
    {
191
        $this->logger = $logger;
192
    }
193
}
194