<?php
/**
+ * @defgroup DifferenceEngine DifferenceEngine
+ *
+ * @file
* See diff.doc
* @todo indicate where diff.doc can be found.
- * @addtogroup DifferenceEngine
*/
/**
/**
* @todo document
- * @public
- * @addtogroup DifferenceEngine
+ * @ingroup DifferenceEngine
*/
class DifferenceEngine {
/**#@+
$this->mRefreshCache = $refreshCache;
}
+ function getTitle() {
+ return $this->mTitle;
+ }
+
function showDiffPage( $diffOnly = false ) {
global $wgUser, $wgOut, $wgUseExternalEditor, $wgUseRCPatrol;
wfProfileIn( __METHOD__ );
$wgOut->setArticleFlag( false );
if ( ! $this->loadRevisionData() ) {
- $t = $this->mTitle->getPrefixedText() . " (Diff: {$this->mOldid}, {$this->mNewid})";
+ $t = $this->mTitle->getPrefixedText();
+ $d = wfMsgExt( 'missingarticle-diff', array( 'escape' ), $this->mOldid, $this->mNewid );
$wgOut->setPagetitle( wfMsg( 'errorpagetitle' ) );
- $wgOut->addWikiMsg( 'missingarticle', "<nowiki>$t</nowiki>" );
+ $wgOut->addWikiMsg( 'missing-article', "<nowiki>$t</nowiki>", $d );
wfProfileOut( __METHOD__ );
return;
}
$sk = $wgUser->getSkin();
- if ( $this->mNewRev->isCurrent() && $wgUser->isAllowed('rollback') ) {
+ // Check if page is editable
+ $editable = $this->mNewRev->getTitle()->userCan( 'edit' );
+ if ( $editable && $this->mNewRev->isCurrent() && $wgUser->isAllowed('rollback') ) {
$rollback = ' ' . $sk->generateRollback( $this->mNewRev );
} else {
$rollback = '';
# Get article text from the DB
#
if ( ! $this->loadNewText() ) {
- $t = $this->mTitle->getPrefixedText() . " (Diff: {$this->mOldid}, " .
- "{$this->mNewid})";
+ $t = $this->mTitle->getPrefixedText();
+ $d = wfMsgExt( 'missingarticle-diff', array( 'escape' ), $this->mOldid, $this->mNewid );
$wgOut->setPagetitle( wfMsg( 'errorpagetitle' ) );
- $wgOut->addWikiMsg( 'missingarticle', "<nowiki>$t</nowiki>" );
+ $wgOut->addWikiMsg( 'missing-article', "<nowiki>$t</nowiki>", $d );
wfProfileOut( __METHOD__ );
return;
}
global $wgOut;
$diff = $this->getDiff( $otitle, $ntitle );
if ( $diff === false ) {
- $wgOut->addWikiMsg( 'missingarticle', "<nowiki>(fixme, bug)</nowiki>" );
+ $wgOut->addWikiMsg( 'missing-article', "<nowiki>(fixme, bug)</nowiki>", '' );
return false;
} else {
$this->showDiffStyle();
if( !function_exists( 'wikidiff_do_diff' ) ) {
dl('php_wikidiff.so');
}
- return $wgContLang->unsegementForDiff( wikidiff_do_diff( $otext, $ntext, 2 ) );
+ return $wgContLang->unsegementForDiff( wikidiff_do_diff( $otext, $ntext, 2 ) ) .
+ $this->debug( 'wikidiff1' );
}
if ( $wgExternalDiffEngine == 'wikidiff2' ) {
if ( function_exists( 'wikidiff2_do_diff' ) ) {
wfProfileIn( 'wikidiff2_do_diff' );
$text = wikidiff2_do_diff( $otext, $ntext, 2 );
+ $text .= $this->debug( 'wikidiff2' );
wfProfileOut( 'wikidiff2_do_diff' );
return $text;
}
$cmd = wfEscapeShellArg( $wgExternalDiffEngine, $tempName1, $tempName2 );
wfProfileIn( __METHOD__ . "-shellexec" );
$difftext = wfShellExec( $cmd );
+ $difftext .= $this->debug( "external $wgExternalDiffEngine" );
wfProfileOut( __METHOD__ . "-shellexec" );
unlink( $tempName1 );
unlink( $tempName2 );
$nta = explode( "\n", $wgContLang->segmentForDiff( $ntext ) );
$diffs = new Diff( $ota, $nta );
$formatter = new TableDiffFormatter();
- return $wgContLang->unsegmentForDiff( $formatter->format( $diffs ) );
+ return $wgContLang->unsegmentForDiff( $formatter->format( $diffs ) ) .
+ $this->debug();
+ }
+
+ /**
+ * Generate a debug comment indicating diff generating time,
+ * server node, and generator backend.
+ */
+ protected function debug( $generator="internal" ) {
+ global $wgShowHostnames, $wgNodeName;
+ $data = array( $generator );
+ if( $wgShowHostnames ) {
+ $data[] = $wgNodeName;
+ }
+ $data[] = wfTimestamp( TS_DB );
+ return "<!-- diff generator: " .
+ implode( " ",
+ array_map(
+ "htmlspecialchars",
+ $data ) ) .
+ " -->\n";
}
-
/**
* Replace line numbers with the text in the user's language
<col class='diff-content' />
<col class='diff-marker' />
<col class='diff-content' />
- <tr>
+ <tr valign='top'>
<td colspan='2' class='diff-otitle'>{$otitle}</td>
<td colspan='2' class='diff-ntitle'>{$ntitle}</td>
</tr>
$timestamp = $wgLang->timeanddate( $this->mNewRev->getTimestamp(), true );
$this->mNewPage = $this->mNewRev->getTitle();
if( $this->mNewRev->isCurrent() ) {
- $newLink = $this->mNewPage->escapeLocalUrl();
+ $newLink = $this->mNewPage->escapeLocalUrl( 'oldid=' . $this->mNewid );
$this->mPagetitle = htmlspecialchars( wfMsg( 'currentrev' ) );
$newEdit = $this->mNewPage->escapeLocalUrl( 'action=edit' );
. " (<a href='$oldEdit'>" . wfMsgHtml( $editable ? 'editold' : 'viewsourceold' ) . "</a>)";
// Add an "undo" link
$newUndo = $this->mNewPage->escapeLocalUrl( 'action=edit&undoafter=' . $this->mOldid . '&undo=' . $this->mNewid);
- if ( $editable && $this->mNewRev->userCan(Revision::DELETED_TEXT) )
+ if( $editable && !$this->mOldRev->isDeleted( Revision::DELETED_TEXT ) && !$this->mNewRev->isDeleted( Revision::DELETED_TEXT ) ) {
$this->mNewtitle .= " (<a href='$newUndo'>" . htmlspecialchars( wfMsg( 'editundo' ) ) . "</a>)";
+ }
- if ( !$this->mOldRev->userCan(Revision::DELETED_TEXT) ) {
- $this->mOldtitle = "<span class='history-deleted'>{$this->mOldPagetitle}</span>";
- } else if ( $this->mOldRev->isDeleted(Revision::DELETED_TEXT) ) {
- $this->mOldtitle = '<span class="history-deleted">'.$this->mOldtitle.'</span>';
+ if( !$this->mOldRev->userCan( Revision::DELETED_TEXT ) ) {
+ $this->mOldtitle = '<span class="history-deleted">' . $this->mOldPagetitle . '</span>';
+ } else if( $this->mOldRev->isDeleted( Revision::DELETED_TEXT ) ) {
+ $this->mOldtitle = '<span class="history-deleted">' . $this->mOldtitle . '</span>';
}
}
/**
* @todo document
* @private
- * @addtogroup DifferenceEngine
+ * @ingroup DifferenceEngine
*/
class _DiffOp {
var $type;
/**
* @todo document
* @private
- * @addtogroup DifferenceEngine
+ * @ingroup DifferenceEngine
*/
class _DiffOp_Copy extends _DiffOp {
var $type = 'copy';
/**
* @todo document
* @private
- * @addtogroup DifferenceEngine
+ * @ingroup DifferenceEngine
*/
class _DiffOp_Delete extends _DiffOp {
var $type = 'delete';
/**
* @todo document
* @private
- * @addtogroup DifferenceEngine
+ * @ingroup DifferenceEngine
*/
class _DiffOp_Add extends _DiffOp {
var $type = 'add';
/**
* @todo document
* @private
- * @addtogroup DifferenceEngine
+ * @ingroup DifferenceEngine
*/
class _DiffOp_Change extends _DiffOp {
var $type = 'change';
*
* @author Geoffrey T. Dairiki, Tim Starling
* @private
- * @addtogroup DifferenceEngine
+ * @ingroup DifferenceEngine
*/
class _DiffEngine {
const MAX_XREF_LENGTH = 10000;
* Class representing a 'diff' between two sequences of strings.
* @todo document
* @private
- * @addtogroup DifferenceEngine
+ * @ingroup DifferenceEngine
*/
class Diff
{
/**
* @todo document, bad name.
* @private
- * @addtogroup DifferenceEngine
+ * @ingroup DifferenceEngine
*/
class MappedDiff extends Diff
{
* to obtain fancier outputs.
* @todo document
* @private
- * @addtogroup DifferenceEngine
+ * @ingroup DifferenceEngine
*/
class DiffFormatter {
/**
/**
* A formatter that outputs unified diffs
- * @addtogroup DifferenceEngine
+ * @ingroup DifferenceEngine
*/
class UnifiedDiffFormatter extends DiffFormatter {
/**
* A pseudo-formatter that just passes along the Diff::$edits array
- * @addtogroup DifferenceEngine
+ * @ingroup DifferenceEngine
*/
class ArrayDiffFormatter extends DiffFormatter {
function format($diff) {
/**
* @todo document
* @private
- * @addtogroup DifferenceEngine
+ * @ingroup DifferenceEngine
*/
class _HWLDF_WordAccumulator {
function _HWLDF_WordAccumulator () {
/**
* @todo document
* @private
- * @addtogroup DifferenceEngine
+ * @ingroup DifferenceEngine
*/
class WordLevelDiff extends MappedDiff {
const MAX_LINE_LENGTH = 10000;
* Wikipedia Table style diff formatter.
* @todo document
* @private
- * @addtogroup DifferenceEngine
+ * @ingroup DifferenceEngine
*/
class TableDiffFormatter extends DiffFormatter {
function TableDiffFormatter() {