interdiff impossible; taking evasive action reverted: --- b/core/core.services.yml +++ a/core/core.services.yml @@ -1105,14 +1105,6 @@ arguments: ['@module_handler'] tags: - { name: mime_type_guesser } - file.mime_type.guesser.fileinfo: - class: Symfony\Component\HttpFoundation\File\MimeType\FileinfoMimeTypeGuesser - tags: - - { name: mime_type_guesser, priority: 64 } - file.mime_type.guesser.filebinary: - class: Symfony\Component\HttpFoundation\File\MimeType\FileBinaryMimeTypeGuesser - tags: - - { name: mime_type_guesser, priority: 32 } renderer: class: Drupal\Core\Render\Renderer arguments: ['@controller_resolver', '@theme.manager', '@plugin.manager.element_info'] unchanged: --- a/core/core.services.yml +++ b/core/core.services.yml @@ -1090,6 +1090,7 @@ services: alias: plugin.manager.element_info file.mime_type.guesser: class: Drupal\Core\File\MimeType\MimeTypeGuesser + arguments: ['@stream_wrapper_manager'] tags: - { name: service_collector, tag: mime_type_guesser, call: addGuesser } file.mime_type.guesser.extension: @@ -1097,6 +1098,14 @@ services: arguments: ['@module_handler'] tags: - { name: mime_type_guesser } + file.mime_type.guesser.fileinfo: + class: Symfony\Component\HttpFoundation\File\MimeType\FileinfoMimeTypeGuesser + tags: + - { name: mime_type_guesser, priority: 64 } + file.mime_type.guesser.filebinary: + class: Symfony\Component\HttpFoundation\File\MimeType\FileBinaryMimeTypeGuesser + tags: + - { name: mime_type_guesser, priority: 32 } renderer: class: Drupal\Core\Render\Renderer arguments: ['@controller_resolver', '@theme.manager', '@plugin.manager.element_info'] diff -u b/core/lib/Drupal/Core/File/MimeType/MimeTypeGuesser.php b/core/lib/Drupal/Core/File/MimeType/MimeTypeGuesser.php --- b/core/lib/Drupal/Core/File/MimeType/MimeTypeGuesser.php +++ b/core/lib/Drupal/Core/File/MimeType/MimeTypeGuesser.php @@ -7,6 +7,7 @@ namespace Drupal\Core\File\MimeType; +use Drupal\Core\StreamWrapper\StreamWrapperManager; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesser as SymfonyMimeTypeGuesser; use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface; @@ -17,6 +18,13 @@ class MimeTypeGuesser implements MimeTypeGuesserInterface { /** + * The stream wrapper manager. + * + * @var \Drupal\Core\StreamWrapper\StreamWrapperManager + */ + protected $streamWrapperManager; + + /** * An array of arrays of registered guessers keyed by priority. * * @var array @@ -36,10 +44,20 @@ protected $sortedGuessers = NULL; /** + * Constructs the mime type guesser service. + * + * @param \Drupal\Core\StreamWrapper\StreamWrapperManager $stream_wrapper_manager + * The stream wrapper manager. + */ + public function __construct(StreamWrapperManager $stream_wrapper_manager) { + $this->streamWrapperManager = $stream_wrapper_manager; + } + + /** * {@inheritdoc} */ public function guess($path) { - if ($wrapper = file_stream_wrapper_get_instance_by_uri($path)) { + if ($wrapper = $this->streamWrapperManager->getViaUri($path)) { // Get the real path from the stream wrapper. $path = $wrapper->realpath(); } only in patch2: unchanged: --- a/core/lib/Drupal/Core/File/MimeType/ExtensionMimeTypeGuesser.php +++ b/core/lib/Drupal/Core/File/MimeType/ExtensionMimeTypeGuesser.php @@ -16,12 +16,12 @@ class ExtensionMimeTypeGuesser implements MimeTypeGuesserInterface { /** - * Default MIME extension mapping. + * MIME extension mappings. * * @var array * Array of mimetypes correlated to the extensions that relate to them. */ - protected $defaultMapping = array( + protected $mapping = array( 'mimetypes' => array( 0 => 'application/andrew-inset', 1 => 'application/atom', @@ -865,40 +865,9 @@ class ExtensionMimeTypeGuesser implements MimeTypeGuesserInterface { ); /** - * The MIME types mapping array after going through the module handler. - * - * @var array - */ - protected $mapping; - - /** - * The module handler. - * - * @var \Drupal\Core\Extension\ModuleHandlerInterface - */ - protected $moduleHandler; - - /** - * Constructs a new ExtensionMimeTypeGuesser. - * - * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler - * The module handler. - */ - public function __construct(ModuleHandlerInterface $module_handler) { - $this->moduleHandler = $module_handler; - } - - /** * {@inheritdoc} */ public function guess($path) { - if ($this->mapping === NULL) { - $mapping = $this->defaultMapping; - // Allow modules to alter the default mapping. - $this->moduleHandler->alter('file_mimetype_mapping', $mapping); - $this->mapping = $mapping; - } - $extension = ''; $file_parts = explode('.', drupal_basename($path)); @@ -920,14 +889,4 @@ public function guess($path) { return 'application/octet-stream'; } - /** - * Sets the mimetypes/extension mapping to use when guessing mimetype. - * - * @param array|null $mapping - * Passing a NULL mapping will cause guess() to use self::$defaultMapping. - */ - public function setMapping(array $mapping = NULL) { - $this->mapping = $mapping; - } - } only in patch2: unchanged: --- a/core/modules/file/src/Tests/FileManagedUnitTestBase.php +++ b/core/modules/file/src/Tests/FileManagedUnitTestBase.php @@ -151,7 +151,8 @@ function assertSameFile(FileInterface $file1, FileInterface $file2) { * * @param $filepath * Optional string specifying the file path. If none is provided then a - * randomly named file will be created in the site's files directory. + * randomly named file with the extension .txt will be created in the site's + * files directory. * @param $contents * Optional contents to save into the file. If a NULL value is provided an * arbitrary string will be used. @@ -182,7 +183,8 @@ function createFile($filepath = NULL, $contents = NULL, $scheme = NULL) { * * @param string $filepath * Optional string specifying the file path. If none is provided then a - * randomly named file will be created in the site's files directory. + * randomly named file with the extension .txt will be created in the site's + * files directory. * @param string $contents * Optional contents to save into the file. If a NULL value is provided an * arbitrary string will be used. @@ -202,7 +204,7 @@ function createUri($filepath = NULL, $contents = NULL, $scheme = NULL) { if (!isset($scheme)) { $scheme = file_default_scheme(); } - $filepath = $scheme . '://' . $filepath; + $filepath = $scheme . '://' . $filepath . '.txt'; if (!isset($contents)) { $contents = "file_put_contents() doesn't seem to appreciate empty strings so let's put in some data."; only in patch2: unchanged: --- a/core/modules/file/src/Tests/SaveDataTest.php +++ b/core/modules/file/src/Tests/SaveDataTest.php @@ -25,7 +25,7 @@ function testWithoutFilename() { $this->assertEqual(file_default_scheme(), file_uri_scheme($result->getFileUri()), "File was placed in Drupal's files directory."); $this->assertEqual($result->getFilename(), drupal_basename($result->getFileUri()), "Filename was set to the file's basename."); $this->assertEqual($contents, file_get_contents($result->getFileUri()), 'Contents of the file are correct.'); - $this->assertEqual($result->getMimeType(), 'application/octet-stream', 'A MIME type was set.'); + $this->assertEqual($result->getMimeType(), 'text/plain', 'A MIME type was set.'); $this->assertTrue($result->isPermanent(), "The file's status was set to permanent."); // Check that the correct hooks were called. @@ -74,7 +74,7 @@ function testExistingRename() { $this->assertEqual('public', file_uri_scheme($result->getFileUri()), "File was placed in Drupal's files directory."); $this->assertEqual($result->getFilename(), $existing->getFilename(), 'Filename was set to the basename of the source, rather than that of the renamed file.'); $this->assertEqual($contents, file_get_contents($result->getFileUri()), 'Contents of the file are correct.'); - $this->assertEqual($result->getMimeType(), 'application/octet-stream', 'A MIME type was set.'); + $this->assertEqual($result->getMimeType(), 'text/plain', 'A MIME type was set.'); $this->assertTrue($result->isPermanent(), "The file's status was set to permanent."); // Check that the correct hooks were called. @@ -102,7 +102,7 @@ function testExistingReplace() { $this->assertEqual('public', file_uri_scheme($result->getFileUri()), "File was placed in Drupal's files directory."); $this->assertEqual($result->getFilename(), $existing->getFilename(), 'Filename was set to the basename of the existing file, rather than preserving the original name.'); $this->assertEqual($contents, file_get_contents($result->getFileUri()), 'Contents of the file are correct.'); - $this->assertEqual($result->getMimeType(), 'application/octet-stream', 'A MIME type was set.'); + $this->assertEqual($result->getMimeType(), 'text/plain', 'A MIME type was set.'); $this->assertTrue($result->isPermanent(), "The file's status was set to permanent."); // Check that the correct hooks were called. only in patch2: unchanged: --- a/core/modules/file/tests/file_test/file_test.module +++ b/core/modules/file/tests/file_test/file_test.module @@ -284,21 +284,6 @@ function file_test_file_url_alter(&$uri) { } /** - * Implements hook_file_mimetype_mapping_alter(). - */ -function file_test_file_mimetype_mapping_alter(&$mapping) { - // Add new mappings. - $mapping['mimetypes']['file_test_mimetype_1'] = 'madeup/file_test_1'; - $mapping['mimetypes']['file_test_mimetype_2'] = 'madeup/file_test_2'; - $mapping['mimetypes']['file_test_mimetype_3'] = 'madeup/doc'; - $mapping['extensions']['file_test_1'] = 'file_test_mimetype_1'; - $mapping['extensions']['file_test_2'] = 'file_test_mimetype_2'; - $mapping['extensions']['file_test_3'] = 'file_test_mimetype_2'; - // Override existing mapping. - $mapping['extensions']['doc'] = 'file_test_mimetype_3'; -} - -/** * Helper validator that returns the $errors parameter. */ function file_test_validator(File $file, $errors) { only in patch2: unchanged: --- a/core/modules/system/file.api.php +++ b/core/modules/system/file.api.php @@ -111,30 +111,6 @@ function hook_file_url_alter(&$uri) { } /** - * Alter MIME type mappings used to determine MIME type from a file extension. - * - * Invoked by \Drupal\Core\File\MimeType\ExtensionMimeTypeGuesser::guess(). It - * is used to allow modules to add to or modify the default mapping from - * \Drupal\Core\File\MimeType\ExtensionMimeTypeGuesser::$defaultMapping. - * - * @param $mapping - * An array of mimetypes correlated to the extensions that relate to them. - * The array has 'mimetypes' and 'extensions' elements, each of which is an - * array. - * - * @see \Drupal\Core\File\MimeType\ExtensionMimeTypeGuesser::guess() - * @see \Drupal\Core\File\MimeType\ExtensionMimeTypeGuesser::$defaultMapping - */ -function hook_file_mimetype_mapping_alter(&$mapping) { - // Add new MIME type 'drupal/info'. - $mapping['mimetypes']['example_info'] = 'drupal/info'; - // Add new extension '.info.yml' and map it to the 'drupal/info' MIME type. - $mapping['extensions']['info'] = 'example_info'; - // Override existing extension mapping for '.ogg' files. - $mapping['extensions']['ogg'] = 189; -} - -/** * Alter archiver information declared by other modules. * * See hook_archiver_info() for a description of archivers and the archiver only in patch2: unchanged: --- a/core/modules/system/src/Tests/File/MimeTypeTest.php +++ /dev/null @@ -1,94 +0,0 @@ - 'application/java-archive', - 'test.jpeg' => 'image/jpeg', - 'test.JPEG' => 'image/jpeg', - 'test.jpg' => 'image/jpeg', - 'test.jar.jpg' => 'image/jpeg', - 'test.jpg.jar' => 'application/java-archive', - 'test.pcf.Z' => 'application/x-font', - 'pcf.z' => 'application/octet-stream', - 'jar' => 'application/octet-stream', - 'some.junk' => 'application/octet-stream', - 'foo.file_test_1' => 'madeup/file_test_1', - 'foo.file_test_2' => 'madeup/file_test_2', - 'foo.doc' => 'madeup/doc', - 'test.ogg' => 'audio/ogg', - ); - - $guesser = $this->container->get('file.mime_type.guesser'); - // Test using default mappings. - foreach ($test_case as $input => $expected) { - // Test stream [URI]. - $output = $guesser->guess($prefix . $input); - $this->assertIdentical($output, $expected, format_string('Mimetype for %input is %output (expected: %expected).', array('%input' => $input, '%output' => $output, '%expected' => $expected))); - - // Test normal path equivalent - $output = $guesser->guess($input); - $this->assertIdentical($output, $expected, format_string('Mimetype (using default mappings) for %input is %output (expected: %expected).', array('%input' => $input, '%output' => $output, '%expected' => $expected))); - } - - // Now test the extension gusser by passing in a custom mapping. - $mapping = array( - 'mimetypes' => array( - 0 => 'application/java-archive', - 1 => 'image/jpeg', - ), - 'extensions' => array( - 'jar' => 0, - 'jpg' => 1, - ) - ); - - $test_case = array( - 'test.jar' => 'application/java-archive', - 'test.jpeg' => 'application/octet-stream', - 'test.jpg' => 'image/jpeg', - 'test.jar.jpg' => 'image/jpeg', - 'test.jpg.jar' => 'application/java-archive', - 'test.pcf.z' => 'application/octet-stream', - 'pcf.z' => 'application/octet-stream', - '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/octet-stream', - 'test.ogg' => 'application/octet-stream', - ); - $extension_guesser = $this->container->get('file.mime_type.guesser.extension'); - $extension_guesser->setMapping($mapping); - - foreach ($test_case as $input => $expected) { - $output = $extension_guesser->guess($input); - $this->assertIdentical($output, $expected, format_string('Mimetype (using passed-in mappings) for %input is %output (expected: %expected).', array('%input' => $input, '%output' => $output, '%expected' => $expected))); - } - } -} only in patch2: unchanged: --- /dev/null +++ b/core/tests/Drupal/Tests/Core/File/ExtensionMimeTypeGuesserTest.php @@ -0,0 +1,59 @@ +assertEquals($mime_type, $guesser->guess($path)); + } + + /** + * Provides data for ExtensionMimeTypeGuesserTest::testGuesser(). + */ + public function guesserDataProvider() { + return [ + ['test.jar', 'application/java-archive'], + ['test.jpeg', 'image/jpeg'], + ['test.JPEG', 'image/jpeg'], + ['test.jpg', 'image/jpeg'], + ['test.jar.jpg', 'image/jpeg'], + ['test.jpg.jar', 'application/java-archive'], + ['test.pcf.Z', 'application/x-font'], + ['pcf.z', 'application/octet-stream'], + ['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'], + ]; + } + +} + +} +namespace { + if (!function_exists('drupal_basename')) { + function drupal_basename($uri, $suffix = NULL) { + return basename($uri, $suffix); + } + } +} \ No newline at end of file only in patch2: unchanged: --- a/core/tests/Drupal/Tests/Core/File/MimeTypeGuesserTest.php +++ b/core/tests/Drupal/Tests/Core/File/MimeTypeGuesserTest.php @@ -14,11 +14,40 @@ /** * @coversDefaultClass \Drupal\Core\File\MimeType\MimeTypeGuesser - * @group DrupalKernel + * @group File */ class MimeTypeGuesserTest extends UnitTestCase { /** + * @covers ::guess + * @covers ::addGuesser + * @covers ::sortGuessers + */ + public function testGuess() { + $stream_wrapper_manager = $this->getMockBuilder('Drupal\Core\StreamWrapper\StreamWrapperManager') + ->disableOriginalConstructor() + ->getMock(); + $stream_wrapper_manager->expects($this->any()) + ->method('getViaUri') + ->willReturn(NULL); + $mime_guesser_service = new MimeTypeGuesser($stream_wrapper_manager); + $guesser_1 = $this->getMock('Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface'); + $guesser_1->expects($this->once()) + ->method('guess') + ->with('file.txt') + ->willReturn('text/plain'); + $mime_guesser_service->addGuesser($guesser_1); + $this->assertEquals('text/plain', $mime_guesser_service->guess('file.txt')); + $guesser_2 = $this->getMock('Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface'); + $guesser_2->expects($this->once()) + ->method('guess') + ->with('file.txt') + ->willReturn('text/x-diff'); + $mime_guesser_service->addGuesser($guesser_2, 10); + $this->assertEquals('text/x-diff', $mime_guesser_service->guess('file.txt')); + } + + /** * @covers ::registerWithSymfonyGuesser * * @see Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesser @@ -33,8 +62,11 @@ public function testSymfonyGuesserRegistration() { if (count($guessers)) { $this->assertNotInstanceOf('Drupal\Core\File\MimeType\MimeTypeGuesser', $guessers[0]); } + $stream_wrapper_manager = $this->getMockBuilder('Drupal\Core\StreamWrapper\StreamWrapperManager') + ->disableOriginalConstructor() + ->getMock(); $container = new ContainerBuilder(); - $container->set('file.mime_type.guesser', new MimeTypeGuesser()); + $container->set('file.mime_type.guesser', new MimeTypeGuesser($stream_wrapper_manager)); MimeTypeGuesser::registerWithSymfonyGuesser($container); $guessers = $this->readAttribute($symfony_guesser, 'guessers'); $this->assertInstanceOf('Drupal\Core\File\MimeType\MimeTypeGuesser', $guessers[0]);