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 $hrDiff = $wgLocalTZoffset %
60;
424 $minDiff = $wgLocalTZoffset - ($hrDiff * 60);
426 } elseif ( strpos( $tz, ':' ) !== false ) {
427 $tzArray = explode( ':', $tz );
428 $hrDiff = intval($tzArray[0]);
429 $minDiff = intval($hrDiff < 0 ?
-$tzArray[1] : $tzArray[1]);
431 $hrDiff = intval( $tz );
434 # No difference ? Return time unchanged
435 if ( 0 == $hrDiff && 0 == $minDiff ) { return $ts; }
437 # Generate an adjusted date
439 (int)substr( $ts, 8, 2) ) +
$hrDiff, # Hours
440 (int)substr( $ts, 10, 2 ) +
$minDiff, # Minutes
441 (int)substr( $ts, 12, 2 ), # Seconds
442 (int)substr( $ts, 4, 2 ), # Month
443 (int)substr( $ts, 6, 2 ), # Day
444 (int)substr( $ts, 0, 4 ) ); #Year
445 return date( 'YmdHis', $t );
449 * This is a workalike of PHP's date() function, but with better
450 * internationalisation, a reduced set of format characters, and a better
453 * Supported format characters are dDjlNwzWFmMntLYyaAgGhHiscrU. See the
454 * PHP manual for definitions. There are a number of extensions, which
457 * xn Do not translate digits of the next numeric format character
458 * xN Toggle raw digit (xn) flag, stays set until explicitly unset
459 * xr Use roman numerals for the next numeric format character
461 * xg Genitive month name
463 * Characters enclosed in double quotes will be considered literal (with
464 * the quotes themselves removed). Unmatched quotes will be considered
465 * literal quotes. Example:
467 * "The month is" F => The month is January
470 * Backslash escaping is also supported.
472 * @param string $format
473 * @param string $ts 14-character timestamp
477 function sprintfDate( $format, $ts ) {
483 for ( $p = 0; $p < strlen( $format ); $p++
) {
486 if ( $code == 'x' && $p < strlen( $format ) - 1 ) {
487 $code .= $format[++
$p];
498 $rawToggle = !$rawToggle;
504 $s .= $this->getMonthNameGen( substr( $ts, 4, 2 ) );
507 $num = substr( $ts, 6, 2 );
510 if ( !$unix ) $unix = wfTimestamp( TS_UNIX
, $ts );
511 $s .= $this->getWeekdayAbbreviation( date( 'w', $unix ) +
1 );
514 $num = intval( substr( $ts, 6, 2 ) );
517 if ( !$unix ) $unix = wfTimestamp( TS_UNIX
, $ts );
518 $s .= $this->getWeekdayName( date( 'w', $unix ) +
1 );
521 if ( !$unix ) $unix = wfTimestamp( TS_UNIX
, $ts );
522 $w = date( 'w', $unix );
526 if ( !$unix ) $unix = wfTimestamp( TS_UNIX
, $ts );
527 $num = date( 'w', $unix );
530 if ( !$unix ) $unix = wfTimestamp( TS_UNIX
, $ts );
531 $num = date( 'z', $unix );
534 if ( !$unix ) $unix = wfTimestamp( TS_UNIX
, $ts );
535 $num = date( 'W', $unix );
538 $s .= $this->getMonthName( substr( $ts, 4, 2 ) );
541 $num = substr( $ts, 4, 2 );
544 $s .= $this->getMonthAbbreviation( substr( $ts, 4, 2 ) );
547 $num = intval( substr( $ts, 4, 2 ) );
550 if ( !$unix ) $unix = wfTimestamp( TS_UNIX
, $ts );
551 $num = date( 't', $unix );
554 if ( !$unix ) $unix = wfTimestamp( TS_UNIX
, $ts );
555 $num = date( 'L', $unix );
558 $num = substr( $ts, 0, 4 );
561 $num = substr( $ts, 2, 2 );
564 $s .= intval( substr( $ts, 8, 2 ) ) < 12 ?
'am' : 'pm';
567 $s .= intval( substr( $ts, 8, 2 ) ) < 12 ?
'AM' : 'PM';
570 $h = substr( $ts, 8, 2 );
571 $num = $h %
12 ?
$h %
12 : 12;
574 $num = intval( substr( $ts, 8, 2 ) );
577 $h = substr( $ts, 8, 2 );
578 $num = sprintf( '%02d', $h %
12 ?
$h %
12 : 12 );
581 $num = substr( $ts, 8, 2 );
584 $num = substr( $ts, 10, 2 );
587 $num = substr( $ts, 12, 2 );
590 if ( !$unix ) $unix = wfTimestamp( TS_UNIX
, $ts );
591 $s .= date( 'c', $unix );
594 if ( !$unix ) $unix = wfTimestamp( TS_UNIX
, $ts );
595 $s .= date( 'r', $unix );
598 if ( !$unix ) $unix = wfTimestamp( TS_UNIX
, $ts );
603 if ( $p < strlen( $format ) - 1 ) {
611 if ( $p < strlen( $format ) - 1 ) {
612 $endQuote = strpos( $format, '"', $p +
1 );
613 if ( $endQuote === false ) {
614 # No terminating quote, assume literal "
617 $s .= substr( $format, $p +
1, $endQuote - $p - 1 );
621 # Quote at end of string, assume literal "
628 if ( $num !== false ) {
629 if ( $rawToggle ||
$raw ) {
632 } elseif ( $roman ) {
633 $s .= self
::romanNumeral( $num );
636 $s .= $this->formatNum( $num, true );
645 * Roman number formatting up to 3000
647 static function romanNumeral( $num ) {
648 static $table = array(
649 array( '', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X' ),
650 array( '', 'X', 'XX', 'XXX', 'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC', 'C' ),
651 array( '', 'C', 'CC', 'CCC', 'CD', 'D', 'DC', 'DCC', 'DCCC', 'CM', 'M' ),
652 array( '', 'M', 'MM', 'MMM' )
655 $num = intval( $num );
656 if ( $num > 3000 ||
$num <= 0 ) {
661 for ( $pow10 = 1000, $i = 3; $i >= 0; $pow10 /= 10, $i-- ) {
662 if ( $num >= $pow10 ) {
663 $s .= $table[$i][floor($num / $pow10)];
665 $num = $num %
$pow10;
671 * This is meant to be used by time(), date(), and timeanddate() to get
672 * the date preference they're supposed to use, it should be used in
676 * function timeanddate([...], $format = true) {
677 * $datePreference = $this->dateFormat($format);
682 * @param mixed $usePrefs: if true, the user's preference is used
683 * if false, the site/language default is used
684 * if int/string, assumed to be a format.
687 function dateFormat( $usePrefs = true ) {
690 if( is_bool( $usePrefs ) ) {
692 $datePreference = $wgUser->getDatePreference();
694 $options = User
::getDefaultOptions();
695 $datePreference = (string)$options['date'];
698 $datePreference = (string)$usePrefs;
702 if( $datePreference == '' ) {
706 return $datePreference;
711 * @param mixed $ts the time format which needs to be turned into a
712 * date('YmdHis') format with wfTimestamp(TS_MW,$ts)
713 * @param bool $adj whether to adjust the time output according to the
714 * user configured offset ($timecorrection)
715 * @param mixed $format true to use user's date format preference
716 * @param string $timecorrection the time offset as returned by
717 * validateTimeZone() in Special:Preferences
720 function date( $ts, $adj = false, $format = true, $timecorrection = false ) {
723 $ts = $this->userAdjust( $ts, $timecorrection );
726 $pref = $this->dateFormat( $format );
727 if( $pref == 'default' ||
!isset( $this->dateFormats
["$pref date"] ) ) {
728 $pref = $this->defaultDateFormat
;
730 return $this->sprintfDate( $this->dateFormats
["$pref date"], $ts );
735 * @param mixed $ts the time format which needs to be turned into a
736 * date('YmdHis') format with wfTimestamp(TS_MW,$ts)
737 * @param bool $adj whether to adjust the time output according to the
738 * user configured offset ($timecorrection)
739 * @param mixed $format true to use user's date format preference
740 * @param string $timecorrection the time offset as returned by
741 * validateTimeZone() in Special:Preferences
744 function time( $ts, $adj = false, $format = true, $timecorrection = false ) {
747 $ts = $this->userAdjust( $ts, $timecorrection );
750 $pref = $this->dateFormat( $format );
751 if( $pref == 'default' ||
!isset( $this->dateFormats
["$pref time"] ) ) {
752 $pref = $this->defaultDateFormat
;
754 return $this->sprintfDate( $this->dateFormats
["$pref time"], $ts );
759 * @param mixed $ts the time format which needs to be turned into a
760 * date('YmdHis') format with wfTimestamp(TS_MW,$ts)
761 * @param bool $adj whether to adjust the time output according to the
762 * user configured offset ($timecorrection)
764 * @param mixed $format what format to return, if it's false output the
765 * default one (default true)
766 * @param string $timecorrection the time offset as returned by
767 * validateTimeZone() in Special:Preferences
770 function timeanddate( $ts, $adj = false, $format = true, $timecorrection = false) {
773 $ts = wfTimestamp( TS_MW
, $ts );
776 $ts = $this->userAdjust( $ts, $timecorrection );
779 $pref = $this->dateFormat( $format );
780 if( $pref == 'default' ||
!isset( $this->dateFormats
["$pref both"] ) ) {
781 $pref = $this->defaultDateFormat
;
784 return $this->sprintfDate( $this->dateFormats
["$pref both"], $ts );
787 function getMessage( $key ) {
789 return isset( $this->messages
[$key] ) ?
$this->messages
[$key] : null;
792 function getAllMessages() {
794 return $this->messages
;
797 function iconv( $in, $out, $string ) {
798 # For most languages, this is a wrapper for iconv
799 return iconv( $in, $out . '//IGNORE', $string );
802 // callback functions for uc(), lc(), ucwords(), ucwordbreaks()
803 function ucwordbreaksCallbackAscii($matches){
804 return $this->ucfirst($matches[1]);
807 function ucwordbreaksCallbackMB($matches){
808 return mb_strtoupper($matches[0]);
811 function ucCallback($matches){
812 list( $wikiUpperChars ) = self
::getCaseMaps();
813 return strtr( $matches[1], $wikiUpperChars );
816 function lcCallback($matches){
817 list( , $wikiLowerChars ) = self
::getCaseMaps();
818 return strtr( $matches[1], $wikiLowerChars );
821 function ucwordsCallbackMB($matches){
822 return mb_strtoupper($matches[0]);
825 function ucwordsCallbackWiki($matches){
826 list( $wikiUpperChars ) = self
::getCaseMaps();
827 return strtr( $matches[0], $wikiUpperChars );
830 function ucfirst( $str ) {
831 return self
::uc( $str, true );
834 function uc( $str, $first = false ) {
835 if ( function_exists( 'mb_strtoupper' ) ) {
837 if ( self
::isMultibyte( $str ) ) {
838 return mb_strtoupper( mb_substr( $str, 0, 1 ) ) . mb_substr( $str, 1 );
840 return ucfirst( $str );
843 return self
::isMultibyte( $str ) ?
mb_strtoupper( $str ) : strtoupper( $str );
846 if ( self
::isMultibyte( $str ) ) {
847 list( $wikiUpperChars ) = $this->getCaseMaps();
848 $x = $first ?
'^' : '';
849 return preg_replace_callback(
850 "/$x([a-z]|[\\xc0-\\xff][\\x80-\\xbf]*)/",
851 array($this,"ucCallback"),
855 return $first ?
ucfirst( $str ) : strtoupper( $str );
860 function lcfirst( $str ) {
861 return self
::lc( $str, true );
864 function lc( $str, $first = false ) {
865 if ( function_exists( 'mb_strtolower' ) )
867 if ( self
::isMultibyte( $str ) )
868 return mb_strtolower( mb_substr( $str, 0, 1 ) ) . mb_substr( $str, 1 );
870 return strtolower( substr( $str, 0, 1 ) ) . substr( $str, 1 );
872 return self
::isMultibyte( $str ) ?
mb_strtolower( $str ) : strtolower( $str );
874 if ( self
::isMultibyte( $str ) ) {
875 list( , $wikiLowerChars ) = self
::getCaseMaps();
876 $x = $first ?
'^' : '';
877 return preg_replace_callback(
878 "/$x([A-Z]|[\\xc0-\\xff][\\x80-\\xbf]*)/",
879 array($this,"lcCallback"),
883 return $first ?
strtolower( substr( $str, 0, 1 ) ) . substr( $str, 1 ) : strtolower( $str );
886 function isMultibyte( $str ) {
887 return (bool)preg_match( '/[\x80-\xff]/', $str );
890 function ucwords($str) {
891 if ( self
::isMultibyte( $str ) ) {
892 $str = self
::lc($str);
894 // regexp to find first letter in each word (i.e. after each space)
895 $replaceRegexp = "/^([a-z]|[\\xc0-\\xff][\\x80-\\xbf]*)| ([a-z]|[\\xc0-\\xff][\\x80-\\xbf]*)/";
897 // function to use to capitalize a single char
898 if ( function_exists( 'mb_strtoupper' ) )
899 return preg_replace_callback(
901 array($this,"ucwordsCallbackMB"),
905 return preg_replace_callback(
907 array($this,"ucwordsCallbackWiki"),
912 return ucwords( strtolower( $str ) );
915 # capitalize words at word breaks
916 function ucwordbreaks($str){
917 if (self
::isMultibyte( $str ) ) {
918 $str = self
::lc($str);
920 // since \b doesn't work for UTF-8, we explicitely define word break chars
921 $breaks= "[ \-\(\)\}\{\.,\?!]";
923 // find first letter after word break
924 $replaceRegexp = "/^([a-z]|[\\xc0-\\xff][\\x80-\\xbf]*)|$breaks([a-z]|[\\xc0-\\xff][\\x80-\\xbf]*)/";
926 if ( function_exists( 'mb_strtoupper' ) )
927 return preg_replace_callback(
929 array($this,"ucwordbreaksCallbackMB"),
933 return preg_replace_callback(
935 array($this,"ucwordsCallbackWiki"),
940 return preg_replace_callback(
941 '/\b([\w\x80-\xff]+)\b/',
942 array($this,"ucwordbreaksCallbackAscii"),
947 * Return a case-folded representation of $s
949 * This is a representation such that caseFold($s1)==caseFold($s2) if $s1
950 * and $s2 are the same except for the case of their characters. It is not
951 * necessary for the value returned to make sense when displayed.
953 * Do *not* perform any other normalisation in this function. If a caller
954 * uses this function when it should be using a more general normalisation
955 * function, then fix the caller.
957 function caseFold( $s ) {
958 return $this->uc( $s );
961 function checkTitleEncoding( $s ) {
962 if( is_array( $s ) ) {
963 wfDebugDieBacktrace( 'Given array to checkTitleEncoding.' );
965 # Check for non-UTF-8 URLs
966 $ishigh = preg_match( '/[\x80-\xff]/', $s);
967 if(!$ishigh) return $s;
969 $isutf8 = preg_match( '/^([\x00-\x7f]|[\xc0-\xdf][\x80-\xbf]|' .
970 '[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xf7][\x80-\xbf]{3})+$/', $s );
971 if( $isutf8 ) return $s;
973 return $this->iconv( $this->fallback8bitEncoding(), "utf-8", $s );
976 function fallback8bitEncoding() {
978 return $this->fallback8bitEncoding
;
982 * Some languages have special punctuation to strip out
983 * or characters which need to be converted for MySQL's
984 * indexing to grok it correctly. Make such changes here.
989 function stripForSearch( $string ) {
991 if ( $wgDBtype != 'mysql' ) {
995 # MySQL fulltext index doesn't grok utf-8, so we
996 # need to fold cases and convert to hex
998 wfProfileIn( __METHOD__
);
999 if( function_exists( 'mb_strtolower' ) ) {
1000 $out = preg_replace(
1001 "/([\\xc0-\\xff][\\x80-\\xbf]*)/e",
1002 "'U8' . bin2hex( \"$1\" )",
1003 mb_strtolower( $string ) );
1005 list( , $wikiLowerChars ) = self
::getCaseMaps();
1006 $out = preg_replace(
1007 "/([\\xc0-\\xff][\\x80-\\xbf]*)/e",
1008 "'U8' . bin2hex( strtr( \"\$1\", \$wikiLowerChars ) )",
1011 wfProfileOut( __METHOD__
);
1015 function convertForSearchResult( $termsArray ) {
1016 # some languages, e.g. Chinese, need to do a conversion
1017 # in order for search results to be displayed correctly
1022 * Get the first character of a string.
1027 function firstChar( $s ) {
1029 preg_match( '/^([\x00-\x7f]|[\xc0-\xdf][\x80-\xbf]|' .
1030 '[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xf7][\x80-\xbf]{3})/', $s, $matches);
1032 return isset( $matches[1] ) ?
$matches[1] : "";
1035 function initEncoding() {
1036 # Some languages may have an alternate char encoding option
1037 # (Esperanto X-coding, Japanese furigana conversion, etc)
1038 # If this language is used as the primary content language,
1039 # an override to the defaults can be set here on startup.
1042 function recodeForEdit( $s ) {
1043 # For some languages we'll want to explicitly specify
1044 # which characters make it into the edit box raw
1045 # or are converted in some way or another.
1046 # Note that if wgOutputEncoding is different from
1047 # wgInputEncoding, this text will be further converted
1048 # to wgOutputEncoding.
1049 global $wgEditEncoding;
1050 if( $wgEditEncoding == '' or
1051 $wgEditEncoding == 'UTF-8' ) {
1054 return $this->iconv( 'UTF-8', $wgEditEncoding, $s );
1058 function recodeInput( $s ) {
1059 # Take the previous into account.
1060 global $wgEditEncoding;
1061 if($wgEditEncoding != "") {
1062 $enc = $wgEditEncoding;
1066 if( $enc == 'UTF-8' ) {
1069 return $this->iconv( $enc, 'UTF-8', $s );
1074 * For right-to-left language support
1084 * A hidden direction mark (LRM or RLM), depending on the language direction
1088 function getDirMark() {
1089 return $this->isRTL() ?
"\xE2\x80\x8F" : "\xE2\x80\x8E";
1093 * An arrow, depending on the language direction
1097 function getArrow() {
1098 return $this->isRTL() ?
'←' : '→';
1102 * To allow "foo[[bar]]" to extend the link over the whole word "foobar"
1106 function linkPrefixExtension() {
1108 return $this->linkPrefixExtension
;
1111 function &getMagicWords() {
1113 return $this->magicWords
;
1116 # Fill a MagicWord object with data from here
1117 function getMagic( &$mw ) {
1118 if ( !isset( $this->mMagicExtensions
) ) {
1119 $this->mMagicExtensions
= array();
1120 wfRunHooks( 'LanguageGetMagic', array( &$this->mMagicExtensions
, $this->getCode() ) );
1122 if ( isset( $this->mMagicExtensions
[$mw->mId
] ) ) {
1123 $rawEntry = $this->mMagicExtensions
[$mw->mId
];
1125 $magicWords =& $this->getMagicWords();
1126 if ( isset( $magicWords[$mw->mId
] ) ) {
1127 $rawEntry = $magicWords[$mw->mId
];
1129 # Fall back to English if local list is incomplete
1130 $magicWords =& Language
::getMagicWords();
1131 $rawEntry = $magicWords[$mw->mId
];
1135 if( !is_array( $rawEntry ) ) {
1136 error_log( "\"$rawEntry\" is not a valid magic thingie for \"$mw->mId\"" );
1138 $mw->mCaseSensitive
= $rawEntry[0];
1139 $mw->mSynonyms
= array_slice( $rawEntry, 1 );
1143 * Get special page names, as an associative array
1144 * case folded alias => real name
1146 function getSpecialPageAliases() {
1148 if ( !isset( $this->mExtendedSpecialPageAliases
) ) {
1149 $this->mExtendedSpecialPageAliases
= $this->specialPageAliases
;
1150 wfRunHooks( 'LangugeGetSpecialPageAliases',
1151 array( &$this->mExtendedSpecialPageAliases
, $this->getCode() ) );
1153 return $this->mExtendedSpecialPageAliases
;
1157 * Italic is unsuitable for some languages
1161 * @param string $text The text to be emphasized.
1164 function emphasize( $text ) {
1165 return "<em>$text</em>";
1169 * Normally we output all numbers in plain en_US style, that is
1170 * 293,291.235 for twohundredninetythreethousand-twohundredninetyone
1171 * point twohundredthirtyfive. However this is not sutable for all
1172 * languages, some such as Pakaran want ੨੯੩,੨੯੫.੨੩੫ and others such as
1173 * Icelandic just want to use commas instead of dots, and dots instead
1174 * of commas like "293.291,235".
1176 * An example of this function being called:
1178 * wfMsg( 'message', $wgLang->formatNum( $num ) )
1181 * See LanguageGu.php for the Gujarati implementation and
1182 * LanguageIs.php for the , => . and . => , implementation.
1184 * @todo check if it's viable to use localeconv() for the decimal
1187 * @param mixed $number the string to be formatted, should be an integer or
1188 * a floating point number.
1189 * @param bool $nocommafy Set to true for special numbers like dates
1192 function formatNum( $number, $nocommafy = false ) {
1193 global $wgTranslateNumerals;
1195 $number = $this->commafy($number);
1196 $s = $this->separatorTransformTable();
1197 if (!is_null($s)) { $number = strtr($number, $s); }
1200 if ($wgTranslateNumerals) {
1201 $s = $this->digitTransformTable();
1202 if (!is_null($s)) { $number = strtr($number, $s); }
1208 function parseFormattedNumber( $number ) {
1209 $s = $this->digitTransformTable();
1210 if (!is_null($s)) { $number = strtr($number, array_flip($s)); }
1212 $s = $this->separatorTransformTable();
1213 if (!is_null($s)) { $number = strtr($number, array_flip($s)); }
1215 $number = strtr( $number, array (',' => '') );
1220 * Adds commas to a given number
1225 function commafy($_) {
1226 return strrev((string)preg_replace('/(\d{3})(?=\d)(?!\d*\.)/','$1,',strrev($_)));
1229 function digitTransformTable() {
1231 return $this->digitTransformTable
;
1234 function separatorTransformTable() {
1236 return $this->separatorTransformTable
;
1241 * For the credit list in includes/Credits.php (action=credits)
1246 function listToText( $l ) {
1249 for ($i = $m; $i >= 0; $i--) {
1252 } else if ($i == $m - 1) {
1253 $s = $l[$i] . ' ' . $this->getMessageFromDB( 'and' ) . ' ' . $s;
1255 $s = $l[$i] . ', ' . $s;
1261 # Crop a string from the beginning or end to a certain number of bytes.
1262 # (Bytes are used because our storage has limited byte lengths for some
1263 # columns in the database.) Multibyte charsets will need to make sure that
1264 # only whole characters are included!
1266 # $length does not include the optional ellipsis.
1267 # If $length is negative, snip from the beginning
1268 function truncate( $string, $length, $ellipsis = "" ) {
1269 if( $length == 0 ) {
1272 if ( strlen( $string ) <= abs( $length ) ) {
1276 $string = substr( $string, 0, $length );
1277 $char = ord( $string[strlen( $string ) - 1] );
1279 if ($char >= 0xc0) {
1280 # We got the first byte only of a multibyte char; remove it.
1281 $string = substr( $string, 0, -1 );
1282 } elseif( $char >= 0x80 &&
1283 preg_match( '/^(.*)(?:[\xe0-\xef][\x80-\xbf]|' .
1284 '[\xf0-\xf7][\x80-\xbf]{1,2})$/', $string, $m ) ) {
1285 # We chopped in the middle of a character; remove it
1288 return $string . $ellipsis;
1290 $string = substr( $string, $length );
1291 $char = ord( $string[0] );
1292 if( $char >= 0x80 && $char < 0xc0 ) {
1293 # We chopped in the middle of a character; remove the whole thing
1294 $string = preg_replace( '/^[\x80-\xbf]+/', '', $string );
1296 return $ellipsis . $string;
1301 * Grammatical transformations, needed for inflected languages
1302 * Invoked by putting {{grammar:case|word}} in a message
1304 * @param string $word
1305 * @param string $case
1308 function convertGrammar( $word, $case ) {
1309 global $wgGrammarForms;
1310 if ( isset($wgGrammarForms['en'][$case][$word]) ) {
1311 return $wgGrammarForms['en'][$case][$word];
1317 * Plural form transformations, needed for some languages.
1318 * For example, where are 3 form of plural in Russian and Polish,
1319 * depending on "count mod 10". See [[w:Plural]]
1320 * For English it is pretty simple.
1322 * Invoked by putting {{plural:count|wordform1|wordform2}}
1323 * or {{plural:count|wordform1|wordform2|wordform3}}
1325 * Example: {{plural:{{NUMBEROFARTICLES}}|article|articles}}
1327 * @param integer $count
1328 * @param string $wordform1
1329 * @param string $wordform2
1330 * @param string $wordform3 (optional)
1331 * @param string $wordform4 (optional)
1332 * @param string $wordform5 (optional)
1335 function convertPlural( $count, $w1, $w2, $w3, $w4, $w5) {
1336 return ( $count == '1' ||
$count == '-1' ) ?
$w1 : $w2;
1340 * For translaing of expiry times
1341 * @param string The validated block time in English
1342 * @param $forContent, avoid html?
1343 * @return Somehow translated block time
1344 * @see LanguageFi.php for example implementation
1346 function translateBlockExpiry( $str, $forContent=false ) {
1348 $scBlockExpiryOptions = $this->getMessageFromDB( 'ipboptions' );
1350 if ( $scBlockExpiryOptions == '-') {
1354 foreach (explode(',', $scBlockExpiryOptions) as $option) {
1355 if ( strpos($option, ":") === false )
1357 list($show, $value) = explode(":", $option);
1358 if ( strcmp ( $str, $value) == 0 ) {
1360 return htmlspecialchars($str) . htmlspecialchars( trim( $show ) );
1362 return '<span title="' . htmlspecialchars($str). '">' . htmlspecialchars( trim( $show ) ) . '</span>';
1370 * languages like Chinese need to be segmented in order for the diff
1373 * @param string $text
1376 function segmentForDiff( $text ) {
1381 * and unsegment to show the result
1383 * @param string $text
1386 function unsegmentForDiff( $text ) {
1390 # convert text to different variants of a language.
1391 function convert( $text, $isTitle = false) {
1392 return $this->mConverter
->convert($text, $isTitle);
1395 # Convert text from within Parser
1396 function parserConvert( $text, &$parser ) {
1397 return $this->mConverter
->parserConvert( $text, $parser );
1400 # Check if this is a language with variants
1401 function hasVariants(){
1402 return sizeof($this->getVariants())>1;
1405 # Put custom tags (e.g. -{ }-) around math to prevent conversion
1406 function armourMath($text){
1407 return $this->mConverter
->armourMath($text);
1412 * Perform output conversion on a string, and encode for safe HTML output.
1413 * @param string $text
1414 * @param bool $isTitle -- wtf?
1416 * @todo this should get integrated somewhere sane
1418 function convertHtml( $text, $isTitle = false ) {
1419 return htmlspecialchars( $this->convert( $text, $isTitle ) );
1422 function convertCategoryKey( $key ) {
1423 return $this->mConverter
->convertCategoryKey( $key );
1427 * get the list of variants supported by this langauge
1428 * see sample implementation in LanguageZh.php
1430 * @return array an array of language codes
1432 function getVariants() {
1433 return $this->mConverter
->getVariants();
1437 function getPreferredVariant( $fromUser = true ) {
1438 return $this->mConverter
->getPreferredVariant( $fromUser );
1442 * if a language supports multiple variants, it is
1443 * possible that non-existing link in one variant
1444 * actually exists in another variant. this function
1445 * tries to find it. See e.g. LanguageZh.php
1447 * @param string $link the name of the link
1448 * @param mixed $nt the title object of the link
1449 * @return null the input parameters may be modified upon return
1451 function findVariantLink( &$link, &$nt ) {
1452 $this->mConverter
->findVariantLink($link, $nt);
1456 * If a language supports multiple variants, converts text
1457 * into an array of all possible variants of the text:
1458 * 'variant' => text in that variant
1461 function convertLinkToAllVariants($text){
1462 return $this->mConverter
->convertLinkToAllVariants($text);
1467 * returns language specific options used by User::getPageRenderHash()
1468 * for example, the preferred language variant
1473 function getExtraHashOptions() {
1474 return $this->mConverter
->getExtraHashOptions();
1478 * for languages that support multiple variants, the title of an
1479 * article may be displayed differently in different variants. this
1480 * function returns the apporiate title defined in the body of the article.
1484 function getParsedTitle() {
1485 return $this->mConverter
->getParsedTitle();
1489 * Enclose a string with the "no conversion" tag. This is used by
1490 * various functions in the Parser
1492 * @param string $text text to be tagged for no conversion
1493 * @return string the tagged text
1495 function markNoConversion( $text, $noParse=false ) {
1496 return $this->mConverter
->markNoConversion( $text, $noParse );
1500 * A regular expression to match legal word-trailing characters
1501 * which should be merged onto a link of the form [[foo]]bar.
1506 function linkTrail() {
1508 return $this->linkTrail
;
1511 function getLangObj() {
1516 * Get the RFC 3066 code for this language object
1518 function getCode() {
1519 return $this->mCode
;
1522 function setCode( $code ) {
1523 $this->mCode
= $code;
1526 static function getFileName( $prefix = 'Language', $code, $suffix = '.php' ) {
1527 return $prefix . str_replace( '-', '_', ucfirst( $code ) ) . $suffix;
1530 static function getMessagesFileName( $code ) {
1532 return self
::getFileName( "$IP/languages/messages/Messages", $code, '.php' );
1535 static function getClassFileName( $code ) {
1537 return self
::getFileName( "$IP/languages/classes/Language", $code, '.php' );
1540 static function getLocalisationArray( $code, $disableCache = false ) {
1541 self
::loadLocalisation( $code, $disableCache );
1542 return self
::$mLocalisationCache[$code];
1546 * Load localisation data for a given code into the static cache
1548 * @return array Dependencies, map of filenames to mtimes
1550 static function loadLocalisation( $code, $disableCache = false ) {
1551 static $recursionGuard = array();
1555 throw new MWException( "Invalid language code requested" );
1558 if ( !$disableCache ) {
1559 # Try the per-process cache
1560 if ( isset( self
::$mLocalisationCache[$code] ) ) {
1561 return self
::$mLocalisationCache[$code]['deps'];
1564 wfProfileIn( __METHOD__
);
1566 # Try the serialized directory
1567 $cache = wfGetPrecompiledData( self
::getFileName( "Messages", $code, '.ser' ) );
1569 self
::$mLocalisationCache[$code] = $cache;
1570 wfDebug( "Language::loadLocalisation(): got localisation for $code from precompiled data file\n" );
1571 wfProfileOut( __METHOD__
);
1572 return self
::$mLocalisationCache[$code]['deps'];
1575 # Try the global cache
1576 $memcKey = wfMemcKey('localisation', $code );
1577 $cache = $wgMemc->get( $memcKey );
1579 # Check file modification times
1580 foreach ( $cache['deps'] as $file => $mtime ) {
1581 if ( !file_exists( $file ) ||
filemtime( $file ) > $mtime ) {
1585 if ( self
::isLocalisationOutOfDate( $cache ) ) {
1586 $wgMemc->delete( $memcKey );
1588 wfDebug( "Language::loadLocalisation(): localisation cache for $code had expired due to update of $file\n" );
1590 self
::$mLocalisationCache[$code] = $cache;
1591 wfDebug( "Language::loadLocalisation(): got localisation for $code from cache\n" );
1592 wfProfileOut( __METHOD__
);
1593 return $cache['deps'];
1597 wfProfileIn( __METHOD__
);
1600 # Default fallback, may be overridden when the messages file is included
1601 if ( $code != 'en' ) {
1607 # Load the primary localisation from the source file
1608 $filename = self
::getMessagesFileName( $code );
1609 if ( !file_exists( $filename ) ) {
1610 wfDebug( "Language::loadLocalisation(): no localisation file for $code, using implicit fallback to en\n" );
1614 $deps = array( $filename => filemtime( $filename ) );
1615 require( $filename );
1616 $cache = compact( self
::$mLocalisationKeys );
1617 wfDebug( "Language::loadLocalisation(): got localisation for $code from source\n" );
1620 if ( !empty( $fallback ) ) {
1621 # Load the fallback localisation, with a circular reference guard
1622 if ( isset( $recursionGuard[$code] ) ) {
1623 throw new MWException( "Error: Circular fallback reference in language code $code" );
1625 $recursionGuard[$code] = true;
1626 $newDeps = self
::loadLocalisation( $fallback, $disableCache );
1627 unset( $recursionGuard[$code] );
1629 $secondary = self
::$mLocalisationCache[$fallback];
1630 $deps = array_merge( $deps, $newDeps );
1632 # Merge the fallback localisation with the current localisation
1633 foreach ( self
::$mLocalisationKeys as $key ) {
1634 if ( isset( $cache[$key] ) ) {
1635 if ( isset( $secondary[$key] ) ) {
1636 if ( in_array( $key, self
::$mMergeableMapKeys ) ) {
1637 $cache[$key] = $cache[$key] +
$secondary[$key];
1638 } elseif ( in_array( $key, self
::$mMergeableListKeys ) ) {
1639 $cache[$key] = array_merge( $secondary[$key], $cache[$key] );
1640 } elseif ( in_array( $key, self
::$mMergeableAliasListKeys ) ) {
1641 $cache[$key] = array_merge_recursive( $cache[$key], $secondary[$key] );
1645 $cache[$key] = $secondary[$key];
1649 # Merge bookstore lists if requested
1650 if ( !empty( $cache['bookstoreList']['inherit'] ) ) {
1651 $cache['bookstoreList'] = array_merge( $cache['bookstoreList'], $secondary['bookstoreList'] );
1653 if ( isset( $cache['bookstoreList']['inherit'] ) ) {
1654 unset( $cache['bookstoreList']['inherit'] );
1658 # Add dependencies to the cache entry
1659 $cache['deps'] = $deps;
1661 # Replace spaces with underscores in namespace names
1662 $cache['namespaceNames'] = str_replace( ' ', '_', $cache['namespaceNames'] );
1664 # Save to both caches
1665 self
::$mLocalisationCache[$code] = $cache;
1666 if ( !$disableCache ) {
1667 $wgMemc->set( $memcKey, $cache );
1670 wfProfileOut( __METHOD__
);
1675 * Test if a given localisation cache is out of date with respect to the
1676 * source Messages files. This is done automatically for the global cache
1677 * in $wgMemc, but is only done on certain occasions for the serialized
1680 * @param $cache mixed Either a language code or a cache array
1682 static function isLocalisationOutOfDate( $cache ) {
1683 if ( !is_array( $cache ) ) {
1684 self
::loadLocalisation( $cache );
1685 $cache = self
::$mLocalisationCache[$cache];
1688 foreach ( $cache['deps'] as $file => $mtime ) {
1689 if ( !file_exists( $file ) ||
filemtime( $file ) > $mtime ) {
1698 * Get the fallback for a given language
1700 static function getFallbackFor( $code ) {
1701 self
::loadLocalisation( $code );
1702 return self
::$mLocalisationCache[$code]['fallback'];
1706 * Get all messages for a given language
1708 static function getMessagesFor( $code ) {
1709 self
::loadLocalisation( $code );
1710 return self
::$mLocalisationCache[$code]['messages'];
1714 * Get a message for a given language
1716 static function getMessageFor( $key, $code ) {
1717 self
::loadLocalisation( $code );
1718 return isset( self
::$mLocalisationCache[$code]['messages'][$key] ) ? self
::$mLocalisationCache[$code]['messages'][$key] : null;
1722 * Load localisation data for this object
1725 if ( !$this->mLoaded
) {
1726 self
::loadLocalisation( $this->getCode() );
1727 $cache =& self
::$mLocalisationCache[$this->getCode()];
1728 foreach ( self
::$mLocalisationKeys as $key ) {
1729 $this->$key = $cache[$key];
1731 $this->mLoaded
= true;
1733 $this->fixUpSettings();
1738 * Do any necessary post-cache-load settings adjustment
1740 function fixUpSettings() {
1741 global $wgExtraNamespaces, $wgMetaNamespace, $wgMetaNamespaceTalk,
1742 $wgNamespaceAliases, $wgAmericanDates;
1743 wfProfileIn( __METHOD__
);
1744 if ( $wgExtraNamespaces ) {
1745 $this->namespaceNames
= $wgExtraNamespaces +
$this->namespaceNames
;
1748 $this->namespaceNames
[NS_PROJECT
] = $wgMetaNamespace;
1749 if ( $wgMetaNamespaceTalk ) {
1750 $this->namespaceNames
[NS_PROJECT_TALK
] = $wgMetaNamespaceTalk;
1752 $talk = $this->namespaceNames
[NS_PROJECT_TALK
];
1753 $talk = str_replace( '$1', $wgMetaNamespace, $talk );
1755 # Allow grammar transformations
1756 # Allowing full message-style parsing would make simple requests
1757 # such as action=raw much more expensive than they need to be.
1758 # This will hopefully cover most cases.
1759 $talk = preg_replace_callback( '/{{grammar:(.*?)\|(.*?)}}/i',
1760 array( &$this, 'replaceGrammarInNamespace' ), $talk );
1761 $talk = str_replace( ' ', '_', $talk );
1762 $this->namespaceNames
[NS_PROJECT_TALK
] = $talk;
1765 # The above mixing may leave namespaces out of canonical order.
1766 # Re-order by namespace ID number...
1767 ksort( $this->namespaceNames
);
1769 # Put namespace names and aliases into a hashtable.
1770 # If this is too slow, then we should arrange it so that it is done
1771 # before caching. The catch is that at pre-cache time, the above
1772 # class-specific fixup hasn't been done.
1773 $this->mNamespaceIds
= array();
1774 foreach ( $this->namespaceNames
as $index => $name ) {
1775 $this->mNamespaceIds
[$this->lc($name)] = $index;
1777 if ( $this->namespaceAliases
) {
1778 foreach ( $this->namespaceAliases
as $name => $index ) {
1779 $this->mNamespaceIds
[$this->lc($name)] = $index;
1782 if ( $wgNamespaceAliases ) {
1783 foreach ( $wgNamespaceAliases as $name => $index ) {
1784 $this->mNamespaceIds
[$this->lc($name)] = $index;
1788 if ( $this->defaultDateFormat
== 'dmy or mdy' ) {
1789 $this->defaultDateFormat
= $wgAmericanDates ?
'mdy' : 'dmy';
1791 wfProfileOut( __METHOD__
);
1794 function replaceGrammarInNamespace( $m ) {
1795 return $this->convertGrammar( trim( $m[2] ), trim( $m[1] ) );
1798 static function getCaseMaps() {
1799 static $wikiUpperChars, $wikiLowerChars;
1800 if ( isset( $wikiUpperChars ) ) {
1801 return array( $wikiUpperChars, $wikiLowerChars );
1804 wfProfileIn( __METHOD__
);
1805 $arr = wfGetPrecompiledData( 'Utf8Case.ser' );
1806 if ( $arr === false ) {
1807 throw new MWException(
1808 "Utf8Case.ser is missing, please run \"make\" in the serialized directory\n" );
1811 wfProfileOut( __METHOD__
);
1812 return array( $wikiUpperChars, $wikiLowerChars );