Merge "registration: Improve license-name validation"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Thu, 29 Sep 2016 04:37:01 +0000 (04:37 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Thu, 29 Sep 2016 04:37:01 +0000 (04:37 +0000)
95 files changed:
includes/CategoryViewer.php
includes/Defines.php
includes/EditPage.php
includes/GlobalFunctions.php
includes/MediaWikiServices.php
includes/Sanitizer.php
includes/ServiceWiring.php
includes/WatchedItemQueryService.php
includes/WatchedItemStore.php
includes/api/ApiBase.php
includes/api/ApiClearHasMsg.php
includes/api/ApiContinuationManager.php
includes/api/ApiPageSet.php
includes/api/ApiQuery.php
includes/api/ApiQueryAllImages.php
includes/api/ApiQueryAllRevisions.php
includes/api/ApiQueryBase.php
includes/api/ApiQueryRecentChanges.php
includes/api/i18n/bn.json
includes/api/i18n/diq.json
includes/cache/BacklinkCache.php
includes/dao/DBAccessBase.php
includes/filerepo/LocalRepo.php
includes/installer/DatabaseInstaller.php
includes/installer/DatabaseUpdater.php
includes/installer/MssqlInstaller.php
includes/installer/MysqlInstaller.php
includes/installer/OracleInstaller.php
includes/installer/PostgresInstaller.php
includes/installer/i18n/bg.json
includes/installer/i18n/mai.json
includes/installer/i18n/sd.json
includes/libs/filebackend/FileBackend.php
includes/libs/lockmanager/DBLockManager.php
includes/libs/rdbms/chronologyprotector/ChronologyProtector.php
includes/libs/rdbms/database/DatabaseDomain.php
includes/libs/rdbms/lbfactory/ILBFactory.php
includes/libs/rdbms/lbfactory/LBFactory.php
includes/libs/rdbms/loadbalancer/LoadBalancer.php
includes/objectcache/ObjectCache.php
includes/parser/Parser.php
includes/resourceloader/ResourceLoaderContext.php
includes/resourceloader/ResourceLoaderUserCSSPrefsModule.php
includes/resourceloader/ResourceLoaderWikiModule.php
includes/specials/SpecialEditWatchlist.php
includes/user/BotPassword.php
languages/i18n/ast.json
languages/i18n/az.json
languages/i18n/be-tarask.json
languages/i18n/diq.json
languages/i18n/dty.json
languages/i18n/eo.json
languages/i18n/fi.json
languages/i18n/fr.json
languages/i18n/he.json
languages/i18n/it.json
languages/i18n/lb.json
languages/i18n/lt.json
languages/i18n/mai.json
languages/i18n/olo.json
languages/i18n/sd.json
languages/i18n/sv.json
languages/i18n/vi.json
load.php
maintenance/Maintenance.php
maintenance/archives/upgradeLogging.php
maintenance/benchmarks/bench_delete_truncate.php
maintenance/convertUserOptions.php
maintenance/deleteOrphanedRevisions.php
maintenance/dumpIterator.php
maintenance/dumpTextPass.php
maintenance/fetchText.php
maintenance/namespaceDupes.php
maintenance/orphans.php
maintenance/populateContentModel.php
maintenance/populateRecentChangesSource.php
maintenance/rebuildImages.php
maintenance/rebuildtextindex.php
maintenance/refreshImageMetadata.php
maintenance/storage/recompressTracked.php
maintenance/updateCollation.php
resources/src/mediawiki.legacy/shared.css
resources/src/mediawiki.less/mediawiki.ui/mixins.less
resources/src/mediawiki.ui/components/buttons.less
resources/src/mediawiki/mediawiki.util.js
tests/parser/ParserTestRunner.php
tests/parser/parserTests.txt
tests/phpunit/MediaWikiTestCase.php
tests/phpunit/includes/GlobalFunctions/wfBCP47Test.php
tests/phpunit/includes/MediaWikiServicesTest.php
tests/phpunit/includes/SanitizerTest.php
tests/phpunit/includes/WatchedItemStoreUnitTest.php
tests/phpunit/includes/api/ApiQueryWatchlistRawIntegrationTest.php
tests/phpunit/includes/auth/TemporaryPasswordPrimaryAuthenticationProviderTest.php
tests/phpunit/includes/utils/MWCryptHKDFTest.php

index 53e855b..c858dd7 100644 (file)
@@ -321,6 +321,8 @@ class CategoryViewer extends ContextSource {
                                array_merge(
                                        LinkCache::getSelectFields(),
                                        [
+                                               'page_namespace',
+                                               'page_title',
                                                'cl_sortkey',
                                                'cat_id',
                                                'cat_title',
index 529dfb3..02930ea 100644 (file)
@@ -77,8 +77,13 @@ define( 'NS_CATEGORY_TALK', 15 );
  * When writing code that should be compatible with older MediaWiki
  * versions, either stick to the old names or define the new constants
  * yourself, if they're not defined already.
+ *
+ * @deprecated since 1.14
  */
 define( 'NS_IMAGE', NS_FILE );
+/**
+ * @deprecated since 1.14
+ */
 define( 'NS_IMAGE_TALK', NS_FILE_TALK );
 /**@}*/
 
index f449283..38f8ab6 100644 (file)
@@ -3300,6 +3300,12 @@ HTML
                        'id' => $name,
                        'cols' => $wgUser->getIntOption( 'cols' ),
                        'rows' => $wgUser->getIntOption( 'rows' ),
+                       // The following classes can be used here:
+                       // * mw-editfont-default
+                       // * mw-editfont-monospace
+                       // * mw-editfont-sans-serif
+                       // * mw-editfont-serif
+                       'class' => 'mw-editfont-' . $wgUser->getOption( 'editfont' ),
                        // Avoid PHP notices when appending preferences
                        // (appending allows customAttribs['style'] to still work).
                        'style' => ''
index 5fe4b4e..311cf25 100644 (file)
@@ -3066,7 +3066,7 @@ function wfSplitWikiID( $wiki ) {
  * @todo Replace calls to wfGetDB with calls to LoadBalancer::getConnection()
  *       on an injected instance of LoadBalancer.
  *
- * @return DatabaseBase
+ * @return Database
  */
 function wfGetDB( $db, $groups = [], $wiki = false ) {
        return wfGetLB( $wiki )->getConnection( $db, $groups, $wiki );
index b16044e..199472a 100644 (file)
@@ -589,6 +589,30 @@ class MediaWikiServices extends ServiceContainer {
                return $this->getService( 'TitleParser' );
        }
 
+       /**
+        * @since 1.28
+        * @return \BagOStuff
+        */
+       public function getMainObjectStash() {
+               return $this->getService( 'MainObjectStash' );
+       }
+
+       /**
+        * @since 1.28
+        * @return \WANObjectCache
+        */
+       public function getMainWANObjectCache() {
+               return $this->getService( 'MainWANObjectCache' );
+       }
+
+       /**
+        * @since 1.28
+        * @return \BagOStuff
+        */
+       public function getLocalServerObjectCache() {
+               return $this->getService( 'LocalServerObjectCache' );
+       }
+
        /**
         * @since 1.28
         * @return VirtualRESTServiceClient
index 8f1fc99..4069658 100644 (file)
@@ -1015,6 +1015,7 @@ class Sanitizer {
                                | url\s*\(
                                | image\s*\(
                                | image-set\s*\(
+                               | attr\s*\([^)]+[\s,]+url
                        !ix', $value ) ) {
                        return '/* insecure input */';
                }
@@ -1867,7 +1868,7 @@ class Sanitizer {
                        list( /* $whole */, $protocol, $host, $rest ) = $matches;
 
                        // Characters that will be ignored in IDNs.
-                       // http://tools.ietf.org/html/3454#section-3.1
+                       // https://tools.ietf.org/html/rfc3454#section-3.1
                        // Strip them before further processing so blacklists and such work.
                        $strip = "/
                                \\s|          # general whitespace
index 6044911..0e4daa6 100644 (file)
@@ -218,6 +218,59 @@ return [
                return $services->getService( '_MediaWikiTitleCodec' );
        },
 
+       'MainObjectStash' => function( MediaWikiServices $services ) {
+               $mainConfig = $services->getMainConfig();
+
+               $id = $mainConfig->get( 'MainStash' );
+               if ( !isset( $mainConfig->get( 'ObjectCaches' )[$id] ) ) {
+                       throw new UnexpectedValueException(
+                               "Cache type \"$id\" is not present in \$wgObjectCaches." );
+               }
+
+               return \ObjectCache::newFromParams( $mainConfig->get( 'ObjectCaches' )[$id] );
+       },
+
+       'MainWANObjectCache' => function( MediaWikiServices $services ) {
+               $mainConfig = $services->getMainConfig();
+
+               $id = $mainConfig->get( 'MainWANCache' );
+               if ( !isset( $mainConfig->get( 'WANObjectCaches' )[$id] ) ) {
+                       throw new UnexpectedValueException(
+                               "WAN cache type \"$id\" is not present in \$wgWANObjectCaches." );
+               }
+
+               $params = $mainConfig->get( 'WANObjectCaches' )[$id];
+               $objectCacheId = $params['cacheId'];
+               if ( !isset( $mainConfig->get( 'ObjectCaches' )[$objectCacheId] ) ) {
+                       throw new UnexpectedValueException(
+                               "Cache type \"$objectCacheId\" is not present in \$wgObjectCaches." );
+               }
+               $params['store'] = $mainConfig->get( 'ObjectCaches' )[$objectCacheId];
+
+               return \ObjectCache::newWANCacheFromParams( $params );
+       },
+
+       'LocalServerObjectCache' => function( MediaWikiServices $services ) {
+               $mainConfig = $services->getMainConfig();
+
+               if ( function_exists( 'apc_fetch' ) ) {
+                       $id = 'apc';
+               } elseif ( function_exists( 'xcache_get' ) && wfIniGetBool( 'xcache.var_size' ) ) {
+                       $id = 'xcache';
+               } elseif ( function_exists( 'wincache_ucache_get' ) ) {
+                       $id = 'wincache';
+               } else {
+                       $id = CACHE_NONE;
+               }
+
+               if ( !isset( $mainConfig->get( 'ObjectCaches' )[$id] ) ) {
+                       throw new UnexpectedValueException(
+                               "Cache type \"$id\" is not present in \$wgObjectCaches." );
+               }
+
+               return \ObjectCache::newFromParams( $mainConfig->get( 'ObjectCaches' )[$id] );
+       },
+
        'VirtualRESTServiceClient' => function( MediaWikiServices $services ) {
                $config = $services->getMainConfig()->get( 'VirtualRestConfig' );
 
index c040fb1..4802f72 100644 (file)
@@ -55,7 +55,7 @@ class WatchedItemQueryService {
        }
 
        /**
-        * @return DatabaseBase
+        * @return Database
         * @throws MWException
         */
        private function getConnection() {
index 478cc5f..90d45ce 100644 (file)
@@ -192,20 +192,11 @@ class WatchedItemStore implements StatsdAwareInterface {
        /**
         * @param int $dbIndex DB_MASTER or DB_REPLICA
         *
-        * @return DatabaseBase
+        * @return IDatabase
         * @throws MWException
         */
-       private function getConnection( $dbIndex ) {
-               return $this->loadBalancer->getConnection( $dbIndex, [ 'watchlist' ] );
-       }
-
-       /**
-        * @param Database $connection
-        *
-        * @throws MWException
-        */
-       private function reuseConnection( $connection ) {
-               $this->loadBalancer->reuseConnection( $connection );
+       private function getConnectionRef( $dbIndex ) {
+               return $this->loadBalancer->getConnectionRef( $dbIndex, [ 'watchlist' ] );
        }
 
        /**
@@ -217,7 +208,7 @@ class WatchedItemStore implements StatsdAwareInterface {
         * @return int
         */
        public function countWatchedItems( User $user ) {
-               $dbr = $this->getConnection( DB_REPLICA );
+               $dbr = $this->getConnectionRef( DB_REPLICA );
                $return = (int)$dbr->selectField(
                        'watchlist',
                        'COUNT(*)',
@@ -226,7 +217,6 @@ class WatchedItemStore implements StatsdAwareInterface {
                        ],
                        __METHOD__
                );
-               $this->reuseConnection( $dbr );
 
                return $return;
        }
@@ -237,7 +227,7 @@ class WatchedItemStore implements StatsdAwareInterface {
         * @return int
         */
        public function countWatchers( LinkTarget $target ) {
-               $dbr = $this->getConnection( DB_REPLICA );
+               $dbr = $this->getConnectionRef( DB_REPLICA );
                $return = (int)$dbr->selectField(
                        'watchlist',
                        'COUNT(*)',
@@ -247,7 +237,6 @@ class WatchedItemStore implements StatsdAwareInterface {
                        ],
                        __METHOD__
                );
-               $this->reuseConnection( $dbr );
 
                return $return;
        }
@@ -263,7 +252,7 @@ class WatchedItemStore implements StatsdAwareInterface {
         * @throws MWException
         */
        public function countVisitingWatchers( LinkTarget $target, $threshold ) {
-               $dbr = $this->getConnection( DB_REPLICA );
+               $dbr = $this->getConnectionRef( DB_REPLICA );
                $visitingWatchers = (int)$dbr->selectField(
                        'watchlist',
                        'COUNT(*)',
@@ -276,7 +265,6 @@ class WatchedItemStore implements StatsdAwareInterface {
                        ],
                        __METHOD__
                );
-               $this->reuseConnection( $dbr );
 
                return $visitingWatchers;
        }
@@ -293,7 +281,7 @@ class WatchedItemStore implements StatsdAwareInterface {
        public function countWatchersMultiple( array $targets, array $options = [] ) {
                $dbOptions = [ 'GROUP BY' => [ 'wl_namespace', 'wl_title' ] ];
 
-               $dbr = $this->getConnection( DB_REPLICA );
+               $dbr = $this->getConnectionRef( DB_REPLICA );
 
                if ( array_key_exists( 'minimumWatchers', $options ) ) {
                        $dbOptions['HAVING'] = 'COUNT(*) >= ' . (int)$options['minimumWatchers'];
@@ -308,8 +296,6 @@ class WatchedItemStore implements StatsdAwareInterface {
                        $dbOptions
                );
 
-               $this->reuseConnection( $dbr );
-
                $watchCounts = [];
                foreach ( $targets as $linkTarget ) {
                        $watchCounts[$linkTarget->getNamespace()][$linkTarget->getDBkey()] = 0;
@@ -341,7 +327,7 @@ class WatchedItemStore implements StatsdAwareInterface {
                array $targetsWithVisitThresholds,
                $minimumWatchers = null
        ) {
-               $dbr = $this->getConnection( DB_REPLICA );
+               $dbr = $this->getConnectionRef( DB_REPLICA );
 
                $conds = $this->getVisitingWatchersCondition( $dbr, $targetsWithVisitThresholds );
 
@@ -357,8 +343,6 @@ class WatchedItemStore implements StatsdAwareInterface {
                        $dbOptions
                );
 
-               $this->reuseConnection( $dbr );
-
                $watcherCounts = [];
                foreach ( $targetsWithVisitThresholds as list( $target ) ) {
                        /* @var LinkTarget $target */
@@ -452,14 +436,13 @@ class WatchedItemStore implements StatsdAwareInterface {
                        return false;
                }
 
-               $dbr = $this->getConnection( DB_REPLICA );
+               $dbr = $this->getConnectionRef( DB_REPLICA );
                $row = $dbr->selectRow(
                        'watchlist',
                        'wl_notificationtimestamp',
                        $this->dbCond( $user, $target ),
                        __METHOD__
                );
-               $this->reuseConnection( $dbr );
 
                if ( !$row ) {
                        return false;
@@ -499,7 +482,7 @@ class WatchedItemStore implements StatsdAwareInterface {
                                "wl_title {$options['sort']}"
                        ];
                }
-               $db = $this->getConnection( $options['forWrite'] ? DB_MASTER : DB_REPLICA );
+               $db = $this->getConnectionRef( $options['forWrite'] ? DB_MASTER : DB_REPLICA );
 
                $res = $db->select(
                        'watchlist',
@@ -508,7 +491,6 @@ class WatchedItemStore implements StatsdAwareInterface {
                        __METHOD__,
                        $dbOptions
                );
-               $this->reuseConnection( $db );
 
                $watchedItems = [];
                foreach ( $res as $row ) {
@@ -569,7 +551,7 @@ class WatchedItemStore implements StatsdAwareInterface {
                        return $timestamps;
                }
 
-               $dbr = $this->getConnection( DB_REPLICA );
+               $dbr = $this->getConnectionRef( DB_REPLICA );
 
                $lb = new LinkBatch( $targetsToLoad );
                $res = $dbr->select(
@@ -581,7 +563,6 @@ class WatchedItemStore implements StatsdAwareInterface {
                        ],
                        __METHOD__
                );
-               $this->reuseConnection( $dbr );
 
                foreach ( $res as $row ) {
                        $timestamps[$row->wl_namespace][$row->wl_title] = $row->wl_notificationtimestamp;
@@ -630,13 +611,12 @@ class WatchedItemStore implements StatsdAwareInterface {
                        $this->uncache( $user, $target );
                }
 
-               $dbw = $this->getConnection( DB_MASTER );
+               $dbw = $this->getConnectionRef( DB_MASTER );
                foreach ( array_chunk( $rows, 100 ) as $toInsert ) {
                        // Use INSERT IGNORE to avoid overwriting the notification timestamp
                        // if there's already an entry for this page
                        $dbw->insert( 'watchlist', $toInsert, __METHOD__, 'IGNORE' );
                }
-               $this->reuseConnection( $dbw );
 
                return true;
        }
@@ -660,7 +640,7 @@ class WatchedItemStore implements StatsdAwareInterface {
 
                $this->uncache( $user, $target );
 
-               $dbw = $this->getConnection( DB_MASTER );
+               $dbw = $this->getConnectionRef( DB_MASTER );
                $dbw->delete( 'watchlist',
                        [
                                'wl_user' => $user->getId(),
@@ -669,7 +649,6 @@ class WatchedItemStore implements StatsdAwareInterface {
                        ], __METHOD__
                );
                $success = (bool)$dbw->affectedRows();
-               $this->reuseConnection( $dbw );
 
                return $success;
        }
@@ -687,7 +666,7 @@ class WatchedItemStore implements StatsdAwareInterface {
                        return false;
                }
 
-               $dbw = $this->getConnection( DB_MASTER );
+               $dbw = $this->getConnectionRef( DB_MASTER );
 
                $conds = [ 'wl_user' => $user->getId() ];
                if ( $targets ) {
@@ -702,8 +681,6 @@ class WatchedItemStore implements StatsdAwareInterface {
                        __METHOD__
                );
 
-               $this->reuseConnection( $dbw );
-
                $this->uncacheUser( $user );
 
                return $success;
@@ -718,7 +695,7 @@ class WatchedItemStore implements StatsdAwareInterface {
         * @return int[] Array of user IDs the timestamp has been updated for
         */
        public function updateNotificationTimestamp( User $editor, LinkTarget $target, $timestamp ) {
-               $dbw = $this->getConnection( DB_MASTER );
+               $dbw = $this->getConnectionRef( DB_MASTER );
                $uids = $dbw->selectFieldValues(
                        'watchlist',
                        'wl_user',
@@ -730,7 +707,6 @@ class WatchedItemStore implements StatsdAwareInterface {
                        ],
                        __METHOD__
                );
-               $this->reuseConnection( $dbw );
 
                $watchers = array_map( 'intval', $uids );
                if ( $watchers ) {
@@ -740,7 +716,7 @@ class WatchedItemStore implements StatsdAwareInterface {
                                function () use ( $timestamp, $watchers, $target, $fname ) {
                                        global $wgUpdateRowsPerQuery;
 
-                                       $dbw = $this->getConnection( DB_MASTER );
+                                       $dbw = $this->getConnectionRef( DB_MASTER );
                                        $factory = wfGetLBFactory();
                                        $ticket = $factory->getEmptyTransactionTicket( __METHOD__ );
 
@@ -762,8 +738,6 @@ class WatchedItemStore implements StatsdAwareInterface {
                                                }
                                        }
                                        $this->uncacheLinkTarget( $target );
-
-                                       $this->reuseConnection( $dbw );
                                },
                                DeferredUpdates::POSTSEND,
                                $dbw
@@ -885,7 +859,7 @@ class WatchedItemStore implements StatsdAwareInterface {
                        $queryOptions['LIMIT'] = $unreadLimit;
                }
 
-               $dbr = $this->getConnection( DB_REPLICA );
+               $dbr = $this->getConnectionRef( DB_REPLICA );
                $rowCount = $dbr->selectRowCount(
                        'watchlist',
                        '1',
@@ -896,7 +870,6 @@ class WatchedItemStore implements StatsdAwareInterface {
                        __METHOD__,
                        $queryOptions
                );
-               $this->reuseConnection( $dbr );
 
                if ( !isset( $unreadLimit ) ) {
                        return $rowCount;
@@ -937,7 +910,7 @@ class WatchedItemStore implements StatsdAwareInterface {
         * @param LinkTarget $newTarget
         */
        public function duplicateEntry( LinkTarget $oldTarget, LinkTarget $newTarget ) {
-               $dbw = $this->getConnection( DB_MASTER );
+               $dbw = $this->getConnectionRef( DB_MASTER );
 
                $result = $dbw->select(
                        'watchlist',
@@ -975,8 +948,6 @@ class WatchedItemStore implements StatsdAwareInterface {
                                __METHOD__
                        );
                }
-
-               $this->reuseConnection( $dbw );
        }
 
 }
index 809d567..4feaac0 100644 (file)
@@ -600,7 +600,7 @@ abstract class ApiBase extends ContextSource {
 
        /**
         * Gets a default replica DB connection object
-        * @return DatabaseBase
+        * @return Database
         */
        protected function getDB() {
                if ( !isset( $this->mSlaveDB ) ) {
index 4ddbd04..13b3577 100644 (file)
 class ApiClearHasMsg extends ApiBase {
        public function execute() {
                $user = $this->getUser();
-               $user->setNewtalk( false );
+               if ( $this->getRequest()->wasPosted() ) {
+                       $user->setNewtalk( false );
+               } else {
+                       DeferredUpdates::addCallableUpdate( function () use ( $user ) {
+                               $user->setNewtalk( false );
+                       } );
+               }
                $this->getResult()->addValue( null, $this->getModuleName(), 'success' );
        }
 
index 6601fb7..19e2453 100644 (file)
@@ -31,6 +31,7 @@ class ApiContinuationManager {
 
        private $continuationData = [];
        private $generatorContinuationData = [];
+       private $generatorNonContinuationData = [];
 
        private $generatorParams = [];
        private $generatorDone = false;
@@ -142,6 +143,26 @@ class ApiContinuationManager {
                $this->continuationData[$name][$paramName] = $paramValue;
        }
 
+       /**
+        * Set the non-continuation parameter for the generator module
+        *
+        * In case the generator isn't going to be continued, this sets the fields
+        * to return.
+        *
+        * @since 1.28
+        * @param ApiBase $module
+        * @param string $paramName
+        * @param string|array $paramValue
+        */
+       public function addGeneratorNonContinueParam( ApiBase $module, $paramName, $paramValue ) {
+               $name = $module->getModuleName();
+               $paramName = $module->encodeParamName( $paramName );
+               if ( is_array( $paramValue ) ) {
+                       $paramValue = implode( '|', $paramValue );
+               }
+               $this->generatorNonContinuationData[$name][$paramName] = $paramValue;
+       }
+
        /**
         * Set the continuation parameter for the generator module
         * @param ApiBase $module
@@ -165,6 +186,15 @@ class ApiContinuationManager {
                return array_merge_recursive( $this->continuationData, $this->generatorContinuationData );
        }
 
+       /**
+        * Fetch raw non-continuation data
+        * @since 1.28
+        * @return array
+        */
+       public function getRawNonContinuation() {
+               return $this->generatorNonContinuationData;
+       }
+
        /**
         * Fetch continuation result data
         * @return array [ (array)$data, (bool)$batchcomplete ]
@@ -192,8 +222,13 @@ class ApiContinuationManager {
                        foreach ( $continuationData as $module => $kvp ) {
                                $data += $kvp;
                        }
-                       $data += $this->generatorParams;
-                       $generatorKeys = implode( '|', array_keys( $this->generatorParams ) );
+                       $generatorParams = [];
+                       foreach ( $this->generatorNonContinuationData as $kvp ) {
+                               $generatorParams += $kvp;
+                       }
+                       $generatorParams += $this->generatorParams;
+                       $data += $generatorParams;
+                       $generatorKeys = implode( '|', array_keys( $generatorParams ) );
                } elseif ( $this->generatorContinuationData ) {
                        // All the generator-using modules are complete, but the
                        // generator isn't. Continue the generator and restart the
index ed229cb..34c17c1 100644 (file)
@@ -1330,7 +1330,7 @@ class ApiPageSet extends ApiBase {
 
        /**
         * Get the database connection (read-only)
-        * @return DatabaseBase
+        * @return Database
         */
        protected function getDB() {
                return $this->mDbSource->getDB();
index 5e3c709..2f53209 100644 (file)
@@ -168,7 +168,7 @@ class ApiQuery extends ApiBase {
         * @param string $name Name to assign to the database connection
         * @param int $db One of the DB_* constants
         * @param array $groups Query groups
-        * @return DatabaseBase
+        * @return Database
         */
        public function getNamedDB( $name, $db, $groups ) {
                if ( !array_key_exists( $name, $this->mNamedDB ) ) {
@@ -258,6 +258,11 @@ class ApiQuery extends ApiBase {
                // Write the continuation data into the result
                $this->setContinuationManager( null );
                if ( $this->mParams['rawcontinue'] ) {
+                       $data = $continuationManager->getRawNonContinuation();
+                       if ( $data ) {
+                               $this->getResult()->addValue( null, 'query-noncontinue', $data,
+                                       ApiResult::ADD_ON_TOP | ApiResult::NO_SIZE_CHECK );
+                       }
                        $data = $continuationManager->getRawContinuation();
                        if ( $data ) {
                                $this->getResult()->addValue( null, 'query-continue', $data,
index 6aeee68..553995c 100644 (file)
@@ -44,7 +44,7 @@ class ApiQueryAllImages extends ApiQueryGeneratorBase {
         * which may not necessarily be the same as the local DB.
         *
         * TODO: allow querying non-local repos.
-        * @return DatabaseBase
+        * @return Database
         */
        protected function getDB() {
                return $this->mRepo->getSlaveDB();
index 060e3e1..d548c46 100644 (file)
@@ -172,6 +172,13 @@ class ApiQueryAllRevisions extends ApiQueryRevisionsBase {
                $nextIndex = 0;
                $generated = [];
                foreach ( $res as $row ) {
+                       if ( $count === 0 && $resultPageSet !== null ) {
+                               // Set the non-continue since the list of all revisions is
+                               // prone to having entries added at the start frequently.
+                               $this->getContinuationManager()->addGeneratorNonContinueParam(
+                                       $this, 'continue', "$row->rev_timestamp|$row->rev_id"
+                               );
+                       }
                        if ( ++$count > $this->limit ) {
                                // We've had enough
                                $this->setContinueEnumParameter( 'continue', "$row->rev_timestamp|$row->rev_id" );
index b35eec2..36ad3a4 100644 (file)
@@ -103,7 +103,7 @@ abstract class ApiQueryBase extends ApiBase {
 
        /**
         * Get the Query database connection (read-only)
-        * @return DatabaseBase
+        * @return Database
         */
        protected function getDB() {
                if ( is_null( $this->mDb ) ) {
@@ -119,7 +119,7 @@ abstract class ApiQueryBase extends ApiBase {
         * @param string $name Name to assign to the database connection
         * @param int $db One of the DB_* constants
         * @param array $groups Query groups
-        * @return DatabaseBase
+        * @return Database
         */
        public function selectNamedDB( $name, $db, $groups ) {
                $this->mDb = $this->getQuery()->getNamedDB( $name, $db, $groups );
index cc3ca60..c4c8afb 100644 (file)
@@ -372,6 +372,13 @@ class ApiQueryRecentChanges extends ApiQueryGeneratorBase {
 
                /* Iterate through the rows, adding data extracted from them to our query result. */
                foreach ( $res as $row ) {
+                       if ( $count === 0 && $resultPageSet !== null ) {
+                               // Set the non-continue since the list of recentchanges is
+                               // prone to having entries added at the start frequently.
+                               $this->getContinuationManager()->addGeneratorNonContinueParam(
+                                       $this, 'continue', "$row->rc_timestamp|$row->rc_id"
+                               );
+                       }
                        if ( ++$count > $params['limit'] ) {
                                // We've reached the one extra which shows that there are
                                // additional pages to be had. Stop here...
index 874639a..71beaaa 100644 (file)
@@ -7,10 +7,18 @@
                ]
        },
        "apihelp-main-param-format": "আউটপুটের বিন্যাস",
+       "apihelp-main-param-requestid": "এখানে প্রদত্ত যেকোন মান প্রতিক্রিয়ার অন্তর্ভুক্ত করা হবে। অনুরোধ পার্থক্য করতে ব্যবহার করা যেতে পারে।",
        "apihelp-block-description": "ব্যবহারকারীকে বাধা দিন।",
+       "apihelp-block-param-reason": "বাধার দানের কারণ।",
+       "apihelp-createaccount-description": "নতুন ব্যবহারকারীর অ্যাকাউন্ট তৈরি করুন",
        "apihelp-createaccount-param-name": "ব্যবহারকারী নাম।",
        "apihelp-delete-description": "একটি পাতা মুছে ফেলুন।",
        "apihelp-delete-example-simple": "<kbd>প্রধান পাতা</kbd> মুছে ফেলুন।",
+       "apihelp-edit-param-text": "পাতার বিষয়বস্তু।",
        "apihelp-edit-param-minor": "অনুল্লেখ্য সম্পাদনা।",
+       "apihelp-edit-param-createonly": "পাতাটি আগেই বিদ্যমান থাকলে সম্পদনা করবেন না।",
+       "apihelp-edit-param-contentmodel": "নতুন বিষয়বস্তুর, বিষয়বস্তু-মডেল।",
+       "apihelp-edit-example-edit": "একটি পাতা সম্পাদনা করুন",
+       "apihelp-edit-example-prepend": "একটি পৃষ্ঠার পূর্বে <kbd>_&#95;NOTOC_&#95;</kbd> লিখুন।",
        "apihelp-login-example-login": "প্রবেশ"
 }
index 31bb5fa..56a65d9 100644 (file)
@@ -20,7 +20,7 @@
        "apihelp-disabled-description": "Eno modul aktiv niyo.",
        "apihelp-edit-description": "Vıraze û pelan bıvurne.",
        "apihelp-edit-param-text": "Zerreki pele",
-       "apihelp-edit-param-minor": "Vurnayışo qıckek.",
+       "apihelp-edit-param-minor": "Vuriyayışa werdi",
        "apihelp-edit-param-notminor": "Vurnayışo qıckek niyo.",
        "apihelp-edit-param-bot": "Nê vurnayışi zey boti nişan ke.",
        "apihelp-edit-example-edit": "Şeker bıvurne",
index 9dfabfd..9e6cf1e 100644 (file)
@@ -139,7 +139,7 @@ class BacklinkCache {
        /**
         * Get the replica DB connection to the database
         * When non existing, will initialize the connection.
-        * @return DatabaseBase
+        * @return Database
         */
        protected function getDB() {
                if ( !isset( $this->db ) ) {
index ed617fe..6a1bbd6 100644 (file)
@@ -53,7 +53,7 @@ abstract class DBAccessBase implements IDBAccessObject {
         * @param int $id Which connection to use
         * @param array $groups Query groups
         *
-        * @return DatabaseBase
+        * @return Database
         */
        protected function getConnection( $id, $groups = [] ) {
                $loadBalancer = wfGetLB( $this->wiki );
index 7b40a7b..21492a5 100644 (file)
@@ -454,7 +454,7 @@ class LocalRepo extends FileRepo {
 
        /**
         * Get a connection to the replica DB
-        * @return DatabaseBase
+        * @return Database
         */
        function getSlaveDB() {
                return wfGetDB( DB_REPLICA );
@@ -462,7 +462,7 @@ class LocalRepo extends FileRepo {
 
        /**
         * Get a connection to the master DB
-        * @return DatabaseBase
+        * @return Database
         */
        function getMasterDB() {
                return wfGetDB( DB_MASTER );
index 2b84144..331d1a1 100644 (file)
@@ -41,7 +41,7 @@ abstract class DatabaseInstaller {
        /**
         * The database connection.
         *
-        * @var DatabaseBase
+        * @var Database
         */
        public $db = null;
 
index fbdc934..aece317 100644 (file)
@@ -57,7 +57,7 @@ abstract class DatabaseUpdater {
        /**
         * Handle to the database subclass
         *
-        * @var DatabaseBase
+        * @var Database
         */
        protected $db;
 
@@ -192,7 +192,7 @@ abstract class DatabaseUpdater {
        /**
         * Get a database connection to run updates
         *
-        * @return DatabaseBase
+        * @return Database
         */
        public function getDB() {
                return $this->db;
index 739be82..c5ec72b 100644 (file)
@@ -182,7 +182,7 @@ class MssqlInstaller extends DatabaseInstaller {
                        return $status;
                }
                /**
-                * @var $conn DatabaseBase
+                * @var $conn Database
                 */
                $conn = $status->value;
 
@@ -240,7 +240,7 @@ class MssqlInstaller extends DatabaseInstaller {
                        return;
                }
                /**
-                * @var $conn DatabaseBase
+                * @var $conn Database
                 */
                $conn = $status->value;
                $conn->selectDB( $this->getVar( 'wgDBname' ) );
index 812742c..5ff47e9 100644 (file)
@@ -124,7 +124,7 @@ class MysqlInstaller extends DatabaseInstaller {
                        return $status;
                }
                /**
-                * @var $conn DatabaseBase
+                * @var $conn Database
                 */
                $conn = $status->value;
 
@@ -168,7 +168,7 @@ class MysqlInstaller extends DatabaseInstaller {
                        return;
                }
                /**
-                * @var $conn DatabaseBase
+                * @var $conn Database
                 */
                $conn = $status->value;
                $conn->selectDB( $this->getVar( 'wgDBname' ) );
@@ -226,7 +226,7 @@ class MysqlInstaller extends DatabaseInstaller {
                $status = $this->getConnection();
 
                /**
-                * @var $conn DatabaseBase
+                * @var $conn Database
                 */
                $conn = $status->value;
 
index 8610834..b8fc4e7 100644 (file)
@@ -150,7 +150,7 @@ class OracleInstaller extends DatabaseInstaller {
                }
 
                /**
-                * @var $conn DatabaseBase
+                * @var $conn Database
                 */
                $conn = $status->value;
 
index 7a2794d..33e1a1f 100644 (file)
@@ -114,7 +114,7 @@ class PostgresInstaller extends DatabaseInstaller {
                        return $status;
                }
                /**
-                * @var $conn DatabaseBase
+                * @var $conn Database
                 */
                $conn = $status->value;
 
@@ -181,7 +181,7 @@ class PostgresInstaller extends DatabaseInstaller {
 
                if ( $status->isOK() ) {
                        /**
-                        * @var $conn DatabaseBase
+                        * @var $conn Database
                         */
                        $conn = $status->value;
                        $conn->clearFlag( DBO_TRX );
@@ -233,7 +233,7 @@ class PostgresInstaller extends DatabaseInstaller {
                                $status = $this->openPgConnection( 'create-schema' );
                                if ( $status->isOK() ) {
                                        /**
-                                        * @var $conn DatabaseBase
+                                        * @var $conn Database
                                         */
                                        $conn = $status->value;
                                        $safeRole = $conn->addIdentifierQuotes( $this->getVar( 'wgDBuser' ) );
@@ -287,7 +287,7 @@ class PostgresInstaller extends DatabaseInstaller {
                        return false;
                }
                /**
-                * @var $conn DatabaseBase
+                * @var $conn Database
                 */
                $conn = $status->value;
                $superuser = $this->getVar( '_InstallUser' );
@@ -588,7 +588,7 @@ class PostgresInstaller extends DatabaseInstaller {
                }
 
                /**
-                * @var $conn DatabaseBase
+                * @var $conn Database
                 */
                $conn = $status->value;
 
@@ -638,7 +638,7 @@ class PostgresInstaller extends DatabaseInstaller {
                        return $status;
                }
                /**
-                * @var $conn DatabaseBase
+                * @var $conn Database
                 */
                $conn = $status->value;
 
index 69891ea..8b1ca18 100644 (file)
        "config-admin-help": "Въвежда се предпочитаното потребителско име, например \"Иванчо Иванчев\".\nТова ще е потребителското име, което администраторът ще използва за влизане в уикито.",
        "config-admin-name-blank": "Необходимо е да бъде въведено потребителско име на администратора.",
        "config-admin-name-invalid": "Посоченото потребителско име \"<nowiki>$1</nowiki>\" е невалидно.\nНеобходимо е да се посочи друго.",
-       "config-admin-password-blank": "Ð\9dеовÑ\85одимо Ðµ Ð´Ð° Ñ\81е Ð²Ñ\8aведе парола за администраторската сметка.",
+       "config-admin-password-blank": "Ð\92Ñ\8aведеÑ\82е парола за администраторската сметка.",
        "config-admin-password-mismatch": "Двете въведени пароли не съвпадат.",
        "config-admin-email": "Адрес за електронна поща:",
        "config-admin-email-help": "Въвеждането на адрес за е-поща позволява получаване на е-писма от другите потребители на уикито, възстановяване на изгубена или забравена парола, оповестяване при промени в страниците от списъка за наблюдение. Това поле може да бъде оставено празно.",
index 8b8e0fb..5e3fc0d 100644 (file)
@@ -21,9 +21,9 @@
        "config-page-dbsettings": "डाटाबेस कुंजी",
        "config-page-name": "नाम",
        "config-page-options": "विकल्प",
-       "config-page-install": "सà¥\8dथापित à¤\95रà¥\81",
+       "config-page-install": "सà¥\8dथापित à¤\95रà¥\80",
        "config-page-complete": "पूर्ण!",
-       "config-page-restart": "स्थापनाके पुनारम्भ करु",
+       "config-page-restart": "स्थापनाक पुनारम्भ करी",
        "config-page-readme": "पढू",
        "config-page-releasenotes": "रिलीज नोट्स",
        "config-page-copying": "अनुकरण",
index 33fa590..21a3297 100644 (file)
@@ -2,11 +2,12 @@
        "@metadata": {
                "authors": [
                        "Sindhu",
-                       "Aursani"
+                       "Aursani",
+                       "Mehtab ahmed"
                ]
        },
        "config-information": "معلومات",
-       "config-localsettings-badkey": "توهان جي ڏنل ڪنجي غيردرست آهي.",
+       "config-localsettings-badkey": "توهان جي سنواري ڏنل ڪنجي غيردرست آهي.",
        "config-your-language": "توهان جي ٻولي:",
        "config-wiki-language": "وڪِي ٻولي:",
        "config-back": "پوئتي ←",
@@ -26,6 +27,5 @@
        "config-page-existingwiki": "موجوده وڪِي",
        "config-restart": "ها، وري کان شروع ڪريو",
        "config-env-php": "PHP $1 تنصيب ٿي چڪو",
-       "config-env-hhvm": "HHVM $1 تنصيب ٿي چڪو.",
-       "config-xml-bad": "PHP جو XML ماڊيول کٽل آهي. ذريعات‌وڪيءَ کي ان ماڊيول ۾  فنڪشنس گھربل آهن ۽ اها موجوده ترتيب يا ڪنفيگيوريشن ۾ ڪم نہ ڪندي. \nتوهان کي گھرجي تہ php-xml RPM پيڪيج تنصيب ڪريو."
+       "config-env-hhvm": "HHVM $1 تنصيب ٿي چڪو."
 }
index 0ef9f63..f33f522 100644 (file)
@@ -185,15 +185,15 @@ abstract class FileBackend implements LoggerAwareInterface {
                $this->concurrency = isset( $config['concurrency'] )
                        ? (int)$config['concurrency']
                        : 50;
-               $this->obResetFunc = isset( $params['obResetFunc'] )
-                       ? $params['obResetFunc']
+               $this->obResetFunc = isset( $config['obResetFunc'] )
+                       ? $config['obResetFunc']
                        : [ $this, 'resetOutputBuffer' ];
-               $this->streamMimeFunc = isset( $params['streamMimeFunc'] )
-                       ? $params['streamMimeFunc']
+               $this->streamMimeFunc = isset( $config['streamMimeFunc'] )
+                       ? $config['streamMimeFunc']
                        : null;
                $this->statusWrapper = isset( $config['statusWrapper'] ) ? $config['statusWrapper'] : null;
 
-               $this->profiler = isset( $params['profiler'] ) ? $params['profiler'] : null;
+               $this->profiler = isset( $config['profiler'] ) ? $config['profiler'] : null;
                $this->logger = isset( $config['logger'] ) ? $config['logger'] : new \Psr\Log\NullLogger();
                $this->statusWrapper = isset( $config['statusWrapper'] ) ? $config['statusWrapper'] : null;
                $this->tmpDirectory = isset( $config['tmpDirectory'] ) ? $config['tmpDirectory'] : null;
@@ -1620,7 +1620,7 @@ abstract class FileBackend implements LoggerAwareInterface {
        protected function scopedProfileSection( $section ) {
                if ( $this->profiler ) {
                        call_user_func( [ $this->profiler, 'profileIn' ], $section );
-                       return new ScopedCallback( [ $this->profiler, 'profileOut' ] );
+                       return new ScopedCallback( [ $this->profiler, 'profileOut' ], [ $section ] );
                }
 
                return null;
index 64a2916..b17b1a0 100644 (file)
@@ -58,7 +58,7 @@ abstract class DBLockManager extends QuorumLockManager {
         *                     - user        : DB user
         *                     - password    : DB user password
         *                     - tablePrefix : DB table prefix
-        *                     - flags       : DB flags (see DatabaseBase)
+        *                     - flags       : DB flags; bitfield of IDatabase::DBO_* constants
         *   - dbsByBucket : Array of 1-16 consecutive integer keys, starting from 0,
         *                   each having an odd-numbered list of DB names (peers) as values.
         *   - lockExpiry  : Lock timeout (seconds) for dropped connections. [optional]
index 94a3b6c..1f9aff1 100644 (file)
@@ -27,7 +27,7 @@ use Psr\Log\LoggerInterface;
  * Class for ensuring a consistent ordering of events as seen by the user, despite replication.
  * Kind of like Hawking's [[Chronology Protection Agency]].
  */
-class ChronologyProtector implements LoggerAwareInterface{
+class ChronologyProtector implements LoggerAwareInterface {
        /** @var BagOStuff */
        protected $store;
        /** @var LoggerInterface */
index 01b6b21..a3ae6f1 100644 (file)
@@ -51,7 +51,6 @@ class DatabaseDomain {
                        throw new InvalidArgumentException( "Prefix must be a string." );
                }
                $this->prefix = $prefix;
-               $this->equivalentString = $this->convertToString();
        }
 
        /**
@@ -105,7 +104,7 @@ class DatabaseDomain {
                        );
                }
 
-               return ( $this->equivalentString === $other );
+               return ( $this->getId() === $other );
        }
 
        /**
@@ -133,6 +132,10 @@ class DatabaseDomain {
         * @return string
         */
        public function getId() {
+               if ( $this->equivalentString === null ) {
+                       $this->equivalentString = $this->convertToString();
+               }
+
                return $this->equivalentString;
        }
 
index d7ca7cd..9c9f18d 100644 (file)
@@ -136,9 +136,9 @@ interface ILBFactory {
        public function flushReplicaSnapshots( $fname = __METHOD__ );
 
        /**
-        * Commit on all connections. Done for two reasons:
-        * 1. To commit changes to the masters.
-        * 2. To release the snapshot on all connections, master and replica DB.
+        * Commit open transactions on all connections. This is useful for two main cases:
+        *   - a) To commit changes to the masters.
+        *   - b) To release the snapshot on all connections, master and replica DBs.
         * @param string $fname Caller name
         * @param array $options Options map:
         *   - maxWriteDuration: abort if more than this much time was spent in write queries
index 85194bc..f5d57c4 100644 (file)
@@ -135,6 +135,36 @@ abstract class LBFactory implements ILBFactory {
                $this->commitMasterChanges( __METHOD__ ); // sanity
        }
 
+       /**
+        * @see ILBFactory::newMainLB()
+        * @param bool $domain
+        * @return LoadBalancer
+        */
+       abstract public function newMainLB( $domain = false );
+
+       /**
+        * @see ILBFactory::getMainLB()
+        * @param bool $domain
+        * @return mixed
+        */
+       abstract public function getMainLB( $domain = false );
+
+       /**
+        * @see ILBFactory::newExternalLB()
+        * @param string $cluster
+        * @param bool $domain
+        * @return LoadBalancer
+        */
+       abstract public function newExternalLB( $cluster, $domain = false );
+
+       /**
+        * @see ILBFactory::getExternalLB()
+        * @param string $cluster
+        * @param bool $domain
+        * @return mixed
+        */
+       abstract public function getExternalLB( $cluster, $domain = false );
+
        /**
         * Call a method of each tracked load balancer
         *
@@ -178,6 +208,8 @@ abstract class LBFactory implements ILBFactory {
                                "$fname: transaction round '{$this->trxRoundId}' still running."
                        );
                }
+               /** @noinspection PhpUnusedLocalVariableInspection */
+               $scope = $this->getScopedPHPBehaviorForCommit(); // try to ignore client aborts
                // Run pre-commit callbacks and suppress post-commit callbacks, aborting on failure
                $this->forEachLBCallMethod( 'finalizeMasterChanges' );
                $this->trxRoundId = false;
@@ -516,6 +548,23 @@ abstract class LBFactory implements ILBFactory {
                $this->requestInfo = $info + $this->requestInfo;
        }
 
+       /**
+        * Make PHP ignore user aborts/disconnects until the returned
+        * value leaves scope. This returns null and does nothing in CLI mode.
+        *
+        * @return ScopedCallback|null
+        */
+       final protected function getScopedPHPBehaviorForCommit() {
+               if ( PHP_SAPI != 'cli' ) { // http://bugs.php.net/bug.php?id=47540
+                       $old = ignore_user_abort( true ); // avoid half-finished operations
+                       return new ScopedCallback( function () use ( $old ) {
+                               ignore_user_abort( $old );
+                       } );
+               }
+
+               return null;
+       }
+
        function __destruct() {
                $this->destroy();
        }
index a60e741..37c028b 100644 (file)
@@ -1101,6 +1101,9 @@ class LoadBalancer implements ILoadBalancer {
        public function commitMasterChanges( $fname = __METHOD__ ) {
                $failures = [];
 
+               /** @noinspection PhpUnusedLocalVariableInspection */
+               $scope = $this->getScopedPHPBehaviorForCommit(); // try to ignore client aborts
+
                $restore = ( $this->trxRoundId !== false );
                $this->trxRoundId = false;
                $this->forEachOpenMasterConnection(
@@ -1516,6 +1519,23 @@ class LoadBalancer implements ILoadBalancer {
                } );
        }
 
+       /**
+        * Make PHP ignore user aborts/disconnects until the returned
+        * value leaves scope. This returns null and does nothing in CLI mode.
+        *
+        * @return ScopedCallback|null
+        */
+       final protected function getScopedPHPBehaviorForCommit() {
+               if ( PHP_SAPI != 'cli' ) { // http://bugs.php.net/bug.php?id=47540
+                       $old = ignore_user_abort( true ); // avoid half-finished operations
+                       return new ScopedCallback( function () use ( $old ) {
+                               ignore_user_abort( $old );
+                       } );
+               }
+
+               return null;
+       }
+
        function __destruct() {
                // Avoid connection leaks for sanity
                $this->closeAll();
index d81f9e1..0f18479 100644 (file)
@@ -274,27 +274,18 @@ class ObjectCache {
         *     // From $wgObjectCaches via newFromParams()
         *     ObjectCache::getLocalServerInstance( [ 'fallback' => $fallbackType ] );
         *
-        * @param int|string|array $fallback Fallback cache or parameter map with 'fallback'
+        * @param int|string $fallback Fallback cache ID
         * @return BagOStuff
         * @throws InvalidArgumentException
         * @since 1.27
+        * @deprecated Since 1.28; use MediaWikiServices::getLocalServerObjectCache
         */
        public static function getLocalServerInstance( $fallback = CACHE_NONE ) {
-               if ( function_exists( 'apc_fetch' ) ) {
-                       $id = 'apc';
-               } elseif ( function_exists( 'xcache_get' ) && wfIniGetBool( 'xcache.var_size' ) ) {
-                       $id = 'xcache';
-               } elseif ( function_exists( 'wincache_ucache_get' ) ) {
-                       $id = 'wincache';
-               } else {
-                       if ( is_array( $fallback ) ) {
-                               $id = isset( $fallback['fallback'] ) ? $fallback['fallback'] : CACHE_NONE;
-                       } else {
-                               $id = $fallback;
-                       }
-               }
+               $cache = MediaWikiServices::getInstance()->getLocalServerObjectCache();
 
-               return self::getInstance( $id );
+               return ( $cache instanceof EmptyBagOStuff )
+                       ? self::getInstance( $fallback )
+                       : $cache;
        }
 
        /**
@@ -383,11 +374,10 @@ class ObjectCache {
         *
         * @since 1.26
         * @return WANObjectCache
+        * @deprecated Since 1.28 Use MediaWikiServices::getMainWANCache()
         */
        public static function getMainWANInstance() {
-               global $wgMainWANCache;
-
-               return self::getWANInstance( $wgMainWANCache );
+               return MediaWikiServices::getInstance()->getMainWANObjectCache();
        }
 
        /**
@@ -407,11 +397,10 @@ class ObjectCache {
         *
         * @return BagOStuff
         * @since 1.26
+        * @deprecated Since 1.28 Use MediaWikiServices::getMainObjectStash
         */
        public static function getMainStashInstance() {
-               global $wgMainStash;
-
-               return self::getInstance( $wgMainStash );
+               return MediaWikiServices::getInstance()->getMainObjectStash();
        }
 
        /**
index 590d51e..a32acc2 100644 (file)
@@ -4138,12 +4138,13 @@ class Parser {
                        # * <b> (r105284)
                        # * <bdi> (bug 72884)
                        # * <span dir="rtl"> and <span dir="ltr"> (bug 35167)
+                       # * <s> and <strike> (T35715)
                        # We strip any parameter from accepted tags (second regex), except dir="rtl|ltr" from <span>,
                        # to allow setting directionality in toc items.
                        $tocline = preg_replace(
                                [
-                                       '#<(?!/?(span|sup|sub|bdi|i|b)(?: [^>]*)?>).*?>#',
-                                       '#<(/?(?:span(?: dir="(?:rtl|ltr)")?|sup|sub|bdi|i|b))(?: .*?)?>#'
+                                       '#<(?!/?(span|sup|sub|bdi|i|b|s|strike)(?: [^>]*)?>).*?>#',
+                                       '#<(/?(?:span(?: dir="(?:rtl|ltr)")?|sup|sub|bdi|i|b|s|strike))(?: .*?)?>#'
                                ],
                                [ '', '<$1>' ],
                                $safeHeadline
index 4a2f759..b17200f 100644 (file)
@@ -26,7 +26,7 @@ use MediaWiki\Logger\LoggerFactory;
 
 /**
  * Object passed around to modules which contains information about the state
- * of a specific loader request
+ * of a specific loader request.
  */
 class ResourceLoaderContext {
        protected $resourceLoader;
@@ -62,26 +62,33 @@ class ResourceLoaderContext {
                $this->request = $request;
                $this->logger = $resourceLoader->getLogger();
 
+               // Future developers: Avoid use of getVal() in this class, which performs
+               // expensive UTF normalisation by default. Use getRawVal() instead.
+               // Values here are either one of a finite number of internal IDs,
+               // or previously-stored user input (e.g. titles, user names) that were passed
+               // to this endpoint by ResourceLoader itself from the canonical value.
+               // Values do not come directly from user input and need not match.
+
                // List of modules
-               $modules = $request->getVal( 'modules' );
+               $modules = $request->getRawVal( 'modules' );
                $this->modules = $modules ? self::expandModuleNames( $modules ) : [];
 
                // Various parameters
-               $this->user = $request->getVal( 'user' );
+               $this->user = $request->getRawVal( 'user' );
                $this->debug = $request->getFuzzyBool(
                        'debug',
                        $resourceLoader->getConfig()->get( 'ResourceLoaderDebug' )
                );
-               $this->only = $request->getVal( 'only', null );
-               $this->version = $request->getVal( 'version', null );
+               $this->only = $request->getRawVal( 'only', null );
+               $this->version = $request->getRawVal( 'version', null );
                $this->raw = $request->getFuzzyBool( 'raw' );
 
                // Image requests
-               $this->image = $request->getVal( 'image' );
-               $this->variant = $request->getVal( 'variant' );
-               $this->format = $request->getVal( 'format' );
+               $this->image = $request->getRawVal( 'image' );
+               $this->variant = $request->getRawVal( 'variant' );
+               $this->format = $request->getRawVal( 'format' );
 
-               $this->skin = $request->getVal( 'skin' );
+               $this->skin = $request->getRawVal( 'skin' );
                $skinnames = Skin::getSkinNames();
                // If no skin is specified, or we don't recognize the skin, use the default skin
                if ( !$this->skin || !isset( $skinnames[$this->skin] ) ) {
@@ -171,7 +178,7 @@ class ResourceLoaderContext {
                if ( $this->language === null ) {
                        // Must be a valid language code after this point (T64849)
                        // Only support uselang values that follow built-in conventions (T102058)
-                       $lang = $this->getRequest()->getVal( 'lang', '' );
+                       $lang = $this->getRequest()->getRawVal( 'lang', '' );
                        // Stricter version of RequestContext::sanitizeLangCode()
                        if ( !Language::isValidBuiltInCode( $lang ) ) {
                                wfDebug( "Invalid user language code\n" );
@@ -187,7 +194,7 @@ class ResourceLoaderContext {
         */
        public function getDirection() {
                if ( $this->direction === null ) {
-                       $this->direction = $this->getRequest()->getVal( 'dir' );
+                       $this->direction = $this->getRequest()->getRawVal( 'dir' );
                        if ( !$this->direction ) {
                                // Determine directionality based on user language (bug 6100)
                                $this->direction = Language::factory( $this->getLanguage() )->getDir();
index 4d0bff7..aef1c74 100644 (file)
@@ -55,12 +55,6 @@ class ResourceLoaderUserCSSPrefsModule extends ResourceLoaderModule {
                        $rules[] = "a { text-decoration: " .
                                ( $options['underline'] ? 'underline' : 'none' ) . "; }";
                }
-               if ( $options['editfont'] !== 'default' ) {
-                       // Double-check that $options['editfont'] consists of safe characters only
-                       if ( preg_match( '/^[a-zA-Z0-9_, -]+$/', $options['editfont'] ) ) {
-                               $rules[] = "textarea { font-family: {$options['editfont']}; }\n";
-                       }
-               }
                $style = implode( "\n", $rules );
                if ( $this->getFlip( $context ) ) {
                        $style = CSSJanus::transform( $style, true, false );
index 4fdd86e..7cbec70 100644 (file)
@@ -305,7 +305,11 @@ class ResourceLoaderWikiModule extends ResourceLoaderModule {
                $titleInfo = [];
                $batch = new LinkBatch;
                foreach ( $pages as $titleText ) {
-                       $batch->addObj( Title::newFromText( $titleText ) );
+                       $title = Title::newFromText( $titleText );
+                       if ( $title ) {
+                               // Page name may be invalid if user-provided (e.g. gadgets)
+                               $batch->addObj( $title );
+                       }
                }
                if ( !$batch->isEmpty() ) {
                        $res = $db->select( 'page',
@@ -359,8 +363,16 @@ class ResourceLoaderWikiModule extends ResourceLoaderModule {
                        // Before we intersect, map the names to canonical form (T145673).
                        $intersect = [];
                        foreach ( $pages as $page => $unused ) {
-                               $title = Title::newFromText( $page )->getPrefixedText();
-                               $intersect[$title] = 1;
+                               $title = Title::newFromText( $page );
+                               if ( $title ) {
+                                       $intersect[ $title->getPrefixedText() ] = 1;
+                               } else {
+                                       // Page name may be invalid if user-provided (e.g. gadgets)
+                                       $rl->getLogger()->info(
+                                               'Invalid wiki page title "{title}" in ' . __METHOD__,
+                                               [ 'title' => $page ]
+                                       );
+                               }
                        }
                        $info = array_intersect_key( $allInfo, $intersect );
 
index a5a45d5..0defcd1 100644 (file)
@@ -68,8 +68,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
         */
        private function initServices() {
                if ( !$this->titleParser ) {
-                       $lang = $this->getContext()->getLanguage();
-                       $this->titleParser = new MediaWikiTitleCodec( $lang, GenderCache::singleton() );
+                       $this->titleParser = MediaWikiServices::getInstance()->getTitleParser();
                }
        }
 
@@ -205,7 +204,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
                        }
                }
 
-               GenderCache::singleton()->doTitlesArray( $titles );
+               MediaWikiServices::getInstance()->getGenderCache()->doTitlesArray( $titles );
 
                $list = [];
                /** @var Title $title */
@@ -355,7 +354,7 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
                                }
                        }
 
-                       GenderCache::singleton()->doTitlesArray( $titles );
+                       MediaWikiServices::getInstance()->getGenderCache()->doTitlesArray( $titles );
 
                        foreach ( $titles as $title ) {
                                $list[] = $title->getPrefixedText();
@@ -431,20 +430,22 @@ class SpecialEditWatchlist extends UnlistedSpecialPage {
                }
 
                $user = $this->getUser();
-               $store = MediaWikiServices::getInstance()->getWatchedItemStore();
-
-               foreach ( $this->badItems as $row ) {
-                       list( $title, $namespace, $dbKey ) = $row;
-                       $action = $title ? 'cleaning up' : 'deleting';
-                       wfDebug( "User {$user->getName()} has broken watchlist item ns($namespace):$dbKey, $action.\n" );
-
-                       $store->removeWatch( $user, new TitleValue( (int)$namespace, $dbKey ) );
-
-                       // Can't just do an UPDATE instead of DELETE/INSERT due to unique index
-                       if ( $title ) {
-                               $user->addWatch( $title );
+               $badItems = $this->badItems;
+               DeferredUpdates::addCallableUpdate( function () use ( $user, $badItems ) {
+                       $store = MediaWikiServices::getInstance()->getWatchedItemStore();
+                       foreach ( $badItems as $row ) {
+                               list( $title, $namespace, $dbKey ) = $row;
+                               $action = $title ? 'cleaning up' : 'deleting';
+                               wfDebug( "User {$user->getName()} has broken watchlist item " .
+                                       "ns($namespace):$dbKey, $action.\n" );
+
+                               $store->removeWatch( $user, new TitleValue( (int)$namespace, $dbKey ) );
+                               // Can't just do an UPDATE instead of DELETE/INSERT due to unique index
+                               if ( $title ) {
+                                       $user->addWatch( $title );
+                               }
                        }
-               }
+               } );
        }
 
        /**
index eae57f4..57610fc 100644 (file)
@@ -68,7 +68,7 @@ class BotPassword implements IDBAccessObject {
        /**
         * Get a database connection for the bot passwords database
         * @param int $db Index of the connection to get, e.g. DB_MASTER or DB_REPLICA.
-        * @return DatabaseBase
+        * @return Database
         */
        public static function getDB( $db ) {
                global $wgBotPasswordsCluster, $wgBotPasswordsDatabase;
index aab16b4..54fe2cb 100644 (file)
        "upload-dialog-disabled": "Nesta wiki tán desactivaes les xubíes de ficheros por aciu d'esti diálogu.",
        "upload-dialog-title": "Xubir ficheru",
        "upload-dialog-button-cancel": "Encaboxar",
+       "upload-dialog-button-back": "Anterior",
        "upload-dialog-button-done": "Fecho",
        "upload-dialog-button-save": "Guardar",
        "upload-dialog-button-upload": "Xubir",
        "htmlform-cloner-create": "Amestar más",
        "htmlform-cloner-delete": "Desaniciar",
        "htmlform-cloner-required": "Necesítase polo menos un valor.",
+       "htmlform-date-placeholder": "AAAA-MM-DD",
+       "htmlform-time-placeholder": "HH:MM:SS",
+       "htmlform-datetime-placeholder": "AAAA-MM-DD HH:MM:SS",
+       "htmlform-date-invalid": "El valor que disti nun ye una data reconocible. Prueba usando'l formatu AAAA-MM-DD.",
+       "htmlform-time-invalid": "El valor que disti nun ye una hora reconocible. Prueba usando'l formatu HH:MM:SS.",
+       "htmlform-datetime-invalid": "Nun se reconoció la fecha y hora nel formatu proporcionáu. Prueba a usar el formatu AAAA-MM-DD HH:MM:SS.",
+       "htmlform-date-toolow": "El valor que disti ye anterior a la fecha más antigua permitida, $1.",
+       "htmlform-date-toohigh": "El valor especificáu ye posterior a la mayor data permitida, $1.",
+       "htmlform-time-toolow": "El valor qu'especificasti ye anterior a la hora más antigua permitida, $1.",
+       "htmlform-time-toohigh": "El valor qu'especificasti ye posterior a la hora más nueva permitida, $1.",
+       "htmlform-datetime-toolow": "El valor qu'especificasti ye anterior a la fecha y hora más antigua permitida, $1.",
+       "htmlform-datetime-toohigh": "El valor qu'especificasti ye posterior a la fecha y hora más nueva permitida, $1.",
        "htmlform-title-badnamespace": "[[:$1]] nun ta nel espaciu de nomes \"{{ns:$2}}\".",
        "htmlform-title-not-creatable": "«$1» nun ye un títulu de páxina que pueda crease",
        "htmlform-title-not-exists": "$1 nun esiste.",
        "unlinkaccounts-success": "Desenllazóse la cuenta.",
        "authenticationdatachange-ignored": "Nun se xestionó'l cambéu de los datos d'autentificacion. ¿Seique, nun se configuró un fornidor?",
        "userjsispublic": "Atención: les subpáxines JavaScript nun tendríen de contener datos acutaos porque son visibles pa otros usuarios.",
-       "usercssispublic": "Atención: les subpáxines CSS nun tendríen de contener datos acutaos porque son visibles pa otros usuarios."
+       "usercssispublic": "Atención: les subpáxines CSS nun tendríen de contener datos acutaos porque son visibles pa otros usuarios.",
+       "restrictionsfield-badip": "Direición o rangu IP inválidu: $1",
+       "restrictionsfield-label": "Rangos d'IP permitíos:",
+       "restrictionsfield-help": "Una única direición IP o rangu CIDR per llinia. P'activar toos, utiliza<br><code>0.0.0.0/0</code><br><code>::/0</code>"
 }
index add8bea..c4d8ba5 100644 (file)
        "yourpasswordagain": "Parolu təkrar daxil edin:",
        "createacct-yourpasswordagain": "Parolu təsdiqlə",
        "createacct-yourpasswordagain-ph": "Parolu təkrar daxil edin",
-       "remembermypassword": "Məni bu kompyuterdə xatırla (maksimum $1 {{PLURAL:$1|gün|gün}})",
        "userlogin-remembermypassword": "Sistemdə qal",
        "userlogin-signwithsecure": "Etibarlı bağlantıdan istifadə edin",
        "yourdomainname": "Sizin domeniniz:",
        "listgrouprights-addgroup-self-all": "Bütün qrupları öz hesabına əlavə edə bilər",
        "listgrouprights-removegroup-self-all": "Bütün qrupları öz hesabından çıxara bilər",
        "listgrouprights-namespaceprotection-namespace": "Adlar fəzası",
+       "restricted-displaytitle-ignored": "İmtina edilmiş görüntü başlıqlarına malik səhifələr",
        "mailnologin": "Ünvan yoxdur",
        "emailuser": "İstifadəçiyə e-məktub göndər",
        "defemailsubject": "\"$1\" adlı istifadəçidən {{SITENAME}} e-məktubu",
        "htmlform-selectorother-other": "Digər",
        "htmlform-no": "Xeyr",
        "htmlform-yes": "Bəli",
-       "sqlite-has-fts": "$1 tam mətn axtarma ilə",
-       "sqlite-no-fts": "$1 tam mətn axtarma olmadan",
        "logentry-delete-delete": "$1 $3 səhifəsini {{GENDER:$2|sildi}}",
        "logentry-suppress-delete": "$1 $3 səhifəsini {{GENDER:$2|gizlətdi}}",
        "revdelete-content-hid": "gizli mətn",
index 61fcf51..9a8c53b 100644 (file)
        "htmlform-cloner-delete": "Выдаліць",
        "htmlform-cloner-required": "Патрабуецца як мінімум яшчэ адно значэньне.",
        "htmlform-date-placeholder": "ГГГГ-ММ-ДД",
+       "htmlform-time-placeholder": "ГГ:ХХ:СС",
+       "htmlform-datetime-placeholder": "ГГГГ-ММ-ДД ГГ:ХХ:СС",
        "htmlform-title-badnamespace": "[[:$1]] знаходзіцца не ў прасторы назваў «{{ns:$2}}».",
        "htmlform-title-not-creatable": "«$1» — немагчымы загаловак для старонкі",
        "htmlform-title-not-exists": "$1 не існуе.",
index ad786d5..3307a81 100644 (file)
        "hr_tip": "Xeta verardiye (teserrufın bıgureyne/bıxebetne)",
        "summary": "Xulasa:",
        "subject": "Mewzu:",
-       "minoredit": "Vurriyayışo werdiyo",
+       "minoredit": "Vuriyayışa werdi",
        "watchthis": "Na pele seyr ke",
        "savearticle": "Qeyd ke",
        "savechanges": "Vurnayışan qeyd ke",
        "recentchanges-noresult": "Goreyê kriteranê kıfşkerdeyan ra qet yew vurnayış nêvêniya.",
        "recentchanges-feed-description": "Ena feed dı vurnayişanê tewr peniyan teqip bık.",
        "recentchanges-label-newpage": "Enê vurnayışi ra yu pera newi vıraziya ya",
-       "recentchanges-label-minor": "Vurriyayışo werdiyo",
+       "recentchanges-label-minor": "Vuriyayışa werdi",
        "recentchanges-label-bot": "Eno vurnayış terefê yew boti ra vıraziyo",
        "recentchanges-label-unpatrolled": "Eno vurnayış hewna dewriya nêbiyo",
        "recentchanges-label-plusminus": "Ebadê pele de bazê bayti de vayeyê cı",
        "recentchanges-submit": "Bımocne",
        "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>",
        "rclistfrom": "$3 $2 ra tepiya vurnayışanê neweyan bımocne",
-       "rcshowhideminor": "vurriyayışê werdi $1",
+       "rcshowhideminor": "Vuriyayışa werdi ya $1",
        "rcshowhideminor-show": "Bımocne",
        "rcshowhideminor-hide": "Bınımne",
        "rcshowhidebots": "botan $1",
        "watchlist-hide": "Bınımne",
        "watchlist-submit": "Bımocne",
        "wlshowtime": "Periyoda zemani asenayışi:",
-       "wlshowhideminor": "vurriyayışê werdi",
+       "wlshowhideminor": "Vuriyayışa werdi",
        "wlshowhidebots": "boti",
        "wlshowhideliu": "karberê qeydıni",
        "wlshowhideanons": "karberê anonimi",
        "tooltip-pt-login": "Mayê şıma ronıştış akerdışi rê dawet keme; labelê ronıştış mecburi niyo",
        "tooltip-pt-logout": "Bıveciye",
        "tooltip-pt-createaccount": "Şıma rê tewsiyey ma xorê jew hesab akerê. Fına zi hesab akerdış mecburi niyo.",
-       "tooltip-ca-talk": "Heqa zerrekê pele de werênayış",
+       "tooltip-ca-talk": "Heqdë zerrekë perra vaten",
        "tooltip-ca-edit": "Ena pele bıvurne",
        "tooltip-ca-addsection": "Zu bınnusteya newi ak",
        "tooltip-ca-viewsource": "Ena pele kılit biya.\nŞıma şenê çımeyê aye bıvênê",
index 45a79b0..545d50a 100644 (file)
        "views": "अवलोकन गरऽ",
        "toolbox": "औजारअन",
        "tool-link-userrights": "परिवर्तन{{GENDER:$1|प्रयोगकर्ता}}समूहहरू",
-       "tool-link-emailuser": "यो ईमेल{{GENDER:$|प्रयोगकर्ता}}",
+       "tool-link-emailuser": "{{GENDER:$1|प्रयोगकर्ता}}लाई एइ इमेलमी पठाऽ",
        "userpage": "प्रयोगकर्ता पाना हेर्न्या",
        "projectpage": "प्रोजेक्ट पानो हेर्न्या",
        "imagepage": "चित्र पानो हेर",
        "databaseerror-query": "अनुरोध: $1",
        "databaseerror-function": "फङ्सन : $1",
        "databaseerror-error": "गल्ती: $1",
+       "transaction-duration-limit-exceeded": "To avoid creating high replication lag, this transaction was aborted because the write duration ($1) exceeded the $2 second limit.\nIf you are changing many items at once, try doing multiple smaller operations instead.",
        "laggedslavemode": "<strong>चेतावनी:</strong> पानामी हालका अद्यतनहरू नहुनस्कदान ।",
        "readonly": "डेटाबेस बन्द गरिया छ",
        "enterlockreason": "ताल्चा मार्नुको कारण दिया, साथै ताल्चा हटाउने समयको अवधि अनुमान लगा।",
        "title-invalid-interwiki": "अनुरोध गरियाको शिर्षकमी अन्तर विकि लिङ्क छ जइलाई शिर्षकमी प्रयोग गद्द नाइपाइनो ।",
        "title-invalid-talk-namespace": "निवेदन गरियाको पानाको शिर्षकले उपलब्ध नभएका कुरडी पानालाई सन्दर्भको रूपमी राख्याको छ ।",
        "title-invalid-characters": "निवेदन गरियाको यै पानाको शिर्षकमी अवैध अक्षर रयाको छः \"$1\" ।",
+       "title-invalid-relative": "शीर्षक एउटा सन्दर्भित मार्ग राख्दछ। सन्दर्भित पृष्ठको शीर्षक (./, ../)अमान्य छ, किनकि त्यो प्राय रूपले पहुँच बाहिर हुन्छ जब त्यसलाई प्रायोगकर्ताको ब्राउजरबाट प्रयोगमी ल्याउने प्रयास गर्ने गरिन्छ।",
        "title-invalid-magic-tilde": "अनुरोध अरिया: पन्ना: शीर्षकमी अमान्य म्याजिक टिल्ड शृङ्खला छ (<nowiki>~~~</nowiki>)।",
        "title-invalid-too-long": "अनुरोध अरिया: पन्ना: शीर्षक भौत लामु छ। यो UTF-8 इनकोडिङमी $1 {{PLURAL:$1|byte|bytes}} है लामु हुनु हुनैन।",
        "title-invalid-leading-colon": "निवेदन गरिया पृष्ठको शिर्षकको शुरूमी अवैध कोलोन रया छ ।",
        "viewsource": "स्रोत हेर",
        "viewsource-title": " $1 को स्रोत हेर",
        "actionthrottled": "कार्य रोकिईयो",
-       "actionthrottledtext": "स्पामको रोकथामको लागि , तमीलाई यो कार्य नापै समयमी मैथै पटक गद्दाबठे सिमित गरियाको छ, र तमीले आफ्नो सिमा पार गरिसक्याछौ ।\nकृपया केही मिनेट पछि पुन: प्रयास गर  ।",
+       "actionthrottledtext": "स्पाम रोकथाम खिलाइ, तमलाई येइ काम थोक्काइ बगतमी झिक्कै फेर अद्दा बठेइ सीमित अरीरैछ, रे तमले आफुनी सीमा पार अरिसकिराइछऽ।\nकृपया केइ मिनट पछा दोसर्‍याँ प्रयास अर्याऽ।",
        "protectedpagetext": "यो पृष्ठ सम्पादन हुनबठे बचाउन सम्पादनमी तथा अन्य कार्यमी रोक लगाइया छ।",
        "viewsourcetext": "तम ये पृष्ठको स्रोत हेद्दु सकुन्छौ और उईको नक्कल उताद्दु सकुन्छौ |",
        "viewyourtext": "यै पानामी रह्याका '''तमरा सम्पादनहरू''' हेद्द या प्रतिलिपी गद्द सक्द्या हौ :",
+       "protectedinterface": "यो पृष्ठले सफ्टवेयरको लागि अन्तरमोहडा पाठ प्रदान गर्दछ , र यसलाई दुरुपयोग हुनबाट बचाउन सुरक्षा प्रदान गरिएको छ।\nसम्पूर्ण विकिहरूका लागि अनुवादमी परिवर्तन गर्नको लागि [https://translatewiki.net/ translatewiki.net], प्रयोग गर्नुहोस् ,  मिडियाविकि स्थानियकरण परियोजना ।",
        "editinginterface": "<strong>चेतावनी:</strong> तमी यै पानालाई सम्पादन गद्द लाग्याछौ, जनले सफ्टवेयरको लागि \nइन्टरफेस सामग्रीहरू प्रदान गरन्छ।\nयै पानामी गरियाको परिवर्तनले यै विकिमी अरु प्रयोगकर्तानको इन्टरफेसको प्रदर्शनमी प्रभाव पडन्छ ।",
        "translateinterface": "सप्पै विकिइनखिलाइ अनुवाद थप्दाइ या बदेल्लाइ, कृपया [https://translatewiki.net/ translatewiki.net]को प्रयोग अर:, मिडियाविकि क्षेत्रीयकरण परियोजना:।",
+       "cascadeprotected": "यो पृष्ठ सम्पादन गर्नबाट सुरक्षित गरिएकोछ किनभनें {{PLURAL:$1|पृष्ठ |पृष्ठहरू}}मा सुरक्षित गर्नुका साथै प्रपात (\"cascading\") विकल्प खुल्ला राखिएको छ:\n$2",
        "namespaceprotected": "तमलाई '''$1'''  नेमस्पेसमी रह्याका पानाहरू सम्पादन गद्या अनुमति छैन ।",
        "customcssprotected": "तमलाई यो  पानो सम्पादन गद्दे अनुमति छैन, किनकी यैमी कुनै अर्को प्रयोगकर्ताको व्यक्तिगत अभिरुचीहरू संग्रहित छन् ।",
        "customjsprotected": "तमलाई यो जाभास्कृप्ट पानो सम्पादन गद्दे अनुमति छैन, किनकी यैमी कुनै अर्को प्रयोगकर्ताको व्यक्तिगत अभिरुचीहरू संग्रहित छन् ।",
        "changepassword-success": "तमरो पासवर्ड सफलतापूर्वक परिवर्तन भयो!",
        "changepassword-throttled": "तमले अलै भौत फेर प्रवेशका निम्ति प्रयास गरया छौ।\nकृपया $1 थोक्कै जागी मात्र प्रयास गर।",
        "botpasswords": "बोट पासवर्ड",
+       "botpasswords-createnew": "नौलो बोट पासवर्ड बनाऽ",
+       "botpasswords-editexisting": "भयाऽ बोट पासवर्ड सम्पादन अरऽ",
        "botpasswords-label-appid": "बोट नाम:",
        "botpasswords-label-create": "सृजना गर",
        "botpasswords-label-update": "नयाँ बनाउनु",
        "botpasswords-label-resetpassword": "पासवर्ड पूर्वनिर्धारित गर",
        "botpasswords-label-grants": "अनुदान आवेदन:",
        "botpasswords-label-grants-column": "प्रदान भयो",
+       "botpasswords-bad-appid": "बोट नाउँ \"$1\" नाइमाणीनो।",
+       "botpasswords-insert-failed": "बोट नाउँ \"$1\" थप्दाइ असफल। कि यो पैली थपीसकीरैछ?",
+       "botpasswords-update-failed": "बोट नाउँ \"$1\" अपडेट अद्दाइ असफल। कि यो मेट्याऽ हो?",
        "botpasswords-created-title": "बोट को पासवर्ड बन्यो",
+       "botpasswords-created-body": "प्रयोगकर्ता \"$2\" को बोट नाउँ \"$1\" खिलाइ बोट पासवर्ड बनायियो।",
        "botpasswords-updated-title": "बोट को पासवर्ड अपडेट भयो",
        "botpasswords-deleted-title": "बोट को पासवर्ड मेटियो",
        "resetpass_forbidden": "पासवर्ड परिवर्तन गर्न नाइँमिल्लो",
        "protect-default": "सब्बै प्रयोगकर्तानहरूलाई अनुमति दिन्या",
        "protect-level-autoconfirmed": "नौला तथा दर्ता भयाका प्रयोगकर्तानलाई मात्र अनुमति दिन्या",
        "protect-cascade": "यै पानामी संलग्न सुरक्षित पानाहरू (लामबद्द सुरक्षा)",
+       "protect-expiry-options": "२ घण्टाहरू:2 hours,१ दिन :1 day,३ दिनहरू:3 days,१ हप्ता:1 week,२ हप्ताहरू:2 weeks,१ महिना:1 month,३ महिनाहरू:3 months,६ महिनाहरू:6 months,१ वर्ष:1 year,अनगिन्ती:infinite",
+       "restriction-type": "अनुमति:",
        "pagesize": "(अक्षरहरू)",
        "undeletepage": "मेट्याका पानाहरू हेद्या र पूर्वरुपमी फर्काउन्या",
        "undeleterevisions": "$1 {{PLURAL:$1|संशोधन|संशोधनहरू}} संग्रहित",
index 5cbe965..d1546a1 100644 (file)
        "logentry-newusers-autocreate": "Uzantokonto $1 estis {{GENDER:$2|kreita}} aŭtomate",
        "logentry-protect-move_prot": "$1 {{GENDER:$2|movis}} protektajn agordojn el $4 al $3",
        "logentry-protect-unprotect": "$1 {{GENDER:$2|forigis}} protekton el $3",
-       "logentry-protect-protect": "$1 {{GENDER:$2|protektis}} $3 $4",
+       "logentry-protect-protect": "$1 {{GENDER:$2|protektis}} la paĝon $3 $4",
        "logentry-protect-protect-cascade": "$1 {{GENDER:$2|protektis}} $3 $4 [rikure]",
        "logentry-protect-modify": "$1 {{GENDER:$2|ŝanĝis}} la nivelon de protekto de $3 $4",
        "logentry-protect-modify-cascade": "$1 {{GENDER:$2|ŝanĝis}} la nivelon de protekto de $3 $4 [rikure]",
index def34be..93f0896 100644 (file)
        "upload-foreign-cant-upload": "Tätä wikiä ei ole konfiguroitu tallentamaan tiedostoja pyydettyyn ulkoiseen tiedostovarastoon.",
        "upload-dialog-title": "Tiedoston tallennus",
        "upload-dialog-button-cancel": "Peru",
+       "upload-dialog-button-back": "Takaisin",
        "upload-dialog-button-done": "Valmis",
        "upload-dialog-button-save": "Tallenna",
        "upload-dialog-button-upload": "Tallenna",
        "linkaccounts-submit": "Linkitä tunnuksia",
        "unlinkaccounts": "Poista tunnusten linkityksiä",
        "unlinkaccounts-success": "Tunnuksen linkitys poistettiin.",
-       "authenticationdatachange-ignored": "Varmennustietojen muutosta ei käsitelty. Ehkä palveluntarjoajaa ei määritelty?"
+       "authenticationdatachange-ignored": "Varmennustietojen muutosta ei käsitelty. Ehkä palveluntarjoajaa ei määritelty?",
+       "restrictionsfield-badip": "Virheellinen IP-osoite tai alue: $1",
+       "restrictionsfield-label": "Sallitut IP-alueet:"
 }
index d57e53f..79538b2 100644 (file)
        "prefs-emailconfirm-label": "Confirmation du courriel :",
        "youremail": "Courriel :",
        "username": "{{GENDER:$1|Nom d'utilisateur|Nom d'utilisatrice}} :",
-       "prefs-memberingroups": "{{GENDER:$2|Membre}} {{PLURAL:$1|du groupe|des groupes}}:",
+       "prefs-memberingroups": "{{GENDER:$2|Membre}} {{PLURAL:$1|du groupe|des groupes}} :",
        "prefs-registration": "Date d'inscription :",
        "yourrealname": "Nom réel :",
        "yourlanguage": "Langue :",
index bdfcfb5..59bd416 100644 (file)
        "upload-dialog-disabled": "אין אפשרות להעלות קבצים באמצעות תיבת הדו־שיח הזאת באתר זה.",
        "upload-dialog-title": "העלאת קובץ",
        "upload-dialog-button-cancel": "ביטול",
+       "upload-dialog-button-back": "חזרה",
        "upload-dialog-button-done": "בוצע",
        "upload-dialog-button-save": "שמירה",
        "upload-dialog-button-upload": "העלאה",
index 97f9194..328d5c7 100644 (file)
        "listfiles_date": "Data",
        "listfiles_name": "Nome",
        "listfiles_user": "Utente",
-       "listfiles_size": "Dimensione in byte",
+       "listfiles_size": "Dimensione",
        "listfiles_description": "Descrizione",
        "listfiles_count": "Versioni",
        "listfiles-show-all": "Includi le vecchie versioni delle immagini",
index 5106ff4..767938c 100644 (file)
        "htmlform-date-invalid": "De Wäert deen Dir aginn hutt gouf net als Datum erkannt. Probéiert de Format JJJJ-MM-DD ze benotzen.",
        "htmlform-time-invalid": "De Wäert deen Dir aginn hutt gouf net als Zäit erkannt. Probéiert de Format HH:MM:SS ze benotzen.",
        "htmlform-datetime-invalid": "De Wäert deen Dir aginn hutt gouf net als Datum an Zäit erkannt. Probéiert de Format JJJJ-MM-DD HH:MM:SS ze benotzen.",
+       "htmlform-date-toolow": "De Wäert deen Dir aginn hutt ass virun deem éischten erlaabten Datum vum $1.",
+       "htmlform-date-toohigh": "De wäert deen Dir aginn hutt ass nom leschten erlaabten Datum vum $1.",
+       "htmlform-time-toolow": "De Wäert deen Dir aginn hutt ass virun der éischter erlaabter Zäit vu(n) $1.",
+       "htmlform-time-toohigh": "De Wäert deen Dir aginn hutt ass no der leschter erlaabter Zäit vu(n) $1.",
        "htmlform-title-badnamespace": "[[:$1]] ass net am Nummraum \"{{ns:$2}}\".",
        "htmlform-title-not-creatable": "\"$1\" ass kee Säitentitel deen ugeluecht ka ginn",
        "htmlform-title-not-exists": "$1 gëtt et net.",
index 90f5c98..ee6a8bc 100644 (file)
        "upload-foreign-cant-upload": "Šis vikis nėra sukonfigūruotas failų įkėlimui į nurodytą išorinę failų talpyklą.",
        "upload-dialog-title": "Įkelti failą",
        "upload-dialog-button-cancel": "Atšaukti",
+       "upload-dialog-button-back": "Atgal",
        "upload-dialog-button-done": "Atlikta",
        "upload-dialog-button-save": "Išsaugoti",
        "upload-dialog-button-upload": "Įkelti",
index 0d7f4fb..cd09ec9 100644 (file)
        "permissionserrorstext-withaction": "अहाँक अनुमति नै अछि $2 लेल, एकर लेल {{PLURAL:$1|कारण|कारणसभ}}सँ:",
        "recreate-moveddeleted-warn": "'''चेतौनी''': अहाँ फेरसँ ओ पन्ना बना रहल छी जे पहिने मेटा देल गेल छै।'''\n\nअहाँ विचारू जे की ई सम्पादन केनाइ उचित अछि।\nऐ पन्नाक मेटाएल बला आ हटाएल वृत्तलेख एतए सुविधा लेल देल जा रहल अछि:",
        "moveddeleted-notice": "ई पन्ना मेटाएल गेल अछि।\nई पन्ना लेल मेटाएल आ स्थानान्तरणक लग सन्दर्भ लेल नीचाँ देल गेल अछि।",
-       "log-fulllog": "सभà¤\9fा à¤µà¥\83तà¥\8dतलà¥\87à¤\96 देखी",
+       "log-fulllog": "समà¥\8dपà¥\82रà¥\8dण à¤²à¥\8cà¤\97 देखी",
        "edit-hook-aborted": "सम्पादन नोकसीसँ खतम भेल।\nई कोनो कारण नै देलक।",
        "edit-gone-missing": "पन्ना अद्यतन नै भऽ सकल।\nलगैए जे ई मेटा देल गेल अछि।",
        "edit-conflict": "सम्पादन अन्तर्विरोध",
        "expansion-depth-exceeded-warning": "पन्ना विस्तार गहिराई पार केनए अछि",
        "parser-unstrip-loop-warning": "Unstrip लूप पाओल गेल",
        "parser-unstrip-recursion-limit": "Unstrip पुनरावर्तन सीमा पार कइर गेल($1)",
-       "converter-manual-rule-error": "म्यानुअल भाषा परिवर्तन नियम में त्रुटि",
+       "converter-manual-rule-error": "म्यानुअल भाषा परिवर्तन नियममे त्रुटि",
        "undo-success": "ई सम्पादन पूर्ववत बदलल जा सकैए।\nकृपा क' नीचाँक तुलनाक जाँच करू ई देखैले जे ई वएह भेल अछि जे अहाँ चाहै छलहुँ, आ तखन सम्पादन ख़तम करबा लेल नीचाँक परिवर्तन सुरक्षित करू ।",
        "undo-failure": "मध्यवर्ती विरोधी सम्पादनक कारण ऐ सम्पादनकेँ खतम नै कएल जा सकैए।",
        "undo-norev": "ई सम्पादन खतम नै कएला जा सकैए कारण ई अछि नै वा मेटा देल गेल अछि।",
        "revdelete-show-file-submit": "हँ",
        "revdelete-selected-text": "[[:$2]] {{PLURAL:$1|क|के}} चयनित अवतरण:",
        "revdelete-selected-file": "[[:$2]] {{PLURAL:$1|क|के}} चयनित फाइल अवतरण:",
-       "logdelete-selected": "{{PLURAL:$1|à¤\9aà¥\81नल à¤µà¥\83तà¥\8dतलà¥\87à¤\96 à¤\98à¤\9fना|à¤\9aà¥\81नल à¤µà¥\83तà¥\8dतलà¥\87à¤\96 घटनासभ}}:",
+       "logdelete-selected": "{{PLURAL:$1|à¤\9aà¥\81नल à¤²à¥\8cà¤\97 à¤\98à¤\9fना|à¤\9aà¥\81नल à¤²à¥\8cà¤\97 घटनासभ}}:",
        "revdelete-text-text": "हटाएल गेल अवतरण पृष्ठ इतिहासमें देखाएल जाएत मुदा वोकर सामग्री सार्वजनिक रूपसँ नै देखाएल जा सकएत अछि।",
        "revdelete-text-file": "हटाएल गेल अवतरण पृष्ठ इतिहासमें देखाएल जाएत मुदा वोकर सामग्री सार्वजनिक रूपसँ नै देखाएल जा सकएत अछि।",
        "logdelete-text": "हटाए गेल प्रवेश घटनासभ अखैनो भी लॉग में दिखाबल ज्यात, लेकिन ओकर सामग्री के कुछ भाग के सार्वजनीक करबाक के लेल दुर्गम भ्या जेत।",
        "revdelete-reasonotherlist": "दोसर कारण",
        "revdelete-edit-reasonlist": "मेटेबाक कारण बदली",
        "revdelete-offender": "संशोधन केनिहार:",
-       "suppressionlog": "दबाà¤\8fलà¤\97à¥\87ल à¤µà¥\83तà¥\8dतलà¥\87à¤\96",
+       "suppressionlog": "नà¥\81à¤\95ाà¤\8fल à¤²à¥\8cà¤\97",
        "suppressionlogtext": "नीचाँ मेटाएल आ प्रतिबन्धक उल्लेख अछि जे संचालकसँ नुकाएल सामिग्री अछि।\nअखन स्थित प्रभावी प्रतिबन्ध आ अवरोध लेल देखू [[Special:BlockList|IP block list]] ।",
-       "mergehistory": "मिà¤\9cà¥\8dà¤\9dर à¤­à¥\87ल à¤ªà¤¨à¥\8dना à¤¸à¤­à¤\95 à¤\87तिहास",
+       "mergehistory": "पà¥\83षà¥\8dठà¤\95 à¤\87तिहास à¤\8fà¤\95तà¥\8dरित à¤\95रà¥\80",
        "mergehistory-header": "ई पन्ना अहाँकेँ एकटा स्रोत पन्नाक एकटा नव पन्नामे संशोधन इतिहासकेँ मिज्झर करबाक अनुमति दैत अछि।\nसुनिश्चित होउ जे ई परिवर्तन ऐतिहासिक पन्ना सांतत्य स्थापित करत।",
-       "mergehistory-box": "दà¥\82 à¤ªà¤¨à¥\8dनाà¤\95 à¤¸à¤\82शà¥\8bधन à¤®à¤¿à¤\9cà¥\8dà¤\9dर à¤\95रà¥\80।",
+       "mergehistory-box": "दà¥\81à¤\88 à¤ªà¥\83षà¥\8dठसभà¤\95 à¤\87तिहास à¤\8fà¤\95तà¥\8dरित à¤\95रà¥\80:",
        "mergehistory-from": "मूल पन्ना:",
        "mergehistory-into": "लक्ष्य पन्ना:",
-       "mergehistory-list": "मिà¤\9cà¥\8dà¤\9dर à¤¯à¥\8bà¤\97à¥\8dय सम्पादन इतिहास",
+       "mergehistory-list": "à¤\8fà¤\95तà¥\8dरितà¥\80à¤\95रण सम्पादन इतिहास",
        "mergehistory-merge": "[[:$1]] एकर संशोधन सभकेँ [[:$2]] मे मिलाएल जा सकैए।\nरेडियो बटन स्तम्भक प्रयोग मात्र संशोधनकेँ निर्धारित समए वा ओइसँ पहिने मिज्झर करबामे प्रयोग करू।\nमोन राखू जे उपर नीचाँक लागिक प्रयोग ऐ स्तम्भकेँ पुनर्स्थापित कऽ देत।",
-       "mergehistory-go": "मिà¤\9cà¥\8dà¤\9dर à¤¹à¥\8bà¤\87 à¤¯à¥\8bà¤\97à¥\8dय à¤¸à¤®à¥\8dपादन à¤¸à¤­à¤\95à¥\87à¤\81 à¤¦à¥\87à¤\96ाà¤\89",
-       "mergehistory-submit": "सà¤\82शà¥\8bधन à¤¸à¤­à¤\95à¥\87 à¤®à¤¿à¤\9cà¥\8dà¤\9dर करी",
-       "mergehistory-empty": "à¤\95à¥\8bनà¥\8b à¤¸à¤\82शà¥\8bधन à¤®à¤¿à¤\9cà¥\8dà¤\9dर à¤¨à¥\88 à¤\95à¤\8fल à¤\9cा à¤¸à¤\95à¥\88à¤\8f।",
+       "mergehistory-go": "à¤\8fà¤\95तà¥\8dरित à¤\95रà¥\88लà¥\87ल à¤²à¤¾à¤¯à¤\95 à¤¸à¤®à¥\8dपादन à¤¦à¥\87à¤\96ाबà¥\80",
+       "mergehistory-submit": "सà¤\82शà¥\8bधन à¤\8fà¤\95तà¥\8dरित करी",
+       "mergehistory-empty": "à¤\95à¥\8bनà¥\8b à¤­à¥\80 à¤\85वतरण à¤\8fà¤\95तà¥\8dरित à¤¨à¥\88 à¤\95à¤\8fल à¤\9cा à¤¸à¤\95ल।",
        "mergehistory-done": "$3 {{PLURAL:$3|संशोधन|संशोधन सभ}} एकर $1 सफलता पूर्वक मिज्झर कएल गेल [[:$2]] मे।",
        "mergehistory-fail": "इतिहासक मिश्रणकेँ नै कऽ सकल, कृपा कऽ पन्ना आ समए परिमितिकेँ फेरसँ जाँचू।",
        "mergehistory-fail-bad-timestamp": "समय सङ्ख्या अमान्य।",
        "mergehistory-comment": "[[:$1]] केँ [[:$2]] मे मिलाएल गेल: $3",
        "mergehistory-same-destination": "स्रोत आ लक्ष्य पन्ना सभ एक्के नै भऽ सकैए",
        "mergehistory-reason": "कारण:",
-       "mergelog": "मिà¤\9cà¥\8dà¤\9dरबला à¤µà¥\83तà¥\8dतलà¥\87à¤\96",
+       "mergelog": "à¤\8fà¤\95तà¥\8dरà¥\80à¤\95रण à¤²à¥\8cà¤\97",
        "revertmerge": "नै मिज्झर",
        "mergelogpagetext": "नीचाँ एक पन्ना इतिहासक दोसरमे अद्यतन मिश्रणक सूची अछि।",
        "history-title": "\"$1\" क संशोधन इतिहास",
        "right-undelete": "पन्ना फेरसँ आनी",
        "right-suppressrevision": "संचालकसँ नुकाएल संशोधनकेँ पुनरीक्षित करी आ फेरसँ आनी",
        "right-viewsuppressed": "कोनो प्रयोक्ताके नुकाएल संसोधन देखु",
-       "right-suppressionlog": "वà¥\8dयà¤\95à¥\8dतिà¤\97त à¤µà¥\83तà¥\8dतलà¥\87à¤\96 देखी",
+       "right-suppressionlog": "निà¤\9cà¥\80 à¤²à¥\8cà¤\97 देखी",
        "right-block": "दोसर प्रयोक्ताकेँ सम्पादनसँ रोकी",
        "right-blockemail": "प्रयोक्ताकेँ ई-पत्र पठेबासँ रोकी",
        "right-hideuser": "एकटा प्रयोक्तानामकेँ प्रतिबन्धित करू, लोकसँ एकरा नुका कऽ",
        "right-noratelimit": "दरक सीमासँ प्रभावित नै",
        "right-import": "दोसर विकीसँ पन्ना लिअ",
        "right-importupload": "पन्नासभकेँ संचिका उपारोपणसँ आनू",
-       "right-patrol": "दà¥\8bसराà¤\95 à¤¸à¤®à¥\8dपादनà¤\95à¥\87à¤\81 à¤¸à¤\82à¤\9aालित à¤¦à¥\87à¤\96ाà¤\89",
-       "right-autopatrol": "अपन सम्पादनकेँ स्वचालित रूपेँ संचालित देखाउ",
+       "right-patrol": "à¤\85नà¥\8dय à¤¸à¤¦à¤¸à¥\8dयसभà¤\95 à¤¸à¤®à¥\8dपादन à¤ªà¤°à¥\80à¤\95à¥\8dषित à¤\9aिनà¥\8dहित à¤\95रà¥\80",
+       "right-autopatrol": "अपन सम्पादन स्वचालित रूपसँ परीक्षित चिन्हित करी",
        "right-patrolmarks": "हालक परिवर्तनमे संचालन चेन्ह देखू",
        "right-unwatchedpages": "एहन पृष्ठसभक सूची देखी जे केकरो ध्यानसूचीमे नै अछि",
-       "right-mergehistory": "पनà¥\8dनाà¤\95 à¤\87तिहास à¤¸à¤­à¤\95à¥\87à¤\81 à¤®à¤¿à¤\9cà¥\8dà¤\9dर à¤\95रà¥\82",
+       "right-mergehistory": "पनà¥\8dनाà¤\95 à¤\87तिहास à¤\8fà¤\95तà¥\8dरित à¤\95रà¥\80",
        "right-userrights": "सभटा प्रयोक्ता अधिकारकेँ सम्पादित करू",
        "right-userrights-interwiki": "दोसर विकीपर प्रयोक्ताक प्रयोक्ता अधिकारक सम्पादन करी",
        "right-siteadmin": "दत्तनिधिकेँ प्रतिबन्धित करू आ फेर प्रतिबन्ध हटाउ",
        "grant-viewmywatchlist": "अपन साकांक्षसूची देखी",
        "newuserlogpage": "प्रयोक्ता रचना लग",
        "newuserlogpagetext": "ई प्रयोक्ता निर्माणक वृत्तलेख अछि।",
-       "rightslog": "पà¥\8dरयà¥\8bà¤\95à¥\8dता à¤\85धिà¤\95ार à¤µà¥\83तà¥\8dतलà¥\87à¤\96",
+       "rightslog": "पà¥\8dरयà¥\8bà¤\95à¥\8dता à¤\85धिà¤\95ार à¤²à¥\8cà¤\97",
        "rightslogtext": "ई प्रयोक्ता अधिकार परिवर्तन सभक वृतलेख छी।",
        "action-read": "ई पन्ना पढी",
        "action-edit": "ई पन्नाक सम्पादित करी",
        "action-createtalk": "ई वार्ता पन्ना बनाबी",
        "action-createaccount": "ई प्रयोक्ता खाता बनाबी",
        "action-autocreateaccount": "स्वतः बाहरी सदस्य खाता बनाबी",
-       "action-history": "पनà¥\8dनाà¤\95 à¤\87तिहास à¤®à¤¿à¤\9cà¥\8dà¤\9dर à¤\95री",
+       "action-history": "à¤\88 à¤ªà¥\83षà¥\8dठà¤\95 à¤\87तिहास à¤¦à¥\87à¤\96ी",
        "action-minoredit": "ऐ सम्पादनके मामूली कही",
        "action-move": "ई पृष्ठके स्थानान्तरित करी",
        "action-move-subpages": "ई पन्ना आ एकर उपपन्नाके स्थानान्तरित करी",
        "action-rollback": "कृपा कऽ अन्तिम प्रयोक्ताक सम्पादनकेँ प्रत्यावर्तित करू जे एक खास पन्नाकेँ सम्पादित केलन्हि",
        "action-import": "ऐ पन्नाकेँ दोसर विकीसँ आनू",
        "action-importupload": "ऐ पन्नाकेँ संचिका उपारोपणसँ आनू",
-       "action-patrol": "दà¥\8bसराà¤\95 à¤¸à¤®à¥\8dपादनà¤\95à¥\87à¤\81 à¤¸à¤\82à¤\9aालित à¤¦à¥\87à¤\96ाà¤\89",
-       "action-autopatrol": "अपन सम्पादनकेँ संचालित देखाउ",
+       "action-patrol": "à¤\85नà¥\8dय à¤¸à¤¦à¤¸à¥\8dयसभà¤\95 à¤¸à¤®à¥\8dपादन à¤ªà¤°à¥\80à¤\95à¥\8dषित à¤\95रà¥\80",
+       "action-autopatrol": "अपन सम्पादन स्वचालित रूपसँ परीक्षित करी",
        "action-unwatchedpages": "बिना संचालित पन्ना सभक सूचीकेँ देखू",
-       "action-mergehistory": "पनà¥\8dनाà¤\95 à¤\87तिहासà¤\95à¥\87à¤\81 à¤®à¤¿à¤\9cà¥\8dà¤\9dर à¤\95रà¥\82",
+       "action-mergehistory": "à¤\88 à¤ªà¥\83षà¥\8dठà¤\95 à¤\87तिहास à¤\8fà¤\95तà¥\8dरित à¤\95रà¥\80",
        "action-userrights": "सभटा प्रयोक्ता अधिकारकेँ सम्पादित करू",
        "action-userrights-interwiki": "दोसर विकीपर प्रयोक्ताक प्रयोक्ता अधिकारक सम्पादन करू",
        "action-siteadmin": "दत्तनिधिकेँ प्रतिबन्धित करू आ फेर प्रतिबन्ध हटाउ",
        "action-editmywatchlist": "काँच साकांक्षसूची संपादित करू",
        "action-viewmywatchlist": "अपन काँच साकांक्षसूची देखु",
        "action-viewmyprivateinfo": "अपन व्यक्तिगत जानकारी देखु",
-       "action-editmyprivateinfo": "à¤\85पन à¤µà¥\8dयà¤\95à¥\8dतिà¤\97त à¤\9cानà¤\95ारà¥\80 à¤¸à¤®à¥\8dपादित à¤\95रà¥\81",
+       "action-editmyprivateinfo": "à¤\85पन à¤µà¥\8dयà¤\95à¥\8dतिà¤\97त à¤\9cानà¤\95ारà¥\80 à¤¸à¤®à¥\8dपादित à¤\95रà¥\80",
        "action-editcontentmodel": "एक पन्ना के सामग्री मॉडल कें सम्पादन।",
        "action-managechangetags": "ट्याग बनाबी आ सक्षम (असक्षम) करी",
        "action-applychangetags": "आहाँ के बदलाव के साथ टैग जोडू।",
        "enhancedrc-history": "इतिहास",
        "recentchanges": "लगक परिवर्तनसभ",
        "recentchanges-legend": "नव परिवर्तन सम्बन्धी विकल्प",
-       "recentchanges-summary": "à¤\88 à¤ªà¤¨à¥\8dनापर à¤µà¤¿à¤\95à¥\80मà¥\87 à¤­à¥\87ल à¤¸à¤­ à¤¸à¤\81 à¤\85दà¥\8dयतन à¤ªà¤°à¤¿à¤µà¤°à¥\8dतनपर à¤¨à¤\9cरि à¤°à¤¾à¤\96à¥\80।",
+       "recentchanges-summary": "à¤\88 à¤µà¤¿à¤\95िमà¥\87 à¤­à¥\87ल à¤¸à¤¨à¥\8dनिà¤\95à¤\9f à¤ªà¤°à¤¿à¤µà¤°à¥\8dतन à¤\88 à¤ªà¥\83षà¥\8dठपर à¤¦à¥\87à¤\96ल à¤\9cा à¤¸à¤\95à¥\88त à¤\85à¤\9bि।",
        "recentchanges-noresult": "इ अवधिके दौरान इ मापदंडके पूर्ण करेत समय कोनो परिवर्तन नै केएल गेल अछि।",
        "recentchanges-feed-description": "ई सूचना-तंत्रांशमे विकीमे भेल सभसँ लगक परिवर्तन ताकी।",
        "recentchanges-label-newpage": "ई सम्पादन एकटा नव पन्नाक निर्माण केलक।",
        "recentchanges-label-minor": "ई एकटा लघु सम्पादन छी",
        "recentchanges-label-bot": "ई सम्पादन यान्त्रिक छल।",
-       "recentchanges-label-unpatrolled": "à¤\90 à¤¸à¤®à¥\8dपादनà¤\95 à¤ªà¥\81नरà¥\80à¤\95à¥\8dषण à¤\85à¤\96न à¤§à¤°à¤¿ à¤¨à¥\88 à¤\95à¤\8fल à¤\97à¥\87ल à¤\85à¤\9bि।",
+       "recentchanges-label-unpatrolled": "à¤\88 à¤¸à¤®à¥\8dपादन à¤\85à¤\96न à¤\9cाà¤\81à¤\9aल à¤¨à¥\88 à¤\97à¥\87ल à¤\85à¤\9bि",
        "recentchanges-label-plusminus": "पन्ना आकार ई बाइट सङ्ख्या सँ बदलल गेल",
        "recentchanges-legend-heading": "<strong>कुञ्जी:</strong>",
        "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} ([[Special:NewPages|नव पन्नसभक सूची]] सेहो देखी)",
        "upload-permitted": "अनुमतित फाइल  {{PLURAL:$2|प्रकार}}: $1।",
        "upload-preferred": "पसन्दिदा फाइल {{PLURAL:$2|प्रकार|प्रकारसभ}}: $1।",
        "upload-prohibited": "प्रतिबन्धित सञ्चिका {{PLURAL:$2|प्रकार|प्रकारसभ}}:$1 ।",
-       "uploadlogpage": "à¤\89पारà¥\8bपण à¤µà¥\83तà¥\8dतलà¥\87à¤\96",
+       "uploadlogpage": "à¤\89पारà¥\8bपण à¤²à¥\8cà¤\97",
        "uploadlogpagetext": "नीचाँ अद्यतन सञ्चिका उपारोपणक वर्णन अछि।\nदेखी [[Special:NewFiles|नव सञ्चिकाक बखारी]] बेसी स्पष्ट समुच्चा दृश्य लेल।",
        "filename": "सञ्चिका नाम",
        "filedesc": "संक्षेप",
        "mimetype": "माइम प्रकार:",
        "download": "अवारोपन",
        "unwatchedpages": "बिन ध्यान देल पन्ना",
-       "listredirects": "रसà¥\8dता à¤¬à¤¦à¤²à¥\87नक सूची",
+       "listredirects": "पà¥\81नरà¥\8dनिरà¥\8dदà¥\87शनसभक सूची",
        "listduplicatedfiles": "डुप्लिकेट के साथ फाइलसभ के सूची।",
        "listduplicatedfiles-entry": "[[:File:$1|$1]] राखैत अछि  [[$3|{{PLURAL:$2|एक प्रतिलिपि|$2 duplicates}}]] ।",
        "unusedtemplates": "बिना प्रयोगक नमूना सभ",
        "unusedtemplateswlh": "दोसर लागि सभ",
        "randompage": "अव्यवस्थित पृष्ठ",
        "randompage-nopages": "ऐमे दोसर पन्ना नै अछि {{PLURAL:$2|namespace|namespaces}}: $1 ।",
-       "randomincategory": "श्रेणी में यादृच्छिक (रैंडम) पन्ना",
+       "randomincategory": "श्रेणीमे यादृच्छिक पृष्ठ",
        "randomincategory-invalidcategory": "\"$1\" एक मान्य श्रेणी नाम नै अछि।",
        "randomincategory-nopages": "[[:Category:$1|$1]] श्रेणीमे कोनो पृष्ठ नै अछि।",
        "randomincategory-category": "श्रेणी:",
        "randomincategory-legend": "श्रेणीमे यादृच्छिक पृष्ठ",
        "randomincategory-submit": "जाए",
-       "randomredirect": "मिà¤\9cà¥\8dà¤\9dर à¤¬à¤¦à¤²à¥\87नबला à¤²à¤¾à¤\97ि",
+       "randomredirect": "à¤\95à¥\8bनà¥\8b à¤\8fà¤\95 à¤ªà¥\81नरà¥\8dनिरà¥\8dदà¥\87शन à¤ªà¤° à¤\9cाà¤\8f",
        "randomredirect-nopages": "नामस्थान \"$1\" मे कोनो बदलेनबला लागि नै अछि।",
        "statistics": "सांख्यिकी",
        "statistics-header-pages": "पन्नाक तथ्याङ्क",
        "double-redirect-fixed-move": "[[$1]] घसकाएल गेल।\nई आब [[$2]] दिस जा रहल अछि।",
        "double-redirect-fixed-maintenance": "द्वितीयक बदलेन [[$1]] सँ [[$2]] कएल गेल।",
        "double-redirect-fixer": "बदलेन स्थायित्व",
-       "brokenredirects": "à¤\9fà¥\82à¤\9fल à¤¬à¤¦à¤²à¥\87न à¤¸à¤­",
+       "brokenredirects": "तà¥\81à¤\9fल à¤ªà¥\81नरà¥\8dनिरà¥\8dदà¥\87शन à¤ªà¥\83षà¥\8dठ",
        "brokenredirectstext": "ई बदलेन सभ नै अवस्थित पन्ना सभक दिस जाइत अछि।",
        "brokenredirects-edit": "सम्पादन करी",
        "brokenredirects-delete": "मेटाबी",
        "prefixindex": "उपसर्गक संग सभटा पृष्ठ",
        "prefixindex-namespace": "उपसर्ग भएल सभ पृष्ठ ($1 नामस्थान)",
        "prefixindex-strip": "सूची में उपसर्ग नुकाउ",
-       "shortpages": "पनà¥\8dना à¤¸à¤­ à¤\9bाà¤\81à¤\9fà¥\82",
+       "shortpages": "à¤\9bà¥\8bà¤\9f à¤ªà¥\83षà¥\8dठसभ",
        "longpages": "नमगर पन्ना सभ",
        "deadendpages": "एकदमसँ अन्त भऽ जाएबला पन्ना सभ",
        "deadendpagestext": "ई पन्ना सभ {{SITENAME}} क दोसर पन्नासँ लागिमे नै रहत।",
        "speciallogtitlelabel": "प्रयोजन (शीर्षक अथवा {{ns:user}}:प्रयोगकर्तानाम):",
        "log": "लौग",
        "logeventslist-submit": "देखाबी",
-       "all-logs-page": "सभ à¤¸à¤¾à¤°à¥\8dवà¤\9cनिà¤\95 à¤µà¥\83तà¥\8dतलà¥\87à¤\96",
+       "all-logs-page": "सभ à¤¸à¤¾à¤°à¥\8dवà¤\9cनिà¤\95 à¤²à¥\8cà¤\97",
        "alllogstext": "{{अन्तर्जाल}} क सभटा उपलब्ध वृत्तलेखक संयुक्त दृश्य।\nअहाँ दृश्यकेँ संकीर्ण करबा लेल वृत्तलेखक एकटा प्रकार चुनि सकै छी, प्रयोक्तानाम (ब्रह्मक्षर-लघ्वक्षर विचारणीय), वा प्रभावित पन्ना (एतौ ब्रह्मक्षर-लघ्वक्षर विचारणीय)।",
        "logempty": "वृत्तलेखमे कोनो मेल खाइबला बौस्तु नै।",
        "log-title-wildcard": "खोज शीर्षक सभ ऐ पाठसँ प्रारम्भ",
        "listusers-submit": "देखाबी",
        "listusers-noresult": "कोनो प्रयोक्ता नै",
        "listusers-blocked": "(प्रतिबन्धित)",
-       "activeusers": "सक्रिय प्रयोक्ता सभक सूची",
+       "activeusers": "सक्रिय प्रयोक्तासभक सूची",
        "activeusers-intro": "ई ओहेन प्रयोक्ता सभक सूची अछि जे पछिला $1 {{PLURAL:$1|दिन|दिन}} मे किछु सक्रियता देखेने छथि।",
        "activeusers-count": "$1 {{PLURAL:$1|कार्य}} पिछला $3 {{PLURAL:$3|दिन|दिनसभ}}मे",
        "activeusers-from": "प्रयोक्ता प्रदर्शन प्रारम्भ भेल:",
        "listgrants-summary": "ई प्रदान केल गेल सूची छी। सदस्य अपन खाताक अनुपयोगक द्वारा उपयोग करि सकैत अछि, मुदा मात्र किछ सीमित अधिकार धरि। ई अधिकार सदस्यद्वारा देल गेल अधिकार धरि सीमित रहैत अछि । एतय [[{{MediaWiki:Listgrouprights-helppage}}|अन्य जानकारी]] सेहो अछि, जे एक अधिकारक बारेमे बताबैत अछि।",
        "listgrants-grant": "अधिकार",
        "listgrants-rights": "अधिकार",
-       "trackingcategories": "शà¥\8dरà¥\87णà¥\80à¤\95à¥\87 à¤\9fà¥\8dरयाà¤\95 à¤\95रà¥\81",
+       "trackingcategories": "à¤\9aिहà¥\8dनित à¤¶à¥\8dरà¥\87णà¥\80सभ",
        "trackingcategories-summary": "ई पृष्ठ पर ओ जोडवाला श्रेणीसभक सूची मिलैत अछि जे स्वतः रूप सँ मिडियाविकि सफ्टवेयरद्वारा बनैत अछि। ओ सभक नाम सम्बन्धित प्रणाली सन्देस बदलै सँ {{ns:8}} नामस्थानमे बदलल जा सकैत अछि।",
        "trackingcategories-msg": "चिह्नित श्रेणी",
        "trackingcategories-name": "सन्देश नाम",
        "actioncomplete": "क्रिया पूर्ण",
        "actionfailed": "कार्य नै भेल",
        "deletedtext": "\"$1\" केँ मेटा देल गेल अछि।\nदेखू $2 हालक मेटाएल सामिग्रीक अभिलेख लेल।",
-       "dellogpage": "मà¥\87à¤\9fाà¤\8fल à¤¸à¤¾à¤®à¤¿à¤\97à¥\8dरà¥\80à¤\95 à¤µà¥\83तà¥\8dतलà¥\87à¤\96",
+       "dellogpage": "मà¥\87à¤\9fाà¤\8fल à¤²à¥\8cà¤\97",
        "dellogpagetext": "नीचाँ एकदम लगक मेटाएल पन्नाकऽ सूची छी।",
-       "deletionlog": "मà¥\87à¤\9fाà¤\8fल à¤¸à¤¾à¤®à¤¿à¤\97à¥\8dरà¥\80à¤\95 à¤µà¥\83तà¥\8dतलà¥\87à¤\96",
+       "deletionlog": "मà¥\87à¤\9fाà¤\8fल à¤²à¥\8cà¤\97",
        "reverted": "पुरान कोनो संशोधन धरि घुराउ",
        "deletecomment": "कारण:",
        "deleteotherreason": "दोसर/ अतिरिक्त कारण:",
        "undeletedpage": "'''$1 के पुनर्स्थापित करल गेल अछि'''\n\nलग पास में हटाओल गेल आ पुनर्स्थापित कएल गेल पन्ना सभके जानकारी के लेल [[Special:Log/delete|हटाओल गेल लग]] देखु।",
        "undelete-header": "हालक मेटाएल पन्ना के लेल [[Special:Log/delete|हटाएल लग]] देखू।",
        "undelete-search-title": "मेटाएल गेल पृष्ठ ताकी",
-       "undelete-search-box": "मेटाएल पन्ना सभकेँ ताकू",
+       "undelete-search-box": "मेटाएल पन्नासभ ताकी",
        "undelete-search-prefix": "से शुरु भेल पन्ना देखाबू.",
        "undelete-search-submit": "ताकू",
        "undelete-no-results": "एहेन पन्ना मेटाएल पेटारमे नै भेटल।",
        "sp-contributions-newbies": "मात्र नव खाताक योगदान देखाबी",
        "sp-contributions-newbies-sub": "नब प्रयोक्ताकऽ लेल",
        "sp-contributions-newbies-title": "नब प्रयोक्ताकऽ योगदान",
-       "sp-contributions-blocklog": "पà¥\8dरतिबनà¥\8dधित à¤µà¥\83तà¥\8dतलà¥\87à¤\96",
+       "sp-contributions-blocklog": "पà¥\8dरतिबनà¥\8dधित à¤²à¥\8cà¤\97",
        "sp-contributions-suppresslog": "{{GENDER:$1|प्रयोगकर्ता}} योगदान दबाबी",
        "sp-contributions-deleted": "{{GENDER:$1|प्रयोगकर्ता}}क मेटाएल योगदान",
        "sp-contributions-uploads": "उपारोपण",
-       "sp-contributions-logs": "वà¥\83तà¥\8dतलà¥\87à¤\96 à¤¸à¤­",
+       "sp-contributions-logs": "लà¥\8cà¤\97",
        "sp-contributions-talk": "वार्त्ता",
        "sp-contributions-userrights": "प्रयोक्ता अधिकारकऽ प्रबन्धन",
        "sp-contributions-blocked-notice": "ई प्रयोक्ता अखन प्रतिबन्धित अछि।\nनव प्रतिबन्धित वृत्तलेख लेख सन्दर्भ नीचाँ देल अछि:",
        "contribslink": "योगदान",
        "emaillink": "ई-पत्र पठाउ",
        "autoblocker": "अहाँक अनिकेत \"[[User:$1|$1]]\" द्वारा प्रयोगक कारण स्वचालित रूपेँ प्रतिबन्धित भऽ गेल।\n$1 एकर प्रतिबन्धक कारण अछि : \"$2\"",
-       "blocklogpage": "पà¥\8dरतिबनà¥\8dधित à¤µà¥\83तà¥\8dतलà¥\87à¤\96",
+       "blocklogpage": "पà¥\8dरतिबनà¥\8dधित à¤²à¥\8cà¤\97",
        "blocklog-showlog": "ऐ प्रयोक्ताकेँ पहिनहिये प्रतिबन्धित कऽ देल गेल अछि।\nप्रतिबन्धक वृत्तलेख सन्दर्भ लेल नीचाँ देल जा रहल अछि:",
        "blocklog-showsuppresslog": "ऐ प्रयोक्ताकेँ पहिनहिये प्रतिबन्धित आ अदृश्य कऽ देल गेल अछि।\nदबाएल वृत्तलेख सन्दर्भ लेल नीचाँ देल जा रहल अछि:",
        "blocklogentry": "प्रतिबन्धित [[$1]] एकर अन्तिम तिथि अछि $2 $3",
        "movepage-page-moved": "पन्ना $1 केँ $2 लग घसका देल गेल अछि।",
        "movepage-page-unmoved": "पन्ना $1 केँ $2 लग नै घसकाएल जा सकैए।",
        "movepage-max-pages": "बेसी सें बेसी $1 पृष्ठ बदलि के {{PLURAL:$1| क देल गेल अछि|क देल गेल अछि}}, आब आर पृष्ठ अपने आप नहि बदलत.",
-       "movelogpage": "स्थानान्तरण लग",
+       "movelogpage": "सà¥\8dथानानà¥\8dतरण à¤²à¥\8cà¤\97",
        "movelogpagetext": "नाम बदलल गेल लेख कऽ सूचि नीचां देल गेल अछि",
        "movesubpage": "{{PLURAL:$1|उप पन्ना|उप पन्ना}}",
        "movesubpagetext": "नीचां $1 {{PLURAL:$1| पन्ना देखाओल गएल अछि, जे अहि पन्नाकऽ उप पन्ना अछि|पन्ना देखावोल गएल अछि, जे अहि पन्नाकऽ उप पन्ना अछि}}।",
        "allmessages-prefix": "उपसर्गक आधारपर छाँटू:",
        "allmessages-language": "भाषा:",
        "allmessages-filter-submit": "चलू",
-       "allmessages-filter-translate": "à¤\85नà¥\81वाद à¤\95रà¥\81",
+       "allmessages-filter-translate": "à¤\85नà¥\81वाद à¤\95रà¥\80",
        "thumbnail-more": "पैग",
        "filemissing": "संचिका हेराएल",
        "thumbnail_error": "लघुचित्र निर्माण कालमे भ्रम:$1",
        "markedaspatrollederror-noautopatrol": "अहाँ अपन कएल संशोधनकेँ संचालित नै कहि सकै छी।",
        "markedaspatrollednotify": "$1 पृष्ठ में कएल गएल ऐ परिवर्तन जाँचल गेल चिन्हासी कएल गेल।",
        "markedaspatrollederrornotify": "जाँचल चिन्हासी असफल भेल।",
-       "patrol-log-page": "सà¤\82à¤\9aालन à¤µà¥\83तà¥\8dतलà¥\87à¤\96",
-       "patrol-log-header": "à¤\88 à¤¸à¤\82à¤\9aालित à¤¸à¤\82शà¥\8bधन à¤¸à¤­à¤\95 à¤µà¥\83तà¥\8dतलà¥\87à¤\96 छी।",
-       "log-show-hide-patrol": "$1 à¤¨à¤¿à¤°à¥\80à¤\95à¥\8dषण à¤µà¥\83तà¥\8dतलà¥\87à¤\96",
+       "patrol-log-page": "परà¥\80à¤\95à¥\8dषण à¤²à¥\8cà¤\97",
+       "patrol-log-header": "à¤\88 à¤ªà¤°à¥\80à¤\95à¥\8dषित à¤\85वतरणसभà¤\95 à¤²à¥\8cà¤\97 छी।",
+       "log-show-hide-patrol": "$1 à¤¨à¤¿à¤°à¥\80à¤\95à¥\8dषण à¤²à¥\8cà¤\97",
        "log-show-hide-tag": "$1 ट्याग लग",
        "deletedrevision": "पुरान संशोधन $1 हटा देलौं",
        "filedeleteerror-short": "संचिका मेटेबामे भ्रम : $1",
        "exif-orientation-1": "सामान्य",
        "exif-orientation-2": "अनुदैर्घ्य मिज्झर",
        "exif-orientation-3": "180° पर घुमायल गेल",
-       "exif-orientation-4": "à¤\85नà¥\81पà¥\8dरसà¥\8dथ à¤®à¤¿à¤\9cà¥\8dà¤\9dर",
+       "exif-orientation-4": "भरà¥\8dà¤\9fिà¤\95लà¥\80 à¤«à¥\8dलिप à¤\95रà¥\80",
        "exif-orientation-5": "90° सी.सी.डब्लू. घुमाओल गेल आ अनुप्रस्थ रूपेँ मिज्झर कएल गेल",
        "exif-orientation-6": "९०° सी.सी.डब्लू. घुमाएल गेल",
        "exif-orientation-7": "९०° सी.डब्लू. घुमाओल गेल आ अनुप्रस्थ रूपेँ मिज्झर कएल गेल",
        "exif-customrendered-0": "सामान्य प्रक्रिया",
        "exif-customrendered-1": "वैकल्पिक प्रक्रिया",
        "exif-exposuremode-0": "स्वयं देखबैत",
-       "exif-exposuremode-1": "सà¤\82à¤\9aालित à¤¦à¥\87à¤\96ाà¤\8fब",
+       "exif-exposuremode-1": "मà¥\88नà¥\8dयà¥\81à¤\85ल à¤\8fà¤\95à¥\8dपà¥\8bà¤\9cर",
        "exif-exposuremode-2": "स्वचालित कोष्ठक",
        "exif-whitebalance-0": "स्वचालित उज्जर सन्तुलन",
        "exif-whitebalance-1": "संचालित उज्जर सन्तुलन",
        "watchlistedit-raw-added": "{{PLURAL:$1|1 शीर्षक छल|$1शीर्षक सभ रहए}} जोड़ल गेल:",
        "watchlistedit-raw-removed": "{{PLURAL:$1|1 शीर्षक छल|$1शीर्षक सभ रहए}} हटाएल गेल:",
        "watchlistedit-clear-title": "ध्यानसूची खाली करी",
-       "watchlistedit-clear-legend": "साà¤\95ाà¤\82à¤\95à¥\8dष-सà¥\82à¤\9aà¥\80 à¤®à¥\87à¤\9fाà¤\89",
+       "watchlistedit-clear-legend": "साà¤\95ाà¤\82à¤\95à¥\8dष-सà¥\82à¤\9aà¥\80 à¤®à¥\87à¤\9fाबà¥\80",
        "watchlistedit-clear-explain": "एही ठाम रहल सभ शिर्षक अहाँक साकांक्ष-सूची से मेटा जाएत",
        "watchlistedit-clear-titles": "शीर्षक",
        "watchlistedit-clear-submit": "साकांक्ष-सूची मेटाउ (ई स्थायी छि!)",
        "watchlistedit-clear-done": "अहाँक साकांक्ष-सूची मेटाओल गेल।",
        "watchlistedit-clear-removed": "{{PLURAL:$1|1 शीर्षक छल|$1शीर्षक सभ रहए}} हटाएल गेल:",
-       "watchlistedit-too-many": "à¤\8fतà¥\87à¤\95 à¤¬à¤¹à¥\81त à¤°à¤¾à¤¸ à¤ªà¤¨à¥\8dना à¤¸à¤­ à¤¦à¥\87à¤\96ावà¥\8bल à¤\9cाà¤\8fत।",
-       "watchlisttools-clear": "साà¤\95ाà¤\82à¤\95à¥\8dष-सà¥\82à¤\9aà¥\80 à¤®à¥\87à¤\9fाà¤\89",
+       "watchlistedit-too-many": "à¤\8fतय à¤¦à¤°à¥\8dशावà¥\88à¤\95 à¤²à¥\87ल à¤\85तà¥\8dयधिà¤\95 à¤ªà¥\83षà¥\8dठ à¤\85à¤\9bि।",
+       "watchlisttools-clear": "साà¤\95ाà¤\82à¤\95à¥\8dष-सà¥\82à¤\9aà¥\80 à¤®à¥\87à¤\9fाबà¥\80",
        "watchlisttools-view": "सम्बन्धित परिवर्तन सभकेँ देखी",
        "watchlisttools-edit": "साकांक्षसूची देखी आ सम्पादित करी",
        "watchlisttools-raw": "काँच साकांक्षसूची सम्पादित करी",
        "specialpages-group-maintenance": "सुस्थापन प्रतिवेदन",
        "specialpages-group-other": "दोसर विशेष पन्ना",
        "specialpages-group-login": "सम्प्रवेश/ सम्प्रवेश आवेदन",
-       "specialpages-group-changes": "हालà¤\95 à¤ªà¤°à¤¿à¤µà¤°à¥\8dतन à¤\86 à¤µà¥\83तà¥\8dतलà¥\87à¤\96",
+       "specialpages-group-changes": "सनà¥\8dनिà¤\95à¤\9f à¤ªà¤°à¤¿à¤µà¤°à¥\8dतन à¤\86 à¤²à¥\8cà¤\97",
        "specialpages-group-media": "मीडिया प्रतिवेदन आ उपारोपण",
        "specialpages-group-users": "प्रयोक्ता आ अधिकार",
-       "specialpages-group-highuse": "बà¥\87सà¥\80 à¤ªà¥\8dरयà¥\8bà¤\97बला à¤ªà¤¨à¥\8dना à¤¸à¤­",
+       "specialpages-group-highuse": "à¤\85तà¥\8dयधिà¤\95 à¤\89पयà¥\8bà¤\97à¥\80 à¤ªà¥\83षà¥\8dठ",
        "specialpages-group-pages": "पन्ना सभक सूची",
        "specialpages-group-pagetools": "पन्नाक औजार सभ",
        "specialpages-group-wiki": "विकी दत्तांश आ औजार सभ",
        "tags-title": "चेन्ह सभ",
        "tags-intro": "ई पन्ना चेन्ह सभकेँ सूचित करैए जे तंत्रांश सम्पादनसँ चिन्हित करए, आ ओकर अर्थ सेहो।",
        "tags-tag": "चेन्हक नाम",
-       "tags-display-header": "परिवरà¥\8dतन à¤¸à¥\82à¤\9aà¥\80 à¤¸à¤­à¤\95 à¤°à¥\82परà¤\82à¤\97",
+       "tags-display-header": "परिवरà¥\8dतन à¤¸à¥\82à¤\9aिसभमà¥\87 à¤ªà¥\8dरदरà¥\8dशन",
        "tags-description-header": "अर्थक पूर्ण विवरण",
        "tags-source-header": "स्रोत",
        "tags-active-header": "सक्रिय?",
        "tags-edit-title": "ट्याग सम्पादन",
        "tags-edit-manage-link": "ट्याग व्यवस्थापन",
        "tags-edit-revision-selected": "[[:$2]] {{PLURAL:$1|क|के}} चयनित अवतरण:",
-       "tags-edit-logentry-selected": "{{PLURAL:$1|à¤\9aà¥\81नल à¤µà¥\83तà¥\8dतलà¥\87à¤\96 à¤\98à¤\9fना|à¤\9aà¥\81नल à¤µà¥\83तà¥\8dतलà¥\87à¤\96 à¤\98à¤\9fना सभ}}:",
+       "tags-edit-logentry-selected": "{{PLURAL:$1|à¤\9aà¥\81नल à¤²à¥\8cà¤\97 à¤\98à¤\9fना|à¤\9aà¥\81नल à¤²à¥\8cà¤\97 à¤\98à¤\9fनासभ}}:",
        "tags-edit-existing-tags-none": "<em>कोनो नै</em>",
        "tags-edit-new-tags": "नव ट्याग:",
        "tags-edit-add": "इ ट्यागसभ जोडी:",
        "htmlform-cloner-delete": "हटाउ",
        "logentry-delete-delete": "$1 पृष्ठ $3 {{GENDER:$2|मेटौलक}}",
        "logentry-delete-restore": "$1 {{GENDER:$2|restored}} page $3",
-       "logentry-delete-event": "$1 {{GENDER:$2|changed}} एकर दृश्य{{PLURAL:$5| एकटा वृत्तलेख|$5 वृत्तलेख}}  $3: $4 केँ",
+       "logentry-delete-event": "$1द्वारा $3 पृष्ठक लौग {{PLURAL:$5|प्रविष्टि|प्रविष्टिसभ}}क दृश्यता {{GENDER:$2|परिवर्तित केलक}}: $4",
        "logentry-delete-revision": "$1 द्वारा $3 पृष्ठक {{PLURAL:$5|एक अवतरण|$5 अवतरणसभ}}क दृश्यता {{GENDER:$2|परिवर्तित}}: $4",
-       "logentry-delete-event-legacy": "$1 {{GENDER:$2|changed}}  $3 पर वृत्तलेख दृश्य",
-       "logentry-delete-revision-legacy": "$1 {{GENDER:$2|changed}}  $3 पर वृत्तलेख संशोधन",
+       "logentry-delete-event-legacy": "$1द्वारा $3 पृष्ठ पर लौग क्रियासभक दृश्यता {{GENDER:$2|परिवर्तित केलक}}",
+       "logentry-delete-revision-legacy": "$1द्वारा $3 पृष्ठ पर अवतरणसभक दृश्यता {{GENDER:$2|परिवर्तित केलक}}",
        "logentry-suppress-delete": "$1 {{GENDER:$2|दबाएल}} page $3",
        "logentry-suppress-event": "$1 चोरिसँ {{GENDER:$2|परिवर्तन कियल गैल}} एकर दृश्य{{PLURAL:$5| एकटा वृत्तलेख|$5 वृत्तलेख}}  $3: $4 पर",
        "logentry-suppress-revision": "$1 चोरिसँ {{GENDER:$2|changed}} एकर दृश्य{{PLURAL:$5| एकटा संशोधन|$5 संशोधन}}  $3: $4 पर",
-       "logentry-suppress-event-legacy": "$1 नुका क {{GENDER:$2|परिवर्तन}}  $3 पर वृत्तलेख दृश्य",
+       "logentry-suppress-event-legacy": "$1द्वारा गुप्त रूपसँ $3 पृष्ठ पर लौग क्रियासभक दृश्यता {{GENDER:$2|परिवर्तित केलक}}",
        "logentry-suppress-revision-legacy": "$1 नुका कऽ {{GENDER:$2|changed}}  $3 पर संशोधन दृश्य",
        "revdelete-content-hid": "सामिग्री नुकाएल",
        "revdelete-summary-hid": "नुकाएल सारांश सम्पादन",
        "feedback-back": "पाछां",
        "feedback-bugcheck": "बहुत निक! जांच करु कि [ $1 known bugs] पहिले स त नै अछि ।",
        "feedback-bugnew": "हम जाँच केलौ। एक नव बग रिपोर्ट करी",
-       "feedback-cancel": "रदà¥\8dद à¤\95रà¥\81",
+       "feedback-cancel": "रदà¥\8dद à¤\95रà¥\80",
        "feedback-close": "भ गेल",
        "feedback-error-title": "त्रुटि",
        "feedback-error1": "त्रुटि: नै पहचानल गेल परिणाम एपीआईसँ",
index fb13702..ef0bd68 100644 (file)
@@ -50,7 +50,7 @@
        "tog-showhiddencats": "Ozuta peitetyt kategouriet",
        "tog-norollbackdiff": "Älä ozuta eroloi, konzu olet ottanuh järilleh aijemban versien järilleh tuondu -toimindol",
        "tog-useeditwarning": "Ollen lähtemäs sivulpäi iäre tallendamattah muutoksii, huomaita minuu",
-       "tog-prefershttps": "Käytä ainos suojattuu yhtevytty ku olet kirjutannuhes",
+       "tog-prefershttps": "Käytä ainos suojattuu yhtevytty, ku olet kirjutannuhes",
        "underline-always": "Ainos",
        "underline-never": "Nikonzu",
        "underline-default": "Käytä livaimen piäazetuksii",
        "minoredit": "Tämä on pieni kohendus",
        "watchthis": "Tarkaile tädä sivuu",
        "savearticle": "Tallenda sivu",
+       "savechanges": "Tallenda muutokset",
        "preview": "Ezikačo",
        "showpreview": "Ezikačo",
        "showdiff": "Luajitut kohendukset",
index 65f90a8..3b9e82a 100644 (file)
        "category-file-count-limited": "هيٺيون يا هيٺيان {{PLURAL:$1|فائيل آهي|$1 فائيل آهن}} هن تازي زمري ۾.",
        "listingcontinuesabbrev": "جاري..",
        "index-category": "ڏسڻيل صفحا",
-       "noindex-category": "غيرڏسڻيل صفحا",
+       "noindex-category": "غير-ڏسڻيل صفحا",
        "broken-file-category": "فائيل جي ٽٽل ڳنڍڻن وارا صفحا",
        "about": "بابت",
        "article": "موادي صفحو",
        "accountcreatedtext": "يوزر کاتو [[{{ns:User}}:$1|$1]] ([[{{ns:User talk}}:$1|talk]]) جي لاءِ تخليق ٿي چڪو آهي.",
        "createaccount-title": "{{SITENAME}} تي کاتو کولڻ",
        "login-throttled": "توهان تازو ئي لاگ اِن ٿيڻ جون هيڪانديون گھڻيون ڪوششون ڪيون آهن. مهرباني ڪري $1 لاءِ ترسي پوءِ وري ڪوشش ڪريو.",
-       "login-abort-generic": "توهان جو لاگ اِن ناڪام ويو.",
+       "login-abort-generic": "توهان جو داخل ٿيڻ ناڪام ويو - بند ڪيل",
        "login-migrated-generic": "توهان جو کاتو لڏي چڪو آهي، ۽ هن وڪيءَ تي توهان جو يُوزنانءُ هاڻي وجود نہ ٿو رکي.",
        "loginlanguagelabel": "ٻولي: $1",
        "createacct-another-realname-tip": "اصل نالو ڄاڻائڻ اختياري آهي. جيڪڏهن توهان اصل نالو ڄاڻايو ٿا، تہ اهو توهان کي توهان جي ڪم جي مڃتا ڏيڻ لاءِ ڪم آندو ويندو.",
        "sp-contributions-newbies-sub": "نون کاتن لاءِ",
        "sp-contributions-newbies-title": "نون کاتن جي لاءِ يوزر جون ڀاڱيداريون",
        "sp-contributions-blocklog": "بنسش لاگ",
-       "sp-contributions-deleted": "يُوزر جون ڊاٺل ڀاڱيداريون",
+       "sp-contributions-deleted": "ڊاٿل {{GENDER:$1|يوزر}} ڀاڱيداريون",
        "sp-contributions-uploads": "چاڙھَ",
        "sp-contributions-logs": "لاگس",
        "sp-contributions-talk": "ڳالھہ",
index 868012a..540c6c0 100644 (file)
        "htmlform-cloner-create": "Lägg till mer",
        "htmlform-cloner-delete": "Ta bort",
        "htmlform-cloner-required": "Det krävs minst ett värde.",
+       "htmlform-date-placeholder": "ÅÅÅÅ-MM-DD",
+       "htmlform-time-placeholder": "TT:MM:SS",
+       "htmlform-datetime-placeholder": "ÅÅÅÅ-MM-DD TT:MM:SS",
        "htmlform-title-badnamespace": "[[:$1]] är inte i \"{{ns:$2}}\"-namnrymden.",
        "htmlform-title-not-creatable": "\"$1\" är inte en sidtitel som kan skapas",
        "htmlform-title-not-exists": "$1 finns inte.",
index 31b213f..3cf6a4d 100644 (file)
@@ -62,7 +62,7 @@
        "tog-enotifminoredits": "Gửi thư cho tôi cả những thay đổi nhỏ trong trang và tập tin",
        "tog-enotifrevealaddr": "Hiện địa chỉ thư điện tử của tôi trong thư thông báo",
        "tog-shownumberswatching": "Hiển thị số người đang xem",
-       "tog-oldsig": "Chữ ký hiện tại:",
+       "tog-oldsig": "Chữ ký hiện tại của bạn:",
        "tog-fancysig": "Xem chữ ký là mã wiki (không có liên kết tự động)",
        "tog-uselivepreview": "Xem trước trực tiếp",
        "tog-forceeditsummary": "Nhắc tôi khi tôi quên tóm lược sửa đổi",
@@ -79,7 +79,7 @@
        "tog-showhiddencats": "Hiển thị thể loại ẩn",
        "tog-norollbackdiff": "Bỏ qua bản so sánh sau khi lùi sửa",
        "tog-useeditwarning": "Cảnh báo khi tôi thoát trang sửa đổi mà chưa lưu trang",
-       "tog-prefershttps": "Luôn kết nối an toàn khi đăng nhập",
+       "tog-prefershttps": "Luôn kết nối an toàn khi đã đăng nhập",
        "underline-always": "Luôn luôn",
        "underline-never": "Không bao giờ",
        "underline-default": "Mặc định của giao diện hoặc trình duyệt",
        "newwindow": "(mở cửa sổ mới)",
        "cancel": "Hủy bỏ",
        "moredotdotdot": "Thêm nữa…",
-       "morenotlisted": "Danh sách này không có đầy đủ.",
+       "morenotlisted": "Danh sách này có thể không đầy đủ.",
        "mypage": "Trang cá nhân",
        "mytalk": "Tin nhắn",
        "anontalk": "Thảo luận",
        "eauthentsent": "Thư xác nhận đã được gửi cho địa chỉ thư điện tử được chỉ định. Trước khi bạn có thể nhận thư, bạn cần thực hiện hướng dẫn trong thư để xác nhận tài khoản thuộc về bạn.",
        "throttled-mailpassword": "Mật khẩu đã được gửi đến cho bạn trong vòng {{PLURAL:$1|$1 giờ|$1 giờ}} đồng hồ trở lại. Để tránh lạm dụng, chỉ có thể gửi mật khẩu $1 giờ đồng hồ một lần.",
        "mailerror": "Lỗi gửi thư : $1",
-       "acct_creation_throttle_hit": "Ai đó cùng [[địa chỉ IP]] với bạn đã mở {{PLURAL:$1|một tài khoản|$1 tài khoản}} ở đây trong vòng 24 giờ. Vì quy định hạn chế số tài khoản mở trên một địa chỉ IP nên bạn hiện không thể mở thêm được nữa dùng địa chỉ IP này.",
+       "acct_creation_throttle_hit": "Ai đó cùng địa chỉ IP với bạn đã mở {{PLURAL:$1|một tài khoản|$1 tài khoản}} ở đây vào $2 qua. Vì quy định hạn chế số tài khoản mở trên một địa chỉ IP nên bạn hiện không thể mở thêm được nữa dùng địa chỉ IP này.",
        "emailauthenticated": "Địa chỉ thư điện tử của bạn được xác nhận vào lúc $3 $2.",
        "emailnotauthenticated": "Địa chỉ thư điện tử của bạn chưa được xác nhận. Các chức năng sau sẽ không gửi thư điện tử.",
        "noemailprefs": "Hãy ghi một địa chỉ thư điện tử trong tùy chọn cá nhân để có thể sử dụng tính năng này.",
        "botpasswords-label-resetpassword": "Đặt lại mật khẩu",
        "botpasswords-label-grants": "Các quyền có liên quan:",
        "botpasswords-help-grants": "Các lượt cấp phép cho phép truy cập các quyền người dùng mà một tài khoản đã có sẵn. Xem thêm thông tin trong [[Special:ListGrants|bảng cấp phép]].",
-       "botpasswords-label-restrictions": "Hạn chế sử dụng:",
        "botpasswords-label-grants-column": "Cấp quyền",
        "botpasswords-bad-appid": "Bot có tên \"$1\" không hợp lệ.",
        "botpasswords-insert-failed": "Không thể thêm tên bot \"$1\". Nó đã được thêm vào chưa?",
        "botpasswords-updated-body": "Đã cập nhật mật khẩu cho bot “$1” của người dùng “$2”.",
        "botpasswords-deleted-title": "Bot mật khẩu đã bị xóa",
        "botpasswords-deleted-body": "Đã xóa mật khẩu cho bot “$1” của người dùng “$2”.",
-       "botpasswords-newpassword": "Mật khẩu mới để đăng nhập như <strong>$1</strong> là <strong>$2</strong>. <em>Xin hãy ghi lại mật khẩu này để mai mốt tham khảo.</em>",
+       "botpasswords-newpassword": "Mật khẩu mới để đăng nhập như <strong>$1</strong> là <strong>$2</strong>. <em>Xin hãy ghi lại mật khẩu này để mai mốt tham khảo.</em> <br> (Các bot cũ cần tên đăng nhập khớp với tên người dùng cuối cùng có thể sử  dụng tên người dùng <strong>$3</strong> và mật khẩu <strong>$4</strong>.)",
        "botpasswords-no-provider": "BotPasswordsSessionProvider không có sẵn.",
        "botpasswords-restriction-failed": "Mật khẩu bot giới hạn ngăn chặn đăng nhập này.",
        "botpasswords-invalid-name": "Tên người dùng đã chỉ định không chứa dấu tách mật khẩu bot (\"$1\").",
        "tags-actions-header": "Tác vụ",
        "tags-active-yes": "Kích hoạt",
        "tags-active-no": "Vô hiệu",
-       "tags-source-extension": "Xác định bởi một mở rộng",
+       "tags-source-extension": "Xác định bởi phần mềm",
        "tags-source-manual": "Áp dụng thủ công bởi người dùng và bot",
        "tags-source-none": "Không còn sử dụng",
        "tags-edit": "sửa",
        "htmlform-title-not-exists": "$1 không tồn tại.",
        "htmlform-user-not-exists": "<strong>$1</strong> không tồn tại.",
        "htmlform-user-not-valid": "<strong>$1</strong> không phải là tên người dùng.",
-       "sqlite-has-fts": "$1 với sự hỗ trợ tìm kiếm toàn văn",
-       "sqlite-no-fts": "$1 không có hỗ trợ tìm kiếm toàn văn",
        "logentry-delete-delete": "$1 {{GENDER:$2}}đã xóa trang “$3”",
        "logentry-delete-restore": "$1 {{GENDER:$2}}đã phục hồi trang “$3”",
        "logentry-delete-event": "$1 {{GENDER:$2}}đã thay đổi mức hiển thị của {{PLURAL:$5|một mục nhật trình|$5 mục nhật trình}} về $3: $4",
index c832237..974771f 100644 (file)
--- a/load.php
+++ b/load.php
@@ -23,6 +23,7 @@
  */
 
 use MediaWiki\Logger\LoggerFactory;
+use MediaWiki\MediaWikiServices;
 
 // This endpoint is supposed to be independent of request cookies and other
 // details of the session. Enforce this constraint with respect to session use.
@@ -35,6 +36,12 @@ if ( !$wgRequest->checkUrlExtension() ) {
        return;
 }
 
+// Don't initialise ChronologyProtector from object cache, and
+// don't wait for unrelated MediaWiki writes when querying ResourceLoader.
+MediaWikiServices::getInstance()->getDBLoadBalancerFactory()->setRequestInfo( [
+       'ChronologyProtection' => 'false',
+] );
+
 // Set up ResourceLoader
 $resourceLoader = new ResourceLoader(
        ConfigFactory::getDefaultInstance()->makeConfig( 'main' ),
index e1a4dc6..1cb5eef 100644 (file)
@@ -1316,7 +1316,7 @@ abstract class Maintenance {
 
        /**
         * Lock the search index
-        * @param DatabaseBase &$db
+        * @param Database &$db
         */
        private function lockSearchindex( $db ) {
                $write = [ 'searchindex' ];
@@ -1334,7 +1334,7 @@ abstract class Maintenance {
 
        /**
         * Unlock the tables
-        * @param DatabaseBase &$db
+        * @param Database &$db
         */
        private function unlockSearchindex( $db ) {
                $db->unlockTables( __CLASS__ . '::' . __METHOD__ );
@@ -1343,7 +1343,7 @@ abstract class Maintenance {
        /**
         * Unlock and lock again
         * Since the lock is low-priority, queued reads will be able to complete
-        * @param DatabaseBase &$db
+        * @param Database &$db
         */
        private function relockSearchindex( $db ) {
                $this->unlockSearchindex( $db );
@@ -1354,7 +1354,7 @@ abstract class Maintenance {
         * Perform a search index update with locking
         * @param int $maxLockTime The maximum time to keep the search index locked.
         * @param string $callback The function that will update the function.
-        * @param DatabaseBase $dbw
+        * @param Database $dbw
         * @param array $results
         */
        public function updateSearchIndex( $maxLockTime, $callback, $dbw, $results ) {
@@ -1390,7 +1390,7 @@ abstract class Maintenance {
 
        /**
         * Update the searchindex table for a given pageid
-        * @param DatabaseBase $dbw A database write handle
+        * @param Database $dbw A database write handle
         * @param int $pageId The page ID to update.
         * @return null|string
         */
index cf5a19c..0beff7c 100644 (file)
@@ -32,7 +32,7 @@ require __DIR__ . '/../commandLine.inc';
 class UpdateLogging {
 
        /**
-        * @var DatabaseBase
+        * @var Database
         */
        public $dbw;
        public $batchSize = 1000;
index e9cdb58..2a8d79a 100644 (file)
@@ -69,7 +69,7 @@ class BenchmarkDeleteTruncate extends Benchmarker {
        }
 
        /**
-        * @param DatabaseBase $dbw
+        * @param Database $dbw
         * @return void
         */
        private function insertData( $dbw ) {
@@ -82,7 +82,7 @@ class BenchmarkDeleteTruncate extends Benchmarker {
        }
 
        /**
-        * @param DatabaseBase $dbw
+        * @param Database $dbw
         * @return void
         */
        private function delete( $dbw ) {
@@ -90,7 +90,7 @@ class BenchmarkDeleteTruncate extends Benchmarker {
        }
 
        /**
-        * @param DatabaseBase $dbw
+        * @param Database $dbw
         * @return void
         */
        private function truncate( $dbw ) {
index 14557f4..b8001a4 100644 (file)
@@ -74,7 +74,7 @@ class ConvertUserOptions extends Maintenance {
 
        /**
         * @param ResultWrapper $res
-        * @param DatabaseBase $dbw
+        * @param Database $dbw
         * @return null|int
         */
        function convertOptionBatch( $res, $dbw ) {
index 507a494..df496d4 100644 (file)
@@ -83,7 +83,7 @@ class DeleteOrphanedRevisions extends Maintenance {
         * Do this inside a transaction
         *
         * @param array $id Array of revision id values
-        * @param DatabaseBase $dbw DatabaseBase class (needs to be a master)
+        * @param Database $dbw Database class (needs to be a master)
         */
        private function deleteRevs( $id, &$dbw ) {
                if ( !is_array( $id ) ) {
index 31272bc..9f983c1 100644 (file)
@@ -117,7 +117,7 @@ abstract class DumpIterator extends Maintenance {
        /**
         * Callback function for each revision, child classes should override
         * processRevision instead.
-        * @param DatabaseBase $rev
+        * @param Database $rev
         */
        public function handleRevision( $rev ) {
                $title = $rev->getTitle();
index d0bda4e..d8661c1 100644 (file)
@@ -86,7 +86,7 @@ class TextPassDumper extends BackupDumper {
        protected $checkpointFiles = [];
 
        /**
-        * @var DatabaseBase
+        * @var Database
         */
        protected $db;
 
index 2ed1efa..9dee6e5 100644 (file)
@@ -71,7 +71,7 @@ class FetchText extends Maintenance {
 
        /**
         * May throw a database error if, say, the server dies during query.
-        * @param DatabaseBase $db
+        * @param Database $db
         * @param int $id The old_id
         * @return string
         */
index 506bc9c..b705500 100644 (file)
@@ -37,7 +37,7 @@ require_once __DIR__ . '/Maintenance.php';
 class NamespaceConflictChecker extends Maintenance {
 
        /**
-        * @var DatabaseBase
+        * @var Database
         */
        protected $db;
 
index 7b8f2cd..e4f3e91 100644 (file)
@@ -56,7 +56,7 @@ class Orphans extends Maintenance {
 
        /**
         * Lock the appropriate tables for the script
-        * @param DatabaseBase $db
+        * @param Database $db
         * @param string $extraTable The name of any extra tables to lock (eg: text)
         */
        private function lockTables( $db, $extraTable = [] ) {
index 401ef12..c6bd794 100644 (file)
@@ -57,7 +57,7 @@ class PopulateContentModel extends Maintenance {
                }
        }
 
-       private function updatePageRows( DatabaseBase $dbw, $pageIds, $model ) {
+       private function updatePageRows( Database $dbw, $pageIds, $model ) {
                $count = count( $pageIds );
                $this->output( "Setting $count rows to $model..." );
                $dbw->update(
@@ -70,7 +70,7 @@ class PopulateContentModel extends Maintenance {
                $this->output( "done.\n" );
        }
 
-       protected function populatePage( DatabaseBase $dbw, $ns ) {
+       protected function populatePage( Database $dbw, $ns ) {
                $toSave = [];
                $lastId = 0;
                $nsCondition = $ns === 'all' ? [] : [ 'page_namespace' => $ns ];
@@ -102,7 +102,7 @@ class PopulateContentModel extends Maintenance {
                }
        }
 
-       private function updateRevisionOrArchiveRows( DatabaseBase $dbw, $ids, $model, $table ) {
+       private function updateRevisionOrArchiveRows( Database $dbw, $ids, $model, $table ) {
                $prefix = $table === 'archive' ? 'ar' : 'rev';
                $model_column = "{$prefix}_content_model";
                $format_column = "{$prefix}_content_format";
@@ -120,7 +120,7 @@ class PopulateContentModel extends Maintenance {
                $this->output( "done.\n" );
        }
 
-       protected function populateRevisionOrArchive( DatabaseBase $dbw, $table, $ns ) {
+       protected function populateRevisionOrArchive( Database $dbw, $table, $ns ) {
                $prefix = $table === 'archive' ? 'ar' : 'rev';
                $model_column = "{$prefix}_content_model";
                $format_column = "{$prefix}_content_format";
index 05098ac..ac87cf3 100644 (file)
@@ -83,7 +83,7 @@ class PopulateRecentChangesSource extends LoggedUpdateMaintenance {
                return __CLASS__;
        }
 
-       protected function buildUpdateCondition( DatabaseBase $dbw ) {
+       protected function buildUpdateCondition( Database $dbw ) {
                $rcNew = $dbw->addQuotes( RC_NEW );
                $rcSrcNew = $dbw->addQuotes( RecentChange::SRC_NEW );
                $rcEdit = $dbw->addQuotes( RC_EDIT );
index 3157186..6aa1f37 100644 (file)
@@ -40,7 +40,7 @@ require_once __DIR__ . '/Maintenance.php';
 class ImageBuilder extends Maintenance {
 
        /**
-        * @var DatabaseBase
+        * @var Database
         */
        protected $dbw;
 
index ec99d84..37636c8 100644 (file)
@@ -36,7 +36,7 @@ class RebuildTextIndex extends Maintenance {
        const RTI_CHUNK_SIZE = 500;
 
        /**
-        * @var DatabaseBase
+        * @var Database
         */
        private $db;
 
index aea966f..df4ce56 100644 (file)
@@ -37,7 +37,7 @@ require_once __DIR__ . '/Maintenance.php';
 class RefreshImageMetadata extends Maintenance {
 
        /**
-        * @var DatabaseBase
+        * @var Database
         */
        protected $dbw;
 
@@ -197,7 +197,7 @@ class RefreshImageMetadata extends Maintenance {
        }
 
        /**
-        * @param DatabaseBase $dbw
+        * @param Database $dbw
         * @return array
         */
        function getConditions( $dbw ) {
index a0efcb8..c5dd53b 100644 (file)
@@ -640,7 +640,7 @@ class RecompressTracked {
        /**
         * Gets a DB master connection for the given external cluster name
         * @param string $cluster
-        * @return DatabaseBase
+        * @return Database
         */
        function getExtDB( $cluster ) {
                $lb = wfGetLBFactory()->getExternalLB( $cluster );
index e754e3c..e70a176 100644 (file)
@@ -242,7 +242,7 @@ TEXT
         * Return an SQL expression selecting rows which sort above the given row,
         * assuming an ordering of cl_collation, cl_to, cl_type, cl_from
         * @param stdClass $row
-        * @param DatabaseBase $dbw
+        * @param Database $dbw
         * @return string
         */
        function getBatchCondition( $row, $dbw ) {
index cb4919f..1522de1 100644 (file)
@@ -105,6 +105,25 @@ span.comment {
        clear: both;
 }
 
+/* Edit font preference */
+/* TODO: for 'default' on non-textareas we could compute the default font of textarea in the client */
+.mw-editfont-default:not( textarea ) {
+       font-family: monospace;
+}
+
+/* Keep this rule separate from the :not rule above so it still works in older browsers */
+.mw-editfont-monospace {
+       font-family: monospace;
+}
+
+.mw-editfont-sans-serif {
+       font-family: sans-serif;
+}
+
+.mw-editfont-serif {
+       font-family: serif;
+}
+
 /**
  * rev_deleted stuff
  */
index 780b372..1bfa3a3 100644 (file)
 // ----------------------------------------------------------------------------
 
 .button-colors( @bgColor, @highlightColor, @activeColor ) {
-       background: @bgColor;
+       background-color: @bgColor;
+       color: @colorButtonText;
+       border: 1px solid @colorFieldBorder;
+
+       // Make sure that `color` isn't inheriting from user-agent styles
+       &:visited {
+               color: @colorButtonText;
+       }
 
        &:hover {
                background-color: @highlightColor;
+               color: @colorGray4;
+               border-color: @colorGray10;
        }
 
        &:focus {
-               border-color: @colorWhite;
-               box-shadow: inset 0 0 0 1px @bgColor, inset 0 0 0 2px @colorWhite;
-               outline-width: 0;
-
-               // Remove the inner border and padding in Firefox.
-               &::-moz-focus-inner {
-                       border-color: transparent;
-                       padding: 0;
-               }
+               background-color: @highlightColor;
+               // Make sure that `color` isn't inheriting from user-agent styles
+               color: @colorButtonText;
+               border-color: @colorProgressive;
+               box-shadow: inset 0 0 0 1px @colorProgressive, inset 0 0 0 2px #fff;
        }
 
        &:active,
        &.is-on,
        &.mw-ui-checked {
                background-color: @activeColor;
+               color: @colorGray1;
+               border-color: @colorGray7;
                box-shadow: none;
        }
-}
-
-.button-colors( @bgColor, @highlightColor, @activeColor ) when ( lightness( @bgColor ) >= 70% ) {
-       color: @colorButtonText;
-       border: 1px solid @colorFieldBorder;
-
-       &:hover,
-       &:active,
-       &:visited {
-               // make sure that is isn't inheriting from a general rule
-               color: @colorButtonText;
-       }
-
-       &:focus {
-               background-color: @highlightColor;
-       }
 
        &:disabled {
-               color: @colorDisabledText;
+               background-color: @colorGray12;
+               color: #fff;
+               border-color: @colorGray12;
 
-               // make sure disabled buttons don't have hover and active states
+               // Make sure disabled buttons don't have hover and active states
                &:hover,
                &:active {
-                       background: @bgColor;
+                       background-color: @colorGray12;
+                       color: #fff;
                        box-shadow: none;
+                       border-color: @colorGray12;
                }
        }
 }
 
-.button-colors( @bgColor, @highlightColor, @activeColor ) when ( lightness( @bgColor ) < 70% ) {
+.button-colors-primary( @bgColor, @highlightColor, @activeColor ) {
+       background-color: @bgColor;
        color: #fff;
        // border of the same color as background so that light background and
        // dark background buttons are the same height and width
        border: 1px solid @bgColor;
-       text-shadow: 0 1px rgba(0, 0, 0, .1);
+       text-shadow: 0 1px rgba( 0, 0, 0, 0.1 );
+
+       &:hover {
+               background-color: @highlightColor;
+               border-color: @highlightColor;
+       }
+
+       &:focus {
+               box-shadow: inset 0 0 0 1px @bgColor, inset 0 0 0 2px #fff;
+       }
+
+       &:active,
+       &.is-on,
+       &.mw-ui-checked {
+               background-color: @activeColor;
+               border-color: @activeColor;
+               box-shadow: none;
+       }
 
        &:disabled {
-               background-color: @colorGray13;
-               border-color: @colorGray13;
+               background-color: @colorGray12;
+               color: #fff;
+               border-color: @colorGray12;
 
-               // make sure disabled buttons don't have hover and active states
+               // Make sure disabled buttons don't have hover and active states
                &:hover,
                &:active,
                &.mw-ui-checked {
+                       background-color: @colorGray12;
+                       color: #fff;
+                       border-color: @colorGray12;
                        box-shadow: none;
                }
        }
 
 .button-colors-quiet( @textColor, @highlightColor, @activeColor ) {
        // Quiet buttons all start gray, and reveal
-       // constructive/progressive/destructive color on hover and active.
+       // progressive/destructive color on hover and active.
        color: @colorButtonText;
 
        &:hover {
index 5931efb..18fdb2f 100644 (file)
        vertical-align: middle;
 
        // Content styling
-       .button-colors( #fff, @colorGray12, @colorGray7 );
+       .button-colors( @colorGray15, #fff, #d9d9d9 );
        text-align: center;
        font-weight: bold;
 
        // Interaction styling
        cursor: pointer;
 
+       &:focus {
+               outline-width: 0;
+
+               // Remove the inner border and padding in Firefox.
+               &::-moz-focus-inner {
+                       border-color: transparent;
+                       padding: 0;
+               }
+       }
+
+       // `:not()` is used exclusively for `transition`s as both are not supported by IE < 9
+       &:not( :disabled ) {
+               .transition( ~'background-color 100ms, color 100ms, border-color 100ms, box-shadow 100ms' );
+       }
+
        &:disabled {
                text-shadow: none;
                cursor: default;
        // Progressive buttons
        //
        // Use progressive buttons for actions which lead to a next step in the process.
+       // .mw-ui-constructive is deprecated; consolidated with `progressive`, see T110555
        // .mw-ui-primary is deprecated, kept for compatibility.
        //
        // Markup:
        //
        // Styleguide 2.1.1.
        &.mw-ui-progressive,
+       &.mw-ui-constructive,
        &.mw-ui-primary {
-               .button-colors( @colorProgressive, @colorProgressiveHighlight, @colorProgressiveActive );
-
-               &.mw-ui-quiet {
-                       .button-colors-quiet( @colorProgressive, @colorProgressiveHighlight, @colorProgressiveActive );
-               }
-       }
-
-       // Constructive buttons (deprecated, consolidated with `progressive` – see T110555)
-       //
-       // Use constructive buttons for actions which result in a final action in the process that results
-       // in a change of state.
-       // e.g. save changes button
-       //
-       // Markup:
-       // <div>
-       //   <button class="mw-ui-button mw-ui-constructive">.mw-ui-constructive</button>
-       // </div>
-       // <div>
-       //   <button class="mw-ui-button mw-ui-constructive" disabled>.mw-ui-constructive</button>
-       // </div>
-       //
-       // Styleguide 2.1.2.
-       &.mw-ui-constructive {
-               .button-colors( @colorProgressive, @colorProgressiveHighlight, @colorProgressiveActive );
+               .button-colors-primary( @colorProgressive, @colorProgressiveHighlight, @colorProgressiveActive );
 
                &.mw-ui-quiet {
                        .button-colors-quiet( @colorProgressive, @colorProgressiveHighlight, @colorProgressiveActive );
        //   <button class="mw-ui-button mw-ui-destructive" disabled>.mw-ui-destructive</button>
        // </div>
        //
-       // Styleguide 2.1.3.
+       // Styleguide 2.1.2.
        &.mw-ui-destructive {
-               .button-colors( @colorDestructive, @colorDestructiveHighlight, @colorDestructiveActive );
+               .button-colors-primary( @colorDestructive, @colorDestructiveHighlight, @colorDestructiveActive );
 
                &.mw-ui-quiet {
                        .button-colors-quiet( @colorDestructive, @colorDestructiveHighlight, @colorDestructiveActive );
        //   <button class="mw-ui-button mw-ui-progressive mw-ui-quiet" disabled>.mw-ui-progressive</button>
        // </div>
        //
-       // Styleguide 2.1.4.
+       // Styleguide 2.1.3.
        &.mw-ui-quiet {
                background: transparent;
                border: 0;
index 294b5de..866f213 100644 (file)
                        // - atext   : defined in RFC 5322 section 3.2.3
                        // - ldh-str : defined in RFC 1034 section 3.5
                        //
-                       // (see STD 68 / RFC 5234 http://tools.ietf.org/html/std68)
+                       // (see STD 68 / RFC 5234 https://tools.ietf.org/html/std68)
                        // First, define the RFC 5322 'atext' which is pretty easy:
                        // atext = ALPHA / DIGIT / ; Printable US-ASCII
                        //     "!" / "#" /    ; characters not including
index 369cd0e..6ca851e 100644 (file)
@@ -1524,7 +1524,7 @@ class ParserTestRunner {
                }
 
                // The RepoGroup cache is invalidated by the creation of file redirects
-               if ( $title->getNamespace() === NS_IMAGE ) {
+               if ( $title->inNamespace( NS_FILE ) ) {
                        RepoGroup::singleton()->clearCache( $title );
                }
        }
index 1e511f6..c3975ca 100644 (file)
@@ -21651,6 +21651,22 @@ __TOC__
 
 !! end
 
+!! test
+T35715: s/strike element in ToC
+!! wikitext
+__TOC__
+== <s>test</s> test <strike>test</strike> ==
+!! html
+<div id="toc" class="toc"><div id="toctitle"><h2>Contents</h2></div>
+<ul>
+<li class="toclevel-1 tocsection-1"><a href="#test_test_test"><span class="tocnumber">1</span> <span class="toctext"><s>test</s> test <strike>test</strike></span></a></li>
+</ul>
+</div>
+
+<h2><span class="mw-headline" id="test_test_test"><s>test</s> test <strike>test</strike></span><span class="mw-editsection"><span class="mw-editsection-bracket">[</span><a href="/index.php?title=Parser_test&amp;action=edit&amp;section=1" title="Edit section: test test test">edit</a><span class="mw-editsection-bracket">]</span></span></h2>
+
+!! end
+
 # Note that the html output does not have the <p></p>, but the
 # html+tidy output *does*.  This is because the empty <p></p> is
 # removed by the sanitizer, but only when tidy is *not* enabled (!).
index 45a7ce5..e53a958 100644 (file)
@@ -336,6 +336,10 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
 
                JobQueueGroup::destroySingletons();
                ObjectCache::clear();
+               $services = MediaWikiServices::getInstance();
+               $services->resetServiceForTesting( 'MainObjectStash' );
+               $services->resetServiceForTesting( 'LocalServerObjectCache' );
+               $services->getMainWANObjectCache()->clearProcessCache();
                FileBackendGroup::destroySingleton();
 
                // TODO: move global state into MediaWikiServices
index c76666d..8fbca6c 100644 (file)
@@ -11,7 +11,7 @@ class WfBCP47Test extends MediaWikiTestCase {
         * This test is used to verify our formatting against all lower and
         * all upper cases language code.
         *
-        * @see http://tools.ietf.org/html/bcp47
+        * @see https://tools.ietf.org/html/bcp47
         * @dataProvider provideLanguageCodes()
         */
        public function testBCP47( $code, $expected ) {
index a05e39d..4fbef6c 100644 (file)
@@ -320,8 +320,11 @@ class MediaWikiServicesTest extends MediaWikiTestCase {
                        '_MediaWikiTitleCodec' => [ '_MediaWikiTitleCodec', MediaWikiTitleCodec::class ],
                        'TitleFormatter' => [ 'TitleFormatter', TitleFormatter::class ],
                        'TitleParser' => [ 'TitleParser', TitleParser::class ],
-                       'VirtualRESTServiceClient' => [ 'VirtualRESTServiceClient', VirtualRESTServiceClient::class ],
-                       'ProxyLookup' => [ 'ProxyLookup', ProxyLookup::class ]
+                       'ProxyLookup' => [ 'ProxyLookup', ProxyLookup::class ],
+                       'MainObjectStash' => [ 'MainObjectStash', BagOStuff::class ],
+                       'MainWANObjectCache' => [ 'MainWANObjectCache', WANObjectCache::class ],
+                       'LocalServerObjectCache' => [ 'LocalServerObjectCache', BagOStuff::class ],
+                       'VirtualRESTServiceClient' => [ 'VirtualRESTServiceClient', VirtualRESTServiceClient::class ]
                ];
        }
 
index 26529e8..c915b70 100644 (file)
@@ -314,6 +314,8 @@ class SanitizerTest extends MediaWikiTestCase {
                                '/* insecure input */',
                                'background-image: -moz-image-set("asdf.png" 1x, "asdf.png" 2x);'
                        ],
+                       [ '/* insecure input */', 'foo: attr( title, url );' ],
+                       [ '/* insecure input */', 'foo: attr( title url );' ],
                ];
        }
 
index 030d9d5..c51d496 100644 (file)
@@ -28,12 +28,12 @@ class WatchedItemStoreUnitTest extends MediaWikiTestCase {
                        ->getMock();
                if ( $expectedConnectionType !== null ) {
                        $mock->expects( $this->any() )
-                               ->method( 'getConnection' )
+                               ->method( 'getConnectionRef' )
                                ->with( $expectedConnectionType )
                                ->will( $this->returnValue( $mockDb ) );
                } else {
                        $mock->expects( $this->any() )
-                               ->method( 'getConnection' )
+                               ->method( 'getConnectionRef' )
                                ->will( $this->returnValue( $mockDb ) );
                }
                $mock->expects( $this->any() )
index 582c076..d6f315d 100644 (file)
@@ -477,6 +477,7 @@ class ApiQueryWatchlistRawIntegrationTest extends ApiTestCase {
                        new TitleValue( 1, 'ApiQueryWatchlistRawIntegrationTestPage1' ),
                ] );
 
+               ObjectCache::getMainWANInstance()->clearProcessCache();
                $result = $this->doListWatchlistRawRequest( [
                        'wrowner' => $otherUser->getName(),
                        'wrtoken' => '1234567890',
index 515a5b3..8161ed4 100644 (file)
@@ -122,6 +122,8 @@ class TemporaryPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestC
        }
 
        public function testTestUserCanAuthenticate() {
+               $user = self::getMutableTestUser()->getUser();
+
                $dbw = wfGetDB( DB_MASTER );
 
                $passwordFactory = new \PasswordFactory();
@@ -142,9 +144,9 @@ class TemporaryPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestC
                                'user_newpassword' => \PasswordFactory::newInvalidPassword()->toString(),
                                'user_newpass_time' => null,
                        ],
-                       [ 'user_name' => 'UTSysop' ]
+                       [ 'user_id' => $user->getId() ]
                );
-               $this->assertFalse( $provider->testUserCanAuthenticate( 'UTSysop' ) );
+               $this->assertFalse( $provider->testUserCanAuthenticate( $user->getName() ) );
 
                $dbw->update(
                        'user',
@@ -152,10 +154,10 @@ class TemporaryPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestC
                                'user_newpassword' => $pwhash,
                                'user_newpass_time' => null,
                        ],
-                       [ 'user_name' => 'UTSysop' ]
+                       [ 'user_id' => $user->getId() ]
                );
-               $this->assertTrue( $provider->testUserCanAuthenticate( 'UTSysop' ) );
-               $this->assertTrue( $provider->testUserCanAuthenticate( 'uTSysop' ) );
+               $this->assertTrue( $provider->testUserCanAuthenticate( $user->getName() ) );
+               $this->assertTrue( $provider->testUserCanAuthenticate( lcfirst( $user->getName() ) ) );
 
                $dbw->update(
                        'user',
@@ -163,12 +165,12 @@ class TemporaryPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestC
                                'user_newpassword' => $pwhash,
                                'user_newpass_time' => $dbw->timestamp( time() - 10 ),
                        ],
-                       [ 'user_name' => 'UTSysop' ]
+                       [ 'user_id' => $user->getId() ]
                );
                $providerPriv->newPasswordExpiry = 100;
-               $this->assertTrue( $provider->testUserCanAuthenticate( 'UTSysop' ) );
+               $this->assertTrue( $provider->testUserCanAuthenticate( $user->getName() ) );
                $providerPriv->newPasswordExpiry = 1;
-               $this->assertFalse( $provider->testUserCanAuthenticate( 'UTSysop' ) );
+               $this->assertFalse( $provider->testUserCanAuthenticate( $user->getName() ) );
 
                $dbw->update(
                        'user',
@@ -176,7 +178,7 @@ class TemporaryPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestC
                                'user_newpassword' => \PasswordFactory::newInvalidPassword()->toString(),
                                'user_newpass_time' => null,
                        ],
-                       [ 'user_name' => 'UTSysop' ]
+                       [ 'user_id' => $user->getId() ]
                );
        }
 
@@ -229,13 +231,15 @@ class TemporaryPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestC
        }
 
        public function testAuthentication() {
+               $user = self::getMutableTestUser()->getUser();
+
                $password = 'TemporaryPassword';
                $hash = ':A:' . md5( $password );
                $dbw = wfGetDB( DB_MASTER );
                $dbw->update(
                        'user',
                        [ 'user_newpassword' => $hash, 'user_newpass_time' => $dbw->timestamp( time() - 10 ) ],
-                       [ 'user_name' => 'UTSysop' ]
+                       [ 'user_id' => $user->getId() ]
                );
 
                $req = new PasswordAuthenticationRequest();
@@ -284,7 +288,7 @@ class TemporaryPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestC
                );
 
                // Validation failure
-               $req->username = 'UTSysop';
+               $req->username = $user->getName();
                $req->password = $password;
                $this->validity = \Status::newFatal( 'arbitrary-failure' );
                $ret = $provider->beginPrimaryAuthentication( $reqs );
@@ -301,20 +305,20 @@ class TemporaryPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestC
                $this->manager->removeAuthenticationSessionData( null );
                $this->validity = \Status::newGood();
                $this->assertEquals(
-                       AuthenticationResponse::newPass( 'UTSysop' ),
+                       AuthenticationResponse::newPass( $user->getName() ),
                        $provider->beginPrimaryAuthentication( $reqs )
                );
                $this->assertNotNull( $this->manager->getAuthenticationSessionData( 'reset-pass' ) );
 
                $this->manager->removeAuthenticationSessionData( null );
                $this->validity = \Status::newGood();
-               $req->username = 'uTSysop';
+               $req->username = lcfirst( $user->getName() );
                $this->assertEquals(
-                       AuthenticationResponse::newPass( 'UTSysop' ),
+                       AuthenticationResponse::newPass( $user->getName() ),
                        $provider->beginPrimaryAuthentication( $reqs )
                );
                $this->assertNotNull( $this->manager->getAuthenticationSessionData( 'reset-pass' ) );
-               $req->username = 'UTSysop';
+               $req->username = $user->getName();
 
                // Expired password
                $providerPriv->newPasswordExpiry = 1;
@@ -408,20 +412,19 @@ class TemporaryPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestC
                $oldpass = 'OldTempPassword';
                $newpass = 'NewTempPassword';
 
-               $hash = ':A:' . md5( $oldpass );
-               $dbw = wfGetDB( DB_MASTER );
-               $dbw->update(
-                       'user',
-                       [ 'user_newpassword' => $hash, 'user_newpass_time' => $dbw->timestamp( time() + 10 ) ],
-                       [ 'user_name' => 'UTSysop' ]
-               );
-
                $dbw = wfGetDB( DB_MASTER );
                $oldHash = $dbw->selectField( 'user', 'user_newpassword', [ 'user_name' => $cuser ] );
                $cb = new \ScopedCallback( function () use ( $dbw, $cuser, $oldHash ) {
                        $dbw->update( 'user', [ 'user_newpassword' => $oldHash ], [ 'user_name' => $cuser ] );
                } );
 
+               $hash = ':A:' . md5( $oldpass );
+               $dbw->update(
+                       'user',
+                       [ 'user_newpassword' => $hash, 'user_newpass_time' => $dbw->timestamp( time() + 10 ) ],
+                       [ 'user_name' => $cuser ]
+               );
+
                $provider = $this->getProvider();
 
                // Sanity check
@@ -500,22 +503,15 @@ class TemporaryPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestC
        }
 
        public function testProviderChangeAuthenticationDataEmail() {
+               $user = self::getMutableTestUser()->getUser();
+
                $dbw = wfGetDB( DB_MASTER );
                $dbw->update(
                        'user',
                        [ 'user_newpass_time' => $dbw->timestamp( time() - 5 * 3600 ) ],
-                       [ 'user_name' => 'UTSysop' ]
+                       [ 'user_id' => $user->getId() ]
                );
 
-               $user = \User::newFromName( 'UTSysop' );
-               $reset = new \ScopedCallback( function ( $email ) use ( $user ) {
-                       $user->setEmail( $email );
-                       $user->saveSettings();
-               }, [ $user->getEmail() ] );
-
-               $user->setEmail( 'test@localhost.localdomain' );
-               $user->saveSettings();
-
                $req = TemporaryPasswordAuthenticationRequest::newRandom();
                $req->username = $user->getName();
                $req->mailpassword = true;
@@ -539,7 +535,7 @@ class TemporaryPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestC
                $dbw->update(
                        'user',
                        [ 'user_newpass_time' => $dbw->timestamp( time() + 5 * 3600 ) ],
-                       [ 'user_name' => 'UTSysop' ]
+                       [ 'user_id' => $user->getId() ]
                );
                $provider = $this->getProvider( [ 'passwordReminderResendTime' => 0 ] );
                $status = $provider->providerAllowsAuthenticationDataChange( $req, true );
@@ -563,16 +559,16 @@ class TemporaryPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestC
                $status = $provider->providerAllowsAuthenticationDataChange( $req, true );
                $this->assertEquals( \StatusValue::newGood(), $status );
 
-               $req->caller = 'UTSysop';
+               $req->caller = $user->getName();
                $status = $provider->providerAllowsAuthenticationDataChange( $req, true );
                $this->assertEquals( \StatusValue::newGood(), $status );
 
                $mailed = false;
                $resetMailer = $this->hookMailer( function ( $headers, $to, $from, $subject, $body )
-                       use ( &$mailed, $req )
+                       use ( &$mailed, $req, $user )
                {
                        $mailed = true;
-                       $this->assertSame( 'test@localhost.localdomain', $to[0]->address );
+                       $this->assertSame( $user->getEmail(), $to[0]->address );
                        $this->assertContains( $req->password, $body );
                        return false;
                } );
@@ -658,12 +654,10 @@ class TemporaryPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestC
                $this->assertEquals( $expect, $provider->beginPrimaryAccountCreation( $user, $user, $reqs ) );
                $this->assertNull( $this->manager->getAuthenticationSessionData( 'no-email' ) );
 
-               // We have to cheat a bit to avoid having to add a new user to
-               // the database to test the actual setting of the password works right
-               $user = \User::newFromName( 'UTSysop' );
+               $user = self::getMutableTestUser()->getUser();
                $req->username = $authreq->username = $user->getName();
                $req->password = $authreq->password = 'NewPassword';
-               $expect = AuthenticationResponse::newPass( 'UTSysop' );
+               $expect = AuthenticationResponse::newPass( $user->getName() );
                $expect->createRequest = $req;
 
                $res2 = $provider->beginPrimaryAccountCreation( $user, $user, $reqs );
@@ -680,12 +674,8 @@ class TemporaryPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestC
 
        public function testAccountCreationEmail() {
                $creator = \User::newFromName( 'Foo' );
-               $user = \User::newFromName( 'UTSysop' );
-               $reset = new \ScopedCallback( function ( $email ) use ( $user ) {
-                       $user->setEmail( $email );
-                       $user->saveSettings();
-               }, [ $user->getEmail() ] );
 
+               $user = self::getMutableTestUser()->getUser();
                $user->setEmail( null );
 
                $req = TemporaryPasswordAuthenticationRequest::newRandom();
@@ -722,9 +712,9 @@ class TemporaryPasswordPrimaryAuthenticationProviderTest extends \MediaWikiTestC
                        return false;
                } );
 
-               $expect = AuthenticationResponse::newPass( 'UTSysop' );
+               $expect = AuthenticationResponse::newPass( $user->getName() );
                $expect->createRequest = clone( $req );
-               $expect->createRequest->username = 'UTSysop';
+               $expect->createRequest->username = $user->getName();
                $res = $provider->beginPrimaryAccountCreation( $user, $creator, [ $req ] );
                $this->assertEquals( $expect, $res );
                $this->assertTrue( $this->manager->getAuthenticationSessionData( 'no-email' ) );
index fafd4fa..760d41e 100644 (file)
@@ -37,7 +37,7 @@ class MWCryptHKDFTest extends MediaWikiTestCase {
        }
 
        /**
-        * Test vectors from Appendix A on http://tools.ietf.org/html/rfc5869
+        * Test vectors from Appendix A on https://tools.ietf.org/html/rfc5869
         */
        public static function providerRfc5869() {