‪TYPO3CMS  ‪main
IconRegistry.php
Go to the documentation of this file.
1 <?php
2 
3 /*
4  * This file is part of the TYPO3 CMS project.
5  *
6  * It is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU General Public License, either version 2
8  * of the License, or any later version.
9  *
10  * For the full copyright and license information, please read the
11  * LICENSE.txt file that was distributed with this source code.
12  *
13  * The TYPO3 project - inspiring people to share!
14  */
15 
17 
26 
32 {
36  protected ‪$fullInitialized = false;
37 
41  protected ‪$tcaInitialized = false;
42 
46  protected ‪$flagsInitialized = false;
47 
51  protected ‪$backendIconsInitialized = false;
52 
58  protected ‪$icons = [];
59 
63  protected ‪$backendIconDeclaration = 'EXT:core/Resources/Public/Icons/T3Icons/icons.json';
64 
71  'png' => BitmapIconProvider::class,
72  'webp' => BitmapIconProvider::class,
73  'svg' => SvgIconProvider::class,
74  ];
75 
82  protected ‪$staticIcons = [
83 
90  ];
91 
97  protected ‪$fileExtensionMapping = [
98  'htm' => 'mimetypes-text-html',
99  'html' => 'mimetypes-text-html',
100  'css' => 'mimetypes-text-css',
101  'js' => 'mimetypes-text-js',
102  'csv' => 'mimetypes-text-csv',
103  'php' => 'mimetypes-text-php',
104  'php6' => 'mimetypes-text-php',
105  'php5' => 'mimetypes-text-php',
106  'php4' => 'mimetypes-text-php',
107  'php3' => 'mimetypes-text-php',
108  'inc' => 'mimetypes-text-php',
109  'ts' => 'mimetypes-text-ts',
110  'typoscript' => 'mimetypes-text-typoscript',
111  'txt' => 'mimetypes-text-text',
112  'class' => 'mimetypes-text-text',
113  'tmpl' => 'mimetypes-text-text',
114  'jpg' => 'mimetypes-media-image',
115  'jpeg' => 'mimetypes-media-image',
116  'gif' => 'mimetypes-media-image',
117  'png' => 'mimetypes-media-image',
118  'bmp' => 'mimetypes-media-image',
119  'tif' => 'mimetypes-media-image',
120  'tiff' => 'mimetypes-media-image',
121  'tga' => 'mimetypes-media-image',
122  'psd' => 'mimetypes-media-image',
123  'eps' => 'mimetypes-media-image',
124  'ai' => 'mimetypes-media-image',
125  'svg' => 'mimetypes-media-image',
126  'pcx' => 'mimetypes-media-image',
127  'avi' => 'mimetypes-media-video',
128  'mpg' => 'mimetypes-media-video',
129  'mpeg' => 'mimetypes-media-video',
130  'mov' => 'mimetypes-media-video',
131  'vimeo' => 'mimetypes-media-video-vimeo',
132  'youtube' => 'mimetypes-media-video-youtube',
133  'wav' => 'mimetypes-media-audio',
134  'mp3' => 'mimetypes-media-audio',
135  'ogg' => 'mimetypes-media-audio',
136  'flac' => 'mimetypes-media-audio',
137  'opus' => 'mimetypes-media-audio',
138  'mid' => 'mimetypes-media-audio',
139  'swf' => 'mimetypes-media-flash',
140  'swa' => 'mimetypes-media-flash',
141  'exe' => 'mimetypes-application',
142  'com' => 'mimetypes-application',
143  't3x' => 'mimetypes-compressed',
144  't3d' => 'mimetypes-compressed',
145  'zip' => 'mimetypes-compressed',
146  'tgz' => 'mimetypes-compressed',
147  'gz' => 'mimetypes-compressed',
148  'pdf' => 'mimetypes-pdf',
149  'doc' => 'mimetypes-word',
150  'dot' => 'mimetypes-word',
151  'docm' => 'mimetypes-word',
152  'docx' => 'mimetypes-word',
153  'dotm' => 'mimetypes-word',
154  'dotx' => 'mimetypes-word',
155  'sxw' => 'mimetypes-word',
156  'rtf' => 'mimetypes-word',
157  'xls' => 'mimetypes-excel',
158  'xlsm' => 'mimetypes-excel',
159  'xlsx' => 'mimetypes-excel',
160  'xltm' => 'mimetypes-excel',
161  'xltx' => 'mimetypes-excel',
162  'sxc' => 'mimetypes-excel',
163  'pps' => 'mimetypes-powerpoint',
164  'ppsx' => 'mimetypes-powerpoint',
165  'ppt' => 'mimetypes-powerpoint',
166  'pptm' => 'mimetypes-powerpoint',
167  'pptx' => 'mimetypes-powerpoint',
168  'potm' => 'mimetypes-powerpoint',
169  'potx' => 'mimetypes-powerpoint',
170  'mount' => 'apps-filetree-mount',
171  'folder' => 'apps-filetree-folder-default',
172  'default' => 'mimetypes-other-other',
173  ];
174 
180  protected ‪$mimeTypeMapping = [
181  'video/*' => 'mimetypes-media-video',
182  'audio/*' => 'mimetypes-media-audio',
183  'image/*' => 'mimetypes-media-image',
184  'text/*' => 'mimetypes-text-text',
185  ];
186 
190  protected $iconAliases = [];
191 
205  protected $deprecatedIcons = [];
206 
210  protected $defaultIconIdentifier = 'default-not-found';
211 
215  protected $cache;
216 
217  private string $cacheIdentifier;
218 
219  public function __construct(‪FrontendInterface $assetsCache, string $cacheIdentifier)
220  {
221  $this->‪cache = $assetsCache;
222  $this->‪cacheIdentifier = $cacheIdentifier;
223  $this->‪initialize();
224  }
225 
231  protected function ‪initialize()
232  {
233  if (!$this->backendIconsInitialized) {
234  $this->‪getCachedBackendIcons();
235  }
236  if (!$this->tcaInitialized && !empty(‪$GLOBALS['TCA'])) {
237  $this->‪registerTCAIcons();
238  }
239  if (!$this->flagsInitialized) {
240  $this->‪getCachedFlagIcons();
241  }
242  if ($this->backendIconsInitialized
243  && $this->tcaInitialized
244  && $this->flagsInitialized) {
245  $this->fullInitialized = true;
246  }
247  }
248 
252  public function ‪getBackendIconsCacheIdentifier(): string
253  {
254  return $this->cacheIdentifier;
255  }
256 
260  protected function ‪getCachedBackendIcons()
261  {
262  $cacheIdentifier = $this->‪getBackendIconsCacheIdentifier();
263  $cacheEntry = $this->‪cache->get($cacheIdentifier);
264 
265  if ($cacheEntry !== false) {
266  $this->icons = $cacheEntry;
267  } else {
269  // all found icons should now be present, for historic reasons now merge w/ the statically declared icons
270  $this->icons = array_merge($this->icons, $this->iconAliases, $this->staticIcons);
271  $this->‪cache->set($cacheIdentifier, $this->icons);
272  }
273  // if there's now at least one icon registered, consider it successful
274  if (is_array($this->icons) && (count($this->icons) >= count($this->staticIcons))) {
275  $this->backendIconsInitialized = true;
276  }
277  }
278 
282  protected function ‪registerBackendIcons(): void
283  {
284  ‪$dir = dirname($this->backendIconDeclaration);
285  $absoluteIconDeclarationPath = GeneralUtility::getFileAbsFileName($this->backendIconDeclaration);
286  $json = json_decode(file_get_contents($absoluteIconDeclarationPath) ?: '', true);
287  foreach ($json['icons'] ?? [] as $declaration) {
288  $iconOptions = [
289  'sprite' => ‪$dir . '/' . $declaration['sprite'],
290  'source' => ‪$dir . '/' . $declaration['svg'],
291  ];
292  // kind of hotfix for now, needs a nicer concept later
293  if ($declaration['category'] === 'spinner') {
294  $iconOptions['spinning'] = true;
295  }
296 
297  $this->‪registerIcon(
298  $declaration['identifier'],
299  SvgSpriteIconProvider::class,
300  $iconOptions
301  );
302  }
303 
304  foreach ($json['aliases'] as $alias => ‪$identifier) {
305  $this->‪registerAlias($alias, ‪$identifier);
306  }
307  }
308 
313  public function ‪isRegistered(‪$identifier)
314  {
315  if (!$this->fullInitialized) {
316  $this->‪initialize();
317  }
318  return isset($this->icons[‪$identifier]);
319  }
320 
325  public function ‪isDeprecated(‪$identifier)
326  {
327  return isset($this->deprecatedIcons[‪$identifier]);
328  }
329 
333  public function ‪getDefaultIconIdentifier()
334  {
335  return $this->defaultIconIdentifier;
336  }
337 
346  public function ‪registerIcon(‪$identifier, $iconProviderClassName, array $options = [])
347  {
348  if (!in_array(IconProviderInterface::class, class_implements($iconProviderClassName) ?: [], true)) {
349  throw new \InvalidArgumentException('An IconProvider must implement '
350  . IconProviderInterface::class, 1437425803);
351  }
352  $this->icons[‪$identifier] = [
353  'provider' => $iconProviderClassName,
354  'options' => $options,
355  ];
356 
357  if (isset($options['deprecated'])) {
358  $this->deprecatedIcons[‪$identifier] = $options['deprecated'];
359  }
360  }
361 
370  public function ‪registerAlias($alias, ‪$identifier)
371  {
372  if (!isset($this->icons[‪$identifier])) {
373  throw new \InvalidArgumentException('No icon with identifier "' . ‪$identifier . '" registered.', 1602251838);
374  }
375  $this->iconAliases[$alias] = $this->icons[‪$identifier];
376  }
377 
384  public function ‪registerFileExtension($fileExtension, $iconIdentifier)
385  {
386  $this->fileExtensionMapping[$fileExtension] = $iconIdentifier;
387  }
388 
395  public function ‪registerMimeTypeIcon($mimeType, $iconIdentifier)
396  {
397  $this->mimeTypeMapping[$mimeType] = $iconIdentifier;
398  }
399 
408  {
409  if (!$this->fullInitialized) {
410  $this->‪initialize();
411  }
412  if ($this->‪isDeprecated(‪$identifier)) {
413  $deprecation = $this->deprecatedIcons[‪$identifier];
414  $since = $deprecation['since'] ?? null;
415  $until = $deprecation['until'] ?? null;
416  $replacement = $deprecation['replacement'] ?? null;
417 
418  $message = 'The icon "%s" is deprecated%s%s.';
419  $arguments = [
421  $since !== null ? ' since ' . $since : '',
422  $until !== null ? ' and will be removed in ' . $until : '',
423  ];
424 
425  if ($replacement) {
426  $message .= ' Please use "%s" instead.';
427  $arguments[] = $replacement;
428  }
429  trigger_error(vsprintf($message, $arguments), E_USER_DEPRECATED);
430  }
431  if (!$this->‪isRegistered(‪$identifier)) {
432  throw new ‪Exception('Icon with identifier "' . ‪$identifier . '" is not registered"', 1437425804);
433  }
434  return $this->icons[‪$identifier];
435  }
436 
440  public function ‪getAllRegisteredIconIdentifiers()
441  {
442  if (!$this->fullInitialized) {
443  $this->‪initialize();
444  }
445  return array_keys($this->icons);
446  }
447 
448  public function ‪getDeprecatedIcons(): array
449  {
450  return $this->deprecatedIcons;
451  }
452 
457  public function ‪getIconIdentifierForFileExtension($fileExtension)
458  {
459  // If the file extension is not valid use the default one
460  if (!isset($this->fileExtensionMapping[$fileExtension])) {
461  $fileExtension = 'default';
462  }
463  return $this->fileExtensionMapping[$fileExtension];
464  }
465 
472  public function ‪getIconIdentifierForMimeType($mimeType)
473  {
474  if (!isset($this->mimeTypeMapping[$mimeType])) {
475  return null;
476  }
477  return $this->mimeTypeMapping[$mimeType];
478  }
479 
483  protected function ‪registerTCAIcons()
484  {
485  $resultArray = [];
486 
487  $tcaTables = array_keys(‪$GLOBALS['TCA'] ?? []);
488  // check every table in the TCA, if an icon is needed
489  foreach ($tcaTables as $tableName) {
490  // This method is only needed for TCA tables where typeicon_classes are not configured
491  $iconIdentifier = 'tcarecords-' . $tableName . '-default';
492  if (
493  isset($this->icons[$iconIdentifier])
494  || !isset(‪$GLOBALS['TCA'][$tableName]['ctrl']['iconfile'])
495  ) {
496  continue;
497  }
498  $resultArray[$iconIdentifier] = ‪$GLOBALS['TCA'][$tableName]['ctrl']['iconfile'];
499  }
500 
501  foreach ($resultArray as $iconIdentifier => $iconFilePath) {
502  $iconProviderClass = $this->‪detectIconProvider($iconFilePath);
503  $this->icons[$iconIdentifier] = [
504  'provider' => $iconProviderClass,
505  'options' => [
506  'source' => $iconFilePath,
507  ],
508  ];
509  }
510  $this->tcaInitialized = true;
511  }
512 
513  protected function ‪getCachedFlagIcons(): void
514  {
515  $cacheIdentifier = $this->‪getBackendIconsCacheIdentifier() . '_flags';
516  $cacheEntry = $this->‪cache->get($cacheIdentifier);
517 
518  if ($cacheEntry === false) {
519  $cacheEntry = $this->‪registerFlags();
520  $this->‪cache->set($cacheIdentifier, $cacheEntry);
521  }
522  $this->icons = array_merge($this->icons, $cacheEntry);
523  // if there's now at least one icon registered, consider it successful
524  if (is_array($cacheEntry) && $cacheEntry !== []) {
525  $this->flagsInitialized = true;
526  }
527  }
528 
532  protected function ‪registerFlags(): array
533  {
534  $iconFolder = 'EXT:core/Resources/Public/Icons/Flags/';
535  $folderPath = GeneralUtility::getFileAbsFileName($iconFolder);
536  $flagIcons = [];
537 
538  if ($handle = opendir($folderPath)) {
539  while (($file = readdir($handle)) !== false) {
540  $fileInfo = pathinfo($folderPath . $file);
541  if ($fileInfo['extension'] !== 'webp') {
542  continue;
543  }
544  $flagIcons['flags-' . strtolower($fileInfo['filename'])] = [
545  'provider' => BitmapIconProvider::class,
546  'options' => [
547  'source' => $iconFolder . $file,
548  ],
549  ];
550  }
551  closedir($handle);
552  }
553 
554  return $flagIcons;
555  }
556 
563  public function ‪detectIconProvider($iconReference)
564  {
565  if (str_ends_with(strtolower((string)$iconReference), 'svg')) {
566  return SvgIconProvider::class;
567  }
568  return BitmapIconProvider::class;
569  }
570 
571  public function ‪warmupCaches(CacheWarmupEvent $event): void
572  {
573  if ($event->hasGroup('system')) {
574  $backupIcons = ‪$this->icons;
575  $backupAliases = $this->iconAliases;
576  $this->icons = [];
577  $this->iconAliases = [];
578 
579  $this->‪registerBackendIcons();
580  // all found icons should now be present, for historic reasons now merge w/ the statically declared icons
581  $this->icons = array_merge($this->icons, $this->iconAliases, $this->staticIcons);
582  $this->‪cache->set($this->‪getBackendIconsCacheIdentifier(), $this->icons);
583 
584  $this->icons = $backupIcons;
585  $this->iconAliases = $backupAliases;
586  }
587  }
588 }
‪TYPO3\CMS\Core\Imaging\IconRegistry\$staticIcons
‪array $staticIcons
Definition: IconRegistry.php:74
‪TYPO3\CMS\Core\Imaging
Definition: Dimension.php:16
‪TYPO3\CMS\Core\Imaging\IconRegistry\registerMimeTypeIcon
‪registerMimeTypeIcon($mimeType, $iconIdentifier)
Definition: IconRegistry.php:381
‪TYPO3\CMS\Core\Imaging\IconRegistry\getIconIdentifierForMimeType
‪string null getIconIdentifierForMimeType($mimeType)
Definition: IconRegistry.php:458
‪TYPO3\CMS\Core\Imaging\IconRegistry\getIconIdentifierForFileExtension
‪string getIconIdentifierForFileExtension($fileExtension)
Definition: IconRegistry.php:443
‪TYPO3\CMS\Core\Imaging\IconRegistry\$icons
‪array $icons
Definition: IconRegistry.php:53
‪TYPO3\CMS\Core\Imaging\IconRegistry\getCachedBackendIcons
‪getCachedBackendIcons()
Definition: IconRegistry.php:246
‪TYPO3\CMS\Core\Imaging\IconRegistry\registerFlags
‪registerFlags()
Definition: IconRegistry.php:518
‪TYPO3\CMS\Core\Exception
Definition: Exception.php:21
‪TYPO3\CMS\Core\Imaging\IconRegistry\$backendIconsInitialized
‪bool $backendIconsInitialized
Definition: IconRegistry.php:47
‪TYPO3\CMS\Core\Imaging\IconRegistry\$tcaInitialized
‪bool $tcaInitialized
Definition: IconRegistry.php:39
‪TYPO3\CMS\Core\Exception
‪$dir
‪$dir
Definition: validateRstFiles.php:257
‪TYPO3\CMS\Core\Cache\Event\CacheWarmupEvent
Definition: CacheWarmupEvent.php:24
‪TYPO3\CMS\Core\Imaging\IconRegistry\$fileExtensionMapping
‪string[] $fileExtensionMapping
Definition: IconRegistry.php:88
‪TYPO3\CMS\Core\Imaging\IconProvider\BitmapIconProvider
Definition: BitmapIconProvider.php:27
‪TYPO3\CMS\Core\Imaging\IconRegistry\getDefaultIconIdentifier
‪string getDefaultIconIdentifier()
Definition: IconRegistry.php:319
‪TYPO3\CMS\Core\Imaging\IconRegistry\getDeprecatedIcons
‪getDeprecatedIcons()
Definition: IconRegistry.php:434
‪TYPO3\CMS\Core\Imaging\IconRegistry\$flagsInitialized
‪bool $flagsInitialized
Definition: IconRegistry.php:43
‪TYPO3\CMS\Core\Imaging\IconRegistry\isRegistered
‪bool isRegistered($identifier)
Definition: IconRegistry.php:299
‪TYPO3\CMS\Core\Imaging\IconRegistry\$mimeTypeMapping
‪string[] $mimeTypeMapping
Definition: IconRegistry.php:170
‪TYPO3\CMS\Core\Imaging\IconProvider\SvgSpriteIconProvider
Definition: SvgSpriteIconProvider.php:30
‪TYPO3\CMS\Core\Imaging\IconRegistry\isDeprecated
‪bool isDeprecated($identifier)
Definition: IconRegistry.php:311
‪TYPO3\CMS\Core\Imaging\IconRegistry\getIconConfigurationByIdentifier
‪mixed getIconConfigurationByIdentifier($identifier)
Definition: IconRegistry.php:393
‪TYPO3\CMS\Core\Imaging\IconRegistry\getAllRegisteredIconIdentifiers
‪array getAllRegisteredIconIdentifiers()
Definition: IconRegistry.php:426
‪TYPO3\CMS\Core\Imaging\IconRegistry\registerIcon
‪registerIcon($identifier, $iconProviderClassName, array $options=[])
Definition: IconRegistry.php:332
‪TYPO3\CMS\Core\Imaging\IconRegistry\getBackendIconsCacheIdentifier
‪getBackendIconsCacheIdentifier()
Definition: IconRegistry.php:238
‪TYPO3\CMS\Core\Imaging\IconRegistry
Definition: IconRegistry.php:32
‪TYPO3\CMS\Core\Imaging\IconRegistry\$backendIconDeclaration
‪string $backendIconDeclaration
Definition: IconRegistry.php:57
‪TYPO3\CMS\Core\Imaging\IconRegistry\registerFileExtension
‪registerFileExtension($fileExtension, $iconIdentifier)
Definition: IconRegistry.php:370
‪TYPO3\CMS\Core\Imaging\IconRegistry\$fullInitialized
‪bool $fullInitialized
Definition: IconRegistry.php:35
‪TYPO3\CMS\Core\Imaging\IconRegistry\warmupCaches
‪warmupCaches(CacheWarmupEvent $event)
Definition: IconRegistry.php:557
‪TYPO3\CMS\Core\Cache\Frontend\FrontendInterface
Definition: FrontendInterface.php:22
‪TYPO3\CMS\Core\Imaging\IconRegistry\cache
‪array< string, $iconAliases=array();protected array $deprecatedIcons=array();protected string $defaultIconIdentifier='default-not-found';protected FrontendInterface $cache;private string $cacheIdentifier;public function __construct(FrontendInterface $assetsCache, string $cacheIdentifier) { $this-> cache
Definition: IconRegistry.php:207
‪TYPO3\CMS\Core\Imaging\IconRegistry\getCachedFlagIcons
‪getCachedFlagIcons()
Definition: IconRegistry.php:499
‪TYPO3\CMS\Core\SingletonInterface
Definition: SingletonInterface.php:22
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Core\Imaging\IconRegistry\cacheIdentifier
‪$this cacheIdentifier
Definition: IconRegistry.php:208
‪TYPO3\CMS\Core\Imaging\IconRegistry\$backendIconAllowedExtensionsWithProvider
‪string[] $backendIconAllowedExtensionsWithProvider
Definition: IconRegistry.php:63
‪TYPO3\CMS\Core\Imaging\IconProvider\SvgIconProvider
Definition: SvgIconProvider.php:26
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Core\Imaging\IconRegistry\initialize
‪initialize()
Definition: IconRegistry.php:217
‪TYPO3\CMS\Core\Imaging\IconRegistry\detectIconProvider
‪string detectIconProvider($iconReference)
Definition: IconRegistry.php:549
‪TYPO3\CMS\Core\Imaging\IconRegistry\registerTCAIcons
‪registerTCAIcons()
Definition: IconRegistry.php:469
‪TYPO3\CMS\Core\Imaging\IconRegistry\registerAlias
‪registerAlias($alias, $identifier)
Definition: IconRegistry.php:356
‪TYPO3\CMS\Core\Imaging\IconRegistry\registerBackendIcons
‪registerBackendIcons()
Definition: IconRegistry.php:268
‪TYPO3\CMS\Webhooks\Message\$identifier
‪identifier readonly string $identifier
Definition: FileAddedMessage.php:37
‪TYPO3\CMS\Core\Cache\Event\CacheWarmupEvent\hasGroup
‪hasGroup(string $group)
Definition: CacheWarmupEvent.php:34