Merge branch 'MDL-27515_m19' of git://github.com/rwijaya/moodle into MOODLE_19_STABLE
[moodle.git] / search / lib.php
blob6e3e98171d67dd48eda4e1c3e5431032a02edfa8
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 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
12 * General function library
14 * This file must not contain any PHP 5, because it is used to test for PHP 5
15 * itself, and needs to be able to be executed on PHP 4 installations.
19 /**
20 * Constants
22 define('SEARCH_INDEX_PATH', "{$CFG->dataroot}/search");
23 define('SEARCH_DATABASE_TABLE', 'block_search_documents');
25 // get document types
26 include "{$CFG->dirroot}/search/searchtypes.php";
28 /**
29 * collects all searchable items identities
30 * @param boolean $namelist if true, only returns list of names of searchable items
31 * @param boolean $verbose if true, prints a discovering status
32 * @return an array of names or an array of type descriptors
34 function search_collect_searchables($namelist=false, $verbose=true){
35 global $CFG;
37 $searchables = array();
38 $searchables_names = array();
40 /// get all installed modules
41 if ($mods = get_records('modules', '', '', 'name', 'id,name')){
43 $searchabletypes = array_values(search_get_document_types());
45 foreach($mods as $mod){
46 if (in_array($mod->name, $searchabletypes)){
47 $mod->location = 'internal';
48 $searchables[$mod->name] = $mod;
49 $searchables_names[] = $mod->name;
50 } else {
51 $documentfile = $CFG->dirroot."/mod/{$mod->name}/search_document.php";
52 $mod->location = 'mod';
53 if (file_exists($documentfile)){
54 $searchables[$mod->name] = $mod;
55 $searchables_names[] = $mod->name;
59 if ($verbose) mtrace(count($searchables).' modules to search in / '.count($mods).' modules found.');
62 /// collects blocks as indexable information may be found in blocks either
63 if ($blocks = get_records('block', '', '', 'name', 'id,name')) {
64 $blocks_searchables = array();
65 // prepend the "block_" prefix to discriminate document type plugins
66 foreach($blocks as $block){
67 $block->dirname = $block->name;
68 $block->name = 'block_'.$block->name;
69 if (in_array('SEARCH_TYPE_'.strtoupper($block->name), $searchabletypes)){
70 $mod->location = 'internal';
71 $blocks_searchables[] = $block;
72 $searchables_names[] = $block->name;
73 } else {
74 $documentfile = $CFG->dirroot."/blocks/{$block->dirname}/search_document.php";
75 if (file_exists($documentfile)){
76 $mod->location = 'blocks';
77 $blocks_searchables[$block->name] = $block;
78 $searchables_names[] = $block->name;
82 if ($verbose) mtrace(count($blocks_searchables).' blocks to search in / '.count($blocks).' blocks found.');
83 $searchables = array_merge($searchables, $blocks_searchables);
86 /// add virtual modules onto the back of the array
88 $additional = search_get_additional_modules();
89 if (!empty($additional)){
90 if ($verbose) mtrace(count($additional).' additional to search in.');
91 $searchables = array_merge($searchables, $additional);
94 if ($namelist)
95 return $searchables_names;
96 return $searchables;
99 /**
100 * returns all the document type constants that are known in core implementation
101 * @param prefix a pattern for recognizing constants
102 * @return an array of type labels
104 function search_get_document_types($prefix = 'SEARCH_TYPE_') {
105 $ret = array();
106 foreach (get_defined_constants() as $key => $value) {
107 if (preg_match("/^{$prefix}/", $key)){
108 $ret[$key] = $value;
111 sort($ret);
112 return $ret;
116 * additional virtual modules to index
118 * By adding 'moo' to the extras array, an additional document type
119 * documents/moo_document.php will be indexed - this allows for
120 * virtual modules to be added to the index, i.e. non-module specific
121 * information.
123 function search_get_additional_modules() {
124 $extras = array(/* additional keywords go here */);
125 if (defined('SEARCH_EXTRAS')){
126 $extras = explode(',', SEARCH_EXTRAS);
129 $ret = array();
130 $temp = new StdClass;
131 foreach($extras as $extra) {
132 $temp->name = $extra;
133 $temp->location = 'internal';
134 $ret[$temp->name] = clone($temp);
136 return $ret;
137 } //search_get_additional_modules
140 * shortens a url so it can fit on the results page
141 * @param url the url
142 * @param length the size limit we want
144 function search_shorten_url($url, $length=30) {
145 return substr($url, 0, $length)."...";
146 } //search_shorten_url
149 * a local function for escaping
150 * @param str the string to escape
151 * @return the escaped string
153 function search_escape_string($str) {
154 global $CFG;
156 switch ($CFG->dbfamily) {
157 case 'mysql':
158 $s = mysql_real_escape_string($str);
159 break;
160 case 'postgres':
161 $s = pg_escape_string($str);
162 break;
163 default:
164 $s = addslashes($str);
166 return $s;
167 } //search_escape_string
170 * simple timer function, on first call, records a current microtime stamp, outputs result on 2nd call
171 * @param cli an output formatting switch
172 * @return void
174 function search_stopwatch($cli = false) {
175 if (!empty($GLOBALS['search_script_start_time'])) {
176 if (!$cli) print '<em>';
177 print round(microtime(true) - $GLOBALS['search_script_start_time'], 6).' '.get_string('seconds', 'search');
178 if (!$cli) print '</em>';
179 unset($GLOBALS['search_script_start_time']);
181 else {
182 $GLOBALS['search_script_start_time'] = microtime(true);
184 } //search_stopwatch
187 * print and exit (for debugging)
188 * @param str a variable to explore
189 * @return void
191 function search_pexit($str = "") {
192 if (is_array($str) or is_object($str)) {
193 print_r($str);
194 } else if ($str) {
195 print $str."<br/>";
197 exit(0);
198 } //search_pexit