regularly. Below only new and removed languages are listed, as well as
changes to languages because of Bugzilla reports.
-* BREAKING CHANGE (T91240): Language code "bh" is not valid in ISO 639 and
- was removed, so it will no longer alias to "bho". If you used "bh" as your
- wiki's $wgLanguageCode, you must update your configuration.
=== Other changes in 1.26 ===
* ChangeTags::tagDescription() will return false if the interface message
);
/**
- * Main cache Wide-Area-Network cache type. This should be a cache with fast access,
+ * Main Wide-Area-Network cache type. This should be a cache with fast access,
* but it may have limited space. By default, it is disabled, since the basic stock
* cache is not fast enough to make it worthwhile. For single data-center setups, this can
* simply be pointed to a cache in $wgWANObjectCaches that uses a local $wgObjectCaches
* a relayer (only matters if there are multiple data-centers)
* - CACHE_NONE: Do not cache
* - (other): A string may be used which identifies a cache
- * configuration in $wgWANObjectCaches.
+ * configuration in $wgWANObjectCaches
+ * @since 1.26
*/
$wgMainWANCache = false;
* a cache identifier from $wgObjectCaches. The "relayerConfig" parameter is an
* array used to construct an EventRelayer object. The "pool" parameter is a
* string that is used as a PubSub channel prefix.
+ *
+ * @since 1.26
*/
$wgWANObjectCaches = array(
CACHE_NONE => array(
*/
);
+/**
+ * Main object stash type. This should be a fast storage system for storing
+ * lightweight data like hit counters and user activity. Sites with multiple
+ * data-centers should have this use a store that replicates all writes. The
+ * store should have enough consistency for CAS operations to be usable.
+ *
+ * The options are:
+ * - db: Store cache objects in the DB
+ * - (other): A string may be used which identifies a cache
+ * configuration in $wgObjectCaches
+ *
+ * @since 1.26
+ */
+$wgMainStash = 'db';
+
/**
* The expiry time for the parser cache, in seconds.
* The default is 86400 (one day).
* is "wp{$fieldname}". If you want a different name
* (eg one without the "wp" prefix), specify it here and
* it will be used without modification.
+ * 'hide-if' -- expression given as an array stating when the field
+ * should be hidden. The first array value has to be the
+ * expression's logic operator. Supported expressions:
+ * 'NOT'
+ * [ 'NOT', array $expression ]
+ * To hide a field if a given expression is not true.
+ * '==='
+ * [ '===', string $fieldName, string $value ]
+ * To hide a field if another field identified by
+ * $field has the value $value.
+ * '!=='
+ * [ '!==', string $fieldName, string $value ]
+ * Same as [ 'NOT', [ '===', $fieldName, $value ]
+ * 'OR', 'AND', 'NOR', 'NAND'
+ * [ 'XXX', array $expression1, ..., array $expressionN ]
+ * To hide a field if one or more (OR), all (AND),
+ * neither (NOR) or not all (NAND) given expressions
+ * are evaluated as true.
+ * The expressions will be given to a JavaScript frontend
+ * module which will continually update the field's
+ * visibility.
*
* Since 1.20, you can chain mutators to ease the form generation:
* @par Example:
/**
* Functions to get cache objects
*
+ * The word "cache" has two main dictionary meanings, and both
+ * are used in this factory class. They are:
+ * - a) A place to store copies or computations on existing data
+ * for higher access speeds (the computer science definition)
+ * - b) A place to store lightweight data that is not canonically
+ * stored anywhere else (e.g. a "hoard" of objects)
+ *
* @ingroup Cache
*/
class ObjectCache {
return self::getWANInstance( $wgMainWANCache );
}
+
+ /**
+ * Stash objects are BagOStuff instances suitable for storing light
+ * weight data that is not canonically stored elsewhere (such as RDBMS).
+ * Stashes should be configured to propagate changes to all data-centers.
+ *
+ * Callers should be prepared for:
+ * - a) Writes to be slower in non-"primary" (e.g. HTTP GET/HEAD only) DCs
+ * - b) Reads to be eventually consistent, e.g. for get()/getMulti()
+ * In general, this means avoiding updates on idempotent HTTP requests and
+ * avoiding an assumption of perfect serializability (or accepting anomalies).
+ * Reads may be eventually consistent or data might rollback as nodes flap.
+ *
+ *
+ * @return BagOStuff
+ * @since 1.26
+ */
+ static function getMainStashInstance() {
+ global $wgMainStash;
+
+ return self::getInstance( $wgMainStash );
+ }
}
'license-name',
);
+ /**
+ * Things that are not 'attributes', but are not in
+ * $globalSettings or $creditsAttributes.
+ *
+ * @var array
+ */
+ protected static $notAttributes = array(
+ 'callback',
+ 'Hooks',
+ 'namespaces',
+ 'ResourceFileModulePaths',
+ 'ResourceModules',
+ 'ResourceModuleSkinStyles',
+ 'ExtensionMessagesFiles',
+ 'MessagesDirs',
+ 'type',
+ 'config',
+ 'ParserTestFiles',
+ 'AutoloadClasses',
+ );
+
/**
* Stuff that is going to be set to $GLOBALS
*
*/
protected $attributes = array();
- /**
- * List of keys that have already been processed
- *
- * @var array
- */
- protected $processed = array();
-
/**
* @param string $path
* @param array $info
$this->extractParserTestFiles( $dir, $info );
if ( isset( $info['callback'] ) ) {
$this->callbacks[] = $info['callback'];
- $this->processed[] = 'callback';
}
$this->extractCredits( $path, $info );
if ( in_array( $key, self::$globalSettings ) ) {
$this->storeToArray( "wg$key", $val, $this->globals );
// Ignore anything that starts with a @
- } elseif ( $key[0] !== '@' && !in_array( $key, $this->processed ) ) {
+ } elseif ( $key[0] !== '@' && !in_array( $key, self::$notAttributes )
+ && !in_array( $key, self::$creditsAttributes )
+ ) {
$this->storeToArray( $key, $val, $this->attributes );
}
}
-
}
public function getExtractedInfo() {
$this->globals['wgHooks'][$name][] = $callback;
}
}
- $this->processed[] = 'Hooks';
}
}
$this->globals['wgNamespaceContentModels'][$id] = $ns['defaultcontentmodel'];
}
}
- $this->processed[] = 'namespaces';
}
}
$this->globals["wgExtensionMessagesFiles"] += array_map( function( $file ) use ( $dir ) {
return "$dir/$file";
}, $info['ExtensionMessagesFiles'] );
- $this->processed[] = 'ExtensionMessagesFiles';
}
}
$this->globals["wgMessagesDirs"][$name][] = "$dir/$file";
}
}
- $this->processed[] = 'MessagesDirs';
}
}
'path' => $path,
'type' => isset( $info['type'] ) ? $info['type'] : 'other',
);
- $this->processed[] = 'type';
foreach ( self::$creditsAttributes as $attr ) {
if ( isset( $info[$attr] ) ) {
$credits[$attr] = $info[$attr];
- $this->processed[] = $attr;
}
}
$this->globals["wg$key"] = $val;
}
}
- $this->processed[] = 'config';
}
}
foreach ( $info['ParserTestFiles'] as $path ) {
$this->globals['wgParserTestFiles'][] = "$dir/$path";
}
- $this->processed[] = 'ParserTestFiles';
}
}
*/
protected $attributes = array();
- /**
- * Processors, 'default' should be set by subclasses in the constructor
- *
- * @var Processor[]
- */
- protected $processors = array();
-
/**
* @var ExtensionRegistry
*/
return;
}
- $this->queued = array_unique( $this->queued );
-
// See if this queue is in APC
$key = wfMemcKey( 'registration', md5( json_encode( $this->queued ) ) );
$data = $this->cache->get( $key );
public function readFromQueue( array $queue ) {
$data = array( 'globals' => array( 'wgAutoloadClasses' => array() ) );
$autoloadClasses = array();
+ $processor = new ExtensionProcessor();
foreach ( $queue as $path => $mtime ) {
$json = file_get_contents( $path );
if ( $json === false ) {
// Set up the autoloader now so custom processors will work
$GLOBALS['wgAutoloadClasses'] += $autoload;
$autoloadClasses += $autoload;
- if ( isset( $info['processor'] ) ) {
- $processor = $this->getProcessor( $info['processor'] );
- } else {
- $processor = $this->getProcessor( 'default' );
- }
$processor->extractInfo( $path, $info );
}
- foreach ( $this->processors as $processor ) {
- $data = array_merge_recursive( $data, $processor->getExtractedInfo() );
- }
+ $data = $processor->getExtractedInfo();
+ // Need to set this so we can += to it later
+ $data['globals']['wgAutoloadClasses'] = array();
foreach ( $data['credits'] as $credit ) {
$data['globals']['wgExtensionCredits'][$credit['type']][] = $credit;
}
- $this->processors = array(); // Reset
$data['autoload'] = $autoloadClasses;
return $data;
}
- protected function getProcessor( $type ) {
- if ( !isset( $this->processors[$type] ) ) {
- $processor = $type === 'default' ? new ExtensionProcessor() : new $type();
- if ( !$processor instanceof Processor ) {
- throw new Exception( "$type is not a Processor" );
- }
- $this->processors[$type] = $processor;
- }
-
- return $this->processors[$type];
- }
-
protected function exportExtractedData( array $info ) {
foreach ( $info['globals'] as $key => $val ) {
if ( !isset( $GLOBALS[$key] ) || !$GLOBALS[$key] ) {
'be-x-old' => "беларуская (тарашкевіца)\xE2\x80\x8E", # (be-tarask compat)
'bg' => 'български', # Bulgarian
'bgn' => 'بلوچی رخشانی', # Western Balochi
+ 'bh' => 'भोजपुरी', # Bihari macro language. Falls back to Bhojpuri (bho)
'bho' => 'भोजपुरी', # Bhojpuri
'bi' => 'Bislama', # Bislama
'bjn' => 'Bahasa Banjar', # Banjarese
--- /dev/null
+<?php
+/** Bihari (भोजपुरी)
+ *
+ * To improve a translation please visit https://translatewiki.net
+ *
+ * @ingroup Language
+ * @file
+ *
+ */
+
+$fallback = 'bho';
+
$processor->extractInfo( $this->dir, self::$default + array(
'@metadata' => array( 'foobarbaz' ),
'AnAttribute' => array( 'omg' ),
+ 'AutoloadClasses' => array( 'FooBar' => 'includes/FooBar.php' ),
) );
$extracted = $processor->getExtractedInfo();
$attributes = $extracted['attributes'];
$this->assertArrayHasKey( 'AnAttribute', $attributes );
$this->assertArrayNotHasKey( '@metadata', $attributes );
+ $this->assertArrayNotHasKey( 'AutoloadClasses', $attributes );
}
public static function provideRegisterHooks() {