Completed
Push — master ( d01bcd...578ad1 )
by Revin
04:37
created

CSS::process()   C

Complexity

Conditions 12
Paths 9

Size

Total Lines 72
Code Lines 42

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 47
CRAP Score 12.0097

Importance

Changes 0
Metric Value
dl 0
loc 72
ccs 47
cts 49
cp 0.9592
rs 5.519
c 0
b 0
f 0
cc 12
eloc 42
nc 9
nop 1
crap 12.0097

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * CSS.php
4
 * @author Revin Roman
5
 * @link https://rmrevin.com
6
 */
7
8
namespace rmrevin\yii\minify\components;
9
10
use tubalmartin\CssMin\Minifier as CSSmin;
11
use yii\helpers\Html;
12
13
/**
14
 * Class CSS
15
 * @package rmrevin\yii\minify\components
16
 */
17
class CSS extends MinifyComponent
18
{
19
20 8
    public function export()
21
    {
22 8
        $cssFiles = $this->view->cssFiles;
23
24 8
        $this->view->cssFiles = [];
25
26 8
        $toMinify = [];
27
28 8 View Code Duplication
        if (!empty($cssFiles)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
29 7
            foreach ($cssFiles as $file => $html) {
30 7
                if ($this->thisFileNeedMinify($file, $html)) {
31 7
                    if ($this->view->concatCss) {
32 7
                        $toMinify[$file] = $html;
33 7
                    } else {
34
                        $this->process([$file => $html]);
35
                    }
36 7
                } else {
37 2
                    if (!empty($toMinify)) {
38 2
                        $this->process($toMinify);
39
40 2
                        $toMinify = [];
41 2
                    }
42
43 2
                    $this->view->cssFiles[$file] = $html;
44
                }
45 7
            }
46 7
        }
47
48 8
        if (!empty($toMinify)) {
49 5
            $this->process($toMinify);
50 5
        }
51
52 8
        unset($toMinify);
53 8
    }
54
55
    /**
56
     * @param array $files
57
     */
58 7
    protected function process(array $files)
59
    {
60 7
        $resultFile = $this->view->minifyPath . DIRECTORY_SEPARATOR . $this->_getSummaryFilesHash($files) . '.css';
61
62 7
        if (!file_exists($resultFile)) {
63 7
            $css = '';
64
65 7
            foreach ($files as $file => $html) {
66 7
                $path = dirname($file);
67 7
                $file = $this->getAbsoluteFilePath($file);
68
69 7
                $content = '';
70
71 7
                if (!file_exists($file)) {
72
                    \Yii::warning(sprintf('Asset file not found `%s`', $file), __METHOD__);
73 7
                } elseif (!is_readable($file)) {
74
                    \Yii::warning(sprintf('Asset file not readable `%s`', $file), __METHOD__);
75 1
                } else {
76 7
                    $content = file_get_contents($file);
77
                }
78
79 7
                $result = [];
80
81 7
                preg_match_all('|url\(([^)]+)\)|is', $content, $m);
82 7
                if (!empty($m[0])) {
83 7
                    foreach ($m[0] as $k => $v) {
84 7
                        if (in_array(strpos($m[1][$k], 'data:'), [0, 1], true)) {
85 7
                            continue;
86
                        }
87
88 7
                        $url = str_replace(['\'', '"'], '', $m[1][$k]);
89
90 7
                        if ($this->isUrl($url)) {
91 7
                            $result[$m[1][$k]] = $url;
92 7
                        } else {
93 7
                            $result[$m[1][$k]] = $path . '/' . $url;
94
                        }
95 7
                    }
96
97 7
                    $content = strtr($content, $result);
98 7
                }
99
100 7
                $css .= $content;
101 7
            }
102
103 7
            $this->expandImports($css);
104
105 7
            $this->removeCssComments($css);
106
107 7
            if ($this->view->minifyCss) {
108 7
                $css = (new CSSmin())
109 7
                    ->run($css, $this->view->cssLinebreakPos);
110 7
            }
111
112 7
            $charsets = false !== $this->view->forceCharset
113 7
                ? ('@charset "' . (string)$this->view->forceCharset . '";' . "\n")
114 7
                : $this->collectCharsets($css);
115
116 7
            $imports = $this->collectImports($css);
117 7
            $fonts = $this->collectFonts($css);
118
119 7
            file_put_contents($resultFile, $charsets . $imports . $fonts . $css);
120
121 7
            if (false !== $this->view->fileMode) {
122 7
                @chmod($resultFile, $this->view->fileMode);
123 7
            }
124 7
        }
125
126 7
        $file = $this->prepareResultFile($resultFile);
127
128 7
        $this->view->cssFiles[$file] = Html::cssFile($file);
129 7
    }
130
131
    /**
132
     * @param string $code
133
     */
134 7
    protected function removeCssComments(&$code)
135
    {
136 7
        if (true === $this->view->removeComments) {
137 7
            $code = preg_replace('#/\*(?:[^*]*(?:\*(?!/))*)*\*/#', '', $code);
138 7
        }
139 7
    }
140
141
    /**
142
     * @param string $code
143
     */
144 7
    protected function expandImports(&$code)
145
    {
146 7
        if (true === $this->view->expandImports) {
147 7
            preg_match_all('|\@import\s([^;]+);|is', str_replace('&amp;', '&', $code), $m);
148
149 7
            if (!empty($m[0])) {
150 7
                foreach ($m[0] as $k => $v) {
151 7
                    $import_url = $m[1][$k];
152
153 7
                    if (!empty($import_url)) {
154 7
                        $import_content = $this->_getImportContent($import_url);
155
156 7
                        if (!empty($import_content)) {
157 7
                            $code = str_replace($m[0][$k], $import_content, $code);
158 7
                        }
159 7
                    }
160 7
                }
161 7
            }
162 7
        }
163 7
    }
164
165
    /**
166
     * @param string $code
167
     * @return string
168
     */
169
    protected function collectCharsets(&$code)
170
    {
171
        return $this->_collect($code, '|\@charset[^;]+|is', function ($string) {
172
            return $string . ';';
173
        });
174
    }
175
176
    /**
177
     * @param string $code
178
     * @return string
179
     */
180 7
    protected function collectImports(&$code)
181
    {
182
        return $this->_collect($code, '|\@import[^;]+|is', function ($string) {
183
            return $string . ';';
184 7
        });
185
    }
186
187
    /**
188
     * @param string $code
189
     * @return string
190
     */
191
    protected function collectFonts(&$code)
192
    {
193 7
        return $this->_collect($code, '|\@font-face\{[^}]+\}|is', function ($string) {
194 7
            return $string;
195 7
        });
196
    }
197
198
    /**
199
     * @param string $code
200
     * @param string $pattern
201
     * @param callable $handler
202
     * @return string
203
     */
204 7
    protected function _collect(&$code, $pattern, $handler)
205
    {
206 7
        $result = '';
207
208 7
        preg_match_all($pattern, $code, $m);
209
210 7
        foreach ($m[0] as $string) {
211 7
            $string = $handler($string);
212 7
            $code = str_replace($string, '', $code);
213
214 7
            $result .= $string . PHP_EOL;
215 7
        }
216
217 7
        return $result;
218
    }
219
220
    /**
221
     * @param string $url
222
     * @return null|string
223
     */
224 7
    protected function _getImportContent($url)
225
    {
226 7
        $result = null;
227
228 7
        if ('url(' === mb_substr($url, 0, 4)) {
229 7
            $url = str_replace(['url(\'', 'url("', 'url(', '\')', '")', ')'], '', $url);
230
231 7
            if (mb_substr($url, 0, 2) === '//') {
232 7
                $url = preg_replace('|^//|', 'http://', $url, 1);
233 7
            }
234
235 7
            if (!empty($url)) {
236 7
                if (!in_array(mb_substr($url, 0, 4), ['http', 'ftp:'], true)) {
237 7
                    $url = \Yii::getAlias($this->view->basePath . $url);
238 7
                }
239
240
                $context = [
241
                    'ssl' => [
242 7
                        'verify_peer'      => false,
243 7
                        'verify_peer_name' => false,
244 7
                    ],
245 7
                ];
246
247 7
                $result = file_get_contents($url, null, stream_context_create($context));
248 7
            }
249 7
        }
250
251 7
        return $result;
252
    }
253
}
254