Location: PHPKode > projects > PapyrusBB > PapyrusBB-0.6/include/tool/Compare.php
<?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/>&nbsp;'.$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/>&nbsp;'.$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">&nbsp;</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();
Return current item: PapyrusBB