%PDF- %PDF-
| Direktori : /www/varak.net/wiki.varak.net/extensions/MobileFrontend/includes/diff/ |
| Current File : //www/varak.net/wiki.varak.net/extensions/MobileFrontend/includes/diff/InlineDifferenceEngine.php |
<?php
use Wikimedia\Assert\Assert;
/**
* Extends the basic DifferenceEngine from core to enable inline difference view
* using only one column instead of two column diff system.
*/
class InlineDifferenceEngine extends DifferenceEngine {
/**
* Checks whether the given Revision was deleted
* @todo FIXME: Upstream to DifferenceEngine - refactor showDiffPage
*
* @return bool
*/
public function isDeletedDiff() {
return $this->mNewRev && $this->mNewRev->isDeleted( Revision::DELETED_TEXT ) ||
$this->mOldRev && $this->mOldRev->isDeleted( Revision::DELETED_TEXT );
}
/**
* Checks whether the given Revision was deleted or if it is delete
* restricted.
* FIXME: Upstream to DifferenceEngine - refactor showDiffPage
*
* @return bool
*/
public function isSuppressedDiff() {
return $this->isDeletedDiff() &&
$this->mNewRev->isDeleted( Revision::DELETED_RESTRICTED );
}
/**
* Checks whether the current user has permission to view the old
* and current revisions.
* @todo FIXME: Upstream to DifferenceEngine - refactor showDiffPage
*
* @return bool
*/
public function isUserAllowedToSee() {
$user = $this->getUser();
$allowed = $this->mNewRev->userCan( Revision::DELETED_TEXT, $user );
if ( $this->mOldRev &&
!$this->mOldRev->userCan( Revision::DELETED_TEXT, $user )
) {
$allowed = false;
}
return $allowed;
}
/**
* Render the inline difference between two revisions
* using InlineDiffEngine
* @throws MWException If the content is not an instance of TextContent and
* wgContentHandlerTextFallback was set to 'fail'.
*
* @param bool $diffOnly
*/
public function showDiffPage( $diffOnly = false ) {
$output = $this->getOutput();
$prevId = $this->getOldid();
$unhide = (bool)$this->getRequest()->getVal( 'unhide' );
$diff = $this->getDiffBody();
$rev = Revision::newFromId( $this->getNewid() );
if ( !$prevId ) {
$audience = $unhide ? Revision::FOR_THIS_USER : Revision::FOR_PUBLIC;
$diff = '<ins>'
. nl2br(
htmlspecialchars(
ContentHandler::getContentText( $rev->getContent( $audience ) )
)
)
. '</ins>';
}
$warnings = $this->getWarningMessageText();
if ( $warnings ) {
$warnings = Html::warningBox( $warnings );
}
if ( $this->isHiddenFromUser() ) {
// When an administrative user deletes a page, the diff is available to
// them and other admins but no indication would be given that it's hidden
// from unprivileged users. It's considered best to present the anon view
// in this case, which is an empty diff.
$diff = '';
}
$output->addHTML(
$warnings .
'<div id="mw-mf-minidiff">' .
$diff .
'</div>'
);
$output->addHTML( Html::rawElement(
'div',
[
'class' => 'patrollink'
],
$this->getPatrolledLink()
) );
}
/**
* Checks whether the diff should be hidden from the current user
* This is based on whether the user is allowed to see it and whether
* the flag unhide is set to allow viewing deleted revisions.
* @todo FIXME: Upstream to DifferenceEngine - refactor showDiffPage
*
* @return bool
*/
public function isHiddenFromUser() {
return $this->isDeletedDiff() && ( !$this->unhide || !$this->isUserAllowedToSee() );
}
/**
* Returns warning messages in situations where a revision cannot be viewed by a user
* explaining to them why.
* Returns empty string when the revision can be viewed.
*
* @return string
*/
public function getWarningMessageText() {
$msg = '';
if ( $this->isHiddenFromUser() ) {
$allowed = $this->isUserAllowedToSee();
$suppressed = $this->isSuppressedDiff();
// This IContextSource object will be used to get a message object for the
// messages used in this function. We need to to this to allow the message to
// get the correct value for the FULLPAGENAME inclusion (which is used in
// rev-suppressed-no-diff, e.g.). Otherwise it would use Special:MobileDiff as
// the target for Special:Log/delete?page=Special:MobileDiff/..., which isn't
// correct and very helpful. To fix this bug, we create a new context from the
// current one and set the title object (which we can get from the new revision).
// Bug: T122984
$context = new DerivativeContext( $this->getContext() );
$revision = $this->mNewRev;
$context->setTitle( $revision->getTitle() );
if ( !$allowed ) {
$msg = $context->msg(
$suppressed ? 'rev-suppressed-no-diff' : 'rev-deleted-no-diff'
)->parse();
} else {
// Give explanation and add a link to view the diff...
$query = $this->getRequest()->appendQueryValue( 'unhide', '1' );
$link = $this->getTitle()->getFullURL( $query );
$msg = $context->msg(
$suppressed ? 'rev-suppressed-unhide-diff' : 'rev-deleted-unhide-diff',
$link
)->parse();
}
}
return $msg;
}
/** @inheritDoc */
public function generateContentDiffBody( Content $old, Content $new ) {
Assert::parameterType( TextContent::class, $old, '$old' );
Assert::parameterType( TextContent::class, $new, '$new' );
$otext = $old->serialize();
$ntext = $new->serialize();
return $this->generateTextDiffBody( $otext, $ntext );
}
/**
* Creates an inline diff
* @param string $otext Old content
* @param string $ntext New content
* @throws \MediaWiki\Diff\ComplexityException
*
* @return string
*/
public function generateTextDiffBody( $otext, $ntext ) {
global $wgContLang;
// First try wikidiff2
if ( function_exists( 'wikidiff2_inline_diff' ) ) {
$text = wikidiff2_inline_diff( $otext, $ntext, 2 );
$text .= $this->debug( 'wikidiff2-inline' );
return $text;
}
// Else slow native PHP diff
$ota = explode( "\n", $wgContLang->segmentForDiff( $otext ) );
$nta = explode( "\n", $wgContLang->segmentForDiff( $ntext ) );
$diffs = new Diff( $ota, $nta );
$formatter = new InlineDiffFormatter();
return $wgContLang->unsegmentForDiff( $formatter->format( $diffs ) );
}
/**
* @inheritDoc
*/
protected function getDiffBodyCacheKeyParams() {
$params = parent::getDiffBodyCacheKeyParams();
$params[0] = 'inline-diff';
return $params;
}
/**
* Create a getter function for the patrol link in Mobile Diff.
* FIXME: This shouldn't be needed, but markPatrolledLink is protected in DifferenceEngine
* @return String
*/
public function getPatrolledLink() {
$linkInfo = $this->getMarkPatrolledLinkInfo();
if ( $linkInfo ) {
$linkInfo = Html::linkButton(
$this->msg( 'markaspatrolleddiff' )->escaped(),
[
'href' => $this->mNewPage->getLocalURL( [
'action' => 'markpatrolled',
'rcid' => $linkInfo['rcid'],
] ),
]
);
}
return $linkInfo;
}
}