phpBB
Statistics
| Revision:

root / trunk / phpBB / search.php

History | View | Annotate | Download (42 kB)

1
<?php
2
/**
3
*
4
* @package phpBB3
5
* @copyright (c) 2005 phpBB Group
6
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
7
*
8
*/
9
10
/**
11
* @ignore
12
*/
13
define('IN_PHPBB', true);
14
$phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './';
15
$phpEx = substr(strrchr(__FILE__, '.'), 1);
16
include($phpbb_root_path . 'common.' . $phpEx);
17
18
// Start session management
19
$user->session_begin();
20
$auth->acl($user->data);
21
$user->setup('search');
22
23
// Define initial vars
24
$mode                        = request_var('mode', '');
25
$search_id                = request_var('search_id', '');
26
$start                        = max(request_var('start', 0), 0);
27
$post_id                = request_var('p', 0);
28
$topic_id                = request_var('t', 0);
29
$view                        = request_var('view', '');
30
31
$submit                        = request_var('submit', false);
32
$keywords                = utf8_normalize_nfc(request_var('keywords', '', true));
33
$add_keywords        = utf8_normalize_nfc(request_var('add_keywords', '', true));
34
$author                        = request_var('author', '', true);
35
$author_id                = request_var('author_id', 0);
36
$show_results        = ($topic_id) ? 'posts' : request_var('sr', 'posts');
37
$show_results        = ($show_results == 'posts') ? 'posts' : 'topics';
38
$search_terms        = request_var('terms', 'all');
39
$search_fields        = request_var('sf', 'all');
40
$search_child        = request_var('sc', true);
41
42
$sort_days                = request_var('st', 0);
43
$sort_key                = request_var('sk', 't');
44
$sort_dir                = request_var('sd', 'd');
45
46
$return_chars        = request_var('ch', ($topic_id) ? -1 : 300);
47
$search_forum        = request_var('fid', array(0));
48
49
// We put login boxes for the case if search_id is newposts, egosearch or unreadposts
50
// because a guest should be able to log in even if guests search is not permitted
51
52
switch ($search_id)
53
{
54
        // Egosearch is an author search
55
        case 'egosearch':
56
                $author_id = $user->data['user_id'];
57
                if ($user->data['user_id'] == ANONYMOUS)
58
                {
59
                        login_box('', $user->lang['LOGIN_EXPLAIN_EGOSEARCH']);
60
                }
61
        break;
62
63
        // Search for unread posts needs to be allowed and user to be logged in if topics tracking for guests is disabled
64
        case 'unreadposts':
65
                if (!$config['load_unreads_search'])
66
                {
67
                        $template->assign_var('S_NO_SEARCH', true);
68
                        trigger_error('NO_SEARCH_UNREADS');
69
                }
70
                else if (!$config['load_anon_lastread'] && !$user->data['is_registered'])
71
                {
72
                        login_box('', $user->lang['LOGIN_EXPLAIN_UNREADSEARCH']);
73
                }
74
        break;
75
76
        // The "new posts" search uses user_lastvisit which is user based, so it should require user to log in.
77
        case 'newposts':
78
                if ($user->data['user_id'] == ANONYMOUS)
79
                {
80
                        login_box('', $user->lang['LOGIN_EXPLAIN_NEWPOSTS']);
81
                }
82
        break;
83
84
        default:
85
                // There's nothing to do here for now ;)
86
        break;
87
}
88
89
// Is user able to search? Has search been disabled?
90
if (!$auth->acl_get('u_search') || !$auth->acl_getf_global('f_search') || !$config['load_search'])
91
{
92
        $template->assign_var('S_NO_SEARCH', true);
93
        trigger_error('NO_SEARCH');
94
}
95
96
// Check search load limit
97
if ($user->load && $config['limit_search_load'] && ($user->load > doubleval($config['limit_search_load'])))
98
{
99
        $template->assign_var('S_NO_SEARCH', true);
100
        trigger_error('NO_SEARCH_TIME');
101
}
102
103
// It is applicable if the configuration setting is non-zero, and the user cannot
104
// ignore the flood setting, and the search is a keyword search.
105
$interval = ($user->data['user_id'] == ANONYMOUS) ? $config['search_anonymous_interval'] : $config['search_interval'];
106
if ($interval && !in_array($search_id, array('unreadposts', 'unanswered', 'active_topics', 'egosearch')) && !$auth->acl_get('u_ignoreflood'))
107
{
108
        if ($user->data['user_last_search'] > time() - $interval)
109
        {
110
                $template->assign_var('S_NO_SEARCH', true);
111
                trigger_error('NO_SEARCH_TIME');
112
        }
113
}
114
115
// Define some vars
116
$limit_days                = array(0 => $user->lang['ALL_RESULTS'], 1 => $user->lang['1_DAY'], 7 => $user->lang['7_DAYS'], 14 => $user->lang['2_WEEKS'], 30 => $user->lang['1_MONTH'], 90 => $user->lang['3_MONTHS'], 180 => $user->lang['6_MONTHS'], 365 => $user->lang['1_YEAR']);
117
$sort_by_text        = array('a' => $user->lang['SORT_AUTHOR'], 't' => $user->lang['SORT_TIME'], 'f' => $user->lang['SORT_FORUM'], 'i' => $user->lang['SORT_TOPIC_TITLE'], 's' => $user->lang['SORT_POST_SUBJECT']);
118
119
$s_limit_days = $s_sort_key = $s_sort_dir = $u_sort_param = '';
120
gen_sort_selects($limit_days, $sort_by_text, $sort_days, $sort_key, $sort_dir, $s_limit_days, $s_sort_key, $s_sort_dir, $u_sort_param);
121
122
if ($keywords || $author || $author_id || $search_id || $submit)
123
{
124
        // clear arrays
125
        $id_ary = array();
126
127
        // If we are looking for authors get their ids
128
        $author_id_ary = array();
129
        $sql_author_match = '';
130
        if ($author_id)
131
        {
132
                $author_id_ary[] = $author_id;
133
        }
134
        else if ($author)
135
        {
136
                if ((strpos($author, '*') !== false) && (utf8_strlen(str_replace(array('*', '%'), '', $author)) < $config['min_search_author_chars']))
137
                {
138
                        trigger_error($user->lang('TOO_FEW_AUTHOR_CHARS', (int) $config['min_search_author_chars']));
139
                }
140
141
                $sql_where = (strpos($author, '*') !== false) ? ' username_clean ' . $db->sql_like_expression(str_replace('*', $db->any_char, utf8_clean_string($author))) : " username_clean = '" . $db->sql_escape(utf8_clean_string($author)) . "'";
142
143
                $sql = 'SELECT user_id
144
                        FROM ' . USERS_TABLE . "
145
                        WHERE $sql_where
146
                                AND user_type <> " . USER_IGNORE;
147
                $result = $db->sql_query_limit($sql, 100);
148
149
                while ($row = $db->sql_fetchrow($result))
150
                {
151
                        $author_id_ary[] = (int) $row['user_id'];
152
                }
153
                $db->sql_freeresult($result);
154
155
                $sql_where = (strpos($author, '*') !== false) ? ' post_username ' . $db->sql_like_expression(str_replace('*', $db->any_char, utf8_clean_string($author))) : " post_username = '" . $db->sql_escape(utf8_clean_string($author)) . "'";
156
157
                $sql = 'SELECT 1 as guest_post
158
                        FROM ' . POSTS_TABLE . "
159
                        WHERE $sql_where
160
                                AND poster_id = " . ANONYMOUS;
161
                $result = $db->sql_query_limit($sql, 1);
162
                $found_guest_post = $db->sql_fetchfield('guest_post');
163
                $db->sql_freeresult($result);
164
165
                if ($found_guest_post)
166
                {
167
                        $author_id_ary[] = ANONYMOUS;
168
                        $sql_author_match = (strpos($author, '*') !== false) ? ' ' . $db->sql_like_expression(str_replace('*', $db->any_char, utf8_clean_string($author))) : " = '" . $db->sql_escape(utf8_clean_string($author)) . "'";
169
                }
170
171
                if (!sizeof($author_id_ary))
172
                {
173
                        trigger_error('NO_SEARCH_RESULTS');
174
                }
175
        }
176
177
        // if we search in an existing search result just add the additional keywords. But we need to use "all search terms"-mode
178
        // so we can keep the old keywords in their old mode, but add the new ones as required words
179
        if ($add_keywords)
180
        {
181
                if ($search_terms == 'all')
182
                {
183
                        $keywords .= ' ' . $add_keywords;
184
                }
185
                else
186
                {
187
                        $search_terms = 'all';
188
                        $keywords = implode(' |', explode(' ', preg_replace('#\s+#u', ' ', $keywords))) . ' ' .$add_keywords;
189
                }
190
        }
191
192
        // Which forums should not be searched? Author searches are also carried out in unindexed forums
193
        if (empty($keywords) && sizeof($author_id_ary))
194
        {
195
                $ex_fid_ary = array_keys($auth->acl_getf('!f_read', true));
196
        }
197
        else
198
        {
199
                $ex_fid_ary = array_unique(array_merge(array_keys($auth->acl_getf('!f_read', true)), array_keys($auth->acl_getf('!f_search', true))));
200
        }
201
202
        $not_in_fid = (sizeof($ex_fid_ary)) ? 'WHERE ' . $db->sql_in_set('f.forum_id', $ex_fid_ary, true) . " OR (f.forum_password <> '' AND fa.user_id <> " . (int) $user->data['user_id'] . ')' : "";
203
204
        $sql = 'SELECT f.forum_id, f.forum_name, f.parent_id, f.forum_type, f.right_id, f.forum_password, f.forum_flags, fa.user_id
205
                FROM ' . FORUMS_TABLE . ' f
206
                LEFT JOIN ' . FORUMS_ACCESS_TABLE . " fa ON (fa.forum_id = f.forum_id
207
                        AND fa.session_id = '" . $db->sql_escape($user->session_id) . "')
208
                $not_in_fid
209
                ORDER BY f.left_id";
210
        $result = $db->sql_query($sql);
211
212
        $right_id = 0;
213
        $reset_search_forum = true;
214
        while ($row = $db->sql_fetchrow($result))
215
        {
216
                if ($row['forum_password'] && $row['user_id'] != $user->data['user_id'])
217
                {
218
                        $ex_fid_ary[] = (int) $row['forum_id'];
219
                        continue;
220
                }
221
222
                // Exclude forums from active topics
223
                if (!($row['forum_flags'] & FORUM_FLAG_ACTIVE_TOPICS) && ($search_id == 'active_topics'))
224
                {
225
                        $ex_fid_ary[] = (int) $row['forum_id'];
226
                        continue;
227
                }
228
229
                if (sizeof($search_forum))
230
                {
231
                        if ($search_child)
232
                        {
233
                                if (in_array($row['forum_id'], $search_forum) && $row['right_id'] > $right_id)
234
                                {
235
                                        $right_id = (int) $row['right_id'];
236
                                }
237
                                else if ($row['right_id'] < $right_id)
238
                                {
239
                                        continue;
240
                                }
241
                        }
242
243
                        if (!in_array($row['forum_id'], $search_forum))
244
                        {
245
                                $ex_fid_ary[] = (int) $row['forum_id'];
246
                                $reset_search_forum = false;
247
                        }
248
                }
249
        }
250
        $db->sql_freeresult($result);
251
252
        // find out in which forums the user is allowed to view approved posts
253
        if ($auth->acl_get('m_approve'))
254
        {
255
                $m_approve_fid_ary = array(-1);
256
                $m_approve_fid_sql = '';
257
        }
258
        else if ($auth->acl_getf_global('m_approve'))
259
        {
260
                $m_approve_fid_ary = array_diff(array_keys($auth->acl_getf('!m_approve', true)), $ex_fid_ary);
261
                $m_approve_fid_sql = ' AND (p.post_approved = 1' . ((sizeof($m_approve_fid_ary)) ? ' OR ' . $db->sql_in_set('p.forum_id', $m_approve_fid_ary, true) : '') . ')';
262
        }
263
        else
264
        {
265
                $m_approve_fid_ary = array();
266
                $m_approve_fid_sql = ' AND p.post_approved = 1';
267
        }
268
269
        if ($reset_search_forum)
270
        {
271
                $search_forum = array();
272
        }
273
274
        // Select which method we'll use to obtain the post_id or topic_id information
275
        $search_type = $config['search_type'];
276
277
        if (!class_exists($search_type))
278
        {
279
                trigger_error('NO_SUCH_SEARCH_MODULE');
280
        }
281
        // We do some additional checks in the module to ensure it can actually be utilised
282
        $error = false;
283
        $search = new $search_type($error);
284
285
        if ($error)
286
        {
287
                trigger_error($error);
288
        }
289
290
        // let the search module split up the keywords
291
        if ($keywords)
292
        {
293
                $correct_query = $search->split_keywords($keywords, $search_terms);
294
                if (!$correct_query || (empty($search->search_query) && !sizeof($author_id_ary) && !$search_id))
295
                {
296
                        $ignored = (sizeof($search->common_words)) ? sprintf($user->lang['IGNORED_TERMS_EXPLAIN'], implode(' ', $search->common_words)) . '<br />' : '';
297
                        trigger_error($ignored . $user->lang('NO_KEYWORDS', $user->lang('CHARACTERS', (int) $search->word_length['min']), $user->lang('CHARACTERS', (int) $search->word_length['max'])));
298
                }
299
        }
300
301
        if (!$keywords && sizeof($author_id_ary))
302
        {
303
                // if it is an author search we want to show topics by default
304
                $show_results = ($topic_id) ? 'posts' : request_var('sr', ($search_id == 'egosearch') ? 'topics' : 'posts');
305
                $show_results = ($show_results == 'posts') ? 'posts' : 'topics';
306
        }
307
308
        // define some variables needed for retrieving post_id/topic_id information
309
        $sort_by_sql = array('a' => 'u.username_clean', 't' => (($show_results == 'posts') ? 'p.post_time' : 't.topic_last_post_time'), 'f' => 'f.forum_id', 'i' => 't.topic_title', 's' => (($show_results == 'posts') ? 'p.post_subject' : 't.topic_title'));
310
311
        // pre-made searches
312
        $sql = $field = $l_search_title = '';
313
        if ($search_id)
314
        {
315
                switch ($search_id)
316
                {
317
                        // Oh holy Bob, bring us some activity...
318
                        case 'active_topics':
319
                                $l_search_title = $user->lang['SEARCH_ACTIVE_TOPICS'];
320
                                $show_results = 'topics';
321
                                $sort_key = 't';
322
                                $sort_dir = 'd';
323
                                $sort_days = request_var('st', 7);
324
                                $sort_by_sql['t'] = 't.topic_last_post_time';
325
326
                                gen_sort_selects($limit_days, $sort_by_text, $sort_days, $sort_key, $sort_dir, $s_limit_days, $s_sort_key, $s_sort_dir, $u_sort_param);
327
                                $s_sort_key = $s_sort_dir = '';
328
329
                                $last_post_time_sql = ($sort_days) ? ' AND t.topic_last_post_time > ' . (time() - ($sort_days * 24 * 3600)) : '';
330
331
                                $sql = 'SELECT t.topic_last_post_time, t.topic_id
332
                                        FROM ' . TOPICS_TABLE . " t
333
                                        WHERE t.topic_moved_id = 0
334
                                                $last_post_time_sql
335
                                                " . str_replace(array('p.', 'post_'), array('t.', 'topic_'), $m_approve_fid_sql) . '
336
                                                ' . ((sizeof($ex_fid_ary)) ? ' AND ' . $db->sql_in_set('t.forum_id', $ex_fid_ary, true) : '') . '
337
                                        ORDER BY t.topic_last_post_time DESC';
338
                                $field = 'topic_id';
339
                        break;
340
341
                        case 'unanswered':
342
                                $l_search_title = $user->lang['SEARCH_UNANSWERED'];
343
                                $show_results = request_var('sr', 'topics');
344
                                $show_results = ($show_results == 'posts') ? 'posts' : 'topics';
345
                                $sort_by_sql['t'] = ($show_results == 'posts') ? 'p.post_time' : 't.topic_last_post_time';
346
                                $sort_by_sql['s'] = ($show_results == 'posts') ? 'p.post_subject' : 't.topic_title';
347
                                $sql_sort = 'ORDER BY ' . $sort_by_sql[$sort_key] . (($sort_dir == 'a') ? ' ASC' : ' DESC');
348
349
                                $sort_join = ($sort_key == 'f') ? FORUMS_TABLE . ' f, ' : '';
350
                                $sql_sort = ($sort_key == 'f') ? ' AND f.forum_id = p.forum_id ' . $sql_sort : $sql_sort;
351
352
                                if ($sort_days)
353
                                {
354
                                        $last_post_time = 'AND p.post_time > ' . (time() - ($sort_days * 24 * 3600));
355
                                }
356
                                else
357
                                {
358
                                        $last_post_time = '';
359
                                }
360
361
                                if ($sort_key == 'a')
362
                                {
363
                                        $sort_join = USERS_TABLE . ' u, ';
364
                                        $sql_sort = ' AND u.user_id = p.poster_id ' . $sql_sort;
365
                                }
366
                                if ($show_results == 'posts')
367
                                {
368
                                        $sql = "SELECT p.post_id
369
                                                FROM $sort_join" . POSTS_TABLE . ' p, ' . TOPICS_TABLE . " t
370
                                                WHERE t.topic_replies = 0
371
                                                        AND p.topic_id = t.topic_id
372
                                                        $last_post_time
373
                                                        $m_approve_fid_sql
374
                                                        " . ((sizeof($ex_fid_ary)) ? ' AND ' . $db->sql_in_set('p.forum_id', $ex_fid_ary, true) : '') . "
375
                                                        $sql_sort";
376
                                        $field = 'post_id';
377
                                }
378
                                else
379
                                {
380
                                        $sql = 'SELECT DISTINCT ' . $sort_by_sql[$sort_key] . ", p.topic_id
381
                                                FROM $sort_join" . POSTS_TABLE . ' p, ' . TOPICS_TABLE . " t
382
                                                WHERE t.topic_replies = 0
383
                                                        AND t.topic_moved_id = 0
384
                                                        AND p.topic_id = t.topic_id
385
                                                        $last_post_time
386
                                                        $m_approve_fid_sql
387
                                                        " . ((sizeof($ex_fid_ary)) ? ' AND ' . $db->sql_in_set('p.forum_id', $ex_fid_ary, true) : '') . "
388
                                                $sql_sort";
389
                                        $field = 'topic_id';
390
                                }
391
                        break;
392
393
                        case 'unreadposts':
394
                                $l_search_title = $user->lang['SEARCH_UNREAD'];
395
                                // force sorting
396
                                $show_results = 'topics';
397
                                $sort_key = 't';
398
                                $sort_by_sql['t'] = 't.topic_last_post_time';
399
                                $sql_sort = 'ORDER BY ' . $sort_by_sql[$sort_key] . (($sort_dir == 'a') ? ' ASC' : ' DESC');
400
401
                                $sql_where = 'AND t.topic_moved_id = 0
402
                                        ' . str_replace(array('p.', 'post_'), array('t.', 'topic_'), $m_approve_fid_sql) . '
403
                                        ' . ((sizeof($ex_fid_ary)) ? 'AND ' . $db->sql_in_set('t.forum_id', $ex_fid_ary, true) : '');
404
405
                                gen_sort_selects($limit_days, $sort_by_text, $sort_days, $sort_key, $sort_dir, $s_limit_days, $s_sort_key, $s_sort_dir, $u_sort_param);
406
                                $s_sort_key = $s_sort_dir = $u_sort_param = $s_limit_days = '';
407
                        break;
408
409
                        case 'newposts':
410
                                $l_search_title = $user->lang['SEARCH_NEW'];
411
                                // force sorting
412
                                $show_results = (request_var('sr', 'topics') == 'posts') ? 'posts' : 'topics';
413
                                $sort_key = 't';
414
                                $sort_dir = 'd';
415
                                $sort_by_sql['t'] = ($show_results == 'posts') ? 'p.post_time' : 't.topic_last_post_time';
416
                                $sql_sort = 'ORDER BY ' . $sort_by_sql[$sort_key] . (($sort_dir == 'a') ? ' ASC' : ' DESC');
417
418
                                gen_sort_selects($limit_days, $sort_by_text, $sort_days, $sort_key, $sort_dir, $s_limit_days, $s_sort_key, $s_sort_dir, $u_sort_param);
419
                                $s_sort_key = $s_sort_dir = $u_sort_param = $s_limit_days = '';
420
421
                                if ($show_results == 'posts')
422
                                {
423
                                        $sql = 'SELECT p.post_id
424
                                                FROM ' . POSTS_TABLE . ' p
425
                                                WHERE p.post_time > ' . $user->data['user_lastvisit'] . "
426
                                                        $m_approve_fid_sql
427
                                                        " . ((sizeof($ex_fid_ary)) ? ' AND ' . $db->sql_in_set('p.forum_id', $ex_fid_ary, true) : '') . "
428
                                                $sql_sort";
429
                                        $field = 'post_id';
430
                                }
431
                                else
432
                                {
433
                                        $sql = 'SELECT t.topic_id
434
                                                FROM ' . TOPICS_TABLE . ' t
435
                                                WHERE t.topic_last_post_time > ' . $user->data['user_lastvisit'] . '
436
                                                        AND t.topic_moved_id = 0
437
                                                        ' . str_replace(array('p.', 'post_'), array('t.', 'topic_'), $m_approve_fid_sql) . '
438
                                                        ' . ((sizeof($ex_fid_ary)) ? 'AND ' . $db->sql_in_set('t.forum_id', $ex_fid_ary, true) : '') . "
439
                                                $sql_sort";
440
/*
441
                [Fix] queued replies missing from "view new posts" (Bug #42705 - Patch by Paul)
442
                - Creates temporary table, query is far from optimized
443
444
                                        $sql = 'SELECT t.topic_id
445
                                                FROM ' . TOPICS_TABLE . ' t, ' . POSTS_TABLE . ' p
446
                                                WHERE p.post_time > ' . $user->data['user_lastvisit'] . '
447
                                                        AND t.topic_id = p.topic_id
448
                                                        AND t.topic_moved_id = 0
449
                                                        ' . $m_approve_fid_sql . '
450
                                                        ' . ((sizeof($ex_fid_ary)) ? 'AND ' . $db->sql_in_set('t.forum_id', $ex_fid_ary, true) : '') . "
451
                                                GROUP BY t.topic_id
452
                                                $sql_sort";
453
*/
454
                                        $field = 'topic_id';
455
                                }
456
                        break;
457
458
                        case 'egosearch':
459
                                $l_search_title = $user->lang['SEARCH_SELF'];
460
                        break;
461
                }
462
        }
463
464
        // show_results should not change after this
465
        $per_page = ($show_results == 'posts') ? $config['posts_per_page'] : $config['topics_per_page'];
466
        $total_match_count = 0;
467
468
        if ($search_id)
469
        {
470
                if ($sql)
471
                {
472
                        // only return up to 1000 ids (the last one will be removed later)
473
                        $result = $db->sql_query_limit($sql, 1001 - $start, $start);
474
475
                        while ($row = $db->sql_fetchrow($result))
476
                        {
477
                                $id_ary[] = (int) $row[$field];
478
                        }
479
                        $db->sql_freeresult($result);
480
481
                        $total_match_count = sizeof($id_ary) + $start;
482
                        $id_ary = array_slice($id_ary, 0, $per_page);
483
                }
484
                else if ($search_id == 'unreadposts')
485
                {
486
                        $id_ary = array_keys(get_unread_topics($user->data['user_id'], $sql_where, $sql_sort, 1001 - $start, $start));
487
488
                        $total_match_count = sizeof($id_ary) + $start;
489
                        $id_ary = array_slice($id_ary, 0, $per_page);
490
                }
491
                else
492
                {
493
                        $search_id = '';
494
                }
495
        }
496
497
        // make sure that some arrays are always in the same order
498
        sort($ex_fid_ary);
499
        sort($m_approve_fid_ary);
500
        sort($author_id_ary);
501
502
        if (!empty($search->search_query))
503
        {
504
                $total_match_count = $search->keyword_search($show_results, $search_fields, $search_terms, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $m_approve_fid_ary, $topic_id, $author_id_ary, $sql_author_match, $id_ary, $start, $per_page);
505
        }
506
        else if (sizeof($author_id_ary))
507
        {
508
                $firstpost_only = ($search_fields === 'firstpost' || $search_fields == 'titleonly') ? true : false;
509
                $total_match_count = $search->author_search($show_results, $firstpost_only, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $m_approve_fid_ary, $topic_id, $author_id_ary, $sql_author_match, $id_ary, $start, $per_page);
510
        }
511
512
        // For some searches we need to print out the "no results" page directly to allow re-sorting/refining the search options.
513
        if (!sizeof($id_ary) && !$search_id)
514
        {
515
                trigger_error('NO_SEARCH_RESULTS');
516
        }
517
518
        $sql_where = '';
519
520
        if (sizeof($id_ary))
521
        {
522
                $sql_where .= $db->sql_in_set(($show_results == 'posts') ? 'p.post_id' : 't.topic_id', $id_ary);
523
                $sql_where .= (sizeof($ex_fid_ary)) ? ' AND (' . $db->sql_in_set('f.forum_id', $ex_fid_ary, true) . ' OR f.forum_id IS NULL)' : '';
524
                $sql_where .= ($show_results == 'posts') ? $m_approve_fid_sql : str_replace(array('p.post_approved', 'p.forum_id'), array('t.topic_approved', 't.forum_id'), $m_approve_fid_sql);
525
        }
526
527
        if ($show_results == 'posts')
528
        {
529
                include($phpbb_root_path . 'includes/functions_posting.' . $phpEx);
530
        }
531
        else
532
        {
533
                include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
534
        }
535
536
        $user->add_lang('viewtopic');
537
538
        // Grab icons
539
        $icons = $cache->obtain_icons();
540
541
        // Output header
542
        if ($search_id && ($total_match_count > 1000))
543
        {
544
                // limit the number to 1000 for pre-made searches
545
                $total_match_count--;
546
                $l_search_matches = $user->lang('FOUND_MORE_SEARCH_MATCHES', (int) $total_match_count);
547
        }
548
        else
549
        {
550
                $l_search_matches = $user->lang('FOUND_SEARCH_MATCHES', (int) $total_match_count);
551
        }
552
553
        // define some vars for urls
554
        $hilit = implode('|', explode(' ', preg_replace('#\s+#u', ' ', str_replace(array('+', '-', '|', '(', ')', '&quot;'), ' ', $keywords))));
555
        // Do not allow *only* wildcard being used for hilight
556
        $hilit = (strspn($hilit, '*') === strlen($hilit)) ? '' : $hilit;
557
558
        $u_hilit = urlencode(htmlspecialchars_decode(str_replace('|', ' ', $hilit)));
559
        $u_show_results = '&amp;sr=' . $show_results;
560
        $u_search_forum = implode('&amp;fid%5B%5D=', $search_forum);
561
562
        $u_search = append_sid("{$phpbb_root_path}search.$phpEx", $u_sort_param . $u_show_results);
563
        $u_search .= ($search_id) ? '&amp;search_id=' . $search_id : '';
564
        $u_search .= ($u_hilit) ? '&amp;keywords=' . urlencode(htmlspecialchars_decode($keywords)) : '';
565
        $u_search .= ($search_terms != 'all') ? '&amp;terms=' . $search_terms : '';
566
        $u_search .= ($topic_id) ? '&amp;t=' . $topic_id : '';
567
        $u_search .= ($author) ? '&amp;author=' . urlencode(htmlspecialchars_decode($author)) : '';
568
        $u_search .= ($author_id) ? '&amp;author_id=' . $author_id : '';
569
        $u_search .= ($u_search_forum) ? '&amp;fid%5B%5D=' . $u_search_forum : '';
570
        $u_search .= (!$search_child) ? '&amp;sc=0' : '';
571
        $u_search .= ($search_fields != 'all') ? '&amp;sf=' . $search_fields : '';
572
        $u_search .= ($return_chars != 300) ? '&amp;ch=' . $return_chars : '';
573
574
        $template->assign_vars(array(
575
                'SEARCH_TITLE'                => $l_search_title,
576
                'SEARCH_MATCHES'        => $l_search_matches,
577
                'SEARCH_WORDS'                => $search->search_query,
578
                'IGNORED_WORDS'                => (sizeof($search->common_words)) ? implode(' ', $search->common_words) : '',
579
                'PAGINATION'                => generate_pagination($u_search, $total_match_count, $per_page, $start),
580
                'PAGE_NUMBER'                => on_page($total_match_count, $per_page, $start),
581
                'TOTAL_MATCHES'                => $total_match_count,
582
                'SEARCH_IN_RESULTS'        => ($search_id) ? false : true,
583
584
                'S_SELECT_SORT_DIR'                => $s_sort_dir,
585
                'S_SELECT_SORT_KEY'                => $s_sort_key,
586
                'S_SELECT_SORT_DAYS'        => $s_limit_days,
587
                'S_SEARCH_ACTION'                => $u_search,
588
                'S_SHOW_TOPICS'                        => ($show_results == 'posts') ? false : true,
589
590
                'GOTO_PAGE_IMG'                => $user->img('icon_post_target', 'GOTO_PAGE'),
591
                'NEWEST_POST_IMG'        => $user->img('icon_topic_newest', 'VIEW_NEWEST_POST'),
592
                'REPORTED_IMG'                => $user->img('icon_topic_reported', 'TOPIC_REPORTED'),
593
                'UNAPPROVED_IMG'        => $user->img('icon_topic_unapproved', 'TOPIC_UNAPPROVED'),
594
                'LAST_POST_IMG'                => $user->img('icon_topic_latest', 'VIEW_LATEST_POST'),
595
596
                'U_SEARCH_WORDS'        => $u_search,
597
        ));
598
599
        if ($sql_where)
600
        {
601
                if ($show_results == 'posts')
602
                {
603
                        // @todo Joining this query to the one below?
604
                        $sql = 'SELECT zebra_id, friend, foe
605
                                FROM ' . ZEBRA_TABLE . '
606
                                WHERE user_id = ' . $user->data['user_id'];
607
                        $result = $db->sql_query($sql);
608
609
                        $zebra = array();
610
                        while ($row = $db->sql_fetchrow($result))
611
                        {
612
                                $zebra[($row['friend']) ? 'friend' : 'foe'][] = $row['zebra_id'];
613
                        }
614
                        $db->sql_freeresult($result);
615
616
                        $sql = 'SELECT p.*, f.forum_id, f.forum_name, t.*, u.username, u.username_clean, u.user_sig, u.user_sig_bbcode_uid, u.user_colour
617
                                FROM ' . POSTS_TABLE . ' p
618
                                        LEFT JOIN ' . TOPICS_TABLE . ' t ON (p.topic_id = t.topic_id)
619
                                        LEFT JOIN ' . FORUMS_TABLE . ' f ON (p.forum_id = f.forum_id)
620
                                        LEFT JOIN ' . USERS_TABLE . " u ON (p.poster_id = u.user_id)
621
                                WHERE $sql_where";
622
                }
623
                else
624
                {
625
                        $sql_from = TOPICS_TABLE . ' t
626
                                LEFT JOIN ' . FORUMS_TABLE . ' f ON (f.forum_id = t.forum_id)
627
                                ' . (($sort_key == 'a') ? ' LEFT JOIN ' . USERS_TABLE . ' u ON (u.user_id = t.topic_poster) ' : '');
628
                        $sql_select = 't.*, f.forum_id, f.forum_name';
629
630
                        if ($user->data['is_registered'])
631
                        {
632
                                if ($config['load_db_track'] && $author_id !== $user->data['user_id'])
633
                                {
634
                                        $sql_from .= ' LEFT JOIN ' . TOPICS_POSTED_TABLE . ' tp ON (tp.user_id = ' . $user->data['user_id'] . '
635
                                                AND t.topic_id = tp.topic_id)';
636
                                        $sql_select .= ', tp.topic_posted';
637
                                }
638
639
                                if ($config['load_db_lastread'])
640
                                {
641
                                        $sql_from .= ' LEFT JOIN ' . TOPICS_TRACK_TABLE . ' tt ON (tt.user_id = ' . $user->data['user_id'] . '
642
                                                        AND t.topic_id = tt.topic_id)
643
                                                LEFT JOIN ' . FORUMS_TRACK_TABLE . ' ft ON (ft.user_id = ' . $user->data['user_id'] . '
644
                                                        AND ft.forum_id = f.forum_id)';
645
                                        $sql_select .= ', tt.mark_time, ft.mark_time as f_mark_time';
646
                                }
647
                        }
648
649
                        if ($config['load_anon_lastread'] || ($user->data['is_registered'] && !$config['load_db_lastread']))
650
                        {
651
                                $tracking_topics = $request->variable($config['cookie_name'] . '_track', '', true, phpbb_request_interface::COOKIE);
652
                                $tracking_topics = ($tracking_topics) ? tracking_unserialize($tracking_topics) : array();
653
                        }
654
655
                        $sql = "SELECT $sql_select
656
                                FROM $sql_from
657
                                WHERE $sql_where";
658
                }
659
                $sql .= ' ORDER BY ' . $sort_by_sql[$sort_key] . ' ' . (($sort_dir == 'd') ? 'DESC' : 'ASC');
660
                $result = $db->sql_query($sql);
661
                $result_topic_id = 0;
662
663
                $rowset = array();
664
665
                if ($show_results == 'topics')
666
                {
667
                        $forums = $rowset = $shadow_topic_list = array();
668
                        while ($row = $db->sql_fetchrow($result))
669
                        {
670
                                $row['forum_id'] = (int) $row['forum_id'];
671
                                $row['topic_id'] = (int) $row['topic_id'];
672
673
                                if ($row['topic_status'] == ITEM_MOVED)
674
                                {
675
                                        $shadow_topic_list[$row['topic_moved_id']] = $row['topic_id'];
676
                                }
677
678
                                $rowset[$row['topic_id']] = $row;
679
680
                                if (!isset($forums[$row['forum_id']]) && $user->data['is_registered'] && $config['load_db_lastread'])
681
                                {
682
                                        $forums[$row['forum_id']]['mark_time'] = $row['f_mark_time'];
683
                                }
684
                                $forums[$row['forum_id']]['topic_list'][] = $row['topic_id'];
685
                                $forums[$row['forum_id']]['rowset'][$row['topic_id']] = &$rowset[$row['topic_id']];
686
                        }
687
                        $db->sql_freeresult($result);
688
689
                        // If we have some shadow topics, update the rowset to reflect their topic information
690
                        if (sizeof($shadow_topic_list))
691
                        {
692
                                $sql = 'SELECT *
693
                                        FROM ' . TOPICS_TABLE . '
694
                                        WHERE ' . $db->sql_in_set('topic_id', array_keys($shadow_topic_list));
695
                                $result = $db->sql_query($sql);
696
697
                                while ($row = $db->sql_fetchrow($result))
698
                                {
699
                                        $orig_topic_id = $shadow_topic_list[$row['topic_id']];
700
701
                                        // We want to retain some values
702
                                        $row = array_merge($row, array(
703
                                                'topic_moved_id'        => $rowset[$orig_topic_id]['topic_moved_id'],
704
                                                'topic_status'                => $rowset[$orig_topic_id]['topic_status'],
705
                                                'forum_name'                => $rowset[$orig_topic_id]['forum_name'])
706
                                        );
707
708
                                        $rowset[$orig_topic_id] = $row;
709
                                }
710
                                $db->sql_freeresult($result);
711
                        }
712
                        unset($shadow_topic_list);
713
714
                        foreach ($forums as $forum_id => $forum)
715
                        {
716
                                if ($user->data['is_registered'] && $config['load_db_lastread'])
717
                                {
718
                                        $topic_tracking_info[$forum_id] = get_topic_tracking($forum_id, $forum['topic_list'], $forum['rowset'], array($forum_id => $forum['mark_time']));
719
                                }
720
                                else if ($config['load_anon_lastread'] || $user->data['is_registered'])
721
                                {
722
                                        $topic_tracking_info[$forum_id] = get_complete_topic_tracking($forum_id, $forum['topic_list']);
723
724
                                        if (!$user->data['is_registered'])
725
                                        {
726
                                                $user->data['user_lastmark'] = (isset($tracking_topics['l'])) ? (int) (base_convert($tracking_topics['l'], 36, 10) + $config['board_startdate']) : 0;
727
                                        }
728
                                }
729
                        }
730
                        unset($forums);
731
                }
732
                else
733
                {
734
                        $bbcode_bitfield = $text_only_message = '';
735
                        $attach_list = array();
736
737
                        while ($row = $db->sql_fetchrow($result))
738
                        {
739
                                // We pre-process some variables here for later usage
740
                                $row['post_text'] = censor_text($row['post_text']);
741
742
                                $text_only_message = $row['post_text'];
743
                                // make list items visible as such
744
                                if ($row['bbcode_uid'])
745
                                {
746
                                        $text_only_message = str_replace('[*:' . $row['bbcode_uid'] . ']', '&sdot;&nbsp;', $text_only_message);
747
                                        // no BBCode in text only message
748
                                        strip_bbcode($text_only_message, $row['bbcode_uid']);
749
                                }
750
751
                                if ($return_chars == -1 || utf8_strlen($text_only_message) < ($return_chars + 3))
752
                                {
753
                                        $row['display_text_only'] = false;
754
                                        $bbcode_bitfield = $bbcode_bitfield | base64_decode($row['bbcode_bitfield']);
755
756
                                        // Does this post have an attachment? If so, add it to the list
757
                                        if ($row['post_attachment'] && $config['allow_attachments'])
758
                                        {
759
                                                $attach_list[$row['forum_id']][] = $row['post_id'];
760
                                        }
761
                                }
762
                                else
763
                                {
764
                                        $row['post_text'] = $text_only_message;
765
                                        $row['display_text_only'] = true;
766
                                }
767
768
                                $rowset[] = $row;
769
                        }
770
                        $db->sql_freeresult($result);
771
772
                        unset($text_only_message);
773
774
                        // Instantiate BBCode if needed
775
                        if ($bbcode_bitfield !== '')
776
                        {
777
                                include_once($phpbb_root_path . 'includes/bbcode.' . $phpEx);
778
                                $bbcode = new bbcode(base64_encode($bbcode_bitfield));
779
                        }
780
781
                        // Pull attachment data
782
                        if (sizeof($attach_list))
783
                        {
784
                                $use_attach_list = $attach_list;
785
                                $attach_list = array();
786
787
                                foreach ($use_attach_list as $forum_id => $_list)
788
                                {
789
                                        if ($auth->acl_get('u_download') && $auth->acl_get('f_download', $forum_id))
790
                                        {
791
                                                $attach_list = array_merge($attach_list, $_list);
792
                                        }
793
                                }
794
                        }
795
796
                        if (sizeof($attach_list))
797
                        {
798
                                $sql = 'SELECT *
799
                                        FROM ' . ATTACHMENTS_TABLE . '
800
                                        WHERE ' . $db->sql_in_set('post_msg_id', $attach_list) . '
801
                                                AND in_message = 0
802
                                        ORDER BY filetime DESC, post_msg_id ASC';
803
                                $result = $db->sql_query($sql);
804
805
                                while ($row = $db->sql_fetchrow($result))
806
                                {
807
                                        $attachments[$row['post_msg_id']][] = $row;
808
                                }
809
                                $db->sql_freeresult($result);
810
                        }
811
                }
812
813
                if ($hilit)
814
                {
815
                        // Remove bad highlights
816
                        $hilit_array = array_filter(explode('|', $hilit), 'strlen');
817
                        foreach ($hilit_array as $key => $value)
818
                        {
819
                                $hilit_array[$key] = str_replace('\*', '\w*?', preg_quote($value, '#'));
820
                                $hilit_array[$key] = preg_replace('#(^|\s)\\\\w\*\?(\s|$)#', '$1\w+?$2', $hilit_array[$key]);
821
                        }
822
                        $hilit = implode('|', $hilit_array);
823
                }
824
825
                foreach ($rowset as $row)
826
                {
827
                        $forum_id = $row['forum_id'];
828
                        $result_topic_id = $row['topic_id'];
829
                        $topic_title = censor_text($row['topic_title']);
830
831
                        $view_topic_url_params = "f=$forum_id&amp;t=$result_topic_id" . (($u_hilit) ? "&amp;hilit=$u_hilit" : '');
832
                        $view_topic_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", $view_topic_url_params);
833
834
                        $replies = ($auth->acl_get('m_approve', $forum_id)) ? $row['topic_replies_real'] : $row['topic_replies'];
835
836
                        if ($show_results == 'topics')
837
                        {
838
                                if ($config['load_db_track'] && $author_id === $user->data['user_id'])
839
                                {
840
                                        $row['topic_posted'] = 1;
841
                                }
842
843
                                $folder_img = $folder_alt = $topic_type = '';
844
                                topic_status($row, $replies, (isset($topic_tracking_info[$forum_id][$row['topic_id']]) && $row['topic_last_post_time'] > $topic_tracking_info[$forum_id][$row['topic_id']]) ? true : false, $folder_img, $folder_alt, $topic_type);
845
846
                                $unread_topic = (isset($topic_tracking_info[$forum_id][$row['topic_id']]) && $row['topic_last_post_time'] > $topic_tracking_info[$forum_id][$row['topic_id']]) ? true : false;
847
848
                                $topic_unapproved = (!$row['topic_approved'] && $auth->acl_get('m_approve', $forum_id)) ? true : false;
849
                                $posts_unapproved = ($row['topic_approved'] && $row['topic_replies'] < $row['topic_replies_real'] && $auth->acl_get('m_approve', $forum_id)) ? true : false;
850
                                $u_mcp_queue = ($topic_unapproved || $posts_unapproved) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=queue&amp;mode=' . (($topic_unapproved) ? 'approve_details' : 'unapproved_posts') . "&amp;t=$result_topic_id", true, $user->session_id) : '';
851
852
                                $row['topic_title'] = preg_replace('#(?!<.*)(?<!\w)(' . $hilit . ')(?!\w|[^<>]*(?:</s(?:cript|tyle))?>)#is', '<span class="posthilit">$1</span>', $row['topic_title']);
853
854
                                $tpl_ary = array(
855
                                        'TOPIC_AUTHOR'                                => get_username_string('username', $row['topic_poster'], $row['topic_first_poster_name'], $row['topic_first_poster_colour']),
856
                                        'TOPIC_AUTHOR_COLOUR'                => get_username_string('colour', $row['topic_poster'], $row['topic_first_poster_name'], $row['topic_first_poster_colour']),
857
                                        'TOPIC_AUTHOR_FULL'                        => get_username_string('full', $row['topic_poster'], $row['topic_first_poster_name'], $row['topic_first_poster_colour']),
858
                                        'FIRST_POST_TIME'                        => $user->format_date($row['topic_time']),
859
                                        'LAST_POST_SUBJECT'                        => $row['topic_last_post_subject'],
860
                                        'LAST_POST_TIME'                        => $user->format_date($row['topic_last_post_time']),
861
                                        'LAST_VIEW_TIME'                        => $user->format_date($row['topic_last_view_time']),
862
                                        'LAST_POST_AUTHOR'                        => get_username_string('username', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']),
863
                                        'LAST_POST_AUTHOR_COLOUR'        => get_username_string('colour', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']),
864
                                        'LAST_POST_AUTHOR_FULL'                => get_username_string('full', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']),
865
866
                                        'PAGINATION'                => topic_generate_pagination($replies, $view_topic_url),
867
                                        'TOPIC_TYPE'                => $topic_type,
868
869
                                        'TOPIC_IMG_STYLE'                => $folder_img,
870
                                        'TOPIC_FOLDER_IMG'                => $user->img($folder_img, $folder_alt),
871
                                        'TOPIC_FOLDER_IMG_ALT'        => $user->lang[$folder_alt],
872
873
                                        'TOPIC_ICON_IMG'                => (!empty($icons[$row['icon_id']])) ? $icons[$row['icon_id']]['img'] : '',
874
                                        'TOPIC_ICON_IMG_WIDTH'        => (!empty($icons[$row['icon_id']])) ? $icons[$row['icon_id']]['width'] : '',
875
                                        'TOPIC_ICON_IMG_HEIGHT'        => (!empty($icons[$row['icon_id']])) ? $icons[$row['icon_id']]['height'] : '',
876
                                        'ATTACH_ICON_IMG'                => ($auth->acl_get('u_download') && $auth->acl_get('f_download', $forum_id) && $row['topic_attachment']) ? $user->img('icon_topic_attach', $user->lang['TOTAL_ATTACHMENTS']) : '',
877
                                        'UNAPPROVED_IMG'                => ($topic_unapproved || $posts_unapproved) ? $user->img('icon_topic_unapproved', ($topic_unapproved) ? 'TOPIC_UNAPPROVED' : 'POSTS_UNAPPROVED') : '',
878
879
                                        'S_TOPIC_TYPE'                        => $row['topic_type'],
880
                                        'S_USER_POSTED'                        => (!empty($row['topic_posted'])) ? true : false,
881
                                        'S_UNREAD_TOPIC'                => $unread_topic,
882
883
                                        'S_TOPIC_REPORTED'                => (!empty($row['topic_reported']) && $auth->acl_get('m_report', $forum_id)) ? true : false,
884
                                        'S_TOPIC_UNAPPROVED'        => $topic_unapproved,
885
                                        'S_POSTS_UNAPPROVED'        => $posts_unapproved,
886
887
                                        'U_LAST_POST'                        => append_sid("{$phpbb_root_path}viewtopic.$phpEx", $view_topic_url_params . '&amp;p=' . $row['topic_last_post_id']) . '#p' . $row['topic_last_post_id'],
888
                                        'U_LAST_POST_AUTHOR'        => get_username_string('profile', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']),
889
                                        'U_TOPIC_AUTHOR'                => get_username_string('profile', $row['topic_poster'], $row['topic_first_poster_name'], $row['topic_first_poster_colour']),
890
                                        'U_NEWEST_POST'                        => append_sid("{$phpbb_root_path}viewtopic.$phpEx", $view_topic_url_params . '&amp;view=unread') . '#unread',
891
                                        'U_MCP_REPORT'                        => append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=reports&amp;mode=reports&amp;t=' . $result_topic_id, true, $user->session_id),
892
                                        'U_MCP_QUEUE'                        => $u_mcp_queue,
893
                                );
894
                        }
895
                        else
896
                        {
897
                                if ((isset($zebra['foe']) && in_array($row['poster_id'], $zebra['foe'])) && (!$view || $view != 'show' || $post_id != $row['post_id']))
898
                                {
899
                                        $template->assign_block_vars('searchresults', array(
900
                                                'S_IGNORE_POST' => true,
901
902
                                                'L_IGNORE_POST' => sprintf($user->lang['POST_BY_FOE'], $row['username'], "<a href=\"$u_search&amp;start=$start&amp;p=" . $row['post_id'] . '&amp;view=show#p' . $row['post_id'] . '">', '</a>'))
903
                                        );
904
905
                                        continue;
906
                                }
907
908
                                // Replace naughty words such as farty pants
909
                                $row['post_subject'] = censor_text($row['post_subject']);
910
911
                                if ($row['display_text_only'])
912
                                {
913
                                        // now find context for the searched words
914
                                        $row['post_text'] = get_context($row['post_text'], array_filter(explode('|', $hilit), 'strlen'), $return_chars);
915
                                        $row['post_text'] = bbcode_nl2br($row['post_text']);
916
                                }
917
                                else
918
                                {
919
                                        // Second parse bbcode here
920
                                        if ($row['bbcode_bitfield'])
921
                                        {
922
                                                $bbcode->bbcode_second_pass($row['post_text'], $row['bbcode_uid'], $row['bbcode_bitfield']);
923
                                        }
924
925
                                        $row['post_text'] = bbcode_nl2br($row['post_text']);
926
                                        $row['post_text'] = smiley_text($row['post_text']);
927
928
                                        if (!empty($attachments[$row['post_id']]))
929
                                        {
930
                                                parse_attachments($forum_id, $row['post_text'], $attachments[$row['post_id']], $update_count);
931
932
                                                // we only display inline attachments
933
                                                unset($attachments[$row['post_id']]);
934
                                        }
935
                                }
936
937
                                if ($hilit)
938
                                {
939
                                        // post highlighting
940
                                        $row['post_text'] = preg_replace('#(?!<.*)(?<!\w)(' . $hilit . ')(?!\w|[^<>]*(?:</s(?:cript|tyle))?>)#is', '<span class="posthilit">$1</span>', $row['post_text']);
941
                                        $row['post_subject'] = preg_replace('#(?!<.*)(?<!\w)(' . $hilit . ')(?!\w|[^<>]*(?:</s(?:cript|tyle))?>)#is', '<span class="posthilit">$1</span>', $row['post_subject']);
942
                                }
943
944
                                $tpl_ary = array(
945
                                        'POST_AUTHOR_FULL'                => get_username_string('full', $row['poster_id'], $row['username'], $row['user_colour'], $row['post_username']),
946
                                        'POST_AUTHOR_COLOUR'        => get_username_string('colour', $row['poster_id'], $row['username'], $row['user_colour'], $row['post_username']),
947
                                        'POST_AUTHOR'                        => get_username_string('username', $row['poster_id'], $row['username'], $row['user_colour'], $row['post_username']),
948
                                        'U_POST_AUTHOR'                        => get_username_string('profile', $row['poster_id'], $row['username'], $row['user_colour'], $row['post_username']),
949
950
                                        'POST_SUBJECT'                => $row['post_subject'],
951
                                        'POST_DATE'                        => (!empty($row['post_time'])) ? $user->format_date($row['post_time']) : '',
952
                                        'MESSAGE'                        => $row['post_text']
953
                                );
954
                        }
955
956
                        $template->assign_block_vars('searchresults', array_merge($tpl_ary, array(
957
                                'FORUM_ID'                        => $forum_id,
958
                                'TOPIC_ID'                        => $result_topic_id,
959
                                'POST_ID'                        => ($show_results == 'posts') ? $row['post_id'] : false,
960
961
                                'FORUM_TITLE'                => $row['forum_name'],
962
                                'TOPIC_TITLE'                => $topic_title,
963
                                'TOPIC_REPLIES'                => $replies,
964
                                'TOPIC_VIEWS'                => $row['topic_views'],
965
966
                                'U_VIEW_TOPIC'                => $view_topic_url,
967
                                'U_VIEW_FORUM'                => append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $forum_id),
968
                                'U_VIEW_POST'                => (!empty($row['post_id'])) ? append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&amp;t=" . $row['topic_id'] . '&amp;p=' . $row['post_id'] . (($u_hilit) ? '&amp;hilit=' . $u_hilit : '')) . '#p' . $row['post_id'] : '')
969
                        ));
970
                }
971
972
                if ($topic_id && ($topic_id == $result_topic_id))
973
                {
974
                        $template->assign_vars(array(
975
                                'SEARCH_TOPIC'                => $topic_title,
976
                                'U_SEARCH_TOPIC'        => $view_topic_url
977
                        ));
978
                }
979
        }
980
        unset($rowset);
981
982
        page_header(($l_search_title) ? $l_search_title : $user->lang['SEARCH']);
983
984
        $template->set_filenames(array(
985
                'body' => 'search_results.html')
986
        );
987
        make_jumpbox(append_sid("{$phpbb_root_path}viewforum.$phpEx"));
988
989
        page_footer();
990
}
991
992
// Search forum
993
$s_forums = '';
994
$sql = 'SELECT f.forum_id, f.forum_name, f.parent_id, f.forum_type, f.left_id, f.right_id, f.forum_password, f.enable_indexing, fa.user_id
995
        FROM ' . FORUMS_TABLE . ' f
996
        LEFT JOIN ' . FORUMS_ACCESS_TABLE . " fa ON (fa.forum_id = f.forum_id
997
                AND fa.session_id = '" . $db->sql_escape($user->session_id) . "')
998
        ORDER BY f.left_id ASC";
999
$result = $db->sql_query($sql);
1000
1001
$right = $cat_right = $padding_inc = 0;
1002
$padding = $forum_list = $holding = '';
1003
$pad_store = array('0' => '');
1004
1005
while ($row = $db->sql_fetchrow($result))
1006
{
1007
        if ($row['forum_type'] == FORUM_CAT && ($row['left_id'] + 1 == $row['right_id']))
1008
        {
1009
                // Non-postable forum with no subforums, don't display
1010
                continue;
1011
        }
1012
1013
        if ($row['forum_type'] == FORUM_POST && ($row['left_id'] + 1 == $row['right_id']) && !$row['enable_indexing'])
1014
        {
1015
                // Postable forum with no subforums and indexing disabled, don't display
1016
                continue;
1017
        }
1018
1019
        if ($row['forum_type'] == FORUM_LINK || ($row['forum_password'] && !$row['user_id']))
1020
        {
1021
                // if this forum is a link or password protected (user has not entered the password yet) then skip to the next branch
1022
                continue;
1023
        }
1024
1025
        if ($row['left_id'] < $right)
1026
        {
1027
                $padding .= '&nbsp; &nbsp;';
1028
                $pad_store[$row['parent_id']] = $padding;
1029
        }
1030
        else if ($row['left_id'] > $right + 1)
1031
        {
1032
                if (isset($pad_store[$row['parent_id']]))
1033
                {
1034
                        $padding = $pad_store[$row['parent_id']];
1035
                }
1036
                else
1037
                {
1038
                        continue;
1039
                }
1040
        }
1041
1042
        $right = $row['right_id'];
1043
1044
        if ($auth->acl_gets('!f_search', '!f_list', $row['forum_id']))
1045
        {
1046
                // if the user does not have permissions to search or see this forum skip only this forum/category
1047
                continue;
1048
        }
1049
1050
        $selected = (in_array($row['forum_id'], $search_forum)) ? ' selected="selected"' : '';
1051
1052
        if ($row['left_id'] > $cat_right)
1053
        {
1054
                // make sure we don't forget anything
1055
                $s_forums .= $holding;
1056
                $holding = '';
1057
        }
1058
1059
        if ($row['right_id'] - $row['left_id'] > 1)
1060
        {
1061
                $cat_right = max($cat_right, $row['right_id']);
1062
1063
                $holding .= '<option value="' . $row['forum_id'] . '"' . $selected . '>' . $padding . $row['forum_name'] . '</option>';
1064
        }
1065
        else
1066
        {
1067
                $s_forums .= $holding . '<option value="' . $row['forum_id'] . '"' . $selected . '>' . $padding . $row['forum_name'] . '</option>';
1068
                $holding = '';
1069
        }
1070
}
1071
1072
if ($holding)
1073
{
1074
        $s_forums .= $holding;
1075
}
1076
1077
$db->sql_freeresult($result);
1078
unset($pad_store);
1079
1080
if (!$s_forums)
1081
{
1082
        trigger_error('NO_SEARCH');
1083
}
1084
1085
// Number of chars returned
1086
$s_characters = '<option value="-1">' . $user->lang['ALL_AVAILABLE'] . '</option>';
1087
$s_characters .= '<option value="0">0</option>';
1088
$s_characters .= '<option value="25">25</option>';
1089
$s_characters .= '<option value="50">50</option>';
1090
1091
for ($i = 100; $i <= 1000 ; $i += 100)
1092
{
1093
        $selected = ($i == 300) ? ' selected="selected"' : '';
1094
        $s_characters .= '<option value="' . $i . '"' . $selected . '>' . $i . '</option>';
1095
}
1096
1097
$s_hidden_fields = array('t' => $topic_id);
1098
1099
if ($_SID)
1100
{
1101
        $s_hidden_fields['sid'] = $_SID;
1102
}
1103
1104
if (!empty($_EXTRA_URL))
1105
{
1106
        foreach ($_EXTRA_URL as $url_param)
1107
        {
1108
                $url_param = explode('=', $url_param, 2);
1109
                $s_hidden_fields[$url_param[0]] = $url_param[1];
1110
        }
1111
}
1112
1113
$template->assign_vars(array(
1114
        'S_SEARCH_ACTION'                => append_sid("{$phpbb_root_path}search.$phpEx", false, true, 0), // We force no ?sid= appending by using 0
1115
        'S_HIDDEN_FIELDS'                => build_hidden_fields($s_hidden_fields),
1116
        'S_CHARACTER_OPTIONS'        => $s_characters,
1117
        'S_FORUM_OPTIONS'                => $s_forums,
1118
        'S_SELECT_SORT_DIR'                => $s_sort_dir,
1119
        'S_SELECT_SORT_KEY'                => $s_sort_key,
1120
        'S_SELECT_SORT_DAYS'        => $s_limit_days,
1121
        'S_IN_SEARCH'                        => true,
1122
));
1123
1124
// only show recent searches to search administrators
1125
if ($auth->acl_get('a_search'))
1126
{
1127
        // Handle large objects differently for Oracle and MSSQL
1128
        switch ($db->sql_layer)
1129
        {
1130
                case 'oracle':
1131
                        $sql = 'SELECT search_time, search_keywords
1132
                                FROM ' . SEARCH_RESULTS_TABLE . '
1133
                                WHERE dbms_lob.getlength(search_keywords) > 0
1134
                                ORDER BY search_time DESC';
1135
                break;
1136
1137
                case 'mssql':
1138
                case 'mssql_odbc':
1139
                case 'mssqlnative':
1140
                        $sql = 'SELECT search_time, search_keywords
1141
                                FROM ' . SEARCH_RESULTS_TABLE . '
1142
                                WHERE DATALENGTH(search_keywords) > 0
1143
                                ORDER BY search_time DESC';
1144
                break;
1145
1146
                default:
1147
                        $sql = 'SELECT search_time, search_keywords
1148
                                FROM ' . SEARCH_RESULTS_TABLE . '
1149
                                WHERE search_keywords <> \'\'
1150
                                ORDER BY search_time DESC';
1151
                break;
1152
        }
1153
        $result = $db->sql_query_limit($sql, 5);
1154
1155
        while ($row = $db->sql_fetchrow($result))
1156
        {
1157
                $keywords = $row['search_keywords'];
1158
1159
                $template->assign_block_vars('recentsearch', array(
1160
                        'KEYWORDS'        => $keywords,
1161
                        'TIME'                => $user->format_date($row['search_time']),
1162
1163
                        'U_KEYWORDS'        => append_sid("{$phpbb_root_path}search.$phpEx", 'keywords=' . urlencode(htmlspecialchars_decode($keywords)))
1164
                ));
1165
        }
1166
        $db->sql_freeresult($result);
1167
}
1168
1169
// Output the basic page
1170
page_header($user->lang['SEARCH']);
1171
1172
$template->set_filenames(array(
1173
        'body' => 'search_body.html')
1174
);
1175
make_jumpbox(append_sid("{$phpbb_root_path}viewforum.$phpEx"));
1176
1177
page_footer();