global sync to HEAD for passing fixes
This commit is contained in:
@@ -1,14 +1,17 @@
|
||||
<?php
|
||||
|
||||
/* This is the global search shortcut block - a single query can be entered, and
|
||||
the user will be redirected to the query page where they can enter more
|
||||
advanced queries, and view the results of their search. When searching from
|
||||
this block, the broadest possible selection of documents is searched.
|
||||
|
||||
Author: Michael Champanis (mchampan)
|
||||
Date: 2006 06 25
|
||||
|
||||
Todo: make strings -> get_string()
|
||||
* the user will be redirected to the query page where they can enter more
|
||||
* advanced queries, and view the results of their search. When searching from
|
||||
* this block, the broadest possible selection of documents is searched.
|
||||
*
|
||||
*
|
||||
* Todo: make strings -> get_string()
|
||||
*
|
||||
* @package search
|
||||
* @subpackage search block
|
||||
* @author: Michael Champanis (mchampan), reengineered by Valery Fremaux
|
||||
* @date: 2006 06 25
|
||||
*/
|
||||
|
||||
class block_search extends block_base {
|
||||
@@ -16,7 +19,7 @@
|
||||
function init() {
|
||||
$this->title = get_string('blockname', 'block_search');
|
||||
$this->cron = 1;
|
||||
$this->version = 2007081100;
|
||||
$this->version = 2008031500;
|
||||
} //init
|
||||
|
||||
// only one instance of this block is required
|
||||
|
||||
@@ -55,6 +55,20 @@
|
||||
} ?>"/><br/><br/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" align="right">
|
||||
<b><?php print_string('usemoodleroot', 'block_search') ?>:</b>
|
||||
</td>
|
||||
<td valign="top" align="left">
|
||||
<?php
|
||||
$usemoodleroot = (isset($CFG->block_search_usemoodleroot)) ? 'checked="checked"' : '' ;
|
||||
$notusemoodleroot = (!isset($CFG->block_search_usemoodleroot)) ? 'checked="checked"' : '' ;
|
||||
?>
|
||||
<input id="block_search_usemoodleroot" type="radio" name="block_search_usemoodleroot" <?php echo $usemoodleroot ?> value="1"/> <?php print_string('yes') ?> -
|
||||
<input id="block_search_usemoodleroot" type="radio" name="block_search_usemoodleroot" <?php echo $notusemoodleroot ?> value="0"/> <?php print_string('no') ?>
|
||||
<br/><br/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" align="right">
|
||||
<b><?php print_string('configpdftotextcmd', 'block_search') ?>:</b>
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
Cette distribution partielle contient une refonte du moteur de
|
||||
recherche globalde Moodle.
|
||||
recherche globale de Moodle.
|
||||
|
||||
Le moteur de recherche est capable d'indexer et de rechercher
|
||||
des informations dans un grand nombre de contenus stockés
|
||||
|
||||
+131
-117
@@ -1,9 +1,13 @@
|
||||
<?php
|
||||
/**
|
||||
* Global Search Engine for Moodle
|
||||
* Michael Champanis (mchampan) [[email protected]]
|
||||
* review 1.8+ : Valery Fremaux [[email protected]]
|
||||
* 2007/08/02
|
||||
*
|
||||
* @package search
|
||||
* @category core
|
||||
* @subpackage search_engine
|
||||
* @author Michael Champanis (mchampan) [[email protected]], Valery Fremaux [[email protected]] > 1.8
|
||||
* @date 2008/03/31
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
*
|
||||
* Asynchronous adder for new indexable contents
|
||||
*
|
||||
@@ -11,134 +15,144 @@
|
||||
* multiple arity to handle multiple document types modules
|
||||
*/
|
||||
|
||||
/**
|
||||
* includes and requires
|
||||
*/
|
||||
require_once('../config.php');
|
||||
require_once("$CFG->dirroot/search/lib.php");
|
||||
|
||||
require_login();
|
||||
/// checks global search activation
|
||||
|
||||
require_login();
|
||||
|
||||
if (empty($CFG->enableglobalsearch)) {
|
||||
error(get_string('globalsearchdisabled', 'search'));
|
||||
}
|
||||
|
||||
if (!isadmin()) {
|
||||
error(get_string('beadmin', 'search'), "$CFG->wwwroot/login/index.php");
|
||||
}
|
||||
|
||||
/// check for php5 (lib.php)
|
||||
|
||||
if (empty($CFG->enableglobalsearch)) {
|
||||
error(get_string('globalsearchdisabled', 'search'));
|
||||
}
|
||||
if (!search_check_php5()) {
|
||||
$phpversion = phpversion();
|
||||
mtrace("Sorry, global search requires PHP 5.0.0 or later (currently using version ".phpversion().")");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
require_once("$CFG->dirroot/search/indexlib.php");
|
||||
|
||||
$index = new Zend_Search_Lucene(SEARCH_INDEX_PATH);
|
||||
$dbcontrol = new IndexDBControl();
|
||||
$addition_count = 0;
|
||||
$startindextime = time();
|
||||
|
||||
$indexdate = $CFG->search_indexer_run_date;
|
||||
|
||||
mtrace('Starting index update (additions)...');
|
||||
mtrace('Index size before: '.$CFG->search_index_size."\n");
|
||||
|
||||
/// get all modules
|
||||
if ($mods = get_records_select('modules')) {
|
||||
|
||||
/// append virtual modules onto array
|
||||
|
||||
if (!isadmin()) {
|
||||
error(get_string('beadmin', 'search'), "$CFG->wwwroot/login/index.php");
|
||||
}
|
||||
|
||||
//check for php5 (lib.php)
|
||||
if (!search_check_php5()) {
|
||||
$phpversion = phpversion();
|
||||
mtrace("Sorry, global search requires PHP 5.0.0 or later (currently using version $phpversion)");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
require_once("$CFG->dirroot/search/indexlib.php");
|
||||
|
||||
$index = new Zend_Search_Lucene(SEARCH_INDEX_PATH);
|
||||
$dbcontrol = new IndexDBControl();
|
||||
$addition_count = 0;
|
||||
$startindextime = time();
|
||||
|
||||
$indexdate = $CFG->search_indexer_run_date;
|
||||
|
||||
mtrace('<pre>Starting index update (additions)...');
|
||||
mtrace('Index size before: '.$CFG->search_index_size."\n");
|
||||
|
||||
//get all modules
|
||||
if ($mods = get_records_select('modules')) {
|
||||
|
||||
//append virtual modules onto array
|
||||
$mods = array_merge($mods, search_get_additional_modules());
|
||||
foreach ($mods as $mod) {
|
||||
//build include file and function names
|
||||
$class_file = $CFG->dirroot.'/search/documents/'.$mod->name.'_document.php';
|
||||
$db_names_function = $mod->name.'_db_names';
|
||||
$get_document_function = $mod->name.'_single_document';
|
||||
$get_newrecords_function = $mod->name.'_new_records';
|
||||
$additions = array();
|
||||
|
||||
if (file_exists($class_file)) {
|
||||
require_once($class_file);
|
||||
$mods = array_merge($mods, search_get_additional_modules());
|
||||
foreach ($mods as $mod) {
|
||||
//build include file and function names
|
||||
$class_file = $CFG->dirroot.'/search/documents/'.$mod->name.'_document.php';
|
||||
$db_names_function = $mod->name.'_db_names';
|
||||
$get_document_function = $mod->name.'_single_document';
|
||||
$get_newrecords_function = $mod->name.'_new_records';
|
||||
$additions = array();
|
||||
|
||||
//if both required functions exist
|
||||
if (function_exists($db_names_function) and function_exists($get_document_function)) {
|
||||
mtrace("Checking $mod->name module for additions.");
|
||||
$valuesArray = $db_names_function();
|
||||
if ($valuesArray){
|
||||
foreach($valuesArray as $values){
|
||||
$where = (isset($values[5])) ? 'AND ('.$values[5].')' : '';
|
||||
$itemtypes = ($values[4] != '*') ? " AND itemtype = '{$values[4]}' " : '' ;
|
||||
|
||||
//select records in MODULE table, but not in SEARCH_DATABASE_TABLE
|
||||
$table = SEARCH_DATABASE_TABLE;
|
||||
$query = "
|
||||
SELECT
|
||||
docid,
|
||||
itemtype
|
||||
FROM
|
||||
{$CFG->prefix}{$table}
|
||||
WHERE
|
||||
doctype = '{$mod->name}'
|
||||
$itemtypes
|
||||
";
|
||||
$docIds = get_records_sql_menu($query);
|
||||
$docIdList = ($docIds) ? implode("','", array_keys($docIds)) : '' ;
|
||||
|
||||
$query = "
|
||||
SELECT id,
|
||||
{$values[0]} as docid
|
||||
FROM
|
||||
{$CFG->prefix}{$values[1]}
|
||||
WHERE
|
||||
id NOT IN ('{$docIdList}') and
|
||||
{$values[2]} > {$indexdate}
|
||||
$where
|
||||
";
|
||||
$records = get_records_sql($query);
|
||||
|
||||
// foreach record, build a module specific search document using the get_document function
|
||||
if (is_array($records)) {
|
||||
foreach($records as $record) {
|
||||
$add = $get_document_function($record->docid, $values[4]);
|
||||
// some documents may not be indexable
|
||||
if ($add)
|
||||
$additions[] = $add;
|
||||
if (file_exists($class_file)) {
|
||||
require_once($class_file);
|
||||
|
||||
//if both required functions exist
|
||||
if (function_exists($db_names_function) and function_exists($get_document_function)) {
|
||||
mtrace("Checking $mod->name module for additions.");
|
||||
$valuesArray = $db_names_function();
|
||||
if ($valuesArray){
|
||||
foreach($valuesArray as $values){
|
||||
$where = (isset($values[5])) ? 'AND ('.$values[5].')' : '';
|
||||
$itemtypes = ($values[4] != '*' && $values[4] != 'any') ? " AND itemtype = '{$values[4]}' " : '' ;
|
||||
|
||||
//select records in MODULE table, but not in SEARCH_DATABASE_TABLE
|
||||
$table = SEARCH_DATABASE_TABLE;
|
||||
$query = "
|
||||
SELECT
|
||||
docid,
|
||||
itemtype
|
||||
FROM
|
||||
{$CFG->prefix}{$table}
|
||||
WHERE
|
||||
doctype = '{$mod->name}'
|
||||
$itemtypes
|
||||
";
|
||||
$docIds = get_records_sql_menu($query);
|
||||
$docIdList = ($docIds) ? implode("','", array_keys($docIds)) : '' ;
|
||||
|
||||
$query = "
|
||||
SELECT id,
|
||||
{$values[0]} as docid
|
||||
FROM
|
||||
{$CFG->prefix}{$values[1]}
|
||||
WHERE
|
||||
id NOT IN ('{$docIdList}') and
|
||||
{$values[2]} > {$indexdate}
|
||||
$where
|
||||
";
|
||||
$records = get_records_sql($query);
|
||||
|
||||
// foreach record, build a module specific search document using the get_document function
|
||||
if (is_array($records)) {
|
||||
foreach($records as $record) {
|
||||
$add = $get_document_function($record->docid, $values[4]);
|
||||
// some documents may not be indexable
|
||||
if ($add)
|
||||
$additions[] = $add;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// foreach document, add it to the index and database table
|
||||
foreach ($additions as $add) {
|
||||
++$addition_count;
|
||||
|
||||
// object to insert into db
|
||||
$dbid = $dbcontrol->addDocument($add);
|
||||
|
||||
// synchronise db with index
|
||||
$add->addField(Zend_Search_Lucene_Field::Keyword('dbid', $dbid));
|
||||
|
||||
mtrace(" Add: $add->title (database id = $add->dbid, moodle instance id = $add->docid)");
|
||||
|
||||
$index->addDocument($add);
|
||||
}
|
||||
}
|
||||
else{
|
||||
mtrace("No types to add.\n");
|
||||
}
|
||||
mtrace("Finished $mod->name.\n");
|
||||
// foreach document, add it to the index and database table
|
||||
foreach ($additions as $add) {
|
||||
++$addition_count;
|
||||
|
||||
// object to insert into db
|
||||
$dbid = $dbcontrol->addDocument($add);
|
||||
|
||||
// synchronise db with index
|
||||
$add->addField(Zend_Search_Lucene_Field::Keyword('dbid', $dbid));
|
||||
|
||||
mtrace(" Add: $add->title (database id = $add->dbid, moodle instance id = $add->docid)");
|
||||
|
||||
$index->addDocument($add);
|
||||
}
|
||||
}
|
||||
else{
|
||||
mtrace("No types to add.\n");
|
||||
}
|
||||
mtrace("Finished $mod->name.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// commit changes
|
||||
|
||||
// commit changes
|
||||
$index->commit();
|
||||
$index->commit();
|
||||
|
||||
/// update index date and size
|
||||
|
||||
// update index date and size
|
||||
set_config("search_indexer_run_date", $startindextime);
|
||||
set_config("search_index_size", (int)$CFG->search_index_size + (int)$addition_count);
|
||||
set_config("search_indexer_run_date", $startindextime);
|
||||
set_config("search_index_size", (int)$CFG->search_index_size + (int)$addition_count);
|
||||
|
||||
/// print some additional info
|
||||
|
||||
// print some additional info
|
||||
mtrace("Added $addition_count documents.");
|
||||
mtrace('Index size after: '.$index->count().'</pre>');
|
||||
mtrace("Added $addition_count documents.");
|
||||
mtrace('Index size after: '.$index->count());
|
||||
|
||||
?>
|
||||
+4
-1
@@ -12,7 +12,10 @@
|
||||
* adds documents created since the last index run
|
||||
*/
|
||||
|
||||
require_once('../config.php');
|
||||
if (!defined('MOODLE_INTERNAL')) {
|
||||
die('Direct access to this script is forbidden.'); /// It must be included from a Moodle page
|
||||
}
|
||||
|
||||
require_once("$CFG->dirroot/search/lib.php");
|
||||
|
||||
if (!search_check_php5()) {
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
* This is a special externalized code for cron handling in PHP5.
|
||||
* Should never be called by a php 4.3.0 implementation.
|
||||
*/
|
||||
|
||||
try{
|
||||
// overrides php limits
|
||||
$maxtimelimit = ini_get('max_execution_time');
|
||||
@@ -11,15 +12,15 @@ try{
|
||||
$maxmemoryamount = ini_get('memory_limit');
|
||||
ini_set('memory_limit', '48M');
|
||||
|
||||
mtrace("<pre>Starting cron...\n");
|
||||
mtrace("--DELETE----");
|
||||
mtrace("\n--DELETE----");
|
||||
require_once("$CFG->dirroot/search/delete.php");
|
||||
mtrace("--UPDATE----");
|
||||
require_once("$CFG->dirroot/search/update.php");
|
||||
mtrace("--ADD-------");
|
||||
require_once("$CFG->dirroot/search/add.php");
|
||||
mtrace("------------");
|
||||
mtrace("cron finished.</pre>");
|
||||
//mtrace("cron finished.</pre>");
|
||||
mtrace('done');
|
||||
|
||||
// set back normal values for php limits
|
||||
ini_set('max_execution_time', $maxtimelimit);
|
||||
|
||||
+112
-102
@@ -1,9 +1,13 @@
|
||||
<?php
|
||||
/**
|
||||
* Global Search Engine for Moodle
|
||||
* Michael Champanis (mchampan) [[email protected]]
|
||||
* review 1.8+ : Valery Fremaux [[email protected]]
|
||||
* 2007/08/02
|
||||
*
|
||||
* @package search
|
||||
* @category core
|
||||
* @subpackage search_engine
|
||||
* @author Michael Champanis (mchampan) [[email protected]], Valery Fremaux [[email protected]] > 1.8
|
||||
* @date 2008/03/31
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
*
|
||||
* Asynchronous index cleaner
|
||||
*
|
||||
@@ -11,122 +15,128 @@
|
||||
* multiple arity to handle multiple document types modules
|
||||
*/
|
||||
|
||||
/**
|
||||
* includes and requires
|
||||
*/
|
||||
require_once('../config.php');
|
||||
require_once("$CFG->dirroot/search/lib.php");
|
||||
|
||||
require_login();
|
||||
|
||||
if (empty($CFG->enableglobalsearch)) {
|
||||
error(get_string('globalsearchdisabled', 'search'));
|
||||
}
|
||||
|
||||
if (!isadmin()) {
|
||||
error(get_string('beadmin', 'search'), "$CFG->wwwroot/login/index.php");
|
||||
} //if
|
||||
|
||||
//check for php5 (lib.php)
|
||||
if (!search_check_php5()) {
|
||||
$phpversion = phpversion();
|
||||
mtrace("Sorry, global search requires PHP 5.0.0 or later (currently using version $phpversion)");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
require_once("$CFG->dirroot/search/indexlib.php");
|
||||
|
||||
$index = new Zend_Search_Lucene(SEARCH_INDEX_PATH);
|
||||
$dbcontrol = new IndexDBControl();
|
||||
$deletion_count = 0;
|
||||
$startcleantime = time();
|
||||
|
||||
mtrace('<pre>Starting clean-up of removed records...');
|
||||
mtrace('Index size before: '.$CFG->search_index_size."\n");
|
||||
|
||||
if ($mods = get_records_select('modules')) {
|
||||
$mods = array_merge($mods, search_get_additional_modules());
|
||||
require_login();
|
||||
|
||||
foreach ($mods as $mod) {
|
||||
//build function names
|
||||
$class_file = $CFG->dirroot.'/search/documents/'.$mod->name.'_document.php';
|
||||
$delete_function = $mod->name.'_delete';
|
||||
$db_names_function = $mod->name.'_db_names';
|
||||
$deletions = array();
|
||||
if (empty($CFG->enableglobalsearch)) {
|
||||
error(get_string('globalsearchdisabled', 'search'));
|
||||
}
|
||||
|
||||
if (!isadmin()) {
|
||||
error(get_string('beadmin', 'search'), "$CFG->wwwroot/login/index.php");
|
||||
} //if
|
||||
|
||||
//check for php5 (lib.php)
|
||||
if (!search_check_php5()) {
|
||||
$phpversion = phpversion();
|
||||
mtrace("Sorry, global search requires PHP 5.0.0 or later (currently using version ".phpversion().")");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
require_once("$CFG->dirroot/search/indexlib.php");
|
||||
|
||||
$index = new Zend_Search_Lucene(SEARCH_INDEX_PATH);
|
||||
$dbcontrol = new IndexDBControl();
|
||||
$deletion_count = 0;
|
||||
$startcleantime = time();
|
||||
|
||||
mtrace('Starting clean-up of removed records...');
|
||||
mtrace('Index size before: '.$CFG->search_index_size."\n");
|
||||
|
||||
if ($mods = get_records_select('modules')) {
|
||||
$mods = array_merge($mods, search_get_additional_modules());
|
||||
|
||||
if (file_exists($class_file)) {
|
||||
require_once($class_file);
|
||||
foreach ($mods as $mod) {
|
||||
//build function names
|
||||
$class_file = $CFG->dirroot.'/search/documents/'.$mod->name.'_document.php';
|
||||
$delete_function = $mod->name.'_delete';
|
||||
$db_names_function = $mod->name.'_db_names';
|
||||
$deletions = array();
|
||||
|
||||
//if both required functions exist
|
||||
if (function_exists($delete_function) and function_exists($db_names_function)) {
|
||||
mtrace("Checking $mod->name module for deletions.");
|
||||
$valuesArray = $db_names_function();
|
||||
if ($valuesArray){
|
||||
foreach($valuesArray as $values){
|
||||
$where = (isset($values[5])) ? 'WHERE '.$values[5] : '';
|
||||
$itemtypes = ($values[4] != '*') ? " itemtype = '{$values[4]}' AND " : '' ;
|
||||
$query = "
|
||||
SELECT
|
||||
id,
|
||||
{$values[0]}
|
||||
FROM
|
||||
{$CFG->prefix}{$values[1]}
|
||||
$where
|
||||
";
|
||||
$docIds = get_records_sql($query);
|
||||
$docIdList = ($docIds) ? implode("','", array_keys($docIds)) : '' ;
|
||||
if (file_exists($class_file)) {
|
||||
require_once($class_file);
|
||||
|
||||
//if both required functions exist
|
||||
if (function_exists($delete_function) and function_exists($db_names_function)) {
|
||||
mtrace("Checking $mod->name module for deletions.");
|
||||
$valuesArray = $db_names_function();
|
||||
if ($valuesArray){
|
||||
foreach($valuesArray as $values){
|
||||
$where = (isset($values[5])) ? 'WHERE '.$values[5] : '';
|
||||
$itemtypes = ($values[4] != '*' && $values[4] != 'any') ? " itemtype = '{$values[4]}' AND " : '' ;
|
||||
$query = "
|
||||
SELECT
|
||||
id,
|
||||
{$values[0]}
|
||||
FROM
|
||||
{$CFG->prefix}{$values[1]}
|
||||
$where
|
||||
";
|
||||
$docIds = get_records_sql($query);
|
||||
$docIdList = ($docIds) ? implode("','", array_keys($docIds)) : '' ;
|
||||
|
||||
$table = SEARCH_DATABASE_TABLE;
|
||||
$query = "
|
||||
SELECT
|
||||
id,
|
||||
docid
|
||||
FROM
|
||||
{$CFG->prefix}{$table}
|
||||
WHERE
|
||||
doctype = '{$mod->name}' AND
|
||||
$itemtypes
|
||||
docid not in ('{$docIdList}')
|
||||
";
|
||||
$records = get_records_sql($query);
|
||||
|
||||
// build an array of all the deleted records
|
||||
if (is_array($records)) {
|
||||
foreach($records as $record) {
|
||||
$deletions[] = $delete_function($record->docid, $values[4]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$table = SEARCH_DATABASE_TABLE;
|
||||
$query = "
|
||||
SELECT
|
||||
id,
|
||||
docid
|
||||
FROM
|
||||
{$CFG->prefix}{$table}
|
||||
WHERE
|
||||
doctype = '{$mod->name}' AND
|
||||
$itemtypes
|
||||
docid not in ('{$docIdList}')
|
||||
";
|
||||
$records = get_records_sql($query);
|
||||
|
||||
// build an array of all the deleted records
|
||||
if (is_array($records)) {
|
||||
foreach($records as $record) {
|
||||
$deletions[] = $delete_function($record->docid, $values[4]);
|
||||
foreach ($deletions as $delete) {
|
||||
// find the specific document in the index, using it's docid and doctype as keys
|
||||
$doc = $index->find("+docid:{$delete->id} +doctype:$mod->name +itemtype:{$delete->itemtype}");
|
||||
|
||||
// get the record, should only be one
|
||||
foreach ($doc as $thisdoc) {
|
||||
++$deletion_count;
|
||||
mtrace(" Delete: $thisdoc->title (database id = $thisdoc->dbid, index id = $thisdoc->id, moodle instance id = $thisdoc->docid)");
|
||||
|
||||
//remove it from index and database table
|
||||
$dbcontrol->delDocument($thisdoc);
|
||||
$index->delete($thisdoc->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($deletions as $delete) {
|
||||
// find the specific document in the index, using it's docid and doctype as keys
|
||||
$doc = $index->find("+docid:{$delete->id} +doctype:$mod->name +itemtype:{$delete->itemtype}");
|
||||
|
||||
// get the record, should only be one
|
||||
foreach ($doc as $thisdoc) {
|
||||
++$deletion_count;
|
||||
mtrace(" Delete: $thisdoc->title (database id = $thisdoc->dbid, index id = $thisdoc->id, moodle instance id = $thisdoc->docid)");
|
||||
|
||||
//remove it from index and database table
|
||||
$dbcontrol->delDocument($thisdoc);
|
||||
$index->delete($thisdoc->id);
|
||||
}
|
||||
else{
|
||||
mtrace("No types to delete.\n");
|
||||
}
|
||||
mtrace("Finished $mod->name.\n");
|
||||
}
|
||||
else{
|
||||
mtrace("No types to delete.\n");
|
||||
}
|
||||
mtrace("Finished $mod->name.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// commit changes
|
||||
|
||||
//commit changes
|
||||
$index->commit();
|
||||
$index->commit();
|
||||
|
||||
/// update index date and index size
|
||||
|
||||
//update index date and index size
|
||||
set_config("search_indexer_cleanup_date", $startcleantime);
|
||||
set_config("search_index_size", (int)$CFG->search_index_size - (int)$deletion_count);
|
||||
|
||||
mtrace("Finished $deletion_count removals.");
|
||||
mtrace('Index size after: '.$index->count().'</pre>');
|
||||
set_config("search_indexer_cleanup_date", $startcleantime);
|
||||
set_config("search_index_size", (int)$CFG->search_index_size - (int)$deletion_count);
|
||||
|
||||
mtrace("Finished $deletion_count removals.");
|
||||
mtrace('Index size after: '.$index->count());
|
||||
|
||||
?>
|
||||
@@ -1,8 +1,13 @@
|
||||
<?php
|
||||
/**
|
||||
* Global Search Engine for Moodle
|
||||
* add-on 1.8+ : Valery Fremaux [[email protected]]
|
||||
* 2007/08/02
|
||||
*
|
||||
* @package search
|
||||
* @category core
|
||||
* @subpackage document_wrappers
|
||||
* @author Valery Fremaux [[email protected]] > 1.8
|
||||
* @date 2008/03/31
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
*
|
||||
* document handling for chat activity module
|
||||
* This file contains the mapping between a chat history and it's indexable counterpart,
|
||||
@@ -10,23 +15,22 @@
|
||||
* Functions for iterating and retrieving the necessary records are now also included
|
||||
* in this file, rather than mod/chat/lib.php
|
||||
*
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
* @package search
|
||||
* @version 2007110400
|
||||
**/
|
||||
*/
|
||||
|
||||
/**
|
||||
* includes and requires
|
||||
*/
|
||||
require_once("$CFG->dirroot/search/documents/document.php");
|
||||
require_once("$CFG->dirroot/mod/chat/lib.php");
|
||||
|
||||
/*
|
||||
/**
|
||||
* a class for representing searchable information
|
||||
*
|
||||
**/
|
||||
*/
|
||||
class ChatTrackSearchDocument extends SearchDocument {
|
||||
|
||||
/**
|
||||
* constructor
|
||||
*
|
||||
*/
|
||||
public function __construct(&$chatsession, $chat_module_id, $course_id, $group_id, $context_id) {
|
||||
// generic information; required
|
||||
@@ -50,8 +54,8 @@ class ChatTrackSearchDocument extends SearchDocument {
|
||||
|
||||
// construct the parent class
|
||||
parent::__construct($doc, $data, $course_id, $group_id, 0, PATH_FOR_SEARCH_TYPE_CHAT);
|
||||
} //constructor
|
||||
} //ChatTrackSearchDocument
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@@ -59,19 +63,23 @@ class ChatTrackSearchDocument extends SearchDocument {
|
||||
* @param cm_id the chat course module
|
||||
* @param start the start time of the session
|
||||
* @param end th end time of the session
|
||||
* @uses CFG
|
||||
* @return a well formed link to session display
|
||||
*/
|
||||
function chat_make_link($cm_id, $start, $end) {
|
||||
global $CFG;
|
||||
|
||||
return $CFG->wwwroot.'/mod/chat/report.php?id='.$cm_id.'&start='.$start.'&end='.$end;
|
||||
} //chat_make_link
|
||||
}
|
||||
|
||||
/**
|
||||
* fetches all the records for a given session and assemble them as a unique track
|
||||
* we revamped here the code of report.php for making sessions, but without any output.
|
||||
* note that we should collect sessions "by groups" if groupmode() is SEPARATEGROUPS.
|
||||
* @param chat_id the database
|
||||
* @param int $chat_id the database
|
||||
* @param int $fromtime
|
||||
* @param int $totime
|
||||
* @uses CFG
|
||||
* @return an array of objects representing the chat sessions.
|
||||
*/
|
||||
function chat_get_session_tracks($chat_id, $fromtime = 0, $totime = 0) {
|
||||
@@ -94,8 +102,7 @@ function chat_get_session_tracks($chat_id, $fromtime = 0, $totime = 0) {
|
||||
foreach($messages as $aMessage){
|
||||
$groupedMessages[$aMessage->groupid][] = $aMessage;
|
||||
}
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
$groupedMessages[-1] = &$messages;
|
||||
}
|
||||
$sessiongap = 5 * 60; // 5 minutes silence means a new session
|
||||
@@ -122,9 +129,8 @@ function chat_get_session_tracks($chat_id, $fromtime = 0, $totime = 0) {
|
||||
$tracks[count($tracks) - 1]->content .= ' '.$message->message;
|
||||
$tracks[count($tracks) - 1]->sessionstart = $message->timestamp;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// we initiate a new session track (backwards)
|
||||
else {
|
||||
$track = new Object();
|
||||
$track->sessionend = $message->timestamp;
|
||||
$track->sessionstart = $message->timestamp;
|
||||
@@ -140,7 +146,7 @@ function chat_get_session_tracks($chat_id, $fromtime = 0, $totime = 0) {
|
||||
}
|
||||
}
|
||||
return $tracks;
|
||||
} //chat_get_session_tracks
|
||||
}
|
||||
|
||||
/**
|
||||
* part of search engine API
|
||||
@@ -149,7 +155,7 @@ function chat_get_session_tracks($chat_id, $fromtime = 0, $totime = 0) {
|
||||
function chat_iterator() {
|
||||
$chatrooms = get_records('chat');
|
||||
return $chatrooms;
|
||||
} //chat_iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* part of search engine API
|
||||
@@ -169,7 +175,7 @@ function chat_get_content_for_index(&$chat) {
|
||||
foreach($sessionTracks as $aTrackId => $aTrack) {
|
||||
foreach($aTrack->sessionusers as $aUserId){
|
||||
$user = get_record('user', 'id', $aUserId);
|
||||
$aTrack->authors = ($user) ? $user->firstname.' '.$user->lastname : '' ;
|
||||
$aTrack->authors = ($user) ? fullname($user) : '' ;
|
||||
$documents[] = new ChatTrackSearchDocument(get_object_vars($aTrack), $cm->id, $chat->course, $aTrack->groupid, $context->id);
|
||||
}
|
||||
}
|
||||
@@ -177,7 +183,7 @@ function chat_get_content_for_index(&$chat) {
|
||||
return $documents;
|
||||
}
|
||||
return array();
|
||||
} //chat_get_content_for_index
|
||||
}
|
||||
|
||||
/**
|
||||
* returns a single data search document based on a chat_session id
|
||||
@@ -202,11 +208,11 @@ function chat_single_document($id, $itemtype) {
|
||||
if ($tracks){
|
||||
$aTrack = $tracks[0];
|
||||
$document = new ChatTrackSearchDocument(get_object_vars($aTrack), $cm->id, $chat->course, $aTrack->groupid, $context->id);
|
||||
return $document;
|
||||
}
|
||||
return $document;
|
||||
}
|
||||
return null;
|
||||
} //chat_single_document
|
||||
}
|
||||
|
||||
/**
|
||||
* dummy delete function that packs id with itemtype.
|
||||
@@ -217,7 +223,7 @@ function chat_delete($info, $itemtype) {
|
||||
$object->id = $info;
|
||||
$object->itemtype = $itemtype;
|
||||
return $object;
|
||||
} //chat_delete
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the var names needed to build a sql query for addition/deletions
|
||||
@@ -226,7 +232,7 @@ function chat_delete($info, $itemtype) {
|
||||
function chat_db_names() {
|
||||
//[primary id], [table name], [time created field name], [time modified field name]
|
||||
return null;
|
||||
} //chat_db_names
|
||||
}
|
||||
|
||||
/**
|
||||
* this function handles the access policy to contents indexed as searchable documents. If this
|
||||
@@ -241,6 +247,7 @@ function chat_db_names() {
|
||||
* points out a session history which is a close sequence of messages.
|
||||
* @param user the user record denoting the user who searches
|
||||
* @param group_id the current group used by the user when searching
|
||||
* @uses CFG
|
||||
* @return true if access is allowed, false elsewhere
|
||||
*/
|
||||
function chat_check_text_access($path, $itemtype, $this_id, $user, $group_id, $context_id){
|
||||
@@ -280,7 +287,7 @@ function chat_check_text_access($path, $itemtype, $this_id, $user, $group_id, $c
|
||||
}
|
||||
|
||||
return true;
|
||||
} //chat_check_text_access
|
||||
}
|
||||
|
||||
/**
|
||||
* this call back is called when displaying the link for some last post processing
|
||||
@@ -290,5 +297,5 @@ function chat_link_post_processing($title){
|
||||
setLocale(LC_TIME, substr(current_language(), 0, 2));
|
||||
$title = preg_replace('/TT_(.*)_TT/e', "userdate(\\1)", $title);
|
||||
return $title;
|
||||
} //chat_link_post_processing
|
||||
}
|
||||
?>
|
||||
@@ -1,8 +1,13 @@
|
||||
<?php
|
||||
/**
|
||||
* Global Search Engine for Moodle
|
||||
* add-on 1.8+ : Valery Fremaux [[email protected]]
|
||||
* 2007/08/02
|
||||
*
|
||||
* @package search
|
||||
* @category core
|
||||
* @subpackage document_wrappers
|
||||
* @author Valery Fremaux [[email protected]] > 1.8
|
||||
* @date 2008/03/31
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
*
|
||||
* document handling for data activity module
|
||||
* This file contains the mapping between a database object and it's indexable counterpart,
|
||||
@@ -10,23 +15,22 @@
|
||||
* Functions for iterating and retrieving the necessary records are now also included
|
||||
* in this file, rather than mod/data/lib.php
|
||||
*
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
* @package search
|
||||
* @version 2007110400
|
||||
**/
|
||||
*/
|
||||
|
||||
/**
|
||||
* includes and requires
|
||||
*/
|
||||
require_once("$CFG->dirroot/search/documents/document.php");
|
||||
require_once("$CFG->dirroot/mod/data/lib.php");
|
||||
|
||||
/*
|
||||
/**
|
||||
* a class for representing searchable information (data records)
|
||||
*
|
||||
**/
|
||||
*/
|
||||
class DataSearchDocument extends SearchDocument {
|
||||
|
||||
/**
|
||||
* constructor
|
||||
*
|
||||
*/
|
||||
public function __construct(&$record, $course_id, $context_id) {
|
||||
// generic information; required
|
||||
@@ -51,18 +55,17 @@ class DataSearchDocument extends SearchDocument {
|
||||
|
||||
// construct the parent class
|
||||
parent::__construct($doc, $data, $course_id, $record['groupid'], $record['userid'], PATH_FOR_SEARCH_TYPE_DATA);
|
||||
} //constructor
|
||||
} //ChatSearchDocument
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* a class for representing searchable information (comments on data records)
|
||||
*
|
||||
**/
|
||||
*/
|
||||
class DataCommentSearchDocument extends SearchDocument {
|
||||
|
||||
/**
|
||||
* constructor
|
||||
*
|
||||
*/
|
||||
public function __construct(&$comment, $course_id, $context_id) {
|
||||
// generic information; required
|
||||
@@ -83,25 +86,27 @@ class DataCommentSearchDocument extends SearchDocument {
|
||||
|
||||
// construct the parent class
|
||||
parent::__construct($doc, $data, $course_id, $comment['groupid'], $comment['userid'], PATH_FOR_SEARCH_TYPE_DATA);
|
||||
} //constructor
|
||||
} //ChatCommentSearchDocument
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* constructs a valid link to a data record content
|
||||
* @param database_id the database reference
|
||||
* @param record_id the record reference
|
||||
* @uses CFG
|
||||
* @return a valid url top access the information as a string
|
||||
*/
|
||||
function data_make_link($database_id, $record_id) {
|
||||
global $CFG;
|
||||
|
||||
return $CFG->wwwroot.'/mod/data/view.php?d='.$database_id.'&rid='.$record_id;
|
||||
} //data_make_link
|
||||
}
|
||||
|
||||
/**
|
||||
* fetches all the records for a given database
|
||||
* @param database_id the database
|
||||
* @param typematch a comma separated list of types that should be considered for searching or *
|
||||
* @uses CFG
|
||||
* @return an array of objects representing the data records.
|
||||
*/
|
||||
function data_get_records($database_id, $typematch = '*') {
|
||||
@@ -127,19 +132,19 @@ function data_get_records($database_id, $typematch = '*') {
|
||||
if($typematch == '*' || preg_match("/\\b{$fieldset[$aDatum->fieldid]->type}\\b/", $typematch)){
|
||||
if (!isset($records[$aDatum->recordid])){
|
||||
$records[$aDatum->recordid]['_first'] = $aDatum->content.' '.$aDatum->content1.' '.$aDatum->content2.' '.$aDatum->content3.' '.$aDatum->content4.' ';
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
$records[$aDatum->recordid][$fieldset[$aDatum->fieldid]->name] = $aDatum->content.' '.$aDatum->content1.' '.$aDatum->content2.' '.$aDatum->content3.' '.$aDatum->content4.' ';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $records;
|
||||
} //data_get_records
|
||||
}
|
||||
|
||||
/**
|
||||
* fetches all the comments for a given database
|
||||
* @param database_id the database
|
||||
* @uses CFG
|
||||
* @return an array of objects representing the data record comments.
|
||||
*/
|
||||
function data_get_comments($database_id) {
|
||||
@@ -163,7 +168,7 @@ function data_get_comments($database_id) {
|
||||
";
|
||||
$comments = get_records_sql($query);
|
||||
return $comments;
|
||||
} //data_get_comments
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@@ -173,7 +178,7 @@ function data_get_comments($database_id) {
|
||||
function data_iterator() {
|
||||
$databases = get_records('data');
|
||||
return $databases;
|
||||
} //data_iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* part of search engine API
|
||||
@@ -221,7 +226,7 @@ function data_get_content_for_index(&$database) {
|
||||
}
|
||||
}
|
||||
return $documents;
|
||||
} //data_get_content_for_index
|
||||
}
|
||||
|
||||
/**
|
||||
* returns a single data search document based on a data entry id
|
||||
@@ -256,8 +261,7 @@ function data_single_document($id, $itemtype) {
|
||||
$recordMetaData->content = $accumulator;
|
||||
// make document
|
||||
$documents[] = new DataSearchDocument(get_object_vars($recordMetaData), $record_course, $context->id);
|
||||
}
|
||||
elseif($itemtype == 'comment'){
|
||||
} elseif($itemtype == 'comment') {
|
||||
// get main records
|
||||
$comment = get_record('data_comments', 'id', $id);
|
||||
$record = get_record('data_records', 'id', $comment->recordid);
|
||||
@@ -272,11 +276,10 @@ function data_single_document($id, $itemtype) {
|
||||
$comment->groupid = $record->groupid;
|
||||
// make document
|
||||
$documents[] = new DataCommentSearchDocument(get_object_vars($comment), $record_course, $context->id);
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
mtrace('Error : bad or missing item type');
|
||||
}
|
||||
} //data_single_document
|
||||
}
|
||||
|
||||
/**
|
||||
* dummy delete function that packs id with itemtype.
|
||||
@@ -287,7 +290,7 @@ function data_delete($info, $itemtype) {
|
||||
$object->id = $info;
|
||||
$object->itemtype = $itemtype;
|
||||
return $object;
|
||||
} //data_delete
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the var names needed to build a sql query for addition/deletions
|
||||
@@ -299,7 +302,7 @@ function data_db_names() {
|
||||
array('id', 'data_records', 'timecreated', 'timemodified', 'record'),
|
||||
array('id', 'data_comments', 'created', 'modified', 'comment')
|
||||
);
|
||||
} //data_db_names
|
||||
}
|
||||
|
||||
/**
|
||||
* this function handles the access policy to contents indexed as searchable documents. If this
|
||||
@@ -314,6 +317,7 @@ function data_db_names() {
|
||||
* points out an indexed data record page.
|
||||
* @param user the user record denoting the user who searches
|
||||
* @param group_id the current group used by the user when searching
|
||||
* @uses CFG
|
||||
* @return true if access is allowed, false elsewhere
|
||||
*/
|
||||
function data_check_text_access($path, $itemtype, $this_id, $user, $group_id, $context_id){
|
||||
@@ -394,5 +398,5 @@ function data_check_text_access($path, $itemtype, $this_id, $user, $group_id, $c
|
||||
}
|
||||
|
||||
return true;
|
||||
} // data_check_text_access
|
||||
}
|
||||
?>
|
||||
@@ -1,14 +1,21 @@
|
||||
<?php
|
||||
/**
|
||||
* Global Search Engine for Moodle
|
||||
* Michael Champanis (mchampan) [[email protected]]
|
||||
* review 1.8+ : Valery Fremaux [[email protected]]
|
||||
* 2007/08/02
|
||||
*
|
||||
* @package search
|
||||
* @category core
|
||||
* @subpackage document_wrappers
|
||||
* @author Michael Campanis (mchampan) [[email protected]], Valery Fremaux [[email protected]] > 1.8
|
||||
* @date 2008/03/31
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
*
|
||||
* Base search document from which other module/block types can
|
||||
* extend.
|
||||
**/
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
abstract class SearchDocument extends Zend_Search_Lucene_Document {
|
||||
public function __construct(&$doc, &$data, $course_id, $group_id, $user_id, $path) {
|
||||
//document identification and indexing
|
||||
@@ -52,7 +59,7 @@ abstract class SearchDocument extends Zend_Search_Lucene_Document {
|
||||
// of multiple capabilities in their code. This possibility should be left open here.
|
||||
$this->addField(Zend_Search_Lucene_Field::UnIndexed('capabilities', $caps));
|
||||
*/
|
||||
} //constructor
|
||||
} //SearchDocument
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -1,9 +1,13 @@
|
||||
<?php
|
||||
/**
|
||||
* Global Search Engine for Moodle
|
||||
* Michael Champanis (mchampan) [[email protected]]
|
||||
* review 1.8+ : Valery Fremaux [[email protected]]
|
||||
* 2007/08/02
|
||||
*
|
||||
* @package search
|
||||
* @category core
|
||||
* @subpackage document_wrappers
|
||||
* @author Michael Campanis (mchampan) [[email protected]], Valery Fremaux [[email protected]] > 1.8
|
||||
* @date 2008/03/31
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
*
|
||||
* document handling for forum activity module
|
||||
* This file contains the mapping between a forum post and it's indexable counterpart,
|
||||
@@ -11,24 +15,22 @@
|
||||
* Functions for iterating and retrieving the necessary records are now also included
|
||||
* in this file, rather than mod/forum/lib.php
|
||||
*
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
* @package search
|
||||
* @version 2007110400
|
||||
**/
|
||||
/* see wiki_document.php for descriptions */
|
||||
*/
|
||||
|
||||
/**
|
||||
* includes and requires
|
||||
*/
|
||||
require_once("$CFG->dirroot/search/documents/document.php");
|
||||
require_once("$CFG->dirroot/mod/forum/lib.php");
|
||||
|
||||
/*
|
||||
/**
|
||||
* a class for representing searchable information
|
||||
*
|
||||
**/
|
||||
*/
|
||||
class ForumSearchDocument extends SearchDocument {
|
||||
|
||||
/**
|
||||
* constructor
|
||||
*
|
||||
*/
|
||||
public function __construct(&$post, $forum_id, $course_id, $itemtype, $context_id) {
|
||||
// generic information
|
||||
@@ -50,8 +52,8 @@ class ForumSearchDocument extends SearchDocument {
|
||||
$data->discussion = $post['discussion'];
|
||||
|
||||
parent::__construct($doc, $data, $course_id, $post['groupid'], $post['userid'], PATH_FOR_SEARCH_TYPE_FORUM);
|
||||
} //constructor
|
||||
} //ForumSearchDocument
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* constructs a valid link to a chat content
|
||||
@@ -63,7 +65,7 @@ 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
|
||||
}
|
||||
|
||||
/**
|
||||
* search standard API
|
||||
@@ -72,7 +74,7 @@ function forum_make_link($discussion_id, $post_id) {
|
||||
function forum_iterator() {
|
||||
$forums = get_records('forum');
|
||||
return $forums;
|
||||
} //forum_iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* search standard API
|
||||
@@ -108,7 +110,7 @@ function forum_get_content_for_index(&$forum) {
|
||||
}
|
||||
}
|
||||
return $documents;
|
||||
} //forum_get_content_for_index
|
||||
}
|
||||
|
||||
/**
|
||||
* returns a single forum search document based on a forum entry id
|
||||
@@ -128,7 +130,7 @@ function forum_single_document($id, $itemtype) {
|
||||
return new ForumSearchDocument(get_object_vars($post), $discussion->forum, $discussion->course, $itemtype, $context->id);
|
||||
}
|
||||
return null;
|
||||
} //forum_single_document
|
||||
}
|
||||
|
||||
/**
|
||||
* dummy delete function that aggregates id with itemtype.
|
||||
@@ -139,7 +141,7 @@ function forum_delete($info, $itemtype) {
|
||||
$object->id = $info;
|
||||
$object->itemtype = $itemtype;
|
||||
return $object;
|
||||
} //forum_delete
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the var names needed to build a sql query for addition/deletions
|
||||
@@ -151,11 +153,12 @@ function forum_db_names() {
|
||||
array('id', 'forum_posts', 'created', 'modified', 'head', 'parent = 0'),
|
||||
array('id', 'forum_posts', 'created', 'modified', 'post', 'parent != 0')
|
||||
);
|
||||
} //forum_db_names
|
||||
}
|
||||
|
||||
/**
|
||||
* reworked faster version from /mod/forum/lib.php
|
||||
* @param forum_id a forum identifier
|
||||
* @uses CFG, USER
|
||||
* @return an array of posts
|
||||
*/
|
||||
function forum_get_discussions_fast($forum_id) {
|
||||
@@ -202,12 +205,13 @@ function forum_get_discussions_fast($forum_id) {
|
||||
d.timemodified DESC
|
||||
";
|
||||
return get_records_sql($query);
|
||||
} //forum_get_discussions_fast
|
||||
}
|
||||
|
||||
/**
|
||||
* reworked faster version from /mod/forum/lib.php
|
||||
* @param parent the id of the first post within the discussion
|
||||
* @param forum_id the forum identifier
|
||||
* @uses CFG
|
||||
* @return an array of posts
|
||||
*/
|
||||
function forum_get_child_posts_fast($parent, $forum_id) {
|
||||
@@ -241,7 +245,7 @@ function forum_get_child_posts_fast($parent, $forum_id) {
|
||||
p.created ASC
|
||||
";
|
||||
return get_records_sql($query);
|
||||
} //forum_get_child_posts_fast
|
||||
}
|
||||
|
||||
/**
|
||||
* this function handles the access policy to contents indexed as searchable documents. If this
|
||||
@@ -256,6 +260,7 @@ function forum_get_child_posts_fast($parent, $forum_id) {
|
||||
* points out the individual post.
|
||||
* @param user the user record denoting the user who searches
|
||||
* @param group_id the current group used by the user when searching
|
||||
* @uses CFG, USER
|
||||
* @return true if access is allowed, false elsewhere
|
||||
*/
|
||||
function forum_check_text_access($path, $itemtype, $this_id, $user, $group_id, $context_id){
|
||||
@@ -290,6 +295,6 @@ function forum_check_text_access($path, $itemtype, $this_id, $user, $group_id, $
|
||||
}
|
||||
|
||||
return true;
|
||||
} //forum_check_text_access
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -1,9 +1,13 @@
|
||||
<?php
|
||||
/**
|
||||
* Global Search Engine for Moodle
|
||||
* Michael Champanis (mchampan) [[email protected]]
|
||||
* review 1.8+ : Valery Fremaux [[email protected]]
|
||||
* 2007/08/02
|
||||
*
|
||||
* @package search
|
||||
* @category core
|
||||
* @subpackage document_wrappers
|
||||
* @author Michael Campanis (mchampan) [[email protected]], Valery Fremaux [[email protected]] > 1.8
|
||||
* @date 2008/03/31
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
*
|
||||
* document handling for glossary activity module
|
||||
* This file contains a mapping between a glossary entry and it's indexable counterpart,
|
||||
@@ -11,17 +15,17 @@
|
||||
* Functions for iterating and retrieving the necessary records are now also included
|
||||
* in this file, rather than mod/glossary/lib.php
|
||||
*
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
* @package search
|
||||
* @version 2007110400
|
||||
**/
|
||||
*/
|
||||
|
||||
/**
|
||||
* includes and requires
|
||||
*/
|
||||
require_once("$CFG->dirroot/search/documents/document.php");
|
||||
|
||||
/*
|
||||
/**
|
||||
* a class for representing searchable information
|
||||
*
|
||||
**/
|
||||
*/
|
||||
class GlossarySearchDocument extends SearchDocument {
|
||||
|
||||
/**
|
||||
@@ -49,18 +53,17 @@ class GlossarySearchDocument extends SearchDocument {
|
||||
|
||||
// construct the parent class
|
||||
parent::__construct($doc, $data, $course_id, -1, $entry['userid'], PATH_FOR_SEARCH_TYPE_GLOSSARY);
|
||||
} //constructor
|
||||
} //GlossarySearchDocument
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* a class for representing searchable information
|
||||
*
|
||||
**/
|
||||
*/
|
||||
class GlossaryCommentSearchDocument extends SearchDocument {
|
||||
|
||||
/**
|
||||
* document constructor
|
||||
*
|
||||
*/
|
||||
public function __construct(&$entry, $glossary_id, $course_id, $context_id) {
|
||||
// generic information; required
|
||||
@@ -83,8 +86,8 @@ class GlossaryCommentSearchDocument extends SearchDocument {
|
||||
|
||||
// construct the parent class
|
||||
parent::__construct($doc, $data, $course_id, -1, $entry['userid'], PATH_FOR_SEARCH_TYPE_GLOSSARY);
|
||||
} //constructor
|
||||
} //GlossaryCommentSearchDocument
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* constructs valid access links to information
|
||||
@@ -102,7 +105,7 @@ function glossary_make_link($entry_id) {
|
||||
// preserve glossary pop-up, be careful where you place your ' and "s
|
||||
//this function is meant to return a url that is placed between href='[url here]'
|
||||
return "$CFG->wwwroot/mod/glossary/showentry.php?eid=$entry_id' onclick='return openpopup(\"/mod/glossary/showentry.php?eid=$entry_id\", \"entry\", DEFAULT_POPUP_SETTINGS, 0);";
|
||||
} //glossary_make_link
|
||||
}
|
||||
|
||||
/**
|
||||
* part of search engine API
|
||||
@@ -111,7 +114,7 @@ function glossary_make_link($entry_id) {
|
||||
function glossary_iterator() {
|
||||
$glossaries = get_records('glossary');
|
||||
return $glossaries;
|
||||
} //glossary_iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* part of search engine API
|
||||
@@ -153,7 +156,7 @@ function glossary_get_content_for_index(&$glossary) {
|
||||
}
|
||||
}
|
||||
return $documents;
|
||||
} //glossary_get_content_for_index
|
||||
}
|
||||
|
||||
/**
|
||||
* part of search engine API
|
||||
@@ -179,7 +182,7 @@ function glossary_single_document($id, $itemtype) {
|
||||
elseif ($itemtype == 'comment'){
|
||||
return new GlossaryCommentSearchDocument(get_object_vars($comment), $entry->glossaryid, $glossary_course, $context->id);
|
||||
}
|
||||
} //glossary_single_document
|
||||
}
|
||||
|
||||
/**
|
||||
* dummy delete function that packs id with itemtype.
|
||||
@@ -190,7 +193,7 @@ function glossary_delete($info, $itemtype) {
|
||||
$object->id = $info;
|
||||
$object->itemtype = $itemtype;
|
||||
return $object;
|
||||
} //glossary_delete
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the var names needed to build a sql query for addition/deletions
|
||||
@@ -202,7 +205,7 @@ function glossary_db_names() {
|
||||
array('id', 'glossary_entries', 'timecreated', 'timemodified', 'standard'),
|
||||
array('id', 'glossary_comments', 'timemodified', 'timemodified', 'comment')
|
||||
);
|
||||
} //glossary_db_names
|
||||
}
|
||||
|
||||
/**
|
||||
* this function handles the access policy to contents indexed as searchable documents. If this
|
||||
@@ -241,6 +244,14 @@ function glossary_check_text_access($path, $itemtype, $this_id, $user, $group_id
|
||||
}
|
||||
|
||||
return true;
|
||||
} //glossary_check_text_access
|
||||
}
|
||||
|
||||
/**
|
||||
* post processes the url for cleaner output.
|
||||
* @param string $title
|
||||
*/
|
||||
function glossary_link_post_processing($title){
|
||||
return mb_convert_encoding($title, 'auto', 'UTF-8');
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -1,29 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
* Global Search Engine for Moodle
|
||||
* Michael Champanis (mchampan) [[email protected]]
|
||||
* creation : Valery Fremaux [[email protected]]
|
||||
* 2007/08/02
|
||||
*
|
||||
* @package search
|
||||
* @category core
|
||||
* @subpackage document_wrappers
|
||||
* @author Michael Campanis (mchampan) [[email protected]], Valery Fremaux [[email protected]] > 1.8
|
||||
* @date 2008/03/31
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
*
|
||||
* document handling for lesson activity module
|
||||
* This file contains the mapping between a lesson page and it's indexable counterpart,
|
||||
*
|
||||
* Functions for iterating and retrieving the necessary records are now also included
|
||||
* in this file, rather than mod/lesson/lib.php
|
||||
*
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
* @package search
|
||||
* @version 2007110400
|
||||
**/
|
||||
/* see wiki_document.php for descriptions */
|
||||
*/
|
||||
|
||||
/**
|
||||
* includes and requires
|
||||
*/
|
||||
require_once("$CFG->dirroot/search/documents/document.php");
|
||||
require_once("$CFG->dirroot/mod/lesson/lib.php");
|
||||
|
||||
/*
|
||||
/**
|
||||
* a class for representing searchable information
|
||||
*
|
||||
**/
|
||||
*/
|
||||
class LessonPageSearchDocument extends SearchDocument {
|
||||
|
||||
/**
|
||||
@@ -48,8 +50,8 @@ class LessonPageSearchDocument extends SearchDocument {
|
||||
$data->lesson = $page['lessonid'];
|
||||
|
||||
parent::__construct($doc, $data, $course_id, 0, 0, PATH_FOR_SEARCH_TYPE_LESSON);
|
||||
} //constructor
|
||||
} //LessonPageSearchDocument
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* constructs a valid link to a chat content
|
||||
@@ -64,7 +66,7 @@ function lesson_make_link($lessonmoduleid, $itemid, $itemtype) {
|
||||
return "{$CFG->wwwroot}/mod/lesson/view.php?id={$lessonmoduleid}&pageid={$itemid}";
|
||||
}
|
||||
return $CFG->wwwroot.'/mod/lesson/view.php?id='.$lessonmoduleid;
|
||||
} //lesson_make_link
|
||||
}
|
||||
|
||||
/**
|
||||
* search standard API
|
||||
@@ -73,7 +75,7 @@ function lesson_make_link($lessonmoduleid, $itemid, $itemtype) {
|
||||
function lesson_iterator() {
|
||||
$lessons = get_records('lesson');
|
||||
return $lessons;
|
||||
} //lesson_iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* search standard API
|
||||
@@ -96,7 +98,7 @@ function lesson_get_content_for_index(&$lesson) {
|
||||
}
|
||||
|
||||
return $documents;
|
||||
} //lesson_get_content_for_index
|
||||
}
|
||||
|
||||
/**
|
||||
* returns a single lesson search document based on a lesson page id
|
||||
@@ -116,7 +118,7 @@ function lesson_single_document($id, $itemtype) {
|
||||
return new LessonPageSearchDocument(get_object_vars($page), $cm->id, $lesson->course, $itemtype, $context->id);
|
||||
}
|
||||
return null;
|
||||
} //lesson_single_document
|
||||
}
|
||||
|
||||
/**
|
||||
* dummy delete function that aggregates id with itemtype.
|
||||
@@ -127,7 +129,7 @@ function lesson_delete($info, $itemtype) {
|
||||
$object->id = $info;
|
||||
$object->itemtype = $itemtype;
|
||||
return $object;
|
||||
} //lesson_delete
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the var names needed to build a sql query for addition/deletions
|
||||
@@ -138,7 +140,7 @@ function lesson_db_names() {
|
||||
return array(
|
||||
array('id', 'lesson_pages', 'timecreated', 'timemodified', 'page')
|
||||
);
|
||||
} //lesson_db_names
|
||||
}
|
||||
|
||||
/**
|
||||
* this function handles the access policy to contents indexed as searchable documents. If this
|
||||
@@ -201,5 +203,5 @@ function lesson_check_text_access($path, $itemtype, $this_id, $user, $group_id,
|
||||
}
|
||||
|
||||
return true;
|
||||
} //lesson_check_text_access
|
||||
}
|
||||
?>
|
||||
@@ -1,40 +1,50 @@
|
||||
<?php
|
||||
/**
|
||||
* Global Search Engine for Moodle
|
||||
* add-on 1.8+ : Valery Fremaux [[email protected]]
|
||||
* 2007/08/02
|
||||
*
|
||||
* @package search
|
||||
* @category core
|
||||
* @subpackage document_wrappers
|
||||
* @author Valery Fremaux [[email protected]] > 1.8
|
||||
* @date 2008/03/31
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
*
|
||||
* this is a format handler for getting text out of a proprietary binary format
|
||||
* so it can be indexed by Lucene search engine
|
||||
*/
|
||||
|
||||
/*
|
||||
/**
|
||||
* MS Word extractor
|
||||
* @param object $resource
|
||||
* @uses CFG, USER
|
||||
*/
|
||||
|
||||
function get_text_for_indexing_doc(&$resource){
|
||||
global $CFG, $USER;
|
||||
|
||||
// SECURITY : do not allow non admin execute anything on system !!
|
||||
if (!isadmin($USER->id)) return;
|
||||
|
||||
$moodleroot = (@$CFG->block_search_usemoodleroot) ? "{$CFG->dirroot}/" : '' ;
|
||||
|
||||
// just call pdftotext over stdout and capture the output
|
||||
if (!empty($CFG->block_search_word_to_text_cmd)){
|
||||
if (!file_exists("{$CFG->dirroot}/{$CFG->block_search_word_to_text_cmd}")){
|
||||
if (!file_exists("{$moodleroot}{$CFG->block_search_word_to_text_cmd}")){
|
||||
mtrace('Error with MSWord to text converter command : exectuable not found.');
|
||||
}
|
||||
else{
|
||||
$file = escapeshellarg($CFG->dataroot.'/'.$resource->course.'/'.$resource->reference);
|
||||
$text_converter_cmd = "{$CFG->dirroot}/{$CFG->block_search_word_to_text_cmd} $file";
|
||||
$command = trim($CFG->block_search_word_to_text_cmd);
|
||||
$text_converter_cmd = "{$moodleroot}{$command} \"$file\"";
|
||||
if ($CFG->block_search_word_to_text_env){
|
||||
putenv($CFG->block_search_word_to_text_env);
|
||||
}
|
||||
mtrace("Executing : $text_converter_cmd");
|
||||
$result = shell_exec($text_converter_cmd);
|
||||
if ($result){
|
||||
return mb_convert_encoding($result, 'UTF8', 'auto');
|
||||
}
|
||||
else{
|
||||
mtrace('Error with MSWord to text converter command : execution failed.');
|
||||
mtrace('Error with MSWord to text converter command : execution failed. ');
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,22 @@
|
||||
<?php
|
||||
/**
|
||||
* Global Search Engine for Moodle
|
||||
* add-on 1.8+ : Valery Fremaux [[email protected]]
|
||||
* 2007/08/02
|
||||
*
|
||||
* @package search
|
||||
* @category core
|
||||
* @subpackage document_wrappers
|
||||
* @author Valery Fremaux [[email protected]] > 1.8
|
||||
* @date 2008/03/31
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
*
|
||||
* this is a format handler for getting text out of a proprietary binary format
|
||||
* so it can be indexed by Lucene search engine
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param object $resource
|
||||
* @uses CFG, USER
|
||||
*/
|
||||
function get_text_for_indexing_htm(&$resource){
|
||||
global $CFG, $USER;
|
||||
|
||||
@@ -15,21 +24,32 @@ function get_text_for_indexing_htm(&$resource){
|
||||
if (!isadmin($USER->id)) return;
|
||||
|
||||
// just get text
|
||||
$text = implode('', file("{$CFG->dataroot}/{$resource->course}/($resource->reference)"));
|
||||
$text = implode('', file("{$CFG->dataroot}/{$resource->course}/{$resource->reference}"));
|
||||
|
||||
// extract keywords and other interesting meta information and put it back as real content for indexing
|
||||
if (preg_match('/(.*)<meta ([^>]*)>(.*)/is',$text, $matches)){
|
||||
if (preg_match('/(.*)<meta ([^>]*)>(.*)/is', $text, $matches)){
|
||||
$prefix = $matches[1];
|
||||
$meta_attributes = $matches[2];
|
||||
$suffix = $matches[3];
|
||||
if (preg_match('/name="(keywords|description)"/i', $attributes)){
|
||||
preg_match('/content="[^"]+"/i', $attributes, $matches);
|
||||
if (preg_match('/name="(keywords|description)"/i', $meta_attributes)){
|
||||
preg_match('/content="([^"]+)"/i', $meta_attributes, $matches);
|
||||
$text = $prefix.' '.$matches[1].' '.$suffix;
|
||||
}
|
||||
}
|
||||
// filter all html tags
|
||||
// $text = clean_text($text, FORMAT_PLAIN);
|
||||
// NOTE : this is done in ResourceSearchDocument __constructor
|
||||
// brutally filters all html tags
|
||||
$text = preg_replace("/<[^>]*>/", '', $text);
|
||||
$text = preg_replace("/<!--[^>]*-->/", '', $text);
|
||||
$text = html_entity_decode($text, ENT_COMPAT, 'UTF-8');
|
||||
$text = mb_convert_encoding($text, 'UTF-8', 'AUTO');
|
||||
|
||||
/*
|
||||
* debug code for tracing input
|
||||
echo "<hr/>";
|
||||
$FILE = fopen("filetrace.log", 'w');
|
||||
fwrite($FILE, $text);
|
||||
fclose($FILE);
|
||||
echo "<hr/>";
|
||||
*/
|
||||
|
||||
if (!empty($CFG->block_search_limit_index_body)){
|
||||
$text = shorten($text, $CFG->block_search_limit_index_body);
|
||||
|
||||
@@ -1,13 +1,21 @@
|
||||
<?php
|
||||
/**
|
||||
* Global Search Engine for Moodle
|
||||
* add-on 1.8+ : Valery Fremaux [[email protected]]
|
||||
* 2007/08/02
|
||||
*
|
||||
* this is a format handler for getting text out of a proprietary binary format
|
||||
* @package search
|
||||
* @category core
|
||||
* @subpackage document_wrappers
|
||||
* @author Valery Fremaux [[email protected]] > 1.8
|
||||
* @date 2008/03/31
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
*
|
||||
* this is a format handler for getting text out of a standard html format
|
||||
* so it can be indexed by Lucene search engine
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param object $resource
|
||||
*/
|
||||
function get_text_for_indexing_html(&$resource){
|
||||
|
||||
// wraps to htm handler
|
||||
|
||||
@@ -1,28 +1,40 @@
|
||||
<?php
|
||||
/**
|
||||
* Global Search Engine for Moodle
|
||||
* add-on 1.8+ : Valery Fremaux [[email protected]]
|
||||
* 2007/08/02
|
||||
*
|
||||
* @package search
|
||||
* @category core
|
||||
* @subpackage document_wrappers
|
||||
* @author Valery Fremaux [[email protected]] > 1.8
|
||||
* @date 2008/03/31
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
*
|
||||
* this is a format handler for getting text out of a proprietary binary format
|
||||
* so it can be indexed by Lucene search engine
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param object $resource
|
||||
* @uses CFG, USER
|
||||
*/
|
||||
function get_text_for_indexing_pdf(&$resource){
|
||||
global $CFG, $USER;
|
||||
|
||||
// SECURITY : do not allow non admin execute anything on system !!
|
||||
if (!isadmin($USER->id)) return;
|
||||
|
||||
$moodleroot = (@$CFG->block_search_usemoodleroot) ? "{$CFG->dirroot}/" : '' ;
|
||||
|
||||
// just call pdftotext over stdout and capture the output
|
||||
if (!empty($CFG->block_search_pdf_to_text_cmd)){
|
||||
preg_match("/^\S+/", $CFG->block_search_pdf_to_text_cmd, $matches);
|
||||
if (!file_exists("{$CFG->dirroot}/{$matches[0]}")){
|
||||
if (!file_exists("{$moodleroot}/{$matches[0]}")){
|
||||
mtrace('Error with pdf to text converter command : exectuable not found.');
|
||||
}
|
||||
else{
|
||||
$file = escapeshellarg($CFG->dataroot.'/'.$resource->course.'/'.$resource->reference);
|
||||
$text_converter_cmd = "{$CFG->dirroot}/{$CFG->block_search_pdf_to_text_cmd} $file -";
|
||||
$command = trim($CFG->block_search_pdf_to_text_cmd);
|
||||
$text_converter_cmd = "{$moodleroot}/{$command} \"$file\" -";
|
||||
$result = shell_exec($text_converter_cmd);
|
||||
if ($result){
|
||||
return $result;
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
<?php
|
||||
/**
|
||||
* Global Search Engine for Moodle
|
||||
* add-on 1.8+ : Valery Fremaux [[email protected]]
|
||||
* 2007/08/02
|
||||
*
|
||||
* @package search
|
||||
* @category core
|
||||
* @subpackage document_wrappers
|
||||
* @author Valery Fremaux [[email protected]] > 1.8
|
||||
* @date 2008/03/31
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
*
|
||||
* this is a format handler for getting text out of a proprietary binary format
|
||||
* so it can be indexed by Lucene search engine
|
||||
*/
|
||||
|
||||
/**
|
||||
/*
|
||||
* first implementation is a trivial heuristic based on ppt character stream :
|
||||
* text sequence always starts with a 00 9F 0F 04 sequence followed by a 15 bytes
|
||||
* sequence
|
||||
@@ -22,6 +27,10 @@
|
||||
* based on these following rules, here is a little empiric texte extractor for PPT
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param object $resource
|
||||
* @uses CFG, USER
|
||||
*/
|
||||
function get_text_for_indexing_ppt(&$resource){
|
||||
global $CFG, $USER;
|
||||
|
||||
|
||||
@@ -1,13 +1,22 @@
|
||||
<?php
|
||||
/**
|
||||
* Global Search Engine for Moodle
|
||||
* add-on 1.8+ : Valery Fremaux [[email protected]]
|
||||
* 2007/08/02
|
||||
*
|
||||
* @package search
|
||||
* @category core
|
||||
* @subpackage document_wrappers
|
||||
* @author Valery Fremaux [[email protected]] > 1.8
|
||||
* @date 2008/03/31
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
*
|
||||
* this is a format handler for getting text out of a proprietary binary format
|
||||
* so it can be indexed by Lucene search engine
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param object $resource
|
||||
* @uses CFG, USER
|
||||
*/
|
||||
function get_text_for_indexing_txt(&$resource){
|
||||
global $CFG, $USER;
|
||||
|
||||
|
||||
@@ -1,13 +1,22 @@
|
||||
<?php
|
||||
/**
|
||||
* Global Search Engine for Moodle
|
||||
* add-on 1.8+ : Valery Fremaux [[email protected]]
|
||||
* 2007/08/02
|
||||
*
|
||||
* @package search
|
||||
* @category core
|
||||
* @subpackage document_wrappers
|
||||
* @author Valery Fremaux [[email protected]] > 1.8
|
||||
* @date 2008/03/31
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
*
|
||||
* this is a format handler for getting text out of a proprietary binary format
|
||||
* so it can be indexed by Lucene search engine
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param object $resource
|
||||
* @uses CFG, USER
|
||||
*/
|
||||
function get_text_for_indexing_xml(&$resource){
|
||||
global $CFG, $USER;
|
||||
|
||||
|
||||
@@ -1,24 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
* Global Search Engine for Moodle
|
||||
* Michael Champanis (mchampan) [[email protected]]
|
||||
* review 1.8+ : Valery Fremaux [[email protected]]
|
||||
* 2007/08/02
|
||||
*
|
||||
* @package search
|
||||
* @category core
|
||||
* @subpackage document_wrappers
|
||||
* @author Michael Campanis (mchampan) [[email protected]], Valery Fremaux [[email protected]] > 1.8
|
||||
* @date 2008/03/31
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
*
|
||||
* document handling for all resources
|
||||
* This file contains the mapping between a resource and it's indexable counterpart,
|
||||
*
|
||||
* Functions for iterating and retrieving the necessary records are now also included
|
||||
* in this file, rather than mod/resource/lib.php
|
||||
**/
|
||||
*/
|
||||
|
||||
/**
|
||||
* requires and includes
|
||||
*/
|
||||
require_once("$CFG->dirroot/search/documents/document.php");
|
||||
require_once("$CFG->dirroot/mod/resource/lib.php");
|
||||
|
||||
/*
|
||||
/* *
|
||||
* a class for representing searchable information
|
||||
*
|
||||
**/
|
||||
*/
|
||||
class ResourceSearchDocument extends SearchDocument {
|
||||
public function __construct(&$resource, $context_id) {
|
||||
// generic information; required
|
||||
@@ -68,6 +75,7 @@ function resource_iterator() {
|
||||
* this function does not need a content iterator, returns all the info
|
||||
* itself;
|
||||
* @param notneeded to comply API, remember to fake the iterator array though
|
||||
* @uses CFG
|
||||
* @return an array of searchable documents
|
||||
*/
|
||||
function resource_get_content_for_index(&$notneeded) {
|
||||
@@ -155,7 +163,10 @@ function resource_get_physical_file(&$resource, $context_id, $getsingle, &$docum
|
||||
global $CFG;
|
||||
|
||||
// cannot index empty references
|
||||
if (empty($resource->reference)) return false;
|
||||
if (empty($resource->reference)){
|
||||
mtrace("Cannot index, empty reference.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// cannot index remote resources
|
||||
if (resource_is_url($resource->reference)){
|
||||
@@ -166,6 +177,7 @@ function resource_get_physical_file(&$resource, $context_id, $getsingle, &$docum
|
||||
$fileparts = pathinfo($resource->reference);
|
||||
// cannot index unknown or masked types
|
||||
if (empty($fileparts['extension'])) {
|
||||
mtrace("Cannot index without explicit extension.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -189,15 +201,15 @@ function resource_get_physical_file(&$resource, $context_id, $getsingle, &$docum
|
||||
$resource->alltext = $function_name($resource);
|
||||
if (!empty($resource->alltext)){
|
||||
if ($getsingle){
|
||||
return new ResourceSearchDocument(get_object_vars($resource), $context_id);
|
||||
}
|
||||
else{
|
||||
$single = new ResourceSearchDocument(get_object_vars($resource), $context_id);
|
||||
mtrace("finished file $resource->name as {$resource->reference}");
|
||||
return $single;
|
||||
} else {
|
||||
$documents[] = new ResourceSearchDocument(get_object_vars($resource), $context_id);
|
||||
}
|
||||
mtrace("finished file $resource->name as {$resource->reference}");
|
||||
}
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
mtrace("fulltext handler not found for $ext type");
|
||||
}
|
||||
return false;
|
||||
@@ -250,8 +262,7 @@ function resource_single_document($id, $itemtype) {
|
||||
$document = resource_get_physical_file($resource, true, $context->id);
|
||||
if (!$document) mtrace("Warning : this document {$resource->name} will not be indexed");
|
||||
return $document;
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
return new ResourceSearchDocument(get_object_vars($resource), $context->id);
|
||||
}
|
||||
}
|
||||
@@ -305,5 +316,13 @@ function resource_check_text_access($path, $itemtype, $this_id, $user, $group_id
|
||||
}
|
||||
|
||||
return true;
|
||||
} //resource_check_text_access
|
||||
}
|
||||
|
||||
/**
|
||||
* post processes the url for cleaner output.
|
||||
* @param string $title
|
||||
*/
|
||||
function resource_link_post_processing($title){
|
||||
return mb_convert_encoding($title, 'auto', 'UTF-8');
|
||||
}
|
||||
?>
|
||||
@@ -1,13 +1,20 @@
|
||||
<?php
|
||||
/**
|
||||
* Global Search Engine for Moodle
|
||||
* add-on 1.8+ : Valery Fremaux [[email protected]]
|
||||
* 2007/08/02
|
||||
*
|
||||
* @package search
|
||||
* @category core
|
||||
* @subpackage document_wrappers
|
||||
* @author Michael Campanis, Valery Fremaux [[email protected]] > 1.8
|
||||
* @date 2008/03/31
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
*
|
||||
* document handling for techproject activity module
|
||||
*/
|
||||
/* see wiki_document.php for descriptions */
|
||||
|
||||
/**
|
||||
* requires and includes
|
||||
*/
|
||||
require_once("$CFG->dirroot/search/documents/document.php");
|
||||
require_once("$CFG->dirroot/mod/techproject/lib.php");
|
||||
|
||||
@@ -84,6 +91,7 @@ function techproject_get_content_for_index(&$techproject) {
|
||||
foreach($entries as $anEntry) {
|
||||
if ($anEntry) {
|
||||
if (strlen($anEntry->description) > 0) {
|
||||
$anEntry->author = '';
|
||||
$documents[] = new TechprojectEntrySearchDocument(get_object_vars($anEntry), $techproject->course, $context->id);
|
||||
}
|
||||
}
|
||||
@@ -113,18 +121,22 @@ function techproject_single_document($id, $itemtype) {
|
||||
switch ($itemtype){
|
||||
case 'requirement':{
|
||||
$entry = get_record('techproject_requirement', 'id', $id);
|
||||
$entry->author = '';
|
||||
break;
|
||||
}
|
||||
case 'specification':{
|
||||
$entry = get_record('techproject_specification', 'id', $id);
|
||||
$entry->author = '';
|
||||
break;
|
||||
}
|
||||
case 'milestone':{
|
||||
$entry = get_record('techproject_milestone', 'id', $id);
|
||||
$entry->author = '';
|
||||
break;
|
||||
}
|
||||
case 'deliverable':{
|
||||
$entry = get_record('techproject_deliverable', 'id', $id);
|
||||
$entry->author = '';
|
||||
break;
|
||||
}
|
||||
case 'task':{
|
||||
@@ -136,7 +148,7 @@ function techproject_single_document($id, $itemtype) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
$techprojet_course = get_field('techproject', 'course', 'id', $entry->projectid);
|
||||
$techproject_course = get_field('techproject', 'course', 'id', $entry->projectid);
|
||||
$coursemodule = get_field('modules', 'id', 'name', 'techproject');
|
||||
$cm = get_record('course_modules', 'course', $techproject_course, 'module', $coursemodule, 'instance', $entry->projectid);
|
||||
$context = get_context_instance(CONTEXT_MODULE, $cm->id);
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
<?php
|
||||
/**
|
||||
* Global Search Engine for Moodle
|
||||
* Michael Champanis (mchampan) [[email protected]]
|
||||
* review 1.8+ : Valery Fremaux [[email protected]]
|
||||
* 2007/08/02
|
||||
*
|
||||
* @package search
|
||||
* @category core
|
||||
* @subpackage document_wrappers
|
||||
* @author Michael Campanis (mchampan) [[email protected]], Valery Fremaux [[email protected]] > 1.8
|
||||
* @date 2008/03/31
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
*
|
||||
* document handling for wiki activity module
|
||||
* This file contains the mapping between a wiki page and it's indexable counterpart,
|
||||
@@ -11,22 +15,21 @@
|
||||
*
|
||||
* Functions for iterating and retrieving the necessary records are now also included
|
||||
* in this file, rather than mod/wiki/lib.php
|
||||
*
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
* @package search
|
||||
* @version 2007110400
|
||||
**/
|
||||
*/
|
||||
|
||||
/**
|
||||
* includes and requires
|
||||
*/
|
||||
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, $course_id, $group_id, $user_id, $context_id) {
|
||||
// generic information; required
|
||||
@@ -36,7 +39,7 @@ class WikiSearchDocument extends SearchDocument {
|
||||
$doc->contextid = $context_id;
|
||||
|
||||
$doc->title = $page['pagename'];
|
||||
$doc->date = $page['timemodified'];
|
||||
$doc->date = $page['lastmodified'];
|
||||
//remove '(ip.ip.ip.ip)' from wiki author field
|
||||
$doc->author = preg_replace('/\(.*?\)/', '', $page['author']);
|
||||
$doc->contents = $page['content'];
|
||||
@@ -48,8 +51,8 @@ class WikiSearchDocument extends SearchDocument {
|
||||
|
||||
// construct the parent class
|
||||
parent::__construct($doc, $data, $course_id, $group_id, $user_id, PATH_FOR_SEARCH_TYPE_WIKI);
|
||||
} //constructor
|
||||
} //WikiSearchDocument
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* converts a page name to cope Wiki constraints. Transforms spaces in plus.
|
||||
@@ -58,13 +61,14 @@ class WikiSearchDocument extends SearchDocument {
|
||||
*/
|
||||
function wiki_name_convert($str) {
|
||||
return str_replace(' ', '+', $str);
|
||||
} //wiki_name_convert
|
||||
}
|
||||
|
||||
/**
|
||||
* constructs a valid link to a wiki content
|
||||
* @param wikiId
|
||||
* @param title
|
||||
* @param version
|
||||
* @param int $wikiId
|
||||
* @param string $title
|
||||
* @param int $version
|
||||
* @uses CFG
|
||||
*/
|
||||
function wiki_make_link($wikiId, $title, $version) {
|
||||
global $CFG;
|
||||
@@ -75,9 +79,9 @@ function wiki_make_link($wikiId, $title, $version) {
|
||||
/**
|
||||
* rescued and converted from ewikimoodlelib.php
|
||||
* retrieves latest version of a page
|
||||
* @param entry the wiki object as a reference
|
||||
* @param pagename the name of the page known by the wiki engine
|
||||
* @param version
|
||||
* @param object $entry the wiki object as a reference
|
||||
* @param string $pagename the name of the page known by the wiki engine
|
||||
* @param int $version
|
||||
*/
|
||||
function wiki_get_latest_page(&$entry, $pagename, $version = 0) {
|
||||
$pagename = "'".addslashes($pagename)."'";
|
||||
@@ -104,20 +108,20 @@ function wiki_get_latest_page(&$entry, $pagename, $version = 0) {
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} //wiki_get_latest_page
|
||||
}
|
||||
|
||||
/**
|
||||
* fetches all pages, including old versions
|
||||
* @param entry the wiki object as a reference
|
||||
* @param object $entry the wiki object as a reference
|
||||
* @return an array of record objects that represents pages of this wiki object
|
||||
*/
|
||||
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
|
||||
*
|
||||
* @param object $entry
|
||||
*/
|
||||
function wiki_get_latest_pages(&$entry) {
|
||||
//== (My)SQL for this
|
||||
@@ -134,14 +138,14 @@ function wiki_get_latest_pages(&$entry) {
|
||||
if ($ids = get_records('wiki_pages', 'wiki', $entry->id, '', 'distinct pagename')) {
|
||||
if ($pagesets = get_records('wiki_pages', 'wiki', $entry->id, '', 'distinct pagename')) {
|
||||
foreach ($pagesets as $aPageset) {
|
||||
$pages[] = wiki_get_latest_page($entry, $aPageset->id);
|
||||
$pages[] = wiki_get_latest_page($entry, $aPageset->pagename);
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return $pages;
|
||||
} //wiki_get_latest_pages
|
||||
}
|
||||
|
||||
/**
|
||||
* part of search engine API
|
||||
@@ -150,7 +154,7 @@ function wiki_get_latest_pages(&$entry) {
|
||||
function wiki_iterator() {
|
||||
$wikis = get_records('wiki');
|
||||
return $wikis;
|
||||
} //wiki_iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* part of search engine API
|
||||
@@ -182,13 +186,13 @@ function wiki_get_content_for_index(&$wiki) {
|
||||
}
|
||||
}
|
||||
return $documents;
|
||||
} //wiki_get_content_for_index
|
||||
}
|
||||
|
||||
/**
|
||||
* returns a single wiki search document based on a wiki_entry id
|
||||
* @param id the id of the wiki
|
||||
* @param itemtype the type of information (standard)
|
||||
* @retuen a searchable document
|
||||
* @return a searchable document
|
||||
*/
|
||||
function wiki_single_document($id, $itemtype) {
|
||||
$page = get_record('wiki_pages', 'id', $id);
|
||||
@@ -197,7 +201,7 @@ function wiki_single_document($id, $itemtype) {
|
||||
$cm = get_record('course_modules', 'course', $entry->course, 'module', $coursemodule, 'instance', $entry->wikiid);
|
||||
$context = get_context_instance(CONTEXT_MODULE, $cm->id);
|
||||
return new WikiSearchDocument(get_object_vars($page), $entry->wikiid, $entry->course, $entry->groupid, $page->userid, $context->id);
|
||||
} //wiki_single_document
|
||||
}
|
||||
|
||||
/**
|
||||
* dummy delete function that packs id with itemtype.
|
||||
@@ -208,13 +212,13 @@ function wiki_delete($info, $itemtype) {
|
||||
$object->id = $info;
|
||||
$object->itemtype = $itemtype;
|
||||
return $object;
|
||||
} //wiki_delete
|
||||
}
|
||||
|
||||
//returns the var names needed to build a sql query for addition/deletions
|
||||
function wiki_db_names() {
|
||||
//[primary id], [table name], [time created field name], [time modified field name]
|
||||
return array(array('id', 'wiki_pages', 'created', 'lastmodified', 'standard'));
|
||||
} //wiki_db_names
|
||||
}
|
||||
|
||||
/**
|
||||
* this function handles the access policy to contents indexed as searchable documents. If this
|
||||
@@ -229,6 +233,7 @@ function wiki_db_names() {
|
||||
* points out the indexed wiki page.
|
||||
* @param user the user record denoting the user who searches
|
||||
* @param group_id the current group used by the user when searching
|
||||
* @uses CFG
|
||||
* @return true if access is allowed, false elsewhere
|
||||
*/
|
||||
function wiki_check_text_access($path, $itemtype, $this_id, $user, $group_id, $context_id){
|
||||
@@ -256,5 +261,5 @@ function wiki_check_text_access($path, $itemtype, $this_id, $user, $group_id, $c
|
||||
}
|
||||
|
||||
return true;
|
||||
} //wiki_check_text_access
|
||||
}
|
||||
?>
|
||||
+11
-2
@@ -1,9 +1,18 @@
|
||||
<?php
|
||||
/*
|
||||
/**
|
||||
* Global Search Engine for Moodle
|
||||
*
|
||||
* @package search
|
||||
* @category core
|
||||
* @subpackage search_engine
|
||||
* @author Michael Champanis (mchampan) [[email protected]], Valery Fremaux [[email protected]] > 1.8
|
||||
* @date 2008/03/31
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
*
|
||||
* Entry page for /search
|
||||
* Redirects to query.php, because that is the most likely place a
|
||||
* user intended to go to when typing moodle.site/search
|
||||
**/
|
||||
*/
|
||||
|
||||
header("Location: query.php");
|
||||
?>
|
||||
+176
-155
@@ -1,9 +1,13 @@
|
||||
<?php
|
||||
/**
|
||||
* Global Search Engine for Moodle
|
||||
* Michael Champanis (mchampan) [[email protected]]
|
||||
* review 1.8+ : Valery Fremaux [[email protected]]
|
||||
* 2007/08/02
|
||||
*
|
||||
* @package search
|
||||
* @category core
|
||||
* @subpackage search_engine
|
||||
* @author Michael Champanis (mchampan) [[email protected]], Valery Fremaux [[email protected]] > 1.8
|
||||
* @date 2008/03/31
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
*
|
||||
* The indexer logic -
|
||||
*
|
||||
@@ -26,178 +30,195 @@
|
||||
@ob_implicit_flush(true);
|
||||
@ob_end_flush();
|
||||
|
||||
/**
|
||||
* includes and requires
|
||||
*/
|
||||
require_once('../config.php');
|
||||
require_once("$CFG->dirroot/search/lib.php");
|
||||
|
||||
//only administrators can index the moodle installation, because access to all pages is required
|
||||
require_login();
|
||||
/// only administrators can index the moodle installation, because access to all pages is required
|
||||
|
||||
if (empty($CFG->enableglobalsearch)) {
|
||||
error(get_string('globalsearchdisabled', 'search'));
|
||||
}
|
||||
require_login();
|
||||
|
||||
if (empty($CFG->enableglobalsearch)) {
|
||||
error(get_string('globalsearchdisabled', 'search'));
|
||||
}
|
||||
|
||||
if (!isadmin()) {
|
||||
error(get_string('beadmin', 'search'), "$CFG->wwwroot/login/index.php");
|
||||
}
|
||||
|
||||
/// confirmation flag to prevent accidental reindexing (indexersplash.php is the correct entry point)
|
||||
|
||||
if (!isadmin()) {
|
||||
error(get_string('beadmin', 'search'), "$CFG->wwwroot/login/index.php");
|
||||
} //if
|
||||
$sure = strtolower(optional_param('areyousure', '', PARAM_ALPHA));
|
||||
|
||||
if ($sure != 'yes') {
|
||||
mtrace("<pre>Sorry, you need to confirm indexing via <a href='indexersplash.php'>indexersplash.php</a>"
|
||||
.". (<a href='index.php'>Back to query page</a>).</pre>");
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/// check for php5 (lib.php)
|
||||
|
||||
//confirmation flag to prevent accidental reindexing (indexersplash.php is the correct entry point)
|
||||
$sure = strtolower(optional_param('areyousure', '', PARAM_ALPHA));
|
||||
if (!search_check_php5()) {
|
||||
$phpversion = phpversion();
|
||||
mtrace("Sorry, global search requires PHP 5.0.0 or later (currently using version ".phpversion().")");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
//php5 found, continue including php5-only files
|
||||
//require_once("$CFG->dirroot/search/Zend/Search/Lucene.php");
|
||||
require_once("$CFG->dirroot/search/indexlib.php");
|
||||
|
||||
mtrace('<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8" /></head><body>');
|
||||
mtrace('<pre>Server Time: '.date('r',time())."\n");
|
||||
|
||||
if (isset($CFG->search_indexer_busy) && $CFG->search_indexer_busy == '1') {
|
||||
//means indexing was not finished previously
|
||||
mtrace("Warning: Indexing was not successfully completed last time, restarting.\n");
|
||||
}
|
||||
|
||||
/// turn on busy flag
|
||||
|
||||
if ($sure != 'yes') {
|
||||
mtrace("<pre>Sorry, you need to confirm indexing via <a href='indexersplash.php'>indexersplash.php</a>"
|
||||
.". (<a href='index.php'>Back to query page</a>).</pre>");
|
||||
set_config('search_indexer_busy', '1');
|
||||
|
||||
//paths
|
||||
$index_path = SEARCH_INDEX_PATH;
|
||||
$index_db_file = "{$CFG->dirroot}/search/db/$CFG->dbtype.sql";
|
||||
$dbcontrol = new IndexDBControl();
|
||||
|
||||
/// setup directory in data root
|
||||
|
||||
exit(0);
|
||||
} //if
|
||||
|
||||
//check for php5 (lib.php)
|
||||
if (!search_check_php5()) {
|
||||
$phpversion = phpversion();
|
||||
mtrace("Sorry, global search requires PHP 5.0.0 or later (currently using version $phpversion)");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
//php5 found, continue including php5-only files
|
||||
//require_once("$CFG->dirroot/search/Zend/Search/Lucene.php");
|
||||
require_once("$CFG->dirroot/search/indexlib.php");
|
||||
|
||||
mtrace('<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8" /></head><body>');
|
||||
mtrace('<pre>Server Time: '.date('r',time())."\n");
|
||||
|
||||
if ($CFG->search_indexer_busy == '1') {
|
||||
//means indexing was not finished previously
|
||||
mtrace("Warning: Indexing was not successfully completed last time, restarting.\n");
|
||||
}
|
||||
|
||||
//turn on busy flag
|
||||
set_config('search_indexer_busy', '1');
|
||||
|
||||
//paths
|
||||
$index_path = SEARCH_INDEX_PATH;
|
||||
$index_db_file = "{$CFG->dirroot}/search/db/$CFG->dbtype.sql";
|
||||
$dbcontrol = new IndexDBControl();
|
||||
|
||||
//setup directory in data root
|
||||
if (!file_exists($index_path)) {
|
||||
mtrace("Data directory ($index_path) does not exist, attempting to create.");
|
||||
if (!mkdir($index_path)) {
|
||||
search_pexit("Error creating data directory at: $index_path. Please correct.");
|
||||
if (!file_exists($index_path)) {
|
||||
mtrace("Data directory ($index_path) does not exist, attempting to create.");
|
||||
if (!mkdir($index_path)) {
|
||||
search_pexit("Error creating data directory at: $index_path. Please correct.");
|
||||
}
|
||||
else {
|
||||
mtrace("Directory successfully created.");
|
||||
}
|
||||
}
|
||||
else {
|
||||
mtrace("Directory successfully created.");
|
||||
mtrace("Using $index_path as data directory.");
|
||||
}
|
||||
}
|
||||
else {
|
||||
mtrace("Using $index_path as data directory.");
|
||||
}
|
||||
|
||||
$index = new Zend_Search_Lucene($index_path, true);
|
||||
|
||||
/*
|
||||
OBSOLETE REGENERATION - DB installs with search block by now
|
||||
if (!$dbcontrol->checkDB()) {
|
||||
search_pexit("Database error. Please check settings/files.");
|
||||
}
|
||||
*/
|
||||
// New regeneration
|
||||
mtrace('Deleting old index entries.');
|
||||
delete_records(SEARCH_DATABASE_TABLE);
|
||||
|
||||
//begin timer
|
||||
search_stopwatch();
|
||||
mtrace("Starting 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.
|
||||
$searchables = array();
|
||||
|
||||
// collects modules
|
||||
if ($mods = get_records('modules', '', '', '', 'id,name')) {
|
||||
$searchables = array_merge($searchables, $mods);
|
||||
}
|
||||
mtrace(count($searchables).' modules found.');
|
||||
|
||||
// collects blocks as indexable information may be found in blocks either
|
||||
if ($blocks = get_records('block', '', '', '', 'id,name')) {
|
||||
// prepend the "block_" prefix to discriminate document type plugins
|
||||
foreach(array_keys($blocks) as $aBlockId){
|
||||
$blocks[$aBlockId]->name = 'block_'.$blocks[$aBlockId]->name;
|
||||
|
||||
$index = new Zend_Search_Lucene($index_path, true);
|
||||
|
||||
/*
|
||||
OBSOLETE REGENERATION - DB installs with search block by now
|
||||
if (!$dbcontrol->checkDB()) {
|
||||
search_pexit("Database error. Please check settings/files.");
|
||||
}
|
||||
$searchables = array_merge($searchables, $blocks);
|
||||
mtrace(count($blocks).' blocks found.');
|
||||
}
|
||||
|
||||
//add virtual modules onto the back of the array
|
||||
$searchables = array_merge($searchables, search_get_additional_modules());
|
||||
if ($searchables){
|
||||
foreach ($searchables as $mod) {
|
||||
$class_file = $CFG->dirroot.'/search/documents/'.$mod->name.'_document.php';
|
||||
|
||||
if (file_exists($class_file)) {
|
||||
include_once($class_file);
|
||||
*/
|
||||
|
||||
//build function names
|
||||
$iter_function = $mod->name.'_iterator';
|
||||
$index_function = $mod->name.'_get_content_for_index';
|
||||
$counter = 0;
|
||||
if (function_exists($index_function) && function_exists($iter_function)) {
|
||||
mtrace("Processing module function $index_function ...");
|
||||
$sources = $iter_function();
|
||||
if ($sources){
|
||||
foreach ($sources as $i) {
|
||||
$documents = $index_function($i);
|
||||
|
||||
//begin transaction
|
||||
if ($documents){
|
||||
foreach($documents as $document) {
|
||||
$counter++;
|
||||
|
||||
//object to insert into db
|
||||
$dbid = $dbcontrol->addDocument($document);
|
||||
|
||||
//synchronise db with index
|
||||
$document->addField(Zend_Search_Lucene_Field::Keyword('dbid', $dbid));
|
||||
|
||||
//add document to index
|
||||
$index->addDocument($document);
|
||||
|
||||
//commit every x new documents, and print a status message
|
||||
if (($counter % 2000) == 0) {
|
||||
$index->commit();
|
||||
mtrace(".. $counter");
|
||||
}
|
||||
}
|
||||
}
|
||||
//end transaction
|
||||
}
|
||||
}
|
||||
|
||||
//commit left over documents, and finish up
|
||||
$index->commit();
|
||||
/// New regeneration
|
||||
|
||||
mtrace('Deleting old index entries.');
|
||||
delete_records(SEARCH_DATABASE_TABLE);
|
||||
|
||||
/// begin timer
|
||||
|
||||
search_stopwatch();
|
||||
mtrace("Starting 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.
|
||||
$searchables = array();
|
||||
|
||||
/// collects modules
|
||||
|
||||
if ($mods = get_records('modules', '', '', '', 'id,name')) {
|
||||
$searchables = array_merge($searchables, $mods);
|
||||
}
|
||||
mtrace(count($searchables).' modules found.');
|
||||
|
||||
mtrace("-- $counter documents indexed");
|
||||
mtrace("done.\n");
|
||||
// collects blocks as indexable information may be found in blocks either
|
||||
if ($blocks = get_records('block', '', '', '', 'id,name')) {
|
||||
// prepend the "block_" prefix to discriminate document type plugins
|
||||
foreach(array_keys($blocks) as $aBlockId){
|
||||
$blocks[$aBlockId]->name = 'block_'.$blocks[$aBlockId]->name;
|
||||
}
|
||||
$searchables = array_merge($searchables, $blocks);
|
||||
mtrace(count($blocks).' blocks found.');
|
||||
}
|
||||
|
||||
/// add virtual modules onto the back of the array
|
||||
|
||||
$searchables = array_merge($searchables, search_get_additional_modules());
|
||||
if ($searchables){
|
||||
foreach ($searchables as $mod) {
|
||||
$class_file = $CFG->dirroot.'/search/documents/'.$mod->name.'_document.php';
|
||||
|
||||
if (file_exists($class_file)) {
|
||||
include_once($class_file);
|
||||
|
||||
//build function names
|
||||
$iter_function = $mod->name.'_iterator';
|
||||
$index_function = $mod->name.'_get_content_for_index';
|
||||
$counter = 0;
|
||||
if (function_exists($index_function) && function_exists($iter_function)) {
|
||||
mtrace("Processing module function $index_function ...");
|
||||
$sources = $iter_function();
|
||||
if ($sources){
|
||||
foreach ($sources as $i) {
|
||||
$documents = $index_function($i);
|
||||
|
||||
//begin transaction
|
||||
if ($documents){
|
||||
foreach($documents as $document) {
|
||||
$counter++;
|
||||
|
||||
//object to insert into db
|
||||
$dbid = $dbcontrol->addDocument($document);
|
||||
|
||||
//synchronise db with index
|
||||
$document->addField(Zend_Search_Lucene_Field::Keyword('dbid', $dbid));
|
||||
|
||||
//add document to index
|
||||
$index->addDocument($document);
|
||||
|
||||
//commit every x new documents, and print a status message
|
||||
if (($counter % 2000) == 0) {
|
||||
$index->commit();
|
||||
mtrace(".. $counter");
|
||||
}
|
||||
}
|
||||
}
|
||||
//end transaction
|
||||
}
|
||||
}
|
||||
|
||||
//commit left over documents, and finish up
|
||||
$index->commit();
|
||||
|
||||
mtrace("-- $counter documents indexed");
|
||||
mtrace("done.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//finished modules
|
||||
mtrace('Finished activity modules');
|
||||
search_stopwatch();
|
||||
|
||||
/// finished modules
|
||||
|
||||
mtrace('Finished activity modules');
|
||||
search_stopwatch();
|
||||
|
||||
mtrace(".<br/><a href='index.php'>Back to query page</a>.");
|
||||
mtrace('</pre>');
|
||||
|
||||
mtrace(".<br/><a href='index.php'>Back to query page</a>.");
|
||||
mtrace('</pre>');
|
||||
/// finished, turn busy flag off
|
||||
|
||||
//finished, turn busy flag off
|
||||
set_config('search_indexer_busy', '0');
|
||||
set_config('search_indexer_busy', '0');
|
||||
|
||||
/// mark the time we last updated
|
||||
|
||||
//mark the time we last updated
|
||||
set_config('search_indexer_run_date', time());
|
||||
set_config('search_indexer_run_date', time());
|
||||
|
||||
/// and the index size
|
||||
|
||||
//and the index size
|
||||
set_config('search_index_size', (int)$index->count());
|
||||
set_config('search_index_size', (int)$index->count());
|
||||
|
||||
?>
|
||||
+67
-42
@@ -1,55 +1,80 @@
|
||||
<?php
|
||||
/**
|
||||
* Global Search Engine for Moodle
|
||||
* Michael Champanis (mchampan) [[email protected]]
|
||||
* review 1.8+ : Valery Fremaux [[email protected]]
|
||||
* 2007/08/02
|
||||
*
|
||||
* @package search
|
||||
* @category core
|
||||
* @subpackage search_engine
|
||||
* @author Michael Champanis (mchampan) [[email protected]], Valery Fremaux [[email protected]] > 1.8
|
||||
* @date 2008/03/31
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
*
|
||||
* This file serves as a splash-screen (entry page) to the indexer script -
|
||||
* it is in place to prevent accidental reindexing which can lead to a loss
|
||||
* of time, amongst other things.
|
||||
**/
|
||||
*/
|
||||
|
||||
/**
|
||||
* includes and requires
|
||||
*/
|
||||
require_once('../config.php');
|
||||
require_once("$CFG->dirroot/search/lib.php");
|
||||
|
||||
require_login();
|
||||
/// check global search is enabled
|
||||
|
||||
if (empty($CFG->enableglobalsearch)) {
|
||||
error(get_string('globalsearchdisabled', 'search'));
|
||||
}
|
||||
require_login();
|
||||
|
||||
if (empty($CFG->enableglobalsearch)) {
|
||||
error(get_string('globalsearchdisabled', 'search'));
|
||||
}
|
||||
|
||||
if (!isadmin()) {
|
||||
error(get_string('beadmin', 'search'), "$CFG->wwwroot/login/index.php");
|
||||
}
|
||||
|
||||
/// check for php5 (lib.php)
|
||||
|
||||
if (!isadmin()) {
|
||||
error(get_string('beadmin', 'search'), "$CFG->wwwroot/login/index.php");
|
||||
}
|
||||
|
||||
//check for php5 (lib.php)
|
||||
if (!search_check_php5()) {
|
||||
$phpversion = phpversion();
|
||||
mtrace("Sorry, global search requires PHP 5.0.0 or later (currently using version $phpversion)");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
require_once("$CFG->dirroot/search/indexlib.php");
|
||||
$indexinfo = new IndexInfo();
|
||||
|
||||
if ($indexinfo->valid()) {
|
||||
mtrace("<pre>The data directory ($indexinfo->path) contains $indexinfo->filecount files, and\n"
|
||||
."there are ".$indexinfo->dbcount." records in the <em>block_search_documents</em> table.\n"
|
||||
."\n"
|
||||
."This indicates that you have already succesfully indexed this site. Follow the link\n"
|
||||
."if you are sure that you want to continue indexing - this will replace any existing\n"
|
||||
."index data (no Moodle data is affected).\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 {
|
||||
header('Location: indexer.php?areyousure=yes');
|
||||
}
|
||||
?>
|
||||
if (!search_check_php5()) {
|
||||
$phpversion = phpversion();
|
||||
mtrace("Sorry, global search requires PHP 5.0.0 or later (currently using version ".phpversion().")");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
require_once("$CFG->dirroot/search/indexlib.php");
|
||||
$indexinfo = new IndexInfo();
|
||||
|
||||
if ($indexinfo->valid()) {
|
||||
$strsearch = get_string('search', 'search');
|
||||
$strquery = get_string('stats');
|
||||
|
||||
$navlinks[] = array('name' => $strsearch, 'link' => "index.php", 'type' => 'misc');
|
||||
$navlinks[] = array('name' => $strquery, 'link' => "stats.php", 'type' => 'misc');
|
||||
$navlinks[] = array('name' => get_string('runindexer','search'), 'link' => null, 'type' => 'misc');
|
||||
if ($CFG->version <= 2007021541){ // 1.8 branch stable timestamp
|
||||
$navigation = '';
|
||||
} else {
|
||||
$navigation = build_navigation($navlinks);
|
||||
}
|
||||
$site = get_site();
|
||||
print_header("$strsearch", "$site->fullname" , $navigation, "", "", true, " ", navmenu($site));
|
||||
|
||||
mtrace("<pre>The data directory ($indexinfo->path) contains $indexinfo->filecount files, and\n"
|
||||
."there are ".$indexinfo->dbcount." records in the <em>block_search_documents</em> table.\n"
|
||||
."\n"
|
||||
."This indicates that you have already succesfully indexed this site. Follow the link\n"
|
||||
."if you are sure that you want to continue indexing - this will replace any existing\n"
|
||||
."index data (no Moodle data is affected).\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>");
|
||||
print_footer();
|
||||
}
|
||||
else {
|
||||
header('Location: indexer.php?areyousure=yes');
|
||||
}
|
||||
?>
|
||||
+43
-32
@@ -1,20 +1,32 @@
|
||||
<?php
|
||||
/*
|
||||
* Author: Michael Champanis
|
||||
/**
|
||||
* Global Search Engine for Moodle
|
||||
*
|
||||
* Reviewed by: Valery Fremaux (2007)
|
||||
* @package search
|
||||
* @category core
|
||||
* @subpackage search_engine
|
||||
* @author Michael Champanis (mchampan) [[email protected]], Valery Fremaux [[email protected]] > 1.8
|
||||
* @date 2008/03/31
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
*
|
||||
* Index info class
|
||||
*
|
||||
* Used to retrieve information about an index.
|
||||
* Has methods to check for valid database and data directory,
|
||||
* and the index itself.
|
||||
**/
|
||||
*/
|
||||
|
||||
/**
|
||||
* includes and requires
|
||||
*/
|
||||
require_once("$CFG->dirroot/search/lib.php");
|
||||
require_once("$CFG->dirroot/search/Zend/Search/Lucene.php");
|
||||
|
||||
/**
|
||||
* main class for searchable information in the Lucene index
|
||||
*/
|
||||
class IndexInfo {
|
||||
|
||||
private $path, //index data directory
|
||||
$size, //size of directory (i.e. the whole index)
|
||||
$filecount, //number of files
|
||||
@@ -35,7 +47,7 @@ class IndexInfo {
|
||||
$validindex = true;
|
||||
} catch(Exception $e) {
|
||||
$validindex = false;
|
||||
} //catch
|
||||
}
|
||||
|
||||
//retrieve file system info about the index if it is valid
|
||||
if ($validindex) {
|
||||
@@ -73,32 +85,29 @@ class IndexInfo {
|
||||
$c = count_records(SEARCH_DATABASE_TABLE, 'doctype', $type);
|
||||
$this->types[$type] = (int)$c;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$this->dbcount = 0;
|
||||
$this->types = array();
|
||||
}
|
||||
|
||||
//check if the busy flag is set
|
||||
if ($CFG->search_indexer_busy == '1') {
|
||||
if (isset($CFG->search_indexer_busy) && $CFG->search_indexer_busy == '1') {
|
||||
$this->complete = false;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$this->complete = true;
|
||||
}
|
||||
|
||||
//get the last run date for the indexer
|
||||
if ($this->valid() && $CFG->search_indexer_run_date) {
|
||||
$this->time = $CFG->search_indexer_run_date;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$this->time = 0;
|
||||
}
|
||||
} //__construct
|
||||
}
|
||||
|
||||
/**
|
||||
* returns false on error, and the error message via referenced variable $err
|
||||
*
|
||||
* @param array $err array of errors
|
||||
*/
|
||||
public function valid(&$err = null) {
|
||||
$err = array();
|
||||
@@ -120,7 +129,7 @@ class IndexInfo {
|
||||
}
|
||||
|
||||
return $ret;
|
||||
} //valid
|
||||
}
|
||||
|
||||
/**
|
||||
* is the index dir valid
|
||||
@@ -129,11 +138,10 @@ class IndexInfo {
|
||||
public function is_valid_dir() {
|
||||
if ($this->filecount > 0) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} //is_valid_dir
|
||||
}
|
||||
|
||||
/**
|
||||
* is the db table valid
|
||||
@@ -142,34 +150,34 @@ class IndexInfo {
|
||||
public function is_valid_db() {
|
||||
if ($this->dbcount > 0) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} //is_valid_db
|
||||
}
|
||||
|
||||
/**
|
||||
* shorthand get method for the class variables
|
||||
*
|
||||
* @param object $var
|
||||
*/
|
||||
public function __get($var) {
|
||||
if (in_array($var, array_keys(get_class_vars(get_class($this))))) {
|
||||
return $this->$var;
|
||||
}
|
||||
} //__get
|
||||
} //IndexInfo
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* DB Index control class
|
||||
*
|
||||
* Used to control the search index database table
|
||||
**/
|
||||
*/
|
||||
class IndexDBControl {
|
||||
|
||||
/**
|
||||
* does the table exist?
|
||||
* OBSOLETE
|
||||
* @deprecated
|
||||
* @uses CFG, db
|
||||
*/
|
||||
public function checkTableExists() {
|
||||
global $CFG, $db;
|
||||
@@ -186,7 +194,8 @@ class IndexDBControl {
|
||||
|
||||
/**
|
||||
* is our database setup valid?
|
||||
* OBSOLETE - Database is installed at install and should not be dropped out
|
||||
* @uses db, CFG
|
||||
* @deprecated Database is installed at install and should not be dropped out
|
||||
*/
|
||||
public function checkDB() {
|
||||
global $CFG, $db;
|
||||
@@ -209,6 +218,7 @@ class IndexDBControl {
|
||||
/**
|
||||
* add a document record to the table
|
||||
* @param document must be a Lucene SearchDocument instance
|
||||
* @uses db, CFG
|
||||
*/
|
||||
public function addDocument($document=null) {
|
||||
global $db, $CFG;
|
||||
@@ -223,7 +233,7 @@ class IndexDBControl {
|
||||
$doc->itemtype = $document->itemtype;
|
||||
$doc->title = search_escape_string($document->title);
|
||||
$doc->url = search_escape_string($document->url);
|
||||
$doc->update = time();
|
||||
$doc->updated = time();
|
||||
$doc->docdate = $document->date;
|
||||
$doc->courseid = $document->course_id;
|
||||
$doc->groupid = $document->group_id;
|
||||
@@ -232,17 +242,18 @@ class IndexDBControl {
|
||||
$id = insert_record(SEARCH_DATABASE_TABLE, $doc);
|
||||
|
||||
return $id;
|
||||
} //addDocument
|
||||
}
|
||||
|
||||
/**
|
||||
* remove a document record from the index
|
||||
* @param document must be a Lucene document instance, or at least a dbid enveloppe
|
||||
* @uses db
|
||||
*/
|
||||
public function delDocument($document) {
|
||||
global $db;
|
||||
|
||||
delete_records(SEARCH_DATABASE_TABLE, 'id', $document->dbid);
|
||||
} //delDocument
|
||||
} //IndexControl
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
+12
-6
@@ -1,14 +1,20 @@
|
||||
<?php
|
||||
/*
|
||||
* Author: Michael Champanis
|
||||
/**
|
||||
* Global Search Engine for Moodle
|
||||
*
|
||||
* @package search
|
||||
* @category core
|
||||
* @subpackage search_engine
|
||||
* @author Michael Champanis (mchampan) [[email protected]], Valery Fremaux [[email protected]] > 1.8
|
||||
* @date 2008/03/31
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
*
|
||||
* General function library
|
||||
*
|
||||
* This file must not contain any PHP 5, because it is used to test for PHP 5
|
||||
* itself, and needs to be able to be executed on PHP 4 installations.
|
||||
*
|
||||
* Reviewed by: Valery Fremaux (2007)
|
||||
* - adding techproject search capabilities
|
||||
* - adding full internationalization
|
||||
**/
|
||||
*/
|
||||
|
||||
/*
|
||||
// function reference
|
||||
|
||||
+351
-327
@@ -1,337 +1,361 @@
|
||||
<?php
|
||||
/**
|
||||
* Global Search Engine for Moodle
|
||||
* Michael Champanis (mchampan) [[email protected]]
|
||||
* review 1.8+ : Valery Fremaux [[email protected]]
|
||||
* 2007/08/02
|
||||
*
|
||||
* 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");
|
||||
|
||||
if ($CFG->forcelogin) {
|
||||
require_login();
|
||||
}
|
||||
|
||||
if (empty($CFG->enableglobalsearch)) {
|
||||
error(get_string('globalsearchdisabled', 'search'));
|
||||
}
|
||||
|
||||
$adv = new Object();
|
||||
|
||||
// check for php5, but don't die yet (see line 52)
|
||||
if ($check = search_check_php5()) {
|
||||
require_once("{$CFG->dirroot}/search/querylib.php");
|
||||
|
||||
$page_number = optional_param('page', -1, PARAM_INT);
|
||||
$pages = ($page_number == -1) ? false : true;
|
||||
$advanced = (optional_param('a', '0', PARAM_INT) == '1') ? true : false;
|
||||
$query_string = optional_param('query_string', '', PARAM_CLEAN);
|
||||
|
||||
if ($pages && isset($_SESSION['search_advanced_query'])) {
|
||||
// if both are set, then we are busy browsing through the result pages of an advanced query
|
||||
$adv = unserialize($_SESSION['search_advanced_query']);
|
||||
}
|
||||
else if ($advanced) {
|
||||
// otherwise we are dealing with a new advanced query
|
||||
unset($_SESSION['search_advanced_query']);
|
||||
session_unregister('search_advanced_query');
|
||||
|
||||
// chars to strip from strings (whitespace)
|
||||
$chars = " \t\n\r\0\x0B,-+";
|
||||
|
||||
// retrieve advanced query variables
|
||||
$adv->mustappear = trim(optional_param('mustappear', '', PARAM_CLEAN), $chars);
|
||||
$adv->notappear = trim(optional_param('notappear', '', PARAM_CLEAN), $chars);
|
||||
$adv->canappear = trim(optional_param('canappear', '', PARAM_CLEAN), $chars);
|
||||
$adv->module = optional_param('module', '', PARAM_CLEAN);
|
||||
$adv->title = trim(optional_param('title', '', PARAM_CLEAN), $chars);
|
||||
$adv->author = trim(optional_param('author', '', PARAM_CLEAN), $chars);
|
||||
}
|
||||
|
||||
if ($advanced) {
|
||||
//parse the advanced variables into a query string
|
||||
//TODO: move out to external query class (QueryParse?)
|
||||
|
||||
$query_string = '';
|
||||
|
||||
// get all available module types
|
||||
$module_types = array_merge(array('all'), array_values(search_get_document_types()));
|
||||
$adv->module = in_array($adv->module, $module_types) ? $adv->module : 'all';
|
||||
|
||||
// convert '1 2' into '+1 +2' for required words field
|
||||
if (strlen(trim($adv->mustappear)) > 0) {
|
||||
$query_string = ' +'.implode(' +', preg_split("/[\s,;]+/", $adv->mustappear));
|
||||
}
|
||||
|
||||
// convert '1 2' into '-1 -2' for not wanted words field
|
||||
if (strlen(trim($adv->notappear)) > 0) {
|
||||
$query_string .= ' -'.implode(' -', preg_split("/[\s,;]+/", $adv->notappear));
|
||||
}
|
||||
|
||||
// this field is left untouched, apart from whitespace being stripped
|
||||
if (strlen(trim($adv->canappear)) > 0) {
|
||||
$query_string .= ' '.implode(' ', preg_split("/[\s,;]+/", $adv->canappear));
|
||||
}
|
||||
|
||||
// add module restriction
|
||||
$doctypestr = get_string('doctype', 'search');
|
||||
$titlestr = get_string('title', 'search');
|
||||
$authorstr = get_string('author', 'search');
|
||||
if ($adv->module != 'all') {
|
||||
$query_string .= " +{$doctypestr}:".$adv->module;
|
||||
}
|
||||
|
||||
// create title search string
|
||||
if (strlen(trim($adv->title)) > 0) {
|
||||
$query_string .= " +{$titlestr}:".implode(" +{$titlestr}:", preg_split("/[\s,;]+/", $adv->title));
|
||||
}
|
||||
|
||||
// create author search string
|
||||
if (strlen(trim($adv->author)) > 0) {
|
||||
$query_string .= " +{$authorstr}:".implode(" +{$authorstr}:", preg_split("/[\s,;]+/", $adv->author));
|
||||
}
|
||||
|
||||
// save our options if the query is valid
|
||||
if (!empty($query_string)) {
|
||||
$_SESSION['search_advanced_query'] = serialize($adv);
|
||||
}
|
||||
}
|
||||
|
||||
// normalise page number
|
||||
if ($page_number < 1) {
|
||||
$page_number = 1;
|
||||
}
|
||||
|
||||
//run the query against the index
|
||||
$sq = new SearchQuery($query_string, $page_number, 10, false);
|
||||
}
|
||||
|
||||
if (!$site = get_site()) {
|
||||
redirect("index.php");
|
||||
}
|
||||
|
||||
$strsearch = get_string('search', 'search');
|
||||
$strquery = get_string('enteryoursearchquery', 'search');
|
||||
|
||||
print_header("$site->shortname: $strsearch: $strquery", "$site->fullname",
|
||||
"<a href=\"index.php\">$strsearch</a> -> $strquery");
|
||||
|
||||
//keep things pretty, even if php5 isn't available
|
||||
if (!$check) {
|
||||
print_heading(search_check_php5(true));
|
||||
print_footer();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
print_box_start();
|
||||
print_heading($strquery);
|
||||
|
||||
print_box_start();
|
||||
|
||||
$vars = get_object_vars($adv);
|
||||
|
||||
if (isset($vars)) {
|
||||
foreach ($vars as $key => $value) {
|
||||
$adv->$key = stripslashes(htmlentities($value));
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
<form id="query" method="get" action="query.php">
|
||||
<?php
|
||||
if (!$advanced) {
|
||||
?>
|
||||
<input type="text" name="query_string" length="50" value="<?php print stripslashes($query_string) ?>" />
|
||||
<input type="submit" value="<?php print_string('search', 'search') ?>" />
|
||||
<a href="query.php?a=1"><?php print_string('advancedsearch', 'search') ?></a> |
|
||||
<a href="stats.php"><?php print_string('statistics', 'search') ?></a>
|
||||
<?php
|
||||
}
|
||||
else {
|
||||
print_box_start();
|
||||
?>
|
||||
<input type="hidden" name="a" value="<?php print $advanced; ?>"/>
|
||||
|
||||
<table border="0" cellpadding="3" cellspacing="3">
|
||||
|
||||
<tr>
|
||||
<td width="240"><?php print_string('thesewordsmustappear', 'search') ?>:</td>
|
||||
<td><input type="text" name="mustappear" length="50" value="<?php print $adv->mustappear; ?>" /></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><?php print_string('thesewordsmustnotappear', 'search') ?>:</td>
|
||||
<td><input type="text" name="notappear" length="50" value="<?php print $adv->notappear; ?>" /></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><?php print_string('thesewordshelpimproverank', 'search') ?>:</td>
|
||||
<td><input type="text" name="canappear" length="50" value="<?php print $adv->canappear; ?>" /></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><?php print_string('whichmodulestosearch?', 'search') ?>:</td>
|
||||
<td>
|
||||
<select name="module">
|
||||
<?php
|
||||
foreach($module_types as $mod) {
|
||||
if ($mod == $adv->module) {
|
||||
if ($mod != 'all'){
|
||||
print "<option value='$mod' selected=\"selected\">".get_string('modulenameplural', $mod)."</option>\n";
|
||||
}
|
||||
else{
|
||||
print "<option value='$mod' selected=\"selected\">".get_string('all', 'search')."</option>\n";
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ($mod != 'all'){
|
||||
print "<option value='$mod'>".get_string('modulenameplural', $mod)."</option>\n";
|
||||
}
|
||||
else{
|
||||
print "<option value='$mod'>".get_string('all', 'search')."</option>\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><?php print_string('wordsintitle', 'search') ?>:</td>
|
||||
<td><input type="text" name="title" length="50" value="<?php print $adv->title; ?>" /></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><?php print_string('authorname', 'search') ?>:</td>
|
||||
<td><input type="text" name="author" length="50" value="<?php print $adv->author; ?>" /></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td colspan="3" align="center"><br /><input type="submit" value="<?php print_string('search', 'search') ?>" /></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td colspan="3" align="center">
|
||||
<table border="0" cellpadding="0" cellspacing="0">
|
||||
<tr>
|
||||
<td><a href="query.php"><?php print_string('normalsearch', 'search') ?></a> |</td>
|
||||
<td> <a href="stats.php"><?php print_string('statistics', 'search') ?></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<?php
|
||||
print_box_end();
|
||||
}
|
||||
?>
|
||||
</form>
|
||||
<br/>
|
||||
|
||||
<div align="center">
|
||||
<?php
|
||||
print_string('searching', 'search') . ': ';
|
||||
|
||||
if ($sq->is_valid_index()) {
|
||||
//use cached variable to show up-to-date index size (takes deletions into account)
|
||||
print $CFG->search_index_size;
|
||||
}
|
||||
else {
|
||||
print "0";
|
||||
}
|
||||
|
||||
print ' ';
|
||||
print_string('documents', 'search');
|
||||
print '.';
|
||||
|
||||
if (!$sq->is_valid_index() and isadmin()) {
|
||||
print '<p>' . get_string('noindexmessage', 'search') . '<a href="indexersplash.php">' . get_string('createanindex', 'search')."</a></p>\n";
|
||||
}
|
||||
|
||||
?>
|
||||
</div>
|
||||
<?php
|
||||
print_box_end();
|
||||
|
||||
// prints all the results in a box
|
||||
if ($sq->is_valid()) {
|
||||
print_box_start();
|
||||
/**
|
||||
* Global Search Engine for Moodle
|
||||
*
|
||||
* @package search
|
||||
* @category core
|
||||
* @subpackage search_engine
|
||||
* @author Michael Champanis (mchampan) [[email protected]], Valery Fremaux [[email protected]] > 1.8
|
||||
* @date 2008/03/31
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
search_stopwatch();
|
||||
$hit_count = $sq->count();
|
||||
/**
|
||||
* includes and requires
|
||||
*/
|
||||
require_once('../config.php');
|
||||
require_once("$CFG->dirroot/search/lib.php");
|
||||
|
||||
|
||||
if ($CFG->forcelogin) {
|
||||
require_login();
|
||||
}
|
||||
|
||||
print "<br />";
|
||||
if (empty($CFG->enableglobalsearch)) {
|
||||
error(get_string('globalsearchdisabled', 'search'));
|
||||
}
|
||||
|
||||
print $hit_count.' '.get_string('resultsreturnedfor', 'search') . " '".stripslashes($query_string)."'.";
|
||||
print "<br />";
|
||||
$adv = new Object();
|
||||
|
||||
/// check for php5, but don't die yet (see line 52)
|
||||
|
||||
if ($check = search_check_php5()) {
|
||||
require_once("{$CFG->dirroot}/search/querylib.php");
|
||||
|
||||
$page_number = optional_param('page', -1, PARAM_INT);
|
||||
$pages = ($page_number == -1) ? false : true;
|
||||
$advanced = (optional_param('a', '0', PARAM_INT) == '1') ? true : false;
|
||||
$query_string = optional_param('query_string', '', PARAM_CLEAN);
|
||||
|
||||
if ($pages && isset($_SESSION['search_advanced_query'])) {
|
||||
// if both are set, then we are busy browsing through the result pages of an advanced query
|
||||
$adv = unserialize($_SESSION['search_advanced_query']);
|
||||
}
|
||||
else if ($advanced) {
|
||||
// otherwise we are dealing with a new advanced query
|
||||
unset($_SESSION['search_advanced_query']);
|
||||
session_unregister('search_advanced_query');
|
||||
|
||||
// chars to strip from strings (whitespace)
|
||||
$chars = " \t\n\r\0\x0B,-+";
|
||||
|
||||
// retrieve advanced query variables
|
||||
$adv->mustappear = trim(optional_param('mustappear', '', PARAM_CLEAN), $chars);
|
||||
$adv->notappear = trim(optional_param('notappear', '', PARAM_CLEAN), $chars);
|
||||
$adv->canappear = trim(optional_param('canappear', '', PARAM_CLEAN), $chars);
|
||||
$adv->module = optional_param('module', '', PARAM_CLEAN);
|
||||
$adv->title = trim(optional_param('title', '', PARAM_CLEAN), $chars);
|
||||
$adv->author = trim(optional_param('author', '', PARAM_CLEAN), $chars);
|
||||
}
|
||||
|
||||
if ($hit_count > 0) {
|
||||
$page_links = $sq->page_numbers();
|
||||
$hits = $sq->results();
|
||||
|
||||
if ($advanced) {
|
||||
// if in advanced mode, search options are saved in the session, so
|
||||
// we can remove the query string var from the page links, and replace
|
||||
// it with a=1 (Advanced = on) instead
|
||||
$page_links = preg_replace("/query_string=[^&]+/", 'a=1', $page_links);
|
||||
//parse the advanced variables into a query string
|
||||
//TODO: move out to external query class (QueryParse?)
|
||||
|
||||
$query_string = '';
|
||||
|
||||
// get all available module types
|
||||
$module_types = array_merge(array('all'), array_values(search_get_document_types()));
|
||||
$adv->module = in_array($adv->module, $module_types) ? $adv->module : 'all';
|
||||
|
||||
// convert '1 2' into '+1 +2' for required words field
|
||||
if (strlen(trim($adv->mustappear)) > 0) {
|
||||
$query_string = ' +'.implode(' +', preg_split("/[\s,;]+/", $adv->mustappear));
|
||||
}
|
||||
|
||||
// convert '1 2' into '-1 -2' for not wanted words field
|
||||
if (strlen(trim($adv->notappear)) > 0) {
|
||||
$query_string .= ' -'.implode(' -', preg_split("/[\s,;]+/", $adv->notappear));
|
||||
}
|
||||
|
||||
// this field is left untouched, apart from whitespace being stripped
|
||||
if (strlen(trim($adv->canappear)) > 0) {
|
||||
$query_string .= ' '.implode(' ', preg_split("/[\s,;]+/", $adv->canappear));
|
||||
}
|
||||
|
||||
// add module restriction
|
||||
$doctypestr = get_string('doctype', 'search');
|
||||
$titlestr = get_string('title', 'search');
|
||||
$authorstr = get_string('author', 'search');
|
||||
if ($adv->module != 'all') {
|
||||
$query_string .= " +{$doctypestr}:".$adv->module;
|
||||
}
|
||||
|
||||
// create title search string
|
||||
if (strlen(trim($adv->title)) > 0) {
|
||||
$query_string .= " +{$titlestr}:".implode(" +{$titlestr}:", preg_split("/[\s,;]+/", $adv->title));
|
||||
}
|
||||
|
||||
// create author search string
|
||||
if (strlen(trim($adv->author)) > 0) {
|
||||
$query_string .= " +{$authorstr}:".implode(" +{$authorstr}:", preg_split("/[\s,;]+/", $adv->author));
|
||||
}
|
||||
|
||||
// save our options if the query is valid
|
||||
if (!empty($query_string)) {
|
||||
$_SESSION['search_advanced_query'] = serialize($adv);
|
||||
}
|
||||
}
|
||||
|
||||
print "<ol>";
|
||||
|
||||
$typestr = get_string('type', 'search');
|
||||
$scorestr = get_string('score', 'search');
|
||||
$authorstr = get_string('author', 'search');
|
||||
foreach ($hits as $listing) {
|
||||
if ($CFG->unicodedb) $listing->title = mb_convert_encoding($listing->title, 'auto', 'UTF8');
|
||||
$title_post_processing_function = $listing->doctype.'_link_post_processing';
|
||||
require_once "{$CFG->dirroot}/search/documents/{$listing->doctype}_document.php";
|
||||
if (function_exists($title_post_processing_function))
|
||||
$listing->title = $title_post_processing_function($listing->title);
|
||||
print "<li value='".($listing->number+1)."'><a href='".str_replace('DEFAULT_POPUP_SETTINGS', DEFAULT_POPUP_SETTINGS ,$listing->url)."'>$listing->title</a><br />\n"
|
||||
."<em>".search_shorten_url($listing->url, 70)."</em><br />\n"
|
||||
."{$typestr}: ".$listing->doctype.", {$scorestr}: ".round($listing->score, 3).", {$authorstr}: ".$listing->author."\n"
|
||||
."</li>\n";
|
||||
}
|
||||
|
||||
print "</ol>";
|
||||
print $page_links;
|
||||
|
||||
// normalise page number
|
||||
if ($page_number < 1) {
|
||||
$page_number = 1;
|
||||
}
|
||||
|
||||
//run the query against the index
|
||||
$sq = new SearchQuery($query_string, $page_number, 10, false);
|
||||
}
|
||||
|
||||
|
||||
if (!$site = get_site()) {
|
||||
redirect("index.php");
|
||||
}
|
||||
|
||||
$strsearch = get_string('search', 'search');
|
||||
$strquery = get_string('enteryoursearchquery', 'search');
|
||||
|
||||
if ($CFG->version < 2007032200){
|
||||
print_header("$site->shortname: $strsearch: $strquery", "$site->fullname",
|
||||
"<a href=\"index.php\">$strsearch</a> -> $strquery");
|
||||
} else {
|
||||
$navlinks[] = array('name' => $strsearch, 'link' => "index.php", 'type' => 'misc');
|
||||
$navlinks[] = array('name' => $strquery, 'link' => null, 'type' => 'misc');
|
||||
$navigation = build_navigation($navlinks);
|
||||
$site = get_site();
|
||||
print_header("$strsearch", "$site->fullname" , $navigation, "", "", true, " ", navmenu($site));
|
||||
}
|
||||
|
||||
//keep things pretty, even if php5 isn't available
|
||||
if (!$check) {
|
||||
print_heading(search_check_php5(true));
|
||||
print_footer();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
print_box_start();
|
||||
print_heading($strquery);
|
||||
|
||||
print_box_start();
|
||||
|
||||
$vars = get_object_vars($adv);
|
||||
|
||||
if (isset($vars)) {
|
||||
foreach ($vars as $key => $value) {
|
||||
// htmlentities breaks non-ascii chars
|
||||
$adv->key = stripslashes($value);
|
||||
//$adv->$key = stripslashes(htmlentities($value));
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
<form id="query" method="get" action="query.php">
|
||||
<?php
|
||||
if (!$advanced) {
|
||||
?>
|
||||
<input type="text" name="query_string" length="50" value="<?php print stripslashes($query_string) ?>" />
|
||||
<input type="submit" value="<?php print_string('search', 'search') ?>" />
|
||||
<a href="query.php?a=1"><?php print_string('advancedsearch', 'search') ?></a> |
|
||||
<a href="stats.php"><?php print_string('statistics', 'search') ?></a>
|
||||
<?php
|
||||
}
|
||||
else {
|
||||
print_box_start();
|
||||
?>
|
||||
<input type="hidden" name="a" value="<?php print $advanced; ?>"/>
|
||||
|
||||
<table border="0" cellpadding="3" cellspacing="3">
|
||||
|
||||
<tr>
|
||||
<td width="240"><?php print_string('thesewordsmustappear', 'search') ?>:</td>
|
||||
<td><input type="text" name="mustappear" length="50" value="<?php print $adv->mustappear; ?>" /></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><?php print_string('thesewordsmustnotappear', 'search') ?>:</td>
|
||||
<td><input type="text" name="notappear" length="50" value="<?php print $adv->notappear; ?>" /></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><?php print_string('thesewordshelpimproverank', 'search') ?>:</td>
|
||||
<td><input type="text" name="canappear" length="50" value="<?php print $adv->canappear; ?>" /></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><?php print_string('whichmodulestosearch?', 'search') ?>:</td>
|
||||
<td>
|
||||
<select name="module">
|
||||
<?php
|
||||
foreach($module_types as $mod) {
|
||||
if ($mod == $adv->module) {
|
||||
if ($mod != 'all'){
|
||||
print "<option value='$mod' selected=\"selected\">".get_string('modulenameplural', $mod)."</option>\n";
|
||||
}
|
||||
else{
|
||||
print "<option value='$mod' selected=\"selected\">".get_string('all', 'search')."</option>\n";
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ($mod != 'all'){
|
||||
print "<option value='$mod'>".get_string('modulenameplural', $mod)."</option>\n";
|
||||
}
|
||||
else{
|
||||
print "<option value='$mod'>".get_string('all', 'search')."</option>\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><?php print_string('wordsintitle', 'search') ?>:</td>
|
||||
<td><input type="text" name="title" length="50" value="<?php print $adv->title; ?>" /></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><?php print_string('authorname', 'search') ?>:</td>
|
||||
<td><input type="text" name="author" length="50" value="<?php print $adv->author; ?>" /></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td colspan="3" align="center"><br /><input type="submit" value="<?php print_string('search', 'search') ?>" /></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td colspan="3" align="center">
|
||||
<table border="0" cellpadding="0" cellspacing="0">
|
||||
<tr>
|
||||
<td><a href="query.php"><?php print_string('normalsearch', 'search') ?></a> |</td>
|
||||
<td> <a href="stats.php"><?php print_string('statistics', 'search') ?></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<?php
|
||||
print_box_end();
|
||||
}
|
||||
?>
|
||||
</form>
|
||||
<br/>
|
||||
|
||||
<div align="center">
|
||||
<?php
|
||||
print_string('searching', 'search') . ': ';
|
||||
|
||||
if ($sq->is_valid_index()) {
|
||||
//use cached variable to show up-to-date index size (takes deletions into account)
|
||||
print $CFG->search_index_size;
|
||||
}
|
||||
else {
|
||||
print "0";
|
||||
}
|
||||
|
||||
print ' ';
|
||||
print_string('documents', 'search');
|
||||
print '.';
|
||||
|
||||
if (!$sq->is_valid_index() and isadmin()) {
|
||||
print '<p>' . get_string('noindexmessage', 'search') . '<a href="indexersplash.php">' . get_string('createanindex', 'search')."</a></p>\n";
|
||||
}
|
||||
|
||||
?>
|
||||
</div>
|
||||
<?php
|
||||
print_box_end();
|
||||
?>
|
||||
<div align="center">
|
||||
<?php
|
||||
print_string('ittook', 'search');
|
||||
search_stopwatch();
|
||||
print_string('tofetchtheseresults', 'search');
|
||||
?>.
|
||||
</div>
|
||||
|
||||
<?php
|
||||
}
|
||||
print_box_end();
|
||||
print_footer();
|
||||
|
||||
// prints all the results in a box
|
||||
if ($sq->is_valid()) {
|
||||
print_box_start();
|
||||
|
||||
search_stopwatch();
|
||||
$hit_count = $sq->count();
|
||||
|
||||
print "<br />";
|
||||
|
||||
print $hit_count.' '.get_string('resultsreturnedfor', 'search') . " '".stripslashes($query_string)."'.";
|
||||
print "<br />";
|
||||
|
||||
if ($hit_count > 0) {
|
||||
$page_links = $sq->page_numbers();
|
||||
$hits = $sq->results();
|
||||
|
||||
if ($advanced) {
|
||||
// if in advanced mode, search options are saved in the session, so
|
||||
// we can remove the query string var from the page links, and replace
|
||||
// it with a=1 (Advanced = on) instead
|
||||
$page_links = preg_replace("/query_string=[^&]+/", 'a=1', $page_links);
|
||||
}
|
||||
|
||||
print "<ol>";
|
||||
|
||||
$typestr = get_string('type', 'search');
|
||||
$scorestr = get_string('score', 'search');
|
||||
$authorstr = get_string('author', 'search');
|
||||
foreach ($hits as $listing) {
|
||||
//if ($CFG->unicodedb) {
|
||||
//$listing->title = mb_convert_encoding($listing->title, 'auto', 'UTF8');
|
||||
//}
|
||||
$title_post_processing_function = $listing->doctype.'_link_post_processing';
|
||||
require_once "{$CFG->dirroot}/search/documents/{$listing->doctype}_document.php";
|
||||
if (function_exists($title_post_processing_function)) {
|
||||
$listing->title = $title_post_processing_function($listing->title);
|
||||
}
|
||||
|
||||
print "<li value='".($listing->number+1)."'><a href='".str_replace('DEFAULT_POPUP_SETTINGS', DEFAULT_POPUP_SETTINGS ,$listing->url)."'>$listing->title</a><br />\n"
|
||||
."<em>".search_shorten_url($listing->url, 70)."</em><br />\n"
|
||||
."{$typestr}: ".$listing->doctype.", {$scorestr}: ".round($listing->score, 3);
|
||||
if (!empty($listing->author)){
|
||||
print ", {$authorstr}: ".$listing->author."\n"
|
||||
."</li>\n";
|
||||
}
|
||||
}
|
||||
print "</ol>";
|
||||
print $page_links;
|
||||
}
|
||||
print_box_end();
|
||||
?>
|
||||
<div align="center">
|
||||
<?php
|
||||
print_string('ittook', 'search');
|
||||
search_stopwatch();
|
||||
print_string('tofetchtheseresults', 'search');
|
||||
?>.
|
||||
</div>
|
||||
|
||||
<?php
|
||||
}
|
||||
print_box_end();
|
||||
print_footer();
|
||||
?>
|
||||
+94
-65
@@ -1,4 +1,18 @@
|
||||
<?php
|
||||
/**
|
||||
* Global Search Engine for Moodle
|
||||
*
|
||||
* @package search
|
||||
* @category core
|
||||
* @subpackage search_engine
|
||||
* @author Michael Champanis (mchampan) [[email protected]], Valery Fremaux [[email protected]] > 1.8
|
||||
* @date 2008/03/31
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
*/
|
||||
|
||||
/**
|
||||
* includes and requires
|
||||
*/
|
||||
require_once("{$CFG->dirroot}/search/Zend/Search/Lucene.php");
|
||||
|
||||
define('DEFAULT_POPUP_SETTINGS', "\"menubar=0,location=0,scrollbars,resizable,width=600,height=450\"");
|
||||
@@ -13,10 +27,12 @@ public $url,
|
||||
$author,
|
||||
$score,
|
||||
$number;
|
||||
} //SearchResult
|
||||
}
|
||||
|
||||
|
||||
//split this into Cache class and extend to SearchCache?
|
||||
/**
|
||||
* split this into Cache class and extend to SearchCache?
|
||||
*/
|
||||
class SearchCache {
|
||||
private $mode,
|
||||
$valid;
|
||||
@@ -32,7 +48,7 @@ private $mode,
|
||||
} //else
|
||||
|
||||
$this->valid = true;
|
||||
} //constructor
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the search cache status
|
||||
@@ -40,7 +56,7 @@ private $mode,
|
||||
*/
|
||||
public function can_cache() {
|
||||
return $this->valid;
|
||||
} //can_cache
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -53,7 +69,7 @@ private $mode,
|
||||
//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
|
||||
}
|
||||
|
||||
//store the new query if id and object are passed in
|
||||
if ($object and $id) {
|
||||
@@ -61,11 +77,10 @@ private $mode,
|
||||
$this->store($id, $object);
|
||||
return true;
|
||||
//otherwise return the stored results
|
||||
}
|
||||
else if ($id and $this->exists($id)) {
|
||||
} else if ($id and $this->exists($id)) {
|
||||
return $this->fetch($id);
|
||||
} //else
|
||||
} //cache
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* do key exist in cache ?
|
||||
@@ -76,8 +91,8 @@ private $mode,
|
||||
switch ($this->mode) {
|
||||
case 'session' :
|
||||
return isset($_SESSION[$id]);
|
||||
} //switch
|
||||
} //exists
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* clears a cached object in cache
|
||||
@@ -90,8 +105,8 @@ private $mode,
|
||||
unset($_SESSION[$id]);
|
||||
session_unregister($id);
|
||||
return;
|
||||
} //switch
|
||||
} //clear
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* fetches a cached object
|
||||
@@ -102,8 +117,8 @@ private $mode,
|
||||
switch ($this->mode) {
|
||||
case 'session' :
|
||||
return ($this->exists($id)) ? unserialize($_SESSION[$id]) : false;
|
||||
} //switch
|
||||
} //fetch
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* put an object in cache
|
||||
@@ -116,9 +131,9 @@ private $mode,
|
||||
case 'session' :
|
||||
$_SESSION[$id] = serialize($object);
|
||||
return;
|
||||
} //switch
|
||||
} //store
|
||||
} //SearchCache
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a single query with results
|
||||
@@ -156,14 +171,14 @@ class SearchQuery {
|
||||
} catch(Exception $e) {
|
||||
$this->validindex = false;
|
||||
return;
|
||||
} //catch
|
||||
}
|
||||
|
||||
if (empty($this->term)) {
|
||||
$this->validquery = false;
|
||||
} else {
|
||||
$this->set_query($this->term);
|
||||
} //else
|
||||
} //constructor
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* determines state of query object depending on query entry and
|
||||
@@ -173,22 +188,20 @@ class SearchQuery {
|
||||
public function set_query($term = '') {
|
||||
if (!empty($term)) {
|
||||
$this->term = $term;
|
||||
} //if
|
||||
}
|
||||
|
||||
if (empty($this->term)) {
|
||||
$this->validquery = false;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$this->validquery = true;
|
||||
} //else
|
||||
}
|
||||
|
||||
if ($this->validquery and $this->validindex) {
|
||||
$this->results = $this->get_results();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
$this->results = array();
|
||||
} //else
|
||||
} //set_query
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* accessor to the result table.
|
||||
@@ -196,11 +209,12 @@ class SearchQuery {
|
||||
*/
|
||||
public function results() {
|
||||
return $this->results;
|
||||
} //results
|
||||
}
|
||||
|
||||
/**
|
||||
* do the effective collection of results
|
||||
*
|
||||
* @param boolean $all
|
||||
* @uses USER
|
||||
*/
|
||||
private function process_results($all=false) {
|
||||
global $USER;
|
||||
@@ -224,22 +238,20 @@ class SearchQuery {
|
||||
if (!$all) {
|
||||
if ($hitcount < $this->results_per_page) {
|
||||
$this->pagenumber = 1;
|
||||
}
|
||||
else if ($this->pagenumber > $totalpages) {
|
||||
} 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 {
|
||||
}
|
||||
} else {
|
||||
$start = 0;
|
||||
$end = $hitcount;
|
||||
} //else
|
||||
}
|
||||
|
||||
$resultdoc = new SearchResult();
|
||||
$resultdocs = array();
|
||||
@@ -258,15 +270,14 @@ class SearchQuery {
|
||||
|
||||
//and store it
|
||||
$resultdocs[] = clone($resultdoc);
|
||||
} //if
|
||||
else{
|
||||
} else {
|
||||
// lowers total_results one unit
|
||||
$this->total_results--;
|
||||
}
|
||||
} //foreach
|
||||
}
|
||||
|
||||
return $resultdocs;
|
||||
} //process_results
|
||||
}
|
||||
|
||||
/**
|
||||
* get results of a search query using a caching strategy if available
|
||||
@@ -281,20 +292,17 @@ class SearchQuery {
|
||||
//cache the results so we don't have to compute this on every page-load
|
||||
$cache->cache($this->term, $resultdocs);
|
||||
//print "Using new results.";
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
//There was something in the cache, so we're using that to save time
|
||||
//print "Using cached results.";
|
||||
} //else
|
||||
}
|
||||
else {
|
||||
}
|
||||
} else {
|
||||
//no caching :(
|
||||
//print "Caching disabled!";
|
||||
$resultdocs = $this->process_results();
|
||||
} //else
|
||||
|
||||
}
|
||||
return $resultdocs;
|
||||
} //get_results
|
||||
}
|
||||
|
||||
/**
|
||||
* constructs the results paging links on results.
|
||||
@@ -314,7 +322,7 @@ class SearchQuery {
|
||||
$ret .= "<a href='query.php?query_string={$query}&page=".($page-1)."'>< {$back}</a> ";
|
||||
} else {
|
||||
$ret .= "< {$back} ";
|
||||
} //else
|
||||
}
|
||||
|
||||
//don't <a href> the current page
|
||||
for ($i = 1; $i <= $pages; $i++) {
|
||||
@@ -322,15 +330,15 @@ class SearchQuery {
|
||||
$ret .= "($i) ";
|
||||
} else {
|
||||
$ret .= "<a href='query.php?query_string={$query}&page={$i}'>{$i}</a> ";
|
||||
} //else
|
||||
} //for
|
||||
}
|
||||
}
|
||||
|
||||
//Next disabled if we're on the last page
|
||||
if ($page < $pages) {
|
||||
$ret .= "<a href='query.php?query_string={$query}&page=".($page+1)."'>{$next} ></a> ";
|
||||
} else {
|
||||
$ret .= "{$next} > ";
|
||||
} //else
|
||||
}
|
||||
|
||||
$ret .= "</div>";
|
||||
|
||||
@@ -343,10 +351,10 @@ class SearchQuery {
|
||||
$start = $page + 5;
|
||||
$end = $pages - 3;
|
||||
$ret = preg_replace("/<a\D+\d+\D+>$start<\/a>.*?<a\D+\d+\D+>$end<\/a>/", '...', $ret);
|
||||
} //if
|
||||
}
|
||||
|
||||
return $ret;
|
||||
} //page_numbers
|
||||
}
|
||||
|
||||
/**
|
||||
* can the user see this result ?
|
||||
@@ -359,6 +367,7 @@ class SearchQuery {
|
||||
* @param path the path that routes to the local lib.php of the searched
|
||||
* surrounding object fot that document
|
||||
* @param item_type a subclassing information for complex module data models
|
||||
* @uses CFG
|
||||
* // TODO reorder parameters more consistently
|
||||
*/
|
||||
private function can_display(&$user, $this_id, $doctype, $course_id, $group_id, $path, $item_type, $context_id) {
|
||||
@@ -411,35 +420,55 @@ class SearchQuery {
|
||||
}
|
||||
|
||||
return true;
|
||||
} //can_display
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function count() {
|
||||
return $this->total_results;
|
||||
} //count
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function is_valid() {
|
||||
return ($this->validquery and $this->validindex);
|
||||
} //is_valid
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function is_valid_query() {
|
||||
return $this->validquery;
|
||||
} //is_valid_query
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function is_valid_index() {
|
||||
return $this->validindex;
|
||||
} //is_valid_index
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function total_pages() {
|
||||
return ceil($this->count()/$this->results_per_page);
|
||||
} //pages
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function get_pagenumber() {
|
||||
return $this->pagenumber;
|
||||
} //get_pagenumber
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function get_results_per_page() {
|
||||
return $this->results_per_page;
|
||||
} //get_results_per_page
|
||||
} //SearchQuery
|
||||
|
||||
}
|
||||
}
|
||||
?>
|
||||
+140
-129
@@ -1,152 +1,163 @@
|
||||
<?php
|
||||
/**
|
||||
/**
|
||||
* Global Search Engine for Moodle
|
||||
* Michael Champanis (mchampan) [[email protected]]
|
||||
* review 1.8+ : Valery Fremaux [[email protected]]
|
||||
* 2007/08/02
|
||||
*
|
||||
* @package search
|
||||
* @category core
|
||||
* @subpackage search_engine
|
||||
* @author Michael Champanis (mchampan) [[email protected]], Valery Fremaux [[email protected]] > 1.8
|
||||
* @date 2008/03/31
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
*
|
||||
* Prints some basic statistics about the current index.
|
||||
* Does some diagnostics if you are logged in as an administrator.
|
||||
*
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
* @package search
|
||||
* @version 2007110400
|
||||
*/
|
||||
|
||||
/**
|
||||
* includes and requires
|
||||
*/
|
||||
require_once('../config.php');
|
||||
require_once("{$CFG->dirroot}/search/lib.php");
|
||||
|
||||
if ($CFG->forcelogin) {
|
||||
require_login();
|
||||
}
|
||||
/// checks global search is enabled
|
||||
|
||||
if (empty($CFG->enableglobalsearch)) {
|
||||
error(get_string('globalsearchdisabled', 'search'));
|
||||
}
|
||||
|
||||
//check for php5, but don't die yet
|
||||
if ($check = search_check_php5()) {
|
||||
require_once("{$CFG->dirroot}/search/indexlib.php");
|
||||
|
||||
$indexinfo = new IndexInfo();
|
||||
}
|
||||
|
||||
if (!$site = get_site()) {
|
||||
redirect("index.php");
|
||||
}
|
||||
|
||||
$strsearch = get_string('search', 'search');
|
||||
$strquery = get_string('statistics', 'search');
|
||||
|
||||
print_header("$site->shortname: $strsearch: $strquery", "$site->fullname",
|
||||
"<a href=\"index.php\">$strsearch</a> -> $strquery");
|
||||
|
||||
//keep things pretty, even if php5 isn't available
|
||||
if (!$check) {
|
||||
print_heading(search_check_php5(true));
|
||||
print_footer();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
print_box_start();
|
||||
print_heading($strquery);
|
||||
|
||||
print_box_start();
|
||||
|
||||
$databasestr = get_string('database', 'search');
|
||||
$documentsinindexstr = get_string('documentsinindex', 'search');
|
||||
$deletionsinindexstr = get_string('deletionsinindex', 'search');
|
||||
$documentsindatabasestr = get_string('documentsindatabase', 'search');
|
||||
$databasestatestr = get_string('databasestate', 'search');
|
||||
|
||||
//this table is only for admins, shows index directory size and location
|
||||
if (isadmin()) {
|
||||
$datadirectorystr = get_string('datadirectory', 'search');
|
||||
$inindexdirectorystr = get_string('filesinindexdirectory', 'search');
|
||||
$totalsizestr = get_string('totalsize', 'search');
|
||||
$errorsstr = get_string('errors', 'search');
|
||||
$solutionsstr = get_string('solutions', 'search');
|
||||
$checkdirstr = get_string('checkdir', 'search');
|
||||
$checkdbstr = get_string('checkdb', 'search');
|
||||
$checkdiradvicestr = get_string('checkdiradvice', 'search');
|
||||
$checkdbadvicestr = get_string('checkdbadvice', 'search');
|
||||
$runindexerteststr = get_string('runindexertest', 'search');
|
||||
$runindexerstr = get_string('runindexer', 'search');
|
||||
|
||||
$admin_table->tablealign = "center";
|
||||
$admin_table->align = array ("right", "left");
|
||||
$admin_table->wrap = array ("nowrap", "nowrap");
|
||||
$admin_table->cellpadding = 5;
|
||||
$admin_table->cellspacing = 0;
|
||||
$admin_table->width = '500';
|
||||
|
||||
$admin_table->data[] = array("<strong>{$datadirectorystr}</strong>", '<em><strong>'.$indexinfo->path.'</strong></em>');
|
||||
$admin_table->data[] = array($inindexdirectorystr, $indexinfo->filecount);
|
||||
$admin_table->data[] = array($totalsizestr, $indexinfo->size);
|
||||
|
||||
if ($indexinfo->time > 0) {
|
||||
$admin_table->data[] = array(get_string('createdon', 'search'), date('r', $indexinfo->time));
|
||||
}
|
||||
else {
|
||||
$admin_table->data[] = array(get_string('createdon', 'search'), '-');
|
||||
}
|
||||
|
||||
if (!$indexinfo->valid($errors)) {
|
||||
$admin_table->data[] = array("<strong>{$errorsstr}</strong>", ' ');
|
||||
foreach ($errors as $key => $value) {
|
||||
$admin_table->data[] = array($key.' ... ', $value);
|
||||
}
|
||||
if ($CFG->forcelogin) {
|
||||
require_login();
|
||||
}
|
||||
|
||||
print_table($admin_table);
|
||||
print_spacer(20);
|
||||
print_heading($solutionsstr);
|
||||
|
||||
unset($admin_table->data);
|
||||
if (isset($errors['dir'])) {
|
||||
$admin_table->data[] = array($checkdirstr, $checkdiradvicestr);
|
||||
}
|
||||
if (isset($errors['db'])) {
|
||||
$admin_table->data[] = array($checkdbstr, $checkdbadvicestr);
|
||||
if (empty($CFG->enableglobalsearch)) {
|
||||
error(get_string('globalsearchdisabled', 'search'));
|
||||
}
|
||||
|
||||
/// check for php5, but don't die yet
|
||||
|
||||
if ($check = search_check_php5()) {
|
||||
require_once("{$CFG->dirroot}/search/indexlib.php");
|
||||
|
||||
$indexinfo = new IndexInfo();
|
||||
}
|
||||
|
||||
$admin_table->data[] = array($runindexerteststr, '<a href="tests/index.php" target="_blank">tests/index.php</a>');
|
||||
$admin_table->data[] = array($runindexerstr, '<a href="indexersplash.php" target="_blank">indexersplash.php</a>');
|
||||
if (!$site = get_site()) {
|
||||
redirect("index.php");
|
||||
}
|
||||
|
||||
print_table($admin_table);
|
||||
print_spacer(20);
|
||||
}
|
||||
|
||||
//this is the standard summary table for normal users, shows document counts
|
||||
$table->tablealign = "center";
|
||||
$table->align = array ("right", "left");
|
||||
$table->wrap = array ("nowrap", "nowrap");
|
||||
$table->cellpadding = 5;
|
||||
$table->cellspacing = 0;
|
||||
$table->width = '500';
|
||||
|
||||
$table->data[] = array("<strong>{$databasestr}</strong>", "<em><strong>{$CFG->prefix}".SEARCH_DATABASE_TABLE.'</strong></em>');
|
||||
|
||||
//add extra fields if we're admin
|
||||
if (isadmin()) {
|
||||
//don't want to confuse users if the two totals don't match (hint: they should)
|
||||
$table->data[] = array($documentsinindexstr, $indexinfo->indexcount);
|
||||
$strsearch = get_string('search', 'search');
|
||||
$strquery = get_string('statistics', 'search');
|
||||
|
||||
//*cough* they should match if deletions were actually removed from the index,
|
||||
//as it turns out, they're only marked as deleted and not returned in search results
|
||||
$table->data[] = array($deletionsinindexstr, (int)$indexinfo->indexcount - (int)$indexinfo->dbcount);
|
||||
}
|
||||
print_header("$site->shortname: $strsearch: $strquery", "$site->fullname",
|
||||
"<a href=\"index.php\">$strsearch</a> -> $strquery");
|
||||
|
||||
/// keep things pretty, even if php5 isn't available
|
||||
|
||||
$table->data[] = array($documentsindatabasestr, $indexinfo->dbcount);
|
||||
if (!$check) {
|
||||
print_heading(search_check_php5(true));
|
||||
print_footer();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
print_box_start();
|
||||
print_heading($strquery);
|
||||
|
||||
print_box_start();
|
||||
|
||||
$databasestr = get_string('database', 'search');
|
||||
$documentsinindexstr = get_string('documentsinindex', 'search');
|
||||
$deletionsinindexstr = get_string('deletionsinindex', 'search');
|
||||
$documentsindatabasestr = get_string('documentsindatabase', 'search');
|
||||
$databasestatestr = get_string('databasestate', 'search');
|
||||
|
||||
/// this table is only for admins, shows index directory size and location
|
||||
|
||||
foreach($indexinfo->types as $key => $value) {
|
||||
$table->data[] = array(get_string('documentsfor', 'search') . " '".get_string('modulenameplural', $key)."'", $value);
|
||||
}
|
||||
if (isadmin()) {
|
||||
$datadirectorystr = get_string('datadirectory', 'search');
|
||||
$inindexdirectorystr = get_string('filesinindexdirectory', 'search');
|
||||
$totalsizestr = get_string('totalsize', 'search');
|
||||
$errorsstr = get_string('errors', 'search');
|
||||
$solutionsstr = get_string('solutions', 'search');
|
||||
$checkdirstr = get_string('checkdir', 'search');
|
||||
$checkdbstr = get_string('checkdb', 'search');
|
||||
$checkdiradvicestr = get_string('checkdiradvice', 'search');
|
||||
$checkdbadvicestr = get_string('checkdbadvice', 'search');
|
||||
$runindexerteststr = get_string('runindexertest', 'search');
|
||||
$runindexerstr = get_string('runindexer', 'search');
|
||||
|
||||
$admin_table->tablealign = "center";
|
||||
$admin_table->align = array ("right", "left");
|
||||
$admin_table->wrap = array ("nowrap", "nowrap");
|
||||
$admin_table->cellpadding = 5;
|
||||
$admin_table->cellspacing = 0;
|
||||
$admin_table->width = '500';
|
||||
|
||||
$admin_table->data[] = array("<strong>{$datadirectorystr}</strong>", '<em><strong>'.$indexinfo->path.'</strong></em>');
|
||||
$admin_table->data[] = array($inindexdirectorystr, $indexinfo->filecount);
|
||||
$admin_table->data[] = array($totalsizestr, $indexinfo->size);
|
||||
|
||||
if ($indexinfo->time > 0) {
|
||||
$admin_table->data[] = array(get_string('createdon', 'search'), date('r', $indexinfo->time));
|
||||
}
|
||||
else {
|
||||
$admin_table->data[] = array(get_string('createdon', 'search'), '-');
|
||||
}
|
||||
|
||||
if (!$indexinfo->valid($errors)) {
|
||||
$admin_table->data[] = array("<strong>{$errorsstr}</strong>", ' ');
|
||||
foreach ($errors as $key => $value) {
|
||||
$admin_table->data[] = array($key.' ... ', $value);
|
||||
}
|
||||
}
|
||||
|
||||
print_table($admin_table);
|
||||
print_spacer(20);
|
||||
print_heading($solutionsstr);
|
||||
|
||||
unset($admin_table->data);
|
||||
if (isset($errors['dir'])) {
|
||||
$admin_table->data[] = array($checkdirstr, $checkdiradvicestr);
|
||||
}
|
||||
if (isset($errors['db'])) {
|
||||
$admin_table->data[] = array($checkdbstr, $checkdbadvicestr);
|
||||
}
|
||||
|
||||
$admin_table->data[] = array($runindexerteststr, '<a href="tests/index.php" target="_blank">tests/index.php</a>');
|
||||
$admin_table->data[] = array($runindexerstr, '<a href="indexersplash.php" target="_blank">indexersplash.php</a>');
|
||||
|
||||
print_table($admin_table);
|
||||
print_spacer(20);
|
||||
}
|
||||
|
||||
/// this is the standard summary table for normal users, shows document counts
|
||||
|
||||
print_heading($databasestatestr);
|
||||
print_table($table);
|
||||
$table->tablealign = "center";
|
||||
$table->align = array ("right", "left");
|
||||
$table->wrap = array ("nowrap", "nowrap");
|
||||
$table->cellpadding = 5;
|
||||
$table->cellspacing = 0;
|
||||
$table->width = '500';
|
||||
|
||||
$table->data[] = array("<strong>{$databasestr}</strong>", "<em><strong>{$CFG->prefix}".SEARCH_DATABASE_TABLE.'</strong></em>');
|
||||
|
||||
/// add extra fields if we're admin
|
||||
|
||||
print_box_end();
|
||||
print_box_end();
|
||||
print_footer();
|
||||
if (isadmin()) {
|
||||
//don't want to confuse users if the two totals don't match (hint: they should)
|
||||
$table->data[] = array($documentsinindexstr, $indexinfo->indexcount);
|
||||
|
||||
//*cough* they should match if deletions were actually removed from the index,
|
||||
//as it turns out, they're only marked as deleted and not returned in search results
|
||||
$table->data[] = array($deletionsinindexstr, (int)$indexinfo->indexcount - (int)$indexinfo->dbcount);
|
||||
}
|
||||
|
||||
$table->data[] = array($documentsindatabasestr, $indexinfo->dbcount);
|
||||
|
||||
foreach($indexinfo->types as $key => $value) {
|
||||
$table->data[] = array(get_string('documentsfor', 'search') . " '".get_string('modulenameplural', $key)."'", $value);
|
||||
}
|
||||
|
||||
print_heading($databasestatestr);
|
||||
print_table($table);
|
||||
|
||||
print_box_end();
|
||||
print_box_end();
|
||||
print_footer();
|
||||
?>
|
||||
+130
-118
@@ -1,9 +1,13 @@
|
||||
<?php
|
||||
/**
|
||||
* Global Search Engine for Moodle
|
||||
* Michael Champanis (mchampan) [[email protected]]
|
||||
* review 1.8+ : Valery Fremaux [[email protected]]
|
||||
* 2007/08/02
|
||||
*
|
||||
* @package search
|
||||
* @category core
|
||||
* @subpackage search_engine
|
||||
* @author Michael Champanis (mchampan) [[email protected]], Valery Fremaux [[email protected]] > 1.8
|
||||
* @date 2008/03/31
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
*
|
||||
* Index asynchronous updator
|
||||
*
|
||||
@@ -11,133 +15,141 @@
|
||||
* multiple arity to handle multiple document types modules
|
||||
*/
|
||||
|
||||
/**
|
||||
* includes and requires
|
||||
*/
|
||||
require_once('../config.php');
|
||||
require_once("$CFG->dirroot/search/lib.php");
|
||||
|
||||
require_login();
|
||||
/// checks global search activation
|
||||
|
||||
if (empty($CFG->enableglobalsearch)) {
|
||||
error(get_string('globalsearchdisabled', 'search'));
|
||||
}
|
||||
|
||||
if (!isadmin()) {
|
||||
error(get_string('beadmin', 'search'), "$CFG->wwwroot/login/index.php");
|
||||
}
|
||||
|
||||
//check for php5 (lib.php)
|
||||
if (!search_check_php5()) {
|
||||
$phpversion = phpversion();
|
||||
mtrace("Sorry, global search requires PHP 5.0.0 or later (currently using version $phpversion)");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
require_once("$CFG->dirroot/search/indexlib.php");
|
||||
|
||||
$index = new Zend_Search_Lucene(SEARCH_INDEX_PATH);
|
||||
$dbcontrol = new IndexDBControl();
|
||||
$update_count = 0;
|
||||
$indexdate = $CFG->search_indexer_update_date;
|
||||
$startupdatedate = time();
|
||||
|
||||
mtrace("<pre>Starting index update (updates)...\n");
|
||||
|
||||
if ($mods = get_records_select('modules')) {
|
||||
$mods = array_merge($mods, search_get_additional_modules());
|
||||
require_login();
|
||||
|
||||
foreach ($mods as $mod) {
|
||||
$class_file = $CFG->dirroot.'/search/documents/'.$mod->name.'_document.php';
|
||||
$get_document_function = $mod->name.'_single_document';
|
||||
$delete_function = $mod->name.'_delete';
|
||||
$db_names_function = $mod->name.'_db_names';
|
||||
$updates = array();
|
||||
|
||||
if (file_exists($class_file)) {
|
||||
require_once($class_file);
|
||||
|
||||
//if both required functions exist
|
||||
if (function_exists($delete_function) and function_exists($db_names_function) and function_exists($get_document_function)) {
|
||||
mtrace("Checking $mod->name module for updates.");
|
||||
$valuesArray = $db_names_function();
|
||||
if ($valuesArray){
|
||||
foreach($valuesArray as $values){
|
||||
|
||||
$where = (isset($values[5])) ? 'AND ('.$values[5].')' : '';
|
||||
$itemtypes = ($values[4] != '*') ? " AND itemtype = '{$values[4]}' " : '' ;
|
||||
if (empty($CFG->enableglobalsearch)) {
|
||||
error(get_string('globalsearchdisabled', 'search'));
|
||||
}
|
||||
|
||||
if (!isadmin()) {
|
||||
error(get_string('beadmin', 'search'), "$CFG->wwwroot/login/index.php");
|
||||
}
|
||||
|
||||
/// check for php5 (lib.php)
|
||||
|
||||
//TODO: check 'in' syntax with other RDBMS' (add and update.php as well)
|
||||
$table = SEARCH_DATABASE_TABLE;
|
||||
$query = "
|
||||
SELECT
|
||||
docid,
|
||||
itemtype
|
||||
FROM
|
||||
{$CFG->prefix}{$table}
|
||||
WHERE
|
||||
doctype = '{$mod->name}'
|
||||
$itemtypes
|
||||
";
|
||||
$docIds = get_records_sql_menu($query);
|
||||
$docIdList = ($docIds) ? implode("','", array_keys($docIds)) : '' ;
|
||||
if (!search_check_php5()) {
|
||||
$phpversion = phpversion();
|
||||
mtrace("Sorry, global search requires PHP 5.0.0 or later (currently using version ".phpversion().")");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
require_once("$CFG->dirroot/search/indexlib.php");
|
||||
|
||||
$index = new Zend_Search_Lucene(SEARCH_INDEX_PATH);
|
||||
$dbcontrol = new IndexDBControl();
|
||||
$update_count = 0;
|
||||
$indexdate = $CFG->search_indexer_update_date;
|
||||
$startupdatedate = time();
|
||||
|
||||
/// indexing changed resources
|
||||
|
||||
mtrace("Starting index update (updates)...\n");
|
||||
|
||||
if ($mods = get_records_select('modules')) {
|
||||
$mods = array_merge($mods, search_get_additional_modules());
|
||||
|
||||
foreach ($mods as $mod) {
|
||||
$class_file = $CFG->dirroot.'/search/documents/'.$mod->name.'_document.php';
|
||||
$get_document_function = $mod->name.'_single_document';
|
||||
$delete_function = $mod->name.'_delete';
|
||||
$db_names_function = $mod->name.'_db_names';
|
||||
$updates = array();
|
||||
|
||||
if (file_exists($class_file)) {
|
||||
require_once($class_file);
|
||||
|
||||
//if both required functions exist
|
||||
if (function_exists($delete_function) and function_exists($db_names_function) and function_exists($get_document_function)) {
|
||||
mtrace("Checking $mod->name module for updates.");
|
||||
$valuesArray = $db_names_function();
|
||||
if ($valuesArray){
|
||||
foreach($valuesArray as $values){
|
||||
|
||||
$query = "
|
||||
SELECT
|
||||
id,
|
||||
{$values[0]} as docid
|
||||
FROM
|
||||
{$CFG->prefix}{$values[1]}
|
||||
WHERE
|
||||
{$values[3]} > {$indexdate} AND
|
||||
id IN ('{$docIdList}')
|
||||
$where
|
||||
";
|
||||
$records = get_records_sql($query);
|
||||
if (is_array($records)) {
|
||||
foreach($records as $record) {
|
||||
$updates[] = $delete_function($record->docid, $docIds[$record->docid]);
|
||||
$where = (isset($values[5])) ? 'AND ('.$values[5].')' : '';
|
||||
$itemtypes = ($values[4] != '*' && $values[4] != 'any') ? " AND itemtype = '{$values[4]}' " : '' ;
|
||||
|
||||
//TODO: check 'in' syntax with other RDBMS' (add and update.php as well)
|
||||
$table = SEARCH_DATABASE_TABLE;
|
||||
$query = "
|
||||
SELECT
|
||||
docid,
|
||||
itemtype
|
||||
FROM
|
||||
{$CFG->prefix}{$table}
|
||||
WHERE
|
||||
doctype = '{$mod->name}'
|
||||
$itemtypes
|
||||
";
|
||||
$docIds = get_records_sql_menu($query);
|
||||
$docIdList = ($docIds) ? implode("','", array_keys($docIds)) : '' ;
|
||||
|
||||
$query = "
|
||||
SELECT
|
||||
id,
|
||||
{$values[0]} as docid
|
||||
FROM
|
||||
{$CFG->prefix}{$values[1]}
|
||||
WHERE
|
||||
{$values[3]} > {$indexdate} AND
|
||||
id IN ('{$docIdList}')
|
||||
$where
|
||||
";
|
||||
$records = get_records_sql($query);
|
||||
if (is_array($records)) {
|
||||
foreach($records as $record) {
|
||||
$updates[] = $delete_function($record->docid, $docIds[$record->docid]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($updates as $update) {
|
||||
++$update_count;
|
||||
|
||||
//delete old document
|
||||
$doc = $index->find("+docid:{$update->id} +doctype:{$mod->name} +itemtype:{$update->itemtype}");
|
||||
|
||||
//get the record, should only be one
|
||||
foreach ($doc as $thisdoc) {
|
||||
mtrace(" Delete: $thisdoc->title (database id = $thisdoc->dbid, index id = $thisdoc->id, moodle instance id = $thisdoc->docid)");
|
||||
$dbcontrol->delDocument($thisdoc);
|
||||
$index->delete($thisdoc->id);
|
||||
}
|
||||
|
||||
//add new modified document back into index
|
||||
$add = $get_document_function($update->id, $update->itemtype);
|
||||
|
||||
//object to insert into db
|
||||
$dbid = $dbcontrol->addDocument($add);
|
||||
|
||||
//synchronise db with index
|
||||
$add->addField(Zend_Search_Lucene_Field::Keyword('dbid', $dbid));
|
||||
mtrace(" Add: $add->title (database id = $add->dbid, moodle instance id = $add->docid)");
|
||||
$index->addDocument($add);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($updates as $update) {
|
||||
++$update_count;
|
||||
|
||||
//delete old document
|
||||
$doc = $index->find("+docid:{$update->id} +doctype:{$mod->name} +itemtype:{$update->itemtype}");
|
||||
|
||||
//get the record, should only be one
|
||||
foreach ($doc as $thisdoc) {
|
||||
mtrace(" Delete: $thisdoc->title (database id = $thisdoc->dbid, index id = $thisdoc->id, moodle instance id = $thisdoc->docid)");
|
||||
$dbcontrol->delDocument($thisdoc);
|
||||
$index->delete($thisdoc->id);
|
||||
}
|
||||
|
||||
//add new modified document back into index
|
||||
$add = $get_document_function($update->id, $update->itemtype);
|
||||
|
||||
//object to insert into db
|
||||
$dbid = $dbcontrol->addDocument($add);
|
||||
|
||||
//synchronise db with index
|
||||
$add->addField(Zend_Search_Lucene_Field::Keyword('dbid', $dbid));
|
||||
mtrace(" Add: $add->title (database id = $add->dbid, moodle instance id = $add->docid)");
|
||||
$index->addDocument($add);
|
||||
}
|
||||
}
|
||||
else{
|
||||
mtrace("No types to update.\n");
|
||||
}
|
||||
mtrace("Finished $mod->name.\n");
|
||||
else{
|
||||
mtrace("No types to update.\n");
|
||||
}
|
||||
mtrace("Finished $mod->name.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//commit changes
|
||||
$index->commit();
|
||||
|
||||
//update index date
|
||||
set_config("search_indexer_update_date", $startupdatedate);
|
||||
|
||||
mtrace("Finished $update_count updates.</pre>");
|
||||
|
||||
//commit changes
|
||||
$index->commit();
|
||||
|
||||
//update index date
|
||||
set_config("search_indexer_update_date", $startupdatedate);
|
||||
|
||||
mtrace("Finished $update_count updates");
|
||||
|
||||
?>
|
||||
Reference in New Issue
Block a user