Merge branch 'wip-MDL-29231-master' of git://github.com/phalacee/moodle
[moodle.git] / search / lib.php
blobd93a633f810e974b05d102351793c8997208286c
1 <?php
2 /**
3 * Global Search Engine for Moodle
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 * @version prepared for 2.0
11 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
13 * General function library
15 * This file must not contain any PHP 5, because it is used to test for PHP 5
16 * itself, and needs to be able to be executed on PHP 4 installations.
20 /**
21 * Constants
23 define('SEARCH_INDEX_PATH', $CFG->dataroot.'/search');
24 define('SEARCH_DATABASE_TABLE', 'block_search_documents');
26 // get document types
27 include_once $CFG->dirroot.'/search/searchtypes.php';
29 /**
30 * collects all searchable items identities
31 * @param boolean $namelist if true, only returns list of names of searchable items
32 * @param boolean $verbose if true, prints a discovering status
33 * @return an array of names or an array of type descriptors
35 function search_collect_searchables($namelist=false, $verbose=true){
36 global $CFG, $DB;
38 $searchables = array();
39 $searchables_names = array();
41 /// get all installed modules
42 if ($mods = $DB->get_records('modules', null, 'name', 'id,name')){
44 $searchabletypes = array_values(search_get_document_types());
46 foreach($mods as $mod){
47 $plugin = new StdClass();
48 $plugin->name = $mod->name;
49 $plugin->type = 'mod';
50 if (in_array($mod->name, $searchabletypes)){
51 $plugin->location = 'internal';
52 $searchables[$plugin->name] = $plugin;
53 $searchables_names[] = $mod->name;
54 } else {
55 $documentfile = $CFG->dirroot."/mod/{$mod->name}/search_document.php";
56 $plugin->location = 'mod';
57 if (file_exists($documentfile)){
58 $searchables[$plugin->name] = $plugin;
59 $searchables_names[] = $mod->name;
63 if ($verbose) mtrace(count($searchables).' modules to search in / '.count($mods).' modules found.');
66 /// collects blocks as indexable information may be found in blocks either
67 if ($blocks = $DB->get_records('block', null, 'name', 'id,name')) {
68 $blocks_searchables = array();
69 // prepend the "block_" prefix to discriminate document type plugins
70 foreach($blocks as $block){
71 $plugin = new StdClass();
72 $plugin->dirname = $block->name;
73 $plugin->name = 'block_'.$block->name;
74 if (in_array('SEARCH_TYPE_'.strtoupper($block->name), $searchabletypes)){
75 $plugin->location = 'internal';
76 $plugin->type = 'block';
77 $blocks_searchables[$plugin->name] = $plugin;
78 $searchables_names[] = $plugin->name;
79 } else {
80 $documentfile = $CFG->dirroot."/blocks/{$plugin->dirname}/search_document.php";
81 if (file_exists($documentfile)){
82 $plugin->location = 'blocks';
83 $plugin->type = 'block';
84 $blocks_searchables[$plugin->name] = $plugin;
85 $searchables_names[] = $plugin->name;
89 if ($verbose) mtrace(count($blocks_searchables).' blocks to search in / '.count($blocks).' blocks found.');
90 $searchables = array_merge($searchables, $blocks_searchables);
93 /// add virtual modules onto the back of the array
95 $additional = search_get_additional_modules($searchables_names);
96 if (!empty($additional)){
97 if ($verbose) mtrace(count($additional).' additional to search in.');
98 $searchables = array_merge($searchables, $additional);
101 if ($namelist)
102 return $searchables_names;
103 return $searchables;
107 * returns all the document type constants that are known in core implementation
108 * @param prefix a pattern for recognizing constants
109 * @return an array of type labels
111 function search_get_document_types($prefix = 'SEARCH_TYPE_') {
112 $ret = array();
113 foreach (get_defined_constants() as $key => $value) {
114 if (preg_match("/^{$prefix}/", $key)){
115 $ret[$key] = $value;
118 sort($ret);
119 return $ret;
123 * additional virtual modules to index
125 * By adding 'moo' to the extras array, an additional document type
126 * documents/moo_document.php will be indexed - this allows for
127 * virtual modules to be added to the index, i.e. non-module specific
128 * information.
130 function search_get_additional_modules(&$searchables_names) {
131 $extras = array(/* additional keywords go here */);
132 if (defined('SEARCH_EXTRAS')){
133 $extras = explode(',', SEARCH_EXTRAS);
136 $ret = array();
137 $temp = new StdClass;
138 foreach($extras as $extra) {
139 $plugin = new StdClass();
140 $plugin->name = $extra;
141 $plugin->location = 'internal';
142 eval('$plugin->type = TYPE_FOR_SEARCH_TYPE_'.strtoupper($extra).';');
143 $ret[$plugin->name] = $plugin;
144 $searchables_names[] = $extra;
147 return $ret;
151 * shortens a url so it can fit on the results page
152 * @param url the url
153 * @param length the size limit we want
155 function search_shorten_url($url, $length=30) {
156 return substr($url, 0, $length)."...";
160 * simple timer function, on first call, records a current microtime stamp, outputs result on 2nd call
161 * @param cli an output formatting switch
162 * @return void
164 function search_stopwatch($cli = false) {
165 if (!empty($GLOBALS['search_script_start_time'])) {
166 if (!$cli) print '<em>';
167 print round(microtime(true) - $GLOBALS['search_script_start_time'], 6).' '.get_string('seconds', 'search');
168 if (!$cli) print '</em>';
169 unset($GLOBALS['search_script_start_time']);
170 } else {
171 $GLOBALS['search_script_start_time'] = microtime(true);
176 * print and exit (for debugging)
177 * @param str a variable to explore
178 * @return void
180 function search_pexit($str = "") {
181 if (is_array($str) or is_object($str)) {
182 print_r($str);
183 } else if ($str) {
184 print $str."<br/>";
186 exit(0);
189 function search_updatedcallback($name) {
190 global $CFG, $DB;
191 // set block to hidden when global search is disabled.
192 if ($CFG->enableglobalsearch != 1) {
193 $DB->set_field('block', 'visible', 0, array('name'=>'search')); // Hide block