Merge "Use TextFormatter in the REST API"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Tue, 17 Sep 2019 18:57:09 +0000 (18:57 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Tue, 17 Sep 2019 18:57:09 +0000 (18:57 +0000)
30 files changed:
RELEASE-NOTES-1.34
autoload.php
includes/DefaultSettings.php
includes/MergeHistory.php
includes/ServiceWiring.php
includes/Setup.php
includes/api/i18n/ko.json
includes/exception/MWExceptionHandler.php
includes/specials/SpecialBlock.php
includes/watcheditem/WatchedItemQueryService.php
languages/i18n/ar.json
languages/i18n/ban.json
languages/i18n/diq.json
languages/i18n/exif/nds-nl.json
languages/i18n/fr.json
languages/i18n/jv.json
languages/i18n/ko.json
languages/i18n/lb.json
languages/i18n/lzh.json
languages/i18n/my.json
languages/i18n/nap.json
languages/i18n/nl.json
languages/i18n/pl.json
languages/i18n/pt-br.json
languages/i18n/roa-tara.json
languages/i18n/zh-hant.json
maintenance/cleanupRevActorPage.php [new file with mode: 0644]
tests/phpunit/includes/api/ApiBlockTest.php
tests/phpunit/includes/watcheditem/WatchedItemQueryServiceUnitTest.php
tests/selenium/wdio-mediawiki/README.md

index c4bbd4a..09f5346 100644 (file)
@@ -572,6 +572,9 @@ because of Phabricator reports.
 * StreamFile::send404Message() and StreamFile::parseRange() are now deprecated.
   Use HTTPFileStreamer::send404Message() and HTTPFileStreamer::parseRange()
   respectively instead.
+* Global variable $wgSysopEmailBans is deprecated; to allow sysops to ban
+  users from sending emails, use
+  $wgGroupPermissions['sysop']['blockemail'] = true;
 
 === Other changes in 1.34 ===
 * …
index f95e001..48d5b30 100644 (file)
@@ -272,6 +272,7 @@ $wgAutoloadLocalClasses = [
        'CleanupInvalidDbKeys' => __DIR__ . '/maintenance/cleanupInvalidDbKeys.php',
        'CleanupPreferences' => __DIR__ . '/maintenance/cleanupPreferences.php',
        'CleanupRemovedModules' => __DIR__ . '/maintenance/cleanupRemovedModules.php',
+       'CleanupRevActorPage' => __DIR__ . '/maintenance/cleanupRevActorPage.php',
        'CleanupSpam' => __DIR__ . '/maintenance/cleanupSpam.php',
        'CleanupUploadStash' => __DIR__ . '/maintenance/cleanupUploadStash.php',
        'CleanupUsersWithNoId' => __DIR__ . '/maintenance/cleanupUsersWithNoId.php',
index 6b04070..c3a37f3 100644 (file)
@@ -4991,6 +4991,8 @@ $wgBlockAllowsUTEdit = true;
 
 /**
  * Allow sysops to ban users from accessing Emailuser
+ * @deprecated since 1.34; `$wgGroupPermissions['sysop']['blockemail'] = true;`
+ * should be used instead
  */
 $wgSysopEmailBans = true;
 
index 4045a54..1a950c5 100644 (file)
@@ -273,6 +273,18 @@ class MergeHistory {
                        return $status;
                }
 
+               // Update denormalized revactor_page too
+               $this->dbw->update(
+                       'revision_actor_temp',
+                       [ 'revactor_page' => $this->dest->getArticleID() ],
+                       [
+                               'revactor_page' => $this->source->getArticleID(),
+                               // Slightly hacky, but should work given the values assigned in this class
+                               str_replace( 'rev_timestamp', 'revactor_timestamp', $this->timeWhere )
+                       ],
+                       __METHOD__
+               );
+
                // Make the source page a redirect if no revisions are left
                $haveRevisions = $this->dbw->lockForUpdate(
                        'revision',
index 4cd3d85..8807d04 100644 (file)
@@ -784,7 +784,8 @@ return [
                        $services->getDBLoadBalancer(),
                        $services->getCommentStore(),
                        $services->getActorMigration(),
-                       $services->getWatchedItemStore()
+                       $services->getWatchedItemStore(),
+                       $services->getPermissionManager()
                );
        },
 
index 518531a..6838c37 100644 (file)
@@ -440,6 +440,13 @@ if ( $wgEnableEmail ) {
        $wgUsersNotifiedOnAllChanges = [];
 }
 
+// $wgSysopEmailBans deprecated in 1.34
+if ( isset( $wgSysopEmailBans ) && $wgSysopEmailBans === false ) {
+       foreach ( $wgGroupPermissions as $group => $_ ) {
+               unset( $wgGroupPermissions[$group]['blockemail'] );
+       }
+}
+
 if ( $wgMetaNamespace === false ) {
        $wgMetaNamespace = str_replace( ' ', '_', $wgSitename );
 }
index 6124066..6f390f9 100644 (file)
@@ -16,7 +16,8 @@
                        "Jonghaya",
                        "Jerrykim306",
                        "코코아",
-                       "Macofe"
+                       "Macofe",
+                       "렌즈"
                ]
        },
        "apihelp-main-extended-description": "<div class=\"hlist plainlinks api-main-links\">\n* [[mw:Special:MyLanguage/API:Main_page|설명문서]]\n* [[mw:Special:MyLanguage/API:FAQ|FAQ]]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api 메일링 리스트]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-api-announce API 알림 사항]\n* [https://phabricator.wikimedia.org/maniphest/query/GebfyV4uCaLd/#R 버그 및 요청]\n</div>\n<strong>상태:</strong> 이 페이지에 보이는 모든 기능은 정상적으로 작동하지만, API는 여전히 활발하게 개발되고 있으며, 언제든지 변경될 수 있습니다. 업데이트 공지를 받아보려면 [https://lists.wikimedia.org/pipermail/mediawiki-api-announce/ mediawiki-api-announce 메일링 리스트]를 구독하십시오.\n\n<strong>잘못된 요청:</strong> API에 잘못된 요청이 전송되면 \"MediaWiki-API-Error\" 키가 포함된 HTTP 헤더가 전송되며 반환되는 헤더와 오류 코드의 값은 모두 동일한 값으로 설정됩니다. 자세한 정보에 대해서는 [[mw:Special:MyLanguage/API:Errors and warnings/ko|API:오류와 경고]]를 참조하십시오.\n\n<strong>테스트하기:</strong> API 요청 테스트를 용이하게 하려면, [[Special:ApiSandbox]]를 보십시오.",
        "apihelp-compare-paramvalue-prop-title": "'from'과 'to' 판의 문서 제목입니다.",
        "apihelp-compare-paramvalue-prop-user": "'from'과 'to' 판의 사용자 이름과 ID입니다.",
        "apihelp-compare-paramvalue-prop-comment": "'from'과 'to' 판의 설명입니다.",
-       "apihelp-compare-paramvalue-prop-parsedcomment": "'from'과 to' 판의 구문 분석된 설명입니다.",
+       "apihelp-compare-paramvalue-prop-parsedcomment": "'from'과 to' 판의 변환된 설명입니다.",
        "apihelp-compare-paramvalue-prop-size": "'from'과 'to' 판의 크기입니다.",
        "apihelp-compare-example-1": "판 1과 2의 차이를 생성합니다.",
        "apihelp-createaccount-summary": "새 사용자 계정을 만듭니다.",
        "apihelp-options-example-complex": "모든 환경 설정을 초기화하고 <kbd>skin</kbd>과 <kbd>nickname</kbd>을 설정합니다.",
        "apihelp-paraminfo-summary": "API 모듈의 정보를 가져옵니다.",
        "apihelp-paraminfo-param-helpformat": "도움말 문자열 포맷.",
-       "apihelp-parse-summary": "ë\82´ì\9a©ì\9d\98 êµ¬ë¬¸ì\9d\84 ë¶\84ì\84\9dí\95\98ê³  í\8c\8cì\84\9c 출력을 반환합니다.",
-       "apihelp-parse-param-summary": "구문 분석할 요약입니다.",
-       "apihelp-parse-paramvalue-prop-text": "위키텍스트의 구문 분석된 텍스트를 제공합니다.",
-       "apihelp-parse-paramvalue-prop-langlinks": "구문 분석된 위키텍스트의 언어 링크를 제공합니다.",
-       "apihelp-parse-paramvalue-prop-categories": "구문 분석된 위키텍스트의 분류를 제공합니다.",
+       "apihelp-parse-summary": "ë\82´ì\9a©ì\9d\84 ë³\80í\99\98í\95\98ê³  출력을 반환합니다.",
+       "apihelp-parse-param-summary": "변환할 요약입니다.",
+       "apihelp-parse-paramvalue-prop-text": "위키텍스트로 변환된 텍스트를 제공합니다.",
+       "apihelp-parse-paramvalue-prop-langlinks": "언어 링크를 위키텍스트로 변환하여 제공합니다.",
+       "apihelp-parse-paramvalue-prop-categories": "분류를 변환된 위키텍스트로 제공합니다.",
        "apihelp-parse-paramvalue-prop-categorieshtml": "분류의 HTML 버전을 제공합니다.",
-       "apihelp-parse-paramvalue-prop-links": "구문 분석된 위키텍스트의 내부 링크를 제공합니다.",
-       "apihelp-parse-paramvalue-prop-templates": "구문 분석된 위키텍스트의 틀을 제공합니다.",
-       "apihelp-parse-paramvalue-prop-images": "구문 ë¶\84ì\84\9dë\90\9c ì\9c\84í\82¤í\85\8dì\8a¤í\8a¸ì\9d\98 ê·¸ë¦¼ì\9d\84 제공합니다.",
-       "apihelp-parse-paramvalue-prop-externallinks": "구문 분석된 위키텍스트의 외부 링크를 제공합니다.",
-       "apihelp-parse-paramvalue-prop-sections": "구문 분석된 위키텍스트의 문단을 제공합니다.",
-       "apihelp-parse-paramvalue-prop-revid": "구문 분석된 페이지의 판 ID를 추가합니다.",
-       "apihelp-parse-paramvalue-prop-displaytitle": "구문 분석된 위키텍스트의 제목을 추가합니다.",
+       "apihelp-parse-paramvalue-prop-links": "내부 링크를 위키텍스트로 변환하여 제공합니다.",
+       "apihelp-parse-paramvalue-prop-templates": "틀을 변환된 위키텍스트로 제공합니다.",
+       "apihelp-parse-paramvalue-prop-images": "그림ì\9d\84 ì\9c\84í\82¤í\85\8dì\8a¤í\8a¸ë¡\9c ë³\80í\99\98í\95\98ì\97¬ 제공합니다.",
+       "apihelp-parse-paramvalue-prop-externallinks": "외부 링크를 위키텍스트로 변환하여 제공합니다.",
+       "apihelp-parse-paramvalue-prop-sections": "문단을 변환된 위키텍스트로 제공합니다.",
+       "apihelp-parse-paramvalue-prop-revid": "변환할 페이지의 판 ID를 추가합니다.",
+       "apihelp-parse-paramvalue-prop-displaytitle": "제목을 변환된 위키텍스트로 추가합니다.",
        "apihelp-parse-paramvalue-prop-headitems": "문서의 <code>&lt;head&gt;</code> 안에 넣을 항목을 제공합니다.",
-       "apihelp-parse-paramvalue-prop-headhtml": "문서의 구문 분석된 <code>&lt;head&gt;</code>를 제공합니다.",
+       "apihelp-parse-paramvalue-prop-headhtml": "문서의 파싱된 doctype, 여는 <code>&lt;html&gt;</code>, <code>&lt;head&gt;</code>, <code>&lt;body&gt;</code>를 제공합니다.",
        "apihelp-parse-paramvalue-prop-modules": "문서에 사용되는 ResourceLoader 모듈을 제공합니다. 불러오려면, <code>mw.loader.using()</code>을 사용하세요. <kbd>jsconfigvars</kbd> 또는 <kbd>encodedjsconfigvars</kbd>는 <kbd>modules</kbd>와 함께 요청해야 합니다.",
        "apihelp-parse-paramvalue-prop-jsconfigvars": "문서에 특화된 자바스크립트 구성 변수를 제공합니다. 적용하려면 <code>mw.config.set()</code>을 사용하세요.",
-       "apihelp-parse-paramvalue-prop-iwlinks": "구문 분석된 위키텍스트의 인터위키 링크를 제공합니다.",
-       "apihelp-parse-paramvalue-prop-wikitext": "구문 분석된 위키텍스트 원문을 제공합니다.",
-       "apihelp-parse-paramvalue-prop-properties": "구문 분석된 위키텍스트에 정의된 다양한 속성을 제공합니다.",
-       "apihelp-parse-param-pst": "구문 분석 이전에 입력에 대한 사전 저장 변환을 수행합니다. 텍스트로 사용할 때에만 유효합니다.",
+       "apihelp-parse-paramvalue-prop-iwlinks": "인터위키 링크를 위키텍스트로 변환하여 제공합니다.",
+       "apihelp-parse-paramvalue-prop-wikitext": "변환한 원문 위키텍스트를 제공합니다.",
+       "apihelp-parse-paramvalue-prop-properties": "정의된 다양한 속성을 변환된 위키텍스트로 제공합니다.",
+       "apihelp-parse-param-pst": "파싱에 앞서 입력에 대한 저장 직전의 변환을 수행합니다. 텍스트로 사용할 때에만 유효합니다.",
        "apihelp-parse-param-disablelimitreport": "파서 출력에서 제한 보고서(\"NewPP limit report\")를 제외합니다.",
        "apihelp-parse-param-disablepp": "<var>$1disablelimitreport</var>를 대신 사용합니다.",
        "apihelp-parse-param-disableeditsection": "파서 출력에서 문단 편집 링크를 제외합니다.",
        "apihelp-parse-param-disabletidy": "파서 출력에서 HTML 정리(예: tidy)를 수행하지 않습니다.",
-       "apihelp-parse-param-preview": "미리 보기 모드에서 구문 분석을 합니다.",
-       "apihelp-parse-param-sectionpreview": "문단 미리 보기 모드에서 구문 분석을 합니다. (미리 보기 모드도 활성화함)",
+       "apihelp-parse-param-preview": "미리 보기 모드에서 파싱합니다.",
+       "apihelp-parse-param-sectionpreview": "문단 미리 보기 모드에서 파싱합니다. (미리 보기 모드도 활성화함)",
        "apihelp-parse-param-disabletoc": "출력에서 목차를 제외합니다.",
        "apihelp-parse-param-useskin": "선택한 스킨을 파서 출력에 적용합니다. 다음의 속성에 영향을 줄 수 있습니다: <kbd>langlinks</kbd>, <kbd>headitems</kbd>, <kbd>modules</kbd>, <kbd>jsconfigvars</kbd>, <kbd>indicators</kbd>.",
        "apihelp-parse-param-contentformat": "입력 텍스트에 사용할 내용 직렬화 포맷입니다. $1text와 함께 사용할 때에만 유효합니다.",
-       "apihelp-parse-example-page": "페이지의 구문을 분석합니다.",
+       "apihelp-parse-example-page": "페이지를 파싱합니다.",
        "apihelp-parse-example-text": "위키텍스트의 구문을 분석합니다.",
-       "apihelp-parse-example-summary": "요약을 구문 분석합니다.",
+       "apihelp-parse-example-summary": "요약을 변환합니다.",
        "apihelp-patrol-summary": "문서나 판을 점검하기.",
        "apihelp-patrol-param-rcid": "점검할 최근 바뀜 ID입니다.",
        "apihelp-patrol-param-revid": "점검할 판 ID입니다.",
        "apihelp-query+imageinfo-summary": "파일 정보와 업로드 역사를 반환합니다.",
        "apihelp-query+imageinfo-param-prop": "가져올 파일 정보입니다:",
        "apihelp-query+imageinfo-paramvalue-prop-timestamp": "업로드된 판에 대한 타임스탬프를 추가합니다.",
-       "apihelp-query+imageinfo-paramvalue-prop-parsedcomment": "판의 설명을 구문 분석합니다.",
+       "apihelp-query+imageinfo-paramvalue-prop-parsedcomment": "판의 설명을 변환합니다.",
        "apihelp-query+imageinfo-paramvalue-prop-sha1": "파일에 대한 SHA-1 해시를 추가합니다.",
        "apihelp-query+imageinfo-paramvalue-prop-mediatype": "파일의 미디어 유형을 추가합니다.",
        "apihelp-query+imageinfo-param-urlheight": "$1urlwidth와 유사합니다.",
        "apihelp-query+revisions+base-paramvalue-prop-contentmodel": "판의 콘텐츠 모델 ID.",
        "apihelp-query+revisions+base-paramvalue-prop-content": "판의 텍스트.",
        "apihelp-query+revisions+base-paramvalue-prop-tags": "판의 태그.",
-       "apihelp-query+revisions+base-param-parse": "<kbd>[[Special:ApiHelp/parse|action=parse]]</kbd>를 ë\8c\80ì\8b  ì\82¬ì\9a©í\95©ë\8b\88ë\8b¤. í\8c\90 ë\82´ì\9a©ì\9d\98 êµ¬ë¬¸ì\9d\84 ë¶\84ì\84\9d합니다. ($1prop=content 필요) 성능 상의 이유로 이 옵션을 사용할 경우 $1limit은 1로 강제됩니다.",
+       "apihelp-query+revisions+base-param-parse": "<kbd>[[Special:ApiHelp/parse|action=parse]]</kbd>를 ë\8c\80ì\8b  ì\82¬ì\9a©í\95\98ì\84¸ì\9a\94. í\8c\90 ë\82´ì\9a©ì\9d\84 í\8c\8cì\8b±합니다. ($1prop=content 필요) 성능 상의 이유로 이 옵션을 사용할 경우 $1limit은 1로 강제됩니다.",
        "apihelp-query+search-summary": "전문 검색을 수행합니다.",
        "apihelp-query+search-param-qiprofile": "쿼리 독립적인 프로파일 사용(순위 알고리즘에 영향있음)",
        "apihelp-query+search-paramvalue-prop-size": "바이트 단위로 문서의 크기를 추가합니다.",
        "apierror-cantsend": "로그인하지 않았거나 인증된 이메일 주소가 없거나 다른 사용자로 이메일을 보낼 권한이 없기 때문에 이메일을 보낼 수 없습니다.",
        "apierror-cantview-deleted-description": "삭제된 파일의 설명을 볼 권한이 없습니다.",
        "apierror-cantview-deleted-metadata": "삭제된 파일의 메타데이터를 볼 권한이 없습니다.",
+       "apierror-cantview-deleted-revision-content": "삭제된 판의 내용을 볼 권한이 없습니다.",
        "apierror-compare-maintextrequired": "<var>$1slots</var>에 <kbd>main</kbd>이 포함되어 있다면 <var>$1text-main</var> 변수는 필수입니다. (메인 슬롯을 삭제할 수 없습니다)",
        "apierror-compare-notext": "<var>$1</var> 변수는 <var>$2</var> 없이 사용할 수 없습니다.",
        "apierror-emptynewsection": "비어있는 새 문단을 만들 수 없습니다.",
index b4e483b..d7c5a85 100644 (file)
@@ -683,16 +683,21 @@ TXT;
         * This method must not assume the exception is an MWException,
         * it is also used to handle PHP exceptions or exceptions from other libraries.
         *
-        * @since 1.22
         * @param Exception|Throwable $e
         * @param string $catcher CAUGHT_BY_* class constant indicating what caught the error
+        * @param array $extraData (since 1.34) Additional data to log
+        * @since 1.22
         */
-       public static function logException( $e, $catcher = self::CAUGHT_BY_OTHER ) {
+       public static function logException( $e, $catcher = self::CAUGHT_BY_OTHER, $extraData = [] ) {
                if ( !( $e instanceof MWException ) || $e->isLoggable() ) {
                        $logger = LoggerFactory::getInstance( 'exception' );
+                       $context = self::getLogContext( $e, $catcher );
+                       if ( $extraData ) {
+                               $context['extraData'] = $extraData;
+                       }
                        $logger->error(
                                self::getLogNormalMessage( $e ),
-                               self::getLogContext( $e, $catcher )
+                               $context
                        );
 
                        $json = self::jsonSerializeException( $e, false, FormatJson::ALL_OK, $catcher );
index 1b0db73..a03455b 100644 (file)
@@ -1124,9 +1124,9 @@ class SpecialBlock extends FormSpecialPage {
         * @return bool
         */
        public static function canBlockEmail( UserIdentity $user ) {
-               global $wgEnableUserEmail, $wgSysopEmailBans;
+               global $wgEnableUserEmail;
 
-               return ( $wgEnableUserEmail && $wgSysopEmailBans && MediaWikiServices::getInstance()
+               return ( $wgEnableUserEmail && MediaWikiServices::getInstance()
                                ->getPermissionManager()
                                ->userHasRight( $user, 'blockemail' ) );
        }
index 13f2b52..d8e4985 100644 (file)
@@ -1,6 +1,7 @@
 <?php
 
 use MediaWiki\Linker\LinkTarget;
+use MediaWiki\Permissions\PermissionManager;
 use MediaWiki\Revision\RevisionRecord;
 use MediaWiki\User\UserIdentity;
 use Wikimedia\Assert\Assert;
@@ -70,16 +71,21 @@ class WatchedItemQueryService {
        /** @var WatchedItemStoreInterface */
        private $watchedItemStore;
 
+       /** @var PermissionManager */
+       private $permissionManager;
+
        public function __construct(
                ILoadBalancer $loadBalancer,
                CommentStore $commentStore,
                ActorMigration $actorMigration,
-               WatchedItemStoreInterface $watchedItemStore
+               WatchedItemStoreInterface $watchedItemStore,
+               PermissionManager $permissionManager
        ) {
                $this->loadBalancer = $loadBalancer;
                $this->commentStore = $commentStore;
                $this->actorMigration = $actorMigration;
                $this->watchedItemStore = $watchedItemStore;
+               $this->permissionManager = $permissionManager;
        }
 
        /**
@@ -549,7 +555,7 @@ class WatchedItemQueryService {
                return $conds;
        }
 
-       private function getUserRelatedConds( IDatabase $db, User $user, array $options ) {
+       private function getUserRelatedConds( IDatabase $db, UserIdentity $user, array $options ) {
                if ( !array_key_exists( 'onlyByUser', $options ) && !array_key_exists( 'notByUser', $options ) ) {
                        return [];
                }
@@ -566,9 +572,11 @@ class WatchedItemQueryService {
 
                // Avoid brute force searches (T19342)
                $bitmask = 0;
-               if ( !$user->isAllowed( 'deletedhistory' ) ) {
+               if ( !$this->permissionManager->userHasRight( $user, 'deletedhistory' ) ) {
                        $bitmask = RevisionRecord::DELETED_USER;
-               } elseif ( !$user->isAllowedAny( 'suppressrevision', 'viewsuppressed' ) ) {
+               } elseif ( !$this->permissionManager
+                       ->userHasAnyRight( $user, 'suppressrevision', 'viewsuppressed' )
+               ) {
                        $bitmask = RevisionRecord::DELETED_USER | RevisionRecord::DELETED_RESTRICTED;
                }
                if ( $bitmask ) {
@@ -578,13 +586,15 @@ class WatchedItemQueryService {
                return $conds;
        }
 
-       private function getExtraDeletedPageLogEntryRelatedCond( IDatabase $db, User $user ) {
+       private function getExtraDeletedPageLogEntryRelatedCond( IDatabase $db, UserIdentity $user ) {
                // LogPage::DELETED_ACTION hides the affected page, too. So hide those
                // entirely from the watchlist, or someone could guess the title.
                $bitmask = 0;
-               if ( !$user->isAllowed( 'deletedhistory' ) ) {
+               if ( !$this->permissionManager->userHasRight( $user, 'deletedhistory' ) ) {
                        $bitmask = LogPage::DELETED_ACTION;
-               } elseif ( !$user->isAllowedAny( 'suppressrevision', 'viewsuppressed' ) ) {
+               } elseif ( !$this->permissionManager
+                       ->userHasAnyRight( $user, 'suppressrevision', 'viewsuppressed' )
+               ) {
                        $bitmask = LogPage::DELETED_ACTION | LogPage::DELETED_RESTRICTED;
                }
                if ( $bitmask ) {
index 7d93d5b..6d48938 100644 (file)
        "createaccountmail": "استخدم كلمة سر عشوائية مؤقتة وارسلها إلى عنوان البريد الإلكتروني المحدد أدناه",
        "createaccountmail-help": "يمكن استخدامه لإنشاء حساب لشخص آخر من دون معرفة كلمة المرور.",
        "createacct-realname": "الاسم الحقيقي (اختياري)",
-       "createacct-reason": "السبب",
+       "createacct-reason": "السبب (مسجل بشكل عام)",
        "createacct-reason-ph": "لماذا تقوم بإنشاء حساب آخر",
        "createacct-reason-help": "رسالة تظهر في سجل إنشاء الحسابات",
        "createacct-submit": "افتح الحساب",
index b142bb5..60fa0a1 100644 (file)
        "minoredit": "Puniki uahan alit",
        "watchthis": "Awasin kaca puniki",
        "savearticle": "Raksa kaca",
-       "publishpage": "Terbitang kaca",
-       "publishchanges": "Wedah uahan",
+       "publishpage": "Wedar kaca",
+       "publishchanges": "Wedar uahan",
        "savearticle-start": "Raksa kaca...",
-       "publishpage-start": "Terbitang kaca…",
-       "publishchanges-start": "Wedah uahan...",
+       "publishpage-start": "Wedar kaca…",
+       "publishchanges-start": "Wedar uahan...",
        "preview": "Pracingak",
-       "showpreview": "Édengang pracingak",
+       "showpreview": "Édéngang pracingak",
        "showdiff": "Cingak uahan",
        "anoneditwarning": "<strong>Pingetan:</strong> Ida dané nénten kacatet ngranjing. Alamat IP ida dané jagi kacatet ring sejarah (indik sané dumunan) ring lembar puniki. Yening ida dane <strong>[$1 log in]</strong> utawi <strong>[$2 create an account]</strong>, your edits will be attributed to your username, along with other benefits.",
        "blockedtext": "<strong>Peséngan penganggé utawi genah IP ragané kablokir .</strong>\n\nBlokir puniki kalaksanayang olih $1.\nKablokir krana <em>$2</em>.\n\n* Kablokir saking: $8\n* Blokir kadaluwarsa ring: $6\n* Tetujon ngablokir: $7\n\nRagané dados ngubungin $1 utawi [[{{MediaWiki:Grouppage-sysop}}|prajuru]] antuk mabligbagin.\nRagané nénten dados nganggén fitur puniki \"{{int:emailuser}}\" sajabaning ragané sampun ngranjingang email sané patut ring [[Special:Preferences|pustaka]] tur ragané nénten kablokir antuk nganggén\nGenah IP ragané sané pinih anyar inggih punika $3, tur ID pamblokiran inggih punika #$5.\nTulung genahang silih sinunggil utawi kalih pidarta ring pitakén sané kakaryanin.",
index 5b83833..e875f19 100644 (file)
@@ -78,7 +78,7 @@
        "tog-norollbackdiff": "Peyser ardışi ra dıme ferqi measne",
        "tog-useeditwarning": "Wexto ke mı yew pela nizami be vurnayışanê nêqeydbiyayeyan caverdê, hay be mı ser de",
        "tog-prefershttps": "Ronışten akerden de tım greyo itimadın bıkarne",
-       "tog-requireemail": "Parolay reset kerdışi rê email lazıma",
+       "tog-requireemail": "Parolapeysernayene rê email lazımo",
        "underline-always": "Tım",
        "underline-never": "Qet",
        "underline-default": "Cild ya zi cı geyrayoğo hesebiyaye",
        "nstab-mediawiki": "Mesac",
        "nstab-template": "Şablon",
        "nstab-help": "Perra pasti",
-       "nstab-category": "Kategori",
+       "nstab-category": "Kategoriye",
        "mainpage-nstab": "Pera seri",
        "nosuchaction": "Fealiyeto wınasi çıniyo",
        "nosuchactiontext": "URL ra kar qebul nêbı.\nŞıma belka URL şaş nuşt, ya zi gıreyi şaş ra ameyi.\nKeyepelê {{SITENAME}} eşkeno xeta aşkera bıkero.",
        "virus-scanfailed": "cıgerayiş tamam nêbı (kod $1)",
        "virus-unknownscanner": "antiviruso ke nêzanyeno:",
        "logouttext": "'''Henda şıma hesab ra veciyay.'''\n\nDiqat kerê ke tayê perri şenê hewna zey şıma kewtê ra cı bıasê, heta şıma ver-virê şanekerê (browserê) xo besterê.",
-       "logging-out-notify": "Şıma yê abıriyenê, reca kem bıpawê",
+       "logging-out-notify": "Şımayê cı ra veciyê, kerem kerê bıpawên.",
        "logout-failed": "Enewke ronıştışo nêracneyêno:$1",
        "cannotlogoutnow-title": "Enewke ronıştışo nêracneyêno",
        "cannotlogoutnow-text": "Gurenayışê $1i de veciyayış mımkın niyo.",
        "rcfilters-filter-showlinkedfrom-label": "Gıreyê pelan ra vurnayışan bıvêne",
        "rcfilters-target-page-placeholder": "Yew nameyê pele (ya zi kategoriye) cı kerê",
        "rcfilters-allcontents-label": "Zerrek pêro",
-       "rcfilters-alldiscussions-label": "Werênayışi pero",
+       "rcfilters-alldiscussions-label": "Werênayışi pêro",
        "rcnotefrom": "Cêr de <strong>$2</strong> ra nata {{PLURAL:$5|vurnayışiyê}} asenê (tewr vêşi <strong>$1</strong> asenê) <strong>$3, $4</strong>",
        "rclistfromreset": "Weçinayışê tarixi ragoze",
        "rclistfrom": "$3 sehat $2 ra tepiya vurnayışanê neweyan bımotne",
        "undelete-search-title": "Bıgeyre pelanê eserıtiyan",
        "undelete-search-box": "bıgêr pelê hewn a biyayeyani",
        "undelete-search-prefix": "pel ê ke pê ney destpêkenî, ramocın",
-       "undelete-search-full": "Zerreki ra serniya pele bımocne",
+       "undelete-search-full": "Zerrekê sernameyanê pele bımocne:",
        "undelete-search-submit": "Cı geyre",
        "undelete-no-results": "Zerre arşîvê esterayîşî de peleyan match nibiyê.",
        "undelete-filename-mismatch": "Vurnayîşê ke pê wextê puli ye $1î nieşkenî biyare: nameyê dosyayî match nibeno",
        "ipb-confirm": "Bloke kerdışi tesdik ke",
        "ipb-sitewide": "Site hemi de",
        "ipb-partial": "Qısmi",
-       "ipb-partial-help": "Peli ya zi namey cayanê spesifikan",
+       "ipb-partial-help": "Peli ya zi nameyê cayanê spesifikan.",
        "ipb-pages-label": "Peli",
        "ipb-namespaces-label": "Heruna nameyan",
        "badipaddress": "Adresê IPî raşt niyo",
        "ipb-blocklist": "Blokî ke hama estê ey bivîne",
        "ipb-blocklist-contribs": "İştirakê {{GENDER:$1|$1}}`i",
        "ipb-blocklist-duration-left": "$1 vet",
-       "block-actions": "Hereketê bloqey :",
+       "block-actions": "Hereketê kıliti:",
        "block-expiry": "Qedyayış:",
-       "block-options": "Weçinıtış dekerê:",
+       "block-options": "Weçinıtışê vêşi:",
        "block-prevent-edit": "Vurnayış",
        "block-reason": "Sebeb:",
        "block-target": "Nameyê karberi ya zi adresa eposteyi",
        "unblocked": "[[User:$1|$1]] blok biyo",
        "unblocked-range": "Blokey $1'i wederya",
        "unblocked-id": "Blokê $1î wedariyayo",
-       "unblocked-ip": "[[Special:Contributions/$1|$1]] bloqe wedarnayo.",
+       "unblocked-ip": "Kılitê [[Special:Contributions/$1|$1]] dariyo we.",
        "blocklist": "Karberê kılitbiyayey",
        "autoblocklist": "Blokeyê otomatiki",
        "autoblocklist-submit": "Cı geyre",
        "autoblocklist-legend": "Lista blokanê otomatikan",
        "autoblocklist-localblocks": "{{PLURAL:$1|otoblokoyo lokal|otoblokeyê lokali}}",
-       "autoblocklist-total-autoblocks": "Amardışê pêroyê autobloqey:$1",
+       "autoblocklist-total-autoblocks": "Amarê kılitkerdışê xoseri pêro piya: $1",
        "autoblocklist-otherblocks": "{{PLURAL:$1|otobloqeyo bin|otobloqeyê bini}}",
        "ipblocklist": "Karberê kılitbiyayey",
        "ipblocklist-legend": "Karberê kılit biyayey bıvin",
        "javascripttest-qunit-intro": "Mediawiki.org dı [dokumanê $1] bıvinê.",
        "tooltip-pt-userpage": "Pela {{GENDER:|şımaya karberi}}",
        "tooltip-pt-anonuserpage": "pelê karberê IPyi",
-       "tooltip-pt-mytalk": "Pera {{GENDER:|şıma}}y vateni",
+       "tooltip-pt-mytalk": "Pela {{GENDER:|toya}} werênayışi",
        "tooltip-pt-anontalk": "'''Ena adresa IP ra vurnayışa sero qal bıqerê'''",
        "tooltip-pt-preferences": "Tercihê {{GENDER:|şıma}}",
        "tooltip-pt-watchlist": "Listey peranê ke to gırotê seyr kerdış",
        "watchlistedit-clear-legend": "Lista serykerdışê pak kerê",
        "watchlistedit-clear-explain": "Listeya serykerdış da şıma dı sernamey pêro besteryay",
        "watchlistedit-clear-titles": "Sernamey:",
-       "watchlistedit-clear-done": "Lista seyrkerdişê şıma biya pak",
+       "watchlistedit-clear-done": "Lista seyrkerdişê şıma biya pak.",
        "watchlisttools-clear": "Lista serykerdışê xo pak kı",
        "watchlisttools-view": "Vurnayışanê elaqedaran bıvêne",
        "watchlisttools-edit": "Lista seyrkerdışi bıvêne û bıvurne",
        "permanentlink-submit": "Şo revizyoni",
        "newsection": "Leteyo newe",
        "newsection-page": "Etiketê pele",
-       "newsection-submit": "Ravêr pele",
+       "newsection-submit": "Şo be pele",
        "dberr-problems": "Mayê muxulêm! Ena sita dı newke xırabiya teknik esta.",
        "dberr-again": "Dı-rê deqiqeyi vınde û heni bar ke.",
        "dberr-info": "(Erzmelumati ra xızmetkari nêreseno: $1)",
index 23871cd..73b2b7b 100644 (file)
        "exif-urgency": "Urgensy",
        "exif-fixtureidentifier": "Grupsname",
        "exif-locationdest": "Weadergeaven lokaty",
-       "exif-locationdestcode": "Kode veur de weeregeven lokasie",
-       "exif-objectcycle": "Tied van de dag waor de media veur bedoeld is",
-       "exif-contact": "Kontaktgegevens",
-       "exif-writer": "Schriever",
-       "exif-languagecode": "Taal",
-       "exif-iimversion": "IIM-versie",
-       "exif-iimcategory": "Kategorie",
-       "exif-iimsupplementalcategory": "Anvullende kategorieën",
-       "exif-datetimeexpires": "Niet te gebruken nao",
-       "exif-datetimereleased": "Uutebröcht op",
-       "exif-originaltransmissionref": "Oorspronkelike taaklokasiekode",
+       "exif-locationdestcode": "Kode vöär de weadergeaven lokaty",
+       "exif-objectcycle": "Tyd van de dag wår de media vöär bedoold is",
+       "exif-contact": "Kontaktgegeavens",
+       "exif-writer": "Skryver",
+       "exif-languagecode": "Språke",
+       "exif-iimversion": "IIM-versy",
+       "exif-iimcategory": "Kategory",
+       "exif-iimsupplementalcategory": "Anvüllende kategoryen",
+       "exif-datetimeexpires": "Neet te bruken nå",
+       "exif-datetimereleased": "Uutbröcht up",
+       "exif-originaltransmissionref": "Oorsprungelike språklokatykode",
        "exif-identifier": "ID",
-       "exif-lens": "Lenze die gebruukt wörden",
-       "exif-serialnumber": "Serienummer van de camera",
-       "exif-cameraownername": "Eigenaar van camera",
+       "exif-lens": "Brukede lense",
+       "exif-serialnumber": "Serynummer van de kamera",
+       "exif-cameraownername": "Eigenaar van kamera",
        "exif-label": "Etiket",
-       "exif-datetimemetadata": "Daotum waorop de metadata veur t lest bie-ewörken bin",
-       "exif-nickname": "Informele naam van de aofbeelding",
-       "exif-rating": "Werdering (op n schaole van 5)",
-       "exif-rightscertificate": "Rechtenbeheercertificaot",
-       "exif-copyrighted": "Auteursrechtstaotus",
-       "exif-copyrightowner": "Auteursrechtenhouwer",
-       "exif-usageterms": "Gebruuksveurweerden",
-       "exif-webstatement": "Internetauteursrechverklaoring",
-       "exif-originaldocumentid": "Uniek ID van t originele dokument",
-       "exif-licenseurl": "Webadres veur auteursrechlisensie",
-       "exif-morepermissionsurl": "Alternatieve lisensiegegevens",
-       "exif-attributionurl": "Gebruuk de volgende verwiezing bie hergebruuk van dit wark",
-       "exif-preferredattributionname": "Gebruuk de volgende makersvermelding bie hergebruuk van dit wark",
+       "exif-datetimemetadata": "Dåtum wårup de metadata vöär et lätst bywarked is",
+       "exif-nickname": "Informele name van de afbealding",
+       "exif-rating": "Wardering (up en skale van 5)",
+       "exif-rightscertificate": "Rechtenbeheyrcertifikaat",
+       "exif-copyrighted": "Autöörsrechtenståtus",
+       "exif-copyrightowner": "Autöörsrechtenholder",
+       "exif-usageterms": "Bruuksbeding",
+       "exif-webstatement": "Binnennetse autöörsrechtenverklåring",
+       "exif-originaldocumentid": "Unik ID van et originele dokument",
+       "exif-licenseurl": "Webadres vöär autöörsrechtenlicensy",
+       "exif-morepermissionsurl": "Alternative licensygegeavens",
+       "exif-attributionurl": "Bruuk de volgende verwysing as dit wark herbruked wördt",
+       "exif-preferredattributionname": "Bruuk de volgende makersvermelding as dit wark herbruked wördt",
        "exif-pngfilecomment": "Opmarking bie PNG-bestaand",
        "exif-disclaimer": "Vöärbehold",
        "exif-contentwarning": "Waorschuwing over inhoud",
index 2cd71f0..6c5d8b5 100644 (file)
        "createaccountmail": "Utiliser un mot de passe aléatoire temporaire et l’envoyer à l’adresse de courriel spécifiée",
        "createaccountmail-help": "Peut être utilisé pour créer un compte pour une autre personne sans connaître le mot de passe.",
        "createacct-realname": "Nom réel (facultatif)",
-       "createacct-reason": "Motif",
+       "createacct-reason": "Motif (connecté publiquement)",
        "createacct-reason-ph": "Pourquoi créez-vous un autre compte",
        "createacct-reason-help": "Message affiché dans le journal de création de compte",
        "createacct-submit": "Créez votre compte",
index f31034c..a00e5fb 100644 (file)
        "accountcreated": "Akun wis kagawé",
        "accountcreatedtext": "Akun panganggo [[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|rembug]]) wis digawé.",
        "createaccount-title": "Gawé akun kanggo {{SITENAME}}",
-       "createaccount-text": "Ana kang nggawé akun nganggo alamat layang-èlé panjenengan ing {{SITENAME}} ($4) kanthi aran \"$2\", mawa tembung wadi \"$3\".\nPanjenengan kudu mlebu log lan ngowahi tembung wadiné panjenengan saiki.\n\nPanjenengan kena nglirwakaké layang iki, manawa akun iki ginawé awit kaluputan.",
+       "createaccount-text": "Ana kang nggawé akun nganggo alamat layang èlèktronikmu ing {{SITENAME}} ($4) aran \"$2\", mawa tembung wadi \"$3\".\nKowé kudu mlebu log lan ngowahi tembung wadimu saiki.\n\nKowé kena nglirwakaké layang iki, manawa akun iki kagawé ora sengaja amarga luput.",
        "login-throttled": "Kowé wis njajal mlebu log ping akèh.\nEntènana $1 sadurung njajal manèh.",
        "login-abort-generic": "Kowé ora bisa mlebu log - Kawurungaké",
        "login-migrated-generic": "Akunmu wis ingalihan, lan jeneng panganggomu wis ora ana manèh ing wiki iki.",
        "loginlanguagelabel": "Basa: $1",
        "suspicious-userlogout": "Panjalukmu supaya metu log tinulak amarga panjaluké kakirim saka pangluru kang rusak utawa proksi telih.",
-       "createacct-another-realname-tip": "Jeneng asli ora kudu diisi.\nYèn diisi, jeneng asliné panjenengan bakal kanggo atribusi awit karyané panjenengan.",
+       "createacct-another-realname-tip": "Jeneng asli ora kudu kaisi.\nYèn koisi, jeneng asliné bakal kaanggo ing atribusi tumrap karyané.",
        "pt-login": "Mlebu log",
        "pt-login-button": "Mlebu log",
        "pt-login-continue-button": "Banjuraké mlebu log",
        "user-mail-no-addy": "Njajal ngirim layang èlèktronik tanpa alamat layang èlèktronik.",
        "user-mail-no-body": "Nyoba ngirim layang e-mail, tapi isine kosong.",
        "changepassword": "Ganti tembung wadi",
-       "resetpass_announce": "Saperlu ngrampungaké olèhé mlebu log, panjenengan kudu nggawé tembung wadi anyar.",
+       "resetpass_announce": "Saperlu ngrampungaké olèhé mlebu log, kowé kudu nggawé tembung wadi anyar.",
        "resetpass_text": "<!-- Tambahaké teks ing kéné -->",
        "resetpass_header": "Ganti tembung wadining akun",
        "oldpassword": "Tembung wadi lawas:",
        "newpassword": "Tembung wadi anyar:",
        "retypenew": "Isi manèh tembung wadi anyaré:",
        "resetpass_submit": "Setèl tembung wadi lan mlebu log",
-       "changepassword-success": "Tembung wadiné panjenengan kasil diowah!",
-       "changepassword-throttled": "Panjenengan wis kakèhan njajal mlebu log.\nTulung nunggu dhisik $1 sadurungé njajal manèh.",
+       "changepassword-success": "Tembung wadimu bisa ingowahan!",
+       "changepassword-throttled": "Kowé wis njajal mlebu log ping akèh.\nEntènana $1 sadurung njajal manèh.",
        "botpasswords": "Tembung wadi bot",
        "botpasswords-disabled": "Tembung wadiné bot dipatèni.",
-       "botpasswords-no-central-id": "Saperlu nganggo tembung wadiné bot, panjenengan kudu mlebu log menyang akun séntral.",
+       "botpasswords-no-central-id": "Saperlu nganggo tembung wadiné bot, kowé kudu mlebu log akun séntral.",
        "botpasswords-existing": "Tembung wadiné bot kang cumepak",
        "botpasswords-createnew": "Gawé anyar tembung wadiné bot",
        "botpasswords-editexisting": "Besut tembung wadiné bot kang anyar",
-       "botpasswords-label-needsreset": "(tembung wadi kudu panjenengan ambali setèl)",
+       "botpasswords-label-needsreset": "(tembung wadi kudu kasetèl ulang)",
        "botpasswords-label-appid": "Jeneng bot:",
        "botpasswords-label-create": "Gawé",
        "botpasswords-label-update": "Anyari",
        "botpasswords-bad-appid": "Jeneng bot \"$1\" ora trep.",
        "botpasswords-insert-failed": "Wurung nambah jeneng bot \"$1\". Apa wis tinambahaké sadurungé?",
        "resetpass_forbidden": "Tembung wadi ora bisa diganti",
-       "resetpass-no-info": "Panjenengan kudu mlebu log saperlu langsung ngaksès kaca iki.",
+       "resetpass-no-info": "Kowé kudu mlebu log saperlu ngaksès kaca iki langsung.",
        "resetpass-submit-loggedin": "Ganti tembung wadi",
        "resetpass-submit-cancel": "Wurung",
-       "resetpass-wrong-oldpass": "Tembung wadi saiki utawa sauntara ora trep.\nPanjengen bokmanawa wis ngganti tembung wadiné panjenengan utawa nyuwun tembung wadi sauntara kang anyar.",
+       "resetpass-wrong-oldpass": "Tembung wadi saiki utawa sadhéla ora trep.\nKowé bokmanawa wis ngganti tembung wadimu utawa njaluk tembung wadi sadhéla kang anyar.",
        "resetpass-temp-password": "Tembung wadi sauntara:",
        "resetpass-abort-generic": "Ngowahi tembung wadi kawurungaké déning èkstènsi.",
        "resetpass-expired": "Tembung wadimu wis kadaluwarsa. Setèl tembung wadi anyar saperlu mlebu log.",
        "userrights-reason": "Alesan:",
        "userrights-no-interwiki": "Panjenengan ora ana hak kanggo ngowahi hak panganggo ing wiki liyané.",
        "userrights-nodatabase": "Basis dhatah $1 ora ana utawa ora enggonan.",
-       "userrights-changeable-col": "Grup kang bisa panjenengan owahi",
-       "userrights-unchangeable-col": "Grup kang ora bisa diowahi panjenengan",
+       "userrights-changeable-col": "Golongan kang bisa koowahi",
+       "userrights-unchangeable-col": "Golongan kang ora bisa koowahi",
        "userrights-irreversible-marker": "$1*",
        "userrights-no-shorten-expiry-marker": "$1#",
        "userrights-expiry-current": "Kadaluwarsa $1",
        "userrights-expiry-options": "1 dina:1 dina,1 minggu:1 minggu,1 wulan:1 wulan,3 wulan:3 wulan,6 wulan:6 wulan,1 taun:1 taun",
        "userrights-invalid-expiry": "Wektu kadaluwarsa golongan \"$1\" ora trep.",
        "userrights-expiry-in-past": "Wektu kadaluwarsa golongan \"$1\" ana ing kala kawuri.",
-       "userrights-conflict": "Konflik pangowahan hak-hak panganggo! Tulung ditinjau maneh lan konfirmasi owah-owahané panjenengan.",
+       "userrights-conflict": "Cengkah owahan hak panganggo! Mangga priksa lan konfirmasi owahanmu.",
        "group": "Golongan:",
        "group-user": "Para panganggo",
        "group-autoconfirmed": "Panganggo kang otomatis kakonfirmasi",
        "right-editmyusercss": "Besut berkas CSS panganggomu",
        "right-editmyuserjson": "Besut berkas JSON panganggomu",
        "right-editmyuserjs": "Besut berkas JavaScript panganggomu",
-       "right-viewmywatchlist": "Deleng pawawangané panjenengan",
+       "right-viewmywatchlist": "Deleng pawawanganmu",
        "right-editmywatchlist": "Owahi pawawangané panjenengan. Cathetan: ana cara liyane kanggo nambahi kaca menyang pratélan, sanadyan ora duwe hak iki.",
        "right-viewmyprivateinfo": "Deleng dhata prianggané panjenengan dhéwé (kaya ta alamat layang-èl, jeneng asli)",
        "right-editmyprivateinfo": "Besut dhata prianggané panjenengan dhéwé (kaya ta alamat layang-èl, jeneng asli)",
-       "right-editmyoptions": "Owahi pilalané panjenengan",
+       "right-editmyoptions": "Besut pilalanmu dhéwé",
        "right-rollback": "Balèkaké kanthi gelis besutaning panganggo pungkasan kang mbesut kaca tinamtu",
        "right-markbotedits": "Tandhani besutan kang kawurungan yèn besutan bot",
        "right-noratelimit": "Ora kadayan watesing cacah besutan.",
        "right-sendemail": "Ngirim layang listrik (e-mail) menyang panganggo liya",
        "grant-group-page-interaction": "Srawungan karo kaca",
        "grant-group-file-interaction": "Srawungan karo médhia",
-       "grant-group-watchlist-interaction": "Srawungan karo pawawangané panjenengan",
+       "grant-group-watchlist-interaction": "Srawung karo pawawanganmu",
        "grant-group-email": "Kirim layang-èl",
        "grant-group-high-volume": "Ngayahi kagiyatan kang akih",
        "grant-group-customization": "Panglarasan lan pilalan",
        "grant-group-administration": "Ngayahi laku administratif",
-       "grant-group-private-information": "Ngaksès dhata pribadhi ngenani panjenengan",
+       "grant-group-private-information": "Aksès dhatah pribadi bab kowé",
        "grant-group-other": "Kagiyatan rena-rena",
        "grant-blockusers": "Blokir lan uculaké blokirané panganggo",
        "grant-createaccount": "Gawé akun",
        "grant-editinterface": "Besut jagad aran MediaWiki lan CSS/JavaScript panganggo",
        "grant-editmycssjs": "Besut CSS/JavaScript panganggomu",
        "grant-editmyoptions": "Besut préferènsi panganggomu",
-       "grant-editmywatchlist": "Besut pawawangané panjenengan",
+       "grant-editmywatchlist": "Besut pawawangmu",
        "grant-editpage": "Besut kaca kang ana",
        "grant-editprotected": "Besut kaca kang kareksa",
        "grant-highvolume": "Besutan gedhi",
        "grant-uploadfile": "Unggah berkas anyar",
        "grant-basic": "Hak pokok",
        "grant-viewdeleted": "Deleng berkas lan kaca kang kabusek",
-       "grant-viewmywatchlist": "Deleng pawawangané panjenengan",
+       "grant-viewmywatchlist": "Deleng pawawanganmu",
        "grant-viewrestrictedlogs": "Deleng isian log kang winates",
        "newuserlogpage": "Log panganggo anyar",
        "newuserlogpagetext": "Ing ngisor iki kapacak log pandaftaran panganggo anyar.",
        "action-import": "impor kaca saka wiki liyané",
        "action-importupload": "impor kaca saka unggahan berkas",
        "action-patrol": "nandhani besutan wong liya yèn wis kapriksa",
-       "action-autopatrol": "nandhani besutané panjenengan dhéwé yèn wis kapriksa",
+       "action-autopatrol": "nandhani besutanmu yèn wis kapriksa",
        "action-unwatchedpages": "deleng pratélan kaca kang ingawasan",
        "action-mergehistory": "nggabungaké sajarah kaca iki",
        "action-userrights": "besut kabèh hak panganggo",
        "action-userrights-interwiki": "besut hak aksès panganggo ing wiki liyané",
        "action-siteadmin": "nggembok utawa mbukak gembok basis dhatah",
        "action-sendemail": "kirim layang-èl",
-       "action-editmyoptions": "besut pilalané panjenengan",
-       "action-editmywatchlist": "owahi pawawangané panjenengan",
+       "action-editmyoptions": "besut pilalanmu",
+       "action-editmywatchlist": "besut pawawanganmu",
        "action-viewmywatchlist": "deleng pawawangané panjenengan",
        "action-viewmyprivateinfo": "deleng katerangan prianggané panjenengan",
        "action-editmyprivateinfo": "besut katerangan prianggané panjenengan",
        "rcfilters-filterlist-noresults": "Saringan ora katemu",
        "rcfilters-noresults-conflict": "Ora ana kasil amarga wewatoné kanggo nggolèk ana masalah",
        "rcfilters-filtergroup-authorship": "Pangripta besutan",
-       "rcfilters-filter-editsbyself-label": "Owah-owahané panjenengan",
+       "rcfilters-filter-editsbyself-label": "Owah-owahanmu",
        "rcfilters-filter-editsbyself-description": "Pasumbangmu dhéwé.",
        "rcfilters-filter-editsbyother-label": "Owah-owahané liyan",
-       "rcfilters-filter-editsbyother-description": "Kabèh owahan kajaba duwèké panjenengan.",
+       "rcfilters-filter-editsbyother-description": "Kabèh owahan kajaba duwému.",
        "rcfilters-filtergroup-user-experience-level": "Pandhaftaran lan pangalaman pangguna",
        "rcfilters-filter-user-experience-level-registered-label": "Kadhaftar",
        "rcfilters-filter-user-experience-level-registered-description": "Pambesut kang mlebu log.",
        "rcfilters-filter-major-description": "Besutan kang ora ditandhani minangka besutan cilik.",
        "rcfilters-filtergroup-watchlist": "Kaca ing pawawangan",
        "rcfilters-filter-watchlist-watched-label": "Ana ing Pawawangan",
-       "rcfilters-filter-watchlist-watched-description": "Owahané kaca-kaca ing Pawawangané panjenengan.",
+       "rcfilters-filter-watchlist-watched-description": "Owahaning kaca-kaca ing Pawawanganmu.",
        "rcfilters-filter-watchlist-watchednew-label": "Owah-owahané Pawawangan anyar",
        "rcfilters-filter-watchlist-watchednew-description": "Owah-owahan ngenani kaca-kaca ing Pawawangané panjenengan kang durung ditiliki.",
        "rcfilters-filter-watchlist-notwatched-label": "Ora ana ing Pawawangan",
        "filetype-unwanted-type": "<strong>\".$1\"</strong> iku jinis barkas kang ora kapéngini.\nAluwung {{PLURAL:$3|jinis barkasé}} $2.",
        "filetype-banned-type": "<strong>\".$1\"</strong> {{PLURAL:$4|dudu jinis barkas kang diidinaké}}.\n{{PLURAL:$3|Jinis barkas}} kang diidinaké $2.",
        "filetype-missing": "Barkas ini ora duwé ekstènsi (contoné \".jpg\").",
-       "empty-file": "Barkas kang panjenengan lebokaké kosong.",
-       "file-too-large": "Barkas kang panjenengan lebokaké kagedhèn.",
+       "empty-file": "Berkas kang kolebokaké kosong.",
+       "file-too-large": "Berkas kang kolebokaké kegedhèn.",
        "filename-tooshort": "Jeneng barkas kecendhèken.",
        "filetype-banned": "Barkas jinis iki dilarang.",
        "verification-error": "Barkas iki ora lulus vèrifikasi.",
-       "hookaborted": "Owahan kang panjenengan ayahi diwurungaké déning èkstènsi.",
+       "hookaborted": "Olèhmu ndandani diwurungaké èstènsi.",
        "illegal-filename": "Jeneng barkas ora diidinaké.",
        "overwrite": "Nibani barkas kang wis ana ora dililakaké.",
        "unknown-error": "Ana masalah kang ora dingertèni.",
        "tmp-write-error": "Ora bisa nulis barkas sauntara.",
        "large-file": "Ukuran barkas disaranaké supaya ora ngluwihi $1 bita; barkas iki ukurané $2 bita.",
        "largefileserver": "Barkas iki luwih gedhé tinimbang kang diidinaké ing paladèn.",
-       "emptyfile": "Barkas kang panjenengan unggahaké katoné kosong. Bokmanawa iki amarga anané salah ketik ing jeneng barkas. Mangga dipastèkaké apa panjenengan pancèn kersa ngunggahaké barkas iki.",
+       "emptyfile": "Berkas kang kounggah katon kosong.\nBokmanawa ana salah tik ing aran berkasé.\nMangga pesthèkaké yèn kowé pancèn péngin ngunggah berkas iki.",
        "windows-nonascii-filename": "Wiki iki ora nyengkuyung jeneng berkas mawa karakter kusus.",
        "fileexists": "Barkas mawa jeneng iku wis ana, mangga dipriksa <strong>[[:$1]]</strong> yèn panjenengan ora yakin sumedya ngowahiné.\n[[$1|thumb]]",
        "filepageexists": "Kaca dhèskripsi kanggo berkas iki wis digawé ing <strong>[[:$1]]</strong>, nanging saiki iki ora tinemu berkas mawa jeneng iku. Ringkesan kang panjenengan lebokaké ora bakal metu ing kaca dhèskripsi. Kanggo ngetokaké dhèskripsi iki, panjenengan kudu mbesut kanthi manual. [[$1|thumb]]",
index 769891d..2068d7a 100644 (file)
        "tog-useeditwarning": "바꾼 내용을 저장하지 않고 편집 페이지를 벗어날 때 내게 알리기",
        "tog-prefershttps": "로그인하는 동안 항상 보안 연결 사용",
        "tog-showrollbackconfirmation": "되돌리기 링크를 클릭할 때 확인창을 표시",
+       "tog-requireemail": "비밀번호 재설정을 위한 이메일 필요",
        "underline-always": "항상",
        "underline-never": "항상 긋지 않기",
        "underline-default": "스킨 또는 브라우저 기본값",
        "createaccountmail": "임의의 임시 비밀번호를 이메일로 보내기",
        "createaccountmail-help": "비밀번호를 기억하지 않고도 다른 사용자를 위한 계정을 만들 수 있습니다.",
        "createacct-realname": "실명 (선택 사항)",
-       "createacct-reason": "이유",
+       "createacct-reason": "이유 (기록은 공개됨)",
        "createacct-reason-ph": "다른 계정을 만들어야 하는 이유가 있나요",
        "createacct-reason-help": "계정 생성 로그에 표시되는 메시지",
        "createacct-submit": "계정 만들기",
index 643e52f..a5b82ce 100644 (file)
        "createaccountmail": "En temporäert zoufällegt Passwuert benotzen an et per E-Mail un déi spezifizéiert E-Mailadress schécken",
        "createaccountmail-help": "Ka benotzt gi fir e Benotzerkont fir eng aner Persoun unzeleeën ouni d'Passwuert gewuer ze ginn.",
        "createacct-realname": "Richtegen Numm (fakultativ)",
-       "createacct-reason": "Grond",
+       "createacct-reason": "Grond (ëffentlech geloggt)",
        "createacct-reason-ph": "Fir wat Dir een anere Benotzerkonnt uleet",
        "createacct-reason-help": "Message deen am Logbuch vun den ugeluechte Benotzerkonte gewise gëtt",
        "createacct-submit": "Äre Benotzerkont uleeën",
index 5924ed2..0ef842a 100644 (file)
        "cannotchangeemail": "郵址不可更於此wiki",
        "emaildisabled": "是站不可遣函也。",
        "accountcreated": "簿增矣",
-       "accountcreatedtext": "[[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|書]])簿增矣。",
+       "accountcreatedtext": "[[{{ns:User}}:$1|$1]]([[{{ns:User talk}}:$1|書]])簿增矣。",
        "createaccount-title": "於{{SITENAME}}增簿",
        "createaccount-text": "有人以汝電郵於{{SITENAME}}增簿。簿名為 \"$2\" ($4)。符節為 \"$3\" 。汝應登而更符節。\n\n如簿誤增,汝可略之。",
        "login-throttled": "汝嘗登簿甚矣。\n請候 $1 而試之。",
index fef0de8..b7e3c12 100644 (file)
        "rollbacklinkcount": "{{PLURAL:$1|တည်းဖြတ်မှု|တည်းဖြတ်မှုများ}} $1 ကို နောက်ပြန်ပြင်ရန်",
        "rollbacklinkcount-morethan": "$1 ထက်ပိုသော {{PLURAL:$1|တည်းဖြတ်မှု|တည်းဖြတ်မှုများ}}ကို နောက်ပြန်ပြင်ရန်",
        "rollbackfailed": "နောက်ပြန်ပြင်ခြင်း မအောင်မြင်ခဲ့ပါ။",
+       "cantrollback": "နောက်ပြန်မပြင်နိုင်ပါ၊ နောက်ဆုံးပံ့ပိုးသူမှာ ဤစာမျက်နှာ၏ တစ်ဦးတည်းသော စာရေးသူဖြစ်ပါသည်။",
        "editcomment": "တည်းဖြတ်မှု အကျဉ်းချုပ်မှာ: <em>$1</em>။",
        "revertpage": "[[Special:Contributions/$2|$2]] ([[User talk:$2|ဆွေးနွေး]]) ၏ ပြင်ဆင်မှုများကို [[User:$1|$1]] ၏ နောက်ဆုံးတည်းဖြတ်မူသို့ နောက်ပြန် ပြန်ပြင်ခဲ့သည်",
+       "rollback-success": "{{GENDER:$3|$1}} မှ နောက်ပြန်ပြင်ခဲ့သည်၊  {{GENDER:$4|$2}} ၏ နောက်ဆုံးမူသို့ ပြန်ပြောင်းခဲ့သည်။",
        "changecontentmodel": "စာမျက်နှာ၏ မာတိကာမော်ဒယ်ကို ပြောင်းလဲရန်",
        "changecontentmodel-legend": "မာတိကာမော်ဒယ်ကို ပြောင်းလဲရန်",
        "changecontentmodel-title-label": "စာမျက်နှာ ခေါင်းစဉ်",
index 3365b11..be1c459 100644 (file)
        "tool-link-userrights": "Càgna gruppe {{GENDER:$1|utente}}",
        "tool-link-userrights-readonly": "Vire gruppe {{GENDER:$1|utente}}",
        "tool-link-emailuser": "Manna na masciata email a st'{{GENDER:$1|utente}}",
-       "imagepage": "Vere a paggena d' 'o file",
-       "mediawikipage": "Vere 'a mmasciata",
-       "templatepage": "Vere 'o template",
-       "viewhelppage": "Vere 'a paggena 'e ajùto",
-       "categorypage": "Vere 'a categurìa",
+       "imagepage": "Vire 'a paggena d' 'o file",
+       "mediawikipage": "Vire 'a mmasciata",
+       "templatepage": "Vire 'o template",
+       "viewhelppage": "Vire 'a paggena 'e ajùto",
+       "categorypage": "Vire 'a categurìa",
        "viewtalkpage": "Vere 'a paggena 'e chiàcchierate",
        "otherlanguages": "Ate lengue",
        "redirectedfrom": "(Redirect 'a $1)",
        "youhavenewmessagesmulti": "Tiene nuove mmasciate $1",
        "editsection": "càgna",
        "editold": "càgna",
-       "viewsourceold": "vere sorgente",
+       "viewsourceold": "vire sorgente",
        "editlink": "càgna",
        "viewsourcelink": "Vire sorgente",
        "editsectionhint": "Modifica a sezzione $1",
        "perfcachedts": "'E ddate ca stanno ccà songhe asciute 'a na copia \"cache\" d' 'o database, 'o cuale tene l'úrdemo agghiurnamento 'o $1. Nu massimo 'e {{PLURAL:$4|unu risultato è|$4 risultate songhe}} a disposizione dint'a \"cache\".",
        "querypage-no-updates": "Ll'agghiurnamente pe' sta paggena songo sospese mmo'. 'E ddate cuntenute ccà nun s'agghiurnarranno.",
        "viewsource": "Vere sorgente",
-       "viewsource-title": "Vere surgente 'e $1",
+       "viewsource-title": "Vire surgente 'e $1",
        "actionthrottled": "Azione ritardata",
        "actionthrottledtext": "Comme mesùra anti-abuse, site lemmetato 'a ffà st'azione troppe vote dint'a nu curto spazio 'e tiempo, e mo stu lèmmeto l'avite superato.\nPe piacere pruvate n'ata vota dint'a quacche minuto.",
        "protectedpagetext": "Sta paggena s'è prutetta pe ne ntuppà 'o càgno o quacche ata azione.",
        "next-page": "paggena aroppo",
        "prevn-title": "{{PLURAL:$1|Risultato precediente|$1 risultate precedenti}}",
        "nextn-title": "{{PLURAL:$1|Risultato successivo|$1 risultate successive}}",
-       "shown-title": "Fa vere {{PLURAL:$1|'nu risultato|$1 risultate}} ppe paggena",
-       "viewprevnext": "Vere($1 {{int:pipe-separator}} $2) ($3).",
+       "shown-title": "Fa verè {{PLURAL:$1|nu risultato|$1 risultate}} pe paggena",
+       "viewprevnext": "Vire ($1 {{int:pipe-separator}} $2) ($3).",
        "searchmenu-exists": "'''Ncopp' 'o sito esiste na paggena c' 'o nomme \"[[:$1]]\"'''\n{{PLURAL:$2|0=|Vedite pure dint'a l'ati risultate 'e cerca.}}",
        "searchmenu-new": "<strong>'''Crèa 'a paggena \"[[:$1]]\" ncopp'a stu wiki!'''</strong> {{PLURAL:$2|0=|Vedite pure 'a paggena truvata c' 'a recerca vuosta|Vedite pure 'e risultate d\"a recerca}}",
        "searchprofile-articles": "Paggene 'e contenute",
        "tooltip-ca-talk": "Vide 'e chiacchere rilative a chesta paggena",
        "tooltip-ca-edit": "Cagna sta paggena",
        "tooltip-ca-addsection": "Cummincia 'na nova sezzione",
-       "tooltip-ca-viewsource": "Chista paggena è prutetta, ma puo vere 'o codice sorgente",
+       "tooltip-ca-viewsource": "Chista paggena è prutetta, ma può verè 'o codice sorgente",
        "tooltip-ca-history": "Vversione 'e primma 'e chesta paggena",
        "tooltip-ca-protect": "Prutegge chesta paggena",
        "tooltip-ca-unprotect": "Càgna 'a prutezzione 'e chesta paggena",
        "tooltip-t-specialpages": "Lista 'e tutte e paggene speciale",
        "tooltip-t-print": "Vversione pe stampà 'a chesta paggena",
        "tooltip-t-permalink": "Jonta permanente a chesta vversione dda paggena",
-       "tooltip-ca-nstab-main": "Vere a paggena e contenuto",
-       "tooltip-ca-nstab-user": "Vere a paggena utente",
+       "tooltip-ca-nstab-main": "Vire 'a paggena 'e contenuto",
+       "tooltip-ca-nstab-user": "Vire 'a paggena utente",
        "tooltip-ca-nstab-media": "Vide 'a pàggena d' 'e media",
        "tooltip-ca-nstab-special": "Chesta è 'na paggena speciale e nun può essere càgnata",
-       "tooltip-ca-nstab-project": "Vere a paggena 'e servizio",
+       "tooltip-ca-nstab-project": "Vire 'a paggena 'e servizio",
        "tooltip-ca-nstab-image": "Vere a paggena ddo file",
        "tooltip-ca-nstab-mediawiki": "Vide 'a mmasciata d' 'o sistema",
-       "tooltip-ca-nstab-template": "Vere 'o modello",
+       "tooltip-ca-nstab-template": "Vire 'o modello",
        "tooltip-ca-nstab-help": "Vide 'a paggena d'aiuto",
-       "tooltip-ca-nstab-category": "Vere a paggena d\"a categurìa",
+       "tooltip-ca-nstab-category": "Vire 'a paggena d' 'a categurìa",
        "tooltip-minoredit": "Rénne chìsto cagnamiénto cchiù ppiccirìllo.",
        "tooltip-save": "Sàrva 'e cagnamiénte.",
        "tooltip-publish": "Pubbreca 'e cagnamiente vuoste",
index 2607b72..e2a6854 100644 (file)
        "createaccountmail": "Gebruik een tijdelijk willekeurig wachtwoord en stuur het naar het opgegeven e-mailadres",
        "createaccountmail-help": "Kan worden gebruikt voor het aanmaken van een account voor een andere persoon zonder het wachtwoord te vernemen.",
        "createacct-realname": "Echte naam (optioneel)",
-       "createacct-reason": "Reden",
+       "createacct-reason": "Reden (door iedereen te zien)",
        "createacct-reason-ph": "Waarom u een ander account aanmaakt",
        "createacct-reason-help": "Weergegeven bericht in het logbestand van aangemaakte gebruikers",
        "createacct-submit": "Uw account aanmaken",
index 069fc5a..048e5f1 100644 (file)
        "createaccountmail": "Użyj tymczasowego hasła wygenerowanego losowo i wyślij je na podany adres e-mail",
        "createaccountmail-help": "Pozwala utworzyć konto dla innej osoby, nie znając jej hasła.",
        "createacct-realname": "Prawdziwe imię i nazwisko (opcjonalnie)",
-       "createacct-reason": "Powód",
+       "createacct-reason": "Powód (podawany publicznie)",
        "createacct-reason-ph": "Dlaczego zakładasz kolejne konto",
        "createacct-reason-help": "Komunikat wyświetlany w rejestrze tworzenia kont",
        "createacct-submit": "Utwórz konto",
index 622ab51..8732554 100644 (file)
        "createaccountmail": "Usar uma senha aleatória e temporária que será enviada ao endereço de e-mail especificado a seguir",
        "createaccountmail-help": "Pode ser utilizado para criar uma conta para outra pessoa sem saber a senha.",
        "createacct-realname": "Nome real (opcional)",
-       "createacct-reason": "Motivo",
+       "createacct-reason": "Motivo (entrado publicamente)",
        "createacct-reason-ph": "Por que você está criando outra conta",
        "createacct-reason-help": "Mensagem mostrada no registro de criação de conta",
        "createacct-submit": "Crie sua conta",
index b7c17dc..7b56d69 100644 (file)
        "createaccountmail": "Ause 'na passuord temboranèe a uecchije e mannale a l'indirizze email specificate",
        "createaccountmail-help": "Pò essere ausate pe ccrejà 'n'utende pe 'n'otre crestiane senze ca adda canoscere 'a passuord.",
        "createacct-realname": "Nome vere (opzionale)",
-       "createacct-reason": "Mutive",
+       "createacct-reason": "Mutive (archiviate pubblecamende)",
        "createacct-reason-ph": "Purcé tu ste ccreje 'n'otre cunde utende?",
        "createacct-reason-help": "Messàgge 'ndrucate jndr'à l'archivije d'a ccrejazzione de le utinde",
        "createacct-submit": "Ccreje 'u cunde utende tune",
index f4154b6..42af915 100644 (file)
        "cannotchangeemail": "此 wiki 無法變更帳號的電子郵件地址。",
        "emaildisabled": "此網站不能傳送電子郵件。",
        "accountcreated": "已建立帳號",
-       "accountcreatedtext": "使用者帳號 [[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|討論]]) 已建立。",
+       "accountcreatedtext": "使用者帳號[[{{ns:User}}:$1|$1]]([[{{ns:User talk}}:$1|討論]])已建立。",
        "createaccount-title": "{{SITENAME}} 的帳號建立",
        "createaccount-text": "不明人士使用您的電子郵件地址在 {{SITENAME}} ($4) 建立了一個帳號名稱為 \"$2\",密碼為 \"$3\"。\n您應該立即登入並更改密碼。\n\n如果該帳號是建立錯誤的話,您可以忽略此訊息。",
        "login-throttled": "您已經嘗試太多次的登入動作。\n請稍等 $1 後再試。",
        "upload-preferred": "建議的檔案類型:$1。",
        "upload-prohibited": "禁止的檔案類型:$1。",
        "uploadlogpage": "上傳日誌",
-       "uploadlogpagetext": "以下清單為最近上傳的檔案。\n請檢視 [[Special:NewFiles|最新檔案圖庫]] 以視覺化的方式檢視。",
+       "uploadlogpagetext": "以下清單為最近上傳的檔案。以視覺化的方式檢視請見[[Special:NewFiles|最新檔案圖庫]]。",
        "filename": "檔案名稱",
        "filedesc": "摘要",
        "fileuploadsummary": "摘要:",
diff --git a/maintenance/cleanupRevActorPage.php b/maintenance/cleanupRevActorPage.php
new file mode 100644 (file)
index 0000000..ac655fc
--- /dev/null
@@ -0,0 +1,77 @@
+<?php
+
+require_once __DIR__ . '/Maintenance.php';
+
+/**
+ * Maintenance script that cleans up cases where rev_page and revactor_page
+ * became desynced, e.g. from T232464.
+ *
+ * @ingroup Maintenance
+ * @since 1.34
+ */
+class CleanupRevActorPage extends LoggedUpdateMaintenance {
+
+       public function __construct() {
+               parent::__construct();
+               $this->addDescription(
+                       'Resyncs revactor_page with rev_page when they differ, e.g. from T232464.'
+               );
+               $this->setBatchSize( 1000 );
+       }
+
+       protected function getUpdateKey() {
+               return __CLASS__;
+       }
+
+       protected function doDBUpdates() {
+               $dbw = $this->getDB( DB_MASTER );
+               $max = $dbw->selectField( 'revision', 'MAX(rev_id)', '', __METHOD__ );
+               $batchSize = $this->mBatchSize;
+
+               $this->output( "Resyncing revactor_page with rev_page...\n" );
+
+               $count = 0;
+               for ( $start = 1; $start <= $max; $start += $batchSize ) {
+                       $end = $start + $batchSize - 1;
+                       $this->output( "... rev_id $start - $end, $count changed\n" );
+
+                       // Fetch the rows needing update
+                       $res = $dbw->select(
+                               [ 'revision', 'revision_actor_temp' ],
+                               [ 'rev_id', 'rev_page' ],
+                               [
+                                       'rev_page != revactor_page',
+                                       "rev_id >= $start",
+                                       "rev_id <= $end",
+                               ],
+                               __METHOD__,
+                               [],
+                               [ 'revision_actor_temp' => [ 'JOIN', 'rev_id = revactor_rev' ] ]
+                       );
+
+                       if ( !$res->numRows() ) {
+                               continue;
+                       }
+
+                       // Update the existing rows
+                       foreach ( $res as $row ) {
+                               $dbw->update(
+                                       'revision_actor_temp',
+                                       [ 'revactor_page' => $row->rev_page ],
+                                       [ 'revactor_rev' => $row->rev_id ],
+                                       __METHOD__
+                               );
+                               $count += $dbw->affectedRows();
+                       }
+
+                       wfWaitForSlaves();
+               }
+
+               $this->output( "Completed resync, $count row(s) updated\n" );
+
+               return true;
+       }
+}
+
+$maintClass = CleanupRevActorPage::class;
+require_once RUN_MAINTENANCE_IF_MAIN;
index 2d19d38..fe6fcfc 100644 (file)
@@ -182,7 +182,6 @@ class ApiBlockTest extends ApiTestCase {
                $this->setMwGlobals( [
                        'wgEnableEmail' => true,
                        'wgEnableUserEmail' => true,
-                       'wgSysopEmailBans' => true,
                ] );
 
                $res = $this->doBlock( [ 'noemail' => '' ] );
@@ -200,7 +199,6 @@ class ApiBlockTest extends ApiTestCase {
                $this->setMwGlobals( [
                        'wgEnableEmail' => true,
                        'wgEnableUserEmail' => true,
-                       'wgSysopEmailBans' => true,
                ] );
 
                $this->setExpectedException( ApiUsageException::class,
index 0b1d013..45fa143 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 
+use MediaWiki\Permissions\PermissionManager;
 use MediaWiki\User\UserIdentityValue;
 use Wikimedia\Rdbms\IDatabase;
 use Wikimedia\Rdbms\LoadBalancer;
@@ -66,14 +67,16 @@ class WatchedItemQueryServiceUnitTest extends MediaWikiTestCase {
 
        /**
         * @param PHPUnit_Framework_MockObject_MockObject|Database $mockDb
+        * @param PHPUnit_Framework_MockObject_MockObject|PermissionManager $mockPM
         * @return WatchedItemQueryService
         */
-       private function newService( $mockDb ) {
+       private function newService( $mockDb, $mockPM = null ) {
                return new WatchedItemQueryService(
                        $this->getMockLoadBalancer( $mockDb ),
                        $this->getMockCommentStore(),
                        $this->getMockActorMigration(),
-                       $this->getMockWatchedItemStore()
+                       $this->getMockWatchedItemStore(),
+                       $mockPM ?: $this->getMockPermissionManager()
                );
        }
 
@@ -153,6 +156,25 @@ class WatchedItemQueryServiceUnitTest extends MediaWikiTestCase {
                return $mock;
        }
 
+       /**
+        * @param string $notAllowedAction
+        * @return PHPUnit_Framework_MockObject_MockObject|PermissionManager
+        */
+       private function getMockPermissionManager( $notAllowedAction = null ) {
+               $mock = $this->getMockBuilder( PermissionManager::class )
+                       ->disableOriginalConstructor()
+                       ->getMock();
+               $mock->method( 'userHasRight' )
+                       ->will( $this->returnCallback( function ( $user, $action ) use ( $notAllowedAction ) {
+                               return $action !== $notAllowedAction;
+                       } ) );
+               $mock->method( 'userHasAnyRight' )
+                       ->will( $this->returnCallback( function ( $user, ...$actions ) use ( $notAllowedAction ) {
+                               return !in_array( $notAllowedAction, $actions );
+                       } ) );
+               return $mock;
+       }
+
        /**
         * @param int $id
         * @param string[] $extraMethods Extra methods that are expected might be called
@@ -177,9 +199,7 @@ class WatchedItemQueryServiceUnitTest extends MediaWikiTestCase {
         */
        private function getMockUnrestrictedNonAnonUserWithId( $id, array $extraMethods = [] ) {
                $mock = $this->getMockNonAnonUserWithId( $id,
-                       array_merge( [ 'isAllowed', 'isAllowedAny', 'useRCPatrol' ], $extraMethods ) );
-               $mock->method( 'isAllowed' )->willReturn( true );
-               $mock->method( 'isAllowedAny' )->willReturn( true );
+                       array_merge( [ 'useRCPatrol' ], $extraMethods ) );
                $mock->method( 'useRCPatrol' )->willReturn( true );
                return $mock;
        }
@@ -189,18 +209,9 @@ class WatchedItemQueryServiceUnitTest extends MediaWikiTestCase {
         * @param string $notAllowedAction
         * @return PHPUnit_Framework_MockObject_MockObject|User
         */
-       private function getMockNonAnonUserWithIdAndRestrictedPermissions( $id, $notAllowedAction ) {
+       private function getMockNonAnonUserWithIdAndRestrictedPermissions( $id ) {
                $mock = $this->getMockNonAnonUserWithId( $id,
-                       [ 'isAllowed', 'isAllowedAny', 'useRCPatrol', 'useNPPatrol' ] );
-
-               $mock->method( 'isAllowed' )
-                       ->will( $this->returnCallback( function ( $action ) use ( $notAllowedAction ) {
-                               return $action !== $notAllowedAction;
-                       } ) );
-               $mock->method( 'isAllowedAny' )
-                       ->will( $this->returnCallback( function ( ...$actions ) use ( $notAllowedAction ) {
-                               return !in_array( $notAllowedAction, $actions );
-                       } ) );
+                       [ 'useRCPatrol', 'useNPPatrol' ] );
                $mock->method( 'useRCPatrol' )->willReturn( false );
                $mock->method( 'useNPPatrol' )->willReturn( false );
 
@@ -213,15 +224,7 @@ class WatchedItemQueryServiceUnitTest extends MediaWikiTestCase {
         */
        private function getMockNonAnonUserWithIdAndNoPatrolRights( $id ) {
                $mock = $this->getMockNonAnonUserWithId( $id,
-                       [ 'isAllowed', 'isAllowedAny', 'useRCPatrol', 'useNPPatrol' ] );
-
-               $mock->expects( $this->any() )
-                       ->method( 'isAllowed' )
-                       ->will( $this->returnValue( true ) );
-               $mock->expects( $this->any() )
-                       ->method( 'isAllowedAny' )
-                       ->will( $this->returnValue( true ) );
-
+                       [ 'useRCPatrol', 'useNPPatrol' ] );
                $mock->expects( $this->any() )
                        ->method( 'useRCPatrol' )
                        ->will( $this->returnValue( false ) );
@@ -1132,9 +1135,10 @@ class WatchedItemQueryServiceUnitTest extends MediaWikiTestCase {
                        )
                        ->will( $this->returnValue( [] ) );
 
-               $user = $this->getMockNonAnonUserWithIdAndRestrictedPermissions( 1, $notAllowedAction );
+               $permissionManager = $this->getMockPermissionManager( $notAllowedAction );
+               $user = $this->getMockNonAnonUserWithIdAndRestrictedPermissions( 1 );
 
-               $queryService = $this->newService( $mockDb );
+               $queryService = $this->newService( $mockDb, $permissionManager );
                $items = $queryService->getWatchedItemsWithRecentChangeInfo( $user, $options );
 
                $this->assertEmpty( $items );
index dc16e81..357fbd9 100644 (file)
@@ -22,11 +22,11 @@ Utilities to interact with the MediaWiki API. Uses the [mwbot](https://github.co
 Actions are performed logged-in using `browser.options.username` and `browser.options.password`,
 which typically come from `MEDIAWIKI_USER` and `MEDIAWIKI_PASSWORD` environment variables.
 
-* `edit(title, content [, string username [, string password [, string baseUrl ] ] ])`
-* `delete(title, reason)`
-* `createAccount(username, password)`
-* `blockUser(username, expiry)`
-* `unblockUser(username)`
+* `edit(string title, string content [, string username [, string password [, string baseUrl ] ] ])`
+* `delete(string title, string reason)`
+* `createAccount(string username, string password)`
+* `blockUser([ string username [, string expiry ] ])`
+* `unblockUser([ string username ])`
 
 ### RunJobs