[ Index ]

PHP Cross Reference of phpBB 2.0.23

title

Body

[close]

/ -> search.php (source)

   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[