These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace Robo\Task\Assets; |
||
4 | |||
5 | use Robo\Result; |
||
6 | use Robo\Task\BaseTask; |
||
7 | |||
8 | abstract class CssPreprocessor extends BaseTask |
||
9 | { |
||
10 | const FORMAT_NAME = ''; |
||
11 | |||
12 | /** |
||
13 | * Default compiler to use. |
||
14 | * |
||
15 | * @var string |
||
16 | */ |
||
17 | protected $compiler; |
||
18 | |||
19 | /** |
||
20 | * Available compilers list |
||
21 | * |
||
22 | * @var string[] |
||
23 | */ |
||
24 | protected $compilers = []; |
||
25 | |||
26 | /** |
||
27 | * Compiler options. |
||
28 | * |
||
29 | * @var array |
||
30 | */ |
||
31 | protected $compilerOptions = []; |
||
32 | |||
33 | /** |
||
34 | * @var array |
||
35 | */ |
||
36 | protected $files = []; |
||
37 | |||
38 | /** |
||
39 | * Constructor. Accepts array of file paths. |
||
40 | * |
||
41 | * @param array $input |
||
42 | */ |
||
43 | public function __construct(array $input) |
||
44 | { |
||
45 | $this->files = $input; |
||
46 | |||
47 | $this->setDefaultCompiler(); |
||
48 | } |
||
49 | |||
50 | protected function setDefaultCompiler() |
||
51 | { |
||
52 | if (isset($this->compilers[0])) { |
||
53 | //set first compiler as default |
||
54 | $this->compiler = $this->compilers[0]; |
||
55 | } |
||
56 | } |
||
57 | |||
58 | /** |
||
59 | * Sets import directories |
||
60 | * Alias for setImportPaths |
||
61 | * @see CssPreprocessor::setImportPaths |
||
62 | * |
||
63 | * @param array|string $dirs |
||
64 | * |
||
65 | * @return $this |
||
66 | */ |
||
67 | public function importDir($dirs) |
||
68 | { |
||
69 | return $this->setImportPaths($dirs); |
||
70 | } |
||
71 | |||
72 | /** |
||
73 | * Adds import directory |
||
74 | * |
||
75 | * @param string $dir |
||
76 | * |
||
77 | * @return $this |
||
78 | */ |
||
79 | public function addImportPath($dir) |
||
80 | { |
||
81 | if (!isset($this->compilerOptions['importDirs'])) { |
||
82 | $this->compilerOptions['importDirs'] = []; |
||
83 | } |
||
84 | |||
85 | if (!in_array($dir, $this->compilerOptions['importDirs'], true)) { |
||
86 | $this->compilerOptions['importDirs'][] = $dir; |
||
87 | } |
||
88 | |||
89 | return $this; |
||
90 | } |
||
91 | |||
92 | /** |
||
93 | * Sets import directories |
||
94 | * |
||
95 | * @param array|string $dirs |
||
96 | * |
||
97 | * @return $this |
||
98 | */ |
||
99 | public function setImportPaths($dirs) |
||
100 | { |
||
101 | if (!is_array($dirs)) { |
||
102 | $dirs = [$dirs]; |
||
103 | } |
||
104 | |||
105 | $this->compilerOptions['importDirs'] = $dirs; |
||
106 | |||
107 | return $this; |
||
108 | } |
||
109 | |||
110 | /** |
||
111 | * @param string $formatterName |
||
112 | * |
||
113 | * @return $this |
||
114 | */ |
||
115 | public function setFormatter($formatterName) |
||
116 | { |
||
117 | $this->compilerOptions['formatter'] = $formatterName; |
||
118 | |||
119 | return $this; |
||
120 | } |
||
121 | |||
122 | /** |
||
123 | * Sets the compiler. |
||
124 | * |
||
125 | * @param string $compiler |
||
126 | * @param array $options |
||
127 | * |
||
128 | * @return $this |
||
129 | */ |
||
130 | public function compiler($compiler, array $options = []) |
||
131 | { |
||
132 | $this->compiler = $compiler; |
||
133 | $this->compilerOptions = array_merge($this->compilerOptions, $options); |
||
134 | |||
135 | return $this; |
||
136 | } |
||
137 | |||
138 | /** |
||
139 | * Compiles file |
||
140 | * |
||
141 | * @param $file |
||
142 | * |
||
143 | * @return bool|mixed |
||
144 | */ |
||
145 | protected function compile($file) |
||
146 | { |
||
147 | if (is_callable($this->compiler)) { |
||
148 | return call_user_func($this->compiler, $file, $this->compilerOptions); |
||
149 | } |
||
150 | |||
151 | if (method_exists($this, $this->compiler)) { |
||
152 | return $this->{$this->compiler}($file); |
||
153 | } |
||
154 | |||
155 | return false; |
||
156 | } |
||
157 | |||
158 | /** |
||
159 | * {@inheritdoc} |
||
160 | */ |
||
161 | public function run() |
||
162 | { |
||
163 | View Code Duplication | if (!in_array($this->compiler, $this->compilers, true) |
|
164 | && !is_callable($this->compiler) |
||
165 | ) { |
||
166 | $message = sprintf('Invalid ' . static::FORMAT_NAME . ' compiler %s!', $this->compiler); |
||
167 | |||
168 | return Result::error($this, $message); |
||
169 | } |
||
170 | |||
171 | foreach ($this->files as $in => $out) { |
||
172 | if (!file_exists($in)) { |
||
173 | $message = sprintf('File %s not found.', $in); |
||
174 | |||
175 | return Result::error($this, $message); |
||
176 | } |
||
177 | if (file_exists($out) && !is_writable($out)) { |
||
178 | return Result::error($this, 'Destination already exists and cannot be overwritten.'); |
||
179 | } |
||
180 | } |
||
181 | |||
182 | foreach ($this->files as $in => $out) { |
||
183 | $css = $this->compile($in); |
||
184 | |||
185 | if ($css instanceof Result) { |
||
186 | return $css; |
||
187 | } elseif (false === $css) { |
||
188 | $message = sprintf( |
||
189 | ucfirst(static::FORMAT_NAME) . ' compilation failed for %s.', |
||
190 | $in |
||
191 | ); |
||
192 | |||
193 | return Result::error($this, $message); |
||
194 | } |
||
195 | |||
196 | $dst = $out . '.part'; |
||
197 | $write_result = file_put_contents($dst, $css); |
||
198 | |||
199 | if (false === $write_result) { |
||
200 | $message = sprintf('File write failed: %s', $out); |
||
201 | |||
202 | @unlink($dst); |
||
0 ignored issues
–
show
|
|||
203 | return Result::error($this, $message); |
||
204 | } |
||
205 | |||
206 | // Cannot be cross-volume: should always succeed |
||
207 | @rename($dst, $out); |
||
0 ignored issues
–
show
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
|
|||
208 | |||
209 | $this->printTaskSuccess('Wrote CSS to {filename}', ['filename' => $out]); |
||
210 | } |
||
211 | |||
212 | return Result::success($this, 'All ' . static::FORMAT_NAME . ' files compiled.'); |
||
213 | } |
||
214 | } |
||
215 |
If you suppress an error, we recommend checking for the error condition explicitly: