[ Index ] |
PHP Cross Reference of phpBB-3.3.11-deutsch |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * 4 * This file is part of the phpBB Forum Software package. 5 * 6 * @copyright (c) phpBB Limited <https://www.phpbb.com> 7 * @license GNU General Public License, version 2 (GPL-2.0) 8 * 9 * For full copyright and license information, please see 10 * the docs/CREDITS.txt file. 11 * 12 */ 13 14 /** 15 * @ignore 16 */ 17 define('IN_PHPBB', true); 18 $phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './'; 19 $phpEx = substr(strrchr(__FILE__, '.'), 1); 20 include($phpbb_root_path . 'common.' . $phpEx); 21 22 // Start session management 23 $user->session_begin(); 24 $auth->acl($user->data); 25 $user->setup('search'); 26 27 // Define initial vars 28 $mode = $request->variable('mode', ''); 29 $search_id = $request->variable('search_id', ''); 30 $start = max($request->variable('start', 0), 0); 31 $post_id = $request->variable('p', 0); 32 $topic_id = $request->variable('t', 0); 33 $view = $request->variable('view', ''); 34 35 $submit = $request->variable('submit', false); 36 $keywords = $request->variable('keywords', '', true); 37 $add_keywords = $request->variable('add_keywords', '', true); 38 $author = $request->variable('author', '', true); 39 $author_id = $request->variable('author_id', 0); 40 $show_results = ($topic_id) ? 'posts' : $request->variable('sr', 'posts'); 41 $show_results = ($show_results == 'posts') ? 'posts' : 'topics'; 42 $search_terms = $request->variable('terms', 'all'); 43 $search_fields = $request->variable('sf', 'all'); 44 $search_child = $request->variable('sc', true); 45 46 $sort_days = $request->variable('st', 0); 47 $sort_key = $request->variable('sk', 't'); 48 $sort_dir = $request->variable('sd', 'd'); 49 50 $return_chars = $request->variable('ch', $topic_id ? 0 : (int) $config['default_search_return_chars']); 51 $search_forum = $request->variable('fid', array(0)); 52 53 // We put login boxes for the case if search_id is newposts, egosearch or unreadposts 54 // because a guest should be able to log in even if guests search is not permitted 55 56 switch ($search_id) 57 { 58 // Egosearch is an author search 59 case 'egosearch': 60 $author_id = $user->data['user_id']; 61 if ($user->data['user_id'] == ANONYMOUS) 62 { 63 login_box('', $user->lang['LOGIN_EXPLAIN_EGOSEARCH']); 64 } 65 break; 66 67 // Search for unread posts needs to be allowed and user to be logged in if topics tracking for guests is disabled 68 case 'unreadposts': 69 if (!$config['load_unreads_search']) 70 { 71 $template->assign_var('S_NO_SEARCH', true); 72 trigger_error('NO_SEARCH_UNREADS'); 73 } 74 else if (!$config['load_anon_lastread'] && !$user->data['is_registered']) 75 { 76 login_box('', $user->lang['LOGIN_EXPLAIN_UNREADSEARCH']); 77 } 78 break; 79 80 // The "new posts" search uses user_lastvisit which is user based, so it should require user to log in. 81 case 'newposts': 82 if ($user->data['user_id'] == ANONYMOUS) 83 { 84 login_box('', $user->lang['LOGIN_EXPLAIN_NEWPOSTS']); 85 } 86 break; 87 88 default: 89 // There's nothing to do here for now ;) 90 break; 91 } 92 93 // Is user able to search? Has search been disabled? 94 if (!$auth->acl_get('u_search') || !$auth->acl_getf_global('f_search') || !$config['load_search']) 95 { 96 $template->assign_var('S_NO_SEARCH', true); 97 trigger_error('NO_SEARCH'); 98 } 99 100 // Check search load limit 101 if ($user->load && $config['limit_search_load'] && ($user->load > doubleval($config['limit_search_load']))) 102 { 103 $template->assign_var('S_NO_SEARCH', true); 104 trigger_error('NO_SEARCH_LOAD'); 105 } 106 107 // It is applicable if the configuration setting is non-zero, and the user cannot 108 // ignore the flood setting, and the search is a keyword search. 109 $interval = ($user->data['user_id'] == ANONYMOUS) ? $config['search_anonymous_interval'] : $config['search_interval']; 110 if ($interval && !in_array($search_id, array('unreadposts', 'unanswered', 'active_topics', 'egosearch')) && !$auth->acl_get('u_ignoreflood')) 111 { 112 if ($user->data['user_last_search'] > time() - $interval) 113 { 114 $template->assign_var('S_NO_SEARCH', true); 115 trigger_error($user->lang('NO_SEARCH_TIME', (int) ($user->data['user_last_search'] + $interval - time()))); 116 } 117 } 118 119 // Define some vars 120 $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']); 121 $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']); 122 123 $s_limit_days = $s_sort_key = $s_sort_dir = $u_sort_param = ''; 124 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); 125 126 /* @var $phpbb_content_visibility \phpbb\content_visibility */ 127 $phpbb_content_visibility = $phpbb_container->get('content.visibility'); 128 129 /* @var $pagination \phpbb\pagination */ 130 $pagination = $phpbb_container->get('pagination'); 131 132 $template->assign_block_vars('navlinks', array( 133 'BREADCRUMB_NAME' => $user->lang('SEARCH'), 134 'U_BREADCRUMB' => append_sid("{$phpbb_root_path}search.$phpEx"), 135 )); 136 137 /** 138 * This event allows you to alter the above parameters, such as keywords and submit 139 * 140 * @event core.search_modify_submit_parameters 141 * @var string keywords The search keywords 142 * @var string author Specifies the author match, when ANONYMOUS is also a search-match 143 * @var int author_id ID of the author to search by 144 * @var string search_id Predefined search type name 145 * @var bool submit Whether or not the form has been submitted 146 * @since 3.1.10-RC1 147 */ 148 $vars = array( 149 'keywords', 150 'author', 151 'author_id', 152 'search_id', 153 'submit', 154 ); 155 extract($phpbb_dispatcher->trigger_event('core.search_modify_submit_parameters', compact($vars))); 156 157 if ($keywords || $author || $author_id || $search_id || $submit) 158 { 159 // clear arrays 160 $id_ary = array(); 161 162 // If we are looking for authors get their ids 163 $author_id_ary = array(); 164 $sql_author_match = ''; 165 if ($author_id) 166 { 167 $author_id_ary[] = $author_id; 168 } 169 else if ($author) 170 { 171 if ((strpos($author, '*') !== false) && (utf8_strlen(str_replace(array('*', '%'), '', $author)) < $config['min_search_author_chars'])) 172 { 173 trigger_error($user->lang('TOO_FEW_AUTHOR_CHARS', (int) $config['min_search_author_chars'])); 174 } 175 176 $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)) . "'"; 177 178 $sql = 'SELECT user_id 179 FROM ' . USERS_TABLE . " 180 WHERE $sql_where 181 AND user_type <> " . USER_IGNORE; 182 $result = $db->sql_query_limit($sql, 100); 183 184 while ($row = $db->sql_fetchrow($result)) 185 { 186 $author_id_ary[] = (int) $row['user_id']; 187 } 188 $db->sql_freeresult($result); 189 190 $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)) . "'"; 191 192 $sql = 'SELECT 1 as guest_post 193 FROM ' . POSTS_TABLE . " 194 WHERE $sql_where 195 AND poster_id = " . ANONYMOUS; 196 $result = $db->sql_query_limit($sql, 1); 197 $found_guest_post = $db->sql_fetchfield('guest_post'); 198 $db->sql_freeresult($result); 199 200 if ($found_guest_post) 201 { 202 $author_id_ary[] = ANONYMOUS; 203 $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)) . "'"; 204 } 205 206 if (!count($author_id_ary)) 207 { 208 trigger_error('NO_SEARCH_RESULTS'); 209 } 210 } 211 212 // if we search in an existing search result just add the additional keywords. But we need to use "all search terms"-mode 213 // so we can keep the old keywords in their old mode, but add the new ones as required words 214 if ($add_keywords) 215 { 216 if ($search_terms == 'all') 217 { 218 $keywords .= ' ' . $add_keywords; 219 } 220 else 221 { 222 $search_terms = 'all'; 223 $keywords = implode(' |', explode(' ', preg_replace('#\s+#u', ' ', $keywords))) . ' ' .$add_keywords; 224 } 225 } 226 227 // Which forums should not be searched? Author searches are also carried out in unindexed forums 228 if (empty($keywords) && count($author_id_ary)) 229 { 230 $ex_fid_ary = array_keys($auth->acl_getf('!f_read', true)); 231 } 232 else 233 { 234 $ex_fid_ary = array_unique(array_merge(array_keys($auth->acl_getf('!f_read', true)), array_keys($auth->acl_getf('!f_search', true)))); 235 } 236 237 $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'] . ')' : ""; 238 239 $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 240 FROM ' . FORUMS_TABLE . ' f 241 LEFT JOIN ' . FORUMS_ACCESS_TABLE . " fa ON (fa.forum_id = f.forum_id 242 AND fa.session_id = '" . $db->sql_escape($user->session_id) . "') 243 $not_in_fid 244 ORDER BY f.left_id"; 245 $result = $db->sql_query($sql); 246 247 $right_id = 0; 248 $reset_search_forum = true; 249 while ($row = $db->sql_fetchrow($result)) 250 { 251 if ($row['forum_password'] && $row['user_id'] != $user->data['user_id']) 252 { 253 $ex_fid_ary[] = (int) $row['forum_id']; 254 continue; 255 } 256 257 // Exclude forums from active topics 258 if (!($row['forum_flags'] & FORUM_FLAG_ACTIVE_TOPICS) && ($search_id == 'active_topics')) 259 { 260 $ex_fid_ary[] = (int) $row['forum_id']; 261 continue; 262 } 263 264 if (count($search_forum)) 265 { 266 if ($search_child) 267 { 268 if (in_array($row['forum_id'], $search_forum) && $row['right_id'] > $right_id) 269 { 270 $right_id = (int) $row['right_id']; 271 } 272 else if ($row['right_id'] < $right_id) 273 { 274 continue; 275 } 276 } 277 278 if (!in_array($row['forum_id'], $search_forum)) 279 { 280 $ex_fid_ary[] = (int) $row['forum_id']; 281 $reset_search_forum = false; 282 } 283 } 284 } 285 $db->sql_freeresult($result); 286 287 // find out in which forums the user is allowed to view posts 288 $m_approve_posts_fid_sql = $phpbb_content_visibility->get_global_visibility_sql('post', $ex_fid_ary, 'p.'); 289 $m_approve_topics_fid_sql = $phpbb_content_visibility->get_global_visibility_sql('topic', $ex_fid_ary, 't.'); 290 291 if ($reset_search_forum) 292 { 293 $search_forum = array(); 294 } 295 296 // Select which method we'll use to obtain the post_id or topic_id information 297 $search_type = $config['search_type']; 298 299 if (!class_exists($search_type)) 300 { 301 trigger_error('NO_SUCH_SEARCH_MODULE'); 302 } 303 // We do some additional checks in the module to ensure it can actually be utilised 304 $error = false; 305 $search = new $search_type($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user, $phpbb_dispatcher); 306 307 if ($error) 308 { 309 trigger_error($error); 310 } 311 312 // let the search module split up the keywords 313 if ($keywords) 314 { 315 $correct_query = $search->split_keywords($keywords, $search_terms); 316 $common_words = $search->get_common_words(); 317 if (!$correct_query || (!$search->get_search_query() && !count($author_id_ary) && !$search_id)) 318 { 319 $ignored = (count($common_words)) ? sprintf($user->lang['IGNORED_TERMS_EXPLAIN'], implode(' ', $common_words)) . '<br />' : ''; 320 $word_length = $search->get_word_length(); 321 if ($word_length) 322 { 323 trigger_error($ignored . $user->lang('NO_KEYWORDS', $user->lang('CHARACTERS', (int) $word_length['min']), $user->lang('CHARACTERS', (int) $word_length['max']))); 324 } 325 else 326 { 327 trigger_error($ignored); 328 } 329 } 330 } 331 332 if (!$keywords && count($author_id_ary)) 333 { 334 // if it is an author search we want to show topics by default 335 $show_results = ($topic_id) ? 'posts' : $request->variable('sr', ($search_id == 'egosearch') ? 'topics' : 'posts'); 336 $show_results = ($show_results == 'posts') ? 'posts' : 'topics'; 337 } 338 339 // define some variables needed for retrieving post_id/topic_id information 340 $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')); 341 342 /** 343 * Event to modify the SQL parameters before pre-made searches 344 * 345 * @event core.search_modify_param_before 346 * @var string keywords String of the specified keywords 347 * @var array sort_by_sql Array of SQL sorting instructions 348 * @var array ex_fid_ary Array of excluded forum ids 349 * @var array author_id_ary Array of exclusive author ids 350 * @var string search_id The id of the search request 351 * @var array id_ary Array of post or topic ids for search result 352 * @var string show_results 'posts' or 'topics' type of ids 353 * @since 3.1.3-RC1 354 * @changed 3.1.10-RC1 Added id_ary, show_results 355 */ 356 $vars = array( 357 'keywords', 358 'sort_by_sql', 359 'ex_fid_ary', 360 'author_id_ary', 361 'search_id', 362 'id_ary', 363 'show_results', 364 ); 365 extract($phpbb_dispatcher->trigger_event('core.search_modify_param_before', compact($vars))); 366 367 // pre-made searches 368 $sql = $field = $l_search_title = ''; 369 if ($search_id) 370 { 371 switch ($search_id) 372 { 373 // Oh holy Bob, bring us some activity... 374 case 'active_topics': 375 $l_search_title = $user->lang['SEARCH_ACTIVE_TOPICS']; 376 $show_results = 'topics'; 377 $sort_key = 't'; 378 $sort_dir = 'd'; 379 $sort_days = $request->variable('st', 7); 380 $sort_by_sql['t'] = 't.topic_last_post_time'; 381 382 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); 383 $s_sort_key = $s_sort_dir = ''; 384 385 $last_post_time_sql = ($sort_days) ? ' AND t.topic_last_post_time > ' . (time() - ($sort_days * 24 * 3600)) : ''; 386 387 $sql = 'SELECT t.topic_last_post_time, t.topic_id 388 FROM ' . TOPICS_TABLE . " t 389 WHERE t.topic_moved_id = 0 390 $last_post_time_sql 391 AND " . $m_approve_topics_fid_sql . ' 392 ' . ((count($ex_fid_ary)) ? ' AND ' . $db->sql_in_set('t.forum_id', $ex_fid_ary, true) : '') . ' 393 ORDER BY t.topic_last_post_time DESC'; 394 $field = 'topic_id'; 395 break; 396 397 case 'unanswered': 398 $l_search_title = $user->lang['SEARCH_UNANSWERED']; 399 $show_results = $request->variable('sr', 'topics'); 400 $show_results = ($show_results == 'posts') ? 'posts' : 'topics'; 401 $sort_by_sql['t'] = ($show_results == 'posts') ? 'p.post_time' : 't.topic_last_post_time'; 402 $sort_by_sql['s'] = ($show_results == 'posts') ? 'p.post_subject' : 't.topic_title'; 403 $sql_sort = 'ORDER BY ' . $sort_by_sql[$sort_key] . (($sort_dir == 'a') ? ' ASC' : ' DESC'); 404 405 $sort_join = ($sort_key == 'f') ? FORUMS_TABLE . ' f, ' : ''; 406 $sql_sort = ($sort_key == 'f') ? ' AND f.forum_id = p.forum_id ' . $sql_sort : $sql_sort; 407 408 if ($sort_days) 409 { 410 $last_post_time = 'AND p.post_time > ' . (time() - ($sort_days * 24 * 3600)); 411 } 412 else 413 { 414 $last_post_time = ''; 415 } 416 417 if ($sort_key == 'a') 418 { 419 $sort_join = USERS_TABLE . ' u, '; 420 $sql_sort = ' AND u.user_id = p.poster_id ' . $sql_sort; 421 } 422 if ($show_results == 'posts') 423 { 424 $sql = "SELECT p.post_id 425 FROM $sort_join" . POSTS_TABLE . ' p, ' . TOPICS_TABLE . " t 426 WHERE t.topic_posts_approved = 1 427 AND p.topic_id = t.topic_id 428 $last_post_time 429 AND $m_approve_posts_fid_sql 430 " . ((count($ex_fid_ary)) ? ' AND ' . $db->sql_in_set('p.forum_id', $ex_fid_ary, true) : '') . " 431 $sql_sort"; 432 $field = 'post_id'; 433 } 434 else 435 { 436 $sql = 'SELECT DISTINCT ' . $sort_by_sql[$sort_key] . ", p.topic_id 437 FROM $sort_join" . POSTS_TABLE . ' p, ' . TOPICS_TABLE . " t 438 WHERE t.topic_posts_approved = 1 439 AND t.topic_moved_id = 0 440 AND p.topic_id = t.topic_id 441 $last_post_time 442 AND $m_approve_topics_fid_sql 443 " . ((count($ex_fid_ary)) ? ' AND ' . $db->sql_in_set('p.forum_id', $ex_fid_ary, true) : '') . " 444 $sql_sort"; 445 $field = 'topic_id'; 446 } 447 break; 448 449 case 'unreadposts': 450 $l_search_title = $user->lang['SEARCH_UNREAD']; 451 // force sorting 452 $show_results = 'topics'; 453 $sort_key = 't'; 454 $sort_by_sql['t'] = 't.topic_last_post_time'; 455 $sql_sort = 'ORDER BY ' . $sort_by_sql[$sort_key] . (($sort_dir == 'a') ? ' ASC' : ' DESC'); 456 457 $sql_where = 'AND t.topic_moved_id = 0 458 AND ' . $m_approve_topics_fid_sql . ' 459 ' . ((count($ex_fid_ary)) ? 'AND ' . $db->sql_in_set('t.forum_id', $ex_fid_ary, true) : ''); 460 461 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); 462 $s_sort_key = $s_sort_dir = $u_sort_param = $s_limit_days = ''; 463 464 $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()) : ''); 465 break; 466 467 case 'newposts': 468 $l_search_title = $user->lang['SEARCH_NEW']; 469 // force sorting 470 $show_results = ($request->variable('sr', 'topics') == 'posts') ? 'posts' : 'topics'; 471 $sort_key = 't'; 472 $sort_dir = 'd'; 473 $sort_by_sql['t'] = ($show_results == 'posts') ? 'p.post_time' : 't.topic_last_post_time'; 474 $sql_sort = 'ORDER BY ' . $sort_by_sql[$sort_key] . (($sort_dir == 'a') ? ' ASC' : ' DESC'); 475 476 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); 477 $s_sort_key = $s_sort_dir = $u_sort_param = $s_limit_days = ''; 478 479 if ($show_results == 'posts') 480 { 481 $sql = 'SELECT p.post_id 482 FROM ' . POSTS_TABLE . ' p 483 WHERE p.post_time > ' . $user->data['user_lastvisit'] . ' 484 AND ' . $m_approve_posts_fid_sql . ' 485 ' . ((count($ex_fid_ary)) ? ' AND ' . $db->sql_in_set('p.forum_id', $ex_fid_ary, true) : '') . " 486 $sql_sort"; 487 $field = 'post_id'; 488 } 489 else 490 { 491 $sql = 'SELECT t.topic_id 492 FROM ' . TOPICS_TABLE . ' t 493 WHERE t.topic_last_post_time > ' . $user->data['user_lastvisit'] . ' 494 AND t.topic_moved_id = 0 495 AND ' . $m_approve_topics_fid_sql . ' 496 ' . ((count($ex_fid_ary)) ? 'AND ' . $db->sql_in_set('t.forum_id', $ex_fid_ary, true) : '') . " 497 $sql_sort"; 498 /* 499 [Fix] queued replies missing from "view new posts" (Bug #42705 - Patch by Paul) 500 - Creates temporary table, query is far from optimized 501 502 $sql = 'SELECT t.topic_id 503 FROM ' . TOPICS_TABLE . ' t, ' . POSTS_TABLE . ' p 504 WHERE p.post_time > ' . $user->data['user_lastvisit'] . ' 505 AND t.topic_id = p.topic_id 506 AND t.topic_moved_id = 0 507 AND ' . $m_approve_topics_fid_sql . " 508 GROUP BY t.topic_id 509 $sql_sort"; 510 */ 511 $field = 'topic_id'; 512 } 513 break; 514 515 case 'egosearch': 516 $l_search_title = $user->lang['SEARCH_SELF']; 517 break; 518 } 519 520 $template->assign_block_vars('navlinks', array( 521 'BREADCRUMB_NAME' => $l_search_title, 522 'U_BREADCRUMB' => append_sid("{$phpbb_root_path}search.$phpEx", "search_id=$search_id"), 523 )); 524 } 525 526 /** 527 * Event to modify data after pre-made searches 528 * 529 * @event core.search_modify_param_after 530 * @var string l_search_title The title of the search page 531 * @var string search_id Predefined search type name 532 * @var string show_results Display topics or posts 533 * @var string sql SQL query corresponding to the pre-made search id 534 * @since 3.1.7-RC1 535 */ 536 $vars = array( 537 'l_search_title', 538 'search_id', 539 'show_results', 540 'sql', 541 ); 542 extract($phpbb_dispatcher->trigger_event('core.search_modify_param_after', compact($vars))); 543 544 // show_results should not change after this 545 $per_page = ($show_results == 'posts') ? $config['posts_per_page'] : $config['topics_per_page']; 546 $total_match_count = 0; 547 548 // Set limit for the $total_match_count to reduce server load 549 $total_matches_limit = 1000; 550 $found_more_search_matches = false; 551 552 if ($search_id) 553 { 554 if ($sql) 555 { 556 // Only return up to $total_matches_limit+1 ids (the last one will be removed later) 557 $result = $db->sql_query_limit($sql, $total_matches_limit + 1); 558 559 while ($row = $db->sql_fetchrow($result)) 560 { 561 $id_ary[] = (int) $row[$field]; 562 } 563 $db->sql_freeresult($result); 564 } 565 else if ($search_id == 'unreadposts') 566 { 567 // Only return up to $total_matches_limit+1 ids (the last one will be removed later) 568 $id_ary = array_keys(get_unread_topics($user->data['user_id'], $sql_where, $sql_sort, $total_matches_limit + 1)); 569 } 570 else 571 { 572 $search_id = ''; 573 } 574 575 $total_match_count = count($id_ary); 576 if ($total_match_count) 577 { 578 // Limit the number to $total_matches_limit for pre-made searches 579 if ($total_match_count > $total_matches_limit) 580 { 581 $found_more_search_matches = true; 582 $total_match_count = $total_matches_limit; 583 } 584 585 // Make sure $start is set to the last page if it exceeds the amount 586 $start = $pagination->validate_start($start, $per_page, $total_match_count); 587 588 $id_ary = array_slice($id_ary, $start, $per_page); 589 } 590 else 591 { 592 // Set $start to 0 if no matches were found 593 $start = 0; 594 } 595 } 596 597 // make sure that some arrays are always in the same order 598 sort($ex_fid_ary); 599 sort($author_id_ary); 600 601 if ($search->get_search_query()) 602 { 603 $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); 604 } 605 else if (count($author_id_ary)) 606 { 607 $firstpost_only = ($search_fields === 'firstpost' || $search_fields == 'titleonly') ? true : false; 608 $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); 609 } 610 611 /** 612 * Event to search otherwise than by keywords or author 613 * 614 * @event core.search_backend_search_after 615 * @var string show_results 'posts' or 'topics' type of ids 616 * @var string search_fields The data fields to search in 617 * @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) 618 * @var array sort_by_sql Array of SQL sorting instructions 619 * @var string sort_key The sort key 620 * @var string sort_dir The sort direction 621 * @var int sort_days Limit the age of results 622 * @var array ex_fid_ary Array of excluded forum ids 623 * @var string m_approve_posts_fid_sql Specifies which types of posts the user can view in which forums 624 * @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 625 * @var array author_id_ary Array of exclusive author ids 626 * @var string sql_author_match Specifies the author match, when ANONYMOUS is also a search-match 627 * @var array id_ary Array of post or topic ids for search result 628 * @var int start The starting id of the results 629 * @var int per_page Number of ids each page is supposed to contain 630 * @var int total_match_count The total number of search matches 631 * @since 3.1.10-RC1 632 */ 633 $vars = array( 634 'show_results', 635 'search_fields', 636 'search_terms', 637 'sort_by_sql', 638 'sort_key', 639 'sort_dir', 640 'sort_days', 641 'ex_fid_ary', 642 'm_approve_posts_fid_sql', 643 'topic_id', 644 'author_id_ary', 645 'sql_author_match', 646 'id_ary', 647 'start', 648 'per_page', 649 'total_match_count', 650 ); 651 extract($phpbb_dispatcher->trigger_event('core.search_backend_search_after', compact($vars))); 652 653 $sql_where = ''; 654 655 if (count($id_ary)) 656 { 657 $sql_where .= $db->sql_in_set(($show_results == 'posts') ? 'p.post_id' : 't.topic_id', $id_ary); 658 $sql_where .= (count($ex_fid_ary)) ? ' AND (' . $db->sql_in_set('f.forum_id', $ex_fid_ary, true) . ' OR f.forum_id IS NULL)' : ''; 659 $sql_where .= ' AND ' . (($show_results == 'posts') ? $m_approve_posts_fid_sql : $m_approve_topics_fid_sql); 660 } 661 662 if ($show_results == 'posts') 663 { 664 include($phpbb_root_path . 'includes/functions_posting.' . $phpEx); 665 } 666 else 667 { 668 include($phpbb_root_path . 'includes/functions_display.' . $phpEx); 669 } 670 671 $user->add_lang('viewtopic'); 672 673 // Grab icons 674 $icons = $cache->obtain_icons(); 675 676 // define some vars for urls 677 // A single wildcard will make the search results look ugly 678 $hilit = phpbb_clean_search_string(str_replace(array('+', '-', '|', '(', ')', '"'), ' ', $keywords)); 679 $hilit = str_replace(' ', '|', $hilit); 680 681 $u_hilit = urlencode(html_entity_decode(str_replace('|', ' ', $hilit), ENT_COMPAT)); 682 $u_show_results = '&sr=' . $show_results; 683 $u_search_forum = implode('&fid%5B%5D=', $search_forum); 684 685 $u_search = append_sid("{$phpbb_root_path}search.$phpEx", $u_sort_param . $u_show_results); 686 $u_search .= ($search_id) ? '&search_id=' . $search_id : ''; 687 $u_search .= ($u_hilit) ? '&keywords=' . urlencode(html_entity_decode($keywords, ENT_COMPAT)) : ''; 688 $u_search .= ($search_terms != 'all') ? '&terms=' . $search_terms : ''; 689 $u_search .= ($topic_id) ? '&t=' . $topic_id : ''; 690 $u_search .= ($author) ? '&author=' . urlencode(html_entity_decode($author, ENT_COMPAT)) : ''; 691 $u_search .= ($author_id) ? '&author_id=' . $author_id : ''; 692 $u_search .= ($u_search_forum) ? '&fid%5B%5D=' . $u_search_forum : ''; 693 $u_search .= (!$search_child) ? '&sc=0' : ''; 694 $u_search .= ($search_fields != 'all') ? '&sf=' . $search_fields : ''; 695 $u_search .= $return_chars !== (int) $config['default_search_return_chars'] ? '&ch=' . $return_chars : ''; 696 697 /** 698 * Event to add or modify search URL parameters 699 * 700 * @event core.search_modify_url_parameters 701 * @var string u_search Search URL parameters string 702 * @var string search_id Predefined search type name 703 * @var string show_results String indicating the show results mode 704 * @var string sql_where The SQL WHERE string used by search to get topic data 705 * @var int total_match_count The total number of search matches 706 * @var array ex_fid_ary Array of excluded forum ids 707 * @since 3.1.7-RC1 708 * @changed 3.1.10-RC1 Added show_results, sql_where, total_match_count 709 * @changed 3.1.11-RC1 Added ex_fid_ary 710 */ 711 $vars = array( 712 'u_search', 713 'search_id', 714 'show_results', 715 'sql_where', 716 'total_match_count', 717 'ex_fid_ary', 718 ); 719 extract($phpbb_dispatcher->trigger_event('core.search_modify_url_parameters', compact($vars))); 720 721 if ($sql_where) 722 { 723 $zebra = []; 724 725 if ($show_results == 'posts') 726 { 727 // @todo Joining this query to the one below? 728 $sql = 'SELECT zebra_id, friend, foe 729 FROM ' . ZEBRA_TABLE . ' 730 WHERE user_id = ' . $user->data['user_id']; 731 $result = $db->sql_query($sql); 732 733 while ($row = $db->sql_fetchrow($result)) 734 { 735 $zebra[($row['friend']) ? 'friend' : 'foe'][] = $row['zebra_id']; 736 } 737 $db->sql_freeresult($result); 738 739 $sql_array = array( 740 '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', 741 'FROM' => array( 742 POSTS_TABLE => 'p', 743 ), 744 'LEFT_JOIN' => array( 745 array( 746 'FROM' => array(TOPICS_TABLE => 't'), 747 'ON' => 'p.topic_id = t.topic_id', 748 ), 749 array( 750 'FROM' => array(FORUMS_TABLE => 'f'), 751 'ON' => 'p.forum_id = f.forum_id', 752 ), 753 array( 754 'FROM' => array(USERS_TABLE => 'u'), 755 'ON' => 'p.poster_id = u.user_id', 756 ), 757 ), 758 'WHERE' => $sql_where, 759 'ORDER_BY' => $sort_by_sql[$sort_key] . ' ' . (($sort_dir == 'd') ? 'DESC' : 'ASC'), 760 ); 761 762 /** 763 * Event to modify the SQL query before the posts data is retrieved 764 * 765 * @event core.search_get_posts_data 766 * @var array sql_array The SQL array 767 * @var array zebra Array of zebra data for the current user 768 * @var int total_match_count The total number of search matches 769 * @var string keywords String of the specified keywords 770 * @var array sort_by_sql Array of SQL sorting instructions 771 * @var string s_sort_dir The sort direction 772 * @var string s_sort_key The sort key 773 * @var string s_limit_days Limit the age of results 774 * @var array ex_fid_ary Array of excluded forum ids 775 * @var array author_id_ary Array of exclusive author ids 776 * @var string search_fields The data fields to search in 777 * @var int search_id The id of the search request 778 * @var int start The starting id of the results 779 * @since 3.1.0-b3 780 */ 781 $vars = array( 782 'sql_array', 783 'zebra', 784 'total_match_count', 785 'keywords', 786 'sort_by_sql', 787 's_sort_dir', 788 's_sort_key', 789 's_limit_days', 790 'ex_fid_ary', 791 'author_id_ary', 792 'search_fields', 793 'search_id', 794 'start', 795 ); 796 extract($phpbb_dispatcher->trigger_event('core.search_get_posts_data', compact($vars))); 797 798 $sql = $db->sql_build_query('SELECT', $sql_array); 799 } 800 else 801 { 802 $sql_from = TOPICS_TABLE . ' t 803 LEFT JOIN ' . FORUMS_TABLE . ' f ON (f.forum_id = t.forum_id) 804 ' . (($sort_key == 'a') ? ' LEFT JOIN ' . USERS_TABLE . ' u ON (u.user_id = t.topic_poster) ' : ''); 805 $sql_select = 't.*, f.forum_id, f.forum_name'; 806 807 if ($user->data['is_registered']) 808 { 809 if ($config['load_db_track'] && $author_id !== $user->data['user_id']) 810 { 811 $sql_from .= ' LEFT JOIN ' . TOPICS_POSTED_TABLE . ' tp ON (tp.user_id = ' . $user->data['user_id'] . ' 812 AND t.topic_id = tp.topic_id)'; 813 $sql_select .= ', tp.topic_posted'; 814 } 815 816 if ($config['load_db_lastread']) 817 { 818 $sql_from .= ' LEFT JOIN ' . TOPICS_TRACK_TABLE . ' tt ON (tt.user_id = ' . $user->data['user_id'] . ' 819 AND t.topic_id = tt.topic_id) 820 LEFT JOIN ' . FORUMS_TRACK_TABLE . ' ft ON (ft.user_id = ' . $user->data['user_id'] . ' 821 AND ft.forum_id = f.forum_id)'; 822 $sql_select .= ', tt.mark_time, ft.mark_time as f_mark_time'; 823 } 824 } 825 826 if ($config['load_anon_lastread'] || ($user->data['is_registered'] && !$config['load_db_lastread'])) 827 { 828 $tracking_topics = $request->variable($config['cookie_name'] . '_track', '', true, \phpbb\request\request_interface::COOKIE); 829 $tracking_topics = ($tracking_topics) ? tracking_unserialize($tracking_topics) : array(); 830 } 831 832 $sql_order_by = $sort_by_sql[$sort_key] . ' ' . (($sort_dir == 'd') ? 'DESC' : 'ASC'); 833 834 /** 835 * Event to modify the SQL query before the topic data is retrieved 836 * 837 * @event core.search_get_topic_data 838 * @var string sql_select The SQL SELECT string used by search to get topic data 839 * @var string sql_from The SQL FROM string used by search to get topic data 840 * @var string sql_where The SQL WHERE string used by search to get topic data 841 * @var int total_match_count The total number of search matches 842 * @var array sort_by_sql Array of SQL sorting instructions 843 * @var string sort_dir The sorting direction 844 * @var string sort_key The sorting key 845 * @var string sql_order_by The SQL ORDER BY string used by search to get topic data 846 * @since 3.1.0-a1 847 * @changed 3.1.0-RC5 Added total_match_count 848 * @changed 3.1.7-RC1 Added sort_by_sql, sort_dir, sort_key, sql_order_by 849 */ 850 $vars = array( 851 'sql_select', 852 'sql_from', 853 'sql_where', 854 'total_match_count', 855 'sort_by_sql', 856 'sort_dir', 857 'sort_key', 858 'sql_order_by', 859 ); 860 extract($phpbb_dispatcher->trigger_event('core.search_get_topic_data', compact($vars))); 861 862 $sql = "SELECT $sql_select 863 FROM $sql_from 864 WHERE $sql_where 865 ORDER BY $sql_order_by"; 866 } 867 $result = $db->sql_query($sql); 868 $result_topic_id = 0; 869 870 $rowset = $attachments = $topic_tracking_info = array(); 871 872 if ($show_results == 'topics') 873 { 874 $forums = $rowset = $shadow_topic_list = array(); 875 while ($row = $db->sql_fetchrow($result)) 876 { 877 $row['forum_id'] = (int) $row['forum_id']; 878 $row['topic_id'] = (int) $row['topic_id']; 879 880 if ($row['topic_status'] == ITEM_MOVED) 881 { 882 $shadow_topic_list[$row['topic_moved_id']] = $row['topic_id']; 883 } 884 885 $rowset[$row['topic_id']] = $row; 886 887 if (!isset($forums[$row['forum_id']]) && $user->data['is_registered'] && $config['load_db_lastread']) 888 { 889 $forums[$row['forum_id']]['mark_time'] = $row['f_mark_time']; 890 } 891 $forums[$row['forum_id']]['topic_list'][] = $row['topic_id']; 892 $forums[$row['forum_id']]['rowset'][$row['topic_id']] = &$rowset[$row['topic_id']]; 893 } 894 $db->sql_freeresult($result); 895 896 // If we have some shadow topics, update the rowset to reflect their topic information 897 if (count($shadow_topic_list)) 898 { 899 $sql = 'SELECT * 900 FROM ' . TOPICS_TABLE . ' 901 WHERE ' . $db->sql_in_set('topic_id', array_keys($shadow_topic_list)); 902 $result = $db->sql_query($sql); 903 904 while ($row = $db->sql_fetchrow($result)) 905 { 906 $orig_topic_id = $shadow_topic_list[$row['topic_id']]; 907 908 // We want to retain some values 909 $row = array_merge($row, array( 910 'topic_moved_id' => $rowset[$orig_topic_id]['topic_moved_id'], 911 'topic_status' => $rowset[$orig_topic_id]['topic_status'], 912 'forum_name' => $rowset[$orig_topic_id]['forum_name']) 913 ); 914 915 $rowset[$orig_topic_id] = $row; 916 } 917 $db->sql_freeresult($result); 918 } 919 unset($shadow_topic_list); 920 921 foreach ($forums as $forum_id => $forum) 922 { 923 if ($user->data['is_registered'] && $config['load_db_lastread']) 924 { 925 $topic_tracking_info[$forum_id] = get_topic_tracking($forum_id, $forum['topic_list'], $forum['rowset'], array($forum_id => $forum['mark_time'])); 926 } 927 else if ($config['load_anon_lastread'] || $user->data['is_registered']) 928 { 929 $topic_tracking_info[$forum_id] = get_complete_topic_tracking($forum_id, $forum['topic_list']); 930 931 if (!$user->data['is_registered']) 932 { 933 $user->data['user_lastmark'] = (isset($tracking_topics['l'])) ? (int) (base_convert($tracking_topics['l'], 36, 10) + $config['board_startdate']) : 0; 934 } 935 } 936 } 937 unset($forums); 938 } 939 else 940 { 941 $text_only_message = ''; 942 $attach_list = array(); 943 944 while ($row = $db->sql_fetchrow($result)) 945 { 946 /** 947 * Modify the row of a post result before the post_text is trimmed 948 * 949 * @event core.search_modify_post_row 950 * @var string hilit String to highlight 951 * @var array row Array with the post data 952 * @var string u_hilit Highlight string to be injected into URL 953 * @var string view Search results view mode 954 * @var array zebra Array with zebra data for the current user 955 * @since 3.2.2-RC1 956 */ 957 $vars = array( 958 'hilit', 959 'row', 960 'u_hilit', 961 'view', 962 'zebra', 963 ); 964 extract($phpbb_dispatcher->trigger_event('core.search_modify_post_row', compact($vars))); 965 966 // We pre-process some variables here for later usage 967 $row['post_text'] = censor_text($row['post_text']); 968 969 $text_only_message = $row['post_text']; 970 // make list items visible as such 971 if ($row['bbcode_uid']) 972 { 973 $text_only_message = str_replace('[*:' . $row['bbcode_uid'] . ']', '⋅ ', $text_only_message); 974 // no BBCode in text only message 975 strip_bbcode($text_only_message, $row['bbcode_uid']); 976 } 977 978 if ($return_chars === 0 || utf8_strlen($text_only_message) < ($return_chars + 3)) 979 { 980 $row['display_text_only'] = false; 981 982 // Does this post have an attachment? If so, add it to the list 983 if ($row['post_attachment'] && $config['allow_attachments']) 984 { 985 $attach_list[$row['forum_id']][] = $row['post_id']; 986 } 987 } 988 else 989 { 990 $row['post_text'] = $text_only_message; 991 $row['display_text_only'] = true; 992 } 993 994 $rowset[] = $row; 995 } 996 $db->sql_freeresult($result); 997 998 unset($text_only_message); 999 1000 // Pull attachment data 1001 if (count($attach_list)) 1002 { 1003 $use_attach_list = $attach_list; 1004 $attach_list = array(); 1005 1006 foreach ($use_attach_list as $forum_id => $_list) 1007 { 1008 if ($auth->acl_get('u_download') && $auth->acl_get('f_download', $forum_id)) 1009 { 1010 $attach_list = array_merge($attach_list, $_list); 1011 } 1012 } 1013 } 1014 1015 if (count($attach_list)) 1016 { 1017 $sql = 'SELECT * 1018 FROM ' . ATTACHMENTS_TABLE . ' 1019 WHERE ' . $db->sql_in_set('post_msg_id', $attach_list) . ' 1020 AND in_message = 0 1021 ORDER BY filetime DESC, post_msg_id ASC'; 1022 $result = $db->sql_query($sql); 1023 1024 while ($row = $db->sql_fetchrow($result)) 1025 { 1026 $attachments[$row['post_msg_id']][] = $row; 1027 } 1028 $db->sql_freeresult($result); 1029 } 1030 } 1031 1032 if ($hilit) 1033 { 1034 // Remove bad highlights 1035 $hilit_array = array_filter(explode('|', $hilit), 'strlen'); 1036 foreach ($hilit_array as $key => $value) 1037 { 1038 $hilit_array[$key] = phpbb_clean_search_string($value); 1039 $hilit_array[$key] = str_replace('\*', '\w*?', preg_quote($hilit_array[$key], '#')); 1040 $hilit_array[$key] = preg_replace('#(^|\s)\\\\w\*\?(\s|$)#', '$1\w+?$2', $hilit_array[$key]); 1041 } 1042 $hilit = implode('|', $hilit_array); 1043 } 1044 1045 /** 1046 * Modify the rowset data 1047 * 1048 * @event core.search_modify_rowset 1049 * @var array attachments Array with posts attachments data 1050 * @var string hilit String to highlight 1051 * @var array rowset Array with the search results data 1052 * @var string show_results String indicating the show results mode 1053 * @var array topic_tracking_info Array with the topics tracking data 1054 * @var string u_hilit Highlight string to be injected into URL 1055 * @var string view Search results view mode 1056 * @var array zebra Array with zebra data for the current user 1057 * @since 3.1.0-b4 1058 * @changed 3.1.0-b5 Added var show_results 1059 */ 1060 $vars = array( 1061 'attachments', 1062 'hilit', 1063 'rowset', 1064 'show_results', 1065 'topic_tracking_info', 1066 'u_hilit', 1067 'view', 1068 'zebra', 1069 ); 1070 extract($phpbb_dispatcher->trigger_event('core.search_modify_rowset', compact($vars))); 1071 1072 foreach ($rowset as $row) 1073 { 1074 $forum_id = $row['forum_id']; 1075 $result_topic_id = $row['topic_id']; 1076 $topic_title = censor_text($row['topic_title']); 1077 $replies = $phpbb_content_visibility->get_count('topic_posts', $row, $forum_id) - 1; 1078 1079 $view_topic_url_params = "t=$result_topic_id" . (($u_hilit) ? "&hilit=$u_hilit" : ''); 1080 $view_topic_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", $view_topic_url_params); 1081 1082 $folder_img = $folder_alt = $u_mcp_queue = ''; 1083 $topic_type = $posts_unapproved = 0; 1084 $unread_topic = $topic_unapproved = $topic_deleted = false; 1085 1086 if ($show_results == 'topics') 1087 { 1088 if ($config['load_db_track'] && $author_id === $user->data['user_id']) 1089 { 1090 $row['topic_posted'] = 1; 1091 } 1092 1093 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); 1094 1095 $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; 1096 1097 $topic_unapproved = (($row['topic_visibility'] == ITEM_UNAPPROVED || $row['topic_visibility'] == ITEM_REAPPROVE) && $auth->acl_get('m_approve', $forum_id)) ? true : false; 1098 $posts_unapproved = ($row['topic_visibility'] == ITEM_APPROVED && $row['topic_posts_unapproved'] && $auth->acl_get('m_approve', $forum_id)) ? true : false; 1099 $topic_deleted = $row['topic_visibility'] == ITEM_DELETED; 1100 $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) : ''; 1101 $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; 1102 1103 $row['topic_title'] = preg_replace('#(?!<.*)(?<!\w)(' . $hilit . ')(?!\w|[^<>]*(?:</s(?:cript|tyle))?>)#isu', '<span class="posthilit">$1</span>', $row['topic_title']); 1104 1105 $tpl_ary = array( 1106 'TOPIC_AUTHOR' => get_username_string('username', $row['topic_poster'], $row['topic_first_poster_name'], $row['topic_first_poster_colour']), 1107 'TOPIC_AUTHOR_COLOUR' => get_username_string('colour', $row['topic_poster'], $row['topic_first_poster_name'], $row['topic_first_poster_colour']), 1108 'TOPIC_AUTHOR_FULL' => get_username_string('full', $row['topic_poster'], $row['topic_first_poster_name'], $row['topic_first_poster_colour']), 1109 'FIRST_POST_TIME' => $user->format_date($row['topic_time']), 1110 'FIRST_POST_TIME_RFC3339' => gmdate(DATE_RFC3339, $row['topic_time']), 1111 'LAST_POST_SUBJECT' => $row['topic_last_post_subject'], 1112 'LAST_POST_TIME' => $user->format_date($row['topic_last_post_time']), 1113 'LAST_POST_TIME_RFC3339' => gmdate(DATE_RFC3339, $row['topic_last_post_time']), 1114 'LAST_VIEW_TIME' => $user->format_date($row['topic_last_view_time']), 1115 'LAST_VIEW_TIME_RFC3339' => gmdate(DATE_RFC3339, $row['topic_last_view_time']), 1116 'LAST_POST_AUTHOR' => get_username_string('username', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']), 1117 'LAST_POST_AUTHOR_COLOUR' => get_username_string('colour', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']), 1118 'LAST_POST_AUTHOR_FULL' => get_username_string('full', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']), 1119 1120 'TOPIC_TYPE' => $topic_type, 1121 1122 'TOPIC_IMG_STYLE' => $folder_img, 1123 'TOPIC_FOLDER_IMG' => $user->img($folder_img, $folder_alt), 1124 'TOPIC_FOLDER_IMG_ALT' => $user->lang[$folder_alt], 1125 1126 'TOPIC_ICON_IMG' => (!empty($icons[$row['icon_id']])) ? $icons[$row['icon_id']]['img'] : '', 1127 'TOPIC_ICON_IMG_WIDTH' => (!empty($icons[$row['icon_id']])) ? $icons[$row['icon_id']]['width'] : '', 1128 'TOPIC_ICON_IMG_HEIGHT' => (!empty($icons[$row['icon_id']])) ? $icons[$row['icon_id']]['height'] : '', 1129 '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']) : '', 1130 'UNAPPROVED_IMG' => ($topic_unapproved || $posts_unapproved) ? $user->img('icon_topic_unapproved', ($topic_unapproved) ? 'TOPIC_UNAPPROVED' : 'POSTS_UNAPPROVED') : '', 1131 1132 'S_TOPIC_TYPE' => $row['topic_type'], 1133 'S_USER_POSTED' => (!empty($row['topic_posted'])) ? true : false, 1134 'S_UNREAD_TOPIC' => $unread_topic, 1135 1136 'S_TOPIC_REPORTED' => (!empty($row['topic_reported']) && $auth->acl_get('m_report', $forum_id)) ? true : false, 1137 'S_TOPIC_UNAPPROVED' => $topic_unapproved, 1138 'S_POSTS_UNAPPROVED' => $posts_unapproved, 1139 'S_TOPIC_DELETED' => $topic_deleted, 1140 'S_HAS_POLL' => ($row['poll_start']) ? true : false, 1141 1142 'U_LAST_POST' => append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'p=' . $row['topic_last_post_id']) . '#p' . $row['topic_last_post_id'], 1143 'U_LAST_POST_AUTHOR' => get_username_string('profile', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']), 1144 'U_TOPIC_AUTHOR' => get_username_string('profile', $row['topic_poster'], $row['topic_first_poster_name'], $row['topic_first_poster_colour']), 1145 'U_NEWEST_POST' => append_sid("{$phpbb_root_path}viewtopic.$phpEx", $view_topic_url_params . '&view=unread') . '#unread', 1146 'U_MCP_REPORT' => append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=reports&mode=reports&t=' . $result_topic_id, true, $user->session_id), 1147 'U_MCP_QUEUE' => $u_mcp_queue, 1148 ); 1149 } 1150 else 1151 { 1152 if ((isset($zebra['foe']) && in_array($row['poster_id'], $zebra['foe'])) && (!$view || $view != 'show' || $post_id != $row['post_id'])) 1153 { 1154 $template->assign_block_vars('searchresults', array( 1155 'S_IGNORE_POST' => true, 1156 1157 '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>')) 1158 ); 1159 1160 continue; 1161 } 1162 1163 // Replace naughty words such as farty pants 1164 $row['post_subject'] = censor_text($row['post_subject']); 1165 1166 if ($row['display_text_only']) 1167 { 1168 // now find context for the searched words 1169 $row['post_text'] = get_context($row['post_text'], array_filter(explode('|', $hilit), 'strlen'), $return_chars); 1170 $row['post_text'] = bbcode_nl2br($row['post_text']); 1171 } 1172 else 1173 { 1174 $parse_flags = ($row['bbcode_bitfield'] ? OPTION_FLAG_BBCODE : 0) | OPTION_FLAG_SMILIES; 1175 $row['post_text'] = generate_text_for_display($row['post_text'], $row['bbcode_uid'], $row['bbcode_bitfield'], $parse_flags, false); 1176 1177 if (!empty($attachments[$row['post_id']])) 1178 { 1179 parse_attachments($forum_id, $row['post_text'], $attachments[$row['post_id']], $update_count); 1180 1181 // we only display inline attachments 1182 unset($attachments[$row['post_id']]); 1183 } 1184 } 1185 1186 if ($hilit) 1187 { 1188 // post highlighting 1189 $row['post_text'] = preg_replace('#(?!<.*)(?<!\w)(' . $hilit . ')(?!\w|[^<>]*(?:</s(?:cript|tyle))?>)#isu', '<span class="posthilit">$1</span>', $row['post_text']); 1190 $row['post_subject'] = preg_replace('#(?!<.*)(?<!\w)(' . $hilit . ')(?!\w|[^<>]*(?:</s(?:cript|tyle))?>)#isu', '<span class="posthilit">$1</span>', $row['post_subject']); 1191 } 1192 1193 $tpl_ary = array( 1194 'POST_AUTHOR_FULL' => get_username_string('full', $row['poster_id'], $row['username'], $row['user_colour'], $row['post_username']), 1195 'POST_AUTHOR_COLOUR' => get_username_string('colour', $row['poster_id'], $row['username'], $row['user_colour'], $row['post_username']), 1196 'POST_AUTHOR' => get_username_string('username', $row['poster_id'], $row['username'], $row['user_colour'], $row['post_username']), 1197 'U_POST_AUTHOR' => get_username_string('profile', $row['poster_id'], $row['username'], $row['user_colour'], $row['post_username']), 1198 1199 'POST_SUBJECT' => $row['post_subject'], 1200 'POST_DATE' => (!empty($row['post_time'])) ? $user->format_date($row['post_time']) : '', 1201 'MESSAGE' => $row['post_text'] 1202 ); 1203 } 1204 1205 $tpl_ary = array_merge($tpl_ary, array( 1206 'FORUM_ID' => $forum_id, 1207 'TOPIC_ID' => $result_topic_id, 1208 'POST_ID' => ($show_results == 'posts') ? $row['post_id'] : false, 1209 1210 'FORUM_TITLE' => $row['forum_name'], 1211 'TOPIC_TITLE' => $topic_title, 1212 'TOPIC_REPLIES' => $replies, 1213 'TOPIC_VIEWS' => $row['topic_views'], 1214 1215 'U_VIEW_TOPIC' => $view_topic_url, 1216 'U_VIEW_FORUM' => append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $forum_id), 1217 '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'] : '', 1218 )); 1219 1220 /** 1221 * Modify the topic data before it is assigned to the template 1222 * 1223 * @event core.search_modify_tpl_ary 1224 * @var array row Array with topic data 1225 * @var array tpl_ary Template block array with topic data 1226 * @var string show_results Display topics or posts 1227 * @var string topic_title Cleaned topic title 1228 * @var int replies The number of topic replies 1229 * @var string view_topic_url The URL to the topic 1230 * @var string folder_img The folder image of the topic 1231 * @var string folder_alt The alt attribute of the topic folder img 1232 * @var int topic_type The topic type 1233 * @var bool unread_topic Whether the topic has unread posts 1234 * @var bool topic_unapproved Whether the topic is unapproved 1235 * @var int posts_unapproved The number of unapproved posts 1236 * @var bool topic_deleted Whether the topic has been deleted 1237 * @var string u_mcp_queue The URL to the corresponding MCP queue page 1238 * @var array zebra The zebra data of the current user 1239 * @var array attachments All the attachments of the search results 1240 * @since 3.1.0-a1 1241 * @changed 3.1.0-b3 Added vars show_results, topic_title, replies, 1242 * view_topic_url, folder_img, folder_alt, topic_type, unread_topic, 1243 * topic_unapproved, posts_unapproved, topic_deleted, u_mcp_queue, 1244 * zebra, attachments 1245 */ 1246 $vars = array( 1247 'row', 1248 'tpl_ary', 1249 'show_results', 1250 'topic_title', 1251 'replies', 1252 'view_topic_url', 1253 'folder_img', 1254 'folder_alt', 1255 'topic_type', 1256 'unread_topic', 1257 'topic_unapproved', 1258 'posts_unapproved', 1259 'topic_deleted', 1260 'u_mcp_queue', 1261 'zebra', 1262 'attachments', 1263 ); 1264 extract($phpbb_dispatcher->trigger_event('core.search_modify_tpl_ary', compact($vars))); 1265 1266 $template->assign_block_vars('searchresults', $tpl_ary); 1267 1268 if ($show_results == 'topics') 1269 { 1270 $pagination->generate_template_pagination($view_topic_url, 'searchresults.pagination', 'start', $replies + 1, $config['posts_per_page'], 1, true, true); 1271 } 1272 } 1273 1274 if ($topic_id && ($topic_id == $result_topic_id)) 1275 { 1276 $template->assign_vars(array( 1277 'SEARCH_TOPIC' => $topic_title, 1278 'L_RETURN_TO_TOPIC' => $user->lang('RETURN_TO', $topic_title), 1279 'U_SEARCH_TOPIC' => $view_topic_url 1280 )); 1281 } 1282 } 1283 unset($rowset); 1284 1285 // Output header 1286 if ($found_more_search_matches) 1287 { 1288 $l_search_matches = $user->lang('FOUND_MORE_SEARCH_MATCHES', (int) $total_match_count); 1289 } 1290 else 1291 { 1292 $l_search_matches = $user->lang('FOUND_SEARCH_MATCHES', (int) $total_match_count); 1293 } 1294 1295 // Check if search backend supports phrase search or not 1296 $phrase_search_disabled = ''; 1297 if (strpos(html_entity_decode($keywords), '"') !== false && method_exists($search, 'supports_phrase_search')) 1298 { 1299 $phrase_search_disabled = $search->supports_phrase_search() ? false : true; 1300 } 1301 1302 $pagination->generate_template_pagination($u_search, 'pagination', 'start', $total_match_count, $per_page, $start); 1303 1304 $template->assign_vars(array( 1305 'SEARCH_TITLE' => $l_search_title, 1306 'SEARCH_MATCHES' => $l_search_matches, 1307 'SEARCH_WORDS' => $keywords, 1308 'SEARCHED_QUERY' => $search->get_search_query(), 1309 'IGNORED_WORDS' => (!empty($common_words)) ? implode(' ', $common_words) : '', 1310 1311 'PHRASE_SEARCH_DISABLED' => $phrase_search_disabled, 1312 1313 'TOTAL_MATCHES' => $total_match_count, 1314 'SEARCH_IN_RESULTS' => ($search_id) ? false : true, 1315 1316 'S_SELECT_SORT_DIR' => $s_sort_dir, 1317 'S_SELECT_SORT_KEY' => $s_sort_key, 1318 'S_SELECT_SORT_DAYS' => $s_limit_days, 1319 'S_SEARCH_ACTION' => $u_search, 1320 'S_SHOW_TOPICS' => ($show_results == 'posts') ? false : true, 1321 1322 'GOTO_PAGE_IMG' => $user->img('icon_post_target', 'GOTO_PAGE'), 1323 'NEWEST_POST_IMG' => $user->img('icon_topic_newest', 'VIEW_NEWEST_POST'), 1324 'REPORTED_IMG' => $user->img('icon_topic_reported', 'TOPIC_REPORTED'), 1325 'UNAPPROVED_IMG' => $user->img('icon_topic_unapproved', 'TOPIC_UNAPPROVED'), 1326 'DELETED_IMG' => $user->img('icon_topic_deleted', 'TOPIC_DELETED'), 1327 'POLL_IMG' => $user->img('icon_topic_poll', 'TOPIC_POLL'), 1328 'LAST_POST_IMG' => $user->img('icon_topic_latest', 'VIEW_LATEST_POST'), 1329 1330 'U_SEARCH_WORDS' => $u_search, 1331 )); 1332 1333 /** 1334 * Modify the title and/or load data for the search results page 1335 * 1336 * @event core.search_results_modify_search_title 1337 * @var int author_id ID of the author to search by 1338 * @var string l_search_title The title of the search page 1339 * @var string search_id Predefined search type name 1340 * @var string show_results Search results output mode - topics or posts 1341 * @var int start The starting id of the results 1342 * @var int total_match_count The count of search results 1343 * @var string keywords The search keywords 1344 * @since 3.1.0-RC4 1345 * @changed 3.1.6-RC1 Added total_match_count and keywords 1346 */ 1347 $vars = array( 1348 'author_id', 1349 'l_search_title', 1350 'search_id', 1351 'show_results', 1352 'start', 1353 'total_match_count', 1354 'keywords', 1355 ); 1356 extract($phpbb_dispatcher->trigger_event('core.search_results_modify_search_title', compact($vars))); 1357 1358 page_header(($l_search_title) ? $l_search_title : $user->lang['SEARCH']); 1359 1360 $template->set_filenames(array( 1361 'body' => 'search_results.html') 1362 ); 1363 make_jumpbox(append_sid("{$phpbb_root_path}viewforum.$phpEx")); 1364 1365 page_footer(); 1366 } 1367 1368 // Search forum 1369 $rowset = array(); 1370 $s_forums = ''; 1371 $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 1372 FROM ' . FORUMS_TABLE . ' f 1373 LEFT JOIN ' . FORUMS_ACCESS_TABLE . " fa ON (fa.forum_id = f.forum_id 1374 AND fa.session_id = '" . $db->sql_escape($user->session_id) . "') 1375 ORDER BY f.left_id ASC"; 1376 $result = $db->sql_query($sql); 1377 1378 while ($row = $db->sql_fetchrow($result)) 1379 { 1380 $rowset[(int) $row['forum_id']] = $row; 1381 } 1382 $db->sql_freeresult($result); 1383 1384 $right = $cat_right = $padding_inc = 0; 1385 $padding = $forum_list = $holding = ''; 1386 $pad_store = array('0' => ''); 1387 1388 /** 1389 * Modify the forum select list for advanced search page 1390 * 1391 * @event core.search_modify_forum_select_list 1392 * @var array rowset Array with the forums list data 1393 * @since 3.1.10-RC1 1394 */ 1395 $vars = array('rowset'); 1396 extract($phpbb_dispatcher->trigger_event('core.search_modify_forum_select_list', compact($vars))); 1397 1398 foreach ($rowset as $row) 1399 { 1400 if ($row['forum_type'] == FORUM_CAT && ($row['left_id'] + 1 == $row['right_id'])) 1401 { 1402 // Non-postable forum with no subforums, don't display 1403 continue; 1404 } 1405 1406 if ($row['forum_type'] == FORUM_POST && ($row['left_id'] + 1 == $row['right_id']) && !$row['enable_indexing']) 1407 { 1408 // Postable forum with no subforums and indexing disabled, don't display 1409 continue; 1410 } 1411 1412 if ($row['forum_type'] == FORUM_LINK || ($row['forum_password'] && !$row['user_id'])) 1413 { 1414 // if this forum is a link or password protected (user has not entered the password yet) then skip to the next branch 1415 continue; 1416 } 1417 1418 if ($row['left_id'] < $right) 1419 { 1420 $padding .= ' '; 1421 $pad_store[$row['parent_id']] = $padding; 1422 } 1423 else if ($row['left_id'] > $right + 1) 1424 { 1425 if (isset($pad_store[$row['parent_id']])) 1426 { 1427 $padding = $pad_store[$row['parent_id']]; 1428 } 1429 else 1430 { 1431 continue; 1432 } 1433 } 1434 1435 $right = $row['right_id']; 1436 1437 if ($auth->acl_gets('!f_search', '!f_list', $row['forum_id'])) 1438 { 1439 // if the user does not have permissions to search or see this forum skip only this forum/category 1440 continue; 1441 } 1442 1443 $selected = (in_array($row['forum_id'], $search_forum)) ? ' selected="selected"' : ''; 1444 1445 if ($row['left_id'] > $cat_right) 1446 { 1447 // make sure we don't forget anything 1448 $s_forums .= $holding; 1449 $holding = ''; 1450 } 1451 1452 if ($row['right_id'] - $row['left_id'] > 1) 1453 { 1454 $cat_right = max($cat_right, $row['right_id']); 1455 1456 $holding .= '<option value="' . $row['forum_id'] . '"' . $selected . '>' . $padding . $row['forum_name'] . '</option>'; 1457 } 1458 else 1459 { 1460 $s_forums .= $holding . '<option value="' . $row['forum_id'] . '"' . $selected . '>' . $padding . $row['forum_name'] . '</option>'; 1461 $holding = ''; 1462 } 1463 } 1464 1465 if ($holding) 1466 { 1467 $s_forums .= $holding; 1468 } 1469 1470 unset($pad_store); 1471 unset($rowset); 1472 1473 if (!$s_forums) 1474 { 1475 trigger_error('NO_SEARCH'); 1476 } 1477 1478 /** 1479 * Build options for a select list for the number of characters returned. 1480 * 1481 * If the admin defined amount is not within the predefined range, 1482 * and the admin did not set it to unlimited (0), we add that option aswell. 1483 * 1484 * @deprecated 3.3.1-RC1 Templates should use an numeric input, in favor of a select. 1485 */ 1486 $s_characters = '<option value="0">' . $language->lang('ALL_AVAILABLE') . '</option>'; 1487 $i_characters = array_merge([25, 50], range(100, 1000, 100)); 1488 1489 if ($config['default_search_return_chars'] && !in_array((int) $config['default_search_return_chars'], $i_characters)) 1490 { 1491 $i_characters[] = (int) $config['default_search_return_chars']; 1492 sort($i_characters); 1493 } 1494 1495 foreach ($i_characters as $i) 1496 { 1497 $selected = $i === (int) $config['default_search_return_chars'] ? ' selected="selected"' : ''; 1498 $s_characters .= sprintf('<option value="%1$s"%2$s>%1$s</option>', $i, $selected); 1499 } 1500 1501 $s_hidden_fields = array('t' => $topic_id); 1502 1503 if ($_SID) 1504 { 1505 $s_hidden_fields['sid'] = $_SID; 1506 } 1507 1508 if (!empty($_EXTRA_URL)) 1509 { 1510 foreach ($_EXTRA_URL as $url_param) 1511 { 1512 $url_param = explode('=', $url_param, 2); 1513 $s_hidden_fields[$url_param[0]] = $url_param[1]; 1514 } 1515 } 1516 1517 $template->assign_vars(array( 1518 'DEFAULT_RETURN_CHARS' => (int) $config['default_search_return_chars'], 1519 'S_SEARCH_ACTION' => append_sid("{$phpbb_root_path}search.$phpEx", false, true, 0), // We force no ?sid= appending by using 0 1520 'S_HIDDEN_FIELDS' => build_hidden_fields($s_hidden_fields), 1521 'S_CHARACTER_OPTIONS' => $s_characters, 1522 'S_FORUM_OPTIONS' => $s_forums, 1523 'S_SELECT_SORT_DIR' => $s_sort_dir, 1524 'S_SELECT_SORT_KEY' => $s_sort_key, 1525 'S_SELECT_SORT_DAYS' => $s_limit_days, 1526 'S_IN_SEARCH' => true, 1527 )); 1528 1529 // only show recent searches to search administrators 1530 if ($auth->acl_get('a_search')) 1531 { 1532 // Handle large objects differently for Oracle and MSSQL 1533 switch ($db->get_sql_layer()) 1534 { 1535 case 'oracle': 1536 $sql = 'SELECT search_time, search_keywords 1537 FROM ' . SEARCH_RESULTS_TABLE . ' 1538 WHERE dbms_lob.getlength(search_keywords) > 0 1539 ORDER BY search_time DESC'; 1540 break; 1541 1542 case 'mssql_odbc': 1543 case 'mssqlnative': 1544 $sql = 'SELECT search_time, search_keywords 1545 FROM ' . SEARCH_RESULTS_TABLE . ' 1546 WHERE DATALENGTH(search_keywords) > 0 1547 ORDER BY search_time DESC'; 1548 break; 1549 1550 default: 1551 $sql = 'SELECT search_time, search_keywords 1552 FROM ' . SEARCH_RESULTS_TABLE . ' 1553 WHERE search_keywords <> \'\' 1554 ORDER BY search_time DESC'; 1555 break; 1556 } 1557 $result = $db->sql_query_limit($sql, 5); 1558 1559 while ($row = $db->sql_fetchrow($result)) 1560 { 1561 $keywords = $row['search_keywords']; 1562 1563 $template->assign_block_vars('recentsearch', array( 1564 'KEYWORDS' => $keywords, 1565 'TIME' => $user->format_date($row['search_time']), 1566 1567 'U_KEYWORDS' => append_sid("{$phpbb_root_path}search.$phpEx", 'keywords=' . urlencode(html_entity_decode($keywords, ENT_COMPAT))) 1568 )); 1569 } 1570 $db->sql_freeresult($result); 1571 } 1572 1573 // Output the basic page 1574 page_header($user->lang['SEARCH']); 1575 1576 $template->set_filenames(array( 1577 'body' => 'search_body.html') 1578 ); 1579 make_jumpbox(append_sid("{$phpbb_root_path}viewforum.$phpEx")); 1580 1581 page_footer();
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sat Nov 4 14:26:03 2023 | Cross-referenced by PHPXref 0.7.1 |