This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
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) |
|
0 ignored issues
–
show
|
|||
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); |
||
203 | return Result::error($this, $message); |
||
204 | } |
||
205 | |||
206 | // Cannot be cross-volume: should always succeed |
||
207 | @rename($dst, $out); |
||
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 |
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.