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\Exception\TaskException; |
||
7 | use Robo\Task\BaseTask; |
||
8 | use Robo\Task\Base\Exec; |
||
9 | use Symfony\Component\Finder\Finder; |
||
10 | use Symfony\Component\Filesystem\Filesystem as sfFilesystem; |
||
11 | |||
12 | /** |
||
13 | * Minifies images. When the required minifier is not installed on the system |
||
14 | * the task will try to download it from the [imagemin](https://github.com/imagemin) repository. |
||
15 | * |
||
16 | * When the task is run without any specified minifier it will compress the images |
||
17 | * based on the extension. |
||
18 | * |
||
19 | * ```php |
||
20 | * $this->taskImageMinify('assets/images/*') |
||
21 | * ->to('dist/images/') |
||
22 | * ->run(); |
||
23 | * ``` |
||
24 | * |
||
25 | * This will use the following minifiers: |
||
26 | * |
||
27 | * - PNG: optipng |
||
28 | * - GIF: gifsicle |
||
29 | * - JPG, JPEG: jpegtran |
||
30 | * - SVG: svgo |
||
31 | * |
||
32 | * When the minifier is specified the task will use that for all the input files. In that case |
||
33 | * it is useful to filter the files with the extension: |
||
34 | * |
||
35 | * ```php |
||
36 | * $this->taskImageMinify('assets/images/*.png') |
||
37 | * ->to('dist/images/') |
||
38 | * ->minifier('pngcrush'); |
||
39 | * ->run(); |
||
40 | * ``` |
||
41 | * |
||
42 | * The task supports the following minifiers: |
||
43 | * |
||
44 | * - optipng |
||
45 | * - pngquant |
||
46 | * - advpng |
||
47 | * - pngout |
||
48 | * - zopflipng |
||
49 | * - pngcrush |
||
50 | * - gifsicle |
||
51 | * - jpegoptim |
||
52 | * - jpeg-recompress |
||
53 | * - jpegtran |
||
54 | * - svgo (only minification, no downloading) |
||
55 | * |
||
56 | * You can also specifiy extra options for the minifiers: |
||
57 | * |
||
58 | * ```php |
||
59 | * $this->taskImageMinify('assets/images/*.jpg') |
||
60 | * ->to('dist/images/') |
||
61 | * ->minifier('jpegtran', ['-progressive' => null, '-copy' => 'none']) |
||
62 | * ->run(); |
||
63 | * ``` |
||
64 | * |
||
65 | * This will execute as: |
||
66 | * `jpegtran -copy none -progressive -optimize -outfile "dist/images/test.jpg" "/var/www/test/assets/images/test.jpg"` |
||
67 | */ |
||
68 | class ImageMinify extends BaseTask |
||
69 | { |
||
70 | /** |
||
71 | * Destination directory for the minified images. |
||
72 | * |
||
73 | * @var string |
||
74 | */ |
||
75 | protected $to; |
||
76 | |||
77 | /** |
||
78 | * Array of the source files. |
||
79 | * |
||
80 | * @var array |
||
81 | */ |
||
82 | protected $dirs = []; |
||
83 | |||
84 | /** |
||
85 | * Symfony 2 filesystem. |
||
86 | * |
||
87 | * @var sfFilesystem |
||
88 | */ |
||
89 | protected $fs; |
||
90 | |||
91 | /** |
||
92 | * Target directory for the downloaded binary executables. |
||
93 | * |
||
94 | * @var string |
||
95 | */ |
||
96 | protected $executableTargetDir; |
||
97 | |||
98 | /** |
||
99 | * Array for the downloaded binary executables. |
||
100 | * |
||
101 | * @var array |
||
102 | */ |
||
103 | protected $executablePaths = []; |
||
104 | |||
105 | /** |
||
106 | * Array for the individual results of all the files. |
||
107 | * |
||
108 | * @var array |
||
109 | */ |
||
110 | protected $results = []; |
||
111 | |||
112 | /** |
||
113 | * Default minifier to use. |
||
114 | * |
||
115 | * @var string |
||
116 | */ |
||
117 | protected $minifier; |
||
118 | |||
119 | /** |
||
120 | * Array for minifier options. |
||
121 | * |
||
122 | * @var array |
||
123 | */ |
||
124 | protected $minifierOptions = []; |
||
125 | |||
126 | /** |
||
127 | * Supported minifiers. |
||
128 | * |
||
129 | * @var array |
||
130 | */ |
||
131 | protected $minifiers = [ |
||
132 | // Default 4 |
||
133 | 'optipng', |
||
134 | 'gifsicle', |
||
135 | 'jpegtran', |
||
136 | 'svgo', |
||
137 | // PNG |
||
138 | 'pngquant', |
||
139 | 'advpng', |
||
140 | 'pngout', |
||
141 | 'zopflipng', |
||
142 | 'pngcrush', |
||
143 | // JPG |
||
144 | 'jpegoptim', |
||
145 | 'jpeg-recompress', |
||
146 | ]; |
||
147 | |||
148 | /** |
||
149 | * Binary repositories of Imagemin. |
||
150 | * |
||
151 | * @link https://github.com/imagemin |
||
152 | * |
||
153 | * @var string[] |
||
154 | */ |
||
155 | protected $imageminRepos = [ |
||
156 | // PNG |
||
157 | 'optipng' => 'https://github.com/imagemin/optipng-bin', |
||
158 | 'pngquant' => 'https://github.com/imagemin/pngquant-bin', |
||
159 | 'advpng' => 'https://github.com/imagemin/advpng-bin', |
||
160 | 'pngout' => 'https://github.com/imagemin/pngout-bin', |
||
161 | 'zopflipng' => 'https://github.com/imagemin/zopflipng-bin', |
||
162 | 'pngcrush' => 'https://github.com/imagemin/pngcrush-bin', |
||
163 | // Gif |
||
164 | 'gifsicle' => 'https://github.com/imagemin/gifsicle-bin', |
||
165 | // JPG |
||
166 | 'jpegtran' => 'https://github.com/imagemin/jpegtran-bin', |
||
167 | 'jpegoptim' => 'https://github.com/imagemin/jpegoptim-bin', |
||
168 | 'cjpeg' => 'https://github.com/imagemin/mozjpeg-bin', // note: we do not support this minifier because it creates JPG from non-JPG files |
||
169 | 'jpeg-recompress' => 'https://github.com/imagemin/jpeg-recompress-bin', |
||
170 | // WebP |
||
171 | 'cwebp' => 'https://github.com/imagemin/cwebp-bin', // note: we do not support this minifier because it creates WebP from non-WebP files |
||
172 | ]; |
||
173 | |||
174 | /** |
||
175 | * @param string|string[] $dirs |
||
176 | */ |
||
177 | public function __construct($dirs) |
||
178 | { |
||
179 | is_array($dirs) |
||
180 | ? $this->dirs = $dirs |
||
181 | : $this->dirs[] = $dirs; |
||
182 | |||
183 | $this->fs = new sfFilesystem(); |
||
184 | |||
185 | // guess the best path for the executables based on __DIR__ |
||
186 | if (($pos = strpos(__DIR__, 'consolidation/robo')) !== false) { |
||
187 | // the executables should be stored in vendor/bin |
||
188 | $this->executableTargetDir = substr(__DIR__, 0, $pos) . 'bin'; |
||
189 | } |
||
190 | |||
191 | // check if the executables are already available |
||
192 | foreach ($this->imageminRepos as $exec => $url) { |
||
193 | $path = $this->executableTargetDir . '/' . $exec; |
||
194 | // if this is Windows add a .exe extension |
||
195 | if (substr($this->getOS(), 0, 3) == 'win') { |
||
196 | $path .= '.exe'; |
||
197 | } |
||
198 | if (is_file($path)) { |
||
199 | $this->executablePaths[$exec] = $path; |
||
200 | } |
||
201 | } |
||
202 | } |
||
203 | |||
204 | /** |
||
205 | * {@inheritdoc} |
||
206 | */ |
||
207 | public function run() |
||
208 | { |
||
209 | // find the files |
||
210 | $files = $this->findFiles($this->dirs); |
||
211 | |||
212 | // minify the files |
||
213 | $result = $this->minify($files); |
||
214 | // check if there was an error |
||
215 | if ($result instanceof Result) { |
||
216 | return $result; |
||
217 | } |
||
218 | |||
219 | $amount = (count($files) == 1 ? 'image' : 'images'); |
||
220 | $message = "Minified {filecount} out of {filetotal} $amount into {destination}"; |
||
221 | $context = ['filecount' => count($this->results['success']), 'filetotal' => count($files), 'destination' => $this->to]; |
||
222 | |||
223 | if (count($this->results['success']) == count($files)) { |
||
224 | $this->printTaskSuccess($message, $context); |
||
225 | |||
226 | return Result::success($this, $message, $context); |
||
227 | } else { |
||
228 | return Result::error($this, $message, $context); |
||
229 | } |
||
230 | } |
||
231 | |||
232 | /** |
||
233 | * Sets the target directory where the files will be copied to. |
||
234 | * |
||
235 | * @param string $target |
||
236 | * |
||
237 | * @return $this |
||
238 | */ |
||
239 | public function to($target) |
||
240 | { |
||
241 | $this->to = rtrim($target, '/'); |
||
242 | |||
243 | return $this; |
||
244 | } |
||
245 | |||
246 | /** |
||
247 | * Sets the minifier. |
||
248 | * |
||
249 | * @param string $minifier |
||
250 | * @param array $options |
||
251 | * |
||
252 | * @return $this |
||
253 | */ |
||
254 | public function minifier($minifier, array $options = []) |
||
255 | { |
||
256 | $this->minifier = $minifier; |
||
257 | $this->minifierOptions = array_merge($this->minifierOptions, $options); |
||
258 | |||
259 | return $this; |
||
260 | } |
||
261 | |||
262 | /** |
||
263 | * @param string[] $dirs |
||
264 | * |
||
265 | * @return array|\Robo\Result |
||
266 | * |
||
267 | * @throws \Robo\Exception\TaskException |
||
268 | */ |
||
269 | View Code Duplication | protected function findFiles($dirs) |
|
270 | { |
||
271 | $files = array(); |
||
272 | |||
273 | // find the files |
||
274 | foreach ($dirs as $k => $v) { |
||
275 | // reset finder |
||
276 | $finder = new Finder(); |
||
277 | |||
278 | $dir = $k; |
||
279 | $to = $v; |
||
280 | // check if target was given with the to() method instead of key/value pairs |
||
281 | if (is_int($k)) { |
||
282 | $dir = $v; |
||
283 | if (isset($this->to)) { |
||
284 | $to = $this->to; |
||
285 | } else { |
||
286 | throw new TaskException($this, 'target directory is not defined'); |
||
287 | } |
||
288 | } |
||
289 | |||
290 | try { |
||
291 | $finder->files()->in($dir); |
||
292 | } catch (\InvalidArgumentException $e) { |
||
293 | // if finder cannot handle it, try with in()->name() |
||
294 | if (strpos($dir, '/') === false) { |
||
295 | $dir = './' . $dir; |
||
296 | } |
||
297 | $parts = explode('/', $dir); |
||
298 | $new_dir = implode('/', array_slice($parts, 0, -1)); |
||
299 | try { |
||
300 | $finder->files()->in($new_dir)->name(array_pop($parts)); |
||
301 | } catch (\InvalidArgumentException $e) { |
||
302 | return Result::fromException($this, $e); |
||
303 | } |
||
304 | } |
||
305 | |||
306 | foreach ($finder as $file) { |
||
307 | // store the absolute path as key and target as value in the files array |
||
308 | $files[$file->getRealpath()] = $this->getTarget($file->getRealPath(), $to); |
||
309 | } |
||
310 | $fileNoun = count($finder) == 1 ? ' file' : ' files'; |
||
311 | $this->printTaskInfo("Found {filecount} $fileNoun in {dir}", ['filecount' => count($finder), 'dir' => $dir]); |
||
312 | } |
||
313 | |||
314 | return $files; |
||
315 | } |
||
316 | |||
317 | /** |
||
318 | * @param string $file |
||
319 | * @param string $to |
||
320 | * |
||
321 | * @return string |
||
322 | */ |
||
323 | protected function getTarget($file, $to) |
||
324 | { |
||
325 | $target = $to . '/' . basename($file); |
||
326 | |||
327 | return $target; |
||
328 | } |
||
329 | |||
330 | /** |
||
331 | * @param string[] $files |
||
332 | * |
||
333 | * @return \Robo\Result |
||
334 | */ |
||
335 | protected function minify($files) |
||
336 | { |
||
337 | // store the individual results into the results array |
||
338 | $this->results = [ |
||
339 | 'success' => [], |
||
340 | 'error' => [], |
||
341 | ]; |
||
342 | |||
343 | // loop through the files |
||
344 | foreach ($files as $from => $to) { |
||
345 | $minifier = ''; |
||
346 | |||
347 | if (!isset($this->minifier)) { |
||
348 | // check filetype based on the extension |
||
349 | $extension = strtolower(pathinfo($from, PATHINFO_EXTENSION)); |
||
350 | |||
351 | // set the default minifiers based on the extension |
||
352 | switch ($extension) { |
||
353 | case 'png': |
||
354 | $minifier = 'optipng'; |
||
355 | break; |
||
356 | case 'jpg': |
||
357 | case 'jpeg': |
||
358 | $minifier = 'jpegtran'; |
||
359 | break; |
||
360 | case 'gif': |
||
361 | $minifier = 'gifsicle'; |
||
362 | break; |
||
363 | case 'svg': |
||
364 | $minifier = 'svgo'; |
||
365 | break; |
||
366 | } |
||
367 | } else { |
||
368 | View Code Duplication | if (!in_array($this->minifier, $this->minifiers, true) |
|
369 | && !is_callable(strtr($this->minifier, '-', '_')) |
||
370 | ) { |
||
371 | $message = sprintf('Invalid minifier %s!', $this->minifier); |
||
372 | |||
373 | return Result::error($this, $message); |
||
374 | } |
||
375 | $minifier = $this->minifier; |
||
376 | } |
||
377 | |||
378 | // Convert minifier name to camelCase (e.g. jpeg-recompress) |
||
379 | $funcMinifier = $this->camelCase($minifier); |
||
380 | |||
381 | // call the minifier method which prepares the command |
||
382 | if (is_callable($funcMinifier)) { |
||
383 | $command = call_user_func($funcMinifier, $from, $to, $this->minifierOptions); |
||
384 | } elseif (method_exists($this, $funcMinifier)) { |
||
385 | $command = $this->{$funcMinifier}($from, $to); |
||
386 | } else { |
||
387 | $message = sprintf('Minifier method <info>%s</info> cannot be found!', $funcMinifier); |
||
388 | |||
389 | return Result::error($this, $message); |
||
390 | } |
||
391 | |||
392 | // launch the command |
||
393 | $this->printTaskInfo('Minifying {filepath} with {minifier}', ['filepath' => $from, 'minifier' => $minifier]); |
||
394 | $result = $this->executeCommand($command); |
||
395 | |||
396 | // check the return code |
||
397 | if ($result->getExitCode() == 127) { |
||
398 | $this->printTaskError('The {minifier} executable cannot be found', ['minifier' => $minifier]); |
||
399 | // try to install from imagemin repository |
||
400 | if (array_key_exists($minifier, $this->imageminRepos)) { |
||
401 | $result = $this->installFromImagemin($minifier); |
||
402 | if ($result instanceof Result) { |
||
403 | if ($result->wasSuccessful()) { |
||
404 | $this->printTaskSuccess($result->getMessage()); |
||
405 | // retry the conversion with the downloaded executable |
||
406 | if (is_callable($minifier)) { |
||
407 | $command = call_user_func($minifier, $from, $to, $this->minifierOptions); |
||
408 | } elseif (method_exists($this, $minifier)) { |
||
409 | $command = $this->{$minifier}($from, $to); |
||
410 | } |
||
411 | // launch the command |
||
412 | $this->printTaskInfo('Minifying {filepath} with {minifier}', ['filepath' => $from, 'minifier' => $minifier]); |
||
413 | $result = $this->executeCommand($command); |
||
414 | } else { |
||
415 | $this->printTaskError($result->getMessage()); |
||
416 | // the download was not successful |
||
417 | return $result; |
||
418 | } |
||
419 | } |
||
420 | } else { |
||
421 | return $result; |
||
422 | } |
||
423 | } |
||
424 | |||
425 | // check the success of the conversion |
||
426 | if ($result->getExitCode() !== 0) { |
||
427 | $this->results['error'][] = $from; |
||
428 | } else { |
||
429 | $this->results['success'][] = $from; |
||
430 | } |
||
431 | } |
||
432 | } |
||
433 | |||
434 | /** |
||
435 | * @return string |
||
436 | */ |
||
437 | View Code Duplication | protected function getOS() |
|
438 | { |
||
439 | $os = php_uname('s'); |
||
440 | $os .= '/' . php_uname('m'); |
||
441 | // replace x86_64 to x64, because the imagemin repo uses that |
||
442 | $os = str_replace('x86_64', 'x64', $os); |
||
443 | // replace i386, i686, etc to x86, because of imagemin |
||
444 | $os = preg_replace('/i[0-9]86/', 'x86', $os); |
||
445 | // turn info to lowercase, because of imagemin |
||
446 | $os = strtolower($os); |
||
447 | |||
448 | return $os; |
||
449 | } |
||
450 | |||
451 | /** |
||
452 | * @param string $command |
||
453 | * |
||
454 | * @return \Robo\Result |
||
455 | */ |
||
456 | protected function executeCommand($command) |
||
457 | { |
||
458 | // insert the options into the command |
||
459 | $a = explode(' ', $command); |
||
460 | $executable = array_shift($a); |
||
461 | foreach ($this->minifierOptions as $key => $value) { |
||
462 | // first prepend the value |
||
463 | if (!empty($value)) { |
||
464 | array_unshift($a, $value); |
||
465 | } |
||
466 | // then add the key |
||
467 | if (!is_numeric($key)) { |
||
468 | array_unshift($a, $key); |
||
469 | } |
||
470 | } |
||
471 | // check if the executable can be replaced with the downloaded one |
||
472 | if (array_key_exists($executable, $this->executablePaths)) { |
||
473 | $executable = $this->executablePaths[$executable]; |
||
474 | } |
||
475 | array_unshift($a, $executable); |
||
476 | $command = implode(' ', $a); |
||
477 | |||
478 | // execute the command |
||
479 | $exec = new Exec($command); |
||
480 | |||
481 | return $exec->inflect($this)->printed(false)->run(); |
||
0 ignored issues
–
show
|
|||
482 | } |
||
483 | |||
484 | /** |
||
485 | * @param string $executable |
||
486 | * |
||
487 | * @return \Robo\Result |
||
488 | */ |
||
489 | protected function installFromImagemin($executable) |
||
490 | { |
||
491 | // check if there is an url defined for the executable |
||
492 | if (!array_key_exists($executable, $this->imageminRepos)) { |
||
493 | $message = sprintf('The executable %s cannot be found in the defined imagemin repositories', $executable); |
||
494 | |||
495 | return Result::error($this, $message); |
||
496 | } |
||
497 | $this->printTaskInfo('Downloading the {executable} executable from the imagemin repository', ['executable' => $executable]); |
||
498 | |||
499 | $os = $this->getOS(); |
||
500 | $url = $this->imageminRepos[$executable] . '/blob/master/vendor/' . $os . '/' . $executable . '?raw=true'; |
||
501 | if (substr($os, 0, 3) == 'win') { |
||
502 | // if it is win, add a .exe extension |
||
503 | $url = $this->imageminRepos[$executable] . '/blob/master/vendor/' . $os . '/' . $executable . '.exe?raw=true'; |
||
504 | } |
||
505 | $data = @file_get_contents($url, false, null); |
||
506 | if ($data === false) { |
||
507 | // there is something wrong with the url, try it without the version info |
||
508 | $url = preg_replace('/x[68][64]\//', '', $url); |
||
509 | $data = @file_get_contents($url, false, null); |
||
510 | if ($data === false) { |
||
511 | // there is still something wrong with the url if it is win, try with win32 |
||
512 | if (substr($os, 0, 3) == 'win') { |
||
513 | $url = preg_replace('win/', 'win32/', $url); |
||
514 | $data = @file_get_contents($url, false, null); |
||
515 | View Code Duplication | if ($data === false) { |
|
516 | // there is nothing more we can do |
||
517 | $message = sprintf('Could not download the executable <info>%s</info>', $executable); |
||
518 | |||
519 | return Result::error($this, $message); |
||
520 | } |
||
521 | } |
||
522 | // if it is not windows there is nothing we can do |
||
523 | $message = sprintf('Could not download the executable <info>%s</info>', $executable); |
||
524 | |||
525 | return Result::error($this, $message); |
||
526 | } |
||
527 | } |
||
528 | // check if target directory exists |
||
529 | if (!is_dir($this->executableTargetDir)) { |
||
530 | mkdir($this->executableTargetDir); |
||
531 | } |
||
532 | // save the executable into the target dir |
||
533 | $path = $this->executableTargetDir . '/' . $executable; |
||
534 | if (substr($os, 0, 3) == 'win') { |
||
535 | // if it is win, add a .exe extension |
||
536 | $path = $this->executableTargetDir . '/' . $executable . '.exe'; |
||
537 | } |
||
538 | $result = file_put_contents($path, $data); |
||
539 | View Code Duplication | if ($result === false) { |
|
540 | $message = sprintf('Could not copy the executable <info>%s</info> to %s', $executable, $path); |
||
541 | |||
542 | return Result::error($this, $message); |
||
543 | } |
||
544 | // set the binary to executable |
||
545 | chmod($path, 0755); |
||
546 | |||
547 | // if everything successful, store the executable path |
||
548 | $this->executablePaths[$executable] = $this->executableTargetDir . '/' . $executable; |
||
549 | // if it is win, add a .exe extension |
||
550 | if (substr($os, 0, 3) == 'win') { |
||
551 | $this->executablePaths[$executable] .= '.exe'; |
||
552 | } |
||
553 | |||
554 | $message = sprintf('Executable <info>%s</info> successfully downloaded', $executable); |
||
555 | |||
556 | return Result::success($this, $message); |
||
557 | } |
||
558 | |||
559 | /** |
||
560 | * @param string $from |
||
561 | * @param string $to |
||
562 | * |
||
563 | * @return string |
||
564 | */ |
||
565 | protected function optipng($from, $to) |
||
566 | { |
||
567 | $command = sprintf('optipng -quiet -out "%s" -- "%s"', $to, $from); |
||
568 | if ($from != $to && is_file($to)) { |
||
569 | // earlier versions of optipng do not overwrite the target without a backup |
||
570 | // http://sourceforge.net/p/optipng/bugs/37/ |
||
571 | unlink($to); |
||
572 | } |
||
573 | |||
574 | return $command; |
||
575 | } |
||
576 | |||
577 | /** |
||
578 | * @param string $from |
||
579 | * @param string $to |
||
580 | * |
||
581 | * @return string |
||
582 | */ |
||
583 | protected function jpegtran($from, $to) |
||
584 | { |
||
585 | $command = sprintf('jpegtran -optimize -outfile "%s" "%s"', $to, $from); |
||
586 | |||
587 | return $command; |
||
588 | } |
||
589 | |||
590 | /** |
||
591 | * @param string $from |
||
592 | * @param string $to |
||
593 | * |
||
594 | * @return string |
||
595 | */ |
||
596 | protected function gifsicle($from, $to) |
||
597 | { |
||
598 | $command = sprintf('gifsicle -o "%s" "%s"', $to, $from); |
||
599 | |||
600 | return $command; |
||
601 | } |
||
602 | |||
603 | /** |
||
604 | * @param string $from |
||
605 | * @param string $to |
||
606 | * |
||
607 | * @return string |
||
608 | */ |
||
609 | protected function svgo($from, $to) |
||
610 | { |
||
611 | $command = sprintf('svgo "%s" "%s"', $from, $to); |
||
612 | |||
613 | return $command; |
||
614 | } |
||
615 | |||
616 | /** |
||
617 | * @param string $from |
||
618 | * @param string $to |
||
619 | * |
||
620 | * @return string |
||
621 | */ |
||
622 | protected function pngquant($from, $to) |
||
623 | { |
||
624 | $command = sprintf('pngquant --force --output "%s" "%s"', $to, $from); |
||
625 | |||
626 | return $command; |
||
627 | } |
||
628 | |||
629 | /** |
||
630 | * @param string $from |
||
631 | * @param string $to |
||
632 | * |
||
633 | * @return string |
||
634 | */ |
||
635 | protected function advpng($from, $to) |
||
636 | { |
||
637 | // advpng does not have any output parameters, copy the file and then compress the copy |
||
638 | $command = sprintf('advpng --recompress --quiet "%s"', $to); |
||
639 | $this->fs->copy($from, $to, true); |
||
640 | |||
641 | return $command; |
||
642 | } |
||
643 | |||
644 | /** |
||
645 | * @param string $from |
||
646 | * @param string $to |
||
647 | * |
||
648 | * @return string |
||
649 | */ |
||
650 | protected function pngout($from, $to) |
||
651 | { |
||
652 | $command = sprintf('pngout -y -q "%s" "%s"', $from, $to); |
||
653 | |||
654 | return $command; |
||
655 | } |
||
656 | |||
657 | /** |
||
658 | * @param string $from |
||
659 | * @param string $to |
||
660 | * |
||
661 | * @return string |
||
662 | */ |
||
663 | protected function zopflipng($from, $to) |
||
664 | { |
||
665 | $command = sprintf('zopflipng -y "%s" "%s"', $from, $to); |
||
666 | |||
667 | return $command; |
||
668 | } |
||
669 | |||
670 | /** |
||
671 | * @param string $from |
||
672 | * @param string $to |
||
673 | * |
||
674 | * @return string |
||
675 | */ |
||
676 | protected function pngcrush($from, $to) |
||
677 | { |
||
678 | $command = sprintf('pngcrush -q -ow "%s" "%s"', $from, $to); |
||
679 | |||
680 | return $command; |
||
681 | } |
||
682 | |||
683 | /** |
||
684 | * @param string $from |
||
685 | * @param string $to |
||
686 | * |
||
687 | * @return string |
||
688 | */ |
||
689 | protected function jpegoptim($from, $to) |
||
690 | { |
||
691 | // jpegoptim only takes the destination directory as an argument |
||
692 | $command = sprintf('jpegoptim --quiet -o --dest "%s" "%s"', dirname($to), $from); |
||
693 | |||
694 | return $command; |
||
695 | } |
||
696 | |||
697 | /** |
||
698 | * @param string $from |
||
699 | * @param string $to |
||
700 | * |
||
701 | * @return string |
||
702 | */ |
||
703 | protected function jpegRecompress($from, $to) |
||
704 | { |
||
705 | $command = sprintf('jpeg-recompress --quiet "%s" "%s"', $from, $to); |
||
706 | |||
707 | return $command; |
||
708 | } |
||
709 | |||
710 | /** |
||
711 | * @param string $text |
||
712 | * |
||
713 | * @return string |
||
714 | */ |
||
715 | public static function camelCase($text) |
||
716 | { |
||
717 | // non-alpha and non-numeric characters become spaces |
||
718 | $text = preg_replace('/[^a-z0-9]+/i', ' ', $text); |
||
719 | $text = trim($text); |
||
720 | // uppercase the first character of each word |
||
721 | $text = ucwords($text); |
||
722 | $text = str_replace(" ", "", $text); |
||
723 | $text = lcfirst($text); |
||
724 | |||
725 | return $text; |
||
726 | } |
||
727 | } |
||
728 |
This method has been deprecated.