From 086ae52d12011746a75f5588e877347bc0457352 Mon Sep 17 00:00:00 2001 From: Pierre Schmitz Date: Fri, 21 Mar 2008 11:49:34 +0100 Subject: Update auf MediaWiki 1.12.0 --- includes/DifferenceEngine.php | 256 ++++++++++++++++++++++++++++++++---------- 1 file changed, 199 insertions(+), 57 deletions(-) (limited to 'includes/DifferenceEngine.php') diff --git a/includes/DifferenceEngine.php b/includes/DifferenceEngine.php index 99bb4798..9aa17bbb 100644 --- a/includes/DifferenceEngine.php +++ b/includes/DifferenceEngine.php @@ -38,8 +38,9 @@ class DifferenceEngine { * @param $old Integer: old ID we want to show and diff with. * @param $new String: either 'prev' or 'next'. * @param $rcid Integer: ??? FIXME (default 0) + * @param $refreshCache boolean If set, refreshes the diff cache */ - function DifferenceEngine( $titleObj = null, $old = 0, $new = 0, $rcid = 0 ) { + function DifferenceEngine( $titleObj = null, $old = 0, $new = 0, $rcid = 0, $refreshCache = false ) { $this->mTitle = $titleObj; wfDebug("DifferenceEngine old '$old' new '$new' rcid '$rcid'\n"); @@ -68,6 +69,7 @@ class DifferenceEngine { $this->mNewid = intval($new); } $this->mRcidMarkPatrolled = intval($rcid); # force it to be an integer + $this->mRefreshCache = $refreshCache; } function showDiffPage( $diffOnly = false ) { @@ -107,9 +109,8 @@ CONTROL; $wgOut->setArticleFlag( false ); if ( ! $this->loadRevisionData() ) { $t = $this->mTitle->getPrefixedText() . " (Diff: {$this->mOldid}, {$this->mNewid})"; - $mtext = wfMsg( 'missingarticle', "$t" ); $wgOut->setPagetitle( wfMsg( 'errorpagetitle' ) ); - $wgOut->addWikitext( $mtext ); + $wgOut->addWikiMsg( 'missingarticle', "$t" ); wfProfileOut( $fname ); return; } @@ -164,14 +165,15 @@ CONTROL; $rcid = $this->mRcidMarkPatrolled; } else { // Look for an unpatrolled change corresponding to this diff + $db = wfGetDB( DB_SLAVE ); $change = RecentChange::newFromConds( array( - // Add redundant timestamp condition so we can use the - // existing index - 'rc_timestamp' => $this->mNewRev->getTimestamp(), + // Add redundant user,timestamp condition so we can use the existing index + 'rc_user_text' => $this->mNewRev->getRawUserText(), + 'rc_timestamp' => $db->timestamp( $this->mNewRev->getTimestamp() ), 'rc_this_oldid' => $this->mNewid, 'rc_last_oldid' => $this->mOldid, - 'rc_patrolled' => 0, + 'rc_patrolled' => 0 ), __METHOD__ ); @@ -217,14 +219,49 @@ CONTROL; $newminor = wfElement( 'span', array( 'class' => 'minor' ), wfMsg( 'minoreditletter') ) . ' '; } + + $rdel = ''; $ldel = ''; + if( $wgUser->isAllowed( 'deleterevision' ) ) { + $revdel = SpecialPage::getTitleFor( 'Revisiondelete' ); + if( !$this->mOldRev->userCan( Revision::DELETED_RESTRICTED ) ) { + // If revision was hidden from sysops + $ldel = wfMsgHtml('rev-delundel'); + } else { + $ldel = $sk->makeKnownLinkObj( $revdel, + wfMsgHtml('rev-delundel'), + 'target=' . urlencode( $this->mOldRev->mTitle->getPrefixedDbkey() ) . + '&oldid=' . urlencode( $this->mOldRev->getId() ) ); + // Bolden oversighted content + if( $this->mOldRev->isDeleted( Revision::DELETED_RESTRICTED ) ) + $ldel = "$ldel"; + } + $ldel = "   ($ldel) "; + // We don't currently handle well changing the top revision's settings + if( $this->mNewRev->isCurrent() ) { + // If revision was hidden from sysops + $rdel = wfMsgHtml('rev-delundel'); + } else if( !$this->mNewRev->userCan( Revision::DELETED_RESTRICTED ) ) { + // If revision was hidden from sysops + $rdel = wfMsgHtml('rev-delundel'); + } else { + $rdel = $sk->makeKnownLinkObj( $revdel, + wfMsgHtml('rev-delundel'), + 'target=' . urlencode( $this->mNewRev->mTitle->getPrefixedDbkey() ) . + '&oldid=' . urlencode( $this->mNewRev->getId() ) ); + // Bolden oversighted content + if( $this->mNewRev->isDeleted( Revision::DELETED_RESTRICTED ) ) + $rdel = "$rdel"; + } + $rdel = "   ($rdel) "; + } - $oldHeader = '
' . $this->mOldtitle . '
' . - '
' . $sk->revUserTools( $this->mOldRev ) . "
" . - '
' . $oldminor . $sk->revComment( $this->mOldRev, !$diffOnly ) . "
" . - '
' . $prevlink . '
'; - $newHeader = '
' .$this->mNewtitle . '
' . - '
' . $sk->revUserTools( $this->mNewRev ) . " $rollback
" . - '
' . $newminor . $sk->revComment( $this->mNewRev, !$diffOnly ) . "
" . + $oldHeader = '
'.$this->mOldtitle.'
' . + '
' . $sk->revUserTools( $this->mOldRev, true ) . "
" . + '
' . $oldminor . $sk->revComment( $this->mOldRev, !$diffOnly, true ) . $ldel . "
" . + '
' . $prevlink .'
'; + $newHeader = '
'.$this->mNewtitle.'
' . + '
' . $sk->revUserTools( $this->mNewRev, true ) . " $rollback
" . + '
' . $newminor . $sk->revComment( $this->mNewRev, !$diffOnly, true ) . $rdel . "
" . '
' . $nextlink . $patrol . '
'; $this->showDiff( $oldHeader, $newHeader ); @@ -245,8 +282,10 @@ CONTROL; $wgOut->addHTML( "

{$this->mPagetitle}

\n" ); #add deleted rev tag if needed - if ( !$this->mNewRev->userCan(Revision::DELETED_TEXT) ) { - $wgOut->addWikiText( wfMsg( 'rev-deleted-text-permission' ) ); + if( !$this->mNewRev->userCan(Revision::DELETED_TEXT) ) { + $wgOut->addWikiMsg( 'rev-deleted-text-permission' ); + } else if( $this->mNewRev->isDeleted(Revision::DELETED_TEXT) ) { + $wgOut->addWikiMsg( 'rev-deleted-text-view' ); } if( !$this->mNewRev->isCurrent() ) { @@ -258,7 +297,20 @@ CONTROL; $wgOut->setRevisionId( $this->mNewRev->getId() ); } - $wgOut->addWikiTextTidy( $this->mNewtext ); + if ($this->mTitle->isCssJsSubpage() || $this->mTitle->isCssOrJsPage()) { + // Stolen from Article::view --AG 2007-10-11 + + // Give hooks a chance to customise the output + if( wfRunHooks( 'ShowRawCssJs', array( $this->mNewtext, $this->mTitle, $wgOut ) ) ) { + // Wrap the whole lot in a
 and don't parse
+				$m = array();
+				preg_match( '!\.(css|js)$!u', $this->mTitle->getText(), $m );
+				$wgOut->addHtml( "
\n" );
+				$wgOut->addHtml( htmlspecialchars( $this->mNewtext ) );
+				$wgOut->addHtml( "\n
\n" ); + } + } else + $wgOut->addWikiTextTidy( $this->mNewtext ); if( !$this->mNewRev->isCurrent() ) { $wgOut->parserOptions()->setEditSection( $oldEditSectionSetting ); @@ -282,9 +334,8 @@ CONTROL; if ( ! $this->loadNewText() ) { $t = $this->mTitle->getPrefixedText() . " (Diff: {$this->mOldid}, " . "{$this->mNewid})"; - $mtext = wfMsg( 'missingarticle', "$t" ); $wgOut->setPagetitle( wfMsg( 'errorpagetitle' ) ); - $wgOut->addWikitext( $mtext ); + $wgOut->addWikiMsg( 'missingarticle', "$t" ); wfProfileOut( $fname ); return; } @@ -324,10 +375,10 @@ CONTROL; * Returns false if the diff could not be generated, otherwise returns true */ function showDiff( $otitle, $ntitle ) { - global $wgOut, $wgRequest; - $diff = $this->getDiff( $otitle, $ntitle, $wgRequest->getVal( 'action' ) == 'purge' ); + global $wgOut; + $diff = $this->getDiff( $otitle, $ntitle ); if ( $diff === false ) { - $wgOut->addWikitext( wfMsg( 'missingarticle', "(fixme, bug)" ) ); + $wgOut->addWikiMsg( 'missingarticle', "(fixme, bug)" ); return false; } else { $this->showDiffStyle(); @@ -352,11 +403,10 @@ CONTROL; * * @param Title $otitle Old title * @param Title $ntitle New title - * @param bool $skipCache Skip the diff cache for this request? * @return mixed */ - function getDiff( $otitle, $ntitle, $skipCache = false ) { - $body = $this->getDiffBody( $skipCache ); + function getDiff( $otitle, $ntitle ) { + $body = $this->getDiffBody(); if ( $body === false ) { return false; } else { @@ -368,43 +418,49 @@ CONTROL; /** * Get the diff table body, without header * - * @param bool $skipCache Skip cache for this request? * @return mixed */ - function getDiffBody( $skipCache = false ) { + function getDiffBody() { global $wgMemc; $fname = 'DifferenceEngine::getDiffBody'; wfProfileIn( $fname ); // Cacheable? $key = false; - if ( $this->mOldid && $this->mNewid && !$skipCache ) { - // Try cache + if ( $this->mOldid && $this->mNewid ) { $key = wfMemcKey( 'diff', 'version', MW_DIFF_VERSION, 'oldid', $this->mOldid, 'newid', $this->mNewid ); - $difftext = $wgMemc->get( $key ); - if ( $difftext ) { - wfIncrStats( 'diff_cache_hit' ); - $difftext = $this->localiseLineNumbers( $difftext ); - $difftext .= "\n\n"; - wfProfileOut( $fname ); - return $difftext; - } + // Try cache + if ( !$this->mRefreshCache ) { + $difftext = $wgMemc->get( $key ); + if ( $difftext ) { + wfIncrStats( 'diff_cache_hit' ); + $difftext = $this->localiseLineNumbers( $difftext ); + $difftext .= "\n\n"; + wfProfileOut( $fname ); + return $difftext; + } + } // don't try to load but save the result } - #loadtext is permission safe, this just clears out the diff + // Loadtext is permission safe, this just clears out the diff if ( !$this->loadText() ) { wfProfileOut( $fname ); return false; } else if ( $this->mOldRev && !$this->mOldRev->userCan(Revision::DELETED_TEXT) ) { - return ''; + return ''; } else if ( $this->mNewRev && !$this->mNewRev->userCan(Revision::DELETED_TEXT) ) { - return ''; + return ''; } $difftext = $this->generateDiffBody( $this->mOldtext, $this->mNewtext ); // Save to cache for 7 days - if ( $key !== false && $difftext !== false ) { + // Only do this for public revs, otherwise an admin can view the diff and a non-admin can nab it! + if ( $this->mOldRev && $this->mOldRev->isDeleted(Revision::DELETED_TEXT) ) { + wfIncrStats( 'diff_uncacheable' ); + } else if ( $this->mNewRev && $this->mNewRev->isDeleted(Revision::DELETED_TEXT) ) { + wfIncrStats( 'diff_uncacheable' ); + } else if ( $key !== false && $difftext !== false ) { wfIncrStats( 'diff_cache_miss' ); $wgMemc->set( $key, $difftext, 7*86400 ); } else { @@ -536,15 +592,9 @@ CONTROL; /** * Add the header to a diff body */ - function addHeader( $diff, $otitle, $ntitle, $multi = '' ) { + static function addHeader( $diff, $otitle, $ntitle, $multi = '' ) { global $wgOut; - - if ( $this->mOldRev && $this->mOldRev->isDeleted(Revision::DELETED_TEXT) ) { - $otitle = ''.$otitle.''; - } - if ( $this->mNewRev && $this->mNewRev->isDeleted(Revision::DELETED_TEXT) ) { - $ntitle = ''.$ntitle.''; - } + $header = " @@ -615,11 +665,16 @@ CONTROL; } else { $newLink = $this->mNewPage->escapeLocalUrl( 'oldid=' . $this->mNewid ); $newEdit = $this->mNewPage->escapeLocalUrl( 'action=edit&oldid=' . $this->mNewid ); - $this->mPagetitle = htmlspecialchars( wfMsg( 'revisionasof', $timestamp ) ); + $this->mPagetitle = wfMsgHTML( 'revisionasof', $timestamp ); $this->mNewtitle = "{$this->mPagetitle}" . " (" . htmlspecialchars( wfMsg( 'editold' ) ) . ")"; } + if ( !$this->mNewRev->userCan(Revision::DELETED_TEXT) ) { + $this->mNewtitle = "{$this->mPagetitle}"; + } else if ( $this->mNewRev->isDeleted(Revision::DELETED_TEXT) ) { + $this->mNewtitle = ''.$this->mNewtitle.''; + } // Load the old revision object $this->mOldRev = false; @@ -647,12 +702,20 @@ CONTROL; $t = $wgLang->timeanddate( $this->mOldRev->getTimestamp(), true ); $oldLink = $this->mOldPage->escapeLocalUrl( 'oldid=' . $this->mOldid ); $oldEdit = $this->mOldPage->escapeLocalUrl( 'action=edit&oldid=' . $this->mOldid ); - $this->mOldtitle = "" . htmlspecialchars( wfMsg( 'revisionasof', $t ) ) - . " (" . htmlspecialchars( wfMsg( 'editold' ) ) . ")"; + $this->mOldPagetitle = htmlspecialchars( wfMsg( 'revisionasof', $t ) ); + $this->mOldtitle = "{$this->mOldPagetitle}" + . " (" . htmlspecialchars( wfMsg( 'editold' ) ) . ")"; // Add an "undo" link $newUndo = $this->mNewPage->escapeLocalUrl( 'action=edit&undoafter=' . $this->mOldid . '&undo=' . $this->mNewid); - $this->mNewtitle .= " (" . htmlspecialchars( wfMsg( 'editundo' ) ) . ")"; + if ( $this->mNewRev->userCan(Revision::DELETED_TEXT) ) + $this->mNewtitle .= " (" . htmlspecialchars( wfMsg( 'editundo' ) ) . ")"; + + if ( !$this->mOldRev->userCan(Revision::DELETED_TEXT) ) { + $this->mOldtitle = "{$this->mOldPagetitle}"; + } else if ( $this->mOldRev->isDeleted(Revision::DELETED_TEXT) ) { + $this->mOldtitle = ''.$this->mOldtitle.''; + } } return true; @@ -673,7 +736,6 @@ CONTROL; return false; } if ( $this->mOldRev ) { - // FIXME: permission tests $this->mOldtext = $this->mOldRev->revText(); if ( $this->mOldtext === false ) { return false; @@ -1584,7 +1646,7 @@ class DiffFormatter } function _start_block($header) { - echo $header; + echo $header . "\n"; } function _end_block() { @@ -1613,6 +1675,84 @@ class DiffFormatter } } +/** + * A formatter that outputs unified diffs + * @addtogroup DifferenceEngine + */ + +class UnifiedDiffFormatter extends DiffFormatter +{ + var $leading_context_lines = 2; + var $trailing_context_lines = 2; + + function _added($lines) { + $this->_lines($lines, '+'); + } + function _deleted($lines) { + $this->_lines($lines, '-'); + } + function _changed($orig, $closing) { + $this->_deleted($orig); + $this->_added($closing); + } + function _block_header($xbeg, $xlen, $ybeg, $ylen) { + return "@@ -$xbeg,$xlen +$ybeg,$ylen @@"; + } +} + +/** + * A pseudo-formatter that just passes along the Diff::$edits array + * @addtogroup DifferenceEngine + */ +class ArrayDiffFormatter extends DiffFormatter +{ + function format($diff) + { + $oldline = 1; + $newline = 1; + $retval = array(); + foreach($diff->edits as $edit) + switch($edit->type) + { + case 'add': + foreach($edit->closing as $l) + { + $retval[] = array( + 'action' => 'add', + 'new'=> $l, + 'newline' => $newline++ + ); + } + break; + case 'delete': + foreach($edit->orig as $l) + { + $retval[] = array( + 'action' => 'delete', + 'old' => $l, + 'oldline' => $oldline++, + ); + } + break; + case 'change': + foreach($edit->orig as $i => $l) + { + $retval[] = array( + 'action' => 'change', + 'old' => $l, + 'new' => @$edit->closing[$i], + 'oldline' => $oldline++, + 'newline' => $newline++, + ); + } + break; + case 'copy': + $oldline += count($edit->orig); + $newline += count($edit->orig); + } + return $retval; + } +} /** * Additions by Axel Boldt follow, partly taken from diff.php, phpwiki-1.3.3 @@ -1828,13 +1968,15 @@ class TableDiffFormatter extends DiffFormatter function _added( $lines ) { foreach ($lines as $line) { echo '' . $this->emptyLine() . - $this->addedLine( htmlspecialchars ( $line ) ) . "\n"; + $this->addedLine( '' . + htmlspecialchars ( $line ) . '' ) . "\n"; } } function _deleted($lines) { foreach ($lines as $line) { - echo '' . $this->deletedLine( htmlspecialchars ( $line ) ) . + echo '' . $this->deletedLine( '' . + htmlspecialchars ( $line ) . '' ) . $this->emptyLine() . "\n"; } } -- cgit v1.2.3-54-g00ecf