[ Index ]

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


Generated: Sun Feb 19 19:47:08 2017 Cross-referenced by PHPXref 0.7.1