MDL-32471 introducing file_storage::get_file_preview() method
authorDavid Mudrak <david@moodle.com>
Tue, 17 Apr 2012 22:41:01 +0000 (00:41 +0200)
committerDavid Mudrak <david@moodle.com>
Tue, 24 Apr 2012 10:09:45 +0000 (12:09 +0200)
lib/filestorage/file_storage.php

index a60b7c2..e4fb0ec 100644 (file)
@@ -152,6 +152,113 @@ class file_storage {
         return new stored_file($this, $file_record, $this->filedir);
     }
 
+    /**
+     * Returns an image file that represent the given stored file as a preview
+     *
+     * At the moment, only GIF, JPEG and PNG files are supported to have previews. In the
+     * future, the support for other mimetypes can be added, too (eg. generate an image
+     * preview of PDF, text documents etc).
+     *
+     * @param stored_file $file the file we want to preview
+     * @param string $mode preview mode, eg. 'thumb'
+     * @return stored_file|bool false if unable to create the preview, stored file otherwise
+     */
+    public function get_file_preview(stored_file $file, $mode) {
+
+        $context = context_system::instance();
+        $path = '/' . trim($mode, '/') . '/';
+        $preview = $this->get_file($context->id, 'core', 'preview', 0, $path, $file->get_contenthash());
+
+        if (!$preview) {
+            $preview = $this->create_file_preview($file, $mode);
+            if (!$preview) {
+                return false;
+            }
+        }
+
+        return $preview;
+    }
+
+    /**
+     * Generates a preview image for the stored file
+     *
+     * @param stored_file $file the file we want to preview
+     * @param string $mode preview mode, eg. 'thumb'
+     * @return stored_file|bool the newly created preview file or false
+     */
+    protected function create_file_preview(stored_file $file, $mode) {
+
+        $mimetype = $file->get_mimetype();
+
+        if ($mimetype == 'image/gif' or $mimetype == 'image/jpeg' or $mimetype == 'image/png') {
+            // make a preview of the image
+            $data = $this->create_imagefile_preview($file, $mode);
+
+        } else {
+            // unable to create the preview of this mimetype yet
+            return false;
+        }
+
+        if (empty($data)) {
+            return false;
+        }
+
+        // getimagesizefromstring() is available from PHP 5.4 but we need to support
+        // lower versions, so...
+        $tmproot = make_temp_directory('thumbnails');
+        $tmpfilepath = $tmproot.'/'.$file->get_contenthash().'_thumb';
+        file_put_contents($tmpfilepath, $data);
+        $imageinfo = getimagesize($tmpfilepath);
+        unlink($tmpfilepath);
+
+        $context = context_system::instance();
+
+        $record = array(
+            'contextid' => $context->id,
+            'component' => 'core',
+            'filearea'  => 'preview',
+            'itemid'    => 0,
+            'filepath'  => '/' . trim($mode, '/') . '/',
+            'filename'  => $file->get_contenthash(),
+        );
+
+        if ($imageinfo) {
+            $record['mimetype'] = $imageinfo['mime'];
+        }
+
+        return $this->create_file_from_string($record, $data);
+    }
+
+    /**
+     * Generates a preview for the stored image file
+     *
+     * @param stored_file $file the image we want to preview
+     * @param string $mode preview mode, eg. 'thumb'
+     * @return string|bool false if a problem occurs, the thumbnail image data otherwise
+     */
+    protected function create_imagefile_preview(stored_file $file, $mode) {
+        global $CFG;
+        require_once($CFG->libdir.'/gdlib.php');
+
+        $tmproot = make_temp_directory('thumbnails');
+        $tmpfilepath = $tmproot.'/'.$file->get_contenthash();
+        $file->copy_content_to($tmpfilepath);
+
+        if ($mode == 'tinyicon') {
+            $data = generate_image_thumbnail($tmpfilepath, 16, 16);
+
+        } else if ($mode == 'thumb') {
+            $data = generate_image_thumbnail($tmpfilepath, 90, 90);
+
+        } else {
+            throw new file_exception('storedfileproblem', 'Invalid preview mode requested');
+        }
+
+        unlink($tmpfilepath);
+
+        return $data;
+    }
+
     /**
      * Fetch file using local file id.
      *