Commit 41dca3c4 authored by Dries's avatar Dries
Browse files

- Patch #331171 by pwolanin, mfb, drewish: allow modules to alter the MIME...

- Patch #331171 by pwolanin, mfb, drewish: allow modules to alter the MIME extension mapping rather than setting a huge variable.
parent 26a5f040
......@@ -125,6 +125,9 @@ Drupal 7.0, xxxx-xx-xx (development version)
* Rewrote file handling to use PHP stream wrappers to enable support for
both public and private files and to support pluggable storage mechanisms
and access to remote resources (e.g. S3 storage or Flickr photos).
* The mime_extension_mapping variable has been removed. Modules that need to
alter the default MIME type extension mappings should implement
hook_file_mimetype_mapping_alter().
- Image handling:
* Improved image handling, including better support for add-on image
libraries.
......
......@@ -1684,12 +1684,12 @@ function file_upload_max_size() {
* An optional map of extensions to their mimetypes, in the form:
* - 'mimetypes': a list of mimetypes, keyed by an identifier,
* - 'extensions': the mapping itself, an associative array in which
* the key is the extension (lowercase) and the value is the mimetype identifier.
* If $mapping is omitted, the drupal variable mime_extension_mapping is checked
* for a value and if that fails then file_default_mimetype_mapping() is called
* the key is the extension (lowercase) and the value is the mimetype
* identifier. If $mapping is NULL file_mimetype_mapping() is called.
*
* @return
* The internet media type registered for the extension or application/octet-stream for unknown extensions.
* The internet media type registered for the extension or
* application/octet-stream for unknown extensions.
* @see
* file_default_mimetype_mapping()
*/
......
......@@ -6,6 +6,24 @@
* Provides mimetype mappings.
*/
/**
* Return an array of MIME extension mappings.
*
* Returns the mapping after modules have altered the default mapping.
*
* @return
* Array of mimetypes correlated to the extensions that relate to them.
* @see file_get_mimetype()
*/
function file_mimetype_mapping() {
$mapping = &drupal_static(__FUNCTION__);
if (!isset($mapping)) {
$mapping = file_default_mimetype_mapping();
// Allow modules to alter the default mapping.
drupal_alter('file_mimetype_mapping', $mapping);
}
return $mapping;
}
/**
* Default MIME extension mapping.
......
......@@ -193,13 +193,10 @@ function getUri() {
*/
static function getMimeType($uri, $mapping = NULL) {
if (!isset($mapping)) {
$mapping = variable_get('mime_extension_mapping', NULL);
if (!isset($mapping)) {
include_once DRUPAL_ROOT . '/includes/file.mimetypes.inc';
// The default file map, defined in file.mimetypes.inc is quite big.
// We only load it when necessary.
$mapping = file_default_mimetype_mapping();
}
// The default file map, defined in file.mimetypes.inc is quite big.
// We only load it when necessary.
include_once DRUPAL_ROOT . '/includes/file.mimetypes.inc';
$mapping = file_mimetype_mapping();
}
$extension = '';
......
......@@ -579,6 +579,8 @@ class FileSaveUploadTest extends FileHookTestCase {
$this->assertTrue($max_fid_after > $this->maxFidBefore, t('A new file was created.'));
$file1 = file_load($max_fid_after);
$this->assertTrue($file1, t('Loaded the file.'));
// MIME type of the uploaded image may be either image/jpeg or image/png.
$this->assertEqual(substr($file1->filemime, 0, 5), 'image', 'A MIME type was set.');
// Reset the hook counters to get rid of the 'load' we just called.
file_test_reset();
......@@ -597,6 +599,8 @@ class FileSaveUploadTest extends FileHookTestCase {
$file2 = file_load($max_fid_after);
$this->assertTrue($file2);
// MIME type of the uploaded image may be either image/jpeg or image/png.
$this->assertEqual(substr($file2->filemime, 0, 5), 'image', 'A MIME type was set.');
// Load both files using file_load_multiple().
$files = file_load_multiple(array($file1->fid, $file2->fid));
......@@ -2034,6 +2038,10 @@ class FileNameMungingTest extends FileTestCase {
* Tests for file_get_mimetype().
*/
class FileMimeTypeTest extends DrupalWebTestCase {
function setUp() {
parent::setUp('file_test');
}
public static function getInfo() {
return array(
'name' => 'File mimetypes',
......@@ -2059,16 +2067,23 @@ class FileMimeTypeTest extends DrupalWebTestCase {
'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 using default mappings (not using 'mime_extension_mapping').
variable_del('mime_extension_mapping');
// Test using default mappings.
foreach ($test_case as $input => $expected) {
// Test stream [URI].
$output = file_get_mimetype($prefix . $input);
$this->assertIdentical($output, $expected, t('Mimetype for %input is %output (expected: %expected).', array('%input' => $input, '%output' => $output, '%expected' => $expected)));
// Test normal path equivalent
$output = file_get_mimetype($input);
$this->assertIdentical($output, $expected, t('Mimetype (using default mappings) for %input is %output (expected: %expected).', array('%input' => $input, '%output' => $output, '%expected' => $expected)));
}
// Now test using mappings from the mime_extension_mapping variable.
// Now test passing in the map.
$mapping = array(
'mimetypes' => array(
0 => 'application/java-archive',
......@@ -2090,21 +2105,11 @@ class FileMimeTypeTest extends DrupalWebTestCase {
'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',
);
variable_set('mime_extension_mapping', $mapping);
foreach ($test_case as $input => $expected) {
// Test stream [URI].
$output = file_get_mimetype($prefix . $input);
$this->assertIdentical($output, $expected, t('Mimetype for %input is %output (expected: %expected).', array('%input' => $input, '%output' => $output, '%expected' => $expected)));
// Test normal path equivalent
$output = file_get_mimetype($input);
$this->assertIdentical($output, $expected, t('Mimetype (using mappings from variable) for %input is %output (expected: %expected).', array('%input' => $input, '%output' => $output, '%expected' => $expected)));
}
// Now test the same when passing in the map.
variable_del('mime_extension_mapping');
foreach ($test_case as $input => $expected) {
$output = file_get_mimetype($input, $mapping);
$this->assertIdentical($output, $expected, t('Mimetype (using passed-in mappings) for %input is %output (expected: %expected).', array('%input' => $input, '%output' => $output, '%expected' => $expected)));
......
......@@ -314,6 +314,21 @@ function file_test_file_url_alter(&$uri) {
}
}
/**
* Implementation of 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 class for testing the stream wrapper registry.
*
......
......@@ -2159,6 +2159,28 @@ function hook_profile_tasks() {
return $tasks;
}
/**
* Alter MIME type mappings used to determine MIME type from a file extension.
*
* This hook is run when file_mimetype_mapping() is called. It is used to
* allow modules to add to or modify the default mapping from
* file_default_mimetype_mapping().
*
* @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 file_default_mimetype_mapping()
*/
function hook_file_mimetype_mapping_alter(&$mapping) {
// Add new MIME type 'drupal/info'.
$mapping['mimetypes']['example_info'] = 'drupal/info';
// Add new extension '.info' 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;
}
/**
* @} End of "addtogroup hooks".
*/
......@@ -207,7 +207,6 @@ class UploadTestCase extends DrupalWebTestCase {
* @param string $filename Name of file to verify.
*/
function checkUploadedFile($filename) {
global $base_url;
$file = 'public://' . $filename;
$this->drupalGet(file_create_url($file), array('external' => TRUE));
$this->assertResponse(array(200), 'Uploaded ' . $filename . ' is accessible.');
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment