Merge "User: Fully clear instance variables when loading not-blocked status"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Thu, 22 Mar 2018 21:40:07 +0000 (21:40 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Thu, 22 Mar 2018 21:40:07 +0000 (21:40 +0000)
15 files changed:
includes/libs/rdbms/database/DBConnRef.php
includes/libs/rdbms/database/Database.php
includes/libs/rdbms/database/IDatabase.php
includes/libs/rdbms/database/IMaintainableDatabase.php
includes/libs/rdbms/database/MaintainableDBConnRef.php
languages/i18n/be-tarask.json
languages/i18n/bn.json
languages/i18n/he.json
languages/i18n/io.json
languages/i18n/li.json
languages/i18n/pl.json
languages/i18n/pt.json
languages/i18n/th.json
resources/src/mediawiki.ui/components/inputs.less
tests/phpunit/includes/libs/rdbms/database/DatabaseSQLTest.php

index c0855df..11ce957 100644 (file)
@@ -211,10 +211,6 @@ class DBConnRef implements IDatabase {
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
-       public function fieldInfo( $table, $field ) {
-               return $this->__call( __FUNCTION__, func_get_args() );
-       }
-
        public function affectedRows() {
                return $this->__call( __FUNCTION__, func_get_args() );
        }
@@ -231,18 +227,10 @@ class DBConnRef implements IDatabase {
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
-       public function reportConnectionError( $error = 'Unknown error' ) {
-               return $this->__call( __FUNCTION__, func_get_args() );
-       }
-
        public function query( $sql, $fname = __METHOD__, $tempIgnore = false ) {
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
-       public function reportQueryError( $error, $errno, $sql, $fname, $tempIgnore = false ) {
-               return $this->__call( __FUNCTION__, func_get_args() );
-       }
-
        public function freeResult( $res ) {
                return $this->__call( __FUNCTION__, func_get_args() );
        }
@@ -304,10 +292,6 @@ class DBConnRef implements IDatabase {
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
-       public function indexUnique( $table, $index ) {
-               return $this->__call( __FUNCTION__, func_get_args() );
-       }
-
        public function insert( $table, $a, $fname = __METHOD__, $options = [] ) {
                return $this->__call( __FUNCTION__, func_get_args() );
        }
@@ -511,7 +495,9 @@ class DBConnRef implements IDatabase {
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
-       public function startAtomic( $fname = __METHOD__ ) {
+       public function startAtomic(
+               $fname = __METHOD__, $cancelable = IDatabase::ATOMIC_NOT_CANCELABLE
+       ) {
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
@@ -543,10 +529,6 @@ class DBConnRef implements IDatabase {
                return $this->__call( __FUNCTION__, func_get_args() );
        }
 
-       public function listTables( $prefix = null, $fname = __METHOD__ ) {
-               return $this->__call( __FUNCTION__, func_get_args() );
-       }
-
        public function timestamp( $ts = 0 ) {
                return $this->__call( __FUNCTION__, func_get_args() );
        }
index c3e36da..211566e 100644 (file)
@@ -912,6 +912,10 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
         */
        abstract protected function closeConnection();
 
+       /**
+        * @param string $error Fallback error message, used if none is given by DB
+        * @throws DBConnectionError
+        */
        public function reportConnectionError( $error = 'Unknown error' ) {
                $myError = $this->lastError();
                if ( $myError ) {
@@ -1287,6 +1291,17 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                return false;
        }
 
+       /**
+        * Report a query error. Log the error, and if neither the object ignore
+        * flag nor the $tempIgnore flag is set, throw a DBQueryError.
+        *
+        * @param string $error
+        * @param int $errno
+        * @param string $sql
+        * @param string $fname
+        * @param bool $tempIgnore
+        * @throws DBQueryError
+        */
        public function reportQueryError( $error, $errno, $sql, $fname, $tempIgnore = false ) {
                if ( $this->ignoreErrors() || $tempIgnore ) {
                        $this->queryLogger->debug( "SQL ERROR (ignored): $error\n" );
@@ -2518,7 +2533,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                }
 
                try {
-                       $this->startAtomic( $fname );
+                       $this->startAtomic( $fname, self::ATOMIC_CANCELABLE );
                        $affectedRowCount = 0;
                        foreach ( $rows as $row ) {
                                // Delete rows which collide with this one
@@ -2623,7 +2638,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
 
                $affectedRowCount = 0;
                try {
-                       $this->startAtomic( $fname );
+                       $this->startAtomic( $fname, self::ATOMIC_CANCELABLE );
                        # Update any existing conflicting row(s)
                        if ( $where !== false ) {
                                $ok = $this->update( $table, $set, $where, $fname );
@@ -2779,7 +2794,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
 
                try {
                        $affectedRowCount = 0;
-                       $this->startAtomic( $fname );
+                       $this->startAtomic( $fname, self::ATOMIC_CANCELABLE );
                        $rows = [];
                        $ok = true;
                        foreach ( $res as $row ) {
@@ -3095,7 +3110,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        $this->trxPreCommitCallbacks[] = [ $callback, $fname ];
                } else {
                        // No transaction is active nor will start implicitly, so make one for this callback
-                       $this->startAtomic( __METHOD__ );
+                       $this->startAtomic( __METHOD__, self::ATOMIC_CANCELABLE );
                        try {
                                call_user_func( $callback );
                                $this->endAtomic( __METHOD__ );
@@ -3279,7 +3294,10 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                $this->query( 'ROLLBACK TO SAVEPOINT ' . $this->addIdentifierQuotes( $identifier ), $fname );
        }
 
-       final public function startAtomic( $fname = __METHOD__ ) {
+       final public function startAtomic(
+               $fname = __METHOD__, $cancelable = self::ATOMIC_NOT_CANCELABLE
+       ) {
+               $savepointId = $cancelable === self::ATOMIC_CANCELABLE ? 'n/a' : null;
                if ( !$this->trxLevel ) {
                        $this->begin( $fname, self::TRANSACTION_INTERNAL );
                        // If DBO_TRX is set, a series of startAtomic/endAtomic pairs will result
@@ -3287,8 +3305,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        if ( !$this->getFlag( self::DBO_TRX ) ) {
                                $this->trxAutomaticAtomic = true;
                        }
-                       $savepointId = null;
-               } else {
+               } elseif ( $cancelable === self::ATOMIC_CANCELABLE ) {
                        $savepointId = 'wikimedia_rdbms_atomic' . ++$this->trxAtomicCounter;
                        if ( strlen( $savepointId ) > 30 ) { // 30 == Oracle's identifier length limit (pre 12c)
                                $this->queryLogger->warning(
@@ -3316,9 +3333,9 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                        throw new DBUnexpectedError( $this, "Invalid atomic section ended (got $fname)." );
                }
 
-               if ( !$savepointId ) {
+               if ( !$this->trxAtomicLevels && $this->trxAutomaticAtomic ) {
                        $this->commit( $fname, self::FLUSHING_INTERNAL );
-               } else {
+               } elseif ( $savepointId && $savepointId !== 'n/a' ) {
                        $this->doReleaseSavepoint( $savepointId, $fname );
                }
        }
@@ -3333,10 +3350,13 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
                if ( $savedFname !== $fname ) {
                        throw new DBUnexpectedError( $this, "Invalid atomic section ended (got $fname)." );
                }
-
                if ( !$savepointId ) {
+                       throw new DBUnexpectedError( $this, "Uncancelable atomic section canceled (got $fname)." );
+               }
+
+               if ( !$this->trxAtomicLevels && $this->trxAutomaticAtomic ) {
                        $this->rollback( $fname, self::FLUSHING_INTERNAL );
-               } else {
+               } elseif ( $savepointId !== 'n/a' ) {
                        $this->doRollbackToSavepoint( $savepointId, $fname );
                }
 
@@ -3344,7 +3364,7 @@ abstract class Database implements IDatabase, IMaintainableDatabase, LoggerAware
        }
 
        final public function doAtomicSection( $fname, callable $callback ) {
-               $this->startAtomic( $fname );
+               $this->startAtomic( $fname, self::ATOMIC_CANCELABLE );
                try {
                        $res = call_user_func_array( $callback, [ $this, $fname ] );
                } catch ( Exception $e ) {
index 47954b6..07f1e23 100644 (file)
@@ -49,6 +49,11 @@ interface IDatabase {
        /** @var string Transaction is requested internally via DBO_TRX/startAtomic() */
        const TRANSACTION_INTERNAL = 'implicit';
 
+       /** @var string Atomic section is not cancelable */
+       const ATOMIC_NOT_CANCELABLE = '';
+       /** @var string Atomic section is cancelable */
+       const ATOMIC_CANCELABLE = 'cancelable';
+
        /** @var string Transaction operation comes from service managing all DBs */
        const FLUSHING_ALL_PEERS = 'flush';
        /** @var string Transaction operation comes from the database class internally */
@@ -228,6 +233,7 @@ interface IDatabase {
         * Should return true if unsure.
         *
         * @return bool
+        * @deprecated Since 1.31; use lastDoneWrites()
         */
        public function doneWrites();
 
@@ -454,17 +460,6 @@ interface IDatabase {
         */
        public function lastError();
 
-       /**
-        * mysql_fetch_field() wrapper
-        * Returns false if the field doesn't exist
-        *
-        * @param string $table Table name
-        * @param string $field Field name
-        *
-        * @return Field
-        */
-       public function fieldInfo( $table, $field );
-
        /**
         * Get the number of rows affected by the last write query
         * @see https://secure.php.net/mysql_affected_rows
@@ -503,12 +498,6 @@ interface IDatabase {
         */
        public function close();
 
-       /**
-        * @param string $error Fallback error message, used if none is given by DB
-        * @throws DBConnectionError
-        */
-       public function reportConnectionError( $error = 'Unknown error' );
-
        /**
         * Run an SQL query and return the result. Normally throws a DBQueryError
         * on failure. If errors are ignored, returns false instead.
@@ -537,19 +526,6 @@ interface IDatabase {
         */
        public function query( $sql, $fname = __METHOD__, $tempIgnore = false );
 
-       /**
-        * Report a query error. Log the error, and if neither the object ignore
-        * flag nor the $tempIgnore flag is set, throw a DBQueryError.
-        *
-        * @param string $error
-        * @param int $errno
-        * @param string $sql
-        * @param string $fname
-        * @param bool $tempIgnore
-        * @throws DBQueryError
-        */
-       public function reportQueryError( $error, $errno, $sql, $fname, $tempIgnore = false );
-
        /**
         * Free a result object returned by query() or select(). It's usually not
         * necessary to call this, just use unset() or let the variable holding
@@ -898,16 +874,6 @@ interface IDatabase {
         */
        public function tableExists( $table, $fname = __METHOD__ );
 
-       /**
-        * Determines if a given index is unique
-        *
-        * @param string $table
-        * @param string $index
-        *
-        * @return bool
-        */
-       public function indexUnique( $table, $index );
-
        /**
         * INSERT wrapper, inserts an array into a table.
         *
@@ -1580,11 +1546,11 @@ interface IDatabase {
        /**
         * Begin an atomic section of statements
         *
-        * If a transaction has been started already, sets a savepoint and tracks
-        * the given section name to make sure the transaction is not committed
-        * pre-maturely. This function can be used in layers (with sub-sections),
-        * so use a stack to keep track of the different atomic sections. If there
-        * is no transaction, one is started implicitly.
+        * If a transaction has been started already, (optionally) sets a savepoint
+        * and tracks the given section name to make sure the transaction is not
+        * committed pre-maturely. This function can be used in layers (with
+        * sub-sections), so use a stack to keep track of the different atomic
+        * sections. If there is no transaction, one is started implicitly.
         *
         * The goal of this function is to create an atomic section of SQL queries
         * without having to start a new transaction if it already exists.
@@ -1596,9 +1562,11 @@ interface IDatabase {
         *
         * @since 1.23
         * @param string $fname
+        * @param string $cancelable Pass self::ATOMIC_CANCELABLE to use a
+        *  savepoint and enable self::cancelAtomic() for this section.
         * @throws DBError
         */
-       public function startAtomic( $fname = __METHOD__ );
+       public function startAtomic( $fname = __METHOD__, $cancelable = self::ATOMIC_NOT_CANCELABLE );
 
        /**
         * Ends an atomic section of SQL statements
@@ -1626,6 +1594,8 @@ interface IDatabase {
         * Note that a call to IDatabase::rollback() will also roll back any open
         * atomic sections.
         *
+        * @note As a micro-optimization to save a few DB calls, this method may only
+        *  be called when startAtomic() was called with the ATOMIC_CANCELABLE flag.
         * @since 1.31
         * @see IDatabase::startAtomic
         * @param string $fname
@@ -1745,16 +1715,6 @@ interface IDatabase {
         */
        public function flushSnapshot( $fname = __METHOD__ );
 
-       /**
-        * List all tables on the database
-        *
-        * @param string $prefix Only show tables with this prefix, e.g. mw_
-        * @param string $fname Calling function name
-        * @throws DBError
-        * @return array
-        */
-       public function listTables( $prefix = null, $fname = __METHOD__ );
-
        /**
         * Convert a timestamp in one of the formats accepted by wfTimestamp()
         * to the format used for inserting into timestamp fields in this DBMS.
index d0c398e..18e3cbb 100644 (file)
@@ -275,6 +275,37 @@ interface IMaintainableDatabase extends IDatabase {
         * @since 1.29
         */
        public function unlockTables( $method );
+
+       /**
+        * List all tables on the database
+        *
+        * @param string $prefix Only show tables with this prefix, e.g. mw_
+        * @param string $fname Calling function name
+        * @throws DBError
+        * @return array
+        */
+       public function listTables( $prefix = null, $fname = __METHOD__ );
+
+       /**
+        * Determines if a given index is unique
+        *
+        * @param string $table
+        * @param string $index
+        *
+        * @return bool
+        */
+       public function indexUnique( $table, $index );
+
+       /**
+        * mysql_fetch_field() wrapper
+        * Returns false if the field doesn't exist
+        *
+        * @param string $table Table name
+        * @param string $field Field name
+        *
+        * @return Field
+        */
+       public function fieldInfo( $table, $field );
 }
 
 class_alias( IMaintainableDatabase::class, 'IMaintainableDatabase' );
index 6c94eb9..ff4b050 100644 (file)
@@ -80,6 +80,18 @@ class MaintainableDBConnRef extends DBConnRef implements IMaintainableDatabase {
        public function unlockTables( $method ) {
                return $this->__call( __FUNCTION__, func_get_args() );
        }
+
+       public function indexUnique( $table, $index ) {
+               return $this->__call( __FUNCTION__, func_get_args() );
+       }
+
+       public function listTables( $prefix = null, $fname = __METHOD__ ) {
+               return $this->__call( __FUNCTION__, func_get_args() );
+       }
+
+       public function fieldInfo( $table, $field ) {
+               return $this->__call( __FUNCTION__, func_get_args() );
+       }
 }
 
 class_alias( MaintainableDBConnRef::class, 'MaintainableDBConnRef' );
index fb2603f..faa81f9 100644 (file)
        "right-patrol": "Пазначэньне рэдагаваньняў як «патруляваных»",
        "right-autopatrol": "Аўтаматычнае пазначэньне рэдагаваньняў як «патруляваных»",
        "right-patrolmarks": "Прагляд пазначэньняў пра патруляваньне ў апошніх зьменах",
-       "right-unwatchedpages": "прагляд сьпісу старонак, за якімі ніхто не назірае",
+       "right-unwatchedpages": "Ð\9fрагляд сьпісу старонак, за якімі ніхто не назірае",
        "right-mergehistory": "аб’яднаньне гісторыі старонак",
        "right-userrights": "рэдагаваньне правоў усіх удзельнікаў",
        "right-userrights-interwiki": "рэдагаваньне правоў удзельнікаў у іншых вікі",
index fcc2bdd..64cc98e 100644 (file)
        "databaseerror-query": "অনুসন্ধান: $1",
        "databaseerror-function": "ফাংশন: $1",
        "databaseerror-error": "ত্রুটি: $1",
-       "transaction-duration-limit-exceeded": "দীর্ঘ পুনঃসৃষ্টি বিলম্ব এড়ানোর জন্য এই ট্রানজাকশনটি বাতিল করা হল, কারণ লিখনের স্থায়িত্ব ($1) $2 সেকেন্ড সীমাটিকে অতিক্রম করে গিয়েছিল। \nযদি আপনি অনেকগুলি আইটেম একসাথে পরিবর্তন করতে চান, তাহলে একাধিক ক্ষুদ্রতর অপারেশন সম্পন্ন করার চেষ্টা করুন।",
+       "transaction-duration-limit-exceeded": "দীর্ঘ পুনঃসৃষ্টি বিলম্ব এড়ানোর জন্য, এই কার্যটি বাতিল করা হল কারণ তা লিখনের স্থায়িত্ব ($1) $2 সেকেন্ড সীমাটিকে অতিক্রম করে গিয়েছিল। \nযদি আপনি অনেকগুলি আইটেম একসাথে পরিবর্তন করছিলেন, তাহলে একাধিক ক্ষুদ্রতর অপারেশন সম্পন্ন করার চেষ্টা করুন।",
        "laggedslavemode": "<strong>সতর্ক বার্তা:</strong> পাতাটি সম্ভবত সম্প্রতি হালনাগাদ করা হয়নি।",
        "readonly": "ডাটাবেজ অবরুদ্ধ",
        "enterlockreason": "অবরুদ্ধ করার কারণ কী তা বলুন, সাথে কখন অবরোধ খুলবেন তার আনুমানিক সময় উল্লেখ করুন",
index c01afb9..48caaa1 100644 (file)
        "rcfilters-group-results-by-page": "חלוקה התוצאות לקבוצות לפי דף",
        "rcfilters-activefilters": "מסננים פעילים",
        "rcfilters-advancedfilters": "מסננים מתקדמים",
-       "rcfilters-limit-title": "×\90×\99×\9c×\95 תוצאות להראות",
+       "rcfilters-limit-title": "×\9b×\9e×\94 תוצאות להראות",
        "rcfilters-limit-and-date-label": "{{PLURAL:$1|שינוי אחד|$1 שינויים}}, $2",
        "rcfilters-date-popup-title": "משך הזמן לחיפוש",
        "rcfilters-days-title": "ימים אחרונים",
        "tooltip-n-recentchanges": "רשימת השינויים האחרונים באתר",
        "tooltip-n-randompage": "טעינת דף אקראי",
        "tooltip-n-help": "המקום למצוא מידע",
-       "tooltip-t-whatlinkshere": "רש×\99×\9e×\94 ×©×\9c ×\9b×\9c ×\93פ×\99 ×\94×\95×\95×\99ק×\99 ×©×\9eקשר×\99×\9d ×\94× ה",
+       "tooltip-t-whatlinkshere": "רש×\99×\9e×\94 ×©×\9c ×\9b×\9c ×\93פ×\99 ×\94×\95×\95×\99ק×\99 ×©×\9eקשר×\99×\9d ×\9c×\93×£ ×\94×\96ה",
        "tooltip-t-recentchangeslinked": "השינויים האחרונים שבוצעו בדפים המקושרים מדף זה",
        "tooltip-feed-rss": "הזנת RSS עבור דף זה",
        "tooltip-feed-atom": "הזנת Atom עבור דף זה",
index 2205dff..dba9532 100644 (file)
        "statistics-files": "Adkargita arkivi",
        "statistics-edits": "Quanto di redakti pos ke {{SITENAME}} kreesis",
        "statistics-edits-average": "Mezavalora quanto di redakti per pagino",
+       "statistics-users": "Enrejistrita [[Special:ListUsers|uzeri]]",
        "statistics-users-active": "Aktiva uzeri",
        "statistics-users-active-desc": "Uzeri qui facis ula agado dum la lasta {{PLURAL:$1|dio|$1 dii}}",
        "pageswithprop": "Pagini kun atributo di pagino",
        "booksources": "Fonti di libri",
        "booksources-search-legend": "Serchez librala fonti",
        "booksources-search": "Serchar",
+       "booksources-text": "Infre vu povas vidar listo di ligili ad altra retsitui qui vendas nova ed uzata libri, ed anke povas havar informi pri la libri quin vu serchabas:\nLa {{SITENAME}} ne mantenas komercala relati kun ta vendeyi mencionata, e la listo ne povas konsideresar rekomendo o vend-anunco.",
        "magiclink-tracking-isbn": "Pagini qui uzas ligili ISBN",
        "specialloguserlabel": "Agero:",
        "speciallogtitlelabel": "Skopo (titulo od {{ns:user}}:uzernomo por uzero):",
index c2737a7..b8bf3ee 100644 (file)
        "newimages-summary": "Op dees speciaal pazjena waere de meis recènt toegevoogde bestenj weergegaeve.",
        "newimages-legend": "Bestandjsnaam",
        "newimages-label": "Bestandjsnaam (of deel daarvan):",
+       "newimages-user": "IP-adres of gebroekersnaam",
+       "newimages-newbies": "Tuin allein de biedrage van nuuj gebroekers",
+       "newimages-showbots": "Tuin botuploads",
+       "newimages-hidepatrolled": "Versjtaek gecontroleerde uploads",
+       "newimages-mediatype": "Mediaformaot:",
        "noimages": "Niks te zeen.",
+       "gallery-slideshow-toggle": "Sjakel miniature",
        "ilsubmit": "Zeuk",
        "bydate": "op datum",
        "sp-newimages-showfrom": "Tuin nuuj besjtande vanaaf $2, $1",
        "confirmemail_body_set": "Emes, waersjienlik doe, met 't IP-adres $1,\nhaet 't e-mailadres geregistreerd veur gebroeker \"$2\" op {{SITENAME}} ingesteld óp dit e-mailadres.\n\nÄöpen de volgende verwiezing in diene webbrowser om te bevestige des toe deze gebroeker bis en om de e-mailmeugelikhejen op {{SITENAME}} opnuuj te activere:\n\n$3\n\nEs se dichzelf *neet* haes aangemeld, volg den de volgende verwiezing om de bevestiging van dien e-mailadres te annulere:\n\n$5\n\nDe bevestigingscode vervilt op $4.",
        "confirmemail_invalidated": "De e-mailbevestiging is geannuleerdj",
        "invalidateemail": "E-mailbevestiging annulere",
+       "notificationemail_subject_changed": "geregistreerd e-mailadres van {{SITENAME}} is verangerd",
+       "notificationemail_subject_removed": "geregistreerd e-mailadres van {{SITENAME}} is eweggehaold",
        "scarytranscludedisabled": "[Interwikitransclusie is oetgesjakeld]",
        "scarytranscludefailed": "[Sjabloon $1 kós neet opgehaold waer]",
        "scarytranscludetoolong": "[URL is te lank]",
        "version-ext-colheader-description": "Besjrieving",
        "version-ext-colheader-credits": "Sjrievers",
        "version-license-title": "Licentie veur $1",
+       "version-credits-title": "Vermeljinge veur $1",
+       "version-credits-not-found": "Gein gedetailleerde meljinge zint aangetroffe veur dees oetbreijing.",
        "version-poweredby-credits": "Deze wiki weurt aangedreve door '''[https://www.mediawiki.org/ MediaWiki]''', copyright © 2001-$1 $2.",
        "version-poweredby-others": "anger",
+       "version-poweredby-translators": "translatewiki.net-euverzètters",
        "version-license-info": "MediaWiki is vrieje sofware; de kins MediaWiki verspreien en/of aanpassen onger de veurwaerde van de GNU General Public License wie gepubliceerd door de Free Software Foundation; ofwaal versie 2 van de Licentie, of - nao diene wönsj - innig later versie.\n\nMediaWiki weurd verspreid in de haop det 't nuttig is, mer ZONGER INNIG GARANTIE; zonger zelfs de implicitiete garantie van VERKOUPBAARHEID of GESJIKHEID VEUR INNIG DOEL IN 'T BIEZÖNJER. Zuuch de GNU General Public License veur mier informatie.\n\nSame mit dit programma heurs se 'n [{{SERVER}}{{SCRIPTPATH}}/COPYING kopie van de GNU General Public License] te höbben ontvange; zo neet, sjrief den nao de Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA of [//www.gnu.org/licenses/old-licenses/gpl-2.0.html laes de licentie online].",
        "version-software": "Geïnstallieërde sofwaer",
        "version-software-product": "Perduk",
        "tags-active-no": "Nae",
        "tags-edit": "bewerking",
        "tags-hitcount": "$1 {{PLURAL:$1|wieziging|wieziginge}}",
+       "tags-deactivate-reason": "Raeje:",
+       "tags-deactivate-submit": "Deaktiveer",
        "comparepages": "Vergeliek pazjena's",
        "compare-page1": "Paasj 1",
        "compare-page2": "Paasj 2",
index c5ea2c0..59f6584 100644 (file)
        "apisandbox-sending-request": "Wysyłanie zapytania API…",
        "apisandbox-loading-results": "Pobieranie wyników API...",
        "apisandbox-results-error": "Wystąpił błąd podczas pobierania odpowiedzi na zapytanie API: $1.",
+       "apisandbox-results-login-suppressed": "To żądanie zostało przetworzone jako wylogowany użytkownik, ponieważ można go obejść w zabezpieczeniach przeglądarki Same-Origin. Zauważ, że automatyczna obsługa tokenów API piaskownicy nie działa poprawnie z takimi żądaniami, proszę wypełnić je ręcznie.",
        "apisandbox-request-selectformat-label": "Pokaż dane z zapytania jako:",
        "apisandbox-request-format-url-label": "zapytanie w adresie URL",
        "apisandbox-request-url-label": "URL zapytania:",
        "ip_range_invalid": "Niepoprawny zakres adresów IP.",
        "ip_range_toolarge": "Zakresy IP większe niż /$1 są niedozwolone.",
        "ip_range_exceeded": "Zakres IP przekracza zakres maksymalny. Dozwolony zakres to /$1.",
+       "ip_range_toolow": "Zakresy adresów IP są niedozwolone.",
        "proxyblocker": "Blokowanie proxy",
        "proxyblockreason": "Twój adres IP został zablokowany, ponieważ jest to adres otwartego proxy.\nO tym poważnym problemie dotyczącym bezpieczeństwa należy poinformować dostawcę Internetu lub pomoc techniczną.",
        "sorbsreason": "Twój adres IP znajduje się na liście serwerów open proxy w DNSBL, używanej przez {{GRAMMAR:B.lp|{{SITENAME}}}}.",
        "authmanager-create-disabled": "Utworzenie konta jest wyłączone.",
        "authmanager-create-from-login": "Aby utworzyć konto, wypełnij odpowiednie pola.",
        "authmanager-create-not-in-progress": "Tworzenie konta nie jest wykonywane lub dane sesji zostały utracone. Zacznij od początku.",
+       "authmanager-create-no-primary": "Podanych danych uwierzytelniających nie można użyć do utworzenia konta.",
        "authmanager-link-not-in-progress": "Tworzenie konta nie jest wykonywane lub dane sesji zostały utracone. Zacznij od początku.",
        "authmanager-authplugin-setpass-failed-title": "Zmiana hasła nie powiodła się",
        "authmanager-authplugin-setpass-failed-message": "Wtyczka do uwierzytelniania uniemożliwiła zmianę hasła.",
        "undelete-cantedit": "Nie możesz odtworzyć tej strony, ponieważ nie masz uprawnień do edytowania tej strony.",
        "undelete-cantcreate": "Nie możesz odtworzyć tej strony, ponieważ nie istnieje strona o tej nazwie, a nie masz uprawnień do jej utworzenia.",
        "pagedata-title": "Dane ze strony",
+       "pagedata-text": "Ta strona udostępnia interfejs danych do stron. Podaj tytuł strony w adresie URL, używając składni podstrony.\n* Negocjacja treści obowiązuje w oparciu o nagłówek Accept Twojego klienta. Oznacza to, że dane strony będą dostarczane w formacie preferowanym przez klienta.",
        "pagedata-not-acceptable": "Nie znaleziono pasującego formatu. Obsługiwane typy MIME: $1",
        "pagedata-bad-title": "Niepoprawny tytuł: $1."
 }
index 617f17c..ebb080d 100644 (file)
        "wrongpasswordempty": "A palavra-passe não foi introduzida. \nIntroduza-a, por favor.",
        "passwordtooshort": "A palavra-passe deve ter no mínimo $1 {{PLURAL:$1|carácter|caracteres}}.",
        "passwordtoolong": "A palavra-passe não pode exceder $1 {{PLURAL:$1|carácter|caracteres}}.",
-       "passwordtoopopular": "Não podem ser usadas palavras-passe vulgares. Escolha uma palavra-passe mais original, por favor.",
+       "passwordtoopopular": "Não podem ser usadas palavras-passe vulgares. Escolha uma palavra-passe mais difícil de adivinhar, por favor.",
        "password-name-match": "A sua palavra-passe tem de ser diferente do seu nome de utilizador.",
        "password-login-forbidden": "Foi proibido o uso deste nome de utilizador e palavra-passe.",
        "mailmypassword": "Reiniciar a palavra-passe",
        "watchlistedit-normal-done": "{{PLURAL:$1|Foi removida uma página|Foram removidas $1 páginas}} da sua lista de páginas vigiadas:",
        "watchlistedit-raw-title": "Editar a lista de páginas vigiadas em forma de texto",
        "watchlistedit-raw-legend": "Editar a lista de páginas vigiadas em forma de texto",
-       "watchlistedit-raw-explain": "A lista de páginas vigiadas é apresentada abaixo.\nPode adicionar ou remover linhas, para aumentar ou reduzir a lista.\nListe uma só página por linha.\nQuando terminar, clique \"{{int:Watchlistedit-raw-submit}}\".\nTambém pode [[Special:EditWatchlist|editar a lista da maneira convencional]].",
+       "watchlistedit-raw-explain": "A lista das páginas vigiadas é apresentada abaixo.\nPode adicionar ou remover linhas, para aumentar ou reduzir a lista.\nListe uma só página por linha.\nQuando terminar, clique \"{{int:Watchlistedit-raw-submit}}\".\nTambém pode [[Special:EditWatchlist|usar o editor padrão]].",
        "watchlistedit-raw-titles": "Páginas:",
        "watchlistedit-raw-submit": "Atualizar a lista de páginas vigiadas",
        "watchlistedit-raw-done": "A sua lista de páginas vigiadas foi atualizada.",
index aace214..ae77870 100644 (file)
        "activeusers-intro": "นี่คือรายการผู้ใช้ที่มีความเคลื่อนไหวใด ๆ ในช่วง $1 วันหลังสุด",
        "activeusers-count": "$1 ปฏิบัติการ{{PLURAL:$1|}} ในช่วง $3 วันหลังสุด",
        "activeusers-from": "แสดงผู้ใช้เริ่มจาก:",
+       "activeusers-groups": "แสดงผู้ใช้ที่อยู่ในกลุ่ม:",
+       "activeusers-excludegroups": "ไม่รวมผู้ใช้ที่อยู่ในกลุ่ม:",
        "activeusers-noresult": "ไม่พบผู้ใช้",
        "activeusers-submit": "แสดงผู้ใช้ที่ยังเคลื่อนไหว",
        "listgrouprights": "สิทธิกลุ่มผู้ใช้",
        "rollback-success": "ย้อนการแก้ไขโดย $1; \nเปลี่ยนกลับไปรุ่นล่าสุดโดย $2",
        "rollback-success-notify": "ย้อนการแก้ไขโดย $1;\nเปลี่ยนกลับไปรุ่นล่าสุดโดย $2 [$3 แสดงการเปลี่ยนแปลง]",
        "sessionfailure-title": "ช่วงเวลาสื่อสารล้มเหลว",
-       "sessionfailure": "à¸\94ูà¹\80หมือà¸\99มีà¸\9bัà¸\8dหาà¸\81ัà¸\9aà¸\8aà¹\88วà¸\87à¹\80วลาสืà¹\88อสารลà¹\87อà¸\81อิà¸\99à¸\82อà¸\87à¸\84ุà¸\93\nà¸\81ารà¸\81ระà¸\97ำà¸\99ีà¹\89à¸\96ูà¸\81ยà¸\81à¹\80ลิà¸\81à¹\80à¸\9bà¹\87à¸\99à¸\81ารà¸\9bà¹\89อà¸\87à¸\81ัà¸\99à¸\81ารลัà¸\81ลอà¸\9aà¸\8aà¹\88วà¸\87à¹\80วลาสืà¹\88อสารà¹\84วà¹\89à¸\81à¹\88อà¸\99 \nà¸\81ลัà¸\9aà¹\84à¸\9bหà¸\99à¹\89าà¸\97ีà¹\88à¹\81ลà¹\89ว à¹\82หลà¸\94หà¸\99à¹\89าà¹\83หมà¹\88 à¹\81ลà¹\89วลอà¸\87อีกครั้ง",
+       "sessionfailure": "à¸\94ูà¹\80หมือà¸\99มีà¸\9bัà¸\8dหาà¸\81ัà¸\9aà¸\8aà¹\88วà¸\87à¹\80วลาสืà¹\88อสารลà¹\87อà¸\81อิà¸\99à¸\82อà¸\87à¸\84ุà¸\93\nà¸\81ารà¸\81ระà¸\97ำà¸\99ีà¹\89à¸\96ูà¸\81ยà¸\81à¹\80ลิà¸\81à¹\80à¸\9bà¹\87à¸\99à¸\81ารà¸\9bà¹\89อà¸\87à¸\81ัà¸\99à¸\81ารลัà¸\81ลอà¸\9aà¸\8aà¹\88วà¸\87à¹\80วลาสืà¹\88อสารà¹\84วà¹\89à¸\81à¹\88อà¸\99 \nà¸\81รุà¸\93าà¸\81รอà¸\81à¹\81à¸\9aà¸\9aอีกครั้ง",
        "changecontentmodel-title-label": "ชื่อหน้า:",
        "changecontentmodel-reason-label": "เหตุผล:",
        "changecontentmodel-submit": "ความเปลี่ยนแปลง",
        "tooltip-namespace_association": "เลือกกล่องนี้เพื่อรวมเนมสเปซคุยหรือเรื่องที่เกี่ยวข้องกับเนมสเปซที่เลือกด้วย",
        "blanknamespace": "(หลัก)",
        "contributions": "เรื่องที่{{GENDER:$1|ผู้ใช้}}นี้เขียน",
-       "contributions-title": "à¹\80รืà¹\88อà¸\87à¸\97ีà¹\88à¹\80à¸\82ียà¸\99โดย $1",
+       "contributions-title": "à¹\80รืà¹\88อà¸\87à¸\97ีà¹\88มีสà¹\88วà¸\99รà¹\88วมโดย $1",
        "mycontris": "เรื่องที่มีส่วนร่วม",
-       "anoncontribs": "à¹\80รืà¹\88อà¸\87à¸\97ีà¹\88à¹\80à¸\82ียà¸\99",
+       "anoncontribs": "à¹\80รืà¹\88อà¸\87à¸\97ีà¹\88มีสà¹\88วà¸\99รà¹\88วม",
        "contribsub2": "สำหรับ {{GENDER:$3|$1}} ($2)",
        "contributions-userdoesnotexist": "บัญชีผู้ใช้ \"$1\" ยังไม่ได้ลงทะเบียน",
        "nocontribs": "ไม่พบการเปลี่ยนแปลงตรงกับเงื่อนไขเหล่านี้",
        "sp-contributions-newbies-sub": "สำหรับบัญชีใหม่",
        "sp-contributions-newbies-title": "การเข้ามีส่วนร่วมสำหรับบัญชีใหม่",
        "sp-contributions-blocklog": "ปูมการบล็อก",
-       "sp-contributions-suppresslog": "ระà¸\87ัà¸\9aà¸\81ารà¹\80à¸\82à¹\89ามีสà¹\88วà¸\99รà¹\88วมà¸\82อà¸\87à¸\9cูà¹\89à¹\83à¸\8aà¹\89",
-       "sp-contributions-deleted": "à¸\81ารà¹\81à¸\81à¹\89à¹\84à¸\82ของผู้ใช้ที่ถูกลบ",
+       "sp-contributions-suppresslog": "ระงับการมีส่วนร่วมของผู้ใช้",
+       "sp-contributions-deleted": "à¸\81ารมà¹\88ีสà¹\88วà¸\99รà¹\88วมของผู้ใช้ที่ถูกลบ",
        "sp-contributions-uploads": "อัปโหลด",
        "sp-contributions-logs": "ปูม",
        "sp-contributions-talk": "คุย",
        "ipb-unblock-addr": "ปลดบล็อก $1",
        "ipb-unblock": "ปลดบล็อกผู้ใช้หรือเลขที่อยู่ไอพี",
        "ipb-blocklist": "ดูการบล็อกที่มีอยู่",
-       "ipb-blocklist-contribs": "à¹\80รืà¹\88อà¸\87à¸\97ีà¹\88à¹\80à¸\82ียà¸\99โดย $1",
+       "ipb-blocklist-contribs": "à¹\80รืà¹\88อà¸\87à¸\97ีà¹\88มีสà¹\88วà¸\99รà¹\88วมโดย $1",
        "ipb-blocklist-duration-left": "เหลือเวลา $1",
        "unblockip": "ปลดบล็อกผู้ใช้",
        "unblockiptext": "ใช้แบบด้านล่างเพื่อคืนการเข้าถึงการเขียนแก่เลขที่อยู่ไอพี หรือชื่อผู้ใช้ที่เคยถูกบล็อก",
        "svg-long-error": "ไฟล์ SVG ไม่ถูกต้อง: $1",
        "show-big-image": "ไฟล์ต้นฉบับ",
        "show-big-image-preview": "ขนาดของตัวอย่างนี้: $1",
-       "show-big-image-preview-differ": "ขนาดขงตัวอย่าง $3 นี้ของไฟล์ $2 นี้: $1",
+       "show-big-image-preview-differ": "à¸\82à¸\99าà¸\94à¸\82อà¸\87à¸\95ัวอยà¹\88าà¸\87 $3 à¸\99ีà¹\89à¸\82อà¸\87à¹\84à¸\9fลà¹\8c $2 à¸\99ีà¹\89: $1",
        "show-big-image-other": "{{PLURAL:$2|ความละเอียด|ความละเอียด}}อื่น: $1",
        "show-big-image-size": "$1 × $2 พิกเซล",
        "file-info-gif-looped": "วนซ้ำ",
        "watchlistedit-clear-titles": "ชื่อเรื่อง:",
        "watchlistedit-clear-submit": "ล้างรายการเฝ้าดู (เป็นการถาวร!)",
        "watchlistedit-clear-done": "ล้างรายการเฝ้าดูของคุณแล้ว",
+       "watchlistedit-clear-jobqueue": "กำลังล้างรายการเฝ้าดูของคุณ อาจใช้เวลาสักหน่อย!",
        "watchlistedit-clear-removed": "ลบ $1 ชื่อเรื่อง:",
        "watchlistedit-too-many": "มีหน้าแสดงที่นี่มากเกิน",
        "watchlisttools-clear": "ล้างรายการเฝ้าดู",
        "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|คุย]])",
        "timezone-local": "ท้องถิ่น",
        "duplicate-defaultsort": "<strong>คำเตือน:</strong> หลักเรียงลำดับปริยาย \"$2\" ได้ลบล้างหลักเรียงลำดับปริยาย \"$1\" ที่มีอยู่ก่อนหน้า",
+       "duplicate-displaytitle": "<strong>คำเตือน:</strong> แสดงชื่อเรื่อง \"$2\" เขียนทับการแสดงชื่อเรื่องก่อนหน้านี้ \"$1\"",
+       "restricted-displaytitle": "<strong>คำเตือน:</strong> ละเลยชื่อเรื่องหน้า \"$1\" เพราะไม่เท่ากับชื่อเรื่องแท้จริงของหน้า",
        "version": "รุ่น",
        "version-extensions": "ส่วนขยายเพิ่ม (extension) ที่ติดตั้ง",
        "version-skins": "หน้าตาที่ติดตั้ง",
        "specialpages-group-maintenance": "รายงานการบำรุงรักษา",
        "specialpages-group-other": "หน้าพิเศษอื่น ๆ",
        "specialpages-group-login": "ล็อกอิน / สร้างบัญชี",
-       "specialpages-group-changes": "à¸\9bรัà¸\9aà¸\9bรุงล่าสุดและปูม",
+       "specialpages-group-changes": "à¹\80à¸\9bลีà¹\88ยà¸\99à¹\81à¸\9bลงล่าสุดและปูม",
        "specialpages-group-media": "รายงานสื่อและการอัปโหลด",
        "specialpages-group-users": "ผู้ใช้และสิทธิ",
        "specialpages-group-highuse": "หน้าที่มีการใช้สูง",
        "authmanager-provider-password": "การพิสูจน์ตัวจริงที่อาศัยรหัสผ่าน",
        "authmanager-provider-password-domain": "การพิสูจน์ตัวจริงที่อาศัยรหัสผ่านและโดเมน",
        "authmanager-provider-temporarypassword": "รหัสผ่านชั่วคราว",
+       "credentialsform-account": "ชื่อบัญชี:",
+       "cannotlink-no-provider-title": "ไม่มีบัญชีที่โยงได้",
+       "cannotlink-no-provider": "ไม่มีบัญชีที่โยงได้",
+       "linkaccounts": "โยงบัญชี",
+       "linkaccounts-success-text": "โยงบัญชีแล้ว",
+       "linkaccounts-submit": "โยงบัญชี",
+       "unlinkaccounts": "เลิกโยงบัญชี",
+       "unlinkaccounts-success": "เลิกโยงบัญชีแล้ว",
        "edit-error-short": "ข้อผิดพลาด: $1",
        "edit-error-long": "ข้อผิดพลาด: $1",
        "revid": "รุ่นแก้ไข $1",
index 1c79d52..bbfd528 100644 (file)
        width: 100%;
        border: 1px solid @colorFieldBorder;
        border-radius: @borderRadius;
-       padding: 0.625em 0.625em 0.546875em;
+       padding: 0.57142857em 0.57142857em 0.5em;
        // necessary for smooth transition
        box-shadow: inset 0 0 0 0.1em #fff;
        font-family: inherit;
        font-size: inherit;
-       line-height: 1.172em;
+       line-height: 1.07142857em;
        vertical-align: middle;
 
        // Normalize & style placeholder text, see T139034
index badba96..981c407 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 
+use Wikimedia\Rdbms\IDatabase;
 use Wikimedia\Rdbms\LikeMatch;
 use Wikimedia\Rdbms\Database;
 
@@ -1366,7 +1367,7 @@ class DatabaseSQLTest extends PHPUnit\Framework\TestCase {
                $this->database->endAtomic( __METHOD__ );
                $this->assertLastSql( 'BEGIN; COMMIT' );
 
-               $this->database->startAtomic( __METHOD__ );
+               $this->database->startAtomic( __METHOD__, IDatabase::ATOMIC_CANCELABLE );
                $this->database->cancelAtomic( __METHOD__ );
                $this->assertLastSql( 'BEGIN; ROLLBACK' );
 
@@ -1374,18 +1375,24 @@ class DatabaseSQLTest extends PHPUnit\Framework\TestCase {
                $this->database->startAtomic( __METHOD__ );
                $this->database->endAtomic( __METHOD__ );
                $this->database->commit( __METHOD__ );
+               $this->assertLastSql( 'BEGIN; COMMIT' );
+
+               $this->database->begin( __METHOD__ );
+               $this->database->startAtomic( __METHOD__, IDatabase::ATOMIC_CANCELABLE );
+               $this->database->endAtomic( __METHOD__ );
+               $this->database->commit( __METHOD__ );
                // phpcs:ignore Generic.Files.LineLength
                $this->assertLastSql( 'BEGIN; SAVEPOINT wikimedia_rdbms_atomic1; RELEASE SAVEPOINT wikimedia_rdbms_atomic1; COMMIT' );
 
                $this->database->begin( __METHOD__ );
-               $this->database->startAtomic( __METHOD__ );
+               $this->database->startAtomic( __METHOD__, IDatabase::ATOMIC_CANCELABLE );
                $this->database->cancelAtomic( __METHOD__ );
                $this->database->commit( __METHOD__ );
                // phpcs:ignore Generic.Files.LineLength
                $this->assertLastSql( 'BEGIN; SAVEPOINT wikimedia_rdbms_atomic1; ROLLBACK TO SAVEPOINT wikimedia_rdbms_atomic1; COMMIT' );
 
-               $this->database->startAtomic( __METHOD__ );
-               $this->database->startAtomic( __METHOD__ );
+               $this->database->startAtomic( __METHOD__, IDatabase::ATOMIC_CANCELABLE );
+               $this->database->startAtomic( __METHOD__, IDatabase::ATOMIC_CANCELABLE );
                $this->database->cancelAtomic( __METHOD__ );
                $this->database->endAtomic( __METHOD__ );
                // phpcs:ignore Generic.Files.LineLength
@@ -1458,4 +1465,20 @@ class DatabaseSQLTest extends PHPUnit\Framework\TestCase {
                }
        }
 
+       /**
+        * @covers \Wikimedia\Rdbms\Database::cancelAtomic
+        */
+       public function testUncancellableAtomicSection() {
+               $this->database->startAtomic( __METHOD__ );
+               try {
+                       $this->database->cancelAtomic( __METHOD__ );
+                       $this->fail( 'Expected exception not thrown' );
+               } catch ( DBUnexpectedError $ex ) {
+                       $this->assertSame(
+                               'Uncancelable atomic section canceled (got ' . __METHOD__ . ').',
+                               $ex->getMessage()
+                       );
+               }
+       }
+
 }