summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorian Pritz <bluewind@xinu.at>2013-08-05 19:40:09 +0200
committerFlorian Pritz <bluewind@xinu.at>2013-08-05 21:51:57 +0200
commit768bf6485cc73ad9b508b227fed8b3fcc3c6b65f (patch)
treee9bbdb3169d867a24167af9773f8140ec88fc7d9
parentae244fdb9fd28db4e1323b5d4da5803699be3412 (diff)
Add history page with thumbnails of images
Signed-off-by: Florian Pritz <bluewind@xinu.at>
-rw-r--r--application/controllers/file.php62
-rw-r--r--application/models/mfile.php112
-rw-r--r--application/views/file/nav_history.php18
-rw-r--r--application/views/file/upload_history.php1
-rw-r--r--application/views/file/upload_history_thumbnails.php19
-rw-r--r--data/css/style.css21
-rw-r--r--data/js/script.js16
7 files changed, 249 insertions, 0 deletions
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<br>
+ $upload_date
+ $dimensions - ${item["mimetype"]}<br>
+ ";
+ }
+
+ $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 @@
+<ul class="nav nav-tabs">
+<?php
+$nav = array(
+ "List" => "file/upload_history",
+ "Thumbnails" => "file/upload_history_thumbnails",
+);
+
+$CI =& get_instance();
+
+foreach ($nav as $key => $item) {
+ ?>
+ <li <?php echo $CI->uri->uri_string() == $item ? 'class="active"' : ''; ?>>
+ <a href="<?php echo site_url($item); ?>"><?php echo $key; ?></a>
+ </li>
+ <?php
+}
+?>
+</ul>
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 @@
<?php register_js_include("/data/js/jquery.tablesorter.min.js"); ?>
+<?php include 'nav_history.php'; ?>
<?php echo form_open("file/do_delete") ?>
<table id="upload_history" class="table table-striped tablesorter">
<thead>
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 @@
+<?php include 'nav_history.php'; ?>
+<!-- Comment markers background: http://stackoverflow.com/a/14776780/953022 -->
+<div class="upload_history_thumbnails"><!--
+ <?php foreach($query as $key => $item): ?>
+ --><a href="<?php echo site_url("/".$item["id"]); ?>" title="<?php echo htmlentities($item["filename"]); ?>" data-content="<?php echo htmlentities($item["tooltip"]); ?>" ><img class="thumb" src="<?php echo site_url("file/thumbnail/".$item["id"]); ?>"></a><!--
+ <?php endforeach; ?>
+--></div>
+
+<div class="row-fluid">
+ <div class="span12 alert alert-block alert-info">
+ <h4 class="alert-heading">Notice!</h4>
+ <p>
+ Currently only jpeg, png and gif images are displayed here. If you are
+ looking for something else, please switch to the
+ <a href="<?php echo site_url("file/upload_history"); ?>">list view</a>
+ which contains your complete history.
+ </p>
+ </div>
+</div>
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) {