Merge "Do not run tests that depend on curl if it is not loaded"
[lhc/web/wiklou.git] / includes / EditPage.php
index 4451867..248378c 100644 (file)
@@ -511,6 +511,7 @@ class EditPage {
         * @deprecated since 1.29, call edit directly
         */
        public function submit() {
+               wfDeprecated( __METHOD__, '1.29' );
                $this->edit();
        }
 
@@ -526,7 +527,7 @@ class EditPage {
         * the newly-edited page.
         */
        public function edit() {
-               global $wgOut, $wgRequest, $wgUser;
+               global $wgRequest;
                // Allow extensions to modify/prevent this form or submission
                if ( !Hooks::run( 'AlternateEdit', [ $this ] ) ) {
                        return;
@@ -536,7 +537,7 @@ class EditPage {
 
                // If they used redlink=1 and the page exists, redirect to the main article
                if ( $wgRequest->getBool( 'redlink' ) && $this->mTitle->exists() ) {
-                       $wgOut->redirect( $this->mTitle->getFullURL() );
+                       $this->context->getOutput()->redirect( $this->mTitle->getFullURL() );
                        return;
                }
 
@@ -569,9 +570,8 @@ class EditPage {
                        wfDebug( __METHOD__ . ": User can't edit\n" );
                        // Auto-block user's IP if the account was "hard" blocked
                        if ( !wfReadOnly() ) {
-                               $user = $wgUser;
-                               DeferredUpdates::addCallableUpdate( function () use ( $user ) {
-                                       $user->spreadAnyEditBlock();
+                               DeferredUpdates::addCallableUpdate( function () {
+                                       $this->context->getUser()->spreadAnyEditBlock();
                                } );
                        }
                        $this->displayPermissionsError( $permErrors );
@@ -656,15 +656,14 @@ class EditPage {
         * @return array
         */
        protected function getEditPermissionErrors( $rigor = 'secure' ) {
-               global $wgUser;
-
-               $permErrors = $this->mTitle->getUserPermissionsErrors( 'edit', $wgUser, $rigor );
+               $user = $this->context->getUser();
+               $permErrors = $this->mTitle->getUserPermissionsErrors( 'edit', $user, $rigor );
                # Can this title be created?
                if ( !$this->mTitle->exists() ) {
                        $permErrors = array_merge(
                                $permErrors,
                                wfArrayDiff2(
-                                       $this->mTitle->getUserPermissionsErrors( 'create', $wgUser, $rigor ),
+                                       $this->mTitle->getUserPermissionsErrors( 'create', $user, $rigor ),
                                        $permErrors
                                )
                        );
@@ -701,13 +700,14 @@ class EditPage {
         * @throws PermissionsError
         */
        protected function displayPermissionsError( array $permErrors ) {
-               global $wgRequest, $wgOut;
+               global $wgRequest;
 
+               $out = $this->context->getOutput();
                if ( $wgRequest->getBool( 'redlink' ) ) {
                        // The edit page was reached via a red link.
                        // Redirect to the article page and let them click the edit tab if
                        // they really want a permission error.
-                       $wgOut->redirect( $this->mTitle->getFullURL() );
+                       $out->redirect( $this->mTitle->getFullURL() );
                        return;
                }
 
@@ -722,7 +722,7 @@ class EditPage {
 
                $this->displayViewSourcePage(
                        $content,
-                       $wgOut->formatPermissionsErrorMessage( $permErrors, 'edit' )
+                       $out->formatPermissionsErrorMessage( $permErrors, 'edit' )
                );
        }
 
@@ -732,29 +732,28 @@ class EditPage {
         * @param string $errorMessage additional wikitext error message to display
         */
        protected function displayViewSourcePage( Content $content, $errorMessage = '' ) {
-               global $wgOut;
+               $out = $this->context->getOutput();
+               Hooks::run( 'EditPage::showReadOnlyForm:initial', [ $this, &$out ] );
 
-               Hooks::run( 'EditPage::showReadOnlyForm:initial', [ $this, &$wgOut ] );
-
-               $wgOut->setRobotPolicy( 'noindex,nofollow' );
-               $wgOut->setPageTitle( $this->context->msg(
+               $out->setRobotPolicy( 'noindex,nofollow' );
+               $out->setPageTitle( $this->context->msg(
                        'viewsource-title',
                        $this->getContextTitle()->getPrefixedText()
                ) );
-               $wgOut->addBacklinkSubtitle( $this->getContextTitle() );
-               $wgOut->addHTML( $this->editFormPageTop );
-               $wgOut->addHTML( $this->editFormTextTop );
+               $out->addBacklinkSubtitle( $this->getContextTitle() );
+               $out->addHTML( $this->editFormPageTop );
+               $out->addHTML( $this->editFormTextTop );
 
                if ( $errorMessage !== '' ) {
-                       $wgOut->addWikiText( $errorMessage );
-                       $wgOut->addHTML( "<hr />\n" );
+                       $out->addWikiText( $errorMessage );
+                       $out->addHTML( "<hr />\n" );
                }
 
                # If the user made changes, preserve them when showing the markup
                # (This happens when a user is blocked during edit, for instance)
                if ( !$this->firsttime ) {
                        $text = $this->textbox1;
-                       $wgOut->addWikiMsg( 'viewyourtext' );
+                       $out->addWikiMsg( 'viewyourtext' );
                } else {
                        try {
                                $text = $this->toEditText( $content );
@@ -763,20 +762,20 @@ class EditPage {
                                # (e.g. for an old revision with a different model)
                                $text = $content->serialize();
                        }
-                       $wgOut->addWikiMsg( 'viewsourcetext' );
+                       $out->addWikiMsg( 'viewsourcetext' );
                }
 
-               $wgOut->addHTML( $this->editFormTextBeforeContent );
+               $out->addHTML( $this->editFormTextBeforeContent );
                $this->showTextbox( $text, 'wpTextbox1', [ 'readonly' ] );
-               $wgOut->addHTML( $this->editFormTextAfterContent );
+               $out->addHTML( $this->editFormTextAfterContent );
 
-               $wgOut->addHTML( $this->makeTemplatesOnThisPageList( $this->getTemplates() ) );
+               $out->addHTML( $this->makeTemplatesOnThisPageList( $this->getTemplates() ) );
 
-               $wgOut->addModules( 'mediawiki.action.edit.collapsibleFooter' );
+               $out->addModules( 'mediawiki.action.edit.collapsibleFooter' );
 
-               $wgOut->addHTML( $this->editFormTextBottom );
+               $out->addHTML( $this->editFormTextBottom );
                if ( $this->mTitle->exists() ) {
-                       $wgOut->returnToMain( null, $this->mTitle );
+                       $out->returnToMain( null, $this->mTitle );
                }
        }
 
@@ -786,7 +785,7 @@ class EditPage {
         * @return bool
         */
        protected function previewOnOpen() {
-               global $wgRequest, $wgUser, $wgPreviewOnOpenNamespaces;
+               global $wgRequest, $wgPreviewOnOpenNamespaces;
                if ( $wgRequest->getVal( 'preview' ) == 'yes' ) {
                        // Explicit override from request
                        return true;
@@ -797,7 +796,7 @@ class EditPage {
                        // Nothing *to* preview for new sections
                        return false;
                } elseif ( ( $wgRequest->getVal( 'preload' ) !== null || $this->mTitle->exists() )
-                       && $wgUser->getOption( 'previewonfirst' )
+                       && $this->context->getUser()->getOption( 'previewonfirst' )
                ) {
                        // Standard preference behavior
                        return true;
@@ -850,8 +849,6 @@ class EditPage {
         * @throws ErrorPageError
         */
        public function importFormData( &$request ) {
-               global $wgContLang, $wgUser;
-
                # Section edit can come from either the form or a link
                $this->section = $request->getVal( 'wpSection', $request->getVal( 'section' ) );
 
@@ -876,8 +873,7 @@ class EditPage {
                                }
                        }
 
-                       # Truncate for whole multibyte characters
-                       $this->summary = $wgContLang->truncate( $request->getText( 'wpSummary' ), 255 );
+                       $this->summary = $request->getText( 'wpSummary' );
 
                        # If the summary consists of a heading, e.g. '==Foobar==', extract the title from the
                        # header syntax, e.g. 'Foobar'. This is mainly an issue when we are using wpSummary for
@@ -889,7 +885,7 @@ class EditPage {
                        # currently doing double duty as both edit summary and section title. Right now this
                        # is just to allow API edits to work around this limitation, but this should be
                        # incorporated into the actual edit form when EditPage is rewritten (Bugs 18654, 26312).
-                       $this->sectiontitle = $wgContLang->truncate( $request->getText( 'wpSectionTitle' ), 255 );
+                       $this->sectiontitle = $request->getText( 'wpSectionTitle' );
                        $this->sectiontitle = preg_replace( '/^\s*=+\s*(.*?)\s*=+\s*$/', '$1', $this->sectiontitle );
 
                        $this->edittime = $request->getVal( 'wpEdittime' );
@@ -961,14 +957,15 @@ class EditPage {
                        $this->minoredit = $request->getCheck( 'wpMinoredit' );
                        $this->watchthis = $request->getCheck( 'wpWatchthis' );
 
+                       $user = $this->context->getUser();
                        # Don't force edit summaries when a user is editing their own user or talk page
                        if ( ( $this->mTitle->mNamespace == NS_USER || $this->mTitle->mNamespace == NS_USER_TALK )
-                               && $this->mTitle->getText() == $wgUser->getName()
+                               && $this->mTitle->getText() == $user->getName()
                        ) {
                                $this->allowBlankSummary = true;
                        } else {
                                $this->allowBlankSummary = $request->getBool( 'wpIgnoreBlankSummary' )
-                                       || !$wgUser->getOption( 'forceeditsummary' );
+                                       || !$user->getOption( 'forceeditsummary' );
                        }
 
                        $this->autoSumm = $request->getText( 'wpAutoSummary' );
@@ -1084,7 +1081,6 @@ class EditPage {
         * @return bool If the requested section is valid
         */
        public function initialiseForm() {
-               global $wgUser;
                $this->edittime = $this->page->getTimestamp();
                $this->editRevId = $this->page->getLatest();
 
@@ -1094,19 +1090,20 @@ class EditPage {
                }
                $this->textbox1 = $this->toEditText( $content );
 
+               $user = $this->context->getUser();
                // activate checkboxes if user wants them to be always active
                # Sort out the "watch" checkbox
-               if ( $wgUser->getOption( 'watchdefault' ) ) {
+               if ( $user->getOption( 'watchdefault' ) ) {
                        # Watch all edits
                        $this->watchthis = true;
-               } elseif ( $wgUser->getOption( 'watchcreations' ) && !$this->mTitle->exists() ) {
+               } elseif ( $user->getOption( 'watchcreations' ) && !$this->mTitle->exists() ) {
                        # Watch creations
                        $this->watchthis = true;
-               } elseif ( $wgUser->isWatched( $this->mTitle ) ) {
+               } elseif ( $user->isWatched( $this->mTitle ) ) {
                        # Already watched
                        $this->watchthis = true;
                }
-               if ( $wgUser->getOption( 'minordefault' ) && !$this->isNew ) {
+               if ( $user->getOption( 'minordefault' ) && !$this->isNew ) {
                        $this->minoredit = true;
                }
                if ( $this->textbox1 === false ) {
@@ -1123,10 +1120,11 @@ class EditPage {
         * @since 1.21
         */
        protected function getContentObject( $def_content = null ) {
-               global $wgOut, $wgRequest, $wgUser, $wgContLang;
+               global $wgRequest, $wgContLang;
 
                $content = false;
 
+               $user = $this->context->getUser();
                // For message page not locally set, use the i18n message.
                // For other non-existent articles, use preload text if any.
                if ( !$this->mTitle->exists() || $this->section == 'new' ) {
@@ -1149,7 +1147,7 @@ class EditPage {
                } else {
                        if ( $this->section != '' ) {
                                // Get section edit text (returns $def_text for invalid sections)
-                               $orig = $this->getOriginalContent( $wgUser );
+                               $orig = $this->getOriginalContent( $user );
                                $content = $orig ? $orig->getSection( $this->section ) : null;
 
                                if ( !$content ) {
@@ -1177,8 +1175,8 @@ class EditPage {
                                                        $undoMsg = 'failure';
                                                } else {
                                                        $oldContent = $this->page->getContent( Revision::RAW );
-                                                       $popts = ParserOptions::newFromUserAndLang( $wgUser, $wgContLang );
-                                                       $newContent = $content->preSaveTransform( $this->mTitle, $wgUser, $popts );
+                                                       $popts = ParserOptions::newFromUserAndLang( $user, $wgContLang );
+                                                       $newContent = $content->preSaveTransform( $this->mTitle, $user, $popts );
                                                        if ( $newContent->getModel() !== $oldContent->getModel() ) {
                                                                // The undo may change content
                                                                // model if its reverting the top
@@ -1231,14 +1229,15 @@ class EditPage {
                                                $undoMsg = 'norev';
                                        }
 
+                                       $out = $this->context->getOutput();
                                        // Messages: undo-success, undo-failure, undo-norev, undo-nochange
                                        $class = ( $undoMsg == 'success' ? '' : 'error ' ) . "mw-undo-{$undoMsg}";
-                                       $this->editFormPageTop .= $wgOut->parse( "<div class=\"{$class}\">" .
+                                       $this->editFormPageTop .= $out->parse( "<div class=\"{$class}\">" .
                                                $this->context->msg( 'undo-' . $undoMsg )->plain() . '</div>', true, /* interface */true );
                                }
 
                                if ( $content === false ) {
-                                       $content = $this->getOriginalContent( $wgUser );
+                                       $content = $this->getOriginalContent( $user );
                                }
                        }
                }
@@ -1364,8 +1363,6 @@ class EditPage {
         * @since 1.21
         */
        protected function getPreloadedContent( $preload, $params = [] ) {
-               global $wgUser;
-
                if ( !empty( $this->mPreloadContent ) ) {
                        return $this->mPreloadContent;
                }
@@ -1376,9 +1373,10 @@ class EditPage {
                        return $handler->makeEmptyContent();
                }
 
+               $user = $this->context->getUser();
                $title = Title::newFromText( $preload );
                # Check for existence to avoid getting MediaWiki:Noarticletext
-               if ( $title === null || !$title->exists() || !$title->userCan( 'read', $wgUser ) ) {
+               if ( $title === null || !$title->exists() || !$title->userCan( 'read', $user ) ) {
                        // TODO: somehow show a warning to the user!
                        return $handler->makeEmptyContent();
                }
@@ -1387,14 +1385,14 @@ class EditPage {
                if ( $page->isRedirect() ) {
                        $title = $page->getRedirectTarget();
                        # Same as before
-                       if ( $title === null || !$title->exists() || !$title->userCan( 'read', $wgUser ) ) {
+                       if ( $title === null || !$title->exists() || !$title->userCan( 'read', $user ) ) {
                                // TODO: somehow show a warning to the user!
                                return $handler->makeEmptyContent();
                        }
                        $page = WikiPage::factory( $title );
                }
 
-               $parserOptions = ParserOptions::newFromUser( $wgUser );
+               $parserOptions = ParserOptions::newFromUser( $user );
                $content = $page->getContent( Revision::RAW );
 
                if ( !$content ) {
@@ -1428,10 +1426,10 @@ class EditPage {
         * @private
         */
        public function tokenOk( &$request ) {
-               global $wgUser;
                $token = $request->getVal( 'wpEditToken' );
-               $this->mTokenOk = $wgUser->matchEditToken( $token );
-               $this->mTokenOkExceptSuffix = $wgUser->matchEditTokenNoSuffix( $token );
+               $user = $this->context->getUser();
+               $this->mTokenOk = $user->matchEditToken( $token );
+               $this->mTokenOkExceptSuffix = $user->matchEditTokenNoSuffix( $token );
                return $this->mTokenOk;
        }
 
@@ -1460,7 +1458,7 @@ class EditPage {
                        $val = 'restored';
                }
 
-               $response = RequestContext::getMain()->getRequest()->response();
+               $response = $this->context->getRequest()->response();
                $response->setCookie( $postEditKey, $val, time() + self::POST_EDIT_COOKIE_DURATION );
        }
 
@@ -1471,10 +1469,8 @@ class EditPage {
         * @return Status The resulting status object.
         */
        public function attemptSave( &$resultDetails = false ) {
-               global $wgUser;
-
                # Allow bots to exempt some edits from bot flagging
-               $bot = $wgUser->isAllowed( 'bot' ) && $this->bot;
+               $bot = $this->context->getUser()->isAllowed( 'bot' ) && $this->bot;
                $status = $this->internalAttemptSave( $resultDetails, $bot );
 
                Hooks::run( 'EditPage::attemptSave:after', [ $this, $status, $resultDetails ] );
@@ -1506,8 +1502,6 @@ class EditPage {
         * @return bool False, if output is done, true if rest of the form should be displayed
         */
        private function handleStatus( Status $status, $resultDetails ) {
-               global $wgUser, $wgOut;
-
                /**
                 * @todo FIXME: once the interface for internalAttemptSave() is made
                 *   nicer, this should use the message in $status
@@ -1523,9 +1517,11 @@ class EditPage {
                        }
                }
 
+               $out = $this->context->getOutput();
+
                // "wpExtraQueryRedirect" is a hidden input to modify
                // after save URL and is not used by actual edit form
-               $request = RequestContext::getMain()->getRequest();
+               $request = $this->context->getRequest();
                $extraQueryRedirect = $request->getVal( 'wpExtraQueryRedirect' );
 
                switch ( $status->value ) {
@@ -1546,7 +1542,7 @@ class EditPage {
 
                        case self::AS_CANNOT_USE_CUSTOM_MODEL:
                        case self::AS_PARSE_ERROR:
-                               $wgOut->addWikiText( '<div class="error">' . "\n" . $status->getWikiText() . '</div>' );
+                               $out->addWikiText( '<div class="error">' . "\n" . $status->getWikiText() . '</div>' );
                                return true;
 
                        case self::AS_SUCCESS_NEW_ARTICLE:
@@ -1559,7 +1555,7 @@ class EditPage {
                                        }
                                }
                                $anchor = isset( $resultDetails['sectionanchor'] ) ? $resultDetails['sectionanchor'] : '';
-                               $wgOut->redirect( $this->mTitle->getFullURL( $query ) . $anchor );
+                               $out->redirect( $this->mTitle->getFullURL( $query ) . $anchor );
                                return false;
 
                        case self::AS_SUCCESS_UPDATE:
@@ -1587,7 +1583,7 @@ class EditPage {
                                        }
                                }
 
-                               $wgOut->redirect( $this->mTitle->getFullURL( $extraQuery ) . $sectionanchor );
+                               $out->redirect( $this->mTitle->getFullURL( $extraQuery ) . $sectionanchor );
                                return false;
 
                        case self::AS_SPAM_ERROR:
@@ -1595,7 +1591,7 @@ class EditPage {
                                return false;
 
                        case self::AS_BLOCKED_PAGE_FOR_USER:
-                               throw new UserBlockedError( $wgUser->getBlock() );
+                               throw new UserBlockedError( $this->context->getUser()->getBlock() );
 
                        case self::AS_IMAGE_REDIRECT_ANON:
                        case self::AS_IMAGE_REDIRECT_LOGGED:
@@ -1734,10 +1730,11 @@ class EditPage {
         * time.
         */
        public function internalAttemptSave( &$result, $bot = false ) {
-               global $wgUser, $wgRequest, $wgMaxArticleSize;
+               global $wgRequest, $wgMaxArticleSize;
                global $wgContentHandlerUseDB;
 
                $status = Status::newGood();
+               $user = $this->context->getUser();
 
                if ( !Hooks::run( 'EditPage::attemptSave', [ $this ] ) ) {
                        wfDebug( "Hook 'EditPage::attemptSave' aborted article saving\n" );
@@ -1750,7 +1747,7 @@ class EditPage {
                if ( $spam !== '' ) {
                        wfDebugLog(
                                'SimpleAntiSpam',
-                               $wgUser->getName() .
+                               $user->getName() .
                                ' editing "' .
                                $this->mTitle->getPrefixedText() .
                                '" submitted bogus field "' .
@@ -1779,9 +1776,9 @@ class EditPage {
                # Check image redirect
                if ( $this->mTitle->getNamespace() == NS_FILE &&
                        $textbox_content->isRedirect() &&
-                       !$wgUser->isAllowed( 'upload' )
+                       !$user->isAllowed( 'upload' )
                ) {
-                               $code = $wgUser->isAnon() ? self::AS_IMAGE_REDIRECT_ANON : self::AS_IMAGE_REDIRECT_LOGGED;
+                               $code = $user->isAnon() ? self::AS_IMAGE_REDIRECT_ANON : self::AS_IMAGE_REDIRECT_LOGGED;
                                $status->setResult( false, $code );
 
                                return $status;
@@ -1829,10 +1826,10 @@ class EditPage {
                        return $status;
                }
 
-               if ( $wgUser->isBlockedFrom( $this->mTitle, false ) ) {
+               if ( $user->isBlockedFrom( $this->mTitle, false ) ) {
                        // Auto-block user's IP if the account was "hard" blocked
                        if ( !wfReadOnly() ) {
-                               $wgUser->spreadAnyEditBlock();
+                               $user->spreadAnyEditBlock();
                        }
                        # Check block state against master, thus 'false'.
                        $status->setResult( false, self::AS_BLOCKED_PAGE_FOR_USER );
@@ -1847,8 +1844,8 @@ class EditPage {
                        return $status;
                }
 
-               if ( !$wgUser->isAllowed( 'edit' ) ) {
-                       if ( $wgUser->isAnon() ) {
+               if ( !$user->isAllowed( 'edit' ) ) {
+                       if ( $user->isAnon() ) {
                                $status->setResult( false, self::AS_READ_ONLY_PAGE_ANON );
                                return $status;
                        } else {
@@ -1864,15 +1861,15 @@ class EditPage {
                                $status->fatal( 'editpage-cannot-use-custom-model' );
                                $status->value = self::AS_CANNOT_USE_CUSTOM_MODEL;
                                return $status;
-                       } elseif ( !$wgUser->isAllowed( 'editcontentmodel' ) ) {
+                       } elseif ( !$user->isAllowed( 'editcontentmodel' ) ) {
                                $status->setResult( false, self::AS_NO_CHANGE_CONTENT_MODEL );
                                return $status;
                        }
                        // Make sure the user can edit the page under the new content model too
                        $titleWithNewContentModel = clone $this->mTitle;
                        $titleWithNewContentModel->setContentModel( $this->contentModel );
-                       if ( !$titleWithNewContentModel->userCan( 'editcontentmodel', $wgUser )
-                               || !$titleWithNewContentModel->userCan( 'edit', $wgUser )
+                       if ( !$titleWithNewContentModel->userCan( 'editcontentmodel', $user )
+                               || !$titleWithNewContentModel->userCan( 'edit', $user )
                        ) {
                                $status->setResult( false, self::AS_NO_CHANGE_CONTENT_MODEL );
                                return $status;
@@ -1884,7 +1881,7 @@ class EditPage {
 
                if ( $this->changeTags ) {
                        $changeTagsStatus = ChangeTags::canAddTagsAccompanyingChange(
-                               $this->changeTags, $wgUser );
+                               $this->changeTags, $user );
                        if ( !$changeTagsStatus->isOK() ) {
                                $changeTagsStatus->value = self::AS_CHANGE_TAG_ERROR;
                                return $changeTagsStatus;
@@ -1896,8 +1893,8 @@ class EditPage {
                        $status->value = self::AS_READ_ONLY_PAGE;
                        return $status;
                }
-               if ( $wgUser->pingLimiter() || $wgUser->pingLimiter( 'linkpurge', 0 )
-                       || ( $changingContentModel && $wgUser->pingLimiter( 'editcontentmodel' ) )
+               if ( $user->pingLimiter() || $user->pingLimiter( 'linkpurge', 0 )
+                       || ( $changingContentModel && $user->pingLimiter( 'editcontentmodel' ) )
                ) {
                        $status->fatal( 'actionthrottledtext' );
                        $status->value = self::AS_RATE_LIMITED;
@@ -1918,7 +1915,7 @@ class EditPage {
 
                if ( $new ) {
                        // Late check for create permission, just in case *PARANOIA*
-                       if ( !$this->mTitle->userCan( 'create', $wgUser ) ) {
+                       if ( !$this->mTitle->userCan( 'create', $user ) ) {
                                $status->fatal( 'nocreatetext' );
                                $status->value = self::AS_NO_CREATE_PERMISSION;
                                wfDebug( __METHOD__ . ": no create permission\n" );
@@ -1942,7 +1939,7 @@ class EditPage {
                                return $status;
                        }
 
-                       if ( !$this->runPostMergeFilters( $textbox_content, $status, $wgUser ) ) {
+                       if ( !$this->runPostMergeFilters( $textbox_content, $status, $user ) ) {
                                return $status;
                        }
 
@@ -1978,7 +1975,7 @@ class EditPage {
                        ) {
                                $this->isConflict = true;
                                if ( $this->section == 'new' ) {
-                                       if ( $this->page->getUserText() == $wgUser->getName() &&
+                                       if ( $this->page->getUserText() == $user->getName() &&
                                                $this->page->getComment() == $this->newSectionSummary()
                                        ) {
                                                // Probably a duplicate submission of a new comment.
@@ -1994,7 +1991,7 @@ class EditPage {
                                } elseif ( $this->section == ''
                                        && Revision::userWasLastToEdit(
                                                DB_MASTER, $this->mTitle->getArticleID(),
-                                               $wgUser->getId(), $this->edittime
+                                               $user->getId(), $this->edittime
                                        )
                                ) {
                                        # Suppress edit conflict with self, except for section edits where merging is required.
@@ -2064,7 +2061,7 @@ class EditPage {
                                return $status;
                        }
 
-                       if ( !$this->runPostMergeFilters( $content, $status, $wgUser ) ) {
+                       if ( !$this->runPostMergeFilters( $content, $status, $user ) ) {
                                return $status;
                        }
 
@@ -2085,7 +2082,7 @@ class EditPage {
                                        return $status;
                                }
                        } elseif ( !$this->allowBlankSummary
-                               && !$content->equals( $this->getOriginalContent( $wgUser ) )
+                               && !$content->equals( $this->getOriginalContent( $user ) )
                                && !$content->isRedirect()
                                && md5( $this->summary ) == $this->autoSumm
                        ) {
@@ -2155,7 +2152,7 @@ class EditPage {
                        $this->summary,
                        $flags,
                        false,
-                       $wgUser,
+                       $user,
                        $content->getDefaultFormat(),
                        $this->changeTags,
                        $this->undidRev
@@ -2179,7 +2176,7 @@ class EditPage {
                $result['nullEdit'] = $doEditStatus->hasMessage( 'edit-no-change' );
                if ( $result['nullEdit'] ) {
                        // We don't know if it was a null edit until now, so increment here
-                       $wgUser->pingLimiter( 'linkpurge' );
+                       $user->pingLimiter( 'linkpurge' );
                }
                $result['redirect'] = $content->isRedirect();
 
@@ -2188,7 +2185,7 @@ class EditPage {
                // If the content model changed, add a log entry
                if ( $changingContentModel ) {
                        $this->addContentModelChangeLogEntry(
-                               $wgUser,
+                               $user,
                                $new ? false : $oldContentModel,
                                $this->contentModel,
                                $this->summary
@@ -2222,13 +2219,11 @@ class EditPage {
         * Register the change of watch status
         */
        protected function updateWatchlist() {
-               global $wgUser;
-
-               if ( !$wgUser->isLoggedIn() ) {
+               $user = $this->context->getUser();
+               if ( !$user->isLoggedIn() ) {
                        return;
                }
 
-               $user = $wgUser;
                $title = $this->mTitle;
                $watch = $this->watchthis;
                // Do this in its own transaction to reduce contention...
@@ -2342,29 +2337,32 @@ class EditPage {
        }
 
        public function setHeaders() {
-               global $wgOut, $wgUser, $wgAjaxEditStash;
+               global $wgAjaxEditStash;
+
+               $out = $this->context->getOutput();
 
-               $wgOut->addModules( 'mediawiki.action.edit' );
-               $wgOut->addModuleStyles( 'mediawiki.action.edit.styles' );
+               $out->addModules( 'mediawiki.action.edit' );
+               $out->addModuleStyles( 'mediawiki.action.edit.styles' );
 
-               if ( $wgUser->getOption( 'showtoolbar' ) ) {
+               $user = $this->context->getUser();
+               if ( $user->getOption( 'showtoolbar' ) ) {
                        // The addition of default buttons is handled by getEditToolbar() which
                        // has its own dependency on this module. The call here ensures the module
                        // is loaded in time (it has position "top") for other modules to register
                        // buttons (e.g. extensions, gadgets, user scripts).
-                       $wgOut->addModules( 'mediawiki.toolbar' );
+                       $out->addModules( 'mediawiki.toolbar' );
                }
 
-               if ( $wgUser->getOption( 'uselivepreview' ) ) {
-                       $wgOut->addModules( 'mediawiki.action.edit.preview' );
+               if ( $user->getOption( 'uselivepreview' ) ) {
+                       $out->addModules( 'mediawiki.action.edit.preview' );
                }
 
-               if ( $wgUser->getOption( 'useeditwarning' ) ) {
-                       $wgOut->addModules( 'mediawiki.action.edit.editWarning' );
+               if ( $user->getOption( 'useeditwarning' ) ) {
+                       $out->addModules( 'mediawiki.action.edit.editWarning' );
                }
 
                # Enabled article-related sidebar, toplinks, etc.
-               $wgOut->setArticleRelated( true );
+               $out->setArticleRelated( true );
 
                $contextTitle = $this->getContextTitle();
                if ( $this->isConflict ) {
@@ -2387,10 +2385,10 @@ class EditPage {
                if ( $displayTitle === false ) {
                        $displayTitle = $contextTitle->getPrefixedText();
                }
-               $wgOut->setPageTitle( $this->context->msg( $msg, $displayTitle ) );
+               $out->setPageTitle( $this->context->msg( $msg, $displayTitle ) );
                # Transmit the name of the message to JavaScript for live preview
                # Keep Resources.php/mediawiki.action.edit.preview in sync with the possible keys
-               $wgOut->addJsConfigVars( [
+               $out->addJsConfigVars( [
                        'wgEditMessage' => $msg,
                        'wgAjaxEditStash' => $wgAjaxEditStash,
                ] );
@@ -2400,16 +2398,16 @@ class EditPage {
         * Show all applicable editing introductions
         */
        protected function showIntro() {
-               global $wgOut, $wgUser;
                if ( $this->suppressIntro ) {
                        return;
                }
 
+               $out = $this->context->getOutput();
                $namespace = $this->mTitle->getNamespace();
 
                if ( $namespace == NS_MEDIAWIKI ) {
                        # Show a warning if editing an interface message
-                       $wgOut->wrapWikiMsg( "<div class='mw-editinginterface'>\n$1\n</div>", 'editinginterface' );
+                       $out->wrapWikiMsg( "<div class='mw-editinginterface'>\n$1\n</div>", 'editinginterface' );
                        # If this is a default message (but not css or js),
                        # show a hint that it is translatable on translatewiki.net
                        if ( !$this->mTitle->hasContentModel( CONTENT_MODEL_CSS )
@@ -2417,7 +2415,7 @@ class EditPage {
                        ) {
                                $defaultMessageText = $this->mTitle->getDefaultMessageText();
                                if ( $defaultMessageText !== false ) {
-                                       $wgOut->wrapWikiMsg( "<div class='mw-translateinterface'>\n$1\n</div>",
+                                       $out->wrapWikiMsg( "<div class='mw-translateinterface'>\n$1\n</div>",
                                                'translateinterface' );
                                }
                        }
@@ -2429,11 +2427,11 @@ class EditPage {
                                # there must be a description url to show a hint to shared repo
                                if ( $descUrl ) {
                                        if ( !$this->mTitle->exists() ) {
-                                               $wgOut->wrapWikiMsg( "<div class=\"mw-sharedupload-desc-create\">\n$1\n</div>", [
+                                               $out->wrapWikiMsg( "<div class=\"mw-sharedupload-desc-create\">\n$1\n</div>", [
                                                                        'sharedupload-desc-create', $file->getRepo()->getDisplayName(), $descUrl
                                                ] );
                                        } else {
-                                               $wgOut->wrapWikiMsg( "<div class=\"mw-sharedupload-desc-edit\">\n$1\n</div>", [
+                                               $out->wrapWikiMsg( "<div class=\"mw-sharedupload-desc-edit\">\n$1\n</div>", [
                                                                        'sharedupload-desc-edit', $file->getRepo()->getDisplayName(), $descUrl
                                                ] );
                                        }
@@ -2449,12 +2447,12 @@ class EditPage {
                        $ip = User::isIP( $username );
                        $block = Block::newFromTarget( $user, $user );
                        if ( !( $user && $user->isLoggedIn() ) && !$ip ) { # User does not exist
-                               $wgOut->wrapWikiMsg( "<div class=\"mw-userpage-userdoesnotexist error\">\n$1\n</div>",
+                               $out->wrapWikiMsg( "<div class=\"mw-userpage-userdoesnotexist error\">\n$1\n</div>",
                                        [ 'userpage-userdoesnotexist', wfEscapeWikiText( $username ) ] );
                        } elseif ( !is_null( $block ) && $block->getType() != Block::TYPE_AUTO ) {
                                # Show log extract if the user is currently blocked
                                LogEventsList::showLogExtract(
-                                       $wgOut,
+                                       $out,
                                        'block',
                                        MWNamespace::getCanonicalName( NS_USER ) . ':' . $block->getTarget(),
                                        '',
@@ -2474,8 +2472,8 @@ class EditPage {
                        $helpLink = wfExpandUrl( Skin::makeInternalOrExternalUrl(
                                $this->context->msg( 'helppage' )->inContentLanguage()->text()
                        ) );
-                       if ( $wgUser->isLoggedIn() ) {
-                               $wgOut->wrapWikiMsg(
+                       if ( $this->context->getUser()->isLoggedIn() ) {
+                               $out->wrapWikiMsg(
                                        // Suppress the external link icon, consider the help url an internal one
                                        "<div class=\"mw-newarticletext plainlinks\">\n$1\n</div>",
                                        [
@@ -2484,7 +2482,7 @@ class EditPage {
                                        ]
                                );
                        } else {
-                               $wgOut->wrapWikiMsg(
+                               $out->wrapWikiMsg(
                                        // Suppress the external link icon, consider the help url an internal one
                                        "<div class=\"mw-newarticletextanon plainlinks\">\n$1\n</div>",
                                        [
@@ -2498,7 +2496,7 @@ class EditPage {
                if ( !$this->mTitle->exists() ) {
                        $dbr = wfGetDB( DB_REPLICA );
 
-                       LogEventsList::showLogExtract( $wgOut, [ 'delete', 'move' ], $this->mTitle,
+                       LogEventsList::showLogExtract( $out, [ 'delete', 'move' ], $this->mTitle,
                                '',
                                [
                                        'lim' => 10,
@@ -2519,9 +2517,8 @@ class EditPage {
                if ( $this->editintro ) {
                        $title = Title::newFromText( $this->editintro );
                        if ( $title instanceof Title && $title->exists() && $title->userCan( 'read' ) ) {
-                               global $wgOut;
                                // Added using template syntax, to take <noinclude>'s into account.
-                               $wgOut->addWikiTextTitleTidy(
+                               $this->context->getOutput()->addWikiTextTitleTidy(
                                        '<div class="mw-editintro">{{:' . $title->getFullText() . '}}</div>',
                                        $this->mTitle
                                );
@@ -2593,7 +2590,7 @@ class EditPage {
        }
 
        /**
-        * Send the edit form and related headers to $wgOut
+        * Send the edit form and related headers to OutputPage
         * @param callable|null $formCallback That takes an OutputPage parameter; will be called
         *     during form output near the top, for captchas and the like.
         *
@@ -2601,8 +2598,6 @@ class EditPage {
         * use the EditPage::showEditForm:fields hook instead.
         */
        public function showEditForm( $formCallback = null ) {
-               global $wgOut, $wgUser;
-
                # need to parse the preview early so that we know which templates are used,
                # otherwise users with "show preview after edit box" will get a blank list
                # we parse this near the beginning so that setHeaders can do the title
@@ -2612,9 +2607,11 @@ class EditPage {
                        $previewOutput = $this->getPreviewText();
                }
 
+               $out = $this->context->getOutput();
+
                // Avoid PHP 7.1 warning of passing $this by reference
                $editPage = $this;
-               Hooks::run( 'EditPage::showEditForm:initial', [ &$editPage, &$wgOut ] );
+               Hooks::run( 'EditPage::showEditForm:initial', [ &$editPage, &$out ] );
 
                $this->setHeaders();
 
@@ -2627,19 +2624,20 @@ class EditPage {
                        // We use $this->section to much before this and getVal('wgSection') directly in other places
                        // at this point we can't reset $this->section to '' to fallback to non-section editing.
                        // Someone is welcome to try refactoring though
-                       $wgOut->showErrorPage( 'sectioneditnotsupported-title', 'sectioneditnotsupported-text' );
+                       $out->showErrorPage( 'sectioneditnotsupported-title', 'sectioneditnotsupported-text' );
                        return;
                }
 
                $this->showHeader();
 
-               $wgOut->addHTML( $this->editFormPageTop );
+               $out->addHTML( $this->editFormPageTop );
 
-               if ( $wgUser->getOption( 'previewontop' ) ) {
+               $user = $this->context->getUser();
+               if ( $user->getOption( 'previewontop' ) ) {
                        $this->displayPreviewArea( $previewOutput, true );
                }
 
-               $wgOut->addHTML( $this->editFormTextTop );
+               $out->addHTML( $this->editFormTextTop );
 
                $showToolbar = true;
                if ( $this->wasDeletedSinceLastEdit() ) {
@@ -2648,14 +2646,14 @@ class EditPage {
                                // Add an confirmation checkbox and explanation.
                                $showToolbar = false;
                        } else {
-                               $wgOut->wrapWikiMsg( "<div class='error mw-deleted-while-editing'>\n$1\n</div>",
+                               $out->wrapWikiMsg( "<div class='error mw-deleted-while-editing'>\n$1\n</div>",
                                        'deletedwhileediting' );
                        }
                }
 
                // @todo add EditForm plugin interface and use it here!
                //       search for textarea1 and textarea2, and allow EditForm to override all uses.
-               $wgOut->addHTML( Html::openElement(
+               $out->addHTML( Html::openElement(
                        'form',
                        [
                                'class' => 'mw-editform',
@@ -2669,11 +2667,11 @@ class EditPage {
 
                if ( is_callable( $formCallback ) ) {
                        wfWarn( 'The $formCallback parameter to ' . __METHOD__ . 'is deprecated' );
-                       call_user_func_array( $formCallback, [ &$wgOut ] );
+                       call_user_func_array( $formCallback, [ &$out ] );
                }
 
                // Add an empty field to trip up spambots
-               $wgOut->addHTML(
+               $out->addHTML(
                        Xml::openElement( 'div', [ 'id' => 'antispam-container', 'style' => 'display: none;' ] )
                        . Html::rawElement(
                                'label',
@@ -2694,7 +2692,7 @@ class EditPage {
 
                // Avoid PHP 7.1 warning of passing $this by reference
                $editPage = $this;
-               Hooks::run( 'EditPage::showEditForm:fields', [ &$editPage, &$wgOut ] );
+               Hooks::run( 'EditPage::showEditForm:fields', [ &$editPage, &$out ] );
 
                // Put these up at the top to ensure they aren't lost on early form submission
                $this->showFormBeforeText();
@@ -2708,7 +2706,7 @@ class EditPage {
                        $key = $comment === ''
                                ? 'confirmrecreate-noreason'
                                : 'confirmrecreate';
-                       $wgOut->addHTML(
+                       $out->addHTML(
                                '<div class="mw-confirm-recreate">' .
                                        $this->context->msg( $key, $username, "<nowiki>$comment</nowiki>" )->parse() .
                                Xml::checkLabel( $this->context->msg( 'recreate' )->text(), 'wpRecreate', 'wpRecreate', false,
@@ -2720,7 +2718,7 @@ class EditPage {
 
                # When the summary is hidden, also hide them on preview/show changes
                if ( $this->nosummary ) {
-                       $wgOut->addHTML( Html::hidden( 'nosummary', true ) );
+                       $out->addHTML( Html::hidden( 'nosummary', true ) );
                }
 
                # If a blank edit summary was previously provided, and the appropriate
@@ -2731,15 +2729,15 @@ class EditPage {
                # For a bit more sophisticated detection of blank summaries, hash the
                # automatic one and pass that in the hidden field wpAutoSummary.
                if ( $this->missingSummary || ( $this->section == 'new' && $this->nosummary ) ) {
-                       $wgOut->addHTML( Html::hidden( 'wpIgnoreBlankSummary', true ) );
+                       $out->addHTML( Html::hidden( 'wpIgnoreBlankSummary', true ) );
                }
 
                if ( $this->undidRev ) {
-                       $wgOut->addHTML( Html::hidden( 'wpUndidRevision', $this->undidRev ) );
+                       $out->addHTML( Html::hidden( 'wpUndidRevision', $this->undidRev ) );
                }
 
                if ( $this->selfRedirect ) {
-                       $wgOut->addHTML( Html::hidden( 'wpIgnoreSelfRedirect', true ) );
+                       $out->addHTML( Html::hidden( 'wpIgnoreSelfRedirect', true ) );
                }
 
                if ( $this->hasPresetSummary ) {
@@ -2750,29 +2748,29 @@ class EditPage {
                }
 
                $autosumm = $this->autoSumm ? $this->autoSumm : md5( $this->summary );
-               $wgOut->addHTML( Html::hidden( 'wpAutoSummary', $autosumm ) );
+               $out->addHTML( Html::hidden( 'wpAutoSummary', $autosumm ) );
 
-               $wgOut->addHTML( Html::hidden( 'oldid', $this->oldid ) );
-               $wgOut->addHTML( Html::hidden( 'parentRevId', $this->getParentRevId() ) );
+               $out->addHTML( Html::hidden( 'oldid', $this->oldid ) );
+               $out->addHTML( Html::hidden( 'parentRevId', $this->getParentRevId() ) );
 
-               $wgOut->addHTML( Html::hidden( 'format', $this->contentFormat ) );
-               $wgOut->addHTML( Html::hidden( 'model', $this->contentModel ) );
+               $out->addHTML( Html::hidden( 'format', $this->contentFormat ) );
+               $out->addHTML( Html::hidden( 'model', $this->contentModel ) );
 
-               $wgOut->enableOOUI();
+               $out->enableOOUI();
 
                if ( $this->section == 'new' ) {
                        $this->showSummaryInput( true, $this->summary );
-                       $wgOut->addHTML( $this->getSummaryPreview( true, $this->summary ) );
+                       $out->addHTML( $this->getSummaryPreview( true, $this->summary ) );
                }
 
-               $wgOut->addHTML( $this->editFormTextBeforeContent );
+               $out->addHTML( $this->editFormTextBeforeContent );
 
-               if ( !$this->isCssJsSubpage && $showToolbar && $wgUser->getOption( 'showtoolbar' ) ) {
-                       $wgOut->addHTML( self::getEditToolbar( $this->mTitle ) );
+               if ( !$this->isCssJsSubpage && $showToolbar && $user->getOption( 'showtoolbar' ) ) {
+                       $out->addHTML( self::getEditToolbar( $this->mTitle ) );
                }
 
                if ( $this->blankArticle ) {
-                       $wgOut->addHTML( Html::hidden( 'wpIgnoreBlankArticle', true ) );
+                       $out->addHTML( Html::hidden( 'wpIgnoreBlankArticle', true ) );
                }
 
                if ( $this->isConflict ) {
@@ -2790,7 +2788,7 @@ class EditPage {
                        $this->showContentForm();
                }
 
-               $wgOut->addHTML( $this->editFormTextAfterContent );
+               $out->addHTML( $this->editFormTextAfterContent );
 
                $this->showStandardInputs();
 
@@ -2800,17 +2798,17 @@ class EditPage {
 
                $this->showEditTools();
 
-               $wgOut->addHTML( $this->editFormTextAfterTools . "\n" );
+               $out->addHTML( $this->editFormTextAfterTools . "\n" );
 
-               $wgOut->addHTML( $this->makeTemplatesOnThisPageList( $this->getTemplates() ) );
+               $out->addHTML( $this->makeTemplatesOnThisPageList( $this->getTemplates() ) );
 
-               $wgOut->addHTML( Html::rawElement( 'div', [ 'class' => 'hiddencats' ],
+               $out->addHTML( Html::rawElement( 'div', [ 'class' => 'hiddencats' ],
                        Linker::formatHiddenCategories( $this->page->getHiddenCategories() ) ) );
 
-               $wgOut->addHTML( Html::rawElement( 'div', [ 'class' => 'limitreport' ],
+               $out->addHTML( Html::rawElement( 'div', [ 'class' => 'limitreport' ],
                        self::getPreviewLimitReport( $this->mParserOutput ) ) );
 
-               $wgOut->addModules( 'mediawiki.action.edit.collapsibleFooter' );
+               $out->addModules( 'mediawiki.action.edit.collapsibleFooter' );
 
                if ( $this->isConflict ) {
                        try {
@@ -2823,7 +2821,7 @@ class EditPage {
                                        $this->contentFormat,
                                        $ex->getMessage()
                                );
-                               $wgOut->addWikiText( '<div class="error">' . $msg->text() . '</div>' );
+                               $out->addWikiText( '<div class="error">' . $msg->text() . '</div>' );
                        }
                }
 
@@ -2837,14 +2835,14 @@ class EditPage {
                } else {
                        $mode = 'text';
                }
-               $wgOut->addHTML( Html::hidden( 'mode', $mode, [ 'id' => 'mw-edit-mode' ] ) );
+               $out->addHTML( Html::hidden( 'mode', $mode, [ 'id' => 'mw-edit-mode' ] ) );
 
                // Marker for detecting truncated form data.  This must be the last
                // parameter sent in order to be of use, so do not move me.
-               $wgOut->addHTML( Html::hidden( 'wpUltimateParam', true ) );
-               $wgOut->addHTML( $this->editFormTextBottom . "\n</form>\n" );
+               $out->addHTML( Html::hidden( 'wpUltimateParam', true ) );
+               $out->addHTML( $this->editFormTextBottom . "\n</form>\n" );
 
-               if ( !$wgUser->getOption( 'previewontop' ) ) {
+               if ( !$user->getOption( 'previewontop' ) ) {
                        $this->displayPreviewArea( $previewOutput, false );
                }
        }
@@ -2891,11 +2889,12 @@ class EditPage {
        }
 
        protected function showHeader() {
-               global $wgOut, $wgUser;
                global $wgAllowUserCss, $wgAllowUserJs;
 
+               $out = $this->context->getOutput();
+               $user = $this->context->getUser();
                if ( $this->isConflict ) {
-                       $this->addExplainConflictHeader( $wgOut );
+                       $this->addExplainConflictHeader( $out );
                        $this->editRevId = $this->page->getLatest();
                } else {
                        if ( $this->section != '' && $this->section != 'new' ) {
@@ -2907,46 +2906,46 @@ class EditPage {
                                }
                        }
 
-                       $buttonLabel = $this->context->msg( $this->getSaveButtonLabel() )->text();
+                       $buttonLabel = $this->context->msg( $this->getSubmitButtonLabel() )->text();
 
                        if ( $this->missingComment ) {
-                               $wgOut->wrapWikiMsg( "<div id='mw-missingcommenttext'>\n$1\n</div>", 'missingcommenttext' );
+                               $out->wrapWikiMsg( "<div id='mw-missingcommenttext'>\n$1\n</div>", 'missingcommenttext' );
                        }
 
                        if ( $this->missingSummary && $this->section != 'new' ) {
-                               $wgOut->wrapWikiMsg(
+                               $out->wrapWikiMsg(
                                        "<div id='mw-missingsummary'>\n$1\n</div>",
                                        [ 'missingsummary', $buttonLabel ]
                                );
                        }
 
                        if ( $this->missingSummary && $this->section == 'new' ) {
-                               $wgOut->wrapWikiMsg(
+                               $out->wrapWikiMsg(
                                        "<div id='mw-missingcommentheader'>\n$1\n</div>",
                                        [ 'missingcommentheader', $buttonLabel ]
                                );
                        }
 
                        if ( $this->blankArticle ) {
-                               $wgOut->wrapWikiMsg(
+                               $out->wrapWikiMsg(
                                        "<div id='mw-blankarticle'>\n$1\n</div>",
                                        [ 'blankarticle', $buttonLabel ]
                                );
                        }
 
                        if ( $this->selfRedirect ) {
-                               $wgOut->wrapWikiMsg(
+                               $out->wrapWikiMsg(
                                        "<div id='mw-selfredirect'>\n$1\n</div>",
                                        [ 'selfredirect', $buttonLabel ]
                                );
                        }
 
                        if ( $this->hookError !== '' ) {
-                               $wgOut->addWikiText( $this->hookError );
+                               $out->addWikiText( $this->hookError );
                        }
 
                        if ( !$this->checkUnicodeCompliantBrowser() ) {
-                               $wgOut->addWikiMsg( 'nonunicodebrowser' );
+                               $out->addWikiMsg( 'nonunicodebrowser' );
                        }
 
                        if ( $this->section != 'new' ) {
@@ -2954,13 +2953,13 @@ class EditPage {
                                if ( $revision ) {
                                        // Let sysop know that this will make private content public if saved
 
-                                       if ( !$revision->userCan( Revision::DELETED_TEXT, $wgUser ) ) {
-                                               $wgOut->wrapWikiMsg(
+                                       if ( !$revision->userCan( Revision::DELETED_TEXT, $user ) ) {
+                                               $out->wrapWikiMsg(
                                                        "<div class='mw-warning plainlinks'>\n$1\n</div>\n",
                                                        'rev-deleted-text-permission'
                                                );
                                        } elseif ( $revision->isDeleted( Revision::DELETED_TEXT ) ) {
-                                               $wgOut->wrapWikiMsg(
+                                               $out->wrapWikiMsg(
                                                        "<div class='mw-warning plainlinks'>\n$1\n</div>\n",
                                                        'rev-deleted-text-view'
                                                );
@@ -2968,26 +2967,26 @@ class EditPage {
 
                                        if ( !$revision->isCurrent() ) {
                                                $this->mArticle->setOldSubtitle( $revision->getId() );
-                                               $wgOut->addWikiMsg( 'editingold' );
+                                               $out->addWikiMsg( 'editingold' );
                                                $this->isOldRev = true;
                                        }
                                } elseif ( $this->mTitle->exists() ) {
                                        // Something went wrong
 
-                                       $wgOut->wrapWikiMsg( "<div class='errorbox'>\n$1\n</div>\n",
+                                       $out->wrapWikiMsg( "<div class='errorbox'>\n$1\n</div>\n",
                                                [ 'missing-revision', $this->oldid ] );
                                }
                        }
                }
 
                if ( wfReadOnly() ) {
-                       $wgOut->wrapWikiMsg(
+                       $out->wrapWikiMsg(
                                "<div id=\"mw-read-only-warning\">\n$1\n</div>",
                                [ 'readonlywarning', wfReadOnlyReason() ]
                        );
-               } elseif ( $wgUser->isAnon() ) {
+               } elseif ( $user->isAnon() ) {
                        if ( $this->formtype != 'preview' ) {
-                               $wgOut->wrapWikiMsg(
+                               $out->wrapWikiMsg(
                                        "<div id='mw-anon-edit-warning' class='warningbox'>\n$1\n</div>",
                                        [ 'anoneditwarning',
                                                // Log-in link
@@ -3001,7 +3000,7 @@ class EditPage {
                                        ]
                                );
                        } else {
-                               $wgOut->wrapWikiMsg( "<div id=\"mw-anon-preview-warning\" class=\"warningbox\">\n$1</div>",
+                               $out->wrapWikiMsg( "<div id=\"mw-anon-preview-warning\" class=\"warningbox\">\n$1</div>",
                                        'anonpreviewwarning'
                                );
                        }
@@ -3009,25 +3008,25 @@ class EditPage {
                        if ( $this->isCssJsSubpage ) {
                                # Check the skin exists
                                if ( $this->isWrongCaseCssJsPage ) {
-                                       $wgOut->wrapWikiMsg(
+                                       $out->wrapWikiMsg(
                                                "<div class='error' id='mw-userinvalidcssjstitle'>\n$1\n</div>",
                                                [ 'userinvalidcssjstitle', $this->mTitle->getSkinFromCssJsSubpage() ]
                                        );
                                }
-                               if ( $this->getTitle()->isSubpageOf( $wgUser->getUserPage() ) ) {
-                                       $wgOut->wrapWikiMsg( '<div class="mw-usercssjspublic">$1</div>',
+                               if ( $this->getTitle()->isSubpageOf( $user->getUserPage() ) ) {
+                                       $out->wrapWikiMsg( '<div class="mw-usercssjspublic">$1</div>',
                                                $this->isCssSubpage ? 'usercssispublic' : 'userjsispublic'
                                        );
                                        if ( $this->formtype !== 'preview' ) {
                                                if ( $this->isCssSubpage && $wgAllowUserCss ) {
-                                                       $wgOut->wrapWikiMsg(
+                                                       $out->wrapWikiMsg(
                                                                "<div id='mw-usercssyoucanpreview'>\n$1\n</div>",
                                                                [ 'usercssyoucanpreview' ]
                                                        );
                                                }
 
                                                if ( $this->isJsSubpage && $wgAllowUserJs ) {
-                                                       $wgOut->wrapWikiMsg(
+                                                       $out->wrapWikiMsg(
                                                                "<div id='mw-userjsyoucanpreview'>\n$1\n</div>",
                                                                [ 'userjsyoucanpreview' ]
                                                        );
@@ -3064,9 +3063,51 @@ class EditPage {
                ];
        }
 
+       /**
+        * Standard summary input and label (wgSummary), abstracted so EditPage
+        * subclasses may reorganize the form.
+        * Note that you do not need to worry about the label's for=, it will be
+        * inferred by the id given to the input. You can remove them both by
+        * passing [ 'id' => false ] to $userInputAttrs.
+        *
+        * @deprecated since 1.30 Use getSummaryInputWidget() instead
+        * @param string $summary The value of the summary input
+        * @param string $labelText The html to place inside the label
+        * @param array $inputAttrs Array of attrs to use on the input
+        * @param array $spanLabelAttrs Array of attrs to use on the span inside the label
+        * @return array An array in the format [ $label, $input ]
+        */
+       public function getSummaryInput( $summary = "", $labelText = null,
+               $inputAttrs = null, $spanLabelAttrs = null
+       ) {
+               wfDeprecated( __METHOD__, '1.30' );
+               $inputAttrs = $this->getSummaryInputAttributes( $inputAttrs );
+               $inputAttrs += Linker::tooltipAndAccesskeyAttribs( 'summary' );
+
+               $spanLabelAttrs = ( is_array( $spanLabelAttrs ) ? $spanLabelAttrs : [] ) + [
+                       'class' => $this->missingSummary ? 'mw-summarymissed' : 'mw-summary',
+                       'id' => "wpSummaryLabel"
+               ];
+
+               $label = null;
+               if ( $labelText ) {
+                       $label = Xml::tags(
+                               'label',
+                               $inputAttrs['id'] ? [ 'for' => $inputAttrs['id'] ] : null,
+                               $labelText
+                       );
+                       $label = Xml::tags( 'span', $spanLabelAttrs, $label );
+               }
+
+               $input = Html::input( 'wpSummary', $summary, 'text', $inputAttrs );
+
+               return [ $label, $input ];
+       }
+
        /**
         * Builds a standard summary input with a label.
         *
+        * @deprecated since 1.30 Use getSummaryInputWidget() instead
         * @param string $summary The value of the summary input
         * @param string $labelText The html to place inside the label
         * @param array $inputAttrs Array of attrs to use on the input
@@ -3074,6 +3115,20 @@ class EditPage {
         * @return OOUI\FieldLayout OOUI FieldLayout with Label and Input
         */
        function getSummaryInputOOUI( $summary = "", $labelText = null, $inputAttrs = null ) {
+               wfDeprecated( __METHOD__, '1.30' );
+               $this->getSummaryInputWidget( $summary, $labelText, $inputAttrs );
+       }
+
+       /**
+        * Builds a standard summary input with a label.
+        *
+        * @param string $summary The value of the summary input
+        * @param string $labelText The html to place inside the label
+        * @param array $inputAttrs Array of attrs to use on the input
+        *
+        * @return OOUI\FieldLayout OOUI FieldLayout with Label and Input
+        */
+       function getSummaryInputWidget( $summary = "", $labelText = null, $inputAttrs = null ) {
                $inputAttrs = OOUI\Element::configFromHtmlAttributes(
                        $this->getSummaryInputAttributes( $inputAttrs )
                );
@@ -3107,8 +3162,6 @@ class EditPage {
         * @param string $summary The text of the summary to display
         */
        protected function showSummaryInput( $isSubjectPreview, $summary = "" ) {
-               global $wgOut;
-
                # Add a class if 'missingsummary' is triggered to allow styling of the summary line
                $summaryClass = $this->missingSummary ? 'mw-summarymissed' : 'mw-summary';
                if ( $isSubjectPreview ) {
@@ -3122,7 +3175,7 @@ class EditPage {
                }
 
                $labelText = $this->context->msg( $isSubjectPreview ? 'subject' : 'summary' )->parse();
-               $wgOut->addHTML( $this->getSummaryInputOOUI(
+               $this->context->getOutput()->addHTML( $this->getSummaryInputWidget(
                                $summary,
                                $labelText,
                                [ 'class' => $summaryClass ]
@@ -3159,21 +3212,19 @@ class EditPage {
        }
 
        protected function showFormBeforeText() {
-               global $wgOut;
-
-               $wgOut->addHTML( Html::hidden( 'wpSection', htmlspecialchars( $this->section ) ) );
-               $wgOut->addHTML( Html::hidden( 'wpStarttime', $this->starttime ) );
-               $wgOut->addHTML( Html::hidden( 'wpEdittime', $this->edittime ) );
-               $wgOut->addHTML( Html::hidden( 'editRevId', $this->editRevId ) );
-               $wgOut->addHTML( Html::hidden( 'wpScrolltop', $this->scrolltop ) );
+               $out = $this->context->getOutput();
+               $out->addHTML( Html::hidden( 'wpSection', htmlspecialchars( $this->section ) ) );
+               $out->addHTML( Html::hidden( 'wpStarttime', $this->starttime ) );
+               $out->addHTML( Html::hidden( 'wpEdittime', $this->edittime ) );
+               $out->addHTML( Html::hidden( 'editRevId', $this->editRevId ) );
+               $out->addHTML( Html::hidden( 'wpScrolltop', $this->scrolltop, [ 'id' => 'wpScrolltop' ] ) );
 
                if ( !$this->checkUnicodeCompliantBrowser() ) {
-                       $wgOut->addHTML( Html::hidden( 'safemode', '1' ) );
+                       $out->addHTML( Html::hidden( 'safemode', '1' ) );
                }
        }
 
        protected function showFormAfterText() {
-               global $wgOut, $wgUser;
                /**
                 * To make it harder for someone to slip a user a page
                 * which submits an edit form to the wiki without their
@@ -3186,7 +3237,11 @@ class EditPage {
                 * include the constant suffix to prevent editing from
                 * broken text-mangling proxies.
                 */
-               $wgOut->addHTML( "\n" . Html::hidden( "wpEditToken", $wgUser->getEditToken() ) . "\n" );
+               $this->context->getOutput()->addHTML(
+                       "\n" .
+                       Html::hidden( "wpEditToken", $this->context->getUser()->getEditToken() ) .
+                       "\n"
+               );
        }
 
        /**
@@ -3260,18 +3315,15 @@ class EditPage {
        }
 
        protected function showTextbox( $text, $name, $customAttribs = [] ) {
-               global $wgOut, $wgUser;
-
                $wikitext = $this->safeUnicodeOutput( $text );
                $wikitext = $this->addNewLineAtEnd( $wikitext );
 
-               $attribs = $this->buildTextboxAttribs( $name, $customAttribs, $wgUser );
+               $attribs = $this->buildTextboxAttribs( $name, $customAttribs, $this->context->getUser() );
 
-               $wgOut->addHTML( Html::textarea( $name, $wikitext, $attribs ) );
+               $this->context->getOutput()->addHTML( Html::textarea( $name, $wikitext, $attribs ) );
        }
 
        protected function displayPreviewArea( $previewOutput, $isOnTop = false ) {
-               global $wgOut;
                $classes = [];
                if ( $isOnTop ) {
                        $classes[] = 'ontop';
@@ -3283,7 +3335,8 @@ class EditPage {
                        $attribs['style'] = 'display: none;';
                }
 
-               $wgOut->addHTML( Xml::openElement( 'div', $attribs ) );
+               $out = $this->context->getOutput();
+               $out->addHTML( Xml::openElement( 'div', $attribs ) );
 
                if ( $this->formtype == 'preview' ) {
                        $this->showPreview( $previewOutput );
@@ -3292,10 +3345,10 @@ class EditPage {
                        $pageViewLang = $this->mTitle->getPageViewLanguage();
                        $attribs = [ 'lang' => $pageViewLang->getHtmlCode(), 'dir' => $pageViewLang->getDir(),
                                'class' => 'mw-content-' . $pageViewLang->getDir() ];
-                       $wgOut->addHTML( Html::rawElement( 'div', $attribs ) );
+                       $out->addHTML( Html::rawElement( 'div', $attribs ) );
                }
 
-               $wgOut->addHTML( '</div>' );
+               $out->addHTML( '</div>' );
 
                if ( $this->formtype == 'diff' ) {
                        try {
@@ -3307,26 +3360,26 @@ class EditPage {
                                        $this->contentFormat,
                                        $ex->getMessage()
                                );
-                               $wgOut->addWikiText( '<div class="error">' . $msg->text() . '</div>' );
+                               $out->addWikiText( '<div class="error">' . $msg->text() . '</div>' );
                        }
                }
        }
 
        /**
-        * Append preview output to $wgOut.
+        * Append preview output to OutputPage.
         * Includes category rendering if this is a category page.
         *
         * @param string $text The HTML to be output for the preview.
         */
        protected function showPreview( $text ) {
-               global $wgOut;
                if ( $this->mArticle instanceof CategoryPage ) {
                        $this->mArticle->openShowCategory();
                }
                # This hook seems slightly odd here, but makes things more
                # consistent for extensions.
-               Hooks::run( 'OutputPageBeforeHTML', [ &$wgOut, &$text ] );
-               $wgOut->addHTML( $text );
+               $out = $this->context->getOutput();
+               Hooks::run( 'OutputPageBeforeHTML', [ &$out, &$text ] );
+               $out->addHTML( $text );
                if ( $this->mArticle instanceof CategoryPage ) {
                        $this->mArticle->closeShowCategory();
                }
@@ -3340,7 +3393,7 @@ class EditPage {
         * save and then make a comparison.
         */
        public function showDiff() {
-               global $wgUser, $wgContLang, $wgOut;
+               global $wgContLang;
 
                $oldtitlemsg = 'currentrev';
                # if message does not exist, show diff against the preloaded default
@@ -3370,8 +3423,9 @@ class EditPage {
                if ( $newContent ) {
                        Hooks::run( 'EditPageGetDiffContent', [ $this, &$newContent ] );
 
-                       $popts = ParserOptions::newFromUserAndLang( $wgUser, $wgContLang );
-                       $newContent = $newContent->preSaveTransform( $this->mTitle, $wgUser, $popts );
+                       $user = $this->context->getUser();
+                       $popts = ParserOptions::newFromUserAndLang( $user, $wgContLang );
+                       $newContent = $newContent->preSaveTransform( $this->mTitle, $user, $popts );
                }
 
                if ( ( $oldContent && !$oldContent->isEmpty() ) || ( $newContent && !$newContent->isEmpty() ) ) {
@@ -3395,7 +3449,7 @@ class EditPage {
                        $difftext = '';
                }
 
-               $wgOut->addHTML( '<div id="wikiDiff">' . $difftext . '</div>' );
+               $this->context->getOutput()->addHTML( '<div id="wikiDiff">' . $difftext . '</div>' );
        }
 
        /**
@@ -3404,8 +3458,7 @@ class EditPage {
        protected function showHeaderCopyrightWarning() {
                $msg = 'editpage-head-copy-warn';
                if ( !$this->context->msg( $msg )->isDisabled() ) {
-                       global $wgOut;
-                       $wgOut->wrapWikiMsg( "<div class='editpage-head-copywarn'>\n$1\n</div>",
+                       $this->context->getOutput()->wrapWikiMsg( "<div class='editpage-head-copywarn'>\n$1\n</div>",
                                'editpage-head-copy-warn' );
                }
        }
@@ -3422,10 +3475,10 @@ class EditPage {
                $msg = 'editpage-tos-summary';
                Hooks::run( 'EditPageTosSummary', [ $this->mTitle, &$msg ] );
                if ( !$this->context->msg( $msg )->isDisabled() ) {
-                       global $wgOut;
-                       $wgOut->addHTML( '<div class="mw-tos-summary">' );
-                       $wgOut->addWikiMsg( $msg );
-                       $wgOut->addHTML( '</div>' );
+                       $out = $this->context->getOutput();
+                       $out->addHTML( '<div class="mw-tos-summary">' );
+                       $out->addWikiMsg( $msg );
+                       $out->addHTML( '</div>' );
                }
        }
 
@@ -3434,8 +3487,7 @@ class EditPage {
         * characters not present on most keyboards for copying/pasting.
         */
        protected function showEditTools() {
-               global $wgOut;
-               $wgOut->addHTML( '<div class="mw-editTools">' .
+               $this->context->getOutput()->addHTML( '<div class="mw-editTools">' .
                        $this->context->msg( 'edittools' )->inContentLanguage()->parse() .
                        '</div>' );
        }
@@ -3529,28 +3581,28 @@ class EditPage {
        }
 
        protected function showStandardInputs( &$tabindex = 2 ) {
-               global $wgOut;
-               $wgOut->addHTML( "<div class='editOptions'>\n" );
+               $out = $this->context->getOutput();
+               $out->addHTML( "<div class='editOptions'>\n" );
 
                if ( $this->section != 'new' ) {
                        $this->showSummaryInput( false, $this->summary );
-                       $wgOut->addHTML( $this->getSummaryPreview( false, $this->summary ) );
+                       $out->addHTML( $this->getSummaryPreview( false, $this->summary ) );
                }
 
-               $checkboxes = $this->getCheckboxesOOUI(
+               $checkboxes = $this->getCheckboxesWidget(
                        $tabindex,
                        [ 'minor' => $this->minoredit, 'watch' => $this->watchthis ]
                );
                $checkboxesHTML = new OOUI\HorizontalLayout( [ 'items' => $checkboxes ] );
 
-               $wgOut->addHTML( "<div class='editCheckboxes'>" . $checkboxesHTML . "</div>\n" );
+               $out->addHTML( "<div class='editCheckboxes'>" . $checkboxesHTML . "</div>\n" );
 
                // Show copyright warning.
-               $wgOut->addWikiText( $this->getCopywarn() );
-               $wgOut->addHTML( $this->editFormTextAfterWarn );
+               $out->addWikiText( $this->getCopywarn() );
+               $out->addHTML( $this->editFormTextAfterWarn );
 
-               $wgOut->addHTML( "<div class='editButtons'>\n" );
-               $wgOut->addHTML( implode( $this->getEditButtons( $tabindex ), "\n" ) . "\n" );
+               $out->addHTML( "<div class='editButtons'>\n" );
+               $out->addHTML( implode( $this->getEditButtons( $tabindex ), "\n" ) . "\n" );
 
                $cancel = $this->getCancelLink();
                if ( $cancel !== '' ) {
@@ -3570,13 +3622,13 @@ class EditPage {
                        $this->context->msg( 'word-separator' )->escaped() .
                        $this->context->msg( 'newwindow' )->parse();
 
-               $wgOut->addHTML( "      <span class='cancelLink'>{$cancel}</span>\n" );
-               $wgOut->addHTML( "      <span class='editHelp'>{$edithelp}</span>\n" );
-               $wgOut->addHTML( "</div><!-- editButtons -->\n" );
+               $out->addHTML( "        <span class='cancelLink'>{$cancel}</span>\n" );
+               $out->addHTML( "        <span class='editHelp'>{$edithelp}</span>\n" );
+               $out->addHTML( "</div><!-- editButtons -->\n" );
 
-               Hooks::run( 'EditPage::showStandardInputs:options', [ $this, $wgOut, &$tabindex ] );
+               Hooks::run( 'EditPage::showStandardInputs:options', [ $this, $out, &$tabindex ] );
 
-               $wgOut->addHTML( "</div><!-- editOptions -->\n" );
+               $out->addHTML( "</div><!-- editOptions -->\n" );
        }
 
        /**
@@ -3584,14 +3636,13 @@ class EditPage {
         * If you want to use another entry point to this function, be careful.
         */
        protected function showConflict() {
-               global $wgOut;
-
+               $out = $this->context->getOutput();
                // Avoid PHP 7.1 warning of passing $this by reference
                $editPage = $this;
-               if ( Hooks::run( 'EditPageBeforeConflictDiff', [ &$editPage, &$wgOut ] ) ) {
+               if ( Hooks::run( 'EditPageBeforeConflictDiff', [ &$editPage, &$out ] ) ) {
                        $this->incrementConflictStats();
 
-                       $wgOut->wrapWikiMsg( '<h2>$1</h2>', "yourdiff" );
+                       $out->wrapWikiMsg( '<h2>$1</h2>', "yourdiff" );
 
                        $content1 = $this->toEditContent( $this->textbox1 );
                        $content2 = $this->toEditContent( $this->textbox2 );
@@ -3604,7 +3655,7 @@ class EditPage {
                                $this->context->msg( 'storedversion' )->text()
                        );
 
-                       $wgOut->wrapWikiMsg( '<h2>$1</h2>', "yourtext" );
+                       $out->wrapWikiMsg( '<h2>$1</h2>', "yourtext" );
                        $this->showTextbox2();
                }
        }
@@ -3734,9 +3785,11 @@ class EditPage {
         * @return string
         */
        public function getPreviewText() {
-               global $wgOut, $wgRawHtml, $wgLang;
+               global $wgRawHtml;
                global $wgAllowUserCss, $wgAllowUserJs;
 
+               $out = $this->context->getOutput();
+
                if ( $wgRawHtml && !$this->mTokenOk ) {
                        // Could be an offsite preview attempt. This is very unsafe if
                        // HTML is enabled, as it could be an attack.
@@ -3745,7 +3798,7 @@ class EditPage {
                                // Do not put big scary notice, if previewing the empty
                                // string, which happens when you initially edit
                                // a category page, due to automatic preview-on-open.
-                               $parsedNote = $wgOut->parse( "<div class='previewnote'>" .
+                               $parsedNote = $out->parse( "<div class='previewnote'>" .
                                        $this->context->msg( 'session_fail_preview_html' )->text() . "</div>",
                                        true, /* interface */true );
                        }
@@ -3768,7 +3821,8 @@ class EditPage {
 
                        # provide a anchor link to the editform
                        $continueEditing = '<span class="mw-continue-editing">' .
-                               '[[#' . self::EDITFORM_ID . '|' . $wgLang->getArrow() . ' ' .
+                               '[[#' . self::EDITFORM_ID . '|' .
+                               $this->context->getLanguage()->getArrow() . ' ' .
                                $this->context->msg( 'continue-editing' )->text() . ']]</span>';
                        if ( $this->mTriedSave && !$this->mTokenOk ) {
                                if ( $this->mTokenOkExceptSuffix ) {
@@ -3833,7 +3887,7 @@ class EditPage {
                        $parserOutput = $parserResult['parserOutput'];
                        $previewHTML = $parserResult['html'];
                        $this->mParserOutput = $parserOutput;
-                       $wgOut->addParserOutputMetadata( $parserOutput );
+                       $out->addParserOutputMetadata( $parserOutput );
 
                        if ( count( $parserOutput->getWarnings() ) ) {
                                $note .= "\n\n" . implode( "\n\n", $parserOutput->getWarnings() );
@@ -3859,7 +3913,7 @@ class EditPage {
 
                $previewhead = "<div class='previewnote'>\n" .
                        '<h2 id="mw-previewheader">' . $this->context->msg( 'preview' )->escaped() . "</h2>" .
-                       $wgOut->parse( $note, true, /* interface */true ) . $conflict . "</div>\n";
+                       $out->parse( $note, true, /* interface */true ) . $conflict . "</div>\n";
 
                $pageViewLang = $this->mTitle->getPageViewLanguage();
                $attribs = [ 'lang' => $pageViewLang->getHtmlCode(), 'dir' => $pageViewLang->getDir(),
@@ -3896,11 +3950,11 @@ class EditPage {
         *   - html: The HTML to be displayed
         */
        protected function doPreviewParse( Content $content ) {
-               global $wgUser;
+               $user = $this->context->getUser();
                $parserOptions = $this->getPreviewParserOptions();
-               $pstContent = $content->preSaveTransform( $this->mTitle, $wgUser, $parserOptions );
+               $pstContent = $content->preSaveTransform( $this->mTitle, $user, $parserOptions );
                $scopedCallback = $parserOptions->setupFakeRevision(
-                       $this->mTitle, $pstContent, $wgUser );
+                       $this->mTitle, $pstContent, $user );
                $parserOutput = $pstContent->getParserOutput( $this->mTitle, null, $parserOptions );
                ScopedCallback::consume( $scopedCallback );
                $parserOutput->setEditSectionTokens( false ); // no section edit links
@@ -4087,11 +4141,11 @@ class EditPage {
         * @return array
         */
        public function getCheckboxesDefinition( $checked ) {
-               global $wgUser;
                $checkboxes = [];
 
+               $user = $this->context->getUser();
                // don't show the minor edit checkbox if it's a new page or section
-               if ( !$this->isNew && $wgUser->isAllowed( 'minoredit' ) ) {
+               if ( !$this->isNew && $user->isAllowed( 'minoredit' ) ) {
                        $checkboxes['wpMinoredit'] = [
                                'id' => 'wpMinoredit',
                                'label-message' => 'minoredit',
@@ -4103,7 +4157,7 @@ class EditPage {
                        ];
                }
 
-               if ( $wgUser->isLoggedIn() ) {
+               if ( $user->isLoggedIn() ) {
                        $checkboxes['wpWatchthis'] = [
                                'id' => 'wpWatchthis',
                                'label-message' => 'watchthis',
@@ -4125,13 +4179,12 @@ class EditPage {
         * Returns an array of html code of the following checkboxes old style:
         * minor and watch
         *
+        * @deprecated since 1.30 Use getCheckboxesWidget() or getCheckboxesDefinition() instead
         * @param int &$tabindex Current tabindex
         * @param array $checked See getCheckboxesDefinition()
         * @return array
         */
        public function getCheckboxes( &$tabindex, $checked ) {
-               global $wgUseMediaWikiUIEverywhere;
-
                $checkboxes = [];
                $checkboxesDef = $this->getCheckboxesDefinition( $checked );
 
@@ -4166,10 +4219,6 @@ class EditPage {
                                '&#160;' .
                                Xml::tags( 'label', $labelAttribs, $label );
 
-                       if ( $wgUseMediaWikiUIEverywhere ) {
-                               $checkboxHtml = Html::rawElement( 'div', [ 'class' => 'mw-ui-checkbox' ], $checkboxHtml );
-                       }
-
                        $checkboxes[ $legacyName ] = $checkboxHtml;
                }
 
@@ -4180,21 +4229,34 @@ class EditPage {
        }
 
        /**
-        * Returns an array of html code of the following checkboxes:
-        * minor and watch
+        * Returns an array of checkboxes for the edit form, including 'minor' and 'watch' checkboxes and
+        * any other added by extensions.
         *
+        * @deprecated since 1.30 Use getCheckboxesWidget() or getCheckboxesDefinition() instead
         * @param int &$tabindex Current tabindex
         * @param array $checked Array of checkbox => bool, where bool indicates the checked
         *                 status of the checkbox
         *
-        * @return array
+        * @return array Associative array of string keys to OOUI\FieldLayout instances
         */
        public function getCheckboxesOOUI( &$tabindex, $checked ) {
+               return $this->getCheckboxesWidget( $tabindex, $checked );
+       }
+
+       /**
+        * Returns an array of checkboxes for the edit form, including 'minor' and 'watch' checkboxes and
+        * any other added by extensions.
+        *
+        * @param int &$tabindex Current tabindex
+        * @param array $checked Array of checkbox => bool, where bool indicates the checked
+        *                 status of the checkbox
+        *
+        * @return array Associative array of string keys to OOUI\FieldLayout instances
+        */
+       public function getCheckboxesWidget( &$tabindex, $checked ) {
                $checkboxes = [];
                $checkboxesDef = $this->getCheckboxesDefinition( $checked );
 
-               $origTabindex = $tabindex;
-
                foreach ( $checkboxesDef as $name => $options ) {
                        $legacyName = isset( $options['legacy-name'] ) ? $options['legacy-name'] : $name;
 
@@ -4207,9 +4269,6 @@ class EditPage {
                        if ( isset( $options['title-message'] ) ) {
                                $title = $this->context->msg( $options['title-message'] )->text();
                        }
-                       if ( isset( $options['label-id'] ) ) {
-                               $labelAttribs['id'] = $options['label-id'];
-                       }
 
                        $checkboxes[ $legacyName ] = new OOUI\FieldLayout(
                                new OOUI\CheckboxInputWidget( [
@@ -4233,7 +4292,19 @@ class EditPage {
                // Backwards-compatibility hack to run the EditPageBeforeEditChecks hook. It's important,
                // people have used it for the weirdest things completely unrelated to checkboxes...
                // And if we're gonna run it, might as well allow its legacy checkboxes to be shown.
-               $legacyCheckboxes = $this->getCheckboxes( $origTabindex, $checked );
+               $legacyCheckboxes = [];
+               if ( !$this->isNew ) {
+                       $legacyCheckboxes['minor'] = '';
+               }
+               $legacyCheckboxes['watch'] = '';
+               // Copy new-style checkboxes into an old-style structure
+               foreach ( $checkboxes as $name => $oouiLayout ) {
+                       $legacyCheckboxes[$name] = (string)$oouiLayout;
+               }
+               // Avoid PHP 7.1 warning of passing $this by reference
+               $ep = $this;
+               Hooks::run( 'EditPageBeforeEditChecks', [ &$ep, &$legacyCheckboxes, &$tabindex ], '1.29' );
+               // Copy back any additional old-style checkboxes into the new-style structure
                foreach ( $legacyCheckboxes as $name => $html ) {
                        if ( $html && !isset( $checkboxes[$name] ) ) {
                                $checkboxes[$name] = new OOUI\Widget( [ 'content' => new OOUI\HtmlSnippet( $html ) ] );
@@ -4248,9 +4319,9 @@ class EditPage {
         *
         * @return string
         */
-       private function getSaveButtonLabel() {
+       protected function getSubmitButtonLabel() {
                $labelAsPublish =
-                       $this->mArticle->getContext()->getConfig()->get( 'EditSubmitButtonLabelPublish' );
+                       $this->context->getConfig()->get( 'EditSubmitButtonLabelPublish' );
 
                // Can't use $this->isNew as that's also true if we're adding a new section to an extant page
                $newPage = !$this->mTitle->exists();
@@ -4275,7 +4346,7 @@ class EditPage {
        public function getEditButtons( &$tabindex ) {
                $buttons = [];
 
-               $buttonLabel = $this->context->msg( $this->getSaveButtonLabel() )->text();
+               $buttonLabel = $this->context->msg( $this->getSubmitButtonLabel() )->text();
 
                $attribs = [
                        'name' => 'wpSave',
@@ -4344,18 +4415,17 @@ class EditPage {
         * they have attempted to edit a nonexistent section.
         */
        public function noSuchSectionPage() {
-               global $wgOut;
-
-               $wgOut->prepareErrorPage( $this->context->msg( 'nosuchsectiontitle' ) );
+               $out = $this->context->getOutput();
+               $out->prepareErrorPage( $this->context->msg( 'nosuchsectiontitle' ) );
 
                $res = $this->context->msg( 'nosuchsectiontext', $this->section )->parseAsBlock();
 
                // Avoid PHP 7.1 warning of passing $this by reference
                $editPage = $this;
                Hooks::run( 'EditPageNoSuchSection', [ &$editPage, &$res ] );
-               $wgOut->addHTML( $res );
+               $out->addHTML( $res );
 
-               $wgOut->returnToMain( false, $this->mTitle );
+               $out->returnToMain( false, $this->mTitle );
        }
 
        /**
@@ -4364,28 +4434,28 @@ class EditPage {
         * @param string|array|bool $match Text (or array of texts) which triggered one or more filters
         */
        public function spamPageWithContent( $match = false ) {
-               global $wgOut, $wgLang;
                $this->textbox2 = $this->textbox1;
 
                if ( is_array( $match ) ) {
-                       $match = $wgLang->listToText( $match );
+                       $match = $this->context->getLanguage()->listToText( $match );
                }
-               $wgOut->prepareErrorPage( $this->context->msg( 'spamprotectiontitle' ) );
+               $out = $this->context->getOutput();
+               $out->prepareErrorPage( $this->context->msg( 'spamprotectiontitle' ) );
 
-               $wgOut->addHTML( '<div id="spamprotected">' );
-               $wgOut->addWikiMsg( 'spamprotectiontext' );
+               $out->addHTML( '<div id="spamprotected">' );
+               $out->addWikiMsg( 'spamprotectiontext' );
                if ( $match ) {
-                       $wgOut->addWikiMsg( 'spamprotectionmatch', wfEscapeWikiText( $match ) );
+                       $out->addWikiMsg( 'spamprotectionmatch', wfEscapeWikiText( $match ) );
                }
-               $wgOut->addHTML( '</div>' );
+               $out->addHTML( '</div>' );
 
-               $wgOut->wrapWikiMsg( '<h2>$1</h2>', "yourdiff" );
+               $out->wrapWikiMsg( '<h2>$1</h2>', "yourdiff" );
                $this->showDiff();
 
-               $wgOut->wrapWikiMsg( '<h2>$1</h2>', "yourtext" );
+               $out->wrapWikiMsg( '<h2>$1</h2>', "yourtext" );
                $this->showTextbox2();
 
-               $wgOut->addReturnTo( $this->getContextTitle(), [ 'action' => 'edit' ] );
+               $out->addReturnTo( $this->getContextTitle(), [ 'action' => 'edit' ] );
        }
 
        /**
@@ -4526,15 +4596,14 @@ class EditPage {
         * @since 1.29
         */
        protected function addEditNotices() {
-               global $wgOut;
-
+               $out = $this->context->getOutput();
                $editNotices = $this->mTitle->getEditNotices( $this->oldid );
                if ( count( $editNotices ) ) {
-                       $wgOut->addHTML( implode( "\n", $editNotices ) );
+                       $out->addHTML( implode( "\n", $editNotices ) );
                } else {
                        $msg = $this->context->msg( 'editnotice-notext' );
                        if ( !$msg->isDisabled() ) {
-                               $wgOut->addHTML(
+                               $out->addHTML(
                                        '<div class="mw-editnotice-notext">'
                                        . $msg->parseAsBlock()
                                        . '</div>'
@@ -4547,10 +4616,8 @@ class EditPage {
         * @since 1.29
         */
        protected function addTalkPageText() {
-               global $wgOut;
-
                if ( $this->mTitle->isTalkPage() ) {
-                       $wgOut->addWikiMsg( 'talkpagetext' );
+                       $this->context->getOutput()->addWikiMsg( 'talkpagetext' );
                }
        }
 
@@ -4558,26 +4625,28 @@ class EditPage {
         * @since 1.29
         */
        protected function addLongPageWarningHeader() {
-               global $wgMaxArticleSize, $wgOut, $wgLang;
+               global $wgMaxArticleSize;
 
                if ( $this->contentLength === false ) {
                        $this->contentLength = strlen( $this->textbox1 );
                }
 
+               $out = $this->context->getOutput();
+               $lang = $this->context->getLanguage();
                if ( $this->tooBig || $this->contentLength > $wgMaxArticleSize * 1024 ) {
-                       $wgOut->wrapWikiMsg( "<div class='error' id='mw-edit-longpageerror'>\n$1\n</div>",
+                       $out->wrapWikiMsg( "<div class='error' id='mw-edit-longpageerror'>\n$1\n</div>",
                                [
                                        'longpageerror',
-                                       $wgLang->formatNum( round( $this->contentLength / 1024, 3 ) ),
-                                       $wgLang->formatNum( $wgMaxArticleSize )
+                                       $lang->formatNum( round( $this->contentLength / 1024, 3 ) ),
+                                       $lang->formatNum( $wgMaxArticleSize )
                                ]
                        );
                } else {
                        if ( !$this->context->msg( 'longpage-hint' )->isDisabled() ) {
-                               $wgOut->wrapWikiMsg( "<div id='mw-edit-longpage-hint'>\n$1\n</div>",
+                               $out->wrapWikiMsg( "<div id='mw-edit-longpage-hint'>\n$1\n</div>",
                                        [
                                                'longpage-hint',
-                                               $wgLang->formatSize( strlen( $this->textbox1 ) ),
+                                               $lang->formatSize( strlen( $this->textbox1 ) ),
                                                strlen( $this->textbox1 )
                                        ]
                                );
@@ -4589,8 +4658,7 @@ class EditPage {
         * @since 1.29
         */
        protected function addPageProtectionWarningHeaders() {
-               global $wgOut;
-
+               $out = $this->context->getOutput();
                if ( $this->mTitle->isProtected( 'edit' ) &&
                        MWNamespace::getRestrictionLevels( $this->mTitle->getNamespace() ) !== [ '' ]
                ) {
@@ -4601,7 +4669,7 @@ class EditPage {
                                # Then it must be protected based on static groups (regular)
                                $noticeMsg = 'protectedpagewarning';
                        }
-                       LogEventsList::showLogExtract( $wgOut, 'protect', $this->mTitle, '',
+                       LogEventsList::showLogExtract( $out, 'protect', $this->mTitle, '',
                                [ 'lim' => 1, 'msgKey' => [ $noticeMsg ] ] );
                }
                if ( $this->mTitle->isCascadeProtected() ) {
@@ -4617,10 +4685,10 @@ class EditPage {
                                }
                        }
                        $notice .= '</div>';
-                       $wgOut->wrapWikiMsg( $notice, [ 'cascadeprotectedwarning', $cascadeSourcesCount ] );
+                       $out->wrapWikiMsg( $notice, [ 'cascadeprotectedwarning', $cascadeSourcesCount ] );
                }
                if ( !$this->mTitle->exists() && $this->mTitle->getRestrictions( 'create' ) ) {
-                       LogEventsList::showLogExtract( $wgOut, 'protect', $this->mTitle, '',
+                       LogEventsList::showLogExtract( $out, 'protect', $this->mTitle, '',
                                [ 'lim' => 1,
                                        'showIfEmpty' => false,
                                        'msgKey' => [ 'titleprotectedwarning' ],
@@ -4635,7 +4703,7 @@ class EditPage {
        protected function addExplainConflictHeader( OutputPage $out ) {
                $out->wrapWikiMsg(
                        "<div class='mw-explainconflict'>\n$1\n</div>",
-                       [ 'explainconflict', $this->context->msg( $this->getSaveButtonLabel() )->text() ]
+                       [ 'explainconflict', $this->context->msg( $this->getSubmitButtonLabel() )->text() ]
                );
        }