From 72e90545454c0e014318fa3c81658e035aac58c1 Mon Sep 17 00:00:00 2001 From: Pierre Schmitz Date: Wed, 10 Jun 2009 13:00:47 +0200 Subject: applying patch to version 1.15.0 --- includes/diff/DifferenceEngine.php | 211 +++++++++++++++++++++++-------------- 1 file changed, 132 insertions(+), 79 deletions(-) (limited to 'includes/diff/DifferenceEngine.php') diff --git a/includes/diff/DifferenceEngine.php b/includes/diff/DifferenceEngine.php index b30ff190..aa48f9f3 100644 --- a/includes/diff/DifferenceEngine.php +++ b/includes/diff/DifferenceEngine.php @@ -27,7 +27,10 @@ class DifferenceEngine { var $mOldRev, $mNewRev; var $mRevisionsLoaded = false; // Have the revisions been loaded var $mTextLoaded = 0; // How many text blobs have been loaded, 0, 1 or 2? + var $mCacheHit = false; // Was the diff fetched from cache? var $htmldiff; + + protected $unhide = false; /**#@-*/ /** @@ -38,23 +41,20 @@ class DifferenceEngine { * @param $rcid Integer: ??? FIXME (default 0) * @param $refreshCache boolean If set, refreshes the diff cache * @param $htmldiff boolean If set, output using HTMLDiff instead of raw wikicode diff + * @param $unhide boolean If set, allow viewing deleted revs */ - function __construct( $titleObj = null, $old = 0, $new = 0, $rcid = 0, $refreshCache = false , $htmldiff = false) { + function __construct( $titleObj = null, $old = 0, $new = 0, $rcid = 0, $refreshCache = false , $htmldiff = false, $unhide = false ) { $this->mTitle = $titleObj; wfDebug("DifferenceEngine old '$old' new '$new' rcid '$rcid'\n"); if ( 'prev' === $new ) { # Show diff between revision $old and the previous one. # Get previous one from DB. - # $this->mNewid = intval($old); - $this->mOldid = $this->mTitle->getPreviousRevisionID( $this->mNewid ); - } elseif ( 'next' === $new ) { - # Show diff between revision $old and the previous one. - # Get previous one from DB. - # + # Show diff between revision $old and the next one. + # Get next one from DB. $this->mOldid = intval($old); $this->mNewid = $this->mTitle->getNextRevisionID( $this->mOldid ); if ( false === $this->mNewid ) { @@ -62,19 +62,32 @@ class DifferenceEngine { # revision is cur, which is "0". $this->mNewid = 0; } - } else { $this->mOldid = intval($old); $this->mNewid = intval($new); + wfRunHooks( 'NewDifferenceEngine', array(&$titleObj, &$this->mOldid, &$this->mNewid, $old, $new) ); } $this->mRcidMarkPatrolled = intval($rcid); # force it to be an integer $this->mRefreshCache = $refreshCache; $this->htmldiff = $htmldiff; + $this->unhide = $unhide; } function getTitle() { return $this->mTitle; } + + function wasCacheHit() { + return $this->mCacheHit; + } + + function getOldid() { + return $this->mOldid; + } + + function getNewid() { + return $this->mNewid; + } function showDiffPage( $diffOnly = false ) { global $wgUser, $wgOut, $wgUseExternalEditor, $wgUseRCPatrol, $wgEnableHtmlDiff; @@ -111,7 +124,7 @@ CONTROL; } $wgOut->setArticleFlag( false ); - if ( ! $this->loadRevisionData() ) { + if ( !$this->loadRevisionData() ) { $t = $this->mTitle->getPrefixedText(); $d = wfMsgExt( 'missingarticle-diff', array( 'escape' ), $this->mOldid, $this->mNewid ); $wgOut->setPagetitle( wfMsg( 'errorpagetitle' ) ); @@ -171,22 +184,26 @@ CONTROL; // If we've been given an explicit change identifier, use it; saves time if( $this->mRcidMarkPatrolled ) { $rcid = $this->mRcidMarkPatrolled; + $rc = RecentChange::newFromId( $rcid ); + // Already patrolled? + $rcid = is_object($rc) && !$rc->getAttribute('rc_patrolled') ? $rcid : 0; } else { // Look for an unpatrolled change corresponding to this diff $db = wfGetDB( DB_SLAVE ); $change = RecentChange::newFromConds( - array( - // Add redundant user,timestamp condition so we can use the existing index - 'rc_user_text' => $this->mNewRev->getUserText( Revision::FOR_THIS_USER ), - 'rc_timestamp' => $db->timestamp( $this->mNewRev->getTimestamp() ), - 'rc_this_oldid' => $this->mNewid, - 'rc_last_oldid' => $this->mOldid, - 'rc_patrolled' => 0 - ), - __METHOD__ + array( + // 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 + ), + __METHOD__ ); if( $change instanceof RecentChange ) { $rcid = $change->mAttribs['rc_id']; + $this->mRcidMarkPatrolled = $rcid; } else { // None found $rcid = 0; @@ -194,11 +211,8 @@ CONTROL; } // Build the link if( $rcid ) { - $patrol = ' [' . $sk->makeKnownLinkObj( - $this->mTitle, - wfMsgHtml( 'markaspatrolleddiff' ), - "action=markpatrolled&rcid={$rcid}" - ) . ']'; + $patrol = ' [' . $sk->makeKnownLinkObj( $this->mTitle, + wfMsgHtml( 'markaspatrolleddiff' ), "action=markpatrolled&rcid={$rcid}" ) . ']'; } else { $patrol = ''; } @@ -206,81 +220,100 @@ CONTROL; $patrol = ''; } + $diffOnlyArg = ''; + # Carry over 'diffonly' param via navigation links + if( $diffOnly != $wgUser->getBoolOption('diffonly') ) { + $diffOnlyArg = '&diffonly='.$diffOnly; + } $htmldiffarg = $this->htmlDiffArgument(); + # Make "previous revision link" $prevlink = $sk->makeKnownLinkObj( $this->mTitle, wfMsgHtml( 'previousdiff' ), - 'diff=prev&oldid='.$this->mOldid.$htmldiffarg, '', '', 'id="differences-prevlink"' ); - if ( $this->mNewRev->isCurrent() ) { + "diff=prev&oldid={$this->mOldid}{$htmldiffarg}{$diffOnlyArg}", '', '', 'id="differences-prevlink"' ); + # Make "next revision link" + if( $this->mNewRev->isCurrent() ) { $nextlink = ' '; } else { $nextlink = $sk->makeKnownLinkObj( $this->mTitle, wfMsgHtml( 'nextdiff' ), - 'diff=next&oldid='.$this->mNewid.$htmldiffarg, '', '', 'id="differences-nextlink"' ); + "diff=next&oldid={$this->mNewid}{$htmldiffarg}{$diffOnlyArg}", '', '', 'id="differences-nextlink"' ); } $oldminor = ''; $newminor = ''; - if ($this->mOldRev->mMinorEdit == 1) { + if( $this->mOldRev->isMinor() ) { $oldminor = Xml::span( wfMsg( 'minoreditletter' ), 'minor' ) . ' '; } - - if ($this->mNewRev->mMinorEdit == 1) { + if( $this->mNewRev->isMinor() ) { $newminor = Xml::span( wfMsg( 'minoreditletter' ), 'minor' ) . ' '; } $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' ); + $ldel = Xml::tags( 'span', array( 'class'=>'mw-revdelundel-link' ), '('.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"; + $query = array( 'target' => $this->mOldRev->mTitle->getPrefixedDbkey(), + 'oldid' => $this->mOldRev->getId() + ); + $ldel = $sk->revDeleteLink( $query, $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' ); + $rdel = Xml::tags( 'span', array( 'class'=>'mw-revdelundel-link' ), '('.wfMsgHtml( 'rev-delundel' ).')' ); } else if( !$this->mNewRev->userCan( Revision::DELETED_RESTRICTED ) ) { // If revision was hidden from sysops - $rdel = wfMsgHtml( 'rev-delundel' ); + $rdel = Xml::tags( 'span', array( 'class'=>'mw-revdelundel-link' ), '('.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"; + $query = array( 'target' => $this->mNewRev->mTitle->getPrefixedDbkey(), + 'oldid' => $this->mNewRev->getId() + ); + $rdel = $sk->revDeleteLink( $query, $this->mNewRev->isDeleted( Revision::DELETED_RESTRICTED ) ); } - $rdel = "   ($rdel) "; + $rdel = "   $rdel "; } $oldHeader = '
'.$this->mOldtitle.'
' . - '
' . $sk->revUserTools( $this->mOldRev, true ) . "
" . - '
' . $oldminor . $sk->revComment( $this->mOldRev, !$diffOnly, true ) . $ldel . "
" . + '
' . $sk->revUserTools( $this->mOldRev, !$this->unhide ) . "
" . + '
' . $oldminor . $sk->revComment( $this->mOldRev, !$diffOnly, !$this->unhide ).$ldel."
" . '
' . $prevlink .'
'; $newHeader = '
'.$this->mNewtitle.'
' . - '
' . $sk->revUserTools( $this->mNewRev, true ) . " $rollback
" . - '
' . $newminor . $sk->revComment( $this->mNewRev, !$diffOnly, true ) . $rdel . "
" . + '
' . $sk->revUserTools( $this->mNewRev, !$this->unhide ) . " $rollback
" . + '
' . $newminor . $sk->revComment( $this->mNewRev, !$diffOnly, !$this->unhide ).$rdel."
" . '
' . $nextlink . $patrol . '
'; - if( $wgEnableHtmlDiff && $this->htmldiff) { + # Check if this user can see the revisions + $allowed = $this->mOldRev->userCan(Revision::DELETED_TEXT) + && $this->mNewRev->userCan(Revision::DELETED_TEXT); + $deleted = $this->mOldRev->isDeleted(Revision::DELETED_TEXT) + || $this->mNewRev->isDeleted(Revision::DELETED_TEXT); + # Output the diff if allowed... + if( $deleted && (!$this->unhide || !$allowed) ) { + $this->showDiffStyle(); + $multi = $this->getMultiNotice(); + $wgOut->addHTML( $this->addHeader( '', $oldHeader, $newHeader, $multi ) ); + if( !$allowed ) { + # Give explanation for why revision is not visible + $wgOut->wrapWikiMsg( "\n", + array( 'rev-deleted-no-diff' ) ); + } else { + # Give explanation and add a link to view the diff... + $link = $this->mTitle->getFullUrl( "diff={$this->mNewid}&oldid={$this->mOldid}". + '&unhide=1&token='.urlencode( $wgUser->editToken($this->mNewid) ) ); + $wgOut->wrapWikiMsg( "\n", + array( 'rev-deleted-unhide-diff', $link ) ); + } + } else if( $wgEnableHtmlDiff && $this->htmldiff ) { $multi = $this->getMultiNotice(); $wgOut->addHTML('
'.$sk->makeKnownLinkObj( $this->mTitle, wfMsgHtml( 'wikicodecomparison' ), - 'diff='.$this->mNewid.'&oldid='.$this->mOldid.'&htmldiff=0', '', '', 'id="differences-switchtype"' ).'
'); + 'diff='.$this->mNewid.'&oldid='.$this->mOldid.'&htmldiff=0', '', '', 'id="differences-switchtype"' ).''); $wgOut->addHTML( $this->addHeader( '', $oldHeader, $newHeader, $multi ) ); $this->renderHtmlDiff(); } else { - if($wgEnableHtmlDiff){ + if( $wgEnableHtmlDiff ) { $wgOut->addHTML('
'.$sk->makeKnownLinkObj( $this->mTitle, wfMsgHtml( 'visualcomparison' ), - 'diff='.$this->mNewid.'&oldid='.$this->mOldid.'&htmldiff=1', '', '', 'id="differences-switchtype"' ).'
'); + 'diff='.$this->mNewid.'&oldid='.$this->mOldid.'&htmldiff=1', '', '', 'id="differences-switchtype"' ).''); } $this->showDiff( $oldHeader, $newHeader ); if( !$diffOnly ) { @@ -294,15 +327,15 @@ CONTROL; * Show the new revision of the page. */ function renderNewRevision() { - global $wgOut; + global $wgOut, $wgUser; wfProfileIn( __METHOD__ ); $wgOut->addHTML( "

{$this->mPagetitle}

\n" ); - #add deleted rev tag if needed + # Add deleted rev tag if needed if( !$this->mNewRev->userCan(Revision::DELETED_TEXT) ) { - $wgOut->addWikiMsg( 'rev-deleted-text-permission' ); + $wgOut->wrapWikiMsg( "\n", 'rev-deleted-text-permission' ); } else if( $this->mNewRev->isDeleted(Revision::DELETED_TEXT) ) { - $wgOut->addWikiMsg( 'rev-deleted-text-view' ); + $wgOut->wrapWikiMsg( "\n", 'rev-deleted-text-view' ); } if( !$this->mNewRev->isCurrent() ) { @@ -314,9 +347,8 @@ CONTROL; $wgOut->setRevisionId( $this->mNewRev->getId() ); } - if ($this->mTitle->isCssJsSubpage() || $this->mTitle->isCssOrJsPage()) { + 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
@@ -326,12 +358,22 @@ CONTROL;
 				$wgOut->addHTML( htmlspecialchars( $this->mNewtext ) );
 				$wgOut->addHTML( "\n
\n" ); } - } else - $wgOut->addWikiTextTidy( $this->mNewtext ); + } else { + $wgOut->addWikiTextTidy( $this->mNewtext ); + } - if( !$this->mNewRev->isCurrent() ) { + if( is_object( $this->mNewRev ) && !$this->mNewRev->isCurrent() ) { $wgOut->parserOptions()->setEditSection( $oldEditSectionSetting ); } + # Add redundant patrol link on bottom... + if( $this->mRcidMarkPatrolled && $this->mTitle->quickUserCan('patrol') ) { + $sk = $wgUser->getSkin(); + $wgOut->addHTML( + "' + ); + } wfProfileOut( __METHOD__ ); } @@ -346,9 +388,9 @@ CONTROL; $wgOut->addHTML( '

'.wfMsgHtml( 'visual-comparison' )."

\n" ); #add deleted rev tag if needed if( !$this->mNewRev->userCan(Revision::DELETED_TEXT) ) { - $wgOut->addWikiMsg( 'rev-deleted-text-permission' ); + $wgOut->wrapWikiMsg( "\n", 'rev-deleted-text-permission' ); } else if( $this->mNewRev->isDeleted(Revision::DELETED_TEXT) ) { - $wgOut->addWikiMsg( 'rev-deleted-text-view' ); + $wgOut->wrapWikiMsg( "\n", 'rev-deleted-text-view' ); } if( !$this->mNewRev->isCurrent() ) { @@ -435,11 +477,15 @@ CONTROL; # $sk = $wgUser->getSkin(); - $nextlink = $sk->makeKnownLinkObj( $this->mTitle, wfMsgHtml( 'nextdiff' ), 'diff=next&oldid='.$this->mNewid.$this->htmlDiffArgument(), '', '', 'id="differences-nextlink"' ); - $header = "
{$this->mOldtitle}
" . - $sk->revUserTools( $this->mNewRev ) . "
" . - $sk->revComment( $this->mNewRev ) . "
" . - $nextlink . "
\n"; + $next = $this->mTitle->getNextRevisionID( $this->mNewid ); + if( !$next ) { + $nextlink = ''; + } else { + $nextlink = '
' . $sk->makeKnownLinkObj( $this->mTitle, wfMsgHtml( 'nextdiff' ), + 'diff=next&oldid=' . $this->mNewid.$this->htmlDiffArgument(), '', '', 'id="differences-nextlink"' ); + } + $header = "
" . + $sk->revUserTools( $this->mNewRev ) . "
" . $sk->revComment( $this->mNewRev ) . $nextlink . "
\n"; $wgOut->addHTML( $header ); @@ -515,11 +561,16 @@ CONTROL; function getDiffBody() { global $wgMemc; wfProfileIn( __METHOD__ ); + $this->mCacheHit = true; // Check if the diff should be hidden from this user + if ( !$this->loadRevisionData() ) + return ''; if ( $this->mOldRev && !$this->mOldRev->userCan(Revision::DELETED_TEXT) ) { return ''; } else if ( $this->mNewRev && !$this->mNewRev->userCan(Revision::DELETED_TEXT) ) { return ''; + } else if ( $this->mOldRev && $this->mNewRev && $this->mOldRev->getID() == $this->mNewRev->getID() ) { + return ''; } // Cacheable? $key = false; @@ -537,6 +588,7 @@ CONTROL; } } // don't try to load but save the result } + $this->mCacheHit = false; // Loadtext is permission safe, this just clears out the diff if ( !$this->loadText() ) { @@ -669,7 +721,7 @@ CONTROL; function localiseLineNumbersCb( $matches ) { global $wgLang; - return wfMsgExt( 'lineno', array( 'parseinline' ), $wgLang->formatNum( $matches[1] ) ); + return wfMsgExt( 'lineno', array (), $wgLang->formatNum( $matches[1] ) ); } @@ -728,6 +780,7 @@ CONTROL; $this->mOldtext = $oldText; $this->mNewtext = $newText; $this->mTextLoaded = 2; + $this->mRevisionsLoaded = true; } /** @@ -751,10 +804,10 @@ CONTROL; // Load the new revision object $this->mNewRev = $this->mNewid - ? Revision::newFromId( $this->mNewid ) - : Revision::newFromTitle( $this->mTitle ); + ? Revision::newFromId( $this->mNewid ) + : Revision::newFromTitle( $this->mTitle ); if( !$this->mNewRev instanceof Revision ) - return false; + return false; // Update the new revision ID in case it was 0 (makes life easier doing UI stuff) $this->mNewid = $this->mNewRev->getId(); @@ -876,7 +929,7 @@ CONTROL; if ( !$this->loadRevisionData() ) { return false; } - $this->mNewtext = $this->mNewRev->getText(); + $this->mNewtext = $this->mNewRev->getText( Revision::FOR_THIS_USER ); return true; } -- cgit v1.2.2