Pagination on topics and a whole crapload of other stuff.
authorDan
Wed, 17 Oct 2007 21:52:27 -0400
changeset 2 253118325c65
parent 1 6f8b7c6fac02
child 3 88b85b9b9272
Pagination on topics and a whole crapload of other stuff.
decir/functions.php
decir/functions_viewtopic.php
decir/restoretopic.php
decir/viewforum.php
decir/viewtopic.php
plugins/Decir.php
--- a/decir/functions.php	Wed Oct 17 20:23:51 2007 -0400
+++ b/decir/functions.php	Wed Oct 17 21:52:27 2007 -0400
@@ -13,15 +13,6 @@
  */
 
 /**
- * Prints out breadcrumbs.
- */
- 
-function decir_breadcrumbs()
-{
-  // placeholder
-}
-
-/**
  * Inserts a post in reply to a topic. Does NOT check any type of authorization at all.
  * @param int Topic ID
  * @param string Post subject
@@ -117,10 +108,12 @@
   $post_text = bbcode_inject_uid($message, $bbcode_uid);
   $post_text = $db->escape($post_text);
   
-  $q = $db->sql_query('UPDATE '.table_prefix."decir_posts SET edit_count = edit_count + 1, edit_reason='$edit_reason', post_subject='$post_subject', last_edited_by=$last_edited_by WHERE post_id=$post_id;");
+  // grace period: if the user is editing his/her own post 10 minutes or less after they originally submitted it, don't mark it as edited
+  $grace = time() - ( 10 * 60 );
+  $q = $db->sql_query('UPDATE '.table_prefix."decir_posts SET post_subject='$post_subject', edit_count = edit_count + 1, edit_reason='$edit_reason', last_edited_by=$last_edited_by WHERE post_id=$post_id AND timestamp < $grace;");
   if ( !$q )
     $db->_die('Decir functions.php in decir_edit_post()');
-  
+
   $q = $db->sql_query('UPDATE '.table_prefix."decir_posts_text SET post_text='$post_text' WHERE post_id=$post_id;");
   if ( !$q )
     $db->_die('Decir functions.php in decir_edit_post()');
@@ -169,7 +162,7 @@
   if ( $row['post_id'] == $post_id )
   {
     // first post in the thread
-    return decir_delete_topic($topic_id, $del_reason);
+    return decir_delete_topic($topic_id, $del_reason, $for_real);
   }
   
   $del_reason = $db->escape($del_reason);
@@ -352,4 +345,47 @@
   return false;
 }
 
+/**
+ * Un-deletes a topic so that the public can see it.
+ * @param int Topic ID
+ */
+
+function decir_restore_topic($topic_id)
+{
+  global $db, $session, $paths, $template, $plugins; // Common objects
+  
+  if ( !is_int($topic_id) )
+    return false;
+  
+  // Obtain a list of posts in the topic
+  $q = $db->sql_query('SELECT post_id FROM '.table_prefix.'decir_posts WHERE topic_id = ' . $topic_id . ';');
+  if ( !$q )
+    $db->_die('Decir functions.php in decir_delete_topic()');
+  if ( $db->numrows() < 1 )
+    return false;
+  $posts = array();
+  while ( $row = $db->fetchrow() )
+  {
+    $posts[] = $row['post_id'];
+  }
+  
+  // Obtain forum ID
+  $q = $db->sql_query('SELECT forum_id FROM '.table_prefix."decir_topics WHERE topic_id = $topic_id;");
+  if ( !$q )
+    $db->_die('Decir functions.php in decir_restore_topic()');
+  list($forum_id) = $db->fetchrow_num();
+  $db->free_result();
+  
+  $q = $db->sql_query('UPDATE ' . table_prefix . "decir_topics SET topic_deleted = 0, topic_deletor = NULL, topic_delete_reason = NULL WHERE topic_id = $topic_id;");
+  
+  // Update forum stats
+  $post_count = count($posts);
+  $q = $db->sql_query('UPDATE '.table_prefix."decir_forums SET num_topics = num_topics + 1, num_posts = num_posts + $post_count WHERE forum_id = $forum_id;");
+  if ( !$q )
+    $db->_die('Decir functions.php in decir_restore_topic()');
+  decir_update_forum_stats($forum_id);
+  
+  return true;
+}
+
 ?>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/decir/functions_viewtopic.php	Wed Oct 17 21:52:27 2007 -0400
@@ -0,0 +1,216 @@
+<?php
+/*
+ * Decir
+ * Version 0.1
+ * Copyright (C) 2007 Dan Fuhry
+ * functions_viewtopic.php - Postbit compiler
+ *
+ * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ */
+
+/**
+ * Internally used in viewtopic; called by paginate()
+ * @package Decir
+ * @subpackage Presentation/UI
+ * @access private
+ */
+
+class DecirPostbit
+{
+  var $post_template = '
+    <!-- Start of post: {POST_ID} -->
+    
+    <a name="{POST_ID}" id="{POST_ID}"></a>
+    <div class="post tblholder">
+      <table border="0" cellspacing="1" cellpadding="4" style="width: 100%;">
+        <!-- BEGIN post_deleted -->
+        <tr>
+          <td class="row3" valign="top" style="height: 100%;">
+            <i>This post was deleted by {LAST_EDITED_BY}.<br />
+            <b>Reason:</b> {EDIT_REASON}</i>
+            <!-- BEGIN show_post -->
+            <br />
+            <br />
+            <b>The deleted post is shown below:</b>
+            <!-- END show_post -->
+          </td>
+          <td class="row1" style="width: 120px;" valign="top">
+            {USER_LINK}
+          </td>
+        </tr>
+        <!-- END post_deleted -->
+        <!-- BEGIN show_post -->
+        <tr>
+          <th colspan="2" style="text-align: left;">Posted: {TIMESTAMP}</th>
+        </tr>
+        <tr>
+          <td class="row3" valign="top" style="height: 100%;">
+            <table border="0" width="100%" style="height: 100%; background-color: transparent;">
+              <tr>
+                <td valign="top" colspan="2">
+                  {POST_TEXT}
+                </td>
+              </tr>
+              <!-- BEGINNOT post_deleted -->
+              <tr>
+                <td valign="bottom" style="text-align: left; font-size: smaller;">
+                  <!-- BEGIN post_edited -->
+                  <i>Last edited by {LAST_EDITED_BY}; edited <b>{EDIT_COUNT}</b> time{EDIT_COUNT_S} in total<br />
+                  <b>Reason:</b> {EDIT_REASON}</i>
+                  <!-- END post_edited -->
+                </td>
+                <td valign="bottom" style="text-align: right;">
+                  <small><a href="{EDIT_LINK}">edit</a> | <a href="{DELETE_LINK}">delete</a> | <a href="{QUOTE_LINK}">+ quote</a></small>
+                </td>
+              </tr>
+              <!-- BEGINELSE post_deleted -->
+              <tr>
+                <td valign="bottom" style="text-align: left; font-size: smaller;">
+                </td>
+                <td valign="bottom" style="text-align: right;">
+                  <small><a href="{RESTORE_LINK}">restore post</a> | <a href="{DELETE_LINK}">physically delete</a></small>
+                </td>
+              </tr>
+              <!-- END post_deleted -->
+            </table>
+          </td>
+          <td class="row1" style="width: 120px;" valign="top">
+            <div class="menu_nojs">
+              {USER_LINK}
+              <ul>
+                <li><a>View profile</a></li>
+                <li><a>Visit homepage</a></li>
+                <li><a href="{QUOTE_LINK}">Quote this post</a></li>
+                <li><a>Vote to ban this user</a></li>
+                <li><a>Send private message</a></li>
+                <li><a>View all messages posted by {USERNAME}</a></li>
+              </ul>
+            </div>
+            <span class="menuclear"></span>
+            {USER_TITLE}<br />
+            <br />
+            Joined: {REG_TIME}
+            <!-- BEGIN whos_online_support -->
+              <br />
+              <!-- BEGIN user_is_online -->
+              <span style="color: #007900;"><b>Online</b></span>
+              <!-- BEGINELSE user_is_online -->
+              <span style="color: #666666;">Offline</span>
+              <!-- END user_is_online -->
+            <!-- END whos_online_support -->
+          </td>
+        </tr>
+        <!-- END show_post -->
+      </table>
+    </div>
+    
+    <!-- End of post: {POST_ID} -->
+    ';
+
+  var $parser;
+
+  /**
+   * Constructor. Sets up parser object.
+   */
+  
+  function __construct()
+  {
+    global $db, $session, $paths, $template, $plugins; // Common objects
+    $this->parser = $template->makeParserText($this->post_template);
+  }
+
+  /**
+   * Renders a post.
+   * @todo document
+   * @access private
+   */
+  
+  function _render($_, $row)
+  {
+    global $db, $session, $paths, $template, $plugins; // Common objects
+    global $whos_online;
+    
+    $poster_name = ( $row['poster_id'] == 1 ) ? $row['poster_name'] : $row['username'];
+    $datetime = date('F d, Y h:i a', $row['timestamp']);
+    $post_text = render_bbcode($row['post_text'], $row['bbcode_uid']);
+    $post_text = RenderMan::smilieyize($post_text);
+    $regtime = date('F Y', $row['reg_time']);
+    
+    $user_color = '#0000AA';
+    switch ( $row['user_level'] )
+    {
+      case USER_LEVEL_ADMIN: $user_color = '#AA0000'; break;
+      case USER_LEVEL_MOD:   $user_color = '#00AA00'; break;
+    }
+    if ( $row['poster_id'] > 1 )
+    {
+      $user_link = "<a style='color: $user_color; background-color: transparent; display: inline; padding: 0;' href='".makeUrlNS('User', str_replace(' ', '_', $poster_name))."'><big>$poster_name</big></a>";
+    }
+    else
+    {
+      $user_link = '<big>'.$poster_name.'</big>';
+    }
+    $quote_link  = makeUrlNS('Special', 'Forum/New/Quote/' . $row['post_id'], false, true);
+    $edit_link   = makeUrlNS('Special', 'Forum/Edit/' . $row['post_id'], false, true);
+    $delete_link = makeUrlNS('Special', 'Forum/Delete/' . $row['post_id'], false, true);
+    $restore_link = makeUrlNS('Special', 'Forum/Delete/' . $row['post_id'], 'act=restore', true);
+    $user_title = 'Anonymous user';
+    switch ( $row['user_level'] )
+    {
+      case USER_LEVEL_ADMIN: $user_title = 'Administrator'; break;
+      case USER_LEVEL_MOD:   $user_title = 'Moderator'; break;
+      case USER_LEVEL_MEMBER:$user_title = 'Member'; break;
+      case USER_LEVEL_GUEST: $user_title = 'Guest'; break;
+    }
+    $leb_link = '';
+    if ( $row['editor'] )
+    {
+      $userpage_url = makeUrlNS('User', sanitize_page_id($row['editor']), false, true);
+      $row['editor'] = htmlspecialchars($row['editor']);
+      $leb_link = "<a href=\"$userpage_url\">{$row['editor']}</a>";
+    }
+    $this->parser->assign_vars(Array(
+        'POST_ID' => (string)$row['post_id'],
+        'USERNAME' => $poster_name,
+        'USER_LINK' => $user_link,
+        'REG_TIME' => $regtime,
+        'TIMESTAMP' => $datetime,
+        'POST_TEXT' => $post_text,
+        'USER_TITLE' => $user_title,
+        'QUOTE_LINK' => $quote_link,
+        'EDIT_LINK' => $edit_link,
+        'DELETE_LINK' => $delete_link,
+        'RESTORE_LINK' => $restore_link,
+        'EDIT_COUNT' => $row['edit_count'],
+        'EDIT_COUNT_S' => ( $row['edit_count'] == 1 ? '' : 's' ),
+        'LAST_EDITED_BY' => $leb_link,
+        'EDIT_REASON' => htmlspecialchars($row['edit_reason'])
+      ));
+    // Decir can integrate with the Who's Online plugin
+    $who_support = $plugins->loaded('WhosOnline') && $row['user_level'] >= USER_LEVEL_GUEST;
+    $user_online = false;
+    if ( $who_support && in_array($row['username'], $whos_online['users']) )
+    {
+      $user_online = true;
+    }
+    elseif ( $row['poster_id'] < 2 )
+    {
+      $who_support = false;
+    }
+    $this->parser->assign_bool(Array(
+        'whos_online_support' => $who_support,
+        'user_is_online' => $user_online,
+        'post_edited' => ( $row['edit_count'] > 0 ),
+        'post_deleted' => ( $row['post_deleted'] == 1 ),
+        // FIXME: This should check something on ACLs
+        'show_post' => ( $row['post_deleted'] != 1 || $session->user_level >= USER_LEVEL_MOD )
+      ));
+    return $this->parser->run();
+  }
+}
+
+?>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/decir/restoretopic.php	Wed Oct 17 21:52:27 2007 -0400
@@ -0,0 +1,82 @@
+<?php
+/*
+ * Decir
+ * Version 0.1
+ * Copyright (C) 2007 Dan Fuhry
+ * restoretopic.php - restores a deleted topic
+ *
+ * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ */
+
+require('common.php');
+
+$tid = $paths->getParam(1);
+if ( strval(intval($tid)) !== $tid )
+{
+  die_friendly('Error', '<p>Invalid topic ID</p>');
+}
+
+$tid = intval($tid);
+
+// Obtain topic info
+$q = $db->sql_query('SELECT t.forum_id, t.topic_id, t.topic_deleted, t.topic_deletor, t.topic_delete_reason, u.username AS deletor FROM '.table_prefix.'decir_topics AS t
+                       LEFT JOIN '.table_prefix.'users AS u
+                         ON ( u.user_id = t.topic_deletor OR t.topic_deletor IS NULL )
+                       WHERE t.topic_id='.$tid.';');
+if ( !$q )
+  $db->_die('Decir restoretopic.php');
+
+if ( $db->numrows() < 1 )
+{
+  die_friendly('Error', '<p>The topic you requested does not exist.</p>');
+}
+
+$row = $db->fetchrow();
+$db->free_result();
+
+$tid = intval($row['topic_id']);
+
+// $acl_type = ( $row['poster_id'] == $session->user_id && $session->user_logged_in ) ? 'decir_edit_own' : 'decir_edit_other';
+
+// FIXME: This will eventually use an ACL rule
+  
+$post_perms = $session->fetch_page_acl(strval($pid), 'DecirPost');
+if ( $session->user_level < USER_LEVEL_MOD ) // ( !$post_perms->get_permissions($acl_type) )
+{
+  die_friendly('Error', '<p>You do not have permission to restore this topic.</p>');
+}
+
+$edit_reason = '';
+if ( isset($_GET['act']) && $_GET['act'] == 'submit' )
+{
+  if ( isset($_POST['do']['restore']) )
+  {
+    $result = decir_restore_topic($tid);
+    if ( $result )
+    {
+      $url = makeUrlNS('Special', 'Forum/Topic/' . $tid, false, true);
+      redirect($url, 'Topic restored', 'The selected topic has been restored.', 4);
+    }
+  }
+  else if ( isset($_POST['do']['noop']) )
+  {
+    $url = makeUrlNS('Special', 'Forum/Topic/' . $tid, false, true);
+    redirect($url, '', '', 0);
+  }
+}
+
+$template->header(true);
+$form_submit_url = makeUrlNS('Special', 'Forum/RestoreTopic/' . $tid, 'act=submit', true);
+?>
+<form action="<?php echo $form_submit_url; ?>" method="post" enctype="multipart/form-data">
+  <p>Are you sure you want to restore this topic? If you do this, the public will be able to view it (providing that an access rule hasn't specified otherwise).</p>
+  <p><input type="submit" name="do[restore]" value="Restore topic" tabindex="3" /> <input tabindex="4" type="submit" name="do[noop]" value="Cancel" /></p>
+</form>
+<?php
+$template->footer(true);
+
+?>
--- a/decir/viewforum.php	Wed Oct 17 20:23:51 2007 -0400
+++ b/decir/viewforum.php	Wed Oct 17 21:52:27 2007 -0400
@@ -36,7 +36,7 @@
 $sort_dir    = ( isset($_GET['sort_dir'])    && in_array($_GET['sort_dir'],    array('ASC', 'DESC')) ) ? $_GET['sort_dir'] : 'DESC';
 
 $q = $db->sql_query('SELECT t.topic_id,t.topic_title,t.topic_type,t.topic_icon,
-                     COUNT(h.hit_id) AS num_views,t.topic_starter AS starter_id, u.username AS topic_starter,
+                     t.num_views,t.topic_starter AS starter_id, u.username AS topic_starter,
                      p.poster_name AS last_post_name, p.timestamp AS last_post_time, t.topic_deleted, u2.username AS deletor,
                      t.topic_delete_reason
                        FROM '.table_prefix.'decir_topics AS t
@@ -75,6 +75,8 @@
     $i++;
     if ( $last_row['topic_id'] != $row['topic_id'] || $i == $db->numrows() )
     {
+      if ( $num_replies < 0 )
+        $num_replies = 0;
       if ( $last_row['topic_deleted'] == 1 )
       {
         $thread_link = '';
--- a/decir/viewtopic.php	Wed Oct 17 20:23:51 2007 -0400
+++ b/decir/viewtopic.php	Wed Oct 17 21:52:27 2007 -0400
@@ -14,11 +14,10 @@
  
 require('common.php');
 require('bbcode.php');
+require('functions_viewtopic.php');
 
 global $whos_online;
 
-$template->header();
-
 if ( strtolower($paths->getParam(0)) == 'post' || isset($_GET['pid']) )
 {
   $pid = ( $n = $paths->getParam(1) ) ? $n : ( ( isset($_GET['pid']) ) ? $_GET['pid'] : 0 );
@@ -26,6 +25,7 @@
   
   if(empty($pid))
   {
+    $template->header();
     echo '<p>Invalid topic ID</p>';
     $template->footer();
     return;
@@ -46,13 +46,19 @@
   
   if(empty($tid))
   {
+    $template->header();
     echo '<p>Invalid topic ID</p>';
     $template->footer();
     return;
   }
 }
 
-$q = $db->sql_query('SELECT forum_id,topic_id FROM '.table_prefix.'decir_topics WHERE topic_id='.$tid.';');
+$q = $db->sql_query('SELECT t.forum_id, t.topic_title, f.forum_name, f.forum_id, t.topic_id, t.topic_deleted, t.topic_deletor, t.topic_delete_reason, u.username AS deletor FROM '.table_prefix.'decir_topics AS t
+                       LEFT JOIN '.table_prefix.'users AS u
+                         ON ( u.user_id = t.topic_deletor OR t.topic_deletor IS NULL )
+                       LEFT JOIN '.table_prefix.'decir_forums AS f
+                         ON ( f.forum_id = t.forum_id )
+                       WHERE t.topic_id='.$tid.';');
 
 if ( !$q )
   $db->_die();
@@ -65,97 +71,57 @@
   $forum_id = $row['forum_id'];
   $topic_id = $row['topic_id'];
   $topic_exists = true;
+  // FIXME: This will be controlled by an ACL rule
+  if ( $row['topic_deleted'] == 1 && $session->user_level < USER_LEVEL_MOD )
+  {
+    $topic_exists = false;
+  }
 }
 else
 {
   $topic_exists = false;
 }
 
-$post_template = <<<TPLCODE
-<a name="{POST_ID}" id="{POST_ID}"></a>
-<div class="post tblholder">
-  <table border="0" cellspacing="1" cellpadding="4" style="width: 100%;">
-    <!-- BEGIN post_deleted -->
-    <tr>
-      <td class="row3" valign="top" style="height: 100%;">
-        <i>This post was deleted by {LAST_EDITED_BY}.<br />
-        <b>Reason:</b> {EDIT_REASON}</i>
-        <!-- BEGIN show_post -->
-        <br />
-        <br />
-        <b>The deleted post is shown below:</b>
-        <!-- END show_post -->
-      </td>
-      <td class="row1" style="width: 120px;" valign="top">
-        {USER_LINK}
-      </td>
-    </tr>
-    <!-- END post_deleted -->
-    <!-- BEGIN show_post -->
-    <tr>
-      <th colspan="2" style="text-align: left;">Posted: {TIMESTAMP}</th>
-    </tr>
-    <tr>
-      <td class="row3" valign="top" style="height: 100%;">
-        <table border="0" width="100%" style="height: 100%; background-color: transparent;">
-          <tr>
-            <td valign="top" colspan="2">
-              {POST_TEXT}
-            </td>
-          </tr>
-          <!-- BEGINNOT post_deleted -->
-          <tr>
-            <td valign="bottom" style="text-align: left; font-size: smaller;">
-              <!-- BEGIN post_edited -->
-              <i>Last edited by {LAST_EDITED_BY}; edited <b>{EDIT_COUNT}</b> time{EDIT_COUNT_S} in total<br />
-              <b>Reason:</b> {EDIT_REASON}</i>
-              <!-- END post_edited -->
-            </td>
-            <td valign="bottom" style="text-align: right;">
-              <small><a href="{EDIT_LINK}">edit</a> | <a href="{DELETE_LINK}">delete</a> | <a href="{QUOTE_LINK}">+ quote</a></small>
-            </td>
-          </tr>
-          <!-- BEGINELSE post_deleted -->
-          <tr>
-            <td valign="bottom" style="text-align: left; font-size: smaller;">
-            </td>
-            <td valign="bottom" style="text-align: right;">
-              <small><a href="{RESTORE_LINK}">restore post</a> | <a href="{DELETE_LINK}">physically delete</a></small>
-            </td>
-          </tr>
-          <!-- END post_deleted -->
-        </table>
-      </td>
-      <td class="row1" style="width: 120px;" valign="top">
-        <div class="menu_nojs">
-          {USER_LINK}
-          <ul>
-            <li><a>View profile</a></li>
-            <li><a>Visit homepage</a></li>
-            <li><a href="{QUOTE_LINK}">Quote this post</a></li>
-            <li><a>Vote to ban this user</a></li>
-            <li><a>Send private message</a></li>
-            <li><a>View all messages posted by {USERNAME}</a></li>
-          </ul>
-        </div>
-        <span class="menuclear"></span>
-        {USER_TITLE}<br />
-        <br />
-        Joined: {REG_TIME}
-        <!-- BEGIN whos_online_support -->
-          <br />
-          <!-- BEGIN user_is_online -->
-          <span style="color: #007900;"><b>Online</b></span>
-          <!-- BEGINELSE user_is_online -->
-          <span style="color: #666666;">Offline</span>
-          <!-- END user_is_online -->
-        <!-- END whos_online_support -->
-      </td>
-    </tr>
-    <!-- END show_post -->
-  </table>
-</div>
-TPLCODE;
+// Set page title
+$template->tpl_strings['PAGE_NAME'] = htmlspecialchars($row['topic_title']) . ' &laquo; ' . htmlspecialchars($row['forum_name']) . ' &laquo; Forums';
+
+$template->header();
+
+// build breadcrumbs
+echo '<div class="breadcrumbs">';
+echo '<a href="' . makeUrlNS('Special', 'Forum') . '">Forum index</a> &raquo; ';
+echo '<a href="' . makeUrlNS('Special', 'Forum/ViewForum/' . $row['forum_id']) . '">' . htmlspecialchars($row['forum_name']) . '</a> &raquo; ';
+echo htmlspecialchars($row['topic_title']);
+echo '</div>';
+
+if ( $row['topic_deleted'] == 1 )
+{
+  // User will at this point have permission to read the deleted topic (and thus restore it)
+  $restore_url = makeUrlNS('Special', 'Forum/RestoreTopic/' . $topic_id, false, true);
+  echo '<div class="usermessage">This topic was deleted by ' . htmlspecialchars($row['deletor']) . '. You can <a href="' . $restore_url . '">restore this topic</a>.<br />
+                                 <i>Reason for deletion: ' . htmlspecialchars($row['topic_delete_reason']) . '</i></div>';
+}
+
+if ( !$topic_exists )
+{
+  die_friendly('Error', '<p>The topic you requested does not exist.</p>');
+}
+
+$sql = 'SELECT COUNT(post_id) AS np FROM '.table_prefix."decir_posts WHERE topic_id=$tid;";
+$q = $db->sql_query($sql);
+if ( !$q )
+  $db->_die();
+list($num_posts) = $db->fetchrow_num();
+$db->free_result();
+
+$offset = 0;
+if ( $p = $paths->getParam(2) )
+{
+  if ( preg_match('/^start=([0-9]+)$/', $p, $m) )
+  {
+    $offset = intval($m[1]);
+  }
+}
 
 $sql = 'SELECT p.post_id,p.poster_name,p.poster_id,u.username,p.timestamp,p.edit_count,p.last_edited_by,p.post_deleted,u2.username AS editor,p.edit_reason,u.user_level,u.reg_time,t.post_text,t.bbcode_uid FROM '.table_prefix.'decir_posts AS p
           LEFT JOIN '.table_prefix.'users AS u
@@ -168,96 +134,26 @@
           GROUP BY p.post_id
           ORDER BY p.timestamp ASC;';
 
-$q = $db->sql_query($sql);
+$q = $db->sql_unbuffered_query($sql);
 if ( !$q )
   $db->_die();
 
-if ( $db->numrows() < 1 )
-{
-  die_friendly('Error', '<p>The topic you requested does not exist.</p>');
-}
-
-$parser = $template->makeParserText($post_template);
+$formatter = new DecirPostbit();
 
-while ( $row = $db->fetchrow() )
-{
-  $poster_name = ( $row['poster_id'] == 1 ) ? $row['poster_name'] : $row['username'];
-  $datetime = date('F d, Y h:i a', $row['timestamp']);
-  $post_text = render_bbcode($row['post_text'], $row['bbcode_uid']);
-  $post_text = RenderMan::smilieyize($post_text);
-  $regtime = date('F Y', $row['reg_time']);
-  
-  $user_color = '#0000AA';
-  switch ( $row['user_level'] )
-  {
-    case USER_LEVEL_ADMIN: $user_color = '#AA0000'; break;
-    case USER_LEVEL_MOD:   $user_color = '#00AA00'; break;
-  }
-  if ( $row['poster_id'] > 1 )
-  {
-    $user_link = "<a style='color: $user_color; background-color: transparent; display: inline; padding: 0;' href='".makeUrlNS('User', str_replace(' ', '_', $poster_name))."'><big>$poster_name</big></a>";
-  }
-  else
-  {
-    $user_link = '<big>'.$poster_name.'</big>';
-  }
-  $quote_link  = makeUrlNS('Special', 'Forum/New/Quote/' . $row['post_id'], false, true);
-  $edit_link   = makeUrlNS('Special', 'Forum/Edit/' . $row['post_id'], false, true);
-  $delete_link = makeUrlNS('Special', 'Forum/Delete/' . $row['post_id'], false, true);
-  $restore_link = makeUrlNS('Special', 'Forum/Delete/' . $row['post_id'], 'act=restore', true);
-  $user_title = 'Anonymous user';
-  switch ( $row['user_level'] )
-  {
-    case USER_LEVEL_ADMIN: $user_title = 'Administrator'; break;
-    case USER_LEVEL_MOD:   $user_title = 'Moderator'; break;
-    case USER_LEVEL_MEMBER:$user_title = 'Member'; break;
-    case USER_LEVEL_GUEST: $user_title = 'Guest'; break;
-  }
-  $leb_link = '';
-  if ( $row['editor'] )
-  {
-    $userpage_url = makeUrlNS('User', sanitize_page_id($row['editor']), false, true);
-    $row['editor'] = htmlspecialchars($row['editor']);
-    $leb_link = "<a href=\"$userpage_url\">{$row['editor']}</a>";
-  }
-  $parser->assign_vars(Array(
-      'POST_ID' => (string)$row['post_id'],
-      'USERNAME' => $poster_name,
-      'USER_LINK' => $user_link,
-      'REG_TIME' => $regtime,
-      'TIMESTAMP' => $datetime,
-      'POST_TEXT' => $post_text,
-      'USER_TITLE' => $user_title,
-      'QUOTE_LINK' => $quote_link,
-      'EDIT_LINK' => $edit_link,
-      'DELETE_LINK' => $delete_link,
-      'RESTORE_LINK' => $restore_link,
-      'EDIT_COUNT' => $row['edit_count'],
-      'EDIT_COUNT_S' => ( $row['edit_count'] == 1 ? '' : 's' ),
-      'LAST_EDITED_BY' => $leb_link,
-      'EDIT_REASON' => htmlspecialchars($row['edit_reason'])
-    ));
-  // Decir can integrate with the Who's Online plugin
-  $who_support = $plugins->loaded('WhosOnline') && $row['user_level'] >= USER_LEVEL_GUEST;
-  $user_online = false;
-  if ( $who_support && in_array($row['username'], $whos_online['users']) )
-  {
-    $user_online = true;
-  }
-  elseif ( $row['poster_id'] < 2 )
-  {
-    $who_support = false;
-  }
-  $parser->assign_bool(Array(
-      'whos_online_support' => $who_support,
-      'user_is_online' => $user_online,
-      'post_edited' => ( $row['edit_count'] > 0 ),
-      'post_deleted' => ( $row['post_deleted'] == 1 ),
-      // FIXME: This should check something on ACLs
-      'show_post' => ( $row['post_deleted'] != 1 || $session->user_level >= USER_LEVEL_MOD )
-    ));
-  echo $parser->run();
-}
+$html = paginate(
+    $q, // MySQL result resource
+    '{post_id}',
+    $num_posts,
+    makeUrlNS('Special', 'Forum/Topic/' . $tid . '/start=%s', false, true),
+    $offset,
+    15,
+    array('post_id' => array($formatter, '_render'))
+  );
+
+if ( $html )
+  echo $html;
+else
+  die_friendly('Error', '<p>The topic you requested does not exist.</p>');
 
 $db->free_result();
 
@@ -294,6 +190,8 @@
 // log the hit
 $time = time();
 $q = $db->sql_query('INSERT INTO '.table_prefix."decir_hits(user_id, topic_id, timestamp) VALUES($session->user_id, $tid, $time);");
+$q = $db->sql_query('UPDATE '.table_prefix."decir_topics SET num_views = num_views + 1 WHERE topic_id = $tid;");
 
 $template->footer();
 
+?>
--- a/plugins/Decir.php	Wed Oct 17 20:23:51 2007 -0400
+++ b/plugins/Decir.php	Wed Oct 17 21:52:27 2007 -0400
@@ -86,6 +86,9 @@
     case 'delete':
       require('delete.php');
       break;
+    case 'restoretopic':
+      require('restoretopic.php');
+      break;
   }
   
   chdir($curdir);