Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • 2.0.x
  • 2.1.x
  • 2.2.x
  • 3.0.x
  • 8.x-1.x
  • 2.0.0
  • 2.0.0-alpha1
  • 2.0.0-rc1
  • 2.0.1
  • 2.0.2
  • 2.1.0
  • 2.1.0-rc1
  • 2.1.0-rc2
  • 2.2.0
  • 2.2.1
  • 3.0.0-alpha1
  • 3.0.0-alpha2
  • 8.x-1.0
  • 8.x-1.0-alpha1
  • 8.x-1.0-beta1
  • 8.x-1.0-rc1
  • 8.x-1.1
  • 8.x-1.2
  • 8.x-1.3
24 results

Target

Select target project
  • project/sophron
  • issue/sophron-3238893
  • issue/sophron-3259032
  • issue/sophron-3281777
  • issue/sophron-3280470
  • issue/sophron-3281767
  • issue/sophron-3272647
  • issue/sophron-3250607
  • issue/sophron-3250619
  • issue/sophron-3254796
  • issue/sophron-3258963
  • issue/sophron-3294784
  • issue/sophron-3294783
  • issue/sophron-3304771
  • issue/sophron-3341086
  • issue/sophron-3341480
  • issue/sophron-3401043
  • issue/sophron-3399335
  • issue/sophron-3399339
  • issue/sophron-3408117
  • issue/sophron-3447934
  • issue/sophron-3447974
  • issue/sophron-3447935
  • issue/sophron-3448849
  • issue/sophron-3450288
  • issue/sophron-3459896
  • issue/sophron-3482029
  • issue/sophron-3458918
  • issue/sophron-3487753
  • issue/sophron-3494318
  • issue/sophron-3519413
  • issue/sophron-3519584
  • issue/sophron-3519605
  • issue/sophron-3520116
34 results
Select Git revision
  • 2.0.x
  • 2.1.x
  • 2.2.x
  • 3.0.x
  • 8.x-1.x
  • 2.0.0
  • 2.0.0-alpha1
  • 2.0.0-rc1
  • 2.0.1
  • 2.0.2
  • 2.1.0
  • 2.1.0-rc1
  • 2.1.0-rc2
  • 2.2.0
  • 2.2.1
  • 3.0.0-alpha1
  • 3.0.0-alpha2
  • 8.x-1.0
  • 8.x-1.0-alpha1
  • 8.x-1.0-beta1
  • 8.x-1.0-rc1
  • 8.x-1.1
  • 8.x-1.2
  • 8.x-1.3
24 results
Show changes
Commits on Source (5)
......@@ -51,6 +51,9 @@ include:
variables:
_PHPUNIT_CONCURRENT: '0'
_PHPUNIT_EXTRA: '-c $CI_PROJECT_DIR/$_WEB_ROOT/core --testdox --colors=always'
BROWSERTEST_OUTPUT_VERBOSE: 'false'
SKIP_CSPELL: '1'
OPT_IN_TEST_PREVIOUS_MAJOR: '1'
OPT_IN_TEST_PREVIOUS_MINOR: '0'
OPT_IN_TEST_NEXT_MINOR: '1'
OPT_IN_TEST_NEXT_MAJOR: '1'
......
......@@ -4,7 +4,7 @@
"description": "Provides an extensive MIME types management API",
"require": {
"drupal/core": "^10.2 || ^11",
"fileeye/mimemap": "^2.1.1"
"fileeye/mimemap": "^2.2.1"
},
"autoload": {
"psr-4": {
......
logo.png

7.24 KiB

......@@ -4,8 +4,3 @@ parameters:
message: "#^Property Drupal\\\\sophron_guesser\\\\ProxyClass\\\\SophronMimeTypeGuesser\\:\\:\\$service \\(Drupal\\\\sophron_guesser\\\\SophronMimeTypeGuesser\\) in isset\\(\\) is not nullable\\.$#"
count: 1
path: sophron_guesser/src/ProxyClass/SophronMimeTypeGuesser.php
-
message: "#^Parameter \\#2 \\$message of method Drupal\\\\Core\\\\Form\\\\FormStateInterface\\:\\:setErrorByName\\(\\) expects string, Drupal\\\\Core\\\\StringTranslation\\\\TranslatableMarkup given\\.$#"
count: 3
path: src/Form/SettingsForm.php
......@@ -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]]
......@@ -31,18 +31,18 @@ class SophronMimeTypeGuesser implements MimeTypeGuesserInterface {
/**
* {@inheritdoc}
*/
public function guessMimeType(string $path): string {
public function guessMimeType(string $path): ?string {
$extension = '';
$file_parts = explode('.', $this->fileSystem->basename($path));
// Remove the first part: a full filename should not match an extension.
array_shift($file_parts);
// Iterate over the file parts, trying to find a match.
// For 'my.awesome.image.jpeg', we try: 'jpeg', then 'image.jpeg', then
// 'awesome.image.jpeg'.
while ($additional_part = array_pop($file_parts)) {
$extension = strtolower($additional_part . ($extension ? '.' . $extension : ''));
// Remove the first part: a full filename should not match an extension,
// then iterate over the file parts, trying to find a match.
// For 'my.awesome.image.jpeg', we try: 'awesome.image.jpeg', then
// 'image.jpeg', then 'jpeg'.
// We explicitly check for NULL because that indicates that the array is
// empty.
while (array_shift($file_parts) !== NULL) {
$extension = strtolower(implode('.', $file_parts));
$mime_map_extension = $this->mimeMapManager->getExtension($extension);
try {
return $mime_map_extension->getDefaultType();
......@@ -52,7 +52,7 @@ class SophronMimeTypeGuesser implements MimeTypeGuesserInterface {
}
}
return 'application/octet-stream';
return NULL;
}
/**
......
......@@ -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();
......
......@@ -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' =>
......
......@@ -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;
}
}
......@@ -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
}
......@@ -4,8 +4,8 @@ declare(strict_types=1);
namespace Drupal\Tests\sophron\Functional;
use Drupal\sophron\MimeMapManagerInterface;
use Drupal\Tests\BrowserTestBase;
use Drupal\sophron\MimeMapManagerInterface;
use FileEye\MimeMap\MappingException;
use PHPUnit\Framework\Attributes\Group;
......
......@@ -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));
}
}
......@@ -40,7 +40,7 @@ class SophronGuesserTest extends KernelTestBase {
*/
public function testGuesserNotInstalled(): void {
$guesser = \Drupal::service('file.mime_type.guesser.extension');
$this->assertEquals('application/octet-stream', $guesser->guessMimeType('fake.jp2'));
$this->assertNull($guesser->guessMimeType('fake.jp2'));
}
/**
......@@ -61,13 +61,13 @@ class SophronGuesserTest extends KernelTestBase {
*/
public function testGuesserInstallUninstall(): void {
$guesser = \Drupal::service('file.mime_type.guesser.extension');
$this->assertEquals('application/octet-stream', $guesser->guessMimeType('fake.jp2'));
$this->assertNull($guesser->guessMimeType('fake.jp2'));
\Drupal::service('module_installer')->install(['sophron_guesser']);
$guesser = \Drupal::service('file.mime_type.guesser.extension');
$this->assertEquals('image/jp2', $guesser->guessMimeType('fake.jp2'));
\Drupal::service('module_installer')->uninstall(['sophron_guesser']);
$guesser = \Drupal::service('file.mime_type.guesser.extension');
$this->assertEquals('application/octet-stream', $guesser->guessMimeType('fake.jp2'));
$this->assertNull($guesser->guessMimeType('fake.jp2'));
}
/**
......@@ -77,6 +77,8 @@ class SophronGuesserTest extends KernelTestBase {
* \Drupal\KernelTests\Core\File\MimeTypeTest::testFileMimeTypeDetection.
*/
public function testFileMimeTypeDetection(): void {
\Drupal::service('module_installer')->install(['sophron_guesser']);
$prefixes = ['public://', 'private://', 'temporary://', 'dummy-remote://'];
$test_case = [
......@@ -87,9 +89,15 @@ class SophronGuesserTest extends KernelTestBase {
'test.jar.jpg' => 'image/jpeg',
'test.jpg.jar' => 'application/java-archive',
'test.pcf.Z' => 'application/x-font',
'pcf.z' => 'application/octet-stream',
'pcf.z' => 'application/x-compress',
'jar' => 'application/octet-stream',
'some.junk' => 'application/octet-stream',
'foo.file_test_1' => 'application/octet-stream',
'foo.file_test_2' => 'application/octet-stream',
'foo.doc' => 'application/msword',
'test.ogg' => 'audio/ogg',
'foobar.0.zip' => 'application/zip',
'foobar..zip' => 'application/zip',
];
$guesser = $this->container->get('file.mime_type.guesser');
......