move code up one directory
[atutor.git] / include / lib / search.inc.php
1 <?php
2 /************************************************************************/
3 /* ATutor                                                                                                                       */
4 /************************************************************************/
5 /* Copyright (c) 2002-2010                                              */
6 /* Inclusive Design Institute                                           */
7 /* http://atutor.ca                                                                                                     */
8 /*                                                                      */
9 /* This program is free software. You can redistribute it and/or        */
10 /* modify it under the terms of the GNU General Public License          */
11 /* as published by the Free Software Foundation.                                        */
12 /************************************************************************/
13 // $Id$
14
15 // NOTE! please see include/html/search.inc.php NOTE!
16
17 function score_cmp($a, $b) {
18     if ($a['score'] == $b['score']) {
19         return 0;
20     }
21     return ($a['score'] > $b['score']) ? -1 : 1;
22 }
23
24
25 function get_search_result($words, $predicate, $course_id, &$num_found, &$total_score){
26         global $_pages, $moduleFactory; 
27
28         $search_results                 = array();
29         $content_search_results = array();
30         $forums_search_results  = array();
31         $course_score                   = 0;
32
33         if (isset($_GET['search_within'])){
34                 if ($_GET['search_within'] == 'content'){
35                         $content_search_results = get_content_search_result($words, $predicate, $course_id, $total_score, $course_score);
36                         $search_results = $content_search_results;
37                 } elseif ($_GET['search_within'] == 'forums'){
38                         $forums_search_results = get_forums_search_result($words, $predicate, $course_id, $total_score, $course_score);
39                         // get all enabled modules
40                         $modules = $moduleFactory->getModules(AT_MODULE_STATUS_ENABLED, 0, TRUE);
41                         // if forum has been disabled, don't search in it. 
42                         if (isset($_SESSION['course_id']) && $_SESSION['course_id']==0){
43                                 $search_results = $forums_search_results;
44                         } elseif (isset($modules['_standard/forums'])){
45                                 $search_results = $forums_search_results;
46                         }
47                 } else {
48                         $content_search_results = get_content_search_result($words, $predicate, $course_id, $total_score, $course_score);
49                         $forums_search_results = get_forums_search_result($words, $predicate, $course_id, $total_score, $course_score);
50                         $search_results = array_merge($content_search_results, $forums_search_results);
51                 }               
52
53                 if ((count($search_results) == 0) && $course_score && ($_GET['display_as'] != 'pages')) {
54                                 $num_found++;
55                 }
56                 $num_found += count($search_results);
57         } 
58         return $search_results;
59 }
60
61 function get_content_search_result($words, $predicate, $course_id, &$total_score, &$course_score) {
62         global $addslashes, $db, $highlight_system_courses, $strlen, $substr, $strtolower;
63
64         $search_results = array();
65         $lower_words    = array();
66
67         $predicate = " $predicate "; // either 'AND' or 'OR'
68
69         $words = trim($words);
70         $words = explode(' ',$words);
71         $words = array_values(array_diff(array_unique($words), array('')));
72         $num_words = count($words);
73         $course_score = 0;
74         $words_sql = '';
75
76         for ($i=0; $i<$num_words; $i++) {
77                 $lower_words[$i] = $strtolower($words[$i]);
78
79                 if ($words_sql) {
80                         $words_sql .= $predicate;
81                 }
82                 $words[$i] = $addslashes($words[$i]);
83                 $words_sql .= ' (C.title LIKE "%'.$words[$i].'%" OR C.text LIKE "%'.$words[$i].'%" OR C.keywords LIKE "%'.$words[$i].'%")';
84
85                 /* search through the course title and description keeping track of its total */
86                 $course_score += 15 * substr_count($strtolower($highlight_system_courses[$course_id]['title']),       $lower_words[$i]);
87                 $course_score += 12 * substr_count($strtolower($highlight_system_courses[$course_id]['description']), $lower_words[$i]);
88
89                 $highlight_system_courses[$course_id]['title']       = highlight($highlight_system_courses[$course_id]['title'],       $words[$i]);
90                 $highlight_system_courses[$course_id]['description'] = highlight($highlight_system_courses[$course_id]['description'], $words[$i]);
91         }
92         if (!$words_sql) {
93                 return;
94         }
95
96         $sql =  'SELECT C.last_modified, C.course_id, C.content_id, C.title, C.text, C.keywords FROM '.TABLE_PREFIX.'content AS C WHERE C.course_id='.$course_id;
97         $sql .= ' AND ('.$words_sql.') LIMIT 200';
98
99         $result = mysql_query($sql, $db);
100         while($row = mysql_fetch_assoc($result)) {
101                 $score = 0;
102
103                 $row['title'] = strip_tags($row['title']);
104                 $row['text']  = strip_tags($row['text']);
105
106                 $lower_title     = $strtolower($row['title']);
107                 $lower_text              = $strtolower($row['text']);
108                 $lower_keywords  = $strtolower($row['keywords']);
109
110                 if ($strlen($row['text']) > 270) {
111                         $row['text']  = $substr($row['text'], 0, 268).'...';
112                 }
113
114                 for ($i=0; $i<$num_words; $i++) {
115                         $score += 8 * substr_count($lower_keywords, $lower_words[$i]); /* keywords are weighed more */
116                         $score += 4 * substr_count($lower_title,    $lower_words[$i]);    /* titles are weighed more */
117                         $score += 1 * substr_count($lower_text,     $lower_words[$i]);
118
119                         $row['title']     = highlight($row['title'],    $words[$i]);
120                         $row['text']      = highlight($row['text'],             $words[$i]);
121                         $row['keywords']  = highlight($row['keywords'], $words[$i]);
122
123                 }
124                 if ($score != 0) {
125                         $score += $course_score;
126                 }
127                 $row['score'] = $score;
128                 $search_results[] = $row;
129
130                 $total_score += $score;
131         }
132
133         if ($total_score == 0) {
134                 $total_score = $course_score;
135         }
136
137         return $search_results;
138 }
139
140 /*
141  * Get forum search results
142  * @author Harris Wong
143  */
144 function get_forums_search_result($words, $predicate, $course_id, &$total_score, &$course_score) {
145         global $addslashes, $db, $highlight_system_courses, $strlen, $substr, $strtolower;
146
147         $search_results = array();
148         $lower_words    = array();
149
150         $predicate = " $predicate "; // either 'AND' or 'OR'
151
152         $words = trim($words);
153         $words = explode(' ',$words);
154         $words = array_values(array_diff(array_unique($words), array('')));
155         $num_words = count($words);
156         $course_score = 0;
157         $words_sql = '';
158
159         for ($i=0; $i<$num_words; $i++) {
160                 $lower_words[$i] = $strtolower($words[$i]);
161
162                 if ($words_sql) {
163                         $words_sql .= $predicate;
164                 }
165                 $words[$i] = $addslashes($words[$i]);
166                 $words_sql .= ' (course_group_forums.title LIKE "%'.$words[$i].'%" OR T.subject LIKE "%'.$words[$i].'%" OR T.body LIKE "%'.$words[$i].'%")';
167
168                 /* search through the course title and description keeping track of its total */
169                 $course_score += 15 * substr_count($strtolower($highlight_system_courses[$course_id]['title']),       $lower_words[$i]);
170                 $course_score += 12 * substr_count($strtolower($highlight_system_courses[$course_id]['description']), $lower_words[$i]);
171         }
172
173         if (!$words_sql) {
174                 return;
175         }
176
177         //forums sql
178         // Wants to get course forums + "my" group forums 
179         //if the search is performed outside of a course, do not search in any group forums
180         // UNION on course_forums and group_forums
181         // TODO: Simplify the query.
182         ((isset($_SESSION['is_admin']) && $_SESSION['is_admin'] > 0) ? $is_admin_string = '1 OR ' : $is_admin_string = '');
183         (isset($_SESSION['member_id']) ? $member_id = $_SESSION['member_id'] : $member_id = 0);
184         $sql =  'SELECT course_group_forums.title AS forum_title, course_group_forums.course_id, T.* FROM '.TABLE_PREFIX.'forums_threads T RIGHT JOIN ';
185         
186         //course forums
187         $sql .= '(      SELECT forum_id, course_id, title, description, num_topics, num_posts, last_post, mins_to_edit FROM '.TABLE_PREFIX.'forums_courses ';
188         $sql .= '       NATURAL JOIN '.TABLE_PREFIX.'forums WHERE course_id='.$course_id;
189         
190         $sql .= '       UNION ';
191
192         //group forums 
193         $sql .= '       SELECT forum_id, course_id, title, description, num_topics, num_posts, last_post, mins_to_edit FROM '.TABLE_PREFIX.'forums_groups NATURAL JOIN ';
194         $sql .= '       (SELECT forum_id, num_topics, num_posts, last_post, mins_to_edit FROM '.TABLE_PREFIX.'forums) AS f NATURAL JOIN ';
195         $sql .= '       '.TABLE_PREFIX.'groups_members NATURAL JOIN ';
196         $sql .= '       (SELECT g.*, gt.course_id FROM '.TABLE_PREFIX.'groups g INNER JOIN '.TABLE_PREFIX.'groups_types gt USING (type_id) WHERE ';
197         $sql .= '       course_id='.$course_id.') AS group_course WHERE '.$is_admin_string .'member_id='.$member_id;
198         $sql .= ') AS course_group_forums ';
199         
200         $sql .= 'USING (forum_id) ';
201         $sql .= 'WHERE ' . $words_sql;
202
203         $result = mysql_query($sql, $db);
204         while($row = mysql_fetch_assoc($result)) {
205                 $score = 0;
206
207                 $row['forum_title'] = strip_tags($row['forum_title']);
208                 $row['subject']  = strip_tags($row['subject']);
209                 $row['body']  = strip_tags($row['body']);
210                 
211                 $lower_forum_title      = $strtolower($row['forum_title']);
212                 $lower_subject          = $strtolower($row['subject']);
213                 $lower_body                     = $strtolower($row['body']);
214                 $num_posts                      = intval($row['num_comments']);
215
216                 if ($strlen($row['body']) > 270) {
217                         $row['body']  = $substr($row['body'], 0, 268).'...';
218                 }
219
220                 for ($i=0; $i<$num_words; $i++) {
221                         $score += 8 * substr_count($lower_forum_title,  $lower_words[$i]);              /* forum's title are weighed more */
222                         $score += 4 * substr_count($lower_subject,              $lower_words[$i]);              /* thread subject are weighed more */
223                         $score += 2 * substr_count($lower_body,                 $lower_words[$i]);
224                         $score += 1 * $num_posts;
225
226                         $row['forum_title']     = highlight($row['forum_title'], $words[$i]);
227                         $row['subject']         = highlight($row['subject'], $words[$i]);
228                         $row['body']            = highlight($row['body'], $words[$i]);
229
230                 }
231                 if ($score != 0) {
232                         $score += $course_score;
233                 }
234                 $row['score'] = $score;
235                 $search_results[] = $row;
236
237                 $total_score += $score;
238         }
239
240         return $search_results;
241
242 }
243
244
245 // My Courses - All courses you're enrolled in (including hidden)
246 function get_my_courses($member_id) {
247         global $db;
248
249         $list = array();
250
251         $sql = "SELECT course_id FROM ".TABLE_PREFIX."course_enrollment WHERE member_id=$member_id AND (approved='y' OR approved='a')";
252         $result = mysql_query($sql, $db);
253         while ($row = mysql_fetch_assoc($result)) {
254                 $list[] = $row['course_id']; // list contains all the Course IDs
255         }
256
257         return $list;
258 }
259
260
261 // All courses (display hidden too if you're enrolled in it)
262 function get_all_courses($member_id) {
263         global $system_courses, $db;
264
265         $list = array();
266
267         $num_courses = count($system_courses);
268
269         // add all the courses that are not hidden,then find the hidden courses that you're enrolled in and then add that to array
270         foreach ($system_courses as $course_id => $course_info) {
271                 if (!$course_info['hide']) {
272                         $list[] = $course_id;
273                 }
274         }
275
276         // if there aren't any hidden courses:
277         if (count($system_courses) == count($list)) {
278                 return $list;
279         }
280
281         if ($_SESSION['valid_user']) {
282                 $my_courses = implode(',', get_my_courses($member_id));
283                 $sql = "SELECT course_id FROM ".TABLE_PREFIX."courses WHERE hide=1 AND course_id IN (0, $my_courses)";
284                 $result = mysql_query($sql, $db);
285                 while ($row = mysql_fetch_assoc($result)) {
286                         $list[] = $row['course_id'];
287                 }
288         }
289         return $list;
290 }
291
292 function print_search_pages($result) {
293         global $count;
294
295         foreach ($result as $items) {
296                 uasort($result, 'score_cmp');
297
298                 echo '<h5>' . $count . '. ';
299                 
300                 if(isset($items['forum_title'])){
301                         //Forum
302                         if ($_SESSION['course_id'] != $items['course_id']) {
303                                 echo '<a href="bounce.php?course='.$items['course_id'].SEP.'p='.urlencode('forum/view.php?fid='.$items['forum_id'].SEP.'pid='.$items['post_id'].SEP.'words='.$_GET['words']).'">'.$items['forum_title'].' - '.$items['subject'].'</a> ';
304                         } else {
305                                 echo '<a href="'.url_rewrite('mods/_standard/forums/forum/view.php?fid='.$items['forum_id'].SEP.'pid='.$items['post_id'].SEP.'words='.$_GET['words']).'">'.$items['forum_title'].' - '.$items['subject'].'</a> ';
306                         }
307                         echo '</h5>'."\n";
308
309                         echo '<p><small>'.$items['body'];
310                 } else {
311                         //Content
312                         if ($_SESSION['course_id'] != $items['course_id']) {
313                                 echo '<a href="bounce.php?course='.$items['course_id'].SEP.'p='.urlencode('content.php?cid='.$items['content_id'].SEP.'words='.$_GET['words']).'">'.$items['title'].'</a> ';
314                         } else {
315                                 echo '<a href="'.url_rewrite('content.php?cid='.$items['content_id'].SEP.'words='.$_GET['words']).'">'.$items['title'].'</a> ';
316                         }
317                         echo '</h5>'."\n";
318
319                         echo '<p><small>'.$items['text'];
320                 }
321
322                 echo '<br /><small class="search-info">[<strong>'._AT('keywords').':</strong> ';
323                 if (isset($items['keywords'])) {
324                         echo $items['keywords'];
325                 } else {
326                         echo '<strong>'._AT('none').'</strong>';
327                 }
328                 echo '. <strong>'._AT('author').':</strong> ';
329                 if (isset($items['member_id'])) {
330                         echo AT_print(get_display_name($items['member_id']), 'members.login');
331                 } else {
332                         echo '<strong>'._AT('none').'</strong>';
333                 }
334                 echo '. <strong>'._AT('updated').':</strong> ';
335                 echo AT_date(_AT('inbox_date_format'), (isset($items['last_modified']) && $items['last_modified']!='')?$items['last_modified']:$items['last_comment'], AT_DATE_MYSQL_DATETIME);
336
337                 echo ']</small>';
338
339                 echo '</small></p>'."\n";
340                 $count++;
341         }
342 }
343
344 ?>