2 require_once("$CFG->dirroot/search/Zend/Search/Lucene.php");
14 //split this into Cache class and extend to SearchCache?
19 public function __construct($mode='session') {
20 $accepted_modes = array('session');
22 if (in_array($mode, $accepted_modes)) {
25 $this->mode
= 'session';
31 public function can_cache() {
35 public function cache($id=false, $object=false) {
36 //see if there was a previous query
37 $last_term = $this->fetch('search_last_term');
39 //if this query is different from the last, clear out the last one
40 if ($id != false and $last_term != $id) {
41 $this->clear($last_term);
44 //store the new query if id and object are passed in
45 if ($object and $id) {
46 $this->store('search_last_term', $id);
47 $this->store($id, $object);
49 //otherwise return the stored results
50 } else if ($id and $this->exists($id)) {
51 return $this->fetch($id);
55 private function exists($id) {
56 switch ($this->mode
) {
58 return isset($_SESSION[$id]);
62 private function clear($id) {
63 switch ($this->mode
) {
65 unset($_SESSION[$id]);
66 session_unregister($id);
71 private function fetch($id) {
72 switch ($this->mode
) {
74 return ($this->exists($id)) ?
unserialize($_SESSION[$id]) : false;
78 private function store($id, $object) {
79 switch ($this->mode
) {
81 $_SESSION[$id] = serialize($object);
99 public function __construct($term='', $page=1, $results_per_page=10, $cache=false) {
103 $this->pagenumber
= $page;
104 $this->cache
= $cache;
105 $this->validquery
= true;
106 $this->validindex
= true;
107 $this->results_per_page
= $results_per_page;
109 $index_path = SEARCH_INDEX_PATH
;
112 $this->index
= new Zend_Search_Lucene($index_path, false);
113 } catch(Exception
$e) {
114 $this->validindex
= false;
118 if (empty($this->term
)) {
119 $this->validquery
= false;
121 $this->set_query($this->term
);
125 public function set_query($term='') {
130 if (empty($this->term
)) {
131 $this->validquery
= false;
133 $this->validquery
= true;
136 if ($this->validquery
and $this->validindex
) {
137 $this->results
= $this->get_results();
139 $this->results
= array();
143 public function results() {
144 return $this->results
;
147 private function process_results($all=false) {
150 $term = strtolower($this->term
);
152 //experimental - return more results
153 $strip_arr = array('author:', 'title:', '+', '-', 'doctype:');
154 $stripped_term = str_replace($strip_arr, '', $term);
156 $hits = $this->index
->find($term." title:".$stripped_term." author:".$stripped_term);
159 $hitcount = count($hits);
160 $this->total_results
= $hitcount;
162 if ($hitcount == 0) return array();
164 $totalpages = ceil($hitcount/$this->results_per_page
);
167 if ($hitcount < $this->results_per_page
) {
168 $this->pagenumber
= 1;
169 } else if ($this->pagenumber
> $totalpages) {
170 $this->pagenumber
=$totalpages;
173 $start = ($this->pagenumber
- 1) * $this->results_per_page
;
174 $end = $start +
$this->results_per_page
;
176 if ($end > $hitcount) {
184 $resultdoc = new SearchResult();
185 $resultdocs = array();
187 for ($i = $start; $i < $end; $i++
) {
190 //check permissions on each result
191 if ($this->can_display($USER, $hit->id
, $hit->doctype
, $hit->course_id
, $hit->group_id
)) {
192 $resultdoc->number
= $i;
193 $resultdoc->url
= $hit->url
;
194 $resultdoc->title
= $hit->title
;
195 $resultdoc->score
= $hit->score
;
196 $resultdoc->doctype
= $hit->doctype
;
197 $resultdoc->author
= $hit->author
;
200 $resultdocs[] = clone($resultdoc);
207 private function get_results() {
208 $cache = new SearchCache();
210 if ($this->cache
and $cache->can_cache()) {
211 if (!($resultdocs = $cache->cache($this->term
))) {
212 $resultdocs = $this->process_results();
213 //cache the results so we don't have to compute this on every page-load
214 $cache->cache($this->term
, $resultdocs);
215 //print "Using new results.";
217 //There was something in the cache, so we're using that to save time
218 //print "Using cached results.";
222 //print "Caching disabled!";
223 $resultdocs = $this->process_results();
229 public function page_numbers() {
230 $pages = $this->total_pages();
231 $query = htmlentities($this->term
);
232 $page = $this->pagenumber
;
236 $ret = "<div align='center' id='search_page_links'>";
238 //Back is disabled if we're on page 1
240 $ret .= "<a href='query.php?query_string=$query&page=".($page-1)."'>< $back</a> ";
242 $ret .= "< $back ";
245 //don't <a href> the current page
246 for ($i = 1; $i <= $pages; $i++
) {
248 $ret .= "[$i] ";
250 $ret .= "<a href='query.php?query_string=$query&page=$i'>$i</a> ";
254 //Next disabled if we're on the last page
255 if ($page < $pages) {
256 $ret .= "<a href='query.php?query_string=$query&page=".($page+
1)."'>$next ></a> ";
258 $ret .= "$next > ";
263 //shorten really long page lists, to stop table distorting width-ways
264 if (strlen($ret) > 70) {
267 $ret = preg_replace("/<a\D+\d+\D+>$start<\/a>.*?<a\D+\d+\D+>$end<\/a>/", '...', $ret);
271 $ret = preg_replace("/<a\D+\d+\D+>$start<\/a>.*?<a\D+\d+\D+>$end<\/a>/", '...', $ret);
277 //can the user see this result?
278 private function can_display(&$user, $this_id, $doctype, $course_id, $group_id) {
279 //this function should return true/false depending on
280 //whether or not a user can see this resource
282 //if one of you nice moodlers see this, feel free to
283 //implement it for me .. :-P
287 public function count() {
288 return $this->total_results
;
291 public function is_valid() {
292 return ($this->validquery
and $this->validindex
);
295 public function is_valid_query() {
296 return $this->validquery
;
299 public function is_valid_index() {
300 return $this->validindex
;
303 public function total_pages() {
304 return ceil($this->count()/$this->results_per_page
);
307 public function get_pagenumber() {
308 return $this->pagenumber
;
311 public function get_results_per_page() {
312 return $this->results_per_page
;
313 } //get_results_per_page