diff options
author | Bharat Mediratta <bharat@menalto.com> | 2008-12-17 05:53:05 +0000 |
---|---|---|
committer | Bharat Mediratta <bharat@menalto.com> | 2008-12-17 05:53:05 +0000 |
commit | 78cd00312e875a5f448b0c1e079644586da42f07 (patch) | |
tree | f710708222b1ba6e756d6967be233e7e9468d184 /core/controllers | |
parent | 8630d61051d3fc2292cec35d098e239132870fa5 (diff) |
Improve performance by finding the item without walking the tree.
Instead, use the level and the name to get a short list of candidates,
and check each one of those. In most cases, this query should give us
the right result the first time.
Diffstat (limited to 'core/controllers')
-rw-r--r-- | core/controllers/file_proxy.php | 62 |
1 files changed, 37 insertions, 25 deletions
diff --git a/core/controllers/file_proxy.php b/core/controllers/file_proxy.php index 6dc27ce1..30117f07 100644 --- a/core/controllers/file_proxy.php +++ b/core/controllers/file_proxy.php @@ -49,53 +49,65 @@ class File_Proxy_Controller extends Controller { // We only handle var/resizes and var/albums $paths = explode("/", $file); - $type = array_shift($paths); + $type = $paths[0]; if ($type != "resizes" && $type != "albums" && $type != "thumbs") { kohana::show_404(); } - // Walk down from the root until we find the item that matches this path - $item = ORM::factory("item", 1); - while ($path = array_shift($paths)) { - $item = ORM::factory("item") - ->where("name", $path) - ->where("level", $item->level + 1) - ->where("parent_id", $item->id) - ->find(); - if (!$item->loaded) { - kohana::show_404(); - } + // If the last element is .album.jpg, pop that off since it's not a real item + if ($paths[count($paths)-1] == ".album.jpg") { + array_pop($paths); + } + if ($paths[count($paths)-1] == "") { + array_pop($paths); + } - // If the last element is .album.jpg then we're done. - if (count($paths) == 1 && $paths[0] == ".album.jpg") { + // Find all items that match the level and name, then iterate over those to find a match. + // In most cases we'll get it in one. Note that for the level calculation, we just count the + // size of $paths. $paths includes the type ("thumbs", etc) but it doesn't include the root, + // so it's a wash. + $count = count($paths); + $compare_file = VARPATH . $file; + $item = null; + foreach (ORM::factory("item") + ->where("name", $paths[$count - 1]) + ->where("level", $count) + ->find_all() as $match) { + if ($type == "albums") { + $match_file = $match->file_path(); + } else if ($type == "resizes") { + $match_file = $match->resize_path(); + } else { + $match_file = $match->thumb_path(); + } + if ($match_file == $compare_file) { + $item = $match; break; } } + if (!$item) { + kohana::show_404(); + } + // Make sure we have access to the item if (!access::can("view", $item)) { kohana::show_404(); } - if ($type == "albums") { - if ($item->is_album()) { - kohana::show_404(); - } - $path = $item->file_path(); - } else if ($type == "resizes") { - $path = $item->resize_path(); - } else { - $path = $item->thumb_path(); + // Don't try to load a directory + if ($type == "albums" && $item->is_album()) { + kohana::show_404(); } - if (!file_exists($path)) { + if (!file_exists($match_file)) { kohana::show_404(); } // Dump out the image header("Content-Type: $item->mime_type"); Kohana::close_buffers(false); - $fd = fopen($path, "rb"); + $fd = fopen($match_file, "rb"); fpassthru($fd); fclose($fd); } |