Option for additional search types added.
[moodle.git] / search / indexer.php
index 0b9db79..c7d8df8 100644 (file)
@@ -1,4 +1,19 @@
 <?php
+  /* The indexer logic -
+   * Look through each installed module's search document class file (/search/documents)
+   * for necessary search functions, and if they're present add the content to the index.
+   * Repeat this for blocks.
+   *
+   * Because the iterator/retrieval functions are now stored in /search/documents/mod_document.php,
+   * /mod/mod/lib.php doesn't have to be modified - and thus the search module becomes quite
+   * self-sufficient. URL's are now stored in the index, stopping us from needing to require
+   * the class files to generate a results page.
+   *
+   * Along with the index data, each document's summary gets stored in the database
+   * and synchronised to the index (flat file) via the primary key ('id') which is mapped
+   * to the 'db_id' field in the index
+   * */
+
   //this'll take some time, set up the environment
   @set_time_limit(0);
   @ob_implicit_flush(true);
   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 (!isadmin()) {
     error("You need to be an admin user to use this page.", "$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 weren't sure enough (<a href='index.php'>back to query page</a>).");
+    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);
   } //if  
   
     exit(0);
   } //if
     
+  //php5 found, continue including php5-only files
   require_once("$CFG->dirroot/search/Zend/Search/Lucene.php");
-  
-  //begin timer
-  search_stopwatch();    
+    
   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");
+  } //if
+
+  //turn on busy flag
+  set_config('search_indexer_busy', '1');
   
   //paths
-  $index_path = $CFG->dataroot.'/search';
+  $index_path = SEARCH_INDEX_PATH;
   $index_db_file = "$CFG->dirroot/search/db/$CFG->dbtype.sql";  
   
+  //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)) {
   } else {
     mtrace("Using $index_path as data directory.");
   } //else
-
-  //stop accidental re-indexing (zzz)
-  //search_pexit("Not indexing at this time.");
-
+  
   $index = new Zend_Search_Lucene($index_path, true);
   
   //create the database tables
   $tables = $db->MetaTables();
     
   if (in_array($CFG->prefix.'search_documents', $tables)) {
-    delete_records('search_documents');
+    //delete_records('search_documents');    
+    //temporary measure - db doesn't have update scripts and I realised that cvs 1.1 db
+    //is incompatible with cvs 1.2! Must fix ASAP.    
+    execute_sql('drop table '.$CFG->prefix.'search_documents', false);
+    
+    ob_start(); //turn output buffering on - to hide modify_database() output
+    modify_database($index_db_file, '', false);
+    ob_end_clean(); //chuck the buffer and resume normal operation
   } else {        
     ob_start(); //turn output buffering on - to hide modify_database() output
     modify_database($index_db_file, '', false);
     ob_end_clean(); //chuck the buffer and resume normal operation
   } //else
+
+  //begin timer
+  search_stopwatch();
+  mtrace("Starting activity modules\n");
   
-  //empty database table goes here
-  // delete * from search_documents;
-  // set auto_increment back to 1
-  
-  //-------- debug stuff
-  /*
-  include_once("$CFG->dirroot/mod/wiki/lib.php");
-  
-  $wikis = get_all_instances_in_courses("wiki", get_courses());
-  #search_pexit($wikis[1]);
-  $entries = wiki_get_entries($wikis[1]);
-  #search_pexit($entries);
-    
-  #$r = wiki_get_pages($entries[134]);
-  $r = wiki_get_latest_pages($entries[95]);
+  //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.
   
-  search_pexit($r);
-  //ignore me --------*/
+  if ($mods = get_records_select('modules' /*'index this module?' where statement*/)) {        
+    $mods = array_merge($mods, search_get_additional_modules());
     
-  mtrace('Starting activity modules');
-  if ($mods = get_records_select('modules' /*'index this module?' where statement*/)) {
-    foreach ($mods as $mod) {
-      $libfile = "$CFG->dirroot/mod/$mod->name/lib.php";
-      if (file_exists($libfile)) {
-        include_once($libfile);
+    foreach ($mods as $mod) {      
+      $class_file = $CFG->dirroot.'/search/documents/'.$mod->name.'_document.php';              
+      
+      if (file_exists($class_file)) {
+        include_once($class_file);
         
         $iter_function = $mod->name.'_iterator';
         $index_function = $mod->name.'_get_content_for_index';
-        $include_file = $CFG->dirroot.'/search/documents/'.$mod->name.'_document.php';        
-        $c = 0;
+                
+        $counter = 0;
         $doc = new stdClass;
                 
         if (function_exists($index_function) && function_exists($iter_function)) {
-          include_once($include_file);
-          
           mtrace("Processing module function $index_function ...");
                      
           foreach ($iter_function() as $i) {
             //begin transaction
             
             foreach($documents as $document) {
-              $c++;
-              
-              //db sync increases indexing time from 55 sec to 73 (64 on Saturday?), so ~30%
-              //therefore, let us make a custom insert function for this search module
-              
-              //data object for db
-              $doc->type = $document->type;
-              $doc->title = mysql_real_escape_string($document->title); //naughty
-              $doc->update = time();
-              $doc->permissions = 0;
-              $doc->url = 'none';
-              $doc->courseid = $document->courseid;
-              $doc->userid = $document->userid;
-              $doc->groupid = $document->groupid;
+              $counter++;
+                            
+              //object to insert into db                            
+              $doc->doctype   = $document->doctype;
+              $doc->title     = search_escape_string($document->title);
+              $doc->url       = search_escape_string($document->url);              
+              $doc->update    = time();                            
+              $doc->courseid  = $document->course_id;              
+              $doc->groupid   = $document->group_id;              
               
               //insert summary into db
               $id = insert_record('search_documents', $doc);
               
               //synchronise db with index
               $document->addField(Zend_Search_Lucene_Field::Keyword('dbid', $id));
+              
+              //add document to index
               $index->addDocument($document);                  
                             
-              //commit every 100 new documents, and print a status message                            
-              if (($c%100) == 0) {
+              //commit every x new documents, and print a status message                            
+              if (($counter%2000) == 0) {
                 $index->commit();
-                mtrace(".. $c");                
+                mtrace(".. $counter");
               } //if
             } //foreach
-            
+
             //end transaction
             
           } //foreach
                   
           //commit left over documents, and finish up  
           $index->commit();
-          mtrace("-- $c documents indexed");
-          mtrace('done.');          
+          
+          mtrace("-- $counter documents indexed");
+          mtrace("done.\n");          
         } //if
       } //if
     } //foreach
   } //if
   
-  //done modules
+  //finished modules
   mtrace('Finished activity modules');
   search_stopwatch();
+  
+  //now blocks...
+  //
+  
   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());
 
 ?>
\ No newline at end of file