Catrope has uploaded a new change for review. https://gerrit.wikimedia.org/r/309237
Change subject: [WIP] ApiVisualEditor: Clean up giant switch statement ...................................................................... [WIP] ApiVisualEditor: Clean up giant switch statement Use elseif, and put the simple cases first. Change-Id: I1addb810b06074ef9b9bacb018d7a9e61cb1704d --- M ApiVisualEditor.php 1 file changed, 271 insertions(+), 277 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/VisualEditor refs/changes/37/309237/1 diff --git a/ApiVisualEditor.php b/ApiVisualEditor.php index 0424873..d806371 100644 --- a/ApiVisualEditor.php +++ b/ApiVisualEditor.php @@ -209,295 +209,289 @@ } wfDebugLog( 'visualeditor', "called on '$title' with paction: '{$params['paction']}'" ); - switch ( $params['paction'] ) { - case 'parse': - case 'wikitext': - case 'metadata': - // Dirty hack to provide the correct context for edit notices - global $wgTitle; // FIXME NOOOOOOOOES - $wgTitle = $title; - RequestContext::getMain()->setTitle( $title ); - // Get information about current revision - if ( $title->exists() ) { - $latestRevision = Revision::newFromTitle( $title ); - if ( $latestRevision === null ) { - $this->dieUsage( 'Could not find latest revision for title', 'latestnotfound' ); - } - $revision = null; - if ( !isset( $parserParams['oldid'] ) || $parserParams['oldid'] === 0 ) { - $parserParams['oldid'] = $latestRevision->getId(); - $revision = $latestRevision; - } else { - $revision = Revision::newFromId( $parserParams['oldid'] ); - if ( $revision === null ) { - $this->dieUsage( 'Could not find revision ID ' . $parserParams['oldid'], 'oldidnotfound' ); - } - } - - $restoring = $revision && !$revision->isCurrent(); - $baseTimestamp = $latestRevision->getTimestamp(); - $oldid = intval( $parserParams['oldid'] ); - - // If requested, request HTML from Parsoid/RESTBase - if ( $params['paction'] === 'parse' ) { - $content = $this->requestRestbase( - 'GET', - 'page/html/' . urlencode( $title->getPrefixedDBkey() ) . '/' . $oldid . '?redirect=false', - [] - ); - if ( $content === false ) { - $this->dieUsage( 'Error contacting the document server', 'docserver' ); - } - } elseif ( $params['paction'] === 'wikitext' ) { - $apiParams = [ - 'action' => 'query', - 'titles' => $title->getPrefixedDBkey(), - 'prop' => 'revisions', - 'rvprop' => 'content' - ]; - $api = new ApiMain( - new DerivativeRequest( - $this->getRequest(), - $apiParams, - false // was posted? - ), - true // enable write? - ); - $api->execute(); - $result = $api->getResultData(); - $content = isset( $result['query']['pages'][$title->getArticleID()]['revisions'][0]['*'] ) ? - $result['query']['pages'][$title->getArticleID()]['revisions'][0]['*'] : - false; - if ( $content === false ) { - $this->dieUsage( 'Error contacting the document server', 'docserver' ); - } - } - - } else { - $content = ''; - Hooks::run( 'EditFormPreloadText', [ &$content, &$title ] ); - if ( $content !== '' ) { - $content = $this->parseWikitextFragment( $title, $content ); - } - $baseTimestamp = wfTimestampNow(); - $oldid = 0; - $restoring = false; - } - - // Get edit notices - $notices = $title->getEditNotices(); - - // Anonymous user notice - if ( $user->isAnon() ) { - $notices[] = $this->msg( - 'anoneditwarning', - // Log-in link - '{{fullurl:Special:UserLogin|returnto={{FULLPAGENAMEE}}}}', - // Sign-up link - '{{fullurl:Special:UserLogin/signup|returnto={{FULLPAGENAMEE}}}}' - )->parseAsBlock(); - } - - // Old revision notice - if ( $restoring ) { - $notices[] = $this->msg( 'editingold' )->parseAsBlock(); - } - - if ( wfReadOnly() ) { - $notices[] = $this->msg( 'readonlywarning', wfReadOnlyReason() ); - } - - // New page notices - if ( !$title->exists() ) { - $notices[] = $this->msg( - $user->isLoggedIn() ? 'newarticletext' : 'newarticletextanon', - wfExpandUrl( Skin::makeInternalOrExternalUrl( - $this->msg( 'helppage' )->inContentLanguage()->text() - ) ) - )->parseAsBlock(); - // Page protected from creation - if ( $title->getRestrictions( 'create' ) ) { - $notices[] = $this->msg( 'titleprotectedwarning' )->parseAsBlock(); - } - } - - // Look at protection status to set up notices + surface class(es) - $protectedClasses = []; - if ( MWNamespace::getRestrictionLevels( $title->getNamespace() ) !== [ '' ] ) { - // Page protected from editing - if ( $title->isProtected( 'edit' ) ) { - # Is the title semi-protected? - if ( $title->isSemiProtected() ) { - $protectedClasses[] = 'mw-textarea-sprotected'; - - $noticeMsg = 'semiprotectedpagewarning'; - } else { - $protectedClasses[] = 'mw-textarea-protected'; - - # Then it must be protected based on static groups (regular) - $noticeMsg = 'protectedpagewarning'; - } - $notices[] = $this->msg( $noticeMsg )->parseAsBlock() . - $this->getLastLogEntry( $title, 'protect' ); - } - - // Deal with cascading edit protection - list( $sources, $restrictions ) = $title->getCascadeProtectionSources(); - if ( isset( $restrictions['edit'] ) ) { - $protectedClasses[] = ' mw-textarea-cprotected'; - - $notice = $this->msg( 'cascadeprotectedwarning' )->parseAsBlock() . '<ul>'; - // Unfortunately there's no nice way to get only the pages which cause - // editing to be restricted - foreach ( $sources as $source ) { - $notice .= "<li>" . Linker::link( $source ) . "</li>"; - } - $notice .= '</ul>'; - $notices[] = $notice; - } - } - - // Permission notice - $permErrors = $title->getUserPermissionsErrors( 'create', $user, 'quick' ); - if ( $permErrors && !$title->exists() ) { - $notices[] = $this->msg( - 'permissionserrorstext-withaction', 1, $this->msg( 'action-createpage' ) - ) . "<br>" . call_user_func_array( [ $this, 'msg' ], $permErrors[0] )->parse(); - } - - // Show notice when editing user / user talk page of a user that doesn't exist - // or who is blocked - // HACK of course this code is partly duplicated from EditPage.php :( - if ( $title->getNamespace() == NS_USER || $title->getNamespace() == NS_USER_TALK ) { - $parts = explode( '/', $title->getText(), 2 ); - $targetUsername = $parts[0]; - $targetUser = User::newFromName( $targetUsername, false /* allow IP users*/ ); - - if ( - !( $targetUser && $targetUser->isLoggedIn() ) && - !User::isIP( $targetUsername ) - ) { // User does not exist - $notices[] = "<div class=\"mw-userpage-userdoesnotexist error\">\n" . - $this->msg( 'userpage-userdoesnotexist', wfEscapeWikiText( $targetUsername ) ) . - "\n</div>"; - } elseif ( $targetUser->isBlocked() ) { // Show log extract if the user is currently blocked - $notices[] = $this->msg( - 'blocked-notice-logextract', - $targetUser->getName() // Support GENDER in notice - )->parseAsBlock() . $this->getLastLogEntry( $targetUser->getUserPage(), 'block' ); - } - } - - // Blocked user notice - if ( $user->isBlockedFrom( $title ) && $user->getBlock()->prevents( 'edit' ) !== false ) { - $notices[] = call_user_func_array( - [ $this, 'msg' ], - $user->getBlock()->getPermissionsError( $this->getContext() ) - )->parseAsBlock(); - } - - // Blocked user notice for global blocks - if ( $user->isBlockedGlobally() ) { - $notices[] = call_user_func_array( - [ $this, 'msg' ], - $user->getGlobalBlock()->getPermissionsError( $this->getContext() ) - )->parseAsBlock(); - } - - // HACK: Build a fake EditPage so we can get checkboxes from it - $article = new Article( $title ); // Deliberately omitting ,0 so oldid comes from request - $ep = new EditPage( $article ); - $req = $this->getRequest(); - $req->setVal( 'format', 'text/x-wiki' ); - $ep->importFormData( $req ); // By reference for some reason (bug 52466) - $tabindex = 0; - $states = [ - 'minor' => $user->getOption( 'minordefault' ) && $title->exists(), - 'watch' => $user->getOption( 'watchdefault' ) || - ( $user->getOption( 'watchcreations' ) && !$title->exists() ) || - $user->isWatched( $title ), - ]; - $checkboxes = $ep->getCheckboxes( $tabindex, $states ); - - // HACK: Find out which red links are on the page - // We do the lookup for the current version. This might not be entirely complete - // if we're loading an oldid, but it'll probably be close enough, and LinkCache - // will automatically request any additional data it needs. - $links = []; - $wikipage = WikiPage::factory( $title ); - $popts = $wikipage->makeParserOptions( 'canonical' ); - $cached = ParserCache::singleton()->get( $article, $popts, true ); - $links = [ - // Array of linked pages that are missing - 'missing' => [], - // For current revisions: 1 (treat all non-missing pages as known) - // For old revisions: array of linked pages that are known - 'known' => $restoring || !$cached ? [] : 1, - ]; - if ( $cached ) { - foreach ( $cached->getLinks() as $namespace => $cachedTitles ) { - foreach ( $cachedTitles as $cachedTitleText => $exists ) { - $cachedTitle = Title::makeTitle( $namespace, $cachedTitleText ); - if ( !$cachedTitle->isKnown() ) { - $links['missing'][] = $cachedTitle->getPrefixedText(); - } elseif ( $links['known'] !== 1 ) { - $links['known'][] = $cachedTitle->getPrefixedText(); - } - } - } - } - // Add information about current page - if ( !$title->isKnown() ) { - $links['missing'][] = $title->getPrefixedText(); - } elseif ( $links['known'] !== 1 ) { - $links['known'][] = $title->getPrefixedText(); - } - - // On parser cache miss, just don't bother populating red link data - + if ( $parms['paction'] === 'getlanglinks' ) { + $langlinks = $this->getLangLinks( $title ); + if ( $langlinks === false ) { + $this->dieUsage( 'Error querying MediaWiki API', 'api-langlinks-error' ); + } else { + $result = [ 'result' => 'success', 'langlinks' => $langlinks ]; + } + } elseif ( $params['paction'] === 'parsefragment' ) { + $wikitext = $params['wikitext']; + if ( $params['pst'] ) { + $wikitext = $this->pstWikitext( $title, $wikitext ); + } + $content = $this->parseWikitextFragment( $title, $wikitext ); + if ( $content === false ) { + $this->dieUsage( 'Error contacting the document server', 'docserver' ); + } else { $result = [ 'result' => 'success', - 'notices' => $notices, - 'checkboxes' => $checkboxes, - 'links' => $links, - 'protectedClasses' => implode( ' ', $protectedClasses ), - 'basetimestamp' => $baseTimestamp, - 'starttimestamp' => wfTimestampNow(), - 'oldid' => $oldid, - + 'content' => $content ]; - if ( $params['paction'] === 'parse' || $params['paction'] === 'wikitext' ) { - $result['content'] = $content; - } - break; + } + } else { + // 'parse', 'wikitext' or 'metadata' - case 'parsefragment': - $wikitext = $params['wikitext']; - if ( $params['pst'] ) { - $wikitext = $this->pstWikitext( $title, $wikitext ); + // Dirty hack to provide the correct context for edit notices + global $wgTitle; // FIXME NOOOOOOOOES + $wgTitle = $title; + RequestContext::getMain()->setTitle( $title ); + + // Get information about current revision + if ( $title->exists() ) { + $latestRevision = Revision::newFromTitle( $title ); + if ( $latestRevision === null ) { + $this->dieUsage( 'Could not find latest revision for title', 'latestnotfound' ); } - $content = $this->parseWikitextFragment( $title, $wikitext ); - if ( $content === false ) { - $this->dieUsage( 'Error contacting the document server', 'docserver' ); + $revision = null; + if ( !isset( $parserParams['oldid'] ) || $parserParams['oldid'] === 0 ) { + $parserParams['oldid'] = $latestRevision->getId(); + $revision = $latestRevision; } else { - $result = [ - 'result' => 'success', - 'content' => $content + $revision = Revision::newFromId( $parserParams['oldid'] ); + if ( $revision === null ) { + $this->dieUsage( 'Could not find revision ID ' . $parserParams['oldid'], 'oldidnotfound' ); + } + } + + $restoring = $revision && !$revision->isCurrent(); + $baseTimestamp = $latestRevision->getTimestamp(); + $oldid = intval( $parserParams['oldid'] ); + + // If requested, request HTML from Parsoid/RESTBase + if ( $params['paction'] === 'parse' ) { + $content = $this->requestRestbase( + 'GET', + 'page/html/' . urlencode( $title->getPrefixedDBkey() ) . '/' . $oldid . '?redirect=false', + [] + ); + if ( $content === false ) { + $this->dieUsage( 'Error contacting the document server', 'docserver' ); + } + } elseif ( $params['paction'] === 'wikitext' ) { + $apiParams = [ + 'action' => 'query', + 'titles' => $title->getPrefixedDBkey(), + 'prop' => 'revisions', + 'rvprop' => 'content' ]; + $api = new ApiMain( + new DerivativeRequest( + $this->getRequest(), + $apiParams, + false // was posted? + ), + true // enable write? + ); + $api->execute(); + $result = $api->getResultData(); + $content = isset( $result['query']['pages'][$title->getArticleID()]['revisions'][0]['*'] ) ? + $result['query']['pages'][$title->getArticleID()]['revisions'][0]['*'] : + false; + if ( $content === false ) { + $this->dieUsage( 'Error contacting the document server', 'docserver' ); + } } - break; - case 'getlanglinks': - $langlinks = $this->getLangLinks( $title ); - if ( $langlinks === false ) { - $this->dieUsage( 'Error querying MediaWiki API', 'api-langlinks-error' ); - } else { - $result = [ 'result' => 'success', 'langlinks' => $langlinks ]; + } else { + $content = ''; + Hooks::run( 'EditFormPreloadText', [ &$content, &$title ] ); + if ( $content !== '' ) { + $content = $this->parseWikitextFragment( $title, $content ); } - break; + $baseTimestamp = wfTimestampNow(); + $oldid = 0; + $restoring = false; + } + + // Get edit notices + $notices = $title->getEditNotices(); + + // Anonymous user notice + if ( $user->isAnon() ) { + $notices[] = $this->msg( + 'anoneditwarning', + // Log-in link + '{{fullurl:Special:UserLogin|returnto={{FULLPAGENAMEE}}}}', + // Sign-up link + '{{fullurl:Special:UserLogin/signup|returnto={{FULLPAGENAMEE}}}}' + )->parseAsBlock(); + } + + // Old revision notice + if ( $restoring ) { + $notices[] = $this->msg( 'editingold' )->parseAsBlock(); + } + + if ( wfReadOnly() ) { + $notices[] = $this->msg( 'readonlywarning', wfReadOnlyReason() ); + } + + // New page notices + if ( !$title->exists() ) { + $notices[] = $this->msg( + $user->isLoggedIn() ? 'newarticletext' : 'newarticletextanon', + wfExpandUrl( Skin::makeInternalOrExternalUrl( + $this->msg( 'helppage' )->inContentLanguage()->text() + ) ) + )->parseAsBlock(); + // Page protected from creation + if ( $title->getRestrictions( 'create' ) ) { + $notices[] = $this->msg( 'titleprotectedwarning' )->parseAsBlock(); + } + } + + // Look at protection status to set up notices + surface class(es) + $protectedClasses = []; + if ( MWNamespace::getRestrictionLevels( $title->getNamespace() ) !== [ '' ] ) { + // Page protected from editing + if ( $title->isProtected( 'edit' ) ) { + # Is the title semi-protected? + if ( $title->isSemiProtected() ) { + $protectedClasses[] = 'mw-textarea-sprotected'; + + $noticeMsg = 'semiprotectedpagewarning'; + } else { + $protectedClasses[] = 'mw-textarea-protected'; + + # Then it must be protected based on static groups (regular) + $noticeMsg = 'protectedpagewarning'; + } + $notices[] = $this->msg( $noticeMsg )->parseAsBlock() . + $this->getLastLogEntry( $title, 'protect' ); + } + + // Deal with cascading edit protection + list( $sources, $restrictions ) = $title->getCascadeProtectionSources(); + if ( isset( $restrictions['edit'] ) ) { + $protectedClasses[] = ' mw-textarea-cprotected'; + + $notice = $this->msg( 'cascadeprotectedwarning' )->parseAsBlock() . '<ul>'; + // Unfortunately there's no nice way to get only the pages which cause + // editing to be restricted + foreach ( $sources as $source ) { + $notice .= "<li>" . Linker::link( $source ) . "</li>"; + } + $notice .= '</ul>'; + $notices[] = $notice; + } + } + + // Permission notice + $permErrors = $title->getUserPermissionsErrors( 'create', $user, 'quick' ); + if ( $permErrors && !$title->exists() ) { + $notices[] = $this->msg( + 'permissionserrorstext-withaction', 1, $this->msg( 'action-createpage' ) + ) . "<br>" . call_user_func_array( [ $this, 'msg' ], $permErrors[0] )->parse(); + } + + // Show notice when editing user / user talk page of a user that doesn't exist + // or who is blocked + // HACK of course this code is partly duplicated from EditPage.php :( + if ( $title->getNamespace() == NS_USER || $title->getNamespace() == NS_USER_TALK ) { + $parts = explode( '/', $title->getText(), 2 ); + $targetUsername = $parts[0]; + $targetUser = User::newFromName( $targetUsername, false /* allow IP users*/ ); + + if ( + !( $targetUser && $targetUser->isLoggedIn() ) && + !User::isIP( $targetUsername ) + ) { // User does not exist + $notices[] = "<div class=\"mw-userpage-userdoesnotexist error\">\n" . + $this->msg( 'userpage-userdoesnotexist', wfEscapeWikiText( $targetUsername ) ) . + "\n</div>"; + } elseif ( $targetUser->isBlocked() ) { // Show log extract if the user is currently blocked + $notices[] = $this->msg( + 'blocked-notice-logextract', + $targetUser->getName() // Support GENDER in notice + )->parseAsBlock() . $this->getLastLogEntry( $targetUser->getUserPage(), 'block' ); + } + } + + // Blocked user notice + if ( $user->isBlockedFrom( $title ) && $user->getBlock()->prevents( 'edit' ) !== false ) { + $notices[] = call_user_func_array( + [ $this, 'msg' ], + $user->getBlock()->getPermissionsError( $this->getContext() ) + )->parseAsBlock(); + } + + // Blocked user notice for global blocks + if ( $user->isBlockedGlobally() ) { + $notices[] = call_user_func_array( + [ $this, 'msg' ], + $user->getGlobalBlock()->getPermissionsError( $this->getContext() ) + )->parseAsBlock(); + } + + // HACK: Build a fake EditPage so we can get checkboxes from it + $article = new Article( $title ); // Deliberately omitting ,0 so oldid comes from request + $ep = new EditPage( $article ); + $req = $this->getRequest(); + $req->setVal( 'format', 'text/x-wiki' ); + $ep->importFormData( $req ); // By reference for some reason (bug 52466) + $tabindex = 0; + $states = [ + 'minor' => $user->getOption( 'minordefault' ) && $title->exists(), + 'watch' => $user->getOption( 'watchdefault' ) || + ( $user->getOption( 'watchcreations' ) && !$title->exists() ) || + $user->isWatched( $title ), + ]; + $checkboxes = $ep->getCheckboxes( $tabindex, $states ); + + // HACK: Find out which red links are on the page + // We do the lookup for the current version. This might not be entirely complete + // if we're loading an oldid, but it'll probably be close enough, and LinkCache + // will automatically request any additional data it needs. + $links = []; + $wikipage = WikiPage::factory( $title ); + $popts = $wikipage->makeParserOptions( 'canonical' ); + $cached = ParserCache::singleton()->get( $article, $popts, true ); + $links = [ + // Array of linked pages that are missing + 'missing' => [], + // For current revisions: 1 (treat all non-missing pages as known) + // For old revisions: array of linked pages that are known + 'known' => $restoring || !$cached ? [] : 1, + ]; + if ( $cached ) { + foreach ( $cached->getLinks() as $namespace => $cachedTitles ) { + foreach ( $cachedTitles as $cachedTitleText => $exists ) { + $cachedTitle = Title::makeTitle( $namespace, $cachedTitleText ); + if ( !$cachedTitle->isKnown() ) { + $links['missing'][] = $cachedTitle->getPrefixedText(); + } elseif ( $links['known'] !== 1 ) { + $links['known'][] = $cachedTitle->getPrefixedText(); + } + } + } + } + // Add information about current page + if ( !$title->isKnown() ) { + $links['missing'][] = $title->getPrefixedText(); + } elseif ( $links['known'] !== 1 ) { + $links['known'][] = $title->getPrefixedText(); + } + + // On parser cache miss, just don't bother populating red link data + + $result = [ + 'result' => 'success', + 'notices' => $notices, + 'checkboxes' => $checkboxes, + 'links' => $links, + 'protectedClasses' => implode( ' ', $protectedClasses ), + 'basetimestamp' => $baseTimestamp, + 'starttimestamp' => wfTimestampNow(), + 'oldid' => $oldid, + + ]; + if ( $params['paction'] === 'parse' || $params['paction'] === 'wikitext' ) { + $result['content'] = $content; + } } - $this->getResult()->addValue( null, $this->getModuleName(), $result ); } -- To view, visit https://gerrit.wikimedia.org/r/309237 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I1addb810b06074ef9b9bacb018d7a9e61cb1704d Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/VisualEditor Gerrit-Branch: master Gerrit-Owner: Catrope <roan.katt...@gmail.com> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits