Verzeichnisstruktur phpBB-3.3.16
- Veröffentlicht
- 27.04.2026
So funktioniert es
|
|
Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück |
Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis. |
|
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
search.php
0001 <?php
0002 /**
0003 *
0004 * This file is part of the phpBB Forum Software package.
0005 *
0006 * @copyright (c) phpBB Limited <https://www.phpbb.com>
0007 * @license GNU General Public License, version 2 (GPL-2.0)
0008 *
0009 * For full copyright and license information, please see
0010 * the docs/CREDITS.txt file.
0011 *
0012 */
0013
0014 /**
0015 * @ignore
0016 */
0017 define('IN_PHPBB', true);
0018 $phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './';
0019 $phpEx = substr(strrchr(__FILE__, '.'), 1);
0020 include($phpbb_root_path . 'common.' . $phpEx);
0021
0022 // Start session management
0023 $user->session_begin();
0024 $auth->acl($user->data);
0025 $user->setup('search');
0026
0027 // Define initial vars
0028 $mode = $request->variable('mode', '');
0029 $search_id = $request->variable('search_id', '');
0030 $start = max($request->variable('start', 0), 0);
0031 $post_id = $request->variable('p', 0);
0032 $topic_id = $request->variable('t', 0);
0033 $view = $request->variable('view', '');
0034
0035 $submit = $request->variable('submit', false);
0036 $keywords = $request->variable('keywords', '', true);
0037 $add_keywords = $request->variable('add_keywords', '', true);
0038 $author = $request->variable('author', '', true);
0039 $author_id = $request->variable('author_id', 0);
0040 $show_results = ($topic_id) ? 'posts' : $request->variable('sr', 'posts');
0041 $show_results = ($show_results == 'posts') ? 'posts' : 'topics';
0042 $search_terms = $request->variable('terms', 'all');
0043 $search_fields = $request->variable('sf', 'all');
0044 $search_child = $request->variable('sc', true);
0045
0046 $sort_days = $request->variable('st', 0);
0047 $sort_key = $request->variable('sk', 't');
0048 $sort_dir = $request->variable('sd', 'd');
0049
0050 $return_chars = $request->variable('ch', $topic_id ? 0 : (int) $config['default_search_return_chars']);
0051 $search_forum = $request->variable('fid', array(0));
0052
0053 // We put login boxes for the case if search_id is newposts, egosearch or unreadposts
0054 // because a guest should be able to log in even if guests search is not permitted
0055
0056 switch ($search_id)
0057 {
0058 // Egosearch is an author search
0059 case 'egosearch':
0060 $author_id = $user->data['user_id'];
0061 if ($user->data['user_id'] == ANONYMOUS)
0062 {
0063 login_box('', $user->lang['LOGIN_EXPLAIN_EGOSEARCH']);
0064 }
0065 break;
0066
0067 // Search for unread posts needs to be allowed and user to be logged in if topics tracking for guests is disabled
0068 case 'unreadposts':
0069 if (!$config['load_unreads_search'])
0070 {
0071 $template->assign_var('S_NO_SEARCH', true);
0072 trigger_error('NO_SEARCH_UNREADS');
0073 }
0074 else if (!$config['load_anon_lastread'] && !$user->data['is_registered'])
0075 {
0076 login_box('', $user->lang['LOGIN_EXPLAIN_UNREADSEARCH']);
0077 }
0078 break;
0079
0080 // The "new posts" search uses user_lastvisit which is user based, so it should require user to log in.
0081 case 'newposts':
0082 if ($user->data['user_id'] == ANONYMOUS)
0083 {
0084 login_box('', $user->lang['LOGIN_EXPLAIN_NEWPOSTS']);
0085 }
0086 break;
0087
0088 default:
0089 // There's nothing to do here for now ;)
0090 break;
0091 }
0092
0093 $search_auth_check_override = false;
0094 /**
0095 * This event allows you to override search auth checks
0096 *
0097 * @event core.search_auth_check_override
0098 * @var bool search_auth_check_override Whether or not the search auth check overridden
0099 * @since 3.3.14-RC1
0100 */
0101 $vars = [
0102 'search_auth_check_override',
0103 ];
0104 extract($phpbb_dispatcher->trigger_event('core.search_auth_check_override', compact($vars)));
0105
0106 // Is user able to search? Has search been disabled?
0107 if (!$search_auth_check_override && (!$auth->acl_get('u_search') || !$auth->acl_getf_global('f_search') || !$config['load_search']))
0108 {
0109 $template->assign_var('S_NO_SEARCH', true);
0110 trigger_error('NO_SEARCH');
0111 }
0112
0113 // Check search load limit
0114 if ($user->load && $config['limit_search_load'] && ($user->load > doubleval($config['limit_search_load'])))
0115 {
0116 $template->assign_var('S_NO_SEARCH', true);
0117 trigger_error('NO_SEARCH_LOAD');
0118 }
0119
0120 // It is applicable if the configuration setting is non-zero, and the user cannot
0121 // ignore the flood setting, and the search is a keyword search.
0122 $interval = ($user->data['user_id'] == ANONYMOUS) ? $config['search_anonymous_interval'] : $config['search_interval'];
0123 if ($interval && !in_array($search_id, array('unreadposts', 'unanswered', 'active_topics', 'egosearch')) && !$auth->acl_get('u_ignoreflood'))
0124 {
0125 if ($user->data['user_last_search'] > time() - $interval)
0126 {
0127 $template->assign_var('S_NO_SEARCH', true);
0128 trigger_error($user->lang('NO_SEARCH_TIME', (int) ($user->data['user_last_search'] + $interval - time())));
0129 }
0130 }
0131
0132 // Define some vars
0133 $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']);
0134 $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']);
0135
0136 $s_limit_days = $s_sort_key = $s_sort_dir = $u_sort_param = '';
0137 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);
0138
0139 /* @var $phpbb_content_visibility \phpbb\content_visibility */
0140 $phpbb_content_visibility = $phpbb_container->get('content.visibility');
0141
0142 /* @var $pagination \phpbb\pagination */
0143 $pagination = $phpbb_container->get('pagination');
0144
0145 $template->assign_block_vars('navlinks', array(
0146 'BREADCRUMB_NAME' => $user->lang('SEARCH'),
0147 'U_BREADCRUMB' => append_sid("{$phpbb_root_path}search.$phpEx"),
0148 ));
0149
0150 /**
0151 * This event allows you to alter the above parameters, such as keywords and submit
0152 *
0153 * @event core.search_modify_submit_parameters
0154 * @var string keywords The search keywords
0155 * @var string author Specifies the author match, when ANONYMOUS is also a search-match
0156 * @var int author_id ID of the author to search by
0157 * @var string search_id Predefined search type name
0158 * @var bool submit Whether or not the form has been submitted
0159 * @since 3.1.10-RC1
0160 */
0161 $vars = array(
0162 'keywords',
0163 'author',
0164 'author_id',
0165 'search_id',
0166 'submit',
0167 );
0168 extract($phpbb_dispatcher->trigger_event('core.search_modify_submit_parameters', compact($vars)));
0169
0170 if ($keywords || $author || $author_id || $search_id || $submit)
0171 {
0172 // clear arrays
0173 $id_ary = array();
0174
0175 // If we are looking for authors get their ids
0176 $author_id_ary = array();
0177 $sql_author_match = '';
0178 if ($author_id)
0179 {
0180 $author_id_ary[] = $author_id;
0181 }
0182 else if ($author)
0183 {
0184 if ((strpos($author, '*') !== false) && (utf8_strlen(str_replace(array('*', '%'), '', $author)) < $config['min_search_author_chars']))
0185 {
0186 trigger_error($user->lang('TOO_FEW_AUTHOR_CHARS', (int) $config['min_search_author_chars']));
0187 }
0188
0189 $sql_where = (strpos($author, '*') !== false) ? ' username_clean ' . $db->sql_like_expression(str_replace('*', $db->get_any_char(), utf8_clean_string($author))) : " username_clean = '" . $db->sql_escape(utf8_clean_string($author)) . "'";
0190
0191 $sql = 'SELECT user_id
0192 FROM ' . USERS_TABLE . "
0193 WHERE $sql_where
0194 AND user_type <> " . USER_IGNORE;
0195 $result = $db->sql_query_limit($sql, 100);
0196
0197 while ($row = $db->sql_fetchrow($result))
0198 {
0199 $author_id_ary[] = (int) $row['user_id'];
0200 }
0201 $db->sql_freeresult($result);
0202
0203 $sql_where = (strpos($author, '*') !== false) ? ' post_username ' . $db->sql_like_expression(str_replace('*', $db->get_any_char(), utf8_clean_string($author))) : " post_username = '" . $db->sql_escape(utf8_clean_string($author)) . "'";
0204
0205 $sql = 'SELECT 1 as guest_post
0206 FROM ' . POSTS_TABLE . "
0207 WHERE $sql_where
0208 AND poster_id = " . ANONYMOUS;
0209 $result = $db->sql_query_limit($sql, 1);
0210 $found_guest_post = $db->sql_fetchfield('guest_post');
0211 $db->sql_freeresult($result);
0212
0213 if ($found_guest_post)
0214 {
0215 $author_id_ary[] = ANONYMOUS;
0216 $sql_author_match = (strpos($author, '*') !== false) ? ' ' . $db->sql_like_expression(str_replace('*', $db->get_any_char(), utf8_clean_string($author))) : " = '" . $db->sql_escape(utf8_clean_string($author)) . "'";
0217 }
0218
0219 if (!count($author_id_ary))
0220 {
0221 trigger_error('NO_SEARCH_RESULTS');
0222 }
0223 }
0224
0225 // if we search in an existing search result just add the additional keywords. But we need to use "all search terms"-mode
0226 // so we can keep the old keywords in their old mode, but add the new ones as required words
0227 if ($add_keywords)
0228 {
0229 if ($search_terms == 'all')
0230 {
0231 $keywords .= ' ' . $add_keywords;
0232 }
0233 else
0234 {
0235 $search_terms = 'all';
0236 $keywords = implode(' |', explode(' ', preg_replace('#\s+#u', ' ', $keywords))) . ' ' .$add_keywords;
0237 }
0238 }
0239
0240 // Which forums should not be searched? Author searches are also carried out in unindexed forums
0241 if (empty($keywords) && count($author_id_ary))
0242 {
0243 $ex_fid_ary = array_keys($auth->acl_getf('!f_read', true));
0244 }
0245 else
0246 {
0247 $ex_fid_ary = array_unique(array_merge(array_keys($auth->acl_getf('!f_read', true)), array_keys($auth->acl_getf('!f_search', true))));
0248 }
0249
0250 // Consider if there are any forums where can read forum = no, can read topics = yes
0251 // In these cases, the user should see the topic title in the search results but not the link to the topic (or any posts) because they don't have the permissions
0252 if ($request->variable('sr', '') == 'topics' && $search_fields == 'titleonly')
0253 {
0254 // The user could get here from a quick search through the viewforum page, or by doing a main search displayed by topics and searching only the topic titles.
0255 // Allow the 'can read topics = yes' forums back in to the search by removing from $ex_fid_ary any of the 'can read topics' forums
0256 $ex_fid_ary = array_diff($ex_fid_ary, array_keys($auth->acl_getf('f_list_topics', true)));
0257 }
0258
0259 $not_in_fid = (count($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'] . ')' : "";
0260
0261 $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
0262 FROM ' . FORUMS_TABLE . ' f
0263 LEFT JOIN ' . FORUMS_ACCESS_TABLE . " fa ON (fa.forum_id = f.forum_id
0264 AND fa.session_id = '" . $db->sql_escape($user->session_id) . "')
0265 $not_in_fid
0266 ORDER BY f.left_id";
0267 $result = $db->sql_query($sql);
0268
0269 $right_id = 0;
0270 $reset_search_forum = true;
0271 while ($row = $db->sql_fetchrow($result))
0272 {
0273 if ($row['forum_password'] && $row['user_id'] != $user->data['user_id'])
0274 {
0275 $ex_fid_ary[] = (int) $row['forum_id'];
0276 continue;
0277 }
0278
0279 // Exclude forums from active topics
0280 if (!($row['forum_flags'] & FORUM_FLAG_ACTIVE_TOPICS) && ($search_id == 'active_topics'))
0281 {
0282 $ex_fid_ary[] = (int) $row['forum_id'];
0283 continue;
0284 }
0285
0286 if (count($search_forum))
0287 {
0288 if ($search_child)
0289 {
0290 if (in_array($row['forum_id'], $search_forum) && $row['right_id'] > $right_id)
0291 {
0292 $right_id = (int) $row['right_id'];
0293 }
0294 else if ($row['right_id'] < $right_id)
0295 {
0296 continue;
0297 }
0298 }
0299
0300 if (!in_array($row['forum_id'], $search_forum))
0301 {
0302 $ex_fid_ary[] = (int) $row['forum_id'];
0303 $reset_search_forum = false;
0304 }
0305 }
0306 }
0307 $db->sql_freeresult($result);
0308
0309 // find out in which forums the user is allowed to view posts
0310 $m_approve_posts_fid_sql = $phpbb_content_visibility->get_global_visibility_sql('post', $ex_fid_ary, 'p.');
0311 $m_approve_topics_fid_sql = $phpbb_content_visibility->get_global_visibility_sql('topic', $ex_fid_ary, 't.');
0312
0313 if ($reset_search_forum)
0314 {
0315 $search_forum = array();
0316 }
0317
0318 // Select which method we'll use to obtain the post_id or topic_id information
0319 $search_type = $config['search_type'];
0320
0321 if (!class_exists($search_type))
0322 {
0323 trigger_error('NO_SUCH_SEARCH_MODULE');
0324 }
0325 // We do some additional checks in the module to ensure it can actually be utilised
0326 $error = false;
0327 $search = new $search_type($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user, $phpbb_dispatcher);
0328
0329 if ($error)
0330 {
0331 trigger_error($error);
0332 }
0333
0334 // let the search module split up the keywords
0335 if ($keywords)
0336 {
0337 $correct_query = $search->split_keywords($keywords, $search_terms);
0338 $common_words = $search->get_common_words();
0339 if (!$correct_query || (!$search->get_search_query() && !count($author_id_ary) && !$search_id))
0340 {
0341 $ignored = (count($common_words)) ? sprintf($user->lang['IGNORED_TERMS_EXPLAIN'], implode(' ', $common_words)) . '<br />' : '';
0342 $word_length = $search->get_word_length();
0343 if ($word_length)
0344 {
0345 trigger_error($ignored . $user->lang('NO_KEYWORDS', $user->lang('CHARACTERS', (int) $word_length['min']), $user->lang('CHARACTERS', (int) $word_length['max'])));
0346 }
0347 else
0348 {
0349 trigger_error($ignored);
0350 }
0351 }
0352 }
0353
0354 if (!$keywords && count($author_id_ary))
0355 {
0356 // if it is an author search we want to show topics by default
0357 $show_results = ($topic_id) ? 'posts' : $request->variable('sr', ($search_id == 'egosearch') ? 'topics' : 'posts');
0358 $show_results = ($show_results == 'posts') ? 'posts' : 'topics';
0359 }
0360
0361 // define some variables needed for retrieving post_id/topic_id information
0362 $sort_by_sql = [
0363 'a' => 'u.username_clean',
0364 't' => (($show_results == 'posts') ? 'p.post_time' : 't.topic_last_post_time'),
0365 'f' => 'f.forum_id',
0366 'i' => 't.topic_title',
0367 's' => (($show_results == 'posts') ? 'p.post_subject' : 't.topic_title')
0368 ];
0369
0370 /**
0371 * Event to modify the SQL parameters before pre-made searches
0372 *
0373 * @event core.search_modify_param_before
0374 * @var string keywords String of the specified keywords
0375 * @var array sort_by_sql Array of SQL sorting instructions
0376 * @var array ex_fid_ary Array of excluded forum ids
0377 * @var array author_id_ary Array of exclusive author ids
0378 * @var string search_id The id of the search request
0379 * @var array id_ary Array of post or topic ids for search result
0380 * @var string show_results 'posts' or 'topics' type of ids
0381 * @since 3.1.3-RC1
0382 * @changed 3.1.10-RC1 Added id_ary, show_results
0383 */
0384 $vars = array(
0385 'keywords',
0386 'sort_by_sql',
0387 'ex_fid_ary',
0388 'author_id_ary',
0389 'search_id',
0390 'id_ary',
0391 'show_results',
0392 );
0393 extract($phpbb_dispatcher->trigger_event('core.search_modify_param_before', compact($vars)));
0394
0395 // pre-made searches
0396 $sql = $field = $l_search_title = '';
0397 if ($search_id)
0398 {
0399 switch ($search_id)
0400 {
0401 // Oh holy Bob, bring us some activity...
0402 case 'active_topics':
0403 $l_search_title = $user->lang['SEARCH_ACTIVE_TOPICS'];
0404 $show_results = 'topics';
0405 $sort_key = 't';
0406 $sort_dir = 'd';
0407 $sort_days = $request->variable('st', 7);
0408 $sort_by_sql['t'] = 't.topic_last_post_time';
0409
0410 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);
0411 $s_sort_key = $s_sort_dir = '';
0412
0413 $last_post_time_sql = ($sort_days) ? ' AND t.topic_last_post_time > ' . (time() - ($sort_days * 24 * 3600)) : '';
0414
0415 $sql = 'SELECT t.topic_last_post_time, t.topic_id
0416 FROM ' . TOPICS_TABLE . " t
0417 WHERE t.topic_moved_id = 0
0418 $last_post_time_sql
0419 AND " . $m_approve_topics_fid_sql . '
0420 ' . ((count($ex_fid_ary)) ? ' AND ' . $db->sql_in_set('t.forum_id', $ex_fid_ary, true) : '') . '
0421 ORDER BY t.topic_last_post_time DESC';
0422 $field = 'topic_id';
0423 break;
0424
0425 case 'unanswered':
0426 $l_search_title = $user->lang['SEARCH_UNANSWERED'];
0427 $show_results = $request->variable('sr', 'topics');
0428 $show_results = ($show_results == 'posts') ? 'posts' : 'topics';
0429 $sort_by_sql['t'] = ($show_results == 'posts') ? 'p.post_time' : 't.topic_last_post_time';
0430 $sort_by_sql['s'] = ($show_results == 'posts') ? 'p.post_subject' : 't.topic_title';
0431 $sql_sort = 'ORDER BY ' . $sort_by_sql[$sort_key] . (($sort_dir == 'a') ? ' ASC' : ' DESC');
0432
0433 $sort_join = ($sort_key == 'f') ? FORUMS_TABLE . ' f, ' : '';
0434 $sql_sort = ($sort_key == 'f') ? ' AND f.forum_id = t.forum_id ' . $sql_sort : $sql_sort;
0435
0436 if ($sort_days)
0437 {
0438 $last_post_time = 'AND ' . ($show_results == 'posts' ? 'p.post_time' : 't.topic_last_post_time') . ' > ' . (time() - ($sort_days * 24 * 3600));
0439 }
0440 else
0441 {
0442 $last_post_time = '';
0443 }
0444
0445 if ($sort_key == 'a')
0446 {
0447 $sort_join = USERS_TABLE . ' u, ';
0448 $sql_sort = ' AND u.user_id = ' . ($show_results == 'posts' ? 'p.poster_id ' : 't.topic_last_poster_id ') . $sql_sort;
0449 }
0450 if ($show_results == 'posts')
0451 {
0452 $sql = "SELECT p.post_id
0453 FROM $sort_join" . POSTS_TABLE . ' p, ' . TOPICS_TABLE . " t
0454 WHERE t.topic_posts_approved = 1
0455 AND p.topic_id = t.topic_id
0456 $last_post_time
0457 AND $m_approve_posts_fid_sql
0458 " . ((count($ex_fid_ary)) ? ' AND ' . $db->sql_in_set('p.forum_id', $ex_fid_ary, true) : '') . "
0459 $sql_sort";
0460 $field = 'post_id';
0461 }
0462 else
0463 {
0464 $sql = 'SELECT DISTINCT ' . $sort_by_sql[$sort_key] . ", t.topic_id
0465 FROM $sort_join" . TOPICS_TABLE . " t
0466 WHERE t.topic_posts_approved = 1
0467 AND t.topic_moved_id = 0
0468 $last_post_time
0469 AND $m_approve_topics_fid_sql
0470 " . ((count($ex_fid_ary)) ? ' AND ' . $db->sql_in_set('t.forum_id', $ex_fid_ary, true) : '') . "
0471 $sql_sort";
0472 $field = 'topic_id';
0473 }
0474 break;
0475
0476 case 'unreadposts':
0477 $l_search_title = $user->lang['SEARCH_UNREAD'];
0478 // force sorting
0479 $show_results = 'topics';
0480 $sort_key = 't';
0481 $sort_by_sql['t'] = 't.topic_last_post_time';
0482 $sql_sort = 'ORDER BY ' . $sort_by_sql[$sort_key] . (($sort_dir == 'a') ? ' ASC' : ' DESC');
0483
0484 $sql_where = 'AND t.topic_moved_id = 0
0485 AND ' . $m_approve_topics_fid_sql . '
0486 ' . ((count($ex_fid_ary)) ? 'AND ' . $db->sql_in_set('t.forum_id', $ex_fid_ary, true) : '');
0487
0488 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);
0489 $s_sort_key = $s_sort_dir = $u_sort_param = $s_limit_days = '';
0490
0491 $template->assign_var('U_MARK_ALL_READ', ($user->data['is_registered'] || $config['load_anon_lastread']) ? append_sid("{$phpbb_root_path}index.$phpEx", 'hash=' . generate_link_hash('global') . '&mark=forums&mark_time=' . time()) : '');
0492 break;
0493
0494 case 'newposts':
0495 $l_search_title = $user->lang['SEARCH_NEW'];
0496 // force sorting
0497 $show_results = ($request->variable('sr', 'topics') == 'posts') ? 'posts' : 'topics';
0498 $sort_key = 't';
0499 $sort_dir = 'd';
0500 $sort_by_sql['t'] = ($show_results == 'posts') ? 'p.post_time' : 't.topic_last_post_time';
0501 $sql_sort = 'ORDER BY ' . $sort_by_sql[$sort_key] . (($sort_dir == 'a') ? ' ASC' : ' DESC');
0502
0503 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);
0504 $s_sort_key = $s_sort_dir = $u_sort_param = $s_limit_days = '';
0505
0506 if ($show_results == 'posts')
0507 {
0508 $sql = 'SELECT p.post_id
0509 FROM ' . POSTS_TABLE . ' p
0510 WHERE p.post_time > ' . $user->data['user_lastvisit'] . '
0511 AND ' . $m_approve_posts_fid_sql . '
0512 ' . ((count($ex_fid_ary)) ? ' AND ' . $db->sql_in_set('p.forum_id', $ex_fid_ary, true) : '') . "
0513 $sql_sort";
0514 $field = 'post_id';
0515 }
0516 else
0517 {
0518 $sql = 'SELECT t.topic_id
0519 FROM ' . TOPICS_TABLE . ' t
0520 WHERE t.topic_last_post_time > ' . $user->data['user_lastvisit'] . '
0521 AND t.topic_moved_id = 0
0522 AND ' . $m_approve_topics_fid_sql . '
0523 ' . ((count($ex_fid_ary)) ? 'AND ' . $db->sql_in_set('t.forum_id', $ex_fid_ary, true) : '') . "
0524 $sql_sort";
0525 /*
0526 [Fix] queued replies missing from "view new posts" (Bug #42705 - Patch by Paul)
0527 - Creates temporary table, query is far from optimized
0528
0529 $sql = 'SELECT t.topic_id
0530 FROM ' . TOPICS_TABLE . ' t, ' . POSTS_TABLE . ' p
0531 WHERE p.post_time > ' . $user->data['user_lastvisit'] . '
0532 AND t.topic_id = p.topic_id
0533 AND t.topic_moved_id = 0
0534 AND ' . $m_approve_topics_fid_sql . "
0535 GROUP BY t.topic_id
0536 $sql_sort";
0537 */
0538 $field = 'topic_id';
0539 }
0540 break;
0541
0542 case 'egosearch':
0543 $l_search_title = $user->lang['SEARCH_SELF'];
0544 break;
0545 }
0546
0547 $template->assign_block_vars('navlinks', array(
0548 'BREADCRUMB_NAME' => $l_search_title,
0549 'U_BREADCRUMB' => append_sid("{$phpbb_root_path}search.$phpEx", "search_id=$search_id"),
0550 ));
0551 }
0552
0553 /**
0554 * Event to modify data after pre-made searches
0555 *
0556 * @event core.search_modify_param_after
0557 * @var string l_search_title The title of the search page
0558 * @var string search_id Predefined search type name
0559 * @var string show_results Display topics or posts
0560 * @var string sql SQL query corresponding to the pre-made search id
0561 * @since 3.1.7-RC1
0562 */
0563 $vars = array(
0564 'l_search_title',
0565 'search_id',
0566 'show_results',
0567 'sql',
0568 );
0569 extract($phpbb_dispatcher->trigger_event('core.search_modify_param_after', compact($vars)));
0570
0571 // show_results should not change after this
0572 $per_page = ($show_results == 'posts') ? $config['posts_per_page'] : $config['topics_per_page'];
0573 $total_match_count = 0;
0574
0575 // Set limit for the $total_match_count to reduce server load
0576 $total_matches_limit = 1000;
0577 $found_more_search_matches = false;
0578
0579 if ($search_id)
0580 {
0581 if ($sql)
0582 {
0583 // Only return up to $total_matches_limit+1 ids (the last one will be removed later)
0584 $result = $db->sql_query_limit($sql, $total_matches_limit + 1);
0585
0586 while ($row = $db->sql_fetchrow($result))
0587 {
0588 $id_ary[] = (int) $row[$field];
0589 }
0590 $db->sql_freeresult($result);
0591 }
0592 else if ($search_id == 'unreadposts')
0593 {
0594 // Only return up to $total_matches_limit+1 ids (the last one will be removed later)
0595 $id_ary = array_keys(get_unread_topics($user->data['user_id'], $sql_where, $sql_sort, $total_matches_limit + 1));
0596 }
0597 else
0598 {
0599 $search_id = '';
0600 }
0601
0602 $total_match_count = count($id_ary);
0603 if ($total_match_count)
0604 {
0605 // Limit the number to $total_matches_limit for pre-made searches
0606 if ($total_match_count > $total_matches_limit)
0607 {
0608 $found_more_search_matches = true;
0609 $total_match_count = $total_matches_limit;
0610 }
0611
0612 // Make sure $start is set to the last page if it exceeds the amount
0613 $start = $pagination->validate_start($start, $per_page, $total_match_count);
0614
0615 $id_ary = array_slice($id_ary, $start, $per_page);
0616 }
0617 else
0618 {
0619 // Set $start to 0 if no matches were found
0620 $start = 0;
0621 }
0622 }
0623
0624 // make sure that some arrays are always in the same order
0625 sort($ex_fid_ary);
0626 sort($author_id_ary);
0627
0628 if ($search->get_search_query())
0629 {
0630 $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_posts_fid_sql, $topic_id, $author_id_ary, $sql_author_match, $id_ary, $start, $per_page);
0631 }
0632 else if (count($author_id_ary))
0633 {
0634 $firstpost_only = ($search_fields === 'firstpost' || $search_fields == 'titleonly') ? true : false;
0635 $total_match_count = $search->author_search($show_results, $firstpost_only, $sort_by_sql, $sort_key, $sort_dir, $sort_days, $ex_fid_ary, $m_approve_posts_fid_sql, $topic_id, $author_id_ary, $sql_author_match, $id_ary, $start, $per_page);
0636 }
0637
0638 /**
0639 * Event to search otherwise than by keywords or author
0640 *
0641 * @event core.search_backend_search_after
0642 * @var string show_results 'posts' or 'topics' type of ids
0643 * @var string search_fields The data fields to search in
0644 * @var string search_terms Is either 'all' (use query as entered, words without prefix should default to "have to be in field") or 'any' (ignore search query parts and just return all posts that contain any of the specified words)
0645 * @var array sort_by_sql Array of SQL sorting instructions
0646 * @var string sort_key The sort key
0647 * @var string sort_dir The sort direction
0648 * @var int sort_days Limit the age of results
0649 * @var array ex_fid_ary Array of excluded forum ids
0650 * @var string m_approve_posts_fid_sql Specifies which types of posts the user can view in which forums
0651 * @var int topic_id is set to 0 or a topic id, if it is not 0 then only posts in this topic should be searched
0652 * @var array author_id_ary Array of exclusive author ids
0653 * @var string sql_author_match Specifies the author match, when ANONYMOUS is also a search-match
0654 * @var array id_ary Array of post or topic ids for search result
0655 * @var int start The starting id of the results
0656 * @var int per_page Number of ids each page is supposed to contain
0657 * @var int total_match_count The total number of search matches
0658 * @since 3.1.10-RC1
0659 */
0660 $vars = array(
0661 'show_results',
0662 'search_fields',
0663 'search_terms',
0664 'sort_by_sql',
0665 'sort_key',
0666 'sort_dir',
0667 'sort_days',
0668 'ex_fid_ary',
0669 'm_approve_posts_fid_sql',
0670 'topic_id',
0671 'author_id_ary',
0672 'sql_author_match',
0673 'id_ary',
0674 'start',
0675 'per_page',
0676 'total_match_count',
0677 );
0678 extract($phpbb_dispatcher->trigger_event('core.search_backend_search_after', compact($vars)));
0679
0680 $sql_where = '';
0681
0682 if (count($id_ary))
0683 {
0684 $sql_where .= $db->sql_in_set(($show_results == 'posts') ? 'p.post_id' : 't.topic_id', $id_ary);
0685 $sql_where .= (count($ex_fid_ary)) ? ' AND (' . $db->sql_in_set('f.forum_id', $ex_fid_ary, true) . ' OR f.forum_id IS NULL)' : '';
0686 $sql_where .= ' AND ' . (($show_results == 'posts') ? $m_approve_posts_fid_sql : $m_approve_topics_fid_sql);
0687 }
0688
0689 if ($show_results == 'posts')
0690 {
0691 include($phpbb_root_path . 'includes/functions_posting.' . $phpEx);
0692 }
0693 else
0694 {
0695 include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
0696 }
0697
0698 $user->add_lang('viewtopic');
0699
0700 // Grab icons
0701 $icons = $cache->obtain_icons();
0702
0703 // define some vars for urls
0704 // A single wildcard will make the search results look ugly
0705 $hilit = phpbb_clean_search_string(str_replace(array('+', '-', '|', '(', ')', '"'), ' ', $keywords));
0706 $hilit = str_replace(' ', '|', $hilit);
0707
0708 $u_hilit = urlencode(html_entity_decode(str_replace('|', ' ', $hilit), ENT_COMPAT));
0709 $u_show_results = 'sr=' . $show_results;
0710 $u_search_forum = implode('&fid%5B%5D=', $search_forum);
0711
0712 $u_search = append_sid("{$phpbb_root_path}search.$phpEx", (($u_sort_param) ? $u_sort_param . '&' : '') . $u_show_results);
0713 $u_search .= ($search_id) ? '&search_id=' . $search_id : '';
0714 $u_search .= ($u_hilit) ? '&keywords=' . urlencode(html_entity_decode($keywords, ENT_COMPAT)) : '';
0715 $u_search .= ($search_terms != 'all') ? '&terms=' . $search_terms : '';
0716 $u_search .= ($topic_id) ? '&t=' . $topic_id : '';
0717 $u_search .= ($author) ? '&author=' . urlencode(html_entity_decode($author, ENT_COMPAT)) : '';
0718 $u_search .= ($author_id) ? '&author_id=' . $author_id : '';
0719 $u_search .= ($u_search_forum) ? '&fid%5B%5D=' . $u_search_forum : '';
0720 $u_search .= (!$search_child) ? '&sc=0' : '';
0721 $u_search .= ($search_fields != 'all') ? '&sf=' . $search_fields : '';
0722 $u_search .= $return_chars !== (int) $config['default_search_return_chars'] ? '&ch=' . $return_chars : '';
0723
0724 /**
0725 * Event to add or modify search URL parameters
0726 *
0727 * @event core.search_modify_url_parameters
0728 * @var string u_search Search URL parameters string
0729 * @var string search_id Predefined search type name
0730 * @var string show_results String indicating the show results mode
0731 * @var string sql_where The SQL WHERE string used by search to get topic data
0732 * @var int total_match_count The total number of search matches
0733 * @var array ex_fid_ary Array of excluded forum ids
0734 * @since 3.1.7-RC1
0735 * @changed 3.1.10-RC1 Added show_results, sql_where, total_match_count
0736 * @changed 3.1.11-RC1 Added ex_fid_ary
0737 */
0738 $vars = array(
0739 'u_search',
0740 'search_id',
0741 'show_results',
0742 'sql_where',
0743 'total_match_count',
0744 'ex_fid_ary',
0745 );
0746 extract($phpbb_dispatcher->trigger_event('core.search_modify_url_parameters', compact($vars)));
0747
0748 if ($sql_where)
0749 {
0750 $zebra = [];
0751
0752 if ($show_results == 'posts')
0753 {
0754 // @todo Joining this query to the one below?
0755 $sql = 'SELECT zebra_id, friend, foe
0756 FROM ' . ZEBRA_TABLE . '
0757 WHERE user_id = ' . $user->data['user_id'];
0758 $result = $db->sql_query($sql);
0759
0760 while ($row = $db->sql_fetchrow($result))
0761 {
0762 $zebra[($row['friend']) ? 'friend' : 'foe'][] = $row['zebra_id'];
0763 }
0764 $db->sql_freeresult($result);
0765
0766 $sql_array = array(
0767 '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',
0768 'FROM' => array(
0769 POSTS_TABLE => 'p',
0770 ),
0771 'LEFT_JOIN' => array(
0772 array(
0773 'FROM' => array(TOPICS_TABLE => 't'),
0774 'ON' => 'p.topic_id = t.topic_id',
0775 ),
0776 array(
0777 'FROM' => array(FORUMS_TABLE => 'f'),
0778 'ON' => 'p.forum_id = f.forum_id',
0779 ),
0780 array(
0781 'FROM' => array(USERS_TABLE => 'u'),
0782 'ON' => 'p.poster_id = u.user_id',
0783 ),
0784 ),
0785 'WHERE' => $sql_where,
0786 'ORDER_BY' => $sort_by_sql[$sort_key] . ' ' . (($sort_dir == 'd') ? 'DESC' : 'ASC'),
0787 );
0788
0789 /**
0790 * Event to modify the SQL query before the posts data is retrieved
0791 *
0792 * @event core.search_get_posts_data
0793 * @var array sql_array The SQL array
0794 * @var array zebra Array of zebra data for the current user
0795 * @var int total_match_count The total number of search matches
0796 * @var string keywords String of the specified keywords
0797 * @var array sort_by_sql Array of SQL sorting instructions
0798 * @var string s_sort_dir The sort direction
0799 * @var string s_sort_key The sort key
0800 * @var string s_limit_days Limit the age of results
0801 * @var array ex_fid_ary Array of excluded forum ids
0802 * @var array author_id_ary Array of exclusive author ids
0803 * @var string search_fields The data fields to search in
0804 * @var int search_id The id of the search request
0805 * @var int start The starting id of the results
0806 * @since 3.1.0-b3
0807 */
0808 $vars = array(
0809 'sql_array',
0810 'zebra',
0811 'total_match_count',
0812 'keywords',
0813 'sort_by_sql',
0814 's_sort_dir',
0815 's_sort_key',
0816 's_limit_days',
0817 'ex_fid_ary',
0818 'author_id_ary',
0819 'search_fields',
0820 'search_id',
0821 'start',
0822 );
0823 extract($phpbb_dispatcher->trigger_event('core.search_get_posts_data', compact($vars)));
0824
0825 $sql = $db->sql_build_query('SELECT', $sql_array);
0826 }
0827 else
0828 {
0829 $sql_from = TOPICS_TABLE . ' t
0830 LEFT JOIN ' . FORUMS_TABLE . ' f ON (f.forum_id = t.forum_id)
0831 ' . (($sort_key == 'a') ? ' LEFT JOIN ' . USERS_TABLE . ' u ON (u.user_id = t.topic_poster) ' : '');
0832 $sql_select = 't.*, f.forum_id, f.forum_name';
0833
0834 if ($user->data['is_registered'])
0835 {
0836 if ($config['load_db_track'] && $author_id !== $user->data['user_id'])
0837 {
0838 $sql_from .= ' LEFT JOIN ' . TOPICS_POSTED_TABLE . ' tp ON (tp.user_id = ' . $user->data['user_id'] . '
0839 AND t.topic_id = tp.topic_id)';
0840 $sql_select .= ', tp.topic_posted';
0841 }
0842
0843 if ($config['load_db_lastread'])
0844 {
0845 $sql_from .= ' LEFT JOIN ' . TOPICS_TRACK_TABLE . ' tt ON (tt.user_id = ' . $user->data['user_id'] . '
0846 AND t.topic_id = tt.topic_id)
0847 LEFT JOIN ' . FORUMS_TRACK_TABLE . ' ft ON (ft.user_id = ' . $user->data['user_id'] . '
0848 AND ft.forum_id = f.forum_id)';
0849 $sql_select .= ', tt.mark_time, ft.mark_time as f_mark_time';
0850 }
0851 }
0852
0853 if ($config['load_anon_lastread'] || ($user->data['is_registered'] && !$config['load_db_lastread']))
0854 {
0855 $tracking_topics = $request->variable($config['cookie_name'] . '_track', '', true, \phpbb\request\request_interface::COOKIE);
0856 $tracking_topics = ($tracking_topics) ? tracking_unserialize($tracking_topics) : array();
0857 }
0858
0859 $sql_order_by = $sort_by_sql[$sort_key] . ' ' . (($sort_dir == 'd') ? 'DESC' : 'ASC');
0860
0861 /**
0862 * Event to modify the SQL query before the topic data is retrieved
0863 *
0864 * @event core.search_get_topic_data
0865 * @var string sql_select The SQL SELECT string used by search to get topic data
0866 * @var string sql_from The SQL FROM string used by search to get topic data
0867 * @var string sql_where The SQL WHERE string used by search to get topic data
0868 * @var int total_match_count The total number of search matches
0869 * @var array sort_by_sql Array of SQL sorting instructions
0870 * @var string sort_dir The sorting direction
0871 * @var string sort_key The sorting key
0872 * @var string sql_order_by The SQL ORDER BY string used by search to get topic data
0873 * @since 3.1.0-a1
0874 * @changed 3.1.0-RC5 Added total_match_count
0875 * @changed 3.1.7-RC1 Added sort_by_sql, sort_dir, sort_key, sql_order_by
0876 */
0877 $vars = array(
0878 'sql_select',
0879 'sql_from',
0880 'sql_where',
0881 'total_match_count',
0882 'sort_by_sql',
0883 'sort_dir',
0884 'sort_key',
0885 'sql_order_by',
0886 );
0887 extract($phpbb_dispatcher->trigger_event('core.search_get_topic_data', compact($vars)));
0888
0889 $sql = "SELECT $sql_select
0890 FROM $sql_from
0891 WHERE $sql_where
0892 ORDER BY $sql_order_by";
0893 }
0894 $result = $db->sql_query($sql);
0895 $result_topic_id = 0;
0896
0897 $rowset = $attachments = $topic_tracking_info = array();
0898
0899 if ($show_results == 'topics')
0900 {
0901 $forums = $rowset = $shadow_topic_list = array();
0902 while ($row = $db->sql_fetchrow($result))
0903 {
0904 $row['forum_id'] = (int) $row['forum_id'];
0905 $row['topic_id'] = (int) $row['topic_id'];
0906
0907 if ($row['topic_status'] == ITEM_MOVED)
0908 {
0909 $shadow_topic_list[$row['topic_moved_id']] = $row['topic_id'];
0910 }
0911
0912 $rowset[$row['topic_id']] = $row;
0913
0914 if (!isset($forums[$row['forum_id']]) && $user->data['is_registered'] && $config['load_db_lastread'])
0915 {
0916 $forums[$row['forum_id']]['mark_time'] = $row['f_mark_time'];
0917 }
0918 $forums[$row['forum_id']]['topic_list'][] = $row['topic_id'];
0919 $forums[$row['forum_id']]['rowset'][$row['topic_id']] = &$rowset[$row['topic_id']];
0920 }
0921 $db->sql_freeresult($result);
0922
0923 // If we have some shadow topics, update the rowset to reflect their topic information
0924 if (count($shadow_topic_list))
0925 {
0926 $sql = 'SELECT *
0927 FROM ' . TOPICS_TABLE . '
0928 WHERE ' . $db->sql_in_set('topic_id', array_keys($shadow_topic_list));
0929 $result = $db->sql_query($sql);
0930
0931 while ($row = $db->sql_fetchrow($result))
0932 {
0933 $orig_topic_id = $shadow_topic_list[$row['topic_id']];
0934
0935 // We want to retain some values
0936 $row = array_merge($row, array(
0937 'topic_moved_id' => $rowset[$orig_topic_id]['topic_moved_id'],
0938 'topic_status' => $rowset[$orig_topic_id]['topic_status'],
0939 'forum_name' => $rowset[$orig_topic_id]['forum_name'])
0940 );
0941
0942 $rowset[$orig_topic_id] = $row;
0943 }
0944 $db->sql_freeresult($result);
0945 }
0946 unset($shadow_topic_list);
0947
0948 foreach ($forums as $forum_id => $forum)
0949 {
0950 if ($user->data['is_registered'] && $config['load_db_lastread'])
0951 {
0952 $topic_tracking_info[$forum_id] = get_topic_tracking($forum_id, $forum['topic_list'], $forum['rowset'], array($forum_id => $forum['mark_time']));
0953 }
0954 else if ($config['load_anon_lastread'] || $user->data['is_registered'])
0955 {
0956 $topic_tracking_info[$forum_id] = get_complete_topic_tracking($forum_id, $forum['topic_list']);
0957
0958 if (!$user->data['is_registered'])
0959 {
0960 $user->data['user_lastmark'] = (isset($tracking_topics['l'])) ? (int) (base_convert($tracking_topics['l'], 36, 10) + $config['board_startdate']) : 0;
0961 }
0962 }
0963 }
0964 unset($forums);
0965 }
0966 else
0967 {
0968 $text_only_message = '';
0969 $attach_list = array();
0970
0971 while ($row = $db->sql_fetchrow($result))
0972 {
0973 /**
0974 * Modify the row of a post result before the post_text is trimmed
0975 *
0976 * @event core.search_modify_post_row
0977 * @var string hilit String to highlight
0978 * @var array row Array with the post data
0979 * @var string u_hilit Highlight string to be injected into URL
0980 * @var string view Search results view mode
0981 * @var array zebra Array with zebra data for the current user
0982 * @since 3.2.2-RC1
0983 */
0984 $vars = array(
0985 'hilit',
0986 'row',
0987 'u_hilit',
0988 'view',
0989 'zebra',
0990 );
0991 extract($phpbb_dispatcher->trigger_event('core.search_modify_post_row', compact($vars)));
0992
0993 // We pre-process some variables here for later usage
0994 $row['post_text'] = censor_text($row['post_text']);
0995
0996 $text_only_message = $row['post_text'];
0997 // make list items visible as such
0998 if ($row['bbcode_uid'])
0999 {
1000 $text_only_message = str_replace('[*:' . $row['bbcode_uid'] . ']', '⋅ ', $text_only_message);
1001 // no BBCode in text only message
1002 strip_bbcode($text_only_message, $row['bbcode_uid']);
1003 }
1004
1005 if ($return_chars === 0 || utf8_strlen($text_only_message) < ($return_chars + 3))
1006 {
1007 $row['display_text_only'] = false;
1008
1009 // Does this post have an attachment? If so, add it to the list
1010 if ($row['post_attachment'] && $config['allow_attachments'])
1011 {
1012 $attach_list[$row['forum_id']][] = $row['post_id'];
1013 }
1014 }
1015 else
1016 {
1017 $row['post_text'] = $text_only_message;
1018 $row['display_text_only'] = true;
1019 }
1020
1021 $rowset[] = $row;
1022 }
1023 $db->sql_freeresult($result);
1024
1025 unset($text_only_message);
1026
1027 // Pull attachment data
1028 if (count($attach_list))
1029 {
1030 $use_attach_list = $attach_list;
1031 $attach_list = array();
1032
1033 foreach ($use_attach_list as $forum_id => $_list)
1034 {
1035 if ($auth->acl_get('u_download') && $auth->acl_get('f_download', $forum_id))
1036 {
1037 $attach_list = array_merge($attach_list, $_list);
1038 }
1039 }
1040 }
1041
1042 if (count($attach_list))
1043 {
1044 $sql = 'SELECT *
1045 FROM ' . ATTACHMENTS_TABLE . '
1046 WHERE ' . $db->sql_in_set('post_msg_id', $attach_list) . '
1047 AND in_message = 0
1048 ORDER BY filetime DESC, post_msg_id ASC';
1049 $result = $db->sql_query($sql);
1050
1051 while ($row = $db->sql_fetchrow($result))
1052 {
1053 $attachments[$row['post_msg_id']][] = $row;
1054 }
1055 $db->sql_freeresult($result);
1056 }
1057 }
1058
1059 if ($hilit)
1060 {
1061 // Remove bad highlights
1062 $hilit_array = array_filter(explode('|', $hilit), 'strlen');
1063 foreach ($hilit_array as $key => $value)
1064 {
1065 $hilit_array[$key] = phpbb_clean_search_string($value);
1066 $hilit_array[$key] = str_replace('\*', '\w*?', preg_quote($hilit_array[$key], '#'));
1067 $hilit_array[$key] = preg_replace('#(^|\s)\\\\w\*\?(\s|$)#', '$1\w+?$2', $hilit_array[$key]);
1068 }
1069 $hilit = implode('|', $hilit_array);
1070 }
1071
1072 /**
1073 * Modify the rowset data
1074 *
1075 * @event core.search_modify_rowset
1076 * @var array attachments Array with posts attachments data
1077 * @var string hilit String to highlight
1078 * @var array rowset Array with the search results data
1079 * @var string show_results String indicating the show results mode
1080 * @var array topic_tracking_info Array with the topics tracking data
1081 * @var string u_hilit Highlight string to be injected into URL
1082 * @var string view Search results view mode
1083 * @var array zebra Array with zebra data for the current user
1084 * @since 3.1.0-b4
1085 * @changed 3.1.0-b5 Added var show_results
1086 */
1087 $vars = array(
1088 'attachments',
1089 'hilit',
1090 'rowset',
1091 'show_results',
1092 'topic_tracking_info',
1093 'u_hilit',
1094 'view',
1095 'zebra',
1096 );
1097 extract($phpbb_dispatcher->trigger_event('core.search_modify_rowset', compact($vars)));
1098
1099 foreach ($rowset as $row)
1100 {
1101 $forum_id = $row['forum_id'];
1102 $result_topic_id = $row['topic_id'];
1103 $topic_title = censor_text($row['topic_title']);
1104 $replies = $phpbb_content_visibility->get_count('topic_posts', $row, $forum_id) - 1;
1105
1106 $view_topic_url_params = "t=$result_topic_id" . (($u_hilit) ? "&hilit=$u_hilit" : '');
1107 $view_topic_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", $view_topic_url_params);
1108
1109 $folder_img = $folder_alt = $u_mcp_queue = '';
1110 $topic_type = $posts_unapproved = 0;
1111 $unread_topic = $topic_unapproved = $topic_deleted = false;
1112
1113 if ($show_results == 'topics')
1114 {
1115 if ($config['load_db_track'] && $author_id === $user->data['user_id'])
1116 {
1117 $row['topic_posted'] = 1;
1118 }
1119
1120 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);
1121
1122 $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;
1123
1124 $topic_unapproved = (($row['topic_visibility'] == ITEM_UNAPPROVED || $row['topic_visibility'] == ITEM_REAPPROVE) && $auth->acl_get('m_approve', $forum_id)) ? true : false;
1125 $posts_unapproved = ($row['topic_visibility'] == ITEM_APPROVED && $row['topic_posts_unapproved'] && $auth->acl_get('m_approve', $forum_id)) ? true : false;
1126 $topic_deleted = $row['topic_visibility'] == ITEM_DELETED;
1127 $u_mcp_queue = ($topic_unapproved || $posts_unapproved) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=queue&mode=' . (($topic_unapproved) ? 'approve_details' : 'unapproved_posts') . "&t=$result_topic_id", true, $user->session_id) : '';
1128 $u_mcp_queue = (!$u_mcp_queue && $topic_deleted) ? append_sid("{$phpbb_root_path}mcp.$phpEx", "i=queue&mode=deleted_topics&t=$result_topic_id", true, $user->session_id) : $u_mcp_queue;
1129
1130 $row['topic_title'] = preg_replace('#(?!<.*)(?<!\w)(' . $hilit . ')(?!\w|[^<>]*(?:</s(?:cript|tyle))?>)#isu', '<span class="posthilit">$1</span>', $row['topic_title']);
1131
1132 $tpl_ary = array(
1133 'TOPIC_AUTHOR' => get_username_string('username', $row['topic_poster'], $row['topic_first_poster_name'], $row['topic_first_poster_colour']),
1134 'TOPIC_AUTHOR_COLOUR' => get_username_string('colour', $row['topic_poster'], $row['topic_first_poster_name'], $row['topic_first_poster_colour']),
1135 'TOPIC_AUTHOR_FULL' => get_username_string('full', $row['topic_poster'], $row['topic_first_poster_name'], $row['topic_first_poster_colour']),
1136 'FIRST_POST_TIME' => $user->format_date($row['topic_time']),
1137 'FIRST_POST_TIME_RFC3339' => gmdate(DATE_RFC3339, $row['topic_time']),
1138 'LAST_POST_SUBJECT' => $row['topic_last_post_subject'],
1139 'LAST_POST_TIME' => $user->format_date($row['topic_last_post_time']),
1140 'LAST_POST_TIME_RFC3339' => gmdate(DATE_RFC3339, $row['topic_last_post_time']),
1141 'LAST_VIEW_TIME' => $user->format_date($row['topic_last_view_time']),
1142 'LAST_VIEW_TIME_RFC3339' => gmdate(DATE_RFC3339, $row['topic_last_view_time']),
1143 'LAST_POST_AUTHOR' => get_username_string('username', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']),
1144 'LAST_POST_AUTHOR_COLOUR' => get_username_string('colour', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']),
1145 'LAST_POST_AUTHOR_FULL' => get_username_string('full', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']),
1146
1147 'TOPIC_TYPE' => $topic_type,
1148
1149 'TOPIC_IMG_STYLE' => $folder_img,
1150 'TOPIC_FOLDER_IMG' => $user->img($folder_img, $folder_alt),
1151 'TOPIC_FOLDER_IMG_ALT' => $user->lang[$folder_alt],
1152
1153 'TOPIC_ICON_IMG' => (!empty($icons[$row['icon_id']])) ? $icons[$row['icon_id']]['img'] : '',
1154 'TOPIC_ICON_IMG_WIDTH' => (!empty($icons[$row['icon_id']])) ? $icons[$row['icon_id']]['width'] : '',
1155 'TOPIC_ICON_IMG_HEIGHT' => (!empty($icons[$row['icon_id']])) ? $icons[$row['icon_id']]['height'] : '',
1156 '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']) : '',
1157 'UNAPPROVED_IMG' => ($topic_unapproved || $posts_unapproved) ? $user->img('icon_topic_unapproved', ($topic_unapproved) ? 'TOPIC_UNAPPROVED' : 'POSTS_UNAPPROVED') : '',
1158
1159 'S_TOPIC_TYPE' => $row['topic_type'],
1160 'S_USER_POSTED' => (!empty($row['topic_posted'])) ? true : false,
1161 'S_UNREAD_TOPIC' => $unread_topic,
1162
1163 'S_TOPIC_REPORTED' => (!empty($row['topic_reported']) && $auth->acl_get('m_report', $forum_id)) ? true : false,
1164 'S_TOPIC_UNAPPROVED' => $topic_unapproved,
1165 'S_POSTS_UNAPPROVED' => $posts_unapproved,
1166 'S_TOPIC_DELETED' => $topic_deleted,
1167 'S_HAS_POLL' => ($row['poll_start']) ? true : false,
1168
1169 'U_LAST_POST' => $auth->acl_get('f_read', $forum_id) ? append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'p=' . $row['topic_last_post_id']) . '#p' . $row['topic_last_post_id'] : false,
1170 'U_LAST_POST_AUTHOR' => get_username_string('profile', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']),
1171 'U_TOPIC_AUTHOR' => get_username_string('profile', $row['topic_poster'], $row['topic_first_poster_name'], $row['topic_first_poster_colour']),
1172 'U_NEWEST_POST' => $auth->acl_get('f_read', $forum_id) ? append_sid("{$phpbb_root_path}viewtopic.$phpEx", $view_topic_url_params . '&view=unread') . '#unread' : false,
1173 'U_MCP_REPORT' => append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=reports&mode=reports&t=' . $result_topic_id, true, $user->session_id),
1174 'U_MCP_QUEUE' => $u_mcp_queue,
1175 );
1176 }
1177 else
1178 {
1179 if ((isset($zebra['foe']) && in_array($row['poster_id'], $zebra['foe'])) && (!$view || $view != 'show' || $post_id != $row['post_id']))
1180 {
1181 $template->assign_block_vars('searchresults', array(
1182 'S_IGNORE_POST' => true,
1183
1184 'L_IGNORE_POST' => sprintf($user->lang['POST_BY_FOE'], $row['username'], "<a href=\"$u_search&start=$start&p=" . $row['post_id'] . '&view=show#p' . $row['post_id'] . '">', '</a>'))
1185 );
1186
1187 continue;
1188 }
1189
1190 // Replace naughty words such as farty pants
1191 $row['post_subject'] = censor_text($row['post_subject']);
1192
1193 if ($row['display_text_only'])
1194 {
1195 // now find context for the searched words
1196 $row['post_text'] = get_context($row['post_text'], array_filter(explode('|', $hilit), 'strlen'), $return_chars);
1197 $row['post_text'] = bbcode_nl2br($row['post_text']);
1198 }
1199 else
1200 {
1201 $parse_flags = ($row['bbcode_bitfield'] ? OPTION_FLAG_BBCODE : 0) | OPTION_FLAG_SMILIES;
1202 $row['post_text'] = generate_text_for_display($row['post_text'], $row['bbcode_uid'], $row['bbcode_bitfield'], $parse_flags, false);
1203
1204 if (!empty($attachments[$row['post_id']]))
1205 {
1206 parse_attachments($forum_id, $row['post_text'], $attachments[$row['post_id']], $update_count);
1207
1208 // we only display inline attachments
1209 unset($attachments[$row['post_id']]);
1210 }
1211 }
1212
1213 if ($hilit)
1214 {
1215 // post highlighting
1216 $row['post_text'] = preg_replace('#(?!<.*)(?<!\w)(' . $hilit . ')(?!\w|[^<>]*(?:</s(?:cript|tyle))?>)#isu', '<span class="posthilit">$1</span>', $row['post_text']);
1217 $row['post_subject'] = preg_replace('#(?!<.*)(?<!\w)(' . $hilit . ')(?!\w|[^<>]*(?:</s(?:cript|tyle))?>)#isu', '<span class="posthilit">$1</span>', $row['post_subject']);
1218 }
1219
1220 $tpl_ary = array(
1221 'POST_AUTHOR_FULL' => get_username_string('full', $row['poster_id'], $row['username'], $row['user_colour'], $row['post_username']),
1222 'POST_AUTHOR_COLOUR' => get_username_string('colour', $row['poster_id'], $row['username'], $row['user_colour'], $row['post_username']),
1223 'POST_AUTHOR' => get_username_string('username', $row['poster_id'], $row['username'], $row['user_colour'], $row['post_username']),
1224 'U_POST_AUTHOR' => get_username_string('profile', $row['poster_id'], $row['username'], $row['user_colour'], $row['post_username']),
1225
1226 'POST_SUBJECT' => $row['post_subject'],
1227 'POST_DATE' => (!empty($row['post_time'])) ? $user->format_date($row['post_time']) : '',
1228 'MESSAGE' => $row['post_text']
1229 );
1230 }
1231
1232 $tpl_ary = array_merge($tpl_ary, array(
1233 'FORUM_ID' => $forum_id,
1234 'TOPIC_ID' => $result_topic_id,
1235 'POST_ID' => ($show_results == 'posts') ? $row['post_id'] : false,
1236
1237 'FORUM_TITLE' => $row['forum_name'],
1238 'TOPIC_TITLE' => $topic_title,
1239 'TOPIC_REPLIES' => $replies,
1240 'TOPIC_VIEWS' => $row['topic_views'],
1241
1242 'U_VIEW_TOPIC' => $auth->acl_get('f_read', $forum_id) ? $view_topic_url : false,
1243 'U_VIEW_FORUM' => append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $forum_id),
1244 'U_VIEW_POST' => (!empty($row['post_id'])) ? append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'p=' . $row['post_id'] . (($u_hilit) ? '&hilit=' . $u_hilit : '')) . '#p' . $row['post_id'] : '',
1245 ));
1246
1247 /**
1248 * Modify the topic data before it is assigned to the template
1249 *
1250 * @event core.search_modify_tpl_ary
1251 * @var array row Array with topic data
1252 * @var array tpl_ary Template block array with topic data
1253 * @var string show_results Display topics or posts
1254 * @var string topic_title Cleaned topic title
1255 * @var int replies The number of topic replies
1256 * @var string view_topic_url The URL to the topic
1257 * @var string folder_img The folder image of the topic
1258 * @var string folder_alt The alt attribute of the topic folder img
1259 * @var int topic_type The topic type
1260 * @var bool unread_topic Whether the topic has unread posts
1261 * @var bool topic_unapproved Whether the topic is unapproved
1262 * @var int posts_unapproved The number of unapproved posts
1263 * @var bool topic_deleted Whether the topic has been deleted
1264 * @var string u_mcp_queue The URL to the corresponding MCP queue page
1265 * @var array zebra The zebra data of the current user
1266 * @var array attachments All the attachments of the search results
1267 * @since 3.1.0-a1
1268 * @changed 3.1.0-b3 Added vars show_results, topic_title, replies,
1269 * view_topic_url, folder_img, folder_alt, topic_type, unread_topic,
1270 * topic_unapproved, posts_unapproved, topic_deleted, u_mcp_queue,
1271 * zebra, attachments
1272 */
1273 $vars = array(
1274 'row',
1275 'tpl_ary',
1276 'show_results',
1277 'topic_title',
1278 'replies',
1279 'view_topic_url',
1280 'folder_img',
1281 'folder_alt',
1282 'topic_type',
1283 'unread_topic',
1284 'topic_unapproved',
1285 'posts_unapproved',
1286 'topic_deleted',
1287 'u_mcp_queue',
1288 'zebra',
1289 'attachments',
1290 );
1291 extract($phpbb_dispatcher->trigger_event('core.search_modify_tpl_ary', compact($vars)));
1292
1293 $template->assign_block_vars('searchresults', $tpl_ary);
1294
1295 if ($show_results == 'topics')
1296 {
1297 $pagination->generate_template_pagination($view_topic_url, 'searchresults.pagination', 'start', $replies + 1, $config['posts_per_page'], 1, true, true);
1298 }
1299 }
1300
1301 if ($topic_id && ($topic_id == $result_topic_id))
1302 {
1303 $template->assign_vars(array(
1304 'SEARCH_TOPIC' => $topic_title,
1305 'L_RETURN_TO_TOPIC' => $user->lang('RETURN_TO', $topic_title),
1306 'U_SEARCH_TOPIC' => $view_topic_url
1307 ));
1308 }
1309 }
1310 unset($rowset);
1311
1312 // Output header
1313 if ($found_more_search_matches)
1314 {
1315 $l_search_matches = $user->lang('FOUND_MORE_SEARCH_MATCHES', (int) $total_match_count);
1316 }
1317 else
1318 {
1319 $l_search_matches = $user->lang('FOUND_SEARCH_MATCHES', (int) $total_match_count);
1320 }
1321
1322 // Check if search backend supports phrase search or not
1323 $phrase_search_disabled = '';
1324 if (strpos(html_entity_decode($keywords), '"') !== false && method_exists($search, 'supports_phrase_search'))
1325 {
1326 $phrase_search_disabled = $search->supports_phrase_search() ? false : true;
1327 }
1328
1329 $pagination->generate_template_pagination($u_search, 'pagination', 'start', $total_match_count, $per_page, $start);
1330
1331 $template->assign_vars(array(
1332 'SEARCH_TITLE' => $l_search_title,
1333 'SEARCH_MATCHES' => $l_search_matches,
1334 'SEARCH_WORDS' => $keywords,
1335 'SEARCHED_QUERY' => $search->get_search_query(),
1336 'IGNORED_WORDS' => (!empty($common_words)) ? implode(' ', $common_words) : '',
1337
1338 'PHRASE_SEARCH_DISABLED' => $phrase_search_disabled,
1339
1340 'TOTAL_MATCHES' => $total_match_count,
1341 'SEARCH_IN_RESULTS' => ($search_id) ? false : true,
1342
1343 'S_SELECT_SORT_DIR' => $s_sort_dir,
1344 'S_SELECT_SORT_KEY' => $s_sort_key,
1345 'S_SELECT_SORT_DAYS' => $s_limit_days,
1346 'S_SEARCH_ACTION' => $u_search,
1347 'S_SHOW_TOPICS' => ($show_results == 'posts') ? false : true,
1348
1349 'GOTO_PAGE_IMG' => $user->img('icon_post_target', 'GOTO_PAGE'),
1350 'NEWEST_POST_IMG' => $user->img('icon_topic_newest', 'VIEW_NEWEST_POST'),
1351 'REPORTED_IMG' => $user->img('icon_topic_reported', 'TOPIC_REPORTED'),
1352 'UNAPPROVED_IMG' => $user->img('icon_topic_unapproved', 'TOPIC_UNAPPROVED'),
1353 'DELETED_IMG' => $user->img('icon_topic_deleted', 'TOPIC_DELETED'),
1354 'POLL_IMG' => $user->img('icon_topic_poll', 'TOPIC_POLL'),
1355 'LAST_POST_IMG' => $user->img('icon_topic_latest', 'VIEW_LATEST_POST'),
1356
1357 'U_SEARCH_WORDS' => $u_search,
1358 ));
1359
1360 /**
1361 * Modify the title and/or load data for the search results page
1362 *
1363 * @event core.search_results_modify_search_title
1364 * @var int author_id ID of the author to search by
1365 * @var string l_search_title The title of the search page
1366 * @var string search_id Predefined search type name
1367 * @var string show_results Search results output mode - topics or posts
1368 * @var int start The starting id of the results
1369 * @var int total_match_count The count of search results
1370 * @var string keywords The search keywords
1371 * @since 3.1.0-RC4
1372 * @changed 3.1.6-RC1 Added total_match_count and keywords
1373 */
1374 $vars = array(
1375 'author_id',
1376 'l_search_title',
1377 'search_id',
1378 'show_results',
1379 'start',
1380 'total_match_count',
1381 'keywords',
1382 );
1383 extract($phpbb_dispatcher->trigger_event('core.search_results_modify_search_title', compact($vars)));
1384
1385 page_header(($l_search_title) ? $l_search_title : $user->lang['SEARCH']);
1386
1387 $template->set_filenames(array(
1388 'body' => 'search_results.html')
1389 );
1390 make_jumpbox(append_sid("{$phpbb_root_path}viewforum.$phpEx"));
1391
1392 page_footer();
1393 }
1394
1395 // Search forum
1396 $rowset = array();
1397 $s_forums = '';
1398 $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
1399 FROM ' . FORUMS_TABLE . ' f
1400 LEFT JOIN ' . FORUMS_ACCESS_TABLE . " fa ON (fa.forum_id = f.forum_id
1401 AND fa.session_id = '" . $db->sql_escape($user->session_id) . "')
1402 ORDER BY f.left_id ASC";
1403 $result = $db->sql_query($sql);
1404
1405 while ($row = $db->sql_fetchrow($result))
1406 {
1407 $rowset[(int) $row['forum_id']] = $row;
1408 }
1409 $db->sql_freeresult($result);
1410
1411 $right = $cat_right = $padding_inc = 0;
1412 $padding = $forum_list = $holding = '';
1413 $pad_store = array('0' => '');
1414
1415 /**
1416 * Modify the forum select list for advanced search page
1417 *
1418 * @event core.search_modify_forum_select_list
1419 * @var array rowset Array with the forums list data
1420 * @since 3.1.10-RC1
1421 */
1422 $vars = array('rowset');
1423 extract($phpbb_dispatcher->trigger_event('core.search_modify_forum_select_list', compact($vars)));
1424
1425 foreach ($rowset as $row)
1426 {
1427 if ($row['forum_type'] == FORUM_CAT && ($row['left_id'] + 1 == $row['right_id']))
1428 {
1429 // Non-postable forum with no subforums, don't display
1430 continue;
1431 }
1432
1433 if ($row['forum_type'] == FORUM_POST && ($row['left_id'] + 1 == $row['right_id']) && !$row['enable_indexing'])
1434 {
1435 // Postable forum with no subforums and indexing disabled, don't display
1436 continue;
1437 }
1438
1439 if ($row['forum_type'] == FORUM_LINK || ($row['forum_password'] && !$row['user_id']))
1440 {
1441 // if this forum is a link or password protected (user has not entered the password yet) then skip to the next branch
1442 continue;
1443 }
1444
1445 if ($row['left_id'] < $right)
1446 {
1447 $padding .= ' ';
1448 $pad_store[$row['parent_id']] = $padding;
1449 }
1450 else if ($row['left_id'] > $right + 1)
1451 {
1452 if (isset($pad_store[$row['parent_id']]))
1453 {
1454 $padding = $pad_store[$row['parent_id']];
1455 }
1456 else
1457 {
1458 continue;
1459 }
1460 }
1461
1462 $right = $row['right_id'];
1463
1464 if ($auth->acl_gets('!f_search', '!f_list', $row['forum_id']))
1465 {
1466 // if the user does not have permissions to search or see this forum skip only this forum/category
1467 continue;
1468 }
1469
1470 $selected = (in_array($row['forum_id'], $search_forum)) ? ' selected="selected"' : '';
1471
1472 if ($row['left_id'] > $cat_right)
1473 {
1474 // make sure we don't forget anything
1475 $s_forums .= $holding;
1476 $holding = '';
1477 }
1478
1479 if ($row['right_id'] - $row['left_id'] > 1)
1480 {
1481 $cat_right = max($cat_right, $row['right_id']);
1482
1483 $holding .= '<option value="' . $row['forum_id'] . '"' . $selected . '>' . $padding . $row['forum_name'] . '</option>';
1484 }
1485 else
1486 {
1487 $s_forums .= $holding . '<option value="' . $row['forum_id'] . '"' . $selected . '>' . $padding . $row['forum_name'] . '</option>';
1488 $holding = '';
1489 }
1490 }
1491
1492 if ($holding)
1493 {
1494 $s_forums .= $holding;
1495 }
1496
1497 unset($pad_store);
1498 unset($rowset);
1499
1500 if (!$s_forums)
1501 {
1502 trigger_error('NO_SEARCH');
1503 }
1504
1505 /**
1506 * Build options for a select list for the number of characters returned.
1507 *
1508 * If the admin defined amount is not within the predefined range,
1509 * and the admin did not set it to unlimited (0), we add that option aswell.
1510 *
1511 * @deprecated 3.3.1-RC1 Templates should use an numeric input, in favor of a select.
1512 */
1513 $s_characters = '<option value="0">' . $language->lang('ALL_AVAILABLE') . '</option>';
1514 $i_characters = array_merge([25, 50], range(100, 1000, 100));
1515
1516 if ($config['default_search_return_chars'] && !in_array((int) $config['default_search_return_chars'], $i_characters))
1517 {
1518 $i_characters[] = (int) $config['default_search_return_chars'];
1519 sort($i_characters);
1520 }
1521
1522 foreach ($i_characters as $i)
1523 {
1524 $selected = $i === (int) $config['default_search_return_chars'] ? ' selected="selected"' : '';
1525 $s_characters .= sprintf('<option value="%1$s"%2$s>%1$s</option>', $i, $selected);
1526 }
1527
1528 $s_hidden_fields = array('t' => $topic_id);
1529
1530 if ($_SID)
1531 {
1532 $s_hidden_fields['sid'] = $_SID;
1533 }
1534
1535 if (!empty($_EXTRA_URL))
1536 {
1537 foreach ($_EXTRA_URL as $url_param)
1538 {
1539 $url_param = explode('=', $url_param, 2);
1540 $s_hidden_fields[$url_param[0]] = $url_param[1];
1541 }
1542 }
1543
1544 $template->assign_vars(array(
1545 'DEFAULT_RETURN_CHARS' => (int) $config['default_search_return_chars'],
1546 'S_SEARCH_ACTION' => append_sid("{$phpbb_root_path}search.$phpEx", false, true, 0), // We force no ?sid= appending by using 0
1547 'S_HIDDEN_FIELDS' => build_hidden_fields($s_hidden_fields),
1548 'S_CHARACTER_OPTIONS' => $s_characters,
1549 'S_FORUM_OPTIONS' => $s_forums,
1550 'S_SELECT_SORT_DIR' => $s_sort_dir,
1551 'S_SELECT_SORT_KEY' => $s_sort_key,
1552 'S_SELECT_SORT_DAYS' => $s_limit_days,
1553 'S_IN_SEARCH' => true,
1554 ));
1555
1556 // only show recent searches to search administrators
1557 if ($auth->acl_get('a_search'))
1558 {
1559 // Handle large objects differently for Oracle and MSSQL
1560 switch ($db->get_sql_layer())
1561 {
1562 case 'oracle':
1563 $sql = 'SELECT search_time, search_keywords
1564 FROM ' . SEARCH_RESULTS_TABLE . '
1565 WHERE dbms_lob.getlength(search_keywords) > 0
1566 ORDER BY search_time DESC';
1567 break;
1568
1569 case 'mssql_odbc':
1570 case 'mssqlnative':
1571 $sql = 'SELECT search_time, search_keywords
1572 FROM ' . SEARCH_RESULTS_TABLE . '
1573 WHERE DATALENGTH(search_keywords) > 0
1574 ORDER BY search_time DESC';
1575 break;
1576
1577 default:
1578 $sql = 'SELECT search_time, search_keywords
1579 FROM ' . SEARCH_RESULTS_TABLE . '
1580 WHERE search_keywords <> \'\'
1581 ORDER BY search_time DESC';
1582 break;
1583 }
1584 $result = $db->sql_query_limit($sql, 5);
1585
1586 while ($row = $db->sql_fetchrow($result))
1587 {
1588 $keywords = $row['search_keywords'];
1589
1590 $template->assign_block_vars('recentsearch', array(
1591 'KEYWORDS' => $keywords,
1592 'TIME' => $user->format_date($row['search_time']),
1593
1594 'U_KEYWORDS' => append_sid("{$phpbb_root_path}search.$phpEx", 'keywords=' . urlencode(html_entity_decode($keywords, ENT_COMPAT)))
1595 ));
1596 }
1597 $db->sql_freeresult($result);
1598 }
1599
1600 // Output the basic page
1601 page_header($user->lang['SEARCH']);
1602
1603 $template->set_filenames(array(
1604 'body' => 'search_body.html')
1605 );
1606 make_jumpbox(append_sid("{$phpbb_root_path}viewforum.$phpEx"));
1607
1608 page_footer();
1609