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/moderate.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 
    25 
    26 define('PUN_ROOT', './');
     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 */
     8
     9define('PUN_ROOT', dirname(__FILE__).'/');
    2710require PUN_ROOT.'include/common.php';
    2811
    2912
    3013// This particular function doesn't require forum-based moderator access. It can be used
    31 // by all moderators and admins.
     14// by all moderators and admins
    3215if (isset($_GET['get_host']))
    3316{
    34         if ($pun_user['g_id'] > PUN_MOD)
     17        if (!$pun_user['is_admmod'])
    3518                message($lang_common['No permission']);
    3619
    3720        // Is get_host an IP address or a post ID?
    38         if (preg_match('/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/', $_GET['get_host']))
     21        if (@preg_match('%^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$%', $_GET['get_host']) || @preg_match('%^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$%', $_GET['get_host']))
    3922                $ip = $_GET['get_host'];
    4023        else
     
    4427                        message($lang_common['Bad request']);
    4528
    46                 $result = $db->query('SELECT poster_ip FROM '.$db->prefix.'posts WHERE id='.$get_host) or error('Impossible de retrouver l\'adresse IP', __FILE__, __LINE__, $db->error());
     29                $result = $db->query('SELECT poster_ip FROM '.$db->prefix.'posts WHERE id='.$get_host) or error('Unable to fetch post IP address', __FILE__, __LINE__, $db->error());
    4730                if (!$db->num_rows($result))
    4831                        message($lang_common['Bad request']);
     
    5134        }
    5235
    53         message('L\'adresse IP est : '.$ip.'<br />Le nom de l\'hÃŽte est : '.@gethostbyaddr($ip).'<br /><br /><a href="admin_users.php?show_users='.$ip.'">Voir plus d\'utilisateurs pour cette IP</a>');
     36        // Load the misc.php language file
     37        require PUN_ROOT.'lang/'.$pun_user['language'].'/misc.php';
     38
     39        message(sprintf($lang_misc['Host info 1'], $ip).'<br />'.sprintf($lang_misc['Host info 2'], @gethostbyaddr($ip)).'<br /><br /><a href="admin_users.php?show_users='.$ip.'">'.$lang_misc['Show more users'].'</a>');
    5440}
    5541
     
    6046        message($lang_common['Bad request']);
    6147
    62 $result = $db->query('SELECT moderators FROM '.$db->prefix.'forums WHERE id='.$fid) or error('UImpossible de retrouver les informations des forums', __FILE__, __LINE__, $db->error());
     48$result = $db->query('SELECT moderators FROM '.$db->prefix.'forums WHERE id='.$fid) or error('Unable to fetch forum info', __FILE__, __LINE__, $db->error());
    6349
    6450$moderators = $db->result($result);
    6551$mods_array = ($moderators != '') ? unserialize($moderators) : array();
    6652
    67 if ($pun_user['g_id'] != PUN_ADMIN && ($pun_user['g_id'] != PUN_MOD || !array_key_exists($pun_user['username'], $mods_array)))
     53if ($pun_user['g_id'] != PUN_ADMIN && ($pun_user['g_moderator'] == '0' || !array_key_exists($pun_user['username'], $mods_array)))
    6854        message($lang_common['No permission']);
    6955
     56// Get topic/forum tracking data
     57if (!$pun_user['is_guest'])
     58        $tracked_topics = get_tracked_topics();
    7059
    7160// Load the misc.php language file
     
    7362
    7463
    75 // All other topic moderation features require a topic id in GET
     64// All other topic moderation features require a topic ID in GET
    7665if (isset($_GET['tid']))
    7766{
     
    8170
    8271        // Fetch some info about the topic
    83         $result = $db->query('SELECT t.subject, t.num_replies, f.id AS forum_id, forum_name FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'subscriptions AS s ON (t.id=s.topic_id AND s.user_id='.$pun_user['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.id='.$fid.' AND t.id='.$tid.' AND t.moved_to IS NULL') or error('UImpossible de retrouver les informations des discussions', __FILE__, __LINE__, $db->error());
     72        $result = $db->query('SELECT t.subject, t.num_replies, t.first_post_id, f.id AS forum_id, forum_name 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 f.id='.$fid.' AND t.id='.$tid.' AND t.moved_to IS NULL') or error('Unable to fetch topic info', __FILE__, __LINE__, $db->error());
    8473        if (!$db->num_rows($result))
    8574                message($lang_common['Bad request']);
     
    8776        $cur_topic = $db->fetch_assoc($result);
    8877
    89 
    9078        // Delete one or more posts
    9179        if (isset($_POST['delete_posts']) || isset($_POST['delete_posts_comply']))
    9280        {
    93                 $posts = $_POST['posts'];
     81                $posts = isset($_POST['posts']) ? $_POST['posts'] : array();
    9482                if (empty($posts))
    9583                        message($lang_misc['No posts selected']);
     
    9987                        confirm_referrer('moderate.php');
    10088
    101                         if (preg_match('/[^0-9,]/', $posts))
     89                        if (@preg_match('%[^0-9,]%', $posts))
    10290                                message($lang_common['Bad request']);
    10391
     92                        // Verify that the post IDs are valid
     93                        $result = $db->query('SELECT 1 FROM '.$db->prefix.'posts WHERE id IN('.$posts.') AND topic_id='.$tid) or error('Unable to check posts', __FILE__, __LINE__, $db->error());
     94
     95                        if ($db->num_rows($result) != substr_count($posts, ',') + 1)
     96                                message($lang_common['Bad request']);
     97
    10498                        // Delete the posts
    105                         $db->query('DELETE FROM '.$db->prefix.'posts WHERE id IN('.$posts.')') or error('Impossible de supprimer les messages', __FILE__, __LINE__, $db->error());
     99                        $db->query('DELETE FROM '.$db->prefix.'posts WHERE id IN('.$posts.')') or error('Unable to delete posts', __FILE__, __LINE__, $db->error());
    106100
    107101                        require PUN_ROOT.'include/search_idx.php';
     
    109103
    110104                        // Get last_post, last_post_id, and last_poster for the topic after deletion
    111                         $result = $db->query('SELECT id, poster, posted FROM '.$db->prefix.'posts WHERE topic_id='.$tid.' ORDER BY id DESC LIMIT 1') or error('Impossible de retrouver les informations du message', __FILE__, __LINE__, $db->error());
     105                        $result = $db->query('SELECT id, poster, posted FROM '.$db->prefix.'posts WHERE topic_id='.$tid.' ORDER BY id DESC LIMIT 1') or error('Unable to fetch post info', __FILE__, __LINE__, $db->error());
    112106                        $last_post = $db->fetch_assoc($result);
    113107
     
    116110
    117111                        // Update the topic
    118                         $db->query('UPDATE '.$db->prefix.'topics SET last_post='.$last_post['posted'].', last_post_id='.$last_post['id'].', last_poster=\''.$db->escape($last_post['poster']).'\', num_replies=num_replies-'.$num_posts_deleted.' WHERE id='.$tid) or error('Impossible de modifier la discussion', __FILE__, __LINE__, $db->error());
     112                        $db->query('UPDATE '.$db->prefix.'topics SET last_post='.$last_post['posted'].', last_post_id='.$last_post['id'].', last_poster=\''.$db->escape($last_post['poster']).'\', num_replies=num_replies-'.$num_posts_deleted.' WHERE id='.$tid) or error('Unable to update topic', __FILE__, __LINE__, $db->error());
    119113
    120114                        update_forum($fid);
     
    124118
    125119
    126                 $page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_misc['Moderate'];
     120                $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_misc['Moderate']);
     121                define('PUN_ACTIVE_PAGE', 'index');
    127122                require PUN_ROOT.'header.php';
    128123
     
    136131                                        <legend><?php echo $lang_misc['Confirm delete legend'] ?></legend>
    137132                                        <div class="infldset">
    138                                                 <input type="hidden" name="posts" value="<?php echo implode(',', array_keys($posts)) ?>" />
     133                                                <input type="hidden" name="posts" value="<?php echo implode(',', array_map('intval', array_keys($posts))) ?>" />
    139134                                                <p><?php echo $lang_misc['Delete posts comply'] ?></p>
    140135                                        </div>
    141136                                </fieldset>
    142137                        </div>
    143                         <p><input type="submit" name="delete_posts_comply" value="<?php echo $lang_misc['Delete'] ?>" /><a href="javascript:history.go(-1)"><?php echo $lang_common['Go back'] ?></a></p>
     138                        <p class="buttons"><input type="submit" name="delete_posts_comply" value="<?php echo $lang_misc['Delete'] ?>" /> <a href="javascript:history.go(-1)"><?php echo $lang_common['Go back'] ?></a></p>
    144139                </form>
    145140        </div>
     
    149144                require PUN_ROOT.'footer.php';
    150145        }
    151 
    152 
    153         // Show the delete multiple posts view
     146        else if (isset($_POST['split_posts']) || isset($_POST['split_posts_comply']))
     147        {
     148                $posts = isset($_POST['posts']) ? $_POST['posts'] : array();
     149                if (empty($posts))
     150                        message($lang_misc['No posts selected']);
     151
     152                if (isset($_POST['split_posts_comply']))
     153                {
     154                        confirm_referrer('moderate.php');
     155
     156                        if (@preg_match('%[^0-9,]%', $posts))
     157                                message($lang_common['Bad request']);
     158
     159                        $move_to_forum = isset($_POST['move_to_forum']) ? intval($_POST['move_to_forum']) : 0;
     160                        if ($move_to_forum < 1)
     161                                message($lang_common['Bad request']);
     162
     163                        // How many posts did we just split off?
     164                        $num_posts_splitted = substr_count($posts, ',') + 1;
     165
     166                        // Verify that the post IDs are valid
     167                        $result = $db->query('SELECT 1 FROM '.$db->prefix.'posts WHERE id IN('.$posts.') AND topic_id='.$tid) or error('Unable to check posts', __FILE__, __LINE__, $db->error());
     168                        if ($db->num_rows($result) != $num_posts_splitted)
     169                                message($lang_common['Bad request']);
     170
     171                        // Verify that the move to forum ID is valid
     172                        $result = $db->query('SELECT 1 FROM '.$db->prefix.'forums AS f LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.group_id='.$pun_user['g_id'].' AND fp.forum_id='.$move_to_forum.') WHERE f.redirect_url IS NULL AND (fp.post_topics IS NULL OR fp.post_topics=1)') or error('Unable to fetch forum permissions', __FILE__, __LINE__, $db->error());
     173                        if (!$db->num_rows($result))
     174                                message($lang_common['Bad request']);
     175
     176                        // Load the post.php language file
     177                        require PUN_ROOT.'lang/'.$pun_user['language'].'/post.php';
     178
     179                        // Check subject
     180                        $new_subject = isset($_POST['new_subject']) ? pun_trim($_POST['new_subject']) : '';
     181
     182                        if ($new_subject == '')
     183                                message($lang_post['No subject']);
     184                        else if (pun_strlen($new_subject) > 70)
     185                                message($lang_post['Too long subject']);
     186
     187                        // Get data from the new first post
     188                        $result = $db->query('SELECT p.id, p.poster, p.posted FROM '.$db->prefix.'posts AS p WHERE id IN('.$posts.') ORDER BY p.id ASC LIMIT 1') or error('Unable to get first post', __FILE__, __LINE__, $db->error());
     189                        $first_post_data = $db->fetch_assoc($result);
     190
     191                        // Create the new topic
     192                        $db->query('INSERT INTO '.$db->prefix.'topics (poster, subject, posted, first_post_id, forum_id) VALUES (\''.$db->escape($first_post_data['poster']).'\', \''.$db->escape($new_subject).'\', '.$first_post_data['posted'].', '.$first_post_data['id'].', '.$move_to_forum.')') or error('Unable to create new topic', __FILE__, __LINE__, $db->error());
     193                        $new_tid = $db->insert_id();
     194
     195                        // Move the posts to the new topic
     196                        $db->query('UPDATE '.$db->prefix.'posts SET topic_id='.$new_tid.' WHERE id IN('.$posts.')') or error('Unable to move posts into new topic', __FILE__, __LINE__, $db->error());
     197
     198                        // Get last_post, last_post_id, and last_poster from the topic and update it
     199                        $result = $db->query('SELECT id, poster, posted FROM '.$db->prefix.'posts WHERE topic_id='.$tid.' ORDER BY id DESC LIMIT 1') or error('Unable to fetch post info', __FILE__, __LINE__, $db->error());
     200                        $last_post_data = $db->fetch_assoc($result);
     201                        $db->query('UPDATE '.$db->prefix.'topics SET last_post='.$last_post_data['posted'].', last_post_id='.$last_post_data['id'].', last_poster=\''.$db->escape($last_post_data['poster']).'\', num_replies=num_replies-'.$num_posts_splitted.' WHERE id='.$tid) or error('Unable to update topic', __FILE__, __LINE__, $db->error());
     202
     203                        // Get last_post, last_post_id, and last_poster from the new topic and update it
     204                        $result = $db->query('SELECT id, poster, posted FROM '.$db->prefix.'posts WHERE topic_id='.$new_tid.' ORDER BY id DESC LIMIT 1') or error('Unable to fetch post info', __FILE__, __LINE__, $db->error());
     205                        $last_post_data = $db->fetch_assoc($result);
     206                        $db->query('UPDATE '.$db->prefix.'topics SET last_post='.$last_post_data['posted'].', last_post_id='.$last_post_data['id'].', last_poster=\''.$db->escape($last_post_data['poster']).'\', num_replies='.($num_posts_splitted-1).' WHERE id='.$new_tid) or error('Unable to update topic', __FILE__, __LINE__, $db->error());
     207
     208                        update_forum($fid);
     209                        update_forum($move_to_forum);
     210
     211                        redirect('viewtopic.php?id='.$new_tid, $lang_misc['Split posts redirect']);
     212                }
     213
     214                $result = $db->query('SELECT c.id AS cid, c.cat_name, f.id AS fid, f.forum_name 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.post_topics IS NULL OR fp.post_topics=1) AND f.redirect_url IS NULL ORDER BY c.disp_position, c.id, f.disp_position') or error('Unable to fetch category/forum list', __FILE__, __LINE__, $db->error());
     215
     216                $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_misc['Moderate']);
     217                $focus_element = array('subject','new_subject');
     218                define('PUN_ACTIVE_PAGE', 'index');
     219                require PUN_ROOT.'header.php';
     220
     221?>
     222<div class="blockform">
     223        <h2><span><?php echo $lang_misc['Split posts'] ?></span></h2>
     224        <div class="box">
     225                <form id="subject" method="post" action="moderate.php?fid=<?php echo $fid ?>&amp;tid=<?php echo $tid ?>">
     226                        <div class="inform">
     227                                <fieldset>
     228                                        <legend><?php echo $lang_misc['Confirm split legend'] ?></legend>
     229                                        <div class="infldset">
     230                                                <input type="hidden" name="posts" value="<?php echo implode(',', array_map('intval', array_keys($posts))) ?>" />
     231                                                <label class="required"><strong><?php echo $lang_misc['New subject'] ?> <span><?php echo $lang_common['Required'] ?></span></strong><br /><input type="text" name="new_subject" size="80" maxlength="70" /><br /></label>
     232                                                <label><?php echo $lang_misc['Move to'] ?>
     233                                                <br /><select name="move_to_forum">
     234<?php
     235
     236        $cur_category = 0;
     237        while ($cur_forum = $db->fetch_assoc($result))
     238        {
     239                if ($cur_forum['cid'] != $cur_category) // A new category since last iteration?
     240                {
     241                        if ($cur_category)
     242                                echo "\t\t\t\t\t\t\t".'</optgroup>'."\n";
     243
     244                        echo "\t\t\t\t\t\t\t".'<optgroup label="'.pun_htmlspecialchars($cur_forum['cat_name']).'">'."\n";
     245                        $cur_category = $cur_forum['cid'];
     246                }
     247
     248                echo "\t\t\t\t\t\t\t\t".'<option value="'.$cur_forum['fid'].'"'.($fid == $cur_forum['fid'] ? ' selected="selected"' : '').'>'.pun_htmlspecialchars($cur_forum['forum_name']).'</option>'."\n";
     249        }
     250
     251?>
     252                                                        </optgroup>
     253                                                </select>
     254                                                <br /></label>
     255                                                <p><?php echo $lang_misc['Split posts comply'] ?></p>
     256                                        </div>
     257                                </fieldset>
     258                        </div>
     259                        <p class="buttons"><input type="submit" name="split_posts_comply" value="<?php echo $lang_misc['Split'] ?>" /> <a href="javascript:history.go(-1)"><?php echo $lang_common['Go back'] ?></a></p>
     260                </form>
     261        </div>
     262</div>
     263<?php
     264
     265                require PUN_ROOT.'footer.php';
     266        }
     267
     268
     269        // Show the moderate posts view
    154270
    155271        // Load the viewtopic.php language file
     
    157273
    158274        // Used to disable the Move and Delete buttons if there are no replies to this topic
    159         $button_status = ($cur_topic['num_replies'] == 0) ? ' disabled' : '';
     275        $button_status = ($cur_topic['num_replies'] == 0) ? ' disabled="disabled"' : '';
    160276
    161277
     
    163279        $num_pages = ceil(($cur_topic['num_replies'] + 1) / $pun_user['disp_posts']);
    164280
    165         $p = (!isset($_GET['p']) || $_GET['p'] <= 1 || $_GET['p'] > $num_pages) ? 1 : $_GET['p'];
     281        $p = (!isset($_GET['p']) || $_GET['p'] <= 1 || $_GET['p'] > $num_pages) ? 1 : intval($_GET['p']);
    166282        $start_from = $pun_user['disp_posts'] * ($p - 1);
    167283
    168284        // Generate paging links
    169         $paging_links = $lang_common['Pages'].': '.paginate($num_pages, $p, 'moderate.php?fid='.$fid.'&amp;tid='.$tid);
     285        $paging_links = '<span class="pages-label">'.$lang_common['Pages'].' </span>'.paginate($num_pages, $p, 'moderate.php?fid='.$fid.'&amp;tid='.$tid);
    170286
    171287
     
    174290
    175291
    176         $page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$cur_topic['subject'];
     292        $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), pun_htmlspecialchars($cur_topic['forum_name']), pun_htmlspecialchars($cur_topic['subject']));
     293        define('PUN_ACTIVE_PAGE', 'index');
    177294        require PUN_ROOT.'header.php';
    178295
    179296?>
    180297<div class="linkst">
    181         <div class="inbox">
    182                 <p class="pagelink conl"><?php echo $paging_links ?></p>
    183                 <ul><li><a href="index.php"><?php echo $lang_common['Index'] ?></a></li><li>&#160;&raquo;&#160;<a href="viewforum.php?id=<?php echo $fid ?>"><?php echo pun_htmlspecialchars($cur_topic['forum_name']) ?></a></li><li>&#160;&raquo;&#160;<?php echo pun_htmlspecialchars($cur_topic['subject']) ?></li></ul>
     298        <div class="inbox crumbsplus">
     299                <ul class="crumbs">
     300                        <li><a href="index.php"><?php echo $lang_common['Index'] ?></a></li>
     301                        <li><span>»&#160;</span><a href="viewforum.php?id=<?php echo $fid ?>"><?php echo pun_htmlspecialchars($cur_topic['forum_name']) ?></a></li>
     302                        <li><span>»&#160;</span><a href="viewtopic.php?id=<?php echo $tid ?>"><?php echo pun_htmlspecialchars($cur_topic['subject']) ?></a></li>
     303                        <li><span>»&#160;</span><strong><?php echo $lang_misc['Moderate'] ?></strong></li>
     304                </ul>
     305                <div class="pagepost">
     306                        <p class="pagelink conl"><?php echo $paging_links ?></p>
     307                </div>
    184308                <div class="clearer"></div>
    185309        </div>
     
    191315        require PUN_ROOT.'include/parser.php';
    192316
    193         $bg_switch = true;      // Used for switching background color in posts
    194         $post_count = 0;        // Keep track of post numbers
     317        $post_count = 0; // Keep track of post numbers
     318
     319        // Retrieve a list of post IDs, LIMIT is (really) expensive so we only fetch the IDs here then later fetch the remaining data
     320        $result = $db->query('SELECT id FROM '.$db->prefix.'posts WHERE topic_id='.$tid.' ORDER BY id LIMIT '.$start_from.','.$pun_user['disp_posts']) or error('Unable to fetch post IDs', __FILE__, __LINE__, $db->error());
     321
     322        $post_ids = array();
     323        for ($i = 0;$cur_post_id = $db->result($result, $i);$i++)
     324                $post_ids[] = $cur_post_id;
    195325
    196326        // Retrieve the posts (and their respective poster)
    197         $result = $db->query('SELECT u.title, u.num_posts, g.g_id, g.g_user_title, p.id, p.poster, p.poster_id, p.message, p.hide_smilies, p.posted, p.edited, p.edited_by FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'users AS u ON u.id=p.poster_id INNER JOIN '.$db->prefix.'groups AS g ON g.g_id=u.group_id WHERE p.topic_id='.$tid.' ORDER BY p.id LIMIT '.$start_from.','.$pun_user['disp_posts'], true) or error('Impossible de retrouver les informations du message', __FILE__, __LINE__, $db->error());
     327        $result = $db->query('SELECT u.title, u.num_posts, g.g_id, g.g_user_title, p.id, p.poster, p.poster_id, p.message, p.hide_smilies, p.posted, p.edited, p.edited_by FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'users AS u ON u.id=p.poster_id INNER JOIN '.$db->prefix.'groups AS g ON g.g_id=u.group_id WHERE p.id IN ('.implode(',', $post_ids).') ORDER BY p.id', true) or error('Unable to fetch post info', __FILE__, __LINE__, $db->error());
    198328
    199329        while ($cur_post = $db->fetch_assoc($result))
     
    201331                $post_count++;
    202332
    203                 // If the poster is a registered user.
     333                // If the poster is a registered user
    204334                if ($cur_post['poster_id'] > 1)
    205335                {
    206                         $poster = '<a href="profile.php?id='.$cur_post['poster_id'].'">'.pun_htmlspecialchars($cur_post['poster']).'</a>';
     336                        if ($pun_user['g_view_users'] == '1')
     337                                $poster = '<a href="profile.php?id='.$cur_post['poster_id'].'">'.pun_htmlspecialchars($cur_post['poster']).'</a>';
     338                        else
     339                                $poster = pun_htmlspecialchars($cur_post['poster']);
    207340
    208341                        // get_title() requires that an element 'username' be present in the array
     
    220353                }
    221354
    222                 // Switch the background color for every message.
    223                 $bg_switch = ($bg_switch) ? $bg_switch = false : $bg_switch = true;
    224                 $vtbg = ($bg_switch) ? ' roweven' : ' rowodd';
    225 
    226355                // Perform the main parsing of the message (BBCode, smilies, censor words etc)
    227356                $cur_post['message'] = parse_message($cur_post['message'], $cur_post['hide_smilies']);
     
    229358?>
    230359
    231 <div class="blockpost<?php echo $vtbg ?>">
    232         <a name="<?php echo $cur_post['id'] ?>"></a>
    233         <h2><span><span class="conr">#<?php echo ($start_from + $post_count) ?>&#160;</span><a href="viewtopic.php?pid=<?php echo $cur_post['id'].'#p'.$cur_post['id'] ?>"><?php echo format_time($cur_post['posted']) ?></a></span></h2>
     360<div id="p<?php echo $cur_post['id'] ?>" class="blockpost<?php if($cur_post['id'] == $cur_topic['first_post_id']) echo ' firstpost' ?><?php echo ($post_count % 2 == 0) ? ' roweven' : ' rowodd' ?><?php if ($post_count == 1) echo ' blockpost1' ?>">
     361        <h2><span><span class="conr">#<?php echo ($start_from + $post_count) ?></span> <a href="viewtopic.php?pid=<?php echo $cur_post['id'].'#p'.$cur_post['id'] ?>"><?php echo format_time($cur_post['posted']) ?></a></span></h2>
    234362        <div class="box">
    235363                <div class="inbox">
    236                         <div class="postleft">
    237                                 <dl>
    238                                         <dt><strong><?php echo $poster ?></strong></dt>
    239                                         <dd><strong><?php echo $user_title ?></strong></dd>
    240                                 </dl>
     364                        <div class="postbody">
     365                                <div class="postleft">
     366                                        <dl>
     367                                                <dt><strong><?php echo $poster ?></strong></dt>
     368                                                <dd class="usertitle"><strong><?php echo $user_title ?></strong></dd>
     369                                        </dl>
     370                                </div>
     371                                <div class="postright">
     372                                        <h3 class="nosize"><?php echo $lang_common['Message'] ?></h3>
     373                                        <div class="postmsg">
     374                                                <?php echo $cur_post['message']."\n" ?>
     375<?php if ($cur_post['edited'] != '') echo "\t\t\t\t\t\t".'<p class="postedit"><em>'.$lang_topic['Last edit'].' '.pun_htmlspecialchars($cur_post['edited_by']).' ('.format_time($cur_post['edited']).')</em></p>'."\n"; ?>
     376                                        </div>
     377                                </div>
    241378                        </div>
    242                         <div class="postright">
    243                                 <h3 class="nosize"><?php echo $lang_common['Message'] ?></h3>
    244                                 <div class="postmsg">
    245                                         <?php echo $cur_post['message']."\n" ?>
    246 <?php if ($cur_post['edited'] != '') echo "\t\t\t\t\t".'<p class="postedit"><em>'.$lang_topic['Last edit'].' '.pun_htmlspecialchars($cur_post['edited_by']).' ('.format_time($cur_post['edited']).')</em></p>'."\n"; ?>
    247                                 </div>
    248                                 <?php if ($start_from + $post_count > 1) echo '<p class="multidelete"><label><strong>'.$lang_misc['Select'].'</strong>&#160;&#160;<input type="checkbox" name="posts['.$cur_post['id'].']" value="1" /></label></p>'."\n" ?>
     379                </div>
     380                <div class="inbox">
     381                        <div class="postfoot clearb">
     382                                <div class="postfootright"><?php echo ($cur_post['id'] != $cur_topic['first_post_id']) ? '<p class="multidelete"><label><strong>'.$lang_misc['Select'].'</strong>&#160;<input type="checkbox" name="posts['.$cur_post['id'].']" value="1" /></label></p>' : '<p>'.$lang_misc['Cannot select first'].'</p>' ?></div>
    249383                        </div>
     384                </div>
     385        </div>
     386</div>
     387
     388<?php
     389
     390        }
     391
     392?>
     393<div class="postlinksb">
     394        <div class="inbox crumbsplus">
     395                <div class="pagepost">
     396                        <p class="pagelink conl"><?php echo $paging_links ?></p>
     397                        <p class="conr modbuttons"><input type="submit" name="split_posts" value="<?php echo $lang_misc['Split'] ?>"<?php echo $button_status ?> /> <input type="submit" name="delete_posts" value="<?php echo $lang_misc['Delete'] ?>"<?php echo $button_status ?> /></p>
    250398                        <div class="clearer"></div>
    251399                </div>
    252         </div>
    253 </div>
    254 
    255 
    256 
    257 
    258 <?php
    259 
    260         }
    261 
    262 ?>
    263 <div class="postlinksb">
    264         <div class="inbox">
    265                 <p class="pagelink conl"><?php echo $paging_links ?></p>
    266                 <p class="conr"><input type="submit" name="delete_posts" value="<?php echo $lang_misc['Delete'] ?>"<?php echo $button_status ?> /></p>
     400                <ul class="crumbs">
     401                        <li><a href="index.php"><?php echo $lang_common['Index'] ?></a></li>
     402                        <li><span>»&#160;</span><a href="viewforum.php?id=<?php echo $fid ?>"><?php echo pun_htmlspecialchars($cur_topic['forum_name']) ?></a></li>
     403                        <li><span>»&#160;</span><a href="viewtopic.php?id=<?php echo $tid ?>"><?php echo pun_htmlspecialchars($cur_topic['subject']) ?></a></li>
     404                        <li><span>»&#160;</span><strong><?php echo $lang_misc['Moderate'] ?></strong></li>
     405                </ul>
    267406                <div class="clearer"></div>
    268407        </div>
     
    282421                confirm_referrer('moderate.php');
    283422
    284                 if (preg_match('/[^0-9,]/', $_POST['topics']))
     423                if (@preg_match('%[^0-9,]%', $_POST['topics']))
    285424                        message($lang_common['Bad request']);
    286425
     
    290429                        message($lang_common['Bad request']);
    291430
    292                 // Delete any redirect topics if there are any (only if we moved/copied the topic back to where it where it was once moved from)
    293                 $db->query('DELETE FROM '.$db->prefix.'topics WHERE forum_id='.$move_to_forum.' AND moved_to IN('.implode(',',$topics).')') or error('Impossible de supprimer les redirections', __FILE__, __LINE__, $db->error());
     431                // Verify that the topic IDs are valid
     432                $result = $db->query('SELECT 1 FROM '.$db->prefix.'topics WHERE id IN('.implode(',',$topics).') AND forum_id='.$fid) or error('Unable to check topics', __FILE__, __LINE__, $db->error());
     433
     434                if ($db->num_rows($result) != count($topics))
     435                        message($lang_common['Bad request']);
     436
     437                // Verify that the move to forum ID is valid
     438                $result = $db->query('SELECT 1 FROM '.$db->prefix.'forums AS f LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.group_id='.$pun_user['g_id'].' AND fp.forum_id='.$move_to_forum.') WHERE f.redirect_url IS NULL AND (fp.post_topics IS NULL OR fp.post_topics=1)') or error('Unable to fetch forum permissions', __FILE__, __LINE__, $db->error());
     439                if (!$db->num_rows($result))
     440                        message($lang_common['Bad request']);
     441
     442                // Delete any redirect topics if there are any (only if we moved/copied the topic back to where it was once moved from)
     443                $db->query('DELETE FROM '.$db->prefix.'topics WHERE forum_id='.$move_to_forum.' AND moved_to IN('.implode(',',$topics).')') or error('Unable to delete redirect topics', __FILE__, __LINE__, $db->error());
    294444
    295445                // Move the topic(s)
    296                 $db->query('UPDATE '.$db->prefix.'topics SET forum_id='.$move_to_forum.' WHERE id IN('.implode(',',$topics).')') or error('Impossible de déplacer la discussion', __FILE__, __LINE__, $db->error());
     446                $db->query('UPDATE '.$db->prefix.'topics SET forum_id='.$move_to_forum.' WHERE id IN('.implode(',',$topics).')') or error('Unable to move topics', __FILE__, __LINE__, $db->error());
    297447
    298448                // Should we create redirect topics?
    299449                if (isset($_POST['with_redirect']))
    300450                {
    301                         while (list(, $cur_topic) = @each($topics))
     451                        foreach ($topics as $cur_topic)
    302452                        {
    303453                                // Fetch info for the redirect topic
    304                                 $result = $db->query('SELECT poster, subject, posted, last_post FROM '.$db->prefix.'topics WHERE id='.$cur_topic) or error('Impossible de retrouver les informations de la discussions', __FILE__, __LINE__, $db->error());
     454                                $result = $db->query('SELECT poster, subject, posted, last_post FROM '.$db->prefix.'topics WHERE id='.$cur_topic) or error('Unable to fetch topic info', __FILE__, __LINE__, $db->error());
    305455                                $moved_to = $db->fetch_assoc($result);
    306456
    307457                                // Create the redirect topic
    308                                 $db->query('INSERT INTO '.$db->prefix.'topics (poster, subject, posted, last_post, moved_to, forum_id) VALUES(\''.$db->escape($moved_to['poster']).'\', \''.$db->escape($moved_to['subject']).'\', '.$moved_to['posted'].', '.$moved_to['last_post'].', '.$cur_topic.', '.$fid.')') or error('Impossible de créer une redirection', __FILE__, __LINE__, $db->error());
     458                                $db->query('INSERT INTO '.$db->prefix.'topics (poster, subject, posted, last_post, moved_to, forum_id) VALUES(\''.$db->escape($moved_to['poster']).'\', \''.$db->escape($moved_to['subject']).'\', '.$moved_to['posted'].', '.$moved_to['last_post'].', '.$cur_topic.', '.$fid.')') or error('Unable to create redirect topic', __FILE__, __LINE__, $db->error());
    309459                        }
    310460                }
    311461
    312                 update_forum($fid);                             // Update the forum FROM which the topic was moved
    313                 update_forum($move_to_forum);   // Update the forum TO which the topic was moved
     462                update_forum($fid); // Update the forum FROM which the topic was moved
     463                update_forum($move_to_forum); // Update the forum TO which the topic was moved
    314464
    315465                $redirect_msg = (count($topics) > 1) ? $lang_misc['Move topics redirect'] : $lang_misc['Move topic redirect'];
     
    323473                        message($lang_misc['No topics selected']);
    324474
    325                 $topics = implode(',', array_keys($topics));
     475                $topics = implode(',', array_map('intval', array_keys($topics)));
    326476                $action = 'multi';
    327477        }
     
    335485        }
    336486
    337         $page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_misc['Moderate'];
     487        $result = $db->query('SELECT c.id AS cid, c.cat_name, f.id AS fid, f.forum_name 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.post_topics IS NULL OR fp.post_topics=1) AND f.redirect_url IS NULL ORDER BY c.disp_position, c.id, f.disp_position') or error('Unable to fetch category/forum list', __FILE__, __LINE__, $db->error());
     488        if ($db->num_rows($result) < 2)
     489                message($lang_misc['Nowhere to move']);
     490
     491        $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_misc['Moderate']);
     492        define('PUN_ACTIVE_PAGE', 'index');
    338493        require PUN_ROOT.'header.php';
    339494
     
    352507<?php
    353508
    354         $result = $db->query('SELECT c.id AS cid, c.cat_name, f.id AS fid, f.forum_name 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());
    355        
    356509        $cur_category = 0;
    357510        while ($cur_forum = $db->fetch_assoc($result))
    358511        {
    359                 if ($cur_forum['cid'] != $cur_category) // A new category since last iteration?
     512                if ($cur_forum['cid'] != $cur_category) // A new category since last iteration?
    360513                {
    361514                        if ($cur_category)
     
    380533                                </fieldset>
    381534                        </div>
    382                         <p><input type="submit" name="move_topics_to" value="<?php echo $lang_misc['Move'] ?>" /><a href="javascript:history.go(-1)"><?php echo $lang_common['Go back'] ?></a></p>
     535                        <p class="buttons"><input type="submit" name="move_topics_to" value="<?php echo $lang_misc['Move'] ?>" /> <a href="javascript:history.go(-1)"><?php echo $lang_common['Go back'] ?></a></p>
    383536                </form>
    384537        </div>
     
    389542}
    390543
     544// Merge two or more topics
     545else if (isset($_POST['merge_topics']) || isset($_POST['merge_topics_comply']))
     546{
     547        if (isset($_POST['merge_topics_comply']))
     548        {
     549                confirm_referrer('moderate.php');
     550
     551                if (@preg_match('%[^0-9,]%', $_POST['topics']))
     552                        message($lang_common['Bad request']);
     553
     554                $topics = explode(',', $_POST['topics']);
     555                if (count($topics) < 2)
     556                        message($lang_misc['Not enough topics selected']);
     557
     558                // Verify that the topic IDs are valid (redirect links will point to the merged topic after the merge)
     559                $result = $db->query('SELECT id FROM '.$db->prefix.'topics WHERE id IN('.implode(',', $topics).') AND forum_id='.$fid.' ORDER BY id ASC') or error('Unable to check topics', __FILE__, __LINE__, $db->error());
     560                if ($db->num_rows($result) != count($topics))
     561                        message($lang_common['Bad request']);
     562
     563                // The topic that we are merging into is the one with the smallest ID
     564                $merge_to_tid = $db->result($result);
     565
     566                // Make any redirect topics point to our new, merged topic
     567                $query = 'UPDATE '.$db->prefix.'topics SET moved_to='.$merge_to_tid.' WHERE moved_to IN('.implode(',', $topics).')';
     568
     569                // Should we create redirect topics?
     570                if (isset($_POST['with_redirect']))
     571                        $query .= ' OR (id IN('.implode(',', $topics).') AND id != '.$merge_to_tid.')';
     572
     573                $db->query($query) or error('Unable to make redirection topics', __FILE__, __LINE__, $db->error());
     574
     575                // Merge the posts into the topic
     576                $db->query('UPDATE '.$db->prefix.'posts SET topic_id='.$merge_to_tid.' WHERE topic_id IN('.implode(',', $topics).')') or error('Unable to merge the posts into the topic', __FILE__, __LINE__, $db->error());
     577
     578                // Delete any subscriptions
     579                $db->query('DELETE FROM '.$db->prefix.'topic_subscriptions WHERE topic_id IN('.implode(',', $topics).') AND topic_id != '.$merge_to_tid) or error('Unable to delete subscriptions', __FILE__, __LINE__, $db->error());
     580
     581                // Without redirection the old topics are removed
     582                if (!isset($_POST['with_redirect']))
     583                        $db->query('DELETE FROM '.$db->prefix.'topics WHERE id IN('.implode(',', $topics).') AND id != '.$merge_to_tid) or error('Unable to delete old topics', __FILE__, __LINE__, $db->error());
     584
     585                // Count number of replies in the topic
     586                $result = $db->query('SELECT COUNT(id) FROM '.$db->prefix.'posts WHERE topic_id='.$merge_to_tid) or error('Unable to fetch post count for topic', __FILE__, __LINE__, $db->error());
     587                $num_replies = $db->result($result, 0) - 1;
     588
     589                // Get last_post, last_post_id and last_poster
     590                $result = $db->query('SELECT posted, id, poster FROM '.$db->prefix.'posts WHERE topic_id='.$merge_to_tid.' ORDER BY id DESC LIMIT 1') or error('Unable to get last post info', __FILE__, __LINE__, $db->error());
     591                list($last_post, $last_post_id, $last_poster) = $db->fetch_row($result);
     592
     593                // Update topic
     594                $db->query('UPDATE '.$db->prefix.'topics SET num_replies='.$num_replies.', last_post='.$last_post.', last_post_id='.$last_post_id.', last_poster=\''.$db->escape($last_poster).'\' WHERE id='.$merge_to_tid) or error('Unable to update topic', __FILE__, __LINE__, $db->error());
     595
     596                // Update the forum FROM which the topic was moved and redirect
     597                update_forum($fid);
     598                redirect('viewforum.php?id='.$fid, $lang_misc['Merge topics redirect']);
     599        }
     600
     601        $topics = isset($_POST['topics']) ? $_POST['topics'] : array();
     602        if (count($topics) < 2)
     603                message($lang_misc['Not enough topics selected']);
     604
     605        $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_misc['Moderate']);
     606        define('PUN_ACTIVE_PAGE', 'index');
     607        require PUN_ROOT.'header.php';
     608
     609?>
     610<div class="blockform">
     611        <h2><span><?php echo $lang_misc['Merge topics'] ?></span></h2>
     612        <div class="box">
     613                <form method="post" action="moderate.php?fid=<?php echo $fid ?>">
     614                        <input type="hidden" name="topics" value="<?php echo implode(',', array_map('intval', array_keys($topics))) ?>" />
     615                        <div class="inform">
     616                                <fieldset>
     617                                        <legend><?php echo $lang_misc['Confirm merge legend'] ?></legend>
     618                                        <div class="infldset">
     619                                                <div class="rbox">
     620                                                        <label><input type="checkbox" name="with_redirect" value="1" /><?php echo $lang_misc['Leave redirect'] ?><br /></label>
     621                                                </div>
     622                                        </div>
     623                                </fieldset>
     624                        </div>
     625                        <p class="buttons"><input type="submit" name="merge_topics_comply" value="<?php echo $lang_misc['Merge'] ?>" /> <a href="javascript:history.go(-1)"><?php echo $lang_common['Go back'] ?></a></p>
     626                </form>
     627        </div>
     628</div>
     629<?php
     630
     631        require PUN_ROOT.'footer.php';
     632}
    391633
    392634// Delete one or more topics
    393 if (isset($_REQUEST['delete_topics']) || isset($_POST['delete_topics_comply']))
     635else if (isset($_POST['delete_topics']) || isset($_POST['delete_topics_comply']))
    394636{
    395637        $topics = isset($_POST['topics']) ? $_POST['topics'] : array();
     
    401643                confirm_referrer('moderate.php');
    402644
    403                 if (preg_match('/[^0-9,]/', $topics))
     645                if (@preg_match('%[^0-9,]%', $topics))
    404646                        message($lang_common['Bad request']);
    405647
    406648                require PUN_ROOT.'include/search_idx.php';
    407649
     650                // Verify that the topic IDs are valid
     651                $result = $db->query('SELECT 1 FROM '.$db->prefix.'topics WHERE id IN('.$topics.') AND forum_id='.$fid) or error('Unable to check topics', __FILE__, __LINE__, $db->error());
     652
     653                if ($db->num_rows($result) != substr_count($topics, ',') + 1)
     654                        message($lang_common['Bad request']);
     655
    408656                // Delete the topics and any redirect topics
    409                 $db->query('DELETE FROM '.$db->prefix.'topics WHERE id IN('.$topics.') OR moved_to IN('.$topics.')') or error('Impossible de supprimer la discussion', __FILE__, __LINE__, $db->error());
     657                $db->query('DELETE FROM '.$db->prefix.'topics WHERE id IN('.$topics.') OR moved_to IN('.$topics.')') or error('Unable to delete topic', __FILE__, __LINE__, $db->error());
    410658
    411659                // Delete any subscriptions
    412                 $db->query('DELETE FROM '.$db->prefix.'subscriptions WHERE topic_id IN('.$topics.')') or error('Impossible de supprimer l\'abonnement', __FILE__, __LINE__, $db->error());
    413 
    414                 // Create a list of the post ID's in this topic and then strip the search index
    415                 $result = $db->query('SELECT id FROM '.$db->prefix.'posts WHERE topic_id IN('.$topics.')') or error('Impossible de retrouver les messages', __FILE__, __LINE__, $db->error());
     660                $db->query('DELETE FROM '.$db->prefix.'topic_subscriptions WHERE topic_id IN('.$topics.')') or error('Unable to delete subscriptions', __FILE__, __LINE__, $db->error());
     661
     662                // Create a list of the post IDs in this topic and then strip the search index
     663                $result = $db->query('SELECT id FROM '.$db->prefix.'posts WHERE topic_id IN('.$topics.')') or error('Unable to fetch posts', __FILE__, __LINE__, $db->error());
    416664
    417665                $post_ids = '';
     
    419667                        $post_ids .= ($post_ids != '') ? ','.$row[0] : $row[0];
    420668
    421                 // We have to check that we actually have a list of post ID's since we could be deleting just a redirect topic
     669                // We have to check that we actually have a list of post IDs since we could be deleting just a redirect topic
    422670                if ($post_ids != '')
    423671                        strip_search_index($post_ids);
    424672
    425673                // Delete posts
    426                 $db->query('DELETE FROM '.$db->prefix.'posts WHERE topic_id IN('.$topics.')') or error('Impossible de supprimer les messages', __FILE__, __LINE__, $db->error());
     674                $db->query('DELETE FROM '.$db->prefix.'posts WHERE topic_id IN('.$topics.')') or error('Unable to delete posts', __FILE__, __LINE__, $db->error());
    427675
    428676                update_forum($fid);
     
    432680
    433681
    434         $page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_misc['Moderate'];
     682        $page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), $lang_misc['Moderate']);
     683        define('PUN_ACTIVE_PAGE', 'index');
    435684        require PUN_ROOT.'header.php';
    436685
    437686?>
    438687<div class="blockform">
    439         <h2><?php echo $lang_misc['Delete topics'] ?></h2>
     688        <h2><span><?php echo $lang_misc['Delete topics'] ?></span></h2>
    440689        <div class="box">
    441690                <form method="post" action="moderate.php?fid=<?php echo $fid ?>">
    442                         <input type="hidden" name="topics" value="<?php echo implode(',', array_keys($topics)) ?>" />
     691                        <input type="hidden" name="topics" value="<?php echo implode(',', array_map('intval', array_keys($topics))) ?>" />
    443692                        <div class="inform">
    444693                                <fieldset>
     
    449698                                </fieldset>
    450699                        </div>
    451                         <p><input type="submit" name="delete_topics_comply" value="<?php echo $lang_misc['Delete'] ?>" /><a href="javascript:history.go(-1)"><?php echo $lang_common['Go back'] ?></a></p>
     700                        <p class="buttons"><input type="submit" name="delete_topics_comply" value="<?php echo $lang_misc['Delete'] ?>" /><a href="javascript:history.go(-1)"><?php echo $lang_common['Go back'] ?></a></p>
    452701                </form>
    453702        </div>
     
    464713        $action = (isset($_REQUEST['open'])) ? 0 : 1;
    465714
    466         // There could be an array of topic ID's in $_POST
     715        // There could be an array of topic IDs in $_POST
    467716        if (isset($_POST['open']) || isset($_POST['close']))
    468717        {
     
    473722                        message($lang_misc['No topics selected']);
    474723
    475                 $db->query('UPDATE '.$db->prefix.'topics SET closed='.$action.' WHERE id IN('.implode(',', $topics).')') or error('Impossible de fermer les discussions', __FILE__, __LINE__, $db->error());
     724                $db->query('UPDATE '.$db->prefix.'topics SET closed='.$action.' WHERE id IN('.implode(',', $topics).') AND forum_id='.$fid) or error('Unable to close topics', __FILE__, __LINE__, $db->error());
    476725
    477726                $redirect_msg = ($action) ? $lang_misc['Close topics redirect'] : $lang_misc['Open topics redirect'];
     
    487736                        message($lang_common['Bad request']);
    488737
    489                 $db->query('UPDATE '.$db->prefix.'topics SET closed='.$action.' WHERE id='.$topic_id) or error('Impossible de fermer la discussion', __FILE__, __LINE__, $db->error());
     738                $db->query('UPDATE '.$db->prefix.'topics SET closed='.$action.' WHERE id='.$topic_id.' AND forum_id='.$fid) or error('Unable to close topic', __FILE__, __LINE__, $db->error());
    490739
    491740                $redirect_msg = ($action) ? $lang_misc['Close topic redirect'] : $lang_misc['Open topic redirect'];
     
    504753                message($lang_common['Bad request']);
    505754
    506         $db->query('UPDATE '.$db->prefix.'topics SET sticky=\'1\' WHERE id='.$stick) or error('Impossible d\'épingler la discussion', __FILE__, __LINE__, $db->error());
     755        $db->query('UPDATE '.$db->prefix.'topics SET sticky=\'1\' WHERE id='.$stick.' AND forum_id='.$fid) or error('Unable to stick topic', __FILE__, __LINE__, $db->error());
    507756
    508757        redirect('viewtopic.php?id='.$stick, $lang_misc['Stick topic redirect']);
     
    519768                message($lang_common['Bad request']);
    520769
    521         $db->query('UPDATE '.$db->prefix.'topics SET sticky=\'0\' WHERE id='.$unstick) or error('Impossible de détacher la discussion', __FILE__, __LINE__, $db->error());
     770        $db->query('UPDATE '.$db->prefix.'topics SET sticky=\'0\' WHERE id='.$unstick.' AND forum_id='.$fid) or error('Unable to unstick topic', __FILE__, __LINE__, $db->error());
    522771
    523772        redirect('viewtopic.php?id='.$unstick, $lang_misc['Unstick topic redirect']);
     
    531780
    532781// Fetch some info about the forum
    533 $result = $db->query('SELECT f.forum_name, f.redirect_url, f.num_topics FROM '.$db->prefix.'forums AS f 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.id='.$fid) or error('Impossible de retrouver les informations de forums', __FILE__, __LINE__, $db->error());
     782$result = $db->query('SELECT f.forum_name, f.redirect_url, f.num_topics, f.sort_by FROM '.$db->prefix.'forums AS f 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.id='.$fid) or error('Unable to fetch forum info', __FILE__, __LINE__, $db->error());
    534783if (!$db->num_rows($result))
    535784        message($lang_common['Bad request']);
     
    541790        message($lang_common['Bad request']);
    542791
    543 $page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.pun_htmlspecialchars($cur_forum['forum_name']);
    544 require PUN_ROOT.'header.php';
     792switch ($cur_forum['sort_by'])
     793{
     794        case 0:
     795                $sort_by = 'last_post DESC';
     796                break;
     797        case 1:
     798                $sort_by = 'posted DESC';
     799                break;
     800        case 2:
     801                $sort_by = 'subject ASC';
     802                break;
     803        default:
     804                $sort_by = 'last_post DESC';
     805                break;
     806}
    545807
    546808// Determine the topic offset (based on $_GET['p'])
    547809$num_pages = ceil($cur_forum['num_topics'] / $pun_user['disp_topics']);
    548810
    549 $p = (!isset($_GET['p']) || $_GET['p'] <= 1 || $_GET['p'] > $num_pages) ? 1 : $_GET['p'];
     811$p = (!isset($_GET['p']) || $_GET['p'] <= 1 || $_GET['p'] > $num_pages) ? 1 : intval($_GET['p']);
    550812$start_from = $pun_user['disp_topics'] * ($p - 1);
    551813
    552814// Generate paging links
    553 $paging_links = $lang_common['Pages'].': '.paginate($num_pages, $p, 'moderate.php?fid='.$fid)
     815$paging_links = '<span class="pages-label">'.$lang_common['Pages'].' </span>'.paginate($num_pages, $p, 'moderate.php?fid='.$fid);
     816
     817$page_title = array(pun_htmlspecialchars($pun_config['o_board_title']), pun_htmlspecialchars($cur_forum['forum_name']));
     818define('PUN_ACTIVE_PAGE', 'index');
     819require PUN_ROOT.'header.php';
    554820
    555821?>
    556822<div class="linkst">
    557         <div class="inbox">
    558                 <p class="pagelink conl"><?php echo $paging_links ?></p>
    559                 <ul><li><a href="index.php"><?php echo $lang_common['Index'] ?></a>&#160;</li><li>&raquo;&#160;<?php echo pun_htmlspecialchars($cur_forum['forum_name']) ?></li></ul>
     823        <div class="inbox crumbsplus">
     824                <ul class="crumbs">
     825                        <li><a href="index.php"><?php echo $lang_common['Index'] ?></a></li>
     826                        <li><span>»&#160;</span><a href="viewforum.php?id=<?php echo $fid ?>"><?php echo pun_htmlspecialchars($cur_forum['forum_name']) ?></a></li>
     827                        <li><span>»&#160;</span><strong><?php echo $lang_misc['Moderate'] ?></strong></li>
     828                </ul>
     829                <div class="pagepost">
     830                        <p class="pagelink conl"><?php echo $paging_links ?></p>
     831                </div>
    560832                <div class="clearer"></div>
    561833        </div>
     
    572844                                        <th class="tcl" scope="col"><?php echo $lang_common['Topic'] ?></th>
    573845                                        <th class="tc2" scope="col"><?php echo $lang_common['Replies'] ?></th>
    574                                         <th class="tc3" scope="col"><?php echo $lang_forum['Views'] ?></th>
    575                                         <th class="tcr"><?php echo $lang_common['Last post'] ?></th>
     846<?php if ($pun_config['o_topic_views'] == '1'): ?>                                      <th class="tc3" scope="col"><?php echo $lang_forum['Views'] ?></th>
     847<?php endif; ?>                                 <th class="tcr"><?php echo $lang_common['Last post'] ?></th>
    576848                                        <th class="tcmod" scope="col"><?php echo $lang_misc['Select'] ?></th>
    577849                                </tr>
     
    580852<?php
    581853
    582 // Select topics
    583 $result = $db->query('SELECT id, poster, subject, posted, last_post, last_post_id, last_poster, num_views, num_replies, closed, sticky, moved_to FROM '.$db->prefix.'topics WHERE forum_id='.$fid.' ORDER BY sticky DESC, last_post DESC LIMIT '.$start_from.', '.$pun_user['disp_topics']) or error('Impossible de retrouver la liste des discussions du forum', __FILE__, __LINE__, $db->error());
    584 
    585 // If there are topics in this forum.
     854
     855// Retrieve a list of topic IDs, LIMIT is (really) expensive so we only fetch the IDs here then later fetch the remaining data
     856$result = $db->query('SELECT id FROM '.$db->prefix.'topics WHERE forum_id='.$fid.' ORDER BY sticky DESC, '.$sort_by.', id DESC LIMIT '.$start_from.', '.$pun_user['disp_topics']) or error('Unable to fetch topic IDs', __FILE__, __LINE__, $db->error());
     857
     858// If there are topics in this forum
    586859if ($db->num_rows($result))
    587860{
     861        $topic_ids = array();
     862        for ($i = 0;$cur_topic_id = $db->result($result, $i);$i++)
     863                $topic_ids[] = $cur_topic_id;
     864
     865        // Select topics
     866        $result = $db->query('SELECT id, poster, subject, posted, last_post, last_post_id, last_poster, num_views, num_replies, closed, sticky, moved_to FROM '.$db->prefix.'topics WHERE id IN('.implode(',', $topic_ids).') ORDER BY sticky DESC, '.$sort_by.', id DESC') or error('Unable to fetch topic list for forum', __FILE__, __LINE__, $db->error());
     867
    588868        $button_status = '';
    589 
     869        $topic_count = 0;
    590870        while ($cur_topic = $db->fetch_assoc($result))
    591871        {
    592872
    593                 $icon_text = $lang_common['Normal icon'];
    594                 $item_status = '';
     873                ++$topic_count;
     874                $status_text = array();
     875                $item_status = ($topic_count % 2 == 0) ? 'roweven' : 'rowodd';
    595876                $icon_type = 'icon';
    596877
    597878                if ($cur_topic['moved_to'] == null)
    598879                {
    599                         $last_post = '<a href="viewtopic.php?pid='.$cur_topic['last_post_id'].'#p'.$cur_topic['last_post_id'].'">'.format_time($cur_topic['last_post']).'</a> '.$lang_common['by'].' '.pun_htmlspecialchars($cur_topic['last_poster']);
     880                        $last_post = '<a href="viewtopic.php?pid='.$cur_topic['last_post_id'].'#p'.$cur_topic['last_post_id'].'">'.format_time($cur_topic['last_post']).'</a> <span class="byuser">'.$lang_common['by'].' '.pun_htmlspecialchars($cur_topic['last_poster']).'</span>';
    600881                        $ghost_topic = false;
    601882                }
    602883                else
    603884                {
    604                         $last_post = '&#160;';
     885                        $last_post = '- - -';
    605886                        $ghost_topic = true;
    606887                }
     
    609890                        $cur_topic['subject'] = censor_words($cur_topic['subject']);
    610891
     892                if ($cur_topic['sticky'] == '1')
     893                {
     894                        $item_status .= ' isticky';
     895                        $status_text[] = '<span class="stickytext">'.$lang_forum['Sticky'].'</span>';
     896                }
     897
    611898                if ($cur_topic['moved_to'] != 0)
    612                         $subject = $lang_forum['Moved'].': <a href="viewtopic.php?id='.$cur_topic['moved_to'].'">'.pun_htmlspecialchars($cur_topic['subject']).'</a> <span class="byuser">'.$lang_common['by'].' '.pun_htmlspecialchars($cur_topic['poster']).'</span>';
     899                {
     900                        $subject = '<a href="viewtopic.php?id='.$cur_topic['moved_to'].'">'.pun_htmlspecialchars($cur_topic['subject']).'</a> <span class="byuser">'.$lang_common['by'].' '.pun_htmlspecialchars($cur_topic['poster']).'</span>';
     901                        $status_text[] = '<span class="movedtext">'.$lang_forum['Moved'].'</span>';
     902                        $item_status .= ' imoved';
     903                }
    613904                else if ($cur_topic['closed'] == '0')
    614                         $subject = '<a href="viewtopic.php?id='.$cur_topic['id'].'">'.pun_htmlspecialchars($cur_topic['subject']).'</a> <span>'.$lang_common['by'].'&#160;'.pun_htmlspecialchars($cur_topic['poster']).'</span>';
     905                        $subject = '<a href="viewtopic.php?id='.$cur_topic['id'].'">'.pun_htmlspecialchars($cur_topic['subject']).'</a> <span class="byuser">'.$lang_common['by'].' '.pun_htmlspecialchars($cur_topic['poster']).'</span>';
    615906                else
    616907                {
    617908                        $subject = '<a href="viewtopic.php?id='.$cur_topic['id'].'">'.pun_htmlspecialchars($cur_topic['subject']).'</a> <span class="byuser">'.$lang_common['by'].' '.pun_htmlspecialchars($cur_topic['poster']).'</span>';
    618                         $icon_text = $lang_common['Closed icon'];
    619                         $item_status = 'iclosed';
    620                 }
    621 
    622                 if ($cur_topic['last_post'] > $pun_user['last_visit'] && !$ghost_topic)
    623                 {
    624                         $icon_text .= ' '.$lang_common['New icon'];
     909                        $status_text[] = '<span class="closedtext">'.$lang_forum['Closed'].'</span>';
     910                        $item_status .= ' iclosed';
     911                }
     912
     913                if (!$ghost_topic && $cur_topic['last_post'] > $pun_user['last_visit'] && (!isset($tracked_topics['topics'][$cur_topic['id']]) || $tracked_topics['topics'][$cur_topic['id']] < $cur_topic['last_post']) && (!isset($tracked_topics['forums'][$fid]) || $tracked_topics['forums'][$fid] < $cur_topic['last_post']))
     914                {
    625915                        $item_status .= ' inew';
    626                         $icon_type = 'icon inew';
     916                        $icon_type = 'icon icon-new';
    627917                        $subject = '<strong>'.$subject.'</strong>';
    628                         $subject_new_posts = '<span class="newtext">[&#160;<a href="viewtopic.php?id='.$cur_topic['id'].'&amp;action=new" title="'.$lang_common['New posts info'].'">'.$lang_common['New posts'].'</a>&#160;]</span>';
     918                        $subject_new_posts = '<span class="newtext">[ <a href="viewtopic.php?id='.$cur_topic['id'].'&amp;action=new" title="'.$lang_common['New posts info'].'">'.$lang_common['New posts'].'</a> ]</span>';
    629919                }
    630920                else
    631921                        $subject_new_posts = null;
    632922
    633                 // We won't display "the dot", but we add the spaces anyway
    634                 if ($pun_config['o_show_dot'] == '1')
    635                         $subject = '&#160;&#160;'.$subject;
    636 
    637                 if ($cur_topic['sticky'] == '1')
    638                 {
    639                         $subject = '<span class="stickytext">'.$lang_forum['Sticky'].': </span>'.$subject;
    640                         $item_status .= ' isticky';
    641                         $icon_text .= ' '.$lang_forum['Sticky'];
    642                 }
     923                // Insert the status text before the subject
     924                $subject = implode(' ', $status_text).' '.$subject;
    643925
    644926                $num_pages_topic = ceil(($cur_topic['num_replies'] + 1) / $pun_user['disp_posts']);
    645927
    646928                if ($num_pages_topic > 1)
    647                         $subject_multipage = '[ '.paginate($num_pages_topic, -1, 'viewtopic.php?id='.$cur_topic['id']).' ]';
     929                        $subject_multipage = '<span class="pagestext">[ '.paginate($num_pages_topic, -1, 'viewtopic.php?id='.$cur_topic['id']).' ]</span>';
    648930                else
    649931                        $subject_multipage = null;
     
    652934                if (!empty($subject_new_posts) || !empty($subject_multipage))
    653935                {
    654                         $subject .= '&#160; '.(!empty($subject_new_posts) ? $subject_new_posts : '');
     936                        $subject .= !empty($subject_new_posts) ? ' '.$subject_new_posts : '';
    655937                        $subject .= !empty($subject_multipage) ? ' '.$subject_multipage : '';
    656938                }
    657939
    658940?>
    659                                 <tr<?php if ($item_status != '') echo ' class="'.trim($item_status).'"'; ?>>
     941                                <tr class="<?php echo $item_status ?>">
    660942                                        <td class="tcl">
    661                                                 <div class="<?php echo $icon_type ?>"><div class="nosize"><?php echo trim($icon_text) ?></div></div>
     943                                                <div class="<?php echo $icon_type ?>"><div class="nosize"><?php echo forum_number_format($topic_count + $start_from) ?></div></div>
    662944                                                <div class="tclcon">
    663                                                         <?php echo $subject."\n" ?>
     945                                                        <div>
     946                                                                <?php echo $subject."\n" ?>
     947                                                        </div>
    664948                                                </div>
    665949                                        </td>
    666                                         <td class="tc2"><?php echo (!$ghost_topic) ? $cur_topic['num_replies'] : '&#160;' ?></td>
    667                                         <td class="tc3"><?php echo (!$ghost_topic) ? $cur_topic['num_views'] : '&#160;' ?></td>
    668                                         <td class="tcr"><?php echo $last_post ?></td>
     950                                        <td class="tc2"><?php echo (!$ghost_topic) ? forum_number_format($cur_topic['num_replies']) : '-' ?></td>
     951<?php if ($pun_config['o_topic_views'] == '1'): ?>                                      <td class="tc3"><?php echo (!$ghost_topic) ? forum_number_format($cur_topic['num_views']) : '-' ?></td>
     952<?php endif; ?>                                 <td class="tcr"><?php echo $last_post ?></td>
    669953                                        <td class="tcmod"><input type="checkbox" name="topics[<?php echo $cur_topic['id'] ?>]" value="1" /></td>
    670954                                </tr>
     
    675959else
    676960{
    677         $button_status = ' disabled';
    678         echo "\t\t\t\t\t".'<tr><td class="tcl" colspan="5">'.$lang_forum['Empty forum'].'</td></tr>'."\n";
     961        $colspan = ($pun_config['o_topic_views'] == '1') ? 5 : 4;
     962        $button_status = ' disabled="disabled"';
     963        echo "\t\t\t\t\t".'<tr><td class="tcl" colspan="'.$colspan.'">'.$lang_forum['Empty forum'].'</td></tr>'."\n";
    679964}
    680965
     
    687972
    688973<div class="linksb">
    689         <div class="inbox">
    690                 <p class="pagelink conl"><?php echo $paging_links ?></p>
    691                 <p class="conr"><input type="submit" name="move_topics" value="<?php echo $lang_misc['Move'] ?>"<?php echo $button_status ?> />&#160;&#160;<input type="submit" name="delete_topics" value="<?php echo $lang_misc['Delete'] ?>"<?php echo $button_status ?> />&#160;&#160;<input type="submit" name="open" value="<?php echo $lang_misc['Open'] ?>"<?php echo $button_status ?> />&#160;&#160;<input type="submit" name="close" value="<?php echo $lang_misc['Close'] ?>"<?php echo $button_status ?> /></p>
     974        <div class="inbox crumbsplus">
     975                <div class="pagepost">
     976                        <p class="pagelink conl"><?php echo $paging_links ?></p>
     977                        <p class="conr modbuttons"><input type="submit" name="move_topics" value="<?php echo $lang_misc['Move'] ?>"<?php echo $button_status ?> /> <input type="submit" name="delete_topics" value="<?php echo $lang_misc['Delete'] ?>"<?php echo $button_status ?> /> <input type="submit" name="merge_topics" value="<?php echo $lang_misc['Merge'] ?>"<?php echo $button_status ?> /> <input type="submit" name="open" value="<?php echo $lang_misc['Open'] ?>"<?php echo $button_status ?> /> <input type="submit" name="close" value="<?php echo $lang_misc['Close'] ?>"<?php echo $button_status ?> /></p>
     978                        <div class="clearer"></div>
     979                </div>
     980                <ul class="crumbs">
     981                        <li><a href="index.php"><?php echo $lang_common['Index'] ?></a></li>
     982                        <li><span>»&#160;</span><a href="viewforum.php?id=<?php echo $fid ?>"><?php echo pun_htmlspecialchars($cur_forum['forum_name']) ?></a></li>
     983                        <li><span>»&#160;</span><strong><?php echo $lang_misc['Moderate'] ?></strong></li>
     984                </ul>
    692985                <div class="clearer"></div>
    693986        </div>
Note: See TracChangeset for help on using the changeset viewer.