X-Git-Url: https://git.cyclocoop.org/%7B%24www_url%7Dadmin/compta/banques/?a=blobdiff_plain;f=includes%2Fapi%2FApiComparePages.php;h=4ba30abfd46e44da0da32fc8f290893d506a8c8f;hb=227a807ef50387393df0641bce0a6cd16e550338;hp=393f43542d87bc3366c9434273166e8fe08adc3c;hpb=a7c30848cfe972c3e2e16b8a962cbfdcd128dc73;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/api/ApiComparePages.php b/includes/api/ApiComparePages.php index 393f43542d..4ba30abfd4 100644 --- a/includes/api/ApiComparePages.php +++ b/includes/api/ApiComparePages.php @@ -22,6 +22,7 @@ use MediaWiki\MediaWikiServices; use MediaWiki\Revision\MutableRevisionRecord; use MediaWiki\Revision\RevisionRecord; +use MediaWiki\Revision\RevisionArchiveRecord; use MediaWiki\Revision\RevisionStore; use MediaWiki\Revision\SlotRecord; @@ -65,19 +66,56 @@ class ApiComparePages extends ApiBase { if ( !$fromRelRev ) { $this->dieWithError( 'apierror-compare-relative-to-nothing' ); } + if ( $params['torelative'] !== 'cur' && $fromRelRev instanceof RevisionArchiveRecord ) { + // RevisionStore's getPreviousRevision/getNextRevision blow up + // when passed an RevisionArchiveRecord for a deleted page + $this->dieWithError( [ 'apierror-compare-relative-to-deleted', $params['torelative'] ] ); + } switch ( $params['torelative'] ) { case 'prev': // Swap 'from' and 'to' - list( $toRev, $toRelRev2, $toValsRev ) = [ $fromRev, $fromRelRev, $fromValsRev ]; - $fromRev = $this->revisionStore->getPreviousRevision( $fromRelRev ); + list( $toRev, $toRelRev, $toValsRev ) = [ $fromRev, $fromRelRev, $fromValsRev ]; + $fromRev = $this->revisionStore->getPreviousRevision( $toRelRev ); $fromRelRev = $fromRev; $fromValsRev = $fromRev; + if ( !$fromRev ) { + $title = Title::newFromLinkTarget( $toRelRev->getPageAsLinkTarget() ); + $this->addWarning( [ + 'apiwarn-compare-no-prev', + wfEscapeWikiText( $title->getPrefixedText() ), + $toRelRev->getId() + ] ); + + // (T203433) Create an empty dummy revision as the "previous". + // The main slot has to exist, the rest will be handled by DifferenceEngine. + $fromRev = $this->revisionStore->newMutableRevisionFromArray( [ + 'title' => $title ?: Title::makeTitle( NS_SPECIAL, 'Badtitle/' . __METHOD__ ) + ] ); + $fromRev->setContent( + SlotRecord::MAIN, + $toRelRev->getContent( SlotRecord::MAIN, RevisionRecord::RAW ) + ->getContentHandler() + ->makeEmptyContent() + ); + } break; case 'next': $toRev = $this->revisionStore->getNextRevision( $fromRelRev ); $toRelRev = $toRev; $toValsRev = $toRev; + if ( !$toRev ) { + $title = Title::newFromLinkTarget( $fromRelRev->getPageAsLinkTarget() ); + $this->addWarning( [ + 'apiwarn-compare-no-next', + wfEscapeWikiText( $title->getPrefixedText() ), + $fromRelRev->getId() + ] ); + + // (T203433) The web UI treats "next" as "cur" in this case. + // Avoid repeating metadata by making a MutableRevisionRecord with no changes. + $toRev = MutableRevisionRecord::newFromParentRevision( $fromRelRev ); + } break; case 'cur': @@ -97,10 +135,12 @@ class ApiComparePages extends ApiBase { list( $toRev, $toRelRev, $toValsRev ) = $this->getDiffRevision( 'to', $params ); } - // Handle missing from or to revisions + // Handle missing from or to revisions (should never happen) + // @codeCoverageIgnoreStart if ( !$fromRev || !$toRev ) { $this->dieWithError( 'apierror-baddiff' ); } + // @codeCoverageIgnoreEnd // Handle revdel if ( !$fromRev->audienceCan(