From 3319ef8538eeda350352b93b76cd72c0da801e30 Mon Sep 17 00:00:00 2001 From: diml Date: Mon, 31 Mar 2008 22:21:42 +0000 Subject: [PATCH] code review for packaging and code cleaning fixes type wilcard issue on add/delete/update cron scripts --- search/add.php | 248 ++++++++------- search/cron_php5.php | 1 + search/delete.php | 212 +++++++------ search/index.php | 13 +- search/indexer.php | 327 +++++++++++--------- search/indexersplash.php | 114 +++---- search/indexlib.php | 71 +++-- search/lib.php | 18 +- search/query.php | 654 ++++++++++++++++++++------------------- search/querylib.php | 159 ++++++---- search/stats.php | 267 ++++++++-------- search/update.php | 242 ++++++++------- 12 files changed, 1237 insertions(+), 1089 deletions(-) diff --git a/search/add.php b/search/add.php index dbe45333ca..1f99bd200b 100644 --- a/search/add.php +++ b/search/add.php @@ -1,9 +1,13 @@ 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(); - -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(); -$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"); +/// 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) -//get all modules -if ($mods = get_records_select('modules')) { + 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 -//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()); + mtrace("Added $addition_count documents."); + mtrace('Index size after: '.$index->count()); ?> \ No newline at end of file diff --git a/search/cron_php5.php b/search/cron_php5.php index e098c7ab71..4a0e9f9f2c 100644 --- a/search/cron_php5.php +++ b/search/cron_php5.php @@ -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'); diff --git a/search/delete.php b/search/delete.php index 11effeea0f..21ed6f61ef 100644 --- a/search/delete.php +++ b/search/delete.php @@ -1,9 +1,13 @@ 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('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(); + + 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"); - 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(); + $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)) : '' ; - - $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]); + 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]); + } } } - } - - 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)"); + 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}"); - //remove it from index and database table - $dbcontrol->delDocument($thisdoc); - $index->delete($thisdoc->id); + // 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 -$index->commit(); + +/// commit changes -//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); + $index->commit(); + +/// update index date and index size -mtrace("Finished $deletion_count removals."); -mtrace('Index size after: '.$index->count()); + 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()); ?> \ No newline at end of file diff --git a/search/index.php b/search/index.php index 264892e33d..089688c965 100644 --- a/search/index.php +++ b/search/index.php @@ -1,9 +1,18 @@ 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"); ?> \ No newline at end of file diff --git a/search/indexer.php b/search/indexer.php index d00928f425..379af25fdc 100644 --- a/search/indexer.php +++ b/search/indexer.php @@ -1,9 +1,13 @@ 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(); - -if (empty($CFG->enableglobalsearch)) { - error(get_string('globalsearchdisabled', 'search')); -} - -if (!isadmin()) { - error(get_string('beadmin', 'search'), "$CFG->wwwroot/login/index.php"); -} //if - -//confirmation flag to prevent accidental reindexing (indexersplash.php is the correct entry point) -$sure = strtolower(optional_param('areyousure', '', PARAM_ALPHA)); - -if ($sure != 'yes') { - mtrace("
Sorry, you need to confirm indexing via indexersplash.php"
-          .". (Back to query page).
"); +/// only administrators can index the moodle installation, because access to all pages is required - exit(0); -} //if + 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) -//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); -} + $sure = strtolower(optional_param('areyousure', '', PARAM_ALPHA)); + + if ($sure != 'yes') { + mtrace("
Sorry, you need to confirm indexing via indexersplash.php"
+              .". (Back to query page).
"); + + 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"); + 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(''); + mtrace('
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
 
-mtrace('');
-mtrace('
Server Time: '.date('r',time())."\n");
+    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.");
+        } 
+        else {
+            mtrace("Directory successfully created.");
+        } 
+    } 
+    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.");
+    }
+    */
 
-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");
-}
+/// New regeneration
 
-//turn on busy flag
-set_config('search_indexer_busy', '1');
+    mtrace('Deleting old index entries.');
+    delete_records(SEARCH_DATABASE_TABLE);
+    
+/// begin timer
 
-//paths
-$index_path = SEARCH_INDEX_PATH;
-$index_db_file = "{$CFG->dirroot}/search/db/$CFG->dbtype.sql";
-$dbcontrol = new IndexDBControl();
+    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
 
-//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.");
-    } 
-    else {
-        mtrace("Directory successfully created.");
-    } 
-} 
-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;
+    if ($mods = get_records('modules', '', '', '', 'id,name')) {
+        $searchables = array_merge($searchables, $mods);
     }
-    $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");
-                                } 
+    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;
+        }
+        $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
                         }
-                        //end transaction
                     }
+            
+                    //commit left over documents, and finish up
+                    $index->commit();
+          
+                    mtrace("-- $counter documents indexed");
+                    mtrace("done.\n");
                 }
-        
-                //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(".
Back to query page."); + mtrace('
'); -mtrace(".
Back to query page."); -mtrace('
'); +/// 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()); ?> \ No newline at end of file diff --git a/search/indexersplash.php b/search/indexersplash.php index 27edca42c0..bc0cda16fb 100644 --- a/search/indexersplash.php +++ b/search/indexersplash.php @@ -1,66 +1,76 @@ 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(); - -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); -} +/// check global search is enabled -require_once("$CFG->dirroot/search/indexlib.php"); -$indexinfo = new IndexInfo(); + 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 ($indexinfo->valid()) { - $strsearch = get_string('search', 'search'); - $strquery = get_string('stats'); + 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(); - $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'); - $navigation = build_navigation($navlinks); - $site = get_site(); - print_header("$strsearch", "$site->fullname" , $navigation, "", "", true, " ", navmenu($site)); - - mtrace("
The data directory ($indexinfo->path) contains $indexinfo->filecount files, and\n"
-          ."there are ".$indexinfo->dbcount." records in the block_search_documents 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"
-          ."Test indexing or "
-          ."Continue indexing or Back to query page."
-          ."
"); - print_footer(); -} -else { - header('Location: indexer.php?areyousure=yes'); -} -?> + 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'); + $navigation = build_navigation($navlinks); + $site = get_site(); + print_header("$strsearch", "$site->fullname" , $navigation, "", "", true, " ", navmenu($site)); + + mtrace("
The data directory ($indexinfo->path) contains $indexinfo->filecount files, and\n"
+              ."there are ".$indexinfo->dbcount." records in the block_search_documents 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"
+              ."Test indexing or "
+              ."Continue indexing or Back to query page."
+              ."
"); + print_footer(); + } + else { + header('Location: indexer.php?areyousure=yes'); + } +?> \ No newline at end of file diff --git a/search/indexlib.php b/search/indexlib.php index a4a5e5ea49..be250ca39e 100644 --- a/search/indexlib.php +++ b/search/indexlib.php @@ -1,20 +1,32 @@ 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,8 +85,7 @@ class IndexInfo { $c = count_records(SEARCH_DATABASE_TABLE, 'doctype', $type); $this->types[$type] = (int)$c; } - } - else { + } else { $this->dbcount = 0; $this->types = array(); } @@ -82,23 +93,21 @@ class IndexInfo { //check if the busy flag is set 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; @@ -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 + } +} ?> \ No newline at end of file diff --git a/search/lib.php b/search/lib.php index 69365d26b9..af40f8f1d9 100644 --- a/search/lib.php +++ b/search/lib.php @@ -1,14 +1,20 @@ 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 diff --git a/search/query.php b/search/query.php index 03675ab974..5d83989188 100644 --- a/search/query.php +++ b/search/query.php @@ -1,346 +1,360 @@ 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"); + /** + * 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 + * @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 + * + */ + + /** + * includes and requires + */ + require_once('../config.php'); + require_once("$CFG->dirroot/search/lib.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 ($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 ($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; + 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']); } - - // create title search string - if (strlen(trim($adv->title)) > 0) { - $query_string .= " +{$titlestr}:".implode(" +{$titlestr}:", preg_split("/[\s,;]+/", $adv->title)); + 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); } - - // create author search string - if (strlen(trim($adv->author)) > 0) { - $query_string .= " +{$authorstr}:".implode(" +{$authorstr}:", preg_split("/[\s,;]+/", $adv->author)); + + 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); + } } - - // 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); } - - // normalise page number - if ($page_number < 1) { - $page_number = 1; + + if (!$site = get_site()) { + redirect("index.php"); } - - //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'); - -$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)); + + $strsearch = get_string('search', 'search'); + $strquery = get_string('enteryoursearchquery', 'search'); + + if ($CFG->version < 2007032200){ + print_header("$site->shortname: $strsearch: $strquery", "$site->fullname", + "$strsearch -> $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); } -} -?> - -
- - -     - | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
:
:
:
: - +     + | + + - -
:
:

- - - - - + else { + print_box_start(); + ?> + + +
| 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
:
:
:
: + +
:
:

+ + + + + +
| 
+
-
- +
+
+ +
+ 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"; } -?> - -
- -
-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 '

' . get_string('noindexmessage', 'search') . '' . get_string('createanindex', 'search')."

\n"; -} - -?> -
-is_valid()) { - print_box_start(); - search_stopwatch(); - $hit_count = $sq->count(); + print ' '; + print_string('documents', 'search'); + print '.'; - print "
"; + if (!$sq->is_valid_index() and isadmin()) { + print '

' . get_string('noindexmessage', 'search') . '' . get_string('createanindex', 'search')."

\n"; + } - print $hit_count.' '.get_string('resultsreturnedfor', 'search') . " '".stripslashes($query_string)."'."; - print "
"; + ?> +
+ 0) { - $page_links = $sq->page_numbers(); - $hits = $sq->results(); + // prints all the results in a box + if ($sq->is_valid()) { + print_box_start(); - 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); - } + search_stopwatch(); + $hit_count = $sq->count(); - print "
    "; + print "
    "; - $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 "
  1. url)."'>$listing->title
    \n" - ."".search_shorten_url($listing->url, 70)."
    \n" - ."{$typestr}: ".$listing->doctype.", {$scorestr}: ".round($listing->score, 3).", {$authorstr}: ".$listing->author."\n" - ."
  2. \n"; - } + print $hit_count.' '.get_string('resultsreturnedfor', 'search') . " '".stripslashes($query_string)."'."; + print "
    "; - print "
"; - print $page_links; - } - + 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 "
    "; + + $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 "
  1. url)."'>$listing->title
    \n" + ."".search_shorten_url($listing->url, 70)."
    \n" + ."{$typestr}: ".$listing->doctype.", {$scorestr}: ".round($listing->score, 3).", {$authorstr}: ".$listing->author."\n" + ."
  2. \n"; + } + + print "
"; + print $page_links; + } + + print_box_end(); + ?> +
+ . +
+ + -
-. -
- - \ No newline at end of file diff --git a/search/querylib.php b/search/querylib.php index 2db68c1fcf..2c5b49cdf5 100644 --- a/search/querylib.php +++ b/search/querylib.php @@ -1,4 +1,18 @@ 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 .= "< {$back} "; } else { $ret .= "< {$back} "; - } //else + } //don't the current page for ($i = 1; $i <= $pages; $i++) { @@ -322,15 +330,15 @@ class SearchQuery { $ret .= "($i) "; } else { $ret .= "{$i} "; - } //else - } //for + } + } //Next disabled if we're on the last page if ($page < $pages) { $ret .= "{$next} > "; } else { $ret .= "{$next} > "; - } //else + } $ret .= ""; @@ -343,10 +351,10 @@ class SearchQuery { $start = $page + 5; $end = $pages - 3; $ret = preg_replace("/$start<\/a>.*?$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 - + } +} ?> \ No newline at end of file diff --git a/search/stats.php b/search/stats.php index 7a41cf9f5c..9e64c04cb6 100644 --- a/search/stats.php +++ b/search/stats.php @@ -1,152 +1,163 @@ 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(); -} - -if (empty($CFG->enableglobalsearch)) { - error(get_string('globalsearchdisabled', 'search')); -} +/// checks global search is enabled -//check for php5, but don't die yet -if ($check = search_check_php5()) { - require_once("{$CFG->dirroot}/search/indexlib.php"); + if ($CFG->forcelogin) { + require_login(); + } - $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", - "$strsearch -> $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("{$datadirectorystr}", ''.$indexinfo->path.''); - $admin_table->data[] = array($inindexdirectorystr, $indexinfo->filecount); - $admin_table->data[] = array($totalsizestr, $indexinfo->size); + if (empty($CFG->enableglobalsearch)) { + error(get_string('globalsearchdisabled', 'search')); + } + +/// check for php5, but don't die yet - if ($indexinfo->time > 0) { - $admin_table->data[] = array(get_string('createdon', 'search'), date('r', $indexinfo->time)); + if ($check = search_check_php5()) { + require_once("{$CFG->dirroot}/search/indexlib.php"); + + $indexinfo = new IndexInfo(); } - else { - $admin_table->data[] = array(get_string('createdon', 'search'), '-'); + + 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", + "$strsearch -> $strquery"); + +/// keep things pretty, even if php5 isn't available - if (!$indexinfo->valid($errors)) { - $admin_table->data[] = array("{$errorsstr}", ' '); - foreach ($errors as $key => $value) { - $admin_table->data[] = array($key.' ... ', $value); - } + if (!$check) { + print_heading(search_check_php5(true)); + print_footer(); + exit(0); } - - print_table($admin_table); - print_spacer(20); - print_heading($solutionsstr); - unset($admin_table->data); - if (isset($errors['dir'])) { - $admin_table->data[] = array($checkdirstr, $checkdiradvicestr); + 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("{$datadirectorystr}", ''.$indexinfo->path.''); + $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("{$errorsstr}", ' '); + 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, 'tests/index.php'); + $admin_table->data[] = array($runindexerstr, 'indexersplash.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("{$databasestr}", "{$CFG->prefix}".SEARCH_DATABASE_TABLE.''); + +/// 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); + + //*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); } - if (isset($errors['db'])) { - $admin_table->data[] = array($checkdbstr, $checkdbadvicestr); + + $table->data[] = array($documentsindatabasestr, $indexinfo->dbcount); + + foreach($indexinfo->types as $key => $value) { + $table->data[] = array(get_string('documentsfor', 'search') . " '".get_string('modulenameplural', $key)."'", $value); } - $admin_table->data[] = array($runindexerteststr, 'tests/index.php'); - $admin_table->data[] = array($runindexerstr, 'indexersplash.php'); + print_heading($databasestatestr); + print_table($table); - 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("{$databasestr}", "{$CFG->prefix}".SEARCH_DATABASE_TABLE.''); - -//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); - - //*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(); + print_box_end(); + print_box_end(); + print_footer(); ?> \ No newline at end of file diff --git a/search/update.php b/search/update.php index f641f1b39f..610735dcc6 100644 --- a/search/update.php +++ b/search/update.php @@ -1,9 +1,13 @@ 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(); - -if (empty($CFG->enableglobalsearch)) { - error(get_string('globalsearchdisabled', 'search')); -} +/// checks global search activation -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(); + 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) -mtrace("Starting index update (updates)...\n"); + 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(); -if ($mods = get_records_select('modules')) { - $mods = array_merge($mods, search_get_additional_modules()); +/// indexing changed resources - 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(); + mtrace("Starting index update (updates)...\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) { + $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 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]}' " : '' ; - - //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 (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); + 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); } - - //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"); + + //commit changes + $index->commit(); + + //update index date + set_config("search_indexer_update_date", $startupdatedate); + + mtrace("Finished $update_count updates"); ?> \ No newline at end of file -- 2.39.5