| [ Index ] |
PHP Cross Reference of phpBB 2.0.23 |
[Summary view] [Print] [Text view]
1 <?php 2 /*************************************************************************** 3 * search.php 4 * ------------------- 5 * begin : Saturday, Feb 13, 2001 6 * copyright : (C) 2001 The phpBB Group 7 * email : support@phpbb.com 8 * 9 * $Id: search.php 6772 2006-12-16 13:11:28Z acydburn $ 10 * 11 * 12 ***************************************************************************/ 13 14 /*************************************************************************** 15 * 16 * This program is free software; you can redistribute it and/or modify 17 * it under the terms of the GNU General Public License as published by 18 * the Free Software Foundation; either version 2 of the License, or 19 * (at your option) any later version. 20 * 21 ***************************************************************************/ 22 23 define('IN_PHPBB', true); 24 $phpbb_root_path = './'; 25 include ($phpbb_root_path . 'extension.inc'); 26 include($phpbb_root_path . 'common.'.$phpEx); 27 include($phpbb_root_path . 'includes/bbcode.'.$phpEx); 28 include($phpbb_root_path . 'includes/functions_search.'.$phpEx); 29 30 // 31 // Start session management 32 // 33 $userdata = session_pagestart($user_ip, PAGE_SEARCH); 34 init_userprefs($userdata); 35 // 36 // End session management 37 // 38 39 // 40 // Define initial vars 41 // 42 if ( isset($HTTP_POST_VARS['mode']) || isset($HTTP_GET_VARS['mode']) ) 43 { 44 $mode = ( isset($HTTP_POST_VARS['mode']) ) ? $HTTP_POST_VARS['mode'] : $HTTP_GET_VARS['mode']; 45 } 46 else 47 { 48 $mode = ''; 49 } 50 51 if ( isset($HTTP_POST_VARS['search_keywords']) || isset($HTTP_GET_VARS['search_keywords']) ) 52 { 53 $search_keywords = ( isset($HTTP_POST_VARS['search_keywords']) ) ? $HTTP_POST_VARS['search_keywords'] : $HTTP_GET_VARS['search_keywords']; 54 } 55 else 56 { 57 $search_keywords = ''; 58 } 59 60 if ( isset($HTTP_POST_VARS['search_author']) || isset($HTTP_GET_VARS['search_author'])) 61 { 62 $search_author = ( isset($HTTP_POST_VARS['search_author']) ) ? $HTTP_POST_VARS['search_author'] : $HTTP_GET_VARS['search_author']; 63 $search_author = phpbb_clean_username($search_author); 64 } 65 else 66 { 67 $search_author = ''; 68 } 69 70 $search_id = ( isset($HTTP_GET_VARS['search_id']) ) ? $HTTP_GET_VARS['search_id'] : ''; 71 72 $show_results = ( isset($HTTP_POST_VARS['show_results']) ) ? $HTTP_POST_VARS['show_results'] : 'posts'; 73 $show_results = ($show_results == 'topics') ? 'topics' : 'posts'; 74 75 if ( isset($HTTP_POST_VARS['search_terms']) ) 76 { 77 $search_terms = ( $HTTP_POST_VARS['search_terms'] == 'all' ) ? 1 : 0; 78 } 79 else 80 { 81 $search_terms = 0; 82 } 83 84 if ( isset($HTTP_POST_VARS['search_fields']) ) 85 { 86 $search_fields = ( $HTTP_POST_VARS['search_fields'] == 'all' ) ? 1 : 0; 87 } 88 else 89 { 90 $search_fields = 0; 91 } 92 93 $return_chars = ( isset($HTTP_POST_VARS['return_chars']) ) ? intval($HTTP_POST_VARS['return_chars']) : 200; 94 95 $search_cat = ( isset($HTTP_POST_VARS['search_cat']) ) ? intval($HTTP_POST_VARS['search_cat']) : -1; 96 $search_forum = ( isset($HTTP_POST_VARS['search_forum']) ) ? intval($HTTP_POST_VARS['search_forum']) : -1; 97 98 $sort_by = ( isset($HTTP_POST_VARS['sort_by']) ) ? intval($HTTP_POST_VARS['sort_by']) : 0; 99 100 if ( isset($HTTP_POST_VARS['sort_dir']) ) 101 { 102 $sort_dir = ( $HTTP_POST_VARS['sort_dir'] == 'DESC' ) ? 'DESC' : 'ASC'; 103 } 104 else 105 { 106 $sort_dir = 'DESC'; 107 } 108 109 if ( !empty($HTTP_POST_VARS['search_time']) || !empty($HTTP_GET_VARS['search_time'])) 110 { 111 $search_time = time() - ( ( ( !empty($HTTP_POST_VARS['search_time']) ) ? intval($HTTP_POST_VARS['search_time']) : intval($HTTP_GET_VARS['search_time']) ) * 86400 ); 112 $topic_days = (!empty($HTTP_POST_VARS['search_time'])) ? intval($HTTP_POST_VARS['search_time']) : intval($HTTP_GET_VARS['search_time']); 113 } 114 else 115 { 116 $search_time = 0; 117 $topic_days = 0; 118 } 119 120 $start = ( isset($HTTP_GET_VARS['start']) ) ? intval($HTTP_GET_VARS['start']) : 0; 121 $start = ($start < 0) ? 0 : $start; 122 123 $sort_by_types = array($lang['Sort_Time'], $lang['Sort_Post_Subject'], $lang['Sort_Topic_Title'], $lang['Sort_Author'], $lang['Sort_Forum']); 124 125 // 126 // encoding match for workaround 127 // 128 $multibyte_charset = 'utf-8, big5, shift_jis, euc-kr, gb2312'; 129 130 // 131 // Begin core code 132 // 133 if ( $mode == 'searchuser' ) 134 { 135 // 136 // This handles the simple windowed user search functions called from various other scripts 137 // 138 if ( isset($HTTP_POST_VARS['search_username']) ) 139 { 140 username_search($HTTP_POST_VARS['search_username']); 141 } 142 else 143 { 144 username_search(''); 145 } 146 147 exit; 148 } 149 else if ( $search_keywords != '' || $search_author != '' || $search_id ) 150 { 151 $store_vars = array('search_results', 'total_match_count', 'split_search', 'sort_by', 'sort_dir', 'show_results', 'return_chars'); 152 $search_results = ''; 153 154 // 155 // Search ID Limiter, decrease this value if you experience further timeout problems with searching forums 156 $limiter = 5000; 157 $current_time = time(); 158 159 // 160 // Cycle through options ... 161 // 162 if ( $search_id == 'newposts' || $search_id == 'egosearch' || $search_id == 'unanswered' || $search_keywords != '' || $search_author != '' ) 163 { 164 // 165 // Flood control 166 // 167 $where_sql = ($userdata['user_id'] == ANONYMOUS) ? "se.session_ip = '$user_ip'" : 'se.session_user_id = ' . $userdata['user_id']; 168 $sql = 'SELECT MAX(sr.search_time) AS last_search_time 169 FROM ' . SEARCH_TABLE . ' sr, ' . SESSIONS_TABLE . " se 170 WHERE sr.session_id = se.session_id 171 AND $where_sql"; 172 if ($result = $db->sql_query($sql)) 173 { 174 if ($row = $db->sql_fetchrow($result)) 175 { 176 if (intval($row['last_search_time']) > 0 && ($current_time - intval($row['last_search_time'])) < intval($board_config['search_flood_interval'])) 177 { 178 message_die(GENERAL_MESSAGE, $lang['Search_Flood_Error']); 179 } 180 } 181 } 182 if ( $search_id == 'newposts' || $search_id == 'egosearch' || ( $search_author != '' && $search_keywords == '' ) ) 183 { 184 if ( $search_id == 'newposts' ) 185 { 186 if ( $userdata['session_logged_in'] ) 187 { 188 $sql = "SELECT post_id 189 FROM " . POSTS_TABLE . " 190 WHERE post_time >= " . $userdata['user_lastvisit']; 191 } 192 else 193 { 194 redirect(append_sid("login.$phpEx?redirect=search.$phpEx&search_id=newposts", true)); 195 } 196 197 $show_results = 'topics'; 198 $sort_by = 0; 199 $sort_dir = 'DESC'; 200 } 201 else if ( $search_id == 'egosearch' ) 202 { 203 if ( $userdata['session_logged_in'] ) 204 { 205 $sql = "SELECT post_id 206 FROM " . POSTS_TABLE . " 207 WHERE poster_id = " . $userdata['user_id']; 208 } 209 else 210 { 211 redirect(append_sid("login.$phpEx?redirect=search.$phpEx&search_id=egosearch", true)); 212 } 213 214 $show_results = 'topics'; 215 $sort_by = 0; 216 $sort_dir = 'DESC'; 217 } 218 else 219 { 220 $search_author = str_replace('*', '%', trim($search_author)); 221 222 if( ( strpos($search_author, '%') !== false ) && ( strlen(str_replace('%', '', $search_author)) < $board_config['search_min_chars'] ) ) 223 { 224 $search_author = ''; 225 } 226 227 $sql = "SELECT user_id 228 FROM " . USERS_TABLE . " 229 WHERE username LIKE '" . str_replace("\'", "''", $search_author) . "'"; 230 if ( !($result = $db->sql_query($sql)) ) 231 { 232 message_die(GENERAL_ERROR, "Couldn't obtain list of matching users (searching for: $search_author)", "", __LINE__, __FILE__, $sql); 233 } 234 235 $matching_userids = ''; 236 if ( $row = $db->sql_fetchrow($result) ) 237 { 238 do 239 { 240 $matching_userids .= ( ( $matching_userids != '' ) ? ', ' : '' ) . $row['user_id']; 241 } 242 while( $row = $db->sql_fetchrow($result) ); 243 } 244 else 245 { 246 message_die(GENERAL_MESSAGE, $lang['No_search_match']); 247 } 248 249 $sql = "SELECT post_id 250 FROM " . POSTS_TABLE . " 251 WHERE poster_id IN ($matching_userids)"; 252 253 if ($search_time) 254 { 255 $sql .= " AND post_time >= " . $search_time; 256 } 257 } 258 259 if ( !($result = $db->sql_query($sql)) ) 260 { 261 message_die(GENERAL_ERROR, 'Could not obtain matched posts list', '', __LINE__, __FILE__, $sql); 262 } 263 264 $search_ids = array(); 265 while( $row = $db->sql_fetchrow($result) ) 266 { 267 $search_ids[] = $row['post_id']; 268 } 269 $db->sql_freeresult($result); 270 271 $total_match_count = count($search_ids); 272 273 } 274 else if ( $search_keywords != '' ) 275 { 276 $stopword_array = @file($phpbb_root_path . 'language/lang_' . $board_config['default_lang'] . '/search_stopwords.txt'); 277 $synonym_array = @file($phpbb_root_path . 'language/lang_' . $board_config['default_lang'] . '/search_synonyms.txt'); 278 279 $split_search = array(); 280 $stripped_keywords = stripslashes($search_keywords); 281 $split_search = ( !strstr($multibyte_charset, $lang['ENCODING']) ) ? split_words(clean_words('search', $stripped_keywords, $stopword_array, $synonym_array), 'search') : split(' ', $search_keywords); 282 unset($stripped_keywords); 283 284 $search_msg_only = ( !$search_fields ) ? "AND m.title_match = 0" : ( ( strstr($multibyte_charset, $lang['ENCODING']) ) ? '' : '' ); 285 286 $word_count = 0; 287 $current_match_type = 'or'; 288 289 $word_match = array(); 290 $result_list = array(); 291 292 for($i = 0; $i < count($split_search); $i++) 293 { 294 if ( strlen(str_replace(array('*', '%'), '', trim($split_search[$i]))) < $board_config['search_min_chars'] ) 295 { 296 $split_search[$i] = ''; 297 continue; 298 } 299 300 switch ( $split_search[$i] ) 301 { 302 case 'and': 303 $current_match_type = 'and'; 304 break; 305 306 case 'or': 307 $current_match_type = 'or'; 308 break; 309 310 case 'not': 311 $current_match_type = 'not'; 312 break; 313 314 default: 315 if ( !empty($search_terms) ) 316 { 317 $current_match_type = 'and'; 318 } 319 320 if ( !strstr($multibyte_charset, $lang['ENCODING']) ) 321 { 322 $match_word = str_replace('*', '%', $split_search[$i]); 323 $sql = "SELECT m.post_id 324 FROM " . SEARCH_WORD_TABLE . " w, " . SEARCH_MATCH_TABLE . " m 325 WHERE w.word_text LIKE '$match_word' 326 AND m.word_id = w.word_id 327 AND w.word_common <> 1 328 $search_msg_only"; 329 } 330 else 331 { 332 $match_word = addslashes('%' . str_replace('*', '', $split_search[$i]) . '%'); 333 $search_msg_only = ( $search_fields ) ? "OR post_subject LIKE '$match_word'" : ''; 334 $sql = "SELECT post_id 335 FROM " . POSTS_TEXT_TABLE . " 336 WHERE post_text LIKE '$match_word' 337 $search_msg_only"; 338 } 339 if ( !($result = $db->sql_query($sql)) ) 340 { 341 message_die(GENERAL_ERROR, 'Could not obtain matched posts list', '', __LINE__, __FILE__, $sql); 342 } 343 344 $row = array(); 345 while( $temp_row = $db->sql_fetchrow($result) ) 346 { 347 $row[$temp_row['post_id']] = 1; 348 349 if ( !$word_count ) 350 { 351 $result_list[$temp_row['post_id']] = 1; 352 } 353 else if ( $current_match_type == 'or' ) 354 { 355 $result_list[$temp_row['post_id']] = 1; 356 } 357 else if ( $current_match_type == 'not' ) 358 { 359 $result_list[$temp_row['post_id']] = 0; 360 } 361 } 362 363 if ( $current_match_type == 'and' && $word_count ) 364 { 365 @reset($result_list); 366 while( list($post_id, $match_count) = @each($result_list) ) 367 { 368 if ( !$row[$post_id] ) 369 { 370 $result_list[$post_id] = 0; 371 } 372 } 373 } 374 375 $word_count++; 376 377 $db->sql_freeresult($result); 378 } 379 } 380 381 @reset($result_list); 382 383 $search_ids = array(); 384 while( list($post_id, $matches) = each($result_list) ) 385 { 386 if ( $matches ) 387 { 388 $search_ids[] = $post_id; 389 } 390 } 391 392 unset($result_list); 393 $total_match_count = count($search_ids); 394 } 395 396 // 397 // If user is logged in then we'll check to see which (if any) private 398 // forums they are allowed to view and include them in the search. 399 // 400 // If not logged in we explicitly prevent searching of private forums 401 // 402 $auth_sql = ''; 403 if ( $search_forum != -1 ) 404 { 405 $is_auth = auth(AUTH_READ, $search_forum, $userdata); 406 407 if ( !$is_auth['auth_read'] ) 408 { 409 message_die(GENERAL_MESSAGE, $lang['No_searchable_forums']); 410 } 411 412 $auth_sql = "f.forum_id = $search_forum"; 413 } 414 else 415 { 416 $is_auth_ary = auth(AUTH_READ, AUTH_LIST_ALL, $userdata); 417 418 if ( $search_cat != -1 ) 419 { 420 $auth_sql = "f.cat_id = $search_cat"; 421 } 422 423 $ignore_forum_sql = ''; 424 while( list($key, $value) = each($is_auth_ary) ) 425 { 426 if ( !$value['auth_read'] ) 427 { 428 $ignore_forum_sql .= ( ( $ignore_forum_sql != '' ) ? ', ' : '' ) . $key; 429 } 430 } 431 432 if ( $ignore_forum_sql != '' ) 433 { 434 $auth_sql .= ( $auth_sql != '' ) ? " AND f.forum_id NOT IN ($ignore_forum_sql) " : "f.forum_id NOT IN ($ignore_forum_sql) "; 435 } 436 } 437 438 // 439 // Author name search 440 // 441 if ( $search_author != '' ) 442 { 443 $search_author = str_replace('*', '%', trim($search_author)); 444 445 if( ( strpos($search_author, '%') !== false ) && ( strlen(str_replace('%', '', $search_author)) < $board_config['search_min_chars'] ) ) 446 { 447 $search_author = ''; 448 } 449 } 450 451 if ( $total_match_count ) 452 { 453 if ( $show_results == 'topics' ) 454 { 455 // 456 // This one is a beast, try to seperate it a bit (workaround for connection timeouts) 457 // 458 $search_id_chunks = array(); 459 $count = 0; 460 $chunk = 0; 461 462 if (count($search_ids) > $limiter) 463 { 464 for ($i = 0; $i < count($search_ids); $i++) 465 { 466 if ($count == $limiter) 467 { 468 $chunk++; 469 $count = 0; 470 } 471 472 $search_id_chunks[$chunk][$count] = $search_ids[$i]; 473 $count++; 474 } 475 } 476 else 477 { 478 $search_id_chunks[0] = $search_ids; 479 } 480 481 $search_ids = array(); 482 483 for ($i = 0; $i < count($search_id_chunks); $i++) 484 { 485 $where_sql = ''; 486 487 if ( $search_time ) 488 { 489 $where_sql .= ( $search_author == '' && $auth_sql == '' ) ? " AND post_time >= $search_time " : " AND p.post_time >= $search_time "; 490 } 491 492 if ( $search_author == '' && $auth_sql == '' ) 493 { 494 $sql = "SELECT topic_id 495 FROM " . POSTS_TABLE . " 496 WHERE post_id IN (" . implode(", ", $search_id_chunks[$i]) . ") 497 $where_sql 498 GROUP BY topic_id"; 499 } 500 else 501 { 502 $from_sql = POSTS_TABLE . " p"; 503 504 if ( $search_author != '' ) 505 { 506 $from_sql .= ", " . USERS_TABLE . " u"; 507 $where_sql .= " AND u.user_id = p.poster_id AND u.username LIKE '$search_author' "; 508 } 509 510 if ( $auth_sql != '' ) 511 { 512 $from_sql .= ", " . FORUMS_TABLE . " f"; 513 $where_sql .= " AND f.forum_id = p.forum_id AND $auth_sql"; 514 } 515 516 $sql = "SELECT p.topic_id 517 FROM $from_sql 518 WHERE p.post_id IN (" . implode(", ", $search_id_chunks[$i]) . ") 519 $where_sql 520 GROUP BY p.topic_id"; 521 } 522 523 if ( !($result = $db->sql_query($sql)) ) 524 { 525 message_die(GENERAL_ERROR, 'Could not obtain topic ids', '', __LINE__, __FILE__, $sql); 526 } 527 528 while ($row = $db->sql_fetchrow($result)) 529 { 530 $search_ids[] = $row['topic_id']; 531 } 532 $db->sql_freeresult($result); 533 } 534 535 $total_match_count = sizeof($search_ids); 536 537 } 538 else if ( $search_author != '' || $search_time || $auth_sql != '' ) 539 { 540 $search_id_chunks = array(); 541 $count = 0; 542 $chunk = 0; 543 544 if (count($search_ids) > $limiter) 545 { 546 for ($i = 0; $i < count($search_ids); $i++) 547 { 548 if ($count == $limiter) 549 { 550 $chunk++; 551 $count = 0; 552 } 553 554 $search_id_chunks[$chunk][$count] = $search_ids[