MDL-33082 Detecting mimetype based on content bytes
authorDongsheng Cai <dongsheng@moodle.com>
Mon, 21 May 2012 05:30:41 +0000 (13:30 +0800)
committerMarina Glancy <marina@moodle.com>
Mon, 21 May 2012 07:26:39 +0000 (15:26 +0800)
lib/filestorage/file_storage.php
lib/filestorage/stored_file.php

index fd3fb10..3672fd5 100644 (file)
@@ -1028,7 +1028,7 @@ class file_storage {
 
         $newrecord->timecreated  = $filerecord->timecreated;
         $newrecord->timemodified = $filerecord->timemodified;
-        $newrecord->mimetype     = empty($filerecord->mimetype) ? mimeinfo('type', $filerecord->filename) : $filerecord->mimetype;
+        $newrecord->mimetype     = empty($filerecord->mimetype) ? $this->mimetype($pathname) : $filerecord->mimetype;
         $newrecord->userid       = empty($filerecord->userid) ? null : $filerecord->userid;
         $newrecord->source       = empty($filerecord->source) ? null : $filerecord->source;
         $newrecord->author       = empty($filerecord->author) ? null : $filerecord->author;
@@ -1145,7 +1145,6 @@ class file_storage {
 
         $newrecord->timecreated  = $filerecord->timecreated;
         $newrecord->timemodified = $filerecord->timemodified;
-        $newrecord->mimetype     = empty($filerecord->mimetype) ? mimeinfo('type', $filerecord->filename) : $filerecord->mimetype;
         $newrecord->userid       = empty($filerecord->userid) ? null : $filerecord->userid;
         $newrecord->source       = empty($filerecord->source) ? null : $filerecord->source;
         $newrecord->author       = empty($filerecord->author) ? null : $filerecord->author;
@@ -1153,6 +1152,9 @@ class file_storage {
         $newrecord->sortorder    = $filerecord->sortorder;
 
         list($newrecord->contenthash, $newrecord->filesize, $newfile) = $this->add_string_to_pool($content);
+        $filepathname = $this->path_from_hash($newrecord->contenthash) . '/' . $newrecord->contenthash;
+        // get mimetype by magic bytes
+        $newrecord->mimetype = empty($filerecord->mimetype) ? $this->mimetype($filepathname) : $filerecord->mimetype;
 
         $newrecord->pathnamehash = $this->get_pathname_hash($newrecord->contextid, $newrecord->component, $newrecord->filearea, $newrecord->itemid, $newrecord->filepath, $newrecord->filename);
 
@@ -1216,7 +1218,7 @@ class file_storage {
         $filerecord->referencefileid   = empty($filerecord->referencefileid) ? 0 : $filerecord->referencefileid;
         $filerecord->referencelastsync = empty($filerecord->referencelastsync) ? 0 : $filerecord->referencelastsync;
         $filerecord->referencelifetime = empty($filerecord->referencelifetime) ? 0 : $filerecord->referencelifetime;
-        $filerecord->mimetype          = empty($filerecord->mimetype) ? mimeinfo('type', $filerecord->filename) : $filerecord->mimetype;
+        $filerecord->mimetype          = empty($filerecord->mimetype) ? $this->mimetype($filerecord->filename) : $filerecord->mimetype;
         $filerecord->userid            = empty($filerecord->userid) ? null : $filerecord->userid;
         $filerecord->source            = empty($filerecord->source) ? null : $filerecord->source;
         $filerecord->author            = empty($filerecord->author) ? null : $filerecord->author;
@@ -1333,7 +1335,7 @@ class file_storage {
         }
 
         if (!isset($filerecord['mimetype'])) {
-            $filerecord['mimetype'] = mimeinfo('type', $filerecord['filename']);
+            $filerecord['mimetype'] = $imageinfo['mimetype'];
         }
 
         $width    = $imageinfo['width'];
@@ -1789,6 +1791,24 @@ class file_storage {
         return $storedfile;
     }
 
+    /**
+     * Return mimetype by given file pathname
+     *
+     * This method uses fileinfo module to get mimetype using magic bytes if file exists.
+     * If not, it will get mimetype based on filename
+     *
+     * @param string $pathname
+     * @return string
+     */
+    public static function mimetype($pathname) {
+        if (file_exists($pathname)) {
+            $finfo = new finfo(FILEINFO_MIME_TYPE);
+            return $finfo->file($pathname);
+        } else {
+            return mimeinfo('type', $pathname);
+        }
+    }
+
     /**
      * Cron cleanup job.
      */
index 5141c61..e9b2e3f 100644 (file)
@@ -154,6 +154,17 @@ class stored_file {
                 throw new coding_exception("Invalid field name, $field doesn't exist in file record");
             }
         }
+        // Validate mimetype field
+        $pathname = $this->get_content_file_location();
+        // try to recover the content from trash
+        if (!is_readable($pathname)) {
+            if (!$this->fs->try_content_recovery($this) or !is_readable($pathname)) {
+                throw new file_exception('storedfilecannotread', '', $pathname);
+            }
+        }
+        $mimetype = $this->fs->mimetype($pathname);
+        $this->file_record->mimetype = $mimetype;
+
         $DB->update_record('files', $this->file_record);
     }