[ Index ]

PHP Cross Reference of phpBB 3.0 Beta 3

title

Body

[close]

/includes/search/ -> search.php (source)

   1  <?php
   2  /** 
   3  *
   4  * @package search
   5  * @version $Id: search.php,v 1.12 2006/09/02 13:33:06 acydburn Exp $
   6  * @copyright (c) 2005 phpBB Group 
   7  * @license http://opensource.org/licenses/gpl-license.php GNU Public License 
   8  *
   9  */
  10  
  11  /**
  12  */
  13  if (!defined('IN_PHPBB'))
  14  {
  15      exit;
  16  }
  17  
  18  /**
  19  * @ignore
  20  */
  21  define('SEARCH_RESULT_NOT_IN_CACHE', 0);
  22  define('SEARCH_RESULT_IN_CACHE', 1);
  23  define('SEARCH_RESULT_INCOMPLETE', 2);
  24  
  25  /**
  26  * search_backend
  27  * optional base class for search plugins providing simple caching based on ACM
  28  * and functions to retrieve ignore_words and synonyms
  29  * @package search
  30  */
  31  class search_backend
  32  {
  33      var $ignore_words = array();
  34      var $match_synonym = array();
  35      var $replace_synonym = array();
  36  
  37  	function search_backend(&$error)
  38      {
  39          // This class cannot be used as a search plugin
  40          $error = true;
  41      }
  42  
  43      /**
  44      * Retrieves a language dependend list of words that should be ignored by the search
  45      */
  46  	function get_ignore_words()
  47      {
  48          if (!sizeof($this->ignore_words))
  49          {
  50              global $user, $phpEx;
  51  
  52              $words = array();
  53  
  54              if (file_exists("{$user->lang_path}/search_ignore_words.$phpEx"))
  55              {
  56                  // include the file containing ignore words
  57                  include("{$user->lang_path}/search_ignore_words.$phpEx");
  58              }
  59  
  60              $this->ignore_words = $words;
  61              unset($words);
  62          }
  63      }
  64  
  65      /**
  66      * Stores a list of synonyms that should be replaced in $this->match_synonym and $this->replace_synonym and caches them
  67      */
  68  	function get_synonyms()
  69      {
  70          if (!sizeof($this->match_synonym))
  71          {
  72              global $user, $phpEx;
  73  
  74              $synonyms = array();
  75  
  76              if (file_exists("{$user->lang_path}/search_synonyms.$phpEx"))
  77              {
  78                  // include the file containing synonyms
  79                  include("{$user->lang_path}/search_synonyms.$phpEx");
  80              }
  81  
  82              $this->match_synonym = array_keys($synonyms);
  83              $this->replace_synonym = array_values($synonyms);
  84  
  85              unset($synonyms);
  86          }
  87      }
  88  
  89      /**
  90      * Retrieves cached search results
  91      *
  92      * @param int result_count will contain the number of all results for the search (not only for the current page)
  93      * @param array id_ary is filled with the ids belonging to the requested page that are stored in the cache
  94      *
  95      * @return int SEARCH_RESULT_NOT_IN_CACHE or SEARCH_RESULT_IN_CACHE or SEARCH_RESULT_INCOMPLETE
  96      */
  97  	function obtain_ids($search_key, &$result_count, &$id_ary, $start, $per_page, $sort_dir)
  98      {
  99          global $cache;
 100  
 101          if (!($stored_ids = $cache->get('_search_results_' . $search_key)))
 102          {
 103              // no search results cached for this search_key
 104              return SEARCH_RESULT_NOT_IN_CACHE;
 105          }
 106          else
 107          {
 108              $result_count = $stored_ids[-1];
 109              $reverse_ids = ($stored_ids[-2] != $sort_dir) ? true : false;
 110              $complete = true;
 111  
 112              // change the start to the actual end of the current request if the sort direction differs
 113              // from the dirction in the cache and reverse the ids later
 114              if ($reverse_ids)
 115              {
 116                  $start = $result_count - $start - $per_page;
 117  
 118                  // the user requested a page past the last index
 119                  if ($start < 0)
 120                  {
 121                      return SEARCH_RESULT_NOT_IN_CACHE;
 122                  }
 123              }
 124  
 125              for ($i = $start, $n = $start + $per_page; ($i < $n) && ($i < $result_count); $i++)
 126              {
 127                  if (!isset($stored_ids[$i]))
 128                  {
 129                      $complete = false;
 130                  }
 131                  else
 132                  {
 133                      $id_ary[] = $stored_ids[$i];
 134                  }
 135              }
 136              unset($stored_ids);
 137  
 138              if ($reverse_ids)
 139              {
 140                  $id_ary = array_reverse($id_ary);
 141              }
 142  
 143              if (!$complete)
 144              {
 145                  return SEARCH_RESULT_INCOMPLETE;
 146              }
 147              return SEARCH_RESULT_IN_CACHE;
 148          }
 149      }
 150  
 151      /**
 152      * Caches post/topic ids
 153      *
 154      * @param array id_ary contains a list of post or topic ids that shall be cached, the first element
 155      *     must have the absolute index $start in the result set.
 156      */
 157  	function save_ids($search_key, $keywords, $author_ary, $result_count, &$id_ary, $start, $sort_dir)
 158      {
 159          global $cache, $config, $db, $user;
 160  
 161          $length = min(sizeof($id_ary), $config['search_block_size']);
 162  
 163          // nothing to cache so exit
 164          if (!$length)
 165          {
 166              return;
 167          }
 168  
 169          $store_ids = array_slice($id_ary, 0, $length);
 170  
 171          // create a new resultset if there is none for this search_key yet
 172          // or add the ids to the existing resultset
 173          if (!($store = $cache->get('_search_results_' . $search_key)))
 174          {
 175              // add the current keywords to the recent searches in the cache which are listed on the search page
 176              if (!empty($keywords) || sizeof($author_ary))
 177              {
 178                  $sql = 'SELECT search_time
 179                      FROM ' . SEARCH_RESULTS_TABLE . '
 180                      WHERE search_key = \'' . $db->sql_escape($search_key) . '\'';
 181                  $result = $db->sql_query($sql);
 182  
 183                  if (!$db->sql_fetchrow($result))
 184                  {
 185                      $sql_ary = array(
 186                          'search_key'        => $search_key,
 187                          'search_time'        => time(),
 188                          'search_keywords'    => $keywords,
 189                          'search_authors'    => ' ' . implode(' ', $author_ary) . ' '
 190                      );
 191  
 192                      $sql = 'INSERT INTO ' . SEARCH_RESULTS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary);
 193                      $db->sql_query($sql);
 194                  }
 195                  $db->sql_freeresult($result);
 196              }
 197  
 198              $sql = 'UPDATE ' . USERS_TABLE . '
 199                  SET user_last_search = ' . time() . '
 200                  WHERE user_id = ' . $user->data['user_id'];
 201              $db->sql_query($sql);
 202  
 203              $store = array(-1 => $result_count, -2 => $sort_dir);
 204              $id_range = range($start, $start + $length - 1);
 205          }
 206          else
 207          {
 208              // we use one set of results for both sort directions so we have to calculate the indizes
 209              // for the reversed array and we also have to reverse the ids themselves
 210              if ($store[-2] != $sort_dir)
 211              {
 212                  $store_ids = array_reverse($store_ids);
 213                  $id_range = range($store[-1] - $start - $length, $store[-1] - $start - 1);
 214              }
 215              else
 216              {
 217                  $id_range = range($start, $start + $length - 1);
 218              }
 219          }
 220  
 221          $store_ids = array_combine($id_range, $store_ids);
 222  
 223          // append the ids
 224          if (is_array($store_ids))
 225          {
 226              $store += $store_ids;
 227  
 228              // if the cache is too big
 229              if (sizeof($store) - 2 > 20 * $config['search_block_size'])
 230              {
 231                  // remove everything in front of two blocks in front of the current start index
 232                  for ($i = 0, $n = $id_range[0] - 2 * $config['search_block_size']; $i < $n; $i++)
 233                  {
 234                      if (isset($store[$i]))
 235                      {
 236                          unset($store[$i]);
 237                      }
 238                  }
 239  
 240                  // remove everything after two blocks after the current stop index
 241                  end($id_range);
 242                  for ($i = $store[-1] - 1, $n = current($id_range) + 2 * $config['search_block_size']; $i > $n; $i--)
 243                  {
 244                      if (isset($store[$i]))
 245                      {
 246                          unset($store[$i]);
 247                      }
 248                  }
 249              }
 250              $cache->put('_search_results_' . $search_key, $store, $config['search_store_results']);
 251  
 252              $sql = 'UPDATE ' . SEARCH_RESULTS_TABLE . ' 
 253                  SET search_time = ' . time() . '
 254                  WHERE search_key = \'' . $db->sql_escape($search_key) . '\'';
 255              $db->sql_query($sql);
 256          }
 257  
 258          unset($store);
 259          unset($store_ids);
 260          unset($id_range);
 261      }
 262  
 263      /**
 264      * Removes old entries from the search results table and removes searches with keywords that contain a word in $words.
 265      */
 266  	function destroy_cache($words, $authors = false)
 267      {
 268          global $db, $cache, $config;
 269  
 270          // clear all searches that searched for the specified words
 271          if (sizeof($words))
 272          {
 273              $sql_where = '';
 274              foreach ($words as $word)
 275              {
 276                  $sql_where .= ' OR search_keywords LIKE \'%' . $db->sql_escape($word) . '%\'';
 277              }
 278  
 279              $sql = 'SELECT search_key
 280                  FROM ' . SEARCH_RESULTS_TABLE . "
 281                  WHERE search_keywords LIKE '%*%' $sql_where";
 282              $result = $db->sql_query($sql);
 283  
 284              while ($row = $db->sql_fetchrow($result))
 285              {
 286                  $cache->destroy('_search_results_' . $row['search_key']);
 287              }
 288              $db->sql_freeresult($result);
 289          }
 290  
 291          // clear all searches that searched for the specified authors
 292          if (is_array($authors) && sizeof($authors))
 293          {
 294              $sql_where = '';
 295              foreach ($authors as $author)
 296              {
 297                  $sql_where .= (($sql_where) ? ' OR ' : '') . 'search_authors LIKE \'% ' . (int) $author . ' %\'';
 298              }
 299  
 300              $sql = 'SELECT search_key
 301                  FROM ' . SEARCH_RESULTS_TABLE . "
 302                  WHERE $sql_where";
 303              $result = $db->sql_query($sql);
 304  
 305              while ($row = $db->sql_fetchrow($result))
 306              {
 307                  $cache->destroy('_search_results_' . $row['search_key']);
 308              }
 309              $db->sql_freeresult($result);
 310          }
 311  
 312          $sql = 'DELETE
 313              FROM ' . SEARCH_RESULTS_TABLE . '
 314              WHERE search_time < ' . (time() - $config['search_store_results']);
 315          $db->sql_query($sql);
 316      }
 317  }
 318  
 319  ?>


Generated: Wed Nov 22 00:35:05 2006 Cross-referenced by PHPXref 0.6