hide print-specific output from cologneblue and nostalgia, too
[lhc/web/wiklou.git] / includes / DifferenceEngine.php
index 712690c..3f0e341 100644 (file)
@@ -1,11 +1,12 @@
-<?
+<?php
 # See diff.doc
 
 class DifferenceEngine {
        /* private */ var $mOldid, $mNewid;
        /* private */ var $mOldtitle, $mNewtitle;
        /* private */ var $mOldtext, $mNewtext;
-
+       /* private */ var $mOldUser, $mNewUser;
+       
        function DifferenceEngine( $old, $new )
        {
                $this->mOldid = $old;
@@ -26,12 +27,34 @@ class DifferenceEngine {
                        $wgOut->addHTML( $mtext );
                        return;
                }
-               $wgOut->supressQuickbar();
+               $wgOut->suppressQuickbar();
                $wgOut->setSubtitle( wfMsg( "difference" ) );
                $wgOut->setRobotpolicy( "noindex,follow" );
+               
+               $sk = $wgUser->getSkin();
+               $talk = $wgLang->getNsText( NS_TALK );
+               $contribs = wfMsg( "contribslink" );
+
+               $oldUserLink = $sk->makeLinkObj( Title::makeTitle( NS_USER, $this->mOldUser ), $this->mOldUser );
+               $newUserLink = $sk->makeLinkObj( Title::makeTitle( NS_USER, $this->mNewUser ), $this->mNewUser );
+               $oldUTLink = $sk->makeLinkObj( Title::makeTitle( NS_USER_TALK, $this->mOldUser ), $talk );
+               $newUTLink = $sk->makeLinkObj( Title::makeTitle( NS_USER_TALK, $this->mNewUser ), $talk );
+               $oldContribs = $sk->makeKnownLinkObj( Title::makeTitle( NS_SPECIAL, "Contributions" ), $contribs,
+                       "target=" . urlencode($this->mOldUser) );
+               $newContribs = $sk->makeKnownLinkObj( Title::makeTitle( NS_SPECIAL, "Contributions" ), $contribs,
+                       "target=" . urlencode($this->mNewUser) );
+               if ( !$this->mNewid && $wgUser->isSysop() ) {
+                       $rollback = "&nbsp;&nbsp;&nbsp;<strong>[" . $sk->makeKnownLinkObj( $wgTitle, wfMsg( "rollbacklink" ),
+                               "action=rollback&from=" . urlencode($this->mNewUser) ) . "]</strong>";
+               } else {
+                       $rollback = "";
+               }
+
+               $oldHeader = "<strong>{$this->mOldtitle}</strong><br>$oldUserLink ($oldUTLink | $oldContribs)";
+               $newHeader = "<strong>{$this->mNewtitle}</strong><br>$newUserLink ($newUTLink | $newContribs) $rollback";
 
                DifferenceEngine::showDiff( $this->mOldtext, $this->mNewtext,
-                 $this->mOldtitle, $this->mNewtitle );
+                 $oldHeader, $newHeader );
                $wgOut->addHTML( "<hr><h2>{$this->mNewtitle}</h2>\n" );
                $wgOut->addWikiText( $this->mNewtext );
        }
@@ -45,12 +68,12 @@ class DifferenceEngine {
                $nta = explode( "\n", str_replace( "\r\n", "\n",
                  htmlspecialchars( $ntext ) ) );
 
-               $wgOut->addHTML( "<table width='98%' border=0
-cellpadding=0 cellspacing='4px'><tr>
+               $wgOut->addHTML( "<table border=0
+cellpadding=0 cellspacing='4px' class='special'><tr>
 <td colspan=2 width='50%' align=center bgcolor='#cccccc'>
-<strong>{$otitle}</strong></td>
+{$otitle}</td>
 <td colspan=2 width='50%' align=center bgcolor='#cccccc'>
-<strong>{$ntitle}</strong></td>
+{$ntitle}</td>
 </tr>\n" );
 
                $diffs = new Diff( $ota, $nta );
@@ -68,50 +91,54 @@ cellpadding=0 cellspacing='4px'><tr>
        {
                global $wgTitle, $wgOut, $wgLang;
                $fname = "DifferenceEngine::loadText";
-
+               
                if ( 0 == $this->mNewid || 0 == $this->mOldid ) {
                        $wgOut->setArticleFlag( true );
                        $this->mNewtitle = wfMsg( "currentrev" );
                        $id = $wgTitle->getArticleID();
-
-                       $sql = "SELECT cur_text FROM cur WHERE cur_id={$id}";
+                       
+                       $sql = "SELECT cur_text, cur_user_text FROM cur WHERE cur_id={$id}";
                        $res = wfQuery( $sql, DB_READ, $fname );
                        if ( 0 == wfNumRows( $res ) ) { return false; }
 
                        $s = wfFetchObject( $res );
                        $this->mNewtext = $s->cur_text;
+                       $this->mNewUser = $s->cur_user_text;
                } else {
-                       $sql = "SELECT old_timestamp,old_text FROM old WHERE " .
+                       $sql = "SELECT old_timestamp,old_text,old_flags,old_user_text FROM old WHERE " .
                          "old_id={$this->mNewid}";
 
                        $res = wfQuery( $sql, DB_READ, $fname );
                        if ( 0 == wfNumRows( $res ) ) { return false; }
 
                        $s = wfFetchObject( $res );
-                       $this->mNewtext = $s->old_text;
+                       $this->mNewtext = Article::getRevisionText( $s );
 
                        $t = $wgLang->timeanddate( $s->old_timestamp, true );
                        $this->mNewtitle = wfMsg( "revisionasof", $t );
+                       $this->mNewUser = $s->old_user_text;
                }
                if ( 0 == $this->mOldid ) {
-                       $sql = "SELECT old_timestamp,old_text FROM old USE INDEX (name_title_timestamp) WHERE " .
+                       $sql = "SELECT old_timestamp,old_text,old_flags,old_user_text " .
+                         "FROM old USE INDEX (name_title_timestamp) WHERE " .
                          "old_namespace=" . $wgTitle->getNamespace() . " AND " .
                          "old_title='" . wfStrencode( $wgTitle->getDBkey() ) .
                          "' ORDER BY inverse_timestamp LIMIT 1";
                        $res = wfQuery( $sql, DB_READ, $fname );
                } else {
-                       $sql = "SELECT old_timestamp,old_text FROM old WHERE " .
+                       $sql = "SELECT old_timestamp,old_text,old_flags,old_user_text FROM old WHERE " .
                          "old_id={$this->mOldid}";
                        $res = wfQuery( $sql, DB_READ, $fname );
                }
                if ( 0 == wfNumRows( $res ) ) { return false; }
 
                $s = wfFetchObject( $res );
-               $this->mOldtext = $s->old_text;
+               $this->mOldtext = Article::getRevisionText( $s );
 
                $t = $wgLang->timeanddate( $s->old_timestamp, true );
                $this->mOldtitle = wfMsg( "revisionasof", $t );
-
+               $this->mOldUser = $s->old_user_text;
+               
                return true;
        }
 }
@@ -127,7 +154,7 @@ define('USE_ASSERTS', function_exists('assert'));
 class _DiffOp {
     var $type;
     var $orig;
-    var $final;
+    var $closing;
     
     function reverse() {
         trigger_error("pure virtual", E_USER_ERROR);
@@ -137,23 +164,23 @@ class _DiffOp {
         return $this->orig ? sizeof($this->orig) : 0;
     }
 
-    function nfinal() {
-        return $this->final ? sizeof($this->final) : 0;
+    function nclosing() {
+        return $this->closing ? sizeof($this->closing) : 0;
     }
 }
 
 class _DiffOp_Copy extends _DiffOp {
     var $type = 'copy';
     
-    function _DiffOp_Copy ($orig, $final = false) {
-        if (!is_array($final))
-            $final = $orig;
+    function _DiffOp_Copy ($orig, $closing = false) {
+        if (!is_array($closing))
+            $closing = $orig;
         $this->orig = $orig;
-        $this->final = $final;
+        $this->closing = $closing;
     }
 
     function reverse() {
-        return new _DiffOp_Copy($this->final, $this->orig);
+        return new _DiffOp_Copy($this->closing, $this->orig);
     }
 }
 
@@ -162,7 +189,7 @@ class _DiffOp_Delete extends _DiffOp {
     
     function _DiffOp_Delete ($lines) {
         $this->orig = $lines;
-        $this->final = false;
+        $this->closing = false;
     }
 
     function reverse() {
@@ -174,25 +201,25 @@ class _DiffOp_Add extends _DiffOp {
     var $type = 'add';
     
     function _DiffOp_Add ($lines) {
-        $this->final = $lines;
+        $this->closing = $lines;
         $this->orig = false;
     }
 
     function reverse() {
-        return new _DiffOp_Delete($this->final);
+        return new _DiffOp_Delete($this->closing);
     }
 }
 
 class _DiffOp_Change extends _DiffOp {
     var $type = 'change';
     
-    function _DiffOp_Change ($orig, $final) {
+    function _DiffOp_Change ($orig, $closing) {
         $this->orig = $orig;
-        $this->final = $final;
+        $this->closing = $closing;
     }
 
     function reverse() {
-        return new _DiffOp_Change($this->final, $this->orig);
+        return new _DiffOp_Change($this->closing, $this->orig);
     }
 }
         
@@ -211,7 +238,7 @@ class _DiffOp_Change extends _DiffOp {
  * diffutils-2.7, which can be found at:
  *   ftp://gnudist.gnu.org/pub/gnu/diffutils/diffutils-2.7.tar.gz
  *
- * Finally, some ideas (subdivision by NCHUNKS > 2, and some optimizations)
+ * closingly, some ideas (subdivision by NCHUNKS > 2, and some optimizations)
  * are my own.
  *
  * @author Geoffrey T. Dairiki
@@ -686,19 +713,19 @@ class Diff
     }
 
     /**
-     * Get the final set of lines.
+     * Get the closing set of lines.
      *
      * This reconstructs the $to_lines parameter passed to the
      * constructor.
      *
      * @return array The sequence of strings.
      */
-    function final() {
+    function closing() {
         $lines = array();
         
         foreach ($this->edits as $edit) {
-            if ($edit->final)
-                array_splice($lines, sizeof($lines), 0, $edit->final);
+            if ($edit->closing)
+                array_splice($lines, sizeof($lines), 0, $edit->closing);
         }
         return $lines;
     }
@@ -711,14 +738,14 @@ class Diff
     function _check ($from_lines, $to_lines) {
         if (serialize($from_lines) != serialize($this->orig()))
             trigger_error("Reconstructed original doesn't match", E_USER_ERROR);
-        if (serialize($to_lines) != serialize($this->final()))
-            trigger_error("Reconstructed final doesn't match", E_USER_ERROR);
+        if (serialize($to_lines) != serialize($this->closing()))
+            trigger_error("Reconstructed closing doesn't match", E_USER_ERROR);
 
         $rev = $this->reverse();
         if (serialize($to_lines) != serialize($rev->orig()))
             trigger_error("Reversed original doesn't match", E_USER_ERROR);
-        if (serialize($from_lines) != serialize($rev->final()))
-            trigger_error("Reversed final doesn't match", E_USER_ERROR);
+        if (serialize($from_lines) != serialize($rev->closing()))
+            trigger_error("Reversed closing doesn't match", E_USER_ERROR);
 
 
         $prevtype = 'none';
@@ -778,10 +805,10 @@ extends Diff
                 $xi += sizeof($orig);
             }
             
-            $final = &$this->edits[$i]->final;
-            if (is_array($final)) {
-                $final = array_slice($to_lines, $yi, sizeof($final));
-                $yi += sizeof($final);
+            $closing = &$this->edits[$i]->closing;
+            if (is_array($closing)) {
+                $closing = array_slice($to_lines, $yi, sizeof($closing));
+                $yi += sizeof($closing);
             }
         }
     }
@@ -862,8 +889,8 @@ class DiffFormatter
 
             if ($edit->orig)
                 $xi += sizeof($edit->orig);
-            if ($edit->final)
-                $yi += sizeof($edit->final);
+            if ($edit->closing)
+                $yi += sizeof($edit->closing);
         }
 
         if (is_array($block))
@@ -880,11 +907,11 @@ class DiffFormatter
             if ($edit->type == 'copy')
                 $this->_context($edit->orig);
             elseif ($edit->type == 'add')
-                $this->_added($edit->final);
+                $this->_added($edit->closing);
             elseif ($edit->type == 'delete')
                 $this->_deleted($edit->orig);
             elseif ($edit->type == 'change')
-                $this->_changed($edit->orig, $edit->final);
+                $this->_changed($edit->orig, $edit->closing);
             else
                 trigger_error("Unknown edit type", E_USER_ERROR);
         }
@@ -933,10 +960,10 @@ class DiffFormatter
         $this->_lines($lines, "<");
     }
 
-    function _changed($orig, $final) {
+    function _changed($orig, $closing) {
         $this->_deleted($orig);
         echo "---\n";
-        $this->_added($final);
+        $this->_added($closing);
     }
 }
 
@@ -1000,13 +1027,13 @@ class _HWLDF_WordAccumulator {
 
 class WordLevelDiff extends MappedDiff
 {
-    function WordLevelDiff ($orig_lines, $final_lines) {
+    function WordLevelDiff ($orig_lines, $closing_lines) {
         list ($orig_words, $orig_stripped) = $this->_split($orig_lines);
-        list ($final_words, $final_stripped) = $this->_split($final_lines);
+        list ($closing_words, $closing_stripped) = $this->_split($closing_lines);
 
         
-        $this->MappedDiff($orig_words, $final_words,
-                          $orig_stripped, $final_stripped);
+        $this->MappedDiff($orig_words, $closing_words,
+                          $orig_stripped, $closing_stripped);
     }
 
     function _split($lines) {
@@ -1032,16 +1059,16 @@ class WordLevelDiff extends MappedDiff
         return $orig->getLines();
     }
 
-    function final () {
-        $final = new _HWLDF_WordAccumulator;
+    function closing () {
+        $closing = new _HWLDF_WordAccumulator;
         
         foreach ($this->edits as $edit) {
             if ($edit->type == 'copy')
-                $final->addWords($edit->final);
-            elseif ($edit->final)
-                $final->addWords($edit->final, 'mark');
+                $closing->addWords($edit->closing);
+            elseif ($edit->closing)
+                $closing->addWords($edit->closing, 'mark');
         }
-        return $final->getLines();
+        return $closing->getLines();
     }
 }
 
@@ -1118,11 +1145,11 @@ class TableDiffFormatter extends DiffFormatter
                }
        }
 
-       function _changed( $orig, $final ) {
+       function _changed( $orig, $closing ) {
                global $wgOut;
-        $diff = new WordLevelDiff( $orig, $final );
+        $diff = new WordLevelDiff( $orig, $closing );
                $del = $diff->orig();
-               $add = $diff->final();
+               $add = $diff->closing();
 
                while ( $line = array_shift( $del ) ) {
                        $aline = array_shift( $add );