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