diff options
Diffstat (limited to 'modules/search/helpers')
| -rw-r--r-- | modules/search/helpers/search.php | 61 | 
1 files changed, 52 insertions, 9 deletions
| diff --git a/modules/search/helpers/search.php b/modules/search/helpers/search.php index 09e5e83f..a77a2433 100644 --- a/modules/search/helpers/search.php +++ b/modules/search/helpers/search.php @@ -18,10 +18,37 @@   * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA  02110-1301, USA.   */  class search_Core { +  /** +   * Add more terms to the query by wildcarding the stem value of the first +   * few terms in the query. +   */ +  static function add_query_terms($q) { +    $MAX_TERMS = 5; +    $terms = explode(" ", $q, $MAX_TERMS); +    for ($i = 0; $i < min(count($terms), $MAX_TERMS - 1); $i++) { +      // Don't wildcard quoted or already wildcarded terms +      if ((substr($terms[$i], 0, 1) != '"') && (substr($terms[$i], -1, 1) != "*")) { +        $terms[] = rtrim($terms[$i], "s") . "*"; +      } +    } +    return implode(" ", $terms); +  } +    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 @@ -31,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 $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;    }    /** @@ -87,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; +  }  } | 
