Pathologic was missing because of a .git folder inside.
[yaffs-website] / web / modules / contrib / imagemagick / src / ImagemagickFormatMapper.php
1 <?php
2
3 namespace Drupal\imagemagick;
4
5 use Drupal\Component\Utility\Unicode;
6 use Drupal\Core\Cache\Cache;
7 use Drupal\Core\Cache\CacheBackendInterface;
8 use Drupal\Core\Config\ConfigFactoryInterface;
9 use Drupal\Core\Config\Schema\SchemaCheckTrait;
10 use Drupal\Core\Config\TypedConfigManagerInterface;
11 use Drupal\Core\StringTranslation\StringTranslationTrait;
12 // @todo change if extension mapping service gets in, see #2311679
13 use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface;
14
15 /**
16  * Provides the ImageMagick format mapper.
17  */
18 class ImagemagickFormatMapper implements ImagemagickFormatMapperInterface {
19
20   use SchemaCheckTrait;
21   use StringTranslationTrait;
22
23   /**
24    * The cache service.
25    *
26    * @var \Drupal\Core\Cache\CacheBackendInterface
27    */
28   protected $cache;
29
30   /**
31    * The MIME type guessing service.
32    * @todo change if extension mapping service gets in, see #2311679
33    *
34    * @var \Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface
35    */
36   protected $mimeTypeMapper;
37
38   /**
39    * The config factory service.
40    *
41    * @var \Drupal\Core\Config\ConfigFactoryInterface
42    */
43   protected $configFactory;
44
45   /**
46    * The typed config service.
47    *
48    * @var \Drupal\Core\Config\TypedConfigManagerInterface
49    */
50   protected $typedConfig;
51
52   /**
53    * Constructs an ImagemagickFormatmapper object.
54    *
55    * @param \Drupal\Core\Cache\CacheBackendInterface $cache_service
56    *   The cache service.
57    * @param \Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface $mime_type_mapper
58    *   The MIME type mapping service.
59    *   @todo change if extension mapping service gets in, see #2311679
60    * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
61    *   The config factory.
62    * @param \Drupal\Core\Config\TypedConfigManagerInterface $typed_config
63    *   The typed config service.
64    */
65   public function __construct(CacheBackendInterface $cache_service, MimeTypeGuesserInterface $mime_type_mapper, ConfigFactoryInterface $config_factory, TypedConfigManagerInterface $typed_config) {
66     $this->cache = $cache_service;
67     // @todo change if extension mapping service gets in, see #2311679
68     $this->mimeTypeMapper = $mime_type_mapper;
69     $this->configFactory = $config_factory;
70     $this->typedConfig = $typed_config;
71   }
72
73   /**
74    * {@inheritdoc}
75    */
76   public function validateMap(array $map) {
77     $errors = [];
78
79     // Get current config object and change the format map.
80     $data = $this->configFactory->get('imagemagick.settings')->get();
81     $data['image_formats'] = $map;
82
83     // Validates against schema.
84     $schema_errors = $this->checkConfigSchema($this->typedConfig, 'imagemagick.settings', $data);
85     if ($schema_errors !== TRUE) {
86       foreach ($schema_errors as $key => $value) {
87         list($object, $path) = explode(':', $key);
88         $components = explode('.', $path);
89         if ($components[0] === 'image_formats') {
90           if (isset($components[2])) {
91             $errors[$components[1]]['variables'][$components[2]][] = $value;
92           }
93           else {
94             $errors[$components[1]]['format'][] = $value;
95           }
96         }
97       }
98     }
99
100     // Other checks.
101     foreach ($map as $key => $value) {
102       if (Unicode::strtoupper($key) != $key) {
103         // Formats must be typed in uppercase.
104         $errors[$key]['format'][] = $this->t("The format (@key) must be entered in all uppercase characters.", ['@key' => $key])->render();
105       }
106       if (!isset($value['mime_type'])) {
107         // Formats must have a MIME type mapped.
108         $errors[$key]['format'][] = $this->t("Missing mime_type variable.")->render();
109       }
110       elseif (!in_array($value['mime_type'], $this->mimeTypeMapper->getMimeTypes())) {
111         // MIME type must exist.
112         $errors[$key]['variables']['mime_type'][] = $this->t("MIME type (@mime_type) not found.", ['@mime_type' => $value['mime_type']])->render();
113       }
114     }
115
116     return $errors;
117   }
118
119   /**
120    * {@inheritdoc}
121    */
122   public function isFormatEnabled($format) {
123     $format = Unicode::strtoupper($format);
124     return $format ? isset($this->resolveEnabledFormats()[$format]) : FALSE;
125   }
126
127   /**
128    * {@inheritdoc}
129    */
130   public function getMimeTypeFromFormat($format) {
131     $format = Unicode::strtoupper($format);
132     if ($this->isFormatEnabled($format)) {
133       return $this->resolveEnabledFormats()[$format];
134     }
135     return NULL;
136   }
137
138   /**
139    * {@inheritdoc}
140    */
141   public function getFormatFromExtension($extension) {
142     $extension = Unicode::strtolower($extension);
143     $enabled_extensions = $this->resolveEnabledExtensions();
144     return $extension ? (isset($enabled_extensions[$extension]) ? $enabled_extensions[$extension] : NULL) : NULL;
145   }
146
147   /**
148    * {@inheritdoc}
149    */
150   public function getEnabledFormats() {
151     return array_keys($this->resolveEnabledFormats());
152   }
153
154   /**
155    * {@inheritdoc}
156    */
157   public function getEnabledExtensions() {
158     return array_keys($this->resolveEnabledExtensions());
159   }
160
161   /**
162    * Returns the enabled image formats, processing the config map.
163    *
164    * Results are cached for subsequent access. Saving the config will
165    * invalidate the cache.
166    *
167    * @return array
168    *   An associative array with ImageMagick formats as keys and their MIME
169    *   type as values.
170    */
171   protected function resolveEnabledFormats() {
172     if ($cache = $this->cache->get("imagemagick:enabled_formats")) {
173       $enabled_image_formats = $cache->data;
174     }
175     else {
176       $config = $this->configFactory->get('imagemagick.settings');
177       $image_formats = $config->get('image_formats');
178       $enabled_image_formats = [];
179       foreach ($image_formats as $format => $data) {
180         if (!isset($data['enabled']) || (isset($data['enabled']) && $data['enabled'])) {
181           if (isset($data['mime_type']) && in_array($data['mime_type'], $this->mimeTypeMapper->getMimeTypes())) {
182             $enabled_image_formats[$format] = $data['mime_type'];
183           }
184         }
185       }
186       ksort($enabled_image_formats);
187       $this->cache->set("imagemagick:enabled_formats", $enabled_image_formats, Cache::PERMANENT, $config->getCacheTags());
188     }
189     return $enabled_image_formats;
190   }
191
192
193   /**
194    * Returns the enabled image file extensions, processing the config map.
195    *
196    * Results are cached for subsequent access. Saving the config will
197    * invalidate the cache.
198    *
199    * @return array
200    *   An associative array with file extensions as keys and their ImageMagick
201    *   format as values.
202    */
203   protected function resolveEnabledExtensions() {
204     if ($cache = $this->cache->get("imagemagick:enabled_extensions")) {
205       $extensions = $cache->data;
206     }
207     else {
208       // Get configured image formats.
209       $image_formats = $this->configFactory->get('imagemagick.settings')->get('image_formats');
210
211       // Get only enabled formats.
212       $enabled_image_formats = array_keys($this->resolveEnabledFormats());
213
214       // Apply defaults.
215       foreach ($enabled_image_formats as $format) {
216         if (isset($image_formats[$format]) && is_array($image_formats[$format])) {
217           $image_formats[$format] += [
218             'mime_type' => NULL,
219             'weight' => 0,
220             'exclude_extensions' => NULL,
221           ];
222         }
223       }
224
225       // Scans the enabled formats to determine enabled file extensions and
226       // their mapping to the internal Image/GraphicsMagick format.
227       $extensions = [];
228       $excluded_extensions = [];
229       foreach ($enabled_image_formats as $format) {
230         $format_extensions = $this->mimeTypeMapper->getExtensionsForMimeType($image_formats[$format]['mime_type']);
231         $weight_checked_extensions = [];
232         foreach ($format_extensions as $ext) {
233           if (!isset($extensions[$ext])) {
234             $weight_checked_extensions[$ext] = $format;
235           }
236           else {
237             // Extension is already present in the array, lower weight format
238             // prevails.
239             if ($image_formats[$format]['weight'] < $image_formats[$extensions[$ext]]['weight']) {
240               $weight_checked_extensions[$ext] = $format;
241             }
242           }
243         }
244         $extensions = array_merge($extensions, $weight_checked_extensions);
245         // Accumulate excluded extensions.
246         if ($image_formats[$format]['exclude_extensions']) {
247           $exclude_extensions_string = Unicode::strtolower(preg_replace('/\s+/', '', $image_formats[$format]['exclude_extensions']));
248           $excluded_extensions = array_merge($excluded_extensions, array_intersect($format_extensions, explode(',', $exclude_extensions_string)));
249         }
250       }
251
252       // Remove the excluded extensions.
253       $excluded_extensions = array_unique($excluded_extensions);
254       $excluded_extensions = array_combine($excluded_extensions, $excluded_extensions);
255       $extensions = array_diff_key($extensions, $excluded_extensions);
256
257       ksort($extensions);
258       $this->cache->set("imagemagick:enabled_extensions", $extensions, Cache::PERMANENT, $this->configFactory->get('imagemagick.settings')->getCacheTags());
259     }
260
261     return $extensions;
262   }
263
264 }