Return to LESS multiple value escape mechanism to prevent invalid output
[lhc/web/wiklou.git] / includes / EditPage.php
index a79b974..4599564 100644 (file)
@@ -476,7 +476,15 @@ class EditPage {
                $this->mArticle = $article;
                $this->page = $article->getPage(); // model object
                $this->mTitle = $article->getTitle();
-               $this->context = $article->getContext();
+
+               // Make sure the local context is in sync with other member variables.
+               // Particularly make sure everything is using the same WikiPage instance.
+               // This should probably be the case in Article as well, but it's
+               // particularly important for EditPage, to make use of the in-place caching
+               // facility in WikiPage::prepareContentForEdit.
+               $this->context = new DerivativeContext( $article->getContext() );
+               $this->context->setWikiPage( $this->page );
+               $this->context->setTitle( $this->mTitle );
 
                $this->contentModel = $this->mTitle->getContentModel();
 
@@ -619,14 +627,23 @@ class EditPage {
                if ( $permErrors ) {
                        wfDebug( __METHOD__ . ": User can't edit\n" );
 
-                       // track block with a cookie if it doesn't exists already
-                       $this->context->getUser()->trackBlockWithCookie();
+                       if ( $this->context->getUser()->getBlock() ) {
+                               // track block with a cookie if it doesn't exists already
+                               $this->context->getUser()->trackBlockWithCookie();
 
-                       // Auto-block user's IP if the account was "hard" blocked
-                       if ( !wfReadOnly() ) {
-                               DeferredUpdates::addCallableUpdate( function () {
-                                       $this->context->getUser()->spreadAnyEditBlock();
-                               } );
+                               // Auto-block user's IP if the account was "hard" blocked
+                               if ( !wfReadOnly() ) {
+                                       DeferredUpdates::addCallableUpdate( function () {
+                                               $this->context->getUser()->spreadAnyEditBlock();
+                                       } );
+                               }
+
+                               $config = $this->context->getConfig();
+                               if ( $config->get( 'EnableBlockNoticeStats' ) ) {
+                                       $wiki = $config->get( 'DBname' );
+                                       $statsd = MediaWikiServices::getInstance()->getStatsdDataFactory();
+                                       $statsd->increment( 'BlockNotices.' . $wiki . '.WikitextEditor.shown' );
+                               }
                        }
                        $this->displayPermissionsError( $permErrors );
 
@@ -672,7 +689,7 @@ class EditPage {
                # that edit() already checked just in case someone tries to sneak
                # in the back door with a hand-edited submission URL.
 
-               if ( 'save' == $this->formtype ) {
+               if ( $this->formtype == 'save' ) {
                        $resultDetails = null;
                        $status = $this->attemptSave( $resultDetails );
                        if ( !$this->handleStatus( $status, $resultDetails ) ) {
@@ -682,7 +699,7 @@ class EditPage {
 
                # First time through: get contents, set time for conflict
                # checking, etc.
-               if ( 'initial' == $this->formtype || $this->firsttime ) {
+               if ( $this->formtype == 'initial' || $this->firsttime ) {
                        if ( $this->initialiseForm() === false ) {
                                $out = $this->context->getOutput();
                                if ( $out->getRedirect() === '' ) { // mcrundo hack redirects, don't override it
@@ -1302,8 +1319,12 @@ class EditPage {
                                        // Messages: undo-success, undo-failure, undo-main-slot-only, undo-norev,
                                        // undo-nochange.
                                        $class = ( $undoMsg == 'success' ? '' : 'error ' ) . "mw-undo-{$undoMsg}";
-                                       $this->editFormPageTop .= $out->parse( "<div class=\"{$class}\">" .
-                                               $this->context->msg( 'undo-' . $undoMsg )->plain() . '</div>', true, /* interface */true );
+                                       $this->editFormPageTop .= Html::rawElement(
+                                               'div', [ 'class' => $class ],
+                                               $out->parseAsInterface(
+                                                       $this->context->msg( 'undo-' . $undoMsg )->plain()
+                                               )
+                                       );
                                }
 
                                if ( $content === false ) {
@@ -1948,7 +1969,7 @@ ERROR;
                        return $status;
                }
 
-               if ( $user->isBlockedFrom( $this->mTitle, false ) ) {
+               if ( $user->isBlockedFrom( $this->mTitle ) ) {
                        // Auto-block user's IP if the account was "hard" blocked
                        if ( !wfReadOnly() ) {
                                $user->spreadAnyEditBlock();
@@ -2590,8 +2611,13 @@ ERROR;
                        if ( !( $user && $user->isLoggedIn() ) && !$ip ) { # User does not exist
                                $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
+                       } elseif (
+                               !is_null( $block ) &&
+                               $block->getType() != Block::TYPE_AUTO &&
+                               ( $block->isSitewide() || $user->isBlockedFrom( $this->mTitle ) )
+                       ) {
+                               // Show log extract if the user is sitewide blocked or is partially
+                               // blocked and not allowed to edit their user page or user talk page
                                LogEventsList::showLogExtract(
                                        $out,
                                        'block',
@@ -2837,7 +2863,7 @@ ERROR;
                // Put these up at the top to ensure they aren't lost on early form submission
                $this->showFormBeforeText();
 
-               if ( $this->wasDeletedSinceLastEdit() && 'save' == $this->formtype ) {
+               if ( $this->wasDeletedSinceLastEdit() && $this->formtype == 'save' ) {
                        $username = $this->lastDelete->user_name;
                        $comment = CommentStore::getStore()
                                ->getComment( 'log_comment', $this->lastDelete )->text;
@@ -3119,7 +3145,10 @@ ERROR;
 
                                        if ( !$revision->isCurrent() ) {
                                                $this->mArticle->setOldSubtitle( $revision->getId() );
-                                               $out->addWikiMsg( 'editingold' );
+                                               $out->wrapWikiMsg(
+                                                       Html::warningBox( "\n$1\n" ),
+                                                       'editingold'
+                                               );
                                                $this->isOldRev = true;
                                        }
                                } elseif ( $this->mTitle->exists() ) {
@@ -3138,16 +3167,22 @@ ERROR;
                        );
                } elseif ( $user->isAnon() ) {
                        if ( $this->formtype != 'preview' ) {
+                               $returntoquery = array_diff_key(
+                                       $this->context->getRequest()->getValues(),
+                                       [ 'title' => true, 'returnto' => true, 'returntoquery' => true ]
+                               );
                                $out->wrapWikiMsg(
                                        "<div id='mw-anon-edit-warning' class='warningbox'>\n$1\n</div>",
                                        [ 'anoneditwarning',
                                                // Log-in link
                                                SpecialPage::getTitleFor( 'Userlogin' )->getFullURL( [
-                                                       'returnto' => $this->getTitle()->getPrefixedDBkey()
+                                                       'returnto' => $this->getTitle()->getPrefixedDBkey(),
+                                                       'returntoquery' => wfArrayToCgi( $returntoquery ),
                                                ] ),
                                                // Sign-up link
                                                SpecialPage::getTitleFor( 'CreateAccount' )->getFullURL( [
-                                                       'returnto' => $this->getTitle()->getPrefixedDBkey()
+                                                       'returnto' => $this->getTitle()->getPrefixedDBkey(),
+                                                       'returntoquery' => wfArrayToCgi( $returntoquery ),
                                                ] )
                                        ]
                                );
@@ -3868,9 +3903,10 @@ ERROR;
                                // 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 = $out->parse( "<div class='previewnote'>" .
-                                       $this->context->msg( 'session_fail_preview_html' )->text() . "</div>",
-                                       true, /* interface */true );
+                               $parsedNote = Html::rawElement( 'div', [ 'class' => 'previewnote' ],
+                                       $out->parseAsInterface(
+                                               $this->context->msg( 'session_fail_preview_html' )->plain()
+                                       ) );
                        }
                        $this->incrementEditFailureStats( 'session_loss' );
                        return $parsedNote;
@@ -3945,7 +3981,7 @@ ERROR;
                                #   sitecsspreview, sitejsonpreview, sitejspreview
                                if ( $level && $format ) {
                                        $note = "<div id='mw-{$level}{$format}preview'>" .
-                                               $this->context->msg( "{$level}{$format}preview" )->text() .
+                                               $this->context->msg( "{$level}{$format}preview" )->plain() .
                                                ' ' . $continueEditing . "</div>";
                                }
                        }
@@ -3979,20 +4015,27 @@ ERROR;
                                $this->contentFormat,
                                $ex->getMessage()
                        );
-                       $note .= "\n\n" . $m->parse();
+                       $note .= "\n\n" . $m->plain(); # gets parsed down below
                        $previewHTML = '';
                }
 
                if ( $this->isConflict ) {
-                       $conflict = '<h2 id="mw-previewconflict">'
-                               . $this->context->msg( 'previewconflict' )->escaped() . "</h2>\n";
+                       $conflict = Html::rawElement(
+                               'h2', [ 'id' => 'mw-previewconflict' ],
+                               $this->context->msg( 'previewconflict' )->escaped()
+                       );
                } else {
                        $conflict = '<hr />';
                }
 
-               $previewhead = "<div class='previewnote'>\n" .
-                       '<h2 id="mw-previewheader">' . $this->context->msg( 'preview' )->escaped() . "</h2>" .
-                       $out->parse( $note, true, /* interface */true ) . $conflict . "</div>\n";
+               $previewhead = Html::rawElement(
+                       'div', [ 'class' => 'previewnote' ],
+                       Html::rawElement(
+                               'h2', [ 'id' => 'mw-previewheader' ],
+                               $this->context->msg( 'preview' )->escaped()
+                       ) .
+                       $out->parseAsInterface( $note ) . $conflict
+               );
 
                $pageViewLang = $this->mTitle->getPageViewLanguage();
                $attribs = [ 'lang' => $pageViewLang->getHtmlCode(), 'dir' => $pageViewLang->getDir(),