* ProfilerOutputUdp was removed. Note that there is a ProfilerOutputStats class.
* WikiPage::doDeleteArticleReal() and WikiPage::doDeleteArticle() now
ignore the 2nd and 3rd arguments (formerly $id and $commit).
+* Removed "loaderScripts" option from ResourceLoaderFileModule class.
+* Removed ORM-like wrapper added in 1.20.
== Compatibility ==
'IDatabase' => __DIR__ . '/includes/db/IDatabase.php',
'IEContentAnalyzer' => __DIR__ . '/includes/libs/IEContentAnalyzer.php',
'IEUrlExtension' => __DIR__ . '/includes/libs/IEUrlExtension.php',
+ 'IExpiringStore' => __DIR__ . '/includes/libs/objectcache/IExpiringStore.php',
'IJobSpecification' => __DIR__ . '/includes/jobqueue/JobSpecification.php',
- 'IORMRow' => __DIR__ . '/includes/db/IORMRow.php',
- 'IORMTable' => __DIR__ . '/includes/db/IORMTable.php',
'IP' => __DIR__ . '/includes/utils/IP.php',
'IPSet' => __DIR__ . '/includes/compat/IPSetCompat.php',
'IPTC' => __DIR__ . '/includes/media/IPTC.php',
'OOUIHTMLForm' => __DIR__ . '/includes/htmlform/OOUIHTMLForm.php',
'ORAField' => __DIR__ . '/includes/db/DatabaseOracle.php',
'ORAResult' => __DIR__ . '/includes/db/DatabaseOracle.php',
- 'ORMIterator' => __DIR__ . '/includes/db/ORMIterator.php',
- 'ORMResult' => __DIR__ . '/includes/db/ORMResult.php',
- 'ORMRow' => __DIR__ . '/includes/db/ORMRow.php',
- 'ORMTable' => __DIR__ . '/includes/db/ORMTable.php',
'ObjectCache' => __DIR__ . '/includes/objectcache/ObjectCache.php',
'ObjectCacheSessionHandler' => __DIR__ . '/includes/objectcache/ObjectCacheSessionHandler.php',
'ObjectFactory' => __DIR__ . '/includes/libs/ObjectFactory.php',
"php": ">=5.3.3",
"psr/log": "1.0.0",
"wikimedia/assert": "0.2.2",
+ "wikimedia/base-convert": "1.0.1",
"wikimedia/cdb": "1.3.0",
"wikimedia/cldr-plural-rule-parser": "1.0.0",
"wikimedia/composer-merge-plugin": "1.2.1",
"wikimedia/ip-set": "1.0.1",
"wikimedia/relpath": "1.0.3",
- "wikimedia/running-stat": "1.0.0",
+ "wikimedia/running-stat": "1.1.0",
"wikimedia/utfnormal": "1.0.3",
"wikimedia/wrappedstring": "2.0.0",
"zordius/lightncandy": "0.21"
"jakub-onderka/php-parallel-lint": "0.9",
"justinrainbow/json-schema": "~1.3",
"mediawiki/mediawiki-codesniffer": "0.4.0",
- "monolog/monolog": "1.14.0",
+ "monolog/monolog": "~1.17.2",
"nmred/kafka-php": "0.1.4",
"phpunit/phpunit": "3.7.37",
"wikimedia/avro": "1.7.7"
public static function isWhitelistedFromAutoblocks( $ip ) {
// Try to get the autoblock_whitelist from the cache, as it's faster
// than getting the msg raw and explode()'ing it.
-
- $lines = ObjectCache::getMainWANInstance()->getWithSetCallback(
+ $cache = ObjectCache::getMainWANInstance();
+ $lines = $cache->getWithSetCallback(
wfMemcKey( 'ipb', 'autoblock', 'whitelist' ),
- 86400,
+ $cache::TTL_DAY,
function () {
return explode( "\n",
wfMessage( 'autoblock_whitelist' )->inContentLanguage()->plain() );
array( 'LOCK IN SHARE MODE' )
);
- if ( $this->mId ) {
+ if ( $this->mID ) {
# The category row already exists, so do a plain UPDATE instead
# of INSERT...ON DUPLICATE KEY UPDATE to avoid creating a gap
# in the cat_id sequence. The row may or may not be "affected".
// Save to cache
$this->firstLetterData = $data;
- $cache->set( $cacheKey, $data, 86400 * 7 /* 1 week */ );
+ $cache->set( $cacheKey, $data, $cache::TTL_WEEK );
return $data;
}
/** @} */ # End of output format settings }
/*************************************************************************//**
- * @name Resource loader settings
+ * @name ResourceLoader settings
* @{
*/
/**
* Client-side resource modules.
*
- * Extensions should add their resource loader module definitions
+ * Extensions should add their ResourceLoader module definitions
* to the $wgResourceModules variable.
*
* @par Example:
$wgResourceBasePath = null;
/**
- * Maximum time in seconds to cache resources served by the resource loader.
+ * Maximum time in seconds to cache resources served by ResourceLoader.
* Used to set last modified headers (max-age/s-maxage).
*
* Following options to distinguish:
*/
$wgAllowSiteCSSOnRestrictedPages = false;
-/** @} */ # End of resource loader settings }
+/** @} */ # End of ResourceLoader settings }
/*************************************************************************//**
* @name Page title and interwiki link settings
function wfBaseConvert( $input, $sourceBase, $destBase, $pad = 1,
$lowercase = true, $engine = 'auto'
) {
- $input = (string)$input;
- if (
- $sourceBase < 2 ||
- $sourceBase > 36 ||
- $destBase < 2 ||
- $destBase > 36 ||
- $sourceBase != (int)$sourceBase ||
- $destBase != (int)$destBase ||
- $pad != (int)$pad ||
- !preg_match(
- "/^[" . substr( '0123456789abcdefghijklmnopqrstuvwxyz', 0, $sourceBase ) . "]+$/i",
- $input
- )
- ) {
- return false;
- }
-
- static $baseChars = array(
- 10 => 'a', 11 => 'b', 12 => 'c', 13 => 'd', 14 => 'e', 15 => 'f',
- 16 => 'g', 17 => 'h', 18 => 'i', 19 => 'j', 20 => 'k', 21 => 'l',
- 22 => 'm', 23 => 'n', 24 => 'o', 25 => 'p', 26 => 'q', 27 => 'r',
- 28 => 's', 29 => 't', 30 => 'u', 31 => 'v', 32 => 'w', 33 => 'x',
- 34 => 'y', 35 => 'z',
-
- '0' => 0, '1' => 1, '2' => 2, '3' => 3, '4' => 4, '5' => 5,
- '6' => 6, '7' => 7, '8' => 8, '9' => 9, 'a' => 10, 'b' => 11,
- 'c' => 12, 'd' => 13, 'e' => 14, 'f' => 15, 'g' => 16, 'h' => 17,
- 'i' => 18, 'j' => 19, 'k' => 20, 'l' => 21, 'm' => 22, 'n' => 23,
- 'o' => 24, 'p' => 25, 'q' => 26, 'r' => 27, 's' => 28, 't' => 29,
- 'u' => 30, 'v' => 31, 'w' => 32, 'x' => 33, 'y' => 34, 'z' => 35
- );
-
- if ( extension_loaded( 'gmp' ) && ( $engine == 'auto' || $engine == 'gmp' ) ) {
- // Removing leading zeros works around broken base detection code in
- // some PHP versions (see <https://bugs.php.net/bug.php?id=50175> and
- // <https://bugs.php.net/bug.php?id=55398>).
- $result = gmp_strval( gmp_init( ltrim( $input, '0' ) ?: '0', $sourceBase ), $destBase );
- } elseif ( extension_loaded( 'bcmath' ) && ( $engine == 'auto' || $engine == 'bcmath' ) ) {
- $decimal = '0';
- foreach ( str_split( strtolower( $input ) ) as $char ) {
- $decimal = bcmul( $decimal, $sourceBase );
- $decimal = bcadd( $decimal, $baseChars[$char] );
- }
-
- // @codingStandardsIgnoreStart Generic.CodeAnalysis.ForLoopWithTestFunctionCall.NotAllowed
- for ( $result = ''; bccomp( $decimal, 0 ); $decimal = bcdiv( $decimal, $destBase, 0 ) ) {
- $result .= $baseChars[bcmod( $decimal, $destBase )];
- }
- // @codingStandardsIgnoreEnd
-
- $result = strrev( $result );
- } else {
- $inDigits = array();
- foreach ( str_split( strtolower( $input ) ) as $char ) {
- $inDigits[] = $baseChars[$char];
- }
-
- // Iterate over the input, modulo-ing out an output digit
- // at a time until input is gone.
- $result = '';
- while ( $inDigits ) {
- $work = 0;
- $workDigits = array();
-
- // Long division...
- foreach ( $inDigits as $digit ) {
- $work *= $sourceBase;
- $work += $digit;
-
- if ( $workDigits || $work >= $destBase ) {
- $workDigits[] = (int)( $work / $destBase );
- }
- $work %= $destBase;
- }
-
- // All that division leaves us with a remainder,
- // which is conveniently our next output digit.
- $result .= $baseChars[$work];
-
- // And we continue!
- $inDigits = $workDigits;
- }
-
- $result = strrev( $result );
- }
-
- if ( !$lowercase ) {
- $result = strtoupper( $result );
- }
-
- return str_pad( $result, $pad, '0', STR_PAD_LEFT );
+ return Wikimedia\base_convert( $input, $sourceBase, $destBase, $pad, $lowercase, $engine );
}
/**
*
* @param string $text
*
- * @throws Exception
* @return array
*/
public function matchAndRemove( &$text ) {
continue;
}
$matches = array();
- $matched = preg_match_all( $regex, $text, $matches, PREG_SET_ORDER );
- if ( $matched === false ) {
- throw new Exception( __METHOD__ . ': preg_match_all returned false' );
- }
- if ( $matched ) {
+ if ( preg_match_all( $regex, $text, $matches, PREG_SET_ORDER ) ) {
foreach ( $matches as $m ) {
list( $name, $param ) = $this->parseMatch( $m );
$found[$name] = $param;
}
}
- $replaced = preg_replace( $regex, '', $text );
- if ( $replaced !== null ) {
- $text = $replaced;
- } else {
- throw new Exception( __METHOD__ . ': preg_replace returned null' );
- }
+ $text = preg_replace( $regex, '', $text );
}
return $found;
}
/**
* @var array Additional stylesheets. Looks like this is for extensions.
- * Might be replaced by resource loader.
+ * Might be replaced by ResourceLoader.
*/
protected $mExtStyles = array();
private $mLanguageLinks = array();
/**
- * Used for JavaScript (pre resource loader)
+ * Used for JavaScript (predates ResourceLoader)
* @todo We should split JS / CSS.
* mScripts content is inserted as is in "<head>" by Skin. This might
* contain either a link to a stylesheet or inline CSS.
/** @var array Array of elements in "<head>". Parser might add its own headers! */
protected $mHeadItems = array();
- // @todo FIXME: Next 5 variables probably come from the resource loader
-
/** @var array */
protected $mModules = array();
/**
* @var bool Comes from the parser. This was probably made to load CSS/JS
* only if we had "<gallery>". Used directly in CategoryPage.php.
- * Looks like resource loader can replace this.
+ * Looks like ResourceLoader can replace this.
*/
public $mNoGallery = false;
}
/**
- * Add one or more modules recognized by the resource loader. Modules added
- * through this function will be loaded by the resource loader when the
+ * Add one or more modules recognized by ResourceLoader. Modules added
+ * through this function will be loaded by ResourceLoader when the
* page loads.
*
* @param string|array $modules Module name (string) or array of module names
}
/**
- * Add only JS of one or more modules recognized by the resource loader. Module
- * scripts added through this function will be loaded by the resource loader when
+ * Add only JS of one or more modules recognized by ResourceLoader. Module
+ * scripts added through this function will be loaded by ResourceLoader when
* the page loads.
*
* @param string|array $modules Module name (string) or array of module names
}
/**
- * Add only CSS of one or more modules recognized by the resource loader.
+ * Add only CSS of one or more modules recognized by ResourceLoader.
*
* Module styles added through this function will be added using standard link CSS
* tags, rather than as a combined Javascript and CSS package. Thus, they will
* @return int
*/
static function numberingroup( $group ) {
- return ObjectCache::getMainWANInstance()->getWithSetCallback(
+ $cache = ObjectCache::getMainWANInstance();
+ return $cache->getWithSetCallback(
wfMemcKey( 'SiteStats', 'groupcounts', $group ),
- 3600,
+ $cache::TTL_HOUR,
function ( $oldValue, &$ttl, array &$setOpts ) use ( $group ) {
$dbr = wfGetDB( DB_SLAVE );
$data[$name] = $this->$name;
}
$data['mVersion'] = self::VERSION;
- $key = wfMemcKey( 'user', 'id', $this->mId );
-
$opts = Database::getCacheSetOptions( wfGetDB( DB_SLAVE ) );
- ObjectCache::getMainWANInstance()->set( $key, $data, 3600, $opts );
+
+ $cache = ObjectCache::getMainWANInstance();
+ $key = wfMemcKey( 'user', 'id', $this->mId );
+ $cache->set( $key, $data, $cache::TTL_HOUR, $opts );
}
/** @name newFrom*() static factory methods */
'subscribers' => array_map( array( 'SpecialVersion', 'arrayToString' ), $subscribers ),
);
- ApiResult::setArrayType( $arr['subscribers'], 'BCarray' );
+ ApiResult::setArrayType( $arr['subscribers'], 'array' );
ApiResult::setIndexedTagName( $arr['subscribers'], 's' );
$data[] = $arr;
}
"apihelp-delete-param-title": "De Övverschreff vun dä Sigg zom fottschmiiße. Kam_mer nit zersamme met „<var lang=\"en\" xml:lang=\"en\" dir=\"ltr\">$1pageid</var>“ bruche.",
"apihelp-delete-param-pageid": "De Kännong vun dä Sigg zom fottschmiiße. Kam_mer nit zersamme met „<var lang=\"en\" xml:lang=\"en\" dir=\"ltr\">$1title</var>“ bruche.",
"apihelp-delete-param-reason": "Der Jrond för et Fottschmiiße. Wann dä nit aanjejovve es, weed ene automattesch usjräschnete Jrond jenumme.",
+ "apihelp-delete-param-tags": "Donn de Makehronge änndere, di för dä Enndraach em Logbohch jesaz wähde sulle.",
"apihelp-delete-param-watch": "Donn di Sigg en däm aktoälle Metmaacher sing Oppaßleß opnämme.",
"apihelp-delete-param-watchlist": "Donn di Sigg op däm aktoälle Metmaacher sing Oppaßleß udder nemm se druß fott, donn de Enschtällonge nämme, udder donn de Oppaßleß jaa nit verändere.",
"apihelp-delete-param-unwatch": "Schmihß di Sigg us däm aktoälle Metmaacher singe Oppaßless erus.",
"apihelp-query+allredirects-example-unique": "Ongerscheidlijje Sigge opleste.",
"apihelp-query+allredirects-example-unique-generator": "Hollt alle Zihlsigge un makkehr di (noch) nit doh sin.",
"apihelp-query+allredirects-example-generator": "Holl de Sigge met de Ömleidonge.",
+ "apihelp-query+allrevisions-description": "Donn alle Väsjohne opleßte.",
+ "apihelp-query+allrevisions-param-start": "Et Dattom un de Zigg vun woh aff opjezallt wähde sull.",
+ "apihelp-query+allrevisions-param-end": "Et Dattom un de Zigg bes woh hen opjezallt wähde sull.",
+ "apihelp-query+allrevisions-param-user": "Donn blohß Väsjohne vun heh däm Metmaacher opleßte.",
+ "apihelp-query+allrevisions-param-excludeuser": "Donn kein Väsjohne vun heh däm Metmaacher opleßte.",
+ "apihelp-query+allrevisions-param-namespace": "Donn blohß Sigge en heh däm Appachtemang opleßte.",
+ "apihelp-query+allrevisions-param-generatetitles": "Wann als ene Jenerahtor enjesaz, brängk dat Övverschreffte un kein Kännonge vun Väsjohne.",
+ "apihelp-query+allrevisions-example-user": "Donn de läzde fuffzisch Beijdrähsch vum Metmaacher „<kbd lang=\"en\" xml:lang=\"en\" dir=\"ltr\">Example</kbd>“ opleßte.",
+ "apihelp-query+allrevisions-example-ns-main": "Donn de eezde fuffzisch Väsjohne em Houp-Appachemang opleßte.",
"apihelp-query+alltransclusions-param-from": "De Övverschreff vun dä ennjeföhschte Sigg, woh de Leß medd aanfange sull.",
"apihelp-query+alltransclusions-param-to": "De Övverschreff vun dä ennjeföhschte Sigg, woh et Zälle ophühre sull.",
"apihelp-query+alltransclusions-param-prefix": "Söhk noh alle dä ennjeföhschte Sigge ier Övverschreffte, di met heh däm Täx aanfange.",
"apihelp-query+recentchanges-param-limit": "Wi vill Änderonge ensjesammp zem aanzeije?",
"apihelp-query+recentchanges-param-type": "Wat för en Zoot Änneronge aanzeije?",
"apihelp-query+recentchanges-param-toponly": "Bloß Änderonge aanzeije, woh de neußte Väsjohn beij eruß kohm.",
+ "apihelp-query+recentchanges-param-generaterevisions": "Wann als ene Jenerahtor enjesaz, brängk dat Kännonge vun Väsjohne un kein Övverschreffte. Enndrähsch en de neußte Änderonge der ohne en Väsjohnskännong, alsu de miehste Logbohchenndrähsch, bränge jaa nix.",
"apihelp-query+recentchanges-example-simple": "Zeijsch de {{LCFIRST:{{int:recentchanges}}}}",
"apihelp-query+redirects-description": "Jiff alle Ömleijdonge noh dä aanjejovve Sigge uß.",
"apihelp-query+redirects-param-prop": "Wat för en Eijeschaffte holle:",
--- /dev/null
+{
+ "@metadata": {
+ "authors": [
+ "Bharathesha Alasandemajalu"
+ ]
+ },
+ "apihelp-query+watchlist-param-type": "ವಾ ನಮೂನೆದ ಬದಲಾವಣೆ ತೊಜವೋಡು",
+ "apihelp-query+watchlist-paramvalue-type-external": "ಪಿದಯೀದ ಬದಲಾವಣೇ",
+ "apihelp-query+watchlist-paramvalue-type-new": "ಪಾಲೆ ಉಂಡುಮಾನ್ಪುನಾ"
+}
"apihelp-query+recentchanges-param-token": "请改用<kbd>[[Special:ApiHelp/query+tokens|action=query&meta=tokens]]</kbd>。",
"apihelp-query+recentchanges-param-limit": "返回总计更新数。",
"apihelp-query+recentchanges-param-type": "显示的更改类型。",
+ "apihelp-query+recentchanges-param-generaterevisions": "当作为生成器使用时,生成修订ID而不是标题。不带关联修订ID的最近更改记录(例如大多数日志记录)将不会生成任何东西。",
"apihelp-query+recentchanges-example-simple": "最近更改列表。",
"apihelp-query+recentchanges-example-generator": "获取有关最近未巡查更改的页面信息。",
"apihelp-query+redirects-description": "返回至指定页面的所有重定向。",
}
/**
- * General accessor to get/set whether SELECT FOR UPDATE should be used
+ * General accessor to get/set whether the master DB should be used
+ *
+ * This used to also set the FOR UPDATE option (locking the rows read
+ * in order to avoid link table inconsistency), which was later removed
+ * for performance on wikis with a high edit rate.
*
* @param bool $update
* @return bool
<?php
/**
- * Resource message blobs storage used by the resource loader.
+ * Resource message blobs storage used by ResourceLoader.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
*/
/**
- * This class provides access to the resource message blobs storage used by
- * the ResourceLoader.
+ * This class provides access to the resource message blobs storage used
+ * by ResourceLoader.
*
* A message blob is a JSON object containing the interface messages for a
* certain resource in a certain language. These message blobs are cached
foreach ( $codes as $code ) {
$sidebarKey = wfMemcKey( 'sidebar', $code );
- $this->wanCache->delete( $sidebarKey, 5 );
+ $this->wanCache->delete( $sidebarKey );
}
// Update the message in the message blob store
}
# Diff and hist links
- if ( $type == RC_LOG && $type != RC_CATEGORIZE ) {
+ if ( $type != RC_LOG && $type != RC_CATEGORIZE ) {
$query['action'] = 'history';
$data['historyLink'] = $this->getDiffHistLinks( $rcObj, $query );
}
+++ /dev/null
-<?php
-/**
- * Interface for representing objects that are stored in some DB table.
- * This is basically an ORM-like wrapper around rows in database tables that
- * aims to be both simple and very flexible. It is centered around an associative
- * array of fields and various methods to do common interaction with the database.
- *
- * Documentation inline and at https://www.mediawiki.org/wiki/Manual:ORMTable
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @since 1.20
- *
- * @file
- * @ingroup ORM
- *
- * @license GNU GPL v2 or later
- * @author Jeroen De Dauw < jeroendedauw@gmail.com >
- */
-
-interface IORMRow {
- /**
- * Load the specified fields from the database.
- *
- * @since 1.20
- * @deprecated since 1.22
- *
- * @param array|null $fields
- * @param bool $override
- * @param bool $skipLoaded
- *
- * @return bool Success indicator
- */
- public function loadFields( $fields = null, $override = true, $skipLoaded = false );
-
- /**
- * Gets the value of a field.
- *
- * @since 1.20
- *
- * @param string $name
- * @param mixed $default
- *
- * @throws MWException
- * @return mixed
- */
- public function getField( $name, $default = null );
-
- /**
- * Gets the value of a field but first loads it if not done so already.
- *
- * @since 1.20
- * @deprecated since 1.22
- *
- * @param string $name
- *
- * @return mixed
- */
- public function loadAndGetField( $name );
-
- /**
- * Remove a field.
- *
- * @since 1.20
- *
- * @param string $name
- */
- public function removeField( $name );
-
- /**
- * Returns the objects database id.
- *
- * @since 1.20
- *
- * @return int|null
- */
- public function getId();
-
- /**
- * Sets the objects database id.
- *
- * @since 1.20
- *
- * @param int|null $id
- */
- public function setId( $id );
-
- /**
- * Gets if a certain field is set.
- *
- * @since 1.20
- *
- * @param string $name
- *
- * @return bool
- */
- public function hasField( $name );
-
- /**
- * Gets if the id field is set.
- *
- * @since 1.20
- *
- * @return bool
- */
- public function hasIdField();
-
- /**
- * Sets multiple fields.
- *
- * @since 1.20
- *
- * @param array $fields The fields to set
- * @param bool $override Override already set fields with the provided values?
- */
- public function setFields( array $fields, $override = true );
-
- /**
- * Serializes the object to an associative array which
- * can then easily be converted into JSON or similar.
- *
- * @since 1.20
- *
- * @param null|array $fields
- * @param bool $incNullId
- *
- * @return array
- */
- public function toArray( $fields = null, $incNullId = false );
-
- /**
- * Load the default values, via getDefaults.
- *
- * @since 1.20
- * @deprecated since 1.22
- *
- * @param bool $override
- */
- public function loadDefaults( $override = true );
-
- /**
- * Writes the answer to the database, either updating it
- * when it already exists, or inserting it when it doesn't.
- *
- * @since 1.20
- *
- * @param string|null $functionName
- * @deprecated since 1.22
- *
- * @return bool Success indicator
- */
- public function save( $functionName = null );
-
- /**
- * Removes the object from the database.
- *
- * @since 1.20
- * @deprecated since 1.22
- *
- * @return bool Success indicator
- */
- public function remove();
-
- /**
- * Return the names and values of the fields.
- *
- * @since 1.20
- *
- * @return array
- */
- public function getFields();
-
- /**
- * Return the names of the fields.
- *
- * @since 1.20
- *
- * @return array
- */
- public function getSetFieldNames();
-
- /**
- * Sets the value of a field.
- * Strings can be provided for other types,
- * so this method can be called from unserialization handlers.
- *
- * @since 1.20
- *
- * @param string $name
- * @param mixed $value
- *
- * @throws MWException
- */
- public function setField( $name, $value );
-
- /**
- * Add an amount (can be negative) to the specified field (needs to be numeric).
- *
- * @since 1.20
- * @deprecated since 1.22
- *
- * @param string $field
- * @param int $amount
- *
- * @return bool Success indicator
- */
- public function addToField( $field, $amount );
-
- /**
- * Return the names of the fields.
- *
- * @since 1.20
- *
- * @return array
- */
- public function getFieldNames();
-
- /**
- * Computes and updates the values of the summary fields.
- *
- * @since 1.20
- * @deprecated since 1.22
- *
- * @param array|string|null $summaryFields
- */
- public function loadSummaryFields( $summaryFields = null );
-
- /**
- * Sets the value for the @see $updateSummaries field.
- *
- * @since 1.20
- * @deprecated since 1.22
- *
- * @param bool $update
- */
- public function setUpdateSummaries( $update );
-
- /**
- * Sets the value for the @see $inSummaryMode field.
- *
- * @since 1.20
- * @deprecated since 1.22
- *
- * @param bool $summaryMode
- */
- public function setSummaryMode( $summaryMode );
-
- /**
- * Returns the table this IORMRow is a row in.
- *
- * @since 1.20
- * @deprecated since 1.22
- *
- * @return IORMTable
- */
- public function getTable();
-}
+++ /dev/null
-<?php
-/**
- * Interface for objects representing a single database table.
- * Documentation inline and at https://www.mediawiki.org/wiki/Manual:ORMTable
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @since 1.20
- *
- * @file
- * @ingroup ORM
- *
- * @license GNU GPL v2 or later
- * @author Jeroen De Dauw < jeroendedauw@gmail.com >
- */
-
-interface IORMTable {
- /**
- * Returns the name of the database table objects of this type are stored in.
- *
- * @since 1.20
- *
- * @return string
- */
- public function getName();
-
- /**
- * Returns the name of a IORMRow implementing class that
- * represents single rows in this table.
- *
- * @since 1.20
- *
- * @return string
- */
- public function getRowClass();
-
- /**
- * Returns an array with the fields and their types this object contains.
- * This corresponds directly to the fields in the database, without prefix.
- *
- * field name => type
- *
- * Allowed types:
- * * id
- * * str
- * * int
- * * float
- * * bool
- * * array
- * * blob
- *
- * @todo Get rid of the id field. Every row instance needs to have one so
- * this is just causing hassle at various locations by requiring an extra
- * check for field name.
- *
- * @since 1.20
- *
- * @return array
- */
- public function getFields();
-
- /**
- * Returns a list of default field values.
- * field name => field value
- *
- * @since 1.20
- *
- * @return array
- */
- public function getDefaults();
-
- /**
- * Returns a list of the summary fields.
- * These are fields that cache computed values, such as the amount of linked objects of $type.
- * This is relevant as one might not want to do actions such as log changes when these get updated.
- *
- * @since 1.20
- *
- * @return array
- */
- public function getSummaryFields();
-
- /**
- * Selects the specified fields of the records matching the provided
- * conditions and returns them as DBDataObject. Field names get prefixed.
- *
- * @see DatabaseBase::select()
- *
- * @since 1.20
- *
- * @param array|string|null $fields
- * @param array $conditions
- * @param array $options
- * @param string|null $functionName
- *
- * @return ORMResult The result set
- * @throws DBQueryError If the query failed (even if the database was in ignoreErrors mode)
- */
- public function select( $fields = null, array $conditions = array(),
- array $options = array(), $functionName = null );
-
- /**
- * Selects the specified fields of the records matching the provided
- * conditions and returns them as DBDataObject. Field names get prefixed.
- *
- * @since 1.20
- *
- * @param array|string|null $fields
- * @param array $conditions
- * @param array $options
- * @param string|null $functionName
- *
- * @return array Array of self
- */
- public function selectObjects( $fields = null, array $conditions = array(),
- array $options = array(), $functionName = null );
-
- /**
- * Do the actual select.
- *
- * @since 1.20
- *
- * @param null|string|array $fields
- * @param array $conditions
- * @param array $options
- * @param null|string $functionName
- *
- * @return ResultWrapper
- * @throws DBQueryError If the query failed (even if the database was in ignoreErrors mode)
- */
- public function rawSelect( $fields = null, array $conditions = array(),
- array $options = array(), $functionName = null );
-
- /**
- * Selects the specified fields of the records matching the provided
- * conditions and returns them as associative arrays.
- * Provided field names get prefixed.
- * Returned field names will not have a prefix.
- *
- * When $collapse is true:
- * If one field is selected, each item in the result array will be this field.
- * If two fields are selected, each item in the result array will have as key
- * the first field and as value the second field.
- * If more then two fields are selected, each item will be an associative array.
- *
- * @since 1.20
- *
- * @param array|string|null $fields
- * @param array $conditions
- * @param array $options
- * @param bool $collapse Set to false to always return each result row as associative array.
- * @param string|null $functionName
- *
- * @return array Array of array
- */
- public function selectFields( $fields = null, array $conditions = array(),
- array $options = array(), $collapse = true, $functionName = null );
-
- /**
- * Selects the specified fields of the first matching record.
- * Field names get prefixed.
- *
- * @since 1.20
- *
- * @param array|string|null $fields
- * @param array $conditions
- * @param array $options
- * @param string|null $functionName
- *
- * @return IORMRow|bool False on failure
- */
- public function selectRow( $fields = null, array $conditions = array(),
- array $options = array(), $functionName = null );
-
- /**
- * Selects the specified fields of the records matching the provided
- * conditions. Field names do NOT get prefixed.
- *
- * @since 1.20
- *
- * @param array $fields
- * @param array $conditions
- * @param array $options
- * @param string|null $functionName
- *
- * @return ResultWrapper
- */
- public function rawSelectRow( array $fields, array $conditions = array(),
- array $options = array(), $functionName = null );
-
- /**
- * Selects the specified fields of the first record matching the provided
- * conditions and returns it as an associative array, or false when nothing matches.
- * This method makes use of selectFields and expects the same parameters and
- * returns the same results (if there are any, if there are none, this method returns false).
- * @see IORMTable::selectFields
- *
- * @since 1.20
- *
- * @param array|string|null $fields
- * @param array $conditions
- * @param array $options
- * @param bool $collapse Set to false to always return each result row as associative array.
- * @param string|null $functionName
- *
- * @return mixed|array|bool False on failure
- */
- public function selectFieldsRow( $fields = null, array $conditions = array(),
- array $options = array(), $collapse = true, $functionName = null );
-
- /**
- * Returns if there is at least one record matching the provided conditions.
- * Condition field names get prefixed.
- *
- * @since 1.20
- *
- * @param array $conditions
- *
- * @return bool
- */
- public function has( array $conditions = array() );
-
- /**
- * Checks if the table exists
- *
- * @since 1.21
- *
- * @return bool
- */
- public function exists();
-
- /**
- * Returns the amount of matching records.
- * Condition field names get prefixed.
- *
- * Note that this can be expensive on large tables.
- * In such cases you might want to use DatabaseBase::estimateRowCount instead.
- *
- * @since 1.20
- *
- * @param array $conditions
- * @param array $options
- *
- * @return int
- */
- public function count( array $conditions = array(), array $options = array() );
-
- /**
- * Removes the object from the database.
- *
- * @since 1.20
- *
- * @param array $conditions
- * @param string|null $functionName
- *
- * @return bool Success indicator
- */
- public function delete( array $conditions, $functionName = null );
-
- /**
- * Get API parameters for the fields supported by this object.
- *
- * @since 1.20
- *
- * @param bool $requireParams
- * @param bool $setDefaults
- *
- * @return array
- */
- public function getAPIParams( $requireParams = false, $setDefaults = false );
-
- /**
- * Returns an array with the fields and their descriptions.
- *
- * field name => field description
- *
- * @since 1.20
- *
- * @return array
- */
- public function getFieldDescriptions();
-
- /**
- * Get the database type used for read operations.
- *
- * @since 1.20
- *
- * @return int DB_ enum
- */
- public function getReadDb();
-
- /**
- * Set the database type to use for read operations.
- *
- * @param int $db
- *
- * @since 1.20
- */
- public function setReadDb( $db );
-
- /**
- * Get the ID of the any foreign wiki to use as a target for database operations
- *
- * @since 1.20
- *
- * @return string|bool The target wiki, in a form that LBFactory
- * understands (or false if the local wiki is used)
- */
- public function getTargetWiki();
-
- /**
- * Set the ID of the any foreign wiki to use as a target for database operations
- *
- * @param string|bool $wiki The target wiki, in a form that LBFactory
- * understands (or false if the local wiki shall be used)
- *
- * @since 1.20
- */
- public function setTargetWiki( $wiki );
-
- /**
- * Get the database type used for read operations.
- * This is to be used instead of wfGetDB.
- *
- * @see LoadBalancer::getConnection
- *
- * @since 1.20
- *
- * @return DatabaseBase The database object
- */
- public function getReadDbConnection();
-
- /**
- * Get the database type used for read operations.
- * This is to be used instead of wfGetDB.
- *
- * @see LoadBalancer::getConnection
- *
- * @since 1.20
- *
- * @return DatabaseBase The database object
- */
- public function getWriteDbConnection();
-
- /**
- * Get the database type used for read operations.
- *
- * @see wfGetLB
- *
- * @since 1.20
- *
- * @return LoadBalancer The database load balancer object
- */
- public function getLoadBalancer();
-
- /**
- * Releases the lease on the given database connection. This is useful mainly
- * for connections to a foreign wiki. It does nothing for connections to the local wiki.
- *
- * @see LoadBalancer::reuseConnection
- *
- * @param DatabaseBase $db The database
- *
- * @since 1.20
- */
- public function releaseConnection( DatabaseBase $db );
-
- /**
- * Update the records matching the provided conditions by
- * setting the fields that are keys in the $values param to
- * their corresponding values.
- *
- * @since 1.20
- *
- * @param array $values
- * @param array $conditions
- *
- * @return bool Success indicator
- */
- public function update( array $values, array $conditions = array() );
-
- /**
- * Computes the values of the summary fields of the objects matching the provided conditions.
- *
- * @since 1.20
- *
- * @param array|string|null $summaryFields
- * @param array $conditions
- */
- public function updateSummaryFields( $summaryFields = null, array $conditions = array() );
-
- /**
- * Takes in an associative array with field names as keys and
- * their values as value. The field names are prefixed with the
- * db field prefix.
- *
- * @since 1.20
- *
- * @param array $values
- *
- * @return array
- */
- public function getPrefixedValues( array $values );
-
- /**
- * Takes in a field or array of fields and returns an
- * array with their prefixed versions, ready for db usage.
- *
- * @since 1.20
- *
- * @param array $fields
- *
- * @return array
- */
- public function getPrefixedFields( array $fields );
-
- /**
- * Takes in a field and returns an it's prefixed version, ready for db usage.
- *
- * @since 1.20
- *
- * @param string|array $field
- *
- * @return string
- */
- public function getPrefixedField( $field );
-
- /**
- * Takes an array of field names with prefix and returns the unprefixed equivalent.
- *
- * @since 1.20
- * @deprecated since 1.25, will be removed
- *
- * @param string[] $fieldNames
- *
- * @return string[]
- */
- public function unprefixFieldNames( array $fieldNames );
-
- /**
- * Takes a field name with prefix and returns the unprefixed equivalent.
- *
- * @since 1.20
- * @deprecated since 1.25, will be removed
- *
- * @param string $fieldName
- *
- * @return string
- */
- public function unprefixFieldName( $fieldName );
-
- /**
- * Get an array with fields from a database result,
- * that can be fed directly to the constructor or
- * to setFields.
- *
- * @since 1.20
- *
- * @param stdClass $result
- *
- * @return array
- */
- public function getFieldsFromDBResult( stdClass $result );
-
- /**
- * Get a new instance of the class from a database result.
- *
- * @since 1.20
- *
- * @param stdClass $result
- *
- * @return IORMRow
- */
- public function newRowFromDBResult( stdClass $result );
-
- /**
- * Get a new instance of the class from an array.
- *
- * @since 1.20
- *
- * @param array $data
- * @param bool $loadDefaults
- *
- * @return IORMRow
- */
- public function newRow( array $data, $loadDefaults = false );
-
- /**
- * Return the names of the fields.
- *
- * @since 1.20
- *
- * @return array
- */
- public function getFieldNames();
-
- /**
- * Gets if the object can take a certain field.
- *
- * @since 1.20
- *
- * @param string $name
- *
- * @return bool
- */
- public function canHaveField( $name );
-}
+++ /dev/null
-<?php
-
-/**
- * Interface for Iterators containing IORMRows.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @since 1.20
- *
- * @file
- * @ingroup ORM
- *
- * @license GNU GPL v2 or later
- * @author Jeroen De Dauw < jeroendedauw@gmail.com >
- */
-interface ORMIterator extends Iterator {
-}
+++ /dev/null
-<?php
-/**
- * ORMIterator that takes a ResultWrapper object returned from
- * a select operation returning IORMRow objects (ie IORMTable::select).
- *
- * Documentation inline and at https://www.mediawiki.org/wiki/Manual:ORMTable
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @since 1.20
- *
- * @file ORMResult.php
- * @ingroup ORM
- *
- * @license GNU GPL v2 or later
- * @author Jeroen De Dauw < jeroendedauw@gmail.com >
- */
-
-class ORMResult implements ORMIterator {
- /**
- * @var ResultWrapper
- */
- protected $res;
-
- /**
- * @var int
- */
- protected $key;
-
- /**
- * @var IORMRow
- */
- protected $current;
-
- /**
- * @var IORMTable
- */
- protected $table;
-
- /**
- * @param IORMTable $table
- * @param ResultWrapper $res
- */
- public function __construct( IORMTable $table, ResultWrapper $res ) {
- $this->table = $table;
- $this->res = $res;
- $this->key = 0;
- $this->setCurrent( $this->res->current() );
- }
-
- /**
- * @param bool|object $row
- */
- protected function setCurrent( $row ) {
- if ( $row === false ) {
- $this->current = false;
- } else {
- $this->current = $this->table->newRowFromDBResult( $row );
- }
- }
-
- /**
- * @return int
- */
- public function count() {
- return $this->res->numRows();
- }
-
- /**
- * @return bool
- */
- public function isEmpty() {
- return $this->res->numRows() === 0;
- }
-
- /**
- * @return IORMRow
- */
- public function current() {
- return $this->current;
- }
-
- /**
- * @return int
- */
- public function key() {
- return $this->key;
- }
-
- public function next() {
- $row = $this->res->next();
- $this->setCurrent( $row );
- $this->key++;
- }
-
- public function rewind() {
- $this->res->rewind();
- $this->key = 0;
- $this->setCurrent( $this->res->current() );
- }
-
- /**
- * @return bool
- */
- public function valid() {
- return $this->current !== false;
- }
-}
+++ /dev/null
-<?php
-/**
- * Abstract base class for representing objects that are stored in some DB table.
- * This is basically an ORM-like wrapper around rows in database tables that
- * aims to be both simple and very flexible. It is centered around an associative
- * array of fields and various methods to do common interaction with the database.
- *
- * Documentation inline and at https://www.mediawiki.org/wiki/Manual:ORMTable
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @since 1.20
- *
- * @file ORMRow.php
- * @ingroup ORM
- *
- * @license GNU GPL v2 or later
- * @author Jeroen De Dauw < jeroendedauw@gmail.com >
- */
-
-class ORMRow implements IORMRow {
- /**
- * The fields of the object.
- * field name (w/o prefix) => value
- *
- * @since 1.20
- * @var array
- */
- protected $fields = array( 'id' => null );
-
- /**
- * If the object should update summaries of linked items when changed.
- * For example, update the course_count field in universities when a course in courses is deleted.
- * Settings this to false can prevent needless updating work in situations
- * such as deleting a university, which will then delete all it's courses.
- *
- * @deprecated since 1.22
- * @since 1.20
- * @var bool
- */
- protected $updateSummaries = true;
-
- /**
- * Indicates if the object is in summary mode.
- * This mode indicates that only summary fields got updated,
- * which allows for optimizations.
- *
- * @deprecated since 1.22
- * @since 1.20
- * @var bool
- */
- protected $inSummaryMode = false;
-
- /**
- * @deprecated since 1.22
- * @since 1.20
- * @var ORMTable|null
- */
- protected $table;
-
- /**
- * Constructor.
- *
- * @since 1.20
- *
- * @param IORMTable|null $table Deprecated since 1.22
- * @param array|null $fields
- * @param bool $loadDefaults Deprecated since 1.22
- */
- public function __construct( IORMTable $table = null, $fields = null, $loadDefaults = false ) {
- $this->table = $table;
-
- if ( !is_array( $fields ) ) {
- $fields = array();
- }
-
- if ( $loadDefaults ) {
- $fields = array_merge( $this->table->getDefaults(), $fields );
- }
-
- $this->setFields( $fields );
- }
-
- /**
- * Load the specified fields from the database.
- *
- * @since 1.20
- * @deprecated since 1.22
- *
- * @param array|null $fields
- * @param bool $override
- * @param bool $skipLoaded
- *
- * @return bool Success indicator
- */
- public function loadFields( $fields = null, $override = true, $skipLoaded = false ) {
- if ( is_null( $this->getId() ) ) {
- return false;
- }
-
- if ( is_null( $fields ) ) {
- $fields = array_keys( $this->table->getFields() );
- }
-
- if ( $skipLoaded ) {
- $fields = array_diff( $fields, array_keys( $this->fields ) );
- }
-
- if ( !empty( $fields ) ) {
- $result = $this->table->rawSelectRow(
- $this->table->getPrefixedFields( $fields ),
- array( $this->table->getPrefixedField( 'id' ) => $this->getId() ),
- array( 'LIMIT' => 1 ),
- __METHOD__
- );
-
- if ( $result !== false ) {
- $this->setFields( $this->table->getFieldsFromDBResult( $result ), $override );
-
- return true;
- }
-
- return false;
- }
-
- return true;
- }
-
- /**
- * Gets the value of a field.
- *
- * @since 1.20
- *
- * @param string $name Field name
- * @param mixed $default Default value to return when none is found
- * (default: null)
- *
- * @throws MWException
- * @return mixed
- */
- public function getField( $name, $default = null ) {
- if ( $this->hasField( $name ) ) {
- return $this->fields[$name];
- } elseif ( !is_null( $default ) ) {
- return $default;
- } else {
- throw new MWException( 'Attempted to get not-set field ' . $name );
- }
- }
-
- /**
- * Gets the value of a field but first loads it if not done so already.
- *
- * @since 1.20
- * @deprecated since 1.22
- *
- * @param string $name
- *
- * @return mixed
- */
- public function loadAndGetField( $name ) {
- if ( !$this->hasField( $name ) ) {
- $this->loadFields( array( $name ) );
- }
-
- return $this->getField( $name );
- }
-
- /**
- * Remove a field.
- *
- * @since 1.20
- *
- * @param string $name
- */
- public function removeField( $name ) {
- unset( $this->fields[$name] );
- }
-
- /**
- * Returns the objects database id.
- *
- * @since 1.20
- *
- * @return int|null
- */
- public function getId() {
- return $this->getField( 'id' );
- }
-
- /**
- * Sets the objects database id.
- *
- * @since 1.20
- *
- * @param int|null $id
- */
- public function setId( $id ) {
- $this->setField( 'id', $id );
- }
-
- /**
- * Gets if a certain field is set.
- *
- * @since 1.20
- *
- * @param string $name
- *
- * @return bool
- */
- public function hasField( $name ) {
- return array_key_exists( $name, $this->fields );
- }
-
- /**
- * Gets if the id field is set.
- *
- * @since 1.20
- *
- * @return bool
- */
- public function hasIdField() {
- return $this->hasField( 'id' ) && !is_null( $this->getField( 'id' ) );
- }
-
- /**
- * Gets the fields => values to write to the table.
- *
- * @since 1.20
- * @deprecated since 1.22
- *
- * @return array
- */
- protected function getWriteValues() {
- $values = array();
-
- foreach ( $this->table->getFields() as $name => $type ) {
- if ( array_key_exists( $name, $this->fields ) ) {
- $value = $this->fields[$name];
-
- // Skip null id fields so that the DBMS can set the default.
- if ( $name === 'id' && is_null( $value ) ) {
- continue;
- }
-
- switch ( $type ) {
- case 'array':
- $value = (array)$value;
- // fall-through!
- case 'blob':
- $value = serialize( $value );
- // fall-through!
- }
-
- $values[$this->table->getPrefixedField( $name )] = $value;
- }
- }
-
- return $values;
- }
-
- /**
- * Sets multiple fields.
- *
- * @since 1.20
- *
- * @param array $fields The fields to set
- * @param bool $override Override already set fields with the provided values?
- */
- public function setFields( array $fields, $override = true ) {
- foreach ( $fields as $name => $value ) {
- if ( $override || !$this->hasField( $name ) ) {
- $this->setField( $name, $value );
- }
- }
- }
-
- /**
- * Serializes the object to an associative array which
- * can then easily be converted into JSON or similar.
- *
- * @since 1.20
- *
- * @param null|array $fields
- * @param bool $incNullId
- *
- * @return array
- */
- public function toArray( $fields = null, $incNullId = false ) {
- $data = array();
- $setFields = array();
-
- if ( !is_array( $fields ) ) {
- $setFields = $this->getSetFieldNames();
- } else {
- foreach ( $fields as $field ) {
- if ( $this->hasField( $field ) ) {
- $setFields[] = $field;
- }
- }
- }
-
- foreach ( $setFields as $field ) {
- if ( $incNullId || $field != 'id' || $this->hasIdField() ) {
- $data[$field] = $this->getField( $field );
- }
- }
-
- return $data;
- }
-
- /**
- * Load the default values, via getDefaults.
- *
- * @since 1.20
- * @deprecated since 1.22
- *
- * @param bool $override
- */
- public function loadDefaults( $override = true ) {
- $this->setFields( $this->table->getDefaults(), $override );
- }
-
- /**
- * Writes the answer to the database, either updating it
- * when it already exists, or inserting it when it doesn't.
- *
- * @since 1.20
- * @deprecated since 1.22 Use IORMTable->updateRow or ->insertRow
- *
- * @param string|null $functionName
- *
- * @return bool Success indicator
- */
- public function save( $functionName = null ) {
- if ( $this->hasIdField() ) {
- return $this->table->updateRow( $this, $functionName );
- } else {
- return $this->table->insertRow( $this, $functionName );
- }
- }
-
- /**
- * Updates the object in the database.
- *
- * @since 1.20
- * @deprecated since 1.22
- *
- * @param string|null $functionName
- *
- * @return bool Success indicator
- */
- protected function saveExisting( $functionName = null ) {
- $dbw = $this->table->getWriteDbConnection();
-
- $success = $dbw->update(
- $this->table->getName(),
- $this->getWriteValues(),
- $this->table->getPrefixedValues( $this->getUpdateConditions() ),
- is_null( $functionName ) ? __METHOD__ : $functionName
- );
-
- $this->table->releaseConnection( $dbw );
-
- // DatabaseBase::update does not always return true for success as documented...
- return $success !== false;
- }
-
- /**
- * Returns the WHERE considtions needed to identify this object so
- * it can be updated.
- *
- * @since 1.20
- *
- * @return array
- */
- protected function getUpdateConditions() {
- return array( 'id' => $this->getId() );
- }
-
- /**
- * Inserts the object into the database.
- *
- * @since 1.20
- * @deprecated since 1.22
- *
- * @param string|null $functionName
- * @param array|null $options
- *
- * @return bool Success indicator
- */
- protected function insert( $functionName = null, array $options = null ) {
- $dbw = $this->table->getWriteDbConnection();
-
- $success = $dbw->insert(
- $this->table->getName(),
- $this->getWriteValues(),
- is_null( $functionName ) ? __METHOD__ : $functionName,
- $options
- );
-
- // DatabaseBase::insert does not always return true for success as documented...
- $success = $success !== false;
-
- if ( $success ) {
- $this->setField( 'id', $dbw->insertId() );
- }
-
- $this->table->releaseConnection( $dbw );
-
- return $success;
- }
-
- /**
- * Removes the object from the database.
- *
- * @since 1.20
- * @deprecated since 1.22, use IORMTable->removeRow
- *
- * @return bool Success indicator
- */
- public function remove() {
- $this->beforeRemove();
-
- $success = $this->table->removeRow( $this, __METHOD__ );
-
- if ( $success ) {
- $this->onRemoved();
- }
-
- return $success;
- }
-
- /**
- * Gets called before an object is removed from the database.
- *
- * @since 1.20
- * @deprecated since 1.22
- */
- protected function beforeRemove() {
- $this->loadFields( $this->getBeforeRemoveFields(), false, true );
- }
-
- /**
- * Before removal of an object happens, @see beforeRemove gets called.
- * This method loads the fields of which the names have been returned by
- * this one (or all fields if null is returned). This allows for loading
- * info needed after removal to get rid of linked data and the like.
- *
- * @since 1.20
- *
- * @return array|null
- */
- protected function getBeforeRemoveFields() {
- return array();
- }
-
- /**
- * Gets called after successful removal.
- * Can be overridden to get rid of linked data.
- *
- * @since 1.20
- * @deprecated since 1.22
- */
- protected function onRemoved() {
- $this->setField( 'id', null );
- }
-
- /**
- * Return the names and values of the fields.
- *
- * @since 1.20
- *
- * @return array
- */
- public function getFields() {
- return $this->fields;
- }
-
- /**
- * Return the names of the fields.
- *
- * @since 1.20
- *
- * @return array
- */
- public function getSetFieldNames() {
- return array_keys( $this->fields );
- }
-
- /**
- * Sets the value of a field.
- * Strings can be provided for other types,
- * so this method can be called from unserialization handlers.
- *
- * @since 1.20
- *
- * @param string $name
- * @param mixed $value
- *
- * @throws MWException
- */
- public function setField( $name, $value ) {
- $this->fields[$name] = $value;
- }
-
- /**
- * Add an amount (can be negative) to the specified field (needs to be numeric).
- *
- * @since 1.20
- * @deprecated since 1.22, use IORMTable->addToField
- *
- * @param string $field
- * @param int $amount
- *
- * @return bool Success indicator
- */
- public function addToField( $field, $amount ) {
- return $this->table->addToField( $this->getUpdateConditions(), $field, $amount );
- }
-
- /**
- * Return the names of the fields.
- *
- * @since 1.20
- * @deprecated since 1.22
- *
- * @return array
- */
- public function getFieldNames() {
- return array_keys( $this->table->getFields() );
- }
-
- /**
- * Computes and updates the values of the summary fields.
- *
- * @since 1.20
- * @deprecated since 1.22
- *
- * @param array|string|null $summaryFields
- */
- public function loadSummaryFields( $summaryFields = null ) {
- }
-
- /**
- * Sets the value for the @see $updateSummaries field.
- *
- * @since 1.20
- * @deprecated since 1.22
- *
- * @param bool $update
- */
- public function setUpdateSummaries( $update ) {
- $this->updateSummaries = $update;
- }
-
- /**
- * Sets the value for the @see $inSummaryMode field.
- *
- * @since 1.20
- * @deprecated since 1.22
- *
- * @param bool $summaryMode
- */
- public function setSummaryMode( $summaryMode ) {
- $this->inSummaryMode = $summaryMode;
- }
-
- /**
- * Returns the table this IORMRow is a row in.
- *
- * @since 1.20
- * @deprecated since 1.22
- *
- * @return IORMTable
- */
- public function getTable() {
- return $this->table;
- }
-}
+++ /dev/null
-<?php
-/**
- * Abstract base class for representing a single database table.
- * Documentation inline and at https://www.mediawiki.org/wiki/Manual:ORMTable
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @since 1.20
- * Non-abstract since 1.21
- *
- * @file ORMTable.php
- * @ingroup ORM
- *
- * @license GNU GPL v2 or later
- * @author Jeroen De Dauw < jeroendedauw@gmail.com >
- */
-
-class ORMTable extends DBAccessBase implements IORMTable {
- /**
- * Cache for instances, used by the singleton method.
- *
- * @since 1.20
- * @deprecated since 1.21
- *
- * @var ORMTable[]
- */
- protected static $instanceCache = array();
-
- /**
- * @since 1.21
- *
- * @var string
- */
- protected $tableName;
-
- /**
- * @since 1.21
- *
- * @var string[]
- */
- protected $fields = array();
-
- /**
- * @since 1.21
- *
- * @var string
- */
- protected $fieldPrefix = '';
-
- /**
- * @since 1.21
- *
- * @var string
- */
- protected $rowClass = 'ORMRow';
-
- /**
- * @since 1.21
- *
- * @var array
- */
- protected $defaults = array();
-
- /**
- * ID of the database connection to use for read operations.
- * Can be changed via @see setReadDb.
- *
- * @since 1.20
- *
- * @var int DB_ enum
- */
- protected $readDb = DB_SLAVE;
-
- /**
- * Constructor.
- *
- * @since 1.21
- *
- * @param string $tableName
- * @param string[] $fields
- * @param array $defaults
- * @param string|null $rowClass
- * @param string $fieldPrefix
- */
- public function __construct( $tableName = '', array $fields = array(),
- array $defaults = array(), $rowClass = null, $fieldPrefix = ''
- ) {
- $this->tableName = $tableName;
- $this->fields = $fields;
- $this->defaults = $defaults;
-
- if ( is_string( $rowClass ) ) {
- $this->rowClass = $rowClass;
- }
-
- $this->fieldPrefix = $fieldPrefix;
- }
-
- /**
- * @see IORMTable::getName
- *
- * @since 1.21
- *
- * @return string
- * @throws MWException
- */
- public function getName() {
- if ( $this->tableName === '' ) {
- throw new MWException( 'The table name needs to be set' );
- }
-
- return $this->tableName;
- }
-
- /**
- * Gets the db field prefix.
- *
- * @since 1.20
- * @deprecated since 1.25, use the $this->fieldPrefix property instead
- *
- * @return string
- */
- protected function getFieldPrefix() {
- return $this->fieldPrefix;
- }
-
- /**
- * @see IORMTable::getRowClass
- *
- * @since 1.21
- *
- * @return string
- */
- public function getRowClass() {
- return $this->rowClass;
- }
-
- /**
- * @see ORMTable::getFields
- *
- * @since 1.21
- *
- * @return array
- * @throws MWException
- */
- public function getFields() {
- if ( $this->fields === array() ) {
- throw new MWException( 'The table needs to have one or more fields' );
- }
-
- return $this->fields;
- }
-
- /**
- * Returns a list of default field values.
- * field name => field value
- *
- * @since 1.20
- *
- * @return array
- */
- public function getDefaults() {
- return $this->defaults;
- }
-
- /**
- * Returns a list of the summary fields.
- * These are fields that cache computed values, such as the amount of linked objects of $type.
- * This is relevant as one might not want to do actions such as log changes when these get updated.
- *
- * @since 1.20
- *
- * @return array
- */
- public function getSummaryFields() {
- return array();
- }
-
- /**
- * Selects the specified fields of the records matching the provided
- * conditions and returns them as DBDataObject. Field names get prefixed.
- *
- * @since 1.20
- *
- * @param array|string|null $fields
- * @param array $conditions
- * @param array $options
- * @param string|null $functionName
- *
- * @return ORMResult
- */
- public function select( $fields = null, array $conditions = array(),
- array $options = array(), $functionName = null
- ) {
- $res = $this->rawSelect( $fields, $conditions, $options, $functionName );
-
- return new ORMResult( $this, $res );
- }
-
- /**
- * Selects the specified fields of the records matching the provided
- * conditions and returns them as DBDataObject. Field names get prefixed.
- *
- * @since 1.20
- *
- * @param array|string|null $fields
- * @param array $conditions
- * @param array $options
- * @param string|null $functionName
- *
- * @return array Array of row objects
- * @throws DBQueryError If the query failed (even if the database was in ignoreErrors mode).
- */
- public function selectObjects( $fields = null, array $conditions = array(),
- array $options = array(), $functionName = null
- ) {
- $result = $this->selectFields( $fields, $conditions, $options, false, $functionName );
-
- $objects = array();
-
- foreach ( $result as $record ) {
- $objects[] = $this->newRow( $record );
- }
-
- return $objects;
- }
-
- /**
- * Do the actual select.
- *
- * @since 1.20
- *
- * @param null|string|array $fields
- * @param array $conditions
- * @param array $options
- * @param null|string $functionName
- * @return ResultWrapper
- * @throws Exception
- * @throws MWException
- */
- public function rawSelect( $fields = null, array $conditions = array(),
- array $options = array(), $functionName = null
- ) {
- if ( is_null( $fields ) ) {
- $fields = array_keys( $this->getFields() );
- } else {
- $fields = (array)$fields;
- }
-
- $dbr = $this->getReadDbConnection();
- $result = $dbr->select(
- $this->getName(),
- $this->getPrefixedFields( $fields ),
- $this->getPrefixedValues( $conditions ),
- is_null( $functionName ) ? __METHOD__ : $functionName,
- $options
- );
-
- /* @var Exception $error */
- $error = null;
-
- if ( $result === false ) {
- // Database connection was in "ignoreErrors" mode. We don't like that.
- // So, we emulate the DBQueryError that should have been thrown.
- $error = new DBQueryError(
- $dbr,
- $dbr->lastError(),
- $dbr->lastErrno(),
- $dbr->lastQuery(),
- is_null( $functionName ) ? __METHOD__ : $functionName
- );
- }
-
- $this->releaseConnection( $dbr );
-
- if ( $error ) {
- // Note: construct the error before releasing the connection,
- // but throw it after.
- throw $error;
- }
-
- return $result;
- }
-
- /**
- * Selects the specified fields of the records matching the provided
- * conditions and returns them as associative arrays.
- * Provided field names get prefixed.
- * Returned field names will not have a prefix.
- *
- * When $collapse is true:
- * If one field is selected, each item in the result array will be this field.
- * If two fields are selected, each item in the result array will have as key
- * the first field and as value the second field.
- * If more then two fields are selected, each item will be an associative array.
- *
- * @since 1.20
- *
- * @param array|string|null $fields
- * @param array $conditions
- * @param array $options
- * @param bool $collapse Set to false to always return each result row as associative array.
- * @param string|null $functionName
- *
- * @return array Array of array
- */
- public function selectFields( $fields = null, array $conditions = array(),
- array $options = array(), $collapse = true, $functionName = null
- ) {
- $objects = array();
-
- $result = $this->rawSelect( $fields, $conditions, $options, $functionName );
-
- foreach ( $result as $record ) {
- $objects[] = $this->getFieldsFromDBResult( $record );
- }
-
- if ( $collapse ) {
- if ( count( $fields ) === 1 ) {
- $objects = array_map( 'array_shift', $objects );
- } elseif ( count( $fields ) === 2 ) {
- $o = array();
-
- foreach ( $objects as $object ) {
- $o[array_shift( $object )] = array_shift( $object );
- }
-
- $objects = $o;
- }
- }
-
- return $objects;
- }
-
- /**
- * Selects the specified fields of the first matching record.
- * Field names get prefixed.
- *
- * @since 1.20
- *
- * @param array|string|null $fields
- * @param array $conditions
- * @param array $options
- * @param string|null $functionName
- *
- * @return IORMRow|bool False on failure
- */
- public function selectRow( $fields = null, array $conditions = array(),
- array $options = array(), $functionName = null
- ) {
- $options['LIMIT'] = 1;
-
- $objects = $this->select( $fields, $conditions, $options, $functionName );
-
- return ( !$objects || $objects->isEmpty() ) ? false : $objects->current();
- }
-
- /**
- * Selects the specified fields of the records matching the provided
- * conditions. Field names do NOT get prefixed.
- *
- * @since 1.20
- *
- * @param array $fields
- * @param array $conditions
- * @param array $options
- * @param string|null $functionName
- *
- * @return stdClass
- */
- public function rawSelectRow( array $fields, array $conditions = array(),
- array $options = array(), $functionName = null
- ) {
- $dbr = $this->getReadDbConnection();
-
- $result = $dbr->selectRow(
- $this->getName(),
- $fields,
- $conditions,
- is_null( $functionName ) ? __METHOD__ : $functionName,
- $options
- );
-
- $this->releaseConnection( $dbr );
-
- return $result;
- }
-
- /**
- * Selects the specified fields of the first record matching the provided
- * conditions and returns it as an associative array, or false when nothing matches.
- * This method makes use of selectFields and expects the same parameters and
- * returns the same results (if there are any, if there are none, this method returns false).
- * @see ORMTable::selectFields
- *
- * @since 1.20
- *
- * @param array|string|null $fields
- * @param array $conditions
- * @param array $options
- * @param bool $collapse Set to false to always return each result row as associative array.
- * @param string|null $functionName
- *
- * @return mixed|array|bool False on failure
- */
- public function selectFieldsRow( $fields = null, array $conditions = array(),
- array $options = array(), $collapse = true, $functionName = null
- ) {
- $options['LIMIT'] = 1;
-
- $objects = $this->selectFields( $fields, $conditions, $options, $collapse, $functionName );
-
- return empty( $objects ) ? false : $objects[0];
- }
-
- /**
- * Returns if there is at least one record matching the provided conditions.
- * Condition field names get prefixed.
- *
- * @since 1.20
- *
- * @param array $conditions
- *
- * @return bool
- */
- public function has( array $conditions = array() ) {
- return $this->selectRow( array( 'id' ), $conditions ) !== false;
- }
-
- /**
- * Checks if the table exists
- *
- * @since 1.21
- *
- * @return bool
- */
- public function exists() {
- $dbr = $this->getReadDbConnection();
- $exists = $dbr->tableExists( $this->getName() );
- $this->releaseConnection( $dbr );
-
- return $exists;
- }
-
- /**
- * Returns the amount of matching records.
- * Condition field names get prefixed.
- *
- * Note that this can be expensive on large tables.
- * In such cases you might want to use DatabaseBase::estimateRowCount instead.
- *
- * @since 1.20
- *
- * @param array $conditions
- * @param array $options
- *
- * @return int
- */
- public function count( array $conditions = array(), array $options = array() ) {
- $res = $this->rawSelectRow(
- array( 'rowcount' => 'COUNT(*)' ),
- $this->getPrefixedValues( $conditions ),
- $options,
- __METHOD__
- );
-
- return $res->rowcount;
- }
-
- /**
- * Removes the object from the database.
- *
- * @since 1.20
- *
- * @param array $conditions
- * @param string|null $functionName
- *
- * @return bool Success indicator
- */
- public function delete( array $conditions, $functionName = null ) {
- $dbw = $this->getWriteDbConnection();
-
- $result = $dbw->delete(
- $this->getName(),
- $conditions === array() ? '*' : $this->getPrefixedValues( $conditions ),
- is_null( $functionName ) ? __METHOD__ : $functionName
- ) !== false; // DatabaseBase::delete does not always return true for success as documented...
-
- $this->releaseConnection( $dbw );
-
- return $result;
- }
-
- /**
- * Get API parameters for the fields supported by this object.
- *
- * @since 1.20
- *
- * @param bool $requireParams
- * @param bool $setDefaults
- *
- * @return array
- */
- public function getAPIParams( $requireParams = false, $setDefaults = false ) {
- $typeMap = array(
- 'id' => 'integer',
- 'int' => 'integer',
- 'float' => 'NULL',
- 'str' => 'string',
- 'bool' => 'integer',
- 'array' => 'string',
- 'blob' => 'string',
- );
-
- $params = array();
- $defaults = $this->getDefaults();
-
- foreach ( $this->getFields() as $field => $type ) {
- if ( $field == 'id' ) {
- continue;
- }
-
- $hasDefault = array_key_exists( $field, $defaults );
-
- $params[$field] = array(
- ApiBase::PARAM_TYPE => $typeMap[$type],
- ApiBase::PARAM_REQUIRED => $requireParams && !$hasDefault
- );
-
- if ( $type == 'array' ) {
- $params[$field][ApiBase::PARAM_ISMULTI] = true;
- }
-
- if ( $setDefaults && $hasDefault ) {
- $default = is_array( $defaults[$field] )
- ? implode( '|', $defaults[$field] )
- : $defaults[$field];
- $params[$field][ApiBase::PARAM_DFLT] = $default;
- }
- }
-
- return $params;
- }
-
- /**
- * Returns an array with the fields and their descriptions.
- *
- * field name => field description
- *
- * @since 1.20
- *
- * @return array
- */
- public function getFieldDescriptions() {
- return array();
- }
-
- /**
- * Get the database ID used for read operations.
- *
- * @since 1.20
- *
- * @return int DB_ enum
- */
- public function getReadDb() {
- return $this->readDb;
- }
-
- /**
- * Set the database ID to use for read operations, use DB_XXX constants or
- * an index to the load balancer setup.
- *
- * @param int $db
- *
- * @since 1.20
- */
- public function setReadDb( $db ) {
- $this->readDb = $db;
- }
-
- /**
- * Get the ID of the any foreign wiki to use as a target for database operations
- *
- * @since 1.20
- *
- * @return string|bool The target wiki, in a form that LBFactory understands
- * (or false if the local wiki is used)
- */
- public function getTargetWiki() {
- return $this->wiki;
- }
-
- /**
- * Set the ID of the any foreign wiki to use as a target for database operations
- *
- * @param string|bool $wiki The target wiki, in a form that LBFactory
- * understands (or false if the local wiki shall be used)
- *
- * @since 1.20
- */
- public function setTargetWiki( $wiki ) {
- $this->wiki = $wiki;
- }
-
- /**
- * Get the database type used for read operations.
- * This is to be used instead of wfGetDB.
- *
- * @see LoadBalancer::getConnection
- *
- * @since 1.20
- *
- * @return DatabaseBase The database object
- */
- public function getReadDbConnection() {
- return $this->getConnection( $this->getReadDb(), array() );
- }
-
- /**
- * Get the database type used for read operations.
- * This is to be used instead of wfGetDB.
- *
- * @see LoadBalancer::getConnection
- *
- * @since 1.20
- *
- * @return DatabaseBase The database object
- */
- public function getWriteDbConnection() {
- return $this->getConnection( DB_MASTER, array() );
- }
-
- /**
- * Releases the lease on the given database connection. This is useful mainly
- * for connections to a foreign wiki. It does nothing for connections to the local wiki.
- *
- * @see LoadBalancer::reuseConnection
- *
- * @param DatabaseBase $db
- *
- * @since 1.20
- */
- // @codingStandardsIgnoreStart Suppress "useless method overriding" sniffer warning
- public function releaseConnection( DatabaseBase $db ) {
- parent::releaseConnection( $db ); // just make it public
- }
- // @codingStandardsIgnoreEnd
-
- /**
- * Update the records matching the provided conditions by
- * setting the fields that are keys in the $values param to
- * their corresponding values.
- *
- * @since 1.20
- *
- * @param array $values
- * @param array $conditions
- *
- * @return bool Success indicator
- */
- public function update( array $values, array $conditions = array() ) {
- $dbw = $this->getWriteDbConnection();
-
- $result = $dbw->update(
- $this->getName(),
- $this->getPrefixedValues( $values ),
- $this->getPrefixedValues( $conditions ),
- __METHOD__
- ) !== false; // DatabaseBase::update does not always return true for success as documented...
-
- $this->releaseConnection( $dbw );
-
- return $result;
- }
-
- /**
- * Computes the values of the summary fields of the objects matching the provided conditions.
- *
- * @since 1.20
- *
- * @param array|string|null $summaryFields
- * @param array $conditions
- */
- public function updateSummaryFields( $summaryFields = null, array $conditions = array() ) {
- $slave = $this->getReadDb();
- $this->setReadDb( DB_MASTER );
-
- /**
- * @var IORMRow $item
- */
- foreach ( $this->select( null, $conditions ) as $item ) {
- $item->loadSummaryFields( $summaryFields );
- $item->setSummaryMode( true );
- $item->save();
- }
-
- $this->setReadDb( $slave );
- }
-
- /**
- * Takes in an associative array with field names as keys and
- * their values as value. The field names are prefixed with the
- * db field prefix.
- *
- * @since 1.20
- *
- * @param array $values
- *
- * @return array
- */
- public function getPrefixedValues( array $values ) {
- $prefixedValues = array();
-
- foreach ( $values as $field => $value ) {
- if ( is_integer( $field ) ) {
- if ( is_array( $value ) ) {
- $field = $value[0];
- $value = $value[1];
- } else {
- $value = explode( ' ', $value, 2 );
- $value[0] = $this->getPrefixedField( $value[0] );
- $prefixedValues[] = implode( ' ', $value );
- continue;
- }
- }
-
- $prefixedValues[$this->getPrefixedField( $field )] = $value;
- }
-
- return $prefixedValues;
- }
-
- /**
- * Takes in a field or array of fields and returns an
- * array with their prefixed versions, ready for db usage.
- *
- * @since 1.20
- *
- * @param array $fields
- *
- * @return array
- */
- public function getPrefixedFields( array $fields ) {
- foreach ( $fields as &$field ) {
- $field = $this->getPrefixedField( $field );
- }
-
- return $fields;
- }
-
- /**
- * Takes in a field and returns an it's prefixed version, ready for db usage.
- *
- * @since 1.20
- *
- * @param string|array $field
- *
- * @return string
- */
- public function getPrefixedField( $field ) {
- return $this->fieldPrefix . $field;
- }
-
- /**
- * Takes an array of field names with prefix and returns the unprefixed equivalent.
- *
- * @since 1.20
- * @deprecated since 1.25, will be removed
- *
- * @param string[] $fieldNames
- *
- * @return string[]
- */
- public function unprefixFieldNames( array $fieldNames ) {
- wfDeprecated( __METHOD__, '1.25' );
-
- return $this->stripFieldPrefix( $fieldNames );
- }
-
- /**
- * Takes an array of field names with prefix and returns the unprefixed equivalent.
- *
- * @param string[] $fieldNames
- *
- * @return string[]
- */
- private function stripFieldPrefix( array $fieldNames ) {
- $start = strlen( $this->fieldPrefix );
-
- return array_map( function ( $fieldName ) use ( $start ) {
- return substr( $fieldName, $start );
- }, $fieldNames );
- }
-
- /**
- * Takes a field name with prefix and returns the unprefixed equivalent.
- *
- * @since 1.20
- * @deprecated since 1.25, will be removed
- *
- * @param string $fieldName
- *
- * @return string
- */
- public function unprefixFieldName( $fieldName ) {
- wfDeprecated( __METHOD__, '1.25' );
-
- return substr( $fieldName, strlen( $this->fieldPrefix ) );
- }
-
- /**
- * Get an instance of this class.
- *
- * @since 1.20
- * @deprecated since 1.21
- *
- * @return IORMTable
- */
- public static function singleton() {
- $class = get_called_class();
-
- if ( !array_key_exists( $class, self::$instanceCache ) ) {
- self::$instanceCache[$class] = new $class;
- }
-
- return self::$instanceCache[$class];
- }
-
- /**
- * Get an array with fields from a database result,
- * that can be fed directly to the constructor or
- * to setFields.
- *
- * @since 1.20
- *
- * @param stdClass $result
- * @throws MWException
- * @return array
- */
- public function getFieldsFromDBResult( stdClass $result ) {
- $result = (array)$result;
-
- $rawFields = array_combine(
- $this->stripFieldPrefix( array_keys( $result ) ),
- array_values( $result )
- );
-
- $fieldDefinitions = $this->getFields();
- $fields = array();
-
- foreach ( $rawFields as $name => $value ) {
- if ( array_key_exists( $name, $fieldDefinitions ) ) {
- switch ( $fieldDefinitions[$name] ) {
- case 'int':
- $value = (int)$value;
- break;
- case 'float':
- $value = (float)$value;
- break;
- case 'bool':
- if ( is_string( $value ) ) {
- $value = $value !== '0';
- } elseif ( is_int( $value ) ) {
- $value = $value !== 0;
- }
- break;
- case 'array':
- if ( is_string( $value ) ) {
- $value = unserialize( $value );
- }
-
- if ( !is_array( $value ) ) {
- $value = array();
- }
- break;
- case 'blob':
- if ( is_string( $value ) ) {
- $value = unserialize( $value );
- }
- break;
- case 'id':
- if ( is_string( $value ) ) {
- $value = (int)$value;
- }
- break;
- }
-
- $fields[$name] = $value;
- } else {
- throw new MWException( 'Attempted to set unknown field ' . $name );
- }
- }
-
- return $fields;
- }
-
- /**
- * @see ORMTable::newRowFromFromDBResult
- *
- * @deprecated since 1.20 use newRowFromDBResult instead
- * @since 1.20
- *
- * @param stdClass $result
- *
- * @return IORMRow
- */
- public function newFromDBResult( stdClass $result ) {
- return self::newRowFromDBResult( $result );
- }
-
- /**
- * Get a new instance of the class from a database result.
- *
- * @since 1.20
- *
- * @param stdClass $result
- *
- * @return IORMRow
- */
- public function newRowFromDBResult( stdClass $result ) {
- return $this->newRow( $this->getFieldsFromDBResult( $result ) );
- }
-
- /**
- * @see ORMTable::newRow
- *
- * @deprecated since 1.20 use newRow instead
- * @since 1.20
- *
- * @param array $data
- * @param bool $loadDefaults
- *
- * @return IORMRow
- */
- public function newFromArray( array $data, $loadDefaults = false ) {
- return static::newRow( $data, $loadDefaults );
- }
-
- /**
- * Get a new instance of the class from an array.
- *
- * @since 1.20
- *
- * @param array $fields
- * @param bool $loadDefaults
- *
- * @return IORMRow
- */
- public function newRow( array $fields, $loadDefaults = false ) {
- $class = $this->getRowClass();
-
- return new $class( $this, $fields, $loadDefaults );
- }
-
- /**
- * Return the names of the fields.
- *
- * @since 1.20
- *
- * @return array
- */
- public function getFieldNames() {
- return array_keys( $this->getFields() );
- }
-
- /**
- * Gets if the object can take a certain field.
- *
- * @since 1.20
- *
- * @param string $name
- *
- * @return bool
- */
- public function canHaveField( $name ) {
- return array_key_exists( $name, $this->getFields() );
- }
-
- /**
- * Updates the provided row in the database.
- *
- * @since 1.22
- *
- * @param IORMRow $row The row to save
- * @param string|null $functionName
- *
- * @return bool Success indicator
- */
- public function updateRow( IORMRow $row, $functionName = null ) {
- $dbw = $this->getWriteDbConnection();
-
- $success = $dbw->update(
- $this->getName(),
- $this->getWriteValues( $row ),
- $this->getPrefixedValues( array( 'id' => $row->getId() ) ),
- is_null( $functionName ) ? __METHOD__ : $functionName
- );
-
- $this->releaseConnection( $dbw );
-
- // DatabaseBase::update does not always return true for success as documented...
- return $success !== false;
- }
-
- /**
- * Inserts the provided row into the database.
- *
- * @since 1.22
- *
- * @param IORMRow $row
- * @param string|null $functionName
- * @param array|null $options
- *
- * @return bool Success indicator
- */
- public function insertRow( IORMRow $row, $functionName = null, array $options = null ) {
- $dbw = $this->getWriteDbConnection();
-
- $success = $dbw->insert(
- $this->getName(),
- $this->getWriteValues( $row ),
- is_null( $functionName ) ? __METHOD__ : $functionName,
- $options
- );
-
- // DatabaseBase::insert does not always return true for success as documented...
- $success = $success !== false;
-
- if ( $success ) {
- $row->setField( 'id', $dbw->insertId() );
- }
-
- $this->releaseConnection( $dbw );
-
- return $success;
- }
-
- /**
- * Gets the fields => values to write to the table.
- *
- * @since 1.22
- *
- * @param IORMRow $row
- *
- * @return array
- */
- protected function getWriteValues( IORMRow $row ) {
- $values = array();
-
- $rowFields = $row->getFields();
-
- foreach ( $this->getFields() as $name => $type ) {
- if ( array_key_exists( $name, $rowFields ) ) {
- $value = $rowFields[$name];
-
- switch ( $type ) {
- case 'array':
- $value = (array)$value;
- // fall-through!
- case 'blob':
- $value = serialize( $value );
- // fall-through!
- }
-
- $values[$this->getPrefixedField( $name )] = $value;
- }
- }
-
- return $values;
- }
-
- /**
- * Removes the provided row from the database.
- *
- * @since 1.22
- *
- * @param IORMRow $row
- * @param string|null $functionName
- *
- * @return bool Success indicator
- */
- public function removeRow( IORMRow $row, $functionName = null ) {
- $success = $this->delete(
- array( 'id' => $row->getId() ),
- is_null( $functionName ) ? __METHOD__ : $functionName
- );
-
- // DatabaseBase::delete does not always return true for success as documented...
- return $success !== false;
- }
-
- /**
- * Add an amount (can be negative) to the specified field (needs to be numeric).
- *
- * @since 1.22
- *
- * @param array $conditions
- * @param string $field
- * @param int $amount
- *
- * @return bool Success indicator
- * @throws MWException
- */
- public function addToField( array $conditions, $field, $amount ) {
- if ( !array_key_exists( $field, $this->fields ) ) {
- throw new MWException( 'Unknown field "' . $field . '" provided' );
- }
-
- if ( $amount == 0 ) {
- return true;
- }
-
- $absoluteAmount = abs( $amount );
- $isNegative = $amount < 0;
-
- $fullField = $this->getPrefixedField( $field );
-
- $dbw = $this->getWriteDbConnection();
-
- $success = $dbw->update(
- $this->getName(),
- array( "$fullField=$fullField" . ( $isNegative ? '-' : '+' ) . $absoluteAmount ),
- $this->getPrefixedValues( $conditions ),
- __METHOD__
- ) !== false; // DatabaseBase::update does not always return true for success as documented...
-
- $this->releaseConnection( $dbw );
-
- return $success;
- }
-}
*/
private $linkDeletions = null;
+ /**
+ * @var User|null
+ */
+ private $user;
+
/**
* Constructor
*
$this->mRevision = $revision;
}
+ /**
+ * Set the User who triggered this LinksUpdate
+ *
+ * @since 1.27
+ * @param User $user
+ */
+ public function setTriggeringUser( User $user ) {
+ $this->user = $user;
+ }
+
+ /**
+ * @since 1.27
+ * @return null|User
+ */
+ public function getTriggeringUser() {
+ return $this->user;
+ }
+
/**
* Invalidate any necessary link lists related to page property changes
* @param array $changed
}
public function getAsJobSpecification() {
+ if ( $this->user ) {
+ $userInfo = array(
+ 'userId' => $this->user->getId(),
+ 'userName' => $this->user->getName(),
+ );
+ } else {
+ $userInfo = false;
+ }
return array(
'wiki' => $this->mDb->getWikiID(),
'job' => new JobSpecification(
array(
// Reuse the parser cache if it was saved
'rootJobTimestamp' => $this->mParserOutput->getCacheTime(),
- 'useRecursiveLinksUpdate' => $this->mRecursive
+ 'useRecursiveLinksUpdate' => $this->mRecursive,
+ 'triggeringUser' => $userInfo,
),
array( 'removeDuplicates' => true ),
$this->getTitle()
);
protected $fileFactory = array( 'ForeignAPIFile', 'newFromTitle' );
- /** @var int Check back with Commons after a day (24*60*60) */
- protected $apiThumbCacheExpiry = 86400;
+ /** @var int Check back with Commons after this expiry */
+ protected $apiThumbCacheExpiry = 86400; // 1 day (24*3600)
- /** @var int Redownload thumbnail files after a month (86400*30) */
- protected $fileCacheExpiry = 2592000;
+ /** @var int Redownload thumbnail files after this expiry */
+ protected $fileCacheExpiry = 2592000; // 1 month (30*24*3600)
/** @var array */
protected $mFileExists = array();
function getInputOOUI( $value ) {
$options = array();
- foreach ( $this->getOptions() as $label => $value ) {
+ foreach ( $this->getOptions() as $label => $data ) {
$options[] = array(
- 'data' => $value,
+ 'data' => $data,
'label' => $this->mOptionsLabelsNotFromMessage ? new OOUI\HtmlSnippet( $label ) : $label,
);
}
"ערן",
"아라",
"Inkbug",
- "Yona b"
+ "Yona b",
+ "Rotemliss"
]
},
"config-desc": "תכנית ההתקנה של מדיה־ויקי",
"config-db-install-account": "חשבון משתמש להתקנה",
"config-db-username": "שם המשתמש במסד הנתונים:",
"config-db-password": "הססמה במסד הנתונים:",
- "config-db-password-empty": "נא להזין ססמה למשתמש מסד הנתונים החדש: $1.\nאף־על־פי שאפשר ליצור חשבונות ללא ססמה, זה לא מאובטח.",
- "config-db-username-empty": "יש להזין ערך עבור \"{{int:config-db-username}}\".",
"config-db-install-username": "יש להכניס שם משתמש שישמש לחיבור למסד נתונים במהלך ההתקנה.\nזהו לא שם משתמש לחשבון במדיה־ויקי; זהו שם משתמש בשרת מסד נתונים.",
"config-db-install-password": "יש להקליד ססמה שתשמש אותך לצורך חיבור למסד נתונים במהלך ההתקנה.\nזוהי לא ססמה של חשבון במדיה־ויקי; זוהי ססמה לשרת מסד נתונים.",
"config-db-install-help": "יש להקליד את שם המשתמש ואת הססמה להתחברות למסד הנתונים במהלך ההתקנה.",
"config-nofile": "הקובץ \"$1\" לא נמצא. האם הוא נמחק?",
"config-extension-link": "הידעת שמדיה־ויקי תומכת ב־[//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions הרחבות]?\n\nבאפשרותך לעיין ב־[//www.mediawiki.org/wiki/Special:MyLanguage/Category:Extensions_by_category הרחבות לפי קטגוריה].",
"mainpagetext": "'''תוכנת מדיה־ויקי הותקנה בהצלחה.'''",
- "mainpagedocfooter": "היעזרו ב[//meta.wikimedia.org/wiki/Help:Contents מדריך למשתמש] למידע על שימוש בתוכנת הוויקי.\n\n== קישורים שימושיים ==\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings רשימת ההגדרות]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ שאלות ותשובות על מדיה־ויקי]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce רשימת התפוצה על השקת גרסאות]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources תרגום מדיה־ויקי לשפה שלך]"
+ "mainpagedocfooter": "היעזרו ב[//meta.wikimedia.org/wiki/Help:Contents מדריך למשתמש] למידע על שימוש בתוכנת הוויקי.\n\n== קישורים שימושיים ==\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings רשימת ההגדרות]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ שאלות ותשובות על מדיה־ויקי]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce רשימת התפוצה על השקת גרסאות]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources תרגום מדיה־ויקי לשפה שלך]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam איך להיאבק נגד ספאם באתר הוויקי שלך]"
}
"config-nofile": "Nie udało się odnaleźć pliku \"$1\". Czy nie został usunięty?",
"config-extension-link": "Czy wiesz, że twoja wiki obsługuje [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Extensions/pl rozszerzenia]?\n\nMożesz przejrzeć [//www.mediawiki.org/wiki/Special:MyLanguage/Category:Extensions_by_category rozszerzenia według kategorii] lub [//www.mediawiki.org/wiki/Extension_Matrix Extension Matrix] aby zobaczyć pełną listę rozszerzeń.",
"mainpagetext": "'''Instalacja MediaWiki powiodła się.'''",
- "mainpagedocfooter": "Zobacz [//meta.wikimedia.org/wiki/Help:Contents przewodnik użytkownika] w celu uzyskania informacji o działaniu oprogramowania wiki.\n\n== Na początek ==\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings/pl Lista ustawień konfiguracyjnych]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ/pl MediaWiki FAQ]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Komunikaty o nowych wersjach MediaWiki]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Przetłumacz MediaWiki na swój język]"
+ "mainpagedocfooter": "Zobacz [//meta.wikimedia.org/wiki/Help:Contents przewodnik użytkownika], aby uzyskać informacje o działaniu oprogramowania wiki.\n\n== Na początek ==\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings/pl Lista ustawień konfiguracyjnych]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ/pl MediaWiki FAQ]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Komunikaty o nowych wersjach MediaWiki]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Przetłumacz MediaWiki na swój język]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam \nDowiedz się, jak walczyć ze spamem na swojej wiki]"
}
"config-help": "ajute",
"config-help-tooltip": "cazze pe spannere",
"mainpagetext": "'''MediaUicchi ha state 'nstallete.'''",
- "mainpagedocfooter": "Vè vide [//meta.wikimedia.org/wiki/Help:Contents User's Guide] pe l'mbormaziune sus a cumme s'ause 'u softuer wiki.\n\n== Pe accumenzà ==\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Liste pe le configuraziune]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ FAQ de MediaWiki]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Elenghe d'a poste de MediaUicchi]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Localizzazzione de MediaUicchi pa lènga toje]"
+ "mainpagedocfooter": "Vè 'ndruche [//meta.wikimedia.org/wiki/Help:Contents User's Guide] pe l'mbormaziune sus a cumme s'ause 'u softuer uicchi.\n\n== Pe accumenzà ==\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings Elenghe de le 'mbostaziune pa configurazione]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ FAQ de MediaUicchi]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce Elenghe d'a poste de MediaUicchi]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources Localizzazzione de MediaUicchi pa lènga toje]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam 'Mbare accume combattere condre a 'u rummate sus 'a uicchi toje]"
}
"config-help": "הילף",
"config-nofile": "מ'האט נישט געקענט טרעפן די טעקע \"$1\". צי האט מען זי אויסגעמעקט?",
"mainpagetext": "'''מעדיעוויקי אינסטאלירט מיט דערפאלג.'''",
- "mainpagedocfooter": "גיט זיך אן עצה מיט [//meta.wikimedia.org/wiki/Help:Contents באניצער'ס וועגווײַזער] פֿאר אינפֿארמאציע וויאזוי זיך באנוצן מיט וויקי ווייכוואַרג.\n\n== נוצליכע וועבלינקען פֿאַר אנהייבערס ==\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings רשימה פון קאנפֿיגוראציעס]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ אפֿט געפֿרעגטע שאלות]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce מעדיעוויקי באפֿרײַאונג פאסטליסטע]* [//www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources איבערזעצן מעדיעוויקי אין אײַער שפראך]"
+ "mainpagedocfooter": "גיט זיך אן עצה מיט [//meta.wikimedia.org/wiki/Help:Contents באניצער'ס וועגווײַזער] פֿאר אינפֿארמאציע וויאזוי זיך באנוצן מיט וויקי ווייכוואַרג.\n\n== נוצליכע וועבלינקען פֿאַר אנהייבערס ==\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Configuration_settings רשימה פון קאנפֿיגוראציעס]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:FAQ אפֿט געפֿרעגטע שאלות]\n* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce מעדיעוויקי באפֿרײַאונג פאסטליסטע]* [//www.mediawiki.org/wiki/Special:MyLanguage/Localisation#Translation_resources איבערזעצן מעדיעוויקי אין אײַער שפראך]\n* [//www.mediawiki.org/wiki/Special:MyLanguage/Manual:Combating_spam לערנט וויאזוי צו באקעמפן בפעם אויף אייער וויקי]"
}
return $value['v'];
} else {
$value = $wgConf->getConfig( $this->wiki, $name );
- $cache->set( $key, array( 'v' => $value ), 86400 + mt_rand( 0, 86400 ) );
+ $cache->set(
+ $key,
+ array( 'v' => $value ),
+ $cache::TTL_DAY + mt_rand( 0, $cache::TTL_DAY )
+ );
return $value;
}
}
}
JobQueue::incrStats( 'inserts', $this->type, count( $items ) );
- JobQueue::incrStats( 'inserts_actual', $pushed );
+ JobQueue::incrStats( 'inserts_actual', $this->type, $pushed );
JobQueue::incrStats( 'dupe_inserts', $this->type,
count( $items ) - $failed - $pushed );
if ( $failed > 0 ) {
$updates = $content->getSecondaryDataUpdates(
$title, null, !empty( $this->params['useRecursiveLinksUpdate'] ), $parserOutput );
foreach ( $updates as $key => $update ) {
- if ( $update instanceof LinksUpdate && isset( $this->params['triggeredRecursive'] ) ) {
- $update->setTriggeredRecursive();
+ if ( $update instanceof LinksUpdate ) {
+ if ( isset( $this->params['triggeredRecursive'] ) ) {
+ $update->setTriggeredRecursive();
+ }
+ if ( isset( $this->params['triggeringUser'] ) && $this->params['triggeringUser'] ) {
+ $userInfo = $this->params['triggeringUser'];
+ if ( $userInfo['userId'] ) {
+ $user = User::newFromId( $userInfo['userId'] );
+ } else {
+ // Anonymous, use the username
+ $user = User::newFromName( $userInfo['userName'], false );
+ }
+ $update->setTriggeringUser( $user );
+ }
}
}
}
for ( $i = 0; $i < $stats['ct']; $i++ ) {
- $this->inclusive[$child][$stat]->push(
+ $this->inclusive[$child][$stat]->addObservation(
$value / $stats['ct']
);
}
*
* @ingroup Cache
*/
-abstract class BagOStuff implements LoggerAwareInterface {
+abstract class BagOStuff implements IExpiringStore, LoggerAwareInterface {
/** @var array[] Lock tracking */
protected $locks = array();
do {
$this->clearLastError();
$casToken = null; // passed by reference
- $currentValue = $this->getWithToken( $key, $casToken, BagOStuff::READ_LATEST );
+ $currentValue = $this->getWithToken( $key, $casToken, self::READ_LATEST );
if ( $this->getLastError() ) {
return false; // don't spam retries (retry only on races)
}
}
$this->clearLastError();
- $currentValue = $this->get( $key, BagOStuff::READ_LATEST );
+ $currentValue = $this->get( $key, self::READ_LATEST );
if ( $this->getLastError() ) {
$success = false;
} else {
}
}
- $expiry = min( $expiry ?: INF, 86400 );
+ $expiry = min( $expiry ?: INF, self::TTL_DAY );
$this->clearLastError();
$timestamp = microtime( true ); // starting UNIX timestamp
* @since 1.26
*/
final public function getScopedLock( $key, $timeout = 6, $expiry = 30, $rclass = '' ) {
- $expiry = min( $expiry ?: INF, 86400 );
+ $expiry = min( $expiry ?: INF, self::TTL_DAY );
if ( !$this->lock( $key, $timeout, $expiry, $rclass ) ) {
return null;
* @return int
*/
protected function convertExpiry( $exptime ) {
- if ( ( $exptime != 0 ) && ( $exptime < 86400 * 3650 /* 10 years */ ) ) {
+ if ( $exptime != 0 && $exptime < ( 10 * self::TTL_YEAR ) ) {
return time() + $exptime;
} else {
return $exptime;
* @return int
*/
protected function convertToRelative( $exptime ) {
- if ( $exptime >= 86400 * 3650 /* 10 years */ ) {
+ if ( $exptime >= ( 10 * self::TTL_YEAR ) ) {
$exptime -= time();
if ( $exptime <= 0 ) {
$exptime = 1;
--- /dev/null
+<?php
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Cache
+ * @author 2015 Timo Tijhof
+ */
+
+/**
+ * Generic base class for storage interfaces.
+ *
+ * Provides convenient TTL constants.
+ *
+ * @ingroup Cache
+ * @since 1.27
+ */
+interface IExpiringStore {
+
+ // Constants for TTL values, in seconds
+ const TTL_MINUTE = 60;
+ const TTL_HOUR = 3600;
+ const TTL_DAY = 86400; // 24 * 3600
+ const TTL_WEEK = 604800; // 7 * 24 * 3600
+ const TTL_MONTH = 2592000; // 30 * 24 * 3600
+ const TTL_YEAR = 31536000; // 365 * 24 * 3600
+}
* @ingroup Cache
* @since 1.26
*/
-class WANObjectCache implements LoggerAwareInterface {
+class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
/** @var BagOStuff The local datacenter cache */
protected $cache;
/** @var HashBagOStuff Script instance PHP cache */
/** Max time expected to pass between delete() and DB commit finishing */
const MAX_COMMIT_DELAY = 3;
- /** Max replication lag before applying TTL_LAGGED to set() */
- const MAX_REPLICA_LAG = 5;
- /** Max time since snapshot transaction start to avoid no-op of set() */
- const MAX_SNAPSHOT_LAG = 5;
+ /** Max replication+snapshot lag before applying TTL_LAGGED or disallowing set() */
+ const MAX_READ_LAG = 7;
/** Seconds to tombstone keys on delete() */
- const HOLDOFF_TTL = 14; // MAX_COMMIT_DELAY + MAX_REPLICA_LAG + MAX_SNAPSHOT_LAG + 1
+ const HOLDOFF_TTL = 11; // MAX_COMMIT_DELAY + MAX_READ_LAG + 1
/** Seconds to keep dependency purge keys around */
- const CHECK_KEY_TTL = 31536000; // 1 year
+ const CHECK_KEY_TTL = self::TTL_YEAR;
/** Seconds to keep lock keys around */
- const LOCK_TTL = 5;
+ const LOCK_TTL = 10;
/** Default remaining TTL at which to consider pre-emptive regeneration */
const LOW_TTL = 30;
/** Default time-since-expiry on a miss that makes a key "hot" */
/** Max TTL to store keys when a data sourced is lagged */
const TTL_LAGGED = 30;
+ /** Tiny negative float to use when CTL comes up >= 0 due to clock skew */
+ const TINY_NEGATIVE = -0.000001;
+
/** Cache format version number */
const VERSION = 1;
const FLD_VALUE = 1;
const FLD_TTL = 2;
const FLD_TIME = 3;
+ const FLD_FLAGS = 4;
+
+ /** @var integer Treat this value as expired-on-arrival */
+ const FLG_STALE = 1;
const ERR_NONE = 0; // no error
const ERR_NO_RESPONSE = 1; // no response
/**
* Fetch the value of a key from cache
*
- * If passed in, $curTTL is set to the remaining TTL (current time left):
- * - a) INF; if the key exists, has no TTL, and is not expired by $checkKeys
- * - b) float (>=0); if the key exists, has a TTL, and is not expired by $checkKeys
- * - c) float (<0); if the key is tombstoned or existing but expired by $checkKeys
- * - d) null; if the key does not exist and is not tombstoned
+ * If supplied, $curTTL is set to the remaining TTL (current time left):
+ * - a) INF; if $key exists, has no TTL, and is not expired by $checkKeys
+ * - b) float (>=0); if $key exists, has a TTL, and is not expired by $checkKeys
+ * - c) float (<0); if $key is tombstoned, stale, or existing but expired by $checkKeys
+ * - d) null; if $key does not exist and is not tombstoned
*
* If a key is tombstoned, $curTTL will reflect the time since delete().
*
* // Fetch the row from the DB
* $row = $dbr->selectRow( ... );
* $key = $cache->makeKey( 'building', $buildingId );
- * $cache->set( $key, $row, 86400, $setOpts );
+ * $cache->set( $key, $row, $cache::TTL_DAY, $setOpts );
* @endcode
*
* @param string $key Cache key
* Generally, other threads should not see values from the future and
* they certainly should not see ones that ended up getting rolled back.
* Default: false
- * - lockTSE : if excessive possible snapshot lag is detected,
- * then stash the value into a temporary location
- * with this TTL. This is only useful if the reads
- * use getWithSetCallback() with "lockTSE" set.
+ * - lockTSE : if excessive replication/snapshot lag is detected, then store the value
+ * with this TTL and flag it as stale. This is only useful if the reads for
+ * this key use getWithSetCallback() with "lockTSE" set.
* Default: WANObjectCache::TSE_NONE
* @return bool Success
*/
$age = isset( $opts['since'] ) ? max( 0, microtime( true ) - $opts['since'] ) : 0;
$lag = isset( $opts['lag'] ) ? $opts['lag'] : 0;
+ // Do not cache potentially uncommitted data as it might get rolled back
if ( !empty( $opts['pending'] ) ) {
$this->logger->info( "Rejected set() for $key due to pending writes." );
return true; // no-op the write for being unsafe
}
- if ( $lag > self::MAX_REPLICA_LAG ) {
- // Too much lag detected; lower TTL so it converges faster
- $ttl = $ttl ? min( $ttl, self::TTL_LAGGED ) : self::TTL_LAGGED;
- $this->logger->warning( "Lowered set() TTL for $key due to replication lag." );
- }
-
- if ( $age > self::MAX_SNAPSHOT_LAG ) {
+ $wrapExtra = array(); // additional wrapped value fields
+ // Check if there's a risk of writing stale data after the purge tombstone expired
+ if ( ( $lag + $age ) > self::MAX_READ_LAG ) {
+ // Case A: read lag with "lockTSE"; save but record value as stale
if ( $lockTSE >= 0 ) {
- $tempTTL = max( 1, (int)$lockTSE ); // set() expects seconds
- $this->cache->set( self::STASH_KEY_PREFIX . $key, $value, $tempTTL );
- }
- $this->logger->warning( "Rejected set() for $key due to snapshot lag." );
+ $ttl = max( 1, (int)$lockTSE ); // set() expects seconds
+ $wrapExtra[self::FLD_FLAGS] = self::FLG_STALE; // mark as stale
+ // Case B: any long-running transaction; ignore this set()
+ } elseif ( $age > self::MAX_READ_LAG ) {
+ $this->logger->warning( "Rejected set() for $key due to snapshot lag." );
+
+ return true; // no-op the write for being unsafe
+ // Case C: high replication lag; lower TTL instead of ignoring all set()s
+ } elseif ( $lag > self::MAX_READ_LAG ) {
+ $ttl = $ttl ? min( $ttl, self::TTL_LAGGED ) : self::TTL_LAGGED;
+ $this->logger->warning( "Lowered set() TTL for $key due to replication lag." );
+ // Case D: medium length request with medium replication lag; ignore this set()
+ } else {
+ $this->logger->warning( "Rejected set() for $key due to high read lag." );
- return true; // no-op the write for being unsafe
+ return true; // no-op the write for being unsafe
+ }
}
- $wrapped = $this->wrap( $value, $ttl );
+ // Wrap that value with time/TTL/version metadata
+ $wrapped = $this->wrap( $value, $ttl ) + $wrapExtra;
$func = function ( $cache, $key, $cWrapped ) use ( $wrapped ) {
return ( is_string( $cWrapped ) )
* $dbw->commit(); // end of request
* @endcode
*
- * If called twice on the same key, then the last hold-off TTL takes
- * precedence. For idempotence, the $ttl should not vary for different
- * delete() calls on the same key. Also note that lowering $ttl reduces
- * the effective range of the 'lockTSE' parameter to getWithSetCallback().
+ * The $ttl parameter can be used when purging values that have not actually changed
+ * recently. For example, a cleanup script to purge cache entries does not really need
+ * a hold-off period, so it can use the value 1. Likewise for user-requested purge.
+ * Note that $ttl limits the effective range of 'lockTSE' for getWithSetCallback().
+ *
+ * If called twice on the same key, then the last hold-off TTL takes precedence. For
+ * idempotence, the $ttl should not vary for different delete() calls on the same key.
*
* @param string $key Cache key
- * @param integer $ttl How long to block writes to the key [seconds]
+ * @param integer $ttl Tombstone TTL; Default: WANObjectCache::HOLDOFF_TTL
* @return bool True if the item was purged or not found, false on failure
*/
final public function delete( $key, $ttl = self::HOLDOFF_TTL ) {
* $catInfo = $cache->getWithSetCallback(
* // Key to store the cached value under
* $cache->makeKey( 'cat-attributes', $catId ),
- * // Time-to-live (seconds)
- * 60,
+ * // Time-to-live (in seconds)
+ * $cache::TTL_MINUTE,
* // Function that derives the new key value
* function ( $oldValue, &$ttl, array &$setOpts ) {
* $dbr = wfGetDB( DB_SLAVE );
* $catConfig = $cache->getWithSetCallback(
* // Key to store the cached value under
* $cache->makeKey( 'site-cat-config' ),
- * // Time-to-live (seconds)
- * 86400,
+ * // Time-to-live (in seconds)
+ * $cache::TTL_DAY,
* // Function that derives the new key value
* function ( $oldValue, &$ttl, array &$setOpts ) {
* $dbr = wfGetDB( DB_SLAVE );
* // Key to store the cached value under
* $cache->makeKey( 'cat-state', $cat->getId() ),
* // Time-to-live (seconds)
- * 900,
+ * $cache::TTL_HOUR,
* // Function that derives the new key value
* function ( $oldValue, &$ttl, array &$setOpts ) {
* // Determine new value from the DB
* $lastCatActions = $cache->getWithSetCallback(
* // Key to store the cached value under
* $cache->makeKey( 'cat-last-actions', 100 ),
- * // Time-to-live (seconds)
+ * // Time-to-live (in seconds)
* 10,
* // Function that derives the new key value
* function ( $oldValue, &$ttl, array &$setOpts ) {
*
* @param mixed $value
* @param integer $ttl [0=forever]
- * @return string
+ * @return array
*/
protected function wrap( $value, $ttl ) {
return array(
$purgeTimestamp = self::parsePurgeValue( $wrapped );
if ( is_float( $purgeTimestamp ) ) {
// Purged values should always have a negative current $ttl
- $curTTL = min( -0.000001, $purgeTimestamp - $now );
+ $curTTL = min( $purgeTimestamp - $now, self::TINY_NEGATIVE );
return array( false, $curTTL );
}
return array( false, null );
}
- if ( $wrapped[self::FLD_TTL] > 0 ) {
+ $flags = isset( $wrapped[self::FLD_FLAGS] ) ? $wrapped[self::FLD_FLAGS] : 0;
+ if ( ( $flags & self::FLG_STALE ) == self::FLG_STALE ) {
+ // Treat as expired, with the cache time as the expiration
+ $age = $now - $wrapped[self::FLD_TIME];
+ $curTTL = min( -$age, self::TINY_NEGATIVE );
+ } elseif ( $wrapped[self::FLD_TTL] > 0 ) {
// Get the approximate time left on the key
$age = $now - $wrapped[self::FLD_TIME];
$curTTL = max( $wrapped[self::FLD_TTL] - $age, 0.0 );
* @param bool $gettext DOCUMENT (Default: false)
* @return bool|SimpleXMLElement
*/
- function getMetaTree( $image, $gettext = false ) {
+ public function getMetaTree( $image, $gettext = false ) {
if ( $gettext && isset( $image->djvuTextTree ) ) {
return $image->djvuTextTree;
}
// Set to false rather than null to avoid further attempts
$image->dejaMetaTree = false;
$image->djvuTextTree = false;
- $tree = new SimpleXMLElement( $metadata );
+ $tree = new SimpleXMLElement( $metadata, LIBXML_PARSEHUGE );
if ( $tree->getName() == 'mw-djvu' ) {
/** @var SimpleXMLElement $b */
foreach ( $tree->children() as $b ) {
return !empty( $metadata ) && $metadata != serialize( array() );
}
- function pageCount( $image ) {
- global $wgMemc;
+ function pageCount( File $image ) {
+ $info = $this->getDimensionInfo( $image );
- $key = wfMemcKey( 'file-djvu', 'pageCount', $image->getSha1() );
+ return $info ? $info['pageCount'] : false;
+ }
- $count = $wgMemc->get( $key );
- if ( $count === false ) {
- $tree = $this->getMetaTree( $image );
- if ( !$tree ) {
- return false;
- }
- $count = count( $tree->xpath( '//OBJECT' ) );
- $wgMemc->set( $key, $count );
+ function getPageDimensions( File $image, $page ) {
+ $index = $page - 1; // MW starts pages at 1
+
+ $info = $this->getDimensionInfo( $image );
+ if ( $info && isset( $info['dimensionsByPage'][$index] ) ) {
+ return $info['dimensionsByPage'][$index];
}
- return $count;
+ return false;
}
- function getPageDimensions( $image, $page ) {
- global $wgMemc;
-
- $key = wfMemcKey( 'file-djvu', 'dimensions', $image->getSha1() );
-
- $dimsByPage = $wgMemc->get( $key );
- if ( !is_array( $dimsByPage ) ) {
- $tree = $this->getMetaTree( $image );
- if ( !$tree ) {
- return false;
- }
+ protected function getDimensionInfo( File $file ) {
+ $that = $this;
- $dimsByPage = array();
- $count = count( $tree->xpath( '//OBJECT' ) );
- for ( $i = 0; $i < $count; ++$i ) {
- $o = $tree->BODY[0]->OBJECT[$i];
- if ( $o ) {
- $dimsByPage[$i] = array(
- 'width' => (int)$o['width'],
- 'height' => (int)$o['height']
- );
- } else {
- $dimsByPage[$i] = false;
+ return ObjectCache::getMainWANInstance()->getWithSetCallback(
+ wfMemcKey( 'file-djvu', 'dimensions', $file->getSha1() ),
+ WANObjectCache::TTL_INDEFINITE,
+ function () use ( $that, $file ) {
+ $tree = $that->getMetaTree( $file );
+ if ( !$tree ) {
+ return false;
}
- }
-
- $wgMemc->set( $key, $dimsByPage );
- }
- $index = $page - 1; // MW starts pages at 1
+ $dimsByPage = array();
+ $count = count( $tree->xpath( '//OBJECT' ) );
+ for ( $i = 0; $i < $count; ++$i ) {
+ $o = $tree->BODY[0]->OBJECT[$i];
+ if ( $o ) {
+ $dimsByPage[$i] = array(
+ 'width' => (int)$o['width'],
+ 'height' => (int)$o['height']
+ );
+ } else {
+ $dimsByPage[$i] = false;
+ }
+ }
- return isset( $dimsByPage[$index] ) ? $dimsByPage[$index] : false;
+ return array( 'pageCount' => $count, 'dimensionsByPage' => $dimsByPage );
+ }
+ );
}
/**
* @param int $page Page number to get information for
* @return bool|string Page text or false when no text found.
*/
- function getPageText( $image, $page ) {
+ function getPageText( File $image, $page ) {
$tree = $this->getMetaTree( $image, true );
if ( !$tree ) {
return false;
* @since 1.23
*/
public function fetchExtendedMetadata( File $file ) {
- global $wgMemc;
+ $cache = ObjectCache::getMainWANInstance();
// If revision deleted, exit immediately
if ( $file->isDeleted( File::DELETED_FILE ) ) {
$file->getSha1()
);
- $cachedValue = $wgMemc->get( $cacheKey );
+ $cachedValue = $cache->get( $cacheKey );
if (
$cachedValue
&& Hooks::run( 'ValidateExtendedMetadataCache', array( $cachedValue['timestamp'], $file ) )
// computation on a cache hit.
$this->sanitizeArrayForAPI( $extendedMetadata );
$valueToCache = array( 'data' => $extendedMetadata, 'timestamp' => wfTimestampNow() );
- $wgMemc->set( $cacheKey, $valueToCache, $maxCacheTime );
+ $cache->set( $cacheKey, $valueToCache, $maxCacheTime );
}
return $extendedMetadata;
* @param File $file
* @return bool
*/
- function pageCount( $file ) {
+ function pageCount( File $file ) {
return false;
}
* @param int $page What page to get dimensions of
* @return array|bool
*/
- function getPageDimensions( $image, $page ) {
+ function getPageDimensions( File $image, $page ) {
$gis = $this->getImageSize( $image, $image->getLocalRefPath() );
if ( $gis ) {
return array(
* @return bool|string Page text or false when no text found or if
* unsupported.
*/
- function getPageText( $image, $page ) {
+ function getPageText( File $image, $page ) {
return false;
}
* @return string|bool Representing the IM version; false on error
*/
protected function getMagickVersion() {
- return ObjectCache::newAccelerator( CACHE_NONE )->getWithSetCallback(
- "imagemagick-version",
- 3600,
+ $cache = ObjectCache::newAccelerator( CACHE_NONE );
+ return $cache->getWithSetCallback(
+ 'imagemagick-version',
+ $cache::TTL_HOUR,
function () {
global $wgImageMagickConvertCommand;
);
if ( $x != 1 ) {
wfDebug( __METHOD__ . ": ImageMagick version check failed\n" );
-
return false;
}
foreach ( $updates as $update ) {
if ( $update instanceof LinksUpdate ) {
$update->setRevision( $revision );
+ $update->setTriggeringUser( $user );
}
DeferredUpdates::addUpdate( $update );
}
$status->value = $logid;
// Show log excerpt on 404 pages rather than just a link
+ $cache = ObjectCache::getMainStashInstance();
$key = wfMemcKey( 'page-recent-delete', md5( $logTitle->getPrefixedText() ) );
- ObjectCache::getMainStashInstance()->set( $key, 1, 86400 );
+ $cache->set( $key, 1, $cache::TTL_DAY );
return $status;
}
if ( !$dateFormatter ) {
$dateFormatter = $cache->getWithSetCallback(
$cache->makeKey( 'dateformatter', $lang->getCode() ),
- 3600,
+ $cache::TTL_HOUR,
function () use ( $lang ) {
return new DateFormatter( $lang );
}
return $driver->tidy( $text );
}
+ /**
+ * Get CSS modules needed if HTML from the current driver is to be displayed.
+ *
+ * This is just a migration tool to allow some changes expected as part of
+ * Tidy replacement (T89331) to be exposed on the client side via user
+ * scripts, without actually replacing tidy. See T49673.
+ *
+ * @return array
+ */
+ public static function getModuleStyles() {
+ $driver = self::singleton();
+ if ( $driver && $driver instanceof MediaWiki\Tidy\RaggettBase ) {
+ return array( 'mediawiki.raggett' );
+ } else {
+ return array();
+ }
+ }
+
/**
* Check HTML for errors, used if $wgValidateAllHtml = true.
*
if ( MWTidy::isEnabled() && $this->mOptions->getTidy() ) {
$text = MWTidy::tidy( $text );
+ $this->mOutput->addModuleStyles( MWTidy::getModuleStyles() );
} else {
# attempt to sanitize at least some nesting problems
# (bug #2702 and quite a few others)
public $mHeadItems = array();
/**
- * @var array $mModules Modules to be loaded by the resource loader
+ * @var array $mModules Modules to be loaded by ResourceLoader
*/
public $mModules = array();
/**
- * @var array $mModuleScripts Modules of which only the JS will be loaded by
- * the resource loader.
+ * @var array $mModuleScripts Modules of which only the JS will be loaded by ResourceLoader.
*/
public $mModuleScripts = array();
/**
- * @var array $mModuleStyles Modules of which only the CSSS will be loaded by
- * the resource loader.
+ * @var array $mModuleStyles Modules of which only the CSSS will be loaded by ResourceLoader.
*/
public $mModuleStyles = array();
<?php
/**
- * Derivative context for resource loader modules.
+ * Derivative context for ResourceLoader modules.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
<?php
/**
- * Context for resource loader modules.
+ * Context for ResourceLoader modules.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
<?php
/**
- * Resource loader module for the edit toolbar.
+ * ResourceLoader module for the edit toolbar.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
<?php
/**
- * Resource loader module based on local JavaScript/CSS files.
+ * ResourceLoader module based on local JavaScript/CSS files.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
*/
protected $debugScripts = array();
- /**
- * @var array List of paths to JavaScript files to include in the startup module
- * @par Usage:
- * @code
- * array( [file-path], [file-path], ... )
- * @endcode
- */
- protected $loaderScripts = array();
-
/**
* @var array List of paths to CSS files to always include
* @par Usage:
* ),
* // Scripts to include in debug contexts
* 'debugScripts' => [file path string or array of file path strings],
- * // Scripts to include in the startup module
- * 'loaderScripts' => [file path string or array of file path strings],
* // Modules which must be loaded before this module
* 'dependencies' => [module name string or array of module name strings],
* 'templates' => array(
// Lists of file paths
case 'scripts':
case 'debugScripts':
- case 'loaderScripts':
case 'styles':
$this->{$member} = (array)$option;
break;
return $this->debugRaw;
}
- /**
- * Get loader script.
- *
- * @return string|bool JavaScript code to be added to startup module
- */
- public function getLoaderScript() {
- if ( count( $this->loaderScripts ) === 0 ) {
- return false;
- }
- return $this->readScriptFiles( $this->loaderScripts );
- }
-
/**
* Get all styles for a given context.
*
$this->templates,
$context->getDebug() ? $this->debugScripts : array(),
$this->getLanguageScripts( $context->getLanguage() ),
- self::tryForKey( $this->skinScripts, $context->getSkin(), 'default' ),
- $this->loaderScripts
+ self::tryForKey( $this->skinScripts, $context->getSkin(), 'default' )
);
if ( $this->skipFunction ) {
$files[] = $this->skipFunction;
// - position (only used by OutputPage)
'scripts',
'debugScripts',
- 'loaderScripts',
'styles',
'languageScripts',
'skinScripts',
<?php
/**
- * Resource loader module for generated and embedded images.
+ * ResourceLoader module for generated and embedded images.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
*/
/**
- * Resource loader module for generated and embedded images.
+ * ResourceLoader module for generated and embedded images.
*
* @since 1.25
*/
<?php
/**
- * Resource loader module for populating language specific data.
+ * ResourceLoader module for populating language specific data.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
<?php
/**
- * Resource loader module for providing language names.
+ * ResourceLoader module for providing language names.
*
* By default these names will be autonyms however other extensions may
* provided language names in the context language (e.g. cldr extension)
<?php
/**
- * Abstraction for resource loader modules.
+ * Abstraction for ResourceLoader modules.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
*/
/**
- * Abstraction for resource loader modules, with name registration and maxage functionality.
+ * Abstraction for ResourceLoader modules, with name registration and maxage functionality.
*/
abstract class ResourceLoaderModule {
# Type of resource
return false;
}
- /**
- * Get the loader JS for this module, if set.
- *
- * @return mixed JavaScript loader code as a string or boolean false if no custom loader set
- */
- public function getLoaderScript() {
- // Stub, override expected
- return false;
- }
-
/**
* Get a list of modules this module depends on.
*
* Dependency information is taken into account when loading a module
* on the client side.
*
- * To add dependencies dynamically on the client side, use a custom
- * loader script, see getLoaderScript()
- *
* Note: It is expected that $context will be made non-optional in the near
* future.
*
<?php
/**
- * Resource loader module for site customizations.
+ * ResourceLoader module for site customizations.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
<?php
/**
- * Resource loader module for skin stylesheets.
+ * ResourceLoader module for skin stylesheets.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
<?php
/**
- * Resource loader module for populating special characters data for some
+ * ResourceLoader module for populating special characters data for some
* editing extensions to use.
*
* This program is free software; you can redistribute it and/or modify
*/
/**
- * Resource loader module for populating special characters data for some
+ * ResourceLoader module for populating special characters data for some
* editing extensions to use.
*/
class ResourceLoaderSpecialCharacterDataModule extends ResourceLoaderModule {
<?php
/**
- * Module for resource loader initialization.
+ * Module for ResourceLoader initialization.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* - array 'dependencies'
* - string|null 'group'
* - string 'source'
- * - string|false 'loader'
*/
public static function compileUnresolvedDependencies( array &$registryData ) {
foreach ( $registryData as $name => &$data ) {
- if ( $data['loader'] !== false ) {
- continue;
- }
$dependencies = $data['dependencies'];
foreach ( $data['dependencies'] as $dependency ) {
$implicitDependencies = self::getImplicitDependencies( $registryData, $dependency );
'dependencies' => $module->getDependencies( $context ),
'group' => $module->getGroup(),
'source' => $module->getSource(),
- 'loader' => $module->getLoaderScript(),
'skip' => $skipFunction,
);
}
// Register sources
$out .= ResourceLoader::makeLoaderSourcesScript( $resourceLoader->getSources() );
- // Concatenate module loader scripts and figure out the different call
- // signatures for mw.loader.register
+ // Figure out the different call signatures for mw.loader.register
$registrations = array();
foreach ( $registryData as $name => $data ) {
- if ( $data['loader'] !== false ) {
- $out .= ResourceLoader::makeCustomLoaderScript(
- $name,
- $data['version'],
- $data['dependencies'],
- $data['group'],
- $data['source'],
- $data['loader']
- );
- continue;
- }
-
// Call mw.loader.register(name, version, dependencies, group, source, skip)
$registrations[] = array(
$name,
<?php
/**
- * Resource loader module for user preference customizations.
+ * ResourceLoader module for user preference customizations.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
<?php
/**
- * Resource loader module for default user preferences.
+ * ResourceLoader module for default user preferences.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
<?php
/**
- * Resource loader module for user customizations.
+ * ResourceLoader module for user customizations.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
<?php
/**
- * Resource loader module for user customizations.
+ * ResourceLoader module for user customizations.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
<?php
/**
- * Resource loader module for user preference customizations.
+ * ResourceLoader module for user preference customizations.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
<?php
/**
- * Resource loader module for user tokens.
+ * ResourceLoader module for user tokens.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
<?php
/**
- * Abstraction for resource loader modules which pull from wiki pages.
+ * Abstraction for ResourceLoader modules that pull from wiki pages.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
*/
/**
- * Abstraction for resource loader modules which pull from wiki pages
+ * Abstraction for ResourceLoader modules which pull from wiki pages
*
* This can only be used for wiki pages in the MediaWiki and User namespaces,
* because of its dependence on the functionality of Title::isCssJsSubpage.
function buildSidebar() {
global $wgEnableSidebarCache, $wgSidebarCacheExpiry;
- $cache = ObjectCache::getMainWANInstance();
- $key = wfMemcKey( 'sidebar', $this->getLanguage()->getCode() );
+ $that = $this;
+ $callback = function () use ( $that ) {
+ $bar = array();
+ $that->addToSidebar( $bar, 'sidebar' );
+ Hooks::run( 'SkinBuildSidebar', array( $that, &$bar ) );
- if ( $wgEnableSidebarCache ) {
- $cachedsidebar = $cache->get( $key );
- if ( $cachedsidebar ) {
- Hooks::run( 'SidebarBeforeOutput', array( $this, &$cachedsidebar ) );
-
- return $cachedsidebar;
- }
- }
+ return $bar;
+ };
- $bar = array();
- $this->addToSidebar( $bar, 'sidebar' );
-
- Hooks::run( 'SkinBuildSidebar', array( $this, &$bar ) );
if ( $wgEnableSidebarCache ) {
- $cache->set( $key, $bar, $wgSidebarCacheExpiry );
+ $cache = ObjectCache::getMainWANInstance();
+ $sidebar = $cache->getWithSetCallback(
+ $cache->makeKey( 'sidebar', $this->getLanguage()->getCode() ),
+ $wgSidebarCacheExpiry,
+ $callback,
+ array( 'lockTSE' => 30 )
+ );
+ } else {
+ $sidebar = $callback();
}
- Hooks::run( 'SidebarBeforeOutput', array( $this, &$bar ) );
+ // Apply post-processing to the cached value
+ Hooks::run( 'SidebarBeforeOutput', array( $this, &$sidebar ) );
- return $bar;
+ return $sidebar;
}
/**
* @param array $bar
* @param string $message
*/
- function addToSidebar( &$bar, $message ) {
+ public function addToSidebar( &$bar, $message ) {
$this->addToSidebarPlain( $bar, wfMessage( $message )->inContentLanguage()->plain() );
}
'mediawiki.special', 'mediawiki.special.search', 'mediawiki.ui', 'mediawiki.ui.button',
'mediawiki.ui.input',
) );
+ $this->addHelpLink( 'Help:Searching' );
// Strip underscores from title parameter; most of the time we'll want
// text form here. But don't strip underscores from actual text params!
$out->addHTML( $this->showInterwiki( $textMatches->getInterwikiResults(
SearchResultSet::SECONDARY_RESULTS ), $term ) );
}
-
- $textMatches->free();
}
- $hasOtherResults = $textMatches->hasInterwikiResults( SearchResultSet::INLINE_RESULTS );
+ $hasOtherResults = $textMatches &&
+ $textMatches->hasInterwikiResults( SearchResultSet::INLINE_RESULTS );
if ( $num === 0 ) {
if ( $textStatus ) {
}
}
+ if ( $textMatches ) {
+ $textMatches->free();
+ }
+
$out->addHTML( '<div class="visualClear"></div>' );
if ( $prevnext ) {
* Produce wiki header for interwiki results
* @param string $interwiki Interwiki name
* @param SearchResultSet $interwikiResult The result set
+ * @return string
*/
protected function interwikiHeader( $interwiki, $interwikiResult ) {
// TODO: we need to figure out how to name wikis correctly
$key = wfMemcKey( 'acctcreate', 'ip', $ip );
$value = $cache->get( $key );
if ( !$value ) {
- $cache->set( $key, 0, 86400 );
+ $cache->set( $key, 0, $cache::TTL_DAY );
}
if ( $value >= $wgAccountCreationThrottle ) {
return Status::newFatal( 'acct_creation_throttle_hit', $wgAccountCreationThrottle );
// Give general extensions, such as a captcha, a chance to abort logins
$abort = self::ABORTED;
if ( !Hooks::run( 'AbortLogin', array( $u, $this->mPassword, &$abort, &$msg ) ) ) {
- if ( !in_array( $abort, self::$statusCodes, true ) ) {
+ if ( !in_array( $abort, array_keys( self::$statusCodes ), true ) ) {
throw new Exception( 'Invalid status code returned from AbortLogin hook: ' . $abort );
}
$this->mAbortLoginErrorMsg = $msg;
// we can trick Tidy into not stripping them out by including them in tidy's new-empty-tags config
$wrappedtext = preg_replace( '!<(link|meta)([^>]*?)(/{0,1}>)!', '<html-$1$2$3', $wrappedtext );
+ // Preserve empty li elements (T49673) by abusing Tidy's datafld hack
+ // The whitespace class is as in TY_(InitMap)
+ $wrappedtext = preg_replace( "!<li>([ \r\n\t\f]*)</li>!",
+ '<li datafld="" class="mw-empty-li">\1</li>', $wrappedtext );
+
// Wrap the whole thing in a doctype and body for Tidy.
$wrappedtext = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"' .
' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html>' .
// Revert <html-{link,meta}> back to <{link,meta}>
$text = preg_replace( '!<html-(link|meta)([^>]*?)(/{0,1}>)!', '<$1$2$3', $text );
+ // Remove datafld
+ $text = str_replace( '<li datafld=""', '<li', $text );
+
// Restore the contents of placeholder tokens
$text = $this->mTokens->replace( $text );
if ( $value === false ) {
$cache->delete( $key );
} else {
- $cache->set( $key, $value, 86400 );
+ $cache->set( $key, $value, $cache::TTL_DAY );
}
}
}
* @return Language
*/
protected static function newFromCode( $code ) {
- // Protect against path traversal below
- if ( !Language::isValidCode( $code )
- || strcspn( $code, ":/\\\000" ) !== strlen( $code )
- ) {
+ if ( !Language::isValidCode( $code ) ) {
throw new MWException( "Invalid language code \"$code\"" );
}
// Check if there is a language class for the code
$class = self::classFromCode( $code );
- self::preloadLanguageClass( $class );
if ( class_exists( $class ) ) {
$lang = new $class;
return $lang;
}
$class = self::classFromCode( $fallbackCode );
- self::preloadLanguageClass( $class );
if ( class_exists( $class ) ) {
- $lang = Language::newFromCode( $fallbackCode );
+ $lang = new $class;
$lang->setCode( $code );
return $lang;
}
*/
public static function isValidCode( $code ) {
static $cache = array();
- if ( isset( $cache[$code] ) ) {
- return $cache[$code];
+ if ( !isset( $cache[$code] ) ) {
+ // People think language codes are html safe, so enforce it.
+ // Ideally we should only allow a-zA-Z0-9-
+ // but, .+ and other chars are often used for {{int:}} hacks
+ // see bugs 37564, 37587, 36938
+ $cache[$code] =
+ // Protect against path traversal
+ strcspn( $code, ":/\\\000&<>'\"" ) === strlen( $code )
+ && !preg_match( MediaWikiTitleCodec::getTitleInvalidRegex(), $code );
}
- // People think language codes are html safe, so enforce it.
- // Ideally we should only allow a-zA-Z0-9-
- // but, .+ and other chars are often used for {{int:}} hacks
- // see bugs 37564, 37587, 36938
- $cache[$code] =
- strcspn( $code, ":/\\\000&<>'\"" ) === strlen( $code )
- && !preg_match( MediaWikiTitleCodec::getTitleInvalidRegex(), $code );
-
return $cache[$code];
}
return false;
}
- /**
- * @param string $code
- * @return string Name of the language class
- */
- public static function classFromCode( $code ) {
- if ( $code == 'en' ) {
- return 'Language';
- } else {
- return 'Language' . str_replace( '-', '_', ucfirst( $code ) );
- }
- }
-
- /**
- * Includes language class files
- *
- * @param string $class Name of the language class
- */
- public static function preloadLanguageClass( $class ) {
- global $IP;
-
- if ( $class === 'Language' ) {
- return;
- }
-
- if ( file_exists( "$IP/languages/classes/$class.php" ) ) {
- include_once "$IP/languages/classes/$class.php";
- }
- }
-
/**
* Get the LocalisationCache instance
*
$this->mParentLanguage = false;
}
- /**
- * Get the name of a file for a certain language code
- * @param string $prefix Prepend this to the filename
- * @param string $code Language code
- * @param string $suffix Append this to the filename
- * @throws MWException
- * @return string $prefix . $mangledCode . $suffix
- */
- public static function getFileName( $prefix = 'Language', $code, $suffix = '.php' ) {
- if ( !self::isValidBuiltInCode( $code ) ) {
- throw new MWException( "Invalid language code \"$code\"" );
- }
-
- return $prefix . str_replace( '-', '_', ucfirst( $code ) ) . $suffix;
- }
-
/**
* Get the language code from a file name. Inverse of getFileName()
* @param string $filename $prefix . $languageCode . $suffix
return str_replace( '_', '-', strtolower( $m[1] ) );
}
+ /**
+ * @param string $code
+ * @return string Name of the language class
+ */
+ public static function classFromCode( $code ) {
+ if ( $code == 'en' ) {
+ return 'Language';
+ } else {
+ return 'Language' . str_replace( '-', '_', ucfirst( $code ) );
+ }
+ }
+
+ /**
+ * Get the name of a file for a certain language code
+ * @param string $prefix Prepend this to the filename
+ * @param string $code Language code
+ * @param string $suffix Append this to the filename
+ * @throws MWException
+ * @return string $prefix . $mangledCode . $suffix
+ */
+ public static function getFileName( $prefix = 'Language', $code, $suffix = '.php' ) {
+ if ( !self::isValidBuiltInCode( $code ) ) {
+ throw new MWException( "Invalid language code \"$code\"" );
+ }
+
+ return $prefix . str_replace( '-', '_', ucfirst( $code ) ) . $suffix;
+ }
+
/**
* @param string $code
* @return string
return "$IP/languages/i18n/$code.json";
}
- /**
- * @param string $code
- * @return string
- */
- public static function getClassFileName( $code ) {
- global $IP;
- return self::getFileName( "$IP/languages/classes/Language", $code, '.php' );
- }
-
/**
* Get the first fallback for a given language.
*
"tog-hideminor": "সাম্প্ৰতিক সাল-সলনিত অগুৰুত্বপূৰ্ণ সম্পাদনা নেদেখুৱাব",
"tog-hidepatrolled": "সাম্প্ৰতিক সাল-সলনিত তহলদাৰী সম্পাদনা নেদেখুৱাব",
"tog-newpageshidepatrolled": "নতুন পৃষ্ঠা তালিকাত তহলদাৰী পৃষ্ঠাসমূহ নেদেখুৱাব",
+ "tog-hidecategorization": "পৃষ্ঠাবোৰৰ শ্ৰেণীকৰণ লুকুৱাওক",
"tog-extendwatchlist": "কেৱল সাম্প্ৰতিকেই নহয, লক্ষ্য-তালিকাৰ সকলো সাল-সলনি বহলাই দেখুৱাওক",
"tog-usenewrc": "পৃষ্ঠাৰ পৰিৱৰ্তনসমূহ শেহতীয়া সালসলনি আৰু লক্ষ্যতালিকাত ভাগ কৰক",
"tog-numberheadings": "শীৰ্ষকত স্বয়ংক্ৰিয়ভাৱে ক্ৰমিক নং দিয়ক",
"tog-watchlisthideliu": "প্ৰবেশ কৰা সদস্যৰ সম্পাদনাসমূহ আঁতৰাই অনুসৰণ-তালিকা দেখুৱাওক",
"tog-watchlisthideanons": "বেনামী সদস্যৰ সম্পাদনাসমূহ আঁতৰাই অনুসৰণ-তালিকা দেখুৱাওক",
"tog-watchlisthidepatrolled": "পৰীক্ষিত সম্পাদনাসমূহ লক্ষ্য-তালিকাৰ পৰা লুকুৱাই ৰাখক",
+ "tog-watchlisthidecategorization": "পৃষ্ঠাবোৰৰ শ্ৰেণীকৰণ লুকুৱাওক",
"tog-ccmeonemails": "মই অন্য সদস্যলৈ পঠোৱা ই-মেইলৰ প্ৰতিলিপি এটা মোলৈও পঠাব",
"tog-diffonly": "পার্থক্যৰ তলত পৃষ্ঠাৰ বিষয়বস্তু নেদেখুৱাব",
"tog-showhiddencats": "নিহিত শ্ৰেণীসমূহ দেখুৱাওক",
"createaccountreason": "কাৰণ:",
"createacct-reason": "কাৰণ",
"createacct-reason-ph": "আপুনি কিয় আন এটা একাউণ্ট সৃষ্টি কৰিছে",
- "createacct-captcha": "সুৰক্ষা পৰীক্ষা",
- "createacct-imgcaptcha-ph": "ওপৰত দেখা পোৱা পাঠ্য লিখক",
"createacct-submit": "আপোনাৰ একাউণ্ট সৃষ্টি কৰক",
"createacct-another-submit": "একাউণ্ট সৃষ্টি কৰক",
"createacct-benefit-heading": "আপোনাৰ দৰে মানুহেই {{SITENAME}} তৈয়াৰ কৰিছে",
"showingresultsinrange": "তলত #<strong>$2</strong>ৰ পৰা #<strong>$3</strong> পৰিসৰৰ ভিতৰত {{PLURAL:$1|<strong>1</strong>টা ফলাফল|<strong>$1</strong>টা লৈকে ফলাফল}} দেখুওৱা হৈছে।",
"search-showingresults": "{{PLURAL:$4|<strong>$3</strong>-ৰ <strong>$1</strong>টো ফলাফল|<strong>$3</strong>-ৰ <strong>$1 - $2</strong>টো ফলাফল}}",
"search-nonefound": "এই অনুসন্ধানৰ কোনো ফলাফল নাই ।",
+ "search-nonefound-thiswiki": "এই ছাইটত এই সন্ধানৰ লগত মিলা কোনো ফলাফল নাই।",
"powersearch-legend": "শক্তিশালী সন্ধান",
"powersearch-ns": "নামস্থানবোৰত সন্ধান:",
"powersearch-togglelabel": "পৰীক্ষা কৰক:",
"rcshowhidemine": "মোৰ সম্পাদনা $1",
"rcshowhidemine-show": "দেখুৱাওক",
"rcshowhidemine-hide": "লুকুৱাওক",
+ "rcshowhidecategorization-show": "দেখুৱাওক",
+ "rcshowhidecategorization-hide": "লুকুৱাওক",
"rclinks": "যোৱা $2 দিনত হোৱা $1 টা সাল-সলনি চাওক ।<br />$3",
"diff": "পাৰ্থক্য",
"hist": "ইতিবৃত্ত",
"showingresultsinrange": "Más abaxo s'{{PLURAL:$1|amuesa|amuesen}} fasta {{PLURAL:$1|<strong>1</strong> resultáu|<strong>$1</strong> resultaos}} nel rangu ente #<strong>$2</strong> y #<strong>$3</strong>.",
"search-showingresults": "{{PLURAL:$4|Resultáu <strong>$1</strong> de <strong>$3</strong>|Resultaos <strong>$1 - $2</strong> de <strong>$3</strong>}}",
"search-nonefound": "Nun hebo resultaos que casaren cola consulta.",
+ "search-nonefound-thiswiki": "Nun hebo resultaos que casaran cola consulta nesti sitiu.",
"powersearch-legend": "Busca avanzada",
"powersearch-ns": "Buscar nos espacios de nome:",
"powersearch-togglelabel": "Comprobar:",
"showingresultsinrange": "Ніжэй паказаныя да {{PLURAL:$1|<strong>$1</strong> выніку ў|<strong>$1</strong> вынікаў у}} дыяпазоне ад <strong>$2</strong> да <strong>$3</strong>.",
"search-showingresults": "{{PLURAL:$4|1=Вынік <strong>$1</strong> з <strong>$3</strong>|Вынікі <strong>$1—$2</strong> з <strong>$3</strong>}}",
"search-nonefound": "Супадзеньняў па запыце ня знойдзена.",
+ "search-nonefound-thiswiki": "Супадзеньняў па запыце ня знойдзена на гэтым сайце.",
"powersearch-legend": "Удасканалены пошук",
"powersearch-ns": "Шукаць у прасторах назваў:",
"powersearch-togglelabel": "Пазначыць:",
"foreign-structured-upload-form-label-not-own-work-message-default": "Калі вы ня можаце загрузіць гэты файл паводле правілаў агульнага сховішча, калі ласка, закрыйце гэты дыялёг і паспрабуйце іншы мэтад.",
"foreign-structured-upload-form-label-not-own-work-local-default": "Вы можаце паспрабаваць скарыстацца [[Special:Upload|старонкай загрузкі {{GRAMMAR:родны|{{SITENAME}}}}]], калі гэты файл можна туды загрузіць згодна з правіламі.",
"foreign-structured-upload-form-label-own-work-message-shared": "Я пацьвярджаю, што зьяўляюся ўласьнікам аўтарскіх правоў на гэты файл, і згодны незваротна перадаць гэты файл ў Вікісховішча на ўмовах ліцэнзіі [https://creativecommons.org/licenses/by-sa/4.0/ Creative Commons Attribution-ShareAlike 4.0], а таксама згодны з [https://wikimediafoundation.org/wiki/Terms_of_Use умовамі выкарыстаньня].",
+ "foreign-structured-upload-form-label-not-own-work-message-shared": "Калі вы не зьяўляецеся ўласьнікам аўтарскіх правоў на гэты файл, або вы жадаеце распаўсюджваць яго пад іншай ліцэнзіяй, можаце скарыстацца [https://commons.wikimedia.org/wiki/Special:UploadWizard Майстарам загрузкі ў Вікісховішча].",
+ "foreign-structured-upload-form-label-not-own-work-local-shared": "Вы таксама можаце скарыстацца [[Special:Upload|старонкай загрузкі {{GRAMMAR:родны|{{SITENAME}}}}]], калі правілы сайту дазваляюць загрузку такога файлу.",
"backend-fail-stream": "Немагчыма накіраваць файл $1.",
"backend-fail-backup": "Немагчыма зрабіць рэзэрвовую копію файла $1.",
"backend-fail-notexists": "Файл $1 не існуе.",
"version-poweredby-others": "অন্যান্য",
"version-poweredby-translators": "translatewiki.net অনুবাদকগণ",
"version-credits-summary": "[[Special:Version|মিডিয়াউইকি]] সফটওয়্যারে অবদানের জন্য আমরা এই ব্যক্তিকে স্বীকৃতি দিতে চাই।",
- "version-license-info": "মিডিয়াউইকি একটি ফ্রি সফটওয়্যার, আপনি এটি বিতরণ করতে পারবেন এবং/অথবা সম্পদানা করতে পারবেন, এক্ষেত্রে ফ্রি সফটওয়্যার ফাউন্ডেশনের প্রকাশিত গনু জেনারেল পাবলিক লাইসেন্সের ২য় অথবা সাম্প্রতিকতম কোনো সংস্করণ মেনে চলতে হবে। \n\nসকলের উপকারের লক্ষ্যে এটি বিতরণ করা হয়ে থাকে, কিন্তু এক্ষেত্রে কোনো ওয়ারেন্টি দেয়া হয় না, এমনকি বিশেষ কোনো কার্যক্ষেত্রে ব্যবহারের জন্যও তথাকথিত ওয়ারেন্টি দেয়া হয় না। বিস্তারিত জানতে দেখুন গনু জেনারেল পাবলিক লাইসেন্স। \n\nএই সফটওয়্যারের সাথে [{{SERVER}}{{SCRIPTPATH}}/COPYING গনু জেনারেল পাবলিক লাইসেন্সের একটি কপি] থাকার কথা; যদি আপনি না পেয়ে থাকেন তাহলে অনুগ্রহ করে ফ্রি সফটওয়্যার ফাউন্ডেশনকে জানান এই ঠিকানায়, Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA অথবা [//www.gnu.org/licenses/old-licenses/gpl-2.0.html অনলাইনে দেখুন]।",
+ "version-license-info": "মিডিয়াউইকি একটি ফ্রি সফটওয়্যার; আপনি এটি বিতরণ করতে পারবেন এবং/অথবা সম্পদানা করতে পারবেন, এক্ষেত্রে ফ্রি সফটওয়্যার ফাউন্ডেশনের প্রকাশিত গনু জেনারেল পাবলিক লাইসেন্সের ২য় অথবা সাম্প্রতিকতম কোনো সংস্করণ মেনে চলতে হবে। \n\nসকলের উপকারের লক্ষ্যে এটি বিতরণ করা হয়ে থাকে, কিন্তু এক্ষেত্রে কোনো ওয়ারেন্টি দেয়া হয় না, এমনকি বিশেষ কোনো কার্যক্ষেত্রে ব্যবহারের জন্যও তথাকথিত ওয়ারেন্টি দেয়া হয় না। বিস্তারিত জানতে দেখুন গনু জেনারেল পাবলিক লাইসেন্স। \n\nএই সফটওয়্যারের সাথে [{{SERVER}}{{SCRIPTPATH}}/COPYING গনু জেনারেল পাবলিক লাইসেন্সের একটি অনুলিপি] থাকার কথা; যদি আপনি না পেয়ে থাকেন তাহলে অনুগ্রহ করে ফ্রি সফটওয়্যার ফাউন্ডেশনকে জানান এই ঠিকানায়, Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA অথবা [//www.gnu.org/licenses/old-licenses/gpl-2.0.html অনলাইনে দেখুন]।",
"version-software": "ইনস্টলকৃত সফটওয়্যার",
"version-software-product": "পণ্য",
"version-software-version": "সংস্করণ",
"logentry-delete-delete": "$1 {{GENDER:$2|obrisao|obrisala}} je stranicu $3",
"logentry-delete-restore": "$1 {{GENDER:$2|vratio|vratila}} je stranicu $3",
"logentry-delete-event": "$1 je {{GENDER:$2|promijenio|promijenila}} vidljivost {{PLURAL:$5|događaja|$5 događaja}} u evidenciji na $3: $4",
- "logentry-delete-revision": "$1 je {{GENDER:$2|promijenio|promijenila}} vidljivost {{PLURAL:$5|izmjene|$5 izmjene|$5 izmjena}} na stranici $3: $4",
+ "logentry-delete-revision": "$1 {{GENDER:$2|promijenio|promijenila}} je vidljivost {{PLURAL:$5|izmjene|$5 izmjene|$5 izmjena}} na stranici $3: $4",
"logentry-delete-event-legacy": "$1 je {{GENDER:$2|promijenio|promijenila}} vidljivost događaja u evidenciji na $3",
"logentry-delete-revision-legacy": "$1 je {{GENDER:$2|promijenio|promijenila}} vidljivost izmjena na stranici $3",
"logentry-suppress-delete": "$1 {{GENDER:$2|potisnuo|potisnula}} je stranicu $3",
"logentry-suppress-revision": "$1 je tajno {{GENDER:$2|promijenio|promijenila}} vidljivost {{PLURAL:$5|izmjene|$5 izmjene|$5 izmjena}} na stranici $3: $4",
"logentry-suppress-event-legacy": "$1 je tajno {{GENDER:$2|promijenio|promijenila}} vidljivost događaja u evidenciji na $3",
"logentry-suppress-revision-legacy": "$1 je tajno {{GENDER:$2|promijenio|promijenila}} vidljivost izmjena na stranici $3",
- "revdelete-content-hid": "skriveni sadržaj",
+ "revdelete-content-hid": "sadržaj je sakriven",
"revdelete-summary-hid": "sažetak izmjene je sakriven",
"revdelete-uname-hid": "sažetak izmjene je sakriven",
"revdelete-content-unhid": "sadržaj je otkriven",
"Xavier Dengra",
"Pginer",
"Eduardo Martinez",
- "Matma Rex"
+ "Matma Rex",
+ "KRLS"
]
},
"tog-underline": "Subratlla els enllaços:",
"revdelete-uname-unhid": "ha revelat un nom d'usuari que era ocult",
"revdelete-restricted": "ha aplicat restriccions als administradors",
"revdelete-unrestricted": "ha tret les restriccions als administradors",
- "logentry-block-block": "$1 {{GENDER:$2|ha estat blocat|ha estat blocada}} {{GENDER:$4|$3}} per un període de temps de $5 $6",
+ "logentry-block-block": "$1 {{GENDER:$2|ha blocat}} {{GENDER:$4|$3}} per un temps de $5 $6",
"logentry-block-unblock": "$1 {{GENDER:$2|va desblocar}} {{GENDER:$4|$3}}",
- "logentry-block-reblock": "$1 {{GENDER:$2|ha canviat}} la configuració del blocatge de {{GENDER:$4|$3}} per un període de temps de $5 $6",
- "logentry-suppress-block": "$1 {{GENDER:$2|ha blocat}} {{GENDER:$4|$3}} per un període de temps de $5 $6",
- "logentry-suppress-reblock": "$1 {{GENDER:$2|ha canviat}} la configuració de blocatge de {{GENDER:$4|$3}} per un període de temps de $5 $6",
+ "logentry-block-reblock": "$1 {{GENDER:$2|ha canviat}} la configuració del blocatge de {{GENDER:$4|$3}} per un temps de $5 $6",
+ "logentry-suppress-block": "$1 {{GENDER:$2|ha blocat}} {{GENDER:$4|$3}} per un temps de $5 $6",
+ "logentry-suppress-reblock": "$1 {{GENDER:$2|ha canviat}} la configuració de blocatge de {{GENDER:$4|$3}} per un temps de $5 $6",
"logentry-import-upload": "$1 {{GENDER:$2|va importar}} $3 a través de càrrega de fitxer",
"logentry-import-interwiki": "$1 {{GENDER:$2|va importar}} $3 d'un altre wiki",
"logentry-merge-merge": "$1 {{GENDER:$2|ha fusionat}} $3 en $4 (revisions fins a $5)",
"createacct-yourpasswordagain": "Бакъе пароль",
"createacct-yourpasswordagain-ph": "Кхин цкъа язъе пароль",
"remembermypassword": "Даглаца сан дӀаяздар хӀокху компьютеран тӀехь (цхьан $1 {{PLURAL:$1|дийнахь}})",
- "userlogin-remembermypassword": "Ð\94агаÑ\85Ñ\8c лаÑ\82Ñ\82 ве/е Ñ\81о",
+ "userlogin-remembermypassword": "СиÑ\81Ñ\82емин Ñ\87оÑ\85Ñ\8c Ó\80ойла",
"userlogin-signwithsecure": "Ларийна цхьаьнакхетар",
"yourdomainname": "Хьан машан меттиг:",
"password-change-forbidden": "Хьан йиш яц хӀокху вики чохь пароль хийца.",
"createaccountreason": "هۆکار:",
"createacct-reason": "ھۆکار",
"createacct-reason-ph": "بۆ ھەژمارێکی تر دروست دەکەی",
- "createacct-captcha": "تاوتوێی ئاسایشی",
- "createacct-imgcaptcha-ph": "دەقەکەی لە ژێرەوە دەیبینی بینووسە",
"createacct-submit": "ھەژمارەکەت دروست بکە",
"createacct-another-submit": "ھەژمارێکی تر دروست بکە",
"createacct-benefit-heading": "{{SITENAME}} لە لایەن کەسانێک وەکوو خۆت دروست کراوە.",
"revdelete-uname-unhid": "ناوی بەکارهێنەری نیشان درا",
"revdelete-restricted": "ئەو سنووری بەرگریانەی خستراوەتە سەر بەڕێوبەران",
"revdelete-unrestricted": "ئەو سنووری بەرگریانەی لابردراوە لە سەر بەڕێوبەران",
+ "logentry-block-block": "$1 {{GENDER:$4|$3}}ی بۆ ماوەی $5 {{GENDER:$2|بەربەست کرد}} $6",
"logentry-move-move": "$1 پەڕەی $3ی {{GENDER:$2|گواستەوە}} بۆ $4",
"logentry-move-move-noredirect": "$1 پەڕەی $3ی بەبێ بەجێھشتنی ڕەوانەکەرێک {{GENDER:$2|گواستەوە}} بۆ $4",
"logentry-move-move_redir": "$1 پەڕەی $3 {{GENDER:$2|گواستەوە}} بۆ $4 کە پێشتر ڕەوانەکەر بوو",
"Alessandro",
"Don Alessandro",
"Urhixidur",
- "아라"
+ "아라",
+ "Исмаил Садуев"
]
},
"tog-underline": "Багълантыларнынъ тюбюни сызув:",
"mytalk": "Музакере",
"anontalk": "Бу IP-нинъ музакереси",
"navigation": "Сайтта ёл тапув",
- "and": " ве",
+ "and": " а",
"qbfind": "Тап",
"qbbrowse": "Бакъып чыкъ",
"qbedit": "Денъиштир",
"createaccountreason": "Себеп:",
"createacct-reason": "Себеп",
"createacct-reason-ph": "Башкъа бир эсап язысы неден себеп яратасынъыз",
- "createacct-captcha": "Телюкесизлик контроли",
- "createacct-imgcaptcha-ph": "Юкъарыда корьген метнинъизни язынъыз",
"createacct-submit": "Эсап язынъызны яратынъыз",
"createacct-another-submit": "Башкъа бир эсап язысы яратынъыз",
"createacct-benefit-heading": "{{SITENAME}} сизинъ киби адамлар тарафындан языла.",
"move-page-legend": "Саифенинъ адыны денъиштирюв",
"movepagetext": "Ашагъыдаки форма къулланылып саифенинъ ады денъиштирилир. Бунынънен берабер денъиштирмелер журналы да янъы адгъа авуштырылыр.\nЭски ады янъы адына ёнетме олур. Эски серлевагъа ёнетип тургъан саифелерни автоматик оларакъ янъартып оласынъыз. Бу арекетни автоматик япмагъа истемесенъиз, бутюн [[Special:DoubleRedirects|чифт]] ве [[Special:BrokenRedirects|йыртыкъ]] ёнетме саифелерини озюнъиз тешкермеге меджбур олурсынъыз. Багълантылар эндиден берли догъру чалышмасындан эмин олмалысынъыз.\n\nЯнъы адда бир саифе энди бар олса, ад денъиштирилюви <strong>япылмайджакъ</strong>, анджакъ бар олгъан саифе ёнетме я да бош олса ад денъиштирилюви мумкюн оладжакъ. Бу демек ки, саифенинъ адыны янълыштан денъиштирген олсанъыз деминки адыны кери къайтарып оласынъыз, амма бар олгъан саифени тесадюфен ёкъ этамайсынъыз.\n\n<strong>ТЕНБИ!</strong>\nАд денъиштирилюви популяр саифелер ичюн буюк ве бекленмеген денъишмелерге себеп ола билир. Лютфен, денъиштирме япмаздан эвель ола биледжеклерни козь огюне алынъыз.",
"movepagetalktext": "Къошулгъан музакере саифесининъ де (бар олса)\nады автоматик тарзда денъиштириледжек. '''Мустесналар:'''\n\n* Айны бу адда бош олмагъан бир музакере саифеси энди бар;\n* Ашагъыдаки бошлукъкъа ишарет къоймадынъыз.\n\nБойле алларда, керек олса, саифелерни къолнен ташымагъа я да бирлештирмеге меджбур олурсынъыз.",
- "movearticle": "Эски ад",
"movecategorypage-warning": "<strong>Ихтар:</strong> Бир категория саифесининъ адыны денъиштирмек узьресинъиз. Лютфен, ялынъыз категория саифесининъ кочюриледжегини ве эски категорияда ер алгъан саифелернинъ янъы категориягъа авотматик оларакъ <em>авуштырылмайджагъыны</em> унутманъыз.",
"movenologintext": "Саифенинъ адыны денъиштирип олмакъ ичюн [[Special:UserLogin|отурым ачынъыз]].",
"movenotallowed": "Саифелер адларыны денъиштирмеге изининъиз ёкъ.",
"showingresultsinrange": "Unten {{PLURAL:$1|wird <strong>ein</strong> Ergebnis|werden bis zu <strong>$1</strong> Ergebnisse}} im Bereich <strong>$2</strong> bis <strong>$3</strong> angezeigt.",
"search-showingresults": "{{PLURAL:$4|Ergebnis <strong>$1</strong> von <strong>$3</strong>|Ergebnisse <strong>$1 bis $2</strong> von <strong>$3</strong>}}",
"search-nonefound": "Zu deiner Suchanfrage wurden keine Ergebnisse gefunden.",
+ "search-nonefound-thiswiki": "Es gibt auf dieser Website keine der Suchanfrage entsprechenden Ergebnisse.",
"powersearch-legend": "Erweiterte Suche",
"powersearch-ns": "Suche in Namensräumen:",
"powersearch-togglelabel": "Wähle aus:",
"JasterTDC",
"Laurenslimb",
"Tusca",
- "Tadol"
+ "Tadol",
+ "Nelson6e65"
]
},
"tog-underline": "Subrayar los enlaces:",
"tog-oldsig": "Firma actual:",
"tog-fancysig": "Tratar la firma como wikitexto (sin un enlace automático)",
"tog-uselivepreview": "Usar previsualización dinámica",
- "tog-forceeditsummary": "Avisarme cuando grabe la página sin escribir un resumen de edición",
+ "tog-forceeditsummary": "Avisarme cuando deje en blanco el resumen de la edición",
"tog-watchlisthideown": "Ocultar mis ediciones de la lista de seguimiento",
"tog-watchlisthidebots": "Ocultar las ediciones de bots de la lista de seguimiento",
"tog-watchlisthideminor": "Ocultar las ediciones menores de la lista de seguimiento",
"group-bot": "رباتها",
"group-sysop": "مدیران",
"group-bureaucrat": "دیوانسالاران",
- "group-suppress": "Ù¾Ù\86Ù\87اÙ\86گران",
+ "group-suppress": "Ù\81رÙ\88Ù\86شاÙ\86Ù\86دگان",
"group-all": "(همه)",
"group-user-member": "{{GENDER:$1|کاربر}}",
"group-autoconfirmed-member": "{{GENDER:$1|کاربر تأییدشده}}",
"group-bot-member": "ربات",
"group-sysop-member": "{{GENDER:$1|مدیر}}",
"group-bureaucrat-member": "{{GENDER:$1|دیوانسالار}}",
- "group-suppress-member": "{{GENDER:$1|Ù¾Ù\86Ù\87اÙ\86گر}}",
+ "group-suppress-member": "{{GENDER:$1|Ù\81رÙ\88Ù\86شاÙ\86Ù\86دÙ\87}}",
"grouppage-user": "{{ns:project}}:کاربران",
"grouppage-autoconfirmed": "{{ns:project}}:کاربران تأییدشده",
"grouppage-bot": "{{ns:project}}:رباتها",
"grouppage-sysop": "{{ns:project}}:مدیران",
"grouppage-bureaucrat": "{{ns:project}}:دیوانسالاران",
- "grouppage-suppress": "{{ns:project}}:Ù¾Ù\86Ù\87اÙ\86گر",
+ "grouppage-suppress": "{{ns:project}}:Ù\81رÙ\88Ù\86شاÙ\86Û\8c",
"right-read": "خواندن صفحه",
"right-edit": "ویرایش صفحه",
"right-createpage": "ایجاد صفحه (در مورد صفحههای غیر بحث)",
"hebrew-calendar-m4": "tévet",
"hebrew-calendar-m5": "chevat",
"hebrew-calendar-m6": "adar",
- "hebrew-calendar-m7": "Nissane",
- "hebrew-calendar-m8": "Iyar",
- "hebrew-calendar-m9": "Sivane",
- "hebrew-calendar-m10": "Tamouz",
- "hebrew-calendar-m11": "Av",
- "hebrew-calendar-m12": "Éloul",
+ "hebrew-calendar-m6a": "adar I",
+ "hebrew-calendar-m6b": "adar II",
+ "hebrew-calendar-m7": "nissan",
+ "hebrew-calendar-m8": "iyar",
+ "hebrew-calendar-m9": "sivan",
+ "hebrew-calendar-m10": "tamouz",
+ "hebrew-calendar-m11": "av",
+ "hebrew-calendar-m12": "eloul",
"hebrew-calendar-m1-gen": "tichri",
"hebrew-calendar-m2-gen": "hechvan",
"hebrew-calendar-m3-gen": "kislev",
"hebrew-calendar-m4-gen": "tévet",
"hebrew-calendar-m5-gen": "chevat",
"hebrew-calendar-m6-gen": "adar",
- "hebrew-calendar-m7-gen": "Nissane",
- "hebrew-calendar-m8-gen": "Iyar",
- "hebrew-calendar-m9-gen": "Sivane",
- "hebrew-calendar-m10-gen": "Tamouz",
- "hebrew-calendar-m11-gen": "Av",
- "hebrew-calendar-m12-gen": "Éloul",
+ "hebrew-calendar-m6a-gen": "adar I",
+ "hebrew-calendar-m6b-gen": "adar II",
+ "hebrew-calendar-m7-gen": "nissan",
+ "hebrew-calendar-m8-gen": "iyar",
+ "hebrew-calendar-m9-gen": "sivan",
+ "hebrew-calendar-m10-gen": "tamouz",
+ "hebrew-calendar-m11-gen": "av",
+ "hebrew-calendar-m12-gen": "eloul",
"signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|discussion]])",
"duplicate-defaultsort": "Attention : la clé de tri par défaut « $2 » écrase la précédente clé « $1 ».",
"duplicate-displaytitle": "<strong>Attention :</strong> Le titre d'affichage «$2» remplace l'ancien titre d'affichage «$1».",
"showingresultsinrange": "{{PLURAL:$1|מוצגת תוצאה <strong>אחת</strong>|מוצגות עד <strong>$1</strong> תוצאות}} בין המספרים <strong>$2</strong> ו־<strong>$3</strong>:",
"search-showingresults": "{{PLURAL:$4|תוצאה <strong>$1</strong> מתוך <strong>$3</strong>|תוצאות <strong>$1 - $2</strong> מתוך <strong>$3</strong>}}",
"search-nonefound": "לא נמצאו תוצאות המתאימות לחיפוש.",
+ "search-nonefound-thiswiki": "לא נמצאו תוצאות המתאימות לחיפוש באתר זה.",
"powersearch-legend": "חיפוש מתקדם",
"powersearch-ns": "חיפוש על־פי מרחבי שם:",
"powersearch-togglelabel": "בחירה:",
"Mirws",
"Ilham",
"Matma Rex",
- "WongKentir"
+ "WongKentir",
+ "Rachmat.Wahidi"
]
},
"tog-underline": "Garis bawahi pranala:",
"sp-contributions-newbies": "Hanya dari para pengguna baru",
"sp-contributions-newbies-sub": "Untuk pengguna baru",
"sp-contributions-newbies-title": "Kontribusi pengguna baru",
- "sp-contributions-blocklog": "Log pemblokiran",
+ "sp-contributions-blocklog": "log pemblokiran",
"sp-contributions-suppresslog": "kontribusi pengguna yang disembunyikan",
"sp-contributions-deleted": "kontribusi pengguna yang dihapus",
"sp-contributions-uploads": "unggahan",
"showingresultsinrange": "{{PLURAL:$1|Viene mostrato|Vengono mostrati}} sotto {{PLURAL:$1|<strong>1</strong> risultato|<strong>$1</strong> risultati}} dal <strong>$2</strong> al <strong>$3</strong>.",
"search-showingresults": "{{PLURAL:$4|Risultato <strong>$1</strong> di <strong>$3</strong>|Risultati <strong>$1 - $2</strong> di <strong>$3</strong>}}",
"search-nonefound": "La ricerca non ha prodotto risultati.",
+ "search-nonefound-thiswiki": "La ricerca non ha prodotto risultati in questo sito.",
"powersearch-legend": "Ricerca avanzata",
"powersearch-ns": "Cerca nei namespace:",
"powersearch-togglelabel": "Seleziona:",
"showingresultsinrange": "<strong>$2</strong> 件目から<strong>$3</strong> 件目までの範囲内で最大 {{PLURAL:$1|<strong>$1</strong> 件の結果}}を表示しています。",
"search-showingresults": "{{PLURAL:$4|<strong>$3</strong> 件中の <strong>$1</strong> 件目|<strong>$3</strong> 件中の <strong>$1</strong> 件目から <strong>$2</strong> 件目}}",
"search-nonefound": "問い合わせに合致する検索結果はありませんでした。",
+ "search-nonefound-thiswiki": "このサイトでの、そのクエリに一致する結果は、何もありませんでした。",
"powersearch-legend": "高度な検索",
"powersearch-ns": "名前空間を指定して検索:",
"powersearch-togglelabel": "チェックを入れる:",
"showingresultsinrange": "#<strong>$2</strong>부터 #<strong>$3</strong>까지의 범위에서 <strong>$1</strong>개의 {{PLURAL:$1|결과}}가 아래에 보입니다.",
"search-showingresults": "{{PLURAL:$4|결과 <strong>$3</strong>개 중 <strong>$1</strong>개|결과 <strong>$3</strong>개 중 <strong>$1 - $2</strong>개}}",
"search-nonefound": "검색어와 일치하는 결과가 없습니다.",
+ "search-nonefound-thiswiki": "이 사이트에서 검색어와 일치하는 결과가 없습니다.",
"powersearch-legend": "고급 검색",
"powersearch-ns": "다음 이름공간에서 검색:",
"powersearch-togglelabel": "확인:",
"passwordreset-emailerror-capture": "En <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"„de eläktrohnesche Poß“\">e-mail</i> met Aanjahbe zom neue Paßwoot för der Zohjang heh sullt verschek wääde, ävver dat Verscheke aan {{GENDER:$2|dä|dat|dä Metmaacher|de|dat}} $2 hät nit jeflup: $1",
"changeemail": "Donn en Adräß för de <i lang=\"en\">e-mail</i> ändere udder fott schmiiße",
"changeemail-header": "Donn heh dat Fommulaa ußfölle, öm Ding Adräß för de <i lang=\"en\" xml:lang=\"en\" dir=\"ltr\" title=\"„de eläktrohnesche Poß“\">e-mail</i> ze ändere. Wann De en Adräß loß wähde wells, maach dat Fäld läddesch, ih dat De dat Fommolaa loß scheks.",
- "changeemail-passwordrequired": "Do moÃ\9f Ding PaÃ\9fwood enjävve, öm di änderong ze beschtähteje.",
+ "changeemail-passwordrequired": "Do moÃ\9f Ding PaÃ\9fwood enjävve, öm di Ã\84nderong ze beschtähteje.",
"changeemail-no-info": "Do mööts ald enjelogg sin, öm tiräk op di Sigg jonn ze dörve",
"changeemail-oldemail": "Ding Address för de <i lang=\"en\">e-mail</i> es jäz:",
"changeemail-newemail": "Ding neue Address för de <i lang=\"en\">e-mail</i> sull wääde:",
"userlogin-yourpassword-ph": "Şîfreya xwe binivîse",
"createacct-yourpassword-ph": "Şîfreya xwe binivîse",
"yourpasswordagain": "Şîfreyê dîsa binivîse:",
- "createacct-yourpasswordagain": "Şîfreye bipejirîne",
- "createacct-yourpasswordagain-ph": "Şîfreyê ji nû ve têkeve",
+ "createacct-yourpasswordagain": "Şîfreyê bipejirîne",
+ "createacct-yourpasswordagain-ph": "Şîfreyê ji nû ve binivîse",
"remembermypassword": "Şifreya min di her têketina min de bîne bîra xwe (herî zêde $1 {{PLURAL:$1|rojekê|rojan}})",
"userlogin-remembermypassword": "Min têketî bihêle",
"userlogin-signwithsecure": "Girêdana parastî bikarbîne",
"gotaccount": "Hesabê te heye? $1.",
"gotaccountlink": "Têkeve",
"userlogin-resetlink": "Te agahiyên hesabê xwe ji bîr kirin?",
- "userlogin-resetpassword-link": "Te şîfreye xwe jibîrkir?",
+ "userlogin-resetpassword-link": "Te şîfreya xwe ji bîr kir?",
"userlogin-helplink2": "Alîkariya têketinê",
- "userlogin-createanother": "Hesabek din çeke",
+ "userlogin-createanother": "Hesabekî din çeke",
"createacct-emailrequired": "E-name",
"createacct-emailoptional": "E-name",
"createacct-email-ph": "E-nameya xwe binivîse",
- "createacct-another-email-ph": "E-nameya xwe têkeve",
- "createaccountmail": "Şîfreyek ji bo ji bo demeke kin bikarbînin û ji navnîşana hatiye diyarkirin re e-nameyek bişînin.",
+ "createacct-another-email-ph": "E-nameya xwe binivîse",
+ "createaccountmail": "Şîfreyeke demkî bikar bîne û wê ji navnîşana hatiye diyarkirin re bişîne.",
"createacct-realname": "Navê te ya rast (Ko tu bixwazi bikeve, pêdivî nîne)",
"createaccountreason": "Sedem:",
"createacct-reason": "Sedem",
- "createacct-reason-ph": "Çima hesabek din çedikîy",
- "createacct-captcha": "Kontrola asayîşê",
- "createacct-imgcaptcha-ph": "Nivîsa ku tu li jor dibînî binivîse",
+ "createacct-reason-ph": "Çima hesabekî din çêdikî",
"createacct-submit": "Hesabê xwe biafirîne",
- "createacct-another-submit": "Hesabek çêke",
- "createacct-benefit-heading": "{{SITENAME}} ji alî mirovên wek te tê çêkirin.",
+ "createacct-another-submit": "Hesabekî çêke",
+ "createacct-benefit-heading": "{{SITENAME}} ji aliyê mirovên wek te ve tê çêkirin.",
"createacct-benefit-body1": "{{PLURAL:$1|guhertin}}",
"createacct-benefit-body2": "{{PLURAL:$1|rûpel}}",
"badretype": "Her du şîfreyên ku te nivîsîn li hevdu nayên.",
"userexists": "Ev navî bikarhênerî berê tê bikaranîn. Xêra xwe navekî din dake.",
"loginerror": "Çewtiya têketinê",
- "createacct-error": "Çewtîya çêkirine hesabê",
+ "createacct-error": "Çewtiya çêkirina hesabî",
"createaccounterror": "Hesab nikare were çêkirin: $1",
"nocookiesnew": "Hesabê bikarhêner hatibû çêkirin, lê te xwe qeyd nekiriye. {{SITENAME}} ji bo qeydkirina bikarhêneran cookie'yan bikartîne. Te bikaranîna cookie'yan girtiye. Xêra xwe cookie'yan qebûl bike, piştre bi navê bikarhêner û şîfreya xwe têkeve.",
"nocookieslogin": "Ji bo qeydkirina bikarhêneran {{SITENAME}} \"cookies\" bikartîne. Te fonksîyona \"cookies\" girtîye. Xêra xwe kerema xwe \"cookies\" gengaz bike û careke din biceribîne.",
- "noname": "Navê ku te nivîsand derbas nabe.",
+ "noname": "Navê ku te nivîsand ne derbasdar e.",
"loginsuccesstitle": "Têketin serkevtî bû!",
"loginsuccess": "Tu niha di {{SITENAME}} de tomarkirî yî wek \"$1\".",
"nosuchuser": "Bikarhênerê bi navê \"$1\" tune. Navê rast binivîse an bi vê formê <b>hesabekî nû çêke</b>. (Ji bo hevalên nû \"Têkeve\" çênabe!)",
"showingresultsinrange": "Долу {{PLURAL:$1|е прикажан до <strong>еден</strong> резултат|се прикажани до <strong>$1</strong> резултати}} во опсег од <strong>$2</strong> до <strong>$3</strong>.",
"search-showingresults": "{{PLURAL:$4|Резултат <strong>$1</strong> од <strong>$3</strong>|Резултати <strong>$1 - $2</strong> од <strong>$3</strong>}}",
"search-nonefound": "Нема резултати што одговараат на бараното.",
+ "search-nonefound-thiswiki": "Нема резултати што одговараат на бараното на ова мрежно место.",
"powersearch-legend": "Напредно пребарување",
"powersearch-ns": "Пребарај во следниве именски простори:",
"powersearch-togglelabel": "Одбери:",
"pool-errorunknown": "अपरिचित त्रुटी",
"pool-servererror": "पूल काउंटर सेवा उपलब्ध नाही($1).",
"poolcounter-usage-error": "वापर त्रूटी:$1",
- "aboutsite": "{{SITENAME}}बद्दल",
+ "aboutsite": "{{SITENAME}} बद्दल",
"aboutpage": "Project:माहितीपृष्ठ",
"copyright": "येथील मजकूर $1च्या अंतर्गत उपलब्ध आहे जोपर्यंत इतर नोंदी केलेल्या नाहीत.",
"copyrightpage": "{{ns:project}}:प्रताधिकार",
"grouppage-suppress": "{{ns:project}}:झापडबंद",
"right-read": "पृष्ठे वाचा",
"right-edit": "पाने संपादा",
- "right-createpage": "पृष्ठे तयार करा (जी चर्चापानांव्यतिरिक्त)",
+ "right-createpage": "पृष्ठे तयार करा (जी चर्चापानांव्यतिरिक्त आहेत)",
"right-createtalk": "चर्चा पृष्ठे तयार करा",
"right-createaccount": "नवीन सदस्य खाती तयार करा",
"right-minoredit": "बदल किरकोळ म्हणून जतन करा",
"download": "अधिभारण करा",
"unwatchedpages": "देखरेख नसलेली पाने",
"listredirects": "पुनर्निर्देशनांची यादी",
+ "listduplicatedfiles": "प्रतिलिपी(डुप्लिकेट) संचिकांची यादी",
"unusedtemplates": "न वापरलेले साचे",
"unusedtemplatestext": "या पानावर साचा नामविश्वातील अशी सर्व पाने आहेत जी कुठल्याही पानात वापरलेली नाहीत. वगळण्यापूर्वी साच्यांना जोडणारे इतर दुवे पाहण्यास विसरू नका.",
"unusedtemplateswlh": "इतर दुवे",
"unusedimages": "न वापरलेल्या संचिका",
"wantedcategories": "पाहिजे असलेले वर्ग",
"wantedpages": "पाहिजे असलेले लेख",
+ "wantedpages-summary": "ही,ज्यांना अधिकांश दुवे आहेत अश्या अस्तित्वात नसलेल्या पानांची यादी आहे. यात ती पाने वगळली आहेत, ज्यांना फक्त पुनर्निर्देशनाचा दुवा आहे. अस्तित्वात नसलेली पण पुनर्निर्देशनाने जोडलेली जी पाने आहेत, अश्यांच्या यादीसाठी [[{{#special:BrokenRedirects}}|मोडकी पुनर्निर्देशने असलेल्या पानांची यादी]] बघा.",
"wantedpages-badtitle": "परिणामाच्या यादीत अवैध शीर्षक: $1",
"wantedfiles": "पाहिजे असलेल्या संचिका",
"wantedfiletext-cat": "पुढील फाइल्स वापरल्या असतील पण आता अस्तित्वात नाहीत. बाहेरील ठिकाणांच्या फाइल्स येथे दिसतात पण असतीलच असे नाही. अशा फाइल्स आढळल्यास वगळल्या जातील. अतिरिक्तपणे,अशी पाने, ज्यात टाकलेल्या संचिका अस्तित्वात नाहीत,त्याची यादी [[:$1]] येथे दिसेल.",
"exif-label": "लेबल",
"exif-datetimemetadata": "मेटाडाटाच्या शेवटच्या बदलाची तारीख",
"exif-nickname": "चित्राचे / फोटोचे सामान्य नाव",
- "exif-rating": "गुण (५ पैकी)",
+ "exif-rating": "गुणानुक्रम (५ पैकी)",
"exif-rightscertificate": "अधिकार व्यवस्थापन प्रमाणपत्र",
"exif-copyrighted": "प्रताधिकार स्थिती",
"exif-copyrightowner": "प्रताधिकार धारक",
"showingresultsinrange": "{{PLURAL:$1|Vene mmustato|Veneno mmustate}} abbascio {{PLURAL:$1|<strong>1</strong> risultato|<strong>$1</strong> risultate}} d' 'o <strong>$2</strong> a 'o <strong>$3</strong>.",
"search-showingresults": "{{PLURAL:$4|Risultato <strong>$1</strong> 'e <strong>$3</strong>|Risultate <strong>$1 - $2</strong> 'e <strong>$3</strong>}}",
"search-nonefound": "'A ricerca nun ha produtto risultate.",
+ "search-nonefound-thiswiki": "Nun ce stevano risultate p' 'a ricerca fatta.",
"powersearch-legend": "Ricerca avanzata",
"powersearch-ns": "Ascìa dint' 'o namespace:",
"powersearch-togglelabel": "Cuntrolla:",
"tog-numberheadings": "Automuattizesti numeroija kirjutuksien nimet",
"tog-showtoolbar": "Ozuta ruadovälinehpalki",
"tog-editondblclick": "Edituiče sivuloi kaksoispainalduksel",
- "tog-editsectiononrightclick": "Korjua sektsielöi painamal sektsien nimie hiiren oigiel näppäimel",
+ "tog-editsectiononrightclick": "Kohendele sektsielöi painamal sektsien nimie hiiren oigiel näppäimel",
"tog-watchcreations": "Ližiä minun luajitut sivut da ližätyt failat minun valvonduluvetteloh",
"tog-watchdefault": "Ližiä minun kohendetut sivut da failat minun valvonduluvetteloh",
"tog-watchmoves": "Ližiä minun siirretyt sivut da failat minun valvonduluvetteloh",
"tog-fancysig": "Allekirjutus wikitekstannu (ilmai automuattistu linkii)",
"tog-uselivepreview": "Käytä välittömiä ezikaččeluu",
"tog-forceeditsummary": "Huomavuta minuu, gu en olle kirjutannuh yhtehveduo",
- "tog-watchlisthideown": "Peitä minun korjavukset valvonduluvettelospäi",
+ "tog-watchlisthideown": "Peitä minun kohendelut valvonduluvettelospäi",
"tog-watchlisthidebots": "Peitä botan kohendukset valdondulistalpäi",
"tog-watchlisthideminor": "Peitä pienet kohendukset valvondulistalpäi",
"tog-watchlisthideliu": "Peitä kirjutannuhuoloin käyttäjien kohendukset valvondulistalpäi",
"print": "Pane bumuagale",
"view": "Kačo",
"view-foreign": "Kačo saital $1",
- "edit": "Korjua",
+ "edit": "Kohendele",
"edit-local": "Edituiče paikallistu kuvavustu",
"create": "Luaji",
"create-local": "Ližiä paikalline kuvavus",
- "editthispage": "Korjua tädä sivuu",
+ "editthispage": "Kohendele tädä sivuu",
"create-this-page": "Luaji tämä sivu",
"delete": "Ota iäre",
"deletethispage": "Ota tämä sivu iäre",
"disclaimers": "Kieldävymine vastuos",
"disclaimerpage": "Project:Vastuos kieldävymine",
"edithelp": "Abu korjuamizeh",
- "helppage-top-gethelp": "Kyzyö abuu",
+ "helppage-top-gethelp": "Kyzy abuu",
"mainpage": "Piäsivu",
"mainpage-description": "Piäsivu",
"policy-url": "Project:Käytändöt",
"newmessageslinkplural": "{{PLURAL:$1|uuzi viesti|999=uuzii viestilöi}}",
"newmessagesdifflinkplural": "{{PLURAL:$1|jälgimäine muutos|jälgimästy muutostu}}",
"youhavenewmessagesmulti": "Sinul on uuzii viestilöi sivuloil $1",
- "editsection": "Korjua",
- "editold": "korjua",
+ "editsection": "Kohendele",
+ "editold": "kohendele",
"viewsourceold": "Kačo algukoodu",
- "editlink": "korjua",
+ "editlink": "kohendele",
"viewsourcelink": "Kačo algukoodu",
- "editsectionhint": "Korjua tädä kohtua: $1",
+ "editsectionhint": "Kohendele tädä kohtua: $1",
"toc": "Sizäldö",
"showtoc": "ozuttua",
"hidetoc": "peittiä",
"hr_tip": "Horizontualine viivu (älä käytä liijakse)",
"summary": "Yhtehvedo:",
"subject": "Tiemu/rubriekku:",
- "minoredit": "Tämä on pieni korjavus",
+ "minoredit": "Tämä on pieni kohendelu",
"watchthis": "Tarkaile tädä sivuu",
"savearticle": "Tallenda sivu",
"preview": "Ezikačo",
"showpreview": "Ezikačo",
- "showdiff": "Luajitut korjavukset",
+ "showdiff": "Luajitut kohendelut",
"anoneditwarning": "<strong>Varaitus:</strong> Et ole kirjutannuhes. Luadinet muutoksii syväindölöih, sinun Ip-adressu tulou nägövih kaikile. Ku <strong>[$1 kirjutannuttos]</strong> libo <strong>[$2 registriiruičettos]</strong>, sinun syväindömuutokset nävytäh sinun käyttäinimel, toizien eduloin ližäkse.",
"summary-preview": "Yhtehvevon ezikačondu:",
"subject-preview": "Teeman ezikačondu:",
"template-semiprotected": "(puolekse suojattu)",
"hiddencategories": "Tämä sivu kuuluu {{PLURAL:$1|1 peitettyh kategourieh|$1 peitettyh kategourieh}}:",
"sectioneditnotsupported-title": "Sektsien kohendustu ei tuveta.",
- "sectioneditnotsupported-text": "Sektsieb kohendustu ei tuveta täl sivul.",
+ "sectioneditnotsupported-text": "Sektsien kohendustu ei tuveta täl sivul.",
"permissionserrors": "Ei oigevuksii",
"permissionserrorstext": "Sinul ei ole lubua toimindoh {{PLURAL:$1|tämän syyn periä|nämmien syylöin periä}}:",
"permissionserrorstext-withaction": "Sinul ei ole lubua toimindoh $2 niškoi, {{PLURAL:$1|tämän syyn periä|nämmien syylöin periä}}:",
"action-move-subpages": "siirrä tämä sivu, da sen alisivut",
"action-movefile": "siirrä tämä failu",
"enhancedrc-history": "histourii",
- "recentchanges": "Uvvet korjavukset",
+ "recentchanges": "Uvvet kohendelut",
"recentchanges-legend": "Tuorehien muutoksien azetukset",
"recentchanges-summary": "Jällitä kaikkii jälgimäzet muutokset wikih täl sivul.",
"recentchanges-label-newpage": "Tämä korjavus on johtanuh uvven sivun luadimizeh",
- "recentchanges-label-minor": "Tämä on pieni korjavus",
+ "recentchanges-label-minor": "Tämä on pieni kohendelu",
"recentchanges-label-bot": "Tämän muutoksen on luadinuh bot",
"recentchanges-label-unpatrolled": "Tädä korjuandua vie ei ole tarkistettu",
"recentchanges-label-plusminus": "Sivu on kazvanuh [] baital",
"boteditletter": "b",
"rc-change-size-new": "Kogo jälles muutoksii: $1 {{PLURAL:$1|baitu|baitua}}",
"recentchangeslinked": "Koskijat muutokset",
- "recentchangeslinked-toolbox": "Toine toizeh liittyjät korjavukset",
+ "recentchangeslinked-toolbox": "Toine toizeh liittyjät kohendelut",
"recentchangeslinked-title": "Muutokset koskijen sivuu \"$1\"",
"recentchangeslinked-summary": "Tämä on nengomien sivuloin korjavuksien luvettelo, kudamih viittuau tämä sivu (libo sih kategourieh kuulujat).Sivut, kudamat kuulutah [[Special:Watchlist|teijän valvonduluvettelo]], ollah <strong>bold</strong>.",
"recentchangeslinked-page": "Sivun nimi:",
"whatlinkshere-hidelinks": "$1 linkat",
"whatlinkshere-filters": "Filtrat",
"blocklink": "Lukiče",
- "contribslink": "korjavukset",
+ "contribslink": "kohendelut",
"movelogpage": "Siirrä loga",
"export": "Vie sivut",
"allmessages-language": "Kieli:",
"tooltip-pt-logout": "Kirjuttai ullos",
"tooltip-pt-createaccount": "Voit registriiruijakseh da kirjuttuakseh järjestelmäh, ga se ei ole vältämätöi",
"tooltip-ca-talk": "Pagize piäsivun sizäldös",
- "tooltip-ca-edit": "Korjua tädä sivuu",
+ "tooltip-ca-edit": "Kohendele tädä sivuu",
"tooltip-ca-addsection": "Luaji uuzi alalugu",
"tooltip-ca-viewsource": "Tämä sivu on suojattu. Voit kaččuo sen lähtehkoudan",
"tooltip-ca-history": "Tämän sivun jälgimäzet muutokset",
"tooltip-save": "Tallenda muutokset",
"tooltip-preview": "Ezikačo muutokset. Ole hyvä, luaji nenga ainos enne tallendamistu!",
"tooltip-diff": "Ozuta sinun luajitut muutokset tekstah",
- "tooltip-rollback": "Yhtel painalluksel poistua jälgimäine korjavus",
+ "tooltip-rollback": "Yhtel painalluksel poistua jälgimäine kohendelu",
"tooltip-undo": "\"Kumua\" tuou järilleh aijemban edituičenduversien da avuau edituičenduankietan ezikaččelendutilas. Sen vuoh voi ližätä kumuandumotiivan yhtehvevos.",
"tooltip-summary": "Kirjuta lyhyt kuvavus",
"simpleantispam-label": "Anti-spam-tarkistus. \n<strong>älä</strong> täytä!",
"showingresultsinrange": "Poniżej wyświetlono co najwyżej {{PLURAL:$1|<strong>1</strong> wynik|<strong>$1</strong> wyniki|<strong>$1</strong> wyników}} w zakresie od <strong>$2</strong> do <strong>$3</strong>.",
"search-showingresults": "{{PLURAL:$4|Wynik <strong>$1</strong> z <strong>$3</strong>|Wyniki <strong>$1 - $2</strong> z <strong>$3</strong>}}",
"search-nonefound": "Brak wyników spełniających kryteria podane w zapytaniu.",
+ "search-nonefound-thiswiki": "Brak wyników spełniających kryteria podane w zapytaniu.",
"powersearch-legend": "Wyszukiwanie zaawansowane",
"powersearch-ns": "Przeszukaj przestrzenie nazw:",
"powersearch-togglelabel": "Zaznacz:",
"prefs-help-recentchangescount": "Uwzględnia ostatnie zmiany, historię stron i rejestry.",
"prefs-help-watchlist-token2": "To jest tajny klucz umożliwiający dostęp do kanału internetowego zmian w obserwowanych przez Ciebie stronach.\nKażdy, kto go zna, będzie mógł je zobaczyć, więc zachowaj go dla siebie.\n[[Special:ResetTokens|Kliknij tu, jeśli musisz go zresetować]].",
"savedprefs": "Twoje preferencje zostały zapisane.",
+ "savedrights": "Zapisano uprawnienia {{GENDER:$1|użytkownika $1|użytkowniczki $1}}.",
"timezonelegend": "Strefa czasowa:",
"localtime": "Czas lokalny:",
"timezoneuseserverdefault": "Użyj domyślnej dla tej wiki ($1)",
"tog-hideminor": "په وروستيو بدلونو کې واړه سمونونه پټول",
"tog-hidepatrolled": "په وروستيو بدلونونو کې څارل شوې سمونونه پټول",
"tog-newpageshidepatrolled": "د نوؤ مخونو په لړليک کې کتل شوي مخونه پټول",
+ "tog-hidecategorization": "په وېشنيزو کې د مخونو وېشنه پټول",
"tog-extendwatchlist": "يوازې د وروستني بدلونونو د ښکاره کولو لپاره نه بلکه د ټولو بدلونونو د ښکاره کولو لپاره کتنلړ غځول",
"tog-usenewrc": "په کتنلړ او وروستي بدلونو مخ باندې ډله ايز بدلونونه",
"tog-numberheadings": "د سرليکونو خپلکاره شمېرايښودنه",
"tog-watchlisthideliu": "په کتنلړ کې د ثبت شويو کارنانو سمونې پټول",
"tog-watchlisthideanons": "په کتنلړ کې د ورکنومو کارنانو سمونې پټول",
"tog-watchlisthidepatrolled": "په کتنلړ کې څارل شوې سمونې پټول",
+ "tog-watchlisthidecategorization": "په وېشنيزو کې د مخونو وېشنه پټول",
"tog-ccmeonemails": "هغه برېښليکونه چې زه يې نورو ته لېږم، د هغو يوه کاپي دې ماته هم راشي",
"tog-diffonly": "د توپيرونو نه لاندې د مخ مېنځپانگه پټول",
"tog-showhiddencats": "پټې وېشنيزې ښکاره کول",
"createaccountreason": "سبب:",
"createacct-reason": "سبب",
"createacct-reason-ph": "ولې تاسې بل گڼون جوړول غوااړۍ",
- "createacct-captcha": "امنيتي تدبير",
- "createacct-imgcaptcha-ph": "پورته ښکاره شوی متن دلته وټاپئ",
"createacct-submit": "گڼون مو جوړ کړئ",
"createacct-another-submit": "گڼون جوړول",
"createacct-benefit-heading": "{{SITENAME}} ستاسې په شان خلکو لخوا جوړ شوی.",
"sig_tip": "ستاسې لاسليک د وخت د ټاپې سره",
"hr_tip": "څنډيزه ليکه (ددې په کارولو کې سپما وکړۍ)",
"summary": "لنډيز:",
- "subject": "سکالو/سرليک:",
+ "subject": "سکالو:",
"minoredit": "دا يو وړوکی سمون دی",
"watchthis": "همدا مخ کتل",
"savearticle": "مخ خوندي کول",
"anonpreviewwarning": "''تاسې غونډال ته نه ياست ننوتي. خوندي کولو سره به ستاسې IP پته به د دې مخ د سمونونو په پېښليک کې ثبت شي.''",
"missingcommenttext": "لطفاً تبصره لاندې وليکۍ.",
"summary-preview": "د لنډيز مخليدنه:",
- "subject-preview": "سکاÙ\84Ù\88/سرÙ\84Ù\8aÚ© مخليدنه:",
+ "subject-preview": "د سکاÙ\84Ù\88 مخليدنه:",
"previewerrortext": "د بدلونونو د مخليدنو په وخت کې مو يوه ستونزه رامېنځ ته شوه.",
"blockedtitle": "پر کارن بنديز لگېدلی",
"blockedtext": "'''ستاسې د کارن-نوم يا آی پي پتې مخنيوی شوی.'''\n\nهمدا بنديز د $1 له خوا پر تاسې لږېدلی. او د همدې کړنې سبب ''$2'' دی.\n\n* د بنديز د پېل نېټه: $8\n* د بنديز د پای نېټه: $6\n* بنديزونه دي پر: $7\n\nتاسې کولای شی چې د $1 او يا هم د يو بل [[{{MediaWiki:Grouppage-sysop}}|پازوال]] سره اړيکې ټينگې کړی او د بنديز ستونزې مو هوارې کړی.\nتاسې نه شی کولای چې د 'کارن ته برېښلک لېږل' کړنې نه گټه پورته کړی تر څو چې تاسې د خپل گڼون په [[Special:Preferences|غوره توبونو]] کې يوه کره برېښليک پته نه وي ځانگړې کړې او تر دې بريده چې پر تاسې د هغې د کارولو بنديز نه وي لگېدلی.\nستاسې د دم مهال آی پي پته $3 ده، او ستاسې د بنديز پېژند #$5 دی. مهرباني وکړۍ د خپلې يادونې پر مهال د دغو دوو څخه د يوه او يا هم د دواړو ورکول مه هېروۍ.",
"rcshowhidemine": "زما سمونې $1",
"rcshowhidemine-show": "ښکاره کول",
"rcshowhidemine-hide": "پټول",
+ "rcshowhidecategorization-show": "ښکاره کول",
+ "rcshowhidecategorization-hide": "پټول",
"rclinks": "هغه وروستي $1 بدلونونه ښکاره کړی چې په $2 ورځو کې پېښ شوي<br />$3",
"diff": "توپير",
"hist": "پېښليک",
"newpageletter": "ن",
"boteditletter": "ر",
"number_of_watching_users_pageview": "[$1 {{PLURAL:$1|کتونکی کارن|کتونکي کارنان}}]",
- "rc_categories": "د Ù\88Û\90Ø´Ù\86Ù\8aزÙ\88 برÙ\8aدÙ\88Ù\86ه (په \"|\" بېلول)",
+ "rc_categories": "د Ù\88Û\90Ø´Ù\86Ù\8aزÙ\88 تر برÙ\8aده (په \"|\" بېلول)",
"rc_categories_any": "له ټاکل شويو هر يو",
"rc-change-size-new": "$1 {{PLURAL:$1|بايټ|بايټونه}} د بدلون وروسته",
"newsectionsummary": "/* $1 */ نوې برخه",
"recentchangeslinked-summary": "دا د هغه بدلونونو لړليک دی چې وروستۍ ځل په تړن لرونکيو مخونو کې د يوه ځانگړي مخ (او يا هم د يوې ځانگړې وېشنيزې غړو) نه رامېنځ ته شوي.\n[[Special:Watchlist|ستاسې د کتنلړ]] مخونه په '''زغرد ليک''' کې ښکاري.",
"recentchangeslinked-page": "د مخ نوم:",
"recentchangeslinked-to": "د ورکړل شوي مخ پر ځای د اړونده تړلي مخونو بدلونونه ښکاره کول",
+ "recentchanges-page-added-to-category": "[[:$1]] وېشنيزې کې ورگډ شو",
+ "recentchanges-page-added-to-category-bundled": "[[:$1]] او {{PLURAL:$2|يو مخ|$2 مخونه}} وېشنيزې کې ورگډ شول",
+ "recentchanges-page-removed-from-category": "[[:$1]] له وېشنيزې وغورځول شو",
+ "recentchanges-page-removed-from-category-bundled": "[[:$1]] او {{PLURAL:$2|يو مخ|$2 مخونه}} له وېشنيزې وغورځول شول",
+ "autochange-username": "د مېډياويکي خپلکاره بدلون",
"upload": "دوتنه پورته کول",
"uploadbtn": "دوتنه پورته کول",
"reuploaddesc": "پورته کېدنه ناگارل او بېرته د پورته کېدنې فورمې ته ورگرځېدل",
"upload-form-label-infoform-description": "څرگندونه",
"upload-form-label-usage-title": "کارېدنې",
"upload-form-label-usage-filename": "د دوتنې نوم",
+ "foreign-structured-upload-form-label-infoform-categories": "وېشنيزې",
+ "foreign-structured-upload-form-label-infoform-date": "نېټه",
"backend-fail-notexists": "د $1 په نوم دوتنه نشته.",
"backend-fail-delete": "د \"$1\" دوتنه ړنګه نه شوه.",
"backend-fail-alreadyexists": "د $1 دوتنه له پخوا نه شته.",
"movenotallowedfile": "تاسې د دوتنو د لېږدولو پرېښله نلرۍ.",
"cant-move-user-page": "تاسې د کارن مخونو د لېږدولو پرېښله نلرۍ (د څېرمه مخونو نه پرته).",
"cant-move-to-user-page": "تاسې د يو کارن مخ ته د يوه بل مخ د لېږدولو پرېښله نلرۍ (د يو کارن د څېرمه مخ نه پرته).",
- "newtitle": "نوي سرليک ته:",
+ "newtitle": "نوی سرليک:",
"move-watch": "همدا مخ کتل",
"movepagebtn": "مخ لېږدول",
"pagemovedsub": "لېږدول په برياليتوب سره ترسره شوه",
"htmlform-cloner-create": "نور ورگډول",
"htmlform-cloner-delete": "غورځول",
"htmlform-cloner-required": "لږ تر لږه يو ارزښت ته اړتيا شته.",
+ "htmlform-title-not-exists": "[[:$1]] نشته.",
+ "htmlform-user-not-exists": "<strong>$1</strong> نشته.",
"logentry-delete-delete": "$1 د $3 مخ {{GENDER:$2|ړنگ کړ}}",
"revdelete-content-hid": "مېنځپانگه پټېدلې",
"revdelete-uname-hid": "کارن نوم پټ شوی",
"special-characters-group-thai": "تايلنډي",
"special-characters-group-lao": "لاوي",
"special-characters-group-khmer": "خمري",
- "mw-widgets-titleinput-description-new-page": "پدې نوم لا تر اوسه پورې مخ نشته",
- "mw-widgets-titleinput-description-redirect": "$1 ته ورگرځول"
+ "mw-widgets-titleinput-description-new-page": "تر اوسه پورې دا مخ نشته",
+ "mw-widgets-titleinput-description-redirect": "$1 ته ورگرځېدنه"
}
"showingresultsinrange": "Ниже показано до {{PLURAL:$1|<strong>1</strong> результата|<strong>$1</strong> результата|<strong>$1</strong> результатов}} в диапазоне от <strong>$2</strong> до <strong>$3</strong>.",
"search-showingresults": "{{PLURAL:$4|Результат <strong>$1</strong> из <strong>$3</strong>|Результаты <strong>$1 — $2</strong> из <strong>$3</strong>}}",
"search-nonefound": "Соответствий запросу не найдено.",
+ "search-nonefound-thiswiki": "Нет результатов, соответствующих запросу на этом сайте.",
"powersearch-legend": "Расширенный поиск",
"powersearch-ns": "Поиск в пространствах имён:",
"powersearch-togglelabel": "Отметить:",
"import-error-special": "\"$1\" сирэй импортаммата, тоҕо диэтэххэ кини угуллубут аатын далыгар саҥа сирэйдэри оҥорор көҥүллэммэт эбит.",
"import-error-invalid": "\"$1\" сирэй импортаммата, тоҕо диэтэххэ маннык аат туттуллара бу биикигэ бобуулаах.",
"import-error-unserialize": "«$1» сирэй $2 барыла структуураланар (десериализация) кыаҕа суох. Барылга иһинээҕитин модела маннык: $3, маннык серияланар: $4.",
+ "import-error-bad-location": "$2 уларытыы, $3 мадьыалы туһанар буолан бу биики «$1» сирэйигэр бигэргэтиллэр кыаҕа суох эбит, тоҕо диэтэххэ ити мадьыал бу сирэйгэ өйөнүллүбэт.",
"import-options-wrong": "Алҕастаах {{PLURAL:$2|опция|опциялар}}: <nowiki>$1</nowiki>",
"import-rootpage-invalid": "Тирэх сирэй ыйыллыбыт аата алҕастаах.",
"import-rootpage-nosubpage": "\"$1\" тирэх сирэй аатын далыгар сирэй үөдүҥнэрэ (подстраницалар) көҥүллэммэттэр",
"importlogpage": "Импорт сурунаала",
"importlogpagetext": "Сирэйдэри историяларын кытта холбуу атын биикилэртэн импортааһын.",
- "import-logentry-upload-detail": "$1 {{PLURAL:$1|барыл|барыл баар}}",
- "import-logentry-interwiki-detail": "баÑ\80Ñ\8bÑ\82а $2 баÑ\80Ñ\8bлÑ\82ан $1 баÑ\80Ñ\8bл",
+ "import-logentry-upload-detail": "$1 {{PLURAL:$1|барыл угулунна|барылы уктубут}}",
+ "import-logentry-interwiki-detail": "Ð\91аÑ\80Ñ\8bÑ\82а $2 баÑ\80Ñ\8bлÑ\82ан $1 баÑ\80Ñ\8bл Ñ\83гÑ\83лÑ\83нна",
"javascripttest": "JavaScript тургутуу",
"javascripttest-pagetext-noframework": "Бу сирэй JavaScript тургутууларга анаммыт.",
"javascripttest-pagetext-unknownframework": "\"$1\" тургутуу биллибэт эйгэтэ.",
"pageinfo-watchers": "Кэтээнэр сирэйдэр ахсааннара",
"pageinfo-visiting-watchers": "Сирэйи кэтиир уонна тиһэх көннөрүүлэри көрбүт дьон ахсаана",
"pageinfo-few-watchers": "$1 кыттааччыттан аҕыйах кэтээччи",
+ "pageinfo-few-visiting-watchers": "Сирэйи кэтиир уонна тиһэх уларыйыылары көрбүт да, атын да кыттааччылар буолуохтарын сөп",
"pageinfo-redirects-name": "Бу сирэйгэ утаарыы ахсаана",
"pageinfo-subpages-name": "Сирэй аннынааҕы сирэйдэр ахсааннара",
"pageinfo-subpages-value": "$1 ($2 утаарыы; $3 көннөрү (утаарыыта суох))",
"signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|ырытыы]])",
"duplicate-defaultsort": "Болҕой: Наардааһын «$2» күлүүһэ урукку «$1» күлүүһү сабар (Ключ сортировки переопределяет прежний ключ).",
"duplicate-displaytitle": "<strong>Болҕой:</strong> Көрдөрүллүбүт «$2» аат урут көрдөрүллүбүт «$1» ааты уларытар.",
+ "invalid-indicator-name": "<strong>Алҕас:Сирэй туругун көрдөрөр индикатор </strong> атрибута <code>name</code> кураанах буолуо суохтаах.",
"version": "MediaWiki барыла (биэрсийэтэ)",
"version-extensions": "Туруоруллубут расширениялар",
"version-skins": "Туруоруллубут тас көстүү барыллара",
"tags-create-invalid-chars": "Бэлиэ аатыгар сопутуой (<code>,</code>) эбэтэр слэш (<code>/</code>) буолуохтаах.",
"tags-create-invalid-title-chars": "Тиэк аатыгар сирэй баһыгар туттуллуо суохтаах бэлиэ киириэ суохтаах",
"tags-create-already-exists": "«$1» тиэк хайыы-үйэ баар эбит.",
+ "tags-create-warnings-above": "«$1» тиэги оҥорорго маннык {{PLURAL:$2|сэрэтии көһүннэ|сэрэтиилэр көһүннүлэр}}:",
+ "tags-create-warnings-below": "Тиэги салгыы оҥоруоххун баҕараҕын дуо?",
"tags-delete-title": "Тиэги сот",
"tags-delete-explanation-initial": "«$1» тиэги билии олоҕуттан сотон эрэҕин.",
"tags-delete-reason": "Төрүөтэ:",
"nstab-template": "Šabluons",
"nstab-help": "Pagelbuos poslapis",
"nstab-category": "Kateguorėjė",
+ "mainpage-nstab": "Pėrms poslapis",
"nosuchaction": "Nier tuokė vēksma",
"nosuchspecialpage": "Nier tuokė specēlėjė poslapė",
"nospecialpagetext": "Tamsta prašiet nelaistėna specēlė̄jė poslapė, laistėnū specēliūju poslapiu sōraša rasėt [[Special:SpecialPages|specēliūju poslapiu sārošė]].",
"right-read": "Skaitītė poslapius",
"right-edit": "Keistė poslapius",
"right-upload": "Ikeltė failus",
+ "right-writeapi": "Nauduotė API rašīmō",
"right-delete": "Trintė poslapius",
"newuserlogpage": "Nauduotuojė kūrėma sārošos",
"rightslog": "Nauduotuoju teisiu istuorėjė",
"undelete-show-file-submit": "Tēp",
"namespace": "Vardū srėtės:",
"invert": "Žīmietė prīšėngā",
+ "tooltip-invert": "Pažīmiekat ton varnalė, ka pakavuotomiet pakeitėmus pasėrinktūs poslapiūs (ė prėgolontės vardū srėtis)",
"namespace_association": "Prėgolontė vardū srėtės",
+ "tooltip-namespace_association": "Pažīmiekat ton varnalė, ka prėgoldītomat aptarėmus, katrėi ī sosėjė so parinkta vardū srėtim",
"blanknamespace": "(Pagrėndinė)",
"contributions": "Nauduotuojė duovis",
"contributions-title": "Nauduotuojė $1 duovis",
"tooltip-t-permalink": "Nūlatėnė nūruoda ton poslapė atmainuō",
"tooltip-ca-nstab-main": "Ruodītė poslapė torėni",
"tooltip-ca-nstab-user": "Ruodītė nauduotuojė poslapi",
- "tooltip-ca-nstab-special": "Tas poslapis īr specēlos - anuo nagalėm keistė.",
+ "tooltip-ca-nstab-special": "Tas poslapis īr specēlos - anon nagalam keistė.",
"tooltip-ca-nstab-project": "Ruodītė pruojekta poslapi",
"tooltip-ca-nstab-image": "Ruodītė abruozdielė poslapi",
"tooltip-ca-nstab-mediawiki": "Veizietė sėstėmas pranešėma",
"spambot_username": "''MediaWiki'' reklamu šalėnėms",
"spam_reverting": "Atkoriama i onkstesne versėje, katra nator nūruodu i $1",
"spam_blanking": "Vėsos versėjės toriejė nūruodu i $1. Ėšvaluoma",
+ "simpleantispam-label": "Patikrėnėms nug šiokšlėnėma.\n<strong>Napildėkat</strong> šėton!",
"pageinfo-header-basic": "Poslapė žėnės",
"pageinfo-header-edits": "Keitėma istuorėjė",
"pageinfo-header-restrictions": "Poslapė apsauga",
"exif-make": "Puortaparata dėrbies",
"exif-model": "Puortaparata muodelis",
"exif-artist": "Autuorios",
+ "exif-exifversion": "Exif atmains",
"exif-colorspace": "Spalvū lauks",
"exif-compressedbitsperpixel": "Abruozdielė sospaudėma rėžėms",
"exif-pixelydimension": "Abruozdielė platoms",
"external_image_whitelist": " #Palikėt ta eilotė, tuokė kāp īr <pre>\n#Īrašīkat standartėniu ėšraišku fragmentus (tėktās dali terp //)\n#Anūs bus miegėnama sotapatintė so ėšuorėniu abruozdieliu adresās\n#Tė, katrėi sotaps, bus ruodomė kāp abruozdielē, a kėtė bus ruodomė tėktās kāp nūoruodas\n#Raidiu dėdoms nier svarbos\n#Eilotės, katuos prasided # īr kuomentarā \n\n#Īterpkat vėsus standartiėniu ėšraišku fragmentus prīš šėta eilote. Palikat šėta eilote, tuokė kāp ana īr </pre>",
"tag-filter": "[[Special:Tags|Žīmiū]] kuošeklis:",
"tag-filter-submit": "Kuošeklis",
+ "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Žīms|Žīmā|Žīmū}}]]: $2)",
"tags-edit": "taisītė",
"comparepages": "Primestė poslapio",
"logentry-delete-delete": "$1 ėštrīnė poslapi $3",
"logentry-delete-restore": "$1 atkūrė poslapi $3",
"revdelete-content-hid": "torėnīs pakavuots",
+ "logentry-block-block": "ožgīnė „[[$1]]“ nug dėrbėma, tas vēk ton čiesa - $2 $3",
"logentry-move-move": "$1 {{GENDER:$2|parvadėna}} poslapi $3 i $4",
"logentry-move-move-noredirect": "$1 {{GENDER:$2|parvadėna}} poslapi nug $3 i $4 nepalinkdoms nusokėma",
"logentry-move-move_redir": "$1 {{GENDER:$2|parvadėna}} poslapi nog $3 i $4 ont bovosė nusokėma",
"showingresultsinrange": "Spodaj prikazujem {{PLURAL:$1|1=<strong>1</strong> rezultat|<strong>$1</strong> rezultata|<strong>$1</strong> rezultate|<strong>$1</strong> rezultatov}} v razponu od št. <strong>$2</strong> do št. <strong>$3</strong>.",
"search-showingresults": "{{PLURAL:$4|Rezultat <strong>$1</strong> od <strong>$3</strong>|Rezultati <strong>$1–$2</strong> od <strong>$3</strong>}}",
"search-nonefound": "Ni bilo zadetkov, ki ustrezajo poizvedbi.",
+ "search-nonefound-thiswiki": "Našli nismo nobenega rezultata, ki bi se ujemal s poizvedbo na tej strani.",
"powersearch-legend": "Napredno iskanje",
"powersearch-ns": "Iskanje v imenskih prostorih:",
"powersearch-togglelabel": "Izberi:",
"parser-template-recursion-depth-warning": "Дубина укључивања шаблона је прекорачена ($1)",
"language-converter-depth-warning": "Прекорачена је граница дубине језичког претварача ($1)",
"node-count-exceeded-category": "Странице у којима је прекорачен број чворова",
- "node-count-exceeded-category-desc": "СÑ\82Ñ\80аниÑ\86а Ñ\98е пÑ\80екоÑ\80аÑ\87ила бÑ\80оÑ\98 Ñ\87воÑ\80ова.",
+ "node-count-exceeded-category-desc": "СÑ\82Ñ\80аниÑ\86е Ñ\81а пÑ\80евиÑ\88е Ñ\87воÑ\80ова (node).",
"node-count-exceeded-warning": "Страница у којој је прекорачен број чворова",
"expansion-depth-exceeded-category": "Странице у којима је прекорачена дубина проширења",
"expansion-depth-exceeded-category-desc": "Страница је прекорачила највећу дубину проширења.",
"Marfuas",
"Macofe",
"Aaoo",
- "Josve05a"
+ "Josve05a",
+ "Pipetricker"
]
},
"tog-underline": "Stryk under länkar:",
"logentry-upload-upload": "$1 {{GENDER:$2|laddade upp}} $3",
"logentry-upload-overwrite": "$1 {{GENDER:$2|laddade upp}} en ny version av $3",
"logentry-upload-revert": "$1 {{GENDER:$2|laddade upp}} $3",
- "log-name-managetags": "Tagghanterings logg",
+ "log-name-managetags": "Märkeshanteringslogg",
"log-description-managetags": "Denna sida innehåller administrativa [[Special:Tags|märke]]srelaterade uppgifter. Loggen innehåller bara åtgärder som utförts manuellt av en administratör; märken kan skapas eller raderas av wikins mjukvara utan att en post registreras i loggen.",
"logentry-managetags-create": "$1 {{GENDER:$2|skapade}} taggen \"$4\"",
"logentry-managetags-delete": "$1 {{GENDER:$2|raderade}} taggen \"$4\" (borttagen från $5 {{PLURAL:$5|version eller loggpost|versioner och/eller loggposter}})",
"VASANTH S.N.",
"VinodSBangera",
"아라",
- "Vishwanatha Badikana"
+ "Vishwanatha Badikana",
+ "Bharathesha Alasandemajalu",
+ "Soundarya shetty s",
+ "రహ్మానుద్దీన్"
]
},
"tog-underline": "ಲಿಂಕ್’ಲೆದ ತಿರ್ತ್ ಗೆರೆ(ಅಂಡರ್ ಲೈನ್) ಪಾಡ್’ಲೆ",
"editfont-sansserif": "ಸಾನ್ಸ್-ಸೆರಿಫ್ ಲಿಪಿ",
"editfont-serif": "ಸೆರಿಫ್ ಲಿಪಿ",
"sunday": "ಐತಾರ",
- "monday": "ಸà³\8bಮವಾರ",
- "tuesday": "ಅಂಗರೆ",
+ "monday": "ಸà³\8bಮಾರà³\8a",
+ "tuesday": "à²\85à²\82à²\97ಾರà³\86",
"wednesday": "ಬುಧವಾರ",
"thursday": "ಗುರುವಾರ",
"friday": "ಶುಕ್ರವಾರ",
"faqpage": "Project:ಸಾಮಾನ್ಯವಾದ್ ಕೇನುನ ಪ್ರಶ್ನೆಲು",
"actions": "ಕ್ರಿಯೆಕ್ಕುಲು",
"namespaces": "ಪುದರ್ ದ ವರ್ಗೊಲು",
- "variants": "ರà³\82ಪಾà²\82ತರ ಹà³\8aà²\82ದà³\8dâ\80\98ನ",
- "navigation-heading": "ಸà²\82à²\9aರಣà³\86 ಮà³\86ನà³\81",
+ "variants": "ರà³\82ಪಾà²\82ತರ ಹà³\8aà²\82ದà³\8dâ\80\8dನ",
+ "navigation-heading": "ಸà²\82à²\9aಾರà³\8aದ ಪರಿವಿಡಿ",
"errorpagetitle": "ದೋಷ",
"returnto": "$1 ಗ್ ಪಿರ ಪೋಲೆ.",
"tagline": "{{SITENAME}} ರ್ದ್",
- "help": "ಸಹಾಯ",
+ "help": "ಸಹಾಯೊ",
"search": "ನಾಡ್",
"searchbutton": "ನಾಡ್",
"go": "ಪೋ",
"history_short": "ಇತಿಹಾಸ",
"updatedmarker": "ಎನ್ನ ಅಕೇರಿದ ವೀಕ್ಷಣೆ ಡ್ದ್ ಬುಕ್ಕ ಆಯಿನ ಬದಲಾವಣೆಲು",
"printableversion": "ಪ್ರಿಂಟ್ ಆವೃತ್ತಿ",
- "permalink": "ಸà³\8dಥಿರ ಸಂಪರ್ಕ",
+ "permalink": "ಸà³\8dತಿರà³\8a ಸಂಪರ್ಕ",
"print": "ಪ್ರಿ೦ಟ್ ಮನ್ಪುಲೆ",
"view": "ತೂಲೆ",
"view-foreign": "$1ಡ್ ತೂಲೆ",
- "edit": "ಸಂಪಾದನೆ ಮಲ್ಪುಲೆ(Edit this page)",
+ "edit": "ಸಂಪಾದನೆ ಮಲ್ಪುಲೆ(ಪಾಲೆನ್ ಸಂಪಾದನೆ ಮಲ್ಪುಲೆ)",
"create": "ಸೃಷ್ಟಿಸಾಲೆ",
"create-local": "ಸ್ಥಳೀಯ ವಿವರಣೆ ಸೇರಾಲೆ",
"editthispage": "ಈ ಪುಟೊನು ಬದಲಾಯಿಸಾಲೆ",
"viewhelppage": "ಸಹಾಯ ಪುಟೊನು ತೂಲೆ",
"categorypage": "ವರ್ಗ ಪುಟೊನು ತೂಲೆ",
"viewtalkpage": "ಚರ್ಚೆನ್ ತೂಲೆ",
- "otherlanguages": "ಬà³\87ತà³\86 à²à²¾à²·ೆಲೆಡ್",
+ "otherlanguages": "ಬà³\87ತà³\86 ಬಾಸೆಲೆಡ್",
"redirectedfrom": "($1 ರ್ದ್ ಪುನರ್ನಿರ್ದೇಶಿತ)",
"redirectpagesub": "ಪುನರ್ನಿರ್ದೇಶನ ಪುಟ",
- "lastmodifiedat": "ಈ ಪುಟ ಇಂದೆತ ದುಂಬು $2, $1 ಕ್ ಬದಲಾತ್’ನ್ಡ್.",
+ "redirectto": "ಪಿರ ಕಡಪುಡ್ಲೆ:",
+ "lastmodifiedat": "ಈ ಪಾಲೆ ಇಂದೆತ ದುಂಬು $2, $1 ಕ್ ಬದಲಾತ್ಂಡ್.",
"viewcount": "ಈ ಪುಟೊನು {{PLURAL:$1|1 ಸರಿ|$1 ಸರಿ}} ತೂತೆರ್.",
"protectedpage": "ಸಂರಕ್ಷಿತ ಪುಟ",
- "jumpto": "ಇಡೆ ಪೋಲೆ:",
+ "jumpto": "ಇಡೆ ಪೋ:",
"jumptonavigation": "ಸಂಚಾರ",
"jumptosearch": "ನಾಡ್’ಲೆ",
"pool-errorunknown": "ಗೊತ್ತಿಂಜಂದಿನ ದೋಷ",
"aboutsite": "{{SITENAME}} ದ ಬಗ್ಗೆ",
- "aboutpage": "Project:ನಮ್ಮ ಬಗ್ಗೆ",
+ "aboutpage": "ಯೋಜನೆ:ಬಗೆಟ್",
"copyright": "ಉಂದು ಈ ಕಾಪಿರೈಟ್ಡ್ ಲಭ್ಯವುಂಡು $1.",
"copyrightpage": "{{ns:project}}:ಕೃತಿಸ್ವಾಮ್ಯತೆಲು",
"currentevents": "ಇತ್ತೆದ ಸಂಗತಿಲು",
- "currentevents-url": "Project:ಇತ್ತೆದ ಸಂಗತಿಲು",
- "disclaimers": "à²\85ಬಾಧà³\8dಯತà³\86ಲà³\81",
- "disclaimerpage": "Project:ಸಾಮಾನ್ಯ ಅಬಾಧ್ಯತೆಲು",
+ "currentevents-url": "ಯೋಜನೆ:ಇತ್ತೆದ ಸಂಗತಿಲು",
+ "disclaimers": "ಹà²\95à³\8dà²\95à³\8dâ\80\8cದà²\95à³\81ಲತà³\8dತà³\8d",
+ "disclaimerpage": "ಯೋಜನೆ:ಸಾಮಾನ್ಯೊ ಹಕ್ಕುದಕುಲತ್ತ್",
"edithelp": "ಸಂಪಾದನೆ(ಎಡಿಟ್) ಮಲ್ಪೆರೆ ಸಹಾಯ",
"mainpage": "ಮುಖ್ಯ ಪುಟ",
- "mainpage-description": "ಮà³\81à²\96à³\8dಯ ಪà³\81à²\9f",
+ "mainpage-description": "ಮà³\81à²\95à³\8dಯà³\8a ಪಾಲà³\86",
"policy-url": "Project:ನಿಯಮಾವಳಿ",
- "portal": "ಸಮà³\81ದಾಯ ಪà³\81à²\9f",
- "portal-url": "Project:ಸಮà³\81ದಾಯ ಪà³\81à²\9f",
+ "portal": "ಸಮà³\81ದಾಯ ಪಾಲà³\86",
+ "portal-url": "Project:ಸಮà³\81ದಾಯ ಪಾಲà³\86",
"privacy": "ಖಾಸಗಿ ನಿಯಮಾವಳಿ",
- "privacypage": "Project:ಖಾಸಗಿಮಾಹಿತಿ ನಿಯಮ",
+ "privacypage": "ಯೋಜನೆ:ಗುಟ್ಟುದ ನೀತಿ",
"badaccess": "ಅನುಮತಿ ದೋಷ",
"badaccess-group0": "ಈರ್ ಕೇನಿನ ಬೇಲೆನ್ ಮಲ್ಪೆರೆ ಇರೆಗ್ ಅನುಮತಿ ಇಜ್ಜಿ.",
"badaccess-groups": "ಈರ್ ಕೇನಿನಂಚಿನ ಕ್ರಿಯೆ ಖಾಲಿ $1 ಗುಂಪುಲೆಡ್ ಒಂಜೆಕ್ ಸೇರ್ದುಪ್ಪುನ ಬಳಕೆದಾರೆರೆಗ್ ಮಾತ್ರ.",
"viewsourceold": "ಮೂಲೊನು ತೂಲೆ",
"editlink": "ಎಡಿಟ್ ಮಲ್ಪುಲೆ",
"viewsourcelink": "ಮೂಲೊನು ತೂಲೆ",
- "editsectionhint": "$1 ವಿà²à²¾à²\97ದ ಸà²\82ಪಾದನà³\86 ಮಲà³\8dಪà³\81ಲೆ",
+ "editsectionhint": "$1 ವಿಬಾà²\97ದ ಸà²\82ಪಾದಿಸಲೆ",
"toc": "ಪರಿವಿಡಿ",
"showtoc": "ತೊಜ್ಪಾವು",
"hidetoc": "ದೆಂಗಾವು",
"red-link-title": "$1 (ಈ ಪುಟ ನನಲ ಅಸ್ತಿತ್ವಡ್ ಇಜ್ಜಿ)",
"sort-descending": "ಇಳಿಕೆ ಕ್ರಮೊಟ್ಟು ಜೋಡಿಸಾಲ",
"sort-ascending": "ಏರಿಕೆ ಕ್ರಮೊಟ್ಟು ಜೋಡಿಸಾಲ",
- "nstab-main": "ಪà³\81à²\9f",
+ "nstab-main": "ಪಾಲà³\86",
"nstab-user": "ಸದಸ್ಯೆರ್ನ ಪುಟ",
"nstab-media": "ಮೀಡಿಯ ಪುಟ",
"nstab-special": "ವಿಶೇಷ ಪುಟ",
"nstab-template": "ಫಲಕ",
"nstab-help": "ಸಹಾಯ ಪುಟ",
"nstab-category": "ವರ್ಗ",
+ "mainpage-nstab": "ಮುಕ್ಯ ಪಾಲೆ",
"nosuchaction": "ಈ ರೀತಿದ ಓವು ಕ್ರಿಯೆಲಾ(ಆಕ್ಶನ್) ಇಜ್ಜಿ",
"nosuchactiontext": "ಈ URLದ ಒಟ್ಟಿಗೆ ಉಪ್ಪುನ ಕ್ರಿಯೆನ್ ವಿಕಿ ಗುರ್ತ ಪತ್ತುಜಿ",
"nosuchspecialpage": "ಈ ಪುದರ್’ದ ಒವುಲಾ ವಿಷೇಶ ಪುಟ ಇಜ್ಜಿ",
"createaccountmail": "ಇ ಮೈಲ್ ಮೂಲಕ",
"createaccountreason": "ಕಾರಣ",
"createacct-submit": "ಪೊಸ ಖಾತೆ ಸುರು ಮಲ್ಪುಲೆ",
+ "createacct-benefit-heading": "{{SITENAME}}ನಿಕ್ಲೆನಂಚಿತ್ತಿನ ಜನೊಕ್ಲೆಡ್ದ್ ಉಂಡಾಪುಂಡು.",
"createacct-benefit-body1": "{{PLURAL:$1|ಸಂಪಾದನೆ|ಸಂಪಾದನೆಲು}}",
"createacct-benefit-body2": "{{PLURAL:$1|ಪುಟ|ಪುಟಕ್ಕುಲು}}",
"createacct-benefit-body3": "{{PLURAL:$1|ಕೊಡುಗೆ|ಕೊಡುಗೆಲು}}",
"preview": "ಮುನ್ನೋಟ",
"showpreview": "ಮುನ್ನೋಟ ತೊಜ್ಪಾವ್",
"showdiff": "ಬದಲಾವಣೆಲೆನ್ ತೊಜ್ಪಾವ್",
- "anoneditwarning": "'''ಜಾಗ್ರತೆ:''' ಈರ್ ಇತ್ತೆ ಲಾಗ್ ಇನ್ ಆತಿಜರ್.\nಈರ್ನ ಐ.ಪಿ ಎಡ್ರೆಸ್ ಈ ಪುಟೊತ ಬದಲಾವಣೆ ಇತಿಹಾಸೊಡು ದಾಖಲಾಪು೦ಡು.",
+ "anoneditwarning": "<strong>ಜಾಗ್ರ್ತೆ:</strong> ಈರ್ ಇತ್ತೆ ಲಾಗ್ ಇನ್ ಆತಿಜರ್. ಈರ್ ಸಂಪೊಲಿತರ್ಂಡ ಈರೆನ ಐ.ಪಿ ಎಡ್ರೆಸ್ ಮಾಂತೆರೆಗ್ಲಾ ತೆರಿವುಂಡು. ಒಂಜೇಲ್ಯೆ <strong>[$1 ಲಾಗಿನ್ ಆಯರ್ಂದಾಂಡ]</strong> ಅತ್ತಂಡ <strong>[$2 ಈ ಅಕೌಂಟ್ ಮಲ್ತರ್ಂಡ]</strong>, ಈರ ಸಂಪೊಲ್ತಿನ ಪೂರ ಬೇತೆ ಲಾಬೊದೊಟ್ಟುಗು ಈರೆನ ಪುದರ್ಗ್ ಸೇರುಂಡು.'",
"anonpreviewwarning": "ಈರ್ ಇತ್ತೆ ಲಾಗ್ ಇನ್ ಆತಿಜರ್. ಈರ್ನ ಐ.ಪಿ ಎಡ್ರೆಸ್ ಈ ಪುಟೊತ ಬದಲಾವಣೆ ಇತಿಹಾಸೊಡು ದಾಖಲಾಪು೦ಡು",
"missingsummary": "'''ಗಮನಿಸಾಲೆ:''' ಈರ್ ಬದಲಾವಣೆದ ಸಾರಾ೦ಶನ್ ಕೊರ್ತಿಜರ್.\nಈರ್ ಪಿರ 'ಒರಿಪಾಲೆ' ಬಟನ್ ನ್ ಒತ್ತ್೦ಡ ಸಾರಾ೦ಶ ಇಜ್ಜ೦ದೆನೇ ಈರ್ನ ಬದಲಾವಣೆ ದಾಖಲಾಪು೦ಡು.",
"missingcommenttext": "ದಯ ಮಲ್ತ್ ದ ಈರ್ನ ಅಭಿಪ್ರಾಯನ್ ತಿರ್ತ್ ಕೊರ್ಲೆ",
"accmailtitle": "ಪ್ರವೇಶಪದ ಕಡಪುಡ್‘ದುಂಡು",
"newarticle": "(ಪೊಸತ್)",
"newarticletext": "ನನಲ ಅಸ್ಥಿತ್ವಡ್ ಉಪ್ಪಂದಿನ ಪುಟೊಗು ಈರ್ ಬೈದರ್.\nಈ ಪುಟೊನು ಸೃಷ್ಟಿ ಮಲ್ಪೆರೆ ತಿರ್ತ್’ದ ಚೌಕೊಡು ಬರೆಯೆರೆ ಸುರು ಮಲ್ಪುಲೆ.\n(ಜಾಸ್ತಿ ಮಾಹಿತಿಗ್ [$1 ಸಹಾಯ ಪುಟೊನು] ತೂಲೆ).\nಈ ಪುಟೊಕು ಈರ್ ತಪ್ಪಾದ್ ಬತ್ತಿತ್ತ್’ನ್ಡ ಇರೆನ ಬ್ರೌಸರ್’ದ '''back''' ಬಟನ್’ನ್ ಒತ್ತ್’ಲೆ.",
- "noarticletext": "ಈ ಪುಟೊಟು ಸದ್ಯಗ್ ಓ ಬರಹಲಾ ಇಜ್ಜಿ, ಈರ್ ಬೇತೆ ಪೂಟೊಲೆಡ್ [[Special:Search/{{PAGENAME}}|ಈ ಲೇಖನೊನು ನಾಡೊಲಿ]] ಅತ್ತ್’ನ್ಡ [{{fullurl:{{FULLPAGENAME}}|action=edit}} ಈ ಪುಟೊನು ಸಂಪಾದನೆ ಮಲ್ಪೊಲಿ].",
+ "noarticletext": "ಈ ಪಾಲೆಡ್ ಸದ್ಯಗ್ ಒವ್ವೇ ಬರವುಲಾ ಇಜ್ಜಿ, ಈರ್ ಬೇತೆ ಪಾಲೆಡ್ [[Special:Search/{{PAGENAME}}|ಈ ಲೇಕನೊನು ನಾಡೊಲಿ]] <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} ಸಂಬಂಧ ಇತ್ತಿನ ಲಾಗ್ಸ್ ನ್ ನಾಡ್ ಲೆ], ಅತ್ತ್ಂಡ [{{fullurl:{{FULLPAGENAME}}|action=edit}} ಈ ಪಾಲೆನು ಸಂಪೊಲಿಪೊಲಿ]</span>.",
+ "noarticletext-nopermission": "ಈ ಪಾಲೆಡ್ ಸದ್ಯಗ್ ಒವ್ವೇ ಬರವುಲಾ ಇಜ್ಜಿ, ಈರ್ ಬೇತೆ ಪಾಲೆಡ್ [[Special:Search/{{PAGENAME}}|ಈ ಲೇಕನೊನು ನಾಡೊಲಿ]] <span class=\"plainlinks\">[{{fullurl:{{#Special:Log}}|page={{FULLPAGENAMEE}}}} ಸಂಬಂಧ ಇತ್ತಿನ ಲಾಗ್ಸ್ ನ್ ನಾಡ್ ಲೆ], ಅತ್ತ್ಂಡ [{{fullurl:{{FULLPAGENAME}}|action=edit}} ಈ ಪಾಲೆನು ಸಂಪೊಲಿಪೊಲಿ]</span>.",
"userpage-userdoesnotexist": "ಬಳಕೆದಾರ ಖಾತೆ \"<nowiki>$1</nowiki>\" ದಾಖಲಾತ್‘ಜ್ಜಿ. ಈರ್ ಉಂದುವೇ ಪುಟನ್ ಸಂಪಾದನೆ ಮಲ್ಪರ ಉಂಡಾಂದ್ ಖಾತ್ರಿ ಮಲ್ತೊನಿ.",
"previewnote": "'''ಉಂದು ಕೇವಲ ಮುನ್ನೋಟ; ಪುಟೊನು ನನಲ ಒರಿಪಾದಿಜಿ ಪನ್ಪುನೇನ್ ಮರಪೊರ್ಚಿ!'''",
"editing": "$1 ಲೇಖನೊನು ಈರ್ ಸಂಪಾದನೆ ಮಲ್ತೊಂದುಲ್ಲರ್",
"template-semiprotected": "(ಅರೆ-ಸಂರಕ್ಷಿತ)",
"hiddencategories": "ಈ ಪುಟ {{PLURAL:$1|೧ ಗುಪ್ತ ವರ್ಗಗ್|$1 ಗುಪ್ತ ವರ್ಗೊಲೆಗ್}} ಸೇರ್ದ್’ನ್ಡ್:",
"permissionserrorstext-withaction": "$2 ಗ್ ಇರೆಗ್ ಅನುಮತಿ ಇಜ್ಜಿ, ಐಕ್ {{PLURAL:$1|ಕಾರಣ|ಕಾರಣೊಲು}}:",
- "moveddeleted-notice": "à²\88 ಪà³\87à²\9cà³\8d à²\85ಸà³\8dತಿತà³\8dವಡà³\8d à²\87à²\9cà³\8dà²\9cಿ.\nಪà³\82à²\9fà³\8aತ ಡಿಲà³\80ಶನà³\8d ಲಾà²\97à³\8dâ\80\99ನà³\8d ತಿರà³\8dತà³\8d à²\95à³\8aರà³\8dತà³\81à²\82ಡà³\81.",
+ "moveddeleted-notice": "à²\88 ಪಾಲà³\86 à²\85ಸà³\8dತಿತà³\8dವಡà³\8d à²\87à²\9cà³\8dà²\9cಿ.\nಪಾಲà³\86ದ ಡಿಲà³\80ಶನà³\8d à²\85ತà³\8dತà³\8dà²\82ಡà³\8d à²\95ಡಪà³\8dಪà³\81ಡà³\81ನà³\86 ಲಾà²\97à³\8dâ\80\8dನà³\8d ತà³\82ಯರà³\86 ತಿರà³\8dತà³\8d à²\95à³\8aರà³\8dತà³\8dà²\82ಡà³\8d.",
"viewpagelogs": "ಈ ಪುಟೊತ ದಾಖಲೆಲೆನ್ ತೂಲೆ",
"nohistory": "ಈ ಪುಟಕ್ ಬದಲಾವಣೆದ ಇತಿಹಾಸ ಇಜ್ಜಿ",
"currentrev": "ಇತ್ತೆದ ಆವೃತ್ತಿ",
"mergehistory-reason": "ಕಾರಣ:",
"revertmerge": "ಅನ್-ಮರ್ಜ್ ಮಲ್ಪುಲೆ",
"history-title": "\"$1\" ಪುಟೊತ ಆವೃತ್ತಿ ಇತಿಹಾಸೊ",
+ "difference-title": "ಪುನರ್ ಪರಿಸೀಲನೆದ ನಡುತ ಯತ್ವಾಸೊ \"$1\"",
"lineno": "$1 ನೇ ಸಾಲ್:",
"compareselectedversions": "ಆಯ್ಕೆ ಮಲ್ತಿನ ಆವೃತ್ತಿಲೆನ್ ಹೊಂದಾಣಿಕೆ ಮಲ್ತ್ ತೂಲೆ",
"editundo": "ದುಂಬುದಲೆಕ",
+ "diff-multi-sameuser": "({{PLURAL:$1|One intermediate revision|$1 intermediate revisions }} ಅವ್ವೇ ಬಳಕೆದಾರೆರೆನ್ ತೋಜಾದ್ಜಿ)",
"searchresults": "ನಾಡಟದ ಫಲಿತಾಂಶೊಲು",
"searchresults-title": "\"$1\" ಕ್ ನಾಡಟದ ಫಲಿತಾಂಶೊಲು",
"notextmatches": "ವಾ ಪುಟೊತ ಪಠ್ಯೊಡುಲಾ ಹೋಲಿಕೆ ಇಜ್ಜಿ",
"prevn": "ದುಂಬುದ {{PLURAL:$1|$1}}",
"nextn": "ಬೊಕ್ಕದ {{PLURAL:$1|$1}}",
+ "nextn-title": "ದುಂಬುದ $1 {{PLURAL:$1|result|ಪಲಿತಾಂಸೊಲ}}",
"shown-title": "ಪ್ರತಿ ಪುಟೊಡುಲಾ $1 {{PLURAL:$1|result|results}} ತೋಜಿಪಾವು",
"viewprevnext": "ತೂಲೆ ($1 {{int:pipe-separator}} $2) ($3)",
+ "searchmenu-new": "<strong>ಈ ಪಾಲೆನ್ ರಚಿಸಲೆ \"[[:$1]]\" ಈ ವಿಕಿಡ್!</strong> {{PLURAL:$2|0=|See also the page found with your search.|See also the search results found.}}",
"searchprofile-articles": "ಲೇಖನ ಪುಟೊ",
"searchprofile-images": "ಬಹುಮಾಧ್ಯಮ",
"searchprofile-everything": "ಪ್ರತಿಯೊಂಜಿ",
"searchprofile-articles-tooltip": "$1 ಟ್ ನಾಡ್ಲೆ",
"searchprofile-images-tooltip": "ಫೈಲ್ ನಾಡ್ಲೆ",
"searchprofile-everything-tooltip": "ಮಾತಾ ಪುಟಕ್ಕುಲೆಡ್ ನಾಡ್ಲೆ (ಪಾತೆರದ ಪುತಲ ಸೇರ್ದ್)",
+ "searchprofile-advanced-tooltip": "ಪುದರ್ದ ಕ್ರಮೊನು ನಾಡ್ಲೆ",
"search-result-size": "$1 ({{PLURAL:$2|೧ ಪದ|$2 ಪದೊಲು}})",
"search-redirect": "(ಪುನರ್ನಿರ್ದೇಶನ $1)",
"search-section": "(ವಿಭಾಗ $1)",
"search-interwiki-more": "(ಮಸ್ತ್)",
"searchrelated": "ಸ೦ಬ೦ಧ ಇತ್ತಿನ",
"searchall": "ಮಾತಾ",
+ "search-showingresults": "{{PLURAL:$4|ಫಲಿತಾಂಶ<strong>$1</strong> of <strong>$3</strong>|ಫಲಿತಾಂಶ <strong>$1 - $2</strong> of <strong>$3</strong>}}",
"search-nonefound": "ಈರೆನ ವಿಚಾರಣೆಗ್ ತಕ್ಕುದಾಯಿನ ಪಲಿತಾಂಶೊಲು ಇಜ್ಜಿ.",
+ "search-nonefound-thiswiki": "ಈ ಸೈಟ್ಡ್ ಪ್ರಶ್ನೆದ ಫಲಿತಾಂಶ ಕೂಡೊಂದಿಜ್ಜಿ",
"powersearch-legend": "ಅಡ್ವಾನ್ಸ್’ಡ್ ಸರ್ಚ್",
"powersearch-ns": "ನೇಮ್-ಸ್ಪೇಸ್’ಲೆಡ್ ನಾಡ್ಲೆ",
"powersearch-toggleall": "ಮಾತಾ",
"grouppage-sysop": "{{ns:project}}:ನಿರ್ವಾಹಕೆರ್",
"right-read": "ಪುಟಕ್ಲೆನ್ ಓದುಲೆ",
"right-edit": "ಪುಟೊನ್ ಸಂಪಾದನೆ ಮಲ್ಪುಲೆ",
+ "right-writeapi": "ಬರೆಯಿನ ಎಪಿಐದ ಬಳಕೆ",
"right-delete": "ಪುಟೊಕುಲೆನ್ ಮಾಜಾಲೆ",
"right-undelete": "ಪುಟೊನ್ ಮಾಜಾವಡೆ",
"newuserlogpage": "ಸದಸ್ಯ ರಚನೆ ಲಾಗ್",
"recentchanges-label-minor": "ಉಂದು ಎಲ್ಯ ಬದಲಾವಣೆ",
"recentchanges-label-bot": "ಈ ಸಂಪಾದನೆನ್ ಒಂಜಿ ಬಾಟ್ ಮಲ್ತ್ದುಂಡು",
"recentchanges-label-unpatrolled": "ಈ ಸಂಪಾದನೆನ್ ನನಲಾ ಪರೀಕ್ಷೆ ಮಲ್ತ್ದಿಜ್ಜಿ.",
+ "recentchanges-label-plusminus": "ಬೈಟ್ಸ್ದ ಲೆಕ್ಕೊಡು ಈ ಪಾಲೆದ ಗಾತ್ರೊ ಬದಲಾತ್ಂಡ್",
+ "recentchanges-legend-heading": "'''ಟಿಪ್ಪಣಿ:'''",
+ "recentchanges-legend-newpage": "{{int:recentchanges-label-newpage}} (ಬೊಕ್ಕೊಲಾ ತೂಲೆ [[Special:NewPages|ಪೊಸ ಪಾಲೆದ ಪಟ್ಟಿ]])",
"rclistfrom": "$3 $2 ರ್ದ್ ಶುರುವಾತಿನ ಪೊಸ ಬದಲಾವಣೆಲೆನ್ ತೊಜ್ಪಾವು",
"rcshowhideminor": "$1 ಎಲ್ಯೆಲ್ಯ ಬದಲಾವಣೆಲು",
"rcshowhideminor-show": "ತೋಜಾಲೆ",
"newpageletter": "ಪೊ",
"boteditletter": "ಬಾ",
"rc_categories_any": "ಒವ್ವೇ",
- "rc-change-size-new": "$1 {{ಬಹುವಚನೊ:$1|ಬೈಟ್|ಬೈಟ್ಲು}}ಬದಲಾವಣೆದ ಬುಕ್ಕೊ",
+ "rc-change-size-new": "$1 {{PLURAL:$1|ಬೈಟ್|ಬೈಟ್ಲು}}ಬದಲಾವಣೆದ ಬುಕ್ಕೊ",
"newsectionsummary": "\n/* $1 */ಪೊಸ ವಿಭಾಗ",
"rc-enhanced-expand": "ವಿವರೊಲೆನ್ ತೊಜ್ಪಾವು (ಜಾವ ಸ್ಕ್ರಿಪ್ಟ್ ಬೋಡಾಪುಂಡು)",
"rc-enhanced-hide": "ವಿವರೊಲೆನ್ ದೆಂಗಾವು",
"recentchangeslinked": "ಸಂಬಂಧ ಉಪ್ಪುನಂಚಿನ ಬದಲಾವಣೆಲು",
"recentchangeslinked-feed": "ಸಂಬಂಧ ಉಪ್ಪುನಂಚಿನ ಬದಲಾವಣೆಲು",
- "recentchangeslinked-toolbox": "ಸà²\82ಬà²\82ಧ ಉಪ್ಪುನಂಚಿನ ಬದಲಾವಣೆಲು",
+ "recentchangeslinked-toolbox": "ಸà²\82ಬà²\82ದà³\8a ಉಪ್ಪುನಂಚಿನ ಬದಲಾವಣೆಲು",
"recentchangeslinked-title": "\"$1\" ಪುಟೊಟು ಆತಿನ ಬದಲಾವಣೆಲು",
"recentchangeslinked-summary": "ಒಂಜಿ ನಿರ್ದಿಷ್ಟ ಪುಟೊರ್ದು (ಅತ್ತ್’ನ್ಡ ನಿರ್ದಿಷ್ಟ ವರ್ಗೊಗು ಸೇರ್ದಿನ ಪುಟೊಲೆರ್ದ್) ಸಂಪರ್ಕ ಉಪ್ಪುನ ಪುಟೊಲೆಡ್ ಇಂಚಿಪ ಮಲ್ತಿನಂಚಿನ ಬದಲಾವಣೆಲೆನ್ ತಿರ್ತ್ ಪಟ್ಟಿ ಮಲ್ಪೆರಾತ್’ನ್ಡ್.\n[[Special:Watchlist|ಇರೆನ ವೀಕ್ಷಣಾಪಟ್ಟಿಡ್]] ಉಪ್ಪುನ ಪುಟೊಲು '''ದಪ್ಪ ಅಕ್ಷರೊಡು''' ಉಂಡು.",
"recentchangeslinked-page": "ಪುಟೊತ ಪುದರ್:",
"linkstoimage": "ಈ ಫೈಲ್’ಗ್ ತಿರ್ತ್’ದ ಈ {{PLURAL:$1|ಪುಟ|$1 ಪುಟೊಲು}} ಲಿಂಕ್ ಕೊರ್ಪುಂಡು.",
"nolinkstoimage": "ಈ ಫೈಲ್ಗ್ ಸಂಪರ್ಕ ಉಪ್ಪುನ ವಾ ಪುಟಲಾ ಇಜ್ಜಿ.",
"sharedupload": "ಈ ಫೈಲ್’ನ್ ಮಸ್ತ್ ಜನ ಪಟ್ಟ್’ದುಲ್ಲೆರ್ ಅಂಚೆನೆ ಉಂದು ಮಸ್ತ್ ಪ್ರೊಜೆಕ್ಟ್’ಲೆಡ್ ಉಪಯೋಗಡುಪ್ಪು.",
+ "sharedupload-desc-here": "ಈ ಪಾಲೆ $1ಡ್ದ್ ಬೊಕ್ಕ ಬೇತೆ ಯೋಜನೆಡ್ದ್ ಗಳಸೊಲಿ.\nಈ ಪಾಲೆದ ವಿವರೊ [$2 ಪಾಲೆದ ವಿವರೊ] ತಿರ್ತ ಸಾಲ್ಡ್ ತೋಜಾದ್ಂಡ್",
"upload-disallowed-here": "ಈರ್ ಈ ಕಡತನ್ ಕುಡ ಬರೆವರೆ ಸಾದ್ಯ ಇಜ್ಜಿ.",
"filedelete-comment": "ಕಾರಣ",
"filedelete-submit": "ಮಾಜಾಲೆ",
- "randompage": "ಯಾದà³\83à²\9aà³\8dà²\9bಿà²\95 ಪà³\81à²\9f",
+ "randompage": "ಯಾದà³\83à²\9aà³\8dà²\9bಿà²\95 ಪಾಲà³\86",
"statistics": "ಅಂಕಿ ಅಂಶೊಲು",
"statistics-header-pages": "ಪುಟೊತ ಅಂಕಿ ಅಂಶಲು",
"nbytes": "$1 {{PLURAL:$1|ಬೈಟ್|ಬೈಟ್ಲು}}",
"actioncomplete": "ಕಾರ್ಯ ಸಂಪೂರ್ಣ",
"dellogpage": "ಡಿಲೀಟ್ ಮಲ್ತಿನ ಫೈಲ್’ಲೆದ ದಾಖಲೆ",
"rollbacklink": "ಪಿರ ಪೋಲೆ",
+ "rollbacklinkcount": "ಪಿರ ದೆತೊನ್ಲೆ $1 {{PLURAL:$1|edit|ಸಂಪಾದನೆಲು}}",
"protectlogpage": "ಸಂರಕ್ಷಣೆ ದಿನಚರಿ",
"protectedarticle": "\"[[$1]]\" ಸಂರಕ್ಷಿತವಾದುಂಡು.",
"modifiedarticleprotection": "\"[[$1]]\" ಪುಟೊತ ಸಂರಕ್ಷಣೆ ಮಟ್ಟ ಬದಲಾಂಡ್",
"undeleteviewlink": "ತೂಲೆ",
"namespace": "ನೇಮ್-ಸ್ಪೇಸ್:",
"invert": "ಆಯ್ಕೆನ್ ತಿರ್ಗಾಲೆ",
- "blanknamespace": "(ಮುಖ್ಯ)",
+ "tooltip-invert": "ಈ ಚೌಕೊದುಲಯಿಡ್ ಅಡೆಂಗಿನ ಪುದರ್ನ್ ಈ ಚೌಕೊಡೆ ಪರೀಕ್ಷಿಪುಲೆ(ಬೊಕ್ಕೊ ಒಟ್ಟುಗಿತ್ತಿನ ಪುದರ್ನ್ಲಾ ಪರೀಕ್ಷಿಪೊಲಿ)",
+ "namespace_association": "ಜತೆಟಿತ್ತಿನ ಪುದರ್",
+ "tooltip-namespace_association": "ಈ ಚೌಕೊನು ಚರ್ಚೆನ್ ಸೇರಾದ್ ಪರೀಕ್ಷಿಪುಲೆ ಅತ್ತ್ಂಡ ವಿಸಯೊಗು ಸರಿಯಾಯಿನ ಪುದರ್ದ ಜತೆಟ್ ಸೇರಾಲೆ",
+ "blanknamespace": "(ಮುಕ್ಯೊ)",
"contributions": "{{$1ಸದಸ್ಯೆರ್ನ}} ಕಾಣಿಕೆಲು",
"contributions-title": "$1 ಗ್ ಸದಸ್ಯೆರ್ನ ಕಾಣಿಕೆ",
"mycontris": "ಎನ್ನ ಕಾಣಿಕೆಲು",
"sp-contributions-search": "ಕಾಣಿಕೆಲೆನ್ ನಾಡ್ಲೆ",
"sp-contributions-username": "ಐ.ಪಿ ವಿಳಾಸ ಅತ್ತ್’ನ್ಡ ಬಳಕೆದ ಪುದರ್:",
"sp-contributions-submit": "ನಾಡ್",
- "whatlinkshere": "à²\87ಡà³\86 ವಾ ಪà³\81à²\9fà³\8aಲà³\81 ಲಿಂಕ್ ಕೊರ್ಪುಂಡು",
+ "whatlinkshere": "à²\87ಡà³\86 ವಾ ಪಾಲà³\86 ಲಿಂಕ್ ಕೊರ್ಪುಂಡು",
"whatlinkshere-title": "\"$1\" ಪುಟೊಗು ಲಿಂಕ್ ಕೊರ್ಪುನ ಪುಟೊಲು",
"whatlinkshere-page": "ಪುಟ:",
"linkshere": "'''[[:$1]]'''ಗ್ ಈ ತಿರ್ತ್’ದ ಪುಟೊಲು ಲಿಂಕ್ ಕೊರ್ಪುಂಡು.",
"tooltip-pt-logout": "ಲಾಗ್ ಔಟ್",
"tooltip-pt-createaccount": "ನಿಕುಲು ಪೊಸ ಖಾತೆ ಸುರುಮಲ್ತ್ದ್ ಲಾಗಿನ್ ಆಪುನೈನ್ ಸ್ವಾಗತ ಮಲ್ಪುವೊ, ಆಂಡಲಾ ಉಂದು ಕಡ್ಡಾಯ ಅತ್ತ್.",
"tooltip-ca-talk": "ಮಾಹಿತಿ ಪುಟೊತ ಬಗ್ಗೆ ಚರ್ಚೆ",
- "tooltip-ca-edit": "à²\88 ಪà³\81à²\9fà³\8aನà³\81 à²\88ರà³\8d ಸà²\82ಪಾದನà³\86 ಮಲà³\8dಪà³\8aಲಿ. ಸà³\87ವà³\8d ಮಲà³\8dಪà³\81ನ ದà³\81à²\82ಬà³\81 ಮà³\81ನà³\8dನà³\8bà²\9fದ à²\89ಪಯà³\8aà²\97 ಮನà³\8dತà³\8aನà³\8dಲà³\86.",
+ "tooltip-ca-edit": "à²\88 ಪಾಲà³\86ನà³\8d ಸà²\82ಪà³\8aಲಿಪà³\81ಲà³\86",
"tooltip-ca-addsection": "ಪೊಸ ಸೆಶನ್ನ್ ಶರು ಮಲ್ಪುಲೆ",
"tooltip-ca-viewsource": "ಉಂದೊಂಜಿ ಸಂರಕ್ಷಿತ ಪುಟ.\nಇಂದೆತ ಮೂಲೊನು ಈರ್ ತೂವೊಲಿ.",
- "tooltip-ca-history": "à²\88 ಪà³\81à²\9fà³\8aತ ಪರತ್ತ್ ಆವೃತ್ತಿಲು",
+ "tooltip-ca-history": "à²\88 ಪಾಲà³\86ದ ಪರತ್ತ್ ಆವೃತ್ತಿಲು",
"tooltip-ca-protect": "ಈ ಪುಟೊನು ಸಂರಕ್ಷಣೆ ಮಲ್ಪುಲೆ",
"tooltip-ca-delete": "ಈ ಪುಟೊನು ಡಿಲೀಟ್ ಮಲ್ಪುಲೆ",
"tooltip-ca-move": "ಈ ಪೂಟೊನು ಮೂವ್(ಸ್ಥಳಾಂತರ) ಮಲ್ಪುಲೆ",
"tooltip-search-fulltext": "ಈ ಪಠ್ಯ ಉಪ್ಪುನಂಚಿನ ಪುಟೊಲೆನ್ ನಾಡ್’ಲ",
"tooltip-p-logo": "ಮುಖ್ಯ ಪುಟೊನು ತೂಲೆ",
"tooltip-n-mainpage": "ಮುಖ್ಯ ಪುಟೊನು ತೂಲೆ",
- "tooltip-n-mainpage-description": "ಮà³\81à²\96à³\8dಯ ಪà³\81à²\9fà³\8aನà³\81 ತೂಲೆ",
+ "tooltip-n-mainpage-description": "ಮà³\81à²\95à³\8dಯà³\8a ಪಾಲà³\86ನà³\8d ತೂಲೆ",
"tooltip-n-portal": "ಪ್ರೊಜೆಕ್ಟ್’ದ ಬಗ್ಗೆ, ಈರ್ ದಾದ ಮಲ್ಪೊಲಿ, ಓಲು ಇಂದೆತ ಬಗ್ಗೆ ತೆರಿಯೊನೊಲಿ",
- "tooltip-n-currentevents": "ಪà³\8dರಸà²\95à³\8dತ à²\98à²\9fನà³\86ಲà³\8dದ ಬà²\97à³\8dà²\97à³\86 ಹಿನ್ನೆಲೆ ಮಾಹಿತಿ ತೆರಿಯೊನ್ಲೆ",
+ "tooltip-n-currentevents": "à²\87ತà³\8dತà³\86ದ à²\98à²\9fನà³\86ಲà³\86 ಬà²\97à³\86ತ ಹಿನ್ನೆಲೆ ಮಾಹಿತಿ ತೆರಿಯೊನ್ಲೆ",
"tooltip-n-recentchanges": "ವಿಕಿಡ್ ದುಂಬುದ ಒಂತೆ ಸಮಯಡ್ ಆತಿನಂಚಿನ ಬದಲಾವಣೆಲ್ದ ಪಟ್ಟಿ",
- "tooltip-n-randompage": "ಯಾದà³\83à²\9aà³\8dà²\9bಿà²\95 ಪà³\81à²\9fವà³\8aಂಜೇನ್ ತೊಜ್ಪಾವ್",
- "tooltip-n-help": "ತà³\86ರಿತà³\8aನà³\86ರà³\86 à²\9cಾà²\97",
- "tooltip-t-whatlinkshere": "à²\87ಡà³\86 ಲಿà²\82à²\95à³\8d à²\95à³\8aರà³\8dಪà³\81ನà²\82à²\9aಿನ ಪà³\82ರ ವಿà²\95ಿ ಪà³\81à²\9fà³\8aಲà³\8dದ ಪಟ್ಟಿ",
- "tooltip-t-recentchangeslinked": "à²\88 ಪà³\81à²\9fà³\8aರà³\8dದà³\81 ಸà²\82ಪರà³\8dà²\95 à²\89ಪà³\8dಪà³\81ನà²\82à²\9aಿನ ಪà³\81à²\9fà³\8aಲೆಡ್ ಇಂಚಿಪದ ಬದಲಾವಣೆಲು",
+ "tooltip-n-randompage": "ಯಾದà³\83à²\9aà³\8dà²\9bಿà²\95 ಪಾಲà³\86 à²\92ಂಜೇನ್ ತೊಜ್ಪಾವ್",
+ "tooltip-n-help": "à²\9cಾà²\97à³\86 ನಾಡà³\8dದà³\8d ಪತà³\8dತà³\86ರà³\86",
+ "tooltip-t-whatlinkshere": "à²\87ಡà³\86 ಲಿà²\82à²\95à³\8d à²\95à³\8aರà³\8dಪà³\81ನà²\82à²\9aಿನ ಪà³\82ರ ವಿà²\95ಿ ಪಾಲà³\86ಲà³\86ನ ಪಟ್ಟಿ",
+ "tooltip-t-recentchangeslinked": "à²\88 ಪಾಲà³\86ಡà³\8dದà³\8d ಸà²\82ಪರà³\8dà²\95 à²\89ಪà³\8dಪà³\81ನà²\82à²\9aಿನ ಪಾಲೆಡ್ ಇಂಚಿಪದ ಬದಲಾವಣೆಲು",
"tooltip-feed-rss": "ಈ ಪುಟೊಗು ಆರ್.ಎಸ್.ಎಸ್ ಫೀಡ್",
"tooltip-feed-atom": "ಈ ಪುಟೊಗು Atom ಫೀಡ್",
"tooltip-t-contributions": "ಈ ಸದಸ್ಯೆರ್ನ ಕಾಣಿಕೆಲ್ದ ಪಟ್ಟಿನ್ ತೊಜ್ಪಾವು",
"tooltip-t-emailuser": "ಈ ಸದಸ್ಯೆರೆಗ್ ಇ-ಮೇಲ್ ಕಡಪುಡ್ಲೆ",
"tooltip-t-upload": "ಫೈಲ್’ನ್ ಅಪ್ಲೋಡ್ ಮಲ್ಪುಲೆ",
- "tooltip-t-specialpages": "ಪà³\82ರ ವಿಷà³\87ಶ ಪà³\81à²\9fà³\8aಲà³\8dದ ಪಟ್ಟಿ",
- "tooltip-t-print": "à²\88 ಪà³\81à²\9fà³\8aತ ಪ್ರಿಂಟ್ ಆವೃತ್ತಿ",
- "tooltip-t-permalink": "ಪà³\81à²\9fà³\8aತ à²\88 à²\86ವà³\83ತà³\8dತಿà²\97à³\8d ಶಾಶ್ವತ ಲಿಂಕ್",
- "tooltip-ca-nstab-main": "ಮಾಹಿತಿ ಪà³\81à²\9fà³\8aನà³\81 ತೂಲೆ",
+ "tooltip-t-specialpages": "ಪà³\82ರ ಪಾಲà³\86ಲà³\86ನ ವಿಸà³\87ಸà³\8a ಪಟ್ಟಿ",
+ "tooltip-t-print": "à²\88 ಪಾಲà³\86ದ ಪ್ರಿಂಟ್ ಆವೃತ್ತಿ",
+ "tooltip-t-permalink": "ಪಾಲà³\86ದ à²\88 à²\86ವà³\83ತà³\8dತಿà²\97à³\8d ಸಾಸ್ವತ ಲಿಂಕ್",
+ "tooltip-ca-nstab-main": "ಮಾಹಿತಿ ಪಾಲà³\86ನà³\8d ತೂಲೆ",
"tooltip-ca-nstab-user": "ಸದಸ್ಯೆರ್ನ ಪುಟೊನು ತೂಲೆ",
- "tooltip-ca-nstab-special": "à²\89à²\82ದà³\8aà²\82à²\9cಿ ವಿಶà³\87ಷ ಪà³\81à²\9f, à²\87à²\82ದà³\86ನà³\8d à²\88ರà³\8d à²\8eಡಿà²\9fà³\8d ಮಲà³\8dಪೆರೆ ಆಪುಜಿ",
+ "tooltip-ca-nstab-special": "à²\89à²\82ದà³\8aà²\82à²\9cಿ à²\87ಸà³\87ಸ ಪಾಲà³\86, à²\87à²\82ದà³\86ನà³\8d à²\88ರà³\8d ಸà²\82ಪà³\8aಲಿಪೆರೆ ಆಪುಜಿ",
"tooltip-ca-nstab-project": "ಪ್ರೊಜೆಕ್ಟ್ ಪುಟೊನು ತೂಲೆ",
"tooltip-ca-nstab-image": "ಫೈಲ್’ದ ಪುಟೊನು ತೂಲೆ",
"tooltip-ca-nstab-template": "ಟೆಂಪ್ಲೇಟ್’ನ್ ತೂಲೆ",
"tooltip-rollback": "\"Rollback\", ಈ ಪುಟದ ಕರಿನ ಬದಾಲವಣೆಗ್ ಒ೦ಜಿ ಕ್ಲಿಕ್ ಡ್ ಕೊನೊಪು೦ಡು",
"tooltip-undo": "\"Undo\" ಈ ಬದಲಾವಣೆನ್ ದೆತೊನುಜಿ ಬುಕ ಪ್ರಿವ್ಯೂ ಮೋಡ್ ಡ್ ಬದಲಾವಣೆ ಮಲ್ಪೆರ್ ಕೊನೊಪು೦ಡು. ಅ೦ಚೆನೆ ಸಮ್ಮರಿ ಡ್ ಬದಲಾವಣೆ ಗ್ ಕಾರಣ ಕೊರ್ರ್ಎ ಆಪು೦ಡು.",
"tooltip-summary": "ಒಂಜಿ ಎಲ್ಯ ಸಾರಾಂಶ ಕೊರ್ಲೆ",
- "pageinfo-toolboxlink": "ಪುಟೊತ ಮಾಹಿತಿ",
+ "simpleantispam-label": "ಯಾಂಟಿ-ಸ್ಪಾಮ್ ಚೆಕ್.\nಮುಲ್ಪ <strong>ದಿಂಜಾವೊಡ್ಚಿ</strong>",
+ "pageinfo-toolboxlink": "ಪಾಲೆದ ಮಾಹಿತಿ",
"previousdiff": "← ದುಂಬುದ ಸಂಪಾದನೆ",
"nextdiff": "ಪೊಸ ಎಡಿಟ್ →",
"file-info-size": "$1 × $2 ಪಿಕ್ಸೆಲ್, ಫೈಲ್’ದ ಗಾತ್ರ: $3, MIME ಪ್ರಕಾರ: $4",
"file-nohires": "ಇಂದೆರ್ದ್ ಜಾಸ್ತಿ ವಿವರವಾಯಿನ ನೋಟ ಇಜ್ಜಿ.",
"svg-long-desc": "ಎಸ್.ವಿ.ಜಿ ಫೈಲ್, ಸುಮಾರಾದ್ $1 × $2 ಪಿಕ್ಸೆಲ್, ಫೈಲ್’ದ ಗಾತ್ರ: $3",
- "show-big-image": "ಮೂಲ ಕಡತ",
+ "show-big-image": "ನಿಜಾವಾಯಿನ ಕಡತ",
+ "show-big-image-preview": "ಪಿರವುದ ಪಾಲೆದ ಗಾತ್ರೊ: $1.",
+ "show-big-image-other": "ಬೇತೆ{{PLURAL:$2|resolution|ನಿರ್ನಯೊಲು}}: $1.",
"show-big-image-size": "$1 × $2 ಪಿಕ್ಸೆಲ್ಸ್",
"bad_image_list": "ವ್ಯವಸ್ಥೆದ ಆಕಾರ ಈ ರೀತಿ ಉಂಡು:\n\nಪಟ್ಟಿಡುಪ್ಪುನಂಚಿನ ದಾಖಲೆಲೆನ್ (* ರ್ದ್ ಶುರು ಆಪುನ ಸಾಲ್’ಲು) ಮಾತ್ರ ಪರಿಗಣನೆಗ್ ದೆತೊನೆರಾಪುಂಡು.\nಪ್ರತಿ ಸಾಲ್’ದ ಶುರುತ ಲಿಂಕ್ ಒಂಜಿ ದೋಷ ಉಪ್ಪುನಂಚಿನ ಫೈಲ್’ಗ್ ಲಿಂಕಾದುಪ್ಪೊಡು.\nಅವ್ವೇ ಸಾಲ್’ದ ಶುರುತ ಪೂರಾ ಲಿಂಕ್’ಲೆನ್ ಪರಿಗನೆರ್ದ್ ದೆಪ್ಪೆರಾಪುಂಡು, ಪಂಡ ಓವು ಪುಟೊಲೆಡ್ ಫೈಲ್’ದ ಬಗ್ಗೆ ಬರ್ಪುಂಡೋ ಔಲು.",
"metadata": "ಮೇಲ್ದರ್ಜೆ ಮಾಹಿತಿ",
"metadata-expand": "ವಿಸ್ತಾರವಾಯಿನ ವಿವರೊಲೆನ್ ತೊಜ್ಪಾವು",
"metadata-collapse": "ವಿಸ್ತಾರವಾಯಿನ ವಿವರೊಲೆನ್ ದೆಂಗಾವು",
"metadata-fields": "ಈ ಸಂದೇಶೊಡು ಪಟ್ಟಿ ಮಲ್ತಿನಂಚಿನ EXIF ಮಿತ್ತ ದರ್ಜೆದ ಮಾಹಿತಿನ್ ಚಿತ್ರ ಪುಟೊಕು ಸೇರ್ಪಾಯೆರೆ ಆವೊಂದುಂಡು. ಪುಟೊಟು ಮಿತ್ತ ದರ್ಜೆ ಮಾಹಿತಿದ ಪಟ್ಟಿನ್ ದೆಪ್ಪುನಗ ಉಂದು ತೋಜುಂಡು.\nಒರಿದನವು ಮೂಲಸ್ಥಿತಿಟ್ ಅಗೋಚರವಾದುಪ್ಪುಂಡು.\n* make\n* model\n* datetimeoriginal\n* exposuretime\n* fnumber\n* isospeedratings\n* focallength\n* artist\n* copyright\n* imagedescription\n* gpslatitude\n* gpslongitude \n* gpsaltitude",
+ "exif-orientation": "ದಿಕ್ಕ್ ದಿಸೆ",
+ "exif-xresolution": "ಅಡ್ಡಗಲದ ರೆಜ಼ಲ್ಯೂಶನ್",
+ "exif-yresolution": "ಉದ್ದೊದ ರೆಜ಼ಲ್ಯೂಶನ್",
"exif-datetime": "ಕಡೊತೊನು ಬದಲಾವಣೆ ಮಲ್ತ್ನ ದಿನಾಂಕೊ ಬೊಕ್ಕ ಸಮಯೊ",
"exif-make": "ಕ್ಯಾಮೆರಾದ ತಯಾರೆಕೆರ್",
"exif-model": "ಕ್ಯಾಮೆರಾ ಮಾದರಿ",
"exif-software": "ಉಪಯೋಗ ಮಲ್ತಿನ ತಂತ್ರಾಂಶ",
"exif-exifversion": "Exif ಆವೃತ್ತಿ",
+ "exif-colorspace": "ಬಣ್ಣದ ಜಾಗೆ",
"exif-datetimeoriginal": "ಮಾಹಿತಿ ಸೃಷ್ಟಿಯಾಯಿನ ದಿನಾಂಕೊ ಬೊಕ್ಕ ಸಮಯ",
"exif-datetimedigitized": "ಗಣಕೀಕರಣದ ದಿನಾಂಕೊ ಬೊಕ್ಕ ಸಮಯೊ",
"exif-orientation-1": "ಸಾಧಾರಣ",
"monthsall": "ಪೂರಾ",
"watchlisttools-view": "ಪ್ರಸ್ತುತ ಬದಲಾವಣೆಲ್ ತೋಜಾಲೆ",
"watchlisttools-edit": "ವೀಕ್ಷಣಾಪಟ್ಟಿನ್ ತೂಲೆ ಬೊಕ್ಕ ಎಡಿಟ್ ಮಲ್ಪುಲೆ",
- "specialpages": "ವಿಷೇಶ ಪುಟೊಲು",
- "tag-list-wrapper": "([[ವಿಸೇಸೊ:ಟ್ಯಾಗುಲು|{{ಬಹುವಚನೊ:$1|ಟ್ಯಾಗ್|ಟ್ಯಾಗುಲು}}]]:$2)",
+ "signature": "[[{{ns:user}}:$1|$2]] ([[{{ns:user_talk}}:$1|ಪಾತೆರ್ಲೆ]])",
+ "specialpages": "ವಿಸೇಸೊ ಪಾಲೆಲು",
+ "tag-filter": "[[Special:Tags|ಟ್ಯಾಗ್]] ಅರಿಪು:",
+ "tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Tag|ಟ್ಯಾಗುಲು}}]]: $2)",
"logentry-delete-delete": "$1 {{GENDER:$2|ಮಾಜಾದ್ಂಡ್}} ಪುಟ $3",
+ "logentry-move-move": "$1 {{GENDER:$2|ಜಾರಲೆ}} ಪಾಲೆ $3 ಡ್ದ್ $4",
"logentry-newusers-create": "ಬಳಕೆದಾರ ಖಾತೆ $1 ನ್ನು {{GENDER:$2|ಸೃಷ್ಟಿ ಮಲ್ತ್ದುಂಡು}}",
"logentry-upload-upload": "$1 {{GENDER:$2|ಅಪ್ಲೋಡ್ ಮಲ್ತ್ದೆರ್}} $3",
"searchsuggest-search": "ನಾಡ್ಲೆ"
"versionrequiredtext": "Bu sahifada ishlash uchun MediaWikining $1-versiyasi talab etiladi.\n[[Special:Version|Dasturiy taʼminot haqida axborot]]ni koʻring.",
"ok": "OK",
"retrievedfrom": " \"$1\" dan olindi",
- "youhavenewmessages": "Sizga $1 keldi ($2).",
+ "youhavenewmessages": "{{PLURAL:$3|Sizga}} $1 keldi ($2).",
"youhavenewmessagesfromusers": "Siz {{PLURAL:$3|boshqa foydalanuvchidan|$3 ta foydalanuvchidan}} $1 oldingiz ($2).",
"youhavenewmessagesmanyusers": "Siz ko'p foydalanuvchilardan $1 oldingiz ($2).",
"newmessageslinkplural": "{{PLURAL:$1|yangi xabar|999=yangi xabarlar}}",
"newmessagesdifflinkplural": "oxirgi {{PLURAL:$1|oʻzgarish|oʻzgarishlar}}",
- "youhavenewmessagesmulti": "Siz $1ga yangi xat oldingiz",
+ "youhavenewmessagesmulti": "Sizga $1da yangi xat keldi",
"editsection": "tahrirlash",
"editold": "tahrirlash",
"viewsourceold": "manbasini koʻrish",
"protectedpagetext": "Bu sahifa tahrirlash va boshqa oʻzgarishlar kiritishdan himoyalangan.",
"viewsourcetext": "Siz bu sahifaning manbasini koʻrishingiz va uni nusxasini olishingiz mumkin:",
"protectedinterface": "Ushbu sahifada dasturiy taʼminot interfeysi xabari mavjud. Bezoriliklardan saqlash uchun uni oʻzgartirish taʼqiqlangan.\nUshbu xabar tarjimasini qoʻshish yoki oʻzgartirish uchun, iltimos, MediaWikining [//translatewiki.net/ translatewiki.net] mahalliylashtirish saytidan foydalaning.",
- "editinginterface": "'''Diqqat:''' Siz dasturiy taʼminot interfeysi matni mavjud boʻlgan sahifani tahrirlamoqdasiz.\nUning oʻzgartirilishi ushbu vikidagi boshqa foydalanuvchilar uchun ham interfeys oʻzgarishiga olib keladi.\nUshbu xabar tarjimasini qoʻshish yoki oʻzgartirish uchun, iltimos, MediaWikining [//translatewiki.net/ translatewiki.net] mahalliylashtirish saytidan foydalaning.",
+ "editinginterface": "<strong>Eʼtibor bering:</strong> Siz interfeys matnini aks ettiruvchi sahifani tahrirlamoqdasiz.\nUning oʻzgartirilishi barcha ushbu vikidan foydalanuvchilar uchun ham interfeys oʻzgarishiga olib keladi.",
"namespaceprotected": "Sizda '''$1''' nomfazosi sahifalarini tahrirlash huquqi yoʻq",
"customcssprotected": "Sizda uchbu CSS sahifani tahrirlash huquqi yoʻq, chunki bu yerda boshqa foydalanuvchining shaxsiy moslamalari saqlanadi.",
"customjsprotected": "Sizda uchbu JavaScript sahifani tahrirlash huquqi yoʻq, chunki bu yerda boshqa foydalanuvchining shaxsiy moslamalari saqlanadi.",
"prefs-displayrc": "Tasvirlash moslamalari",
"prefs-displaywatchlist": "Tasvirlash moslamalari",
"prefs-diffs": "Versiyalar farqi",
- "userrights": "Foydalanuvchi huquqlarini oʻzgartirish",
+ "userrights": "Huquqlarini oʻzgartirish",
"userrights-lookup-user": "Foydalanuvchini tanlash",
"userrights-user-editname": "Foydalanuvchi nomi:",
"editusergroup": "Shu foydalanuvchi huquqlarini oʻzgartirish",
"listgrouprights-rights": "Huquqlar",
"listgrouprights-helppage": "Help:Guruhlar huquqlari",
"listgrouprights-members": "(a’zolar ro‘yxati)",
- "emailuser": "Foydalanuvchiga maktub",
+ "emailuser": "Maktub yuborish",
"emailuser-title-target": "Ushbu {{GENDER:$1|foydalanuvchi}}ga maktub joʻnatish",
"emailuser-title-notarget": "Foydalanuvchiga elektron maktub yozish",
"defemailsubject": "{{SITENAME}} — $1 tomonidan maktub",
"usermaildisabled": "Foydalanuvchi elektron pochtasi o‘chirilgan",
"noemailtitle": "Elektron pochta manzili mavjud emas",
"noemailtext": "Bu foydalanuvchi e-mail manzil koʻrsatgani yoʻq.",
- "emailtarget": "Oluvchi ishtirokchining ismini kiriting",
+ "emailtarget": "Kimga xat joʻnatmoqchisiz?",
"emailusername": "Foydalanuvchi nomi:",
- "emailusernamesubmit": "Jo'natish",
- "email-legend": "Boshqa {{SITENAME}} ishtirokchisiga xat jo'natish",
+ "emailusernamesubmit": "Joʻnatish",
+ "email-legend": "{{SITENAME}} loyihasining boshqa bir foydalanuvchisiga xat joʻnatish",
"emailfrom": "Kimdan:",
"emailto": "Kimga:",
"emailsubject": "Sarlavha:",
"emailsend": "Joʻnatish",
"emailccme": "Maktub nusxasi mening elektron pochtamga joʻnatilsin",
"emailccsubject": "$1ga maktubingizning nusxasi: $2",
- "emailsent": "Xat jo'natildi",
+ "emailsent": "Xat joʻnatildi",
"emailsenttext": "Sizning elektron maktubingiz jo'natildi.",
"usermessage-summary": "Tizimli xabar qoldirish.",
"usermessage-editor": "Tizimli etkazish",
"tooltip-feed-rss": "Bu sahifa uchun RSS ta'minot",
"tooltip-feed-atom": "Bu sahifa uchun Atom ta'minot",
"tooltip-t-contributions": "Ushbu foydalanuvchi qoʻshgan hissasini koʻrish",
- "tooltip-t-emailuser": "Ushbu foydalanuvchiga xat jo‘natish",
+ "tooltip-t-emailuser": "Ushbu foydalanuvchiga elektron maktub yozish",
"tooltip-t-upload": "Rasmlar yoki media fayllar yuklash",
"tooltip-t-specialpages": "Maxsus sahifalar ro‘yxati",
"tooltip-t-print": "Ushbu sahifaning bosma uchun versiyasi",
"log-fulllog": "Kitaa an bug-os nga taramdan",
"edit-conflict": "Diri pagkakauroyon han pagliwat.",
"edit-no-change": "Ginpabay-an an im pagliwat, mahitungod nga waray pagbalyo nga nabuhat ha nakasurat.",
+ "postedit-confirmation-created": "Nahimo an pakli.",
"postedit-confirmation-saved": "Natipig an imo ginliwat.",
"edit-already-exists": "Diri nakakahimo hin bag-o nga pakli.\nAada na ito.",
"defaultmessagetext": "Aada-nga-daan nga teksto han mensahe",
"upload-file-error": "Sayop ha sulod",
"upload-misc-error": "Waray kasasabti nga sayop hin pagkarga-paigbaw",
"upload-http-error": "Mayda nahitabo nga sayop hin HTTP: $1",
+ "upload-dialog-button-cancel": "Pasagda",
+ "upload-dialog-button-done": "Tima na",
+ "upload-dialog-button-save": "Igtipig",
+ "upload-dialog-button-upload": "Upload",
+ "upload-form-label-select-file": "Pagpili hin file",
+ "upload-form-label-infoform-title": "Mga detalye",
+ "upload-form-label-infoform-name": "Ngaran",
+ "upload-form-label-usage-title": "Paggamit",
+ "upload-form-label-usage-filename": "Ngaran han file",
+ "foreign-structured-upload-form-label-own-work": "Buhat ko ini",
+ "foreign-structured-upload-form-label-infoform-categories": "Mga kategorya",
+ "foreign-structured-upload-form-label-infoform-date": "Petsa",
"backend-fail-notexists": "Waray ngada an paypay nga $1.",
"backend-fail-delete": "Diri nakakapara han paypay nga \"$1\".",
"backend-fail-alreadyexists": "May-ada na paypay nga \"$1\".",
"editfont-monospace": "Dayoob mbind genn dig-digal",
"editfont-sansserif": "Dayoob mbind bu amul-dig",
"editfont-serif": "Dayoob mbind bu am-dig",
- "sunday": "dibéer",
- "monday": "altine",
- "tuesday": "talaata",
+ "sunday": "Dibéer",
+ "monday": "Altine",
+ "tuesday": "Talaata",
"wednesday": "àllarba",
"thursday": "alxamis",
- "friday": "Ã jjuma",
- "saturday": "gaawu",
+ "friday": "Ã\80jjuma",
+ "saturday": "Gaawu",
"sun": "dib",
"mon": "alt",
- "tue": "tal",
+ "tue": "Tal",
"wed": "àll",
"thu": "alx",
"fri": "àjj",
"sat": "gaa",
- "january": "Semwiyee",
+ "january": "Samwiyee",
"february": "Fewriyee",
"march": "Maars",
"april": "Awril",
"september": "Sattumbar",
"october": "Oktoobar",
"november": "Nowembar",
- "december": "Deesàmbar",
+ "december": "Samwiye",
"january-gen": "Samwie",
"february-gen": "Fewirie",
"march-gen": "Maars",
"actions": "Jëf",
"namespaces": "Barabu tur",
"variants": "Wuute",
- "navigation-heading": "Njëlul joowiin",
+ "navigation-heading": "Njëlu joowiin",
"errorpagetitle": "Njuumte",
"returnto": "Dellu ci wii xët $1.",
"tagline": "Jóge {{SITENAME}}.",
"unprotectthispage": "Aaradil wii xët",
"newpage": "Xët wu bees",
"talkpage": "Xëtu waxtaanuwaay",
- "talkpagelinktext": "Diisoo",
+ "talkpagelinktext": "Waxtaan",
"specialpage": "Xëtu jagleel",
"personaltools": "Samay jumtukaay",
"articlepage": "Gis jukki bi",
"talk": "Waxtaan",
- "views": "Xool yo",
- "toolbox": "Boyotu jumtukaay yi",
+ "views": "Wone yi",
+ "toolbox": "Boyotu jumtukaay",
"userpage": "Xëtu jëfandikukat",
"projectpage": "Wone xëtu sémb wi",
"imagepage": "Wone xëtu dencukaay bi",
"redirectedfrom": "(Yoonalaat gu jóge $1)",
"redirectpagesub": "Xëtu yoonalaat",
"redirectto": "Jëmalewaat:",
- "lastmodifiedat": "Coppite bu mujj bu xët wii $1 ci $2.<br />",
+ "lastmodifiedat": "Coppite gu mujj gu xët wii $1 ci $2.<br />",
"viewcount": "Xët wii nemmeeku nañ ko {{PLURAL:$1|$1 yoon|$1 yoon}}.",
"protectedpage": "Xët wees aar",
- "jumpto": "Dem :",
+ "jumpto": "Dem:",
"jumptonavigation": "Joowiin",
"jumptosearch": "Seet",
"view-pool-error": "jéggalu, joxekaay yi dañoo xat nii-nii.\nJëfandikukat yiy jéem a ubbi xët wii dañoo bari.\nTaaxiirlul ba ci kanam nga jéemaat.\n\n$1",
"aboutpage": "Project:Ci mbiri",
"copyright": "Ëmbit laa ngi jàppandi ci $1.",
"copyrightpage": "{{ns:project}}:Copyright",
- "currentevents": "Luy xew",
- "currentevents-url": "Project:Luy xew",
+ "currentevents": "Liy xew",
+ "currentevents-url": "Project:Liy xew",
"disclaimers": "Ay aartu",
"disclaimerpage": "Project:Aartu yu daj",
"edithelp": "Ndimbal",
"editlink": "soppi",
"viewsourcelink": "xool gongikuwaayam",
"editsectionhint": "Soppi bii xaaj : $1",
- "toc": "Tëraliin",
+ "toc": "Ëmbiit",
"showtoc": "Wone",
"hidetoc": "Nëbb",
"thisisdeleted": "Da ngaa bëgg a wone walla delloowaat $1 ?",
"createacct-emailoptional": "Màkkaanu m-bataaxal (mu-neex-la)",
"createacct-email-ph": "Duggalal sa màkkaanu m-bataaxal",
"createaccountmail": "Jaare ko ci m-bataaxal",
- "createacct-captcha": "Caytug kaaraange",
- "createacct-imgcaptcha-ph": "Duggalal mbind miy toftal mi ngay gis",
"createacct-submit": "Sos sa sàq",
"createacct-benefit-heading": "{{SITENAME}} ñu mel ni yaw a koy toppatoo.",
"createacct-benefit-body1": "{{PLURAL:$1|Coppite}}",
"templatesused": "{{PLURAL:$1| Royuwaay bi| Royuwaay yi}} nekk ci wii xët :",
"templatesusedpreview": "{{PLURAL:$1| Royuwaay bi|Royuwaay yi}} nekk ci gii wonendi :",
"templatesusedsection": "Royuwaay yi ne ci bii xaaj:",
- "template-protected": "(aar)",
+ "template-protected": "(aarees)",
"template-semiprotected": "(aar-diggu)",
"hiddencategories": "{{PLURAL:$1|wàll bu nëbbu bu|wàll yu nëbbu yu }} xët wii bokk :",
"nocreatetext": "Jëfandikukat yi bindu rekk a man a sosi xët ci {{SITENAME}}. Man nga dellu ginnaaw walla soppi aw xët wu am ba noppi, [[Special:UserLogin|duggu walla sos am sàq]].",
"rcshowhidemine-hide": "Nëbb",
"rclinks": "Wone $1 coppite yi mujj ci $2 fan yi mujj <br />$3.",
"diff": "wuute",
- "hist": "Jaar",
+ "hist": "jaar",
"hide": "Nëbb",
"show": "Wone",
"minoreditletter": "m",
"filehist-current": "teew",
"filehist-datetime": "Taariix ak Waxtu",
"filehist-thumb": "Tuutal",
- "filehist-thumbtext": "Tuutal gu sumb bu $1",
+ "filehist-thumbtext": "Tuutal gu sumb bu $1",
"filehist-user": "Jëfandikukat",
"filehist-dimensions": "Dayoo",
"filehist-filesize": "Dayoo ŋara wi",
"tooltip-pt-preferences": "Say tànneef",
"tooltip-pt-watchlist": "Limu xët yi ngay topp",
"tooltip-pt-mycontris": "Limu say cëru",
- "tooltip-pt-login": "Woo nan la ngir nga xammeku, waaye doonul lu manuta ñakk.",
+ "tooltip-pt-login": "Woo nan la ngir nga xammeku, waaye doonul lu manul-ñàkk.",
"tooltip-pt-logout": "Génn",
"tooltip-pt-createaccount": "Dees na la digal nga bindu te dugg, donte doonul lu manul-ñàkk",
"tooltip-ca-talk": "Waxtaan yi ñeel xët wii",
"tooltip-ca-move": "Tuddewaatal xët wii",
"tooltip-ca-watch": "Yokk xët wii ci sa limu toppte",
"tooltip-ca-unwatch": "Jële xët wii ci sa limu toppte",
- "tooltip-search": "Seet ci biir {{SITENAME}}",
+ "tooltip-search": "Seet ci {{SITENAME}}",
"tooltip-search-go": "Dem ci xët wi tudd ni nga wax, su dee am na.",
- "tooltip-search-fulltext": "Seet xët yi ëmb kàddu gi",
+ "tooltip-search-fulltext": "Seet mbind mi ci biir xët yi",
"tooltip-p-logo": "Xët wu njëkk",
- "tooltip-n-mainpage": "Nemmeeku xëtu njëlbéen",
- "tooltip-n-mainpage-description": "Nemmeku xët wu njëkk wi",
- "tooltip-n-portal": "Ngir xam dara ci mbiri sémb bi, noo ci mana jàppe",
+ "tooltip-n-mainpage": "Nemmeeku xët wu njëkk wi",
+ "tooltip-n-mainpage-description": "Nemmeeku xët wu njëkk wi",
+ "tooltip-n-portal": "Ngir xam dara ci mbiri sémb bi, noo ci man a jàppe",
"tooltip-n-currentevents": "Xibaar ci xew-xew yu teew yi",
"tooltip-n-recentchanges": "Limu coppite yi mujj ci wiki bi",
"tooltip-n-randompage": "Wone aw xët ci mbetteel",
- "tooltip-n-help": "Xëtu ndimbal wi",
- "tooltip-t-whatlinkshere": "limu xët yi ci wiki bi yi lëkkalook wii",
+ "tooltip-n-help": "Xëtu ndimbal",
+ "tooltip-t-whatlinkshere": "Limu xët yi ci wiki bi te lëkkalook wii",
"tooltip-t-recentchangeslinked": "Limu coppite yu mujj yu xët yi lëkkalook wii",
"tooltip-feed-rss": "Walug RSS ngir wii xët",
"tooltip-feed-atom": "Walug Atom ngir wii xët",
"tooltip-t-emailuser": "Yónne ab m-bataaxal bii jëfandikukat",
"tooltip-t-upload": "Yeb ay dencukaay",
"tooltip-t-specialpages": "Limu xëti jagleel yépp",
- "tooltip-t-print": "Sumb bu móolu bu xët wii",
+ "tooltip-t-print": "Sumb bu móolu bu wii xët",
"tooltip-t-permalink": "Lëkkalekaay bu sax buy jëme ci bii sumb bu xët wi",
"tooltip-ca-nstab-main": "Xool jukki bi",
"tooltip-ca-nstab-user": "Xool xëtu jëfandikukat wi",
"tooltip-ca-nstab-media": "Xool xëtu dencukaay wi",
- "tooltip-ca-nstab-special": "Lii aw xëtu jagleel la, kenn manu kaa soppi.",
+ "tooltip-ca-nstab-special": "Lii aw xëtu jagleel la, kenn manu koo soppi.",
"tooltip-ca-nstab-project": "Xool xëtu sémb wi",
"tooltip-ca-nstab-image": "Xool xëtu dencukaay wi",
"tooltip-ca-nstab-mediawiki": "Xool bataaxalu noste bi",
"tooltip-watch": "Yokk xët wii ci sa limu toppte",
"tooltip-recreate": "Sosaat xët wi donte dañ kaa faroon",
"tooltip-upload": "Door yeb gi",
- "tooltip-rollback": "\"Delloowaat\" dafay neenal coppitey cërukat bi mujj ci xët wii ci benn cuq.",
+ "tooltip-rollback": "\"Delloowaat\" dafay neenal coppitey cërukat bi mujj ci xët wii ci benn kilig.",
"tooltip-undo": "\"Neenal\" dafay far coppite yi te ubbi palanteeru coppite bi ci anamug wonendi.\nDafay tax nga man a bind ngirte li ci boyotu tënk bi.",
"tooltip-summary": "Def ci ab tënk",
"common.css": "/* CSS yiñ def fii dañuy am ay njeexit ci col yépp */",
"tog-hideminor": "באַהאַלטן מינערדיקע רעדאַקטירונגען אין לעצטע ענדערונגען",
"tog-hidepatrolled": "באַהאַלטן פאַטראלירטע רעדאַקטירונגען אין לעצטע ענדערונגען",
"tog-newpageshidepatrolled": "באַהאַלטן פאַטראלירטע בלעטער פון דער ליסטע פון נײַע בלעטער",
+ "tog-hidecategorization": "באהאלטן קאעגאריזירן בלעטער",
"tog-extendwatchlist": "פארברייטערן די אויפפאסן ליסטע צו צייגן אלע פאסנדע ענדערונגען (אנדערשט: בלויז די לעצטע ענדערונג פון יעדן בלאט)",
"tog-usenewrc": "גרופירן ענדערונגען לויטן בלאט אין \"לעצטע ענדערונגען\" און אויפֿפאסן ליסטע",
"tog-numberheadings": "נומערירן קעפּלעך אויטאָמאַטיש",
"tog-watchlisthideliu": "באהאלטן רעדאקטירונגען פון איינלאגירטע באניצערס פון דער אויפֿפאסונג ליסטע",
"tog-watchlisthideanons": "באהאלטן רעדאקטירונגען פון אנאנימע באניצערס פון דער אויפֿפאסונג ליסטע",
"tog-watchlisthidepatrolled": "באַהאַלטן פאַטראלירטע רעדאַקטירונגען פֿון דער אויפֿפאַסונג ליסטע",
+ "tog-watchlisthidecategorization": "באהאלטן קאעגאריזירן בלעטער",
"tog-ccmeonemails": "שיק מיר קאפיעס פון בליצבריוו וואס איך שיק צו אנדערע באַניצער",
"tog-diffonly": "ווייז נישט אינהאלט אונטער די דיפערענץ",
"tog-showhiddencats": "ווײַזן באהאלטענע קאטעגאריעס",
"rcshowhidemine": "$1 מײַנע רעדאַקטירוננגען",
"rcshowhidemine-show": "ווײַזן",
"rcshowhidemine-hide": "באַהאַלטן",
+ "rcshowhidecategorization": "$1 בלאט קאטעגאריזירונג",
+ "rcshowhidecategorization-show": "ווײַזן",
+ "rcshowhidecategorization-hide": "באַהאַלטן",
"rclinks": "װײַזן די לעצטע $1 ענדערונגען אין די לעצטע $2 טעג.<br />$3",
"diff": "אונטערשייד",
"hist": "היסטאריע",
"showingresultsinrange": "下面显示区间#<strong>$2</strong>至#<strong>$3</strong>的<strong>$1</strong>条结果。",
"search-showingresults": "{{PLURAL:$4|<strong>$3</strong>条结果中的<strong>$1</strong>条|<strong>$3</strong>条结果中的<strong>$1~$2</strong>条}}",
"search-nonefound": "找不到和查询相匹配的结果。",
+ "search-nonefound-thiswiki": "在此网站找不到匹配查询的结果。",
"powersearch-legend": "高级搜索",
"powersearch-ns": "搜索名字空间:",
"powersearch-togglelabel": "选择:",
<?php
/**
- * This file is the entry point for the resource loader.
+ * This file is the entry point for ResourceLoader.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
--- Table for storing JSON message blobs for the resource loader
+-- Table for storing JSON message blobs for ResourceLoader
CREATE TABLE /*_*/msg_resource (
-- Resource name
mr_resource varbinary(255) NOT NULL,
);
CREATE INDEX /*i*/lc_lang_key ON /*_*/l10n_cache (lc_lang, lc_key);
--- Table for caching JSON message texts for the resource loader
+-- Table for caching JSON message texts for ResourceLoader
CREATE TABLE /*_*/msg_resource (
-- Resource name
mr_resource nvarchar(255) NOT NULL,
) /*$wgDBTableOptions*/;
CREATE INDEX /*i*/lc_lang_key ON /*_*/l10n_cache (lc_lang, lc_key);
--- Table for caching JSON message blobs for the resource loader
+-- Table for caching JSON message blobs for ResourceLoader
CREATE TABLE /*_*/msg_resource (
-- Resource name
mr_resource varbinary(255) NOT NULL,
'scripts' => 'resources/src/mediawiki/mediawiki.experiments.js',
'targets' => array( 'desktop', 'mobile' ),
),
+ 'mediawiki.raggett' => array(
+ 'styles' => 'resources/src/mediawiki/mediawiki.raggett.css'
+ ),
/* MediaWiki Action */
display: inline !ie;
}
.searchresults {
+ margin: 1em 0 1em .4em;
}
-.searchresults p {
- margin-left: 0.4em;
- margin-top: 1em;
- margin-bottom: 1.2em;
+/* needs extra specificity to override `.mw-body p` selector */
+.mw-body p.mw-search-nonefound {
+ margin: 0;
+}
+.mw-search-interwiki-header {
+ font-weight: bold;
+}
+.mw-search-nonefound + .mw-search-interwiki-header {
+ margin-top: 0;
}
div.searchresult {
font-size: 95%;
width: 38em;
}
.mw-search-results {
- margin-left: 0.4em;
+ margin-left: 0;
float: left;
}
.mw-search-results li {
padding-left: 0.25em;
}
.mw-search-profile-tabs div.search-types ul {
- margin: 0 !important;
- padding: 0 !important;
- list-style: none !important;
+ margin: 0;
+ padding: 0;
+ list-style: none;
}
.mw-search-profile-tabs div.search-types ul li {
float: left;
fieldset#mw-searchoptions {
margin: 0;
- padding: 0.5em 0.75em 0.75em 0.75em !important;
+ padding: 0.5em 0.75em 0.75em 0.75em;
border: none;
background-color: #f9f9f9;
- border: 1px solid silver !important;
- border-top-width: 0 !important;
+ border: 1px solid silver;
+ border-top-width: 0;
}
fieldset#mw-searchoptions legend {
display: none;
redirect: suggestionPage.redirect !== undefined,
disambiguation: OO.getProp( suggestionPage, 'pageprops', 'disambiguation' ) !== undefined,
imageUrl: OO.getProp( suggestionPage, 'thumbnail', 'source' ),
- description: OO.getProp( suggestionPage, 'terms', 'description' )
+ description: OO.getProp( suggestionPage, 'terms', 'description' ),
+ // sort index
+ index: suggestionPage.index
};
// Throw away pages from wrong namespaces. This can happen when 'showRedirectTargets' is true
}
}
+ titles.sort( function ( a, b ) {
+ return pageData[ a ].index - pageData[ b ].index;
+ } );
+
// If not found, run value through mw.Title to avoid treating a match as a
// mismatch where normalisation would make them matching (bug 48476)
* @inheritdoc
*/
mw.ForeignStructuredUpload.BookletLayout.prototype.initialize = function () {
- mw.ForeignStructuredUpload.BookletLayout.parent.prototype.initialize.call( this );
- // Point the CategorySelector to the right wiki as soon as we know what the right wiki is
- this.upload.apiPromise.done( function ( api ) {
- // If this is a ForeignApi, it will have a apiUrl, otherwise we don't need to do anything
- if ( api.apiUrl ) {
- // Can't reuse the same object, CategorySelector calls #abort on its mw.Api instance
- this.categoriesWidget.api = new mw.ForeignApi( api.apiUrl );
- }
- }.bind( this ) );
+ var deferred = $.Deferred();
+ mw.ForeignStructuredUpload.BookletLayout.parent.prototype.initialize.call( this )
+ .done( function () {
+ // Point the CategorySelector to the right wiki
+ this.upload.apiPromise.done( function ( api ) {
+ // If this is a ForeignApi, it will have a apiUrl, otherwise we don't need to do anything
+ if ( api.apiUrl ) {
+ // Can't reuse the same object, CategorySelector calls #abort on its mw.Api instance
+ this.categoriesWidget.api = new mw.ForeignApi( api.apiUrl );
+ }
+ deferred.resolve();
+ }.bind( this ) );
+ }.bind( this ) );
+ return deferred.promise();
};
/**
/**
* Initialize for a new upload
+ *
+ * @return {jQuery.Promise} Promise resolved when everything is initialized
*/
mw.Upload.BookletLayout.prototype.initialize = function () {
this.clear();
this.upload = this.createUpload();
this.setPage( 'upload' );
+ return $.Deferred().resolve().promise();
};
/**
mw.Upload.Dialog.prototype.getSetupProcess = function ( data ) {
return mw.Upload.Dialog.parent.prototype.getSetupProcess.call( this, data )
.next( function () {
- this.uploadBooklet.initialize();
+ return this.uploadBooklet.initialize();
}, this );
};
--- /dev/null
+.mw-empty-li {
+ display: none;
+}
'WikitextContentTest' => "$testDir/phpunit/includes/content/WikitextContentTest.php",
# tests/phpunit/includes/db
- 'ORMRowTest' => "$testDir/phpunit/includes/db/ORMRowTest.php",
- 'ORMTableTest' => "$testDir/phpunit/includes/db/ORMTableTest.php",
- 'PageORMTableForTesting' => "$testDir/phpunit/includes/db/ORMTableTest.php",
'DatabaseTestHelper' => "$testDir/phpunit/includes/db/DatabaseTestHelper.php",
# tests/phpunit/includes/diff
<ref name="b"><span id="Z">foo</span>bar</ref>
</references>
!! end
+
+!! test
+Empty LI (T49673)
+!! wikitext
+* a
+*
+*
+* b
+!! html/php+tidy
+<ul>
+<li>a</li>
+<li class="mw-empty-li"></li>
+<li class="mw-empty-li"></li>
+<li>b</li>
+</ul>
+!! end
+++ /dev/null
-<?php
-/**
- * @group GlobalFunctions
- * @covers ::wfBaseConvert
- */
-class WfBaseConvertTest extends MediaWikiTestCase {
- public static function provideSingleDigitConversions() {
- return array(
- // 2 3 5 8 10 16 36
- array( '0', '0', '0', '0', '0', '0', '0' ),
- array( '1', '1', '1', '1', '1', '1', '1' ),
- array( '10', '2', '2', '2', '2', '2', '2' ),
- array( '11', '10', '3', '3', '3', '3', '3' ),
- array( '100', '11', '4', '4', '4', '4', '4' ),
- array( '101', '12', '10', '5', '5', '5', '5' ),
- array( '110', '20', '11', '6', '6', '6', '6' ),
- array( '111', '21', '12', '7', '7', '7', '7' ),
- array( '1000', '22', '13', '10', '8', '8', '8' ),
- array( '1001', '100', '14', '11', '9', '9', '9' ),
- array( '1010', '101', '20', '12', '10', 'a', 'a' ),
- array( '1011', '102', '21', '13', '11', 'b', 'b' ),
- array( '1100', '110', '22', '14', '12', 'c', 'c' ),
- array( '1101', '111', '23', '15', '13', 'd', 'd' ),
- array( '1110', '112', '24', '16', '14', 'e', 'e' ),
- array( '1111', '120', '30', '17', '15', 'f', 'f' ),
- array( '10000', '121', '31', '20', '16', '10', 'g' ),
- array( '10001', '122', '32', '21', '17', '11', 'h' ),
- array( '10010', '200', '33', '22', '18', '12', 'i' ),
- array( '10011', '201', '34', '23', '19', '13', 'j' ),
- array( '10100', '202', '40', '24', '20', '14', 'k' ),
- array( '10101', '210', '41', '25', '21', '15', 'l' ),
- array( '10110', '211', '42', '26', '22', '16', 'm' ),
- array( '10111', '212', '43', '27', '23', '17', 'n' ),
- array( '11000', '220', '44', '30', '24', '18', 'o' ),
- array( '11001', '221', '100', '31', '25', '19', 'p' ),
- array( '11010', '222', '101', '32', '26', '1a', 'q' ),
- array( '11011', '1000', '102', '33', '27', '1b', 'r' ),
- array( '11100', '1001', '103', '34', '28', '1c', 's' ),
- array( '11101', '1002', '104', '35', '29', '1d', 't' ),
- array( '11110', '1010', '110', '36', '30', '1e', 'u' ),
- array( '11111', '1011', '111', '37', '31', '1f', 'v' ),
- array( '100000', '1012', '112', '40', '32', '20', 'w' ),
- array( '100001', '1020', '113', '41', '33', '21', 'x' ),
- array( '100010', '1021', '114', '42', '34', '22', 'y' ),
- array( '100011', '1022', '120', '43', '35', '23', 'z' )
- );
- }
-
- /**
- * @dataProvider provideSingleDigitConversions
- */
- public function testDigitToBase2( $base2, $base3, $base5, $base8, $base10, $base16, $base36 ) {
- $this->assertSame( $base2, wfBaseConvert( $base3, '3', '2' ) );
- $this->assertSame( $base2, wfBaseConvert( $base5, '5', '2' ) );
- $this->assertSame( $base2, wfBaseConvert( $base8, '8', '2' ) );
- $this->assertSame( $base2, wfBaseConvert( $base10, '10', '2' ) );
- $this->assertSame( $base2, wfBaseConvert( $base16, '16', '2' ) );
- $this->assertSame( $base2, wfBaseConvert( $base36, '36', '2' ) );
- }
-
- /**
- * @dataProvider provideSingleDigitConversions
- */
- public function testDigitToBase3( $base2, $base3, $base5, $base8, $base10, $base16, $base36 ) {
- $this->assertSame( $base3, wfBaseConvert( $base2, '2', '3' ) );
- $this->assertSame( $base3, wfBaseConvert( $base5, '5', '3' ) );
- $this->assertSame( $base3, wfBaseConvert( $base8, '8', '3' ) );
- $this->assertSame( $base3, wfBaseConvert( $base10, '10', '3' ) );
- $this->assertSame( $base3, wfBaseConvert( $base16, '16', '3' ) );
- $this->assertSame( $base3, wfBaseConvert( $base36, '36', '3' ) );
- }
-
- /**
- * @dataProvider provideSingleDigitConversions
- */
- public function testDigitToBase5( $base2, $base3, $base5, $base8, $base10, $base16, $base36 ) {
- $this->assertSame( $base5, wfBaseConvert( $base2, '2', '5' ) );
- $this->assertSame( $base5, wfBaseConvert( $base3, '3', '5' ) );
- $this->assertSame( $base5, wfBaseConvert( $base8, '8', '5' ) );
- $this->assertSame( $base5, wfBaseConvert( $base10, '10', '5' ) );
- $this->assertSame( $base5, wfBaseConvert( $base16, '16', '5' ) );
- $this->assertSame( $base5, wfBaseConvert( $base36, '36', '5' ) );
- }
-
- /**
- * @dataProvider provideSingleDigitConversions
- */
- public function testDigitToBase8( $base2, $base3, $base5, $base8, $base10, $base16, $base36 ) {
- $this->assertSame( $base8, wfBaseConvert( $base2, '2', '8' ) );
- $this->assertSame( $base8, wfBaseConvert( $base3, '3', '8' ) );
- $this->assertSame( $base8, wfBaseConvert( $base5, '5', '8' ) );
- $this->assertSame( $base8, wfBaseConvert( $base10, '10', '8' ) );
- $this->assertSame( $base8, wfBaseConvert( $base16, '16', '8' ) );
- $this->assertSame( $base8, wfBaseConvert( $base36, '36', '8' ) );
- }
-
- /**
- * @dataProvider provideSingleDigitConversions
- */
- public function testDigitToBase10( $base2, $base3, $base5, $base8, $base10, $base16, $base36 ) {
- $this->assertSame( $base10, wfBaseConvert( $base2, '2', '10' ) );
- $this->assertSame( $base10, wfBaseConvert( $base3, '3', '10' ) );
- $this->assertSame( $base10, wfBaseConvert( $base5, '5', '10' ) );
- $this->assertSame( $base10, wfBaseConvert( $base8, '8', '10' ) );
- $this->assertSame( $base10, wfBaseConvert( $base16, '16', '10' ) );
- $this->assertSame( $base10, wfBaseConvert( $base36, '36', '10' ) );
- }
-
- /**
- * @dataProvider provideSingleDigitConversions
- */
- public function testDigitToBase16( $base2, $base3, $base5, $base8, $base10, $base16, $base36 ) {
- $this->assertSame( $base16, wfBaseConvert( $base2, '2', '16' ) );
- $this->assertSame( $base16, wfBaseConvert( $base3, '3', '16' ) );
- $this->assertSame( $base16, wfBaseConvert( $base5, '5', '16' ) );
- $this->assertSame( $base16, wfBaseConvert( $base8, '8', '16' ) );
- $this->assertSame( $base16, wfBaseConvert( $base10, '10', '16' ) );
- $this->assertSame( $base16, wfBaseConvert( $base36, '36', '16' ) );
- }
-
- /**
- * @dataProvider provideSingleDigitConversions
- */
- public function testDigitToBase36( $base2, $base3, $base5, $base8, $base10, $base16, $base36 ) {
- $this->assertSame( $base36, wfBaseConvert( $base2, '2', '36' ) );
- $this->assertSame( $base36, wfBaseConvert( $base3, '3', '36' ) );
- $this->assertSame( $base36, wfBaseConvert( $base5, '5', '36' ) );
- $this->assertSame( $base36, wfBaseConvert( $base8, '8', '36' ) );
- $this->assertSame( $base36, wfBaseConvert( $base10, '10', '36' ) );
- $this->assertSame( $base36, wfBaseConvert( $base16, '16', '36' ) );
- }
-
- public function testLargeNumber() {
- $this->assertSame( '1100110001111010000000101110100', wfBaseConvert( 'sd89ys', 36, 2 ) );
- $this->assertSame( '11102112120221201101', wfBaseConvert( 'sd89ys', 36, 3 ) );
- $this->assertSame( '12003102232400', wfBaseConvert( 'sd89ys', 36, 5 ) );
- $this->assertSame( '14617200564', wfBaseConvert( 'sd89ys', 36, 8 ) );
- $this->assertSame( '1715274100', wfBaseConvert( 'sd89ys', 36, 10 ) );
- $this->assertSame( '663d0174', wfBaseConvert( 'sd89ys', 36, 16 ) );
- }
-
- public static function provideNumbers() {
- $x = array();
- $chars = '0123456789abcdefghijklmnopqrstuvwxyz';
- for ( $i = 0; $i < 50; $i++ ) {
- $base = mt_rand( 2, 36 );
- $len = mt_rand( 10, 100 );
-
- $str = '';
- for ( $j = 0; $j < $len; $j++ ) {
- $str .= $chars[mt_rand( 0, $base - 1 )];
- }
-
- $x[] = array( $base, $str );
- }
-
- return $x;
- }
-
- /**
- * @dataProvider provideNumbers
- */
- public function testIdentity( $base, $number ) {
- $this->assertSame( $number, wfBaseConvert( $number, $base, $base, strlen( $number ) ) );
- }
-
- public function testInvalid() {
- $this->assertFalse( wfBaseConvert( '101', 1, 15 ) );
- $this->assertFalse( wfBaseConvert( '101', 15, 1 ) );
- $this->assertFalse( wfBaseConvert( '101', 37, 15 ) );
- $this->assertFalse( wfBaseConvert( '101', 15, 37 ) );
- $this->assertFalse( wfBaseConvert( 'abcde', 10, 11 ) );
- $this->assertFalse( wfBaseConvert( '12930', 2, 10 ) );
- $this->assertFalse( wfBaseConvert( '101', 'abc', 15 ) );
- $this->assertFalse( wfBaseConvert( '101', 15, 'abc' ) );
- }
-
- public function testPadding() {
- $number = "10101010101";
- $this->assertSame(
- strlen( $number ) + 5,
- strlen( wfBaseConvert( $number, 2, 2, strlen( $number ) + 5 ) )
- );
- $this->assertSame(
- strlen( $number ),
- strlen( wfBaseConvert( $number, 2, 2, strlen( $number ) - 5 ) )
- );
- }
-
- public function testLeadingZero() {
- $this->assertSame( '24', wfBaseConvert( '010', 36, 16 ) );
- $this->assertSame( '37d4', wfBaseConvert( '0b10', 36, 16 ) );
- $this->assertSame( 'a734', wfBaseConvert( '0x10', 36, 16 ) );
- }
-}
}
/**
- * The Resource Loader uses wfTimestamp() to convert timestamps
- * from If-Modified-Since header. Thus it must be able to parse all
- * rfc2616 date formats
* @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3.1
* @dataProvider provideHttpDates
*/
+++ /dev/null
-<?php
-
-/**
- * Abstract class to construct tests for ORMRow deriving classes.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @since 1.20
- *
- * @ingroup Test
- *
- * @group ORM
- *
- * The database group has as a side effect that temporal database tables are created. This makes
- * it possible to test without poisoning a production database.
- * @group Database
- *
- * Some of the tests takes more time, and needs therefor longer time before they can be aborted
- * as non-functional. The reason why tests are aborted is assumed to be set up of temporal databases
- * that hold the first tests in a pending state awaiting access to the database.
- * @group medium
- *
- * @author Jeroen De Dauw < jeroendedauw@gmail.com >
- */
-abstract class ORMRowTest extends \MediaWikiTestCase {
-
- /**
- * @since 1.20
- * @return string
- */
- abstract protected function getRowClass();
-
- /**
- * @since 1.20
- * @return IORMTable
- */
- abstract protected function getTableInstance();
-
- /**
- * @since 1.20
- * @return array
- */
- abstract public function constructorTestProvider();
-
- /**
- * @since 1.20
- * @param IORMRow $row
- * @param array $data
- */
- protected function verifyFields( IORMRow $row, array $data ) {
- foreach ( array_keys( $data ) as $fieldName ) {
- $this->assertEquals( $data[$fieldName], $row->getField( $fieldName ) );
- }
- }
-
- /**
- * @since 1.20
- * @param array $data
- * @param bool $loadDefaults
- * @return IORMRow
- */
- protected function getRowInstance( array $data, $loadDefaults ) {
- $class = $this->getRowClass();
-
- return new $class( $this->getTableInstance(), $data, $loadDefaults );
- }
-
- /**
- * @since 1.20
- * @return array
- */
- protected function getMockValues() {
- return array(
- 'id' => 1,
- 'str' => 'foobar4645645',
- 'int' => 42,
- 'float' => 4.2,
- 'bool' => true,
- 'array' => array( 42, 'foobar' ),
- 'blob' => new stdClass()
- );
- }
-
- /**
- * @since 1.20
- * @return array
- */
- protected function getMockFields() {
- $mockValues = $this->getMockValues();
- $mockFields = array();
-
- foreach ( $this->getTableInstance()->getFields() as $name => $type ) {
- if ( $name !== 'id' ) {
- $mockFields[$name] = $mockValues[$type];
- }
- }
-
- return $mockFields;
- }
-
- /**
- * @since 1.20
- * @return array Array of IORMRow
- */
- public function instanceProvider() {
- $instances = array();
-
- foreach ( $this->constructorTestProvider() as $arguments ) {
- $instances[] = array( call_user_func_array( array( $this, 'getRowInstance' ), $arguments ) );
- }
-
- return $instances;
- }
-
- /**
- * @dataProvider constructorTestProvider
- */
- public function testConstructor( array $data, $loadDefaults ) {
- $this->verifyFields( $this->getRowInstance( $data, $loadDefaults ), $data );
- }
-
- /**
- * @dataProvider constructorTestProvider
- */
- public function testSaveAndRemove( array $data, $loadDefaults ) {
- $item = $this->getRowInstance( $data, $loadDefaults );
-
- $this->assertTrue( $item->save() );
-
- $this->assertTrue( $item->hasIdField() );
- $this->assertTrue( is_integer( $item->getId() ) );
-
- $id = $item->getId();
-
- $this->assertTrue( $item->save() );
-
- $this->assertEquals( $id, $item->getId() );
-
- $this->verifyFields( $item, $data );
-
- $this->assertTrue( $item->remove() );
-
- $this->assertFalse( $item->hasIdField() );
-
- $this->assertTrue( $item->save() );
-
- $this->verifyFields( $item, $data );
-
- $this->assertTrue( $item->remove() );
-
- $this->assertFalse( $item->hasIdField() );
-
- $this->verifyFields( $item, $data );
- }
-
- /**
- * @dataProvider instanceProvider
- */
- public function testSetField( IORMRow $item ) {
- foreach ( $this->getMockFields() as $name => $value ) {
- $item->setField( $name, $value );
- $this->assertEquals( $value, $item->getField( $name ) );
- }
- }
-
- /**
- * @since 1.20
- * @param array $expected
- * @param IORMRow $item
- */
- protected function assertFieldValues( array $expected, IORMRow $item ) {
- foreach ( $expected as $name => $type ) {
- if ( $name !== 'id' ) {
- $this->assertEquals( $expected[$name], $item->getField( $name ) );
- }
- }
- }
-
- /**
- * @dataProvider instanceProvider
- */
- public function testSetFields( IORMRow $item ) {
- $originalValues = $item->getFields();
-
- $item->setFields( array(), false );
-
- foreach ( $item->getTable()->getFields() as $name => $type ) {
- $originalHas = array_key_exists( $name, $originalValues );
- $newHas = $item->hasField( $name );
-
- $this->assertEquals( $originalHas, $newHas );
-
- if ( $originalHas && $newHas ) {
- $this->assertEquals( $originalValues[$name], $item->getField( $name ) );
- }
- }
-
- $mockFields = $this->getMockFields();
-
- $item->setFields( $mockFields, false );
-
- $this->assertFieldValues( $originalValues, $item );
-
- $item->setFields( $mockFields, true );
-
- $this->assertFieldValues( $mockFields, $item );
- }
-
- // TODO: test all of the methods!
-
-}
+++ /dev/null
-<?php
-/**
- * Abstract class to construct tests for ORMTable deriving classes.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @since 1.21
- *
- * @ingroup Test
- *
- * @group ORM
- * @group Database
- *
- * @covers PageORMTableForTesting
- *
- * @author Jeroen De Dauw < jeroendedauw@gmail.com >
- * @author Daniel Kinzler
- */
-
-class ORMTableTest extends MediaWikiTestCase {
-
- /**
- * @since 1.21
- * @return string
- */
- protected function getTableClass() {
- return 'PageORMTableForTesting';
- }
-
- /**
- * @since 1.21
- * @return IORMTable
- */
- public function getTable() {
- $class = $this->getTableClass();
-
- return $class::singleton();
- }
-
- /**
- * @since 1.21
- * @return string
- */
- public function getRowClass() {
- return $this->getTable()->getRowClass();
- }
-
- /**
- * @since 1.21
- */
- public function testSingleton() {
- $class = $this->getTableClass();
-
- $this->assertInstanceOf( $class, $class::singleton() );
- $this->assertTrue( $class::singleton() === $class::singleton() );
- }
-}
-
-/**
- * Dummy ORM table for testing, reading Title objects from the page table.
- *
- * @since 1.21
- */
-
-class PageORMTableForTesting extends ORMTable {
-
- public function __construct() {
- $this->fieldPrefix = 'page_';
- }
-
- /**
- * @see ORMTable::getName
- *
- * @return string
- */
- public function getName() {
- return 'page';
- }
-
- /**
- * @see ORMTable::getRowClass
- *
- * @return string
- */
- public function getRowClass() {
- return 'Title';
- }
-
- /**
- * @see ORMTable::newRow
- *
- * @return IORMRow
- */
- public function newRow( array $data, $loadDefaults = false ) {
- return Title::makeTitle( $data['namespace'], $data['title'] );
- }
-
- /**
- * @see ORMTable::getFields
- *
- * @return array
- */
- public function getFields() {
- return array(
- 'id' => 'int',
- 'namespace' => 'int',
- 'title' => 'str',
- );
- }
-}
+++ /dev/null
-<?php
-
-/**
- * Tests for the TestORMRow class.
- * TestORMRow is a dummy class to be able to test the abstract ORMRow class.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @ingroup Test
- * @author Jeroen De Dauw < jeroendedauw@gmail.com >
- */
-
-/**
- * The database group has as a side effect that temporal database tables are created. This makes
- * it possible to test without poisoning a production database.
- *
- * Some of the tests takes more time, and needs therefor longer time before they can be aborted
- * as non-functional. The reason why tests are aborted is assumed to be set up of temporal databases
- * that hold the first tests in a pending state awaiting access to the database.
- *
- * @since 1.20
- *
- * @group ORM
- * @group Database
- * @group medium
- * @covers TestORMRow
- */
-class TestORMRowTest extends ORMRowTest {
-
- /**
- * @since 1.20
- * @return string
- */
- protected function getRowClass() {
- return 'TestORMRow';
- }
-
- /**
- * @since 1.20
- * @return IORMTable
- */
- protected function getTableInstance() {
- return TestORMTable::singleton();
- }
-
- protected function setUp() {
- parent::setUp();
-
- $dbw = wfGetDB( DB_MASTER );
-
- $isSqlite = $GLOBALS['wgDBtype'] === 'sqlite';
- $isPostgres = $GLOBALS['wgDBtype'] === 'postgres';
-
- $idField = $isSqlite ? 'INTEGER' : 'INT unsigned';
- $primaryKey = $isSqlite ? 'PRIMARY KEY AUTOINCREMENT' : 'auto_increment PRIMARY KEY';
-
- if ( $isPostgres ) {
- $dbw->query(
- 'CREATE TABLE IF NOT EXISTS ' . $dbw->tableName( 'orm_test' ) . "(
- test_id serial PRIMARY KEY,
- test_name TEXT NOT NULL DEFAULT '',
- test_age INTEGER NOT NULL DEFAULT 0,
- test_height REAL NOT NULL DEFAULT 0,
- test_awesome INTEGER NOT NULL DEFAULT 0,
- test_stuff BYTEA,
- test_moarstuff BYTEA,
- test_time TIMESTAMPTZ
- );",
- __METHOD__
- );
- } else {
- $dbw->query(
- 'CREATE TABLE IF NOT EXISTS ' . $dbw->tableName( 'orm_test' ) . '(
- test_id ' . $idField . ' NOT NULL ' . $primaryKey . ',
- test_name VARCHAR(255) NOT NULL,
- test_age TINYINT unsigned NOT NULL,
- test_height FLOAT NOT NULL,
- test_awesome TINYINT unsigned NOT NULL,
- test_stuff BLOB NOT NULL,
- test_moarstuff BLOB NOT NULL,
- test_time varbinary(14) NOT NULL
- );',
- __METHOD__
- );
- }
- }
-
- protected function tearDown() {
- $dbw = wfGetDB( DB_MASTER );
- $dbw->dropTable( 'orm_test', __METHOD__ );
-
- parent::tearDown();
- }
-
- public function constructorTestProvider() {
- $dbw = wfGetDB( DB_MASTER );
- return array(
- array(
- array(
- 'name' => 'Foobar',
- 'time' => $dbw->timestamp( '20120101020202' ),
- 'age' => 42,
- 'height' => 9000.1,
- 'awesome' => true,
- 'stuff' => array( 13, 11, 7, 5, 3, 2 ),
- 'moarstuff' => (object)array( 'foo' => 'bar', 'bar' => array( 4, 2 ), 'baz' => true )
- ),
- true
- ),
- );
- }
-
- /**
- * @since 1.21
- * @return array
- */
- protected function getMockValues() {
- return array(
- 'id' => 1,
- 'str' => 'foobar4645645',
- 'int' => 42,
- 'float' => 4.2,
- 'bool' => '',
- 'array' => array( 42, 'foobar' ),
- 'blob' => new stdClass()
- );
- }
-}
-
-class TestORMRow extends ORMRow {
-}
-
-class TestORMTable extends ORMTable {
-
- public function __construct() {
- $this->fieldPrefix = 'test_';
- }
-
- /**
- * Returns the name of the database table objects of this type are stored in.
- *
- * @since 1.20
- *
- * @return string
- */
- public function getName() {
- return 'orm_test';
- }
-
- /**
- * Returns the name of a IORMRow implementing class that
- * represents single rows in this table.
- *
- * @since 1.20
- *
- * @return string
- */
- public function getRowClass() {
- return 'TestORMRow';
- }
-
- /**
- * Returns an array with the fields and their types this object contains.
- * This corresponds directly to the fields in the database, without prefix.
- *
- * field name => type
- *
- * Allowed types:
- * * id
- * * str
- * * int
- * * float
- * * bool
- * * array
- * * blob
- *
- * @since 1.20
- *
- * @return array
- */
- public function getFields() {
- return array(
- 'id' => 'id',
- 'name' => 'str',
- 'age' => 'int',
- 'height' => 'float',
- 'awesome' => 'bool',
- 'stuff' => 'array',
- 'moarstuff' => 'blob',
- 'time' => 'str', // TS_MW
- );
- }
-}
return $value;
};
- $cache->delete( $key );
$ret = $cache->getWithSetCallback( $key, 30, $func, array( 'lockTSE' => 5 ) );
$this->assertEquals( $value, $ret );
$this->assertEquals( 1, $calls, 'Value was populated' );
$this->assertEquals( 1, $calls, 'Callback was not used' );
}
+ /**
+ * @covers WANObjectCache::getWithSetCallback()
+ */
+ public function testLockTSESlow() {
+ $cache = $this->cache;
+ $key = wfRandomString();
+ $value = wfRandomString();
+
+ $calls = 0;
+ $func = function( $oldValue, &$ttl, &$setOpts ) use ( &$calls, $value ) {
+ ++$calls;
+ $setOpts['since'] = microtime( true ) - 10;
+ return $value;
+ };
+
+ // Value should be marked as stale due to snapshot lag
+ $curTTL = null;
+ $ret = $cache->getWithSetCallback( $key, 30, $func, array( 'lockTSE' => 5 ) );
+ $this->assertEquals( $value, $ret );
+ $this->assertEquals( $value, $cache->get( $key, $curTTL ), 'Value was populated' );
+ $this->assertLessThan( 0, $curTTL, 'Value has negative curTTL' );
+ $this->assertEquals( 1, $calls, 'Value was generated' );
+
+ // Acquire a lock to verify that getWithSetCallback uses lockTSE properly
+ $this->internalCache->lock( $key, 0 );
+ $ret = $cache->getWithSetCallback( $key, 30, $func, array( 'lockTSE' => 5 ) );
+ $this->assertEquals( $value, $ret );
+ $this->assertEquals( 1, $calls, 'Callback was not used' );
+ }
+
/**
* @covers WANObjectCache::getMulti()
*/
$t6 = $this->cache->getCheckKeyTime( $key );
$this->assertEquals( $t5, $t6, 'Check key time did not change' );
}
+
+ public function testSetWithLag() {
+ $value = 1;
+
+ $key = wfRandomString();
+ $opts = array( 'lag' => 300, 'since' => microtime( true ) );
+ $this->cache->set( $key, $value, 30, $opts );
+ $this->assertEquals( $value, $this->cache->get( $key ), "Rep-lagged value written." );
+
+ $key = wfRandomString();
+ $opts = array( 'lag' => 0, 'since' => microtime( true ) - 300 );
+ $this->cache->set( $key, $value, 30, $opts );
+ $this->assertEquals( false, $this->cache->get( $key ), "Trx-lagged value not written." );
+
+ $key = wfRandomString();
+ $opts = array( 'lag' => 5, 'since' => microtime( true ) - 5 );
+ $this->cache->set( $key, $value, 30, $opts );
+ $this->assertEquals( false, $this->cache->get( $key ), "Lagged value not written." );
+ }
+
+ public function testWritePending() {
+ $value = 1;
+
+ $key = wfRandomString();
+ $opts = array( 'pending' => true );
+ $this->cache->set( $key, $value, 30, $opts );
+ $this->assertEquals( false, $this->cache->get( $key ), "Pending value not written." );
+ }
}
}
/**
- * @covers MemcachedBagOStuff::makeKeyInternal
+ * @covers MemcachedBagOStuff::makeKey
*/
public function testKeyNormalization() {
$this->assertEquals(
$this->cache->makeKey( 'long_key_part_hashed', str_repeat( 'y', 500 ) )
);
}
+
+ /**
+ * @dataProvider validKeyProvider
+ */
+ public function testValidateKeyEncoding( $key ) {
+ $this->assertSame( $key, $this->cache->validateKeyEncoding( $key ) );
+ }
+
+ public function validKeyProvider() {
+ return array(
+ 'empty' => array( '' ),
+ 'digits' => array( '09' ),
+ 'letters' => array( 'AZaz' ),
+ 'ASCII special characters' => array( '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~' ),
+ );
+ }
+
+ /**
+ * @dataProvider invalidKeyProvider
+ */
+ public function testValidateKeyEncodingThrowsException( $key ) {
+ $this->setExpectedException( 'Exception' );
+ $this->cache->validateKeyEncoding( $key );
+ }
+
+ public function invalidKeyProvider() {
+ return array(
+ array( "\x00" ),
+ array( ' ' ),
+ array( "\x1F" ),
+ array( "\x7F" ),
+ array( "\x80" ),
+ array( "\xFF" ),
+ );
+ }
}
// Bug T116683 serialize_precision of 100
// may break testing against floating point values
// treated with PHP's serialize()
- ini_set( 'serialize_precision', 14 );
+ ini_set( 'serialize_precision', 17 );
}
public function execute() {
'lists' => array(
'scripts',
'debugScripts',
- 'loaderScripts',
'styles',
),
* @return array (MediaTransformOutput|bool, string|bool error message HTML)
*/
function wfGenerateThumbnail( File $file, array $params, $thumbName, $thumbPath ) {
- global $wgMemc, $wgAttemptFailureEpoch;
+ global $wgAttemptFailureEpoch;
- $key = wfMemcKey( 'attempt-failures', $wgAttemptFailureEpoch,
- $file->getRepo()->getName(), $file->getSha1(), md5( $thumbName ) );
+ $cache = ObjectCache::getLocalClusterInstance();
+ $key = $cache->makeKey(
+ 'attempt-failures',
+ $wgAttemptFailureEpoch,
+ $file->getRepo()->getName(),
+ $file->getSha1(),
+ md5( $thumbName )
+ );
// Check if this file keeps failing to render
- if ( $wgMemc->get( $key ) >= 4 ) {
+ if ( $cache->get( $key ) >= 4 ) {
return array( false, wfMessage( 'thumbnail_image-failure-limit', 4 ) );
}
$done = false;
// Record failures on PHP fatals in addition to caching exceptions
- register_shutdown_function( function () use ( &$done, $key ) {
+ register_shutdown_function( function () use ( $cache, &$done, $key ) {
if ( !$done ) { // transform() gave a fatal
- global $wgMemc;
// Randomize TTL to reduce stampedes
- $wgMemc->incrWithInit( $key, 3600 + mt_rand( 0, 300 ) );
+ $cache->incrWithInit( $key, $cache::TTL_HOUR + mt_rand( 0, 300 ) );
}
} );
if ( !$thumb || $thumb->isError() ) {
// Randomize TTL to reduce stampedes
- $wgMemc->incrWithInit( $key, 3600 + mt_rand( 0, 300 ) );
+ $cache->incrWithInit( $key, $cache::TTL_HOUR + mt_rand( 0, 300 ) );
}
return array( $thumb, $errorHtml );