You are here

class ImagemagickFormatMapper in ImageMagick 8

Same name and namespace in other branches
  1. 8.3 src/ImagemagickFormatMapper.php \Drupal\imagemagick\ImagemagickFormatMapper
  2. 8.2 src/ImagemagickFormatMapper.php \Drupal\imagemagick\ImagemagickFormatMapper

Provides the ImageMagick format mapper.

Hierarchy

Expanded class hierarchy of ImagemagickFormatMapper

1 string reference to 'ImagemagickFormatMapper'
imagemagick.services.yml in ./imagemagick.services.yml
imagemagick.services.yml
1 service uses ImagemagickFormatMapper
imagemagick.format_mapper in ./imagemagick.services.yml
Drupal\imagemagick\ImagemagickFormatMapper

File

src/ImagemagickFormatMapper.php, line 18

Namespace

Drupal\imagemagick
View source
class ImagemagickFormatMapper implements ImagemagickFormatMapperInterface {
  use SchemaCheckTrait;
  use StringTranslationTrait;

  /**
   * The cache service.
   *
   * @var \Drupal\Core\Cache\CacheBackendInterface
   */
  protected $cache;

  /**
   * The MIME type guessing service.
   * @todo change if extension mapping service gets in, see #2311679
   *
   * @var \Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface
   */
  protected $mimeTypeMapper;

  /**
   * The config factory service.
   *
   * @var \Drupal\Core\Config\ConfigFactoryInterface
   */
  protected $configFactory;

  /**
   * The typed config service.
   *
   * @var \Drupal\Core\Config\TypedConfigManagerInterface
   */
  protected $typedConfig;

  /**
   * Constructs an ImagemagickFormatmapper object.
   *
   * @param \Drupal\Core\Cache\CacheBackendInterface $cache_service
   *   The cache service.
   * @param \Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface $mime_type_mapper
   *   The MIME type mapping service.
   *   @todo change if extension mapping service gets in, see #2311679
   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
   *   The config factory.
   * @param \Drupal\Core\Config\TypedConfigManagerInterface $typed_config
   *   The typed config service.
   */
  public function __construct(CacheBackendInterface $cache_service, MimeTypeGuesserInterface $mime_type_mapper, ConfigFactoryInterface $config_factory, TypedConfigManagerInterface $typed_config) {
    $this->cache = $cache_service;

    // @todo change if extension mapping service gets in, see #2311679
    $this->mimeTypeMapper = $mime_type_mapper;
    $this->configFactory = $config_factory;
    $this->typedConfig = $typed_config;
  }

  /**
   * {@inheritdoc}
   */
  public function validateMap(array $map) {
    $errors = [];

    // Get current config object and change the format map.
    $data = $this->configFactory
      ->get('imagemagick.settings')
      ->get();
    $data['image_formats'] = $map;

    // Validates against schema.
    $schema_errors = $this
      ->checkConfigSchema($this->typedConfig, 'imagemagick.settings', $data);
    if ($schema_errors !== TRUE) {
      foreach ($schema_errors as $key => $value) {
        list($object, $path) = explode(':', $key);
        $components = explode('.', $path);
        if ($components[0] === 'image_formats') {
          if (isset($components[2])) {
            $errors[$components[1]]['variables'][$components[2]][] = $value;
          }
          else {
            $errors[$components[1]]['format'][] = $value;
          }
        }
      }
    }

    // Other checks.
    foreach ($map as $key => $value) {
      if (Unicode::strtoupper($key) != $key) {

        // Formats must be typed in uppercase.
        $errors[$key]['format'][] = $this
          ->t("The format (@key) must be entered in all uppercase characters.", [
          '@key' => $key,
        ])
          ->render();
      }
      if (!isset($value['mime_type'])) {

        // Formats must have a MIME type mapped.
        $errors[$key]['format'][] = $this
          ->t("Missing mime_type variable.")
          ->render();
      }
      elseif (!in_array($value['mime_type'], $this->mimeTypeMapper
        ->getMimeTypes())) {

        // MIME type must exist.
        $errors[$key]['variables']['mime_type'][] = $this
          ->t("MIME type (@mime_type) not found.", [
          '@mime_type' => $value['mime_type'],
        ])
          ->render();
      }
    }
    return $errors;
  }

  /**
   * {@inheritdoc}
   */
  public function isFormatEnabled($format) {
    $format = Unicode::strtoupper($format);
    return $format ? isset($this
      ->resolveEnabledFormats()[$format]) : FALSE;
  }

  /**
   * {@inheritdoc}
   */
  public function getMimeTypeFromFormat($format) {
    $format = Unicode::strtoupper($format);
    if ($this
      ->isFormatEnabled($format)) {
      return $this
        ->resolveEnabledFormats()[$format];
    }
    return NULL;
  }

  /**
   * {@inheritdoc}
   */
  public function getFormatFromExtension($extension) {
    $extension = Unicode::strtolower($extension);
    $enabled_extensions = $this
      ->resolveEnabledExtensions();
    return $extension ? isset($enabled_extensions[$extension]) ? $enabled_extensions[$extension] : NULL : NULL;
  }

  /**
   * {@inheritdoc}
   */
  public function getEnabledFormats() {
    return array_keys($this
      ->resolveEnabledFormats());
  }

  /**
   * {@inheritdoc}
   */
  public function getEnabledExtensions() {
    return array_keys($this
      ->resolveEnabledExtensions());
  }

  /**
   * Returns the enabled image formats, processing the config map.
   *
   * Results are cached for subsequent access. Saving the config will
   * invalidate the cache.
   *
   * @return array
   *   An associative array with ImageMagick formats as keys and their MIME
   *   type as values.
   */
  protected function resolveEnabledFormats() {
    if ($cache = $this->cache
      ->get("imagemagick:enabled_formats")) {
      $enabled_image_formats = $cache->data;
    }
    else {
      $config = $this->configFactory
        ->get('imagemagick.settings');
      $image_formats = $config
        ->get('image_formats');
      $enabled_image_formats = [];
      foreach ($image_formats as $format => $data) {
        if (!isset($data['enabled']) || isset($data['enabled']) && $data['enabled']) {
          if (isset($data['mime_type']) && in_array($data['mime_type'], $this->mimeTypeMapper
            ->getMimeTypes())) {
            $enabled_image_formats[$format] = $data['mime_type'];
          }
        }
      }
      ksort($enabled_image_formats);
      $this->cache
        ->set("imagemagick:enabled_formats", $enabled_image_formats, Cache::PERMANENT, $config
        ->getCacheTags());
    }
    return $enabled_image_formats;
  }

  /**
   * Returns the enabled image file extensions, processing the config map.
   *
   * Results are cached for subsequent access. Saving the config will
   * invalidate the cache.
   *
   * @return array
   *   An associative array with file extensions as keys and their ImageMagick
   *   format as values.
   */
  protected function resolveEnabledExtensions() {
    if ($cache = $this->cache
      ->get("imagemagick:enabled_extensions")) {
      $extensions = $cache->data;
    }
    else {

      // Get configured image formats.
      $image_formats = $this->configFactory
        ->get('imagemagick.settings')
        ->get('image_formats');

      // Get only enabled formats.
      $enabled_image_formats = array_keys($this
        ->resolveEnabledFormats());

      // Apply defaults.
      foreach ($enabled_image_formats as $format) {
        if (isset($image_formats[$format]) && is_array($image_formats[$format])) {
          $image_formats[$format] += [
            'mime_type' => NULL,
            'weight' => 0,
            'exclude_extensions' => NULL,
          ];
        }
      }

      // Scans the enabled formats to determine enabled file extensions and
      // their mapping to the internal Image/GraphicsMagick format.
      $extensions = [];
      $excluded_extensions = [];
      foreach ($enabled_image_formats as $format) {
        $format_extensions = $this->mimeTypeMapper
          ->getExtensionsForMimeType($image_formats[$format]['mime_type']);
        $weight_checked_extensions = [];
        foreach ($format_extensions as $ext) {
          if (!isset($extensions[$ext])) {
            $weight_checked_extensions[$ext] = $format;
          }
          else {

            // Extension is already present in the array, lower weight format
            // prevails.
            if ($image_formats[$format]['weight'] < $image_formats[$extensions[$ext]]['weight']) {
              $weight_checked_extensions[$ext] = $format;
            }
          }
        }
        $extensions = array_merge($extensions, $weight_checked_extensions);

        // Accumulate excluded extensions.
        if ($image_formats[$format]['exclude_extensions']) {
          $exclude_extensions_string = Unicode::strtolower(preg_replace('/\\s+/', '', $image_formats[$format]['exclude_extensions']));
          $excluded_extensions = array_merge($excluded_extensions, array_intersect($format_extensions, explode(',', $exclude_extensions_string)));
        }
      }

      // Remove the excluded extensions.
      $excluded_extensions = array_unique($excluded_extensions);
      $excluded_extensions = array_combine($excluded_extensions, $excluded_extensions);
      $extensions = array_diff_key($extensions, $excluded_extensions);
      ksort($extensions);
      $this->cache
        ->set("imagemagick:enabled_extensions", $extensions, Cache::PERMANENT, $this->configFactory
        ->get('imagemagick.settings')
        ->getCacheTags());
    }
    return $extensions;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
ImagemagickFormatMapper::$cache protected property The cache service.
ImagemagickFormatMapper::$configFactory protected property The config factory service.
ImagemagickFormatMapper::$mimeTypeMapper protected property The MIME type guessing service. @todo change if extension mapping service gets in, see #2311679
ImagemagickFormatMapper::$typedConfig protected property The typed config service.
ImagemagickFormatMapper::getEnabledExtensions public function Gets the list of currently enabled image file extensions. Overrides ImagemagickFormatMapperInterface::getEnabledExtensions
ImagemagickFormatMapper::getEnabledFormats public function Gets the list of currently enabled image formats. Overrides ImagemagickFormatMapperInterface::getEnabledFormats
ImagemagickFormatMapper::getFormatFromExtension public function Gets the image format, given the image file extension. Overrides ImagemagickFormatMapperInterface::getFormatFromExtension
ImagemagickFormatMapper::getMimeTypeFromFormat public function Gets the MIME type of an image format. Overrides ImagemagickFormatMapperInterface::getMimeTypeFromFormat
ImagemagickFormatMapper::isFormatEnabled public function Checks if an image format is enabled in the toolkit. Overrides ImagemagickFormatMapperInterface::isFormatEnabled
ImagemagickFormatMapper::resolveEnabledExtensions protected function Returns the enabled image file extensions, processing the config map.
ImagemagickFormatMapper::resolveEnabledFormats protected function Returns the enabled image formats, processing the config map.
ImagemagickFormatMapper::validateMap public function Validates the format map. Overrides ImagemagickFormatMapperInterface::validateMap
ImagemagickFormatMapper::__construct public function Constructs an ImagemagickFormatmapper object.
SchemaCheckTrait::$configName protected property The configuration object name under test.
SchemaCheckTrait::$schema protected property The config schema wrapper object for the configuration object under test.
SchemaCheckTrait::checkConfigSchema public function Checks the TypedConfigManager has a valid schema for the configuration.
SchemaCheckTrait::checkValue protected function Helper method to check data type.
StringTranslationTrait::$stringTranslation protected property The string translation service. 1
StringTranslationTrait::formatPlural protected function Formats a string containing a count of items.
StringTranslationTrait::getNumberOfPlurals protected function Returns the number of plurals supported by a given language.
StringTranslationTrait::getStringTranslation protected function Gets the string translation service.
StringTranslationTrait::setStringTranslation public function Sets the string translation service to use. 2
StringTranslationTrait::t protected function Translates a string to the current language or to a given language.