-
Notifications
You must be signed in to change notification settings - Fork 379
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1219 from franmomu/feature-refactor-post-processor
[Post-Processors] Add timeout option, refactor processors, add tests for all, add/remove/deprecate options
- Loading branch information
Showing
22 changed files
with
1,488 additions
and
263 deletions.
There are no files selected for viewing
50 changes: 50 additions & 0 deletions
50
Exception/Imagine/Filter/PostProcessor/InvalidOptionException.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the `liip/LiipImagineBundle` project. | ||
* | ||
* (c) https://github.com/liip/LiipImagineBundle/graphs/contributors | ||
* | ||
* For the full copyright and license information, please view the LICENSE.md | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Liip\ImagineBundle\Exception\Imagine\Filter\PostProcessor; | ||
|
||
use Liip\ImagineBundle\Exception\ExceptionInterface; | ||
|
||
class InvalidOptionException extends \RuntimeException implements ExceptionInterface | ||
{ | ||
public function __construct(string $message, array $options = []) | ||
{ | ||
parent::__construct(sprintf('Invalid post-processor configuration provided (%s) with options %s.', | ||
$message, $this->stringifyOptions($options))); | ||
} | ||
|
||
private function stringifyOptions(array $options = []): string | ||
{ | ||
if (0 === count($options)) { | ||
return '[]'; | ||
} | ||
|
||
$options = array_map([$this, 'stringifyOptionValue'], $options); | ||
|
||
array_walk($options, function (&$o, $name) { | ||
$o = sprintf('%s="%s"', $name, $o); | ||
}); | ||
|
||
return sprintf('[%s]', implode(', ', $options)); | ||
} | ||
|
||
/** | ||
* @param mixed $value | ||
*/ | ||
private function stringifyOptionValue($value): string | ||
{ | ||
if (is_scalar($value)) { | ||
return $value; | ||
} | ||
|
||
return json_encode($value); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the `liip/LiipImagineBundle` project. | ||
* | ||
* (c) https://github.com/liip/LiipImagineBundle/graphs/contributors | ||
* | ||
* For the full copyright and license information, please view the LICENSE.md | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Liip\ImagineBundle\Imagine\Filter\PostProcessor; | ||
|
||
use Liip\ImagineBundle\Binary\BinaryInterface; | ||
use Liip\ImagineBundle\Binary\FileBinaryInterface; | ||
use Symfony\Component\Filesystem\Exception\IOException; | ||
use Symfony\Component\Filesystem\Filesystem; | ||
use Symfony\Component\Process\Process; | ||
|
||
abstract class AbstractPostProcessor implements PostProcessorInterface | ||
{ | ||
/** | ||
* @var string | ||
*/ | ||
protected $executablePath; | ||
|
||
/** | ||
* @var string|null | ||
*/ | ||
protected $temporaryRootPath; | ||
|
||
/** | ||
* @var Filesystem | ||
*/ | ||
private $filesystem; | ||
|
||
public function __construct(string $executablePath, string $temporaryRootPath = null) | ||
{ | ||
$this->executablePath = $executablePath; | ||
$this->temporaryRootPath = $temporaryRootPath; | ||
$this->filesystem = new Filesystem(); | ||
} | ||
|
||
protected function createProcess(array $arguments = [], array $options = []): Process | ||
{ | ||
$process = new Process($arguments); | ||
|
||
if (!isset($options['process'])) { | ||
return $process; | ||
} | ||
|
||
if (isset($options['process']['timeout'])) { | ||
$process->setTimeout($options['process']['timeout']); | ||
} | ||
|
||
if (isset($options['process']['working_directory'])) { | ||
$process->setWorkingDirectory($options['process']['working_directory']); | ||
} | ||
|
||
if (isset($options['process']['environment_variables']) && is_array($options['process']['environment_variables'])) { | ||
$process->setEnv($options['process']['environment_variables']); | ||
} | ||
|
||
return $process; | ||
} | ||
|
||
protected function isBinaryTypeJpgImage(BinaryInterface $binary): bool | ||
{ | ||
return $this->isBinaryTypeMatch($binary, ['image/jpeg', 'image/jpg']); | ||
} | ||
|
||
protected function isBinaryTypePngImage(BinaryInterface $binary): bool | ||
{ | ||
return $this->isBinaryTypeMatch($binary, ['image/png']); | ||
} | ||
|
||
protected function isBinaryTypeMatch(BinaryInterface $binary, array $types): bool | ||
{ | ||
return in_array($binary->getMimeType(), $types, true); | ||
} | ||
|
||
protected function writeTemporaryFile(BinaryInterface $binary, array $options = [], string $prefix = null): string | ||
{ | ||
$temporary = $this->acquireTemporaryFilePath($options, $prefix); | ||
|
||
if ($binary instanceof FileBinaryInterface) { | ||
$this->filesystem->copy($binary->getPath(), $temporary, true); | ||
} else { | ||
$this->filesystem->dumpFile($temporary, $binary->getContent()); | ||
} | ||
|
||
return $temporary; | ||
} | ||
|
||
protected function acquireTemporaryFilePath(array $options, string $prefix = null): string | ||
{ | ||
$root = $options['temp_dir'] ?? $this->temporaryRootPath ?: sys_get_temp_dir(); | ||
|
||
if (!is_dir($root)) { | ||
try { | ||
$this->filesystem->mkdir($root); | ||
} catch (IOException $exception) { | ||
// ignore failure as "tempnam" function will revert back to system default tmp path as last resort | ||
} | ||
} | ||
|
||
if (false === $file = @tempnam($root, $prefix ?: 'post-processor')) { | ||
throw new \RuntimeException(sprintf('Temporary file cannot be created in "%s"', $root)); | ||
} | ||
|
||
return $file; | ||
} | ||
|
||
/** | ||
* @param int[] $validReturns | ||
* @param string[] $errors | ||
*/ | ||
protected function isSuccessfulProcess(Process $process, array $validReturns = [0], array $errors = ['ERROR']): bool | ||
{ | ||
if (count($validReturns) > 0 && !in_array($process->getExitCode(), $validReturns, true)) { | ||
return false; | ||
} | ||
|
||
foreach ($errors as $string) { | ||
if (false !== strpos($process->getOutput(), $string)) { | ||
return false; | ||
} | ||
} | ||
|
||
return true; | ||
} | ||
|
||
protected function triggerSetterMethodDeprecation(string $method): void | ||
{ | ||
@trigger_error(sprintf('The %s() method was deprecated in 2.2 and will be removed in 3.0. You must ' | ||
.'setup the class state via its __construct() method. You can still pass filter-specific options to the '. | ||
'process() method to overwrite behavior.', $method), E_USER_DEPRECATED); | ||
} | ||
} |
Oops, something went wrong.