summaryrefslogtreecommitdiff
path: root/modules/search
diff options
context:
space:
mode:
Diffstat (limited to 'modules/search')
-rw-r--r--modules/search/controllers/search.php43
-rw-r--r--modules/search/helpers/search.php45
2 files changed, 78 insertions, 10 deletions
diff --git a/modules/search/controllers/search.php b/modules/search/controllers/search.php
index 5db63ab0..e4ac6702 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,9 +42,10 @@ 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);
$template = new Theme_View("page.html", "collection", "search");
@@ -52,5 +65,33 @@ class Search_Controller extends Controller {
$template->content->q = $q;
print $template;
+
+ item::set_display_context_callback(
+ "Search_Controller::get_display_context", $title, $q_with_more_terms, $q);
+ }
+
+ static function get_display_context($item, $title, $query_terms, $q) {
+ $position = search::get_position($item, $query_terms);
+
+ if ($position > 1) {
+ list ($count, $result_data) = search::search($query_terms, 3, $position - 2);
+ list ($previous_item, $ignore, $next_item) = $result_data;
+ } else {
+ $previous_item = null;
+ list ($count, $result_data) = search::search($query_terms, 1, $position);
+ list ($next_item) = $result_data;
+ }
+
+ $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)->set_first(),
+ Breadcrumb::instance(t("Search: %q", array("q" => $q)), $search_url),
+ Breadcrumb::instance($item->title, $item->url())->set_last()));
}
}
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;
+ }
}