From 768bf6485cc73ad9b508b227fed8b3fcc3c6b65f Mon Sep 17 00:00:00 2001 From: Florian Pritz Date: Mon, 5 Aug 2013 19:40:09 +0200 Subject: Add history page with thumbnails of images Signed-off-by: Florian Pritz --- application/controllers/file.php | 62 ++++++++++++ application/models/mfile.php | 112 +++++++++++++++++++++ application/views/file/nav_history.php | 18 ++++ application/views/file/upload_history.php | 1 + .../views/file/upload_history_thumbnails.php | 19 ++++ data/css/style.css | 21 ++++ data/js/script.js | 16 +++ 7 files changed, 249 insertions(+) create mode 100644 application/views/file/nav_history.php create mode 100644 application/views/file/upload_history_thumbnails.php diff --git a/application/controllers/file.php b/application/controllers/file.php index 630e550de..78ecd5096 100644 --- a/application/controllers/file.php +++ b/application/controllers/file.php @@ -380,6 +380,68 @@ class File extends CI_Controller { echo $this->config->item('upload_max_size'); } + function thumbnail() + { + $id = $this->uri->segment(3); + + if (!$this->mfile->valid_id($id)) { + return $this->_non_existent(); + } + + $etag = "$id-thumb"; + handle_etag($etag); + + $thumb = $this->mfile->makeThumb($id, 150, IMAGETYPE_JPEG); + + if ($thumb === false) { + show_error("Failed to generate thumbnail"); + } + + $filedata = $this->mfile->get_filedata($id); + if (!$filedata) { + show_error("Failed to get file data"); + } + + $this->output->set_header("Cache-Control:max-age=31536000, public"); + $this->output->set_header("Expires: ".date("r", time() + 365 * 24 * 60 * 60)); + $this->output->set_content_type("image/jpeg"); + $this->output->set_output($thumb); + } + + function upload_history_thumbnails() + { + $this->muser->require_access(); + + $user = $this->muser->get_userid(); + + $query = $this->db->query(" + SELECT `id`, `filename`, `mimetype`, `date`, `hash`, `filesize` + FROM files + WHERE user = ? + AND mimetype IN ('image/jpeg', 'image/png', 'image/gif') + ORDER BY date ASC + ", array($user))->result_array(); + + foreach($query as $key => $item) { + $filesize = format_bytes($item["filesize"]); + $dimensions = $this->mfile->image_dimension($this->mfile->file($item["hash"])); + $upload_date = date("r", $item["date"]); + + $query[$key]["filesize"] = $filesize; + $query[$key]["tooltip"] = " + ${item["id"]} - $filesize
+ $upload_date + $dimensions - ${item["mimetype"]}
+ "; + } + + $this->data["query"] = $query; + + $this->load->view('header', $this->data); + $this->load->view($this->var->view_dir.'/upload_history_thumbnails', $this->data); + $this->load->view('footer', $this->data); + } + function upload_history() { $this->muser->require_access(); diff --git a/application/models/mfile.php b/application/models/mfile.php index 7d6056a9c..a7bab5d51 100644 --- a/application/models/mfile.php +++ b/application/models/mfile.php @@ -101,6 +101,118 @@ class Mfile extends CI_Model { return $mimetype; } + public function image_dimension($file) + { + list($width, $height) = getimagesize($file); + + return "${width}x${height}"; + } + + /* + * This returns a square thumbnail for the input image + * Source: http://salman-w.blogspot.co.at/2009/04/crop-to-fit-image-using-aspphp.html + */ + public function makeThumb($id, $size = 150, $target_type = null) + { + $filedata = $this->get_filedata($id); + if (!$filedata) { + return false; + } + + $source_path = $this->file($filedata["hash"]); + + list($source_width, $source_height, $source_type) = getimagesize($source_path); + + if ($target_type === null) { + $target_type = $source_type; + } + + $target_width = $size; + $target_height = $size; + + switch ($source_type) { + case IMAGETYPE_GIF: + $source_gdim = imagecreatefromgif($source_path); + break; + case IMAGETYPE_JPEG: + $source_gdim = imagecreatefromjpeg($source_path); + break; + case IMAGETYPE_PNG: + $source_gdim = imagecreatefrompng($source_path); + break; + default: + show_error("Unsupported image type"); + } + + $source_aspect_ratio = $source_width / $source_height; + $desired_aspect_ratio = $target_width / $target_height; + + if ($source_aspect_ratio > $desired_aspect_ratio) { + // Triggered when source image is wider + $temp_height = $target_height; + $temp_width = round(($target_height * $source_aspect_ratio)); + } else { + // Triggered otherwise (i.e. source image is similar or taller) + $temp_width = $target_width; + $temp_height = round(($target_width / $source_aspect_ratio)); + } + + /* + * Resize the image into a temporary GD image + */ + + $temp_gdim = imagecreatetruecolor($temp_width, $temp_height); + imagecopyresampled( + $temp_gdim, + $source_gdim, + 0, 0, + 0, 0, + $temp_width, $temp_height, + $source_width, $source_height + ); + + /* + * Copy cropped region from temporary image into the desired GD image + */ + + $x0 = ($temp_width - $target_width) / 2; + $y0 = ($temp_height - $target_height) / 2; + $thumb = imagecreatetruecolor($target_width, $target_height); + imagecopy( + $thumb, + $temp_gdim, + 0, 0, + $x0, $y0, + $target_width, $target_height + ); + + ob_start(); + switch ($target_type) { + case IMAGETYPE_GIF: + $ret = imagegif($thumb); + break; + case IMAGETYPE_JPEG: + $ret = imagejpeg($thumb); + break; + case IMAGETYPE_PNG: + $ret = imagepng($thumb); + break; + default: + assert(0); + } + $result = ob_get_clean(); + + if (!$ret) { + show_error("Failed to create thumbnail"); + } + + imagedestroy($thumb); + imagedestroy($temp_gdim); + imagedestroy($source_gdim); + + return $result; + } + // Add a hash to the DB function add_file($hash, $id, $filename) { diff --git a/application/views/file/nav_history.php b/application/views/file/nav_history.php new file mode 100644 index 000000000..1a3e55c0b --- /dev/null +++ b/application/views/file/nav_history.php @@ -0,0 +1,18 @@ + diff --git a/application/views/file/upload_history.php b/application/views/file/upload_history.php index 8e030d360..344afc28a 100644 --- a/application/views/file/upload_history.php +++ b/application/views/file/upload_history.php @@ -1,4 +1,5 @@ + diff --git a/application/views/file/upload_history_thumbnails.php b/application/views/file/upload_history_thumbnails.php new file mode 100644 index 000000000..55ee90191 --- /dev/null +++ b/application/views/file/upload_history_thumbnails.php @@ -0,0 +1,19 @@ + + + + +
+
+

Notice!

+

+ Currently only jpeg, png and gif images are displayed here. If you are + looking for something else, please switch to the + ">list view + which contains your complete history. +

+
+
diff --git a/data/css/style.css b/data/css/style.css index 15860db83..ad956c57f 100644 --- a/data/css/style.css +++ b/data/css/style.css @@ -217,6 +217,27 @@ body { z-index: 1500; } +.popover { + word-break: break-word; + word-wrap: normal; +} + +.upload_history_thumbnails { + margin: 0 auto; + padding-bottom: 50px; +} + +.upload_history_thumbnails img.thumb, +.upload_history_thumbnails a { + width: 150px; + height: 150px; +} + +.upload_history_thumbnails a { + margin: 1px; + display: inline-block; +} + /* highlighting theme */ .hll { background-color: #ffffcc } diff --git a/data/js/script.js b/data/js/script.js index a7cf3aa54..f747941e5 100644 --- a/data/js/script.js +++ b/data/js/script.js @@ -62,6 +62,22 @@ function fixedEncodeURIComponent (str) { window.lines_wrapped = !window.lines_wrapped; }); + $('.upload_history_thumbnails a').popover({ + trigger: "hover", + placement: "bottom", + html: true, + }); + + function handle_resize() { + var div = $('.upload_history_thumbnails'); + div.width(div.parent().width() - (div.parent().width() % div.find('a').outerWidth(true))); + } + + $(window).resize(function() { + handle_resize(); + }); + handle_resize(); + // check file size before uploading if browser support html5 if (window.File && window.FileList) { function checkFileUpload(evt) { -- cgit v1.2.3-24-g4f1b