function parserConvert($t, $p) {return $t;}
function getVariants() { return array( $this->mLang->getCode() ); }
function getPreferredVariant() {return $this->mLang->getCode(); }
- function findVariantLink(&$l, &$n, $forTemplate = false) {}
+ function findVariantLink(&$l, &$n, $ignoreOtherCond = false) {}
function getExtraHashOptions() {return '';}
function getParsedTitle() {return '';}
function markNoConversion($text, $noParse=false) {return $text;}
var $mConverter, $mVariants, $mCode, $mLoaded = false;
var $mMagicExtensions = array(), $mMagicHookDone = false;
- static public $mLocalisationKeys = array( 'fallback', 'namespaceNames',
- 'skinNames', 'mathNames',
- 'bookstoreList', 'magicWords', 'messages', 'rtl', 'digitTransformTable',
+ static public $mLocalisationKeys = array(
+ 'fallback', 'namespaceNames', 'mathNames', 'bookstoreList',
+ 'magicWords', 'messages', 'rtl', 'digitTransformTable',
'separatorTransformTable', 'fallback8bitEncoding', 'linkPrefixExtension',
'defaultUserOptionOverrides', 'linkTrail', 'namespaceAliases',
'dateFormats', 'datePreferences', 'datePreferenceMigrationMap',
if ( isset( $aliases[$name][0] ) ) {
$name = $aliases[$name][0];
}
- return $this->getNsText(NS_SPECIAL) . ':' . $name;
+ return $this->getNsText( NS_SPECIAL ) . ':' . $name;
}
function getQuickbarSettings() {
);
}
- function getSkinNames() {
- $this->load();
- return $this->skinNames;
- }
-
function getMathNames() {
$this->load();
return $this->mathNames;
* internationalisation, a reduced set of format characters, and a better
* escaping format.
*
- * Supported format characters are dDjlNwzWFmMntLYyaAgGhHiscrU. See the
- * PHP manual for definitions. There are a number of extensions, which
- * start with "x":
+ * Supported format characters are dDjlNwzWFmMntLoYyaAgGhHiscrU. See the
+ * PHP manual for definitions. "o" format character is supported since
+ * PHP 5.1.0, previous versions return literal o.
+ * There are a number of extensions, which start with "x":
*
* xn Do not translate digits of the next numeric format character
* xN Toggle raw digit (xn) flag, stays set until explicitly unset
* xjn n (month number) in Hebrew calendar
* xjY Y (full year) in Hebrew calendar
*
- * xmj j (day number) in Hijri calendar
- * xmF F (month name) in Hijri calendar
- * xmn n (month number) in Hijri calendar
- * xmY Y (full year) in Hijri calendar
+ * xmj j (day number) in Hijri calendar
+ * xmF F (month name) in Hijri calendar
+ * xmn n (month number) in Hijri calendar
+ * xmY Y (full year) in Hijri calendar
*
* xkY Y (full year) in Thai solar calendar. Months and days are
* identical to the Gregorian calendar
* @param $ts String: 14-character timestamp
* YYYYMMDDHHMMSS
* 01234567890123
+ * @todo emulation of "o" format character for PHP pre 5.1.0
+ * @todo handling of "o" format character for Iranian, Hebrew, Hijri & Thai?
*/
function sprintfDate( $format, $ts ) {
$s = '';
if ( !$unix ) $unix = wfTimestamp( TS_UNIX, $ts );
$num = gmdate( 'L', $unix );
break;
+ # 'o' is supported since PHP 5.1.0
+ # return literal if not supported
+ # TODO: emulation for pre 5.1.0 versions
+ case 'o':
+ if ( !$unix ) $unix = wfTimestamp( TS_UNIX, $ts );
+ if ( version_compare(PHP_VERSION, '5.1.0') === 1 )
+ $num = date( 'o', $unix );
+ else
+ $s .= 'o';
+ break;
case 'Y':
$num = substr( $ts, 0, 4 );
break;
$n = $minLength-1;
$out = preg_replace(
"/\b(\w{1,$n})\b/",
- "$1U800",
+ "$1u800",
$out );
}
// "example.wikipedia.com" and "192.168.83.1" as well.
$out = preg_replace(
"/(\w)\.(\w|\*)/u",
- "$1U82e$2",
+ "$1u82e$2",
$out );
wfProfileOut( __METHOD__ );
* settings or anything else of the sort.
*/
protected function stripForSearchCallback( $matches ) {
- return 'U8' . bin2hex( $matches[1] );
+ return 'u8' . bin2hex( $matches[1] );
}
/**
if (!$nocommafy) {
$number = $this->commafy($number);
$s = $this->separatorTransformTable();
- if (!is_null($s)) { $number = strtr($number, $s); }
+ if ($s) { $number = strtr($number, $s); }
}
if ($wgTranslateNumerals) {
$s = $this->digitTransformTable();
- if (!is_null($s)) { $number = strtr($number, $s); }
+ if ($s) { $number = strtr($number, $s); }
}
return $number;
function parseFormattedNumber( $number ) {
$s = $this->digitTransformTable();
- if (!is_null($s)) { $number = strtr($number, array_flip($s)); }
+ if ($s) { $number = strtr($number, array_flip($s)); }
$s = $this->separatorTransformTable();
- if (!is_null($s)) { $number = strtr($number, array_flip($s)); }
+ if ($s) { $number = strtr($number, array_flip($s)); }
$number = strtr( $number, array (',' => '') );
return $number;
/**
- * For the credit list in includes/Credits.php (action=credits)
+ * Take a list of strings and build a locale-friendly comma-separated
+ * list, using the local comma-separator message.
+ * The last two strings are chained with an "and".
*
* @param $l Array
* @return string
*/
function listToText( $l ) {
$s = '';
- $m = count($l) - 1;
- for ($i = $m; $i >= 0; $i--) {
- if ($i == $m) {
- $s = $l[$i];
- } else if ($i == $m - 1) {
- $s = $l[$i] . $this->getMessageFromDB( 'and' ) . $this->getMessageFromDB( 'word-separator' ) . $s;
- } else {
- $s = $l[$i] . $this->getMessageFromDB( 'comma-separator' ) . $s;
+ $m = count( $l ) - 1;
+ if( $m == 1 ) {
+ return $l[0] . $this->getMessageFromDB( 'and' ) . $this->getMessageFromDB( 'word-separator' ) . $l[1];
+ }
+ else {
+ for ( $i = $m; $i >= 0; $i-- ) {
+ if ( $i == $m ) {
+ $s = $l[$i];
+ } else if( $i == $m - 1 ) {
+ $s = $l[$i] . $this->getMessageFromDB( 'and' ) . $this->getMessageFromDB( 'word-separator' ) . $s;
+ } else {
+ $s = $l[$i] . $this->getMessageFromDB( 'comma-separator' ) . $s;
+ }
}
+ return $s;
}
- return $s;
}
-
+
/**
* Take a list of strings and build a locale-friendly comma-separated
* list, using the local comma-separator message.
* @param $list array of strings to put in a comma list
* @return string
*/
- function commaList( $list, $forContent = false ) {
+ function commaList( $list ) {
return implode(
$list,
wfMsgExt( 'comma-separator', array( 'escapenoentities', 'language' => $this ) ) );
}
-
+
+ /**
+ * Take a list of strings and build a locale-friendly semicolon-separated
+ * list, using the local semicolon-separator message.
+ * @param $list array of strings to put in a semicolon list
+ * @return string
+ */
+ function semicolonList( $list ) {
+ return implode(
+ $list,
+ wfMsgExt( 'semicolon-separator', array( 'escapenoentities', 'language' => $this ) ) );
+ }
+
/**
* Same as commaList, but separate it with the pipe instead.
* @param $list array of strings to put in a pipe list
* @param $ellipsis String to append to the truncated text
* @return string
*/
- function truncate( $string, $length, $ellipsis = "" ) {
+ function truncate( $string, $length, $ellipsis = '...' ) {
+ # Use the localized ellipsis character
+ if( $ellipsis == '...' ) {
+ $ellipsis = wfMsgExt( 'ellipsis', array( 'escapenoentities', 'language' => $this ) );
+ }
+
if( $length == 0 ) {
return $ellipsis;
}
} elseif( $char >= 0x80 &&
preg_match( '/^(.*)(?:[\xe0-\xef][\x80-\xbf]|' .
'[\xf0-\xf7][\x80-\xbf]{1,2})$/', $string, $m ) ) {
- # We chopped in the middle of a character; remove it
+ # We chopped in the middle of a character; remove it
$string = $m[1];
}
return $string . $ellipsis;
return $word;
}
+ /**
+ * Provides an alternative text depending on specified gender.
+ * Usage {{gender:username|masculine|feminine|neutral}}.
+ * username is optional, in which case the gender of current user is used,
+ * but only in (some) interface messages; otherwise default gender is used.
+ * If second or third parameter are not specified, masculine is used.
+ * These details may be overriden per language.
+ */
+ function gender( $gender, $forms ) {
+ if ( !count($forms) ) { return ''; }
+ $forms = $this->preConvertPlural( $forms, 2 );
+ if ( $gender === 'male' ) return $forms[0];
+ if ( $gender === 'female' ) return $forms[1];
+ return isset($forms[2]) ? $forms[2] : $forms[0];
+ }
+
/**
* Plural form transformations, needed for some languages.
* For example, there are 3 form of plural in Russian and Polish,
*
* @param $link String: the name of the link
* @param $nt Mixed: the title object of the link
+ * @param boolean $ignoreOtherCond: to disable other conditions when
+ * we need to transclude a template or update a category's link
* @return null the input parameters may be modified upon return
*/
- function findVariantLink( &$link, &$nt, $forTemplate = false ) {
- $this->mConverter->findVariantLink($link, $nt, $forTemplate );
+ function findVariantLink( &$link, &$nt, $ignoreOtherCond = false ) {
+ $this->mConverter->findVariantLink( $link, $nt, $ignoreOtherCond );
}
/**
* into an array of all possible variants of the text:
* 'variant' => text in that variant
*/
-
function convertLinkToAllVariants($text){
return $this->mConverter->convertLinkToAllVariants($text);
}
$cache = compact( self::$mLocalisationKeys );
wfDebug( "Language::loadLocalisation(): got localisation for $code from source\n" );
}
+
+ # Load magic word source file
+ global $IP;
+ $filename = "$IP/includes/MagicWord.php";
+ $newDeps = array( $filename => filemtime( $filename ) );
+ $deps = array_merge( $deps, $newDeps );
if ( !empty( $fallback ) ) {
# Load the fallback localisation, with a circular reference guard
self::loadLocalisation( $cache );
$cache = self::$mLocalisationCache[$cache];
}
+ // At least one language file and the MagicWord file needed
+ if( count($cache['deps']) < 2 ) {
+ return true;
+ }
$expired = false;
foreach ( $cache['deps'] as $file => $mtime ) {
if ( !file_exists( $file ) || filemtime( $file ) > $mtime ) {
$this->namespaceNames[NS_PROJECT_TALK] = $wgMetaNamespaceTalk;
} else {
$talk = $this->namespaceNames[NS_PROJECT_TALK];
- $talk = str_replace( '$1', $wgMetaNamespace, $talk );
-
- # Allow grammar transformations
- # Allowing full message-style parsing would make simple requests
- # such as action=raw much more expensive than they need to be.
- # This will hopefully cover most cases.
- $talk = preg_replace_callback( '/{{grammar:(.*?)\|(.*?)}}/i',
- array( &$this, 'replaceGrammarInNamespace' ), $talk );
- $talk = str_replace( ' ', '_', $talk );
- $this->namespaceNames[NS_PROJECT_TALK] = $talk;
+ $this->namespaceNames[NS_PROJECT_TALK] =
+ $this->fixVariableInNamespace( $talk );
}
# The above mixing may leave namespaces out of canonical order.
}
if ( $this->namespaceAliases ) {
foreach ( $this->namespaceAliases as $name => $index ) {
+ if ( $index === NS_PROJECT_TALK ) {
+ unset( $this->namespaceAliases[$name] );
+ $name = $this->fixVariableInNamespace( $name );
+ $this->namespaceAliases[$name] = $index;
+ }
$this->mNamespaceIds[$this->lc($name)] = $index;
}
}
wfProfileOut( __METHOD__ );
}
+ function fixVariableInNamespace( $talk ) {
+ if ( strpos( $talk, '$1' ) === false ) return $talk;
+
+ global $wgMetaNamespace;
+ $talk = str_replace( '$1', $wgMetaNamespace, $talk );
+
+ # Allow grammar transformations
+ # Allowing full message-style parsing would make simple requests
+ # such as action=raw much more expensive than they need to be.
+ # This will hopefully cover most cases.
+ $talk = preg_replace_callback( '/{{grammar:(.*?)\|(.*?)}}/i',
+ array( &$this, 'replaceGrammarInNamespace' ), $talk );
+ return str_replace( ' ', '_', $talk );
+ }
+
function replaceGrammarInNamespace( $m ) {
return $this->convertGrammar( trim( $m[2] ), trim( $m[1] ) );
}