MDL-11719 increased size of idnumber in user table - needed for some enrolment plugin...
[moodle.git] / search / indexer.php
CommitLineData
682d4032 1<?php
2f338ab5 2/**
3* Global Search Engine for Moodle
3319ef85 4*
5* @package search
6* @category core
7* @subpackage search_engine
8* @author Michael Champanis (mchampan) [cynnical@gmail.com], Valery Fremaux [valery.fremaux@club-internet.fr] > 1.8
9* @date 2008/03/31
10* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
2f338ab5 11*
12* The indexer logic -
13*
14* Look through each installed module's or block's search document class file (/search/documents)
15* for necessary search functions, and if they're present add the content to the index.
16* Repeat this for blocks.
17*
18* Because the iterator/retrieval functions are now stored in /search/documents/<mod>_document.php,
19* /mod/mod/lib.php doesn't have to be modified - and thus the search module becomes quite
20* self-sufficient. URL's are now stored in the index, stopping us from needing to require
21* the class files to generate a results page.
22*
23* Along with the index data, each document's summary gets stored in the database
24* and synchronised to the index (flat file) via the primary key ('id') which is mapped
25* to the 'dbid' field in the index
26* */
27
28//this'll take some time, set up the environment
29@set_time_limit(0);
30@ob_implicit_flush(true);
31@ob_end_flush();
32
3319ef85 33/**
34* includes and requires
35*/
2f338ab5 36require_once('../config.php');
37require_once("$CFG->dirroot/search/lib.php");
38
3319ef85 39/// only administrators can index the moodle installation, because access to all pages is required
eef868d1 40
3319ef85 41 require_login();
42
43 if (empty($CFG->enableglobalsearch)) {
44 error(get_string('globalsearchdisabled', 'search'));
45 }
46
47 if (!isadmin()) {
48 error(get_string('beadmin', 'search'), "$CFG->wwwroot/login/index.php");
49 }
50
51/// confirmation flag to prevent accidental reindexing (indexersplash.php is the correct entry point)
eef868d1 52
3319ef85 53 $sure = strtolower(optional_param('areyousure', '', PARAM_ALPHA));
54
55 if ($sure != 'yes') {
56 mtrace("<pre>Sorry, you need to confirm indexing via <a href='indexersplash.php'>indexersplash.php</a>"
57 .". (<a href='index.php'>Back to query page</a>).</pre>");
58
59 exit(0);
60 }
61
3319ef85 62 //php5 found, continue including php5-only files
63 //require_once("$CFG->dirroot/search/Zend/Search/Lucene.php");
64 require_once("$CFG->dirroot/search/indexlib.php");
65
66 mtrace('<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8" /></head><body>');
67 mtrace('<pre>Server Time: '.date('r',time())."\n");
68
69 if (isset($CFG->search_indexer_busy) && $CFG->search_indexer_busy == '1') {
70 //means indexing was not finished previously
71 mtrace("Warning: Indexing was not successfully completed last time, restarting.\n");
72 }
73
74/// turn on busy flag
eef868d1 75
3319ef85 76 set_config('search_indexer_busy', '1');
77
78 //paths
79 $index_path = SEARCH_INDEX_PATH;
80 $index_db_file = "{$CFG->dirroot}/search/db/$CFG->dbtype.sql";
81 $dbcontrol = new IndexDBControl();
82
83/// setup directory in data root
84
85 if (!file_exists($index_path)) {
86 mtrace("Data directory ($index_path) does not exist, attempting to create.");
87 if (!mkdir($index_path)) {
88 search_pexit("Error creating data directory at: $index_path. Please correct.");
adddd26d 89 } else {
3319ef85 90 mtrace("Directory successfully created.");
91 }
adddd26d 92 } else {
3319ef85 93 mtrace("Using $index_path as data directory.");
94 }
95
96 $index = new Zend_Search_Lucene($index_path, true);
97
98 /*
99 OBSOLETE REGENERATION - DB installs with search block by now
100 if (!$dbcontrol->checkDB()) {
101 search_pexit("Database error. Please check settings/files.");
102 }
103 */
b585dc5f 104
3319ef85 105/// New regeneration
b585dc5f 106
3319ef85 107 mtrace('Deleting old index entries.');
108 delete_records(SEARCH_DATABASE_TABLE);
109
110/// begin timer
eef868d1 111
3319ef85 112 search_stopwatch();
113 mtrace("Starting activity modules\n");
114
115 //the presence of the required search functions -
116 // * mod_iterator
117 // * mod_get_content_for_index
118 //are the sole basis for including a module in the index at the moment.
119 $searchables = array();
120
121/// collects modules
eef868d1 122
3319ef85 123 if ($mods = get_records('modules', '', '', '', 'id,name')) {
124 $searchables = array_merge($searchables, $mods);
2f338ab5 125 }
3319ef85 126 mtrace(count($searchables).' modules found.');
127
128 // collects blocks as indexable information may be found in blocks either
129 if ($blocks = get_records('block', '', '', '', 'id,name')) {
130 // prepend the "block_" prefix to discriminate document type plugins
131 foreach(array_keys($blocks) as $aBlockId){
132 $blocks[$aBlockId]->name = 'block_'.$blocks[$aBlockId]->name;
133 }
134 $searchables = array_merge($searchables, $blocks);
135 mtrace(count($blocks).' blocks found.');
136 }
137
138/// add virtual modules onto the back of the array
139
140 $searchables = array_merge($searchables, search_get_additional_modules());
141 if ($searchables){
142 foreach ($searchables as $mod) {
143 $class_file = $CFG->dirroot.'/search/documents/'.$mod->name.'_document.php';
144
145 if (file_exists($class_file)) {
146 include_once($class_file);
147
148 //build function names
149 $iter_function = $mod->name.'_iterator';
150 $index_function = $mod->name.'_get_content_for_index';
151 $counter = 0;
152 if (function_exists($index_function) && function_exists($iter_function)) {
153 mtrace("Processing module function $index_function ...");
154 $sources = $iter_function();
155 if ($sources){
156 foreach ($sources as $i) {
157 $documents = $index_function($i);
158
159 //begin transaction
160 if ($documents){
161 foreach($documents as $document) {
162 $counter++;
163
164 //object to insert into db
165 $dbid = $dbcontrol->addDocument($document);
166
167 //synchronise db with index
168 $document->addField(Zend_Search_Lucene_Field::Keyword('dbid', $dbid));
169
170 //add document to index
171 $index->addDocument($document);
172
173 //commit every x new documents, and print a status message
174 if (($counter % 2000) == 0) {
175 $index->commit();
176 mtrace(".. $counter");
177 }
178 }
2f338ab5 179 }
3319ef85 180 //end transaction
2f338ab5 181 }
2f338ab5 182 }
3319ef85 183
184 //commit left over documents, and finish up
185 $index->commit();
186
187 mtrace("-- $counter documents indexed");
188 mtrace("done.\n");
2f338ab5 189 }
2f338ab5 190 }
191 }
192 }
3319ef85 193
194/// finished modules
195
196 mtrace('Finished activity modules');
197 search_stopwatch();
198
199 mtrace(".<br/><a href='index.php'>Back to query page</a>.");
200 mtrace('</pre>');
2f338ab5 201
3319ef85 202/// finished, turn busy flag off
2f338ab5 203
3319ef85 204 set_config('search_indexer_busy', '0');
205
206/// mark the time we last updated
2f338ab5 207
3319ef85 208 set_config('search_indexer_run_date', time());
209
210/// and the index size
2f338ab5 211
3319ef85 212 set_config('search_index_size', (int)$index->count());
eef868d1 213
682d4032 214?>