return core_filetypes::get_types();
}
+/**
+ * Determine a file's MIME type based on the given filename using the function mimeinfo.
+ *
+ * This function retrieves a file's MIME type for a file that will be sent to the user.
+ * This should only be used for file-sending purposes just like in send_stored_file, send_file, and send_temp_file.
+ * Should the file's MIME type cannot be determined by mimeinfo, it will return 'application/octet-stream' as a default
+ * MIME type which should tell the browser "I don't know what type of file this is, so just download it.".
+ *
+ * @param string $filename The file's filename.
+ * @return string The file's MIME type or 'application/octet-stream' if it cannot be determined.
+ */
+function get_mimetype_for_sending($filename = '') {
+ // Guess the file's MIME type using mimeinfo.
+ $mimetype = mimeinfo('type', $filename);
+
+ // Use octet-stream as fallback if MIME type cannot be determined by mimeinfo.
+ if (!$mimetype || $mimetype === 'document/unknown') {
+ $mimetype = 'application/octet-stream';
+ }
+
+ return $mimetype;
+}
+
/**
* Obtains information about a filetype based on its extension. Will
* use a default if no information is present about that particular
function send_temp_file($path, $filename, $pathisstring=false) {
global $CFG;
- if (core_useragent::is_firefox()) {
- // only FF is known to correctly save to disk before opening...
- $mimetype = mimeinfo('type', $filename);
- } else {
- $mimetype = 'application/x-forcedownload';
- }
+ // Guess the file's MIME type.
+ $mimetype = get_mimetype_for_sending($filename);
// close session - not needed anymore
\core\session\manager::write_close();
\core\session\manager::write_close(); // Unlock session during file serving.
- // Use given MIME type if specified, otherwise guess it using mimeinfo.
- // IE, Konqueror and Opera open html file directly in browser from web even when directed to save it to disk :-O
- // only Firefox saves all files locally before opening when content-disposition: attachment stated
- $isFF = core_useragent::is_firefox(); // only FF properly tested
- $mimetype = ($forcedownload and !$isFF) ? 'application/x-forcedownload' :
- ($mimetype ? $mimetype : mimeinfo('type', $filename));
+ // Use given MIME type if specified, otherwise guess it.
+ if (!$mimetype || $mimetype === 'document/unknown') {
+ $mimetype = get_mimetype_for_sending($filename);
+ }
// if user is using IE, urlencode the filename so that multibyte file name will show up correctly on popup
if (core_useragent::is_ie()) {
\core\session\manager::write_close(); // Unlock session during file serving.
- // Use given MIME type if specified, otherwise guess it using mimeinfo.
- // IE, Konqueror and Opera open html file directly in browser from web even when directed to save it to disk :-O
- // only Firefox saves all files locally before opening when content-disposition: attachment stated
$filename = is_null($filename) ? $stored_file->get_filename() : $filename;
- $isFF = core_useragent::is_firefox(); // only FF properly tested
- $mimetype = ($forcedownload and !$isFF) ? 'application/x-forcedownload' :
- ($stored_file->get_mimetype() ? $stored_file->get_mimetype() : mimeinfo('type', $filename));
+
+ // Use given MIME type if specified.
+ $mimetype = $stored_file->get_mimetype();
+
+ // Otherwise guess it.
+ if (!$mimetype || $mimetype === 'document/unknown') {
+ $mimetype = get_mimetype_for_sending($filename);
+ }
// if user is using IE, urlencode the filename so that multibyte file name will show up correctly on popup
if (core_useragent::is_ie()) {
$this->assertEquals(true, $mimeinfo['txt']['defaulticon']);
}
+ /**
+ * Tests for get_mimetype_for_sending function.
+ */
+ public function test_get_mimetype_for_sending() {
+ // Without argument.
+ $this->assertEquals('application/octet-stream', get_mimetype_for_sending());
+
+ // Argument is null.
+ $this->assertEquals('application/octet-stream', get_mimetype_for_sending(null));
+
+ // Filename having no extension.
+ $this->assertEquals('application/octet-stream', get_mimetype_for_sending('filenamewithoutextension'));
+
+ // Test using the extensions listed from the get_mimetypes_array function.
+ $mimetypes = get_mimetypes_array();
+ foreach ($mimetypes as $ext => $info) {
+ if ($ext === 'xxx') {
+ $this->assertEquals('application/octet-stream', get_mimetype_for_sending('SampleFile.' . $ext));
+ } else {
+ $this->assertEquals($info['type'], get_mimetype_for_sending('SampleFile.' . $ext));
+ }
+ }
+ }
+
/**
* Test curl agent settings.
*/