Provide a way to restore an old revision with multiple slots.
authordaniel <daniel.kinzler@wikimedia.de>
Tue, 18 Sep 2018 15:36:59 +0000 (17:36 +0200)
committerdaniel <daniel.kinzler@wikimedia.de>
Mon, 24 Sep 2018 17:46:30 +0000 (19:46 +0200)
Bug: T204732
Change-Id: I0ea2711e68c78465a5e5cfaa0181ad5ce983d35a

autoload.php
includes/DefaultSettings.php
includes/EditPage.php
includes/actions/McrRestoreAction.php [new file with mode: 0644]
includes/actions/McrUndoAction.php
languages/i18n/en.json
languages/i18n/qqq.json

index 67285d0..77245ed 100644 (file)
@@ -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',
index d335dcc..10eb443 100644 (file)
@@ -8017,6 +8017,7 @@ $wgActions = [
        'info' => true,
        'markpatrolled' => true,
        'mcrundo' => McrUndoAction::class,
+       'mcrrestore' => McrRestoreAction::class,
        'protect' => true,
        'purge' => true,
        'raw' => true,
index f1f0572..7384ca2 100644 (file)
@@ -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() . '</div>', 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 (file)
index 0000000..fbc39d7
--- /dev/null
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Temporary action for restoring multi-content revisions
+ * @file
+ * @ingroup Actions
+ */
+
+/**
+ * Temporary action for restoring multi-content revisions.
+ *
+ * This is intended to go away when real MCR support is added to EditPage and
+ * the standard revert-by-edit behavior can be implemented there instead.
+ *
+ * @ingroup Actions
+ * @since 1.32
+ * @deprecated since 1.32
+ */
+class McrRestoreAction extends McrUndoAction {
+
+       public function getName() {
+               return 'mcrrestore';
+       }
+
+       public function getDescription() {
+               return '';
+       }
+
+       protected function initFromParameters() {
+               $curRev = $this->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' );
+       }
+
+}
index 15a394d..6309362 100644 (file)
@@ -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() );
index 1831b9f..af4bbb5 100644 (file)
        "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.",
index a65c3c8..eeb0a1c 100644 (file)
        "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",