Verzeichnisstruktur phpBB-3.3.15


Veröffentlicht
28.08.2024

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

(Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

search.php

Zuletzt modifiziert: 02.04.2025, 15:01 - Dateigröße: 56.79 KiB


0001  <?php
0002  /**
0003  *
0004  * This file is part of the phpBB Forum Software package.
0005  *
0006  * @copyright (c) phpBB Limited <https://www.phpbb.com>
0007  * @license GNU General Public License, version 2 (GPL-2.0)
0008  *
0009  * For full copyright and license information, please see
0010  * the docs/CREDITS.txt file.
0011  *
0012  */
0013   
0014  /**
0015  * @ignore
0016  */
0017  define('IN_PHPBB', true);
0018  $phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './';
0019  $phpEx = substr(strrchr(__FILE__, '.'), 1);
0020  include($phpbb_root_path . 'common.' . $phpEx);
0021   
0022  // Start session management
0023  $user->session_begin();
0024  $auth->acl($user->data);
0025  $user->setup('search');
0026   
0027  // Define initial vars
0028  $mode            = $request->variable('mode', '');
0029  $search_id        = $request->variable('search_id', '');
0030  $start            = max($request->variable('start', 0), 0);
0031  $post_id        = $request->variable('p', 0);
0032  $topic_id        = $request->variable('t', 0);
0033  $view            = $request->variable('view', '');
0034   
0035  $submit            = $request->variable('submit', false);
0036  $keywords        = $request->variable('keywords', '', true);
0037  $add_keywords    = $request->variable('add_keywords', '', true);
0038  $author            = $request->variable('author', '', true);
0039  $author_id        = $request->variable('author_id', 0);
0040  $show_results    = ($topic_id) ? 'posts' : $request->variable('sr', 'posts');
0041  $show_results    = ($show_results == 'posts') ? 'posts' : 'topics';
0042  $search_terms    = $request->variable('terms', 'all');
0043  $search_fields    = $request->variable('sf', 'all');
0044  $search_child    = $request->variable('sc', true);
0045   
0046  $sort_days        = $request->variable('st', 0);
0047  $sort_key        = $request->variable('sk', 't');
0048  $sort_dir        = $request->variable('sd', 'd');
0049   
0050  $return_chars    = $request->variable('ch', $topic_id ? 0 : (int) $config['default_search_return_chars']);
0051  $search_forum    = $request->variable('fid', array(0));
0052   
0053  // We put login boxes for the case if search_id is newposts, egosearch or unreadposts
0054  // because a guest should be able to log in even if guests search is not permitted
0055   
0056  switch ($search_id)
0057  {
0058      // Egosearch is an author search
0059      case 'egosearch':
0060          $author_id = $user->data['user_id'];
0061          if ($user->data['user_id'] == ANONYMOUS)
0062          {
0063              login_box('', $user->lang['LOGIN_EXPLAIN_EGOSEARCH']);
0064          }
0065      break;
0066   
0067      // Search for unread posts needs to be allowed and user to be logged in if topics tracking for guests is disabled
0068      case 'unreadposts':
0069          if (!$config['load_unreads_search'])
0070          {
0071              $template->assign_var('S_NO_SEARCH', true);
0072              trigger_error('NO_SEARCH_UNREADS');
0073          }
0074          else if (!$config['load_anon_lastread'] && !$user->data['is_registered'])
0075          {
0076              login_box('', $user->lang['LOGIN_EXPLAIN_UNREADSEARCH']);
0077          }
0078      break;
0079   
0080      // The "new posts" search uses user_lastvisit which is user based, so it should require user to log in.
0081      case 'newposts':
0082          if ($user->data['user_id'] == ANONYMOUS)
0083          {
0084              login_box('', $user->lang['LOGIN_EXPLAIN_NEWPOSTS']);
0085          }
0086      break;
0087   
0088      default:
0089          // There's nothing to do here for now ;)
0090      break;
0091  }
0092   
0093  $search_auth_check_override = false;
0094  /**
0095  * This event allows you to override search auth checks
0096  *
0097  * @event core.search_auth_check_override
0098  * @var    bool    search_auth_check_override    Whether or not the search auth check overridden
0099  * @since 3.3.14-RC1
0100  */
0101  $vars = [
0102      'search_auth_check_override',
0103  ];
0104  extract($phpbb_dispatcher->trigger_event('core.search_auth_check_override', compact($vars)));
0105   
0106  // Is user able to search? Has search been disabled?
0107  if (!$search_auth_check_override && (!$auth->acl_get('u_search') || !$auth->acl_getf_global('f_search') || !$config['load_search']))
0108  {
0109      $template->assign_var('S_NO_SEARCH', true);
0110      trigger_error('NO_SEARCH');
0111  }
0112   
0113  // Check search load limit
0114  if ($user->load && $config['limit_search_load'] && ($user->load > doubleval($config['limit_search_load'])))
0115  {
0116      $template->assign_var('S_NO_SEARCH', true);
0117      trigger_error('NO_SEARCH_LOAD');
0118  }
0119   
0120  // It is applicable if the configuration setting is non-zero, and the user cannot
0121  // ignore the flood setting, and the search is a keyword search.
0122  $interval = ($user->data['user_id'] == ANONYMOUS) ? $config['search_anonymous_interval'] : $config['search_interval'];
0123  if ($interval && !in_array($search_id, array('unreadposts', 'unanswered', 'active_topics', 'egosearch')) && !$auth->acl_get('u_ignoreflood'))
0124  {
0125      if ($user->data['user_last_search'] > time() - $interval)
0126      {
0127          $template->assign_var('S_NO_SEARCH', true);
0128          trigger_error($user->lang('NO_SEARCH_TIME', (int) ($user->data['user_last_search'] + $interval - time())));
0129      }
0130  }
0131   
0132  // Define some vars
0133  $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']);
0134  $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']);
0135   
0136  $s_limit_days = $s_sort_key = $s_sort_dir = $u_sort_param = '';
0137  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);
0138   
0139  /* @var $phpbb_content_visibility \phpbb\content_visibility */
0140  $phpbb_content_visibility = $phpbb_container->get('content.visibility');
0141   
0142  /* @var $pagination \phpbb\pagination */
0143  $pagination = $phpbb_container->get('pagination');
0144   
0145  $template->assign_block_vars('navlinks', array(
0146      'BREADCRUMB_NAME'    => $user->lang('SEARCH'),
0147      'U_BREADCRUMB'        => append_sid("{$phpbb_root_path}search.$phpEx"),
0148  ));
0149   
0150  /**
0151  * This event allows you to alter the above parameters, such as keywords and submit
0152  *
0153  * @event core.search_modify_submit_parameters
0154  * @var    string    keywords    The search keywords
0155  * @var    string    author        Specifies the author match, when ANONYMOUS is also a search-match
0156  * @var    int        author_id    ID of the author to search by
0157  * @var    string    search_id    Predefined search type name
0158  * @var    bool    submit        Whether or not the form has been submitted
0159  * @since 3.1.10-RC1
0160  */
0161  $vars = array(
0162      'keywords',
0163      'author',
0164      'author_id',
0165      'search_id',
0166      'submit',
0167  );
0168  extract($phpbb_dispatcher->trigger_event('core.search_modify_submit_parameters', compact($vars)));
0169   
0170  if ($keywords || $author || $author_id || $search_id || $submit)
0171  {
0172      // clear arrays
0173      $id_ary = array();
0174   
0175      // If we are looking for authors get their ids
0176      $author_id_ary = array();
0177      $sql_author_match = '';
0178      if ($author_id)
0179      {
0180          $author_id_ary[] = $author_id;
0181      }
0182      else if ($author)
0183      {
0184          if ((strpos($author, '*') !== false) && (utf8_strlen(str_replace(array('*', '%'), '', $author)) < $config['min_search_author_chars']))
0185          {
0186              trigger_error($user->lang('TOO_FEW_AUTHOR_CHARS', (int) $config['min_search_author_chars']));
0187          }
0188   
0189          $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)) . "'";
0190   
0191          $sql = 'SELECT user_id
0192              FROM ' . USERS_TABLE . "
0193              WHERE $sql_where
0194                  AND user_type <> " . USER_IGNORE;
0195          $result = $db->sql_query_limit($sql, 100);
0196   
0197          while ($row = $db->sql_fetchrow($result))
0198          {
0199              $author_id_ary[] = (int) $row['user_id'];
0200          }
0201          $db->sql_freeresult($result);
0202   
0203          $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)) . "'";
0204   
0205          $sql = 'SELECT 1 as guest_post
0206              FROM ' . POSTS_TABLE . "
0207              WHERE $sql_where
0208                  AND poster_id = " . ANONYMOUS;
0209          $result = $db->sql_query_limit($sql, 1);
0210          $found_guest_post = $db->sql_fetchfield('guest_post');
0211          $db->sql_freeresult($result);
0212   
0213          if ($found_guest_post)
0214          {
0215              $author_id_ary[] = ANONYMOUS;
0216              $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)) . "'";
0217          }
0218   
0219          if (!count($author_id_ary))
0220          {
0221              trigger_error('NO_SEARCH_RESULTS');
0222          }
0223      }
0224   
0225      // if we search in an existing search result just add the additional keywords. But we need to use "all search terms"-mode
0226      // so we can keep the old keywords in their old mode, but add the new ones as required words
0227      if ($add_keywords)
0228      {
0229          if ($search_terms == 'all')
0230          {
0231              $keywords .= ' ' . $add_keywords;
0232          }
0233          else
0234          {
0235              $search_terms = 'all';
0236              $keywords = implode(' |', explode(' ', preg_replace('#\s+#u', ' ', $keywords))) . ' ' .$add_keywords;
0237          }
0238      }
0239   
0240      // Which forums should not be searched? Author searches are also carried out in unindexed forums
0241      if (empty($keywords) && count($author_id_ary))
0242      {
0243          $ex_fid_ary = array_keys($auth->acl_getf('!f_read', true));
0244      }
0245      else
0246      {
0247          $ex_fid_ary = array_unique(array_merge(array_keys($auth->acl_getf('!f_read', true)), array_keys($auth->acl_getf('!f_search', true))));
0248      }
0249   
0250      $not_in_fid = (count($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'] . ')' : "";
0251   
0252      $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
0253          FROM ' . FORUMS_TABLE . ' f
0254          LEFT JOIN ' . FORUMS_ACCESS_TABLE . " fa ON (fa.forum_id = f.forum_id
0255              AND fa.session_id = '" . $db->sql_escape($user->session_id) . "')
0256          $not_in_fid
0257          ORDER BY f.left_id";
0258      $result = $db->sql_query($sql);
0259   
0260      $right_id = 0;
0261      $reset_search_forum = true;
0262      while ($row = $db->sql_fetchrow($result))
0263      {
0264          if ($row['forum_password'] && $row['user_id'] != $user->data['user_id'])
0265          {
0266              $ex_fid_ary[] = (int) $row['forum_id'];
0267              continue;
0268          }
0269   
0270          // Exclude forums from active topics
0271          if (!($row['forum_flags'] & FORUM_FLAG_ACTIVE_TOPICS) && ($search_id == 'active_topics'))
0272          {
0273              $ex_fid_ary[] = (int) $row['forum_id'];
0274              continue;
0275          }
0276   
0277          if (count($search_forum))
0278          {
0279              if ($search_child)
0280              {
0281                  if (in_array($row['forum_id'], $search_forum) && $row['right_id'] > $right_id)
0282                  {
0283                      $right_id = (int) $row['right_id'];
0284                  }
0285                  else if ($row['right_id'] < $right_id)
0286                  {
0287                      continue;
0288                  }
0289              }
0290   
0291              if (!in_array($row['forum_id'], $search_forum))
0292              {
0293                  $ex_fid_ary[] = (int) $row['forum_id'];
0294                  $reset_search_forum = false;
0295              }
0296          }
0297      }
0298      $db->sql_freeresult($result);
0299   
0300      // find out in which forums the user is allowed to view posts
0301      $m_approve_posts_fid_sql = $phpbb_content_visibility->get_global_visibility_sql('post', $ex_fid_ary, 'p.');
0302      $m_approve_topics_fid_sql = $phpbb_content_visibility->get_global_visibility_sql('topic', $ex_fid_ary, 't.');
0303   
0304      if ($reset_search_forum)
0305      {
0306          $search_forum = array();
0307      }
0308   
0309      // Select which method we'll use to obtain the post_id or topic_id information
0310      $search_type = $config['search_type'];
0311   
0312      if (!class_exists($search_type))
0313      {
0314          trigger_error('NO_SUCH_SEARCH_MODULE');
0315      }
0316      // We do some additional checks in the module to ensure it can actually be utilised
0317      $error = false;
0318      $search = new $search_type($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user, $phpbb_dispatcher);
0319   
0320      if ($error)
0321      {
0322          trigger_error($error);
0323      }
0324   
0325      // let the search module split up the keywords
0326      if ($keywords)
0327      {
0328          $correct_query = $search->split_keywords($keywords, $search_terms);
0329          $common_words = $search->get_common_words();
0330          if (!$correct_query || (!$search->get_search_query() && !count($author_id_ary) && !$search_id))
0331          {
0332              $ignored = (count($common_words)) ? sprintf($user->lang['IGNORED_TERMS_EXPLAIN'], implode(' ', $common_words)) . '<br />' : '';
0333              $word_length = $search->get_word_length();
0334              if ($word_length)
0335              {
0336                  trigger_error($ignored . $user->lang('NO_KEYWORDS', $user->lang('CHARACTERS', (int) $word_length['min']), $user->lang('CHARACTERS', (int) $word_length['max'])));
0337              }
0338              else
0339              {
0340                  trigger_error($ignored);
0341              }
0342          }
0343      }
0344   
0345      if (!$keywords && count($author_id_ary))
0346      {
0347          // if it is an author search we want to show topics by default
0348          $show_results = ($topic_id) ? 'posts' : $request->variable('sr', ($search_id == 'egosearch') ? 'topics' : 'posts');
0349          $show_results = ($show_results == 'posts') ? 'posts' : 'topics';
0350      }
0351   
0352      // define some variables needed for retrieving post_id/topic_id information
0353      $sort_by_sql = [
0354          'a' => 'u.username_clean',
0355          't' => (($show_results == 'posts') ? 'p.post_time' : 't.topic_last_post_time'),
0356          'f' => 'f.forum_id',
0357          'i' => 't.topic_title',
0358          's' => (($show_results == 'posts') ? 'p.post_subject' : 't.topic_title')
0359      ];
0360   
0361      /**
0362      * Event to modify the SQL parameters before pre-made searches
0363      *
0364      * @event core.search_modify_param_before
0365      * @var    string    keywords        String of the specified keywords
0366      * @var    array    sort_by_sql        Array of SQL sorting instructions
0367      * @var    array    ex_fid_ary        Array of excluded forum ids
0368      * @var    array    author_id_ary    Array of exclusive author ids
0369      * @var    string    search_id        The id of the search request
0370      * @var    array    id_ary            Array of post or topic ids for search result
0371      * @var    string    show_results    'posts' or 'topics' type of ids
0372      * @since 3.1.3-RC1
0373      * @changed 3.1.10-RC1 Added id_ary, show_results
0374      */
0375      $vars = array(
0376          'keywords',
0377          'sort_by_sql',
0378          'ex_fid_ary',
0379          'author_id_ary',
0380          'search_id',
0381          'id_ary',
0382          'show_results',
0383      );
0384      extract($phpbb_dispatcher->trigger_event('core.search_modify_param_before', compact($vars)));
0385   
0386      // pre-made searches
0387      $sql = $field = $l_search_title = '';
0388      if ($search_id)
0389      {
0390          switch ($search_id)
0391          {
0392              // Oh holy Bob, bring us some activity...
0393              case 'active_topics':
0394                  $l_search_title = $user->lang['SEARCH_ACTIVE_TOPICS'];
0395                  $show_results = 'topics';
0396                  $sort_key = 't';
0397                  $sort_dir = 'd';
0398                  $sort_days = $request->variable('st', 7);
0399                  $sort_by_sql['t'] = 't.topic_last_post_time';
0400   
0401                  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);
0402                  $s_sort_key = $s_sort_dir = '';
0403   
0404                  $last_post_time_sql = ($sort_days) ? ' AND t.topic_last_post_time > ' . (time() - ($sort_days * 24 * 3600)) : '';
0405   
0406                  $sql = 'SELECT t.topic_last_post_time, t.topic_id
0407                      FROM ' . TOPICS_TABLE . " t
0408                      WHERE t.topic_moved_id = 0
0409                          $last_post_time_sql
0410                          AND " . $m_approve_topics_fid_sql . '
0411                          ' . ((count($ex_fid_ary)) ? ' AND ' . $db->sql_in_set('t.forum_id', $ex_fid_ary, true) : '') . '
0412                      ORDER BY t.topic_last_post_time DESC';
0413                  $field = 'topic_id';
0414              break;
0415   
0416              case 'unanswered':
0417                  $l_search_title = $user->lang['SEARCH_UNANSWERED'];
0418                  $show_results = $request->variable('sr', 'topics');
0419                  $show_results = ($show_results == 'posts') ? 'posts' : 'topics';
0420                  $sort_by_sql['t'] = ($show_results == 'posts') ? 'p.post_time' : 't.topic_last_post_time';
0421                  $sort_by_sql['s'] = ($show_results == 'posts') ? 'p.post_subject' : 't.topic_title';
0422                  $sql_sort = 'ORDER BY ' . $sort_by_sql[$sort_key] . (($sort_dir == 'a') ? ' ASC' : ' DESC');
0423   
0424                  $sort_join = ($sort_key == 'f') ? FORUMS_TABLE . ' f, ' : '';
0425                  $sql_sort = ($sort_key == 'f') ? ' AND f.forum_id = t.forum_id ' . $sql_sort : $sql_sort;
0426   
0427                  if ($sort_days)
0428                  {
0429                      $last_post_time = 'AND ' . ($show_results == 'posts' ? 'p.post_time' : 't.topic_last_post_time') . ' > ' . (time() - ($sort_days * 24 * 3600));
0430                  }
0431                  else
0432                  {
0433                      $last_post_time = '';
0434                  }
0435   
0436                  if ($sort_key == 'a')
0437                  {
0438                      $sort_join = USERS_TABLE . ' u, ';
0439                      $sql_sort = ' AND u.user_id = ' . ($show_results == 'posts' ? 'p.poster_id ' : 't.topic_last_poster_id ') . $sql_sort;
0440                  }
0441                  if ($show_results == 'posts')
0442                  {
0443                      $sql = "SELECT p.post_id
0444                          FROM $sort_join" . POSTS_TABLE . ' p, ' . TOPICS_TABLE . " t
0445                          WHERE t.topic_posts_approved = 1
0446                              AND p.topic_id = t.topic_id
0447                              $last_post_time
0448                              AND $m_approve_posts_fid_sql
0449                              " . ((count($ex_fid_ary)) ? ' AND ' . $db->sql_in_set('p.forum_id', $ex_fid_ary, true) : '') . "
0450                              $sql_sort";
0451                      $field = 'post_id';
0452                  }
0453                  else
0454                  {
0455                      $sql = 'SELECT DISTINCT ' . $sort_by_sql[$sort_key] . ", t.topic_id
0456                          FROM $sort_join" . TOPICS_TABLE . " t
0457                          WHERE t.topic_posts_approved = 1
0458                              AND t.topic_moved_id = 0
0459                              $last_post_time
0460                              AND $m_approve_topics_fid_sql
0461                              " . ((count($ex_fid_ary)) ? ' AND ' . $db->sql_in_set('t.forum_id', $ex_fid_ary, true) : '') . "
0462                          $sql_sort";
0463                      $field = 'topic_id';
0464                  }
0465              break;
0466   
0467              case 'unreadposts':
0468                  $l_search_title = $user->lang['SEARCH_UNREAD'];
0469                  // force sorting
0470                  $show_results = 'topics';
0471                  $sort_key = 't';
0472                  $sort_by_sql['t'] = 't.topic_last_post_time';
0473                  $sql_sort = 'ORDER BY ' . $sort_by_sql[$sort_key] . (($sort_dir == 'a') ? ' ASC' : ' DESC');
0474   
0475                  $sql_where = 'AND t.topic_moved_id = 0
0476                      AND ' . $m_approve_topics_fid_sql . '
0477                      ' . ((count($ex_fid_ary)) ? 'AND ' . $db->sql_in_set('t.forum_id', $ex_fid_ary, true) : '');
0478   
0479                  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);
0480                  $s_sort_key = $s_sort_dir = $u_sort_param = $s_limit_days = '';
0481   
0482                  $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()) : '');
0483              break;
0484   
0485              case 'newposts':
0486                  $l_search_title = $user->lang['SEARCH_NEW'];
0487                  // force sorting
0488                  $show_results = ($request->variable('sr', 'topics') == 'posts') ? 'posts' : 'topics';
0489                  $sort_key = 't';
0490                  $sort_dir = 'd';
0491                  $sort_by_sql['t'] = ($show_results == 'posts') ? 'p.post_time' : 't.topic_last_post_time';
0492                  $sql_sort = 'ORDER BY ' . $sort_by_sql[$sort_key] . (($sort_dir == 'a') ? ' ASC' : ' DESC');
0493   
0494                  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);
0495                  $s_sort_key = $s_sort_dir = $u_sort_param = $s_limit_days = '';
0496   
0497                  if ($show_results == 'posts')
0498                  {
0499                      $sql = 'SELECT p.post_id
0500                          FROM ' . POSTS_TABLE . ' p
0501                          WHERE p.post_time > ' . $user->data['user_lastvisit'] . '
0502                              AND ' . $m_approve_posts_fid_sql . '
0503                              ' . ((count($ex_fid_ary)) ? ' AND ' . $db->sql_in_set('p.forum_id', $ex_fid_ary, true) : '') . "
0504                          $sql_sort";
0505                      $field = 'post_id';
0506                  }
0507                  else
0508                  {
0509                      $sql = 'SELECT t.topic_id
0510                          FROM ' . TOPICS_TABLE . ' t
0511                          WHERE t.topic_last_post_time > ' . $user->data['user_lastvisit'] . '
0512                              AND t.topic_moved_id = 0
0513                              AND ' . $m_approve_topics_fid_sql . '
0514                              ' . ((count($ex_fid_ary)) ? 'AND ' . $db->sql_in_set('t.forum_id', $ex_fid_ary, true) : '') . "
0515                          $sql_sort";
0516  /*
0517          [Fix] queued replies missing from "view new posts" (Bug #42705 - Patch by Paul)
0518          - Creates temporary table, query is far from optimized
0519   
0520                      $sql = 'SELECT t.topic_id
0521                          FROM ' . TOPICS_TABLE . ' t, ' . POSTS_TABLE . ' p
0522                          WHERE p.post_time > ' . $user->data['user_lastvisit'] . '
0523                              AND t.topic_id = p.topic_id
0524                              AND t.topic_moved_id = 0
0525                              AND ' . $m_approve_topics_fid_sql . "
0526                          GROUP BY t.topic_id
0527                          $sql_sort";
0528  */
0529                      $field = 'topic_id';
0530                  }
0531              break;
0532   
0533              case 'egosearch':
0534                  $l_search_title = $user->lang['SEARCH_SELF'];
0535              break;
0536          }
0537   
0538          $template->assign_block_vars('navlinks', array(
0539              'BREADCRUMB_NAME'    => $l_search_title,
0540              'U_BREADCRUMB'        => append_sid("{$phpbb_root_path}search.$phpEx", "search_id=$search_id"),
0541          ));
0542      }
0543   
0544      /**
0545      * Event to modify data after pre-made searches
0546      *
0547      * @event core.search_modify_param_after
0548      * @var    string    l_search_title    The title of the search page
0549      * @var    string    search_id        Predefined search type name
0550      * @var    string    show_results    Display topics or posts
0551      * @var    string    sql                SQL query corresponding to the pre-made search id
0552      * @since 3.1.7-RC1
0553      */
0554      $vars = array(
0555          'l_search_title',
0556          'search_id',
0557          'show_results',
0558          'sql',
0559      );
0560      extract($phpbb_dispatcher->trigger_event('core.search_modify_param_after', compact($vars)));
0561   
0562      // show_results should not change after this
0563      $per_page = ($show_results == 'posts') ? $config['posts_per_page'] : $config['topics_per_page'];
0564      $total_match_count = 0;
0565   
0566      // Set limit for the $total_match_count to reduce server load
0567      $total_matches_limit = 1000;
0568      $found_more_search_matches = false;
0569   
0570      if ($search_id)
0571      {
0572          if ($sql)
0573          {
0574              // Only return up to $total_matches_limit+1 ids (the last one will be removed later)
0575              $result = $db->sql_query_limit($sql, $total_matches_limit + 1);
0576   
0577              while ($row = $db->sql_fetchrow($result))
0578              {
0579                  $id_ary[] = (int) $row[$field];
0580              }
0581              $db->sql_freeresult($result);
0582          }
0583          else if ($search_id == 'unreadposts')
0584          {
0585              // Only return up to $total_matches_limit+1 ids (the last one will be removed later)
0586              $id_ary = array_keys(get_unread_topics($user->data['user_id'], $sql_where, $sql_sort, $total_matches_limit + 1));
0587          }
0588          else
0589          {
0590              $search_id = '';
0591          }
0592   
0593          $total_match_count = count($id_ary);
0594          if ($total_match_count)
0595          {
0596              // Limit the number to $total_matches_limit for pre-made searches
0597              if ($total_match_count > $total_matches_limit)
0598              {
0599                  $found_more_search_matches = true;
0600                  $total_match_count = $total_matches_limit;
0601              }
0602   
0603              // Make sure $start is set to the last page if it exceeds the amount
0604              $start = $pagination->validate_start($start, $per_page, $total_match_count);
0605   
0606              $id_ary = array_slice($id_ary, $start, $per_page);
0607          }
0608          else
0609          {
0610              // Set $start to 0 if no matches were found
0611              $start = 0;
0612          }
0613      }
0614   
0615      // make sure that some arrays are always in the same order
0616      sort($ex_fid_ary);
0617      sort($author_id_ary);
0618   
0619      if ($search->get_search_query())
0620      {
0621          $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);
0622      }
0623      else if (count($author_id_ary))
0624      {
0625          $firstpost_only = ($search_fields === 'firstpost' || $search_fields == 'titleonly') ? true : false;
0626          $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);
0627      }
0628   
0629      /**
0630      * Event to search otherwise than by keywords or author
0631      *
0632      * @event core.search_backend_search_after
0633      * @var    string        show_results                'posts' or 'topics' type of ids
0634      * @var    string        search_fields                The data fields to search in
0635      * @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)
0636      * @var    array        sort_by_sql                    Array of SQL sorting instructions
0637      * @var    string        sort_key                    The sort key
0638      * @var    string        sort_dir                    The sort direction
0639      * @var    int            sort_days                    Limit the age of results
0640      * @var    array        ex_fid_ary                    Array of excluded forum ids
0641      * @var    string        m_approve_posts_fid_sql        Specifies which types of posts the user can view in which forums
0642      * @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
0643      * @var    array        author_id_ary                Array of exclusive author ids
0644      * @var    string        sql_author_match            Specifies the author match, when ANONYMOUS is also a search-match
0645      * @var    array        id_ary                        Array of post or topic ids for search result
0646      * @var    int            start                        The starting id of the results
0647      * @var    int            per_page                    Number of ids each page is supposed to contain
0648      * @var    int            total_match_count            The total number of search matches
0649      * @since 3.1.10-RC1
0650      */
0651      $vars = array(
0652          'show_results',
0653          'search_fields',
0654          'search_terms',
0655          'sort_by_sql',
0656          'sort_key',
0657          'sort_dir',
0658          'sort_days',
0659          'ex_fid_ary',
0660          'm_approve_posts_fid_sql',
0661          'topic_id',
0662          'author_id_ary',
0663          'sql_author_match',
0664          'id_ary',
0665          'start',
0666          'per_page',
0667          'total_match_count',
0668      );
0669      extract($phpbb_dispatcher->trigger_event('core.search_backend_search_after', compact($vars)));
0670   
0671      $sql_where = '';
0672   
0673      if (count($id_ary))
0674      {
0675          $sql_where .= $db->sql_in_set(($show_results == 'posts') ? 'p.post_id' : 't.topic_id', $id_ary);
0676          $sql_where .= (count($ex_fid_ary)) ? ' AND (' . $db->sql_in_set('f.forum_id', $ex_fid_ary, true) . ' OR f.forum_id IS NULL)' : '';
0677          $sql_where .= ' AND ' . (($show_results == 'posts') ? $m_approve_posts_fid_sql : $m_approve_topics_fid_sql);
0678      }
0679   
0680      if ($show_results == 'posts')
0681      {
0682          include($phpbb_root_path . 'includes/functions_posting.' . $phpEx);
0683      }
0684      else
0685      {
0686          include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
0687      }
0688   
0689      $user->add_lang('viewtopic');
0690   
0691      // Grab icons
0692      $icons = $cache->obtain_icons();
0693   
0694      // define some vars for urls
0695      // A single wildcard will make the search results look ugly
0696      $hilit = phpbb_clean_search_string(str_replace(array('+', '-', '|', '(', ')', '&quot;'), ' ', $keywords));
0697      $hilit = str_replace(' ', '|', $hilit);
0698   
0699      $u_hilit = urlencode(html_entity_decode(str_replace('|', ' ', $hilit), ENT_COMPAT));
0700      $u_show_results = 'sr=' . $show_results;
0701      $u_search_forum = implode('&amp;fid%5B%5D=', $search_forum);
0702   
0703      $u_search = append_sid("{$phpbb_root_path}search.$phpEx", (($u_sort_param) ? $u_sort_param . '&amp;' : '') . $u_show_results);
0704      $u_search .= ($search_id) ? '&amp;search_id=' . $search_id : '';
0705      $u_search .= ($u_hilit) ? '&amp;keywords=' . urlencode(html_entity_decode($keywords, ENT_COMPAT)) : '';
0706      $u_search .= ($search_terms != 'all') ? '&amp;terms=' . $search_terms : '';
0707      $u_search .= ($topic_id) ? '&amp;t=' . $topic_id : '';
0708      $u_search .= ($author) ? '&amp;author=' . urlencode(html_entity_decode($author, ENT_COMPAT)) : '';
0709      $u_search .= ($author_id) ? '&amp;author_id=' . $author_id : '';
0710      $u_search .= ($u_search_forum) ? '&amp;fid%5B%5D=' . $u_search_forum : '';
0711      $u_search .= (!$search_child) ? '&amp;sc=0' : '';
0712      $u_search .= ($search_fields != 'all') ? '&amp;sf=' . $search_fields : '';
0713      $u_search .= $return_chars !== (int) $config['default_search_return_chars'] ? '&amp;ch=' . $return_chars : '';
0714   
0715      /**
0716      * Event to add or modify search URL parameters
0717      *
0718      * @event core.search_modify_url_parameters
0719      * @var    string    u_search        Search URL parameters string
0720      * @var    string    search_id        Predefined search type name
0721      * @var    string    show_results    String indicating the show results mode
0722      * @var    string    sql_where        The SQL WHERE string used by search to get topic data
0723      * @var    int        total_match_count    The total number of search matches
0724      * @var    array    ex_fid_ary        Array of excluded forum ids
0725      * @since 3.1.7-RC1
0726      * @changed 3.1.10-RC1 Added show_results, sql_where, total_match_count
0727      * @changed 3.1.11-RC1 Added ex_fid_ary
0728      */
0729      $vars = array(
0730          'u_search',
0731          'search_id',
0732          'show_results',
0733          'sql_where',
0734          'total_match_count',
0735          'ex_fid_ary',
0736      );
0737      extract($phpbb_dispatcher->trigger_event('core.search_modify_url_parameters', compact($vars)));
0738   
0739      if ($sql_where)
0740      {
0741          $zebra = [];
0742   
0743          if ($show_results == 'posts')
0744          {
0745              // @todo Joining this query to the one below?
0746              $sql = 'SELECT zebra_id, friend, foe
0747                  FROM ' . ZEBRA_TABLE . '
0748                  WHERE user_id = ' . $user->data['user_id'];
0749              $result = $db->sql_query($sql);
0750   
0751              while ($row = $db->sql_fetchrow($result))
0752              {
0753                  $zebra[($row['friend']) ? 'friend' : 'foe'][] = $row['zebra_id'];
0754              }
0755              $db->sql_freeresult($result);
0756   
0757              $sql_array = array(
0758                  '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',
0759                  'FROM'        => array(
0760                      POSTS_TABLE        => 'p',
0761                  ),
0762                  'LEFT_JOIN' => array(
0763                      array(
0764                          'FROM'    => array(TOPICS_TABLE => 't'),
0765                          'ON'    => 'p.topic_id = t.topic_id',
0766                      ),
0767                      array(
0768                          'FROM'    => array(FORUMS_TABLE => 'f'),
0769                          'ON'    => 'p.forum_id = f.forum_id',
0770                      ),
0771                      array(
0772                          'FROM'    => array(USERS_TABLE => 'u'),
0773                          'ON'    => 'p.poster_id = u.user_id',
0774                      ),
0775                  ),
0776                  'WHERE'    => $sql_where,
0777                  'ORDER_BY' => $sort_by_sql[$sort_key] . ' ' . (($sort_dir == 'd') ? 'DESC' : 'ASC'),
0778              );
0779   
0780              /**
0781              * Event to modify the SQL query before the posts data is retrieved
0782              *
0783              * @event core.search_get_posts_data
0784              * @var    array    sql_array        The SQL array
0785              * @var    array    zebra            Array of zebra data for the current user
0786              * @var    int        total_match_count    The total number of search matches
0787              * @var    string    keywords        String of the specified keywords
0788              * @var    array    sort_by_sql        Array of SQL sorting instructions
0789              * @var    string    s_sort_dir        The sort direction
0790              * @var    string    s_sort_key        The sort key
0791              * @var    string    s_limit_days    Limit the age of results
0792              * @var    array    ex_fid_ary        Array of excluded forum ids
0793              * @var    array    author_id_ary    Array of exclusive author ids
0794              * @var    string    search_fields    The data fields to search in
0795              * @var    int        search_id        The id of the search request
0796              * @var    int        start            The starting id of the results
0797              * @since 3.1.0-b3
0798              */
0799              $vars = array(
0800                  'sql_array',
0801                  'zebra',
0802                  'total_match_count',
0803                  'keywords',
0804                  'sort_by_sql',
0805                  's_sort_dir',
0806                  's_sort_key',
0807                  's_limit_days',
0808                  'ex_fid_ary',
0809                  'author_id_ary',
0810                  'search_fields',
0811                  'search_id',
0812                  'start',
0813              );
0814              extract($phpbb_dispatcher->trigger_event('core.search_get_posts_data', compact($vars)));
0815   
0816              $sql = $db->sql_build_query('SELECT', $sql_array);
0817          }
0818          else
0819          {
0820              $sql_from = TOPICS_TABLE . ' t
0821                  LEFT JOIN ' . FORUMS_TABLE . ' f ON (f.forum_id = t.forum_id)
0822                  ' . (($sort_key == 'a') ? ' LEFT JOIN ' . USERS_TABLE . ' u ON (u.user_id = t.topic_poster) ' : '');
0823              $sql_select = 't.*, f.forum_id, f.forum_name';
0824   
0825              if ($user->data['is_registered'])
0826              {
0827                  if ($config['load_db_track'] && $author_id !== $user->data['user_id'])
0828                  {
0829                      $sql_from .= ' LEFT JOIN ' . TOPICS_POSTED_TABLE . ' tp ON (tp.user_id = ' . $user->data['user_id'] . '
0830                          AND t.topic_id = tp.topic_id)';
0831                      $sql_select .= ', tp.topic_posted';
0832                  }
0833   
0834                  if ($config['load_db_lastread'])
0835                  {
0836                      $sql_from .= ' LEFT JOIN ' . TOPICS_TRACK_TABLE . ' tt ON (tt.user_id = ' . $user->data['user_id'] . '
0837                              AND t.topic_id = tt.topic_id)
0838                          LEFT JOIN ' . FORUMS_TRACK_TABLE . ' ft ON (ft.user_id = ' . $user->data['user_id'] . '
0839                              AND ft.forum_id = f.forum_id)';
0840                      $sql_select .= ', tt.mark_time, ft.mark_time as f_mark_time';
0841                  }
0842              }
0843   
0844              if ($config['load_anon_lastread'] || ($user->data['is_registered'] && !$config['load_db_lastread']))
0845              {
0846                  $tracking_topics = $request->variable($config['cookie_name'] . '_track', '', true, \phpbb\request\request_interface::COOKIE);
0847                  $tracking_topics = ($tracking_topics) ? tracking_unserialize($tracking_topics) : array();
0848              }
0849   
0850              $sql_order_by = $sort_by_sql[$sort_key] . ' ' . (($sort_dir == 'd') ? 'DESC' : 'ASC');
0851   
0852              /**
0853              * Event to modify the SQL query before the topic data is retrieved
0854              *
0855              * @event core.search_get_topic_data
0856              * @var    string    sql_select        The SQL SELECT string used by search to get topic data
0857              * @var    string    sql_from        The SQL FROM string used by search to get topic data
0858              * @var    string    sql_where        The SQL WHERE string used by search to get topic data
0859              * @var    int        total_match_count    The total number of search matches
0860              * @var    array    sort_by_sql        Array of SQL sorting instructions
0861              * @var    string    sort_dir        The sorting direction
0862              * @var    string    sort_key        The sorting key
0863              * @var    string    sql_order_by    The SQL ORDER BY string used by search to get topic data
0864              * @since 3.1.0-a1
0865              * @changed 3.1.0-RC5 Added total_match_count
0866              * @changed 3.1.7-RC1 Added sort_by_sql, sort_dir, sort_key, sql_order_by
0867              */
0868              $vars = array(
0869                  'sql_select',
0870                  'sql_from',
0871                  'sql_where',
0872                  'total_match_count',
0873                  'sort_by_sql',
0874                  'sort_dir',
0875                  'sort_key',
0876                  'sql_order_by',
0877              );
0878              extract($phpbb_dispatcher->trigger_event('core.search_get_topic_data', compact($vars)));
0879   
0880              $sql = "SELECT $sql_select
0881                  FROM $sql_from
0882                  WHERE $sql_where
0883                  ORDER BY $sql_order_by";
0884          }
0885          $result = $db->sql_query($sql);
0886          $result_topic_id = 0;
0887   
0888          $rowset = $attachments = $topic_tracking_info = array();
0889   
0890          if ($show_results == 'topics')
0891          {
0892              $forums = $rowset = $shadow_topic_list = array();
0893              while ($row = $db->sql_fetchrow($result))
0894              {
0895                  $row['forum_id'] = (int) $row['forum_id'];
0896                  $row['topic_id'] = (int) $row['topic_id'];
0897   
0898                  if ($row['topic_status'] == ITEM_MOVED)
0899                  {
0900                      $shadow_topic_list[$row['topic_moved_id']] = $row['topic_id'];
0901                  }
0902   
0903                  $rowset[$row['topic_id']] = $row;
0904   
0905                  if (!isset($forums[$row['forum_id']]) && $user->data['is_registered'] && $config['load_db_lastread'])
0906                  {
0907                      $forums[$row['forum_id']]['mark_time'] = $row['f_mark_time'];
0908                  }
0909                  $forums[$row['forum_id']]['topic_list'][] = $row['topic_id'];
0910                  $forums[$row['forum_id']]['rowset'][$row['topic_id']] = &$rowset[$row['topic_id']];
0911              }
0912              $db->sql_freeresult($result);
0913   
0914              // If we have some shadow topics, update the rowset to reflect their topic information
0915              if (count($shadow_topic_list))
0916              {
0917                  $sql = 'SELECT *
0918                      FROM ' . TOPICS_TABLE . '
0919                      WHERE ' . $db->sql_in_set('topic_id', array_keys($shadow_topic_list));
0920                  $result = $db->sql_query($sql);
0921   
0922                  while ($row = $db->sql_fetchrow($result))
0923                  {
0924                      $orig_topic_id = $shadow_topic_list[$row['topic_id']];
0925   
0926                      // We want to retain some values
0927                      $row = array_merge($row, array(
0928                          'topic_moved_id'    => $rowset[$orig_topic_id]['topic_moved_id'],
0929                          'topic_status'        => $rowset[$orig_topic_id]['topic_status'],
0930                          'forum_name'        => $rowset[$orig_topic_id]['forum_name'])
0931                      );
0932   
0933                      $rowset[$orig_topic_id] = $row;
0934                  }
0935                  $db->sql_freeresult($result);
0936              }
0937              unset($shadow_topic_list);
0938   
0939              foreach ($forums as $forum_id => $forum)
0940              {
0941                  if ($user->data['is_registered'] && $config['load_db_lastread'])
0942                  {
0943                      $topic_tracking_info[$forum_id] = get_topic_tracking($forum_id, $forum['topic_list'], $forum['rowset'], array($forum_id => $forum['mark_time']));
0944                  }
0945                  else if ($config['load_anon_lastread'] || $user->data['is_registered'])
0946                  {
0947                      $topic_tracking_info[$forum_id] = get_complete_topic_tracking($forum_id, $forum['topic_list']);
0948   
0949                      if (!$user->data['is_registered'])
0950                      {
0951                          $user->data['user_lastmark'] = (isset($tracking_topics['l'])) ? (int) (base_convert($tracking_topics['l'], 36, 10) + $config['board_startdate']) : 0;
0952                      }
0953                  }
0954              }
0955              unset($forums);
0956          }
0957          else
0958          {
0959              $text_only_message = '';
0960              $attach_list = array();
0961   
0962              while ($row = $db->sql_fetchrow($result))
0963              {
0964                  /**
0965                  * Modify the row of a post result before the post_text is trimmed
0966                  *
0967                  * @event core.search_modify_post_row
0968                  * @var    string    hilit                    String to highlight
0969                  * @var    array    row                        Array with the post data
0970                  * @var    string    u_hilit                    Highlight string to be injected into URL
0971                  * @var    string    view                    Search results view mode
0972                  * @var    array    zebra                    Array with zebra data for the current user
0973                  * @since 3.2.2-RC1
0974                  */
0975                  $vars = array(
0976                      'hilit',
0977                      'row',
0978                      'u_hilit',
0979                      'view',
0980                      'zebra',
0981                  );
0982                  extract($phpbb_dispatcher->trigger_event('core.search_modify_post_row', compact($vars)));
0983   
0984                  // We pre-process some variables here for later usage
0985                  $row['post_text'] = censor_text($row['post_text']);
0986   
0987                  $text_only_message = $row['post_text'];
0988                  // make list items visible as such
0989                  if ($row['bbcode_uid'])
0990                  {
0991                      $text_only_message = str_replace('[*:' . $row['bbcode_uid'] . ']', '&sdot;&nbsp;', $text_only_message);
0992                      // no BBCode in text only message
0993                      strip_bbcode($text_only_message, $row['bbcode_uid']);
0994                  }
0995   
0996                  if ($return_chars === 0 || utf8_strlen($text_only_message) < ($return_chars + 3))
0997                  {
0998                      $row['display_text_only'] = false;
0999   
1000                      // Does this post have an attachment? If so, add it to the list
1001                      if ($row['post_attachment'] && $config['allow_attachments'])
1002                      {
1003                          $attach_list[$row['forum_id']][] = $row['post_id'];
1004                      }
1005                  }
1006                  else
1007                  {
1008                      $row['post_text'] = $text_only_message;
1009                      $row['display_text_only'] = true;
1010                  }
1011   
1012                  $rowset[] = $row;
1013              }
1014              $db->sql_freeresult($result);
1015   
1016              unset($text_only_message);
1017   
1018              // Pull attachment data
1019              if (count($attach_list))
1020              {
1021                  $use_attach_list = $attach_list;
1022                  $attach_list = array();
1023   
1024                  foreach ($use_attach_list as $forum_id => $_list)
1025                  {
1026                      if ($auth->acl_get('u_download') && $auth->acl_get('f_download', $forum_id))
1027                      {
1028                          $attach_list = array_merge($attach_list, $_list);
1029                      }
1030                  }
1031              }
1032   
1033              if (count($attach_list))
1034              {
1035                  $sql = 'SELECT *
1036                      FROM ' . ATTACHMENTS_TABLE . '
1037                      WHERE ' . $db->sql_in_set('post_msg_id', $attach_list) . '
1038                          AND in_message = 0
1039                      ORDER BY filetime DESC, post_msg_id ASC';
1040                  $result = $db->sql_query($sql);
1041   
1042                  while ($row = $db->sql_fetchrow($result))
1043                  {
1044                      $attachments[$row['post_msg_id']][] = $row;
1045                  }
1046                  $db->sql_freeresult($result);
1047              }
1048          }
1049   
1050          if ($hilit)
1051          {
1052              // Remove bad highlights
1053              $hilit_array = array_filter(explode('|', $hilit), 'strlen');
1054              foreach ($hilit_array as $key => $value)
1055              {
1056                  $hilit_array[$key] = phpbb_clean_search_string($value);
1057                  $hilit_array[$key] = str_replace('\*', '\w*?', preg_quote($hilit_array[$key], '#'));
1058                  $hilit_array[$key] = preg_replace('#(^|\s)\\\\w\*\?(\s|$)#', '$1\w+?$2', $hilit_array[$key]);
1059              }
1060              $hilit = implode('|', $hilit_array);
1061          }
1062   
1063          /**
1064          * Modify the rowset data
1065          *
1066          * @event core.search_modify_rowset
1067          * @var    array    attachments                Array with posts attachments data
1068          * @var    string    hilit                    String to highlight
1069          * @var    array    rowset                    Array with the search results data
1070          * @var    string    show_results            String indicating the show results mode
1071          * @var    array    topic_tracking_info        Array with the topics tracking data
1072          * @var    string    u_hilit                    Highlight string to be injected into URL
1073          * @var    string    view                    Search results view mode
1074          * @var    array    zebra                    Array with zebra data for the current user
1075          * @since 3.1.0-b4
1076          * @changed 3.1.0-b5 Added var show_results
1077          */
1078          $vars = array(
1079              'attachments',
1080              'hilit',
1081              'rowset',
1082              'show_results',
1083              'topic_tracking_info',
1084              'u_hilit',
1085              'view',
1086              'zebra',
1087          );
1088          extract($phpbb_dispatcher->trigger_event('core.search_modify_rowset', compact($vars)));
1089   
1090          foreach ($rowset as $row)
1091          {
1092              $forum_id = $row['forum_id'];
1093              $result_topic_id = $row['topic_id'];
1094              $topic_title = censor_text($row['topic_title']);
1095              $replies = $phpbb_content_visibility->get_count('topic_posts', $row, $forum_id) - 1;
1096   
1097              $view_topic_url_params = "t=$result_topic_id" . (($u_hilit) ? "&amp;hilit=$u_hilit" : '');
1098              $view_topic_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", $view_topic_url_params);
1099   
1100              $folder_img = $folder_alt = $u_mcp_queue = '';
1101              $topic_type = $posts_unapproved = 0;
1102              $unread_topic = $topic_unapproved = $topic_deleted = false;
1103   
1104              if ($show_results == 'topics')
1105              {
1106                  if ($config['load_db_track'] && $author_id === $user->data['user_id'])
1107                  {
1108                      $row['topic_posted'] = 1;
1109                  }
1110   
1111                  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);
1112   
1113                  $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;
1114   
1115                  $topic_unapproved = (($row['topic_visibility'] == ITEM_UNAPPROVED || $row['topic_visibility'] == ITEM_REAPPROVE) && $auth->acl_get('m_approve', $forum_id)) ? true : false;
1116                  $posts_unapproved = ($row['topic_visibility'] == ITEM_APPROVED && $row['topic_posts_unapproved'] && $auth->acl_get('m_approve', $forum_id)) ? true : false;
1117                  $topic_deleted = $row['topic_visibility'] == ITEM_DELETED;
1118                  $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) : '';
1119                  $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;
1120   
1121                  $row['topic_title'] = preg_replace('#(?!<.*)(?<!\w)(' . $hilit . ')(?!\w|[^<>]*(?:</s(?:cript|tyle))?>)#isu', '<span class="posthilit">$1</span>', $row['topic_title']);
1122   
1123                  $tpl_ary = array(
1124                      'TOPIC_AUTHOR'                => get_username_string('username', $row['topic_poster'], $row['topic_first_poster_name'], $row['topic_first_poster_colour']),
1125                      'TOPIC_AUTHOR_COLOUR'        => get_username_string('colour', $row['topic_poster'], $row['topic_first_poster_name'], $row['topic_first_poster_colour']),
1126                      'TOPIC_AUTHOR_FULL'            => get_username_string('full', $row['topic_poster'], $row['topic_first_poster_name'], $row['topic_first_poster_colour']),
1127                      'FIRST_POST_TIME'            => $user->format_date($row['topic_time']),
1128                      'FIRST_POST_TIME_RFC3339'    => gmdate(DATE_RFC3339, $row['topic_time']),
1129                      'LAST_POST_SUBJECT'            => $row['topic_last_post_subject'],
1130                      'LAST_POST_TIME'            => $user->format_date($row['topic_last_post_time']),
1131                      'LAST_POST_TIME_RFC3339'    => gmdate(DATE_RFC3339, $row['topic_last_post_time']),
1132                      'LAST_VIEW_TIME'            => $user->format_date($row['topic_last_view_time']),
1133                      'LAST_VIEW_TIME_RFC3339'    => gmdate(DATE_RFC3339, $row['topic_last_view_time']),
1134                      'LAST_POST_AUTHOR'            => get_username_string('username', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']),
1135                      'LAST_POST_AUTHOR_COLOUR'    => get_username_string('colour', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']),
1136                      'LAST_POST_AUTHOR_FULL'        => get_username_string('full', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']),
1137   
1138                      'TOPIC_TYPE'        => $topic_type,
1139   
1140                      'TOPIC_IMG_STYLE'        => $folder_img,
1141                      'TOPIC_FOLDER_IMG'        => $user->img($folder_img, $folder_alt),
1142                      'TOPIC_FOLDER_IMG_ALT'    => $user->lang[$folder_alt],
1143   
1144                      'TOPIC_ICON_IMG'        => (!empty($icons[$row['icon_id']])) ? $icons[$row['icon_id']]['img'] : '',
1145                      'TOPIC_ICON_IMG_WIDTH'    => (!empty($icons[$row['icon_id']])) ? $icons[$row['icon_id']]['width'] : '',
1146                      'TOPIC_ICON_IMG_HEIGHT'    => (!empty($icons[$row['icon_id']])) ? $icons[$row['icon_id']]['height'] : '',
1147                      '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']) : '',
1148                      'UNAPPROVED_IMG'        => ($topic_unapproved || $posts_unapproved) ? $user->img('icon_topic_unapproved', ($topic_unapproved) ? 'TOPIC_UNAPPROVED' : 'POSTS_UNAPPROVED') : '',
1149   
1150                      'S_TOPIC_TYPE'            => $row['topic_type'],
1151                      'S_USER_POSTED'            => (!empty($row['topic_posted'])) ? true : false,
1152                      'S_UNREAD_TOPIC'        => $unread_topic,
1153   
1154                      'S_TOPIC_REPORTED'        => (!empty($row['topic_reported']) && $auth->acl_get('m_report', $forum_id)) ? true : false,
1155                      'S_TOPIC_UNAPPROVED'    => $topic_unapproved,
1156                      'S_POSTS_UNAPPROVED'    => $posts_unapproved,
1157                      'S_TOPIC_DELETED'        => $topic_deleted,
1158                      'S_HAS_POLL'            => ($row['poll_start']) ? true : false,
1159   
1160                      'U_LAST_POST'            => append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'p=' . $row['topic_last_post_id']) . '#p' . $row['topic_last_post_id'],
1161                      'U_LAST_POST_AUTHOR'    => get_username_string('profile', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']),
1162                      'U_TOPIC_AUTHOR'        => get_username_string('profile', $row['topic_poster'], $row['topic_first_poster_name'], $row['topic_first_poster_colour']),
1163                      'U_NEWEST_POST'            => append_sid("{$phpbb_root_path}viewtopic.$phpEx", $view_topic_url_params . '&amp;view=unread') . '#unread',
1164                      'U_MCP_REPORT'            => append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=reports&amp;mode=reports&amp;t=' . $result_topic_id, true, $user->session_id),
1165                      'U_MCP_QUEUE'            => $u_mcp_queue,
1166                  );
1167              }
1168              else
1169              {
1170                  if ((isset($zebra['foe']) && in_array($row['poster_id'], $zebra['foe'])) && (!$view || $view != 'show' || $post_id != $row['post_id']))
1171                  {
1172                      $template->assign_block_vars('searchresults', array(
1173                          'S_IGNORE_POST' => true,
1174   
1175                          '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>'))
1176                      );
1177   
1178                      continue;
1179                  }
1180   
1181                  // Replace naughty words such as farty pants
1182                  $row['post_subject'] = censor_text($row['post_subject']);
1183   
1184                  if ($row['display_text_only'])
1185                  {
1186                      // now find context for the searched words
1187                      $row['post_text'] = get_context($row['post_text'], array_filter(explode('|', $hilit), 'strlen'), $return_chars);
1188                      $row['post_text'] = bbcode_nl2br($row['post_text']);
1189                  }
1190                  else
1191                  {
1192                      $parse_flags = ($row['bbcode_bitfield'] ? OPTION_FLAG_BBCODE : 0) | OPTION_FLAG_SMILIES;
1193                      $row['post_text'] = generate_text_for_display($row['post_text'], $row['bbcode_uid'], $row['bbcode_bitfield'], $parse_flags, false);
1194   
1195                      if (!empty($attachments[$row['post_id']]))
1196                      {
1197                          parse_attachments($forum_id, $row['post_text'], $attachments[$row['post_id']], $update_count);
1198   
1199                          // we only display inline attachments
1200                          unset($attachments[$row['post_id']]);
1201                      }
1202                  }
1203   
1204                  if ($hilit)
1205                  {
1206                      // post highlighting
1207                      $row['post_text'] = preg_replace('#(?!<.*)(?<!\w)(' . $hilit . ')(?!\w|[^<>]*(?:</s(?:cript|tyle))?>)#isu', '<span class="posthilit">$1</span>', $row['post_text']);
1208                      $row['post_subject'] = preg_replace('#(?!<.*)(?<!\w)(' . $hilit . ')(?!\w|[^<>]*(?:</s(?:cript|tyle))?>)#isu', '<span class="posthilit">$1</span>', $row['post_subject']);
1209                  }
1210   
1211                  $tpl_ary = array(
1212                      'POST_AUTHOR_FULL'        => get_username_string('full', $row['poster_id'], $row['username'], $row['user_colour'], $row['post_username']),
1213                      'POST_AUTHOR_COLOUR'    => get_username_string('colour', $row['poster_id'], $row['username'], $row['user_colour'], $row['post_username']),
1214                      'POST_AUTHOR'            => get_username_string('username', $row['poster_id'], $row['username'], $row['user_colour'], $row['post_username']),
1215                      'U_POST_AUTHOR'            => get_username_string('profile', $row['poster_id'], $row['username'], $row['user_colour'], $row['post_username']),
1216   
1217                      'POST_SUBJECT'        => $row['post_subject'],
1218                      'POST_DATE'            => (!empty($row['post_time'])) ? $user->format_date($row['post_time']) : '',
1219                      'MESSAGE'            => $row['post_text']
1220                  );
1221              }
1222   
1223              $tpl_ary = array_merge($tpl_ary, array(
1224                  'FORUM_ID'            => $forum_id,
1225                  'TOPIC_ID'            => $result_topic_id,
1226                  'POST_ID'            => ($show_results == 'posts') ? $row['post_id'] : false,
1227   
1228                  'FORUM_TITLE'        => $row['forum_name'],
1229                  'TOPIC_TITLE'        => $topic_title,
1230                  'TOPIC_REPLIES'        => $replies,
1231                  'TOPIC_VIEWS'        => $row['topic_views'],
1232   
1233                  'U_VIEW_TOPIC'        => $view_topic_url,
1234                  'U_VIEW_FORUM'        => append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $forum_id),
1235                  'U_VIEW_POST'        => (!empty($row['post_id'])) ? append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'p=' . $row['post_id'] . (($u_hilit) ? '&amp;hilit=' . $u_hilit : '')) . '#p' . $row['post_id'] : '',
1236              ));
1237   
1238              /**
1239              * Modify the topic data before it is assigned to the template
1240              *
1241              * @event core.search_modify_tpl_ary
1242              * @var    array    row                Array with topic data
1243              * @var    array    tpl_ary            Template block array with topic data
1244              * @var    string    show_results    Display topics or posts
1245              * @var    string    topic_title        Cleaned topic title
1246              * @var    int        replies            The number of topic replies
1247              * @var    string    view_topic_url    The URL to the topic
1248              * @var    string    folder_img        The folder image of the topic
1249              * @var    string    folder_alt        The alt attribute of the topic folder img
1250              * @var    int        topic_type        The topic type
1251              * @var    bool    unread_topic    Whether the topic has unread posts
1252              * @var    bool    topic_unapproved    Whether the topic is unapproved
1253              * @var    int        posts_unapproved    The number of unapproved posts
1254              * @var    bool    topic_deleted    Whether the topic has been deleted
1255              * @var    string    u_mcp_queue        The URL to the corresponding MCP queue page
1256              * @var    array    zebra            The zebra data of the current user
1257              * @var    array    attachments        All the attachments of the search results
1258              * @since 3.1.0-a1
1259              * @changed 3.1.0-b3 Added vars show_results, topic_title, replies,
1260              *        view_topic_url, folder_img, folder_alt, topic_type, unread_topic,
1261              *        topic_unapproved, posts_unapproved, topic_deleted, u_mcp_queue,
1262              *        zebra, attachments
1263              */
1264              $vars = array(
1265                  'row',
1266                  'tpl_ary',
1267                  'show_results',
1268                  'topic_title',
1269                  'replies',
1270                  'view_topic_url',
1271                  'folder_img',
1272                  'folder_alt',
1273                  'topic_type',
1274                  'unread_topic',
1275                  'topic_unapproved',
1276                  'posts_unapproved',
1277                  'topic_deleted',
1278                  'u_mcp_queue',
1279                  'zebra',
1280                  'attachments',
1281              );
1282              extract($phpbb_dispatcher->trigger_event('core.search_modify_tpl_ary', compact($vars)));
1283   
1284              $template->assign_block_vars('searchresults', $tpl_ary);
1285   
1286              if ($show_results == 'topics')
1287              {
1288                  $pagination->generate_template_pagination($view_topic_url, 'searchresults.pagination', 'start', $replies + 1, $config['posts_per_page'], 1, true, true);
1289              }
1290          }
1291   
1292          if ($topic_id && ($topic_id == $result_topic_id))
1293          {
1294              $template->assign_vars(array(
1295                  'SEARCH_TOPIC'        => $topic_title,
1296                  'L_RETURN_TO_TOPIC'    => $user->lang('RETURN_TO', $topic_title),
1297                  'U_SEARCH_TOPIC'    => $view_topic_url
1298              ));
1299          }
1300      }
1301      unset($rowset);
1302   
1303      // Output header
1304      if ($found_more_search_matches)
1305      {
1306          $l_search_matches = $user->lang('FOUND_MORE_SEARCH_MATCHES', (int) $total_match_count);
1307      }
1308      else
1309      {
1310          $l_search_matches = $user->lang('FOUND_SEARCH_MATCHES', (int) $total_match_count);
1311      }
1312   
1313      // Check if search backend supports phrase search or not
1314      $phrase_search_disabled = '';
1315      if (strpos(html_entity_decode($keywords), '"') !== false && method_exists($search, 'supports_phrase_search'))
1316      {
1317          $phrase_search_disabled = $search->supports_phrase_search() ? false : true;
1318      }
1319   
1320      $pagination->generate_template_pagination($u_search, 'pagination', 'start', $total_match_count, $per_page, $start);
1321   
1322      $template->assign_vars(array(
1323          'SEARCH_TITLE'        => $l_search_title,
1324          'SEARCH_MATCHES'    => $l_search_matches,
1325          'SEARCH_WORDS'        => $keywords,
1326          'SEARCHED_QUERY'    => $search->get_search_query(),
1327          'IGNORED_WORDS'        => (!empty($common_words)) ? implode(' ', $common_words) : '',
1328   
1329          'PHRASE_SEARCH_DISABLED'        => $phrase_search_disabled,
1330   
1331          'TOTAL_MATCHES'        => $total_match_count,
1332          'SEARCH_IN_RESULTS'    => ($search_id) ? false : true,
1333   
1334          'S_SELECT_SORT_DIR'        => $s_sort_dir,
1335          'S_SELECT_SORT_KEY'        => $s_sort_key,
1336          'S_SELECT_SORT_DAYS'    => $s_limit_days,
1337          'S_SEARCH_ACTION'        => $u_search,
1338          'S_SHOW_TOPICS'            => ($show_results == 'posts') ? false : true,
1339   
1340          'GOTO_PAGE_IMG'        => $user->img('icon_post_target', 'GOTO_PAGE'),
1341          'NEWEST_POST_IMG'    => $user->img('icon_topic_newest', 'VIEW_NEWEST_POST'),
1342          'REPORTED_IMG'        => $user->img('icon_topic_reported', 'TOPIC_REPORTED'),
1343          'UNAPPROVED_IMG'    => $user->img('icon_topic_unapproved', 'TOPIC_UNAPPROVED'),
1344          'DELETED_IMG'        => $user->img('icon_topic_deleted', 'TOPIC_DELETED'),
1345          'POLL_IMG'            => $user->img('icon_topic_poll', 'TOPIC_POLL'),
1346          'LAST_POST_IMG'        => $user->img('icon_topic_latest', 'VIEW_LATEST_POST'),
1347   
1348          'U_SEARCH_WORDS'    => $u_search,
1349      ));
1350   
1351      /**
1352      * Modify the title and/or load data for the search results page
1353      *
1354      * @event core.search_results_modify_search_title
1355      * @var    int        author_id            ID of the author to search by
1356      * @var    string    l_search_title        The title of the search page
1357      * @var    string    search_id            Predefined search type name
1358      * @var    string    show_results        Search results output mode - topics or posts
1359      * @var    int        start                The starting id of the results
1360      * @var    int        total_match_count    The count of search results
1361      * @var    string    keywords            The search keywords
1362      * @since 3.1.0-RC4
1363      * @changed 3.1.6-RC1 Added total_match_count and keywords
1364      */
1365      $vars = array(
1366          'author_id',
1367          'l_search_title',
1368          'search_id',
1369          'show_results',
1370          'start',
1371          'total_match_count',
1372          'keywords',
1373      );
1374      extract($phpbb_dispatcher->trigger_event('core.search_results_modify_search_title', compact($vars)));
1375   
1376      page_header(($l_search_title) ? $l_search_title : $user->lang['SEARCH']);
1377   
1378      $template->set_filenames(array(
1379          'body' => 'search_results.html')
1380      );
1381      make_jumpbox(append_sid("{$phpbb_root_path}viewforum.$phpEx"));
1382   
1383      page_footer();
1384  }
1385   
1386  // Search forum
1387  $rowset = array();
1388  $s_forums = '';
1389  $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
1390      FROM ' . FORUMS_TABLE . ' f
1391      LEFT JOIN ' . FORUMS_ACCESS_TABLE . " fa ON (fa.forum_id = f.forum_id
1392          AND fa.session_id = '" . $db->sql_escape($user->session_id) . "')
1393      ORDER BY f.left_id ASC";
1394  $result = $db->sql_query($sql);
1395   
1396  while ($row = $db->sql_fetchrow($result))
1397  {
1398      $rowset[(int) $row['forum_id']] = $row;
1399  }
1400  $db->sql_freeresult($result);
1401   
1402  $right = $cat_right = $padding_inc = 0;
1403  $padding = $forum_list = $holding = '';
1404  $pad_store = array('0' => '');
1405   
1406  /**
1407  * Modify the forum select list for advanced search page
1408  *
1409  * @event core.search_modify_forum_select_list
1410  * @var    array    rowset    Array with the forums list data
1411  * @since 3.1.10-RC1
1412  */
1413  $vars = array('rowset');
1414  extract($phpbb_dispatcher->trigger_event('core.search_modify_forum_select_list', compact($vars)));
1415   
1416  foreach ($rowset as $row)
1417  {
1418      if ($row['forum_type'] == FORUM_CAT && ($row['left_id'] + 1 == $row['right_id']))
1419      {
1420          // Non-postable forum with no subforums, don't display
1421          continue;
1422      }
1423   
1424      if ($row['forum_type'] == FORUM_POST && ($row['left_id'] + 1 == $row['right_id']) && !$row['enable_indexing'])
1425      {
1426          // Postable forum with no subforums and indexing disabled, don't display
1427          continue;
1428      }
1429   
1430      if ($row['forum_type'] == FORUM_LINK || ($row['forum_password'] && !$row['user_id']))
1431      {
1432          // if this forum is a link or password protected (user has not entered the password yet) then skip to the next branch
1433          continue;
1434      }
1435   
1436      if ($row['left_id'] < $right)
1437      {
1438          $padding .= '&nbsp; &nbsp;';
1439          $pad_store[$row['parent_id']] = $padding;
1440      }
1441      else if ($row['left_id'] > $right + 1)
1442      {
1443          if (isset($pad_store[$row['parent_id']]))
1444          {
1445              $padding = $pad_store[$row['parent_id']];
1446          }
1447          else
1448          {
1449              continue;
1450          }
1451      }
1452   
1453      $right = $row['right_id'];
1454   
1455      if ($auth->acl_gets('!f_search', '!f_list', $row['forum_id']))
1456      {
1457          // if the user does not have permissions to search or see this forum skip only this forum/category
1458          continue;
1459      }
1460   
1461      $selected = (in_array($row['forum_id'], $search_forum)) ? ' selected="selected"' : '';
1462   
1463      if ($row['left_id'] > $cat_right)
1464      {
1465          // make sure we don't forget anything
1466          $s_forums .= $holding;
1467          $holding = '';
1468      }
1469   
1470      if ($row['right_id'] - $row['left_id'] > 1)
1471      {
1472          $cat_right = max($cat_right, $row['right_id']);
1473   
1474          $holding .= '<option value="' . $row['forum_id'] . '"' . $selected . '>' . $padding . $row['forum_name'] . '</option>';
1475      }
1476      else
1477      {
1478          $s_forums .= $holding . '<option value="' . $row['forum_id'] . '"' . $selected . '>' . $padding . $row['forum_name'] . '</option>';
1479          $holding = '';
1480      }
1481  }
1482   
1483  if ($holding)
1484  {
1485      $s_forums .= $holding;
1486  }
1487   
1488  unset($pad_store);
1489  unset($rowset);
1490   
1491  if (!$s_forums)
1492  {
1493      trigger_error('NO_SEARCH');
1494  }
1495   
1496  /**
1497   * Build options for a select list for the number of characters returned.
1498   *
1499   * If the admin defined amount is not within the predefined range,
1500   * and the admin did not set it to unlimited (0), we add that option aswell.
1501   *
1502   * @deprecated 3.3.1-RC1    Templates should use an numeric input, in favor of a select.
1503   */
1504  $s_characters = '<option value="0">' . $language->lang('ALL_AVAILABLE') . '</option>';
1505  $i_characters = array_merge([25, 50], range(100, 1000, 100));
1506   
1507  if ($config['default_search_return_chars'] && !in_array((int) $config['default_search_return_chars'], $i_characters))
1508  {
1509      $i_characters[] = (int) $config['default_search_return_chars'];
1510      sort($i_characters);
1511  }
1512   
1513  foreach ($i_characters as $i)
1514  {
1515      $selected = $i === (int) $config['default_search_return_chars'] ? ' selected="selected"' : '';
1516      $s_characters .= sprintf('<option value="%1$s"%2$s>%1$s</option>', $i, $selected);
1517  }
1518   
1519  $s_hidden_fields = array('t' => $topic_id);
1520   
1521  if ($_SID)
1522  {
1523      $s_hidden_fields['sid'] = $_SID;
1524  }
1525   
1526  if (!empty($_EXTRA_URL))
1527  {
1528      foreach ($_EXTRA_URL as $url_param)
1529      {
1530          $url_param = explode('=', $url_param, 2);
1531          $s_hidden_fields[$url_param[0]] = $url_param[1];
1532      }
1533  }
1534   
1535  $template->assign_vars(array(
1536      'DEFAULT_RETURN_CHARS'    => (int) $config['default_search_return_chars'],
1537      'S_SEARCH_ACTION'        => append_sid("{$phpbb_root_path}search.$phpEx", false, true, 0), // We force no ?sid= appending by using 0
1538      'S_HIDDEN_FIELDS'        => build_hidden_fields($s_hidden_fields),
1539      'S_CHARACTER_OPTIONS'    => $s_characters,
1540      'S_FORUM_OPTIONS'        => $s_forums,
1541      'S_SELECT_SORT_DIR'        => $s_sort_dir,
1542      'S_SELECT_SORT_KEY'        => $s_sort_key,
1543      'S_SELECT_SORT_DAYS'    => $s_limit_days,
1544      'S_IN_SEARCH'            => true,
1545  ));
1546   
1547  // only show recent searches to search administrators
1548  if ($auth->acl_get('a_search'))
1549  {
1550      // Handle large objects differently for Oracle and MSSQL
1551      switch ($db->get_sql_layer())
1552      {
1553          case 'oracle':
1554              $sql = 'SELECT search_time, search_keywords
1555                  FROM ' . SEARCH_RESULTS_TABLE . '
1556                  WHERE dbms_lob.getlength(search_keywords) > 0
1557                  ORDER BY search_time DESC';
1558          break;
1559   
1560          case 'mssql_odbc':
1561          case 'mssqlnative':
1562              $sql = 'SELECT search_time, search_keywords
1563                  FROM ' . SEARCH_RESULTS_TABLE . '
1564                  WHERE DATALENGTH(search_keywords) > 0
1565                  ORDER BY search_time DESC';
1566          break;
1567   
1568          default:
1569              $sql = 'SELECT search_time, search_keywords
1570                  FROM ' . SEARCH_RESULTS_TABLE . '
1571                  WHERE search_keywords <> \'\'
1572                  ORDER BY search_time DESC';
1573          break;
1574      }
1575      $result = $db->sql_query_limit($sql, 5);
1576   
1577      while ($row = $db->sql_fetchrow($result))
1578      {
1579          $keywords = $row['search_keywords'];
1580   
1581          $template->assign_block_vars('recentsearch', array(
1582              'KEYWORDS'    => $keywords,
1583              'TIME'        => $user->format_date($row['search_time']),
1584   
1585              'U_KEYWORDS'    => append_sid("{$phpbb_root_path}search.$phpEx", 'keywords=' . urlencode(html_entity_decode($keywords, ENT_COMPAT)))
1586          ));
1587      }
1588      $db->sql_freeresult($result);
1589  }
1590   
1591  // Output the basic page
1592  page_header($user->lang['SEARCH']);
1593   
1594  $template->set_filenames(array(
1595      'body' => 'search_body.html')
1596  );
1597  make_jumpbox(append_sid("{$phpbb_root_path}viewforum.$phpEx"));
1598   
1599  page_footer();
1600