Verzeichnisstruktur phpBB-3.1.0


Veröffentlicht
27.10.2014

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