X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2FEditPage.php;h=d1f874ead7711d9bb64b2a41fce554eb848b2d42;hb=fe94275c8fcfc248a5eae857dde7c5772d993ab5;hp=2ae941f2455638edb99c5a091e17eea4b983fdea;hpb=b24fafd6066f8bffeb2b4c0b9e8e22d1b2f07cf2;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/EditPage.php b/includes/EditPage.php index 2ae941f245..f1f0572bac 100644 --- a/includes/EditPage.php +++ b/includes/EditPage.php @@ -236,7 +236,7 @@ class EditPage { public $action = 'submit'; /** @var bool Whether an edit conflict needs to be resolved. Detected based on whether - * $editRevId is different from the current revision. When a conflict has successfully + * $editRevId is different than the latest revision. When a conflict has successfully * been resolved by a 3-way-merge, this field is set to false. */ public $isConflict = false; @@ -250,7 +250,10 @@ class EditPage { /** @var string */ public $formtype; - /** @var bool */ + /** @var bool + * True the first time the edit form is rendered, false after re-rendering + * with diff, save prompts, etc. + */ public $firsttime; /** @var bool|stdClass */ @@ -330,7 +333,9 @@ class EditPage { /** @var bool */ public $recreate = false; - /** @var string */ + /** @var string + * Page content input field. + */ public $textbox1 = ''; /** @var string */ @@ -339,18 +344,24 @@ class EditPage { /** @var string */ public $summary = ''; - /** @var bool */ + /** @var bool + * If true, hide the summary field. + */ public $nosummary = false; - /** @var string */ + /** @var string + * Timestamp of the latest revision of the page when editing was initiated + * on the client. + */ public $edittime = ''; - /** @var int ID of the current revision at the time editing was initiated on the client. - * This is used to detect and resolve edit conflicts. + /** @var int Revision ID of the latest revision of the page when editing + * was initiated on the client. This is used to detect and resolve edit + * conflicts. * * @note 0 if the page did not exist at that time. * @note When starting an edit from an old revision, this still records the current - * revision at the time , not the one the edit is based on. + * revision at the time, not the one the edit is based on. * * @see $oldid * @see getBaseRevision() @@ -363,10 +374,14 @@ class EditPage { /** @var string */ public $sectiontitle = ''; - /** @var string */ + /** @var string + * Timestamp from the first time the edit form was rendered. + */ public $starttime = ''; /** @var int Revision ID the edit is based on, or 0 if it's the current revision. + * FIXME: This isn't used in conflict resolution--provide a better + * justification or merge with parentRevId. * @see $editRevId */ public $oldid = 0; @@ -648,7 +663,7 @@ class EditPage { $this->isConflict = false; # Show applicable editing introductions - if ( $this->formtype === 'initial' || $this->firsttime ) { + if ( $this->formtype == 'initial' || $this->firsttime ) { $this->showIntro(); } @@ -657,7 +672,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 ( 'save' == $this->formtype ) { $resultDetails = null; $status = $this->attemptSave( $resultDetails ); if ( !$this->handleStatus( $status, $resultDetails ) ) { @@ -667,9 +682,12 @@ class EditPage { # First time through: get contents, set time for conflict # checking, etc. - if ( 'initial' === $this->formtype || $this->firsttime ) { + if ( 'initial' == $this->formtype || $this->firsttime ) { if ( $this->initialiseForm() === false ) { - $this->noSuchSectionPage(); + $out = $this->context->getOutput(); + if ( $out->getRedirect() === '' ) { // mcrundo hack redirects, don't override it + $this->noSuchSectionPage(); + } return; } @@ -706,9 +724,9 @@ class EditPage { foreach ( $permErrors as $error ) { if ( ( $this->preview || $this->diff ) && ( - $error[0] === 'blockedtext' || - $error[0] === 'autoblockedtext' || - $error[0] === 'systemblockedtext' + $error[0] == 'blockedtext' || + $error[0] == 'autoblockedtext' || + $error[0] == 'systemblockedtext' ) ) { $remove[] = $error; @@ -825,13 +843,13 @@ class EditPage { // security reasons return false; } - if ( $request->getVal( 'preview' ) === 'yes' ) { + if ( $request->getVal( 'preview' ) == 'yes' ) { // Explicit override from request return true; - } elseif ( $request->getVal( 'preview' ) === 'no' ) { + } elseif ( $request->getVal( 'preview' ) == 'no' ) { // Explicit override from request return false; - } elseif ( $this->section === 'new' ) { + } elseif ( $this->section == 'new' ) { // Nothing *to* preview for new sections return false; } elseif ( ( $request->getVal( 'preload' ) !== null || $this->mTitle->exists() ) @@ -895,7 +913,7 @@ class EditPage { throw new ErrorPageError( 'sectioneditnotsupported-title', 'sectioneditnotsupported-text' ); } - $this->isNew = !$this->mTitle->exists() || $this->section === 'new'; + $this->isNew = !$this->mTitle->exists() || $this->section == 'new'; if ( $request->wasPosted() ) { # These fields need to be checked for encoding. @@ -995,8 +1013,8 @@ class EditPage { $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() === $user->getName() + if ( ( $this->mTitle->mNamespace == NS_USER || $this->mTitle->mNamespace == NS_USER_TALK ) + && $this->mTitle->getText() == $user->getName() ) { $this->allowBlankSummary = true; } else { @@ -1036,11 +1054,11 @@ class EditPage { // When creating a new section, we can preload a section title by passing it as the // preloadtitle parameter in the URL (T15100) - if ( $this->section === 'new' && $request->getVal( 'preloadtitle' ) ) { + if ( $this->section == 'new' && $request->getVal( 'preloadtitle' ) ) { $this->sectiontitle = $request->getVal( 'preloadtitle' ); // Once wpSummary isn't being use for setting section titles, we should delete this. $this->summary = $request->getVal( 'preloadtitle' ); - } elseif ( $this->section !== 'new' && $request->getVal( 'summary' ) ) { + } elseif ( $this->section != 'new' && $request->getVal( 'summary' ) !== '' ) { $this->summary = $request->getText( 'summary' ); if ( $this->summary !== '' ) { $this->hasPresetSummary = true; @@ -1156,16 +1174,14 @@ class EditPage { * @since 1.21 */ protected function getContentObject( $def_content = null ) { - global $wgContLang; - $content = false; $user = $this->context->getUser(); $request = $this->context->getRequest(); // 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' ) { - if ( $this->mTitle->getNamespace() === NS_MEDIAWIKI && $this->section !== 'new' ) { + if ( !$this->mTitle->exists() || $this->section == 'new' ) { + if ( $this->mTitle->getNamespace() == NS_MEDIAWIKI && $this->section != 'new' ) { # If this is a system message, get the default text. $msg = $this->mTitle->getDefaultMessageText(); @@ -1207,8 +1223,13 @@ class EditPage { !$oldrev->isDeleted( Revision::DELETED_TEXT ) ) { if ( WikiPage::hasDifferencesOutsideMainSlot( $undorev, $oldrev ) ) { - // Cannot yet undo edits that involve anything other the main slot. - $undoMsg = 'main-slot-only'; + // Hack for undo while EditPage can't handle multi-slot editing + $this->context->getOutput()->redirect( $this->mTitle->getFullURL( [ + 'action' => 'mcrundo', + 'undo' => $undo, + 'undoafter' => $undoafter, + ] ) ); + return false; } else { $content = $this->page->getUndoContent( $undorev, $oldrev ); @@ -1220,7 +1241,8 @@ class EditPage { if ( $undoMsg === null ) { $oldContent = $this->page->getContent( Revision::RAW ); - $popts = ParserOptions::newFromUserAndLang( $user, $wgContLang ); + $popts = ParserOptions::newFromUserAndLang( + $user, MediaWikiServices::getInstance()->getContentLanguage() ); $newContent = $content->preSaveTransform( $this->mTitle, $user, $popts ); if ( $newContent->getModel() !== $oldContent->getModel() ) { // The undo may change content @@ -1242,7 +1264,7 @@ class EditPage { # If we just undid one rev, use an autosummary $firstrev = $oldrev->getNext(); - if ( $firstrev && $firstrev->getId() === $undo ) { + if ( $firstrev && $firstrev->getId() == $undo ) { $userText = $undorev->getUserText(); if ( $userText === '' ) { $undoSummary = $this->context->msg( @@ -1277,7 +1299,7 @@ class EditPage { $out = $this->context->getOutput(); // Messages: undo-success, undo-failure, undo-main-slot-only, undo-norev, // undo-nochange. - $class = ( $undoMsg === 'success' ? '' : 'error ' ) . "mw-undo-{$undoMsg}"; + $class = ( $undoMsg == 'success' ? '' : 'error ' ) . "mw-undo-{$undoMsg}"; $this->editFormPageTop .= $out->parse( "
" . $this->context->msg( 'undo-' . $undoMsg )->plain() . '
', true, /* interface */true ); } @@ -1307,7 +1329,7 @@ class EditPage { * @return Content|null */ private function getOriginalContent( User $user ) { - if ( $this->section === 'new' ) { + if ( $this->section == 'new' ) { return $this->getCurrentContent(); } $revision = $this->mArticle->getRevisionFetched(); @@ -1498,7 +1520,7 @@ class EditPage { $postEditKey = self::POST_EDIT_COOKIE_KEY_PREFIX . $revisionId; $val = 'saved'; - if ( $statusValue === self::AS_SUCCESS_NEW_ARTICLE ) { + if ( $statusValue == self::AS_SUCCESS_NEW_ARTICLE ) { $val = 'created'; } elseif ( $this->oldid ) { $val = 'restored'; @@ -1553,8 +1575,8 @@ class EditPage { * @todo FIXME: once the interface for internalAttemptSave() is made * nicer, this should use the message in $status */ - if ( $status->value === self::AS_SUCCESS_UPDATE - || $status->value === self::AS_SUCCESS_NEW_ARTICLE + if ( $status->value == self::AS_SUCCESS_UPDATE + || $status->value == self::AS_SUCCESS_NEW_ARTICLE ) { $this->incrementResolvedConflicts(); @@ -1617,7 +1639,7 @@ class EditPage { ); if ( $resultDetails['redirect'] ) { - if ( $extraQuery === '' ) { + if ( $extraQuery == '' ) { $extraQuery = 'redirect=no'; } else { $extraQuery = 'redirect=no&' . $extraQuery; @@ -1667,7 +1689,7 @@ class EditPage { // is if an extension hook aborted from inside ArticleSave. // Render the status object into $this->hookError // FIXME this sucks, we should just use the Status object throughout - $this->hookError = '
' ."\n" . $status->getWikiText() . + $this->hookError = '
' . "\n" . $status->getWikiText() . '
'; return true; } @@ -1684,7 +1706,7 @@ class EditPage { */ protected function runPostMergeFilters( Content $content, Status $status, User $user ) { // Run old style post-section-merge edit filter - if ( $this->hookError !== '' ) { + if ( $this->hookError != '' ) { # ...or the hook could be expecting us to produce an error $status->fatal( 'hookaborted' ); $status->value = self::AS_HOOK_ERROR_EXPECTED; @@ -1760,7 +1782,7 @@ ERROR; if ( $this->summary === '' ) { $cleanSectionTitle = $wgParser->stripSectionName( $this->sectiontitle ); return $this->context->msg( 'newsectionsummary' ) - ->rawParams( $cleanSectionTitle )->inContentLanguage()->text(); + ->plaintextParams( $cleanSectionTitle )->inContentLanguage()->text(); } } elseif ( $this->summary !== '' ) { $sectionanchor = $this->guessSectionName( $this->summary ); @@ -1768,7 +1790,7 @@ ERROR; # in the revision summary. $cleanSummary = $wgParser->stripSectionName( $this->summary ); return $this->context->msg( 'newsectionsummary' ) - ->rawParams( $cleanSummary )->inContentLanguage()->text(); + ->plaintextParams( $cleanSummary )->inContentLanguage()->text(); } return $this->summary; } @@ -1846,7 +1868,7 @@ ERROR; } # Check image redirect - if ( $this->mTitle->getNamespace() === NS_FILE && + if ( $this->mTitle->getNamespace() == NS_FILE && $textbox_content->isRedirect() && !$user->isAllowed( 'upload' ) ) { @@ -1858,7 +1880,7 @@ ERROR; # Check for spam $match = self::matchSummarySpamRegex( $this->summary ); - if ( $match === false && $this->section === 'new' ) { + if ( $match === false && $this->section == 'new' ) { # $wgSpamRegex is enforced on this new heading/summary because, unlike # regular summaries, it is added to the actual wikitext. if ( $this->sectiontitle !== '' ) { @@ -1891,7 +1913,7 @@ ERROR; $status->fatal( 'hookaborted' ); $status->value = self::AS_HOOK_ERROR; return $status; - } elseif ( $this->hookError !== '' ) { + } elseif ( $this->hookError != '' ) { # ...or the hook could be expecting us to produce an error $status->fatal( 'hookaborted' ); $status->value = self::AS_HOOK_ERROR_EXPECTED; @@ -2020,7 +2042,7 @@ ERROR; $content = $textbox_content; $result['sectionanchor'] = ''; - if ( $this->section === 'new' ) { + if ( $this->section == 'new' ) { if ( $this->sectiontitle !== '' ) { // Insert the section title above the content. $content = $content->addSectionHeader( $this->sectiontitle ); @@ -2047,13 +2069,13 @@ ERROR; // revision that was current when editing was initiated on the client. // This is checked based on the timestamp and revision ID. // TODO: the timestamp based check can probably go away now. - if ( $timestamp !== $this->edittime - || ( $this->editRevId !== null && $this->editRevId !== $latest ) + if ( $timestamp != $this->edittime + || ( $this->editRevId !== null && $this->editRevId != $latest ) ) { $this->isConflict = true; - if ( $this->section === 'new' ) { - if ( $this->page->getUserText() === $user->getName() && - $this->page->getComment() === $this->newSectionSummary() + if ( $this->section == 'new' ) { + if ( $this->page->getUserText() == $user->getName() && + $this->page->getComment() == $this->newSectionSummary() ) { // Probably a duplicate submission of a new comment. // This can happen when CDN resends a request after @@ -2142,9 +2164,9 @@ ERROR; return $status; } - if ( $this->section === 'new' ) { + if ( $this->section == 'new' ) { // Handle the user preference to force summaries here - if ( !$this->allowBlankSummary && trim( $this->summary ) === '' ) { + if ( !$this->allowBlankSummary && trim( $this->summary ) == '' ) { $this->missingSummary = true; $status->fatal( 'missingsummary' ); // or 'missingcommentheader' if $section == 'new'. Blegh $status->value = self::AS_SUMMARY_NEEDED; @@ -2152,7 +2174,7 @@ ERROR; } // Do not allow the user to post an empty comment - if ( $this->textbox1 === '' ) { + if ( $this->textbox1 == '' ) { $this->missingComment = true; $status->fatal( 'missingcommenttext' ); $status->value = self::AS_TEXTBOX_EMPTY; @@ -2161,7 +2183,7 @@ ERROR; } elseif ( !$this->allowBlankSummary && !$content->equals( $this->getOriginalContent( $user ) ) && !$content->isRedirect() - && md5( $this->summary ) === $this->autoSumm + && md5( $this->summary ) == $this->autoSumm ) { $this->missingSummary = true; $status->fatal( 'missingsummary' ); @@ -2171,9 +2193,9 @@ ERROR; # All's well $sectionanchor = ''; - if ( $this->section === 'new' ) { + if ( $this->section == 'new' ) { $this->summary = $this->newSectionSummary( $sectionanchor ); - } elseif ( $this->section !== '' ) { + } elseif ( $this->section != '' ) { # Try to get a section anchor from the section source, redirect # to edited section if header found. # XXX: Might be better to integrate this into Article::replaceSectionAtRev @@ -2305,7 +2327,7 @@ ERROR; $watch = $this->watchthis; // Do this in its own transaction to reduce contention... DeferredUpdates::addCallableUpdate( function () use ( $user, $title, $watch ) { - if ( $watch === $user->isWatched( $title, User::IGNORE_USER_RIGHTS ) ) { + if ( $watch == $user->isWatched( $title, User::IGNORE_USER_RIGHTS ) ) { return; // nothing to change } WatchAction::doWatchOrUnwatch( $watch, $title, $user ); @@ -2361,7 +2383,7 @@ ERROR; * Returns the revision that was current at the time editing was initiated on the client, * even if the edit was based on an old revision. * - * @warning: this method is very poorly named. If the user opened the form with ?oldid=X, + * @warning this method is very poorly named. If the user opened the form with ?oldid=X, * one might think of X as the "base revision", which is NOT what this returns, * see oldid for that. One might further assume that this corresponds to the $baseRevId * parameter of WikiPage::doEditContent, which is not the case either. @@ -2451,11 +2473,11 @@ ERROR; $contextTitle = $this->getContextTitle(); if ( $this->isConflict ) { $msg = 'editconflict'; - } elseif ( $contextTitle->exists() && $this->section !== '' ) { - $msg = $this->section === 'new' ? 'editingcomment' : 'editingsection'; + } elseif ( $contextTitle->exists() && $this->section != '' ) { + $msg = $this->section == 'new' ? 'editingcomment' : 'editingsection'; } else { $msg = $contextTitle->exists() - || ( $contextTitle->getNamespace() === NS_MEDIAWIKI + || ( $contextTitle->getNamespace() == NS_MEDIAWIKI && $contextTitle->getDefaultMessageText() !== false ) ? 'editing' @@ -2468,6 +2490,8 @@ ERROR; $displayTitle = isset( $this->mParserOutput ) ? $this->mParserOutput->getDisplayTitle() : false; if ( $displayTitle === false ) { $displayTitle = $contextTitle->getPrefixedText(); + } else { + $out->setDisplayTitle( $displayTitle ); } $out->setPageTitle( $this->context->msg( $msg, $displayTitle ) ); @@ -2499,7 +2523,7 @@ ERROR; $out = $this->context->getOutput(); $namespace = $this->mTitle->getNamespace(); - if ( $namespace === NS_MEDIAWIKI ) { + if ( $namespace == NS_MEDIAWIKI ) { # Show a warning if editing an interface message $out->wrapWikiMsg( "
\n$1\n
", 'editinginterface' ); # If this is a default message (but not css, json, or js), @@ -2515,7 +2539,7 @@ ERROR; 'translateinterface' ); } } - } elseif ( $namespace === NS_FILE ) { + } elseif ( $namespace == NS_FILE ) { # Show a hint to shared repo $file = wfFindFile( $this->mTitle ); if ( $file && !$file->isLocal() ) { @@ -2537,7 +2561,7 @@ ERROR; # Show a warning message when someone creates/edits a user (talk) page but the user does not exist # Show log extract when the user is currently blocked - if ( $namespace === NS_USER || $namespace === NS_USER_TALK ) { + if ( $namespace == NS_USER || $namespace == NS_USER_TALK ) { $username = explode( '/', $this->mTitle->getText(), 2 )[0]; $user = User::newFromName( $username, false /* allow IP users */ ); $ip = User::isIP( $username ); @@ -2545,7 +2569,7 @@ ERROR; if ( !( $user && $user->isLoggedIn() ) && !$ip ) { # User does not exist $out->wrapWikiMsg( "
\n$1\n
", [ 'userpage-userdoesnotexist', wfEscapeWikiText( $username ) ] ); - } elseif ( !is_null( $block ) && $block->getType() !== Block::TYPE_AUTO ) { + } elseif ( !is_null( $block ) && $block->getType() != Block::TYPE_AUTO ) { # Show log extract if the user is currently blocked LogEventsList::showLogExtract( $out, @@ -2699,7 +2723,7 @@ ERROR; # we parse this near the beginning so that setHeaders can do the title # setting work instead of leaving it in getPreviewText $previewOutput = ''; - if ( $this->formtype === 'preview' ) { + if ( $this->formtype == 'preview' ) { $previewOutput = $this->getPreviewText(); } @@ -2715,7 +2739,7 @@ ERROR; $this->addEditNotices(); if ( !$this->isConflict && - $this->section !== '' && + $this->section != '' && !$this->isSectionEditSupported() ) { // 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. @@ -2737,7 +2761,7 @@ ERROR; $showToolbar = true; if ( $this->wasDeletedSinceLastEdit() ) { - if ( $this->formtype === 'save' ) { + if ( $this->formtype == 'save' ) { // Hide the toolbar and edit area, user can click preview to get it back // Add an confirmation checkbox and explanation. $showToolbar = false; @@ -2796,7 +2820,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() && 'save' == $this->formtype ) { $username = $this->lastDelete->user_name; $comment = CommentStore::getStore() ->getComment( 'log_comment', $this->lastDelete )->text; @@ -2828,7 +2852,7 @@ ERROR; # #### # 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 ) ) { + if ( $this->missingSummary || ( $this->section == 'new' && $this->nosummary ) ) { $out->addHTML( Html::hidden( 'wpIgnoreBlankSummary', true ) ); } @@ -2847,7 +2871,7 @@ ERROR; $this->autoSumm = md5( '' ); } - $autosumm = $this->autoSumm ?: md5( $this->summary ); + $autosumm = $this->autoSumm !== '' ? $this->autoSumm : md5( $this->summary ); $out->addHTML( Html::hidden( 'wpAutoSummary', $autosumm ) ); $out->addHTML( Html::hidden( 'oldid', $this->oldid ) ); @@ -2858,7 +2882,7 @@ ERROR; $out->enableOOUI(); - if ( $this->section === 'new' ) { + if ( $this->section == 'new' ) { $this->showSummaryInput( true, $this->summary ); $out->addHTML( $this->getSummaryPreview( true, $this->summary ) ); } @@ -2980,7 +3004,7 @@ ERROR; $type = false; if ( $this->preview ) { $type = 'preview'; - } elseif ( $this->section !== '' ) { + } elseif ( $this->section != '' ) { $type = 'section'; } @@ -3012,7 +3036,7 @@ ERROR; $this->addExplainConflictHeader( $out ); $this->editRevId = $this->page->getLatest(); } else { - if ( $this->section !== '' && $this->section !== 'new' ) { + if ( $this->section != '' && $this->section != 'new' ) { if ( !$this->summary && !$this->preview && !$this->diff ) { $sectionTitle = self::extractSectionTitle( $this->textbox1 ); // FIXME: use Content object if ( $sectionTitle !== false ) { @@ -3027,14 +3051,14 @@ ERROR; $out->wrapWikiMsg( "
\n$1\n
", 'missingcommenttext' ); } - if ( $this->missingSummary && $this->section !== 'new' ) { + if ( $this->missingSummary && $this->section != 'new' ) { $out->wrapWikiMsg( "
\n$1\n
", [ 'missingsummary', $buttonLabel ] ); } - if ( $this->missingSummary && $this->section === 'new' ) { + if ( $this->missingSummary && $this->section == 'new' ) { $out->wrapWikiMsg( "
\n$1\n
", [ 'missingcommentheader', $buttonLabel ] @@ -3059,7 +3083,7 @@ ERROR; $out->addWikiText( $this->hookError ); } - if ( $this->section !== 'new' ) { + if ( $this->section != 'new' ) { $revision = $this->mArticle->getRevisionFetched(); if ( $revision ) { // Let sysop know that this will make private content public if saved @@ -3096,7 +3120,7 @@ ERROR; [ 'readonlywarning', wfReadOnlyReason() ] ); } elseif ( $user->isAnon() ) { - if ( $this->formtype !== 'preview' ) { + if ( $this->formtype != 'preview' ) { $out->wrapWikiMsg( "
\n$1\n
", [ 'anoneditwarning', @@ -3167,7 +3191,7 @@ ERROR; } /** - * Helper function for summary input functions, which returns the neccessary + * Helper function for summary input functions, which returns the necessary * attributes for the input. * * @param array|null $inputAttrs Array of attrs to use on the input @@ -3331,7 +3355,7 @@ ERROR; * @param string|null $textoverride Optional text to override $this->textarea1 with */ protected function showTextbox1( $customAttribs = null, $textoverride = null ) { - if ( $this->wasDeletedSinceLastEdit() && $this->formtype === 'save' ) { + if ( $this->wasDeletedSinceLastEdit() && $this->formtype == 'save' ) { $attribs = [ 'style' => 'display:none;' ]; } else { $builder = new TextboxBuilder(); @@ -3384,14 +3408,14 @@ ERROR; $attribs = [ 'id' => 'wikiPreview', 'class' => implode( ' ', $classes ) ]; - if ( $this->formtype !== 'preview' ) { + if ( $this->formtype != 'preview' ) { $attribs['style'] = 'display: none;'; } $out = $this->context->getOutput(); $out->addHTML( Xml::openElement( 'div', $attribs ) ); - if ( $this->formtype === 'preview' ) { + if ( $this->formtype == 'preview' ) { $this->showPreview( $previewOutput ); } else { // Empty content container for LivePreview @@ -3403,7 +3427,7 @@ ERROR; $out->addHTML( '
' ); - if ( $this->formtype === 'diff' ) { + if ( $this->formtype == 'diff' ) { try { $this->showDiff(); } catch ( MWContentSerializationException $ex ) { @@ -3446,11 +3470,9 @@ ERROR; * save and then make a comparison. */ public function showDiff() { - global $wgContLang; - $oldtitlemsg = 'currentrev'; # if message does not exist, show diff against the preloaded default - if ( $this->mTitle->getNamespace() === NS_MEDIAWIKI && !$this->mTitle->exists() ) { + if ( $this->mTitle->getNamespace() == NS_MEDIAWIKI && !$this->mTitle->exists() ) { $oldtext = $this->mTitle->getDefaultMessageText(); if ( $oldtext !== false ) { $oldtitlemsg = 'defaultmessagetext'; @@ -3477,7 +3499,8 @@ ERROR; Hooks::run( 'EditPageGetDiffContent', [ $this, &$newContent ] ); $user = $this->context->getUser(); - $popts = ParserOptions::newFromUserAndLang( $user, $wgContLang ); + $popts = ParserOptions::newFromUserAndLang( $user, + MediaWikiServices::getInstance()->getContentLanguage() ); $newContent = $newContent->preSaveTransform( $this->mTitle, $user, $popts ); } @@ -3588,10 +3611,10 @@ ERROR; * Get the Limit report for page previews * * @since 1.22 - * @param ParserOutput $output ParserOutput object from the parse + * @param ParserOutput|null $output ParserOutput object from the parse * @return string HTML */ - public static function getPreviewLimitReport( $output ) { + public static function getPreviewLimitReport( ParserOutput $output = null ) { global $wgLang; if ( !$output || !$output->getLimitReportData() ) { @@ -3641,7 +3664,7 @@ ERROR; $out = $this->context->getOutput(); $out->addHTML( "
\n" ); - if ( $this->section !== 'new' ) { + if ( $this->section != 'new' ) { $this->showSummaryInput( false, $this->summary ); $out->addHTML( $this->getSummaryPreview( false, $this->summary ) ); } @@ -3764,6 +3787,8 @@ ERROR; } /** + * Get the last log record of this page being deleted, if ever. This is + * used to detect whether a delete occurred during editing. * @return bool|stdClass */ protected function getLastDelete() { @@ -3879,17 +3904,17 @@ ERROR; $level = false; } - if ( $content->getModel() === CONTENT_MODEL_CSS ) { + if ( $content->getModel() == CONTENT_MODEL_CSS ) { $format = 'css'; if ( $level === 'user' && !$config->get( 'AllowUserCss' ) ) { $format = false; } - } elseif ( $content->getModel() === CONTENT_MODEL_JSON ) { + } elseif ( $content->getModel() == CONTENT_MODEL_JSON ) { $format = 'json'; if ( $level === 'user' /* No comparable 'AllowUserJson' */ ) { $format = false; } - } elseif ( $content->getModel() === CONTENT_MODEL_JAVASCRIPT ) { + } elseif ( $content->getModel() == CONTENT_MODEL_JAVASCRIPT ) { $format = 'js'; if ( $level === 'user' && !$config->get( 'AllowUserJs' ) ) { $format = false; @@ -3974,6 +3999,12 @@ ERROR; $parserOptions->setIsPreview( true ); $parserOptions->setIsSectionPreview( !is_null( $this->section ) && $this->section !== '' ); $parserOptions->enableLimitReport(); + + // XXX: we could call $parserOptions->setCurrentRevisionCallback here to force the + // current revision to be null during PST, until setupFakeRevision is called on + // the ParserOptions. Currently, we rely on Parser::getRevisionObject() to ignore + // existing revisions in preview mode. + return $parserOptions; } @@ -3989,9 +4020,14 @@ ERROR; protected function doPreviewParse( Content $content ) { $user = $this->context->getUser(); $parserOptions = $this->getPreviewParserOptions(); + + // NOTE: preSaveTransform doesn't have a fake revision to operate on. + // Parser::getRevisionObject() will return null in preview mode, + // causing the context user to be used for {{subst:REVISIONUSER}}. + // XXX: Alternatively, we could also call setupFakeRevision() a second time: + // once before PST with $content, and then after PST with $pstContent. $pstContent = $content->preSaveTransform( $this->mTitle, $user, $parserOptions ); - $scopedCallback = $parserOptions->setupFakeRevision( - $this->mTitle, $pstContent, $user ); + $scopedCallback = $parserOptions->setupFakeRevision( $this->mTitle, $pstContent, $user ); $parserOutput = $pstContent->getParserOutput( $this->mTitle, null, $parserOptions ); ScopedCallback::consume( $scopedCallback ); return [ @@ -4006,7 +4042,7 @@ ERROR; * @return array */ public function getTemplates() { - if ( $this->preview || $this->section !== '' ) { + if ( $this->preview || $this->section != '' ) { $templates = []; if ( !isset( $this->mParserOutput ) ) { return $templates; @@ -4030,8 +4066,7 @@ ERROR; * @return string */ public static function getEditToolbar( $title = null ) { - global $wgContLang, $wgOut; - global $wgEnableUploads, $wgForeignFileRepos; + global $wgOut, $wgEnableUploads, $wgForeignFileRepos; $imagesAvailable = $wgEnableUploads || count( $wgForeignFileRepos ); $showSignature = true; @@ -4039,6 +4074,8 @@ ERROR; $showSignature = MWNamespace::wantSignatures( $title->getNamespace() ); } + $contLang = MediaWikiServices::getInstance()->getContentLanguage(); + /** * $toolarray is an array of arrays each of which includes the * opening tag, the closing tag, optionally a sample text that is @@ -4086,14 +4123,14 @@ ERROR; ], $imagesAvailable ? [ 'id' => 'mw-editbutton-image', - 'open' => '[[' . $wgContLang->getNsText( NS_FILE ) . ':', + 'open' => '[[' . $contLang->getNsText( NS_FILE ) . ':', 'close' => ']]', 'sample' => wfMessage( 'image_sample' )->text(), 'tip' => wfMessage( 'image_tip' )->text(), ] : false, $imagesAvailable ? [ 'id' => 'mw-editbutton-media', - 'open' => '[[' . $wgContLang->getNsText( NS_MEDIA ) . ':', + 'open' => '[[' . $contLang->getNsText( NS_MEDIA ) . ':', 'close' => ']]', 'sample' => wfMessage( 'media_sample' )->text(), 'tip' => wfMessage( 'media_tip' )->text(), @@ -4121,7 +4158,7 @@ ERROR; ] ]; - $script = 'mw.loader.using("mediawiki.toolbar", function () {'; + $script = ''; foreach ( $toolarray as $tool ) { if ( !$tool ) { continue; @@ -4148,15 +4185,16 @@ ERROR; ); } - $script .= '});'; - $toolbar = '
'; if ( Hooks::run( 'EditPageBeforeEditToolbar', [ &$toolbar ] ) ) { // Only add the old toolbar cruft to the page payload if the toolbar has not // been over-written by a hook caller $nonce = $wgOut->getCSPNonce(); - $wgOut->addScript( ResourceLoader::makeInlineScript( $script, $nonce ) ); + $wgOut->addScript( Html::inlineScript( + ResourceLoader::makeInlineCodeWithModule( 'mediawiki.toolbar', $script ), + $nonce + ) ); }; return $toolbar;