mirror of
https://github.com/moodle/moodle.git
synced 2025-08-04 16:36:37 +02:00

Scripts that do not want buffered output just define NO_OUTPUT_BUFFERING before including config.php. The fileserving code now checks if the headers are already sent which detects misconfigured servers.
225 lines
No EOL
7.8 KiB
PHP
225 lines
No EOL
7.8 KiB
PHP
<?php
|
|
/**
|
|
* Global Search Engine for Moodle
|
|
*
|
|
* @package search
|
|
* @category core
|
|
* @subpackage search_engine
|
|
* @author Michael Champanis (mchampan) [cynnical@gmail.com], Valery Fremaux [valery.fremaux@club-internet.fr] > 1.8
|
|
* @date 2008/03/31
|
|
* @version prepared for Moodle 2.0
|
|
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
|
*
|
|
* The indexer logic -
|
|
*
|
|
* Look through each installed module's or block's search document class file (/search/documents)
|
|
* for necessary search functions, and if they're present add the content to the index.
|
|
* Repeat this for blocks.
|
|
*
|
|
* Because the iterator/retrieval functions are now stored in /search/documents/<mod>_document.php,
|
|
* /mod/mod/lib.php doesn't have to be modified - and thus the search module becomes quite
|
|
* self-sufficient. URL's are now stored in the index, stopping us from needing to require
|
|
* the class files to generate a results page.
|
|
*
|
|
* Along with the index data, each document's summary gets stored in the database
|
|
* and synchronised to the index (flat file) via the primary key ('id') which is mapped
|
|
* to the 'dbid' field in the index
|
|
* */
|
|
|
|
|
|
/**
|
|
* includes and requires
|
|
*/
|
|
|
|
define('NO_OUTPUT_BUFFERING', true);
|
|
|
|
require_once('../config.php');
|
|
require_once($CFG->dirroot.'/search/lib.php');
|
|
|
|
//this'll take some time, set up the environment
|
|
@set_time_limit(0);
|
|
|
|
ini_set('include_path', $CFG->dirroot.DIRECTORY_SEPARATOR.'search'.PATH_SEPARATOR.ini_get('include_path'));
|
|
|
|
/// only administrators can index the moodle installation, because access to all pages is required
|
|
|
|
require_login();
|
|
|
|
if (empty($CFG->enableglobalsearch)) {
|
|
print_error('globalsearchdisabled', 'search');
|
|
}
|
|
|
|
if (!has_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM))) {
|
|
print_error('beadmin', 'search', get_login_url());
|
|
}
|
|
|
|
/// confirmation flag to prevent accidental reindexing (indexersplash.php is the correct entry point)
|
|
|
|
$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)
|
|
|
|
//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
|
|
|
|
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, $CFG->directorypermissions)) {
|
|
search_pexit("Error creating data directory at: $index_path. Please correct.");
|
|
}
|
|
else {
|
|
mtrace("Directory successfully created.");
|
|
}
|
|
}
|
|
else {
|
|
mtrace("Using {$index_path} as data directory.");
|
|
}
|
|
|
|
Zend_Search_Lucene_Analysis_Analyzer::setDefault(new Zend_Search_Lucene_Analysis_Analyzer_Common_Utf8_CaseInsensitive());
|
|
$index = new Zend_Search_Lucene($index_path, true);
|
|
|
|
/// New regeneration
|
|
|
|
mtrace('Deleting old index entries.');
|
|
$DB->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 = search_collect_searchables();
|
|
|
|
/// start indexation
|
|
|
|
if ($searchables){
|
|
foreach ($searchables as $mod) {
|
|
|
|
//mark last update times for mods to now.
|
|
$indexdatestring = 'search_indexer_update_date_'.$mod->name;
|
|
set_config($indexdatestring, time());
|
|
$indexdatestring = 'search_indexer_run_date_'.$mod->name;
|
|
set_config($indexdatestring, time());
|
|
|
|
mtrace("starting indexing {$mod->name}\n");
|
|
|
|
$key = 'search_in_'.$mod->name;
|
|
if (isset($CFG->$key) && !$CFG->$key) {
|
|
mtrace("module $key has been administratively disabled. Skipping...\n");
|
|
continue;
|
|
}
|
|
|
|
if ($mod->location == 'internal'){
|
|
$class_file = $CFG->dirroot.'/search/documents/'.$mod->name.'_document.php';
|
|
} else {
|
|
$class_file = $CFG->dirroot.'/'.$mod->location.'/'.$mod->name.'/search_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++;
|
|
|
|
// temporary fix until MDL-24822 is resolved
|
|
if ($document->group_id == -1 and $mod->name ='forum') {
|
|
$document->group_id = 0;
|
|
}
|
|
//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");
|
|
}
|
|
} else {
|
|
mtrace ("No search document found for plugin {$mod->name}. Ignoring.");
|
|
}
|
|
}
|
|
}
|
|
|
|
/// finished modules
|
|
|
|
mtrace('Finished activity modules');
|
|
search_stopwatch();
|
|
|
|
mtrace(".<br/><a href='index.php'>Back to query page</a>.");
|
|
mtrace('</pre>');
|
|
|
|
/// finished, turn busy flag off
|
|
|
|
set_config('search_indexer_busy', '0');
|
|
|
|
/// mark the time we last updated
|
|
|
|
set_config('search_indexer_run_date', time());
|
|
|
|
/// and the index size
|
|
|
|
set_config('search_index_size', (int)$index->count());
|
|
|
|
?>
|