summaryrefslogtreecommitdiff
path: root/modules/gallery/helpers/item.php
diff options
context:
space:
mode:
authorshadlaws <shad@shadlaws.com>2013-02-26 18:39:59 +0100
committershadlaws <shad@shadlaws.com>2013-02-26 18:39:59 +0100
commit251e9d5c8f727b886676e010481a6090ddac028c (patch)
treef7dd7fa36887727961abd56ff11c25b239327f62 /modules/gallery/helpers/item.php
parent81011785aa8bbaad6dcfe5bb44a247cad778ed75 (diff)
#2010 - Revise item::find_by_path to search for jpg-converted items.
- added extra $var_subdir argument to item::find_by_path. - changed item::find_by_path to use $var_subdir to detect if we should look for a jpg-converted item or not (e.g. movie thumbs) - moved the album thumb detection to item::find_by_path to ensure it knows to look for an exact album match. - added more sanity checks to item::find_by_path (now has fewer false positive possibilities). - updated file_proxy to remove the need to guess different movie files. - updated File_Proxy_Controller - new sanity checks catch previously undetected bug. - added additional unit tests for item::find_by_path.
Diffstat (limited to 'modules/gallery/helpers/item.php')
-rw-r--r--modules/gallery/helpers/item.php81
1 files changed, 67 insertions, 14 deletions
diff --git a/modules/gallery/helpers/item.php b/modules/gallery/helpers/item.php
index 9882a9c5..bbbc81d6 100644
--- a/modules/gallery/helpers/item.php
+++ b/modules/gallery/helpers/item.php
@@ -203,10 +203,18 @@ class item_Core {
/**
* Find an item by its path. If there's no match, return an empty Item_Model.
* NOTE: the caller is responsible for performing security checks on the resulting item.
+ *
+ * In addition to $path, $var_subdir can be specified ("albums", "resizes", or "thumbs"). This
+ * corresponds to the file's directory in var, which is what's used in file_proxy. By specifying
+ * this, we can be smarter about items whose formats get converted (e.g. movies that get jpg
+ * thumbs). If omitted, it defaults to "albums" which looks for identical matches between $path
+ * and the item name, just like pre-v3.1 behavior.
+ *
* @param string $path
+ * @param string $var_subdir
* @return object Item_Model
*/
- static function find_by_path($path) {
+ static function find_by_path($path, $var_subdir="albums") {
$path = trim($path, "/");
// The root path name is NULL not "", hence this workaround.
@@ -214,35 +222,80 @@ class item_Core {
return item::root();
}
+ $search_full_name = true;
+ $album_thumb = false;
+ if (($var_subdir == "thumbs") && preg_match("|^(.*)/\.album\.jpg$|", $path, $matches)) {
+ // It's an album thumb - remove "/.album.jpg" from the path.
+ $path = $matches[1];
+ $album_thumb = true;
+ } else if (($var_subdir != "albums") && preg_match("/^(.*)\.jpg$/", $path, $matches)) {
+ // Item itself could be non-jpg (e.g. movies) - remove .jpg from path, don't search full name.
+ $path = $matches[1];
+ $search_full_name = false;
+ }
+
// Check to see if there's an item in the database with a matching relative_path_cache value.
- // Since that field is urlencoded, we must urlencoded the components of the path.
+ // Since that field is urlencoded, we must urlencode the components of the path.
foreach (explode("/", $path) as $part) {
$encoded_array[] = rawurlencode($part);
}
$encoded_path = join("/", $encoded_array);
- $item = ORM::factory("item")
- ->where("relative_path_cache", "=", $encoded_path)
- ->find();
- if ($item->loaded()) {
- return $item;
+ if ($search_full_name) {
+ $item = ORM::factory("item")
+ ->where("relative_path_cache", "=", $encoded_path)
+ ->find();
+ // See if the item was found and if it should have been found.
+ if ($item->loaded() &&
+ (($var_subdir == "albums") || $item->is_photo() || $album_thumb)) {
+ return $item;
+ }
+ } else {
+ // Note that the below query uses LIKE with wildcard % at end, which is still sargable and
+ // therefore still takes advantage of the indexed relative_path_cache (i.e. still quick).
+ $item = ORM::factory("item")
+ ->where("relative_path_cache", "LIKE", Database::escape_for_like($encoded_path) . ".%")
+ ->find();
+ // See if the item was found and should be a jpg.
+ if ($item->loaded() &&
+ (($item->is_movie() && ($var_subdir == "thumbs")) ||
+ ($item->is_photo() && (preg_match("/^(.*)\.jpg$/", $item->name))))) {
+ return $item;
+ }
}
// Since the relative_path_cache field is a cache, it can be unavailable. If we don't find
// anything, fall back to checking the path the hard way.
$paths = explode("/", $path);
- foreach (ORM::factory("item")
- ->where("name", "=", end($paths))
- ->where("level", "=", count($paths) + 1)
- ->find_all() as $item) {
- if (urldecode($item->relative_path()) == $path) {
- return $item;
+ if ($search_full_name) {
+ foreach (ORM::factory("item")
+ ->where("name", "=", end($paths))
+ ->where("level", "=", count($paths) + 1)
+ ->find_all() as $item) {
+ // See if the item was found and if it should have been found.
+ if ((urldecode($item->relative_path()) == $path) &&
+ (($var_subdir == "albums") || $item->is_photo() || $album_thumb)) {
+ return $item;
+ }
+ }
+ } else {
+ foreach (ORM::factory("item")
+ ->where("name", "LIKE", Database::escape_for_like(end($paths)) . ".%")
+ ->where("level", "=", count($paths) + 1)
+ ->find_all() as $item) {
+ // Compare relative_path without extension (regexp same as legal_file::change_extension),
+ // see if it should be a jpg.
+ if ((preg_replace("/\.[^\.\/]*?$/", "", urldecode($item->relative_path())) == $path) &&
+ (($item->is_movie() && ($var_subdir == "thumbs")) ||
+ ($item->is_photo() && (preg_match("/^(.*)\.jpg$/", $item->name))))) {
+ return $item;
+ }
}
}
+ // Nothing found - return an empty item model.
return new Item_Model();
}
-
/**
* Locate an item using the URL. We assume that the url is in the form /a/b/c where each
* component matches up with an item slug. If there's no match, return an empty Item_Model