6 if( !defined( 'MEDIAWIKI' ) ) {
7 echo "This file is part of MediaWiki, it is not a valid entry point.\n";
12 # In general you should not make customizations in these language files
13 # directly, but should use the MediaWiki: special namespace to customize
14 # user interface messages through the wiki.
15 # See http://meta.wikipedia.org/wiki/MediaWiki_namespace
17 # NOTE TO TRANSLATORS: Do not copy this whole file when making translations!
18 # A lot of common constants and a base class with inheritable methods are
19 # defined here, which should not be redefined. See the other LanguageXx.php
24 global $wgLanguageNames;
25 require_once( dirname(__FILE__
) . '/Names.php' ) ;
27 global $wgInputEncoding, $wgOutputEncoding;
30 * These are always UTF-8, they exist only for backwards compatibility
32 $wgInputEncoding = "UTF-8";
33 $wgOutputEncoding = "UTF-8";
35 if( function_exists( 'mb_strtoupper' ) ) {
36 mb_internal_encoding('UTF-8');
39 /* a fake language converter */
42 function FakeConverter($langobj) {$this->mLang
= $langobj;}
43 function convert($t, $i) {return $t;}
44 function parserConvert($t, $p) {return $t;}
45 function getVariants() { return array( $this->mLang
->getCode() ); }
46 function getPreferredVariant() {return $this->mLang
->getCode(); }
47 function findVariantLink(&$l, &$n) {}
48 function getExtraHashOptions() {return '';}
49 function getParsedTitle() {return '';}
50 function markNoConversion($text, $noParse=false) {return $text;}
51 function convertCategoryKey( $key ) {return $key; }
52 function convertLinkToAllVariants($text){ return array( $this->mLang
->getCode() => $text); }
53 function armourMath($text){ return $text; }
56 #--------------------------------------------------------------------------
57 # Internationalisation code
58 #--------------------------------------------------------------------------
61 var $mConverter, $mVariants, $mCode, $mLoaded = false;
63 static public $mLocalisationKeys = array( 'fallback', 'namespaceNames',
64 'skinNames', 'mathNames',
65 'bookstoreList', 'magicWords', 'messages', 'rtl', 'digitTransformTable',
66 'separatorTransformTable', 'fallback8bitEncoding', 'linkPrefixExtension',
67 'defaultUserOptionOverrides', 'linkTrail', 'namespaceAliases',
68 'dateFormats', 'datePreferences', 'datePreferenceMigrationMap',
69 'defaultDateFormat', 'extraUserToggles', 'specialPageAliases' );
71 static public $mMergeableMapKeys = array( 'messages', 'namespaceNames', 'mathNames',
72 'dateFormats', 'defaultUserOptionOverrides', 'magicWords' );
74 static public $mMergeableListKeys = array( 'extraUserToggles' );
76 static public $mMergeableAliasListKeys = array( 'specialPageAliases' );
78 static public $mLocalisationCache = array();
80 static public $mWeekdayMsgs = array(
81 'sunday', 'monday', 'tuesday', 'wednesday', 'thursday',
85 static public $mWeekdayAbbrevMsgs = array(
86 'sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'
89 static public $mMonthMsgs = array(
90 'january', 'february', 'march', 'april', 'may_long', 'june',
91 'july', 'august', 'september', 'october', 'november',
94 static public $mMonthGenMsgs = array(
95 'january-gen', 'february-gen', 'march-gen', 'april-gen', 'may-gen', 'june-gen',
96 'july-gen', 'august-gen', 'september-gen', 'october-gen', 'november-gen',
99 static public $mMonthAbbrevMsgs = array(
100 'jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug',
101 'sep', 'oct', 'nov', 'dec'
105 * Create a language object for a given language code
107 static function factory( $code ) {
109 static $recursionLevel = 0;
111 if ( $code == 'en' ) {
114 $class = 'Language' . str_replace( '-', '_', ucfirst( $code ) );
115 // Preload base classes to work around APC/PHP5 bug
116 if ( file_exists( "$IP/languages/classes/$class.deps.php" ) ) {
117 include_once("$IP/languages/classes/$class.deps.php");
119 if ( file_exists( "$IP/languages/classes/$class.php" ) ) {
120 include_once("$IP/languages/classes/$class.php");
124 if ( $recursionLevel > 5 ) {
125 throw new MWException( "Language fallback loop detected when creating class $class\n" );
128 if( ! class_exists( $class ) ) {
129 $fallback = Language
::getFallbackFor( $code );
131 $lang = Language
::factory( $fallback );
133 $lang->setCode( $code );
141 function __construct() {
142 $this->mConverter
= new FakeConverter($this);
143 // Set the code to the name of the descendant
144 if ( get_class( $this ) == 'Language' ) {
147 $this->mCode
= str_replace( '_', '-', strtolower( substr( get_class( $this ), 8 ) ) );
152 * Hook which will be called if this is the content language.
153 * Descendants can use this to register hook functions or modify globals
155 function initContLang() {}
161 function getDefaultUserOptions() {
162 return User
::getDefaultOptions();
165 function getFallbackLanguageCode() {
167 return $this->fallback
;
171 * Exports $wgBookstoreListEn
174 function getBookstoreList() {
176 return $this->bookstoreList
;
182 function getNamespaces() {
184 return $this->namespaceNames
;
188 * A convenience function that returns the same thing as
189 * getNamespaces() except with the array values changed to ' '
190 * where it found '_', useful for producing output to be displayed
191 * e.g. in <select> forms.
195 function getFormattedNamespaces() {
196 $ns = $this->getNamespaces();
197 foreach($ns as $k => $v) {
198 $ns[$k] = strtr($v, '_', ' ');
204 * Get a namespace value by key
206 * $mw_ns = $wgContLang->getNsText( NS_MEDIAWIKI );
207 * echo $mw_ns; // prints 'MediaWiki'
210 * @param int $index the array key of the namespace to return
211 * @return mixed, string if the namespace value exists, otherwise false
213 function getNsText( $index ) {
214 $ns = $this->getNamespaces();
215 return isset( $ns[$index] ) ?
$ns[$index] : false;
219 * A convenience function that returns the same thing as
220 * getNsText() except with '_' changed to ' ', useful for
225 function getFormattedNsText( $index ) {
226 $ns = $this->getNsText( $index );
227 return strtr($ns, '_', ' ');
231 * Get a namespace key by value, case insensitive.
232 * Only matches namespace names for the current language, not the
233 * canonical ones defined in Namespace.php.
235 * @param string $text
236 * @return mixed An integer if $text is a valid value otherwise false
238 function getLocalNsIndex( $text ) {
240 $lctext = $this->lc($text);
241 return isset( $this->mNamespaceIds
[$lctext] ) ?
$this->mNamespaceIds
[$lctext] : false;
245 * Get a namespace key by value, case insensitive. Canonical namespace
246 * names override custom ones defined for the current language.
248 * @param string $text
249 * @return mixed An integer if $text is a valid value otherwise false
251 function getNsIndex( $text ) {
253 $lctext = $this->lc($text);
254 if( ( $ns = Namespace::getCanonicalIndex( $lctext ) ) !== null ) return $ns;
255 return isset( $this->mNamespaceIds
[$lctext] ) ?
$this->mNamespaceIds
[$lctext] : false;
259 * short names for language variants used for language conversion links.
261 * @param string $code
264 function getVariantname( $code ) {
265 return $this->getMessageFromDB( "variantname-$code" );
268 function specialPage( $name ) {
269 $aliases = $this->getSpecialPageAliases();
270 if ( isset( $aliases[$name][0] ) ) {
271 $name = $aliases[$name][0];
273 return $this->getNsText(NS_SPECIAL
) . ':' . $name;
276 function getQuickbarSettings() {
278 $this->getMessage( 'qbsettings-none' ),
279 $this->getMessage( 'qbsettings-fixedleft' ),
280 $this->getMessage( 'qbsettings-fixedright' ),
281 $this->getMessage( 'qbsettings-floatingleft' ),
282 $this->getMessage( 'qbsettings-floatingright' )
286 function getSkinNames() {
288 return $this->skinNames
;
291 function getMathNames() {
293 return $this->mathNames
;
296 function getDatePreferences() {
298 return $this->datePreferences
;
301 function getDateFormats() {
303 return $this->dateFormats
;
306 function getDefaultDateFormat() {
308 return $this->defaultDateFormat
;
311 function getDatePreferenceMigrationMap() {
313 return $this->datePreferenceMigrationMap
;
316 function getDefaultUserOptionOverrides() {
318 return $this->defaultUserOptionOverrides
;
321 function getExtraUserToggles() {
323 return $this->extraUserToggles
;
326 function getUserToggle( $tog ) {
327 return $this->getMessageFromDB( "tog-$tog" );
331 * Get language names, indexed by code.
332 * If $customisedOnly is true, only returns codes with a messages file
334 public static function getLanguageNames( $customisedOnly = false ) {
335 global $wgLanguageNames;
336 if ( !$customisedOnly ) {
337 return $wgLanguageNames;
341 $messageFiles = glob( "$IP/languages/messages/Messages*.php" );
343 foreach ( $messageFiles as $file ) {
345 if( preg_match( '/Messages([A-Z][a-z_]+)\.php$/', $file, $m ) ) {
346 $code = str_replace( '_', '-', strtolower( $m[1] ) );
347 if ( isset( $wgLanguageNames[$code] ) ) {
348 $names[$code] = $wgLanguageNames[$code];
356 * Ugly hack to get a message maybe from the MediaWiki namespace, if this
357 * language object is the content or user language.
359 function getMessageFromDB( $msg ) {
360 global $wgContLang, $wgLang;
361 if ( $wgContLang->getCode() == $this->getCode() ) {
363 return wfMsgForContent( $msg );
364 } elseif ( $wgLang->getCode() == $this->getCode() ) {
366 return wfMsg( $msg );
368 # Neither, get from localisation
369 return $this->getMessage( $msg );
373 function getLanguageName( $code ) {
374 global $wgLanguageNames;
375 if ( ! array_key_exists( $code, $wgLanguageNames ) ) {
378 return $wgLanguageNames[$code];
381 function getMonthName( $key ) {
382 return $this->getMessageFromDB( self
::$mMonthMsgs[$key-1] );
385 function getMonthNameGen( $key ) {
386 return $this->getMessageFromDB( self
::$mMonthGenMsgs[$key-1] );
389 function getMonthAbbreviation( $key ) {
390 return $this->getMessageFromDB( self
::$mMonthAbbrevMsgs[$key-1] );
393 function getWeekdayName( $key ) {
394 return $this->getMessageFromDB( self
::$mWeekdayMsgs[$key-1] );
397 function getWeekdayAbbreviation( $key ) {
398 return $this->getMessageFromDB( self
::$mWeekdayAbbrevMsgs[$key-1] );
402 * Used by date() and time() to adjust the time output.
404 * @param int $ts the time in date('YmdHis') format
405 * @param mixed $tz adjust the time by this amount (default false,
406 * mean we get user timecorrection setting)
409 function userAdjust( $ts, $tz = false ) {
410 global $wgUser, $wgLocalTZoffset;
413 $tz = $wgUser->getOption( 'timecorrection' );
416 # minutes and hours differences:
421 # Global offset in minutes.
422 if( isset($wgLocalTZoffset) ) {
423 if( $wgLocalTZoffset >= 0 ) {
424 $hrDiff = floor($wgLocalTZoffset / 60);
426 $hrDiff = ceil($wgLocalTZoffset / 60);
428 $minDiff = $wgLocalTZoffset %
60;
430 } elseif ( strpos( $tz, ':' ) !== false ) {
431 $tzArray = explode( ':', $tz );
432 $hrDiff = intval($tzArray[0]);
433 $minDiff = intval($hrDiff < 0 ?
-$tzArray[1] : $tzArray[1]);
435 $hrDiff = intval( $tz );
438 # No difference ? Return time unchanged
439 if ( 0 == $hrDiff && 0 == $minDiff ) { return $ts; }
441 # Generate an adjusted date
443 (int)substr( $ts, 8, 2) ) +
$hrDiff, # Hours
444 (int)substr( $ts, 10, 2 ) +
$minDiff, # Minutes
445 (int)substr( $ts, 12, 2 ), # Seconds
446 (int)substr( $ts, 4, 2 ), # Month
447 (int)substr( $ts, 6, 2 ), # Day
448 (int)substr( $ts, 0, 4 ) ); #Year
449 return date( 'YmdHis', $t );
453 * This is a workalike of PHP's date() function, but with better
454 * internationalisation, a reduced set of format characters, and a better
457 * Supported format characters are dDjlNwzWFmMntLYyaAgGhHiscrU. See the
458 * PHP manual for definitions. There are a number of extensions, which
461 * xn Do not translate digits of the next numeric format character
462 * xN Toggle raw digit (xn) flag, stays set until explicitly unset
463 * xr Use roman numerals for the next numeric format character
465 * xg Genitive month name
467 * Characters enclosed in double quotes will be considered literal (with
468 * the quotes themselves removed). Unmatched quotes will be considered
469 * literal quotes. Example:
471 * "The month is" F => The month is January
474 * Backslash escaping is also supported.
476 * Input timestamp is assumed to be pre-normalized to the desired local
479 * @param string $format
480 * @param string $ts 14-character timestamp
484 function sprintfDate( $format, $ts ) {
490 for ( $p = 0; $p < strlen( $format ); $p++
) {
493 if ( $code == 'x' && $p < strlen( $format ) - 1 ) {
494 $code .= $format[++
$p];
505 $rawToggle = !$rawToggle;
511 $s .= $this->getMonthNameGen( substr( $ts, 4, 2 ) );
514 $num = substr( $ts, 6, 2 );
517 if ( !$unix ) $unix = wfTimestamp( TS_UNIX
, $ts );
518 $s .= $this->getWeekdayAbbreviation( gmdate( 'w', $unix ) +
1 );
521 $num = intval( substr( $ts, 6, 2 ) );
524 if ( !$unix ) $unix = wfTimestamp( TS_UNIX
, $ts );
525 $s .= $this->getWeekdayName( gmdate( 'w', $unix ) +
1 );
528 if ( !$unix ) $unix = wfTimestamp( TS_UNIX
, $ts );
529 $w = gmdate( 'w', $unix );
533 if ( !$unix ) $unix = wfTimestamp( TS_UNIX
, $ts );
534 $num = gmdate( 'w', $unix );
537 if ( !$unix ) $unix = wfTimestamp( TS_UNIX
, $ts );
538 $num = gmdate( 'z', $unix );
541 if ( !$unix ) $unix = wfTimestamp( TS_UNIX
, $ts );
542 $num = gmdate( 'W', $unix );
545 $s .= $this->getMonthName( substr( $ts, 4, 2 ) );
548 $num = substr( $ts, 4, 2 );
551 $s .= $this->getMonthAbbreviation( substr( $ts, 4, 2 ) );
554 $num = intval( substr( $ts, 4, 2 ) );
557 if ( !$unix ) $unix = wfTimestamp( TS_UNIX
, $ts );
558 $num = gmdate( 't', $unix );
561 if ( !$unix ) $unix = wfTimestamp( TS_UNIX
, $ts );
562 $num = gmdate( 'L', $unix );
565 $num = substr( $ts, 0, 4 );
568 $num = substr( $ts, 2, 2 );
571 $s .= intval( substr( $ts, 8, 2 ) ) < 12 ?
'am' : 'pm';
574 $s .= intval( substr( $ts, 8, 2 ) ) < 12 ?
'AM' : 'PM';
577 $h = substr( $ts, 8, 2 );
578 $num = $h %
12 ?
$h %
12 : 12;
581 $num = intval( substr( $ts, 8, 2 ) );
584 $h = substr( $ts, 8, 2 );
585 $num = sprintf( '%02d', $h %
12 ?
$h %
12 : 12 );
588 $num = substr( $ts, 8, 2 );
591 $num = substr( $ts, 10, 2 );
594 $num = substr( $ts, 12, 2 );
597 if ( !$unix ) $unix = wfTimestamp( TS_UNIX
, $ts );
598 $s .= gmdate( 'c', $unix );
601 if ( !$unix ) $unix = wfTimestamp( TS_UNIX
, $ts );
602 $s .= gmdate( 'r', $unix );
605 if ( !$unix ) $unix = wfTimestamp( TS_UNIX
, $ts );
610 if ( $p < strlen( $format ) - 1 ) {
618 if ( $p < strlen( $format ) - 1 ) {
619 $endQuote = strpos( $format, '"', $p +
1 );
620 if ( $endQuote === false ) {
621 # No terminating quote, assume literal "
624 $s .= substr( $format, $p +
1, $endQuote - $p - 1 );
628 # Quote at end of string, assume literal "
635 if ( $num !== false ) {
636 if ( $rawToggle ||
$raw ) {
639 } elseif ( $roman ) {
640 $s .= self
::romanNumeral( $num );
643 $s .= $this->formatNum( $num, true );
652 * Roman number formatting up to 3000
654 static function romanNumeral( $num ) {
655 static $table = array(
656 array( '', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X' ),
657 array( '', 'X', 'XX', 'XXX', 'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC', 'C' ),
658 array( '', 'C', 'CC', 'CCC', 'CD', 'D', 'DC', 'DCC', 'DCCC', 'CM', 'M' ),
659 array( '', 'M', 'MM', 'MMM' )
662 $num = intval( $num );
663 if ( $num > 3000 ||
$num <= 0 ) {
668 for ( $pow10 = 1000, $i = 3; $i >= 0; $pow10 /= 10, $i-- ) {
669 if ( $num >= $pow10 ) {
670 $s .= $table[$i][floor($num / $pow10)];
672 $num = $num %
$pow10;
678 * This is meant to be used by time(), date(), and timeanddate() to get
679 * the date preference they're supposed to use, it should be used in
683 * function timeanddate([...], $format = true) {
684 * $datePreference = $this->dateFormat($format);
689 * @param mixed $usePrefs: if true, the user's preference is used
690 * if false, the site/language default is used
691 * if int/string, assumed to be a format.
694 function dateFormat( $usePrefs = true ) {
697 if( is_bool( $usePrefs ) ) {
699 $datePreference = $wgUser->getDatePreference();
701 $options = User
::getDefaultOptions();
702 $datePreference = (string)$options['date'];
705 $datePreference = (string)$usePrefs;
709 if( $datePreference == '' ) {
713 return $datePreference;
718 * @param mixed $ts the time format which needs to be turned into a
719 * date('YmdHis') format with wfTimestamp(TS_MW,$ts)
720 * @param bool $adj whether to adjust the time output according to the
721 * user configured offset ($timecorrection)
722 * @param mixed $format true to use user's date format preference
723 * @param string $timecorrection the time offset as returned by
724 * validateTimeZone() in Special:Preferences
727 function date( $ts, $adj = false, $format = true, $timecorrection = false ) {
730 $ts = $this->userAdjust( $ts, $timecorrection );
733 $pref = $this->dateFormat( $format );
734 if( $pref == 'default' ||
!isset( $this->dateFormats
["$pref date"] ) ) {
735 $pref = $this->defaultDateFormat
;
737 return $this->sprintfDate( $this->dateFormats
["$pref date"], $ts );
742 * @param mixed $ts the time format which needs to be turned into a
743 * date('YmdHis') format with wfTimestamp(TS_MW,$ts)
744 * @param bool $adj whether to adjust the time output according to the
745 * user configured offset ($timecorrection)
746 * @param mixed $format true to use user's date format preference
747 * @param string $timecorrection the time offset as returned by
748 * validateTimeZone() in Special:Preferences
751 function time( $ts, $adj = false, $format = true, $timecorrection = false ) {
754 $ts = $this->userAdjust( $ts, $timecorrection );
757 $pref = $this->dateFormat( $format );
758 if( $pref == 'default' ||
!isset( $this->dateFormats
["$pref time"] ) ) {
759 $pref = $this->defaultDateFormat
;
761 return $this->sprintfDate( $this->dateFormats
["$pref time"], $ts );
766 * @param mixed $ts the time format which needs to be turned into a
767 * date('YmdHis') format with wfTimestamp(TS_MW,$ts)
768 * @param bool $adj whether to adjust the time output according to the
769 * user configured offset ($timecorrection)
771 * @param mixed $format what format to return, if it's false output the
772 * default one (default true)
773 * @param string $timecorrection the time offset as returned by
774 * validateTimeZone() in Special:Preferences
777 function timeanddate( $ts, $adj = false, $format = true, $timecorrection = false) {
780 $ts = wfTimestamp( TS_MW
, $ts );
783 $ts = $this->userAdjust( $ts, $timecorrection );
786 $pref = $this->dateFormat( $format );
787 if( $pref == 'default' ||
!isset( $this->dateFormats
["$pref both"] ) ) {
788 $pref = $this->defaultDateFormat
;
791 return $this->sprintfDate( $this->dateFormats
["$pref both"], $ts );
794 function getMessage( $key ) {
796 return isset( $this->messages
[$key] ) ?
$this->messages
[$key] : null;
799 function getAllMessages() {
801 return $this->messages
;
804 function iconv( $in, $out, $string ) {
805 # For most languages, this is a wrapper for iconv
806 return iconv( $in, $out . '//IGNORE', $string );
809 // callback functions for uc(), lc(), ucwords(), ucwordbreaks()
810 function ucwordbreaksCallbackAscii($matches){
811 return $this->ucfirst($matches[1]);
814 function ucwordbreaksCallbackMB($matches){
815 return mb_strtoupper($matches[0]);
818 function ucCallback($matches){
819 list( $wikiUpperChars ) = self
::getCaseMaps();
820 return strtr( $matches[1], $wikiUpperChars );
823 function lcCallback($matches){
824 list( , $wikiLowerChars ) = self
::getCaseMaps();
825 return strtr( $matches[1], $wikiLowerChars );
828 function ucwordsCallbackMB($matches){
829 return mb_strtoupper($matches[0]);
832 function ucwordsCallbackWiki($matches){
833 list( $wikiUpperChars ) = self
::getCaseMaps();
834 return strtr( $matches[0], $wikiUpperChars );
837 function ucfirst( $str ) {
838 return self
::uc( $str, true );
841 function uc( $str, $first = false ) {
842 if ( function_exists( 'mb_strtoupper' ) ) {
844 if ( self
::isMultibyte( $str ) ) {
845 return mb_strtoupper( mb_substr( $str, 0, 1 ) ) . mb_substr( $str, 1 );
847 return ucfirst( $str );
850 return self
::isMultibyte( $str ) ?
mb_strtoupper( $str ) : strtoupper( $str );
853 if ( self
::isMultibyte( $str ) ) {
854 list( $wikiUpperChars ) = $this->getCaseMaps();
855 $x = $first ?
'^' : '';
856 return preg_replace_callback(
857 "/$x([a-z]|[\\xc0-\\xff][\\x80-\\xbf]*)/",
858 array($this,"ucCallback"),
862 return $first ?
ucfirst( $str ) : strtoupper( $str );
867 function lcfirst( $str ) {
868 return self
::lc( $str, true );
871 function lc( $str, $first = false ) {
872 if ( function_exists( 'mb_strtolower' ) )
874 if ( self
::isMultibyte( $str ) )
875 return mb_strtolower( mb_substr( $str, 0, 1 ) ) . mb_substr( $str, 1 );
877 return strtolower( substr( $str, 0, 1 ) ) . substr( $str, 1 );
879 return self
::isMultibyte( $str ) ?
mb_strtolower( $str ) : strtolower( $str );
881 if ( self
::isMultibyte( $str ) ) {
882 list( , $wikiLowerChars ) = self
::getCaseMaps();
883 $x = $first ?
'^' : '';
884 return preg_replace_callback(
885 "/$x([A-Z]|[\\xc0-\\xff][\\x80-\\xbf]*)/",
886 array($this,"lcCallback"),
890 return $first ?
strtolower( substr( $str, 0, 1 ) ) . substr( $str, 1 ) : strtolower( $str );
893 function isMultibyte( $str ) {
894 return (bool)preg_match( '/[\x80-\xff]/', $str );
897 function ucwords($str) {
898 if ( self
::isMultibyte( $str ) ) {
899 $str = self
::lc($str);
901 // regexp to find first letter in each word (i.e. after each space)
902 $replaceRegexp = "/^([a-z]|[\\xc0-\\xff][\\x80-\\xbf]*)| ([a-z]|[\\xc0-\\xff][\\x80-\\xbf]*)/";
904 // function to use to capitalize a single char
905 if ( function_exists( 'mb_strtoupper' ) )
906 return preg_replace_callback(
908 array($this,"ucwordsCallbackMB"),
912 return preg_replace_callback(
914 array($this,"ucwordsCallbackWiki"),
919 return ucwords( strtolower( $str ) );
922 # capitalize words at word breaks
923 function ucwordbreaks($str){
924 if (self
::isMultibyte( $str ) ) {
925 $str = self
::lc($str);
927 // since \b doesn't work for UTF-8, we explicitely define word break chars
928 $breaks= "[ \-\(\)\}\{\.,\?!]";
930 // find first letter after word break
931 $replaceRegexp = "/^([a-z]|[\\xc0-\\xff][\\x80-\\xbf]*)|$breaks([a-z]|[\\xc0-\\xff][\\x80-\\xbf]*)/";
933 if ( function_exists( 'mb_strtoupper' ) )
934 return preg_replace_callback(
936 array($this,"ucwordbreaksCallbackMB"),
940 return preg_replace_callback(
942 array($this,"ucwordsCallbackWiki"),
947 return preg_replace_callback(
948 '/\b([\w\x80-\xff]+)\b/',
949 array($this,"ucwordbreaksCallbackAscii"),
954 * Return a case-folded representation of $s
956 * This is a representation such that caseFold($s1)==caseFold($s2) if $s1
957 * and $s2 are the same except for the case of their characters. It is not
958 * necessary for the value returned to make sense when displayed.
960 * Do *not* perform any other normalisation in this function. If a caller
961 * uses this function when it should be using a more general normalisation
962 * function, then fix the caller.
964 function caseFold( $s ) {
965 return $this->uc( $s );
968 function checkTitleEncoding( $s ) {
969 if( is_array( $s ) ) {
970 wfDebugDieBacktrace( 'Given array to checkTitleEncoding.' );
972 # Check for non-UTF-8 URLs
973 $ishigh = preg_match( '/[\x80-\xff]/', $s);
974 if(!$ishigh) return $s;
976 $isutf8 = preg_match( '/^([\x00-\x7f]|[\xc0-\xdf][\x80-\xbf]|' .
977 '[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xf7][\x80-\xbf]{3})+$/', $s );
978 if( $isutf8 ) return $s;
980 return $this->iconv( $this->fallback8bitEncoding(), "utf-8", $s );
983 function fallback8bitEncoding() {
985 return $this->fallback8bitEncoding
;
989 * Some languages have special punctuation to strip out
990 * or characters which need to be converted for MySQL's
991 * indexing to grok it correctly. Make such changes here.
996 function stripForSearch( $string ) {
998 if ( $wgDBtype != 'mysql' ) {
1002 # MySQL fulltext index doesn't grok utf-8, so we
1003 # need to fold cases and convert to hex
1005 wfProfileIn( __METHOD__
);
1006 if( function_exists( 'mb_strtolower' ) ) {
1007 $out = preg_replace(
1008 "/([\\xc0-\\xff][\\x80-\\xbf]*)/e",
1009 "'U8' . bin2hex( \"$1\" )",
1010 mb_strtolower( $string ) );
1012 list( , $wikiLowerChars ) = self
::getCaseMaps();
1013 $out = preg_replace(
1014 "/([\\xc0-\\xff][\\x80-\\xbf]*)/e",
1015 "'U8' . bin2hex( strtr( \"\$1\", \$wikiLowerChars ) )",
1018 wfProfileOut( __METHOD__
);
1022 function convertForSearchResult( $termsArray ) {
1023 # some languages, e.g. Chinese, need to do a conversion
1024 # in order for search results to be displayed correctly
1029 * Get the first character of a string.
1034 function firstChar( $s ) {
1036 preg_match( '/^([\x00-\x7f]|[\xc0-\xdf][\x80-\xbf]|' .
1037 '[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xf7][\x80-\xbf]{3})/', $s, $matches);
1039 return isset( $matches[1] ) ?
$matches[1] : "";
1042 function initEncoding() {
1043 # Some languages may have an alternate char encoding option
1044 # (Esperanto X-coding, Japanese furigana conversion, etc)
1045 # If this language is used as the primary content language,
1046 # an override to the defaults can be set here on startup.
1049 function recodeForEdit( $s ) {
1050 # For some languages we'll want to explicitly specify
1051 # which characters make it into the edit box raw
1052 # or are converted in some way or another.
1053 # Note that if wgOutputEncoding is different from
1054 # wgInputEncoding, this text will be further converted
1055 # to wgOutputEncoding.
1056 global $wgEditEncoding;
1057 if( $wgEditEncoding == '' or
1058 $wgEditEncoding == 'UTF-8' ) {
1061 return $this->iconv( 'UTF-8', $wgEditEncoding, $s );
1065 function recodeInput( $s ) {
1066 # Take the previous into account.
1067 global $wgEditEncoding;
1068 if($wgEditEncoding != "") {
1069 $enc = $wgEditEncoding;
1073 if( $enc == 'UTF-8' ) {
1076 return $this->iconv( $enc, 'UTF-8', $s );
1081 * For right-to-left language support
1091 * A hidden direction mark (LRM or RLM), depending on the language direction
1095 function getDirMark() {
1096 return $this->isRTL() ?
"\xE2\x80\x8F" : "\xE2\x80\x8E";
1100 * An arrow, depending on the language direction
1104 function getArrow() {
1105 return $this->isRTL() ?
'←' : '→';
1109 * To allow "foo[[bar]]" to extend the link over the whole word "foobar"
1113 function linkPrefixExtension() {
1115 return $this->linkPrefixExtension
;
1118 function &getMagicWords() {
1120 return $this->magicWords
;
1123 # Fill a MagicWord object with data from here
1124 function getMagic( &$mw ) {
1125 if ( !isset( $this->mMagicExtensions
) ) {
1126 $this->mMagicExtensions
= array();
1127 wfRunHooks( 'LanguageGetMagic', array( &$this->mMagicExtensions
, $this->getCode() ) );
1129 if ( isset( $this->mMagicExtensions
[$mw->mId
] ) ) {
1130 $rawEntry = $this->mMagicExtensions
[$mw->mId
];
1132 $magicWords =& $this->getMagicWords();
1133 if ( isset( $magicWords[$mw->mId
] ) ) {
1134 $rawEntry = $magicWords[$mw->mId
];
1136 # Fall back to English if local list is incomplete
1137 $magicWords =& Language
::getMagicWords();
1138 $rawEntry = $magicWords[$mw->mId
];
1142 if( !is_array( $rawEntry ) ) {
1143 error_log( "\"$rawEntry\" is not a valid magic thingie for \"$mw->mId\"" );
1145 $mw->mCaseSensitive
= $rawEntry[0];
1146 $mw->mSynonyms
= array_slice( $rawEntry, 1 );
1150 * Get special page names, as an associative array
1151 * case folded alias => real name
1153 function getSpecialPageAliases() {
1155 if ( !isset( $this->mExtendedSpecialPageAliases
) ) {
1156 $this->mExtendedSpecialPageAliases
= $this->specialPageAliases
;
1157 wfRunHooks( 'LangugeGetSpecialPageAliases',
1158 array( &$this->mExtendedSpecialPageAliases
, $this->getCode() ) );
1160 return $this->mExtendedSpecialPageAliases
;
1164 * Italic is unsuitable for some languages
1168 * @param string $text The text to be emphasized.
1171 function emphasize( $text ) {
1172 return "<em>$text</em>";
1176 * Normally we output all numbers in plain en_US style, that is
1177 * 293,291.235 for twohundredninetythreethousand-twohundredninetyone
1178 * point twohundredthirtyfive. However this is not sutable for all
1179 * languages, some such as Pakaran want ੨੯੩,੨੯੫.੨੩੫ and others such as
1180 * Icelandic just want to use commas instead of dots, and dots instead
1181 * of commas like "293.291,235".
1183 * An example of this function being called:
1185 * wfMsg( 'message', $wgLang->formatNum( $num ) )
1188 * See LanguageGu.php for the Gujarati implementation and
1189 * LanguageIs.php for the , => . and . => , implementation.
1191 * @todo check if it's viable to use localeconv() for the decimal
1194 * @param mixed $number the string to be formatted, should be an integer or
1195 * a floating point number.
1196 * @param bool $nocommafy Set to true for special numbers like dates
1199 function formatNum( $number, $nocommafy = false ) {
1200 global $wgTranslateNumerals;
1202 $number = $this->commafy($number);
1203 $s = $this->separatorTransformTable();
1204 if (!is_null($s)) { $number = strtr($number, $s); }
1207 if ($wgTranslateNumerals) {
1208 $s = $this->digitTransformTable();
1209 if (!is_null($s)) { $number = strtr($number, $s); }
1215 function parseFormattedNumber( $number ) {
1216 $s = $this->digitTransformTable();
1217 if (!is_null($s)) { $number = strtr($number, array_flip($s)); }
1219 $s = $this->separatorTransformTable();
1220 if (!is_null($s)) { $number = strtr($number, array_flip($s)); }
1222 $number = strtr( $number, array (',' => '') );
1227 * Adds commas to a given number
1232 function commafy($_) {
1233 return strrev((string)preg_replace('/(\d{3})(?=\d)(?!\d*\.)/','$1,',strrev($_)));
1236 function digitTransformTable() {
1238 return $this->digitTransformTable
;
1241 function separatorTransformTable() {
1243 return $this->separatorTransformTable
;
1248 * For the credit list in includes/Credits.php (action=credits)
1253 function listToText( $l ) {
1256 for ($i = $m; $i >= 0; $i--) {
1259 } else if ($i == $m - 1) {
1260 $s = $l[$i] . ' ' . $this->getMessageFromDB( 'and' ) . ' ' . $s;
1262 $s = $l[$i] . ', ' . $s;
1268 # Crop a string from the beginning or end to a certain number of bytes.
1269 # (Bytes are used because our storage has limited byte lengths for some
1270 # columns in the database.) Multibyte charsets will need to make sure that
1271 # only whole characters are included!
1273 # $length does not include the optional ellipsis.
1274 # If $length is negative, snip from the beginning
1275 function truncate( $string, $length, $ellipsis = "" ) {
1276 if( $length == 0 ) {
1279 if ( strlen( $string ) <= abs( $length ) ) {
1283 $string = substr( $string, 0, $length );
1284 $char = ord( $string[strlen( $string ) - 1] );
1286 if ($char >= 0xc0) {
1287 # We got the first byte only of a multibyte char; remove it.
1288 $string = substr( $string, 0, -1 );
1289 } elseif( $char >= 0x80 &&
1290 preg_match( '/^(.*)(?:[\xe0-\xef][\x80-\xbf]|' .
1291 '[\xf0-\xf7][\x80-\xbf]{1,2})$/', $string, $m ) ) {
1292 # We chopped in the middle of a character; remove it
1295 return $string . $ellipsis;
1297 $string = substr( $string, $length );
1298 $char = ord( $string[0] );
1299 if( $char >= 0x80 && $char < 0xc0 ) {
1300 # We chopped in the middle of a character; remove the whole thing
1301 $string = preg_replace( '/^[\x80-\xbf]+/', '', $string );
1303 return $ellipsis . $string;
1308 * Grammatical transformations, needed for inflected languages
1309 * Invoked by putting {{grammar:case|word}} in a message
1311 * @param string $word
1312 * @param string $case
1315 function convertGrammar( $word, $case ) {
1316 global $wgGrammarForms;
1317 if ( isset($wgGrammarForms['en'][$case][$word]) ) {
1318 return $wgGrammarForms['en'][$case][$word];
1324 * Plural form transformations, needed for some languages.
1325 * For example, where are 3 form of plural in Russian and Polish,
1326 * depending on "count mod 10". See [[w:Plural]]
1327 * For English it is pretty simple.
1329 * Invoked by putting {{plural:count|wordform1|wordform2}}
1330 * or {{plural:count|wordform1|wordform2|wordform3}}
1332 * Example: {{plural:{{NUMBEROFARTICLES}}|article|articles}}
1334 * @param integer $count
1335 * @param string $wordform1
1336 * @param string $wordform2
1337 * @param string $wordform3 (optional)
1338 * @param string $wordform4 (optional)
1339 * @param string $wordform5 (optional)
1342 function convertPlural( $count, $w1, $w2, $w3, $w4, $w5) {
1343 return ( $count == '1' ||
$count == '-1' ) ?
$w1 : $w2;
1347 * For translaing of expiry times
1348 * @param string The validated block time in English
1349 * @param $forContent, avoid html?
1350 * @return Somehow translated block time
1351 * @see LanguageFi.php for example implementation
1353 function translateBlockExpiry( $str, $forContent=false ) {
1355 $scBlockExpiryOptions = $this->getMessageFromDB( 'ipboptions' );
1357 if ( $scBlockExpiryOptions == '-') {
1361 foreach (explode(',', $scBlockExpiryOptions) as $option) {
1362 if ( strpos($option, ":") === false )
1364 list($show, $value) = explode(":", $option);
1365 if ( strcmp ( $str, $value) == 0 ) {
1367 return htmlspecialchars($str) . htmlspecialchars( trim( $show ) );
1369 return '<span title="' . htmlspecialchars($str). '">' . htmlspecialchars( trim( $show ) ) . '</span>';
1377 * languages like Chinese need to be segmented in order for the diff
1380 * @param string $text
1383 function segmentForDiff( $text ) {
1388 * and unsegment to show the result
1390 * @param string $text
1393 function unsegmentForDiff( $text ) {
1397 # convert text to different variants of a language.
1398 function convert( $text, $isTitle = false) {
1399 return $this->mConverter
->convert($text, $isTitle);
1402 # Convert text from within Parser
1403 function parserConvert( $text, &$parser ) {
1404 return $this->mConverter
->parserConvert( $text, $parser );
1407 # Check if this is a language with variants
1408 function hasVariants(){
1409 return sizeof($this->getVariants())>1;
1412 # Put custom tags (e.g. -{ }-) around math to prevent conversion
1413 function armourMath($text){
1414 return $this->mConverter
->armourMath($text);
1419 * Perform output conversion on a string, and encode for safe HTML output.
1420 * @param string $text
1421 * @param bool $isTitle -- wtf?
1423 * @todo this should get integrated somewhere sane
1425 function convertHtml( $text, $isTitle = false ) {
1426 return htmlspecialchars( $this->convert( $text, $isTitle ) );
1429 function convertCategoryKey( $key ) {
1430 return $this->mConverter
->convertCategoryKey( $key );
1434 * get the list of variants supported by this langauge
1435 * see sample implementation in LanguageZh.php
1437 * @return array an array of language codes
1439 function getVariants() {
1440 return $this->mConverter
->getVariants();
1444 function getPreferredVariant( $fromUser = true ) {
1445 return $this->mConverter
->getPreferredVariant( $fromUser );
1449 * if a language supports multiple variants, it is
1450 * possible that non-existing link in one variant
1451 * actually exists in another variant. this function
1452 * tries to find it. See e.g. LanguageZh.php
1454 * @param string $link the name of the link
1455 * @param mixed $nt the title object of the link
1456 * @return null the input parameters may be modified upon return
1458 function findVariantLink( &$link, &$nt ) {
1459 $this->mConverter
->findVariantLink($link, $nt);
1463 * If a language supports multiple variants, converts text
1464 * into an array of all possible variants of the text:
1465 * 'variant' => text in that variant
1468 function convertLinkToAllVariants($text){
1469 return $this->mConverter
->convertLinkToAllVariants($text);
1474 * returns language specific options used by User::getPageRenderHash()
1475 * for example, the preferred language variant
1480 function getExtraHashOptions() {
1481 return $this->mConverter
->getExtraHashOptions();
1485 * for languages that support multiple variants, the title of an
1486 * article may be displayed differently in different variants. this
1487 * function returns the apporiate title defined in the body of the article.
1491 function getParsedTitle() {
1492 return $this->mConverter
->getParsedTitle();
1496 * Enclose a string with the "no conversion" tag. This is used by
1497 * various functions in the Parser
1499 * @param string $text text to be tagged for no conversion
1500 * @return string the tagged text
1502 function markNoConversion( $text, $noParse=false ) {
1503 return $this->mConverter
->markNoConversion( $text, $noParse );
1507 * A regular expression to match legal word-trailing characters
1508 * which should be merged onto a link of the form [[foo]]bar.
1513 function linkTrail() {
1515 return $this->linkTrail
;
1518 function getLangObj() {
1523 * Get the RFC 3066 code for this language object
1525 function getCode() {
1526 return $this->mCode
;
1529 function setCode( $code ) {
1530 $this->mCode
= $code;
1533 static function getFileName( $prefix = 'Language', $code, $suffix = '.php' ) {
1534 return $prefix . str_replace( '-', '_', ucfirst( $code ) ) . $suffix;
1537 static function getMessagesFileName( $code ) {
1539 return self
::getFileName( "$IP/languages/messages/Messages", $code, '.php' );
1542 static function getClassFileName( $code ) {
1544 return self
::getFileName( "$IP/languages/classes/Language", $code, '.php' );
1547 static function getLocalisationArray( $code, $disableCache = false ) {
1548 self
::loadLocalisation( $code, $disableCache );
1549 return self
::$mLocalisationCache[$code];
1553 * Load localisation data for a given code into the static cache
1555 * @return array Dependencies, map of filenames to mtimes
1557 static function loadLocalisation( $code, $disableCache = false ) {
1558 static $recursionGuard = array();
1562 throw new MWException( "Invalid language code requested" );
1565 if ( !$disableCache ) {
1566 # Try the per-process cache
1567 if ( isset( self
::$mLocalisationCache[$code] ) ) {
1568 return self
::$mLocalisationCache[$code]['deps'];
1571 wfProfileIn( __METHOD__
);
1573 # Try the serialized directory
1574 $cache = wfGetPrecompiledData( self
::getFileName( "Messages", $code, '.ser' ) );
1576 self
::$mLocalisationCache[$code] = $cache;
1577 wfDebug( "Language::loadLocalisation(): got localisation for $code from precompiled data file\n" );
1578 wfProfileOut( __METHOD__
);
1579 return self
::$mLocalisationCache[$code]['deps'];
1582 # Try the global cache
1583 $memcKey = wfMemcKey('localisation', $code );
1584 $cache = $wgMemc->get( $memcKey );
1586 # Check file modification times
1587 foreach ( $cache['deps'] as $file => $mtime ) {
1588 if ( !file_exists( $file ) ||
filemtime( $file ) > $mtime ) {
1592 if ( self
::isLocalisationOutOfDate( $cache ) ) {
1593 $wgMemc->delete( $memcKey );
1595 wfDebug( "Language::loadLocalisation(): localisation cache for $code had expired due to update of $file\n" );
1597 self
::$mLocalisationCache[$code] = $cache;
1598 wfDebug( "Language::loadLocalisation(): got localisation for $code from cache\n" );
1599 wfProfileOut( __METHOD__
);
1600 return $cache['deps'];
1604 wfProfileIn( __METHOD__
);
1607 # Default fallback, may be overridden when the messages file is included
1608 if ( $code != 'en' ) {
1614 # Load the primary localisation from the source file
1615 $filename = self
::getMessagesFileName( $code );
1616 if ( !file_exists( $filename ) ) {
1617 wfDebug( "Language::loadLocalisation(): no localisation file for $code, using implicit fallback to en\n" );
1621 $deps = array( $filename => filemtime( $filename ) );
1622 require( $filename );
1623 $cache = compact( self
::$mLocalisationKeys );
1624 wfDebug( "Language::loadLocalisation(): got localisation for $code from source\n" );
1627 if ( !empty( $fallback ) ) {
1628 # Load the fallback localisation, with a circular reference guard
1629 if ( isset( $recursionGuard[$code] ) ) {
1630 throw new MWException( "Error: Circular fallback reference in language code $code" );
1632 $recursionGuard[$code] = true;
1633 $newDeps = self
::loadLocalisation( $fallback, $disableCache );
1634 unset( $recursionGuard[$code] );
1636 $secondary = self
::$mLocalisationCache[$fallback];
1637 $deps = array_merge( $deps, $newDeps );
1639 # Merge the fallback localisation with the current localisation
1640 foreach ( self
::$mLocalisationKeys as $key ) {
1641 if ( isset( $cache[$key] ) ) {
1642 if ( isset( $secondary[$key] ) ) {
1643 if ( in_array( $key, self
::$mMergeableMapKeys ) ) {
1644 $cache[$key] = $cache[$key] +
$secondary[$key];
1645 } elseif ( in_array( $key, self
::$mMergeableListKeys ) ) {
1646 $cache[$key] = array_merge( $secondary[$key], $cache[$key] );
1647 } elseif ( in_array( $key, self
::$mMergeableAliasListKeys ) ) {
1648 $cache[$key] = array_merge_recursive( $cache[$key], $secondary[$key] );
1652 $cache[$key] = $secondary[$key];
1656 # Merge bookstore lists if requested
1657 if ( !empty( $cache['bookstoreList']['inherit'] ) ) {
1658 $cache['bookstoreList'] = array_merge( $cache['bookstoreList'], $secondary['bookstoreList'] );
1660 if ( isset( $cache['bookstoreList']['inherit'] ) ) {
1661 unset( $cache['bookstoreList']['inherit'] );
1665 # Add dependencies to the cache entry
1666 $cache['deps'] = $deps;
1668 # Replace spaces with underscores in namespace names
1669 $cache['namespaceNames'] = str_replace( ' ', '_', $cache['namespaceNames'] );
1671 # Save to both caches
1672 self
::$mLocalisationCache[$code] = $cache;
1673 if ( !$disableCache ) {
1674 $wgMemc->set( $memcKey, $cache );
1677 wfProfileOut( __METHOD__
);
1682 * Test if a given localisation cache is out of date with respect to the
1683 * source Messages files. This is done automatically for the global cache
1684 * in $wgMemc, but is only done on certain occasions for the serialized
1687 * @param $cache mixed Either a language code or a cache array
1689 static function isLocalisationOutOfDate( $cache ) {
1690 if ( !is_array( $cache ) ) {
1691 self
::loadLocalisation( $cache );
1692 $cache = self
::$mLocalisationCache[$cache];
1695 foreach ( $cache['deps'] as $file => $mtime ) {
1696 if ( !file_exists( $file ) ||
filemtime( $file ) > $mtime ) {
1705 * Get the fallback for a given language
1707 static function getFallbackFor( $code ) {
1708 self
::loadLocalisation( $code );
1709 return self
::$mLocalisationCache[$code]['fallback'];
1713 * Get all messages for a given language
1715 static function getMessagesFor( $code ) {
1716 self
::loadLocalisation( $code );
1717 return self
::$mLocalisationCache[$code]['messages'];
1721 * Get a message for a given language
1723 static function getMessageFor( $key, $code ) {
1724 self
::loadLocalisation( $code );
1725 return isset( self
::$mLocalisationCache[$code]['messages'][$key] ) ? self
::$mLocalisationCache[$code]['messages'][$key] : null;
1729 * Load localisation data for this object
1732 if ( !$this->mLoaded
) {
1733 self
::loadLocalisation( $this->getCode() );
1734 $cache =& self
::$mLocalisationCache[$this->getCode()];
1735 foreach ( self
::$mLocalisationKeys as $key ) {
1736 $this->$key = $cache[$key];
1738 $this->mLoaded
= true;
1740 $this->fixUpSettings();
1745 * Do any necessary post-cache-load settings adjustment
1747 function fixUpSettings() {
1748 global $wgExtraNamespaces, $wgMetaNamespace, $wgMetaNamespaceTalk,
1749 $wgNamespaceAliases, $wgAmericanDates;
1750 wfProfileIn( __METHOD__
);
1751 if ( $wgExtraNamespaces ) {
1752 $this->namespaceNames
= $wgExtraNamespaces +
$this->namespaceNames
;
1755 $this->namespaceNames
[NS_PROJECT
] = $wgMetaNamespace;
1756 if ( $wgMetaNamespaceTalk ) {
1757 $this->namespaceNames
[NS_PROJECT_TALK
] = $wgMetaNamespaceTalk;
1759 $talk = $this->namespaceNames
[NS_PROJECT_TALK
];
1760 $talk = str_replace( '$1', $wgMetaNamespace, $talk );
1762 # Allow grammar transformations
1763 # Allowing full message-style parsing would make simple requests
1764 # such as action=raw much more expensive than they need to be.
1765 # This will hopefully cover most cases.
1766 $talk = preg_replace_callback( '/{{grammar:(.*?)\|(.*?)}}/i',
1767 array( &$this, 'replaceGrammarInNamespace' ), $talk );
1768 $talk = str_replace( ' ', '_', $talk );
1769 $this->namespaceNames
[NS_PROJECT_TALK
] = $talk;
1772 # The above mixing may leave namespaces out of canonical order.
1773 # Re-order by namespace ID number...
1774 ksort( $this->namespaceNames
);
1776 # Put namespace names and aliases into a hashtable.
1777 # If this is too slow, then we should arrange it so that it is done
1778 # before caching. The catch is that at pre-cache time, the above
1779 # class-specific fixup hasn't been done.
1780 $this->mNamespaceIds
= array();
1781 foreach ( $this->namespaceNames
as $index => $name ) {
1782 $this->mNamespaceIds
[$this->lc($name)] = $index;
1784 if ( $this->namespaceAliases
) {
1785 foreach ( $this->namespaceAliases
as $name => $index ) {
1786 $this->mNamespaceIds
[$this->lc($name)] = $index;
1789 if ( $wgNamespaceAliases ) {
1790 foreach ( $wgNamespaceAliases as $name => $index ) {
1791 $this->mNamespaceIds
[$this->lc($name)] = $index;
1795 if ( $this->defaultDateFormat
== 'dmy or mdy' ) {
1796 $this->defaultDateFormat
= $wgAmericanDates ?
'mdy' : 'dmy';
1798 wfProfileOut( __METHOD__
);
1801 function replaceGrammarInNamespace( $m ) {
1802 return $this->convertGrammar( trim( $m[2] ), trim( $m[1] ) );
1805 static function getCaseMaps() {
1806 static $wikiUpperChars, $wikiLowerChars;
1807 if ( isset( $wikiUpperChars ) ) {
1808 return array( $wikiUpperChars, $wikiLowerChars );
1811 wfProfileIn( __METHOD__
);
1812 $arr = wfGetPrecompiledData( 'Utf8Case.ser' );
1813 if ( $arr === false ) {
1814 throw new MWException(
1815 "Utf8Case.ser is missing, please run \"make\" in the serialized directory\n" );
1818 wfProfileOut( __METHOD__
);
1819 return array( $wikiUpperChars, $wikiLowerChars );