diff --git a/imagemagick.api.php b/imagemagick.api.php index 01f2799..51478cb 100644 --- a/imagemagick.api.php +++ b/imagemagick.api.php @@ -19,7 +19,7 @@ * file system to allow processing. * * @param \Drupal\imagemagick\ImagemagickExecArguments $arguments - * The ImageMagick execution arguments object. + * The ImageMagick/GraphicsMagick execution arguments object. * * @see \Drupal\imagemagick\Plugin\ImageToolkit\ImagemagickToolkit::parseFile() * @see \Drupal\imagemagick\ImagemagickExecArguments::getSource() @@ -37,11 +37,11 @@ function hook_imagemagick_pre_parse_file_alter(\Drupal\imagemagick\ImagemagickEx * systems. * * @param \Drupal\imagemagick\ImagemagickExecArguments $arguments - * The ImageMagick execution arguments object. + * The ImageMagick/GraphicsMagick execution arguments object. * + * @see \Drupal\imagemagick\Plugin\ImageToolkit\ImagemagickToolkit::save() * @see \Drupal\imagemagick\ImagemagickExecArguments::getDestination() * @see \Drupal\imagemagick\ImagemagickExecArguments::getDestinationLocalPath() - * @see \Drupal\imagemagick\Plugin\ImageToolkit\ImagemagickToolkit::save() */ function hook_imagemagick_post_save_alter(\Drupal\imagemagick\ImagemagickExecArguments $arguments) { } @@ -63,30 +63,23 @@ function hook_imagemagick_post_save_alter(\Drupal\imagemagick\ImagemagickExecArg * ImageMagick automatically converts the target image to the format denoted by * the file extension. However, since changing the file extension is not always * an option, you can specify an alternative image format via - * $toolkit->setDestinationFormat('format'), where 'format' is a string - * denoting an Imagemagick supported format. + * $arguments->setDestinationFormat('format'), where 'format' is a string + * denoting an Imagemagick supported format, or via + * $arguments->setDestinationFormatFromExtension('extension'), where + * 'extension' is a string denoting an image file extension. + * * When the destination format is set, it is passed to ImageMagick's convert * binary with the syntax "[format]:[destination]". * * @param \Drupal\imagemagick\ImagemagickExecArguments $arguments - * The ImageMagick execution arguments object. + * The ImageMagick/GraphicsMagick execution arguments object. * @param string $command - * The ImageMagick binary being called. + * The ImageMagick/GraphicsMagick command being called. * * @see http://www.imagemagick.org/script/command-line-processing.php#output * @see http://www.imagemagick.org/Usage/files/#save * - * @see \Drupal\imagemagick\ImagemagickExecArguments::add() - * @see \Drupal\imagemagick\ImagemagickExecArguments::find() - * @see \Drupal\imagemagick\ImagemagickExecArguments::remove() - * @see \Drupal\imagemagick\ImagemagickExecArguments::reset() - * @see \Drupal\imagemagick\ImagemagickExecArguments::getSource() - * @see \Drupal\imagemagick\ImagemagickExecArguments::setSourceLocalPath() - * @see \Drupal\imagemagick\ImagemagickExecArguments::getSourceLocalPath() - * @see \Drupal\imagemagick\ImagemagickExecArguments::getDestination() - * @see \Drupal\imagemagick\ImagemagickExecArguments::setDestinationLocalPath() - * @see \Drupal\imagemagick\ImagemagickExecArguments::getDestinationLocalPath() - * @see \Drupal\imagemagick\Plugin\ImageToolkit\ImagemagickToolkit::arguments() + * @see \Drupal\imagemagick\ImagemagickExecArguments * @see \Drupal\imagemagick\Plugin\ImageToolkit\ImagemagickToolkit::convert() * @see \Drupal\imagemagick\Plugin\FileMetadata\ImagemagickIdentify::identify() */ diff --git a/imagemagick.services.yml b/imagemagick.services.yml index 5a42754..87e2e3f 100644 --- a/imagemagick.services.yml +++ b/imagemagick.services.yml @@ -4,7 +4,7 @@ services: arguments: ['@cache.default', '@imagemagick.mime_type_mapper', '@config.factory', '@config.typed'] imagemagick.exec_manager: class: Drupal\imagemagick\ImagemagickExecManager - arguments: ['@logger.channel.image', '@config.factory', '@app.root', '@current_user'] + arguments: ['@logger.channel.image', '@config.factory', '@app.root', '@current_user', '@imagemagick.format_mapper', '@module_handler'] imagemagick.mime_type_mapper: class: Drupal\imagemagick\ImagemagickMimeTypeMapper arguments: ['@file.mime_type.guesser.extension'] diff --git a/src/ImagemagickExecArguments.php b/src/ImagemagickExecArguments.php index 21542c2..ade3074 100644 --- a/src/ImagemagickExecArguments.php +++ b/src/ImagemagickExecArguments.php @@ -463,7 +463,20 @@ class ImagemagickExecArguments { * @return $this */ public function setSourceFormat($format) { - $this->sourceFormat = $format; + $this->sourceFormat = $this->execManager->getFormatMapper()->isFormatEnabled($format) ? $format : ''; + return $this; + } + + /** + * Sets the source image format from an image file extension. + * + * @param string $extension + * The image file extension. + * + * @return $this + */ + public function setSourceFormatFromExtension($extension) { + $this->sourceFormat = $this->execManager->getFormatMapper()->getFormatFromExtension($extension) ?: ''; return $this; } @@ -591,6 +604,23 @@ class ImagemagickExecArguments { } /** + * Sets the image destination format from an image file extension. + * + * When set, it is passed to the convert binary in the syntax + * "[format]:[destination]", where [format] is a string denoting an + * ImageMagick's image format. + * + * @param string $extension + * The destination image file extension. + * + * @return $this + */ + public function setDestinationFormatFromExtension($extension) { + $this->destinationFormat = $this->execManager->getFormatMapper()->getFormatFromExtension($extension) ?: ''; + return $this; + } + + /** * Gets the image destination format. * * When set, it is passed to the convert binary in the syntax diff --git a/src/ImagemagickExecManager.php b/src/ImagemagickExecManager.php index 4d93975..7439506 100644 --- a/src/ImagemagickExecManager.php +++ b/src/ImagemagickExecManager.php @@ -4,6 +4,7 @@ namespace Drupal\imagemagick; use Drupal\Component\Utility\Timer; use Drupal\Core\Config\ConfigFactoryInterface; +use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Session\AccountProxyInterface; use Drupal\Core\StringTranslation\StringTranslationTrait; use Psr\Log\LoggerInterface; @@ -59,6 +60,20 @@ class ImagemagickExecManager implements ImagemagickExecManagerInterface { protected $configFactory; /** + * The module handler service. + * + * @var \Drupal\Core\Extension\ModuleHandlerInterface + */ + protected $moduleHandler; + + /** + * The format mapper service. + * + * @var \Drupal\imagemagick\ImagemagickFormatMapperInterface + */ + protected $formatMapper; + + /** * Constructs an ImagemagickExecManager object. * * @param \Psr\Log\LoggerInterface $logger @@ -69,16 +84,46 @@ class ImagemagickExecManager implements ImagemagickExecManagerInterface { * The app root. * @param \Drupal\Core\Session\AccountProxyInterface $current_user * The current user. + * @param \Drupal\imagemagick\ImagemagickFormatMapperInterface $format_mapper + * The format mapper service. + * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler + * The module handler service. */ - public function __construct(LoggerInterface $logger, ConfigFactoryInterface $config_factory, $app_root, AccountProxyInterface $current_user) { + public function __construct(LoggerInterface $logger, ConfigFactoryInterface $config_factory, $app_root, AccountProxyInterface $current_user, ImagemagickFormatMapperInterface $format_mapper, ModuleHandlerInterface $module_handler) { $this->logger = $logger; $this->configFactory = $config_factory; $this->appRoot = $app_root; $this->currentUser = $current_user; + $this->formatMapper = $format_mapper; + $this->moduleHandler = $module_handler; $this->isWindows = substr(PHP_OS, 0, 3) === 'WIN'; } /** + * Returns the format mapper. + * + * @return \Drupal\imagemagick\ImagemagickFormatMapperInterface + * The format mapper service. + * + * @todo in 8.x-3.0, add this method to the interface. + */ + public function getFormatMapper() { + return $this->formatMapper; + } + + /** + * Returns the module handler. + * + * @return \Drupal\Core\Extension\ModuleHandlerInterface + * The module handler service. + * + * @todo in 8.x-3.0, add this method to the interface. + */ + public function getModuleHandler() { + return $this->moduleHandler; + } + + /** * Sets the execution timeout (max. runtime). * * To disable the timeout, set this value to null. diff --git a/src/Plugin/ImageToolkit/ImagemagickToolkit.php b/src/Plugin/ImageToolkit/ImagemagickToolkit.php index 0d31e39..53de471 100644 --- a/src/Plugin/ImageToolkit/ImagemagickToolkit.php +++ b/src/Plugin/ImageToolkit/ImagemagickToolkit.php @@ -187,13 +187,13 @@ class ImagemagickToolkit extends ImageToolkitBase { '#group' => 'imagemagick_settings', ]; $options = [ - 'imagemagick' => $this->getPackageLabel('imagemagick'), - 'graphicsmagick' => $this->getPackageLabel('graphicsmagick'), + 'imagemagick' => $this->getExecManager()->getPackageLabel('imagemagick'), + 'graphicsmagick' => $this->getExecManager()->getPackageLabel('graphicsmagick'), ]; $form['suite']['binaries'] = [ '#type' => 'radios', '#title' => $this->t('Suite'), - '#default_value' => $this->getPackage(), + '#default_value' => $this->getExecManager()->getPackage(), '#options' => $options, '#required' => TRUE, '#description' => $this->t("Select the graphics package to use."), @@ -207,7 +207,7 @@ class ImagemagickToolkit extends ImageToolkitBase { '#description' => $this->t('If needed, the path to the package executables (convert, identify, gm, etc.), including the trailing slash/backslash. For example: /usr/bin/ or C:\Program Files\ImageMagick-6.3.4-Q16\.'), ]; // Version information. - $status = $this->execManager->checkPath($config->get('path_to_binaries')); + $status = $this->getExecManager()->checkPath($config->get('path_to_binaries')); if (empty($status['errors'])) { $version_info = explode("\n", preg_replace('/\r/', '', Html::escape($status['output']))); } @@ -235,7 +235,7 @@ class ImagemagickToolkit extends ImageToolkitBase { '#description' => $this->t("@suite formats: %formats
Image file extensions: %extensions", [ '%formats' => implode(', ', $this->formatMapper->getEnabledFormats()), '%extensions' => Unicode::strtolower(implode(', ', static::getSupportedExtensions())), - '@suite' => $this->getPackageLabel(), + '@suite' => $this->getExecManager()->getPackageLabel(), ]), ]; // Image formats map. @@ -255,7 +255,7 @@ class ImagemagickToolkit extends ImageToolkitBase { if (empty($status['errors'])) { $this->arguments()->add('-list format', ImagemagickExecArguments::PRE_SOURCE); $output = NULL; - $this->execManager->execute('convert', $this->arguments(), $output); + $this->getExecManager()->execute('convert', $this->arguments(), $output); $this->arguments()->reset(); $formats_info = implode('
', explode("\n", preg_replace('/\r/', '', Html::escape($output)))); $form['formats']['list'] = [ @@ -263,7 +263,7 @@ class ImagemagickToolkit extends ImageToolkitBase { '#collapsible' => TRUE, '#open' => FALSE, '#title' => $this->t('Format list'), - '#description' => $this->t("Supported image formats returned by executing 'convert -list format'. Note: these are the formats supported by the installed @suite executable, not by the toolkit.

", ['@suite' => $this->getPackageLabel()]), + '#description' => $this->t("Supported image formats returned by executing 'convert -list format'. Note: these are the formats supported by the installed @suite executable, not by the toolkit.

", ['@suite' => $this->getExecManager()->getPackageLabel()]), ]; $form['formats']['list']['list'] = [ '#markup' => "
" . $formats_info . "
", @@ -334,7 +334,7 @@ class ImagemagickToolkit extends ImageToolkitBase { '#description' => $this->t("The locale to be used to prepare the command passed to executables. The default, 'en_US.UTF-8', should work in most cases. If that is not available on the server, enter another locale. 'Installed Locales' below provides a list of locales installed on the server."), ]; // Installed locales. - $locales = $this->execManager->getInstalledLocales(); + $locales = $this->getExecManager()->getInstalledLocales(); $locales_info = implode('
', explode("\n", preg_replace('/\r/', '', Html::escape($locales)))); $form['exec']['installed_locales'] = [ '#type' => 'details', @@ -412,6 +412,16 @@ class ImagemagickToolkit extends ImageToolkitBase { } /** + * Returns the ImageMagick execution manager service. + * + * @return \Drupal\imagemagick\ImagemagickExecManagerInterface + * The ImageMagick execution manager service. + */ + public function getExecManager() { + return $this->execManager; + } + + /** * Gets the binaries package in use. * * @param string $package @@ -420,9 +430,15 @@ class ImagemagickToolkit extends ImageToolkitBase { * @return string * The default package ('imagemagick'|'graphicsmagick'), or the $package * argument. + * + * @deprecated in 8.x-2.3, will be removed in 8.x-3.0. Use + * ImagemagickExecManagerInterface::getPackage() instead. + * + * @see https://www.drupal.org/project/imagemagick/issues/2938375 */ public function getPackage($package = NULL) { - return $this->execManager->getPackage($package); + @trigger_error('getPackage() is deprecated in 8.x-2.3, will be removed in 8.x-3.0. Use ImagemagickExecManagerInterface::getPackage() instead. See https://www.drupal.org/project/imagemagick/issues/2938375.', E_USER_DEPRECATED); + return $this->getExecManager()->getPackage($package); } /** @@ -434,9 +450,15 @@ class ImagemagickToolkit extends ImageToolkitBase { * @return string * A translated label of the binaries package in use, or the $package * argument. + * + * @deprecated in 8.x-2.3, will be removed in 8.x-3.0. Use + * ImagemagickExecManagerInterface::getPackageLabel() instead. + * + * @see https://www.drupal.org/project/imagemagick/issues/2938375 */ public function getPackageLabel($package = NULL) { - return $this->execManager->getPackageLabel($package); + @trigger_error('getPackageLabel() is deprecated in 8.x-2.3, will be removed in 8.x-3.0. Use ImagemagickExecManagerInterface::getPackageLabel() instead. See https://www.drupal.org/project/imagemagick/issues/2938375.', E_USER_DEPRECATED); + return $this->getExecManager()->getPackageLabel($package); } /** @@ -452,9 +474,15 @@ class ImagemagickToolkit extends ImageToolkitBase { * - output: The shell output of 'convert -version', if any. * - errors: A list of error messages indicating if the executable could * not be found or executed. + * + * @deprecated in 8.x-2.3, will be removed in 8.x-3.0. Use + * ImagemagickExecManagerInterface::checkPath() instead. + * + * @see https://www.drupal.org/project/imagemagick/issues/2938375 */ public function checkPath($path, $package = NULL) { - return $this->execManager->checkPath($path, $package); + @trigger_error('checkPath() is deprecated in 8.x-2.3, will be removed in 8.x-3.0. Use ImagemagickExecManagerInterface::checkPath() instead. See https://www.drupal.org/project/imagemagick/issues/2938375.', E_USER_DEPRECATED); + return $this->getExecManager()->checkPath($path, $package); } /** @@ -480,7 +508,7 @@ class ImagemagickToolkit extends ImageToolkitBase { // it will prevent the entire image toolkit selection form from being // submitted. if ($form_state->getValue(['image_toolkit']) === 'imagemagick') { - $status = $this->execManager->checkPath($form_state->getValue([ + $status = $this->getExecManager()->checkPath($form_state->getValue([ 'imagemagick', 'suite', 'path_to_binaries', ]), $form_state->getValue(['imagemagick', 'suite', 'binaries'])); if ($status['errors']) { @@ -549,7 +577,7 @@ class ImagemagickToolkit extends ImageToolkitBase { */ public function setSource($source) { parent::setSource($source); - $this->arguments->setSource($source); + $this->arguments()->setSource($source); return $this; } @@ -557,7 +585,7 @@ class ImagemagickToolkit extends ImageToolkitBase { * {@inheritdoc} */ public function getSource() { - return $this->arguments->getSource(); + return $this->arguments()->getSource(); } /** @@ -565,16 +593,32 @@ class ImagemagickToolkit extends ImageToolkitBase { * * @return string * A filesystem path. + * + * @deprecated in 8.x-2.3, will be removed in 8.x-3.0. Use + * ::ensureSourceLocalPath() instead. + * + * @see https://www.drupal.org/project/imagemagick/issues/2938375 */ public function getSourceLocalPath() { + @trigger_error('getSourceLocalPath() is deprecated in 8.x-2.3, will be removed in 8.x-3.0. Use ::ensureSourceLocalPath() instead. See https://www.drupal.org/project/imagemagick/issues/2938375.', E_USER_DEPRECATED); + return $this->ensureSourceLocalPath(); + } + + /** + * Ensures that the local filesystem path to the image file exists. + * + * @return string + * A filesystem path. + */ + public function ensureSourceLocalPath() { // If sourceLocalPath is NULL, then ensure it is prepared. This can // happen if image was identified via cached metadata: the cached data are // available, but the temp file path is not resolved, or even the temp file // could be missing if it was copied locally from a remote file system. - if (!$this->arguments->getSourceLocalPath() && $this->getSource()) { + if (!$this->arguments()->getSourceLocalPath() && $this->getSource()) { $this->moduleHandler->alter('imagemagick_pre_parse_file', $this->arguments); } - return $this->arguments->getSourceLocalPath(); + return $this->arguments()->getSourceLocalPath(); } /** @@ -584,9 +628,15 @@ class ImagemagickToolkit extends ImageToolkitBase { * A filesystem path. * * @return $this + * + * @deprecated in 8.x-2.3, will be removed in 8.x-3.0. Use + * ImagemagickExecArguments::setSourceLocalPath() instead. + * + * @see https://www.drupal.org/project/imagemagick/issues/2938375 */ public function setSourceLocalPath($path) { - $this->arguments->setSourceLocalPath($path); + @trigger_error('setSourceLocalPath() is deprecated in 8.x-2.3, will be removed in 8.x-3.0. Use ImagemagickExecArguments::setSourceLocalPath() instead. See https://www.drupal.org/project/imagemagick/issues/2938375.', E_USER_DEPRECATED); + $this->arguments()->setSourceLocalPath($path); return $this; } @@ -595,9 +645,15 @@ class ImagemagickToolkit extends ImageToolkitBase { * * @return string * The source image format. + * + * @deprecated in 8.x-2.3, will be removed in 8.x-3.0. Use + * ImagemagickExecArguments::getSourceFormat() instead. + * + * @see https://www.drupal.org/project/imagemagick/issues/2938375 */ public function getSourceFormat() { - return $this->arguments->getSourceFormat(); + @trigger_error('getSourceFormat() is deprecated in 8.x-2.3, will be removed in 8.x-3.0. Use ImagemagickExecArguments::getSourceFormat() instead. See https://www.drupal.org/project/imagemagick/issues/2938375.', E_USER_DEPRECATED); + return $this->arguments()->getSourceFormat(); } /** @@ -607,9 +663,15 @@ class ImagemagickToolkit extends ImageToolkitBase { * The image format. * * @return $this + * + * @deprecated in 8.x-2.3, will be removed in 8.x-3.0. Use + * ImagemagickExecArguments::setSourceFormat() instead. + * + * @see https://www.drupal.org/project/imagemagick/issues/2938375 */ public function setSourceFormat($format) { - $this->arguments->setSourceFormat($this->formatMapper->isFormatEnabled($format) ? $format : ''); + @trigger_error('setSourceFormat() is deprecated in 8.x-2.3, will be removed in 8.x-3.0. Use ImagemagickExecArguments::setSourceFormat() instead. See https://www.drupal.org/project/imagemagick/issues/2938375.', E_USER_DEPRECATED); + $this->arguments()->setSourceFormat($format); return $this; } @@ -620,10 +682,15 @@ class ImagemagickToolkit extends ImageToolkitBase { * The image file extension. * * @return $this + * + * @deprecated in 8.x-2.3, will be removed in 8.x-3.0. Use + * ImagemagickExecArguments::setSourceFormatFromExtension() instead. + * + * @see https://www.drupal.org/project/imagemagick/issues/2938375 */ public function setSourceFormatFromExtension($extension) { - $format = $this->formatMapper->getFormatFromExtension($extension); - $this->arguments->setSourceFormat($format ?: ''); + @trigger_error('setSourceFormatFromExtension() is deprecated in 8.x-2.3, will be removed in 8.x-3.0. Use ImagemagickExecArguments::setSourceFormatFromExtension() instead. See https://www.drupal.org/project/imagemagick/issues/2938375.', E_USER_DEPRECATED); + $this->arguments()->setSourceFormatFromExtension($extension); return $this; } @@ -638,7 +705,7 @@ class ImagemagickToolkit extends ImageToolkitBase { if ($this->getSource() !== NULL) { $file_md = $this->fileMetadataManager->uri($this->getSource()); if ($file_md->getLocalTempPath() === NULL) { - $file_md->setLocalTempPath($this->getSourceLocalPath()); + $file_md->setLocalTempPath($this->ensureSourceLocalPath()); } $orientation = $file_md->getMetadata('exif', 'Orientation'); $this->setExifOrientation(isset($orientation['value']) ? $orientation['value'] : NULL); @@ -691,9 +758,15 @@ class ImagemagickToolkit extends ImageToolkitBase { * * @return string * The image destination URI/path. + * + * @deprecated in 8.x-2.3, will be removed in 8.x-3.0. Use + * ImagemagickExecArguments::getDestination() instead. + * + * @see https://www.drupal.org/project/imagemagick/issues/2938375 */ public function getDestination() { - return $this->arguments->getDestination(); + @trigger_error('getDestination() is deprecated in 8.x-2.3, will be removed in 8.x-3.0. Use ImagemagickExecArguments::getDestination() instead. See https://www.drupal.org/project/imagemagick/issues/2938375.', E_USER_DEPRECATED); + return $this->arguments()->getDestination(); } /** @@ -703,9 +776,15 @@ class ImagemagickToolkit extends ImageToolkitBase { * The image destination URI/path. * * @return $this + * + * @deprecated in 8.x-2.3, will be removed in 8.x-3.0. Use + * ImagemagickExecArguments::setDestination() instead. + * + * @see https://www.drupal.org/project/imagemagick/issues/2938375 */ public function setDestination($destination) { - $this->arguments->setDestination($destination); + @trigger_error('setDestination() is deprecated in 8.x-2.3, will be removed in 8.x-3.0. Use ImagemagickExecArguments::setDestination() instead. See https://www.drupal.org/project/imagemagick/issues/2938375.', E_USER_DEPRECATED); + $this->arguments()->setDestination($destination); return $this; } @@ -714,9 +793,15 @@ class ImagemagickToolkit extends ImageToolkitBase { * * @return string * A filesystem path. + * + * @deprecated in 8.x-2.3, will be removed in 8.x-3.0. Use + * ImagemagickExecArguments::getDestinationLocalPath() instead. + * + * @see https://www.drupal.org/project/imagemagick/issues/2938375 */ public function getDestinationLocalPath() { - return $this->arguments->getDestinationLocalPath(); + @trigger_error('getDestinationLocalPath() is deprecated in 8.x-2.3, will be removed in 8.x-3.0. Use ImagemagickExecArguments::getDestinationLocalPath() instead. See https://www.drupal.org/project/imagemagick/issues/2938375.', E_USER_DEPRECATED); + return $this->arguments()->getDestinationLocalPath(); } /** @@ -726,9 +811,15 @@ class ImagemagickToolkit extends ImageToolkitBase { * A filesystem path. * * @return $this + * + * @deprecated in 8.x-2.3, will be removed in 8.x-3.0. Use + * ImagemagickExecArguments::setDestinationLocalPath() instead. + * + * @see https://www.drupal.org/project/imagemagick/issues/2938375 */ public function setDestinationLocalPath($path) { - $this->arguments->setDestinationLocalPath($path); + @trigger_error('setDestinationLocalPath() is deprecated in 8.x-2.3, will be removed in 8.x-3.0. Use ImagemagickExecArguments::setDestinationLocalPath() instead. See https://www.drupal.org/project/imagemagick/issues/2938375.', E_USER_DEPRECATED); + $this->arguments()->setDestinationLocalPath($path); return $this; } @@ -741,9 +832,15 @@ class ImagemagickToolkit extends ImageToolkitBase { * * @return string * The image destination format. + * + * @deprecated in 8.x-2.3, will be removed in 8.x-3.0. Use + * ImagemagickExecArguments::getDestinationFormat() instead. + * + * @see https://www.drupal.org/project/imagemagick/issues/2938375 */ public function getDestinationFormat() { - return $this->arguments->getDestinationFormat(); + @trigger_error('getDestinationFormat() is deprecated in 8.x-2.3, will be removed in 8.x-3.0. Use ImagemagickExecArguments::getDestinationFormat() instead. See https://www.drupal.org/project/imagemagick/issues/2938375.', E_USER_DEPRECATED); + return $this->arguments()->getDestinationFormat(); } /** @@ -757,9 +854,15 @@ class ImagemagickToolkit extends ImageToolkitBase { * The image destination format. * * @return $this + * + * @deprecated in 8.x-2.3, will be removed in 8.x-3.0. Use + * ImagemagickExecArguments::setDestinationFormat() instead. + * + * @see https://www.drupal.org/project/imagemagick/issues/2938375 */ public function setDestinationFormat($format) { - $this->arguments->setDestinationFormat($this->formatMapper->isFormatEnabled($format) ? $format : ''); + @trigger_error('setDestinationFormat() is deprecated in 8.x-2.3, will be removed in 8.x-3.0. Use ImagemagickExecArguments::setDestinationFormat() instead. See https://www.drupal.org/project/imagemagick/issues/2938375.', E_USER_DEPRECATED); + $this->arguments()->setDestinationFormat($this->formatMapper->isFormatEnabled($format) ? $format : ''); return $this; } @@ -774,10 +877,15 @@ class ImagemagickToolkit extends ImageToolkitBase { * The destination image file extension. * * @return $this + * + * @deprecated in 8.x-2.3, will be removed in 8.x-3.0. Use + * ImagemagickExecArguments::setDestinationFormatFromExtension() instead. + * + * @see https://www.drupal.org/project/imagemagick/issues/2938375 */ public function setDestinationFormatFromExtension($extension) { - $format = $this->formatMapper->getFormatFromExtension($extension); - $this->arguments->setDestinationFormat($format ?: ''); + @trigger_error('setDestinationFormatFromExtension() is deprecated in 8.x-2.3, will be removed in 8.x-3.0. Use ImagemagickExecArguments::setDestinationFormatFromExtension() instead. See https://www.drupal.org/project/imagemagick/issues/2938375.', E_USER_DEPRECATED); + $this->arguments()->setDestinationFormatFromExtension($extension); return $this; } @@ -825,7 +933,7 @@ class ImagemagickToolkit extends ImageToolkitBase { * {@inheritdoc} */ public function getMimeType() { - return $this->formatMapper->getMimeTypeFromFormat($this->getSourceFormat()); + return $this->formatMapper->getMimeTypeFromFormat($this->arguments()->getSourceFormat()); } /** @@ -851,7 +959,7 @@ class ImagemagickToolkit extends ImageToolkitBase { */ public function getArguments() { @trigger_error('getArguments() is deprecated in 8.x-2.3, will be removed in 8.x-3.0. Use ::arguments() instead, using ImagemagickExecArguments methods to manipulate arguments. See https://www.drupal.org/project/imagemagick/issues/2925780.', E_USER_DEPRECATED); - return $this->arguments->getArguments(); + return $this->arguments()->getArguments(); } /** @@ -869,7 +977,7 @@ class ImagemagickToolkit extends ImageToolkitBase { */ public function getStringForBinary() { @trigger_error('getStringForBinary() is deprecated in 8.x-2.3, will be removed in 8.x-3.0. Use ImageMagickExecArguments::toString() instead. See https://www.drupal.org/project/imagemagick/issues/2925780.', E_USER_DEPRECATED); - return $this->arguments->getStringForBinary(); + return $this->arguments()->getStringForBinary(); } /** @@ -887,7 +995,7 @@ class ImagemagickToolkit extends ImageToolkitBase { */ public function addArgument($arg) { @trigger_error('addArgument() is deprecated in 8.x-2.3, will be removed in 8.x-3.0. Use ImageMagickExecArguments::add() instead. See https://www.drupal.org/project/imagemagick/issues/2925780.', E_USER_DEPRECATED); - $this->arguments->addArgument($arg); + $this->arguments()->addArgument($arg); return $this; } @@ -906,7 +1014,7 @@ class ImagemagickToolkit extends ImageToolkitBase { */ public function prependArgument($arg) { @trigger_error('prependArgument() is deprecated in 8.x-2.3, will be removed in 8.x-3.0. Use ImageMagickExecArguments::add() instead. See https://www.drupal.org/project/imagemagick/issues/2925780.', E_USER_DEPRECATED); - $this->arguments->prependArgument($arg); + $this->arguments()->prependArgument($arg); return $this; } @@ -927,7 +1035,7 @@ class ImagemagickToolkit extends ImageToolkitBase { */ public function findArgument($arg) { @trigger_error('findArgument() is deprecated in 8.x-2.3, will be removed in 8.x-3.0. Use ImageMagickExecArguments::find() instead. See https://www.drupal.org/project/imagemagick/issues/2925780.', E_USER_DEPRECATED); - return $this->arguments->findArgument($arg); + return $this->arguments()->findArgument($arg); } /** @@ -945,7 +1053,7 @@ class ImagemagickToolkit extends ImageToolkitBase { */ public function removeArgument($index) { @trigger_error('removeArgument() is deprecated in 8.x-2.3, will be removed in 8.x-3.0. Use ImageMagickExecArguments::remove() instead. See https://www.drupal.org/project/imagemagick/issues/2936615.', E_USER_DEPRECATED); - $this->arguments->removeArgument($index); + $this->arguments()->removeArgument($index); return $this; } @@ -961,7 +1069,7 @@ class ImagemagickToolkit extends ImageToolkitBase { */ public function resetArguments() { @trigger_error('resetArguments() is deprecated in 8.x-2.3, will be removed in 8.x-3.0. Use ImageMagickExecArguments::reset() instead. See https://www.drupal.org/project/imagemagick/issues/2936615.', E_USER_DEPRECATED); - $this->arguments->resetArguments(); + $this->arguments()->resetArguments(); return $this; } @@ -977,7 +1085,7 @@ class ImagemagickToolkit extends ImageToolkitBase { */ public function countArguments() { @trigger_error('countArguments() is deprecated in 8.x-2.3, will be removed in 8.x-3.0. Use ImageMagickExecArguments::find() instead, then count the result. See https://www.drupal.org/project/imagemagick/issues/2936615.', E_USER_DEPRECATED); - return $this->arguments->countArguments(); + return $this->arguments()->countArguments(); } /** @@ -997,19 +1105,19 @@ class ImagemagickToolkit extends ImageToolkitBase { */ public function escapeShellArg($arg) { @trigger_error('escapeShellArg() is deprecated in 8.x-2.3, will be removed in 8.x-3.0. Use ImageMagickExecArguments::escape() instead. See https://www.drupal.org/project/imagemagick/issues/2936680.', E_USER_DEPRECATED); - return $this->execManager->escapeShellArg($arg); + return $this->getExecManager()->escapeShellArg($arg); } /** * {@inheritdoc} */ public function save($destination) { - $this->setDestination($destination); + $this->arguments()->setDestination($destination); if ($ret = $this->convert()) { // Allow modules to alter the destination file. $this->moduleHandler->alter('imagemagick_post_save', $this->arguments); // Reset local path to allow saving to other file. - $this->setDestinationLocalPath(''); + $this->arguments()->setDestinationLocalPath(''); } return $ret; } @@ -1046,20 +1154,21 @@ class ImagemagickToolkit extends ImageToolkitBase { // Sets the local file path to the one retrieved by identify if available. if ($source_local_path = $file_md->getMetadata('imagemagick_identify', 'source_local_path')) { - $this->setSourceLocalPath($source_local_path); + $this->arguments()->setSourceLocalPath($source_local_path); } // Process parsed data from the first frame. $format = $file_md->getMetadata('imagemagick_identify', 'format'); if ($this->formatMapper->isFormatEnabled($format)) { $this - ->setSourceFormat($format) ->setWidth((int) $file_md->getMetadata('imagemagick_identify', 'width')) ->setHeight((int) $file_md->getMetadata('imagemagick_identify', 'height')) ->setExifOrientation($file_md->getMetadata('imagemagick_identify', 'exif_orientation')) ->setFrames($file_md->getMetadata('imagemagick_identify', 'frames_count')); + $this->arguments() + ->setSourceFormat($format); // Only Imagemagick allows to get colorspace information via 'identify'. - if ($this->getPackage() === 'imagemagick') { + if ($this->getExecManager()->getPackage() === 'imagemagick') { $this->arguments() ->setSourceColorspace($file_md->getMetadata('imagemagick_identify', 'colorspace')) ->setDestinationColorspace($file_md->getMetadata('imagemagick_identify', 'colorspace')); @@ -1093,13 +1202,14 @@ class ImagemagickToolkit extends ImageToolkitBase { $format = $this->formatMapper->getFormatFromExtension(image_type_to_extension($data[2], FALSE)); if ($format) { $this - ->setSourceFormat($format) ->setWidth($data[0]) ->setHeight($data[1]) // 'getimagesize' cannot provide information on number of frames in an // image and EXIF orientation, so set to defaults. ->setExifOrientation(static::EXIF_ORIENTATION_NOT_FETCHED) ->setFrames(NULL); + $this->arguments() + ->setSourceFormat($format); return TRUE; } @@ -1116,7 +1226,7 @@ class ImagemagickToolkit extends ImageToolkitBase { $config = $this->configFactory->get('imagemagick.settings'); // Ensure sourceLocalPath is prepared. - $this->getSourceLocalPath(); + $this->ensureSourceLocalPath(); // Allow modules to alter the command line parameters. $command = 'convert'; @@ -1125,41 +1235,41 @@ class ImagemagickToolkit extends ImageToolkitBase { // Delete any cached file metadata for the destination image file, before // creating a new one, and release the URI from the manager so that // metadata will not stick in the same request. - $this->fileMetadataManager->deleteCachedMetadata($this->getDestination()); - $this->fileMetadataManager->release($this->getDestination()); + $this->fileMetadataManager->deleteCachedMetadata($this->arguments()->getDestination()); + $this->fileMetadataManager->release($this->arguments()->getDestination()); // When destination format differs from source format, and source image // is multi-frame, convert only the first frame. - $destination_format = $this->getDestinationFormat() ?: $this->getSourceFormat(); - if ($this->getSourceFormat() !== $destination_format && ($this->getFrames() === NULL || $this->getFrames() > 1)) { - $this->arguments->setSourceFrames('[0]'); + $destination_format = $this->arguments()->getDestinationFormat() ?: $this->arguments()->getSourceFormat(); + if ($this->arguments()->getSourceFormat() !== $destination_format && ($this->getFrames() === NULL || $this->getFrames() > 1)) { + $this->arguments()->setSourceFrames('[0]'); } // Execute the command. - $success = $this->execManager->execute($command, $this->arguments) && file_exists($this->getDestinationLocalPath()); + $success = $this->getExecManager()->execute($command, $this->arguments) && file_exists($this->arguments()->getDestinationLocalPath()); // Under some circumstances (actually the most common), we can safely build // a new FileMetadata entry and assign data to it. This will save I/O in // future requests. if ($success && $config->get('use_identify') && - $this->getPackage() === 'imagemagick' && + $this->getExecManager()->getPackage() === 'imagemagick' && $this->getFrames() === 1 && $this->getWidth() !== NULL && $this->getHeight() !== NULL ) { - $destination_image_md = $this->fileMetadataManager->uri($this->getDestination()); + $destination_image_md = $this->fileMetadataManager->uri($this->arguments()->getDestination()); $metadata = [ 'frames' => [ 0 => [ - 'format' => $this->getDestinationFormat() ?: $this->getSourceFormat(), + 'format' => $this->arguments()->getDestinationFormat() ?: $this->arguments()->getSourceFormat(), 'width' => $this->getWidth(), 'height' => $this->getHeight(), 'colorspace' => $this->arguments()->getDestinationColorspace(), 'exif_orientation' => $this->getExifOrientation(), ], ], - 'source_local_path' => $this->getDestinationLocalPath(), + 'source_local_path' => $this->arguments()->getDestinationLocalPath(), ]; $destination_image_md->loadMetadata('imagemagick_identify', $metadata); } @@ -1181,7 +1291,7 @@ class ImagemagickToolkit extends ImageToolkitBase { ]); } else { - $status = $this->execManager->checkPath($this->configFactory->get('imagemagick.settings')->get('path_to_binaries')); + $status = $this->getExecManager()->checkPath($this->configFactory->get('imagemagick.settings')->get('path_to_binaries')); if (!empty($status['errors'])) { // Can not execute 'convert'. $severity = REQUIREMENT_ERROR; diff --git a/src/Plugin/ImageToolkit/Operation/imagemagick/Convert.php b/src/Plugin/ImageToolkit/Operation/imagemagick/Convert.php index f66b687..b5865ec 100644 --- a/src/Plugin/ImageToolkit/Operation/imagemagick/Convert.php +++ b/src/Plugin/ImageToolkit/Operation/imagemagick/Convert.php @@ -40,7 +40,7 @@ class Convert extends ImagemagickImageToolkitOperationBase { * {@inheritdoc} */ protected function execute(array $arguments) { - $this->getToolkit()->setDestinationFormatFromExtension($arguments['extension']); + $this->getToolkit()->arguments()->setDestinationFormatFromExtension($arguments['extension']); return TRUE; } diff --git a/src/Plugin/ImageToolkit/Operation/imagemagick/CreateNew.php b/src/Plugin/ImageToolkit/Operation/imagemagick/CreateNew.php index 3bf39e1..3a92843 100644 --- a/src/Plugin/ImageToolkit/Operation/imagemagick/CreateNew.php +++ b/src/Plugin/ImageToolkit/Operation/imagemagick/CreateNew.php @@ -75,21 +75,21 @@ class CreateNew extends ImagemagickImageToolkitOperationBase { */ protected function execute(array $arguments) { $this->getToolkit() - ->setSourceLocalPath('') - ->setSourceFormatFromExtension($arguments['extension']) ->setWidth($arguments['width']) ->setHeight($arguments['height']) ->setExifOrientation(NULL) ->setFrames(1); $this->getToolkit()->arguments() - ->setSourceColorspace($this->getToolkit()->getPackage() === 'imagemagick' ? 'sRGB' : NULL) - ->setDestinationColorspace($this->getToolkit()->getPackage() === 'imagemagick' ? 'sRGB' : NULL) + ->setSourceFormatFromExtension($arguments['extension']) + ->setSourceLocalPath('') + ->setSourceColorspace($this->getToolkit()->getExecManager()->getPackage() === 'imagemagick' ? 'sRGB' : NULL) + ->setDestinationColorspace($this->getToolkit()->getExecManager()->getPackage() === 'imagemagick' ? 'sRGB' : NULL) ->reset(); $arg = '-size ' . $arguments['width'] . 'x' . $arguments['height']; // Transparent color syntax for GIF files differs by package. if ($arguments['extension'] === 'gif') { - switch ($this->getToolkit()->getPackage()) { + switch ($this->getToolkit()->getExecManager()->getPackage()) { case 'imagemagick': $arg .= ' xc:transparent -transparent-color ' . $this->escapeArgument($arguments['transparent_color']); break; diff --git a/src/Plugin/ImageToolkit/Operation/imagemagick/Desaturate.php b/src/Plugin/ImageToolkit/Operation/imagemagick/Desaturate.php index 30e13f3..07c864a 100644 --- a/src/Plugin/ImageToolkit/Operation/imagemagick/Desaturate.php +++ b/src/Plugin/ImageToolkit/Operation/imagemagick/Desaturate.php @@ -28,7 +28,7 @@ class Desaturate extends ImagemagickImageToolkitOperationBase { */ protected function execute(array $arguments) { $this->addArgument('-colorspace GRAY'); - $this->getToolkit()->arguments()->setDestinationColorspace($this->getToolkit()->getPackage() === 'imagemagick' ? 'GRAY' : NULL); + $this->getToolkit()->arguments()->setDestinationColorspace($this->getToolkit()->getExecManager()->getPackage() === 'imagemagick' ? 'GRAY' : NULL); return TRUE; } diff --git a/tests/src/Functional/ToolkitImagemagickFileMetadataTest.php b/tests/src/Functional/ToolkitImagemagickFileMetadataTest.php index c639a15..e2249df 100644 --- a/tests/src/Functional/ToolkitImagemagickFileMetadataTest.php +++ b/tests/src/Functional/ToolkitImagemagickFileMetadataTest.php @@ -113,7 +113,7 @@ class ToolkitImagemagickFileMetadataTest extends BrowserTestBase { ->set('binaries', $binaries) ->set('use_identify', $parsing_method === 'imagemagick_identify') ->save(); - $status = \Drupal::service('image.toolkit.manager')->createInstance('imagemagick')->checkPath(''); + $status = \Drupal::service('image.toolkit.manager')->createInstance('imagemagick')->getExecManager()->checkPath(''); if (!empty($status['errors'])) { // Bots running automated test on d.o. do not have binaries installed, // so the test will be skipped; it can be run locally where binaries are @@ -625,6 +625,14 @@ class ToolkitImagemagickFileMetadataTest extends BrowserTestBase { * Tests getSourceLocalPath() for re-creating local path. */ public function testSourceLocalPath() { + $status = \Drupal::service('image.toolkit.manager')->createInstance('imagemagick')->getExecManager()->checkPath(''); + if (!empty($status['errors'])) { + // Bots running automated test on d.o. do not have binaries installed, + // so the test will be skipped; it can be run locally where binaries are + // installed. + $this->markTestSkipped("Tests for 'imagemagick' cannot run because the binaries are not available on the shell path."); + } + $config = \Drupal::configFactory()->getEditable('imagemagick.settings'); $config_mdm = \Drupal::configFactory()->getEditable('file_mdm.settings'); @@ -646,17 +654,16 @@ class ToolkitImagemagickFileMetadataTest extends BrowserTestBase { // Load up the image. $image = $this->imageFactory->get($source_uri); $this->assertEqual($source_uri, $image->getToolkit()->getSource()); - $this->assertEqual(drupal_realpath($source_uri), $image->getToolkit()->getSourceLocalPath()); + $this->assertEqual(drupal_realpath($source_uri), $image->getToolkit()->arguments()->getSourceLocalPath()); // Free up the URI from the file metadata manager to force reload from // cache. Simulates that next imageFactory->get is from another request. $fmdm->release($source_uri); - // Re-load the image, getLocalSourcePath should still return the local - // path. + // Re-load the image, ensureLocalSourcePath should return the local path. $image1 = $this->imageFactory->get($source_uri); $this->assertEqual($source_uri, $image1->getToolkit()->getSource()); - $this->assertEqual(drupal_realpath($source_uri), $image1->getToolkit()->getSourceLocalPath()); + $this->assertEqual(drupal_realpath($source_uri), $image1->getToolkit()->ensureSourceLocalPath()); } } diff --git a/tests/src/Functional/ToolkitImagemagickTest.php b/tests/src/Functional/ToolkitImagemagickTest.php index 9dbeb26..ce40f62 100644 --- a/tests/src/Functional/ToolkitImagemagickTest.php +++ b/tests/src/Functional/ToolkitImagemagickTest.php @@ -106,7 +106,7 @@ class ToolkitImagemagickTest extends BrowserTestBase { if ($check_path) { // The test can only be executed if binaries are available on the shell // path. - $status = \Drupal::service('image.toolkit.manager')->createInstance('imagemagick')->checkPath(''); + $status = \Drupal::service('image.toolkit.manager')->createInstance('imagemagick')->getExecManager()->checkPath(''); if (!empty($status['errors'])) { // Bots running automated test on d.o. do not have binaries installed, // so the test will be skipped; it can be run locally where binaries @@ -350,7 +350,7 @@ class ToolkitImagemagickTest extends BrowserTestBase { $this->assertTrue($image->isValid()); // @todo Suite specifics, temporarily adjust tests. - $package = $image->getToolkit()->getPackage(); + $package = $image->getToolkit()->getExecManager()->getPackage(); if ($package === 'graphicsmagick') { // @todo Issues with crop and convert on GIF files, investigate. if (in_array($file, [ @@ -509,14 +509,14 @@ class ToolkitImagemagickTest extends BrowserTestBase { // Test handling a file stored through a remote stream wrapper. $image = $this->imageFactory->get('dummy-remote://image-test.png'); // Source file should be equal to the copied local temp source file. - $this->assertEqual(filesize('dummy-remote://image-test.png'), filesize($image->getToolkit()->getSourceLocalPath())); + $this->assertEqual(filesize('dummy-remote://image-test.png'), filesize($image->getToolkit()->arguments()->getSourceLocalPath())); $image->desaturate(); $this->assertTrue($image->save('dummy-remote://remote-image-test.png')); // Destination file should exists, and destination local temp file should // have been reset. - $this->assertTrue(file_exists($image->getToolkit()->getDestination())); - $this->assertEqual('dummy-remote://remote-image-test.png', $image->getToolkit()->getDestination()); - $this->assertIdentical('', $image->getToolkit()->getDestinationLocalPath()); + $this->assertTrue(file_exists($image->getToolkit()->arguments()->getDestination())); + $this->assertEqual('dummy-remote://remote-image-test.png', $image->getToolkit()->arguments()->getDestination()); + $this->assertIdentical('', $image->getToolkit()->arguments()->getDestinationLocalPath()); // Test retrieval of EXIF information. file_unmanaged_copy(drupal_get_path('module', 'imagemagick') . '/misc/test-exif.jpeg', 'public://', FILE_EXISTS_REPLACE); @@ -621,6 +621,252 @@ class ToolkitImagemagickTest extends BrowserTestBase { } /** + * Legacy methods tests. + * + * @param string $binaries + * The graphics package binaries to use for testing. + * + * @dataProvider providerManipulationTest + * + * @todo remove in 8.x-3.0. + * + * @group legacy + */ + public function testManipulationsLegacy($binaries) { + $this->setUpToolkit($binaries); + + // Check package. + $toolkit = \Drupal::service('image.toolkit.manager')->createInstance('imagemagick'); + $this->assertSame($binaries, $toolkit->getPackage()); + $this->assertNotNull($toolkit->getPackageLabel()); + $this->assertSame([], $toolkit->checkPath('')['errors']); + + // Typically the corner colors will be unchanged. These colors are in the + // order of top-left, top-right, bottom-right, bottom-left. + $default_corners = [ + $this->red, + $this->green, + $this->blue, + $this->transparent, + ]; + + // A list of files that will be tested. + $files = [ + 'image-test.png', + 'image-test.gif', + 'image-test-no-transparency.gif', + 'image-test.jpg', + ]; + + // Setup a list of tests to perform on each type. + $operations = [ + 'resize' => [ + 'function' => 'resize', + 'arguments' => ['width' => 20, 'height' => 10], + 'width' => 20, + 'height' => 10, + 'corners' => $default_corners, + 'tolerance' => 0, + ], + 'scale_x' => [ + 'function' => 'scale', + 'arguments' => ['width' => 20], + 'width' => 20, + 'height' => 10, + 'corners' => $default_corners, + 'tolerance' => 0, + ], + 'scale_y' => [ + 'function' => 'scale', + 'arguments' => ['height' => 10], + 'width' => 20, + 'height' => 10, + 'corners' => $default_corners, + 'tolerance' => 0, + ], + 'upscale_x' => [ + 'function' => 'scale', + 'arguments' => ['width' => 80, 'upscale' => TRUE], + 'width' => 80, + 'height' => 40, + 'corners' => $default_corners, + 'tolerance' => 0, + ], + 'upscale_y' => [ + 'function' => 'scale', + 'arguments' => ['height' => 40, 'upscale' => TRUE], + 'width' => 80, + 'height' => 40, + 'corners' => $default_corners, + 'tolerance' => 0, + ], + 'crop' => [ + 'function' => 'crop', + 'arguments' => ['x' => 12, 'y' => 4, 'width' => 16, 'height' => 12], + 'width' => 16, + 'height' => 12, + 'corners' => array_fill(0, 4, $this->white), + 'tolerance' => 0, + ], + 'scale_and_crop' => [ + 'function' => 'scale_and_crop', + 'arguments' => ['width' => 10, 'height' => 8], + 'width' => 10, + 'height' => 8, + 'corners' => array_fill(0, 4, $this->black), + 'tolerance' => 100, + ], + 'convert_jpg' => [ + 'function' => 'convert', + 'width' => 40, + 'height' => 20, + 'arguments' => ['extension' => 'jpeg'], + 'mimetype' => 'image/jpeg', + 'corners' => $default_corners, + 'tolerance' => 0, + ], + 'convert_gif' => [ + 'function' => 'convert', + 'width' => 40, + 'height' => 20, + 'arguments' => ['extension' => 'gif'], + 'mimetype' => 'image/gif', + 'corners' => $default_corners, + 'tolerance' => 15, + ], + 'convert_png' => [ + 'function' => 'convert', + 'width' => 40, + 'height' => 20, + 'arguments' => ['extension' => 'png'], + 'mimetype' => 'image/png', + 'corners' => $default_corners, + 'tolerance' => 5, + ], + 'rotate_5' => [ + 'function' => 'rotate', + 'arguments' => [ + 'degrees' => 5, + 'background' => '#FF00FF', + 'resize_filter' => 'Box', + ], + 'width' => 41, + 'height' => 23, + 'corners' => array_fill(0, 4, $this->fuchsia), + 'tolerance' => 5, + ], + 'rotate_minus_10' => [ + 'function' => 'rotate', + 'arguments' => [ + 'degrees' => -10, + 'background' => '#FF00FF', + 'resize_filter' => 'Box', + ], + 'width' => 41, + 'height' => 26, + 'corners' => array_fill(0, 4, $this->fuchsia), + 'tolerance' => 15, + ], + 'rotate_90' => [ + 'function' => 'rotate', + 'arguments' => ['degrees' => 90, 'background' => '#FF00FF'], + 'width' => 20, + 'height' => 40, + 'corners' => [$this->transparent, $this->red, $this->green, $this->blue], + 'tolerance' => 0, + ], + 'rotate_transparent_5' => [ + 'function' => 'rotate', + 'arguments' => ['degrees' => 5, 'resize_filter' => 'Box'], + 'width' => 41, + 'height' => 23, + 'corners' => array_fill(0, 4, $this->transparent), + 'tolerance' => 0, + ], + 'rotate_transparent_90' => [ + 'function' => 'rotate', + 'arguments' => ['degrees' => 90], + 'width' => 20, + 'height' => 40, + 'corners' => [$this->transparent, $this->red, $this->green, $this->blue], + 'tolerance' => 0, + ], + 'desaturate' => [ + 'function' => 'desaturate', + 'arguments' => [], + 'height' => 20, + 'width' => 40, + // Grayscale corners are a bit funky. Each of the corners are a shade of + // gray. The values of these were determined simply by looking at the + // final image to see what desaturated colors end up being. + 'corners' => [ + array_fill(0, 3, 76) + [3 => 0], + array_fill(0, 3, 149) + [3 => 0], + array_fill(0, 3, 29) + [3 => 0], + array_fill(0, 3, 225) + [3 => 127], + ], + // @todo tolerance here is too high. Check reasons. + 'tolerance' => 17000, + ], + ]; + + // Prepare a copy of test files. + $this->getTestFiles('image'); + + foreach ($files as $file) { + $image_uri = 'public://' . $file; + foreach ($operations as $op => $values) { + // Load up a fresh image. + $image = $this->imageFactory->get($image_uri); + if (!$image->isValid()) { + $this->fail("Could not load image $file."); + continue 2; + } + + // Check that no multi-frame information is set. + $this->assertIdentical(1, $image->getToolkit()->getFrames()); + + // Legacy source tests. + $this->assertSame($image_uri, $image->getToolkit()->getSource()); + $this->assertSame($image->getToolkit()->arguments()->getSourceLocalPath(), $image->getToolkit()->getSourceLocalPath()); + $this->assertSame($image->getToolkit()->arguments()->getSourceFormat(), $image->getToolkit()->getSourceFormat()); + + // Perform our operation. + $image->apply($values['function'], $values['arguments']); + + // Save image. + $file_path = $this->testDirectory . '/' . $op . substr($file, -4); + $this->assertTrue($image->save($file_path)); + + // Legacy destination tests. + $this->assertSame($file_path, $image->getToolkit()->getDestination()); + $this->assertSame('', $image->getToolkit()->getDestinationLocalPath()); + $this->assertNotNull($image->getToolkit()->arguments()->getSourceFormat(), $image->getToolkit()->getDestinationFormat()); + + // Reload image. + $image = $this->imageFactory->get($file_path); + $this->assertTrue($image->isValid()); + + // Legacy set methods. + $image->getToolkit()->setSourceLocalPath('bar'); + $image->getToolkit()->setSourceFormat('PNG'); + $image->getToolkit()->setDestination('foo'); + $image->getToolkit()->setDestinationLocalPath('baz'); + $image->getToolkit()->setDestinationFormat('GIF'); + $this->assertSame('bar', $image->getToolkit()->arguments()->getSourceLocalPath()); + $this->assertSame('PNG', $image->getToolkit()->arguments()->getSourceFormat()); + $this->assertSame('foo', $image->getToolkit()->arguments()->getDestination()); + $this->assertSame('baz', $image->getToolkit()->arguments()->getDestinationLocalPath()); + $this->assertSame('GIF', $image->getToolkit()->arguments()->getDestinationFormat()); + $image->getToolkit()->setSourceFormatFromExtension('jpg'); + $image->getToolkit()->setDestinationFormatFromExtension('jpg'); + $this->assertSame('JPEG', $image->getToolkit()->arguments()->getSourceFormat()); + $this->assertSame('JPEG', $image->getToolkit()->arguments()->getDestinationFormat()); + } + } + } + + /** * Test ImageMagick subform and settings. */ public function testFormAndSettings() {