From dfb095a26267f8b68b40add03dfe407966c49b92 Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Sat, 7 Aug 2010 22:18:28 -0700 Subject: Add the ability to replace the source data file in Item_Model::save(). Refactor the rotate code in Quick_Controller to replace the data file, and then have gallery_event::item_updated_data_file() pick up after the change is saved, rebuild the image and handle album covers. This is much more portable than before and it will allow any mechanism (eg: REST) to replace the source image. --- modules/gallery/models/item.php | 74 +++++++++++++++++++++++++++-------------- 1 file changed, 49 insertions(+), 25 deletions(-) (limited to 'modules/gallery/models') diff --git a/modules/gallery/models/item.php b/modules/gallery/models/item.php index c00b7972..5257bbb9 100644 --- a/modules/gallery/models/item.php +++ b/modules/gallery/models/item.php @@ -316,7 +316,7 @@ class Item_Model extends ORM_MPTT { unset($significant_changes["relative_url_cache"]); unset($significant_changes["relative_path_cache"]); - if (!empty($this->changed) && $significant_changes) { + if ((!empty($this->changed) && $significant_changes) || isset($this->data_file)) { $this->updated = time(); if (!$this->loaded()) { // Create a new item. @@ -341,30 +341,19 @@ class Item_Model extends ORM_MPTT { } // Get the width, height and mime type from our data file for photos and movies. - if ($this->is_movie() || $this->is_photo()) { - $pi = pathinfo($this->data_file); - + if ($this->is_photo() || $this->is_movie()) { if ($this->is_photo()) { - $image_info = getimagesize($this->data_file); - $this->width = $image_info[0]; - $this->height = $image_info[1]; - $this->mime_type = $image_info["mime"]; - - // Force an extension onto the name if necessary - if (empty($pi["extension"])) { - $pi["extension"] = image_type_to_extension($image_info[2], false); - $this->name .= "." . $pi["extension"]; - } - } else { - list ($this->width, $this->height) = movie::getmoviesize($this->data_file); - - // No extension? Assume FLV. - if (empty($pi["extension"])) { - $pi["extension"] = "flv"; - $this->name .= "." . $pi["extension"]; - } + list ($this->width, $this->height, $this->mime_type, $extension) = + photo::get_file_metadata($this->data_file); + } else if ($this->is_movie()) { + list ($this->width, $this->height, $this->mime_type, $extension) = + movie::get_file_metadata($this->data_file); + } - $this->mime_type = in_array(strtolower($pi["extension"]), array("mp4", "m4v")) ? "video/mp4" : "video/x-flv"; + // Force an extension onto the name if necessary + $pi = pathinfo($this->data_file); + if (empty($pi["extension"])) { + $this->name = "{$this->name}.$extension"; } } @@ -479,7 +468,30 @@ class Item_Model extends ORM_MPTT { ->execute(); } + // Replace the data file, if requested. + // @todo: we don't handle the case where you swap in a file of a different mime type + // should we prevent that in validation? or in set_data_file() + if ($this->data_file && ($this->is_photo() || $this->is_movie())) { + copy($this->data_file, $this->file_path()); + + // Get the width, height and mime type from our data file for photos and movies. + if ($this->is_photo()) { + list ($this->width, $this->height) = photo::get_file_metadata($this->file_path()); + } else if ($this->is_movie()) { + list ($this->width, $this->height) = movie::get_file_metadata($this->file_path()); + } + $this->thumb_dirty = 1; + $this->resize_dirty = 1; + } + module::event("item_updated", $original, $this); + + if ($this->data_file) { + // Null out the data file variable here, otherwise this event will trigger another + // save() which will think that we're doing another file move. + $this->data_file = null; + module::event("item_updated_data_file", $this); + } } } else if (!empty($this->changed)) { // Insignificant changes only. Don't fire events or do any special checking to try to keep @@ -765,8 +777,9 @@ class Item_Model extends ORM_MPTT { $this->rules["slug"] = array(); } - // Movies and photos must have data files - if (($this->is_photo() || $this->is_movie()) && !$this->loaded()) { + // Movies and photos must have data files. Verify the data file on new items, or if it has + // been replaced. + if (($this->is_photo() || $this->is_movie()) && $this->data_file) { $this->rules["name"]["callbacks"][] = array($this, "valid_data_file"); } } @@ -842,6 +855,17 @@ class Item_Model extends ORM_MPTT { } else if (filesize($this->data_file) == 0) { $v->add_error("name", "empty_data_file"); } + + if ($this->loaded()) { + if ($this->is_photo()) { + list ($a, $b, $mime_type) = photo::get_file_metadata($this->data_file); + } else if ($this->is_movie()) { + list ($a, $b, $mime_type) = movie::get_file_metadata($this->data_file); + } + if ($mime_type != $this->mime_type) { + $v->add_error("name", "cant_change_mime_type"); + } + } } /** -- cgit v1.2.3 From 9de371e1b3bda42fdaf564af502c0c986eeada10 Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Mon, 9 Aug 2010 22:55:58 -0700 Subject: Use the data_rest implementation to proxy access to raw thumb/resize/full data files when permissions are in play. --- modules/gallery/models/item.php | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'modules/gallery/models') diff --git a/modules/gallery/models/item.php b/modules/gallery/models/item.php index 5257bbb9..1dea60e8 100644 --- a/modules/gallery/models/item.php +++ b/modules/gallery/models/item.php @@ -974,13 +974,26 @@ class Item_Model extends ORM_MPTT { unset($data["album_cover_item_id"]); if (access::can("view_full", $this) && $this->is_photo()) { - $data["file_url"] = $this->file_url(true); + if (access::user_can(identity::guest(), "view_full", $this)) { + $data["file_url"] = $this->file_url(true); + } else { + $data["file_url"] = rest::url("data", $this, "full"); + } } if (($tmp = $this->resize_url(true)) && $this->is_photo()) { - $data["resize_url"] = $tmp; + if (access::user_can(identity::guest(), "view", $this)) { + $data["resize_url"] = $tmp; + } else { + $data["resize_url"] = rest::url("data", $this, "resize"); + } + } + + if (access::user_can(identity::guest(), "view", $this)) { + $data["thumb_url"] = $this->thumb_url(true); + } else { + $data["thumb_url"] = rest::url("data", $this, "thumb"); } - $data["thumb_url"] = $this->thumb_url(true); $data["can_edit"] = access::can("edit", $this); // Elide some internal-only data that is going to cause confusion in the client. -- cgit v1.2.3 From dbe595f15e9c3f359fa447cf270e914b6d6d809e Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Sat, 14 Aug 2010 16:10:32 -0700 Subject: Always use the data resource to return thumbs, resizes and full sizes. That way the client does not have to differentiate between RESTful request types and raw request types. If there's a public raw url, return that as well. --- modules/gallery/models/item.php | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) (limited to 'modules/gallery/models') diff --git a/modules/gallery/models/item.php b/modules/gallery/models/item.php index 1dea60e8..c4591279 100644 --- a/modules/gallery/models/item.php +++ b/modules/gallery/models/item.php @@ -668,9 +668,9 @@ class Item_Model extends ORM_MPTT { public function resize_img($extra_attrs) { $attrs = array_merge($extra_attrs, array("src" => $this->resize_url(), - "alt" => $this->title, - "width" => $this->resize_width, - "height" => $this->resize_height) + "alt" => $this->title, + "width" => $this->resize_width, + "height" => $this->resize_height) ); // html::image forces an absolute url which we don't want return ""; @@ -973,27 +973,25 @@ class Item_Model extends ORM_MPTT { } unset($data["album_cover_item_id"]); - if (access::can("view_full", $this) && $this->is_photo()) { - if (access::user_can(identity::guest(), "view_full", $this)) { - $data["file_url"] = $this->file_url(true); - } else { - $data["file_url"] = rest::url("data", $this, "full"); - } + if (access::can("view_full", $this) && !$this->is_album()) { + $data["file_url"] = rest::url("data", $this, "full"); + } + if (access::user_can(identity::guest(), "view_full", $this)) { + $data["file_url_public"] = $this->file_url(true); } - if (($tmp = $this->resize_url(true)) && $this->is_photo()) { + if ($this->is_photo()) { + $data["resize_url"] = rest::url("data", $this, "resize"); if (access::user_can(identity::guest(), "view", $this)) { - $data["resize_url"] = $tmp; - } else { - $data["resize_url"] = rest::url("data", $this, "resize"); + $data["resize_url_public"] = $this->resize_url(true); } } + $data["thumb_url"] = rest::url("data", $this, "thumb"); if (access::user_can(identity::guest(), "view", $this)) { - $data["thumb_url"] = $this->thumb_url(true); - } else { - $data["thumb_url"] = rest::url("data", $this, "thumb"); + $data["thumb_url_public"] = $this->thumb_url(true); } + $data["can_edit"] = access::can("edit", $this); // Elide some internal-only data that is going to cause confusion in the client. -- cgit v1.2.3 From 3ff91e5e33eee7a3f4941a8036c71089d0f2074e Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Wed, 25 Aug 2010 10:05:21 -0700 Subject: Null out Item_Model::$data_file in Item_Model::save() when we're creating a new item, else the item_created event will trigger subsequent saves which will think that they need to post an item_updated_data_file event. Partial fix for #1286 --- modules/gallery/models/item.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'modules/gallery/models') diff --git a/modules/gallery/models/item.php b/modules/gallery/models/item.php index c4591279..1db766e9 100644 --- a/modules/gallery/models/item.php +++ b/modules/gallery/models/item.php @@ -411,7 +411,9 @@ class Item_Model extends ORM_MPTT { } // This will almost definitely trigger another save, so put it at the end so that we're - // tail recursive. + // tail recursive. Null out the data file variable first, otherwise the next save will + // trigger an item_updated_data_file event. + $this->data_file = null; module::event("item_created", $this); } else { // Update an existing item -- cgit v1.2.3