moodle/search/querylib.php

316 lines
8.5 KiB
PHP
Raw Normal View History

2006-07-25 17:10:58 +00:00
<?php
require_once("$CFG->dirroot/search/Zend/Search/Lucene.php");
class SearchResult {
public $url,
$title,
2006-07-25 17:10:58 +00:00
$doctype,
$author,
$score,
$number;
} //SearchResult
//split this into Cache class and extend to SearchCache?
class SearchCache {
private $mode,
$valid;
2006-07-25 17:10:58 +00:00
public function __construct($mode='session') {
$accepted_modes = array('session');
2006-07-25 17:10:58 +00:00
if (in_array($mode, $accepted_modes)) {
$this->mode = $mode;
} else {
$this->mode = 'session';
} //else
2006-07-25 17:10:58 +00:00
$this->valid = true;
} //constructor
2006-07-25 17:10:58 +00:00
public function can_cache() {
return $this->valid;
} //can_cache
2006-07-25 17:10:58 +00:00
public function cache($id=false, $object=false) {
//see if there was a previous query
$last_term = $this->fetch('search_last_term');
2006-07-25 17:10:58 +00:00
//if this query is different from the last, clear out the last one
if ($id != false and $last_term != $id) {
$this->clear($last_term);
} //if
2006-07-25 17:10:58 +00:00
//store the new query if id and object are passed in
if ($object and $id) {
$this->store('search_last_term', $id);
$this->store($id, $object);
return true;
//otherwise return the stored results
} else if ($id and $this->exists($id)) {
2006-07-25 17:10:58 +00:00
return $this->fetch($id);
} //else
} //cache
2006-07-25 17:10:58 +00:00
private function exists($id) {
switch ($this->mode) {
case 'session' :
return isset($_SESSION[$id]);
} //switch
} //exists
2006-07-25 17:10:58 +00:00
private function clear($id) {
switch ($this->mode) {
case 'session' :
unset($_SESSION[$id]);
session_unregister($id);
return;
} //switch
} //clear
2006-07-25 17:10:58 +00:00
private function fetch($id) {
switch ($this->mode) {
case 'session' :
return ($this->exists($id)) ? unserialize($_SESSION[$id]) : false;
} //switch
} //fetch
2006-07-25 17:10:58 +00:00
private function store($id, $object) {
switch ($this->mode) {
case 'session' :
$_SESSION[$id] = serialize($object);
return;
} //switch
} //store
2006-07-25 17:10:58 +00:00
} //SearchCache
2006-07-25 17:10:58 +00:00
class SearchQuery {
private $index,
$term,
$pagenumber,
2006-07-25 17:10:58 +00:00
$cache,
$validquery,
$validindex,
2006-07-25 17:10:58 +00:00
$results,
$results_per_page,
$total_results;
2006-07-25 17:10:58 +00:00
public function __construct($term='', $page=1, $results_per_page=10, $cache=false) {
global $CFG;
2006-07-25 17:10:58 +00:00
$this->term = $term;
$this->pagenumber = $page;
$this->cache = $cache;
$this->validquery = true;
$this->validindex = true;
$this->results_per_page = $results_per_page;
2006-07-25 17:10:58 +00:00
$index_path = SEARCH_INDEX_PATH;
2006-07-25 17:10:58 +00:00
try {
$this->index = new Zend_Search_Lucene($index_path, false);
} catch(Exception $e) {
$this->validindex = false;
2006-07-25 17:10:58 +00:00
return;
} //catch
2006-07-25 17:10:58 +00:00
if (empty($this->term)) {
$this->validquery = false;
} else {
$this->set_query($this->term);
} //else
2006-07-25 17:10:58 +00:00
} //constructor
public function set_query($term='') {
2006-07-25 17:10:58 +00:00
if (!empty($term)) {
$this->term = $term;
} //if
2006-07-25 17:10:58 +00:00
if (empty($this->term)) {
$this->validquery = false;
} else {
$this->validquery = true;
} //else
2006-07-25 17:10:58 +00:00
if ($this->validquery and $this->validindex) {
$this->results = $this->get_results();
} else {
$this->results = array();
} //else
2006-07-25 17:10:58 +00:00
} //set_query
2006-07-25 17:10:58 +00:00
public function results() {
return $this->results;
2006-07-25 17:10:58 +00:00
} //results
private function process_results($all=false) {
2006-07-25 17:10:58 +00:00
global $USER;
$term = strtolower($this->term);
//experimental - return more results
$strip_arr = array('author:', 'title:', '+', '-', 'doctype:');
$stripped_term = str_replace($strip_arr, '', $term);
$hits = $this->index->find($term." title:".$stripped_term." author:".$stripped_term);
//--
$hitcount = count($hits);
$this->total_results = $hitcount;
if ($hitcount == 0) return array();
$totalpages = ceil($hitcount/$this->results_per_page);
if (!$all) {
if ($hitcount < $this->results_per_page) {
$this->pagenumber = 1;
} else if ($this->pagenumber > $totalpages) {
$this->pagenumber =$totalpages;
} //if
$start = ($this->pagenumber - 1) * $this->results_per_page;
$end = $start + $this->results_per_page;
if ($end > $hitcount) {
$end = $hitcount;
} //if
} else {
$start = 0;
$end = $hitcount;
} //else
$resultdoc = new SearchResult();
$resultdocs = array();
for ($i = $start; $i < $end; $i++) {
$hit = $hits[$i];
2006-07-25 17:10:58 +00:00
//check permissions on each result
2006-08-14 02:29:43 +00:00
if ($this->can_display($USER, $hit->id, $hit->doctype, $hit->course_id, $hit->group_id)) {
2006-07-25 17:10:58 +00:00
$resultdoc->number = $i;
$resultdoc->url = $hit->url;
$resultdoc->title = $hit->title;
$resultdoc->score = $hit->score;
$resultdoc->doctype = $hit->doctype;
$resultdoc->author = $hit->author;
2006-07-25 17:10:58 +00:00
//and store it
$resultdocs[] = clone($resultdoc);
2006-07-25 17:10:58 +00:00
} //if
} //foreach
2006-07-25 17:10:58 +00:00
return $resultdocs;
} //process_results
2006-07-25 17:10:58 +00:00
private function get_results() {
$cache = new SearchCache();
if ($this->cache and $cache->can_cache()) {
2006-07-25 17:10:58 +00:00
if (!($resultdocs = $cache->cache($this->term))) {
$resultdocs = $this->process_results();
2006-07-25 17:10:58 +00:00
//cache the results so we don't have to compute this on every page-load
$cache->cache($this->term, $resultdocs);
2006-07-25 17:10:58 +00:00
//print "Using new results.";
} else {
2006-07-25 17:10:58 +00:00
//There was something in the cache, so we're using that to save time
//print "Using cached results.";
} //else
2006-07-25 17:10:58 +00:00
} else {
//no caching :(
//print "Caching disabled!";
$resultdocs = $this->process_results();
2006-07-25 17:10:58 +00:00
} //else
return $resultdocs;
} //get_results
2006-07-25 17:10:58 +00:00
public function page_numbers() {
$pages = $this->total_pages();
$query = htmlentities($this->term);
2006-07-25 17:10:58 +00:00
$page = $this->pagenumber;
$next = "Next";
$back = "Back";
$ret = "<div align='center' id='search_page_links'>";
2006-07-25 17:10:58 +00:00
//Back is disabled if we're on page 1
if ($page > 1) {
$ret .= "<a href='query.php?query_string=$query&page=".($page-1)."'>< $back</a>&nbsp;";
} else {
$ret .= "< $back&nbsp;";
} //else
2006-07-25 17:10:58 +00:00
//don't <a href> the current page
for ($i = 1; $i <= $pages; $i++) {
if ($page == $i) {
$ret .= "[$i]&nbsp;";
} else {
$ret .= "<a href='query.php?query_string=$query&page=$i'>$i</a>&nbsp;";
} //else
} //for
2006-07-25 17:10:58 +00:00
//Next disabled if we're on the last page
if ($page < $pages) {
2006-07-25 17:10:58 +00:00
$ret .= "<a href='query.php?query_string=$query&page=".($page+1)."'>$next ></a>&nbsp;";
} else {
$ret .= "$next >&nbsp;";
} //else
$ret .= "</div>";
2006-07-25 17:10:58 +00:00
//shorten really long page lists, to stop table distorting width-ways
if (strlen($ret) > 70) {
$start = 4;
$end = $page - 5;
2006-07-25 17:10:58 +00:00
$ret = preg_replace("/<a\D+\d+\D+>$start<\/a>.*?<a\D+\d+\D+>$end<\/a>/", '...', $ret);
2006-07-25 17:10:58 +00:00
$start = $page + 5;
$end = $pages - 3;
2006-07-25 17:10:58 +00:00
$ret = preg_replace("/<a\D+\d+\D+>$start<\/a>.*?<a\D+\d+\D+>$end<\/a>/", '...', $ret);
} //if
2006-07-25 17:10:58 +00:00
return $ret;
} //page_numbers
2006-07-25 17:10:58 +00:00
//can the user see this result?
2006-08-14 02:29:43 +00:00
private function can_display(&$user, $this_id, $doctype, $course_id, $group_id) {
2006-07-25 17:10:58 +00:00
//this function should return true/false depending on
//whether or not a user can see this resource
//..
//if one of you nice moodlers see this, feel free to
//implement it for me .. :-P
2006-07-25 17:10:58 +00:00
return true;
} //can_display
2006-07-25 17:10:58 +00:00
public function count() {
return $this->total_results;
2006-07-25 17:10:58 +00:00
} //count
2006-07-25 17:10:58 +00:00
public function is_valid() {
return ($this->validquery and $this->validindex);
} //is_valid
2006-07-25 17:10:58 +00:00
public function is_valid_query() {
return $this->validquery;
} //is_valid_query
public function is_valid_index() {
return $this->validindex;
} //is_valid_index
2006-07-25 17:10:58 +00:00
public function total_pages() {
return ceil($this->count()/$this->results_per_page);
} //pages
2006-07-25 17:10:58 +00:00
public function get_pagenumber() {
return $this->pagenumber;
} //get_pagenumber
2006-07-25 17:10:58 +00:00
public function get_results_per_page() {
return $this->results_per_page;
} //get_results_per_page
2006-07-25 17:10:58 +00:00
} //SearchQuery
?>