From 9da12daf4626bbde4bbf246aab8e2549e3eca7a6 Mon Sep 17 00:00:00 2001 From: daniel Date: Tue, 18 Sep 2018 17:36:59 +0200 Subject: [PATCH] Provide a way to restore an old revision with multiple slots. Bug: T204732 Change-Id: I0ea2711e68c78465a5e5cfaa0181ad5ce983d35a --- autoload.php | 1 + includes/DefaultSettings.php | 1 + includes/EditPage.php | 30 ++++++++++++++- includes/actions/McrRestoreAction.php | 55 +++++++++++++++++++++++++++ includes/actions/McrUndoAction.php | 18 ++++++--- languages/i18n/en.json | 1 + languages/i18n/qqq.json | 1 + 7 files changed, 101 insertions(+), 6 deletions(-) create mode 100644 includes/actions/McrRestoreAction.php diff --git a/autoload.php b/autoload.php index 67285d0a89..77245ed1cc 100644 --- a/autoload.php +++ b/autoload.php @@ -850,6 +850,7 @@ $wgAutoloadLocalClasses = [ 'MappedIterator' => __DIR__ . '/includes/libs/MappedIterator.php', 'MarkpatrolledAction' => __DIR__ . '/includes/actions/MarkpatrolledAction.php', 'McTest' => __DIR__ . '/maintenance/mctest.php', + 'McrRestoreAction' => __DIR__ . '/includes/actions/McrRestoreAction.php', 'McrUndoAction' => __DIR__ . '/includes/actions/McrUndoAction.php', 'MediaHandler' => __DIR__ . '/includes/media/MediaHandler.php', 'MediaHandlerFactory' => __DIR__ . '/includes/media/MediaHandlerFactory.php', diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php index d335dccac0..10eb44346e 100644 --- a/includes/DefaultSettings.php +++ b/includes/DefaultSettings.php @@ -8017,6 +8017,7 @@ $wgActions = [ 'info' => true, 'markpatrolled' => true, 'mcrundo' => McrUndoAction::class, + 'mcrrestore' => McrRestoreAction::class, 'protect' => true, 'purge' => true, 'raw' => true, diff --git a/includes/EditPage.php b/includes/EditPage.php index f1f0572bac..7384ca216c 100644 --- a/includes/EditPage.php +++ b/includes/EditPage.php @@ -1222,7 +1222,9 @@ class EditPage { !$undorev->isDeleted( Revision::DELETED_TEXT ) && !$oldrev->isDeleted( Revision::DELETED_TEXT ) ) { - if ( WikiPage::hasDifferencesOutsideMainSlot( $undorev, $oldrev ) ) { + if ( WikiPage::hasDifferencesOutsideMainSlot( $undorev, $oldrev ) + || !$this->isSupportedContentModel( $oldrev->getContentModel() ) + ) { // Hack for undo while EditPage can't handle multi-slot editing $this->context->getOutput()->redirect( $this->mTitle->getFullURL( [ 'action' => 'mcrundo', @@ -1304,6 +1306,32 @@ class EditPage { $this->context->msg( 'undo-' . $undoMsg )->plain() . '', true, /* interface */true ); } + if ( $content === false ) { + // Hack for restoring old revisions while EditPage + // can't handle multi-slot editing. + + $curRevision = $this->page->getRevision(); + $oldRevision = $this->mArticle->getRevisionFetched(); + + if ( $curRevision + && $oldRevision + && $curRevision->getId() !== $oldRevision->getId() + && ( WikiPage::hasDifferencesOutsideMainSlot( $oldRevision, $curRevision ) + || !$this->isSupportedContentModel( $oldRevision->getContentModel() ) ) + ) { + $this->context->getOutput()->redirect( + $this->mTitle->getFullURL( + [ + 'action' => 'mcrrestore', + 'restore' => $oldRevision->getId(), + ] + ) + ); + + return false; + } + } + if ( $content === false ) { $content = $this->getOriginalContent( $user ); } diff --git a/includes/actions/McrRestoreAction.php b/includes/actions/McrRestoreAction.php new file mode 100644 index 0000000000..fbc39d716c --- /dev/null +++ b/includes/actions/McrRestoreAction.php @@ -0,0 +1,55 @@ +page->getRevision(); + if ( !$curRev ) { + throw new ErrorPageError( 'mcrundofailed', 'nopagetext' ); + } + $this->curRev = $curRev->getRevisionRecord(); + $this->cur = $this->getRequest()->getInt( 'cur', $this->curRev->getId() ); + + $this->undo = $this->cur; + $this->undoafter = $this->getRequest()->getInt( 'restore' ); + + if ( $this->undo == 0 || $this->undoafter == 0 ) { + throw new ErrorPageError( 'mcrundofailed', 'mcrundo-missingparam' ); + } + } + + protected function addStatePropagationFields( HTMLForm $form ) { + $form->addHiddenField( 'restore', $this->undoafter ); + $form->addHiddenField( 'cur', $this->curRev->getId() ); + } + + protected function alterForm( HTMLForm $form ) { + parent::alterForm( $form ); + + $form->setWrapperLegendMsg( 'confirm-mcrrestore-title' ); + } + +} diff --git a/includes/actions/McrUndoAction.php b/includes/actions/McrUndoAction.php index 15a394da09..6309362ae0 100644 --- a/includes/actions/McrUndoAction.php +++ b/includes/actions/McrUndoAction.php @@ -28,10 +28,10 @@ use MediaWiki\Storage\SlotRecord; */ class McrUndoAction extends FormAction { - private $undo = 0, $undoafter = 0, $cur = 0; + protected $undo = 0, $undoafter = 0, $cur = 0; /** @param RevisionRecord|null */ - private $curRev = null; + protected $curRev = null; public function getName() { return 'mcrundo'; @@ -90,9 +90,7 @@ class McrUndoAction extends FormAction { parent::show(); } - protected function checkCanExecute( User $user ) { - parent::checkCanExecute( $user ); - + protected function initFromParameters() { $this->undoafter = $this->getRequest()->getInt( 'undoafter' ); $this->undo = $this->getRequest()->getInt( 'undo' ); @@ -106,6 +104,12 @@ class McrUndoAction extends FormAction { } $this->curRev = $curRev->getRevisionRecord(); $this->cur = $this->getRequest()->getInt( 'cur', $this->curRev->getId() ); + } + + protected function checkCanExecute( User $user ) { + parent::checkCanExecute( $user ); + + $this->initFromParameters(); $revisionLookup = MediaWikiServices::getInstance()->getRevisionLookup(); @@ -412,6 +416,10 @@ class McrUndoAction extends FormAction { 'attribs' => Linker::tooltipAndAccesskeyAttribs( 'diff' ), ] ); + $this->addStatePropagationFields( $form ); + } + + protected function addStatePropagationFields( HTMLForm $form ) { $form->addHiddenField( 'undo', $this->undo ); $form->addHiddenField( 'undoafter', $this->undoafter ); $form->addHiddenField( 'cur', $this->curRev->getId() ); diff --git a/languages/i18n/en.json b/languages/i18n/en.json index 1831b9fc8e..af4bbb554e 100644 --- a/languages/i18n/en.json +++ b/languages/i18n/en.json @@ -3670,6 +3670,7 @@ "confirm-unwatch-top": "Remove this page from your watchlist?", "confirm-rollback-button": "OK", "confirm-rollback-top": "Revert edits to this page?", + "confirm-mcrrestore-title": "Restore a revision", "confirm-mcrundo-title": "Undo a change", "mcrundofailed": "Undo failed", "mcrundo-missingparam": "Missing required parameters on request.", diff --git a/languages/i18n/qqq.json b/languages/i18n/qqq.json index a65c3c84d1..eeb0a1cf59 100644 --- a/languages/i18n/qqq.json +++ b/languages/i18n/qqq.json @@ -3872,6 +3872,7 @@ "confirm-unwatch-top": "Used as confirmation message.", "confirm-rollback-button": "Used as Submit button text.\n{{Identical|OK}}", "confirm-rollback-top": "Used as confirmation message.", + "confirm-mcrrestore-title": "Title for the editless restore form.", "confirm-mcrundo-title": "Title for the editless undo form.", "mcrundofailed": "Title of the error page when an editless undo fails.", "mcrundo-missingparam": "Error displayed when parameters for action=mcrundo are missing", -- 2.20.1