diff --git a/3.0/modules/tag_albums/controllers/admin_tag_albums.php b/3.0/modules/tag_albums/controllers/admin_tag_albums.php new file mode 100644 index 00000000..71cf8eb6 --- /dev/null +++ b/3.0/modules/tag_albums/controllers/admin_tag_albums.php @@ -0,0 +1,100 @@ +content = new View("admin_tag_albums.html"); + + // Generate a form for the admin Settings. + $view->content->tag_albums_form = $this->_get_admin_form(); + + // Display the page. + print $view; + } + + private function _get_admin_form() { + $form = new Forge("admin/tag_albums/saveprefs", "", "post", + array("id" => "g-tag-albums-admin-form")); + + $tag_albums_tagsort_group = $form->group("Tag_Albums_Tag_Sort")->label(t("\"All Tags\" Album Preferences")); + $tag_albums_tagsort_group->dropdown("tag_sort_by") + ->label(t("Sort \"All Tags\" Albums By:")) + ->options( + array("name" => "Name", + "count" => "Count", + "id" => "ID Number")) + ->selected(module::get_var("tag_albums", "tag_sort_by")); + $tag_albums_tagsort_group->dropdown("tag_sort_direction") + ->label(t("Display Albums In:")) + ->options( + array("ASC" => "Ascending Order", + "DESC" => "Descending")) + ->selected(module::get_var("tag_albums", "tag_sort_direction")); + + $tag_albums_tagitemsort_group = $form->group("Tag_Albums_Tag_Item_Sort")->label(t("\"All Tags\" Sub-Album Preferences")); + $tag_albums_tagitemsort_group->dropdown("subalbum_sort_by") + ->label(t("Sort Contents of Sub-Albums By:")) + ->options( + array("title" => "Title", + "name" => "File name", + "captured" => "Date captured", + "created" => "Date uploaded", + "updated" => "Date modified", + "view_count" => "Number of views")) + ->selected(module::get_var("tag_albums", "subalbum_sort_by")); + $tag_albums_tagitemsort_group->dropdown("subalbum_sort_direction") + ->label(t("Display Contents of Sub-Albums In:")) + ->options( + array("ASC" => "Ascending Order", + "DESC" => "Descending")) + ->selected(module::get_var("tag_albums", "subalbum_sort_direction")); + + // Add a save button to the form. + $form->submit("SaveSettings")->value(t("Save")); + + // Return the newly generated form. + return $form; + } + + public function saveprefs() { + // Prevent Cross Site Request Forgery + access::verify_csrf(); + + $form = $this->_get_admin_form(); + if ($form->validate()) { + Kohana_Log::add("error",print_r($form,1)); + module::set_var("tag_albums", "tag_sort_by", $form->Tag_Albums_Tag_Sort->tag_sort_by->value); + module::set_var("tag_albums", "tag_sort_direction", $form->Tag_Albums_Tag_Sort->tag_sort_direction->value); + module::set_var("tag_albums", "subalbum_sort_by", $form->Tag_Albums_Tag_Item_Sort->subalbum_sort_by->value); + module::set_var("tag_albums", "subalbum_sort_direction", $form->Tag_Albums_Tag_Item_Sort->subalbum_sort_direction->value); + + message::success(t("Your settings have been saved.")); + url::redirect("admin/tag_albums"); + } + + // Else show the page with errors + $view = new Admin_View("admin.html"); + $view->content = new View("admin_tag_albums.html"); + $view->content->tag_albums_form = $form; + print $view; + } +} diff --git a/3.0/modules/tag_albums/controllers/tag_albums.php b/3.0/modules/tag_albums/controllers/tag_albums.php new file mode 100644 index 00000000..3e47f1e7 --- /dev/null +++ b/3.0/modules/tag_albums/controllers/tag_albums.php @@ -0,0 +1,649 @@ +where("id", "=", $id) + ->find_all(); + + // If it doesn't exist, redirect to the modules root page. + if (count($album_tags) == 0) { + url::redirect("tag_albums/"); + } + + // If it does exist, and is set to *, load a list of all tags. + if ($album_tags[0]->tags == "*") { + $this->index($id); + } else { + // Otherwise, populate this page with the specified items. + + // Inherit permissions, title and description from the album that linked to this page. + $album = ORM::factory("item", $album_tags[0]->album_id); + access::required("view", $album); + $page_title = $album->title; + $page_description = $album->description; + + // Determine page sort order. + $sort_page_field = $album->sort_column; + $sort_page_direction = $album->sort_order; + + // Determine search type (AND/OR) and generate an array of the tag ids. + $tag_ids = Array(); + foreach (explode(",", $album_tags[0]->tags) as $tag_name) { + $tag = ORM::factory("tag")->where("name", "=", trim($tag_name))->find(); + if ($tag->loaded()) { + $tag_ids[] = $tag->id; + } + } + $album_tags_search_type = $album_tags[0]->search_type; + + // Figure out how many items are in this "virtual album" + $count = $this->_count_records($tag_ids, $album_tags_search_type, true); + + // Figure out how many items to display on each page. + $page_size = module::get_var("gallery", "page_size", 9); + + // Figure out which page # the visitor is on and + // don't allow the visitor to go below page 1. + $page = Input::instance()->get("page", 1); + if ($page < 1) { + url::redirect("tag_albums/album/" . $id); + } + + // First item to display. + $offset = ($page - 1) * $page_size; + + // Figure out what the highest page number is. + $max_pages = ceil($count / $page_size); + + // Don't let the visitor go past the last page. + if ($max_pages && $page > $max_pages) { + url::redirect("tag_albums/album/{$id}/?page=$max_pages"); + } + + // Figure out which items to display on this page and store their details in $children. + $tag_children = $this->_get_records($tag_ids, $page_size, $offset, "items." . $sort_page_field, $sort_page_direction, $album_tags_search_type, true); + $children = Array(); + foreach ($tag_children as $one_child) { + $child_tag = new Tag_Albums_Item($one_child->name, url::site("tag_albums/show/" . $one_child->id . "/0/" . $id), $one_child->type); + $child_tag->id = $one_child->id; + if ($one_child->has_thumb()) { + $child_tag->set_thumb($one_child->thumb_url(), $one_child->thumb_width, $one_child->thumb_height); + } + $children[] = $child_tag; + } + + // Set up the previous and next page buttons. + if ($page > 1) { + $previous_page = $page - 1; + $view->previous_page_link = url::site("tag_albums/album/{$id}/?page={$previous_page}"); + } + if ($page < $max_pages) { + $next_page = $page + 1; + $view->next_page_link = url::site("tag_albums/album/{$id}/?page={$next_page}"); + } + + // Set up breadcrumbs. + $tag_album_breadcrumbs = Array(); + $counter = 0; + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($album->title, ""); + $parent_item = ORM::factory("item", $album->parent_id); + while ($parent_item->id != 1) { + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($parent_item->title, $parent_item->url()); + $parent_item = ORM::factory("item", $parent_item->parent_id); + } + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($parent_item->title, $parent_item->url()); + $tag_album_breadcrumbs = array_reverse($tag_album_breadcrumbs, true); + + // Set up and display the actual page. + $template = new Theme_View("page.html", "collection", "Tag Albums"); + $template->page_title = $page_title; + $template->set_global("page", $page); + $template->set_global("page_size", $page_size); + $template->set_global("max_pages", $max_pages); + $template->set_global("children", $children); + $template->set_global("children_count", $count); + $template->content = new View("tag_albums.html"); + $template->content->title = $page_title; + $template->content->description = $page_description; + $template->set_global("breadcrumbs", $tag_album_breadcrumbs); + print $template; + } + } + + public function index($id) { + // Load a page containing sub-albums for each tag in the gallery. + + // If an ID was specified, make sure it's valid. + $album_tags = ORM::factory("tags_album_id") + ->where("id", "=", $id) + ->find_all(); + if (count($album_tags) == 0) { + $id = ""; + } + + // Inherit permissions, title and description from the album that linked to this page, + // if available, if not use the root album and some default values. + $album = ""; + $page_title = t("All Tags"); + $page_description = ""; + if ($id == "") { + $album = ORM::factory("item", 1); + access::required("view", $album); + } else { + $album = ORM::factory("item", $album_tags[0]->album_id); + access::required("view", $album); + $page_title = $album->title; + $page_description = $album->description; + } + + // Figure out sort order from module preferences. + $sort_page_field = module::get_var("tag_albums", "tag_sort_by", "name"); + $sort_page_direction = module::get_var("tag_albums", "tag_sort_direction", "ASC"); + + // Figure out how many items to display on each page. + $page_size = module::get_var("gallery", "page_size", 9); + + // Figure out which page # the visitor is on and + // don't allow the visitor to go below page 1. + $page = Input::instance()->get("page", 1); + if ($page < 1) { + url::redirect("tag_albums/"); + } + + // First item to display. + $offset = ($page - 1) * $page_size; + + // Determine the total number of items, + // for page numbering purposes. + $all_tags_count = ORM::factory("tag") + ->count_all(); + + // Figure out what the highest page number is. + $max_pages = ceil($all_tags_count / $page_size); + + // Don't let the visitor go past the last page. + if ($max_pages && $page > $max_pages) { + url::redirect("tag_albums/?page=$max_pages"); + } + + // Figure out which items to display on this page. + $display_tags = ORM::factory("tag") + ->order_by("tags." . $sort_page_field, $sort_page_direction) + ->find_all($page_size, $offset); + + // Set up the previous and next page buttons. + if ($page > 1) { + $previous_page = $page - 1; + $view->previous_page_link = url::site("tag_albums/album/" . $id . "/?page={$previous_page}"); + } + if ($page < $max_pages) { + $next_page = $page + 1; + $view->next_page_link = url::site("tag_albums/album/" . $id . "/?page={$next_page}"); + } + + // Generate an arry of "fake" items, one for each tag on the page. + // Grab thumbnails from the most recently uploaded item for each tag, if available. + $children = Array(); + foreach ($display_tags as $one_tag) { + $tag_item = ORM::factory("item") + ->viewable() + ->join("items_tags", "items.id", "items_tags.item_id") + ->where("items_tags.tag_id", "=", $one_tag->id) + ->order_by("items.id", "DESC") + ->find_all(1, 0); + $child_tag = new Tag_Albums_Item($one_tag->name, url::site("tag_albums/tag/" . $one_tag->id . "/" . $id), "album"); + if (count($tag_item) > 0) { + if ($tag_item[0]->has_thumb()) { + $child_tag->set_thumb($tag_item[0]->thumb_url(), $tag_item[0]->thumb_width, $tag_item[0]->thumb_height); + } + } + $children[] = $child_tag; + } + + // Set up breadcrumbs. + $tag_album_breadcrumbs = Array(); + if ($id != "") { + $counter = 0; + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($album->title, ""); + $parent_item = ORM::factory("item", $album->parent_id); + while ($parent_item->id != 1) { + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($parent_item->title, $parent_item->url()); + $parent_item = ORM::factory("item", $parent_item->parent_id); + } + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($parent_item->title, $parent_item->url()); + $tag_album_breadcrumbs = array_reverse($tag_album_breadcrumbs, true); + } else { + $tag_album_breadcrumbs[0] = new Tag_Albums_Breadcrumb(item::root()->title, item::root()->url()); + $tag_album_breadcrumbs[1] = new Tag_Albums_Breadcrumb($page_title, ""); + } + + // Set up and display the actual page. + $template = new Theme_View("page.html", "collection", "Tag Albums"); + $template->page_title = $page_title; + $template->set_global("page", $page); + $template->set_global("page_size", $page_size); + $template->set_global("max_pages", $max_pages); + $template->set_global("children", $children); + $template->set_global("children_count", $all_tags_count); + $template->content = new View("tag_albums.html"); + $template->content->title = $page_title; + $template->content->description = $page_description; + $template->set_global("breadcrumbs", $tag_album_breadcrumbs); + print $template; + } + + public function tag($id, $album_id) { + // Display a dynamic album containing everything tagged with a specific tag where, + // TAG is $id. + // Optionally, set the breadcrumbs to make this page look like an album where the + // album is $album_id. + + // Make sure $album_id is valid, clear it out if it isn't. + $album_tags = ORM::factory("tags_album_id") + ->where("id", "=", $album_id) + ->find_all(); + if (count($album_tags) == 0) { + $album_id = ""; + } + + // Figure out sort order from module preferences. + $sort_page_field = module::get_var("tag_albums", "subalbum_sort_by", "title"); + $sort_page_direction = module::get_var("tag_albums", "subalbum_sort_direction", "ASC"); + + // Figure out how many items to display on each page. + $page_size = module::get_var("gallery", "page_size", 9); + + // Figure out which page # the visitor is on and + // don't allow the visitor to go below page 1. + $page = Input::instance()->get("page", 1); + if ($page < 1) { + url::redirect("tag_albums/tag/" . $id . "/" . $album_id); + } + + // First item to display. + $offset = ($page - 1) * $page_size; + + // Determine the total number of items, + // for page numbering purposes. + $count = $this->_count_records(Array($id), "OR", true); + + // Figure out what the highest page number is. + $max_pages = ceil($count / $page_size); + + // Don't let the visitor go past the last page. + if ($max_pages && $page > $max_pages) { + url::redirect("tag_albums/tag/{$id}/" . $album_id . "/?page=$max_pages"); + } + + // Figure out which items to display on this page. + $tag_children = $this->_get_records(Array($id), $page_size, $offset, "items." . $sort_page_field, $sort_page_direction, "OR", true); + + // Create an array of "fake" items to display on the page. + $children = Array(); + foreach ($tag_children as $one_child) { + $child_tag = new Tag_Albums_Item($one_child->name, url::site("tag_albums/show/" . $one_child->id . "/" . $id . "/" . $album_id), $one_child->type); + $child_tag->id = $one_child->id; + if ($one_child->has_thumb()) { + $child_tag->set_thumb($one_child->thumb_url(), $one_child->thumb_width, $one_child->thumb_height); + } + $children[] = $child_tag; + } + + // Set up the previous and next page buttons. + if ($page > 1) { + $previous_page = $page - 1; + $view->previous_page_link = url::site("tag_albums/tag/{$id}/" . $album_id . "/?page={$previous_page}"); + } + if ($page < $max_pages) { + $next_page = $page + 1; + $view->next_page_link = url::site("tag_albums/tag/{$id}/" . $album_id . "/?page={$next_page}"); + } + + // Load the current tag. + $display_tag = ORM::factory("tag", $id); + + // Set up breadcrumbs for the page. + $tag_album_breadcrumbs = Array(); + if ($album_id != "") { + $counter = 0; + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($display_tag->name, ""); + $parent_item = ORM::factory("item", $album_tags[0]->album_id); + if ($album_tags[0]->tags != "*") { + $parent_item = ORM::factory("item", $parent_item->parent_id); + } + while ($parent_item->id != 1) { + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($parent_item->title, $parent_item->url()); + $parent_item = ORM::factory("item", $parent_item->parent_id); + } + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($parent_item->title, $parent_item->url()); + $tag_album_breadcrumbs = array_reverse($tag_album_breadcrumbs, true); + } else { + $tag_album_breadcrumbs[0] = new Tag_Albums_Breadcrumb(item::root()->title, item::root()->url()); + $tag_album_breadcrumbs[1] = new Tag_Albums_Breadcrumb("All Tags", url::site("tag_albums/")); + $tag_album_breadcrumbs[2] = new Tag_Albums_Breadcrumb($display_tag->name, ""); + } + + // Set up and display the actual page. + $template = new Theme_View("page.html", "collection", "Tag Albums"); + $template->page_title = $display_tag->name; + $template->set_global("page", $page); + $template->set_global("page_size", $page_size); + $template->set_global("max_pages", $max_pages); + $template->set_global("children", $children); + $template->set_global("children_count", $count); + $template->content = new View("tag_albums.html"); + $template->content->title = $display_tag->name; + $template->set_global("breadcrumbs", $tag_album_breadcrumbs); + print $template; + } + + public function show($item_id, $tag_id, $album_id) { + // Display the specified photo or video ($item_id) with breadcrumbs + // that point back to a virtual album ($tag_id / $album_id). + + // Make sure #album_id is valid, clear it out if it isn't. + $album_tags = ORM::factory("tags_album_id") + ->where("id", "=", $album_id) + ->find_all(); + if (count($album_tags) == 0) { + $album_id = ""; + } + + // Load the tag and item, make sure the user has access to the item. + $display_tag = ORM::factory("tag", $tag_id); + $item = ORM::factory("item", $item_id); + access::required("view", $item); + + // Figure out sort order from module preferences. + $sort_page_field = ""; + $sort_page_direction = ""; + if (($tag_id > 0) || (count($album_tags) == 0)) { + $sort_page_field = module::get_var("tag_albums", "subalbum_sort_by", "title"); + $sort_page_direction = module::get_var("tag_albums", "subalbum_sort_direction", "ASC"); + } else { + $parent_album = ORM::factory("item", $album_tags[0]->album_id); + $sort_page_field = $parent_album->sort_column; + $sort_page_direction = $parent_album->sort_order; + } + + // Load the number of items in the parent album, and determine previous and next items. + $sibling_count = ""; + $tag_children = ""; + $previous_item = ""; + $next_item = ""; + $position = 0; + if ($tag_id > 0) { + $sibling_count = $this->_count_records(Array($tag_id), "OR", false); + $position = $this->_get_position($item->$sort_page_field, $item->id, Array($tag_id), "items." . $sort_page_field, $sort_page_direction, $album_tags_search_type); + if ($position > 1) { + $previous_item_object = $this->_get_records(Array($tag_id), 1, $position-2, "items." . $sort_page_field, $sort_page_direction, $album_tags_search_type, false); + if (count($previous_item_object) > 0) { + $previous_item = new Tag_Albums_Item($previous_item_object[0]->name, url::site("tag_albums/show/" . $previous_item_object[0]->id . "/" . $tag_id . "/" . $album_id), $previous_item_object[0]->type); + } + } + $next_item_object = $this->_get_records(Array($tag_id), 1, $position, "items." . $sort_page_field, $sort_page_direction, $album_tags_search_type, false); + if (count($next_item_object) > 0) { + $next_item = new Tag_Albums_Item($next_item_object[0]->name, url::site("tag_albums/show/" . $next_item_object[0]->id . "/" . $tag_id . "/" . $album_id), $next_item_object[0]->type); + } + } else { + $tag_ids = Array(); + foreach (explode(",", $album_tags[0]->tags) as $tag_name) { + $tag = ORM::factory("tag")->where("name", "=", trim($tag_name))->find(); + if ($tag->loaded()) { + $tag_ids[] = $tag->id; + } + } + $album_tags_search_type = $album_tags[0]->search_type; + $sibling_count = $this->_count_records($tag_ids, $album_tags_search_type, false); + $position = $this->_get_position($item->$sort_page_field, $item->id, $tag_ids, "items." . $sort_page_field, $sort_page_direction, $album_tags_search_type); + if ($position > 1) { + $previous_item_object = $this->_get_records($tag_ids, 1, $position-2, "items." . $sort_page_field, $sort_page_direction, $album_tags_search_type, false); + if (count($previous_item_object) > 0) { + $previous_item = new Tag_Albums_Item($previous_item_object[0]->name, url::site("tag_albums/show/" . $previous_item_object[0]->id . "/" . $tag_id . "/" . $album_id), $previous_item_object[0]->type); + } + } + $next_item_object = $this->_get_records($tag_ids, 1, $position, "items." . $sort_page_field, $sort_page_direction, $album_tags_search_type, false); + if (count($next_item_object) > 0) { + $next_item = new Tag_Albums_Item($next_item_object[0]->name, url::site("tag_albums/show/" . $next_item_object[0]->id . "/" . $tag_id . "/" . $album_id), $next_item_object[0]->type); + } + } + + // Set up breadcrumbs + $tag_album_breadcrumbs = Array(); + if ($album_id != "") { + $counter = 0; + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($item->title, ""); + if ($album_tags[0]->tags == "*") { + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($display_tag->name, url::site("tag_albums/tag/" . $display_tag->id . "/" . $album_id)); + } + $parent_item = ORM::factory("item", $album_tags[0]->album_id); + while ($parent_item->id != 1) { + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($parent_item->title, $parent_item->url()); + $parent_item = ORM::factory("item", $parent_item->parent_id); + } + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($parent_item->title, $parent_item->url()); + $tag_album_breadcrumbs = array_reverse($tag_album_breadcrumbs, true); + } else { + $tag_album_breadcrumbs[0] = new Tag_Albums_Breadcrumb(item::root()->title, item::root()->url()); + $tag_album_breadcrumbs[1] = new Tag_Albums_Breadcrumb("All Tags", url::site("tag_albums/")); + $tag_album_breadcrumbs[2] = new Tag_Albums_Breadcrumb($display_tag->name, url::site("tag_albums/tag/" . $display_tag->id)); + $tag_album_breadcrumbs[3] = new Tag_Albums_Breadcrumb($item->title, ""); + } + + // Load the page. + if ($item->is_photo()) { + $template = new Theme_View("page.html", "item", "photo"); + $template->page_title = $item->title; + $template->set_global("children", Array()); + $template->set_global("item", $item); + $template->set_global("previous_item", $previous_item); + $template->set_global("next_item", $next_item); + $template->set_global("children_count", 0); + $template->set_global("position", $position); + $template->set_global("sibling_count", $sibling_count); + $template->content = new View("tag_albums_photo.html"); + $template->content->title = $item->title; + $template->set_global("breadcrumbs", $tag_album_breadcrumbs); + print $template; + } elseif ($item->is_movie()) { + $template = new Theme_View("page.html", "item", "movie"); + $template->page_title = $item->title; + $template->set_global("children", Array()); + $template->set_global("item", $item); + $template->set_global("previous_item", $previous_item); + $template->set_global("next_item", $next_item); + $template->set_global("children_count", 0); + $template->set_global("position", $position); + $template->set_global("sibling_count", $sibling_count); + $template->content = new View("tag_albums_movie.html"); + $template->content->title = $item->title; + $template->set_global("breadcrumbs", $tag_album_breadcrumbs); + print $template; + } else { + // If it's something we don't know how to deal with, just redirect to its real page. + url::redirect(url::abs_site("{$item->type}s/{$item->id}")); + } + } + + private function _get_position($item_title, $item_id, $tag_ids, $sort_field, $sort_direction, $search_type) { + // Determine an item's position within a virtual album. + + // Convert ASC/DESC to < or > characters. + if (!strcasecmp($sort_direction, "DESC")) { + $comp = ">"; + } else { + $comp = "<"; + } + + // Figure out how many items are _before the current item. + $items_model = ORM::factory("item"); + if ($search_type == "AND") { + $items_model->select('COUNT("*") AS result_count'); + } else { + $items_model->select("items.id"); + } + $items_model->viewable(); + $items_model->join("items_tags", "items.id", "items_tags.item_id"); + $items_model->open(); + $items_model->where("items_tags.tag_id", "=", $tag_ids[0]); + $counter = 1; + while ($counter < count($tag_ids)) { + $items_model->or_where("items_tags.tag_id", "=", $tag_ids[$counter]); + $counter++; + } + $items_model->close(); + $items_model->and_where("items.type", "!=", "album"); + $items_model->and_where($sort_field, $comp, $item_title); + $items_model->order_by($sort_field, $sort_direction); + $items_model->group_by("items.id"); + if ($search_type == "AND") { + $items_model->having("result_count", "=", count($tag_ids)); + } + $position = count($items_model->find_all()); + + // In case multiple items have identical sort criteria, query for + // everything with the same criteria, and increment the position + // one at a time until we find the right item. + $items_model = ORM::factory("item"); + if ($search_type == "AND") { + $items_model->select("items.id"); + $items_model->select('COUNT("*") AS result_count'); + } else { + $items_model->select("items.id"); + } + $items_model->viewable(); + $items_model->join("items_tags", "items.id", "items_tags.item_id"); + $items_model->open(); + $items_model->where("items_tags.tag_id", "=", $tag_ids[0]); + $counter = 1; + while ($counter < count($tag_ids)) { + $items_model->or_where("items_tags.tag_id", "=", $tag_ids[$counter]); + $counter++; + } + $items_model->close(); + $items_model->and_where("items.type", "!=", "album"); + $items_model->and_where($sort_field, "=", $item_title); + $items_model->order_by($sort_field, $sort_direction); + $items_model->group_by("items.id"); + if ($search_type == "AND") { + $items_model->having("result_count", "=", count($tag_ids)); + } + $match_items = $items_model->find_all(); + foreach ($match_items as $one_item) { + $position++; + if ($one_item->id == $item_id) { + break; + } + } + + return ($position); + } + + private function _get_records($tag_ids, $page_size, $offset, $sort_field, $sort_direction, $search_type, $include_albums) { + // Returns an array of items to be displayed on the current page. + + $items_model = ORM::factory("item"); + if ($search_type == "AND") { + // For some reason, if I do 'select("*")' the item ids all have values that are 1000+ + // higher then they should be. So instead, I'm manually selecting each column that I need. + $items_model->select("items.id"); + $items_model->select("items.name"); + $items_model->select("items.type"); + $items_model->select("items.thumb_width"); + $items_model->select("items.thumb_height"); + $items_model->select("items.left_ptr"); + $items_model->select("items.right_ptr"); + $items_model->select("items.relative_path_cache"); + $items_model->select('COUNT("*") AS result_count'); + } + $items_model->viewable(); + $items_model->join("items_tags", "items.id", "items_tags.item_id"); + $items_model->open(); + $items_model->where("items_tags.tag_id", "=", $tag_ids[0]); + $counter = 1; + while ($counter < count($tag_ids)) { + $items_model->or_where("items_tags.tag_id", "=", $tag_ids[$counter]); + $counter++; + } + $items_model->close(); + if ($include_albums == false) { + $items_model->and_where("items.type", "!=", "album"); + } + $items_model->order_by($sort_field, $sort_direction); + $items_model->group_by("items.id"); + if ($search_type == "AND") { + $items_model->having("result_count", "=", count($tag_ids)); + } + return $items_model->find_all($page_size, $offset); + } + + private function _count_records($tag_ids, $search_type, $include_albums) { + // Count the number of viewable items for the designated tag(s) + // and return that number. + + if (count($tag_ids) == 0) { + // If no tags were specified, return 0. + return 0; + + } elseif (count($tag_ids) == 1) { + // if one tag was specified, we can use count_all to get the number. + $count = ORM::factory("item") + ->viewable() + ->join("items_tags", "items.id", "items_tags.item_id") + ->where("items_tags.tag_id", "=", $tag_ids[0]); + if ($include_albums == false) { + $count->and_where("items.type", "!=", "album"); + } + return $count->count_all(); + + } else { + // If multiple tags were specified, count_all won't work, + // so we'll have to do count(find_all) instead. + $items_model = ORM::factory("item"); + if ($search_type == "AND") { + $items_model->select('COUNT("*") AS result_count'); + } else { + $items_model->select('items.id'); + } + $items_model->viewable(); + $items_model->join("items_tags", "items.id", "items_tags.item_id"); + $items_model->where("items_tags.tag_id", "=", $tag_ids[0]); + $counter = 1; + while ($counter < count($tag_ids)) { + $items_model->or_where("items_tags.tag_id", "=", $tag_ids[$counter]); + $counter++; + } + if ($include_albums == false) { + $items_model->and_where("items.type", "!=", "album"); + } + $items_model->group_by("items.id"); + if ($search_type == "AND") { + $items_model->having("result_count", "=", count($tag_ids)); + } + + return count($items_model->find_all()); + } + } +} diff --git a/3.0/modules/tag_albums/helpers/tag_albums_block.php b/3.0/modules/tag_albums/helpers/tag_albums_block.php new file mode 100644 index 00000000..7243722c --- /dev/null +++ b/3.0/modules/tag_albums/helpers/tag_albums_block.php @@ -0,0 +1,40 @@ + t("Tag Albums")); + } + + static function get($block_id, $theme) { + $block = ""; + + switch ($block_id) { + case "tag_albums": + // Make a new sidebar block. + $block = new Block(); + $block->css_id = "g-tag-albums"; + $block->title = t("Tag Albums"); + $block->content = new View("tag_albums_block.html"); + + break; + } + return $block; + } +} diff --git a/3.0/modules/tag_albums/helpers/tag_albums_event.php b/3.0/modules/tag_albums/helpers/tag_albums_event.php new file mode 100644 index 00000000..033293f1 --- /dev/null +++ b/3.0/modules/tag_albums/helpers/tag_albums_event.php @@ -0,0 +1,110 @@ +module == "tag") { + $data->messages["warn"][] = t("The Tag Albums module requires the Tags module."); + } + } + + static function module_change($changes) { + // See if the Tags module is installed, + // tell the user to install it if it isn't. + if (!module::is_active("tag") || in_array("tag", $changes->deactivate)) { + site_status::warning( + t("The Tag Albums module requires the Tags module. " . + "Activate the Tags module now", + array("url" => url::site("admin/modules"))), + "tag_albums_needs_tag"); + } else { + site_status::clear("tag_albums_needs_tag"); + } + } + + static function admin_menu($menu, $theme) { + // Add a link to the admin page to the Content menu. + $menu->get("settings_menu") + ->append(Menu::factory("link") + ->id("tag_albums") + ->label(t("Tag Albums Settings")) + ->url(url::site("admin/tag_albums"))); + } + + static function item_edit_form($item, $form) { + // Create fields on the album edit screen to allow the user to link + // the album to a tag_albums page. + if (!($item->is_album())) { + return; + } + + $url = url::site("tags/autocomplete"); + $form->script("") + ->text("$('form input[name=tag_albums]').ready(function() { + $('form input[name=tag_albums]').autocomplete( + '$url', {max: 30, multiple: true, multipleSeparator: ',', cacheLength: 1}); + });"); + + $album_tags = ORM::factory("tags_album_id") + ->where("album_id", "=", $item->id) + ->find_all(); + + $tag_names = ""; + $tag_album_type = "OR"; + if (count($album_tags) > 0) { + $tag_names = $album_tags[0]->tags; + $tag_album_type = $album_tags[0]->search_type; + } + + $tags_album_group = $form->edit_item->group("tags_album_group"); + $tags_album_group->dropdown("tags_album_type") + ->options( + array("OR" => t("Display items that contain ANY of the following tags:"), + "AND" => t("Display items that contain ALL of the following tags:"))) + ->selected($tag_album_type); + $tags_album_group->input("tag_albums") + ->value($tag_names); + } + + static function item_deleted($item) { + // Whenever an item is deleted, delete any corresponding data. + db::build()->delete("tags_album_ids")->where("album_id", "=", $item->id)->execute(); + } + + static function item_edit_form_completed($item, $form) { + // Update the database with any changes to the tag_albums field. + if (!($item->is_album())) { + return; + } + + $record = ORM::factory("tags_album_id")->where("album_id", "=", $item->id)->find(); + + if ($form->edit_item->tags_album_group->tag_albums->value != "") { + if (!$record->loaded()) { + $record->album_id = $item->id; + } + $record->tags = $form->edit_item->tags_album_group->tag_albums->value; + $record->search_type = $form->edit_item->tags_album_group->tags_album_type->value; + $record->save(); + } else { + db::build()->delete("tags_album_ids")->where("album_id", "=", $item->id)->execute(); + } + } +} diff --git a/3.0/modules/tag_albums/helpers/tag_albums_installer.php b/3.0/modules/tag_albums/helpers/tag_albums_installer.php new file mode 100644 index 00000000..6fa9fa10 --- /dev/null +++ b/3.0/modules/tag_albums/helpers/tag_albums_installer.php @@ -0,0 +1,57 @@ +query("CREATE TABLE IF NOT EXISTS {tags_album_ids} ( + `id` int(9) NOT NULL auto_increment, + `album_id` int(9) NOT NULL, + `tags` varchar(2048) default NULL, + `search_type` varchar(128) NOT NULL, + PRIMARY KEY (`id`), + KEY(`album_id`, `id`)) + DEFAULT CHARSET=utf8;"); + + // Set up some default values. + module::set_var("tag_albums", "tag_sort_by", "name"); + module::set_var("tag_albums", "tag_sort_direction", "ASC"); + module::set_var("tag_albums", "subalbum_sort_by", "title"); + module::set_var("tag_albums", "subalbum_sort_direction", "ASC"); + + // Set the module's version number. + module::set_version("tag_albums", 1); + } + + static function deactivate() { + site_status::clear("tag_albums_needs_tag"); + } + + static function can_activate() { + $messages = array(); + if (!module::is_active("tag")) { + $messages["warn"][] = t("The Tag Albums module requires the Tags module."); + } + return $messages; + } + + static function uninstall() { + module::delete("tag_albums"); + } +} diff --git a/3.0/modules/tag_albums/helpers/tag_albums_theme.php b/3.0/modules/tag_albums/helpers/tag_albums_theme.php new file mode 100644 index 00000000..3eae0c61 --- /dev/null +++ b/3.0/modules/tag_albums/helpers/tag_albums_theme.php @@ -0,0 +1,34 @@ +item()) { + $album_tags = ORM::factory("tags_album_id") + ->where("album_id", "=", $theme->item->id) + ->find_all(); + if (count($album_tags) > 0) { + url::redirect(url::abs_site("tag_albums/album/" . $album_tags[0]->id)); + } + } + return; + } +} diff --git a/3.0/modules/tag_albums/libraries/Tag_Albums_Breadcrumb.php b/3.0/modules/tag_albums/libraries/Tag_Albums_Breadcrumb.php new file mode 100644 index 00000000..ba576e49 --- /dev/null +++ b/3.0/modules/tag_albums/libraries/Tag_Albums_Breadcrumb.php @@ -0,0 +1,31 @@ +title = $new_title; + $this->url = $new_url; + } +} diff --git a/3.0/modules/tag_albums/libraries/Tag_Albums_Item.php b/3.0/modules/tag_albums/libraries/Tag_Albums_Item.php new file mode 100644 index 00000000..beddc108 --- /dev/null +++ b/3.0/modules/tag_albums/libraries/Tag_Albums_Item.php @@ -0,0 +1,110 @@ +item_type == "album") { + return true; + } else { + return false; + } + } + + public function has_thumb() { + if ($this->thumb_url != "") { + return true; + } else { + return false; + } + } + + public function thumb_img($extra_attrs=array(), $max=null, $center_vertically=false) { + list ($height, $width) = $this->scale_dimensions($max); + if ($center_vertically && $max) { + // The constant is divide by 2 to calculate the file and 10 to convert to em + $margin_top = (int)(($max - $height) / 20); + $extra_attrs["style"] = "margin-top: {$margin_top}em"; + $extra_attrs["title"] = $this->title; + } + $attrs = array_merge($extra_attrs, + array( + "src" => $this->thumb_url(), + "alt" => $this->title, + "width" => $width, + "height" => $height) + ); + // html::image forces an absolute url which we don't want + return ""; + } + + public function scale_dimensions($max) { + $width = $this->thumb_width; + $height = $this->thumb_height; + + if ($width <= $max && $height <= $max) { + return array($height, $width); + } + + if ($height) { + if (isset($max)) { + if ($width > $height) { + $height = (int)($max * $height / $width); + $width = $max; + } else { + $width = (int)($max * $width / $height); + $height = $max; + } + } + } else { + // Missing thumbnail, can happen on albums with no photos yet. + // @todo we should enforce a placeholder for those albums. + $width = 0; + $height = 0; + } + return array($height, $width); + } + + public function thumb_url() { + return $this->thumb_url; + } + + public function url() { + return $this->url; + } + + public function set_thumb($new_url, $new_width, $new_height) { + $this->thumb_url = $new_url; + $this->thumb_width = $new_width; + $this->thumb_height = $new_height; + } + + public function __construct($new_title, $new_url, $new_type) { + $this->title = $new_title; + $this->url = $new_url; + $this->item_type = $new_type; + } +} diff --git a/3.0/modules/tag_albums/models/tag.php b/3.0/modules/tag_albums/models/tag.php new file mode 100644 index 00000000..d15a36e0 --- /dev/null +++ b/3.0/modules/tag_albums/models/tag.php @@ -0,0 +1,141 @@ +loaded()) { + // Set reasonable defaults + $this->count = 0; + } + } + + /** + * 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) + * @return ORM_Iterator + */ + public function items($limit=null, $offset=null, $type=null) { + $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->find_all($limit, $offset); + } + + /** + * Return the count of all viewable items associated with this tag. + * @param string $type the type of item (album, photo) + * @return integer + */ + public function items_count($type=null) { + $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(); + } + + /** + * Overload ORM::save() to trigger an item_related_update event for all items that are related + * to this tag. + */ + public function save() { + $related_item_ids = array(); + foreach (db::build() + ->select("item_id") + ->from("items_tags") + ->where("tag_id", "=", $this->id) + ->execute() as $row) { + $related_item_ids[$row->item_id] = 1; + } + + if (isset($this->object_relations["items"])) { + $added = array_diff($this->changed_relations["items"], $this->object_relations["items"]); + $removed = array_diff($this->object_relations["items"], $this->changed_relations["items"]); + if (isset($this->changed_relations["items"])) { + $changed = array_merge($added, $removed); + } + $this->count = count($this->object_relations["items"]) + count($added) - count($removed); + } + + $result = parent::save(); + + if (!empty($changed)) { + foreach (ORM::factory("item")->where("id", "IN", $changed)->find_all() as $item) { + module::event("item_related_update", $item); + } + } + + return $result; + } + + /** + * Overload ORM::delete() to trigger an item_related_update event for all items that are + * related to this tag, and delete all items_tags relationships. + */ + public function delete($ignored_id=null) { + $related_item_ids = array(); + foreach (db::build() + ->select("item_id") + ->from("items_tags") + ->where("tag_id", "=", $this->id) + ->execute() as $row) { + $related_item_ids[$row->item_id] = 1; + } + + db::build()->delete("items_tags")->where("tag_id", "=", $this->id)->execute(); + $result = parent::delete(); + + if ($related_item_ids) { + foreach (ORM::factory("item") + ->where("id", "IN", array_keys($related_item_ids)) + ->find_all() as $item) { + module::event("item_related_update", $item); + } + } + return $result; + } + + /** + * Return the server-relative url to this item, eg: + * /gallery3/index.php/tags/35 + * + * @param string $query the query string (eg "page=3") + */ + public function url($query=null) { + $url = url::site("/tag_albums/tag/{$this->id}/" . urlencode($this->name)); + if ($query) { + $url .= "?$query"; + } + return $url; + } +} diff --git a/3.0/modules/tag_albums/models/tags_album_id.php b/3.0/modules/tag_albums/models/tags_album_id.php new file mode 100644 index 00000000..a9b16b4f --- /dev/null +++ b/3.0/modules/tag_albums/models/tags_album_id.php @@ -0,0 +1,21 @@ + +

+ +

+
+
+ +
diff --git a/3.0/modules/tag_albums/views/tag_albums.html.php b/3.0/modules/tag_albums/views/tag_albums.html.php new file mode 100644 index 00000000..c2466522 --- /dev/null +++ b/3.0/modules/tag_albums/views/tag_albums.html.php @@ -0,0 +1,64 @@ + +
+ + + + + +
+ +
+ dynamic_top() ?> +

+
+
+ + + + +dynamic_bottom() ?> + +paginator() ?> diff --git a/3.0/modules/tag_albums/views/tag_albums_block.html.php b/3.0/modules/tag_albums/views/tag_albums_block.html.php new file mode 100644 index 00000000..d4b08087 --- /dev/null +++ b/3.0/modules/tag_albums/views/tag_albums_block.html.php @@ -0,0 +1,4 @@ + + diff --git a/3.0/modules/tag_albums/views/tag_albums_movie.html.php b/3.0/modules/tag_albums/views/tag_albums_movie.html.php new file mode 100644 index 00000000..f15823ec --- /dev/null +++ b/3.0/modules/tag_albums/views/tag_albums_movie.html.php @@ -0,0 +1,44 @@ + +
+ + + + + +
+
+ photo_top() ?> + + paginator() ?> + +
+ resize_top($item) ?> + movie_img(array("class" => "g-movie", "id" => "g-item-id-{$item->id}")) ?> + resize_bottom($item) ?> +
+ +
+

title) ?>

+
description)) ?>
+
+ + photo_bottom() ?> +
diff --git a/3.0/modules/tag_albums/views/tag_albums_photo.html.php b/3.0/modules/tag_albums/views/tag_albums_photo.html.php new file mode 100644 index 00000000..4f78696e --- /dev/null +++ b/3.0/modules/tag_albums/views/tag_albums_photo.html.php @@ -0,0 +1,75 @@ + +
+ + + + + +
+ + + + + +
+ photo_top() ?> + + paginator() ?> + + + +
+

title) ?>

+
description)) ?>
+
+ + photo_bottom() ?> +
diff --git a/3.1/modules/tag_albums/controllers/admin_tag_albums.php b/3.1/modules/tag_albums/controllers/admin_tag_albums.php new file mode 100644 index 00000000..71cf8eb6 --- /dev/null +++ b/3.1/modules/tag_albums/controllers/admin_tag_albums.php @@ -0,0 +1,100 @@ +content = new View("admin_tag_albums.html"); + + // Generate a form for the admin Settings. + $view->content->tag_albums_form = $this->_get_admin_form(); + + // Display the page. + print $view; + } + + private function _get_admin_form() { + $form = new Forge("admin/tag_albums/saveprefs", "", "post", + array("id" => "g-tag-albums-admin-form")); + + $tag_albums_tagsort_group = $form->group("Tag_Albums_Tag_Sort")->label(t("\"All Tags\" Album Preferences")); + $tag_albums_tagsort_group->dropdown("tag_sort_by") + ->label(t("Sort \"All Tags\" Albums By:")) + ->options( + array("name" => "Name", + "count" => "Count", + "id" => "ID Number")) + ->selected(module::get_var("tag_albums", "tag_sort_by")); + $tag_albums_tagsort_group->dropdown("tag_sort_direction") + ->label(t("Display Albums In:")) + ->options( + array("ASC" => "Ascending Order", + "DESC" => "Descending")) + ->selected(module::get_var("tag_albums", "tag_sort_direction")); + + $tag_albums_tagitemsort_group = $form->group("Tag_Albums_Tag_Item_Sort")->label(t("\"All Tags\" Sub-Album Preferences")); + $tag_albums_tagitemsort_group->dropdown("subalbum_sort_by") + ->label(t("Sort Contents of Sub-Albums By:")) + ->options( + array("title" => "Title", + "name" => "File name", + "captured" => "Date captured", + "created" => "Date uploaded", + "updated" => "Date modified", + "view_count" => "Number of views")) + ->selected(module::get_var("tag_albums", "subalbum_sort_by")); + $tag_albums_tagitemsort_group->dropdown("subalbum_sort_direction") + ->label(t("Display Contents of Sub-Albums In:")) + ->options( + array("ASC" => "Ascending Order", + "DESC" => "Descending")) + ->selected(module::get_var("tag_albums", "subalbum_sort_direction")); + + // Add a save button to the form. + $form->submit("SaveSettings")->value(t("Save")); + + // Return the newly generated form. + return $form; + } + + public function saveprefs() { + // Prevent Cross Site Request Forgery + access::verify_csrf(); + + $form = $this->_get_admin_form(); + if ($form->validate()) { + Kohana_Log::add("error",print_r($form,1)); + module::set_var("tag_albums", "tag_sort_by", $form->Tag_Albums_Tag_Sort->tag_sort_by->value); + module::set_var("tag_albums", "tag_sort_direction", $form->Tag_Albums_Tag_Sort->tag_sort_direction->value); + module::set_var("tag_albums", "subalbum_sort_by", $form->Tag_Albums_Tag_Item_Sort->subalbum_sort_by->value); + module::set_var("tag_albums", "subalbum_sort_direction", $form->Tag_Albums_Tag_Item_Sort->subalbum_sort_direction->value); + + message::success(t("Your settings have been saved.")); + url::redirect("admin/tag_albums"); + } + + // Else show the page with errors + $view = new Admin_View("admin.html"); + $view->content = new View("admin_tag_albums.html"); + $view->content->tag_albums_form = $form; + print $view; + } +} diff --git a/3.1/modules/tag_albums/controllers/tag_albums.php b/3.1/modules/tag_albums/controllers/tag_albums.php new file mode 100644 index 00000000..3e47f1e7 --- /dev/null +++ b/3.1/modules/tag_albums/controllers/tag_albums.php @@ -0,0 +1,649 @@ +where("id", "=", $id) + ->find_all(); + + // If it doesn't exist, redirect to the modules root page. + if (count($album_tags) == 0) { + url::redirect("tag_albums/"); + } + + // If it does exist, and is set to *, load a list of all tags. + if ($album_tags[0]->tags == "*") { + $this->index($id); + } else { + // Otherwise, populate this page with the specified items. + + // Inherit permissions, title and description from the album that linked to this page. + $album = ORM::factory("item", $album_tags[0]->album_id); + access::required("view", $album); + $page_title = $album->title; + $page_description = $album->description; + + // Determine page sort order. + $sort_page_field = $album->sort_column; + $sort_page_direction = $album->sort_order; + + // Determine search type (AND/OR) and generate an array of the tag ids. + $tag_ids = Array(); + foreach (explode(",", $album_tags[0]->tags) as $tag_name) { + $tag = ORM::factory("tag")->where("name", "=", trim($tag_name))->find(); + if ($tag->loaded()) { + $tag_ids[] = $tag->id; + } + } + $album_tags_search_type = $album_tags[0]->search_type; + + // Figure out how many items are in this "virtual album" + $count = $this->_count_records($tag_ids, $album_tags_search_type, true); + + // Figure out how many items to display on each page. + $page_size = module::get_var("gallery", "page_size", 9); + + // Figure out which page # the visitor is on and + // don't allow the visitor to go below page 1. + $page = Input::instance()->get("page", 1); + if ($page < 1) { + url::redirect("tag_albums/album/" . $id); + } + + // First item to display. + $offset = ($page - 1) * $page_size; + + // Figure out what the highest page number is. + $max_pages = ceil($count / $page_size); + + // Don't let the visitor go past the last page. + if ($max_pages && $page > $max_pages) { + url::redirect("tag_albums/album/{$id}/?page=$max_pages"); + } + + // Figure out which items to display on this page and store their details in $children. + $tag_children = $this->_get_records($tag_ids, $page_size, $offset, "items." . $sort_page_field, $sort_page_direction, $album_tags_search_type, true); + $children = Array(); + foreach ($tag_children as $one_child) { + $child_tag = new Tag_Albums_Item($one_child->name, url::site("tag_albums/show/" . $one_child->id . "/0/" . $id), $one_child->type); + $child_tag->id = $one_child->id; + if ($one_child->has_thumb()) { + $child_tag->set_thumb($one_child->thumb_url(), $one_child->thumb_width, $one_child->thumb_height); + } + $children[] = $child_tag; + } + + // Set up the previous and next page buttons. + if ($page > 1) { + $previous_page = $page - 1; + $view->previous_page_link = url::site("tag_albums/album/{$id}/?page={$previous_page}"); + } + if ($page < $max_pages) { + $next_page = $page + 1; + $view->next_page_link = url::site("tag_albums/album/{$id}/?page={$next_page}"); + } + + // Set up breadcrumbs. + $tag_album_breadcrumbs = Array(); + $counter = 0; + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($album->title, ""); + $parent_item = ORM::factory("item", $album->parent_id); + while ($parent_item->id != 1) { + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($parent_item->title, $parent_item->url()); + $parent_item = ORM::factory("item", $parent_item->parent_id); + } + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($parent_item->title, $parent_item->url()); + $tag_album_breadcrumbs = array_reverse($tag_album_breadcrumbs, true); + + // Set up and display the actual page. + $template = new Theme_View("page.html", "collection", "Tag Albums"); + $template->page_title = $page_title; + $template->set_global("page", $page); + $template->set_global("page_size", $page_size); + $template->set_global("max_pages", $max_pages); + $template->set_global("children", $children); + $template->set_global("children_count", $count); + $template->content = new View("tag_albums.html"); + $template->content->title = $page_title; + $template->content->description = $page_description; + $template->set_global("breadcrumbs", $tag_album_breadcrumbs); + print $template; + } + } + + public function index($id) { + // Load a page containing sub-albums for each tag in the gallery. + + // If an ID was specified, make sure it's valid. + $album_tags = ORM::factory("tags_album_id") + ->where("id", "=", $id) + ->find_all(); + if (count($album_tags) == 0) { + $id = ""; + } + + // Inherit permissions, title and description from the album that linked to this page, + // if available, if not use the root album and some default values. + $album = ""; + $page_title = t("All Tags"); + $page_description = ""; + if ($id == "") { + $album = ORM::factory("item", 1); + access::required("view", $album); + } else { + $album = ORM::factory("item", $album_tags[0]->album_id); + access::required("view", $album); + $page_title = $album->title; + $page_description = $album->description; + } + + // Figure out sort order from module preferences. + $sort_page_field = module::get_var("tag_albums", "tag_sort_by", "name"); + $sort_page_direction = module::get_var("tag_albums", "tag_sort_direction", "ASC"); + + // Figure out how many items to display on each page. + $page_size = module::get_var("gallery", "page_size", 9); + + // Figure out which page # the visitor is on and + // don't allow the visitor to go below page 1. + $page = Input::instance()->get("page", 1); + if ($page < 1) { + url::redirect("tag_albums/"); + } + + // First item to display. + $offset = ($page - 1) * $page_size; + + // Determine the total number of items, + // for page numbering purposes. + $all_tags_count = ORM::factory("tag") + ->count_all(); + + // Figure out what the highest page number is. + $max_pages = ceil($all_tags_count / $page_size); + + // Don't let the visitor go past the last page. + if ($max_pages && $page > $max_pages) { + url::redirect("tag_albums/?page=$max_pages"); + } + + // Figure out which items to display on this page. + $display_tags = ORM::factory("tag") + ->order_by("tags." . $sort_page_field, $sort_page_direction) + ->find_all($page_size, $offset); + + // Set up the previous and next page buttons. + if ($page > 1) { + $previous_page = $page - 1; + $view->previous_page_link = url::site("tag_albums/album/" . $id . "/?page={$previous_page}"); + } + if ($page < $max_pages) { + $next_page = $page + 1; + $view->next_page_link = url::site("tag_albums/album/" . $id . "/?page={$next_page}"); + } + + // Generate an arry of "fake" items, one for each tag on the page. + // Grab thumbnails from the most recently uploaded item for each tag, if available. + $children = Array(); + foreach ($display_tags as $one_tag) { + $tag_item = ORM::factory("item") + ->viewable() + ->join("items_tags", "items.id", "items_tags.item_id") + ->where("items_tags.tag_id", "=", $one_tag->id) + ->order_by("items.id", "DESC") + ->find_all(1, 0); + $child_tag = new Tag_Albums_Item($one_tag->name, url::site("tag_albums/tag/" . $one_tag->id . "/" . $id), "album"); + if (count($tag_item) > 0) { + if ($tag_item[0]->has_thumb()) { + $child_tag->set_thumb($tag_item[0]->thumb_url(), $tag_item[0]->thumb_width, $tag_item[0]->thumb_height); + } + } + $children[] = $child_tag; + } + + // Set up breadcrumbs. + $tag_album_breadcrumbs = Array(); + if ($id != "") { + $counter = 0; + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($album->title, ""); + $parent_item = ORM::factory("item", $album->parent_id); + while ($parent_item->id != 1) { + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($parent_item->title, $parent_item->url()); + $parent_item = ORM::factory("item", $parent_item->parent_id); + } + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($parent_item->title, $parent_item->url()); + $tag_album_breadcrumbs = array_reverse($tag_album_breadcrumbs, true); + } else { + $tag_album_breadcrumbs[0] = new Tag_Albums_Breadcrumb(item::root()->title, item::root()->url()); + $tag_album_breadcrumbs[1] = new Tag_Albums_Breadcrumb($page_title, ""); + } + + // Set up and display the actual page. + $template = new Theme_View("page.html", "collection", "Tag Albums"); + $template->page_title = $page_title; + $template->set_global("page", $page); + $template->set_global("page_size", $page_size); + $template->set_global("max_pages", $max_pages); + $template->set_global("children", $children); + $template->set_global("children_count", $all_tags_count); + $template->content = new View("tag_albums.html"); + $template->content->title = $page_title; + $template->content->description = $page_description; + $template->set_global("breadcrumbs", $tag_album_breadcrumbs); + print $template; + } + + public function tag($id, $album_id) { + // Display a dynamic album containing everything tagged with a specific tag where, + // TAG is $id. + // Optionally, set the breadcrumbs to make this page look like an album where the + // album is $album_id. + + // Make sure $album_id is valid, clear it out if it isn't. + $album_tags = ORM::factory("tags_album_id") + ->where("id", "=", $album_id) + ->find_all(); + if (count($album_tags) == 0) { + $album_id = ""; + } + + // Figure out sort order from module preferences. + $sort_page_field = module::get_var("tag_albums", "subalbum_sort_by", "title"); + $sort_page_direction = module::get_var("tag_albums", "subalbum_sort_direction", "ASC"); + + // Figure out how many items to display on each page. + $page_size = module::get_var("gallery", "page_size", 9); + + // Figure out which page # the visitor is on and + // don't allow the visitor to go below page 1. + $page = Input::instance()->get("page", 1); + if ($page < 1) { + url::redirect("tag_albums/tag/" . $id . "/" . $album_id); + } + + // First item to display. + $offset = ($page - 1) * $page_size; + + // Determine the total number of items, + // for page numbering purposes. + $count = $this->_count_records(Array($id), "OR", true); + + // Figure out what the highest page number is. + $max_pages = ceil($count / $page_size); + + // Don't let the visitor go past the last page. + if ($max_pages && $page > $max_pages) { + url::redirect("tag_albums/tag/{$id}/" . $album_id . "/?page=$max_pages"); + } + + // Figure out which items to display on this page. + $tag_children = $this->_get_records(Array($id), $page_size, $offset, "items." . $sort_page_field, $sort_page_direction, "OR", true); + + // Create an array of "fake" items to display on the page. + $children = Array(); + foreach ($tag_children as $one_child) { + $child_tag = new Tag_Albums_Item($one_child->name, url::site("tag_albums/show/" . $one_child->id . "/" . $id . "/" . $album_id), $one_child->type); + $child_tag->id = $one_child->id; + if ($one_child->has_thumb()) { + $child_tag->set_thumb($one_child->thumb_url(), $one_child->thumb_width, $one_child->thumb_height); + } + $children[] = $child_tag; + } + + // Set up the previous and next page buttons. + if ($page > 1) { + $previous_page = $page - 1; + $view->previous_page_link = url::site("tag_albums/tag/{$id}/" . $album_id . "/?page={$previous_page}"); + } + if ($page < $max_pages) { + $next_page = $page + 1; + $view->next_page_link = url::site("tag_albums/tag/{$id}/" . $album_id . "/?page={$next_page}"); + } + + // Load the current tag. + $display_tag = ORM::factory("tag", $id); + + // Set up breadcrumbs for the page. + $tag_album_breadcrumbs = Array(); + if ($album_id != "") { + $counter = 0; + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($display_tag->name, ""); + $parent_item = ORM::factory("item", $album_tags[0]->album_id); + if ($album_tags[0]->tags != "*") { + $parent_item = ORM::factory("item", $parent_item->parent_id); + } + while ($parent_item->id != 1) { + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($parent_item->title, $parent_item->url()); + $parent_item = ORM::factory("item", $parent_item->parent_id); + } + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($parent_item->title, $parent_item->url()); + $tag_album_breadcrumbs = array_reverse($tag_album_breadcrumbs, true); + } else { + $tag_album_breadcrumbs[0] = new Tag_Albums_Breadcrumb(item::root()->title, item::root()->url()); + $tag_album_breadcrumbs[1] = new Tag_Albums_Breadcrumb("All Tags", url::site("tag_albums/")); + $tag_album_breadcrumbs[2] = new Tag_Albums_Breadcrumb($display_tag->name, ""); + } + + // Set up and display the actual page. + $template = new Theme_View("page.html", "collection", "Tag Albums"); + $template->page_title = $display_tag->name; + $template->set_global("page", $page); + $template->set_global("page_size", $page_size); + $template->set_global("max_pages", $max_pages); + $template->set_global("children", $children); + $template->set_global("children_count", $count); + $template->content = new View("tag_albums.html"); + $template->content->title = $display_tag->name; + $template->set_global("breadcrumbs", $tag_album_breadcrumbs); + print $template; + } + + public function show($item_id, $tag_id, $album_id) { + // Display the specified photo or video ($item_id) with breadcrumbs + // that point back to a virtual album ($tag_id / $album_id). + + // Make sure #album_id is valid, clear it out if it isn't. + $album_tags = ORM::factory("tags_album_id") + ->where("id", "=", $album_id) + ->find_all(); + if (count($album_tags) == 0) { + $album_id = ""; + } + + // Load the tag and item, make sure the user has access to the item. + $display_tag = ORM::factory("tag", $tag_id); + $item = ORM::factory("item", $item_id); + access::required("view", $item); + + // Figure out sort order from module preferences. + $sort_page_field = ""; + $sort_page_direction = ""; + if (($tag_id > 0) || (count($album_tags) == 0)) { + $sort_page_field = module::get_var("tag_albums", "subalbum_sort_by", "title"); + $sort_page_direction = module::get_var("tag_albums", "subalbum_sort_direction", "ASC"); + } else { + $parent_album = ORM::factory("item", $album_tags[0]->album_id); + $sort_page_field = $parent_album->sort_column; + $sort_page_direction = $parent_album->sort_order; + } + + // Load the number of items in the parent album, and determine previous and next items. + $sibling_count = ""; + $tag_children = ""; + $previous_item = ""; + $next_item = ""; + $position = 0; + if ($tag_id > 0) { + $sibling_count = $this->_count_records(Array($tag_id), "OR", false); + $position = $this->_get_position($item->$sort_page_field, $item->id, Array($tag_id), "items." . $sort_page_field, $sort_page_direction, $album_tags_search_type); + if ($position > 1) { + $previous_item_object = $this->_get_records(Array($tag_id), 1, $position-2, "items." . $sort_page_field, $sort_page_direction, $album_tags_search_type, false); + if (count($previous_item_object) > 0) { + $previous_item = new Tag_Albums_Item($previous_item_object[0]->name, url::site("tag_albums/show/" . $previous_item_object[0]->id . "/" . $tag_id . "/" . $album_id), $previous_item_object[0]->type); + } + } + $next_item_object = $this->_get_records(Array($tag_id), 1, $position, "items." . $sort_page_field, $sort_page_direction, $album_tags_search_type, false); + if (count($next_item_object) > 0) { + $next_item = new Tag_Albums_Item($next_item_object[0]->name, url::site("tag_albums/show/" . $next_item_object[0]->id . "/" . $tag_id . "/" . $album_id), $next_item_object[0]->type); + } + } else { + $tag_ids = Array(); + foreach (explode(",", $album_tags[0]->tags) as $tag_name) { + $tag = ORM::factory("tag")->where("name", "=", trim($tag_name))->find(); + if ($tag->loaded()) { + $tag_ids[] = $tag->id; + } + } + $album_tags_search_type = $album_tags[0]->search_type; + $sibling_count = $this->_count_records($tag_ids, $album_tags_search_type, false); + $position = $this->_get_position($item->$sort_page_field, $item->id, $tag_ids, "items." . $sort_page_field, $sort_page_direction, $album_tags_search_type); + if ($position > 1) { + $previous_item_object = $this->_get_records($tag_ids, 1, $position-2, "items." . $sort_page_field, $sort_page_direction, $album_tags_search_type, false); + if (count($previous_item_object) > 0) { + $previous_item = new Tag_Albums_Item($previous_item_object[0]->name, url::site("tag_albums/show/" . $previous_item_object[0]->id . "/" . $tag_id . "/" . $album_id), $previous_item_object[0]->type); + } + } + $next_item_object = $this->_get_records($tag_ids, 1, $position, "items." . $sort_page_field, $sort_page_direction, $album_tags_search_type, false); + if (count($next_item_object) > 0) { + $next_item = new Tag_Albums_Item($next_item_object[0]->name, url::site("tag_albums/show/" . $next_item_object[0]->id . "/" . $tag_id . "/" . $album_id), $next_item_object[0]->type); + } + } + + // Set up breadcrumbs + $tag_album_breadcrumbs = Array(); + if ($album_id != "") { + $counter = 0; + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($item->title, ""); + if ($album_tags[0]->tags == "*") { + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($display_tag->name, url::site("tag_albums/tag/" . $display_tag->id . "/" . $album_id)); + } + $parent_item = ORM::factory("item", $album_tags[0]->album_id); + while ($parent_item->id != 1) { + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($parent_item->title, $parent_item->url()); + $parent_item = ORM::factory("item", $parent_item->parent_id); + } + $tag_album_breadcrumbs[$counter++] = new Tag_Albums_Breadcrumb($parent_item->title, $parent_item->url()); + $tag_album_breadcrumbs = array_reverse($tag_album_breadcrumbs, true); + } else { + $tag_album_breadcrumbs[0] = new Tag_Albums_Breadcrumb(item::root()->title, item::root()->url()); + $tag_album_breadcrumbs[1] = new Tag_Albums_Breadcrumb("All Tags", url::site("tag_albums/")); + $tag_album_breadcrumbs[2] = new Tag_Albums_Breadcrumb($display_tag->name, url::site("tag_albums/tag/" . $display_tag->id)); + $tag_album_breadcrumbs[3] = new Tag_Albums_Breadcrumb($item->title, ""); + } + + // Load the page. + if ($item->is_photo()) { + $template = new Theme_View("page.html", "item", "photo"); + $template->page_title = $item->title; + $template->set_global("children", Array()); + $template->set_global("item", $item); + $template->set_global("previous_item", $previous_item); + $template->set_global("next_item", $next_item); + $template->set_global("children_count", 0); + $template->set_global("position", $position); + $template->set_global("sibling_count", $sibling_count); + $template->content = new View("tag_albums_photo.html"); + $template->content->title = $item->title; + $template->set_global("breadcrumbs", $tag_album_breadcrumbs); + print $template; + } elseif ($item->is_movie()) { + $template = new Theme_View("page.html", "item", "movie"); + $template->page_title = $item->title; + $template->set_global("children", Array()); + $template->set_global("item", $item); + $template->set_global("previous_item", $previous_item); + $template->set_global("next_item", $next_item); + $template->set_global("children_count", 0); + $template->set_global("position", $position); + $template->set_global("sibling_count", $sibling_count); + $template->content = new View("tag_albums_movie.html"); + $template->content->title = $item->title; + $template->set_global("breadcrumbs", $tag_album_breadcrumbs); + print $template; + } else { + // If it's something we don't know how to deal with, just redirect to its real page. + url::redirect(url::abs_site("{$item->type}s/{$item->id}")); + } + } + + private function _get_position($item_title, $item_id, $tag_ids, $sort_field, $sort_direction, $search_type) { + // Determine an item's position within a virtual album. + + // Convert ASC/DESC to < or > characters. + if (!strcasecmp($sort_direction, "DESC")) { + $comp = ">"; + } else { + $comp = "<"; + } + + // Figure out how many items are _before the current item. + $items_model = ORM::factory("item"); + if ($search_type == "AND") { + $items_model->select('COUNT("*") AS result_count'); + } else { + $items_model->select("items.id"); + } + $items_model->viewable(); + $items_model->join("items_tags", "items.id", "items_tags.item_id"); + $items_model->open(); + $items_model->where("items_tags.tag_id", "=", $tag_ids[0]); + $counter = 1; + while ($counter < count($tag_ids)) { + $items_model->or_where("items_tags.tag_id", "=", $tag_ids[$counter]); + $counter++; + } + $items_model->close(); + $items_model->and_where("items.type", "!=", "album"); + $items_model->and_where($sort_field, $comp, $item_title); + $items_model->order_by($sort_field, $sort_direction); + $items_model->group_by("items.id"); + if ($search_type == "AND") { + $items_model->having("result_count", "=", count($tag_ids)); + } + $position = count($items_model->find_all()); + + // In case multiple items have identical sort criteria, query for + // everything with the same criteria, and increment the position + // one at a time until we find the right item. + $items_model = ORM::factory("item"); + if ($search_type == "AND") { + $items_model->select("items.id"); + $items_model->select('COUNT("*") AS result_count'); + } else { + $items_model->select("items.id"); + } + $items_model->viewable(); + $items_model->join("items_tags", "items.id", "items_tags.item_id"); + $items_model->open(); + $items_model->where("items_tags.tag_id", "=", $tag_ids[0]); + $counter = 1; + while ($counter < count($tag_ids)) { + $items_model->or_where("items_tags.tag_id", "=", $tag_ids[$counter]); + $counter++; + } + $items_model->close(); + $items_model->and_where("items.type", "!=", "album"); + $items_model->and_where($sort_field, "=", $item_title); + $items_model->order_by($sort_field, $sort_direction); + $items_model->group_by("items.id"); + if ($search_type == "AND") { + $items_model->having("result_count", "=", count($tag_ids)); + } + $match_items = $items_model->find_all(); + foreach ($match_items as $one_item) { + $position++; + if ($one_item->id == $item_id) { + break; + } + } + + return ($position); + } + + private function _get_records($tag_ids, $page_size, $offset, $sort_field, $sort_direction, $search_type, $include_albums) { + // Returns an array of items to be displayed on the current page. + + $items_model = ORM::factory("item"); + if ($search_type == "AND") { + // For some reason, if I do 'select("*")' the item ids all have values that are 1000+ + // higher then they should be. So instead, I'm manually selecting each column that I need. + $items_model->select("items.id"); + $items_model->select("items.name"); + $items_model->select("items.type"); + $items_model->select("items.thumb_width"); + $items_model->select("items.thumb_height"); + $items_model->select("items.left_ptr"); + $items_model->select("items.right_ptr"); + $items_model->select("items.relative_path_cache"); + $items_model->select('COUNT("*") AS result_count'); + } + $items_model->viewable(); + $items_model->join("items_tags", "items.id", "items_tags.item_id"); + $items_model->open(); + $items_model->where("items_tags.tag_id", "=", $tag_ids[0]); + $counter = 1; + while ($counter < count($tag_ids)) { + $items_model->or_where("items_tags.tag_id", "=", $tag_ids[$counter]); + $counter++; + } + $items_model->close(); + if ($include_albums == false) { + $items_model->and_where("items.type", "!=", "album"); + } + $items_model->order_by($sort_field, $sort_direction); + $items_model->group_by("items.id"); + if ($search_type == "AND") { + $items_model->having("result_count", "=", count($tag_ids)); + } + return $items_model->find_all($page_size, $offset); + } + + private function _count_records($tag_ids, $search_type, $include_albums) { + // Count the number of viewable items for the designated tag(s) + // and return that number. + + if (count($tag_ids) == 0) { + // If no tags were specified, return 0. + return 0; + + } elseif (count($tag_ids) == 1) { + // if one tag was specified, we can use count_all to get the number. + $count = ORM::factory("item") + ->viewable() + ->join("items_tags", "items.id", "items_tags.item_id") + ->where("items_tags.tag_id", "=", $tag_ids[0]); + if ($include_albums == false) { + $count->and_where("items.type", "!=", "album"); + } + return $count->count_all(); + + } else { + // If multiple tags were specified, count_all won't work, + // so we'll have to do count(find_all) instead. + $items_model = ORM::factory("item"); + if ($search_type == "AND") { + $items_model->select('COUNT("*") AS result_count'); + } else { + $items_model->select('items.id'); + } + $items_model->viewable(); + $items_model->join("items_tags", "items.id", "items_tags.item_id"); + $items_model->where("items_tags.tag_id", "=", $tag_ids[0]); + $counter = 1; + while ($counter < count($tag_ids)) { + $items_model->or_where("items_tags.tag_id", "=", $tag_ids[$counter]); + $counter++; + } + if ($include_albums == false) { + $items_model->and_where("items.type", "!=", "album"); + } + $items_model->group_by("items.id"); + if ($search_type == "AND") { + $items_model->having("result_count", "=", count($tag_ids)); + } + + return count($items_model->find_all()); + } + } +} diff --git a/3.1/modules/tag_albums/helpers/tag_albums_block.php b/3.1/modules/tag_albums/helpers/tag_albums_block.php new file mode 100644 index 00000000..7243722c --- /dev/null +++ b/3.1/modules/tag_albums/helpers/tag_albums_block.php @@ -0,0 +1,40 @@ + t("Tag Albums")); + } + + static function get($block_id, $theme) { + $block = ""; + + switch ($block_id) { + case "tag_albums": + // Make a new sidebar block. + $block = new Block(); + $block->css_id = "g-tag-albums"; + $block->title = t("Tag Albums"); + $block->content = new View("tag_albums_block.html"); + + break; + } + return $block; + } +} diff --git a/3.1/modules/tag_albums/helpers/tag_albums_event.php b/3.1/modules/tag_albums/helpers/tag_albums_event.php new file mode 100644 index 00000000..033293f1 --- /dev/null +++ b/3.1/modules/tag_albums/helpers/tag_albums_event.php @@ -0,0 +1,110 @@ +module == "tag") { + $data->messages["warn"][] = t("The Tag Albums module requires the Tags module."); + } + } + + static function module_change($changes) { + // See if the Tags module is installed, + // tell the user to install it if it isn't. + if (!module::is_active("tag") || in_array("tag", $changes->deactivate)) { + site_status::warning( + t("The Tag Albums module requires the Tags module. " . + "Activate the Tags module now", + array("url" => url::site("admin/modules"))), + "tag_albums_needs_tag"); + } else { + site_status::clear("tag_albums_needs_tag"); + } + } + + static function admin_menu($menu, $theme) { + // Add a link to the admin page to the Content menu. + $menu->get("settings_menu") + ->append(Menu::factory("link") + ->id("tag_albums") + ->label(t("Tag Albums Settings")) + ->url(url::site("admin/tag_albums"))); + } + + static function item_edit_form($item, $form) { + // Create fields on the album edit screen to allow the user to link + // the album to a tag_albums page. + if (!($item->is_album())) { + return; + } + + $url = url::site("tags/autocomplete"); + $form->script("") + ->text("$('form input[name=tag_albums]').ready(function() { + $('form input[name=tag_albums]').autocomplete( + '$url', {max: 30, multiple: true, multipleSeparator: ',', cacheLength: 1}); + });"); + + $album_tags = ORM::factory("tags_album_id") + ->where("album_id", "=", $item->id) + ->find_all(); + + $tag_names = ""; + $tag_album_type = "OR"; + if (count($album_tags) > 0) { + $tag_names = $album_tags[0]->tags; + $tag_album_type = $album_tags[0]->search_type; + } + + $tags_album_group = $form->edit_item->group("tags_album_group"); + $tags_album_group->dropdown("tags_album_type") + ->options( + array("OR" => t("Display items that contain ANY of the following tags:"), + "AND" => t("Display items that contain ALL of the following tags:"))) + ->selected($tag_album_type); + $tags_album_group->input("tag_albums") + ->value($tag_names); + } + + static function item_deleted($item) { + // Whenever an item is deleted, delete any corresponding data. + db::build()->delete("tags_album_ids")->where("album_id", "=", $item->id)->execute(); + } + + static function item_edit_form_completed($item, $form) { + // Update the database with any changes to the tag_albums field. + if (!($item->is_album())) { + return; + } + + $record = ORM::factory("tags_album_id")->where("album_id", "=", $item->id)->find(); + + if ($form->edit_item->tags_album_group->tag_albums->value != "") { + if (!$record->loaded()) { + $record->album_id = $item->id; + } + $record->tags = $form->edit_item->tags_album_group->tag_albums->value; + $record->search_type = $form->edit_item->tags_album_group->tags_album_type->value; + $record->save(); + } else { + db::build()->delete("tags_album_ids")->where("album_id", "=", $item->id)->execute(); + } + } +} diff --git a/3.1/modules/tag_albums/helpers/tag_albums_installer.php b/3.1/modules/tag_albums/helpers/tag_albums_installer.php new file mode 100644 index 00000000..6fa9fa10 --- /dev/null +++ b/3.1/modules/tag_albums/helpers/tag_albums_installer.php @@ -0,0 +1,57 @@ +query("CREATE TABLE IF NOT EXISTS {tags_album_ids} ( + `id` int(9) NOT NULL auto_increment, + `album_id` int(9) NOT NULL, + `tags` varchar(2048) default NULL, + `search_type` varchar(128) NOT NULL, + PRIMARY KEY (`id`), + KEY(`album_id`, `id`)) + DEFAULT CHARSET=utf8;"); + + // Set up some default values. + module::set_var("tag_albums", "tag_sort_by", "name"); + module::set_var("tag_albums", "tag_sort_direction", "ASC"); + module::set_var("tag_albums", "subalbum_sort_by", "title"); + module::set_var("tag_albums", "subalbum_sort_direction", "ASC"); + + // Set the module's version number. + module::set_version("tag_albums", 1); + } + + static function deactivate() { + site_status::clear("tag_albums_needs_tag"); + } + + static function can_activate() { + $messages = array(); + if (!module::is_active("tag")) { + $messages["warn"][] = t("The Tag Albums module requires the Tags module."); + } + return $messages; + } + + static function uninstall() { + module::delete("tag_albums"); + } +} diff --git a/3.1/modules/tag_albums/helpers/tag_albums_theme.php b/3.1/modules/tag_albums/helpers/tag_albums_theme.php new file mode 100644 index 00000000..3eae0c61 --- /dev/null +++ b/3.1/modules/tag_albums/helpers/tag_albums_theme.php @@ -0,0 +1,34 @@ +item()) { + $album_tags = ORM::factory("tags_album_id") + ->where("album_id", "=", $theme->item->id) + ->find_all(); + if (count($album_tags) > 0) { + url::redirect(url::abs_site("tag_albums/album/" . $album_tags[0]->id)); + } + } + return; + } +} diff --git a/3.1/modules/tag_albums/libraries/Tag_Albums_Breadcrumb.php b/3.1/modules/tag_albums/libraries/Tag_Albums_Breadcrumb.php new file mode 100644 index 00000000..ba576e49 --- /dev/null +++ b/3.1/modules/tag_albums/libraries/Tag_Albums_Breadcrumb.php @@ -0,0 +1,31 @@ +title = $new_title; + $this->url = $new_url; + } +} diff --git a/3.1/modules/tag_albums/libraries/Tag_Albums_Item.php b/3.1/modules/tag_albums/libraries/Tag_Albums_Item.php new file mode 100644 index 00000000..beddc108 --- /dev/null +++ b/3.1/modules/tag_albums/libraries/Tag_Albums_Item.php @@ -0,0 +1,110 @@ +item_type == "album") { + return true; + } else { + return false; + } + } + + public function has_thumb() { + if ($this->thumb_url != "") { + return true; + } else { + return false; + } + } + + public function thumb_img($extra_attrs=array(), $max=null, $center_vertically=false) { + list ($height, $width) = $this->scale_dimensions($max); + if ($center_vertically && $max) { + // The constant is divide by 2 to calculate the file and 10 to convert to em + $margin_top = (int)(($max - $height) / 20); + $extra_attrs["style"] = "margin-top: {$margin_top}em"; + $extra_attrs["title"] = $this->title; + } + $attrs = array_merge($extra_attrs, + array( + "src" => $this->thumb_url(), + "alt" => $this->title, + "width" => $width, + "height" => $height) + ); + // html::image forces an absolute url which we don't want + return ""; + } + + public function scale_dimensions($max) { + $width = $this->thumb_width; + $height = $this->thumb_height; + + if ($width <= $max && $height <= $max) { + return array($height, $width); + } + + if ($height) { + if (isset($max)) { + if ($width > $height) { + $height = (int)($max * $height / $width); + $width = $max; + } else { + $width = (int)($max * $width / $height); + $height = $max; + } + } + } else { + // Missing thumbnail, can happen on albums with no photos yet. + // @todo we should enforce a placeholder for those albums. + $width = 0; + $height = 0; + } + return array($height, $width); + } + + public function thumb_url() { + return $this->thumb_url; + } + + public function url() { + return $this->url; + } + + public function set_thumb($new_url, $new_width, $new_height) { + $this->thumb_url = $new_url; + $this->thumb_width = $new_width; + $this->thumb_height = $new_height; + } + + public function __construct($new_title, $new_url, $new_type) { + $this->title = $new_title; + $this->url = $new_url; + $this->item_type = $new_type; + } +} diff --git a/3.1/modules/tag_albums/models/tag.php b/3.1/modules/tag_albums/models/tag.php new file mode 100644 index 00000000..d15a36e0 --- /dev/null +++ b/3.1/modules/tag_albums/models/tag.php @@ -0,0 +1,141 @@ +loaded()) { + // Set reasonable defaults + $this->count = 0; + } + } + + /** + * 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) + * @return ORM_Iterator + */ + public function items($limit=null, $offset=null, $type=null) { + $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->find_all($limit, $offset); + } + + /** + * Return the count of all viewable items associated with this tag. + * @param string $type the type of item (album, photo) + * @return integer + */ + public function items_count($type=null) { + $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(); + } + + /** + * Overload ORM::save() to trigger an item_related_update event for all items that are related + * to this tag. + */ + public function save() { + $related_item_ids = array(); + foreach (db::build() + ->select("item_id") + ->from("items_tags") + ->where("tag_id", "=", $this->id) + ->execute() as $row) { + $related_item_ids[$row->item_id] = 1; + } + + if (isset($this->object_relations["items"])) { + $added = array_diff($this->changed_relations["items"], $this->object_relations["items"]); + $removed = array_diff($this->object_relations["items"], $this->changed_relations["items"]); + if (isset($this->changed_relations["items"])) { + $changed = array_merge($added, $removed); + } + $this->count = count($this->object_relations["items"]) + count($added) - count($removed); + } + + $result = parent::save(); + + if (!empty($changed)) { + foreach (ORM::factory("item")->where("id", "IN", $changed)->find_all() as $item) { + module::event("item_related_update", $item); + } + } + + return $result; + } + + /** + * Overload ORM::delete() to trigger an item_related_update event for all items that are + * related to this tag, and delete all items_tags relationships. + */ + public function delete($ignored_id=null) { + $related_item_ids = array(); + foreach (db::build() + ->select("item_id") + ->from("items_tags") + ->where("tag_id", "=", $this->id) + ->execute() as $row) { + $related_item_ids[$row->item_id] = 1; + } + + db::build()->delete("items_tags")->where("tag_id", "=", $this->id)->execute(); + $result = parent::delete(); + + if ($related_item_ids) { + foreach (ORM::factory("item") + ->where("id", "IN", array_keys($related_item_ids)) + ->find_all() as $item) { + module::event("item_related_update", $item); + } + } + return $result; + } + + /** + * Return the server-relative url to this item, eg: + * /gallery3/index.php/tags/35 + * + * @param string $query the query string (eg "page=3") + */ + public function url($query=null) { + $url = url::site("/tag_albums/tag/{$this->id}/" . urlencode($this->name)); + if ($query) { + $url .= "?$query"; + } + return $url; + } +} diff --git a/3.1/modules/tag_albums/models/tags_album_id.php b/3.1/modules/tag_albums/models/tags_album_id.php new file mode 100644 index 00000000..a9b16b4f --- /dev/null +++ b/3.1/modules/tag_albums/models/tags_album_id.php @@ -0,0 +1,21 @@ + +

+ +

+
+
+ +
diff --git a/3.1/modules/tag_albums/views/tag_albums.html.php b/3.1/modules/tag_albums/views/tag_albums.html.php new file mode 100644 index 00000000..c2466522 --- /dev/null +++ b/3.1/modules/tag_albums/views/tag_albums.html.php @@ -0,0 +1,64 @@ + +
+ + +
    + + + > + + url) : ?> + title) ?> + + title) ?> + + + + +
+ + +
+ +
+ dynamic_top() ?> +

+
+
+ + + + +dynamic_bottom() ?> + +paginator() ?> diff --git a/3.1/modules/tag_albums/views/tag_albums_block.html.php b/3.1/modules/tag_albums/views/tag_albums_block.html.php new file mode 100644 index 00000000..d4b08087 --- /dev/null +++ b/3.1/modules/tag_albums/views/tag_albums_block.html.php @@ -0,0 +1,4 @@ + + diff --git a/3.1/modules/tag_albums/views/tag_albums_movie.html.php b/3.1/modules/tag_albums/views/tag_albums_movie.html.php new file mode 100644 index 00000000..f15823ec --- /dev/null +++ b/3.1/modules/tag_albums/views/tag_albums_movie.html.php @@ -0,0 +1,44 @@ + +
+ + +
    + + + > + + url) : ?> + title) ?> + + title) ?> + + + + +
+ + +
+
+ photo_top() ?> + + paginator() ?> + +
+ resize_top($item) ?> + movie_img(array("class" => "g-movie", "id" => "g-item-id-{$item->id}")) ?> + resize_bottom($item) ?> +
+ +
+

title) ?>

+
description)) ?>
+
+ + photo_bottom() ?> +
diff --git a/3.1/modules/tag_albums/views/tag_albums_photo.html.php b/3.1/modules/tag_albums/views/tag_albums_photo.html.php new file mode 100644 index 00000000..4f78696e --- /dev/null +++ b/3.1/modules/tag_albums/views/tag_albums_photo.html.php @@ -0,0 +1,75 @@ + +
+ + +
    + + + > + + url) : ?> + title) ?> + + title) ?> + + + + +
+ + +
+ + + + + +
+ photo_top() ?> + + paginator() ?> + + + +
+

title) ?>

+
description)) ?>
+
+ + photo_bottom() ?> +