Ignore:
Timestamp:
Nov 14, 2011, 11:17:15 PM (13 years ago)
Author:
dj3c1t
Message:

passage a Fluxbb 1.4.7

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/rsr.v5.1.dev/web/punbb/search.php

    r1 r3  
    11<?php
    2 /***********************************************************************
    3 
    4   Copyright (C) 2002-2005  Rickard Andersson (rickard@punbb.org)
    5 
    6   This file is part of PunBB.
    7 
    8   PunBB is free software; you can redistribute it and/or modify it
    9   under the terms of the GNU General Public License as published
    10   by the Free Software Foundation; either version 2 of the License,
    11   or (at your option) any later version.
    12 
    13   PunBB is distributed in the hope that it will be useful, but
    14   WITHOUT ANY WARRANTY; without even the implied warranty of
    15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    16   GNU General Public License for more details.
    17 
    18   You should have received a copy of the GNU General Public License
    19   along with this program; if not, write to the Free Software
    20   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
    21   MA  02111-1307  USA
    22 
    23 ************************************************************************/
    24 
     2
     3/**
     4 * Copyright (C) 2008-2011 FluxBB
     5 * based on code by Rickard Andersson copyright (C) 2002-2008 PunBB
     6 * License: http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
     7 */
    258
    269// The contents of this file are very much inspired by the file search.php
    27 // from the phpBB Group forum software phpBB2 (http://www.phpbb.com).
    28 
    29 
    30 define('PUN_ROOT', './');
     10// from the phpBB Group forum software phpBB2 (http://www.phpbb.com)
     11
     12define('PUN_ROOT', dirname(__FILE__).'/');
    3113require PUN_ROOT.'include/common.php';
    32 
    3314
    3415// Load the search.php language file
    3516require PUN_ROOT.'lang/'.$pun_user['language'].'/search.php';
     17require PUN_ROOT.'lang/'.$pun_user['language'].'/forum.php';
    3618
    3719
     
    4123        message($lang_search['No search permission']);
    4224
    43 
    44 // Detect two byte character sets
    45 $multibyte = (isset($lang_common['lang_multibyte']) && $lang_common['lang_multibyte']) ? true : false;
    46 
     25require PUN_ROOT.'include/search_idx.php';
    4726
    4827// Figure out what to do :-)
     
    5029{
    5130        $action = (isset($_GET['action'])) ? $_GET['action'] : null;
    52         $forum = (isset($_GET['forum'])) ? intval($_GET['forum']) : -1;
    53         $sort_dir = (isset($_GET['sort_dir'])) ? (($_GET['sort_dir'] == 'DESC') ? 'DESC' : 'ASC') : 'DESC';
    54         if (isset($search_id)) unset($search_id);
     31        $forums = isset($_GET['forums']) ? (is_array($_GET['forums']) ? $_GET['forums'] : explode(',', $_GET['forums'])) : (isset($_GET['forum']) ? array($_GET['forum']) : array());
     32        $sort_dir = (isset($_GET['sort_dir']) && $_GET['sort_dir'] == 'DESC') ? 'DESC' : 'ASC';
     33
     34        $forums = array_map('intval', $forums);
     35
     36        // Allow the old action names for backwards compatibility reasons
     37        if ($action == 'show_user')
     38                $action = 'show_user_posts';
     39        else if ($action == 'show_24h')
     40                $action = 'show_recent';
    5541
    5642        // If a search_id was supplied
     
    6450        else if ($action == 'search')
    6551        {
    66                 $keywords = (isset($_GET['keywords'])) ? strtolower(trim($_GET['keywords'])) : null;
    67                 $author = (isset($_GET['author'])) ? strtolower(trim($_GET['author'])) : null;
    68                
    69                 if (preg_match('#^[\*%]+$#', $keywords) || strlen(str_replace(array('*', '%'), '', $keywords)) < 3)
     52                $keywords = (isset($_GET['keywords'])) ? utf8_strtolower(pun_trim($_GET['keywords'])) : null;
     53                $author = (isset($_GET['author'])) ? utf8_strtolower(pun_trim($_GET['author'])) : null;
     54
     55                if (preg_match('%^[\*\%]+$%', $keywords) || (pun_strlen(str_replace(array('*', '%'), '', $keywords)) < PUN_SEARCH_MIN_WORD && !is_cjk($keywords)))
    7056                        $keywords = '';
    7157
    72                 if (preg_match('#^[\*%]+$#', $author) || strlen(str_replace(array('*', '%'), '', $author)) < 3)
     58                if (preg_match('%^[\*\%]+$%', $author) || pun_strlen(str_replace(array('*', '%'), '', $author)) < 2)
    7359                        $author = '';
    7460
     
    7965                        $author = str_replace('*', '%', $author);
    8066
    81                 $show_as = (isset($_GET['show_as'])) ? $_GET['show_as'] : 'posts';
    82                 $sort_by = (isset($_GET['sort_by'])) ? intval($_GET['sort_by']) : null;
    83                 $search_in = (!isset($_GET['search_in']) || $_GET['search_in'] == 'all') ? 0 : (($_GET['search_in'] == 'message') ? 1 : -1);
     67                $show_as = (isset($_GET['show_as']) && $_GET['show_as'] == 'topics') ? 'topics' : 'posts';
     68                $sort_by = (isset($_GET['sort_by'])) ? intval($_GET['sort_by']) : 0;
     69                $search_in = (!isset($_GET['search_in']) || $_GET['search_in'] == '0') ? 0 : (($_GET['search_in'] == '1') ? 1 : -1);
    8470        }
    85         // If it's a user search (by id)
    86         else if ($action == 'show_user')
     71        // If it's a user search (by ID)
     72        else if ($action == 'show_user_posts' || $action == 'show_user_topics' || $action == 'show_subscriptions')
    8773        {
    88                 $user_id = intval($_GET['user_id']);
     74                $user_id = (isset($_GET['user_id'])) ? intval($_GET['user_id']) : $pun_user['id'];
    8975                if ($user_id < 2)
    9076                        message($lang_common['Bad request']);
     77
     78                // Subscribed topics can only be viewed by admins, moderators and the users themselves
     79                if ($action == 'show_subscriptions' && !$pun_user['is_admmod'] && $user_id != $pun_user['id'])
     80                        message($lang_common['No permission']);
    9181        }
    92         else
     82        else if ($action == 'show_recent')
     83                $interval = isset($_GET['value']) ? intval($_GET['value']) : 86400;
     84        else if ($action == 'show_replies')
    9385        {
    94                 if ($action != 'show_new' && $action != 'show_24h' && $action != 'show_unanswered' && $action != 'show_subscriptions')
     86                if ($pun_user['is_guest'])
    9587                        message($lang_common['Bad request']);
    9688        }
     89        else if ($action != 'show_new' && $action != 'show_unanswered')
     90                message($lang_common['Bad request']);
    9791
    9892
     
    10296                $ident = ($pun_user['is_guest']) ? get_remote_address() : $pun_user['username'];
    10397
    104                 $result = $db->query('SELECT search_data FROM '.$db->prefix.'search_cache WHERE id='.$search_id.' AND ident=\''.$db->escape($ident).'\'') or error('Impossible de retrouver les résultats de la recherche', __FILE__, __LINE__, $db->error());
     98                $result = $db->query('SELECT search_data FROM '.$db->prefix.'search_cache WHERE id='.$search_id.' AND ident=\''.$db->escape($ident).'\'') or error('Unable to fetch search results', __FILE__, __LINE__, $db->error());
    10599                if ($row = $db->fetch_assoc($result))
    106100                {
    107101                        $temp = unserialize($row['search_data']);
    108102
    109                         $search_results = $temp['search_results'];
     103                        $search_ids = unserialize($temp['search_ids']);
    110104                        $num_hits = $temp['num_hits'];
    111105                        $sort_by = $temp['sort_by'];
    112106                        $sort_dir = $temp['sort_dir'];
    113107                        $show_as = $temp['show_as'];
     108                        $search_type = $temp['search_type'];
    114109
    115110                        unset($temp);
     
    123118
    124119                // Search a specific forum?
    125                 $forum_sql = ($forum != -1) ? ' AND t.forum_id = '.$forum : '';
     120                $forum_sql = (!empty($forums) || (empty($forums) && $pun_config['o_search_all_forums'] == '0' && !$pun_user['is_admmod'])) ? ' AND t.forum_id IN ('.implode(',', $forums).')' : '';
    126121
    127122                if (!empty($author) || !empty($keywords))
    128123                {
     124                        // Flood protection
     125                        if ($pun_user['last_search'] && (time() - $pun_user['last_search']) < $pun_user['g_search_flood'] && (time() - $pun_user['last_search']) >= 0)
     126                                message(sprintf($lang_search['Search flood'], $pun_user['g_search_flood']));
     127
     128                        if (!$pun_user['is_guest'])
     129                                $db->query('UPDATE '.$db->prefix.'users SET last_search='.time().' WHERE id='.$pun_user['id']) or error('Unable to update user', __FILE__, __LINE__, $db->error());
     130                        else
     131                                $db->query('UPDATE '.$db->prefix.'online SET last_search='.time().' WHERE ident=\''.$db->escape(get_remote_address()).'\'' ) or error('Unable to update user', __FILE__, __LINE__, $db->error());
     132
     133                        switch ($sort_by)
     134                        {
     135                                case 1:
     136                                        $sort_by_sql = ($show_as == 'topics') ? 't.poster' : 'p.poster';
     137                                        $sort_type = SORT_STRING;
     138                                        break;
     139
     140                                case 2:
     141                                        $sort_by_sql = 't.subject';
     142                                        $sort_type = SORT_STRING;
     143                                        break;
     144
     145                                case 3:
     146                                        $sort_by_sql = 't.forum_id';
     147                                        $sort_type = SORT_NUMERIC;
     148                                        break;
     149
     150                                case 4:
     151                                        $sort_by_sql = 't.last_post';
     152                                        $sort_type = SORT_NUMERIC;
     153                                        break;
     154
     155                                default:
     156                                        $sort_by_sql = ($show_as == 'topics') ? 't.last_post' : 'p.posted';
     157                                        $sort_type = SORT_NUMERIC;
     158                                        break;
     159                        }
     160
    129161                        // If it's a search for keywords
    130162                        if ($keywords)
    131163                        {
    132                                 $stopwords = (array)@file(PUN_ROOT.'lang/'.$pun_user['language'].'/stopwords.txt');
    133                                 $stopwords = array_map('trim', $stopwords);
    134 
    135                                 // Are we searching for multibyte charset text?
    136                                 if ($multibyte)
    137                                 {
    138                                         // Strip out excessive whitespace
    139                                         $keywords = trim(preg_replace('#\s+#', ' ', $keywords));
    140 
    141                                         $keywords_array = explode(' ', $keywords);
    142                                 }
    143                                 else
    144                                 {
    145                                         // Filter out non-alphabetical chars
    146                                         $noise_match = array('^', '$', '&', '(', ')', '<', '>', '`', '\'', '"', '|', ',', '@', '_', '?', '%', '~', '[', ']', '{', '}', ':', '\\', '/', '=', '#', '\'', ';', '!', '€');
    147                                         $noise_replace = array(' ', ' ', ' ', ' ', ' ', ' ', ' ', '',  '',   ' ', ' ', ' ', ' ', '',  ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '' ,  ' ', ' ', ' ', ' ',  ' ', ' ', ' ');
    148                                         $keywords = str_replace($noise_match, $noise_replace, $keywords);
    149 
    150                                         // Strip out excessive whitespace
    151                                         $keywords = trim(preg_replace('#\s+#', ' ', $keywords));
    152 
    153                                         // Fill an array with all the words
    154                                         $keywords_array = explode(' ', $keywords);
    155 
    156                                         if (empty($keywords_array))
    157                                                 message($lang_search['No hits']);
    158 
    159                                         while (list($i, $word) = @each($keywords_array))
    160                                         {
    161                                                 $num_chars = pun_strlen($word);
    162 
    163                                                 if ($num_chars < 3 || $num_chars > 20 || in_array($word, $stopwords))
    164                                                         unset($keywords_array[$i]);
    165                                         }
    166 
    167                                         // Should we search in message body or topic subject specifically?
    168                                         $search_in_cond = ($search_in) ? (($search_in > 0) ? ' AND m.subject_match = 0' : ' AND m.subject_match = 1') : '';
    169                                 }
     164                                // split the keywords into words
     165                                $keywords_array = split_words($keywords, false);
     166
     167                                if (empty($keywords_array))
     168                                        message($lang_search['No hits']);
     169
     170                                // Should we search in message body or topic subject specifically?
     171                                $search_in_cond = ($search_in) ? (($search_in > 0) ? ' AND m.subject_match = 0' : ' AND m.subject_match = 1') : '';
    170172
    171173                                $word_count = 0;
    172174                                $match_type = 'and';
    173                                 @reset($keywords_array);
    174                                 while (list(, $cur_word) = @each($keywords_array))
     175
     176                                $sort_data = array();
     177                                foreach ($keywords_array as $cur_word)
    175178                                {
    176179                                        switch ($cur_word)
     
    184187                                                default:
    185188                                                {
    186                                                         // Are we searching for multibyte charset text?
    187                                                         if ($multibyte)
     189                                                        if (is_cjk($cur_word))
    188190                                                        {
    189                                                                 $cur_word = $db->escape('%'.str_replace('*', '', $cur_word).'%');
    190                                                                 $cur_word_like = ($db_type == 'pgsql') ? 'ILIKE \''.$cur_word.'\'' : 'LIKE \''.$cur_word.'\'';
    191 
    192                                                                 if ($search_in > 0)
    193                                                                         $sql = 'SELECT id FROM '.$db->prefix.'posts WHERE message '.$cur_word_like;
    194                                                                 else if ($search_in < 0)
    195                                                                         $sql = 'SELECT p.id FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'topics AS t ON t.id=p.topic_id WHERE t.subject '.$cur_word_like.' GROUP BY p.id, t.id';
    196                                                                 else
    197                                                                         $sql = 'SELECT p.id FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'topics AS t ON t.id=p.topic_id WHERE p.message '.$cur_word_like.' OR t.subject '.$cur_word_like.' GROUP BY p.id, t.id';
     191                                                                $where_cond = str_replace('*', '%', $cur_word);
     192                                                                $where_cond = ($search_in ? (($search_in > 0) ? 'p.message LIKE \'%'.$db->escape($where_cond).'%\'' : 't.subject LIKE \'%'.$db->escape($where_cond).'%\'') : 'p.message LIKE \'%'.$db->escape($where_cond).'%\' OR t.subject LIKE \'%'.$db->escape($where_cond).'%\'');
     193
     194                                                                $result = $db->query('SELECT p.id AS post_id, p.topic_id, '.$sort_by_sql.' AS sort_by FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'topics AS t ON t.id=p.topic_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=t.forum_id AND fp.group_id='.$pun_user['g_id'].') WHERE ('.$where_cond.') AND (fp.read_forum IS NULL OR fp.read_forum=1)'.$forum_sql, true) or error('Unable to search for posts', __FILE__, __LINE__, $db->error());
    198195                                                        }
    199196                                                        else
     197                                                                $result = $db->query('SELECT m.post_id, p.topic_id, '.$sort_by_sql.' AS sort_by FROM '.$db->prefix.'search_words AS w INNER JOIN '.$db->prefix.'search_matches AS m ON m.word_id = w.id INNER JOIN '.$db->prefix.'posts AS p ON p.id=m.post_id INNER JOIN '.$db->prefix.'topics AS t ON t.id=p.topic_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=t.forum_id AND fp.group_id='.$pun_user['g_id'].') WHERE w.word LIKE \''.$db->escape(str_replace('*', '%', $cur_word)).'\''.$search_in_cond.' AND (fp.read_forum IS NULL OR fp.read_forum=1)'.$forum_sql, true) or error('Unable to search for posts', __FILE__, __LINE__, $db->error());
     198
     199                                                        $row = array();
     200                                                        while ($temp = $db->fetch_assoc($result))
    200201                                                        {
    201                                                                 $cur_word = str_replace('*', '%', $cur_word);
    202                                                                 $sql = 'SELECT m.post_id FROM '.$db->prefix.'search_words AS w INNER JOIN '.$db->prefix.'search_matches AS m ON m.word_id = w.id WHERE w.word LIKE \''.$cur_word.'\''.$search_in_cond;
    203                                                         }
    204 
    205                                                         $result = $db->query($sql, true) or error('Impossible de rechercher les messages', __FILE__, __LINE__, $db->error());
    206 
    207                                                         $row = array();
    208                                                         while ($temp = $db->fetch_row($result))
    209                                                         {
    210                                                                 $row[$temp[0]] = 1;
     202                                                                $row[$temp['post_id']] = $temp['topic_id'];
    211203
    212204                                                                if (!$word_count)
    213                                                                         $result_list[$temp[0]] = 1;
     205                                                                {
     206                                                                        $keyword_results[$temp['post_id']] = $temp['topic_id'];
     207                                                                        $sort_data[$temp['post_id']] = $temp['sort_by'];
     208                                                                }
    214209                                                                else if ($match_type == 'or')
    215                                                                         $result_list[$temp[0]] = 1;
     210                                                                {
     211                                                                        $keyword_results[$temp['post_id']] = $temp['topic_id'];
     212                                                                        $sort_data[$temp['post_id']] = $temp['sort_by'];
     213                                                                }
    216214                                                                else if ($match_type == 'not')
    217                                                                         $result_list[$temp[0]] = 0;
     215                                                                {
     216                                                                        unset($keyword_results[$temp['post_id']]);
     217                                                                        unset($sort_data[$temp['post_id']]);
     218                                                                }
    218219                                                        }
    219220
    220221                                                        if ($match_type == 'and' && $word_count)
    221222                                                        {
    222                                                                 @reset($result_list);
    223                                                                 while (list($post_id,) = @each($result_list))
     223                                                                foreach ($keyword_results as $post_id => $topic_id)
    224224                                                                {
    225225                                                                        if (!isset($row[$post_id]))
    226                                                                                 $result_list[$post_id] = 0;
     226                                                                        {
     227                                                                                unset($keyword_results[$post_id]);
     228                                                                                unset($sort_data[$post_id]);
     229                                                                        }
    227230                                                                }
    228231                                                        }
     
    236239                                }
    237240
    238                                 @reset($result_list);
    239                                 while (list($post_id, $matches) = @each($result_list))
    240                                 {
    241                                         if ($matches)
    242                                                 $keyword_results[] = $post_id;
    243                                 }
    244 
    245                                 unset($result_list);
     241                                // Sort the results - annoyingly array_multisort re-indexes arrays with numeric keys, so we need to split the keys out into a seperate array then combine them again after
     242                                $post_ids = array_keys($keyword_results);
     243                                $topic_ids = array_values($keyword_results);
     244
     245                                array_multisort(array_values($sort_data), $sort_dir == 'DESC' ? SORT_DESC : SORT_ASC, $sort_type, $post_ids, $topic_ids);
     246
     247                                // combine the arrays back into a key=>value array (array_combine is PHP5 only unfortunately)
     248                                $num_results = count($keyword_results);
     249                                $keyword_results = array();
     250                                for ($i = 0;$i < $num_results;$i++)
     251                                        $keyword_results[$post_ids[$i]] = $topic_ids[$i];
     252
     253                                unset($sort_data, $post_ids, $topic_ids);
    246254                        }
    247255
    248256                        // If it's a search for author name (and that author name isn't Guest)
    249                         if ($author && strcasecmp($author, 'Guest') && strcasecmp($author, $lang_common['Guest']))
     257                        if ($author && $author != 'guest' && $author != utf8_strtolower($lang_common['Guest']))
    250258                        {
    251259                                switch ($db_type)
    252260                                {
    253261                                        case 'pgsql':
    254                                                 $result = $db->query('SELECT id FROM '.$db->prefix.'users WHERE username ILIKE \''.$db->escape($author).'\'') or error('Impossible de retrouver les membres', __FILE__, __LINE__, $db->error());
     262                                                $result = $db->query('SELECT id FROM '.$db->prefix.'users WHERE username ILIKE \''.$db->escape($author).'\'') or error('Unable to fetch users', __FILE__, __LINE__, $db->error());
    255263                                                break;
    256264
    257265                                        default:
    258                                                 $result = $db->query('SELECT id FROM '.$db->prefix.'users WHERE username LIKE \''.$db->escape($author).'\'') or error('Impossible de retrouver les membres', __FILE__, __LINE__, $db->error());
     266                                                $result = $db->query('SELECT id FROM '.$db->prefix.'users WHERE username LIKE \''.$db->escape($author).'\'') or error('Unable to fetch users', __FILE__, __LINE__, $db->error());
    259267                                                break;
    260268                                }
     
    262270                                if ($db->num_rows($result))
    263271                                {
    264                                         $user_ids = '';
     272                                        $user_ids = array();
    265273                                        while ($row = $db->fetch_row($result))
    266                                                 $user_ids .= (($user_ids != '') ? ',' : '').$row[0];
    267 
    268                                         $result = $db->query('SELECT id FROM '.$db->prefix.'posts WHERE poster_id IN('.$user_ids.')') or error('Impossible de retrouver la liste des messages correspondants', __FILE__, __LINE__, $db->error());
    269 
    270                                         $search_ids = array();
    271                                         while ($row = $db->fetch_row($result))
    272                                                 $author_results[] = $row[0];
     274                                                $user_ids[] = $row[0];
     275
     276                                        $result = $db->query('SELECT p.id AS post_id, p.topic_id FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'topics AS t ON t.id=p.topic_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=t.forum_id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND p.poster_id IN('.implode(',', $user_ids).')'.$forum_sql.' ORDER BY '.$sort_by_sql.' '.$sort_dir) or error('Unable to fetch matched posts list', __FILE__, __LINE__, $db->error());
     277                                        while ($temp = $db->fetch_assoc($result))
     278                                                $author_results[$temp['post_id']] = $temp['topic_id'];
    273279
    274280                                        $db->free_result($result);
     
    276282                        }
    277283
    278 
     284                        // If we searched for both keywords and author name we want the intersection between the results
    279285                        if ($author && $keywords)
    280286                        {
    281                                 // If we searched for both keywords and author name we want the intersection between the results
    282                                 $search_ids = array_intersect($keyword_results, $author_results);
    283                                 unset($keyword_results, $author_results);
     287                                $search_ids = array_intersect_assoc($keyword_results, $author_results);
     288                                $search_type = array('both', array($keywords, pun_trim($_GET['author'])), implode(',', $forums), $search_in);
    284289                        }
    285290                        else if ($keywords)
     291                        {
    286292                                $search_ids = $keyword_results;
     293                                $search_type = array('keywords', $keywords, implode(',', $forums), $search_in);
     294                        }
    287295                        else
     296                        {
    288297                                $search_ids = $author_results;
     298                                $search_type = array('author', pun_trim($_GET['author']), implode(',', $forums), $search_in);
     299                        }
     300
     301                        unset($keyword_results, $author_results);
     302
     303                        if ($show_as == 'topics')
     304                                $search_ids = array_values($search_ids);
     305                        else
     306                                $search_ids = array_keys($search_ids);
     307
     308                        $search_ids = array_unique($search_ids);
    289309
    290310                        $num_hits = count($search_ids);
    291311                        if (!$num_hits)
    292312                                message($lang_search['No hits']);
    293 
    294 
    295                         if ($show_as == 'topics')
    296                         {
    297                                 $result = $db->query('SELECT t.id FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'topics AS t ON t.id=p.topic_id INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND p.id IN('.implode(',', $search_ids).')'.$forum_sql.' GROUP BY t.id', true) or error('Impossible de retrouver la liste des discussions', __FILE__, __LINE__, $db->error());
    298 
    299                                 $search_ids = array();
    300                                 while ($row = $db->fetch_row($result))
    301                                         $search_ids[] = $row[0];
    302 
    303                                 $db->free_result($result);
    304 
    305                                 $num_hits = count($search_ids);
    306                         }
    307                         else
    308                         {
    309                                 $result = $db->query('SELECT p.id FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'topics AS t ON t.id=p.topic_id INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND p.id IN('.implode(',', $search_ids).')'.$forum_sql, true) or error('Impossible de retrouver la liste des discussions', __FILE__, __LINE__, $db->error());
    310 
    311                                 $search_ids = array();
    312                                 while ($row = $db->fetch_row($result))
    313                                         $search_ids[] = $row[0];
    314 
    315                                 $db->free_result($result);
    316 
    317                                 $num_hits = count($search_ids);
    318                         }
    319                 }
    320                 else if ($action == 'show_new' || $action == 'show_24h' || $action == 'show_user' || $action == 'show_subscriptions' || $action == 'show_unanswered')
    321                 {
    322                         // If it's a search for new posts
     313                }
     314                else if ($action == 'show_new' || $action == 'show_recent' || $action == 'show_replies' || $action == 'show_user_posts' || $action == 'show_user_topics' || $action == 'show_subscriptions' || $action == 'show_unanswered')
     315                {
     316                        $search_type = array('action', $action);
     317                        $show_as = 'topics';
     318                        // We want to sort things after last post
     319                        $sort_by = 0;
     320                        $sort_dir = 'DESC';
     321
     322                        // If it's a search for new posts since last visit
    323323                        if ($action == 'show_new')
    324324                        {
     
    326326                                        message($lang_common['No permission']);
    327327
    328                                 $result = $db->query('SELECT t.id FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND t.last_post>'.$pun_user['last_visit']) or error('Impossible de retrouver la liste des discussions', __FILE__, __LINE__, $db->error());
     328                                $result = $db->query('SELECT t.id FROM '.$db->prefix.'topics AS t LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=t.forum_id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND t.last_post>'.$pun_user['last_visit'].' AND t.moved_to IS NULL'.(isset($_GET['fid']) ? ' AND t.forum_id='.intval($_GET['fid']) : '').' ORDER BY t.last_post DESC') or error('Unable to fetch topic list', __FILE__, __LINE__, $db->error());
    329329                                $num_hits = $db->num_rows($result);
    330330
     
    332332                                        message($lang_search['No new posts']);
    333333                        }
    334                         // If it's a search for todays posts
    335                         else if ($action == 'show_24h')
    336                         {
    337                                 $result = $db->query('SELECT t.id FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND t.last_post>'.(time() - 86400)) or error('Impossible de retrouver la liste des discussions', __FILE__, __LINE__, $db->error());
     334                        // If it's a search for recent posts (in a certain time interval)
     335                        else if ($action == 'show_recent')
     336                        {
     337                                $result = $db->query('SELECT t.id FROM '.$db->prefix.'topics AS t LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=t.forum_id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND t.last_post>'.(time() - $interval).' AND t.moved_to IS NULL'.(isset($_GET['fid']) ? ' AND t.forum_id='.intval($_GET['fid']) : '').' ORDER BY t.last_post DESC') or error('Unable to fetch topic list', __FILE__, __LINE__, $db->error());
    338338                                $num_hits = $db->num_rows($result);
    339339
     
    341341                                        message($lang_search['No recent posts']);
    342342                        }
    343                         // If it's a search for posts by a specific user ID
    344                         else if ($action == 'show_user')
    345                         {
    346                                 $result = $db->query('SELECT t.id FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'posts AS p ON t.id=p.topic_id INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND p.poster_id='.$user_id.' GROUP BY t.id') or error('Impossible de retrouver la liste des discussions', __FILE__, __LINE__, $db->error());
     343                        // If it's a search for topics in which the user has posted
     344                        else if ($action == 'show_replies')
     345                        {
     346                                $result = $db->query('SELECT t.id FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'posts AS p ON t.id=p.topic_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=t.forum_id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND p.poster_id='.$pun_user['id'].' GROUP BY t.id'.($db_type == 'pgsql' ? ', t.last_post' : '').' ORDER BY t.last_post DESC') or error('Unable to fetch topic list', __FILE__, __LINE__, $db->error());
    347347                                $num_hits = $db->num_rows($result);
    348348
     
    350350                                        message($lang_search['No user posts']);
    351351                        }
     352                        // If it's a search for posts by a specific user ID
     353                        else if ($action == 'show_user_posts')
     354                        {
     355                                $show_as = 'posts';
     356
     357                                $result = $db->query('SELECT p.id FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'topics AS t ON p.topic_id=t.id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=t.forum_id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND p.poster_id='.$user_id.' ORDER BY p.posted DESC') or error('Unable to fetch user posts', __FILE__, __LINE__, $db->error());
     358                                $num_hits = $db->num_rows($result);
     359
     360                                if (!$num_hits)
     361                                        message($lang_search['No user posts']);
     362
     363                                // Pass on the user ID so that we can later know whos posts we're searching for
     364                                $search_type[2] = $user_id;
     365                        }
     366                        // If it's a search for topics by a specific user ID
     367                        else if ($action == 'show_user_topics')
     368                        {
     369                                $result = $db->query('SELECT t.id FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'posts AS p ON t.first_post_id=p.id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=t.forum_id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND p.poster_id='.$user_id.' ORDER BY t.last_post DESC') or error('Unable to fetch user topics', __FILE__, __LINE__, $db->error());
     370                                $num_hits = $db->num_rows($result);
     371
     372                                if (!$num_hits)
     373                                        message($lang_search['No user topics']);
     374
     375                                // Pass on the user ID so that we can later know whos topics we're searching for
     376                                $search_type[2] = $user_id;
     377                        }
    352378                        // If it's a search for subscribed topics
    353379                        else if ($action == 'show_subscriptions')
     
    356382                                        message($lang_common['Bad request']);
    357383
    358                                 $result = $db->query('SELECT t.id FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'subscriptions AS s ON (t.id=s.topic_id AND s.user_id='.$pun_user['id'].') INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1)') or error('Impossible de retrouver la liste des discussions', __FILE__, __LINE__, $db->error());
     384                                $result = $db->query('SELECT t.id FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'topic_subscriptions AS s ON (t.id=s.topic_id AND s.user_id='.$user_id.') LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=t.forum_id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) ORDER BY t.last_post DESC') or error('Unable to fetch topic list', __FILE__, __LINE__, $db->error());
    359385                                $num_hits = $db->num_rows($result);
    360386
    361387                                if (!$num_hits)
    362388                                        message($lang_search['No subscriptions']);
     389
     390                                // Pass on user ID so that we can later know whose subscriptions we're searching for
     391                                $search_type[2] = $user_id;
    363392                        }
    364393                        // If it's a search for unanswered posts
    365394                        else
    366395                        {
    367                                 $result = $db->query('SELECT t.id FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND t.num_replies=0 AND t.moved_to IS NULL') or error('Impossible de retrouver la liste des discussions', __FILE__, __LINE__, $db->error());
     396                                $result = $db->query('SELECT t.id FROM '.$db->prefix.'topics AS t LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=t.forum_id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND t.num_replies=0 AND t.moved_to IS NULL ORDER BY t.last_post DESC') or error('Unable to fetch topic list', __FILE__, __LINE__, $db->error());
    368397                                $num_hits = $db->num_rows($result);
    369398
     
    371400                                        message($lang_search['No unanswered']);
    372401                        }
    373 
    374                         // We want to sort things after last post
    375                         $sort_by = 4;
    376402
    377403                        $search_ids = array();
     
    380406
    381407                        $db->free_result($result);
    382 
    383                         $show_as = 'topics';
    384408                }
    385409                else
     
    389413                // Prune "old" search results
    390414                $old_searches = array();
    391                 $result = $db->query('SELECT ident FROM '.$db->prefix.'online') or error('Impossible de retrouver la liste de utilisateurs en ligne', __FILE__, __LINE__, $db->error());
     415                $result = $db->query('SELECT ident FROM '.$db->prefix.'online') or error('Unable to fetch online list', __FILE__, __LINE__, $db->error());
    392416
    393417                if ($db->num_rows($result))
     
    396420                                $old_searches[] = '\''.$db->escape($row[0]).'\'';
    397421
    398                         $db->query('DELETE FROM '.$db->prefix.'search_cache WHERE ident NOT IN('.implode(',', $old_searches).')') or error('Impossible de supprimer les résultats de recherches', __FILE__, __LINE__, $db->error());
    399                 }
    400 
    401                 // Final search results
    402                 $search_results = implode(',', $search_ids);
     422                        $db->query('DELETE FROM '.$db->prefix.'search_cache WHERE ident NOT IN('.implode(',', $old_searches).')') or error('Unable to delete search results', __FILE__, __LINE__, $db->error());
     423                }
    403424
    404425                // Fill an array with our results and search properties
    405                 $temp['search_results'] = $search_results;
    406                 $temp['num_hits'] = $num_hits;
    407                 $temp['sort_by'] = $sort_by;
    408                 $temp['sort_dir'] = $sort_dir;
    409                 $temp['show_as'] = $show_as;
    410                 $temp = serialize($temp);
     426                $temp = serialize(array(
     427                        'search_ids'            => serialize($search_ids),
     428                        'num_hits'                      => $num_hits,
     429                        'sort_by'                       => $sort_by,
     430                        'sort_dir'                      => $sort_dir,
     431                        'show_as'                       => $show_as,
     432                        'search_type'           => $search_type
     433                ));
    411434                $search_id = mt_rand(1, 2147483647);
    412435
    413436                $ident = ($pun_user['is_guest']) ? get_remote_address() : $pun_user['username'];
    414437
    415                 $db->query('INSERT INTO '.$db->prefix.'search_cache (id, ident, search_data) VALUES('.$search_id.', \''.$db->escape($ident).'\', \''.$db->escape($temp).'\')') or error('Impossible d\'insérer les résultats de recherche', __FILE__, __LINE__, $db->error());
    416 
    417                 if ($action != 'show_new' && $action != 'show_24h')
     438                $db->query('INSERT INTO '.$db->prefix.'search_cache (id, ident, search_data) VALUES('.$search_id.', \''.$db->escape($ident).'\', \''.$db->escape($temp).'\')') or error('Unable to insert search results', __FILE__, __LINE__, $db->error());
     439
     440                if ($search_type[0] != 'action')
    418441                {
    419442                        $db->end_transaction();
     
    426449        }
    427450
     451        $forum_actions = array();
     452
     453        // If we're on the new posts search, display a "mark all as read" link
     454        if (!$pun_user['is_guest'] && $search_type[0] == 'action' && $search_type[1] == 'show_new')
     455                $forum_actions[] = '<a href="misc.php?action=markread">'.$lang_common['Mark all as read'].'</a>';
    428456
    429457        // Fetch results to display
    430         if ($search_results != '')
     458        if (!empty($search_ids))
    431459        {
    432                 $group_by_sql = '';
    433460                switch ($sort_by)
    434461                {
     
    445472                                break;
    446473
    447                         case 4:
    448                                 $sort_by_sql = 't.last_post';
     474                        default:
     475                                $sort_by_sql = ($show_as == 'topics') ? 't.last_post' : 'p.posted';
    449476                                break;
    450 
    451                         default:
    452                         {
    453                                 $sort_by_sql = ($show_as == 'topics') ? 't.posted' : 'p.posted';
    454 
    455                                 if ($show_as == 'topics')
    456                                         $group_by_sql = ', t.posted';
    457 
    458                                 break;
    459                         }
    460                 }
    461 
    462                 if ($show_as == 'posts')
    463                 {
    464                         $substr_sql = ($db_type != 'sqlite') ? 'SUBSTRING' : 'SUBSTR';
    465                         $sql = 'SELECT p.id AS pid, p.poster AS pposter, p.posted AS pposted, p.poster_id, '.$substr_sql.'(p.message, 1, 1000) AS message, t.id AS tid, t.poster, t.subject, t.last_post, t.last_post_id, t.last_poster, t.num_replies, t.forum_id FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'topics AS t ON t.id=p.topic_id WHERE p.id IN('.$search_results.') ORDER BY '.$sort_by_sql;
    466                 }
    467                 else
    468                         $sql = 'SELECT t.id AS tid, t.poster, t.subject, t.last_post, t.last_post_id, t.last_poster, t.num_replies, t.closed, t.forum_id FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'topics AS t ON t.id=p.topic_id WHERE t.id IN('.$search_results.') GROUP BY t.id, t.poster, t.subject, t.last_post, t.last_post_id, t.last_poster, t.num_replies, t.closed, t.forum_id'.$group_by_sql.' ORDER BY '.$sort_by_sql;
    469 
     477                }
    470478
    471479                // Determine the topic or post offset (based on $_GET['p'])
     
    473481                $num_pages = ceil($num_hits / $per_page);
    474482
    475                 $p = (!isset($_GET['p']) || $_GET['p'] <= 1 || $_GET['p'] > $num_pages) ? 1 : $_GET['p'];
     483                $p = (!isset($_GET['p']) || $_GET['p'] <= 1 || $_GET['p'] > $num_pages) ? 1 : intval($_GET['p']);
    476484                $start_from = $per_page * ($p - 1);
    477485
    478486                // Generate paging links
    479                 $paging_links = $lang_common['Pages'].': '.paginate($num_pages, $p, 'search.php?search_id='.$search_id);
    480 
    481 
    482                 $sql .= ' '.$sort_dir.' LIMIT '.$start_from.', '.$per_page;
    483 
    484                 $result = $db->query($sql) or error('Impossible de retrouver les résultats de recherches', __FILE__, __LINE__, $db->error());
     487                $paging_links = '<span class="pages-label">'.$lang_common['Pages'].' </span>'.paginate($num_pages, $p, 'search.php?search_id='.$search_id);
     488
     489                // throw away the first $start_from of $search_ids, only keep the top $per_page of $search_ids
     490                $search_ids = array_slice($search_ids, $start_from, $per_page);
     491
     492                // Run the query and fetch the results
     493                if ($show_as == 'posts')
     494                        $result = $db->query('SELECT p.id AS pid, p.poster AS pposter, p.posted AS pposted, p.poster_id, p.message, p.hide_smilies, t.id AS tid, t.poster, t.subject, t.first_post_id, t.last_post, t.last_post_id, t.last_poster, t.num_replies, t.forum_id, f.forum_name FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'topics AS t ON t.id=p.topic_id INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id WHERE p.id IN('.implode(',', $search_ids).') ORDER BY '.$sort_by_sql.' '.$sort_dir) or error('Unable to fetch search results', __FILE__, __LINE__, $db->error());
     495                else
     496                        $result = $db->query('SELECT t.id AS tid, t.poster, t.subject, t.last_post, t.last_post_id, t.last_poster, t.num_replies, t.closed, t.sticky, t.forum_id, f.forum_name FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id WHERE t.id IN('.implode(',', $search_ids).') ORDER BY '.$sort_by_sql.' '.$sort_dir) or error('Unable to fetch search results', __FILE__, __LINE__, $db->error());
    485497
    486498                $search_set = array();
     
    488500                        $search_set[] = $row;
    489501
    490                 $db->free_result($result);
    491 
    492                 $page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_search['Search results'];
     502                $crumbs_text = array();
     503                $crumbs_text['show_as'] = $lang_search['Search'];
     504
     505                if ($search_type[0] == 'action')
     506                {
     507                        if ($search_type[1] == 'show_user_topics')
     508                                $crumbs_text['search_type'] = '<a href="search.php?action=show_user_topics&amp;user_id='.$search_type[2].'">'.sprintf($lang_search['Quick search show_user_topics'], pun_htmlspecialchars($search_set[0]['poster'])).'</a>';
     509                        else if ($search_type[1] == 'show_user_posts')
     510                                $crumbs_text['search_type'] = '<a href="search.php?action=show_user_posts&amp;user_id='.$search_type[2].'">'.sprintf($lang_search['Quick search show_user_posts'], pun_htmlspecialchars($search_set[0]['pposter'])).'</a>';
     511                        else if ($search_type[1] == 'show_subscriptions')
     512                        {
     513                                // Fetch username of subscriber
     514                                $subscriber_id = $search_type[2];
     515                                $result = $db->query('SELECT username FROM '.$db->prefix.'users WHERE id='.$subscriber_id) or error('Unable to fetch username of subscriber', __FILE__, __LINE__, $db->error());
     516
     517                                if ($db->num_rows($result))
     518                                        $subscriber_name = $db->result($result);
     519                                else
     520                                        message($lang_common['Bad request']);
     521
     522                                $crumbs_text['search_type'] = '<a href="search.php?action=show_subscriptions&amp;user_id='.$subscriber_id.'">'.sprintf($lang_search['Quick search show_subscriptions'], pun_htmlspecialchars($subscriber_name)).'</a>';
     523                        }
     524                        else
     525                                $crumbs_text['search_type'] = '<a href="search.php?action='.$search_type[1].'">'.$lang_search['Quick search '.$search_type[1]].'</a>';
     526                }
     527                else
     528                {
     529                        $keywords = $author = '';
     530
     531                        if ($search_type[0] == 'both')
     532                        {
     533                                list ($keywords, $author) = $search_type[1];
     534                                $crumbs_text['search_type'] = sprintf($lang_search['By both show as '.$show_as], pun_htmlspecialchars($keywords), pun_htmlspecialchars($author));
     535                        }
     536                        else if ($search_type[0] == 'keywords')
     537                        {
     538                                $keywords = $search_type[1];
     539                                $crumbs_text['search_type'] = sprintf($lang_search['By keywords show as '.$show_as], pun_htmlspecialchars($keywords));
     540                        }
     541                        else if ($search_type[0] == 'author')
     542                        {
     543                                $author = $search_type[1];
     544                                $crumbs_text['search_type'] = sprintf($lang_search['By user show as '.$show_as], pun_htmlspecialchars($author));
     545                        }
     546
     547                        $crumbs_text['search_type'] = '<a href="search.php?action=search&amp;keywords='.urlencode($keywords).'&amp;author='.urlencode($author).'&amp;forums='.$search_type[2].'&amp;search_in='.$search_type[3].'&amp;sort_by='.$sort_by.'&amp;sort_dir='.$sort_dir.'&amp;show_as='.$show_as.'">'.$crumbs_text['search_type'].'</a>';
     548                }
     549
     550                $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_search['Search results']);
     551                define('PUN_ACTIVE_PAGE', 'search');
    493552                require PUN_ROOT.'header.php';
    494 
    495553
    496554?>
    497555<div class="linkst">
    498         <div class="inbox">
    499                 <p class="pagelink"><?php echo $paging_links ?></p>
     556        <div class="inbox crumbsplus">
     557                <ul class="crumbs">
     558                        <li><a href="index.php"><?php echo $lang_common['Index'] ?></a></li>
     559                        <li><span>»&#160;</span><a href="search.php"><?php echo $crumbs_text['show_as'] ?></a></li>
     560                        <li><span>»&#160;</span><strong><?php echo $crumbs_text['search_type'] ?></strong></li>
     561                </ul>
     562                <div class="pagepost">
     563                        <p class="pagelink"><?php echo $paging_links ?></p>
     564                </div>
     565                <div class="clearer"></div>
    500566        </div>
    501567</div>
     
    503569<?php
    504570
    505                 //Set background switching on for show as posts
    506                 $bg_switch = true;
    507 
    508571                if ($show_as == 'topics')
    509572                {
     573                        $topic_count = 0;
    510574
    511575?>
    512576<div id="vf" class="blocktable">
    513         <h2><span><?php echo $lang_search['Search results']; ?></span></h2>
     577        <h2><span><?php echo $lang_search['Search results'] ?></span></h2>
    514578        <div class="box">
    515579                <div class="inbox">
     
    517581                        <thead>
    518582                                <tr>
    519                                         <th class="tcl" scope="col"><?php echo $lang_common['Topic']; ?></th>
     583                                        <th class="tcl" scope="col"><?php echo $lang_common['Topic'] ?></th>
    520584                                        <th class="tc2" scope="col"><?php echo $lang_common['Forum'] ?></th>
    521585                                        <th class="tc3" scope="col"><?php echo $lang_common['Replies'] ?></th>
     
    527591
    528592                }
    529 
    530                 // Fetch the list of forums
    531                 $result = $db->query('SELECT id, forum_name FROM '.$db->prefix.'forums') or error('Impossible de retrouver la liste des forums', __FILE__, __LINE__, $db->error());
    532 
    533                 $forum_list = array();
    534                 while ($forum_list[] = $db->fetch_row($result))
    535                         ;
    536 
    537                 // Finally, lets loop through the results and output them
    538                 for ($i = 0; $i < count($search_set); ++$i)
    539                 {
    540                         @reset($forum_list);
    541                         while (list(, $temp) = @each($forum_list))
    542                         {
    543                                 if ($temp[0] == $search_set[$i]['forum_id'])
    544                                         $forum = '<a href="viewforum.php?id='.$temp[0].'">'.pun_htmlspecialchars($temp[1]).'</a>';
    545                         }
     593                else if ($show_as == 'posts')
     594                {
     595                        require PUN_ROOT.'lang/'.$pun_user['language'].'/topic.php';
     596
     597                        require PUN_ROOT.'include/parser.php';
     598
     599                        $post_count = 0;
     600                }
     601
     602                // Get topic/forum tracking data
     603                if (!$pun_user['is_guest'])
     604                        $tracked_topics = get_tracked_topics();
     605
     606                foreach ($search_set as $cur_search)
     607                {
     608                        $forum = '<a href="viewforum.php?id='.$cur_search['forum_id'].'">'.pun_htmlspecialchars($cur_search['forum_name']).'</a>';
    546609
    547610                        if ($pun_config['o_censoring'] == '1')
    548                                 $search_set[$i]['subject'] = censor_words($search_set[$i]['subject']);
    549 
     611                                $cur_search['subject'] = censor_words($cur_search['subject']);
    550612
    551613                        if ($show_as == 'posts')
    552614                        {
    553                                 $icon = '<div class="icon"><div class="nosize">'.$lang_common['Normal icon'].'</div></div>'."\n";
    554                                 $subject = '<a href="viewtopic.php?id='.$search_set[$i]['tid'].'">'.pun_htmlspecialchars($search_set[$i]['subject']).'</a>';
    555 
    556                                 if (!$pun_user['is_guest'] && $search_set[$i]['last_post'] > $pun_user['last_visit'])
    557                                         $icon = '<div class="icon inew"><div class="nosize">'.$lang_common['New icon'].'</div></div>'."\n";
    558 
     615                                ++$post_count;
     616                                $icon_type = 'icon';
     617
     618                                if (!$pun_user['is_guest'] && $cur_search['last_post'] > $pun_user['last_visit'] && (!isset($tracked_topics['topics'][$cur_search['tid']]) || $tracked_topics['topics'][$cur_search['tid']] < $cur_search['last_post']) && (!isset($tracked_topics['forums'][$cur_search['forum_id']]) || $tracked_topics['forums'][$cur_search['forum_id']] < $cur_search['last_post']))
     619                                {
     620                                        $item_status = 'inew';
     621                                        $icon_type = 'icon icon-new';
     622                                        $icon_text = $lang_topic['New icon'];
     623                                }
     624                                else
     625                                {
     626                                        $item_status = '';
     627                                        $icon_text = '<!-- -->';
     628                                }
    559629
    560630                                if ($pun_config['o_censoring'] == '1')
    561                                         $search_set[$i]['message'] = censor_words($search_set[$i]['message']);
    562 
    563                                 $message = str_replace("\n", '<br />', pun_htmlspecialchars($search_set[$i]['message']));
    564                                 $pposter = pun_htmlspecialchars($search_set[$i]['pposter']);
    565 
    566                                 if ($search_set[$i]['poster_id'] > 1)
    567                                         $pposter = '<strong><a href="profile.php?id='.$search_set[$i]['poster_id'].'">'.$pposter.'</a></strong>';
    568 
    569                                 if (pun_strlen($message) >= 1000)
    570                                         $message .= ' &hellip;';
    571 
    572                                 $vtpost1 = ($i == 0) ? ' vtp1' : '';
    573 
    574                                 // Switch the background color for every message.
    575                                 $bg_switch = ($bg_switch) ? $bg_switch = false : $bg_switch = true;
    576                                 $vtbg = ($bg_switch) ? ' rowodd' : ' roweven';
     631                                        $cur_search['message'] = censor_words($cur_search['message']);
     632
     633                                $message = parse_message($cur_search['message'], $cur_search['hide_smilies']);
     634                                $pposter = pun_htmlspecialchars($cur_search['pposter']);
     635
     636                                if ($cur_search['poster_id'] > 1)
     637                                {
     638                                        if ($pun_user['g_view_users'] == '1')
     639                                                $pposter = '<strong><a href="profile.php?id='.$cur_search['poster_id'].'">'.$pposter.'</a></strong>';
     640                                        else
     641                                                $pposter = '<strong>'.$pposter.'</strong>';
     642                                }
    577643
    578644
    579645?>
    580 <div class="blockpost searchposts<?php echo $vtbg ?>">
    581         <h2><?php echo $forum ?>&#160;&raquo;&#160;<?php echo $subject ?>&#160;&raquo;&#160;<a href="viewtopic.php?pid=<?php echo $search_set[$i]['pid'].'#p'.$search_set[$i]['pid'] ?>"><?php echo format_time($search_set[$i]['pposted']) ?></a></h2>
     646<div class="blockpost<?php echo ($post_count % 2 == 0) ? ' roweven' : ' rowodd' ?><?php if ($cur_search['pid'] == $cur_search['first_post_id']) echo ' firstpost' ?><?php if ($post_count == 1) echo ' blockpost1' ?><?php if ($item_status != '') echo ' '.$item_status ?>">
     647        <h2><span><span class="conr">#<?php echo ($start_from + $post_count) ?></span> <span><?php if ($cur_search['pid'] != $cur_search['first_post_id']) echo $lang_topic['Re'].' ' ?><?php echo $forum ?></span> <span>»&#160;<a href="viewtopic.php?id=<?php echo $cur_search['tid'] ?>"><?php echo pun_htmlspecialchars($cur_search['subject']) ?></a></span> <span>»&#160;<a href="viewtopic.php?pid=<?php echo $cur_search['pid'].'#p'.$cur_search['pid'] ?>"><?php echo format_time($cur_search['pposted']) ?></a></span></span></h2>
    582648        <div class="box">
    583649                <div class="inbox">
    584                         <div class="postleft">
    585                                 <dl>
    586                                         <dt><?php echo $pposter ?></dt>
    587                                         <dd>Replies: <?php echo $search_set[$i]['num_replies'] ?></dd>
    588                                         <dd><?php echo $icon; ?></dd>
    589                                         <dd><p class="clearb"><a href="viewtopic.php?pid=<?php echo $search_set[$i]['pid'].'#p'.$search_set[$i]['pid'] ?>"><?php echo $lang_search['Go to post'] ?></a></p></dd>
    590                                 </dl>
     650                        <div class="postbody">
     651                                <div class="postleft">
     652                                        <dl>
     653                                                <dt><?php echo $pposter ?></dt>
     654<?php if ($cur_search['pid'] == $cur_search['first_post_id']) : ?>                                              <dd><span><?php echo $lang_topic['Replies'].' '.forum_number_format($cur_search['num_replies']) ?></span></dd>
     655<?php endif; ?>
     656                                                <dd><div class="<?php echo $icon_type ?>"><div class="nosize"><?php echo $icon_text ?></div></div></dd>
     657                                        </dl>
     658                                </div>
     659                                <div class="postright">
     660                                        <div class="postmsg">
     661                                                <?php echo $message."\n" ?>
     662                                        </div>
     663                                </div>
     664                                <div class="clearer"></div>
    591665                        </div>
    592                         <div class="postright">
    593                                 <div class="postmsg">
    594                                         <p><?php echo $message ?></p>
     666                </div>
     667                <div class="inbox">
     668                        <div class="postfoot clearb">
     669                                <div class="postfootright">
     670                                        <ul>
     671                                                <li><span><a href="viewtopic.php?id=<?php echo $cur_search['tid'] ?>"><?php echo $lang_search['Go to topic'] ?></a></span></li>
     672                                                <li><span><a href="viewtopic.php?pid=<?php echo $cur_search['pid'].'#p'.$cur_search['pid'] ?>"><?php echo $lang_search['Go to post'] ?></a></span></li>
     673                                        </ul>
    595674                                </div>
    596675                        </div>
    597                         <div class="clearer"></div>
    598676                </div>
    599677        </div>
     
    604682                        else
    605683                        {
    606                                 $icon = '<div class="icon"><div class="nosize">'.$lang_common['Normal icon'].'</div></div>'."\n";
    607 
    608                                 $icon_text = $lang_common['Normal icon'];
    609                                 $item_status = '';
     684                                ++$topic_count;
     685                                $status_text = array();
     686                                $item_status = ($topic_count % 2 == 0) ? 'roweven' : 'rowodd';
    610687                                $icon_type = 'icon';
    611688
    612 
    613                                 $subject = '<a href="viewtopic.php?id='.$search_set[$i]['tid'].'">'.pun_htmlspecialchars($search_set[$i]['subject']).'</a> <span class="byuser">'.$lang_common['by'].'&#160;'.pun_htmlspecialchars($search_set[$i]['poster']).'</span>';
    614 
    615                                 if ($search_set[$i]['closed'] != '0')
     689                                $subject = '<a href="viewtopic.php?id='.$cur_search['tid'].'">'.pun_htmlspecialchars($cur_search['subject']).'</a> <span class="byuser">'.$lang_common['by'].' '.pun_htmlspecialchars($cur_search['poster']).'</span>';
     690
     691                                if ($cur_search['sticky'] == '1')
    616692                                {
    617                                         $icon_text = $lang_common['Closed icon'];
    618                                         $item_status = 'iclosed';
     693                                        $item_status .= ' isticky';
     694                                        $status_text[] = '<span class="stickytext">'.$lang_forum['Sticky'].'</span>';
    619695                                }
    620696
    621                                 if (!$pun_user['is_guest'] && $search_set[$i]['last_post'] > $pun_user['last_visit'])
     697                                if ($cur_search['closed'] != '0')
    622698                                {
    623                                         $icon_text .= ' '.$lang_common['New icon'];
     699                                        $status_text[] = '<span class="closedtext">'.$lang_forum['Closed'].'</span>';
     700                                        $item_status .= ' iclosed';
     701                                }
     702
     703                                if (!$pun_user['is_guest'] && $cur_search['last_post'] > $pun_user['last_visit'] && (!isset($tracked_topics['topics'][$cur_search['tid']]) || $tracked_topics['topics'][$cur_search['tid']] < $cur_search['last_post']) && (!isset($tracked_topics['forums'][$cur_search['forum_id']]) || $tracked_topics['forums'][$cur_search['forum_id']] < $cur_search['last_post']))
     704                                {
    624705                                        $item_status .= ' inew';
    625                                         $icon_type = 'icon inew';
     706                                        $icon_type = 'icon icon-new';
    626707                                        $subject = '<strong>'.$subject.'</strong>';
    627                                         $subject_new_posts = '<span class="newtext">[&#160;<a href="viewtopic.php?id='.$search_set[$i]['tid'].'&amp;action=new" title="'.$lang_common['New posts info'].'">'.$lang_common['New posts'].'</a>&#160;]</span>';
     708                                        $subject_new_posts = '<span class="newtext">[ <a href="viewtopic.php?id='.$cur_search['tid'].'&amp;action=new" title="'.$lang_common['New posts info'].'">'.$lang_common['New posts'].'</a> ]</span>';
    628709                                }
    629710                                else
    630711                                        $subject_new_posts = null;
    631712
    632                                 $num_pages_topic = ceil(($search_set[$i]['num_replies'] + 1) / $pun_user['disp_posts']);
     713                                // Insert the status text before the subject
     714                                $subject = implode(' ', $status_text).' '.$subject;
     715
     716                                $num_pages_topic = ceil(($cur_search['num_replies'] + 1) / $pun_user['disp_posts']);
    633717
    634718                                if ($num_pages_topic > 1)
    635                                         $subject_multipage = '[ '.paginate($num_pages_topic, -1, 'viewtopic.php?id='.$search_set[$i]['tid']).' ]';
     719                                        $subject_multipage = '<span class="pagestext">[ '.paginate($num_pages_topic, -1, 'viewtopic.php?id='.$cur_search['tid']).' ]</span>';
    636720                                else
    637721                                        $subject_multipage = null;
     
    640724                                if (!empty($subject_new_posts) || !empty($subject_multipage))
    641725                                {
    642                                         $subject .= '&#160; '.(!empty($subject_new_posts) ? $subject_new_posts : '');
     726                                        $subject .= !empty($subject_new_posts) ? ' '.$subject_new_posts : '';
    643727                                        $subject .= !empty($subject_multipage) ? ' '.$subject_multipage : '';
    644728                                }
    645729
    646730?>
    647                                 <tr<?php if ($item_status != '') echo ' class="'.trim($item_status).'"'; ?>>
     731                                <tr class="<?php echo $item_status ?>">
    648732                                        <td class="tcl">
    649                                                 <div class="intd">
    650                                                         <div class="<?php echo $icon_type ?>"><div class="nosize"><?php echo trim($icon_text) ?></div></div>
    651                                                         <div class="tclcon">
     733                                                <div class="<?php echo $icon_type ?>"><div class="nosize"><?php echo forum_number_format($topic_count + $start_from) ?></div></div>
     734                                                <div class="tclcon">
     735                                                        <div>
    652736                                                                <?php echo $subject."\n" ?>
    653737                                                        </div>
     
    655739                                        </td>
    656740                                        <td class="tc2"><?php echo $forum ?></td>
    657                                         <td class="tc3"><?php echo $search_set[$i]['num_replies'] ?></td>
    658                                         <td class="tcr"><?php echo '<a href="viewtopic.php?pid='.$search_set[$i]['last_post_id'].'#p'.$search_set[$i]['last_post_id'].'">'.format_time($search_set[$i]['last_post']).'</a> '.$lang_common['by'].'&#160;'.pun_htmlspecialchars($search_set[$i]['last_poster']) ?></td>
     741                                        <td class="tc3"><?php echo forum_number_format($cur_search['num_replies']) ?></td>
     742                                        <td class="tcr"><?php echo '<a href="viewtopic.php?pid='.$cur_search['last_post_id'].'#p'.$cur_search['last_post_id'].'">'.format_time($cur_search['last_post']).'</a> <span class="byuser">'.$lang_common['by'].' '.pun_htmlspecialchars($cur_search['last_poster']) ?></span></td>
    659743                                </tr>
    660744<?php
     
    668752?>
    669753<div class="<?php echo ($show_as == 'topics') ? 'linksb' : 'postlinksb'; ?>">
    670         <div class="inbox">
    671                 <p class="pagelink"><?php echo $paging_links ?></p>
     754        <div class="inbox crumbsplus">
     755                <div class="pagepost">
     756                        <p class="pagelink"><?php echo $paging_links ?></p>
     757                </div>
     758                <ul class="crumbs">
     759                        <li><a href="index.php"><?php echo $lang_common['Index'] ?></a></li>
     760                        <li><span>»&#160;</span><a href="search.php"><?php echo $crumbs_text['show_as'] ?></a></li>
     761                        <li><span>»&#160;</span><strong><?php echo $crumbs_text['search_type'] ?></strong></li>
     762                </ul>
     763<?php echo (!empty($forum_actions) ? "\t\t".'<p class="subscribelink clearb">'.implode(' - ', $forum_actions).'</p>'."\n" : '') ?>
     764                <div class="clearer"></div>
    672765        </div>
    673766</div>
    674767<?php
    675768
    676                 $footer_style = 'search';
    677769                require PUN_ROOT.'footer.php';
    678770        }
     
    682774
    683775
    684 $page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_search['Search'];
     776$page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_search['Search']);
    685777$focus_element = array('search', 'keywords');
     778define('PUN_ACTIVE_PAGE', 'search');
    686779require PUN_ROOT.'header.php';
    687780
     
    706799                                        <legend><?php echo $lang_search['Search in legend'] ?></legend>
    707800                                        <div class="infldset">
    708                                                 <label class="conl"><?php echo $lang_search['Forum search'] ?>
    709                                                 <br /><select id="forum" name="forum">
    710801<?php
    711802
    712 if ($pun_config['o_search_all_forums'] == '1' || $pun_user['g_id'] < PUN_GUEST)
    713         echo "\t\t\t\t\t\t\t".'<option value="-1">'.$lang_search['All forums'].'</option>'."\n";
    714 
    715 $result = $db->query('SELECT c.id AS cid, c.cat_name, f.id AS fid, f.forum_name, f.redirect_url FROM '.$db->prefix.'categories AS c INNER JOIN '.$db->prefix.'forums AS f ON c.id=f.cat_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND f.redirect_url IS NULL ORDER BY c.disp_position, c.id, f.disp_position', true) or error('Impossible de retrouver la liste des catégories et des forums', __FILE__, __LINE__, $db->error());
    716 
    717 $cur_category = 0;
    718 while ($cur_forum = $db->fetch_assoc($result))
     803$result = $db->query('SELECT c.id AS cid, c.cat_name, f.id AS fid, f.forum_name, f.redirect_url FROM '.$db->prefix.'categories AS c INNER JOIN '.$db->prefix.'forums AS f ON c.id=f.cat_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND f.redirect_url IS NULL ORDER BY c.disp_position, c.id, f.disp_position', true) or error('Unable to fetch category/forum list', __FILE__, __LINE__, $db->error());
     804
     805// We either show a list of forums of which multiple can be selected
     806if ($pun_config['o_search_all_forums'] == '1' || $pun_user['is_admmod'])
    719807{
    720         if ($cur_forum['cid'] != $cur_category) // A new category since last iteration?
     808        echo "\t\t\t\t\t\t".'<div class="conl multiselect">'.$lang_search['Forum search']."\n";
     809        echo "\t\t\t\t\t\t".'<br />'."\n";
     810        echo "\t\t\t\t\t\t".'<div class="checklist">'."\n";
     811
     812        $cur_category = 0;
     813        while ($cur_forum = $db->fetch_assoc($result))
    721814        {
    722                 if ($cur_category)
    723                         echo "\t\t\t\t\t\t\t".'</optgroup>'."\n";
    724 
    725                 echo "\t\t\t\t\t\t\t".'<optgroup label="'.pun_htmlspecialchars($cur_forum['cat_name']).'">'."\n";
    726                 $cur_category = $cur_forum['cid'];
     815                if ($cur_forum['cid'] != $cur_category) // A new category since last iteration?
     816                {
     817                        if ($cur_category)
     818                                echo "\t\t\t\t\t\t\t".'</fieldset>'."\n";
     819
     820                        echo "\t\t\t\t\t\t\t".'<fieldset><legend><span>'.pun_htmlspecialchars($cur_forum['cat_name']).'</span></legend>'."\n";
     821                        $cur_category = $cur_forum['cid'];
     822                }
     823
     824                echo "\t\t\t\t\t\t\t\t".'<div class="checklist-item"><span class="fld-input"><input type="checkbox" name="forums[]" id="forum-'.$cur_forum['fid'].'" value="'.$cur_forum['fid'].'" /></span> <label for="forum-'.$cur_forum['fid'].'">'.pun_htmlspecialchars($cur_forum['forum_name']).'</label></div>'."\n";
    727825        }
    728826
    729         echo "\t\t\t\t\t\t\t\t".'<option value="'.$cur_forum['fid'].'">'.pun_htmlspecialchars($cur_forum['forum_name']).'</option>'."\n";
     827        echo "\t\t\t\t\t\t\t".'</fieldset>'."\n";
     828        echo "\t\t\t\t\t\t".'</div>'."\n";
     829        echo "\t\t\t\t\t\t".'</div>'."\n";
    730830}
     831// ... or a simple select list for one forum only
     832else
     833{
     834        echo "\t\t\t\t\t\t".'<label class="conl">'.$lang_search['Forum search']."\n";
     835        echo "\t\t\t\t\t\t".'<br />'."\n";
     836        echo "\t\t\t\t\t\t".'<select id="forum" name="forum">'."\n";
     837
     838        $cur_category = 0;
     839        while ($cur_forum = $db->fetch_assoc($result))
     840        {
     841                if ($cur_forum['cid'] != $cur_category) // A new category since last iteration?
     842                {
     843                        if ($cur_category)
     844                                echo "\t\t\t\t\t\t\t".'</optgroup>'."\n";
     845
     846                        echo "\t\t\t\t\t\t\t".'<optgroup label="'.pun_htmlspecialchars($cur_forum['cat_name']).'">'."\n";
     847                        $cur_category = $cur_forum['cid'];
     848                }
     849
     850                echo "\t\t\t\t\t\t\t\t".'<option value="'.$cur_forum['fid'].'">'.pun_htmlspecialchars($cur_forum['forum_name']).'</option>'."\n";
     851        }
     852
     853        echo "\t\t\t\t\t\t\t".'</optgroup>'."\n";
     854        echo "\t\t\t\t\t\t".'</select>'."\n";
     855        echo "\t\t\t\t\t\t".'<br /></label>'."\n";
     856}
    731857
    732858?>
    733                                                         </optgroup>
     859                                                <label class="conl"><?php echo $lang_search['Search in']."\n" ?>
     860                                                <br /><select id="search_in" name="search_in">
     861                                                        <option value="0"><?php echo $lang_search['Message and subject'] ?></option>
     862                                                        <option value="1"><?php echo $lang_search['Message only'] ?></option>
     863                                                        <option value="-1"><?php echo $lang_search['Topic only'] ?></option>
    734864                                                </select>
    735865                                                <br /></label>
    736                                                 <label class="conl"><?php echo $lang_search['Search in'] ?>
    737                                                 <br /><select id="search_in" name="search_in">
    738                                                         <option value="all"><?php echo $lang_search['Message and subject'] ?></option>
    739                                                         <option value="message"><?php echo $lang_search['Message only'] ?></option>
    740                                                         <option value="topic"><?php echo $lang_search['Topic only'] ?></option>
    741                                                 </select>
    742                                                 <br /></label>
    743                                                 <p class="clearb"><?php echo $lang_search['Search in info'] ?></p>
     866                                                <p class="clearl"><?php echo $lang_search['Search in info'] ?></p>
     867<?php echo ($pun_config['o_search_all_forums'] == '1' || $pun_user['is_admmod'] ? '<p>'.$lang_search['Search multiple forums info'].'</p>' : '') ?>
    744868                                        </div>
    745869                                </fieldset>
     
    749873                                        <legend><?php echo $lang_search['Search results legend'] ?></legend>
    750874                                        <div class="infldset">
    751                                                 <label class="conl"><?php echo $lang_search['Sort by'] ?>
     875                                                <label class="conl"><?php echo $lang_search['Sort by']."\n" ?>
    752876                                                <br /><select name="sort_by">
    753877                                                        <option value="0"><?php echo $lang_search['Sort by post time'] ?></option>
     
    757881                                                </select>
    758882                                                <br /></label>
    759                                                 <label class="conl"><?php echo $lang_search['Sort order'] ?>
     883                                                <label class="conl"><?php echo $lang_search['Sort order']."\n" ?>
    760884                                                <br /><select name="sort_dir">
    761885                                                        <option value="DESC"><?php echo $lang_search['Descending'] ?></option>
     
    763887                                                </select>
    764888                                                <br /></label>
    765                                                 <label class="conl"><?php echo $lang_search['Show as'] ?>
     889                                                <label class="conl"><?php echo $lang_search['Show as']."\n" ?>
    766890                                                <br /><select name="show_as">
    767891                                                        <option value="topics"><?php echo $lang_search['Show as topics'] ?></option>
     
    773897                                </fieldset>
    774898                        </div>
    775                         <p><input type="submit" name="search" value="<?php echo $lang_common['Submit'] ?>" accesskey="s" /></p>
     899                        <p class="buttons"><input type="submit" name="search" value="<?php echo $lang_common['Submit'] ?>" accesskey="s" /></p>
    776900                </form>
    777901        </div>
Note: See TracChangeset for help on using the changeset viewer.