Version 1
[yaffs-website] / web / modules / contrib / imagemagick / src / ImagemagickFormatMapper.php
diff --git a/web/modules/contrib/imagemagick/src/ImagemagickFormatMapper.php b/web/modules/contrib/imagemagick/src/ImagemagickFormatMapper.php
new file mode 100644 (file)
index 0000000..e21a854
--- /dev/null
@@ -0,0 +1,264 @@
+<?php
+
+namespace Drupal\imagemagick;
+
+use Drupal\Component\Utility\Unicode;
+use Drupal\Core\Cache\Cache;
+use Drupal\Core\Cache\CacheBackendInterface;
+use Drupal\Core\Config\ConfigFactoryInterface;
+use Drupal\Core\Config\Schema\SchemaCheckTrait;
+use Drupal\Core\Config\TypedConfigManagerInterface;
+use Drupal\Core\StringTranslation\StringTranslationTrait;
+// @todo change if extension mapping service gets in, see #2311679
+use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface;
+
+/**
+ * Provides the ImageMagick format mapper.
+ */
+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;
+  }
+
+}