From a246b6fe450e21f735824d5a089a8e652b12885f Mon Sep 17 00:00:00 2001 From: Tim Almdal Date: Sun, 7 Aug 2011 13:27:27 -0700 Subject: Initial commit of a patch for Ticket #1764. as discussed here: https://github.com/gallery/gallery3/pull/58/files#r72949. Create a Breadcrumb library which has two static methods for_item (which takes a an item and builds the entire breadcrumb for the item) or build (which takes a variable number of Breadcrumb elements and creates a breadcrumb based on the specified elements). Used tag->url() to build the tag album url. Escaped the query string for the search. Tightened up the breadcrumb code in page.html.php. When adding the show query parameter, we can't blindly concatenate using the ? separator. We have to check that we use a & if a query parameter already exists. --- modules/tag/controllers/tag.php | 3 +++ 1 file changed, 3 insertions(+) (limited to 'modules/tag') diff --git a/modules/tag/controllers/tag.php b/modules/tag/controllers/tag.php index 8f885dea..44a171fd 100644 --- a/modules/tag/controllers/tag.php +++ b/modules/tag/controllers/tag.php @@ -40,6 +40,9 @@ class Tag_Controller extends Controller { "page_size" => $page_size, "tag" => $tag, "children" => $tag->items($page_size, $offset), + "breadcrumbs" => Breadcrumb::build_from_list( + new Breadcrumb(item::root()->title, "/", item::root()->id), + new Breadcrumb($tag->name, $tag->url())), "children_count" => $children_count)); $template->content = new View("dynamic.html"); $template->content->title = t("Tag: %tag_name", array("tag_name" => $tag->name)); -- cgit v1.2.3 From 67719c6f610a71c1bc12d5126e0adac84d7b85c6 Mon Sep 17 00:00:00 2001 From: Bharat Mediratta Date: Mon, 8 Aug 2011 20:28:31 -0700 Subject: Simplification of 59b04b897b8a664cd7334b017fac8158a6281434 for #1764: - Breadcrumb::build_from_item becomes Breadcrumb::array_from_item_parents - Eliminate Breadcrumb::$id -- it's no longer necessary - Fold Breadcrumb::generate_show_query_strings into Breadcrumb::array_from_item_parents - Create Breadcrumb::set_first() and Breadcrumb::set_last() - Breadcrumb::build_from_list goes away, we just use arrays for this - Change Search_Controller and Tag_Controller to just create an array of Breadcrumb instances with the first/last marked appropriately - Breadcrumb_Test loses a bunch of complexity. --- modules/gallery/controllers/albums.php | 2 +- modules/gallery/controllers/movies.php | 2 +- modules/gallery/controllers/photos.php | 2 +- modules/gallery/libraries/Breadcrumb.php | 70 +++++++++++++++---------------- modules/gallery/tests/Breadcrumb_Test.php | 33 ++++----------- modules/search/controllers/search.php | 17 ++++---- modules/tag/controllers/tag.php | 20 +++++---- 7 files changed, 65 insertions(+), 81 deletions(-) (limited to 'modules/tag') diff --git a/modules/gallery/controllers/albums.php b/modules/gallery/controllers/albums.php index 90071fb5..1c48c734 100644 --- a/modules/gallery/controllers/albums.php +++ b/modules/gallery/controllers/albums.php @@ -69,7 +69,7 @@ class Albums_Controller extends Items_Controller { "item" => $album, "children" => $album->viewable()->children($page_size, $offset), "parents" => $album->parents()->as_array(), // view calls empty() on this - "breadcrumbs" => Breadcrumb::build_from_item($album), + "breadcrumbs" => Breadcrumb::array_from_item_parents($album), "children_count" => $children_count)); $template->content = new View("album.html"); diff --git a/modules/gallery/controllers/movies.php b/modules/gallery/controllers/movies.php index 77d92e13..0f12c3fb 100644 --- a/modules/gallery/controllers/movies.php +++ b/modules/gallery/controllers/movies.php @@ -43,7 +43,7 @@ class Movies_Controller extends Items_Controller { "children" => array(), "children_count" => 0, "parents" => $movie->parents()->as_array(), - "breadcrumbs" => Breadcrumb::build_from_item($movie), + "breadcrumbs" => Breadcrumb::array_from_item_parents($movie), "next_item" => $next_item, "previous_item" => $previous_item, "sibling_count" => $movie->parent()->viewable()->children_count($where), diff --git a/modules/gallery/controllers/photos.php b/modules/gallery/controllers/photos.php index 5c8c7b34..af8aed16 100644 --- a/modules/gallery/controllers/photos.php +++ b/modules/gallery/controllers/photos.php @@ -43,7 +43,7 @@ class Photos_Controller extends Items_Controller { "children" => array(), "children_count" => 0, "parents" => $photo->parents()->as_array(), - "breadcrumbs" => Breadcrumb::build_from_item($photo), + "breadcrumbs" => Breadcrumb::array_from_item_parents($photo), "next_item" => $next_item, "previous_item" => $previous_item, "sibling_count" => $photo->parent()->viewable()->children_count($where), diff --git a/modules/gallery/libraries/Breadcrumb.php b/modules/gallery/libraries/Breadcrumb.php index 3a2499ba..e151890d 100644 --- a/modules/gallery/libraries/Breadcrumb.php +++ b/modules/gallery/libraries/Breadcrumb.php @@ -20,55 +20,51 @@ class Breadcrumb_Core { public $title; public $url; - public $id; public $first; public $last; - static function build_from_item($item) { - $breadcrumbs = array(); - foreach ($item->parents() as $element) { - $breadcrumbs[] = new Breadcrumb($element->title, $element->url(), $element->id); - } - - if (!empty($breadcrumbs)) { - $breadcrumbs[] = new Breadcrumb($item->title, $item->url(), $item->id); - } + static function instance($title, $url) { + return new Breadcrumb($title, $url); + } - return self::generate_show_query_strings($breadcrumbs); + public function __construct($title, $url) { + $this->title = $title; + $this->url = $url; + $this->first = false; + $this->last = false; } /** - * This static function takes a list (variable arguments) of Breadcrumbs and builds a dynamic - * breadcrumb list. Used to create a breadcrumb for dynamic albums. Will really be useful - * for the display context change. + * Return an array of Breadcrumb instances build from the parents of a given item. + * The first and last Breadcrumb instances will be marked first/last as appropriate. + * Each breadcrumb will have a ?show= query parameter that refers to the id of the next + * item in line. + * + * @return array Breadcrumb instances */ - static function build_from_list() { - return self::generate_show_query_strings(func_get_args()); - } - - private static function generate_show_query_strings($breadcrumbs) { - if (!empty($breadcrumbs)) { + static function array_from_item_parents($item) { + if ($item->id == item::root()->id) { + return array(); + } - end($breadcrumbs)->last = true;; - while ($breadcrumb = current($breadcrumbs)) { - if (isset($last_id) && $last_id > 0) { - $query = parse_url($breadcrumb->url, PHP_URL_QUERY); - $breadcrumb->url = $breadcrumb->url . ($query ? "&" : "?") . "show={$last_id}"; - } - $last_id = $breadcrumb->id; - $breadcrumb = prev($breadcrumbs); - } - $breadcrumbs[0]->first = true; + $bc = array_merge($item->parents()->as_array(), array($item)); + for ($i = 0; $i < count($bc) - 1; $i++) { + $bc[$i] = new Breadcrumb($bc[$i]->title, $bc[$i]->url("show={$bc[$i+1]->id}")); } + $bc[$i] = new Breadcrumb($item->title, $item->url()); - return $breadcrumbs; + $bc[0]->set_first(); + end($bc)->set_last(); + return $bc; } - public function __construct($title, $url, $id=0) { - $this->title = $title; - $this->url = $url; - $this->id = $id; - $this->first = false; - $this->last = false; + public function set_first() { + $this->first = true; + return $this; + } + + public function set_last() { + $this->last = true; + return $this; } } diff --git a/modules/gallery/tests/Breadcrumb_Test.php b/modules/gallery/tests/Breadcrumb_Test.php index 9f9aeddc..ed2e5608 100644 --- a/modules/gallery/tests/Breadcrumb_Test.php +++ b/modules/gallery/tests/Breadcrumb_Test.php @@ -21,31 +21,16 @@ class Breadcrumb_Test extends Gallery_Unit_Test_Case { private $album; private $item; - public function setup() { - $this->album = test::random_album(); - $this->item = test::random_photo($this->album); - $this->album->reload(); - } - - public function teardown() { - $this->album = null; - $this->item = null; - } - public function build_breadcrumbs_for_item_test() { - $breadcrumbs = Breadcrumb::build_from_item($this->item); - $this->assert_equal("Gallery", $breadcrumbs[0]->title); - $this->assert_equal($this->album->title, $breadcrumbs[1]->title); - $this->assert_equal($this->item->title, $breadcrumbs[2]->title); - } + $album = test::random_album(); + $item = test::random_photo($album); - public function build_breadcrumbs_from_items_test() { - $breadcrumbs = Breadcrumb::build_from_list( - new Breadcrumb(item::root()->title, "/", item::root()->id), - new Breadcrumb($this->album->title, $this->album->relative_path(), $this->album->id), - new Breadcrumb($this->item->title, $this->item->relative_path(), $this->item->id)); - $this->assert_equal("Gallery", $breadcrumbs[0]->title); - $this->assert_equal($this->album->title, $breadcrumbs[1]->title); - $this->assert_equal($this->item->title, $breadcrumbs[2]->title); + $expected = array(); + $expected[] = Breadcrumb::instance( + item::root()->title, item::root()->url("show={$album->id}"))->set_first(); + $expected[] = + Breadcrumb::instance($album->title, $album->url("show={$item->id}")); + $expected[] = Breadcrumb::instance($item->title, $item->url())->set_last(); + $this->assert_equal($expected, Breadcrumb::array_from_item_parents($item)); } } \ No newline at end of file diff --git a/modules/search/controllers/search.php b/modules/search/controllers/search.php index d30ffa67..5db63ab0 100644 --- a/modules/search/controllers/search.php +++ b/modules/search/controllers/search.php @@ -37,14 +37,15 @@ class Search_Controller extends Controller { $template = new Theme_View("page.html", "collection", "search"); $root = item::root(); - $search_url = url::abs_site("search?q=" . urlencode($q)); - $template->set_global(array("page" => $page, - "max_pages" => $max_pages, - "page_size" => $page_size, - "breadcrumbs" => Breadcrumb::build_from_list( - new Breadcrumb(item::root()->title, "/", item::root()->id), - new Breadcrumb($q, $search_url)), - "children_count" => $count)); + $template->set_global( + array("page" => $page, + "max_pages" => $max_pages, + "page_size" => $page_size, + "breadcrumbs" => array( + Breadcrumb::instance($root->title, $root->url())->set_first(), + Breadcrumb::instance($q, url::abs_site("search?q=" . urlencode($q)))->set_last(), + ), + "children_count" => $count)); $template->content = new View("search.html"); $template->content->items = $result; diff --git a/modules/tag/controllers/tag.php b/modules/tag/controllers/tag.php index 44a171fd..7786daa1 100644 --- a/modules/tag/controllers/tag.php +++ b/modules/tag/controllers/tag.php @@ -34,16 +34,18 @@ class Tag_Controller extends Controller { url::redirect(url::merge(array("page" => $max_pages))); } + $root = item::root(); $template = new Theme_View("page.html", "collection", "tag"); - $template->set_global(array("page" => $page, - "max_pages" => $max_pages, - "page_size" => $page_size, - "tag" => $tag, - "children" => $tag->items($page_size, $offset), - "breadcrumbs" => Breadcrumb::build_from_list( - new Breadcrumb(item::root()->title, "/", item::root()->id), - new Breadcrumb($tag->name, $tag->url())), - "children_count" => $children_count)); + $template->set_global( + array("page" => $page, + "max_pages" => $max_pages, + "page_size" => $page_size, + "tag" => $tag, + "children" => $tag->items($page_size, $offset), + "breadcrumbs" => array( + Breadcrumb::instance($root->title, $root->url())->set_first(), + Breadcrumb::instance($tag->name, $tag->url())->set_last()), + "children_count" => $children_count)); $template->content = new View("dynamic.html"); $template->content->title = t("Tag: %tag_name", array("tag_name" => $tag->name)); -- cgit v1.2.3 From 933a34986dbca248f388e8aa3c3aea4a6d71a94b Mon Sep 17 00:00:00 2001 From: Tim Almdal Date: Thu, 11 Aug 2011 22:04:20 -0700 Subject: Patch for tickets #1428 and #1760 Create the concept of a Photo_Display_Context. If the user is browsing a dynamic album (i.e. tags) and chooses to look at an image in that album. The display of the image happens correctly, but the 'next' and 'previous' buttons are no longer consistent. When one of these is clicked, Gallery will open the adjacent image in the actuall album, not the dynamic album. --- modules/gallery/controllers/albums.php | 3 + modules/gallery/controllers/movies.php | 23 ++----- modules/gallery/controllers/photos.php | 23 ++----- modules/gallery/libraries/Display_Context.php | 71 ++++++++++++++++++++++ modules/gallery/libraries/Item_Display_Context.php | 44 ++++++++++++++ modules/search/controllers/search.php | 21 ++++++- modules/search/helpers/search.php | 45 +++++++++++--- .../search/libraries/Search_Display_Context.php | 52 ++++++++++++++++ modules/tag/controllers/tag.php | 22 ++++++- modules/tag/helpers/tag.php | 19 ++++++ modules/tag/libraries/Tag_Display_Context.php | 49 +++++++++++++++ modules/tag/models/tag.php | 38 ++++++------ 12 files changed, 344 insertions(+), 66 deletions(-) create mode 100644 modules/gallery/libraries/Display_Context.php create mode 100644 modules/gallery/libraries/Item_Display_Context.php create mode 100644 modules/search/libraries/Search_Display_Context.php create mode 100644 modules/tag/libraries/Tag_Display_Context.php (limited to 'modules/tag') diff --git a/modules/gallery/controllers/albums.php b/modules/gallery/controllers/albums.php index 1c48c734..9bf7b9bf 100644 --- a/modules/gallery/controllers/albums.php +++ b/modules/gallery/controllers/albums.php @@ -60,6 +60,9 @@ class Albums_Controller extends Items_Controller { url::redirect($album->abs_url("page=$max_pages")); } + Display_Context::factory("item") + ->save(); + $template = new Theme_View("page.html", "collection", "album"); $template->set_global( array("page" => $page, diff --git a/modules/gallery/controllers/movies.php b/modules/gallery/controllers/movies.php index 0f12c3fb..bbf89f17 100644 --- a/modules/gallery/controllers/movies.php +++ b/modules/gallery/controllers/movies.php @@ -27,27 +27,12 @@ class Movies_Controller extends Items_Controller { access::required("view", $movie); - $where = array(array("type", "!=", "album")); - $position = item::get_position($movie, $where); - if ($position > 1) { - list ($previous_item, $ignore, $next_item) = - $movie->parent()->viewable()->children(3, $position - 2, $where); - } else { - $previous_item = null; - list ($next_item) = $movie->parent()->viewable()->children(1, $position, $where); - } - $template = new Theme_View("page.html", "item", "movie"); $template->set_global( - array("item" => $movie, - "children" => array(), - "children_count" => 0, - "parents" => $movie->parents()->as_array(), - "breadcrumbs" => Breadcrumb::array_from_item_parents($movie), - "next_item" => $next_item, - "previous_item" => $previous_item, - "sibling_count" => $movie->parent()->viewable()->children_count($where), - "position" => $position)); + array_merge(array("item" => $movie, + "children" => array(), + "children_count" => 0), + Display_Context::factory()->display_context($movie))); $template->content = new View("movie.html"); diff --git a/modules/gallery/controllers/photos.php b/modules/gallery/controllers/photos.php index af8aed16..49bb5a25 100644 --- a/modules/gallery/controllers/photos.php +++ b/modules/gallery/controllers/photos.php @@ -27,27 +27,12 @@ class Photos_Controller extends Items_Controller { access::required("view", $photo); - $where = array(array("type", "!=", "album")); - $position = item::get_position($photo, $where); - if ($position > 1) { - list ($previous_item, $ignore, $next_item) = - $photo->parent()->viewable()->children(3, $position - 2, $where); - } else { - $previous_item = null; - list ($next_item) = $photo->parent()->viewable()->children(1, $position, $where); - } - $template = new Theme_View("page.html", "item", "photo"); $template->set_global( - array("item" => $photo, - "children" => array(), - "children_count" => 0, - "parents" => $photo->parents()->as_array(), - "breadcrumbs" => Breadcrumb::array_from_item_parents($photo), - "next_item" => $next_item, - "previous_item" => $previous_item, - "sibling_count" => $photo->parent()->viewable()->children_count($where), - "position" => $position)); + array_merge(array("item" => $photo, + "children" => array(), + "children_count" => 0), + Display_Context::factory()->display_context($photo))); $template->content = new View("photo.html"); diff --git a/modules/gallery/libraries/Display_Context.php b/modules/gallery/libraries/Display_Context.php new file mode 100644 index 00000000..5054cffb --- /dev/null +++ b/modules/gallery/libraries/Display_Context.php @@ -0,0 +1,71 @@ +get("display_context_id", ""); + $context = Cache::instance()->get($display_context_id, null); + $context = empty($context) ? new Item_Display_Context() : unserialize($context); + } else { + $class_prefix = ucfirst(strtolower($display_context_name)); + $class_name = "{$class_prefix}_Display_Context"; + $context = new $class_name(); + } + + return $context; + } + + protected function __construct($display_context_name) { + // $this->reset($display_context_name); + $this->_data = array(); + $this->_display_context_name = $display_context_name; + } + + final function get($key) { + return empty($this->_data[$key]) ? null : $this->_data[$key]; + } + + final function set($key, $value=null) { + if (is_array($key)) { + if ((array)$key == $key) { + $this->_data = array_merge($this->_data, $key); + } else { + $this->_data = array_merge($this->_data, array_fill_keys($key, $value)); + } + } else { + $this->_data[$key] = $value; + } + return $this; + } + + final function save() { + $context_data = serialize($this); + $display_context_id = "display_context_" . md5($context_data); + Session::instance()->set("display_context_id", $display_context_id); + Cache::instance()->set($display_context_id, $context_data); + return $this; + } + + abstract function display_context($item); +} diff --git a/modules/gallery/libraries/Item_Display_Context.php b/modules/gallery/libraries/Item_Display_Context.php new file mode 100644 index 00000000..d0562790 --- /dev/null +++ b/modules/gallery/libraries/Item_Display_Context.php @@ -0,0 +1,44 @@ + 1) { + list ($previous_item, $ignore, $next_item) = + $item->parent()->viewable()->children(3, $position - 2, $where); + } else { + $previous_item = null; + list ($next_item) = $item->parent()->viewable()->children(1, $position, $where); + } + + return array("position" =>$position, + "previous_item" => $previous_item, + "next_item" =>$next_item, + "sibling_count" => $item->parent()->viewable()->children_count($where), + "parents" => $item->parents()->as_array(), + "breadcrumbs" => Breadcrumb::array_from_item_parents($item)); + } +} diff --git a/modules/search/controllers/search.php b/modules/search/controllers/search.php index 5db63ab0..1d5a55bf 100644 --- a/modules/search/controllers/search.php +++ b/modules/search/controllers/search.php @@ -21,6 +21,18 @@ class Search_Controller extends Controller { public function index() { $page_size = module::get_var("gallery", "page_size", 9); $q = Input::instance()->get("q"); + $q_with_more_terms = search::add_query_terms($q); + $show = Input::instance()->get("show"); + + if ($show) { + $child = ORM::factory("item", $show); + $index = search::get_position($child, $q_with_more_terms); + if ($index) { + $page = ceil($index / $page_size); + url::redirect( url::abs_site("search?q=" . urlencode($q) . ($page == 1 ? "" : "&page=$page"))); + } + } + $page = Input::instance()->get("page", 1); // Make sure that the page references a valid offset @@ -30,11 +42,18 @@ class Search_Controller extends Controller { $offset = ($page - 1) * $page_size; - $q_with_more_terms = search::add_query_terms($q); list ($count, $result) = search::search($q_with_more_terms, $page_size, $offset); + $title = t("Search: %q", array("q" => $q_with_more_terms)); + $max_pages = max(ceil($count / $page_size), 1); + Display_Context::factory("search") + ->set(array("title" => $title, + "query_terms" => $q_with_more_terms, + "q" => $q)) + ->save(); + $template = new Theme_View("page.html", "collection", "search"); $root = item::root(); $template->set_global( diff --git a/modules/search/helpers/search.php b/modules/search/helpers/search.php index a3fd795a..a77a2433 100644 --- a/modules/search/helpers/search.php +++ b/modules/search/helpers/search.php @@ -36,8 +36,19 @@ class search_Core { static function search($q, $limit, $offset) { $db = Database::instance(); - $q = $db->escape($q); + $query = self::_build_query_base($q) . + "ORDER BY `score` DESC " . + "LIMIT $limit OFFSET " . (int)$offset; + + $data = $db->query($query); + $count = $db->query("SELECT FOUND_ROWS() as c")->current()->c; + + return array($count, new ORM_Iterator(ORM::factory("item"), $data)); + } + + private static function _build_query_base($q, $where=array()) { + $q = Database::instance()->escape($q); if (!identity::active_user()->admin) { foreach (identity::group_ids_for_active_user() as $id) { $fields[] = "`view_$id` = TRUE"; // access::ALLOW @@ -47,18 +58,13 @@ class search_Core { $access_sql = ""; } - $query = + return "SELECT SQL_CALC_FOUND_ROWS {items}.*, " . " MATCH({search_records}.`data`) AGAINST ('$q') AS `score` " . "FROM {items} JOIN {search_records} ON ({items}.`id` = {search_records}.`item_id`) " . "WHERE MATCH({search_records}.`data`) AGAINST ('$q' IN BOOLEAN MODE) " . - $access_sql . - "ORDER BY `score` DESC " . - "LIMIT $limit OFFSET " . (int)$offset; - $data = $db->query($query); - $count = $db->query("SELECT FOUND_ROWS() as c")->current()->c; - - return array($count, new ORM_Iterator(ORM::factory("item"), $data)); + (empty($where) ? "" : " AND " . join(" AND ", $where)) . + $access_sql; } /** @@ -103,4 +109,25 @@ class search_Core { return array($remaining, $total, $percent); } + + static function get_position($item, $q) { + $page_size = module::get_var("gallery", "page_size", 9); + + $query = self::_build_query_base($q, array("{items}.id = " . $item->id)); + + $db = Database::instance(); + + // Truncate the score by two decimal places as this resolves the issues + // that arise due to in exact numeric conversions. + $score = $db->query($query)->current()->score; + $score = substr($score, 0, strlen($score) - 2); + + $data = $db->query(self::_build_query_base($q) . "having `score` >= " . $score); + + $data->seek($data->count() - 1); + + while ($data->get("id") != $item->id && $data->prev()->valid()); + + return $data->key() + 1; + } } diff --git a/modules/search/libraries/Search_Display_Context.php b/modules/search/libraries/Search_Display_Context.php new file mode 100644 index 00000000..aed3a125 --- /dev/null +++ b/modules/search/libraries/Search_Display_Context.php @@ -0,0 +1,52 @@ +get("query_terms")); + + if ($position > 1) { + list ($count, $result_data) = + search::search($this->get("query_terms"), 3, $position - 2); + list ($previous_item, $ignore, $next_item) = $result_data; + } else { + $previous_item = null; + list ($count, $result_data) = search::search($this->get("query_terms"), 1, $position); + list ($next_item) = $result_data; + } + + $q = $this->get("q"); + $search_url = url::abs_site("search?q=" . urlencode($q) . "&show={$item->id}"); + $root = item::root(); + + return array("position" =>$position, + "previous_item" => $previous_item, + "next_item" =>$next_item, + "sibling_count" => $count, + "breadcrumbs" => array( + Breadcrumb::instance($root->title, "/", $root->id), + Breadcrumb::instance($q, $search_url), + Breadcrumb::instance($item->title, $item->url()))); + } +} diff --git a/modules/tag/controllers/tag.php b/modules/tag/controllers/tag.php index 7786daa1..06e2b5ed 100644 --- a/modules/tag/controllers/tag.php +++ b/modules/tag/controllers/tag.php @@ -22,7 +22,22 @@ class Tag_Controller extends Controller { $tag_id = $function; $tag = ORM::factory("tag")->where("id", "=", $tag_id)->find(); $page_size = module::get_var("gallery", "page_size", 9); - $page = (int) Input::instance()->get("page", "1"); + + $input = Input::instance(); + $show = $input->get("show"); + + if ($show) { + $child = ORM::factory("item", $show); + $index = tag::get_position($tag, $child); + if ($index) { + $page = ceil($index / $page_size); + $uri = "tag/$tag_id/" . urlencode($tag->name); + url::redirect($uri . ($page == 1 ? "" : "?page=$page")); + } + } else { + $page = (int) $input->get("page", "1"); + } + $children_count = $tag->items_count(); $offset = ($page-1) * $page_size; $max_pages = max(ceil($children_count / $page_size), 1); @@ -35,6 +50,11 @@ class Tag_Controller extends Controller { } $root = item::root(); + $title = t("Tag: %tag_name", array("tag_name" => $tag->name)); + Display_Context::factory("tag") + ->set(array("tag" => $tag)) + ->save(); + $template = new Theme_View("page.html", "collection", "tag"); $template->set_global( array("page" => $page, diff --git a/modules/tag/helpers/tag.php b/modules/tag/helpers/tag.php index c21104ee..83a00080 100644 --- a/modules/tag/helpers/tag.php +++ b/modules/tag/helpers/tag.php @@ -136,4 +136,23 @@ class tag_Core { // extremely rare case. db::build()->delete("tags")->where("count", "=", 0)->execute(); } + + /** + * Find the position of the given item in the tag collection. The resulting + * value is 1-indexed, so the first child in the album is at position 1. + * + * @param Tag_Model $tag + * @param Item_Model $item + * @param array $where an array of arrays, each compatible with ORM::where() + */ + static function get_position($tag, $item, $where=array()) { + return ORM::factory("item") + ->viewable() + ->join("items_tags", "items.id", "items_tags.item_id") + ->where("items_tags.tag_id", "=", $tag->id) + ->where("items.id", "<=", $item->id) + ->merge_where($where) + ->order_by("items.id") + ->count_all(); + } } \ No newline at end of file diff --git a/modules/tag/libraries/Tag_Display_Context.php b/modules/tag/libraries/Tag_Display_Context.php new file mode 100644 index 00000000..47c79088 --- /dev/null +++ b/modules/tag/libraries/Tag_Display_Context.php @@ -0,0 +1,49 @@ +get("tag"); + + $where = array(array("type", "!=", "album")); + + $position = tag::get_position($tag, $item, $where); + if ($position > 1) { + list ($previous_item, $ignore, $next_item) = $tag->items(3, $position - 2, $where); + } else { + $previous_item = null; + list ($next_item) = $tag->items(1, $position, $where); + } + + $root = item::root(); + return array("position" =>$position, + "previous_item" => $previous_item, + "next_item" =>$next_item, + "sibling_count" => $tag->items_count($where), + "breadcrumbs" => array( + Breadcrumb::instance($root->title, $root->url())->set_first(), + Breadcrumb::instance($tag->name, $tag->url("show={$item->id}")), + Breadcrumb::instance($item->title, $item->url())->set_last())); + } +} diff --git a/modules/tag/models/tag.php b/modules/tag/models/tag.php index bb79e707..a7150df8 100644 --- a/modules/tag/models/tag.php +++ b/modules/tag/models/tag.php @@ -33,35 +33,39 @@ class Tag_Model_Core extends ORM { * Return all viewable items associated with this tag. * @param integer $limit number of rows to limit result to * @param integer $offset offset in result to start returning rows from - * @param string $type the type of item (album, photo) + * @param string $where an array of arrays, each compatible with ORM::where() * @return ORM_Iterator */ - public function items($limit=null, $offset=null, $type=null) { - $model = ORM::factory("item") + public function items($limit=null, $offset=null, $where=array()) { + if (is_scalar($where)) { + // backwards compatibility + $where = array(array("items.type", "=", $where)); + } + return ORM::factory("item") ->viewable() ->join("items_tags", "items.id", "items_tags.item_id") - ->where("items_tags.tag_id", "=", $this->id); - if ($type) { - $model->where("items.type", "=", $type); - } - return $model->find_all($limit, $offset); + ->where("items_tags.tag_id", "=", $this->id) + ->merge_where($where) + ->order_by("items.id") + ->find_all($limit, $offset); } /** * Return the count of all viewable items associated with this tag. - * @param string $type the type of item (album, photo) + * @param string $where an array of arrays, each compatible with ORM::where() * @return integer */ - public function items_count($type=null) { - $model = ORM::factory("item") + public function items_count($where=array()) { + if (is_scalar($where)) { + // backwards compatibility + $where = array(array("items.type", "=", $where)); + } + return $model = ORM::factory("item") ->viewable() ->join("items_tags", "items.id", "items_tags.item_id") - ->where("items_tags.tag_id", "=", $this->id); - - if ($type) { - $model->where("items.type", "=", $type); - } - return $model->count_all(); + ->where("items_tags.tag_id", "=", $this->id) + ->merge_where($where) + ->count_all(); } /** -- cgit v1.2.3