Passed
Push — master ( 705078...6d4d5d )
by
unknown
15:39
created

IconRegistry::getBackendIconsCacheIdentifier()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
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
16
namespace TYPO3\CMS\Core\Imaging;
17
18
use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface;
19
use TYPO3\CMS\Core\Core\Environment;
20
use TYPO3\CMS\Core\Exception;
21
use TYPO3\CMS\Core\Imaging\IconProvider\BitmapIconProvider;
22
use TYPO3\CMS\Core\Imaging\IconProvider\FontawesomeIconProvider;
23
use TYPO3\CMS\Core\Imaging\IconProvider\SvgIconProvider;
24
use TYPO3\CMS\Core\Imaging\IconProvider\SvgSpriteIconProvider;
25
use TYPO3\CMS\Core\Information\Typo3Version;
26
use TYPO3\CMS\Core\SingletonInterface;
27
use TYPO3\CMS\Core\Utility\GeneralUtility;
28
use TYPO3\CMS\Core\Utility\StringUtility;
29
30
/**
31
 * Class IconRegistry, which makes it possible to register custom icons
32
 * from within an extension.
33
 */
34
class IconRegistry implements SingletonInterface
35
{
36
    /**
37
     * @var bool
38
     */
39
    protected $fullInitialized = false;
40
41
    /**
42
     * @var bool
43
     */
44
    protected $tcaInitialized = false;
45
46
    /**
47
     * @var bool
48
     */
49
    protected $flagsInitialized = false;
50
51
    /**
52
     * @var bool
53
     */
54
    protected $moduleIconsInitialized = false;
55
56
    /**
57
     * @var bool
58
     */
59
    protected $backendIconsInitialized = false;
60
61
    /**
62
     * Registered icons
63
     *
64
     * @var array
65
     */
66
    protected $icons = [];
67
68
    /**
69
     * @var string
70
     */
71
    protected $backendIconDeclaration = 'EXT:core/Resources/Public/Icons/T3Icons/icons.json';
72
73
    /**
74
     * List of allowed icon file extensions with their Provider class
75
     *
76
     * @var string[]
77
     */
78
    protected $backendIconAllowedExtensionsWithProvider = [
79
        'png' => BitmapIconProvider::class,
80
        'svg' => SvgIconProvider::class
81
    ];
82
83
    /**
84
     * manually registered icons
85
     * hopefully obsolete one day
86
     *
87
     * @var array
88
     */
89
    protected $staticIcons = [
90
91
        /**
92
         * Important Information:
93
         *
94
         * Icons are maintained in an external repository, if new icons are needed
95
         * please request them at: https://github.com/typo3/typo3.icons/issues
96
         */
97
98
        // Apps
99
        'apps-pagetree-category-toggle-hide-checked' => [
100
            'provider' => FontawesomeIconProvider::class,
101
            'options' => [
102
                'name' => 'check-square'
103
            ]
104
        ],
105
106
        // Status
107
        'status-dialog-information' => [
108
            'provider' => FontawesomeIconProvider::class,
109
            'options' => [
110
                'name' => 'exclamation-circle'
111
            ]
112
        ],
113
        'status-dialog-ok' => [
114
            'provider' => FontawesomeIconProvider::class,
115
            'options' => [
116
                'name' => 'check-circle',
117
            ]
118
        ],
119
        'status-dialog-notification' => [
120
            'provider' => FontawesomeIconProvider::class,
121
            'options' => [
122
                'name' => 'exclamation-circle'
123
            ]
124
        ],
125
        'status-dialog-warning' => [
126
            'provider' => FontawesomeIconProvider::class,
127
            'options' => [
128
                'name' => 'exclamation-triangle'
129
            ]
130
        ],
131
        'status-dialog-error' => [
132
            'provider' => FontawesomeIconProvider::class,
133
            'options' => [
134
                'name' => 'exclamation-circle'
135
            ]
136
        ],
137
        'status-status-checked' => [
138
            'provider' => FontawesomeIconProvider::class,
139
            'options' => [
140
                'name' => 'check',
141
            ]
142
        ],
143
        'status-status-current' => [
144
            'provider' => FontawesomeIconProvider::class,
145
            'options' => [
146
                'name' => 'caret-right',
147
            ]
148
        ],
149
        'status-status-sorting-asc' => [
150
            'provider' => FontawesomeIconProvider::class,
151
            'options' => [
152
                'name' => 'caret-up',
153
            ]
154
        ],
155
        'status-status-sorting-desc' => [
156
            'provider' => FontawesomeIconProvider::class,
157
            'options' => [
158
                'name' => 'caret-down',
159
            ]
160
        ],
161
        'status-status-sorting-light-asc' => [
162
            'provider' => FontawesomeIconProvider::class,
163
            'options' => [
164
                'name' => 'caret-up',
165
            ]
166
        ],
167
        'status-status-sorting-light-desc' => [
168
            'provider' => FontawesomeIconProvider::class,
169
            'options' => [
170
                'name' => 'caret-down',
171
            ]
172
        ],
173
        'status-status-permission-granted' => [
174
            'provider' => FontawesomeIconProvider::class,
175
            'options' => [
176
                'name' => 'check',
177
            ]
178
        ],
179
        'status-status-permission-denied' => [
180
            'provider' => FontawesomeIconProvider::class,
181
            'options' => [
182
                'name' => 'times',
183
            ]
184
        ],
185
186
        // Empty
187
        'empty-empty' => [
188
            'provider' => FontawesomeIconProvider::class,
189
            'options' => [
190
                'name' => 'empty-empty',
191
            ]
192
        ],
193
194
        // System Information
195
        'information-php-version' => [
196
            'provider' => FontawesomeIconProvider::class,
197
            'options' => [
198
                'name' => 'code'
199
            ]
200
        ],
201
        'information-database' =>  [
202
            'provider' => FontawesomeIconProvider::class,
203
            'options' => [
204
                'name' => 'database'
205
            ]
206
        ],
207
        'information-application-context' => [
208
            'provider' => FontawesomeIconProvider::class,
209
            'options' => [
210
                'name' => 'tasks'
211
            ]
212
        ],
213
        'information-composer-mode' => [
214
            'provider' => FontawesomeIconProvider::class,
215
            'options' => [
216
                'name' => 'music'
217
            ]
218
        ],
219
        'information-git' => [
220
            'provider' => FontawesomeIconProvider::class,
221
            'options' => [
222
                'name' => 'git'
223
            ]
224
        ],
225
        'information-webserver' => [
226
            'provider' => FontawesomeIconProvider::class,
227
            'options' => [
228
                'name' => 'server'
229
            ]
230
        ],
231
        'information-os-linux' => [
232
            'provider' => FontawesomeIconProvider::class,
233
            'options' => [
234
                'name' => 'linux'
235
            ]
236
        ],
237
        'information-os-apple' => [
238
            'provider' => FontawesomeIconProvider::class,
239
            'options' => [
240
                'name' => 'apple'
241
            ]
242
        ],
243
        'information-os-windows' => [
244
            'provider' => FontawesomeIconProvider::class,
245
            'options' => [
246
                'name' => 'windows'
247
            ]
248
        ],
249
250
        // Sysnote
251
        'sysnote-type-0' => [
252
            'provider' => FontawesomeIconProvider::class,
253
            'options' => [
254
                'name' => 'sticky-note-o'
255
            ]
256
        ],
257
        'sysnote-type-1' => [
258
            'provider' => FontawesomeIconProvider::class,
259
            'options' => [
260
                'name' => 'cog'
261
            ]
262
        ],
263
        'sysnote-type-2' => [
264
            'provider' => FontawesomeIconProvider::class,
265
            'options' => [
266
                'name' => 'code'
267
            ]
268
        ],
269
        'sysnote-type-3' => [
270
            'provider' => FontawesomeIconProvider::class,
271
            'options' => [
272
                'name' => 'thumb-tack'
273
            ]
274
        ],
275
        'sysnote-type-4' => [
276
            'provider' => FontawesomeIconProvider::class,
277
            'options' => [
278
                'name' => 'check-square'
279
            ]
280
        ]
281
    ];
282
283
    /**
284
     * Mapping of file extensions to mimetypes
285
     *
286
     * @var string[]
287
     */
288
    protected $fileExtensionMapping = [
289
        'htm' => 'mimetypes-text-html',
290
        'html' => 'mimetypes-text-html',
291
        'css' => 'mimetypes-text-css',
292
        'js' => 'mimetypes-text-js',
293
        'csv' => 'mimetypes-text-csv',
294
        'php' => 'mimetypes-text-php',
295
        'php6' => 'mimetypes-text-php',
296
        'php5' => 'mimetypes-text-php',
297
        'php4' => 'mimetypes-text-php',
298
        'php3' => 'mimetypes-text-php',
299
        'inc' => 'mimetypes-text-php',
300
        'ts' => 'mimetypes-text-ts',
301
        'typoscript' => 'mimetypes-text-typoscript',
302
        'txt' => 'mimetypes-text-text',
303
        'class' => 'mimetypes-text-text',
304
        'tmpl' => 'mimetypes-text-text',
305
        'jpg' => 'mimetypes-media-image',
306
        'jpeg' => 'mimetypes-media-image',
307
        'gif' => 'mimetypes-media-image',
308
        'png' => 'mimetypes-media-image',
309
        'bmp' => 'mimetypes-media-image',
310
        'tif' => 'mimetypes-media-image',
311
        'tiff' => 'mimetypes-media-image',
312
        'tga' => 'mimetypes-media-image',
313
        'psd' => 'mimetypes-media-image',
314
        'eps' => 'mimetypes-media-image',
315
        'ai' => 'mimetypes-media-image',
316
        'svg' => 'mimetypes-media-image',
317
        'pcx' => 'mimetypes-media-image',
318
        'avi' => 'mimetypes-media-video',
319
        'mpg' => 'mimetypes-media-video',
320
        'mpeg' => 'mimetypes-media-video',
321
        'mov' => 'mimetypes-media-video',
322
        'vimeo' => 'mimetypes-media-video-vimeo',
323
        'youtube' => 'mimetypes-media-video-youtube',
324
        'wav' => 'mimetypes-media-audio',
325
        'mp3' => 'mimetypes-media-audio',
326
        'ogg' => 'mimetypes-media-audio',
327
        'flac' => 'mimetypes-media-audio',
328
        'opus' => 'mimetypes-media-audio',
329
        'mid' => 'mimetypes-media-audio',
330
        'swf' => 'mimetypes-media-flash',
331
        'swa' => 'mimetypes-media-flash',
332
        'exe' => 'mimetypes-application',
333
        'com' => 'mimetypes-application',
334
        't3x' => 'mimetypes-compressed',
335
        't3d' => 'mimetypes-compressed',
336
        'zip' => 'mimetypes-compressed',
337
        'tgz' => 'mimetypes-compressed',
338
        'gz' => 'mimetypes-compressed',
339
        'pdf' => 'mimetypes-pdf',
340
        'doc' => 'mimetypes-word',
341
        'dot' => 'mimetypes-word',
342
        'docm' => 'mimetypes-word',
343
        'docx' => 'mimetypes-word',
344
        'dotm' => 'mimetypes-word',
345
        'dotx' => 'mimetypes-word',
346
        'sxw' => 'mimetypes-word',
347
        'rtf' => 'mimetypes-word',
348
        'xls' => 'mimetypes-excel',
349
        'xlsm' => 'mimetypes-excel',
350
        'xlsx' => 'mimetypes-excel',
351
        'xltm' => 'mimetypes-excel',
352
        'xltx' => 'mimetypes-excel',
353
        'sxc' => 'mimetypes-excel',
354
        'pps' => 'mimetypes-powerpoint',
355
        'ppsx' => 'mimetypes-powerpoint',
356
        'ppt' => 'mimetypes-powerpoint',
357
        'pptm' => 'mimetypes-powerpoint',
358
        'pptx' => 'mimetypes-powerpoint',
359
        'potm' => 'mimetypes-powerpoint',
360
        'potx' => 'mimetypes-powerpoint',
361
        'mount' => 'apps-filetree-mount',
362
        'folder' => 'apps-filetree-folder-default',
363
        'default' => 'mimetypes-other-other',
364
    ];
365
366
    /**
367
     * Mapping of mime types to icons
368
     *
369
     * @var string[]
370
     */
371
    protected $mimeTypeMapping = [
372
        'video/*' => 'mimetypes-media-video',
373
        'audio/*' => 'mimetypes-media-audio',
374
        'image/*' => 'mimetypes-media-image',
375
        'text/*' => 'mimetypes-text-text',
376
    ];
377
378
    /**
379
     * @var array<string, string>
380
     */
381
    protected $iconAliases = [];
382
383
    /**
384
     * Array of deprecated icons, add deprecated icons to this array and remove it from registry
385
     * - Index of this array contains the deprecated icon
386
     * - Value of each entry may contain a possible new identifier
387
     *
388
     * Example:
389
     * [
390
     *   'deprecated-icon-identifier' => 'new-icon-identifier',
391
     *   'another-deprecated-identifier' => null,
392
     * ]
393
     *
394
     * @var array
395
     * @deprecated These icons will be removed in TYPO3 v12
396
     */
397
    protected $deprecatedIcons = [];
398
399
    /**
400
     * @var string
401
     */
402
    protected $defaultIconIdentifier = 'default-not-found';
403
404
    /**
405
     * @var FrontendInterface
406
     */
407
    protected $cache;
408
409
    public function __construct(FrontendInterface $assetsCache)
410
    {
411
        $this->cache = $assetsCache;
412
        $this->initialize();
413
    }
414
415
    /**
416
     * Initialize the registry
417
     * This method can be called multiple times, depending on initialization status.
418
     * In some cases e.g. TCA is not available, the method must be called multiple times.
419
     */
420
    protected function initialize()
421
    {
422
        if (!$this->backendIconsInitialized) {
423
            $this->getCachedBackendIcons();
424
        }
425
        if (!$this->tcaInitialized && !empty($GLOBALS['TCA'])) {
426
            $this->registerTCAIcons();
427
        }
428
        if (!$this->moduleIconsInitialized && !empty($GLOBALS['TBE_MODULES'])) {
429
            $this->registerModuleIcons();
430
        }
431
        if (!$this->flagsInitialized) {
432
            $this->registerFlags();
433
        }
434
        if ($this->backendIconsInitialized
435
            && $this->tcaInitialized
436
            && $this->moduleIconsInitialized
437
            && $this->flagsInitialized) {
438
            $this->fullInitialized = true;
439
        }
440
    }
441
442
    protected function getBackendIconsCacheIdentifier(): string
443
    {
444
        return 'BackendIcons_' . sha1((string)(new Typo3Version()) . Environment::getProjectPath() . 'BackendIcons');
445
    }
446
447
    /**
448
     * Retrieve the icons from cache render them when not cached yet
449
     */
450
    protected function getCachedBackendIcons()
451
    {
452
        $cacheIdentifier = $this->getBackendIconsCacheIdentifier();
453
        $cacheEntry = $this->cache->get($cacheIdentifier);
454
455
        if ($cacheEntry !== false) {
456
            $this->icons = $cacheEntry;
457
        } else {
458
            $this->registerBackendIcons();
459
            // all found icons should now be present, for historic reasons now merge w/ the statically declared icons
460
            $this->icons = array_merge($this->icons, $this->iconAliases, $this->staticIcons);
461
            $this->cache->set($cacheIdentifier, $this->icons);
462
        }
463
        // if there's now at least one icon registered, consider it successful
464
        if (is_array($this->icons) && (count($this->icons) >= count($this->staticIcons))) {
465
            $this->backendIconsInitialized = true;
466
        }
467
    }
468
469
    /**
470
     * Automatically find and register the core backend icons
471
     */
472
    protected function registerBackendIcons(): void
473
    {
474
        $dir = dirname($this->backendIconDeclaration);
475
        $absoluteIconDeclarationPath = GeneralUtility::getFileAbsFileName($this->backendIconDeclaration);
476
        $json = json_decode(file_get_contents($absoluteIconDeclarationPath), true);
477
        foreach ($json['icons'] ?? [] as $declaration) {
478
            $iconOptions = [
479
                'sprite' => $dir . '/' . $declaration['sprite'],
480
                'source' => $dir . '/' . $declaration['svg'],
481
            ];
482
            // kind of hotfix for now, needs a nicer concept later
483
            if ($declaration['category'] === 'spinner') {
484
                $iconOptions['spinning'] = true;
485
            }
486
487
            $this->registerIcon(
488
                $declaration['identifier'],
489
                SvgSpriteIconProvider::class,
490
                $iconOptions
491
            );
492
        }
493
494
        foreach ($json['aliases'] as $alias => $identifier) {
495
            $this->registerAlias($alias, $identifier);
496
        }
497
    }
498
499
    /**
500
     * @param string $identifier
501
     * @return bool
502
     */
503
    public function isRegistered($identifier)
504
    {
505
        if (!$this->fullInitialized) {
506
            $this->initialize();
507
        }
508
        return isset($this->icons[$identifier]);
509
    }
510
511
    /**
512
     * @param string $identifier
513
     * @return bool
514
     */
515
    public function isDeprecated($identifier)
516
    {
517
        return isset($this->deprecatedIcons[$identifier]);
518
    }
519
520
    /**
521
     * @return string
522
     */
523
    public function getDefaultIconIdentifier()
524
    {
525
        return $this->defaultIconIdentifier;
526
    }
527
528
    /**
529
     * Registers an icon to be available inside the Icon Factory
530
     *
531
     * @param string $identifier
532
     * @param string $iconProviderClassName
533
     * @param array $options
534
     *
535
     * @throws \InvalidArgumentException
536
     */
537
    public function registerIcon($identifier, $iconProviderClassName, array $options = [])
538
    {
539
        if (!in_array(IconProviderInterface::class, class_implements($iconProviderClassName), true)) {
540
            throw new \InvalidArgumentException('An IconProvider must implement '
541
                . IconProviderInterface::class, 1437425803);
542
        }
543
        $this->icons[$identifier] = [
544
            'provider' => $iconProviderClassName,
545
            'options' => $options
546
        ];
547
    }
548
549
    /**
550
     * Registers an icon to be available inside the Icon Factory
551
     *
552
     * @param string $alias
553
     * @param string $identifier
554
     *
555
     * @throws \InvalidArgumentException
556
     */
557
    public function registerAlias($alias, $identifier)
558
    {
559
        if (!isset($this->icons[$identifier])) {
560
            throw new \InvalidArgumentException('No icon with identifier "' . $identifier . '" registered.', 1602251838);
561
        }
562
        $this->iconAliases[$alias] = $this->icons[$identifier];
563
    }
564
565
    /**
566
     * Register an icon for a file extension
567
     *
568
     * @param string $fileExtension
569
     * @param string $iconIdentifier
570
     */
571
    public function registerFileExtension($fileExtension, $iconIdentifier)
572
    {
573
        $this->fileExtensionMapping[$fileExtension] = $iconIdentifier;
574
    }
575
576
    /**
577
     * Register an icon for a mime-type
578
     *
579
     * @param string $mimeType
580
     * @param string $iconIdentifier
581
     */
582
    public function registerMimeTypeIcon($mimeType, $iconIdentifier)
583
    {
584
        $this->mimeTypeMapping[$mimeType] = $iconIdentifier;
585
    }
586
587
    /**
588
     * Fetches the configuration provided by registerIcon()
589
     *
590
     * @param string $identifier the icon identifier
591
     * @return mixed
592
     * @throws Exception
593
     */
594
    public function getIconConfigurationByIdentifier($identifier)
595
    {
596
        if (!$this->fullInitialized) {
597
            $this->initialize();
598
        }
599
        if ($this->isDeprecated($identifier)) {
600
            $replacement = $this->deprecatedIcons[$identifier] ?? null;
601
            if (!empty($replacement)) {
602
                $message = 'The icon "%s" is deprecated since TYPO3 v9 and will be removed in TYPO3 v10.0. Please use "%s" instead.';
603
                $arguments = [$identifier, $replacement];
604
                $identifier = $replacement;
605
            } else {
606
                $message = 'The icon "%s" is deprecated since TYPO3 v9 and will be removed in TYPO3 v10.0.';
607
                $arguments = [$identifier];
608
            }
609
            trigger_error(vsprintf($message, $arguments), E_USER_DEPRECATED);
610
        }
611
        if (!$this->isRegistered($identifier)) {
612
            throw new Exception('Icon with identifier "' . $identifier . '" is not registered"', 1437425804);
613
        }
614
        return $this->icons[$identifier];
615
    }
616
617
    /**
618
     * @return array
619
     */
620
    public function getAllRegisteredIconIdentifiers()
621
    {
622
        if (!$this->fullInitialized) {
623
            $this->initialize();
624
        }
625
        return array_keys($this->icons);
626
    }
627
628
    /**
629
     * @return array
630
     */
631
    public function getDeprecatedIcons(): array
632
    {
633
        return $this->deprecatedIcons;
634
    }
635
636
    /**
637
     * @param string $fileExtension
638
     * @return string
639
     */
640
    public function getIconIdentifierForFileExtension($fileExtension)
641
    {
642
        // If the file extension is not valid use the default one
643
        if (!isset($this->fileExtensionMapping[$fileExtension])) {
644
            $fileExtension = 'default';
645
        }
646
        return $this->fileExtensionMapping[$fileExtension];
647
    }
648
649
    /**
650
     * Get iconIdentifier for given mimeType
651
     *
652
     * @param string $mimeType
653
     * @return string|null Returns null if no icon is registered for the mimeType
654
     */
655
    public function getIconIdentifierForMimeType($mimeType)
656
    {
657
        if (!isset($this->mimeTypeMapping[$mimeType])) {
658
            return null;
659
        }
660
        return $this->mimeTypeMapping[$mimeType];
661
    }
662
663
    /**
664
     * Calculates the cache identifier based on the current registry
665
     *
666
     * @return string
667
     * @internal
668
     */
669
    public function getCacheIdentifier(): string
670
    {
671
        if (!$this->fullInitialized) {
672
            $this->initialize();
673
        }
674
675
        return sha1((string)json_encode($this->icons));
676
    }
677
678
    /**
679
     * Load icons from TCA for each table and add them as "tcarecords-XX" to $this->icons
680
     */
681
    protected function registerTCAIcons()
682
    {
683
        $resultArray = [];
684
685
        $tcaTables = array_keys($GLOBALS['TCA'] ?? []);
686
        // check every table in the TCA, if an icon is needed
687
        foreach ($tcaTables as $tableName) {
688
            // This method is only needed for TCA tables where typeicon_classes are not configured
689
            $iconIdentifier = 'tcarecords-' . $tableName . '-default';
690
            if (
691
                isset($this->icons[$iconIdentifier])
692
                || !isset($GLOBALS['TCA'][$tableName]['ctrl']['iconfile'])
693
            ) {
694
                continue;
695
            }
696
            $resultArray[$iconIdentifier] = $GLOBALS['TCA'][$tableName]['ctrl']['iconfile'];
697
        }
698
699
        foreach ($resultArray as $iconIdentifier => $iconFilePath) {
700
            $iconProviderClass = $this->detectIconProvider($iconFilePath);
701
            $this->icons[$iconIdentifier] = [
702
                'provider' => $iconProviderClass,
703
                'options' => [
704
                    'source' => $iconFilePath
705
                ]
706
            ];
707
        }
708
        $this->tcaInitialized = true;
709
    }
710
711
    /**
712
     * Register module icons
713
     */
714
    protected function registerModuleIcons()
715
    {
716
        $moduleConfiguration = $GLOBALS['TBE_MODULES']['_configuration'] ?? [];
717
        foreach ($moduleConfiguration as $moduleKey => $singleModuleConfiguration) {
718
            $iconIdentifier = !empty($singleModuleConfiguration['iconIdentifier'])
719
                ? $singleModuleConfiguration['iconIdentifier']
720
                : null;
721
722
            if ($iconIdentifier !== null) {
723
                // iconIdentifier found, icon is registered, continue
724
                continue;
725
            }
726
727
            $iconPath = !empty($singleModuleConfiguration['icon'])
728
                ? $singleModuleConfiguration['icon']
729
                : null;
730
            $iconProviderClass = $this->detectIconProvider($iconPath);
731
            $iconIdentifier = 'module-icon-' . $moduleKey;
732
733
            $this->icons[$iconIdentifier] = [
734
                'provider' => $iconProviderClass,
735
                'options' => [
736
                    'source' => $iconPath
737
                ]
738
            ];
739
        }
740
        $this->moduleIconsInitialized = true;
741
    }
742
743
    /**
744
     * Register flags
745
     */
746
    protected function registerFlags()
747
    {
748
        $iconFolder = 'EXT:core/Resources/Public/Icons/Flags/';
749
        $files = [
750
            'AD', 'AE', 'AF', 'AG', 'AI', 'AL', 'AM', 'AN', 'AO', 'AQ', 'AR', 'AS', 'AT', 'AU', 'AW', 'AX', 'AZ',
751
            'BA', 'BB', 'BD', 'BE', 'BF', 'BG', 'BH', 'BI', 'BJ', 'BL', 'BM', 'BN', 'BO', 'BQ', 'BR', 'BS', 'BT', 'BV', 'BW', 'BY', 'BZ',
752
            'CA', 'CC', 'CD', 'CF', 'CG', 'CH', 'CI', 'CK', 'CL', 'CM', 'CN', 'CO', 'CR', 'CS', 'CU', 'CV', 'CW', 'CX', 'CY', 'CZ',
753
            'DE', 'DJ', 'DK', 'DM', 'DO', 'DZ',
754
            'EC', 'EE', 'EG', 'EH', 'ER', 'ES', 'ET', 'EU',
755
            'FI', 'FJ', 'FK', 'FM', 'FO', 'FR',
756
            'GA', 'GB-ENG', 'GB-NIR', 'GB-SCT', 'GB-WLS', 'GB', 'GD', 'GE', 'GF', 'GG', 'GH', 'GI', 'GL', 'GM', 'GN', 'GP', 'GQ', 'GR', 'GS', 'GT', 'GU', 'GW', 'GY',
757
            'HK', 'HM', 'HN', 'HR', 'HT', 'HU',
758
            'ID', 'IE', 'IL', 'IM', 'IN', 'IO', 'IQ', 'IR', 'IS', 'IT',
759
            'JE', 'JM', 'JO', 'JP',
760
            'KE', 'KG', 'KH', 'KI', 'KL', 'KM', 'KN', 'KP', 'KR', 'KW', 'KY', 'KZ',
761
            'LA', 'LB', 'LC', 'LI', 'LK', 'LR', 'LS', 'LT', 'LU', 'LV', 'LY',
762
            'MA', 'MC', 'MD', 'ME', 'MF', 'MG', 'MH', 'MI', 'MK', 'ML', 'MM', 'MN', 'MO', 'MP', 'MQ', 'MR', 'MS', 'MT', 'MU', 'MV', 'MW', 'MX', 'MY', 'MZ',
763
            'NA', 'NC', 'NE', 'NF', 'NG', 'NI', 'NL', 'NO', 'NP', 'NR', 'NU', 'NZ',
764
            'OM',
765
            'PA', 'PE', 'PF', 'PG', 'PH', 'PK', 'PL', 'PM', 'PN', 'PR', 'PS', 'PT', 'PW', 'PY',
766
            'QA', 'QC',
767
            'RE', 'RO', 'RS', 'RU', 'RW',
768
            'SA', 'SB', 'SC', 'SD', 'SE', 'SG', 'SH', 'SI', 'SJ', 'SK', 'SL', 'SM', 'SN', 'SO', 'SR', 'SS', 'ST', 'SV', 'SX', 'SY', 'SZ',
769
            'TC', 'TD', 'TF', 'TG', 'TH', 'TJ', 'TK', 'TL', 'TM', 'TN', 'TO', 'TR', 'TT', 'TV', 'TW', 'TZ',
770
            'UA', 'UG', 'UM', 'US', 'UY', 'UZ',
771
            'VA', 'VC', 'VE', 'VG', 'VI', 'VN', 'VU',
772
            'WF', 'WS',
773
            'YE', 'YT',
774
            'ZA', 'ZM', 'ZW',
775
            // Special Flags
776
            'catalonia',
777
            'multiple',
778
            'en-us-gb'
779
        ];
780
        foreach ($files as $file) {
781
            $identifier = strtolower($file);
782
            $this->icons['flags-' . $identifier] = [
783
                'provider' => BitmapIconProvider::class,
784
                'options' => [
785
                    'source' => $iconFolder . $file . '.png'
786
                ]
787
            ];
788
        }
789
        $this->flagsInitialized = true;
790
    }
791
792
    /**
793
     * Detect the IconProvider of an icon
794
     *
795
     * @param string $iconReference
796
     * @return string
797
     */
798
    public function detectIconProvider($iconReference)
799
    {
800
        if (StringUtility::endsWith(strtolower($iconReference), 'svg')) {
801
            return SvgIconProvider::class;
802
        }
803
        return BitmapIconProvider::class;
804
    }
805
}
806