Search functions moved from mod/name/lib.php to search/documents/mod_document.php.

Pagination added to query page. Various small changes and amendments.
This commit is contained in:
mchampan
2006-07-11 17:15:22 +00:00
parent 079aa26d7d
commit a25a3912f7
14 changed files with 555 additions and 181 deletions
+3 -3
View File
@@ -6,7 +6,7 @@
this block, the broadest possible selection of documents is searched.
Author: Michael Champanis (mchampan)
Date: 2006 06 23
Date: 2006 06 25
Todo: make strings -> get_string()
*/
@@ -15,7 +15,7 @@
function init() {
$this->title = "Global Search"; //get_string()
$this->version = 20060625;
$this->version = 2006062500;
} //init
// only one instance of this block is required
@@ -46,7 +46,7 @@
//basic search form
$this->content->text =
'<form name="query" method="post" action="search/query.php">'
'<form name="query" method="get" action="search/query.php">'
. "<label for=''>$label</label>"
. '<input type="text" name="query_string" length="50" value=""/>'
. '<input type="submit" value="'.$button.'"/>'
-106
View File
@@ -352,112 +352,6 @@ function wiki_get_entries(&$wiki, $byindex=NULL) {
}
}
/*==== Global search modifications
* Author: Michael Champanis (mchampan)
* Last date: 2006 06 25
* These modifications allow wiki documents to be indexed in the new
* search engine module - they are probably not final, and as such
* shouldn't be used by other stuff for the time being
**/
//rescued and converted from ewikimoodlelib.php
//retrieves latest version of a page
function wiki_get_latest_page(&$entry, $pagename, $version=0) {
$pagename = "'".addslashes($pagename)."'";
if ($version > 0 and is_int($version)) {
$version = "AND (version=$version)";
} else {
$version = '';
} //else
$select = "(pagename=$pagename) AND wiki=".$entry->id." $version ";
$sort = 'version DESC';
//change this to recordset_select, as per http://docs.moodle.org/en/Datalib_Notes
if ($result_arr = get_records_select('wiki_pages', $select, $sort, '*', 0, 1)) {
foreach ($result_arr as $obj) {
$result_obj = $obj;
} //foreach
} //if
if (isset($result_obj)) {
$result_obj->meta = @unserialize($result_obj->meta);
return $result_obj;
} else {
return false;
} //else
} //wiki_get_latest_page
//fetches all pages, including old versions
function wiki_get_pages(&$entry) {
return get_records('wiki_pages', 'wiki', $entry->id);
} //wiki_get_pages
//fetches all the latest versions of all the pages
function wiki_get_latest_pages(&$entry) {
//== (My)SQL for this
/* select * from wiki_pages
inner join
(select wiki_pages.pagename, max(wiki_pages.version) as ver
from wiki_pages group by pagename) as a
on ((wiki_pages.version = a.ver) and
(wiki_pages.pagename like a.pagename)) */
$pages = array();
//http://moodle.org/bugs/bug.php?op=show&bugid=5877&pos=0
//if ($ids = get_records('wiki_pages', 'wiki', $entry->id, '', 'distinct pagename')) {
if ($rs = get_recordset('wiki_pages', 'wiki', $entry->id, '', 'distinct pagename')) {
$ids = $rs->GetRows();
//--
foreach ($ids as $id) {
$pages[] = wiki_get_latest_page($entry, $id[0]);
} //foreach
} else {
return false;
} //else
return $pages;
} //wiki_get_latest_pages
function wiki_iterator() {
return get_all_instances_in_courses("wiki", get_courses());
} //wiki_search_index
function wiki_get_content_for_index(&$wiki) {
$documents = array();
$entries = wiki_get_entries($wiki);
foreach($entries as $entry) {
//all pages
//$pages = wiki_get_pages($entry);
//latest pages
$pages = wiki_get_latest_pages($entry);
$i = 0;
if (is_array($pages)) {
foreach($pages as $page) {
if (strlen($page->content) > 0) {
$i++;
$documents[] = new WikiSearchDocument($page, $entry->wikiid, $entry->course, $entry->groupid);
} //if
} //foreach
//print "$entry->id : $i"; print "<br>";
} else {
print $pages;
} //else
} //foreach
return $documents;
} //wiki_get_content_for_index
/*==== Global search modifications end */
function wiki_get_default_entry(&$wiki, &$course, $userid=0, $groupid=0) {
/// Returns the wiki entry according to the wiki type.
/// Optionally, will return wiki entry for $userid student wiki, or
+35 -1
View File
@@ -1,4 +1,38 @@
latest
2006/07/11
----------
(Warning: It took me 1900 seconds to index the forum, go make coffee
whilst you wait.)
Forum search functions changed to use 'get_recordset' instead of
'get_records', for speed reasons. This provides a significant improvement,
but indexing is still slow - getting data from the database and Zend's
tokenising _seem_ to be the prime suspects at the moment.
/search/tests/ added - index.php can be used to see which modules are
ready to be included in the search index, and it informs you of any
errors - should be a prerequisite for indexing.
Search result pagination added to query.php, will default to 20 until
an admin page for the search module is written.
2006/07/07
----------
Search-enabling functions moved out've the mod's lib.php files and into
/search/documents/mod_document.php - this requires the search module to
operate without requiring modification of lib files.
SearchDocument base class improved, and the way module documents extend
it. A custom-data field has been added to allow modules to add any custom
data they wish to be stored in the index - this field is serialised into
the index as a binary field.
Database field 'type' renamed to 'doctype' to match the renaming in the
index, 'type' seems to be a reserved word in Lucene. Several index field
names change to be more descriptive (cid -> course_id). URLs are now
stored in the index, and don't have to be generated on the fly during
display of query results.
2006/07/05
------
Started cleaning and standardising things.
+1 -1
View File
@@ -1,6 +1,6 @@
CREATE TABLE IF NOT EXISTS `prefix_search_documents` (
`id` int(11) NOT NULL auto_increment,
`type` varchar(12) NOT NULL default 'none',
`doctype` varchar(12) NOT NULL default 'none',
`title` varchar(100) NOT NULL default '',
`url` varchar(100) NOT NULL default '',
`updated` timestamp NOT NULL default CURRENT_TIMESTAMP,
+1 -1
View File
@@ -1,6 +1,6 @@
CREATE TABLE prefix_search_documents (
id SERIAL8 PRIMARY KEY,
"type" varchar(12) NOT NULL DEFAULT 'none',
doctype varchar(12) NOT NULL DEFAULT 'none',
title varchar(100) NOT NULL default '',
url varchar(100) NOT NULL default '',
updated timestamp NOT NULL DEFAULT NOW(),
+12 -4
View File
@@ -4,10 +4,18 @@
* */
class SearchDocument extends Zend_Search_Lucene_Document {
public function __construct($document_type, $cid, $gid) {
$this->addField(Zend_Search_Lucene_Field::Keyword('type', $document_type));
$this->addField(Zend_Search_Lucene_Field::Keyword('courseid', $cid));
$this->addField(Zend_Search_Lucene_Field::Keyword('groupid', $gid));
public function __construct(&$doc, &$data, $document_type, $course_id, $group_id) {
$this->addField(Zend_Search_Lucene_Field::Keyword('id', $doc->id));
$this->addField(Zend_Search_Lucene_Field::Text('title', $doc->title));
$this->addField(Zend_Search_Lucene_Field::Text('author', $doc->author));
$this->addField(Zend_Search_Lucene_Field::UnStored('contents', $doc->contents));
$this->addField(Zend_Search_Lucene_Field::UnIndexed('url', $doc->url));
$this->addField(Zend_Search_Lucene_Field::Binary('data', serialize($data)));
$this->addField(Zend_Search_Lucene_Field::Keyword('doctype', $document_type));
$this->addField(Zend_Search_Lucene_Field::Keyword('course_id', $course_id));
$this->addField(Zend_Search_Lucene_Field::Keyword('group_id', $group_id));
} //constructor
} //SearchDocument
+155
View File
@@ -0,0 +1,155 @@
<?php
/* see wiki_document.php for descriptions */
require_once("$CFG->dirroot/search/documents/document.php");
require_once("$CFG->dirroot/mod/forum/lib.php");
class ForumSearchDocument extends SearchDocument {
public function __construct(&$post, $forum_id, $course_id, $group_id) {
// generic information
/*$doc->id = $post->id;
$doc->title = $post->subject;
$doc->author = $post->firstname." ".$post->lastname;
$doc->contents = $post->message;*/
$doc->id = $post['id'];
$doc->title = $post['subject'];
$doc->author = $post['firstname']." ".$post['lastname'];
$doc->contents = $post['message'];
$doc->url = forum_make_link($post['discussion'], $post['id']);
// module specific information
$data->forum = $forum_id;
$data->discussion = $post['discussion'];
parent::__construct($doc, $data, SEARCH_FORUM_TYPE, $course_id, $group_id);
} //constructor
} //ForumSearchDocument
function forum_make_link($discussion_id, $post_id) {
global $CFG;
return $CFG->wwwroot.'/mod/forum/discuss.php?d='.$discussion_id.'#'.$post_id;
} //forum_make_link
function forum_iterator() {
//no @ = Undefined index: 82 in /home/michael/public_html/moodle/lib/datalib.php on line 2671
return @get_all_instances_in_courses("forum", get_courses());
} //forum_iterator
function forum_get_content_for_index(&$forum) {
$documents = array();
if (!$forum) return $documents;
$posts = forum_get_discussions_fast($forum->id);
if (!$posts) return $documents;
while (!$posts->EOF) {
$post = $posts->fields;
if (is_array($post)) {
if (strlen($post['message']) > 0 && ($post['deleted'] != 1)) {
$documents[] = new ForumSearchDocument($post, $forum->id, $forum->course, $post['groupid']);
} //if
if ($children = forum_get_child_posts_fast($post['id'], $forum->id)) {
while (!$children->EOF) {
$child = $children->fields;
if (strlen($child['message']) > 0 && ($child['deleted'] != 1)) {
$documents[] = new ForumSearchDocument($child, $forum->id, $forum->course, $post['groupid']);
} //if
$children->MoveNext();
} //foreach
} //if
} //if
$posts->MoveNext();
} //foreach
return $documents;
} //forum_get_content_for_index
//old slower version
function forum_get_content_for_index_old(&$forum) {
$documents = array();
if (!$forum) return $documents;
$posts = forum_get_discussions($forum->id);
if (!$posts) return $documents;
foreach($posts as $post) {
if (is_object($post)) {
if (strlen($post->message) > 0 && ($post->deleted != 1)) {
$documents[] = new ForumSearchDocument($post, $forum->id, $forum->course, $post->groupid);
} //if
if ($children = forum_get_child_posts($post->id, $forum->id)) {
foreach ($children as $child) {
if (strlen($child->message) > 0 && ($child->deleted != 1)) {
$documents[] = new ForumSearchDocument($child, $forum->id, $forum->course, $post->groupid);
} //if
} //foreach
} //if
} //if
} //foreach
return $documents;
} //forum_get_content_for_index_old
//reworked faster version from /mod/forum/lib.php
function forum_get_discussions_fast($forum) {
global $CFG, $USER;
$timelimit='';
if (!empty($CFG->forum_enabletimedposts)) {
if (!((isadmin() and !empty($CFG->admineditalways)) || isteacher(get_field('forum', 'course', 'id', $forum)))) {
$now = time();
$timelimit = " AND ((d.timestart = 0 OR d.timestart <= '$now') AND (d.timeend = 0 OR d.timeend > '$now')";
if (!empty($USER->id)) {
$timelimit .= " OR d.userid = '$USER->id'";
}
$timelimit .= ')';
}
}
if ($CFG->dbtype == 'postgres7') {
return get_recordset_sql("SELECT p.id, p.subject, p.discussion, p.message,
p.deleted, d.groupid, u.firstname, u.lastname
FROM {$CFG->prefix}forum_discussions d
JOIN {$CFG->prefix}forum_posts p ON p.discussion = d.id
JOIN {$CFG->prefix}user u ON p.userid = u.id
WHERE d.forum = '$forum'
AND p.parent = 0
$timelimit
ORDER BY d.timemodified DESC");
} else {
return get_recordset_sql("SELECT p.id, p.subject, p.discussion, p.message, p.deleted,
d.groupid, u.firstname, u.lastname
FROM ({$CFG->prefix}forum_posts p,
{$CFG->prefix}user u,
{$CFG->prefix}forum_discussions d)
WHERE d.forum = '$forum'
AND p.discussion = d.id
AND p.parent = 0
AND p.userid = u.id $timelimit
ORDER BY d.timemodified DESC");
} //else
} //forum_get_discussions_fast
//reworked faster version from /mod/forum/lib.php
function forum_get_child_posts_fast($parent, $forumid) {
global $CFG;
return get_recordset_sql("SELECT p.id, p.subject, p.discussion, p.message, p.deleted,
$forumid AS forum, u.firstname, u.lastname
FROM {$CFG->prefix}forum_posts p
LEFT JOIN {$CFG->prefix}user u ON p.userid = u.id
WHERE p.parent = '$parent'
ORDER BY p.created ASC");
} //forum_get_child_posts_fast
?>
+117 -11
View File
@@ -1,28 +1,134 @@
<?php
/* Wiki Search Document class and functions
* This file contains the mapping between a wiki page and it's indexable counterpart,
* e.g. searchdocument->title = wikipage->pagename
*
* Functions for iterating and retrieving the necessary records are now also included
* in this file, rather than mod/wiki/lib.php
* */
require_once("$CFG->dirroot/search/documents/document.php");
require_once("$CFG->dirroot/mod/wiki/lib.php");
/* All the $doc->___ fields are required by the base document class!
* Each and every module that requires search functionality must correctly
* map their internal fields to the five $doc fields (id, title, author, contents
* and url). Any module specific data can be added to the $data object, which is
* serialised into a binary field in the index.
* */
class WikiSearchDocument extends SearchDocument {
public function __construct(&$page, $wiki_id, $cid, $gid) {
$this->addField(Zend_Search_Lucene_Field::Text('title', $page->pagename));
$this->addField(Zend_Search_Lucene_Field::Text('author', $page->author));
$this->addField(Zend_Search_Lucene_Field::UnStored('contents', $page->content));
public function __construct(&$page, $wiki_id, $course_id, $group_id) {
// generic information; required
$doc->id = $page->id;
$doc->title = $page->pagename;
$doc->author = $page->author;
$doc->contents = $page->content;
$doc->url = wiki_make_link($wiki_id, $page->pagename, $page->version);
$this->addField(Zend_Search_Lucene_Field::Keyword('id', $page->id));
$this->addField(Zend_Search_Lucene_Field::Keyword('version', $page->version));
$this->addField(Zend_Search_Lucene_Field::Keyword('wiki', $wiki_id));
// module specific information; optional
$data->version = $page->version;
$data->wiki = $wiki_id;
parent::__construct(SEARCH_WIKI_TYPE, $cid, $gid);
// construct the parent class
parent::__construct($doc, $data, SEARCH_WIKI_TYPE, $course_id, $group_id);
} //constructor
} //WikiSearchDocument
function wiki_name_convert($str) {
return str_replace(' ', '+', $str);
} //wiki_name_convert
function wiki_make_link(&$doc) {
function wiki_make_link($wiki_id, $title, $version) {
global $CFG;
return $CFG->wwwroot.'/mod/wiki/view.php?wid='.$doc->wiki.'&page='.wiki_name_convert($doc->title).'&version='.$doc->version;
return $CFG->wwwroot.'/mod/wiki/view.php?wid='.$wiki_id.'&page='.wiki_name_convert($title).'&version='.$version;
} //wiki_make_link
//rescued and converted from ewikimoodlelib.php
//retrieves latest version of a page
function wiki_get_latest_page(&$entry, $pagename, $version=0) {
$pagename = "'".addslashes($pagename)."'";
if ($version > 0 and is_int($version)) {
$version = "AND (version=$version)";
} else {
$version = '';
} //else
$select = "(pagename=$pagename) AND wiki=".$entry->id." $version ";
$sort = 'version DESC';
//change this to recordset_select, as per http://docs.moodle.org/en/Datalib_Notes
if ($result_arr = get_records_select('wiki_pages', $select, $sort, '*', 0, 1)) {
foreach ($result_arr as $obj) {
$result_obj = $obj;
} //foreach
} //if
if (isset($result_obj)) {
$result_obj->meta = @unserialize($result_obj->meta);
return $result_obj;
} else {
return false;
} //else
} //wiki_get_latest_page
//fetches all pages, including old versions
function wiki_get_pages(&$entry) {
return get_records('wiki_pages', 'wiki', $entry->id);
} //wiki_get_pages
//fetches all the latest versions of all the pages
function wiki_get_latest_pages(&$entry) {
//== (My)SQL for this
/* select * from wiki_pages
inner join
(select wiki_pages.pagename, max(wiki_pages.version) as ver
from wiki_pages group by pagename) as a
on ((wiki_pages.version = a.ver) and
(wiki_pages.pagename like a.pagename)) */
$pages = array();
//http://moodle.org/bugs/bug.php?op=show&bugid=5877&pos=0
//if ($ids = get_records('wiki_pages', 'wiki', $entry->id, '', 'distinct pagename')) {
if ($rs = get_recordset('wiki_pages', 'wiki', $entry->id, '', 'distinct pagename')) {
$ids = $rs->GetRows();
//--
foreach ($ids as $id) {
$pages[] = wiki_get_latest_page($entry, $id[0]);
} //foreach
} else {
return false;
} //else
return $pages;
} //wiki_get_latest_pages
function wiki_iterator() {
return get_all_instances_in_courses("wiki", get_courses());
} //wiki_iterator
function wiki_get_content_for_index(&$wiki) {
$documents = array();
$entries = wiki_get_entries($wiki);
foreach($entries as $entry) {
//all pages
//$pages = wiki_get_pages($entry);
//latest pages
$pages = wiki_get_latest_pages($entry);
if (is_array($pages)) {
foreach($pages as $page) {
if (strlen($page->content) > 0) {
$documents[] = new WikiSearchDocument($page, $entry->wikiid, $entry->course, $entry->groupid);
} //if
} //foreach
} //if
} //foreach
return $documents;
} //wiki_get_content_for_index
?>
+47 -32
View File
@@ -1,12 +1,17 @@
<?php
/* The indexer logic -
* Look through each installed module's lib file for necessary search functions,
* and if they're present (and the module search document class file), add the
* content to the index. Repeat this for blocks.
* Look through each installed module's search document class file (/search/documents)
* for necessary search functions, and if they're present add the content to the index.
* Repeat this for blocks.
*
* Because the iterator/retrieval functions are now stored in /search/documents/mod_document.php,
* /mod/mod/lib.php doesn't have to be modified - and thus the search module becomes quite
* self-sufficient. URL's are now stored in the index, stopping us from needing to require
* the class files to generate a results page.
*
* Along with the index data, each document's summary gets stored in the database
* and synchronised to the index (flat file) via the primary key ('id') which is mapped
* to the 'dbid' field in the index
* to the 'db_id' field in the index
* */
//this'll take some time, set up the environment
@@ -44,8 +49,11 @@
//php5 found, continue including php5-only files
require_once("$CFG->dirroot/search/Zend/Search/Lucene.php");
//begin timer
search_stopwatch();
if (get_config("search_indexer_busy") == 1) {
} //if
//turn on busy flag
set_config("search_indexer_busy", 1);
mtrace('<pre>Server Time: '.date('r',time())."\n");
//paths
@@ -63,21 +71,30 @@
} else {
mtrace("Using $index_path as data directory.");
} //else
$index = new Zend_Search_Lucene($index_path, true);
//create the database tables
$tables = $db->MetaTables();
if (in_array($CFG->prefix.'search_documents', $tables)) {
delete_records('search_documents');
//delete_records('search_documents');
//temporary measure - db doesn't have update scripts and I realised that cvs 1.1 db
//is incompatible with cvs 1.2! Must fix ASAP.
execute_sql('drop table '.$CFG->prefix.'search_documents', false);
ob_start(); //turn output buffering on - to hide modify_database() output
modify_database($index_db_file, '', false);
ob_end_clean(); //chuck the buffer and resume normal operation
} else {
ob_start(); //turn output buffering on - to hide modify_database() output
modify_database($index_db_file, '', false);
ob_end_clean(); //chuck the buffer and resume normal operation
} //else
mtrace('Starting activity modules');
//begin timer
search_stopwatch();
mtrace("Starting activity modules\n");
//the presence of the required search functions -
// * mod_iterator
@@ -86,23 +103,18 @@
if ($mods = get_records_select('modules' /*'index this module?' where statement*/)) {
foreach ($mods as $mod) {
$libfile = "$CFG->dirroot/mod/$mod->name/lib.php";
$class_file = $CFG->dirroot.'/search/documents/'.$mod->name.'_document.php';
if (file_exists($libfile)) {
include_once($libfile);
if (file_exists($class_file)) {
include_once($class_file);
$iter_function = $mod->name.'_iterator';
$index_function = $mod->name.'_get_content_for_index';
//specific module search document class
$class_file = $CFG->dirroot.'/search/documents/'.$mod->name.'_document.php';
$counter = 0;
$doc = new stdClass;
if (file_exists($class_file) && function_exists($index_function) && function_exists($iter_function)) {
include_once($class_file);
if (function_exists($index_function) && function_exists($iter_function)) {
mtrace("Processing module function $index_function ...");
foreach ($iter_function() as $i) {
@@ -113,30 +125,30 @@
foreach($documents as $document) {
$counter++;
//data object for db
$doc->type = $document->type;
$doc->title = search_escape_string($document->title);
$doc->update = time();
$doc->url = 'none';
$doc->courseid = $document->courseid;
$doc->groupid = $document->groupid;
//object to insert into db
$doc->doctype = $document->doctype;
$doc->title = search_escape_string($document->title);
$doc->url = search_escape_string($document->url);
$doc->update = time();
$doc->courseid = $document->course_id;
$doc->groupid = $document->group_id;
//insert summary into db
$id = insert_record('search_documents', $doc);
//synchronise db with index
$document->addField(Zend_Search_Lucene_Field::Keyword('dbid', $id));
$document->addField(Zend_Search_Lucene_Field::Keyword('db_id', $id));
//add document to index
$index->addDocument($document);
//commit every x new documents, and print a status message
if (($counter%200) == 0) {
if (($counter%2000) == 0) {
$index->commit();
mtrace(".. $counter");
mtrace(".. $counter");
} //if
} //foreach
//end transaction
} //foreach
@@ -145,7 +157,7 @@
$index->commit();
mtrace("-- $counter documents indexed");
mtrace('done.');
mtrace("done.\n");
} //if
} //if
} //foreach
@@ -160,5 +172,8 @@
mtrace(".<br><a href='index.php'>Back to query page</a>.");
mtrace('</pre>');
//finished, turn busy flag off
set_config("search_indexer_busy", 0);
?>
+6 -1
View File
@@ -42,7 +42,12 @@
."started and cancelled an indexing session. Follow the link if you are sure that\n"
."you want to continue indexing - this will replace any existing index data (no\n"
."Moodle data is affected).\n"
."\n"
."\n"
."You are encouraged to use the 'Test indexing' script before continuing onto\n"
."indexing - this will check if the modules are set up correctly. Please correct\n"
."any errors before proceeding.\n"
."\n"
."<a href='tests/index.php'>Test indexing</a> or "
."<a href='indexer.php?areyousure=yes'>Continue indexing</a> or <a href='index.php'>Back to query page</a>."
."</pre>");
} else {
+2 -1
View File
@@ -6,10 +6,11 @@
//document types that can be searched
define('SEARCH_NO_TYPE', 'none');
define('SEARCH_WIKI_TYPE', 'wiki');
define('SEARCH_FORUM_TYPE', 'forum');
//returns all the document type constants
function search_get_document_types() {
$r = Array(SEARCH_WIKI_TYPE, SEARCH_NO_TYPE);
$r = Array(SEARCH_WIKI_TYPE, SEARCH_NO_TYPE, SEARCH_FORUM_TYPE);
return $r;
} //search_get_document_types
+85 -19
View File
@@ -1,16 +1,44 @@
<?php
/* The query page - accepts a user-entered query string and returns results.
*
* Queries are boolean-aware, e.g.:
*
* '+' term required
* '-' term must not be present
* '' (no modifier) term's presence increases rank, but isn't required
* 'field:' search this field
*
* Examples:
*
* 'earthquake +author:michael'
* Searches for documents written by 'michael' that contain 'earthquake'
*
* 'earthquake +doctype:wiki'
* Search all wiki pages for 'earthquake'
*
* '+author:helen +author:foster'
* All articles written by Helen Foster
*
* */
require_once('../config.php');
require_once("$CFG->dirroot/search/lib.php");
//check for php5, but don't die yet (see line 27)
if ($check = search_check_php5()) {
require_once("$CFG->dirroot/search/Zend/Search/Lucene.php");
require_once("$CFG->dirroot/search/documents/wiki_document.php");
$query_string = optional_param('query_string', '', PARAM_CLEAN);
$query_string = optional_param('query_string', '', PARAM_CLEAN);
$page_number = optional_param('page', 1, PARAM_INT);
if ($page_number < 1) {
$page_number = 1;
} //if
$index_path = "$CFG->dataroot/search";
$no_index = false; //optimism!
$results_per_page = 10;
try {
$index = new Zend_Search_Lucene($index_path, false);
@@ -23,7 +51,7 @@
if (!$site = get_site()) {
redirect("index.php");
} //if
$strsearch = "Search"; //get_string();
$strquery = "Enter your search query"; //get_string();
@@ -45,7 +73,7 @@
?>
<form name="query" method="get" action="query.php">
<input type="text" name="query_string" length="50" value="<?php print $query_string ?>"/>
<input type="text" name="query_string" length="50" value="<?php print stripslashes(htmlentities($query_string)) ?>"/>
&nbsp;<input type="submit" value="Search"/>&nbsp;&nbsp;<a href="query.php?advanced=yes">Advanced search</a>
<a href="stats.php">Statistics</a>
</form>
@@ -77,27 +105,65 @@ if ($no_index and isadmin()) {
print_simple_box_start('center', '50%', 'white', 10);
search_stopwatch();
$hits = $index->find(strtolower($query_string));
if (count($hits) > 0) {
$link_function = $hits[0]->type.'_make_link';
} //if
$hits = $index->find(strtolower($query_string));
$hit_count = count($hits);
print "<br>";
print count($hits)." results returned for '".$query_string."'.";
print "<br><br>";
print $hit_count." results returned for '".stripslashes($query_string)."'.";
print "<br>";
if ($hit_count > 0) {
if ($hit_count < $results_per_page) {
$page_number = 1;
} else if ($page_number > ceil($hit_count/$results_per_page)) {
$page_number = $hit_count/$results_per_page;
} //if
print "<ol>";
$start = ($page_number - 1)*$results_per_page;
$end = $start + $results_per_page;
foreach ($hits as $listing) {
print "<li><a href='".$link_function($listing)."'>$listing->title</a><br>\n"
."<em>".search_shorten_url($link_function($listing), 70)."</em><br>\n"
."Type: ".$listing->type.", score: ".round($listing->score, 3)."<br>\n"
."<br></li>\n";
} //foreach
print "<ol>";
for ($i = $start; $i < $end; $i++) {
if ($i >= $hit_count) {
break;
} //if
$listing = $hits[$i];
print "<li value='".($i+1)."'><a href='".$listing->url."'>$listing->title</a><br>\n"
."<em>".search_shorten_url($listing->url, 70)."</em><br>\n"
."Type: ".$listing->doctype.", score: ".round($listing->score, 3).", author: ".$listing->author."<br>\n"
."<br></li>\n";
} //for
print "</ol>";
} //if
print "</ol>";
print "<div align='center'>";
if ($page_number > 1) {
print "<a href='query.php?query_string=$query_string&page=".($page_number-1)."'>< Back</a>&nbsp;";
} else {
print "< Back&nbsp;";
} //else
for ($i = 1; $i <= ceil($hit_count/$results_per_page); $i++) {
if ($page_number == $i) {
print "[$i]&nbsp;";
} else {
print "<a href='query.php?query_string=$query_string&page=$i'>$i</a>&nbsp;";
} //else
} //for
if ($page_number < ceil($hit_count/$results_per_page)) {
print "<a href='query.php?query_string=$query_string&page=".($page_number+1)."'>Next ></a>&nbsp;";
} else {
print "Next >&nbsp;";
} //else
print "</div>";
print_simple_box_end();
} //if
+1 -1
View File
@@ -27,7 +27,7 @@
$type_counts['Total'] = count_records('search_documents');
foreach($types as $type) {
$c = count_records('search_documents', 'type', $type);
$c = count_records('search_documents', 'doctype', $type);
$type_counts[$type] = (int)$c;
} //foreach
} else {
+90
View File
@@ -0,0 +1,90 @@
<?php
/* Used to test if modules/blocks are ready to included in the search index.
* Carries out some basic function/file existence tests - the search module
* is expected to exist, along with the db schema files and the search data
* directory.
* */
@set_time_limit(0);
@ob_implicit_flush(true);
@ob_end_flush();
require_once('../../config.php');
require_once("$CFG->dirroot/search/lib.php");
require_login();
if (!isadmin()) {
error("You need to be an admin user to use this page.", "$CFG->wwwroot/login/index.php");
} //if
mtrace('<pre>Server Time: '.date('r',time()));
mtrace("Testing global search capabilities:\n");
$phpversion = phpversion();
if (!search_check_php5()) {
mtrace("ERROR: PHP 5.0.0 or later required (currently using version $phpversion).");
exit(0);
} else {
mtrace("Success: PHP 5.0.0 or later is installed ($phpversion).\n");
} //else
//fix paths for testing
set_include_path(get_include_path().":../");
require_once("$CFG->dirroot/search/Zend/Search/Lucene.php");
mtrace("Checking activity modules:\n");
//the presence of the required search functions -
// * mod_iterator
// * mod_get_content_for_index
//are the sole basis for including a module in the index at the moment.
if ($mods = get_records_select('modules')) {
foreach ($mods as $mod) {
$class_file = $CFG->dirroot.'/search/documents/'.$mod->name.'_document.php';
if (file_exists($class_file)) {
include_once($class_file);
if (!defined('SEARCH_'.strtoupper($mod->name).'_TYPE')) {
mtrace("ERROR: Constant 'SEARCH_".strtoupper($mod->name)."_TYPE' is not defined in /search/lib.php");
continue;
} //if
$iter_function = $mod->name.'_iterator';
$index_function = $mod->name.'_get_content_for_index';
if (function_exists($index_function) && function_exists($iter_function)) {
if (is_array($iter_function())) {
$documents = $index_function(array_pop($iter_function()));
if (is_array($documents)) {
mtrace("Success: '$mod->name' module seems to be ready for indexing.");
} else {
mtrace("ERROR: $index_function() doesn't seem to be returning an array.");
} //else
} else {
mtrace("ERROR: $iter_function() doesn't seem to be returning an object array.");
} //else
} else {
mtrace("ERROR: $iter_function() and/or $index_function() does not exist in $class_file");
} //else
} else {
mtrace("Notice: $class_file does not exist, this module will not be indexed.");
} //else
} //foreach
} //if
//finished modules
mtrace("\nFinished checking activity modules.");
//now blocks...
//
mtrace("<br><a href='../index.php'>Back to query page</a> or <a href='../indexersplash.php'>Start indexing</a>.");
mtrace('</pre>');
?>