MtDu has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/330340 )
Change subject: Add api 'setPageLanguage' action for Special:PageLanguage ...................................................................... Add api 'setPageLanguage' action for Special:PageLanguage Currently, a user who wants to set a page's language must use the Special:PageLanguage interface. However, this is not easy for bots and scripts to use. The addition of this API makes this process easier for everyone. Bug: T74958 Change-Id: I42e74ed3bcd0bfa9ec0c344ba67668210450c975 --- M autoload.php M includes/api/ApiMain.php A includes/api/ApiSetPageLanguage.php M includes/api/i18n/en.json M includes/api/i18n/qqq.json M includes/specials/SpecialPageLanguage.php M languages/i18n/en.json M languages/i18n/qqq.json 8 files changed, 195 insertions(+), 19 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core refs/changes/40/330340/1 diff --git a/autoload.php b/autoload.php index cdbdf1f..a38fca2 100644 --- a/autoload.php +++ b/autoload.php @@ -139,6 +139,7 @@ 'ApiRsd' => __DIR__ . '/includes/api/ApiRsd.php', 'ApiSerializable' => __DIR__ . '/includes/api/ApiSerializable.php', 'ApiSetNotificationTimestamp' => __DIR__ . '/includes/api/ApiSetNotificationTimestamp.php', + 'ApiSetPageLanguage' => __DIR__ . '/includes/api/ApiSetPageLanguage.php', 'ApiStashEdit' => __DIR__ . '/includes/api/ApiStashEdit.php', 'ApiTag' => __DIR__ . '/includes/api/ApiTag.php', 'ApiTokens' => __DIR__ . '/includes/api/ApiTokens.php', diff --git a/includes/api/ApiMain.php b/includes/api/ApiMain.php index 4220fb8..52f1d95 100644 --- a/includes/api/ApiMain.php +++ b/includes/api/ApiMain.php @@ -106,6 +106,7 @@ 'managetags' => 'ApiManageTags', 'tag' => 'ApiTag', 'mergehistory' => 'ApiMergeHistory', + 'setpagelanguage' => 'ApiSetPageLanguage', ]; /** diff --git a/includes/api/ApiSetPageLanguage.php b/includes/api/ApiSetPageLanguage.php new file mode 100755 index 0000000..0d2def1 --- /dev/null +++ b/includes/api/ApiSetPageLanguage.php @@ -0,0 +1,141 @@ +<?php +/** + * + * + * Created on January 1, 2017 + * + * Copyright © 2017 Justin Du "<justin.d...@gmail.com>" + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * http://www.gnu.org/copyleft/gpl.html + * + * @file + */ + +/** + * API module that facilitates changing the language of a page. The API equivalent of SpecialPageLanguage. + * Requires API write mode to be enabled. + * + * @ingroup API + */ +class ApiSetPageLanguage extends ApiBase { + /** + * Extracts the title and language from the request parameters and invokes + * the static SpecialPageLanguage::changePageLanguage() function with these as arguments. + * If the language change succeeds, the details of the article changed + * and the reason for the language change are added to the result object. + */ + public function execute() { + // Check if change language feature is enabled + global $wgPageLanguageuseDB; + if ( !$wgPageLanguageuseDB ) { + $this->dieWithError( 'apierror-pagelang-disabled' ); + } + + // Check if the user has permissions + $this->checkUserRightsAny( 'pagelang' ); + + $this->useTransactionalTimeLimit(); + + $params = $this->extractRequestParams(); + + $pageObj = $this->getTitleOrPageId( $params, 'fromdbmaster' ); + if ( !$pageObj->exists() ) { + $this->dieWithError( 'apierror-missingtitle' ); + } + + $titleObj = $pageObj->getTitle(); + $reason = $params['reason']; + $user = $this->getUser(); + + // Check that the user is allowed to edit the page + $this->checkTitleUserPermissions( $titleObj, 'edit' ); + + // If change tagging was requested, check that the user is allowed to tag, + // and the tags are valid + if ( count( $params['tags'] ) ) { + $tagStatus = ChangeTags::canAddTagsAccompanyingChange( $params['tags'], $user ); + if ( !$tagStatus->isOK() ) { + $this->dieStatus( $tagStatus ); + } + } + + $status = SpecialPageLanguage::changePageLanguage( + $this->getContext(), + $titleObj, + $params['lang'], + $params['tags'] + ); + + if ( !$status->isGood() ) { + $this->dieStatus( $status ); + } + + $r = [ + 'title' => $titleObj->getPrefixedText(), + 'performer' => $status->value['performer'], + 'oldLanguage' => $status->value['oldLanguage'], + 'newLanguage' => $status->value['newLanguage'], + 'logId' => $status->value['logId'], + 'reason' => $params['reason'] + ]; + $this->getResult()->addValue( null, $this->getModuleName(), $r ); + } + + public function mustBePosted() { + return true; + } + + public function isWriteMode() { + return true; + } + + public function getAllowedParams() { + return [ + 'title' => null, + 'pageid' => [ + ApiBase::PARAM_TYPE => 'integer' + ], + 'reason' => null, + 'tags' => [ + ApiBase::PARAM_TYPE => 'tags', + ApiBase::PARAM_ISMULTI => true, + ], + 'lang' => [ + ApiBase::PARAM_TYPE => array_merge( + array_keys( Language::fetchLanguageNames( null, 'mwfile' ) ), + 'default' + ) + ], + ]; + } + + public function needsToken() { + return 'csrf'; + } + + protected function getExamplesMessages() { + return [ + 'action=delete&title=Main%20Page&token=123ABC' + => 'apihelp-delete-example-simple', + 'action=delete&title=Main%20Page&token=123ABC&reason=Preparing%20for%20move' + => 'apihelp-delete-example-reason', + ]; + } + + public function getHelpUrls() { + return 'https://www.mediawiki.org/wiki/API:ChangePageLanguage'; + } +} diff --git a/includes/api/i18n/en.json b/includes/api/i18n/en.json index bc9fbf6..33df546 100644 --- a/includes/api/i18n/en.json +++ b/includes/api/i18n/en.json @@ -1733,6 +1733,7 @@ "apierror-upload-missingresult": "No result in status data.", "apierror-urlparamnormal": "Could not normalize image parameters for $1.", "apierror-writeapidenied": "You're not allowed to edit this wiki through the API.", + "apierror-pagelang-disabled": "Changing the language of a WikiPage has not been allowed on this wiki.", "apiwarn-alldeletedrevisions-performance": "For better performance when generating titles, set <kbd>$1dir=newer</kbd>.", "apiwarn-badurlparam": "Could not parse <var>$1urlparam</var> for $2. Using only width and height.", diff --git a/includes/api/i18n/qqq.json b/includes/api/i18n/qqq.json index 9d467cc..18bfd74 100644 --- a/includes/api/i18n/qqq.json +++ b/includes/api/i18n/qqq.json @@ -1626,6 +1626,7 @@ "apierror-upload-missingresult": "{{doc-apierror}}", "apierror-urlparamnormal": "{{doc-apierror}}\n\nParameters:\n* $1 - Image title.", "apierror-writeapidenied": "{{doc-apierror}}", + "apierror-pagelang-disabled": "{{doc-apierror}}", "apiwarn-alldeletedrevisions-performance": "{{doc-apierror}}\n\nParameters:\n* $1 - Module parameter prefix, e.g. \"bl\".", "apiwarn-badurlparam": "{{doc-apierror}}\n\nParameters:\n* $1 - Module parameter prefix, e.g. \"bl\".\n* $2 - Image title.", "apiwarn-badutf8": "{{doc-apierror}}\n\nParameters:\n* $1 - Parameter name.\n{{doc-important|Do not translate \"\\t\", \"\\n\", and \"\\r\"}}", diff --git a/includes/specials/SpecialPageLanguage.php b/includes/specials/SpecialPageLanguage.php index 61b6a8c..913e4aa 100644 --- a/includes/specials/SpecialPageLanguage.php +++ b/includes/specials/SpecialPageLanguage.php @@ -114,26 +114,45 @@ * @return bool */ public function onSubmit( array $data ) { - $title = Title::newFromText( $data['pagename'] ); + $pageName = $data['pagename']; + + // Check if user wants to use default language + if ( $data['selectoptions'] == 1 ) { + $newLangauge = 'default'; + } else { + $newLanguage = $data['language']; + } + + $title = Title::newFromText( $pageName ); // Check if title is valid if ( !$title ) { return false; } + return self::changePageLanguage( $this->getContext(), $title, $newLanguage )->isOK(); + } + + /** + * + * @param string $pageName + * @param string $newLanguage + * @return bool + */ + public static function changePageLanguage( IContextSource $context, Title $title, $newLanguage, $tags=[] ) { // Get the default language for the wiki - $defLang = $this->getConfig()->get( 'LanguageCode' ); + $defLang = $context->getConfig()->get( 'LanguageCode' ); $pageId = $title->getArticleID(); // Check if article exists if ( !$pageId ) { - return false; + return Status::newFatal( 'pagelang-nonexistent-page', $title ); } // Load the page language from DB $dbw = wfGetDB( DB_MASTER ); - $langOld = $dbw->selectField( + $oldLanguage = $dbw->selectField( 'page', 'page_lang', [ 'page_id' => $pageId ], @@ -141,38 +160,36 @@ ); // Url to redirect to after the operation - $this->goToUrl = $title->getFullURL(); + // TODO $this->goToUrl = $title->getFullURL(); - // Check if user wants to use default language - if ( $data['selectoptions'] == 1 ) { - $langNew = null; - } else { - $langNew = $data['language']; + // Check if user wants to use the default language + if ( $newLanguage === 'default' ) { + $newLanguage = null; } // No change in language - if ( $langNew === $langOld ) { - return false; + if ( $newLanguage === $oldLanguage ) { + return Status::newFatal( 'pagelang-unchanged-language', $title, $oldLanguage ); } // Hardcoded [def] if the language is set to null - $logOld = $langOld ? $langOld : $defLang . '[def]'; - $logNew = $langNew ? $langNew : $defLang . '[def]'; + $logOld = $oldLanguage ? $oldLanguage : $defLang . '[def]'; + $logNew = $newLanguage ? $newLanguage : $defLang . '[def]'; // Writing new page language to database $dbw = wfGetDB( DB_MASTER ); $dbw->update( 'page', - [ 'page_lang' => $langNew ], + [ 'page_lang' => $newLanguage ], [ 'page_id' => $pageId, - 'page_lang' => $langOld + 'page_lang' => $oldLanguage ], __METHOD__ ); if ( !$dbw->affectedRows() ) { - return false; + return Status::newFatal( 'pagelang-db-failed' ); } // Logging change of language @@ -181,9 +198,10 @@ '5::newlanguage' => $logNew ]; $entry = new ManualLogEntry( 'pagelang', 'pagelang' ); - $entry->setPerformer( $this->getUser() ); + $entry->setPerformer( $context->getUser() ); $entry->setTarget( $title ); $entry->setParameters( $logParams ); + $entry->setTags( $tags ); $logid = $entry->insert(); $entry->publish( $logid ); @@ -191,7 +209,14 @@ // Force re-render so that language-based content (parser functions etc.) gets updated $title->invalidateCache(); - return true; + $status = Status::newGood(); + $status->value = [ + 'performer' => $context->getUser(), + 'oldLanguage' => $logOld, + 'newLanguage' => $logNew, + 'logId' => $logid, + ]; + return $status; } public function onSuccess() { diff --git a/languages/i18n/en.json b/languages/i18n/en.json index f2b27fc..a48156d 100644 --- a/languages/i18n/en.json +++ b/languages/i18n/en.json @@ -4047,6 +4047,9 @@ "pagelang-use-default": "Use default language", "pagelang-select-lang": "Select language", "pagelang-submit": "Submit", + "pagelang-nonexistent-page": "The page $1 does not exist.", + "pagelang-unchanged-language": "The page $1 is already set to language $2.", + "pagelang-db-failed": "The database failed to change the page language.", "right-pagelang": "Change page language", "action-pagelang": "change the page language", "log-name-pagelang": "Language change log", diff --git a/languages/i18n/qqq.json b/languages/i18n/qqq.json index 99f7679..efdec3a 100644 --- a/languages/i18n/qqq.json +++ b/languages/i18n/qqq.json @@ -4231,6 +4231,9 @@ "pagelang-use-default": "Radio label for selector on Special:PageLanguage for default language", "pagelang-select-lang": "Radio label for selector on Special:PageLanguage for language selection\n{{Identical|Select language}}", "pagelang-submit": "Submit button label for Special:PageLanguage form\n{{Identical|Submit}}", + "pagelang-nonexistent-page": "Error message shown when the page the user is trying to change the language on does not exist.\n\nParameters:\n* $1 - the title of the nonexistent page", + "pagelang-unchanged-language": "Error message shown when the language the user is trying to change the page to and the current language the page is in are the same.\n\nParameters:\n* $1 - the title of the target page, $2 - the current language of the page", + "pagelang-db-failed": "Error message shown when the database fails to update the language of the page", "right-pagelang": "{{Doc-right|pagelang}}\nRight to change page language on Special:PageLanguage", "action-pagelang": "{{Doc-action|pagelang}}", "log-name-pagelang": "Display entry for log name for changes in page language in Special:Log.", -- To view, visit https://gerrit.wikimedia.org/r/330340 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I42e74ed3bcd0bfa9ec0c344ba67668210450c975 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/core Gerrit-Branch: master Gerrit-Owner: MtDu <justin.d...@gmail.com> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits