[ Index ]

PHP Cross Reference of phpBB-3.1.10-deutsch

title

Body

[close]

/ -> search.php (source)

   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') . '&amp;mark=forums&amp;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('+', '-', '|', '(', ')', '&quot;'), ' ', $keywords));
 666      $hilit = str_replace(' ', '|', $hilit);
 667  
 668      $u_hilit = urlencode(htmlspecialchars_decode(str_replace('|', ' ', $hilit)));
 669      $u_show_results = '&amp;sr=' . $show_results;
 670      $u_search_forum = implode('&amp;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) ? '&amp;search_id=' . $search_id : '';
 674      $u_search .= ($u_hilit) ? '&amp;keywords=' . urlencode(htmlspecialchars_decode($keywords)) : '';
 675      $u_search .= ($search_terms != 'all') ? '&amp;terms=' . $search_terms : '';
 676      $u_search .= ($topic_id) ? '&amp;t=' . $topic_id : '';
 677      $u_search .= ($author) ? '&amp;author=' . urlencode(htmlspecialchars_decode($author)) : '';
 678      $u_search .= ($author_id) ? '&amp;author_id=' . $author_id : '';
 679      $u_search .= ($u_search_forum) ? '&amp;fid%5B%5D=' . $u_search_forum : '';
 680      $u_search .= (!$search_child) ? '&amp;sc=0' : '';
 681      $u_search .= ($search_fields != 'all') ? '&amp;sf=' . $search_fields : '';
 682      $u_search .= ($return_chars != 300) ? '&amp;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      * @since 3.1.7-RC1
 694      * @changed 3.1.10-RC1 Added show_results, sql_where, total_match_count
 695      */
 696      $vars = array(
 697          'u_search',
 698          'search_id',
 699          'show_results',
 700          'sql_where',
 701          'total_match_count',
 702      );
 703      extract($phpbb_dispatcher->trigger_event('core.search_modify_url_parameters', compact($vars)));
 704  
 705      if ($sql_where)
 706      {
 707          if ($show_results == 'posts')
 708          {
 709              // @todo Joining this query to the one below?
 710              $sql = 'SELECT zebra_id, friend, foe
 711                  FROM ' . ZEBRA_TABLE . '
 712                  WHERE user_id = ' . $user->data['user_id'];
 713              $result = $db->sql_query($sql);
 714  
 715              $zebra = array();
 716              while ($row = $db->sql_fetchrow($result))
 717              {
 718                  $zebra[($row['friend']) ? 'friend' : 'foe'][] = $row['zebra_id'];
 719              }
 720              $db->sql_freeresult($result);
 721  
 722              $sql_array = array(
 723                  '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',
 724                  'FROM'        => array(
 725                      POSTS_TABLE        => 'p',
 726                  ),
 727                  'LEFT_JOIN' => array(
 728                      array(
 729                          'FROM'    => array(TOPICS_TABLE => 't'),
 730                          'ON'    => 'p.topic_id = t.topic_id',
 731                      ),
 732                      array(
 733                          'FROM'    => array(FORUMS_TABLE => 'f'),
 734                          'ON'    => 'p.forum_id = f.forum_id',
 735                      ),
 736                      array(
 737                          'FROM'    => array(USERS_TABLE => 'u'),
 738                          'ON'    => 'p.poster_id = u.user_id',
 739                      ),
 740                  ),
 741                  'WHERE'    => $sql_where,
 742                  'ORDER_BY' => $sort_by_sql[$sort_key] . ' ' . (($sort_dir == 'd') ? 'DESC' : 'ASC'),
 743              );
 744  
 745              /**
 746              * Event to modify the SQL query before the posts data is retrieved
 747              *
 748              * @event core.search_get_posts_data
 749              * @var    array    sql_array        The SQL array
 750              * @var    array    zebra            Array of zebra data for the current user
 751              * @var    int        total_match_count    The total number of search matches
 752              * @var    string    keywords        String of the specified keywords
 753              * @var    array    sort_by_sql        Array of SQL sorting instructions
 754              * @var    string    s_sort_dir        The sort direction
 755              * @var    string    s_sort_key        The sort key
 756              * @var    string    s_limit_days    Limit the age of results
 757              * @var    array    ex_fid_ary        Array of excluded forum ids
 758              * @var    array    author_id_ary    Array of exclusive author ids
 759              * @var    string    search_fields    The data fields to search in
 760              * @var    int        search_id        The id of the search request
 761              * @var    int        start            The starting id of the results
 762              * @since 3.1.0-b3
 763              */
 764              $vars = array(
 765                  'sql_array',
 766                  'zebra',
 767                  'total_match_count',
 768                  'keywords',
 769                  'sort_by_sql',
 770                  's_sort_dir',
 771                  's_sort_key',
 772                  's_limit_days',
 773                  'ex_fid_ary',
 774                  'author_id_ary',
 775                  'search_fields',
 776                  'search_id',
 777                  'start',
 778              );
 779              extract($phpbb_dispatcher->trigger_event('core.search_get_posts_data', compact($vars)));
 780  
 781              $sql = $db->sql_build_query('SELECT', $sql_array);
 782          }
 783          else
 784          {
 785              $sql_from = TOPICS_TABLE . ' t
 786                  LEFT JOIN ' . FORUMS_TABLE . ' f ON (f.forum_id = t.forum_id)
 787                  ' . (($sort_key == 'a') ? ' LEFT JOIN ' . USERS_TABLE . ' u ON (u.user_id = t.topic_poster) ' : '');
 788              $sql_select = 't.*, f.forum_id, f.forum_name';
 789  
 790              if ($user->data['is_registered'])
 791              {
 792                  if ($config['load_db_track'] && $author_id !== $user->data['user_id'])
 793                  {
 794                      $sql_from .= ' LEFT JOIN ' . TOPICS_POSTED_TABLE . ' tp ON (tp.user_id = ' . $user->data['user_id'] . '
 795                          AND t.topic_id = tp.topic_id)';
 796                      $sql_select .= ', tp.topic_posted';
 797                  }
 798  
 799                  if ($config['load_db_lastread'])
 800                  {
 801                      $sql_from .= ' LEFT JOIN ' . TOPICS_TRACK_TABLE . ' tt ON (tt.user_id = ' . $user->data['user_id'] . '
 802                              AND t.topic_id = tt.topic_id)
 803                          LEFT JOIN ' . FORUMS_TRACK_TABLE . ' ft ON (ft.user_id = ' . $user->data['user_id'] . '
 804                              AND ft.forum_id = f.forum_id)';
 805                      $sql_select .= ', tt.mark_time, ft.mark_time as f_mark_time';
 806                  }
 807              }
 808  
 809              if ($config['load_anon_lastread'] || ($user->data['is_registered'] && !$config['load_db_lastread']))
 810              {
 811                  $tracking_topics = $request->variable($config['cookie_name'] . '_track', '', true, \phpbb\request\request_interface::COOKIE);
 812                  $tracking_topics = ($tracking_topics) ? tracking_unserialize($tracking_topics) : array();
 813              }
 814  
 815              $sql_order_by = $sort_by_sql[$sort_key] . ' ' . (($sort_dir == 'd') ? 'DESC' : 'ASC');
 816  
 817              /**
 818              * Event to modify the SQL query before the topic data is retrieved
 819              *
 820              * @event core.search_get_topic_data
 821              * @var    string    sql_select        The SQL SELECT string used by search to get topic data
 822              * @var    string    sql_from        The SQL FROM string used by search to get topic data
 823              * @var    string    sql_where        The SQL WHERE string used by search to get topic data
 824              * @var    int        total_match_count    The total number of search matches
 825              * @var    array    sort_by_sql        Array of SQL sorting instructions
 826              * @var    string    sort_dir        The sorting direction
 827              * @var    string    sort_key        The sorting key
 828              * @var    string    sql_order_by    The SQL ORDER BY string used by search to get topic data
 829              * @since 3.1.0-a1
 830              * @changed 3.1.0-RC5 Added total_match_count
 831              * @changed 3.1.7-RC1 Added sort_by_sql, sort_dir, sort_key, sql_order_by
 832              */
 833              $vars = array(
 834                  'sql_select',
 835                  'sql_from',
 836                  'sql_where',
 837                  'total_match_count',
 838                  'sort_by_sql',
 839                  'sort_dir',
 840                  'sort_key',
 841                  'sql_order_by',
 842              );
 843              extract($phpbb_dispatcher->trigger_event('core.search_get_topic_data', compact($vars)));
 844  
 845              $sql = "SELECT $sql_select
 846                  FROM $sql_from
 847                  WHERE $sql_where
 848                  ORDER BY $sql_order_by";
 849          }
 850          $result = $db->sql_query($sql);
 851          $result_topic_id = 0;
 852  
 853          $rowset = array();
 854  
 855          if ($show_results == 'topics')
 856          {
 857              $forums = $rowset = $shadow_topic_list = array();
 858              while ($row = $db->sql_fetchrow($result))
 859              {
 860                  $row['forum_id'] = (int) $row['forum_id'];
 861                  $row['topic_id'] = (int) $row['topic_id'];
 862  
 863                  if ($row['topic_status'] == ITEM_MOVED)
 864                  {
 865                      $shadow_topic_list[$row['topic_moved_id']] = $row['topic_id'];
 866                  }
 867  
 868                  $rowset[$row['topic_id']] = $row;
 869  
 870                  if (!isset($forums[$row['forum_id']]) && $user->data['is_registered'] && $config['load_db_lastread'])
 871                  {
 872                      $forums[$row['forum_id']]['mark_time'] = $row['f_mark_time'];
 873                  }
 874                  $forums[$row['forum_id']]['topic_list'][] = $row['topic_id'];
 875                  $forums[$row['forum_id']]['rowset'][$row['topic_id']] = &$rowset[$row['topic_id']];
 876              }
 877              $db->sql_freeresult($result);
 878  
 879              // If we have some shadow topics, update the rowset to reflect their topic information
 880              if (sizeof($shadow_topic_list))
 881              {
 882                  $sql = 'SELECT *
 883                      FROM ' . TOPICS_TABLE . '
 884                      WHERE ' . $db->sql_in_set('topic_id', array_keys($shadow_topic_list));
 885                  $result = $db->sql_query($sql);
 886  
 887                  while ($row = $db->sql_fetchrow($result))
 888                  {
 889                      $orig_topic_id = $shadow_topic_list[$row['topic_id']];
 890  
 891                      // We want to retain some values
 892                      $row = array_merge($row, array(
 893                          'topic_moved_id'    => $rowset[$orig_topic_id]['topic_moved_id'],
 894                          'topic_status'        => $rowset[$orig_topic_id]['topic_status'],
 895                          'forum_name'        => $rowset[$orig_topic_id]['forum_name'])
 896                      );
 897  
 898                      $rowset[$orig_topic_id] = $row;
 899                  }
 900                  $db->sql_freeresult($result);
 901              }
 902              unset($shadow_topic_list);
 903  
 904              foreach ($forums as $forum_id => $forum)
 905              {
 906                  if ($user->data['is_registered'] && $config['load_db_lastread'])
 907                  {
 908                      $topic_tracking_info[$forum_id] = get_topic_tracking($forum_id, $forum['topic_list'], $forum['rowset'], array($forum_id => $forum['mark_time']));
 909                  }
 910                  else if ($config['load_anon_lastread'] || $user->data['is_registered'])
 911                  {
 912                      $topic_tracking_info[$forum_id] = get_complete_topic_tracking($forum_id, $forum['topic_list']);
 913  
 914                      if (!$user->data['is_registered'])
 915                      {
 916                          $user->data['user_lastmark'] = (isset($tracking_topics['l'])) ? (int) (base_convert($tracking_topics['l'], 36, 10) + $config['board_startdate']) : 0;
 917                      }
 918                  }
 919              }
 920              unset($forums);
 921          }
 922          else
 923          {
 924              $text_only_message = '';
 925              $attach_list = array();
 926  
 927              while ($row = $db->sql_fetchrow($result))
 928              {
 929                  // We pre-process some variables here for later usage
 930                  $row['post_text'] = censor_text($row['post_text']);
 931  
 932                  $text_only_message = $row['post_text'];
 933                  // make list items visible as such
 934                  if ($row['bbcode_uid'])
 935                  {
 936                      $text_only_message = str_replace('[*:' . $row['bbcode_uid'] . ']', '&sdot;&nbsp;', $text_only_message);
 937                      // no BBCode in text only message
 938                      strip_bbcode($text_only_message, $row['bbcode_uid']);
 939                  }
 940  
 941                  if ($return_chars == -1 || utf8_strlen($text_only_message) < ($return_chars + 3))
 942                  {
 943                      $row['display_text_only'] = false;
 944  
 945                      // Does this post have an attachment? If so, add it to the list
 946                      if ($row['post_attachment'] && $config['allow_attachments'])
 947                      {
 948                          $attach_list[$row['forum_id']][] = $row['post_id'];
 949                      }
 950                  }
 951                  else
 952                  {
 953                      $row['post_text'] = $text_only_message;
 954                      $row['display_text_only'] = true;
 955                  }
 956  
 957                  $rowset[] = $row;
 958              }
 959              $db->sql_freeresult($result);
 960  
 961              unset($text_only_message);
 962  
 963              // Pull attachment data
 964              if (sizeof($attach_list))
 965              {
 966                  $use_attach_list = $attach_list;
 967                  $attach_list = array();
 968  
 969                  foreach ($use_attach_list as $forum_id => $_list)
 970                  {
 971                      if ($auth->acl_get('u_download') && $auth->acl_get('f_download', $forum_id))
 972                      {
 973                          $attach_list = array_merge($attach_list, $_list);
 974                      }
 975                  }
 976              }
 977  
 978              if (sizeof($attach_list))
 979              {
 980                  $sql = 'SELECT *
 981                      FROM ' . ATTACHMENTS_TABLE . '
 982                      WHERE ' . $db->sql_in_set('post_msg_id', $attach_list) . '
 983                          AND in_message = 0
 984                      ORDER BY filetime DESC, post_msg_id ASC';
 985                  $result = $db->sql_query($sql);
 986  
 987                  while ($row = $db->sql_fetchrow($result))
 988                  {
 989                      $attachments[$row['post_msg_id']][] = $row;
 990                  }
 991                  $db->sql_freeresult($result);
 992              }
 993          }
 994  
 995          if ($hilit)
 996          {
 997              // Remove bad highlights
 998              $hilit_array = array_filter(explode('|', $hilit), 'strlen');
 999              foreach ($hilit_array as $key => $value)
1000              {
1001                  $hilit_array[$key] = phpbb_clean_search_string($value);
1002                  $hilit_array[$key] = str_replace('\*', '\w*?', preg_quote($hilit_array[$key], '#'));
1003                  $hilit_array[$key] = preg_replace('#(^|\s)\\\\w\*\?(\s|$)#', '$1\w+?$2', $hilit_array[$key]);
1004              }
1005              $hilit = implode('|', $hilit_array);
1006          }
1007  
1008          /**
1009          * Modify the rowset data
1010          *
1011          * @event core.search_modify_rowset
1012          * @var    array    attachments                Array with posts attachments data
1013          * @var    string    hilit                    String to highlight
1014          * @var    array    rowset                    Array with the search results data
1015          * @var    string    show_results            String indicating the show results mode
1016          * @var    array    topic_tracking_info        Array with the topics tracking data
1017          * @var    string    u_hilit                    Highlight string to be injected into URL
1018          * @var    string    view                    Search results view mode
1019          * @var    array    zebra                    Array with zebra data for the current user
1020          * @since 3.1.0-b4
1021          * @changed 3.1.0-b5 Added var show_results
1022          */
1023          $vars = array(
1024              'attachments',
1025              'hilit',
1026              'rowset',
1027              'show_results',
1028              'topic_tracking_info',
1029              'u_hilit',
1030              'view',
1031              'zebra',
1032          );
1033          extract($phpbb_dispatcher->trigger_event('core.search_modify_rowset', compact($vars)));
1034  
1035          foreach ($rowset as $row)
1036          {
1037              $forum_id = $row['forum_id'];
1038              $result_topic_id = $row['topic_id'];
1039              $topic_title = censor_text($row['topic_title']);
1040              $replies = $phpbb_content_visibility->get_count('topic_posts', $row, $forum_id) - 1;
1041  
1042              $view_topic_url_params = "f=$forum_id&amp;t=$result_topic_id" . (($u_hilit) ? "&amp;hilit=$u_hilit" : '');
1043              $view_topic_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", $view_topic_url_params);
1044  
1045              if ($show_results == 'topics')
1046              {
1047                  if ($config['load_db_track'] && $author_id === $user->data['user_id'])
1048                  {
1049                      $row['topic_posted'] = 1;
1050                  }
1051  
1052                  $folder_img = $folder_alt = $topic_type = '';
1053                  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);
1054  
1055                  $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;
1056  
1057                  $topic_unapproved = (($row['topic_visibility'] == ITEM_UNAPPROVED || $row['topic_visibility'] == ITEM_REAPPROVE) && $auth->acl_get('m_approve', $forum_id)) ? true : false;
1058                  $posts_unapproved = ($row['topic_visibility'] == ITEM_APPROVED && $row['topic_posts_unapproved'] && $auth->acl_get('m_approve', $forum_id)) ? true : false;
1059                  $topic_deleted = $row['topic_visibility'] == ITEM_DELETED;
1060                  $u_mcp_queue = ($topic_unapproved || $posts_unapproved) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=queue&amp;mode=' . (($topic_unapproved) ? 'approve_details' : 'unapproved_posts') . "&amp;t=$result_topic_id", true, $user->session_id) : '';
1061                  $u_mcp_queue = (!$u_mcp_queue && $topic_deleted) ? append_sid("{$phpbb_root_path}mcp.$phpEx", "i=queue&amp;mode=deleted_topics&amp;t=$result_topic_id", true, $user->session_id) : $u_mcp_queue;
1062  
1063                  $row['topic_title'] = preg_replace('#(?!<.*)(?<!\w)(' . $hilit . ')(?!\w|[^<>]*(?:</s(?:cript|tyle))?>)#is', '<span class="posthilit">$1</span>', $row['topic_title']);
1064  
1065                  $tpl_ary = array(
1066                      'TOPIC_AUTHOR'                => get_username_string('username', $row['topic_poster'], $row['topic_first_poster_name'], $row['topic_first_poster_colour']),
1067                      'TOPIC_AUTHOR_COLOUR'        => get_username_string('colour', $row['topic_poster'], $row['topic_first_poster_name'], $row['topic_first_poster_colour']),
1068                      'TOPIC_AUTHOR_FULL'            => get_username_string('full', $row['topic_poster'], $row['topic_first_poster_name'], $row['topic_first_poster_colour']),
1069                      'FIRST_POST_TIME'            => $user->format_date($row['topic_time']),
1070                      'LAST_POST_SUBJECT'            => $row['topic_last_post_subject'],
1071                      'LAST_POST_TIME'            => $user->format_date($row['topic_last_post_time']),
1072                      'LAST_VIEW_TIME'            => $user->format_date($row['topic_last_view_time']),
1073                      'LAST_POST_AUTHOR'            => get_username_string('username', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']),
1074                      'LAST_POST_AUTHOR_COLOUR'    => get_username_string('colour', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']),
1075                      'LAST_POST_AUTHOR_FULL'        => get_username_string('full', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']),
1076  
1077                      'TOPIC_TYPE'        => $topic_type,
1078  
1079                      'TOPIC_IMG_STYLE'        => $folder_img,
1080                      'TOPIC_FOLDER_IMG'        => $user->img($folder_img, $folder_alt),
1081                      'TOPIC_FOLDER_IMG_ALT'    => $user->lang[$folder_alt],
1082  
1083                      'TOPIC_ICON_IMG'        => (!empty($icons[$row['icon_id']])) ? $icons[$row['icon_id']]['img'] : '',
1084                      'TOPIC_ICON_IMG_WIDTH'    => (!empty($icons[$row['icon_id']])) ? $icons[$row['icon_id']]['width'] : '',
1085                      'TOPIC_ICON_IMG_HEIGHT'    => (!empty($icons[$row['icon_id']])) ? $icons[$row['icon_id']]['height'] : '',
1086                      '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']) : '',
1087                      'UNAPPROVED_IMG'        => ($topic_unapproved || $posts_unapproved) ? $user->img('icon_topic_unapproved', ($topic_unapproved) ? 'TOPIC_UNAPPROVED' : 'POSTS_UNAPPROVED') : '',
1088  
1089                      'S_TOPIC_TYPE'            => $row['topic_type'],
1090                      'S_USER_POSTED'            => (!empty($row['topic_posted'])) ? true : false,
1091                      'S_UNREAD_TOPIC'        => $unread_topic,
1092  
1093                      'S_TOPIC_REPORTED'        => (!empty($row['topic_reported']) && $auth->acl_get('m_report', $forum_id)) ? true : false,
1094                      'S_TOPIC_UNAPPROVED'    => $topic_unapproved,
1095                      'S_POSTS_UNAPPROVED'    => $posts_unapproved,
1096                      'S_TOPIC_DELETED'        => $topic_deleted,
1097                      'S_HAS_POLL'            => ($row['poll_start']) ? true : false,
1098  
1099                      'U_LAST_POST'            => append_sid("{$phpbb_root_path}viewtopic.$phpEx", $view_topic_url_params . '&amp;p=' . $row['topic_last_post_id']) . '#p' . $row['topic_last_post_id'],
1100                      'U_LAST_POST_AUTHOR'    => get_username_string('profile', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']),
1101                      'U_TOPIC_AUTHOR'        => get_username_string('profile', $row['topic_poster'], $row['topic_first_poster_name'], $row['topic_first_poster_colour']),
1102                      'U_NEWEST_POST'            => append_sid("{$phpbb_root_path}viewtopic.$phpEx", $view_topic_url_params . '&amp;view=unread') . '#unread',
1103                      'U_MCP_REPORT'            => append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=reports&amp;mode=reports&amp;t=' . $result_topic_id, true, $user->session_id),
1104                      'U_MCP_QUEUE'            => $u_mcp_queue,
1105                  );
1106              }
1107              else
1108              {
1109                  if ((isset($zebra['foe']) && in_array($row['poster_id'], $zebra['foe'])) && (!$view || $view != 'show' || $post_id != $row['post_id']))
1110                  {
1111                      $template->assign_block_vars('searchresults', array(
1112                          'S_IGNORE_POST' => true,
1113  
1114                          'L_IGNORE_POST' => sprintf($user->lang['POST_BY_FOE'], $row['username'], "<a href=\"$u_search&amp;start=$start&amp;p=" . $row['post_id'] . '&amp;view=show#p' . $row['post_id'] . '">', '</a>'))
1115                      );
1116  
1117                      continue;
1118                  }
1119  
1120                  // Replace naughty words such as farty pants
1121                  $row['post_subject'] = censor_text($row['post_subject']);
1122  
1123                  if ($row['display_text_only'])
1124                  {
1125                      // now find context for the searched words
1126                      $row['post_text'] = get_context($row['post_text'], array_filter(explode('|', $hilit), 'strlen'), $return_chars);
1127                      $row['post_text'] = bbcode_nl2br($row['post_text']);
1128                  }
1129                  else
1130                  {
1131                      $parse_flags = ($row['bbcode_bitfield'] ? OPTION_FLAG_BBCODE : 0) | OPTION_FLAG_SMILIES;
1132                      $row['post_text'] = generate_text_for_display($row['post_text'], $row['bbcode_uid'], $row['bbcode_bitfield'], $parse_flags, false);
1133  
1134                      if (!empty($attachments[$row['post_id']]))
1135                      {
1136                          parse_attachments($forum_id, $row['post_text'], $attachments[$row['post_id']], $update_count);
1137  
1138                          // we only display inline attachments
1139                          unset($attachments[$row['post_id']]);
1140                      }
1141                  }
1142  
1143                  if ($hilit)
1144                  {
1145                      // post highlighting
1146                      $row['post_text'] = preg_replace('#(?!<.*)(?<!\w)(' . $hilit . ')(?!\w|[^<>]*(?:</s(?:cript|tyle))?>)#is', '<span class="posthilit">$1</span>', $row['post_text']);
1147                      $row['post_subject'] = preg_replace('#(?!<.*)(?<!\w)(' . $hilit . ')(?!\w|[^<>]*(?:</s(?:cript|tyle))?>)#is', '<span class="posthilit">$1</span>', $row['post_subject']);
1148                  }
1149  
1150                  $tpl_ary = array(
1151                      'POST_AUTHOR_FULL'        => get_username_string('full', $row['poster_id'], $row['username'], $row['user_colour'], $row['post_username']),
1152                      'POST_AUTHOR_COLOUR'    => get_username_string('colour', $row['poster_id'], $row['username'], $row['user_colour'], $row['post_username']),
1153                      'POST_AUTHOR'            => get_username_string('username', $row['poster_id'], $row['username'], $row['user_colour'], $row['post_username']),
1154                      'U_POST_AUTHOR'            => get_username_string('profile', $row['poster_id'], $row['username'], $row['user_colour'], $row['post_username']),
1155  
1156                      'POST_SUBJECT'        => $row['post_subject'],
1157                      'POST_DATE'            => (!empty($row['post_time'])) ? $user->format_date($row['post_time']) : '',
1158                      'MESSAGE'            => $row['post_text']
1159                  );
1160              }
1161  
1162              $tpl_ary = array_merge($tpl_ary, array(
1163                  'FORUM_ID'            => $forum_id,
1164                  'TOPIC_ID'            => $result_topic_id,
1165                  'POST_ID'            => ($show_results == 'posts') ? $row['post_id'] : false,
1166  
1167                  'FORUM_TITLE'        => $row['forum_name'],
1168                  'TOPIC_TITLE'        => $topic_title,
1169                  'TOPIC_REPLIES'        => $replies,
1170                  'TOPIC_VIEWS'        => $row['topic_views'],
1171  
1172                  'U_VIEW_TOPIC'        => $view_topic_url,
1173                  'U_VIEW_FORUM'        => append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $forum_id),
1174                  'U_VIEW_POST'        => (!empty($row['post_id'])) ? append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&amp;t=" . $row['topic_id'] . '&amp;p=' . $row['post_id'] . (($u_hilit) ? '&amp;hilit=' . $u_hilit : '')) . '#p' . $row['post_id'] : '',
1175              ));
1176  
1177              /**
1178              * Modify the topic data before it is assigned to the template
1179              *
1180              * @event core.search_modify_tpl_ary
1181              * @var    array    row                Array with topic data
1182              * @var    array    tpl_ary            Template block array with topic data
1183              * @var    string    show_results    Display topics or posts
1184              * @var    string    topic_title        Cleaned topic title
1185              * @var    int        replies            The number of topic replies
1186              * @var    string    view_topic_url    The URL to the topic
1187              * @var    string    folder_img        The folder image of the topic
1188              * @var    string    folder_alt        The alt attribute of the topic folder img
1189              * @var    int        topic_type        The topic type
1190              * @var    bool    unread_topic    Whether the topic has unread posts
1191              * @var    bool    topic_unapproved    Whether the topic is unapproved
1192              * @var    int        posts_unapproved    The number of unapproved posts
1193              * @var    bool    topic_deleted    Whether the topic has been deleted
1194              * @var    string    u_mcp_queue        The URL to the corresponding MCP queue page
1195              * @var    array    zebra            The zebra data of the current user
1196              * @var    array    attachments        All the attachments of the search results
1197              * @since 3.1.0-a1
1198              * @changed 3.1.0-b3 Added vars show_results, topic_title, replies,
1199              *        view_topic_url, folder_img, folder_alt, topic_type, unread_topic,
1200              *        topic_unapproved, posts_unapproved, topic_deleted, u_mcp_queue,
1201              *        zebra, attachments
1202              */
1203              $vars = array(
1204                  'row',
1205                  'tpl_ary',
1206                  'show_results',
1207                  'topic_title',
1208                  'replies',
1209                  'view_topic_url',
1210                  'folder_img',
1211                  'folder_alt',
1212                  'topic_type',
1213                  'unread_topic',
1214                  'topic_unapproved',
1215                  'posts_unapproved',
1216                  'topic_deleted',
1217                  'u_mcp_queue',
1218                  'zebra',
1219                  'attachments',
1220              );
1221              extract($phpbb_dispatcher->trigger_event('core.search_modify_tpl_ary', compact($vars)));
1222  
1223              $template->assign_block_vars('searchresults', $tpl_ary);
1224  
1225              if ($show_results == 'topics')
1226              {
1227                  $pagination->generate_template_pagination($view_topic_url, 'searchresults.pagination', 'start', $replies + 1, $config['posts_per_page'], 1, true, true);
1228              }
1229          }
1230  
1231          if ($topic_id && ($topic_id == $result_topic_id))
1232          {
1233              $template->assign_vars(array(
1234                  'SEARCH_TOPIC'        => $topic_title,
1235                  'L_RETURN_TO_TOPIC'    => $user->lang('RETURN_TO', $topic_title),
1236                  'U_SEARCH_TOPIC'    => $view_topic_url
1237              ));
1238          }
1239      }
1240      unset($rowset);
1241  
1242      // Output header
1243      if ($found_more_search_matches)
1244      {
1245          $l_search_matches = $user->lang('FOUND_MORE_SEARCH_MATCHES', (int) $total_match_count);
1246      }
1247      else
1248      {
1249          $l_search_matches = $user->lang('FOUND_SEARCH_MATCHES', (int) $total_match_count);
1250      }
1251  
1252      // Check if search backend supports phrase search or not
1253      $phrase_search_disabled = '';
1254      if (strpos(html_entity_decode($keywords), '"') !== false && method_exists($search, 'supports_phrase_search'))
1255      {
1256          $phrase_search_disabled = $search->supports_phrase_search() ? false : true;
1257      }
1258  
1259      $pagination->generate_template_pagination($u_search, 'pagination', 'start', $total_match_count, $per_page, $start);
1260  
1261      $template->assign_vars(array(
1262          'SEARCH_TITLE'        => $l_search_title,
1263          'SEARCH_MATCHES'    => $l_search_matches,
1264          'SEARCH_WORDS'        => $keywords,
1265          'SEARCHED_QUERY'    => $search->get_search_query(),
1266          'IGNORED_WORDS'        => (!empty($common_words)) ? implode(' ', $common_words) : '',
1267  
1268          'PHRASE_SEARCH_DISABLED'        => $phrase_search_disabled,
1269  
1270          'TOTAL_MATCHES'        => $total_match_count,
1271          'SEARCH_IN_RESULTS'    => ($search_id) ? false : true,
1272  
1273          'S_SELECT_SORT_DIR'        => $s_sort_dir,
1274          'S_SELECT_SORT_KEY'        => $s_sort_key,
1275          'S_SELECT_SORT_DAYS'    => $s_limit_days,
1276          'S_SEARCH_ACTION'        => $u_search,
1277          'S_SHOW_TOPICS'            => ($show_results == 'posts') ? false : true,
1278  
1279          'GOTO_PAGE_IMG'        => $user->img('icon_post_target', 'GOTO_PAGE'),
1280          'NEWEST_POST_IMG'    => $user->img('icon_topic_newest', 'VIEW_NEWEST_POST'),
1281          'REPORTED_IMG'        => $user->img('icon_topic_reported', 'TOPIC_REPORTED'),
1282          'UNAPPROVED_IMG'    => $user->img('icon_topic_unapproved', 'TOPIC_UNAPPROVED'),
1283          'DELETED_IMG'        => $user->img('icon_topic_deleted', 'TOPIC_DELETED'),
1284          'POLL_IMG'            => $user->img('icon_topic_poll', 'TOPIC_POLL'),
1285          'LAST_POST_IMG'        => $user->img('icon_topic_latest', 'VIEW_LATEST_POST'),
1286  
1287          'U_SEARCH_WORDS'    => $u_search,
1288      ));
1289  
1290      /**
1291      * Modify the title and/or load data for the search results page
1292      *
1293      * @event core.search_results_modify_search_title
1294      * @var    int        author_id            ID of the author to search by
1295      * @var    string    l_search_title        The title of the search page
1296      * @var    string    search_id            Predefined search type name
1297      * @var    string    show_results        Search results output mode - topics or posts
1298      * @var    int        start                The starting id of the results
1299      * @var    int        total_match_count    The count of search results
1300      * @var    string    keywords            The search keywords
1301      * @since 3.1.0-RC4
1302      * @changed 3.1.6-RC1 Added total_match_count and keywords
1303      */
1304      $vars = array(
1305          'author_id',
1306          'l_search_title',
1307          'search_id',
1308          'show_results',
1309          'start',
1310          'total_match_count',
1311          'keywords',
1312      );
1313      extract($phpbb_dispatcher->trigger_event('core.search_results_modify_search_title', compact($vars)));
1314  
1315      page_header(($l_search_title) ? $l_search_title : $user->lang['SEARCH']);
1316  
1317      $template->set_filenames(array(
1318          'body' => 'search_results.html')
1319      );
1320      make_jumpbox(append_sid("{$phpbb_root_path}viewforum.$phpEx"));
1321  
1322      page_footer();
1323  }
1324  
1325  // Search forum
1326  $rowset = array();
1327  $s_forums = '';
1328  $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
1329      FROM ' . FORUMS_TABLE . ' f
1330      LEFT JOIN ' . FORUMS_ACCESS_TABLE . " fa ON (fa.forum_id = f.forum_id
1331          AND fa.session_id = '" . $db->sql_escape($user->session_id) . "')
1332      ORDER BY f.left_id ASC";
1333  $result = $db->sql_query($sql);
1334  
1335  while ($row = $db->sql_fetchrow($result))
1336  {
1337      $rowset[(int) $row['forum_id']] = $row;
1338  }
1339  $db->sql_freeresult($result);
1340  
1341  $right = $cat_right = $padding_inc = 0;
1342  $padding = $forum_list = $holding = '';
1343  $pad_store = array('0' => '');
1344  
1345  /**
1346  * Modify the forum select list for advanced search page
1347  *
1348  * @event core.search_modify_forum_select_list
1349  * @var    array    rowset    Array with the forums list data
1350  * @since 3.1.10-RC1
1351  */
1352  $vars = array('rowset');
1353  extract($phpbb_dispatcher->trigger_event('core.search_modify_forum_select_list', compact($vars)));
1354  
1355  foreach ($rowset as $row)
1356  {
1357      if ($row['forum_type'] == FORUM_CAT && ($row['left_id'] + 1 == $row['right_id']))
1358      {
1359          // Non-postable forum with no subforums, don't display
1360          continue;
1361      }
1362  
1363      if ($row['forum_type'] == FORUM_POST && ($row['left_id'] + 1 == $row['right_id']) && !$row['enable_indexing'])
1364      {
1365          // Postable forum with no subforums and indexing disabled, don't display
1366          continue;
1367      }
1368  
1369      if ($row['forum_type'] == FORUM_LINK || ($row['forum_password'] && !$row['user_id']))
1370      {
1371          // if this forum is a link or password protected (user has not entered the password yet) then skip to the next branch
1372          continue;
1373      }
1374  
1375      if ($row['left_id'] < $right)
1376      {
1377          $padding .= '&nbsp; &nbsp;';
1378          $pad_store[$row['parent_id']] = $padding;
1379      }
1380      else if ($row['left_id'] > $right + 1)
1381      {
1382          if (isset($pad_store[$row['parent_id']]))
1383          {
1384              $padding = $pad_store[$row['parent_id']];
1385          }
1386          else
1387          {
1388              continue;
1389          }
1390      }
1391  
1392      $right = $row['right_id'];
1393  
1394      if ($auth->acl_gets('!f_search', '!f_list', $row['forum_id']))
1395      {
1396          // if the user does not have permissions to search or see this forum skip only this forum/category
1397          continue;
1398      }
1399  
1400      $selected = (in_array($row['forum_id'], $search_forum)) ? ' selected="selected"' : '';
1401  
1402      if ($row['left_id'] > $cat_right)
1403      {
1404          // make sure we don't forget anything
1405          $s_forums .= $holding;
1406          $holding = '';
1407      }
1408  
1409      if ($row['right_id'] - $row['left_id'] > 1)
1410      {
1411          $cat_right = max($cat_right, $row['right_id']);
1412  
1413          $holding .= '<option value="' . $row['forum_id'] . '"' . $selected . '>' . $padding . $row['forum_name'] . '</option>';
1414      }
1415      else
1416      {
1417          $s_forums .= $holding . '<option value="' . $row['forum_id'] . '"' . $selected . '>' . $padding . $row['forum_name'] . '</option>';
1418          $holding = '';
1419      }
1420  }
1421  
1422  if ($holding)
1423  {
1424      $s_forums .= $holding;
1425  }
1426  
1427  unset($pad_store);
1428  unset($rowset);
1429  
1430  if (!$s_forums)
1431  {
1432      trigger_error('NO_SEARCH');
1433  }
1434  
1435  // Number of chars returned
1436  $s_characters = '<option value="-1">' . $user->lang['ALL_AVAILABLE'] . '</option>';
1437  $s_characters .= '<option value="0">0</option>';
1438  $s_characters .= '<option value="25">25</option>';
1439  $s_characters .= '<option value="50">50</option>';
1440  
1441  for ($i = 100; $i <= 1000; $i += 100)
1442  {
1443      $selected = ($i == 300) ? ' selected="selected"' : '';
1444      $s_characters .= '<option value="' . $i . '"' . $selected . '>' . $i . '</option>';
1445  }
1446  
1447  $s_hidden_fields = array('t' => $topic_id);
1448  
1449  if ($_SID)
1450  {
1451      $s_hidden_fields['sid'] = $_SID;
1452  }
1453  
1454  if (!empty($_EXTRA_URL))
1455  {
1456      foreach ($_EXTRA_URL as $url_param)
1457      {
1458          $url_param = explode('=', $url_param, 2);
1459          $s_hidden_fields[$url_param[0]] = $url_param[1];
1460      }
1461  }
1462  
1463  $template->assign_vars(array(
1464      'S_SEARCH_ACTION'        => append_sid("{$phpbb_root_path}search.$phpEx", false, true, 0), // We force no ?sid= appending by using 0
1465      'S_HIDDEN_FIELDS'        => build_hidden_fields($s_hidden_fields),
1466      'S_CHARACTER_OPTIONS'    => $s_characters,
1467      'S_FORUM_OPTIONS'        => $s_forums,
1468      'S_SELECT_SORT_DIR'        => $s_sort_dir,
1469      'S_SELECT_SORT_KEY'        => $s_sort_key,
1470      'S_SELECT_SORT_DAYS'    => $s_limit_days,
1471      'S_IN_SEARCH'            => true,
1472  ));
1473  
1474  // only show recent searches to search administrators
1475  if ($auth->acl_get('a_search'))
1476  {
1477      // Handle large objects differently for Oracle and MSSQL
1478      switch ($db->get_sql_layer())
1479      {
1480          case 'oracle':
1481              $sql = 'SELECT search_time, search_keywords
1482                  FROM ' . SEARCH_RESULTS_TABLE . '
1483                  WHERE dbms_lob.getlength(search_keywords) > 0
1484                  ORDER BY search_time DESC';
1485          break;
1486  
1487          case 'mssql':
1488          case 'mssql_odbc':
1489          case 'mssqlnative':
1490              $sql = 'SELECT search_time, search_keywords
1491                  FROM ' . SEARCH_RESULTS_TABLE . '
1492                  WHERE DATALENGTH(search_keywords) > 0
1493                  ORDER BY search_time DESC';
1494          break;
1495  
1496          default:
1497              $sql = 'SELECT search_time, search_keywords
1498                  FROM ' . SEARCH_RESULTS_TABLE . '
1499                  WHERE search_keywords <> \'\'
1500                  ORDER BY search_time DESC';
1501          break;
1502      }
1503      $result = $db->sql_query_limit($sql, 5);
1504  
1505      while ($row = $db->sql_fetchrow($result))
1506      {
1507          $keywords = $row['search_keywords'];
1508  
1509          $template->assign_block_vars('recentsearch', array(
1510              'KEYWORDS'    => $keywords,
1511              'TIME'        => $user->format_date($row['search_time']),
1512  
1513              'U_KEYWORDS'    => append_sid("{$phpbb_root_path}search.$phpEx", 'keywords=' . urlencode(htmlspecialchars_decode($keywords)))
1514          ));
1515      }
1516      $db->sql_freeresult($result);
1517  }
1518  
1519  // Output the basic page
1520  page_header($user->lang['SEARCH']);
1521  
1522  $template->set_filenames(array(
1523      'body' => 'search_body.html')
1524  );
1525  make_jumpbox(append_sid("{$phpbb_root_path}viewforum.$phpEx"));
1526  
1527  page_footer();


Generated: Sun Feb 19 19:52:41 2017 Cross-referenced by PHPXref 0.7.1