MDL-59960 core_files: improve mimetype detection

Improve mimetype detection for remote files that
have no file extension.  The mimetype detection
that makes use of the file, only works with local
files, so do not use the remote path which can be
a URL or stream.
This commit is contained in:
Mark Nielsen
2017-08-28 11:36:15 -07:00
parent 9eb3c173ae
commit ee8bce2d3b
2 changed files with 11 additions and 26 deletions
+3 -15
View File
@@ -514,14 +514,13 @@ abstract class file_system {
* @return string The MIME type.
*/
public function mimetype_from_hash($contenthash, $filename) {
$pathname = $this->get_remote_path_from_hash($contenthash);
$pathname = $this->get_local_path_from_hash($contenthash);
$mimetype = file_storage::mimetype($pathname, $filename);
if (!$this->is_file_readable_locally_by_hash($contenthash, false) && $mimetype === 'document/unknown') {
if ($mimetype === 'document/unknown' && !$this->is_file_readable_locally_by_hash($contenthash)) {
// The type is unknown, but the full checks weren't completed because the file isn't locally available.
// Ensure we have a local copy and try again.
$pathname = $this->get_local_path_from_hash($contenthash, true);
$mimetype = file_storage::mimetype_from_file($pathname);
}
@@ -539,18 +538,7 @@ abstract class file_system {
// Files with an empty filesize are treated as directories and have no mimetype.
return null;
}
$pathname = $this->get_remote_path_from_storedfile($file);
$mimetype = file_storage::mimetype($pathname, $file->get_filename());
if (!$this->is_file_readable_locally_by_storedfile($file) && $mimetype === 'document/unknown') {
// The type is unknown, but the full checks weren't completed because the file isn't locally available.
// Ensure we have a local copy and try again.
$pathname = $this->get_local_path_from_storedfile($file, true);
$mimetype = file_storage::mimetype_from_file($pathname);
}
return $mimetype;
return $this->mimetype_from_hash($file->get_contenthash(), $file->get_filename());
}
/**
+8 -11
View File
@@ -951,14 +951,13 @@ class core_files_file_system_testcase extends advanced_testcase {
* a locally available file whose filename does not suggest mimetype.
*/
public function test_mimetype_from_hash_using_file_content() {
$filepath = '/path/to/file/not/currently/on/disk';
$filecontent = 'example content';
$contenthash = file_storage::hash_from_string($filecontent);
$filename = 'example';
$filepath = __DIR__ . "/fixtures/testimage.jpg";
$fs = $this->get_testable_mock(['get_remote_path_from_hash']);
$fs->method('get_remote_path_from_hash')->willReturn($filepath);
$fs = $this->get_testable_mock(['get_local_path_from_hash']);
$fs->method('get_local_path_from_hash')->willReturn($filepath);
$result = $fs->mimetype_from_hash($contenthash, $filename);
$this->assertEquals('image/jpeg', $result);
@@ -1023,8 +1022,8 @@ class core_files_file_system_testcase extends advanced_testcase {
*/
public function test_mimetype_from_storedfile_using_file_content() {
$filepath = __DIR__ . "/fixtures/testimage.jpg";
$fs = $this->get_testable_mock(['get_remote_path_from_storedfile']);
$fs->method('get_remote_path_from_storedfile')->willReturn($filepath);
$fs = $this->get_testable_mock(['get_local_path_from_hash']);
$fs->method('get_local_path_from_hash')->willReturn($filepath);
$file = $this->get_stored_file('example content');
@@ -1040,14 +1039,12 @@ class core_files_file_system_testcase extends advanced_testcase {
$filepath = __DIR__ . "/fixtures/testimage.jpg";
$fs = $this->get_testable_mock([
'get_remote_path_from_storedfile',
'is_file_readable_locally_by_storedfile',
'get_local_path_from_storedfile',
'is_file_readable_locally_by_hash',
'get_local_path_from_hash',
]);
$fs->method('get_remote_path_from_storedfile')->willReturn('/path/to/remote/file');
$fs->method('is_file_readable_locally_by_storedfile')->willReturn(false);
$fs->method('get_local_path_from_storedfile')->willReturn($filepath);
$fs->method('is_file_readable_locally_by_hash')->willReturn(false);
$fs->method('get_local_path_from_hash')->will($this->onConsecutiveCalls('/path/to/remote/file', $filepath));
$file = $this->get_stored_file('example content');