root / trunk / phpBB / includes / search / search.php

View | Annotate | Download (8 KB)

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