|
1 <?php |
|
2 /*********************************************************************** |
|
3 |
|
4 Copyright (C) 2002-2008 PunBB.org |
|
5 |
|
6 This file is part of PunBB. |
|
7 |
|
8 PunBB is free software; you can redistribute it and/or modify it |
|
9 under the terms of the GNU General Public License as published |
|
10 by the Free Software Foundation; either version 2 of the License, |
|
11 or (at your option) any later version. |
|
12 |
|
13 PunBB is distributed in the hope that it will be useful, but |
|
14 WITHOUT ANY WARRANTY; without even the implied warranty of |
|
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
16 GNU General Public License for more details. |
|
17 |
|
18 You should have received a copy of the GNU General Public License |
|
19 along with this program; if not, write to the Free Software |
|
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, |
|
21 MA 02111-1307 USA |
|
22 |
|
23 ************************************************************************/ |
|
24 |
|
25 |
|
26 // if (!defined('PUN_ROOT')) |
|
27 // define('PUN_ROOT', './'); |
|
28 // require PUN_ROOT.'include/common.php'; |
|
29 |
|
30 // import globals (I really hope this isn't dangerous) |
|
31 foreach ( $GLOBALS as $key => $_ ) |
|
32 { |
|
33 $$key =& $GLOBALS[$key]; |
|
34 } |
|
35 |
|
36 ($hook = get_hook('se_start')) ? eval($hook) : null; |
|
37 |
|
38 // Load the search.php language file |
|
39 require PUN_ROOT.'lang/'.$pun_user['language'].'/search.php'; |
|
40 |
|
41 if ($pun_user['g_read_board'] == '0') |
|
42 message($lang_common['No view']); |
|
43 else if ($pun_user['g_search'] == '0') |
|
44 message($lang_search['No search permission']); |
|
45 |
|
46 |
|
47 // Figure out what to do :-) |
|
48 if (isset($_GET['action']) || isset($_GET['search_id'])) |
|
49 { |
|
50 // Grab and validate all the submitted data |
|
51 $action = (isset($_GET['action'])) ? $_GET['action'] : null; |
|
52 $value = (isset($_GET['value'])) ? intval($_GET['value']) : 86400; |
|
53 $forum = (isset($_GET['forum'])) ? intval($_GET['forum']) : -1; |
|
54 $sort_dir = (isset($_GET['sort_dir'])) ? (($_GET['sort_dir'] == 'DESC') ? 'DESC' : 'ASC') : 'DESC'; |
|
55 if (isset($search_id)) unset($search_id); |
|
56 |
|
57 // If a search_id was supplied |
|
58 if (isset($_GET['search_id'])) |
|
59 { |
|
60 $search_id = intval($_GET['search_id']); |
|
61 if ($db_type == 'mysql' || $db_type == 'mysqli') |
|
62 message($lang_common['Bad request']); |
|
63 if ($search_id < 1) |
|
64 message($lang_common['Bad request']); |
|
65 } |
|
66 |
|
67 // A list of valid actions (extensions can add their own actions to the array) |
|
68 $valid_actions = array('search', 'show_new', 'show_recent', 'show_user_posts', 'show_user_topics', 'show_subscriptions', 'show_unanswered'); |
|
69 |
|
70 ($hook = get_hook('se_search_selected')) ? eval($hook) : null; |
|
71 |
|
72 // Validate action |
|
73 if ($action && !in_array($action, $valid_actions)) |
|
74 message($lang_common['Bad request']); |
|
75 |
|
76 // If it's a regular search (keywords and/or author) |
|
77 if ($action == 'search') |
|
78 { |
|
79 $keywords = (isset($_GET['keywords'])) ? strtolower(trim($_GET['keywords'])) : null; |
|
80 $author = (isset($_GET['author'])) ? strtolower(trim($_GET['author'])) : null; |
|
81 |
|
82 if (preg_match('#^[\*%]+$#', $keywords) || pun_strlen(str_replace(array('*', '%'), '', $keywords)) < 3) |
|
83 $keywords = ''; |
|
84 |
|
85 if (preg_match('#^[\*%]+$#', $author) || pun_strlen(str_replace(array('*', '%'), '', $author)) < 2) |
|
86 $author = ''; |
|
87 |
|
88 if (!$keywords && !$author) |
|
89 message($lang_search['No terms']); |
|
90 |
|
91 if ($author) |
|
92 $author = str_replace('*', '%', $author); |
|
93 |
|
94 $show_as = (isset($_GET['show_as'])) ? $_GET['show_as'] : 'posts'; |
|
95 $sort_by = (isset($_GET['sort_by'])) ? intval($_GET['sort_by']) : null; |
|
96 $search_in = (!isset($_GET['search_in']) || $_GET['search_in'] == 'all') ? 0 : (($_GET['search_in'] == 'message') ? 1 : -1); |
|
97 |
|
98 } |
|
99 // If it's a user search (by id), make sure we have a user_id |
|
100 else if ($action == 'show_user_posts' || $action == 'show_user_topics') |
|
101 { |
|
102 $user_id = isset($_GET['user_id']) ? intval($_GET['user_id']) : 0; |
|
103 if ($user_id < 2) |
|
104 message($lang_common['Bad request']); |
|
105 } |
|
106 |
|
107 // First of all lets find out if we need to cache the results, we only need to do this for detailed queries, not quicksearches or for mysql(i) |
|
108 if ($db_type != 'mysql' && $db_type != 'mysqli' && (isset($keywords) || isset($author))) |
|
109 { |
|
110 // We need to grab results, insert them into the cache and reload with a search id before showing them |
|
111 $keyword_results = $author_results = array(); |
|
112 |
|
113 // If it's a search for keywords |
|
114 if ($keywords) |
|
115 { |
|
116 $stopwords = (array)@file(PUN_ROOT.'lang/'.$pun_user['language'].'/stopwords.txt'); |
|
117 $stopwords = array_map('trim', $stopwords); |
|
118 |
|
119 // Filter out non-alphabetical chars |
|
120 $noise_match = array('^', '$', '&', '(', ')', '<', '>', '`', '\'', '"', '|', ',', '@', '_', '?', '%', '~', '[', ']', '{', '}', ':', '\\', '/', '=', '#', '\'', ';', '!', 'ยค'); |
|
121 $noise_replace = array(' ', ' ', ' ', ' ', ' ', ' ', ' ', '', '', ' ', ' ', ' ', ' ', '', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '' , ' ', ' ', ' ', ' ', ' ', ' ', ' '); |
|
122 $keywords = str_replace($noise_match, $noise_replace, $keywords); |
|
123 |
|
124 // Strip out excessive whitespace |
|
125 $keywords = trim(preg_replace('#\s+#', ' ', $keywords)); |
|
126 |
|
127 // Fill an array with all the words |
|
128 $keywords_array = explode(' ', $keywords); |
|
129 if (empty($keywords_array)) |
|
130 message($lang_search['No hits']); |
|
131 |
|
132 while (list($i, $word) = @each($keywords_array)) |
|
133 { |
|
134 $num_chars = pun_strlen($word); |
|
135 |
|
136 if ($word !== 'or' && ($num_chars < 3 || $num_chars > 20 || in_array($word, $stopwords))) |
|
137 unset($keywords_array[$i]); |
|
138 } |
|
139 |
|
140 $word_count = 0; |
|
141 $match_type = 'and'; |
|
142 $result_list = array(); |
|
143 @reset($keywords_array); |
|
144 while (list(, $cur_word) = @each($keywords_array)) |
|
145 { |
|
146 switch ($cur_word) |
|
147 { |
|
148 case 'and': |
|
149 case 'or': |
|
150 case 'not': |
|
151 $match_type = $cur_word; |
|
152 break; |
|
153 |
|
154 default: |
|
155 { |
|
156 $cur_word = str_replace('*', '%', $cur_word); |
|
157 |
|
158 $query = array( |
|
159 'SELECT' => 'm.post_id', |
|
160 'FROM' => 'search_words AS w', |
|
161 'JOINS' => array( |
|
162 array( |
|
163 'INNER JOIN' => 'search_matches AS m', |
|
164 'ON' => 'm.word_id=w.id' |
|
165 ) |
|
166 ), |
|
167 'WHERE' => 'w.word LIKE \''.$cur_word.'\'' |
|
168 ); |
|
169 |
|
170 // Search in what? |
|
171 if ($search_in) |
|
172 $query['WHERE'] .= ($search_in > 0 ? ' AND m.subject_match=0' : ' AND m.subject_match=1'); |
|
173 |
|
174 ($hook = get_hook('se_qr_get_keyword_hits')) ? eval($hook) : null; |
|
175 $result = $pun_db->query_build($query, true) or error(__FILE__, __LINE__); |
|
176 |
|
177 $row = array(); |
|
178 while ($temp = $pun_db->fetch_row($result)) |
|
179 { |
|
180 $row[$temp[0]] = 1; |
|
181 |
|
182 if (!$word_count) |
|
183 $result_list[$temp[0]] = 1; |
|
184 else if ($match_type == 'or') |
|
185 $result_list[$temp[0]] = 1; |
|
186 else if ($match_type == 'not') |
|
187 $result_list[$temp[0]] = 0; |
|
188 } |
|
189 |
|
190 if ($match_type == 'and' && $word_count) |
|
191 { |
|
192 @reset($result_list); |
|
193 while (list($post_id,) = @each($result_list)) |
|
194 { |
|
195 if (!isset($row[$post_id])) |
|
196 $result_list[$post_id] = 0; |
|
197 } |
|
198 } |
|
199 |
|
200 ++$word_count; |
|
201 $pun_db->free_result($result); |
|
202 |
|
203 break; |
|
204 } |
|
205 } |
|
206 } |
|
207 |
|
208 @reset($result_list); |
|
209 while (list($post_id, $matches) = @each($result_list)) |
|
210 { |
|
211 if ($matches) |
|
212 $keyword_results[] = $post_id; |
|
213 } |
|
214 |
|
215 unset($result_list); |
|
216 } |
|
217 |
|
218 // If it's a search for author name (and that author name isn't Guest) |
|
219 if ($author && strtolower($author) != 'guest' && strtolower($author) != strtolower($lang_common['Guest'])) |
|
220 { |
|
221 $query = array( |
|
222 'SELECT' => 'u.id', |
|
223 'FROM' => 'users AS u', |
|
224 'WHERE' => 'u.username '.($db_type == 'pgsql' ? 'ILIKE' : 'LIKE').' \''.$pun_db->escape($author).'\'' |
|
225 ); |
|
226 |
|
227 ($hook = get_hook('se_qr_get_author')) ? eval($hook) : null; |
|
228 $result = $pun_db->query_build($query) or error(__FILE__, __LINE__); |
|
229 |
|
230 if ($pun_db->num_rows($result)) |
|
231 { |
|
232 $user_ids = ''; |
|
233 while ($row = $pun_db->fetch_row($result)) |
|
234 $user_ids .= (($user_ids != '') ? ',' : '').$row[0]; |
|
235 |
|
236 $query = array( |
|
237 'SELECT' => 'p.id', |
|
238 'FROM' => 'posts AS p', |
|
239 'WHERE' => 'p.poster_id IN('.$user_ids.')' |
|
240 ); |
|
241 |
|
242 ($hook = get_hook('se_qr_get_author_hits')) ? eval($hook) : null; |
|
243 $result = $pun_db->query_build($query) or error(__FILE__, __LINE__); |
|
244 |
|
245 $search_ids = array(); |
|
246 while ($row = $pun_db->fetch_row($result)) |
|
247 $author_results[] = $row[0]; |
|
248 |
|
249 $pun_db->free_result($result); |
|
250 } |
|
251 } |
|
252 |
|
253 if ($author && $keywords) |
|
254 { |
|
255 // If we searched for both keywords and author name we want the intersection between the results |
|
256 $search_ids = array_intersect($keyword_results, $author_results); |
|
257 unset($keyword_results, $author_results); |
|
258 } |
|
259 else if ($keywords) |
|
260 $search_ids = $keyword_results; |
|
261 else |
|
262 $search_ids = $author_results; |
|
263 |
|
264 if (count($search_ids) == 0) |
|
265 message($lang_search['No hits']); |
|
266 |
|
267 |
|
268 // Setup the default show_as topics search |
|
269 $query = array( |
|
270 'SELECT' => 't.id', |
|
271 'FROM' => 'posts AS p', |
|
272 'JOINS' => array( |
|
273 array( |
|
274 'INNER JOIN' => 'topics AS t', |
|
275 'ON' => 't.id=p.topic_id' |
|
276 ), |
|
277 array( |
|
278 'LEFT JOIN' => 'forum_perms AS fp', |
|
279 'ON' => '(fp.forum_id=t.forum_id AND fp.group_id='.$pun_user['g_id'].')' |
|
280 ) |
|
281 ), |
|
282 'WHERE' => '(fp.read_forum IS NULL OR fp.read_forum=1) AND p.id IN('.implode(',', $search_ids).')', |
|
283 'GROUP BY' => 't.id' |
|
284 ); |
|
285 |
|
286 // Search a specific forum? |
|
287 if ($forum != -1 || ($forum == -1 && $pun_config['o_search_all_forums'] == '0' && !$pun_user['is_admmod'])) |
|
288 $query['WHERE'] .= ' AND t.forum_id = '.$forum; |
|
289 |
|
290 // Adjust the query if show_as posts |
|
291 if ($show_as == 'posts') |
|
292 { |
|
293 $query['SELECT'] = 'p.id'; |
|
294 unset($query['GROUP BY']); |
|
295 } |
|
296 |
|
297 ($hook = get_hook('se_qr_get_hits')) ? eval($hook) : null; |
|
298 $result = $pun_db->query_build($query, true) or error(__FILE__, __LINE__); |
|
299 |
|
300 $search_ids = array(); |
|
301 while ($row = $pun_db->fetch_row($result)) |
|
302 $search_ids[] = $row[0]; |
|
303 |
|
304 |
|
305 // Prune "old" search results |
|
306 $query = array( |
|
307 'SELECT' => 'o.ident', |
|
308 'FROM' => 'online AS o' |
|
309 ); |
|
310 |
|
311 ($hook = get_hook('se_qr_get_online_idents')) ? eval($hook) : null; |
|
312 $result = $pun_db->query_build($query) or error(__FILE__, __LINE__); |
|
313 if ($pun_db->num_rows($result)) |
|
314 { |
|
315 $online_idents = array(); |
|
316 while ($row = $pun_db->fetch_row($result)) |
|
317 $online_idents[] = '\''.$pun_db->escape($row[0]).'\''; |
|
318 |
|
319 $query = array( |
|
320 'DELETE' => 'search_cache', |
|
321 'WHERE' => 'ident NOT IN('.implode(',', $online_idents).')' |
|
322 ); |
|
323 |
|
324 ($hook = get_hook('se_qr_delete_old_cached_searches')) ? eval($hook) : null; |
|
325 $pun_db->query_build($query) or error(__FILE__, __LINE__); |
|
326 } |
|
327 |
|
328 // Final search results |
|
329 $search_results = implode(',', $search_ids); |
|
330 |
|
331 // Fill an array with our results and search properties |
|
332 $temp['search_results'] = $search_results; |
|
333 $temp['sort_by'] = $sort_by; |
|
334 $temp['sort_dir'] = $sort_dir; |
|
335 $temp['show_as'] = $show_as; |
|
336 $temp = serialize($temp); |
|
337 $search_id = mt_rand(1, 2147483647); |
|
338 |
|
339 $ident = ($pun_user['is_guest']) ? get_remote_address() : $pun_user['username']; |
|
340 |
|
341 $query = array( |
|
342 'INSERT' => 'id, ident, search_data', |
|
343 'INTO' => 'search_cache', |
|
344 'VALUES' => $search_id.', \''.$pun_db->escape($ident).'\', \''.$pun_db->escape($temp).'\'' |
|
345 ); |
|
346 |
|
347 ($hook = get_hook('se_qr_cache_search')) ? eval($hook) : null; |
|
348 $pun_db->query_build($query) or error(__FILE__, __LINE__); |
|
349 |
|
350 $pun_db->end_transaction(); |
|
351 $pun_db->close(); |
|
352 |
|
353 // Redirect the user to the cached result page |
|
354 header('Location: '.str_replace('&', '&', pun_link($pun_url['search_results'], $search_id))); |
|
355 exit; |
|
356 } |
|
357 |
|
358 // If we're still running we don't need to cache results but we still need to get them, either from the cache or from their respective sources. |
|
359 |
|
360 // We're doing a fulltext search! |
|
361 else if (($db_type == 'mysql' || $db_type == 'mysqli') && (isset($keywords) || isset($author))) |
|
362 { |
|
363 // Are we limiting the results to a specific forum? |
|
364 if ($forum != -1 || ($forum == -1 && $pun_config['o_search_all_forums'] == '0' && !$pun_user['is_admmod'])) |
|
365 $forum_where = ' AND f.id = '.$forum; |
|
366 else |
|
367 $forum_where = ''; |
|
368 |
|
369 // Sort out how to order the results |
|
370 switch ($sort_by) |
|
371 { |
|
372 case 1: |
|
373 $sort_by_sql = ($show_as == 'topics') ? 'poster' : 'p.poster'; |
|
374 break; |
|
375 |
|
376 case 2: |
|
377 $sort_by_sql = 'subject'; |
|
378 break; |
|
379 |
|
380 case 3: |
|
381 $sort_by_sql = 'forum_id'; |
|
382 break; |
|
383 |
|
384 case 4: |
|
385 if ($show_as == 'posts') |
|
386 $sort_by_sql = 'MATCH(p.message) AGAINST(\''.$pun_db->escape($keywords).'\')'; |
|
387 else |
|
388 $sort_by_sql = 'total_relevance'; |
|
389 break; |
|
390 |
|
391 default: |
|
392 $sort_by_sql = ($show_as == 'topics') ? 'posted' : 'p.posted'; |
|
393 break; |
|
394 } |
|
395 |
|
396 // Generate the query to give us our results |
|
397 if ($show_as == 'posts') |
|
398 $query = ' |
|
399 SELECT |
|
400 p.id AS pid, p.poster AS pposter, p.posted AS pposted, p.poster_id, SUBSTRING(p.message, 1, 1000) AS message, t.id AS tid, t.poster, t.subject, t.first_post_id, t.posted, t.last_post, t.last_post_id, t.last_poster, t.num_replies, t.forum_id, f.forum_name |
|
401 FROM '.$pun_db->prefix.'posts AS p LEFT JOIN '.$pun_db->prefix.'topics AS t ON t.id=p.topic_id LEFT JOIN '.$pun_db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$pun_db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') |
|
402 WHERE |
|
403 (fp.read_forum IS NULL OR fp.read_forum=1) |
|
404 '.($author ? 'AND p.poster LIKE \''.$pun_db->escape($author).'\'' : '').' |
|
405 '.($keywords ? 'AND MATCH(p.message) AGAINST(\''.$pun_db->escape($keywords).'\' IN BOOLEAN MODE)' : '').' |
|
406 '.$forum_where.' |
|
407 ORDER BY '.$sort_by_sql.' '.$sort_dir; |
|
408 else |
|
409 { |
|
410 $query = ' |
|
411 SELECT |
|
412 *, SUM(relevance) AS total_relevance FROM |
|
413 ( |
|
414 SELECT |
|
415 t.id AS tid, t.poster, t.subject, t.first_post_id, t.last_post, t.last_post_id, t.last_poster, t.num_replies, t.closed, t.forum_id, t.posted, f.forum_name, MATCH(t.subject) AGAINST(\''.$pun_db->escape($keywords).'\') AS relevance |
|
416 FROM '.$pun_db->prefix.'topics AS t LEFT JOIN '.$pun_db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$pun_db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') |
|
417 WHERE |
|
418 (fp.read_forum IS NULL OR fp.read_forum=1) |
|
419 '.($keywords ? 'AND MATCH(t.subject) AGAINST(\''.$pun_db->escape($keywords).'\' IN BOOLEAN MODE)' : '').' |
|
420 '.$forum_where.' |
|
421 UNION |
|
422 SELECT |
|
423 t.id AS tid, t.poster, t.subject, t.first_post_id, t.last_post, t.last_post_id, t.last_poster, t.num_replies, t.closed, t.forum_id, t.posted, f.forum_name, MATCH(p.message) AGAINST(\''.$pun_db->escape($keywords).'\') AS relevance |
|
424 FROM '.$pun_db->prefix.'posts AS p INNER JOIN '.$pun_db->prefix.'topics AS t ON p.topic_id = t.id LEFT JOIN '.$pun_db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$pun_db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') |
|
425 WHERE |
|
426 (fp.read_forum IS NULL OR fp.read_forum=1) |
|
427 '.($author ? 'AND p.poster LIKE \''.$pun_db->escape($author).'\'' : '').' |
|
428 '.($keywords ? 'AND MATCH(p.message) AGAINST(\''.$pun_db->escape($keywords).'\' IN BOOLEAN MODE)' : '').' |
|
429 '.$forum_where.' |
|
430 ) AS tmp |
|
431 GROUP BY tid |
|
432 ORDER BY '.$sort_by_sql.' '.$sort_dir; |
|
433 } |
|
434 |
|
435 $url_type = $pun_url['search_resultft']; |
|
436 |
|
437 $search_id = array($keywords, $forum, $author, ($search_in == 0 ) ? 'all' : (($search_in == 1) ? 'message' : 'subject'), $sort_by, $sort_dir, $show_as); |
|
438 } |
|
439 // We aren't doing a fulltext but we are getting results, if a valid search_id was supplied we attempt to fetch the search results from the cache |
|
440 else if (isset($search_id)) |
|
441 { |
|
442 $ident = ($pun_user['is_guest']) ? get_remote_address() : $pun_user['username']; |
|
443 |
|
444 $query = array( |
|
445 'SELECT' => 'sc.search_data', |
|
446 'FROM' => 'search_cache AS sc', |
|
447 'WHERE' => 'sc.id='.$search_id.' AND sc.ident=\''.$pun_db->escape($ident).'\'' |
|
448 ); |
|
449 |
|
450 ($hook = get_hook('se_qr_get_cached_search_data')) ? eval($hook) : null; |
|
451 $result = $pun_db->query_build($query) or error(__FILE__, __LINE__); |
|
452 if ($row = $pun_db->fetch_assoc($result)) |
|
453 { |
|
454 $temp = unserialize($row['search_data']); |
|
455 |
|
456 $search_results = $temp['search_results']; |
|
457 $sort_by = $temp['sort_by']; |
|
458 $sort_dir = $temp['sort_dir']; |
|
459 $show_as = $temp['show_as']; |
|
460 |
|
461 unset($temp); |
|
462 } |
|
463 else |
|
464 message($lang_search['No hits']); |
|
465 |
|
466 switch ($sort_by) |
|
467 { |
|
468 case 1: |
|
469 $sort_by_sql = ($show_as == 'topics') ? 't.poster' : 'p.poster'; |
|
470 break; |
|
471 |
|
472 case 2: |
|
473 $sort_by_sql = 't.subject'; |
|
474 break; |
|
475 |
|
476 case 3: |
|
477 $sort_by_sql = 't.forum_id'; |
|
478 break; |
|
479 |
|
480 default: |
|
481 $sort_by_sql = ($show_as == 'topics') ? 't.posted' : 'p.posted'; |
|
482 break; |
|
483 } |
|
484 |
|
485 if ($show_as == 'posts') |
|
486 { |
|
487 $query = array( |
|
488 'SELECT' => 'p.id AS pid, p.poster AS pposter, p.posted AS pposted, p.poster_id, '.(($db_type != 'sqlite') ? 'SUBSTRING' : 'SUBSTR').'(p.message, 1, 1000) AS message, t.id AS tid, t.poster, t.subject, t.first_post_id, t.posted, t.last_post, t.last_post_id, t.last_poster, t.num_replies, t.forum_id, f.forum_name', |
|
489 'FROM' => 'posts AS p', |
|
490 'JOINS' => array( |
|
491 array( |
|
492 'INNER JOIN' => 'topics AS t', |
|
493 'ON' => 't.id=p.topic_id' |
|
494 ), |
|
495 array( |
|
496 'INNER JOIN' => 'forums AS f', |
|
497 'ON' => 'f.id=t.forum_id' |
|
498 ) |
|
499 ), |
|
500 'WHERE' => 'p.id IN('.$search_results.')', |
|
501 'ORDER BY' => $sort_by_sql |
|
502 ); |
|
503 |
|
504 ($hook = get_hook('se_qr_get_cached_hits_as_posts')) ? eval($hook) : null; |
|
505 } |
|
506 else |
|
507 { |
|
508 $query = array( |
|
509 'SELECT' => 't.id AS tid, t.poster, t.subject, t.first_post_id, t.posted, t.last_post, t.last_post_id, t.last_poster, t.num_replies, t.closed, t.forum_id, f.forum_name', |
|
510 'FROM' => 'topics AS t', |
|
511 'JOINS' => array( |
|
512 array( |
|
513 'INNER JOIN' => 'forums AS f', |
|
514 'ON' => 'f.id=t.forum_id' |
|
515 ) |
|
516 ), |
|
517 'WHERE' => 't.id IN('.$search_results.')', |
|
518 'ORDER BY' => 'p.id, '.$sort_by_sql |
|
519 ); |
|
520 |
|
521 ($hook = get_hook('se_qr_get_cached_hits_as_topics')) ? eval($hook) : null; |
|
522 } |
|
523 |
|
524 $url_type = $pun_url['search_results']; |
|
525 } |
|
526 else if (in_array($action, $valid_actions)) |
|
527 { |
|
528 $search_id = ''; |
|
529 $show_as = 'topics'; |
|
530 switch ($action) |
|
531 { |
|
532 case 'show_new': |
|
533 if ($pun_user['is_guest']) |
|
534 message($lang_common['No permission']); |
|
535 |
|
536 $query = array( |
|
537 'SELECT' => 't.id AS tid, t.poster, t.subject, t.last_post, t.last_post_id, t.last_poster, t.num_replies, t.closed, t.forum_id, f.forum_name', |
|
538 'FROM' => 'topics AS t', |
|
539 'JOINS' => array( |
|
540 array( |
|
541 'INNER JOIN' => 'forums AS f', |
|
542 'ON' => 'f.id=t.forum_id' |
|
543 ), |
|
544 array( |
|
545 'LEFT JOIN' => 'forum_perms AS fp', |
|
546 'ON' => '(fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].')' |
|
547 ) |
|
548 ), |
|
549 'WHERE' => '(fp.read_forum IS NULL OR fp.read_forum=1) AND t.last_post>'.$pun_user['last_visit'].' AND t.moved_to IS NULL', |
|
550 'ORDER BY' => 't.last_post DESC' |
|
551 ); |
|
552 |
|
553 ($hook = get_hook('se_qr_get_new')) ? eval($hook) : null; |
|
554 |
|
555 $url_type = $pun_url['search_new']; |
|
556 break; |
|
557 |
|
558 case 'show_recent': |
|
559 $query = array( |
|
560 'SELECT' => 't.id AS tid, t.poster, t.subject, t.last_post, t.last_post_id, t.last_poster, t.num_replies, t.closed, t.forum_id, f.forum_name', |
|
561 'FROM' => 'topics AS t', |
|
562 'JOINS' => array( |
|
563 array( |
|
564 'INNER JOIN' => 'posts AS p', |
|
565 'ON' => 'p.topic_id=t.id' |
|
566 ), |
|
567 array( |
|
568 'INNER JOIN' => 'forums AS f', |
|
569 'ON' => 'f.id=t.forum_id' |
|
570 ), |
|
571 array( |
|
572 'LEFT JOIN' => 'forum_perms AS fp', |
|
573 'ON' => '(fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].')' |
|
574 ) |
|
575 ), |
|
576 'WHERE' => '(fp.read_forum IS NULL OR fp.read_forum=1) AND p.posted>'.(time() - $value).' AND t.moved_to IS NULL', |
|
577 'GROUP BY' => 't.id', |
|
578 'ORDER BY' => 't.last_post DESC' |
|
579 ); |
|
580 |
|
581 ($hook = get_hook('se_qr_get_recent')) ? eval($hook) : null; |
|
582 |
|
583 $url_type = $pun_url['search_24h']; |
|
584 break; |
|
585 |
|
586 case 'show_user_posts': |
|
587 $query = array( |
|
588 'SELECT' => 'p.id AS pid, p.poster AS pposter, p.posted AS pposted, p.poster_id, '.(($db_type != 'sqlite') ? 'SUBSTRING' : 'SUBSTR').'(p.message, 1, 1000) AS message, t.id AS tid, t.poster, t.subject, t.first_post_id, t.posted, t.last_post, t.last_post_id, t.last_poster, t.num_replies, t.forum_id, f.forum_name', |
|
589 'FROM' => 'posts AS p', |
|
590 'JOINS' => array( |
|
591 array( |
|
592 'INNER JOIN' => 'topics AS t', |
|
593 'ON' => 't.id=p.topic_id' |
|
594 ), |
|
595 array( |
|
596 'INNER JOIN' => 'forums AS f', |
|
597 'ON' => 'f.id=t.forum_id' |
|
598 ), |
|
599 array( |
|
600 'LEFT JOIN' => 'forum_perms AS fp', |
|
601 'ON' => '(fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].')' |
|
602 ) |
|
603 ), |
|
604 'WHERE' => '(fp.read_forum IS NULL OR fp.read_forum=1) AND p.poster_id='.$user_id, |
|
605 'ORDER BY' => 'pposted DESC' |
|
606 ); |
|
607 |
|
608 ($hook = get_hook('se_qr_get_user_posts')) ? eval($hook) : null; |
|
609 |
|
610 $url_type = $pun_url['search_user_posts']; |
|
611 $search_id = $user_id; |
|
612 $show_as = 'posts'; |
|
613 break; |
|
614 |
|
615 case 'show_user_topics': |
|
616 $query = array( |
|
617 'SELECT' => 't.id AS tid, t.poster, t.subject, t.last_post, t.last_post_id, t.last_poster, t.num_replies, t.closed, t.forum_id, f.forum_name', |
|
618 'FROM' => 'topics AS t', |
|
619 'JOINS' => array( |
|
620 array( |
|
621 'INNER JOIN' => 'posts AS p', |
|
622 'ON' => 't.first_post_id=p.id' |
|
623 ), |
|
624 array( |
|
625 'INNER JOIN' => 'forums AS f', |
|
626 'ON' => 'f.id=t.forum_id' |
|
627 ), |
|
628 array( |
|
629 'LEFT JOIN' => 'forum_perms AS fp', |
|
630 'ON' => '(fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].')' |
|
631 ) |
|
632 ), |
|
633 'WHERE' => '(fp.read_forum IS NULL OR fp.read_forum=1) AND p.poster_id='.$user_id, |
|
634 'ORDER BY' => 't.last_post DESC' |
|
635 ); |
|
636 |
|
637 ($hook = get_hook('se_qr_get_user_topics')) ? eval($hook) : null; |
|
638 |
|
639 $url_type = $pun_url['search_user_topics']; |
|
640 $search_id = $user_id; |
|
641 break; |
|
642 |
|
643 case 'show_subscriptions': |
|
644 if ($pun_user['is_guest']) |
|
645 message($lang_common['Bad request']); |
|
646 |
|
647 $query = array( |
|
648 'SELECT' => 't.id AS tid, t.poster, t.subject, t.last_post, t.last_post_id, t.last_poster, t.num_replies, t.closed, t.forum_id, f.forum_name', |
|
649 'FROM' => 'topics AS t', |
|
650 'JOINS' => array( |
|
651 array( |
|
652 'INNER JOIN' => 'subscriptions AS s', |
|
653 'ON' => '(t.id=s.topic_id AND s.user_id='.$pun_user['id'].')' |
|
654 ), |
|
655 array( |
|
656 'INNER JOIN' => 'forums AS f', |
|
657 'ON' => 'f.id=t.forum_id' |
|
658 ), |
|
659 array( |
|
660 'LEFT JOIN' => 'forum_perms AS fp', |
|
661 'ON' => '(fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].')' |
|
662 ) |
|
663 ), |
|
664 'WHERE' => '(fp.read_forum IS NULL OR fp.read_forum=1)', |
|
665 'ORDER BY' => 't.last_post DESC' |
|
666 ); |
|
667 |
|
668 ($hook = get_hook('se_qr_get_subscriptions')) ? eval($hook) : null; |
|
669 |
|
670 $url_type = $pun_url['search_subscriptions']; |
|
671 break; |
|
672 |
|
673 case 'show_unanswered': |
|
674 $query = array( |
|
675 'SELECT' => 't.id AS tid, t.poster, t.subject, t.last_post, t.last_post_id, t.last_poster, t.num_replies, t.closed, t.forum_id, f.forum_name', |
|
676 'FROM' => 'topics AS t', |
|
677 'JOINS' => array( |
|
678 array( |
|
679 'INNER JOIN' => 'posts AS p', |
|
680 'ON' => 't.id=p.topic_id' |
|
681 ), |
|
682 array( |
|
683 'INNER JOIN' => 'forums AS f', |
|
684 'ON' => 'f.id=t.forum_id' |
|
685 ), |
|
686 array( |
|
687 'LEFT JOIN' => 'forum_perms AS fp', |
|
688 'ON' => '(fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].')' |
|
689 ) |
|
690 ), |
|
691 'WHERE' => '(fp.read_forum IS NULL OR fp.read_forum=1) AND t.num_replies=0 AND t.moved_to IS NULL', |
|
692 'GROUP BY' => 't.id', |
|
693 'ORDER BY' => 't.last_post DESC' |
|
694 ); |
|
695 |
|
696 ($hook = get_hook('se_qr_get_unanswered')) ? eval($hook) : null; |
|
697 |
|
698 $url_type = $pun_url['search_unanswered']; |
|
699 break; |
|
700 |
|
701 default: |
|
702 // A good place for an extension to add a new search type (action must be added to $valid_actions first) |
|
703 ($hook = get_hook('se_new_action')) ? eval($hook) : null; |
|
704 break; |
|
705 } |
|
706 } |
|
707 else |
|
708 message($lang_common['Bad request']); |
|
709 |
|
710 // We now have a query that will give us our results in $query, lets get the data! |
|
711 if (is_array($query)) |
|
712 $result = $pun_db->query_build($query) or error(__FILE__, __LINE__); |
|
713 else |
|
714 $result = $pun_db->query($query) or error(__FILE__, __LINE__); |
|
715 |
|
716 // Make sure we actually have some results |
|
717 $num_hits = $pun_db->num_rows($result); |
|
718 if ($num_hits == 0) |
|
719 { |
|
720 $pun_page['search_again'] = '<a href="'.pun_link($pun_url['search']).'">'.$lang_search['Perform new search'].'</a>'; |
|
721 |
|
722 switch ($action) |
|
723 { |
|
724 case 'show_new': |
|
725 message($lang_search['No new posts'], $pun_page['search_again']); |
|
726 |
|
727 case 'show_recent': |
|
728 message($lang_search['No recent posts'], $pun_page['search_again']); |
|
729 |
|
730 case 'show_user_posts': |
|
731 message($lang_search['No user posts'], $pun_page['search_again']); |
|
732 |
|
733 case 'show_user_topics': |
|
734 message($lang_search['No user topics'], $pun_page['search_again']); |
|
735 |
|
736 case 'show_subscriptions': |
|
737 message($lang_search['No subscriptions'], $pun_page['search_again']); |
|
738 |
|
739 case 'show_unanswered': |
|
740 message($lang_search['No unanswered'], $pun_page['search_again']); |
|
741 |
|
742 default: |
|
743 ($hook = get_hook('se_new_action_no_hits')) ? eval($hook) : null; |
|
744 message($lang_search['No hits'], $pun_page['search_again']); |
|
745 } |
|
746 } |
|
747 |
|
748 // Get topic/forum tracking data |
|
749 if (!$pun_user['is_guest']) |
|
750 $tracked_topics = get_tracked_topics(); |
|
751 |
|
752 // Determine the topic or post offset (based on $_GET['p']) |
|
753 $pun_page['per_page'] = ($show_as == 'posts') ? $pun_user['disp_posts'] : $pun_user['disp_topics']; |
|
754 $pun_page['num_pages'] = ceil($num_hits / $pun_page['per_page']); |
|
755 |
|
756 $pun_page['page'] = (!isset($_GET['p']) || $_GET['p'] <= 1 || $_GET['p'] > $pun_page['num_pages']) ? 1 : $_GET['p']; |
|
757 $pun_page['start_from'] = $pun_page['per_page'] * ($pun_page['page'] - 1); |
|
758 $pun_page['finish_at'] = min(($pun_page['start_from'] + $pun_page['per_page']), $num_hits); |
|
759 |
|
760 // Generate paging links |
|
761 $pun_page['page_post'] = '<p class="paging"><strong>'.$lang_common['Pages'].'</strong> '.pun_paginate($pun_page['num_pages'], $pun_page['page'], $url_type, $search_id).'</p>'; |
|
762 |
|
763 |
|
764 // Fill $search_set with out search hits |
|
765 $search_set = array(); |
|
766 $row_num = 0; |
|
767 while ($row = $pun_db->fetch_assoc($result)) |
|
768 { |
|
769 if ($pun_page['start_from'] <= $row_num && $pun_page['finish_at'] > $row_num) |
|
770 $search_set[] = $row; |
|
771 ++$row_num; |
|
772 } |
|
773 |
|
774 $pun_db->free_result($result); |
|
775 |
|
776 |
|
777 // Navigation links for header and page numbering for title/meta description |
|
778 if ($pun_page['page'] < $pun_page['num_pages']) |
|
779 { |
|
780 $pun_page['nav'][] = '<link rel="last" href="'.pun_sublink($url_type, $pun_url['page'], $pun_page['num_pages'], $search_id).'" title="'.$lang_common['Page'].' '.$pun_page['num_pages'].'" />'; |
|
781 $pun_page['nav'][] = '<link rel="next" href="'.pun_sublink($url_type, $pun_url['page'], ($pun_page['page'] + 1), $search_id).'" title="'.$lang_common['Page'].' '.($pun_page['page'] + 1).'" />'; |
|
782 } |
|
783 if ($pun_page['page'] > 1) |
|
784 { |
|
785 $pun_page['nav'][] = '<link rel="prev" href="'.pun_sublink($url_type, $pun_url['page'], ($pun_page['page'] - 1), $search_id).'" title="'.$lang_common['Page'].' '.($pun_page['page'] - 1).'" />'; |
|
786 $pun_page['nav'][] = '<link rel="first" href="'.pun_link($url_type, $search_id).'" title="'.$lang_common['Page'].' 1" />'; |
|
787 } |
|
788 |
|
789 // Setup breadcrumbs and results header and footer |
|
790 $pun_page['main_foot_options'][] = '<a class="user-option" href="'.pun_link($pun_url['search']).'">'.$lang_search['Perform new search'].'</a>'; |
|
791 $pun_page['crumbs'][] = array($pun_config['o_board_title'], pun_link($pun_url['index'])); |
|
792 |
|
793 switch ($action) |
|
794 { |
|
795 case 'show_new': |
|
796 $pun_page['crumbs'][] = $lang_common['New posts']; |
|
797 $pun_page['main_info'] = (($pun_page['num_pages'] == 1) ? sprintf($lang_common['Page info'], $lang_search['Topics with new'], $num_hits) : '<span>'.sprintf($lang_common['Page number'], $pun_page['page'], $pun_page['num_pages']).' </span>'.sprintf($lang_common['Paged info'], $lang_search['Topics with new'], $pun_page['start_from'] + 1, $pun_page['finish_at'], $num_hits)); |
|
798 $pun_page['main_foot_options'][] = '<a class="user-option" href="'.pun_link($pun_url['mark_read']).'">'.$lang_common['Mark all as read'].'</a>'; |
|
799 break; |
|
800 |
|
801 case 'show_recent': |
|
802 $pun_page['crumbs'][] = $lang_common['Recent posts']; |
|
803 $pun_page['main_info'] = (($pun_page['num_pages'] == 1) ? sprintf($lang_common['Page info'], $lang_search['Topics with recent'], $num_hits) : '<span>'.sprintf($lang_common['Page number'], $pun_page['page'], $pun_page['num_pages']).' </span>'.sprintf($lang_common['Paged info'], $lang_search['Topics with recent'], $pun_page['start_from'] + 1, $pun_page['finish_at'], $num_hits)); |
|
804 break; |
|
805 |
|
806 case 'show_unanswered': |
|
807 $pun_page['crumbs'][] = $lang_common['Unanswered topics']; |
|
808 $pun_page['main_info'] = (($pun_page['num_pages'] == 1) ? sprintf($lang_common['Page info'], $lang_common['Unanswered topics'], $num_hits) : '<span>'.sprintf($lang_common['Page number'], $pun_page['page'], $pun_page['num_pages']).' </span>'.sprintf($lang_common['Paged info'], $lang_common['Unanswered topics'], $pun_page['start_from'] + 1, $pun_page['finish_at'], $num_hits)); |
|
809 break; |
|
810 |
|
811 case 'show_user_posts': |
|
812 $pun_page['crumbs'][] = sprintf($lang_search['Posts by'], $search_set[0]['pposter']); |
|
813 $pun_page['main_info'] = (($pun_page['num_pages'] == 1) ? sprintf($lang_common['Page info'], sprintf($lang_search['Posts by'], $search_set[0]['pposter']), $num_hits) : '<span>'.sprintf($lang_common['Page number'], $pun_page['page'], $pun_page['num_pages']).' </span>'.sprintf($lang_common['Paged info'], sprintf($lang_search['Posts by'], $search_set[0]['pposter']), $pun_page['start_from'] + 1, $pun_page['finish_at'], $num_hits)); |
|
814 $pun_page['main_foot_options'][] = '<a class="user-option" href="'.pun_link($pun_url['search_user_topics'], $search_id).'">'.sprintf($lang_search['Topics by'], $search_set[0]['pposter']).'</a>'; |
|
815 break; |
|
816 |
|
817 case 'show_user_topics': |
|
818 $pun_page['crumbs'][] = sprintf($lang_search['Topics by'], $search_set[0]['poster']); |
|
819 $pun_page['main_info'] = (($pun_page['num_pages'] == 1) ? sprintf($lang_common['Page info'], sprintf($lang_search['Topics by'], $search_set[0]['poster']), $num_hits) : '<span>'.sprintf($lang_common['Page number'], $pun_page['page'], $pun_page['num_pages']).' </span>'.sprintf($lang_common['Paged info'], sprintf($lang_search['Topics by'], $search_set[0]['poster']), $pun_page['start_from'] + 1, $pun_page['finish_at'], $num_hits)); |
|
820 $pun_page['main_foot_options'][] = '<a class="user-option" href="'.pun_link($pun_url['search_user_posts'], $search_id).'">'.sprintf($lang_search['Posts by'], $search_set[0]['poster']).'</a>'; |
|
821 break; |
|
822 |
|
823 case 'show_subscriptions': |
|
824 $pun_page['crumbs'][] = $lang_common['Your subscriptions']; |
|
825 $pun_page['main_info'] = (($pun_page['num_pages'] == 1) ? sprintf($lang_common['Page info'], $lang_common['Your subscriptions'], $num_hits) : '<span>'.sprintf($lang_common['Page number'], $pun_page['page'], $pun_page['num_pages']).' </span>'.sprintf($lang_common['Paged info'], $lang_common['Your subscriptions'], $pun_page['start_from'] + 1, $pun_page['finish_at'], $num_hits)); |
|
826 break; |
|
827 |
|
828 default: |
|
829 $pun_page['crumbs'][] = $lang_search['Search results']; |
|
830 $pun_page['main_info'] = (($pun_page['num_pages'] == 1) ? sprintf($lang_common['Page info'], (($show_as=='topics') ? $lang_common['Topics'] : $lang_common['Posts']), $num_hits) : '<span>'.sprintf($lang_common['Page number'], $pun_page['page'], $pun_page['num_pages']).' </span>'.sprintf($lang_common['Paged info'], (($show_as=='topics') ? $lang_common['Topics'] : $lang_common['Posts']), $pun_page['start_from'] + 1, $pun_page['finish_at'], $num_hits)); |
|
831 break; |
|
832 } |
|
833 |
|
834 ($hook = get_hook('se_results_pre_header_load')) ? eval($hook) : null; |
|
835 |
|
836 define('PUN_PAGE', $show_as == 'topics' ? 'searchtopics' : 'searchposts'); |
|
837 require PUN_ROOT.'header.php'; |
|
838 |
|
839 if ($show_as == 'topics') |
|
840 { |
|
841 // Load the forum.php language file |
|
842 require PUN_ROOT.'lang/'.$pun_user['language'].'/forum.php'; |
|
843 |
|
844 ?> |
|
845 <div id="pun-main" class="main paged"> |
|
846 |
|
847 <h1><span><?php echo end($pun_page['crumbs']) ?></span></h1> |
|
848 |
|
849 <div class="paged-head"> |
|
850 <?php echo $pun_page['page_post']."\n" ?> |
|
851 </div> |
|
852 |
|
853 <div class="main-head"> |
|
854 <h2><span><?php echo $pun_page['main_info'] ?></span></h2> |
|
855 </div> |
|
856 |
|
857 <div class="main-content forum"> |
|
858 <table cellspacing="0" summary="<?php echo $lang_search['Table summary'] ?>"> |
|
859 <thead> |
|
860 <tr> |
|
861 <th class="tcl" scope="col"><?php echo $lang_common['Topic']; ?></th> |
|
862 <th class="tc2" scope="col"><?php echo $lang_common['Forum'] ?></th> |
|
863 <th class="tc3" scope="col"><?php echo $lang_common['Replies'] ?></th> |
|
864 <th class="tcr" scope="col"><?php echo $lang_common['Last post'] ?></th> |
|
865 </tr> |
|
866 </thead> |
|
867 <tbody class="statused"> |
|
868 <?php |
|
869 |
|
870 } |
|
871 else |
|
872 { |
|
873 // Load the topic.php language file |
|
874 require PUN_ROOT.'lang/'.$pun_user['language'].'/topic.php'; |
|
875 |
|
876 ?> |
|
877 <div id="pun-main" class="main paged"> |
|
878 |
|
879 <h1><span><?php echo end($pun_page['crumbs']) ?></span></h1> |
|
880 |
|
881 <div class="paged-head"> |
|
882 <?php echo $pun_page['page_post']."\n" ?> |
|
883 </div> |
|
884 |
|
885 <div class="main-head"> |
|
886 <h2><span><?php echo $pun_page['main_info'] ?></span></h2> |
|
887 </div> |
|
888 |
|
889 <div class="main-content topic"> |
|
890 <?php |
|
891 |
|
892 } |
|
893 |
|
894 $pun_page['item_count'] = 0; |
|
895 |
|
896 // Finally, lets loop through the results and output them |
|
897 for ($i = 0; $i < count($search_set); ++$i) |
|
898 { |
|
899 ++$pun_page['item_count']; |
|
900 |
|
901 if ($pun_config['o_censoring'] == '1') |
|
902 $search_set[$i]['subject'] = censor_words($search_set[$i]['subject']); |
|
903 |
|
904 if ($show_as == 'posts') |
|
905 { |
|
906 // Generate the post heading |
|
907 $pun_page['item_head'] = array( |
|
908 'num' => '<strong>'.($pun_page['start_from'] + $pun_page['item_count']).'</strong>', |
|
909 'user' => '<cite>'.(($search_set[$i]['pid'] == $search_set[$i]['first_post_id']) ? sprintf($lang_topic['Topic by'], htmlspecialchars($search_set[$i]['pposter'])) : sprintf($lang_topic['Reply by'], htmlspecialchars($search_set[$i]['pposter']))).'</cite>', |
|
910 'date' => '<span>'.format_time($search_set[$i]['pposted']).'</span>' |
|
911 ); |
|
912 |
|
913 $pun_page['item_head'] = '<a class="permalink" rel="bookmark" title="'.$lang_topic['Permalink post'].'" href="'.pun_link($pun_url['post'], $search_set[$i]['pid']).'">'.implode(' ', $pun_page['item_head']).'</a>'; |
|
914 |
|
915 // Generate author identification |
|
916 $pun_page['user_ident'] = (($search_set[$i]['poster_id'] > 1) ? '<strong class="username"><a title="'.sprintf($lang_search['Go to profile'], htmlspecialchars($search_set[$i]['pposter'])).'" href="'.pun_link($pun_url['user'], $search_set[$i]['poster_id']).'">'.htmlspecialchars($search_set[$i]['pposter']).'</a></strong>' : '<strong class="username">'.htmlspecialchars($search_set[$i]['pposter']).'</strong>'); |
|
917 |
|
918 // Generate the post options links |
|
919 $pun_page['post_options'] = array(); |
|
920 $pun_page['post_options'][] = '<a href="'.pun_link($pun_url['forum'], $search_set[$i]['forum_id']).'"><span>'.$lang_search['Go to forum'].'<span>: '.htmlspecialchars($search_set[$i]['forum_name']).'</span></span></a>'; |
|
921 |
|
922 if ($search_set[$i]['pid'] != $search_set[$i]['first_post_id']) |
|
923 $pun_page['post_options'][] = '<a class="permalink" rel="bookmark" title="'.$lang_topic['Permalink topic'].'" href="'.pun_link($pun_url['topic'], $search_set[$i]['tid']).'"><span>'.$lang_search['Go to topic'].'<span>: '.htmlspecialchars($search_set[$i]['subject']).'</span></span></a>'; |
|
924 |
|
925 $pun_page['post_options'][] = '<a class="permalink" rel="bookmark" title="'.$lang_topic['Permalink post'].'" href="'.pun_link($pun_url['post'], $search_set[$i]['pid']).'"><span>'.$lang_search['Go to post'].' <span>'.($pun_page['start_from'] + $pun_page['item_count']).'</span></span></a>'; |
|
926 |
|
927 // Generate the post title |
|
928 $pun_page['item_subject'] = array(); |
|
929 if ($search_set[$i]['pid'] == $search_set[$i]['first_post_id']) |
|
930 $pun_page['item_subject'][] = '<strong>'.$lang_common['Topic'].': '.htmlspecialchars($search_set[$i]['subject']).'</strong>'; |
|
931 else |
|
932 $pun_page['item_subject'][] = '<strong>'.$lang_common['Re'].' '.htmlspecialchars($search_set[$i]['subject']).'</strong>'; |
|
933 |
|
934 $pun_page['item_subject'][] = sprintf($lang_search['Topic info'], htmlspecialchars($search_set[$i]['poster']), htmlspecialchars($search_set[$i]['forum_name']), $search_set[$i]['num_replies']); |
|
935 |
|
936 // Generate the post message |
|
937 if ($pun_config['o_censoring'] == '1') |
|
938 $search_set[$i]['message'] = censor_words($search_set[$i]['message']); |
|
939 |
|
940 $pun_page['message'] = str_replace("\n", '<br />', htmlspecialchars($search_set[$i]['message'])); |
|
941 |
|
942 if (pun_strlen($pun_page['message']) >= 1000) |
|
943 $pun_page['message'] .= ' …'; |
|
944 |
|
945 // Give the post some class |
|
946 $pun_page['item_status'] = array( |
|
947 'post', |
|
948 (($pun_page['item_count'] % 2 == 0) ? 'odd' : 'even' ) |
|
949 ); |
|
950 |
|
951 if ($pun_page['item_count'] == 1) |
|
952 $pun_page['item_status'][] = 'firstpost'; |
|
953 |
|
954 if (($pun_page['start_from'] + $pun_page['item_count']) == $pun_page['finish_at']) |
|
955 $pun_page['item_status'][] = 'lastpost'; |
|
956 |
|
957 if ($search_set[$i]['pid'] == $search_set[$i]['first_post_id']) |
|
958 $pun_page['item_status'][] = 'topicpost'; |
|
959 |
|
960 ($hook = get_hook('se_results_posts_row_pre_display')) ? eval($hook) : null; |
|
961 |
|
962 ?> |
|
963 <div class="<?php echo implode(' ', $pun_page['item_status']) ?>"> |
|
964 <div class="postmain"> |
|
965 <div class="posthead"> |
|
966 <h3><?php echo $pun_page['item_head'] ?></h3> |
|
967 </div> |
|
968 <div class="postbody"> |
|
969 <div class="user"> |
|
970 <h4 class="user-ident"><?php echo $pun_page['user_ident'] ?></h4> |
|
971 </div> |
|
972 <div class="post-entry"> |
|
973 <h4 class="entry-title"><?php echo implode(' ', $pun_page['item_subject']) ?></h4> |
|
974 <div class="entry-content"> |
|
975 <p><?php echo $pun_page['message'] ?></p> |
|
976 </div> |
|
977 </div> |
|
978 </div> |
|
979 <div class="postfoot"> |
|
980 <div class="post-options"><?php echo implode(' ', $pun_page['post_options']) ?></div> |
|
981 </div> |
|
982 </div> |
|
983 </div> |
|
984 <?php |
|
985 |
|
986 } |
|
987 else |
|
988 { |
|
989 ++$pun_page['item_count']; |
|
990 |
|
991 // Start from scratch |
|
992 $pun_page['item_subject'] = $pun_page['item_status'] = $pun_page['item_last_post'] = $pun_page['item_nav'] = array(); |
|
993 $pun_page['item_indicator'] = ''; |
|
994 $pun_page['item_alt_message'] = $lang_common['Topic'].' '.($pun_page['start_from'] + $pun_page['item_count']); |
|
995 |
|
996 if ($search_set[$i]['closed'] != '0') |
|
997 { |
|
998 $pun_page['item_subject'][] = $lang_common['Closed']; |
|
999 $pun_page['item_status'][] = 'closed'; |
|
1000 } |
|
1001 |
|
1002 $pun_page['item_subject'][] = '<a href="'.pun_link($pun_url['topic'], $search_set[$i]['tid']).'">'.htmlspecialchars($search_set[$i]['subject']).'</a>'; |
|
1003 |
|
1004 $pun_page['item_pages'] = ceil(($search_set[$i]['num_replies'] + 1) / $pun_user['disp_posts']); |
|
1005 |
|
1006 if ($pun_page['item_pages'] > 1) |
|
1007 $pun_page['item_nav'][] = pun_paginate($pun_page['item_pages'], -1, $pun_url['topic'], $search_set[$i]['tid']); |
|
1008 |
|
1009 // Does this topic contains posts we haven't read? If so, tag it accordingly. |
|
1010 if (!$pun_user['is_guest'] && $search_set[$i]['last_post'] > $pun_user['last_visit'] && (!isset($tracked_topics['topics'][$search_set[$i]['tid']]) || $tracked_topics['topics'][$search_set[$i]['tid']] < $search_set[$i]['last_post']) && (!isset($tracked_topics['forums'][$search_set[$i]['forum_id']]) || $tracked_topics['forums'][$search_set[$i]['forum_id']] < $search_set[$i]['last_post'])) |
|
1011 { |
|
1012 $pun_page['item_nav'][] = '<a href="'.pun_link($pun_url['topic_new_posts'], $search_set[$i]['tid']).'" title="'.$lang_forum['New posts info'].'">'.$lang_common['New posts'].'</a>'; |
|
1013 $pun_page['item_status'][] = 'new'; |
|
1014 } |
|
1015 |
|
1016 if (!empty($pun_page['item_nav'])) |
|
1017 $pun_page['item_subject'][] = '<span class="topic-nav">[ '.implode('  ', $pun_page['item_nav']).' ]</span>'; |
|
1018 |
|
1019 $pun_page['item_subject'][] = '<span class="byuser">'.sprintf($lang_common['By user'], htmlspecialchars($search_set[$i]['poster'])).'</span>'; |
|
1020 $pun_page['item_last_post'][] = '<a href="'.pun_link($pun_url['post'], $search_set[$i]['last_post_id']).'">'.format_time($search_set[$i]['last_post']).'</a>'; |
|
1021 $pun_page['item_last_post'][] = '<span class="byuser">'.sprintf($lang_common['By user'], htmlspecialchars($search_set[$i]['last_poster'])).'</span>'; |
|
1022 $pun_page['item_indicator'] = '<span class="status '.implode(' ', $pun_page['item_status']).'" title="'.$pun_page['item_alt_message'].'"><img src="'.$base_url.'/style/'.$pun_user['style'].'/status.png" alt="'.$pun_page['item_alt_message'].'" />'.$pun_page['item_indicator'].'</span>'; |
|
1023 |
|
1024 ($hook = get_hook('se_results_topics_row_pre_display')) ? eval($hook) : null; |
|
1025 |
|
1026 ?> |
|
1027 <tr class="<?php echo ($pun_page['item_count'] % 2 != 0) ? 'odd' : 'even' ?>"> |
|
1028 <td class="tcl"><?php echo $pun_page['item_indicator'].' '.implode(' ', $pun_page['item_subject']) ?></td> |
|
1029 <td class="tc2"><?php echo htmlspecialchars($search_set[$i]['forum_name']) ?></td> |
|
1030 <td class="tc3"><?php echo $search_set[$i]['num_replies'] ?></td> |
|
1031 <td class="tcr"><?php echo implode(' ', $pun_page['item_last_post']) ?></td> |
|
1032 </tr> |
|
1033 <?php |
|
1034 |
|
1035 } |
|
1036 } |
|
1037 |
|
1038 if ($show_as == 'topics') |
|
1039 { |
|
1040 |
|
1041 ?> |
|
1042 </tbody> |
|
1043 </table> |
|
1044 <?php |
|
1045 |
|
1046 } |
|
1047 |
|
1048 ?> |
|
1049 </div> |
|
1050 |
|
1051 <div class="main-foot"> |
|
1052 <p class="h2"><strong><?php echo $pun_page['main_info'] ?></strong></p> |
|
1053 <?php if (!empty($pun_page['main_foot_options'])): ?> <p class="main-options"><?php echo implode(' ', $pun_page['main_foot_options']) ?></p> |
|
1054 <?php endif; ?> </div> |
|
1055 |
|
1056 <div class="paged-foot"> |
|
1057 <?php echo $pun_page['page_post']."\n" ?> |
|
1058 </div> |
|
1059 |
|
1060 </div> |
|
1061 |
|
1062 <div id="pun-crumbs-foot"> |
|
1063 <p class="crumbs"><?php echo generate_crumbs(false) ?></p> |
|
1064 </div> |
|
1065 <?php |
|
1066 |
|
1067 require PUN_ROOT.'footer.php'; |
|
1068 } |
|
1069 |
|
1070 // Setup form |
|
1071 $pun_page['set_count'] = $pun_page['fld_count'] = 0; |
|
1072 |
|
1073 // Setup form information |
|
1074 $pun_page['frm-info'] = array('<li><span>'.$lang_search['Search info'].'</span></li>'); |
|
1075 if ($db_type == 'mysql' || $db_type == 'mysqli') |
|
1076 { |
|
1077 $pun_page['frm-info'][] = '<li><span>'.$lang_search['Refine info fulltext'].'</span></li>'; |
|
1078 $pun_page['frm-info'][] = '<li><span>'.$lang_search['Wildcard info fulltext'].'</span></li>'; |
|
1079 } |
|
1080 else |
|
1081 { |
|
1082 $pun_page['frm-info'][] = '<li><span>'.$lang_search['Refine info'].'</span></li>'; |
|
1083 $pun_page['frm-info'][] = '<li><span>'.$lang_search['Wildcard info'].'<span></li>'; |
|
1084 } |
|
1085 |
|
1086 // Setup predefined search (pds) links |
|
1087 $pun_page['pd_searches'] = array( |
|
1088 '<a href="'.pun_link($pun_url['search_24h']).'">'.$lang_common['Recent posts'].'</a>', |
|
1089 '<a href="'.pun_link($pun_url['search_unanswered']).'">'.$lang_common['Unanswered topics'].'</a>' |
|
1090 ); |
|
1091 |
|
1092 if (!$pun_user['is_guest']) |
|
1093 { |
|
1094 array_push( |
|
1095 $pun_page['pd_searches'], |
|
1096 '<a href="'.pun_link($pun_url['search_new']).'" title="'.$lang_common['New posts info'].'">'.$lang_common['New posts'].'</a>', |
|
1097 '<a href="'.pun_link($pun_url['search_user_posts'], $pun_user['id']).'">'.$lang_common['Your posts'].'</a>', |
|
1098 '<a href="'.pun_link($pun_url['search_user_topics'], $pun_user['id']).'">'.$lang_common['Your topics'].'</a>' |
|
1099 ); |
|
1100 |
|
1101 if ($pun_config['o_subscriptions'] == '1') |
|
1102 $pun_page['pd_searches'][] = '<a href="'.pun_link($pun_url['search_subscriptions']).'">'.$lang_common['Your subscriptions'].'</a>'; |
|
1103 } |
|
1104 |
|
1105 // Setup breadcrumbs |
|
1106 $pun_page['crumbs'] = array( |
|
1107 array($pun_config['o_board_title'], pun_link($pun_url['index'])), |
|
1108 $lang_common['Search'] |
|
1109 ); |
|
1110 |
|
1111 ($hook = get_hook('se_pre_header_load')) ? eval($hook) : null; |
|
1112 |
|
1113 define('PUN_PAGE', 'search'); |
|
1114 require PUN_ROOT.'header.php'; |
|
1115 |
|
1116 ?> |
|
1117 <div id="pun-main" class="main"> |
|
1118 |
|
1119 <h1><span><?php echo $lang_common['Search'] ?></span></h1> |
|
1120 |
|
1121 <div class="main-head"> |
|
1122 <h2><span><?php echo $lang_search['Search heading'] ?></span></h2> |
|
1123 </div> |
|
1124 <div class="main-content frm"> |
|
1125 <div class="frm-info"> |
|
1126 <h3><?php echo $lang_search['Predefined searches'] ?></h3> |
|
1127 <p class="actions"><?php echo implode(' ', $pun_page['pd_searches']) ?></p> |
|
1128 <h3><?php echo $lang_search['Using criteria'] ?></h3> |
|
1129 <ul> |
|
1130 <?php echo implode("\n\t\t\t\t", $pun_page['frm-info'])."\n" ?> |
|
1131 </ul> |
|
1132 </div> |
|
1133 <form id="afocus" class="frm-form" method="get" accept-charset="utf-8" action="<?php echo pun_link($pun_url['search']) ?>"> |
|
1134 <div class="hidden"> |
|
1135 <input type="hidden" name="action" value="search" /> |
|
1136 </div> |
|
1137 <?php ($hook = get_hook('se_pre_criteria_fieldset')) ? eval($hook) : null; ?> |
|
1138 <fieldset class="frm-set set<?php echo ++$pun_page['set_count'] ?>"> |
|
1139 <legend class="frm-legend"><strong><?php echo $lang_search['Search legend'] ?></strong></legend> |
|
1140 <?php ($hook = get_hook('se_criteria_start')) ? eval($hook) : null; ?> |
|
1141 <div class="frm-fld text"> |
|
1142 <label for="fld<?php echo ++$pun_page['fld_count'] ?>"> |
|
1143 <span class="fld-label"><?php echo $lang_search['Keyword search'] ?></span><br /> |
|
1144 <span class="fld-input"><input type="text" id="fld<?php echo $pun_page['fld_count'] ?>" name="keywords" size="40" maxlength="100" /></span><br /> |
|
1145 <span class="fld-help"><?php echo $lang_search['Keyword info'] ?></span> |
|
1146 </label> |
|
1147 </div> |
|
1148 <?php ($hook = get_hook('se_criteria_pre_author_field')) ? eval($hook) : null; ?> |
|
1149 <div class="frm-fld text"> |
|
1150 <label for="fld<?php echo ++$pun_page['fld_count'] ?>"> |
|
1151 <span class="fld-label"><?php echo $lang_search['Author search'] ?></span><br /> |
|
1152 <span class="fld-input"><input id="fld<?php echo $pun_page['fld_count'] ?>" type="text" name="author" size="25" maxlength="25" /></span><br /> |
|
1153 <span class="fld-help"><?php echo $lang_search['Author info'] ?></span> |
|
1154 </label> |
|
1155 </div> |
|
1156 <?php ($hook = get_hook('se_criteria_pre_forum_field')) ? eval($hook) : null; ?> |
|
1157 <div class="frm-fld select"> |
|
1158 <label for="fld<?php echo ++$pun_page['fld_count'] ?>"> |
|
1159 <span class="fld-label"><?php echo $lang_search['Forum search'] ?></span><br /> |
|
1160 <span class="fld-input"><select id="fld<?php echo $pun_page['fld_count'] ?>" name="forum"> |
|
1161 <?php |
|
1162 |
|
1163 if ($pun_config['o_search_all_forums'] == '1' || $pun_user['is_admmod']) |
|
1164 echo " \t\t\t\t\t".'<option value="-1">'.$lang_search['All forums'].'</option>'."\n"; |
|
1165 |
|
1166 // Get the list of categories and forums |
|
1167 $query = array( |
|
1168 'SELECT' => 'c.id AS cid, c.cat_name, f.id AS fid, f.forum_name, f.redirect_url', |
|
1169 'FROM' => 'categories AS c', |
|
1170 'JOINS' => array( |
|
1171 array( |
|
1172 'INNER JOIN' => 'forums AS f', |
|
1173 'ON' => 'c.id=f.cat_id' |
|
1174 ), |
|
1175 array( |
|
1176 'LEFT JOIN' => 'forum_perms AS fp', |
|
1177 'ON' => '(fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].')' |
|
1178 ) |
|
1179 ), |
|
1180 'WHERE' => '(fp.read_forum IS NULL OR fp.read_forum=1) AND f.redirect_url IS NULL', |
|
1181 'ORDER BY' => 'c.disp_position, c.id, f.disp_position' |
|
1182 ); |
|
1183 |
|
1184 ($hook = get_hook('se_qr_get_cats_and_forums')) ? eval($hook) : null; |
|
1185 $result = $pun_db->query_build($query, true) or error(__FILE__, __LINE__); |
|
1186 |
|
1187 $cur_category = 0; |
|
1188 while ($cur_forum = $pun_db->fetch_assoc($result)) |
|
1189 { |
|
1190 if ($cur_forum['cid'] != $cur_category) // A new category since last iteration? |
|
1191 { |
|
1192 if ($cur_category) |
|
1193 echo "\t\t\t\t\t\t".'</optgroup>'."\n"; |
|
1194 |
|
1195 echo "\t\t\t\t\t\t".'<optgroup label="'.htmlspecialchars($cur_forum['cat_name']).'">'."\n"; |
|
1196 $cur_category = $cur_forum['cid']; |
|
1197 } |
|
1198 |
|
1199 echo "\t\t\t\t\t\t".'<option value="'.$cur_forum['fid'].'">'.htmlspecialchars($cur_forum['forum_name']).'</option>'."\n"; |
|
1200 } |
|
1201 |
|
1202 ?> |
|
1203 </optgroup> |
|
1204 </select></span><br /> |
|
1205 </label> |
|
1206 </div> |
|
1207 <?php ($hook = get_hook('se_criteria_end')) ? eval($hook) : null; ?> |
|
1208 </fieldset> |
|
1209 <?php ($hook = get_hook('se_pre_results_fieldset')) ? eval($hook) : null; ?> |
|
1210 <fieldset class="frm-set set<?php echo ++$pun_page['set_count'] ?>"> |
|
1211 <legend class="frm-legend"><strong><?php echo $lang_search['Results legend'] ?></strong></legend> |
|
1212 <?php ($hook = get_hook('se_results_start')) ? eval($hook) : null; ?> |
|
1213 <div class="frm-fld select"> |
|
1214 <label for="fld<?php echo ++$pun_page['fld_count'] ?>"> |
|
1215 <span class="fld-label"><?php echo $lang_search['Sort by'] ?></span><br /> |
|
1216 <span class="fld-input"><select id="fld<?php echo $pun_page['fld_count'] ?>" name="sort_by"> |
|
1217 <?php if ($db_type == 'mysql' || $db_type == 'mysqli'):?> |
|
1218 <option value="4"><?php echo $lang_search['Sort by relevance'] ?></option> |
|
1219 <?php endif; ?> <option value="0"><?php echo $lang_search['Sort by post time'] ?></option> |
|
1220 <option value="1"><?php echo $lang_search['Sort by author'] ?></option> |
|
1221 <option value="2"><?php echo $lang_search['Sort by subject'] ?></option> |
|
1222 <option value="3"><?php echo $lang_search['Sort by forum'] ?></option> |
|
1223 </select></span><br /> |
|
1224 </label> |
|
1225 </div> |
|
1226 <?php ($hook = get_hook('se_results_pre_sort_choices')) ? eval($hook) : null; ?> |
|
1227 <fieldset class="frm-group"> |
|
1228 <legend><span><?php echo $lang_search['Sort order'] ?></span></legend> |
|
1229 <div class="radbox frm-yesno"><label for="fld<?php echo ++$pun_page['fld_count'] ?>"><input type="radio" id="fld<?php echo $pun_page['fld_count'] ?>" name="sort_dir" value="ASC" /> <?php echo $lang_search['Ascending'] ?></label> <label for="fld<?php echo ++$pun_page['fld_count'] ?>"><input type="radio" id="fld<?php echo $pun_page['fld_count'] ?>" name="sort_dir" value="DESC" checked="checked" /> <?php echo $lang_search['Descending'] ?></label></div> |
|
1230 </fieldset> |
|
1231 <?php ($hook = get_hook('se_results_pre_display_choices')) ? eval($hook) : null; ?> |
|
1232 <fieldset class="frm-group"> |
|
1233 <legend><span><?php echo $lang_search['Display results'] ?></span></legend> |
|
1234 <div class="radbox frm-yesno"><label for="fld<?php echo ++$pun_page['fld_count'] ?>"><input type="radio" id="fld<?php echo $pun_page['fld_count'] ?>" name="show_as" value="topics" checked="checked" /> <?php echo $lang_search['Show as topics'] ?></label> <label for="fld<?php echo ++$pun_page['fld_count'] ?>"><input type="radio" id="fld<?php echo $pun_page['fld_count'] ?>" name="show_as" value="posts" /> <?php echo $lang_search['Show as posts'] ?></label></div> |
|
1235 </fieldset> |
|
1236 <?php ($hook = get_hook('se_results_end')) ? eval($hook) : null; ?> |
|
1237 </fieldset> |
|
1238 <?php ($hook = get_hook('se_pre_buttons')) ? eval($hook) : null; ?> |
|
1239 <div class="frm-buttons"> |
|
1240 <span class="submit"><input type="submit" name="search" value="<?php echo $lang_search['Submit search'] ?>" accesskey="s" title="<?php echo $lang_common['Submit title'] ?>" /></span> |
|
1241 </div> |
|
1242 </form> |
|
1243 </div> |
|
1244 |
|
1245 </div> |
|
1246 <?php |
|
1247 |
|
1248 ($hook = get_hook('se_end')) ? eval($hook) : null; |
|
1249 |
|
1250 require PUN_ROOT.'footer.php'; |