Verzeichnisstruktur phpBB-3.3.16


Veröffentlicht
27.04.2026

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