From e6969ac359229924e793cf3ed6e995fba29c8787 Mon Sep 17 00:00:00 2001 From: mondrake <28163-mondrake@users.noreply.drupalcode.org> Date: Tue, 17 Dec 2024 10:40:43 +0000 Subject: [PATCH] Issue #3494318: Update map --- composer.json | 2 +- resources/drupal_map_build.yml | 1 + src/Form/SettingsForm.php | 18 ++- src/Map/DrupalMap.php | 190 +++++++++++++++++++++++++--- src/MimeMapManager.php | 75 +++++++++-- src/MimeMapManagerInterface.php | 16 +++ tests/src/Kernel/SophronApiTest.php | 7 + 7 files changed, 280 insertions(+), 29 deletions(-) diff --git a/composer.json b/composer.json index 83a021c..a84d6fd 100644 --- a/composer.json +++ b/composer.json @@ -4,7 +4,7 @@ "description": "Provides an extensive MIME types management API", "require": { "drupal/core": "^10.2 || ^11", - "fileeye/mimemap": "^2.2" + "fileeye/mimemap": "^2.2.1" }, "autoload": { "psr-4": { diff --git a/resources/drupal_map_build.yml b/resources/drupal_map_build.yml index 62bc8d5..95d0968 100644 --- a/resources/drupal_map_build.yml +++ b/resources/drupal_map_build.yml @@ -325,3 +325,4 @@ - [setExtensionDefaultType, [wav, audio/x-wav]] - [setExtensionDefaultType, [odb, application/vnd.oasis.opendocument.database]] - [setExtensionDefaultType, [sds, application/vnd.stardivision.chart]] + - [setExtensionDefaultType, [sct, text/scriptlet]] diff --git a/src/Form/SettingsForm.php b/src/Form/SettingsForm.php index 8d392ea..daf6f28 100644 --- a/src/Form/SettingsForm.php +++ b/src/Form/SettingsForm.php @@ -168,7 +168,16 @@ class SettingsForm extends ConfigFormBase { } // Mapping gaps. - if ($gaps = $this->determineMapGaps()) { + // @todo BC starts. Resolve in sophron:3.0.0. + if (method_exists($this->mimeMapManager, 'determineMapGaps')) { + $gaps = $this->mimeMapManager->determineMapGaps($this->mimeMapManager->getMapClass()); + } + else { + // @phpstan-ignore method.deprecated + $gaps = $this->determineMapGaps(); + } + // @todo BC ends. + if ($gaps !== []) { $form['mapping']['gaps'] = [ '#type' => 'details', '#collapsible' => TRUE, @@ -317,8 +326,15 @@ class SettingsForm extends ConfigFormBase { * @return array * An array of simple arrays, each having a file extension, its Drupal MIME * type guess, and a gap information. + * + * @deprecated in sophron:2.2.0 and is removed from sophron:3.0.0. Use + * MimeMapManager::determineMapGaps() instead. + * + * @see https://www.drupal.org/project/sophron/issues/3494318 */ protected function determineMapGaps(): array { + @trigger_error(__METHOD__ . '() is deprecated in sophron:2.2.0 and is removed from sophron:3.0.0. Use MimeMapManager::determineMapGaps() instead. See https://www.drupal.org/project/sophron/issues/3494318', E_USER_DEPRECATED); + $core_extended_guesser = new CoreExtensionMimeTypeGuesserExtended(); $extensions = $core_extended_guesser->listExtensions(); diff --git a/src/Map/DrupalMap.php b/src/Map/DrupalMap.php index 12072f3..8b4af07 100644 --- a/src/Map/DrupalMap.php +++ b/src/Map/DrupalMap.php @@ -3259,7 +3259,6 @@ class DrupalMap extends AbstractMap { 5 => 'efi', 6 => 'ocx', 7 => 'sys', - 8 => 'lib', ), ), 'application/vnd.mif' => @@ -4193,7 +4192,7 @@ class DrupalMap extends AbstractMap { array ( 'desc' => array ( - 0 => 'OpenOffice.org extension', + 0 => 'LibreOffice extension', ), 'e' => array ( @@ -4652,7 +4651,10 @@ class DrupalMap extends AbstractMap { ), 'e' => array ( - 0 => 'sqsh', + 0 => 'sfs', + 1 => 'sqfs', + 2 => 'sqsh', + 3 => 'squashfs', ), ), 'application/vnd.stardivision.calc' => @@ -4773,7 +4775,7 @@ class DrupalMap extends AbstractMap { array ( 'desc' => array ( - 0 => 'LibreOffice Calc spreadsheet', + 0 => 'OpenOffice.org 1.0 Calc spreadsheet', ), 'e' => array ( @@ -4784,7 +4786,7 @@ class DrupalMap extends AbstractMap { array ( 'desc' => array ( - 0 => 'LibreOffice Calc template', + 0 => 'OpenOffice.org 1.0 Calc template', ), 'e' => array ( @@ -4795,7 +4797,7 @@ class DrupalMap extends AbstractMap { array ( 'desc' => array ( - 0 => 'LibreOffice Draw drawing', + 0 => 'OpenOffice.org 1.0 Draw drawing', ), 'e' => array ( @@ -4806,7 +4808,7 @@ class DrupalMap extends AbstractMap { array ( 'desc' => array ( - 0 => 'LibreOffice Draw template', + 0 => 'OpenOffice.org 1.0 Draw template', ), 'e' => array ( @@ -4817,7 +4819,7 @@ class DrupalMap extends AbstractMap { array ( 'desc' => array ( - 0 => 'LibreOffice Impress presentation', + 0 => 'OpenOffice.org 1.0 Impress presentation', ), 'e' => array ( @@ -4828,7 +4830,7 @@ class DrupalMap extends AbstractMap { array ( 'desc' => array ( - 0 => 'LibreOffice Impress template', + 0 => 'OpenOffice.org 1.0 Impress template', ), 'e' => array ( @@ -4839,7 +4841,7 @@ class DrupalMap extends AbstractMap { array ( 'desc' => array ( - 0 => 'LibreOffice Math formula', + 0 => 'OpenOffice.org 1.0 Math formula', ), 'e' => array ( @@ -4850,7 +4852,7 @@ class DrupalMap extends AbstractMap { array ( 'desc' => array ( - 0 => 'LibreOffice Writer document', + 0 => 'OpenOffice.org 1.0 Writer document', ), 'e' => array ( @@ -4861,7 +4863,7 @@ class DrupalMap extends AbstractMap { array ( 'desc' => array ( - 0 => 'LibreOffice Writer global document', + 0 => 'OpenOffice.org 1.0 Writer global document', ), 'e' => array ( @@ -4872,7 +4874,7 @@ class DrupalMap extends AbstractMap { array ( 'desc' => array ( - 0 => 'LibreOffice Writer template', + 0 => 'OpenOffice.org 1.0 Writer template', ), 'e' => array ( @@ -5424,6 +5426,7 @@ class DrupalMap extends AbstractMap { array ( 0 => 'a', 1 => 'ar', + 2 => 'lib', ), ), 'application/x-arj' => @@ -7877,6 +7880,19 @@ class DrupalMap extends AbstractMap { 0 => 'pce', ), ), + 'application/x-pcapng' => + array ( + 'desc' => + array ( + 0 => 'PCAPNG packet capture', + 1 => 'PCAPNG: PCAP Next Generation', + ), + 'e' => + array ( + 0 => 'pcapng', + 1 => 'ntar', + ), + ), 'application/x-perl' => array ( 'a' => @@ -11315,6 +11331,14 @@ class DrupalMap extends AbstractMap { ), 'image/vnd.fpx' => array ( + 'a' => + array ( + 0 => 'image/x-fpx', + ), + 'desc' => + array ( + 0 => 'FlashPix image', + ), 'e' => array ( 0 => 'fpx', @@ -11759,6 +11783,19 @@ class DrupalMap extends AbstractMap { 2 => 'jpc', ), ), + 'image/x-kiss-cel' => + array ( + 'desc' => + array ( + 0 => 'KiSS cel', + 1 => 'KiSS: Kisekae Set System', + ), + 'e' => + array ( + 0 => 'cel', + 1 => 'kcf', + ), + ), 'image/x-kodak-dcr' => array ( 'desc' => @@ -11936,6 +11973,17 @@ class DrupalMap extends AbstractMap { 0 => 'pef', ), ), + 'image/x-pfm' => + array ( + 'desc' => + array ( + 0 => 'Portable FloatMap', + ), + 'e' => + array ( + 0 => 'pfm', + ), + ), 'image/x-photo-cd' => array ( 'desc' => @@ -12011,6 +12059,17 @@ class DrupalMap extends AbstractMap { 0 => 'ppm', ), ), + 'image/x-pxr' => + array ( + 'desc' => + array ( + 0 => 'Pixar raster', + ), + 'e' => + array ( + 0 => 'pxr', + ), + ), 'image/x-quicktime' => array ( 'desc' => @@ -12034,6 +12093,18 @@ class DrupalMap extends AbstractMap { 0 => 'rgb', ), ), + 'image/x-sct' => + array ( + 'desc' => + array ( + 0 => 'Scitex CT', + 1 => 'CT: Continuous Tone', + ), + 'e' => + array ( + 0 => 'sct', + ), + ), 'image/x-sgi' => array ( 'desc' => @@ -12453,7 +12524,8 @@ class DrupalMap extends AbstractMap { 0 => 'ics', 1 => 'ifb', 2 => 'vcs', - 3 => 'icz', + 3 => 'icalendar', + 4 => 'icz', ), ), 'text/css' => @@ -12986,6 +13058,10 @@ class DrupalMap extends AbstractMap { ), 'text/x-asm' => array ( + 'desc' => + array ( + 0 => 'Assembly code', + ), 'e' => array ( 0 => 's', @@ -13739,6 +13815,17 @@ class DrupalMap extends AbstractMap { 1 => 'nimble', ), ), + 'text/x-nix' => + array ( + 'desc' => + array ( + 0 => 'Nix source code', + ), + 'e' => + array ( + 0 => 'nix', + ), + ), 'text/x-objc++src' => array ( 'desc' => @@ -16387,6 +16474,13 @@ class DrupalMap extends AbstractMap { 0 => 'chemical/x-cxf', ), ), + 'cel' => + array ( + 't' => + array ( + 0 => 'image/x-kiss-cel', + ), + ), 'cer' => array ( 't' => @@ -19250,6 +19344,13 @@ class DrupalMap extends AbstractMap { 0 => 'application/x-ica', ), ), + 'icalendar' => + array ( + 't' => + array ( + 0 => 'text/calendar', + ), + ), 'icb' => array ( 't' => @@ -19936,6 +20037,13 @@ class DrupalMap extends AbstractMap { 1 => 'application/x-karbon', ), ), + 'kcf' => + array ( + 't' => + array ( + 0 => 'image/x-kiss-cel', + ), + ), 'kdc' => array ( 't' => @@ -20265,7 +20373,7 @@ class DrupalMap extends AbstractMap { array ( 't' => array ( - 0 => 'application/vnd.microsoft.portable-executable', + 0 => 'application/x-archive', ), ), 'link66' => @@ -21793,6 +21901,13 @@ class DrupalMap extends AbstractMap { 0 => 'application/vnd.nitf', ), ), + 'nix' => + array ( + 't' => + array ( + 0 => 'text/x-nix', + ), + ), 'nlu' => array ( 't' => @@ -21871,6 +21986,13 @@ class DrupalMap extends AbstractMap { 0 => 'video/x-nsv', ), ), + 'ntar' => + array ( + 't' => + array ( + 0 => 'application/x-pcapng', + ), + ), 'ntf' => array ( 't' => @@ -22510,6 +22632,13 @@ class DrupalMap extends AbstractMap { 1 => 'application/vnd.tcpdump.pcap', ), ), + 'pcapng' => + array ( + 't' => + array ( + 0 => 'application/x-pcapng', + ), + ), 'pcd' => array ( 't' => @@ -22682,6 +22811,7 @@ class DrupalMap extends AbstractMap { 't' => array ( 0 => 'application/x-font-type1', + 1 => 'image/x-pfm', ), ), 'pfr' => @@ -23252,6 +23382,13 @@ class DrupalMap extends AbstractMap { 0 => 'text/x-cython', ), ), + 'pxr' => + array ( + 't' => + array ( + 0 => 'image/x-pxr', + ), + ), 'py' => array ( 't' => @@ -24127,6 +24264,7 @@ class DrupalMap extends AbstractMap { 't' => array ( 0 => 'text/scriptlet', + 1 => 'image/x-sct', ), ), 'scurl' => @@ -24309,6 +24447,7 @@ class DrupalMap extends AbstractMap { 't' => array ( 0 => 'application/vnd.spotfire.sfs', + 1 => 'application/vnd.squashfs', ), ), 'sfv' => @@ -24795,6 +24934,13 @@ class DrupalMap extends AbstractMap { 3 => 'audio/x-speex', ), ), + 'sqfs' => + array ( + 't' => + array ( + 0 => 'application/vnd.squashfs', + ), + ), 'sql' => array ( 't' => @@ -24824,6 +24970,13 @@ class DrupalMap extends AbstractMap { 0 => 'application/vnd.squashfs', ), ), + 'squashfs' => + array ( + 't' => + array ( + 0 => 'application/vnd.squashfs', + ), + ), 'sr2' => array ( 't' => @@ -29691,6 +29844,13 @@ class DrupalMap extends AbstractMap { 0 => 'application/fits', ), ), + 'image/x-fpx' => + array ( + 't' => + array ( + 0 => 'image/vnd.fpx', + ), + ), 'image/x-icb' => array ( 't' => diff --git a/src/MimeMapManager.php b/src/MimeMapManager.php index 006a94d..e6fb49d 100644 --- a/src/MimeMapManager.php +++ b/src/MimeMapManager.php @@ -15,6 +15,7 @@ use FileEye\MimeMap\Extension; use FileEye\MimeMap\Map\AbstractMap; use FileEye\MimeMap\Map\DefaultMap; use FileEye\MimeMap\MapHandler; +use FileEye\MimeMap\MappingException; use FileEye\MimeMap\Type; use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; @@ -55,8 +56,8 @@ class MimeMapManager implements MimeMapManagerInterface { /** * {@inheritdoc} */ - public function isMapClassValid(string $map_class): bool { - if (class_exists($map_class) && in_array(AbstractMap::class, class_parents($map_class))) { + public function isMapClassValid(string $mapClass): bool { + if (class_exists($mapClass) && in_array(AbstractMap::class, class_parents($mapClass))) { return TRUE; } return FALSE; @@ -77,8 +78,8 @@ class MimeMapManager implements MimeMapManagerInterface { break; case static::CUSTOM_MAP: - $map_class = $this->sophronSettings->get('map_class'); - $this->setMapClass($this->isMapClassValid($map_class) ? $map_class : DrupalMap::class); + $mapClass = $this->sophronSettings->get('map_class'); + $this->setMapClass($this->isMapClassValid($mapClass) ? $mapClass : DrupalMap::class); break; } @@ -89,12 +90,12 @@ class MimeMapManager implements MimeMapManagerInterface { /** * {@inheritdoc} */ - public function setMapClass(string $map_class): MimeMapManagerInterface { - $this->currentMapClass = $map_class; - if (!isset($this->initializedMapClasses[$map_class])) { - $event = new MapEvent($map_class); + public function setMapClass(string $mapClass): MimeMapManagerInterface { + $this->currentMapClass = $mapClass; + if (!isset($this->initializedMapClasses[$mapClass])) { + $event = new MapEvent($mapClass); $this->eventDispatcher->dispatch($event, MapEvent::INIT); - $this->initializedMapClasses[$map_class] = $event->getErrors(); + $this->initializedMapClasses[$mapClass] = $event->getErrors(); } return $this; } @@ -102,9 +103,9 @@ class MimeMapManager implements MimeMapManagerInterface { /** * {@inheritdoc} */ - public function getMappingErrors(string $map_class): array { - $this->setMapClass($map_class); - return $this->initializedMapClasses[$map_class] ?? []; + public function getMappingErrors(string $mapClass): array { + $this->setMapClass($mapClass); + return $this->initializedMapClasses[$mapClass] ?? []; } /** @@ -149,4 +150,54 @@ class MimeMapManager implements MimeMapManagerInterface { ]; } + /** + * Returns an array of gaps of a map vs Drupal's core mapping. + * + * @param class-string<\FileEye\MimeMap\Map\MimeMapInterface> $mapClass + * A FQCN. + * + * @return array + * An array of simple arrays, each having a file extension, its Drupal MIME + * type guess, and a gap information. + * + * @todo add to interface in sophron:3.0.0 + */ + public function determineMapGaps(string $mapClass): array { + $currentMapClass = $this->getMapClass(); + $this->setMapClass($mapClass); + + $core_extended_guesser = new CoreExtensionMimeTypeGuesserExtended(); + + $extensions = $core_extended_guesser->listExtensions(); + sort($extensions); + + $rows = []; + foreach ($extensions as $ext) { + $drupal_mime_type = $core_extended_guesser->guessMimeType('a.' . (string) $ext); + + $extension = $this->getExtension((string) $ext); + try { + $mimemap_mime_type = $extension->getDefaultType(); + } + catch (MappingException $e) { + $mimemap_mime_type = ''; + } + + $gap = ''; + if ($mimemap_mime_type === '') { + $gap = $this->t('No MIME type mapped to this file extension.'); + } + elseif (mb_strtolower($drupal_mime_type) != mb_strtolower($mimemap_mime_type)) { + $gap = $this->t("File extension mapped to '@type' instead.", ['@type' => $mimemap_mime_type]); + } + + if ($gap !== '') { + $rows[] = [(string) $ext, $drupal_mime_type, $gap]; + } + } + + $this->setMapClass($currentMapClass); + return $rows; + } + } diff --git a/src/MimeMapManagerInterface.php b/src/MimeMapManagerInterface.php index 087b37e..2c7acb7 100644 --- a/src/MimeMapManagerInterface.php +++ b/src/MimeMapManagerInterface.php @@ -130,4 +130,20 @@ interface MimeMapManagerInterface { */ public function requirements(string $phase): array; + // phpcs:disable + /** + * Returns an array of gaps of a map vs Drupal's core mapping. + * + * @param class-string<\FileEye\MimeMap\Map\MimeMapInterface> $mapClass + * A FQCN. + * + * @return array + * An array of simple arrays, each having a file extension, its Drupal MIME + * type guess, and a gap information. + * + * @todo add to interface in sophron:3.0.0 + */ + // public function determineMapGaps(string $mapClass): array; + // phpcs:enable + } diff --git a/tests/src/Kernel/SophronApiTest.php b/tests/src/Kernel/SophronApiTest.php index 82225e7..18b9fc4 100644 --- a/tests/src/Kernel/SophronApiTest.php +++ b/tests/src/Kernel/SophronApiTest.php @@ -127,4 +127,11 @@ class SophronApiTest extends KernelTestBase { $this->assertCount(4, $manager->getMappingErrors(DefaultMap::class)); } + /** + * Tests no mapping errors for DrupalMap vs core. + */ + public function testZeroMappingErrorsForDrupalMap(): void { + $this->assertSame([], \Drupal::service(MimeMapManagerInterface::class)->determineMapGaps(DrupalMap::class)); + } + } -- GitLab