<?php
defined('WikyBlog') or die("Not an entry point...");
class topicHistory{
var $deleteRandom = false;
var $maxRevision;
var $revisionInfo;
function topicHistory(){
global $page;
$this->deleteRandom = dechex(mt_rand(0, 0x7fffffff)) . dechex(mt_rand(0, 0x7fffffff));
switch($page->userCmd){
case 'show':
$this->showRevision();
break;
case 'difference':
$this->difference();
break;
case 'compare':
$this->compareTwo();
break;
}
}
function getInstructions($maxRev,$minRev){
global $dbObject,$wbTables,$page;
$query = ' SELECT `instructions`, `revision`, `username`, `ip`, `summary`, `modified` FROM '.$wbTables['all_history'].' WHERE ';
$query .= ' `file_id` = "'.wbDB::escape($dbObject->file_id).'" ';
$query .= ' AND `revision` >= "'.wbDB::escape($minRev).'" ';
if( $maxRev !== false ){
$query .= ' AND `revision` < "'.wbDB::escape($maxRev).'" ';
}
$query .= ' ORDER BY `revision` DESC';
$result = wbDB::runQuery($query);
$num = mysql_num_rows($result);
if( $num < 1 ){
return false;
}
$affectedPosts = array();
$i = 0;
while($row = mysql_fetch_assoc($result) ){
if( !isset($this->maxRevision ) ){
$this->maxRevision = $row['revision'];
}
$instructions = unserialize($row['instructions']);
$post = $instructions['post'];
if( $instructions['action'] == 'delpost' ){
$affectedPosts[$post] = $this->deleteRandom;
}
if( $instructions['action'] == 'edit' ){
$affectedPosts[$post] = $instructions['text'];
}
$i++;
if( $num == $i ){
$this->revisionInfo = $row;
}
}
if( count($affectedPosts) < 1 ){
return false;
}
ksort($affectedPosts);
return $affectedPosts;
}
//////////////////////////////////////////////////////
//
// single revision functions
//
function showRevision(){
global $page,$dbObject,$langA,$wbTables;
if( !$dbObject->exists ){
message('FILE_MUST_EXIST');
return false;
}
$revNum =& $_GET['revNum'];
$title = $langA['revision'].$revNum;
$dbObject->links[$title] = '/Edit'.$dbObject->uniqLink.'?cmd=show&revNum='.$revNum;
//which post
$query = ' SELECT `instructions`, `modified` FROM '.$wbTables['all_history'].' WHERE ';
$query .= ' `file_id` = "'.wbDB::escape($dbObject->file_id).'" ';
$query .= ' AND `revision` = "'.wbDB::escape($revNum).'" ';
$query .= ' GROUP BY `file_id` ';
$result = wbDB::runQuery($query);
$row = mysql_fetch_assoc($result);
$instructions = unserialize($row['instructions']);
$selectedPost = $instructions['post'];
$modified = $row['modified'];
//get all the edits that possibly affect these entries
$affectedPosts = $this->getInstructions(false,$revNum);
//Get the posts surrounding the selected post
$query = 'SELECT SQL_CALC_FOUND_ROWS '.$wbTables['bb_posts'].'.* ';
$query .= ' FROM '.$wbTables['bb_posts'];
$query .= ' WHERE ';
$query .= ' `file_id` = "'.wbDB::escape($dbObject->file_id).'" ';
$query .= ' AND `id` >= "'.wbDB::escape($selectedPost-3).'" ';
$query .= ' AND `id` <= "'.wbDB::escape($selectedPost+3).'" ';
$query .= ' ORDER BY `id` ASC ';
$result = wbDB::runQuery($query);
//message
$message = $langA['revision_as_of'].dbFromDate($modified,3);
//previous|next links
$showLinks = array();
if( $revNum > 1){
$prevNum = $revNum-1;
$showLinks[] = wbLinks::local('/Edit'.$dbObject->uniqLink.'?cmd=show&revNum='.$prevNum,wbLang::text('show_prev_revision',$prevNum));
}
if( ($this->maxRevision-1) == $revNum ){
$showLinks[] = wbLinks::local($dbObject->uniqLink,'current_revision');
}else{
$nextNum = ($revNum+1);
$showLinks[] = wbLinks::local('/Edit'.$dbObject->uniqLink.'?cmd=show&revNum='.$nextNum,wbLang::text('show_next_revision',$nextNum));
}
if(count($showLinks) > 0){
$message .= '<br/><span class="sm">'.implode(' | ',$showLinks).'</span>';
}
message($message);
ob_start();
pluginIncludeFile('themes/default/template.php');
$this->replyLink = false;
while($row = mysql_fetch_assoc($result) ){
$post = $row['id'];
if( isset($affectedPosts[$post]) ){
if( $affectedPosts[$post] == $this->deleteRandom){
continue;
}
$row['text'] = $affectedPosts[$post];
}
$id = $row['id'];
unset($row['id']);
forumTemplate::postDisplay($row,$id);
//forumListing::abbrevOutput($row,$id);
//echo '<h3 class="underline">Post: '.$row['id'].'</h3>';
//echo $row['text'];
//echo showArray($row);
}
$page->contentA[$title] = wb::get_clean();
}
//////////////////////////////////////////////////////
//
// multiple revision functions
//
function difference(){
global $dbObject,$wbTables,$page;
$query = ' SELECT `revision` FROM '.$wbTables['all_history'].' WHERE ';
$query .= ' `file_id` = '.$dbObject->file_id;
$query .= ' AND `revision` > 0';
$query .= ' ORDER BY `revision` DESC';
$query .= ' LIMIT 1 OFFSET 0 ';
$result = wbDB::runQuery($query);
$num = mysql_num_rows($result);
if( $num < 1 ){
return false;
}
$row = mysql_fetch_assoc($result);
$_GET['rev1'] = $row['revision'];
$_GET['rev2'] = ($row['revision']-1);
$this->compareTwo();
}
function compareTwo(){
global $wbTables,$dbObject,$page,$langA,$dbObject;
if( !$dbObject->exists ){
message('FILE_MUST_EXIST');
return false;
}
if( isset($_GET['revNum1']) ){
$revNum1 = $_GET['revNum1'];
$revNum2 = $page->cmdArg[0];
}else{
$revNum1 = $_GET['rev1'];
$revNum2 = $_GET['rev2'];
}
//////// 1) Make sure times are set
if( empty($revNum1) || empty($revNum2) ){
message('SELECT_TWO_VERSIONS');
return;
}elseif( $revNum1 == $revNum2){
message('SELECT_TWO_VERSIONS');
return;
}
//////// 2) Find Min and Max times => get their events
$max = max($revNum1,$revNum2);
$min = min($revNum1,$revNum2);
$affectedSince = $this->getInstructions(false,$max);
$newerInfo = $this->revisionInfo;
$affectedPosts = $this->getInstructions($max,$min);
$olderInfo = $this->revisionInfo;
if( !$affectedPosts ){
return false;
}
//////// 3) Output
if( $this->maxRevision == $max ){
$temp = $langA['current'];
}else{
$temp = $max;
}
$title = toDisplay($dbObject->title).' ('.$min.$langA['vs'].$temp.')';
$page->displayTitle = $title;
if( $this->maxRevision == $max ){
$title = $langA['diff'];
$dbObject->links[$title] = '/Edit'.$dbObject->uniqLink.'?cmd=difference'; //for compatibility with changelog links
}else{
$dbObject->links[$title] = '/Edit'.$dbObject->uniqLink.'?cmd=compare&rev1='.$min.'&rev2='.$max;
}
ob_start();
//Top of Differences
//
//
echo '<table cellspacing="3" cellpadding="1" border="0" width="98%">';
echo '<tr><td></td><td style="text-align:center;width:50%">';
$isOwner = isOwner();
// Old Header
//
$editLink = false;
if( $this->maxRevision == $min ){
echo '<h4 class="heading">'.wbLinks::local($dbObject->uniqLink,$langA['current_revision']).'</h4>';
}else{
echo '<h4 class="heading">';
$temp = wbLang::text('revision_num_as_of',$min,dbFromDate($olderInfo['modified'],3));
echo wbLinks::local('/Edit'.$dbObject->uniqLink.'?cmd=show&revNum='.$min,$temp);
echo '</h4>';
}
if( !empty($olderInfo['username']) ){
echo wbLinks::local('/'.$olderInfo['username'].'/Home',$olderInfo['username']);
$user = $olderInfo['username'];
}else{
echo $olderInfo['ip'];
$user = $olderInfo['ip'];
}
if( isset($_SESSION['username']) && ($_SESSION['username'] != $user) ){
echo ' <span class="sm">('.wbLinks::special('Permissions?guest='.$user,'user permissions','title="'.$langA['SET_USER_PERMISSIONS'].$user.'"',$_SESSION['username']).')</span> ';
}
echo '<br/> '.$olderInfo['summary'];
if( $min > 1){
echo '<br/><span class="sm">'.wbLinks::local('/Edit'.$dbObject->uniqLink.'?cmd=compare&rev1='.($min-1).'&rev2='.$min,$langA['compare_with_prev']).' </span>';
}elseif( $min == 1){
echo '<br/><span class="sm">'.wbLinks::local('/Edit'.$dbObject->uniqLink.'?cmd=difference',$langA['compare_with_prev']).' </span>';
}
echo '</td><td></td>';
echo '<td style="text-align:center;width:50%">';
// New Header
//
$editLink = false;
if( $this->maxRevision == $max ){
echo '<h4 class="heading">'.wbLinks::local($dbObject->uniqLink,$langA['current_revision']).'</h4>';
}else{
echo '<h4 class="heading">';
$temp = wbLang::text('revision_num_as_of',$max,dbFromDate($newerInfo['modified'],3));
echo wbLinks::local('/Edit'.$dbObject->uniqLink.'?cmd=show&revNum='.$max,$temp);
echo '</h4>';
}
if( !empty($newerInfo['username']) ){
echo wbLinks::local('/'.$newerInfo['username'].'/Home',$newerInfo['username']);
$user = $newerInfo['username'];
}else{
echo $newerInfo['ip'];
$user = $newerInfo['ip'];
}
if( isset($_SESSION['username']) && ($_SESSION['username'] != $user) ){
echo ' <span class="sm">('.wbLinks::special('Permissions?guest='.$user,'user permissions','title="'.$langA['SET_USER_PERMISSIONS'].$user.'"',$_SESSION['username']).')</span> ';
}
echo '<br/> '.$newerInfo['summary'];
if( $this->maxRevision != $max ){
if( ($this->maxRevision-1) == $max ){
echo '<br/><span class="sm">'.wbLinks::local('/Edit'.$dbObject->uniqLink.'?cmd=difference',$langA['compare_with_next']).' </span>';
}else{
echo '<br/><span class="sm">'.wbLinks::local('/Edit'.$dbObject->uniqLink.'?cmd=compare&rev1='.$max.'&rev2='.($max+1),$langA['compare_with_next']).' </span>';
}
}
echo '</td></tr>';
$this->applyInstructions($affectedPosts,$affectedSince);
$page->contentA[$title] = wb::get_clean();
echo '</table>';
}
//put the instructions in meaningful sets
function applyInstructions(&$affectedPosts,&$affectedSince){
global $dbObject,$wbTables,$page,$langA;
$page->css2 = true;
// message(showArray($affectedPosts));
// message(showArray($affectedSince));
$startIndex = $prevIndex = $endIndex = false;
$instructionSet = $instructionSince = array();
foreach($affectedPosts as $postId => $value){
if( $prevIndex && ( $endIndex < ($postId -1)) ){
$this->showSet($startIndex,$endIndex,$instructionSet,$instructionSince);
$startIndex = $prevIndex = $endIndex = false;
$instructionSet = $instructionSince = array();
}
//starting
if( $startIndex === false ){
$startIndex = ($postId - 1);
if( isset($affectedSince[$startIndex]) ){
$instructionSince[$startIndex] = $affectedSince[$startIndex];
}
}
if( isset($affectedSince[$postId]) ){
$instructionSince[$postId] = $affectedSince[$postId];;
}
$instructionSet[$postId] = $value;
$prevIndex = $postId;
$endIndex = ($postId +1);
if( isset($affectedSince[$endIndex]) ){
$instructionSince[$endIndex] = $affectedSince[$endIndex];
}
}
if( $prevIndex ){
$this->showSet($startIndex,$endIndex,$instructionSet,$instructionSince);
}
}
//show the sets of instructions
function showSet($start,$end,$instructions,$instructionSince){
global $wbTables,$dbObject,$langA;
// message(showArray($instructions));
// message(showArray($instructionSince));
echo '<tr><td colspan="4">';
echo '<h3 class="underline">';
echo wbLang::text('POSTS_THROUGH',$start,$end);
echo '</h3>';
echo '</td></tr>';
echo '<tr><th>';
echo '</th><th>';
echo 'older';
echo '</th><th>';
echo '</th><th>';
echo 'newer';
echo '</tr>';
$query = 'SELECT `id`, `text` FROM '.$wbTables['bb_posts'];
$query .= ' WHERE ';
$query .= ' `file_id` = "'.wbDB::escape($dbObject->file_id).'" ';
$query .= ' AND `id` >= "'.$start.'" ';
$query .= ' AND `id` <= "'.$end.'" ';
$query .= ' ORDER BY `id` ASC';
$result = wbDB::runQuery($query);
while($row = mysql_fetch_assoc($result) ){
$id = $row['id'];
if( isset($instructionSince[$id]) ){
if( $id == $end ){
return;
}
if( $instructionSince[$id] == $this->deleteRandom ){
$row['text'] = '';
}else{
$row['text'] = $instructionSince[$id];
}
}
echo '<tr><td style="white-space:nowrap">';
echo $langA['post'].' '.$id;
echo '</td>';
if( isset($instructions[$id]) ){
if( $instructions[$id] == $this->deleteRandom ){
echo '<td class="historyDelete"> </td>';
}else{
echo '<td class="historyDelete">';
echo $instructions[$id];
echo '</td>';
}
echo '<td></td>';
echo '<td class="historyAdd">';
echo $row['text'];
echo '</td>';
//nothing changed
}else{
echo '<td class="historyNeut">';
echo $row['text'];
echo '</td>';
echo '<td></td>';
echo '<td class="historyNeut">';
echo $row['text'];
echo '</td>';
}
echo '</tr>';
}
}
}
new topicHistory();