Same for core messages and language...
[lhc/web/wiklou.git] / languages / Language.php
1 <?php
2 /**
3 * @package MediaWiki
4 * @subpackage Language
5 */
6
7 if( defined( 'MEDIAWIKI' ) ) {
8
9 #
10 # In general you should not make customizations in these language files
11 # directly, but should use the MediaWiki: special namespace to customize
12 # user interface messages through the wiki.
13 # See http://meta.wikipedia.org/wiki/MediaWiki_namespace
14 #
15 # NOTE TO TRANSLATORS: Do not copy this whole file when making translations!
16 # A lot of common constants and a base class with inheritable methods are
17 # defined here, which should not be redefined. See the other LanguageXx.php
18 # files for examples.
19 #
20
21 #--------------------------------------------------------------------------
22 # Language-specific text
23 #--------------------------------------------------------------------------
24
25 if($wgMetaNamespace === FALSE)
26 $wgMetaNamespace = str_replace( ' ', '_', $wgSitename );
27
28 /* private */ $wgNamespaceNamesEn = array(
29 NS_MEDIA => 'Media',
30 NS_SPECIAL => 'Special',
31 NS_MAIN => '',
32 NS_TALK => 'Talk',
33 NS_USER => 'User',
34 NS_USER_TALK => 'User_talk',
35 NS_PROJECT => $wgMetaNamespace,
36 NS_PROJECT_TALK => $wgMetaNamespace . '_talk',
37 NS_IMAGE => 'Image',
38 NS_IMAGE_TALK => 'Image_talk',
39 NS_MEDIAWIKI => 'MediaWiki',
40 NS_MEDIAWIKI_TALK => 'MediaWiki_talk',
41 NS_TEMPLATE => 'Template',
42 NS_TEMPLATE_TALK => 'Template_talk',
43 NS_HELP => 'Help',
44 NS_HELP_TALK => 'Help_talk',
45 NS_CATEGORY => 'Category',
46 NS_CATEGORY_TALK => 'Category_talk',
47 );
48
49 if(isset($wgExtraNamespaces)) {
50 $wgNamespaceNamesEn=$wgNamespaceNamesEn+$wgExtraNamespaces;
51 }
52
53 /* private */ $wgDefaultUserOptionsEn = array(
54 'quickbar' => 1,
55 'underline' => 2,
56 'cols' => 80,
57 'rows' => 25,
58 'searchlimit' => 20,
59 'contextlines' => 5,
60 'contextchars' => 50,
61 'skin' => $wgDefaultSkin,
62 'math' => 1,
63 'rcdays' => 7,
64 'rclimit' => 50,
65 'highlightbroken' => 1,
66 'stubthreshold' => 0,
67 'previewontop' => 1,
68 'editsection' => 1,
69 'editsectiononrightclick'=> 0,
70 'showtoc' => 1,
71 'showtoolbar' => 1,
72 'date' => 0,
73 'imagesize' => 2,
74 'thumbsize' => 2,
75 'rememberpassword' => 0,
76 'enotifwatchlistpages' => 0,
77 'enotifusertalkpages' => 1,
78 'enotifminoredits' => 0,
79 'enotifrevealaddr' => 0,
80 'shownumberswatching' => 1,
81 'fancysig' => 0,
82 'externaleditor' => 0,
83 'externaldiff' => 0,
84 'showjumplinks' => 1,
85 'numberheadings' => 0,
86 );
87
88 /* private */ $wgQuickbarSettingsEn = array(
89 'None', 'Fixed left', 'Fixed right', 'Floating left', 'Floating right'
90 );
91
92 /* private */ $wgSkinNamesEn = array(
93 'standard' => 'Classic',
94 'nostalgia' => 'Nostalgia',
95 'cologneblue' => 'Cologne Blue',
96 'davinci' => 'DaVinci',
97 'mono' => 'Mono',
98 'monobook' => 'MonoBook',
99 'myskin' => 'MySkin',
100 'chick' => 'Chick'
101 );
102
103 /* private */ $wgMathNamesEn = array(
104 MW_MATH_PNG => 'mw_math_png',
105 MW_MATH_SIMPLE => 'mw_math_simple',
106 MW_MATH_HTML => 'mw_math_html',
107 MW_MATH_SOURCE => 'mw_math_source',
108 MW_MATH_MODERN => 'mw_math_modern',
109 MW_MATH_MATHML => 'mw_math_mathml'
110 );
111
112 /**
113 * Whether to use user or default setting in Language::date()
114 *
115 * NOTE: the array string values are no longer important!
116 * The actual date format functions are now called for the selection in
117 * Special:Preferences, and the 'datedefault' message for MW_DATE_DEFAULT.
118 *
119 * The array keys make up the set of formats which this language allows
120 * the user to select. It's exposed via Language::getDateFormats().
121 *
122 * @access private
123 */
124 $wgDateFormatsEn = array(
125 MW_DATE_DEFAULT => 'No preference',
126 MW_DATE_DMY => '16:12, 15 January 2001',
127 MW_DATE_MDY => '16:12, January 15, 2001',
128 MW_DATE_YMD => '16:12, 2001 January 15',
129 MW_DATE_ISO => '2001-01-15 16:12:34'
130 );
131
132 /* private */ $wgUserTogglesEn = array(
133 'highlightbroken',
134 'justify',
135 'hideminor',
136 'usenewrc',
137 'numberheadings',
138 'showtoolbar',
139 'editondblclick',
140 'editsection',
141 'editsectiononrightclick',
142 'showtoc',
143 'rememberpassword',
144 'editwidth',
145 'watchdefault',
146 'minordefault',
147 'previewontop',
148 'previewonfirst',
149 'nocache',
150 'enotifwatchlistpages',
151 'enotifusertalkpages',
152 'enotifminoredits',
153 'enotifrevealaddr',
154 'shownumberswatching',
155 'fancysig',
156 'externaleditor',
157 'externaldiff',
158 'showjumplinks',
159 );
160
161 /* private */ $wgBookstoreListEn = array(
162 'AddALL' => 'http://www.addall.com/New/Partner.cgi?query=$1&type=ISBN',
163 'PriceSCAN' => 'http://www.pricescan.com/books/bookDetail.asp?isbn=$1',
164 'Barnes & Noble' => 'http://search.barnesandnoble.com/bookSearch/isbnInquiry.asp?isbn=$1',
165 'Amazon.com' => 'http://www.amazon.com/exec/obidos/ISBN=$1'
166 );
167
168 # Read language names
169 global $wgLanguageNames;
170 /** */
171 require_once( 'Names.php' );
172
173 $wgLanguageNamesEn =& $wgLanguageNames;
174
175
176 /* private */ $wgWeekdayNamesEn = array(
177 'sunday', 'monday', 'tuesday', 'wednesday', 'thursday',
178 'friday', 'saturday'
179 );
180
181
182 /* private */ $wgMonthNamesEn = array(
183 'january', 'february', 'march', 'april', 'may_long', 'june',
184 'july', 'august', 'september', 'october', 'november',
185 'december'
186 );
187 /* private */ $wgMonthNamesGenEn = array(
188 'january-gen', 'february-gen', 'march-gen', 'april-gen', 'may-gen', 'june-gen',
189 'july-gen', 'august-gen', 'september-gen', 'october-gen', 'november-gen',
190 'december-gen'
191 );
192
193 /* private */ $wgMonthAbbreviationsEn = array(
194 'jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug',
195 'sep', 'oct', 'nov', 'dec'
196 );
197
198 # Note to translators:
199 # Please include the English words as synonyms. This allows people
200 # from other wikis to contribute more easily.
201 #
202 /* private */ $wgMagicWordsEn = array(
203 # ID CASE SYNONYMS
204 MAG_REDIRECT => array( 0, '#REDIRECT' ),
205 MAG_NOTOC => array( 0, '__NOTOC__' ),
206 MAG_FORCETOC => array( 0, '__FORCETOC__' ),
207 MAG_TOC => array( 0, '__TOC__' ),
208 MAG_NOEDITSECTION => array( 0, '__NOEDITSECTION__' ),
209 MAG_START => array( 0, '__START__' ),
210 MAG_CURRENTMONTH => array( 1, 'CURRENTMONTH' ),
211 MAG_CURRENTMONTHNAME => array( 1, 'CURRENTMONTHNAME' ),
212 MAG_CURRENTMONTHNAMEGEN => array( 1, 'CURRENTMONTHNAMEGEN' ),
213 MAG_CURRENTMONTHABBREV => array( 1, 'CURRENTMONTHABBREV' ),
214 MAG_CURRENTDAY => array( 1, 'CURRENTDAY' ),
215 MAG_CURRENTDAY2 => array( 1, 'CURRENTDAY2' ),
216 MAG_CURRENTDAYNAME => array( 1, 'CURRENTDAYNAME' ),
217 MAG_CURRENTYEAR => array( 1, 'CURRENTYEAR' ),
218 MAG_CURRENTTIME => array( 1, 'CURRENTTIME' ),
219 MAG_NUMBEROFARTICLES => array( 1, 'NUMBEROFARTICLES' ),
220 MAG_NUMBEROFFILES => array( 1, 'NUMBEROFFILES' ),
221 MAG_PAGENAME => array( 1, 'PAGENAME' ),
222 MAG_PAGENAMEE => array( 1, 'PAGENAMEE' ),
223 MAG_NAMESPACE => array( 1, 'NAMESPACE' ),
224 MAG_NAMESPACEE => array( 1, 'NAMESPACEE' ),
225 MAG_FULLPAGENAME => array( 1, 'FULLPAGENAME' ),
226 MAG_FULLPAGENAMEE => array( 1, 'FULLPAGENAMEE' ),
227 MAG_MSG => array( 0, 'MSG:' ),
228 MAG_SUBST => array( 0, 'SUBST:' ),
229 MAG_MSGNW => array( 0, 'MSGNW:' ),
230 MAG_END => array( 0, '__END__' ),
231 MAG_IMG_THUMBNAIL => array( 1, 'thumbnail', 'thumb' ),
232 MAG_IMG_MANUALTHUMB => array( 1, 'thumbnail=$1', 'thumb=$1'),
233 MAG_IMG_RIGHT => array( 1, 'right' ),
234 MAG_IMG_LEFT => array( 1, 'left' ),
235 MAG_IMG_NONE => array( 1, 'none' ),
236 MAG_IMG_WIDTH => array( 1, '$1px' ),
237 MAG_IMG_CENTER => array( 1, 'center', 'centre' ),
238 MAG_IMG_FRAMED => array( 1, 'framed', 'enframed', 'frame' ),
239 MAG_INT => array( 0, 'INT:' ),
240 MAG_SITENAME => array( 1, 'SITENAME' ),
241 MAG_NS => array( 0, 'NS:' ),
242 MAG_LOCALURL => array( 0, 'LOCALURL:' ),
243 MAG_LOCALURLE => array( 0, 'LOCALURLE:' ),
244 MAG_SERVER => array( 0, 'SERVER' ),
245 MAG_SERVERNAME => array( 0, 'SERVERNAME' ),
246 MAG_SCRIPTPATH => array( 0, 'SCRIPTPATH' ),
247 MAG_GRAMMAR => array( 0, 'GRAMMAR:' ),
248 MAG_NOTITLECONVERT => array( 0, '__NOTITLECONVERT__', '__NOTC__'),
249 MAG_NOCONTENTCONVERT => array( 0, '__NOCONTENTCONVERT__', '__NOCC__'),
250 MAG_CURRENTWEEK => array( 1, 'CURRENTWEEK' ),
251 MAG_CURRENTDOW => array( 1, 'CURRENTDOW' ),
252 MAG_REVISIONID => array( 1, 'REVISIONID' ),
253 MAG_PLURAL => array( 0, 'PLURAL:' ),
254 MAG_FULLURL => array( 0, 'FULLURL:' ),
255 MAG_FULLURLE => array( 0, 'FULLURLE:' ),
256 MAG_LCFIRST => array( 0, 'LCFIRST:' ),
257 MAG_UCFIRST => array( 0, 'UCFIRST:' ),
258 MAG_LC => array( 0, 'LC:' ),
259 MAG_UC => array( 0, 'UC:' ),
260 );
261
262 if (!$wgCachedMessageArrays) {
263 require_once('Messages.php');
264 }
265
266 /* a fake language converter */
267 class fakeConverter {
268 var $mLang;
269 function fakeConverter($langobj) {$this->mLang = $langobj;}
270 function convert($t, $i) {return $t;}
271 function getVariants() { return array( $this->mLang->getCode() ); }
272 function getPreferredVariant() {return $this->mLang->getCode(); }
273 function findVariantLink(&$l, &$n) {}
274 function getExtraHashOptions() {return '';}
275 function getParsedTitle() {return '';}
276 function markNoConversion($text) {return $text;}
277 function convertCategoryKey( $key ) {return $key; }
278
279 }
280
281 #--------------------------------------------------------------------------
282 # Internationalisation code
283 #--------------------------------------------------------------------------
284
285 class Language {
286 var $mConverter;
287 function Language() {
288
289 # Copies any missing values in the specified arrays from En to the current language
290 $fillin = array( 'wgSysopSpecialPages', 'wgValidSpecialPages', 'wgDeveloperSpecialPages' );
291 $name = get_class( $this );
292
293 if( strpos( $name, 'language' ) == 0){
294 $lang = ucfirst( substr( $name, 8 ) );
295 foreach( $fillin as $arrname ){
296 $langver = "{$arrname}{$lang}";
297 $enver = "{$arrname}En";
298 if( ! isset( $GLOBALS[$langver] ) || ! isset( $GLOBALS[$enver] ))
299 continue;
300 foreach($GLOBALS[$enver] as $spage => $text){
301 if( ! isset( $GLOBALS[$langver][$spage] ) )
302 $GLOBALS[$langver][$spage] = $text;
303 }
304 }
305 }
306 $this->mConverter = new fakeConverter($this);
307 }
308
309 /**
310 * Exports the default user options as defined in
311 * $wgDefaultUserOptionsEn, user preferences can override some of these
312 * depending on what's in (Local|Default)Settings.php and some defines.
313 *
314 * @return array
315 */
316 function getDefaultUserOptions() {
317 global $wgDefaultUserOptionsEn ;
318 return $wgDefaultUserOptionsEn ;
319 }
320
321 /**
322 * Exports $wgBookstoreListEn
323 * @return array
324 */
325 function getBookstoreList() {
326 global $wgBookstoreListEn ;
327 return $wgBookstoreListEn ;
328 }
329
330 /**
331 * @return array
332 */
333 function getNamespaces() {
334 global $wgNamespaceNamesEn;
335 return $wgNamespaceNamesEn;
336 }
337
338 /**
339 * A convenience function that returns the same thing as
340 * getNamespaces() except with the array values changed to ' '
341 * where it found '_', useful for producing output to be displayed
342 * e.g. in <select> forms.
343 *
344 * @return array
345 */
346 function getFormattedNamespaces() {
347 $ns = $this->getNamespaces();
348 foreach($ns as $k => $v) {
349 $ns[$k] = strtr($v, '_', ' ');
350 }
351 return $ns;
352 }
353
354 /**
355 * Get a namespace value by key
356 * <code>
357 * $mw_ns = $wgContLang->getNsText( NS_MEDIAWIKI );
358 * echo $mw_ns; // prints 'MediaWiki'
359 * </code>
360 *
361 * @param int $index the array key of the namespace to return
362 * @return mixed, string if the namespace value exists, otherwise false
363 */
364 function getNsText( $index ) {
365 $ns = $this->getNamespaces();
366 return isset( $ns[$index] ) ? $ns[$index] : false;
367 }
368
369 /**
370 * A convenience function that returns the same thing as
371 * getNsText() except with '_' changed to ' ', useful for
372 * producing output.
373 *
374 * @return array
375 */
376 function getFormattedNsText( $index ) {
377 $ns = $this->getNsText( $index );
378 return strtr($ns, '_', ' ');
379 }
380
381 /**
382 * Get a namespace key by value, case insensetive.
383 *
384 * @param string $text
385 * @return mixed An integer if $text is a valid value otherwise false
386 */
387 function getNsIndex( $text ) {
388 $ns = $this->getNamespaces();
389
390 foreach ( $ns as $i => $n ) {
391 if ( strcasecmp( $n, $text ) == 0)
392 return $i;
393 }
394 return false;
395 }
396
397 /**
398 * short names for language variants used for language conversion links.
399 *
400 * @param string $code
401 * @return string
402 */
403 function getVariantname( $code ) {
404 return wfMsg( "variantname-$code" );
405 }
406
407 function specialPage( $name ) {
408 return $this->getNsText(NS_SPECIAL) . ':' . $name;
409 }
410
411 function getQuickbarSettings() {
412 global $wgQuickbarSettingsEn;
413 return $wgQuickbarSettingsEn;
414 }
415
416 function getSkinNames() {
417 global $wgSkinNamesEn;
418 return $wgSkinNamesEn;
419 }
420
421 function getMathNames() {
422 global $wgMathNamesEn;
423 return $wgMathNamesEn;
424 }
425
426 function getDateFormats() {
427 global $wgDateFormatsEn;
428 return $wgDateFormatsEn;
429 }
430
431 function getUserToggles() {
432 global $wgUserTogglesEn;
433 return $wgUserTogglesEn;
434 }
435
436 function getUserToggle( $tog ) {
437 return wfMsg( "tog-$tog" );
438 }
439
440 function getLanguageNames() {
441 global $wgLanguageNamesEn;
442 return $wgLanguageNamesEn;
443 }
444
445 function getLanguageName( $code ) {
446 global $wgLanguageNamesEn;
447 if ( ! array_key_exists( $code, $wgLanguageNamesEn ) ) {
448 return '';
449 }
450 return $wgLanguageNamesEn[$code];
451 }
452
453 function getMonthName( $key ) {
454 global $wgMonthNamesEn, $wgContLang;
455 // see who called us and use the correct message function
456 if( get_class( $wgContLang->getLangObj() ) == get_class( $this ) )
457 return wfMsgForContent($wgMonthNamesEn[$key-1]);
458 else
459 return wfMsg($wgMonthNamesEn[$key-1]);
460 }
461
462 /* by default we just return base form */
463 function getMonthNameGen( $key ) {
464 return $this->getMonthName( $key );
465 }
466
467 function getMonthAbbreviation( $key ) {
468 global $wgMonthAbbreviationsEn, $wgContLang;
469 // see who called us and use the correct message function
470 if( get_class( $wgContLang->getLangObj() ) == get_class( $this ) )
471 return wfMsgForContent(@$wgMonthAbbreviationsEn[$key-1]);
472 else
473 return wfMsg(@$wgMonthAbbreviationsEn[$key-1]);
474 }
475
476 function getWeekdayName( $key ) {
477 global $wgWeekdayNamesEn, $wgContLang;
478 // see who called us and use the correct message function
479 if( get_class( $wgContLang->getLangObj() ) == get_class( $this ) )
480 return wfMsgForContent($wgWeekdayNamesEn[$key-1]);
481 else
482 return wfMsg($wgWeekdayNamesEn[$key-1]);
483 }
484
485 /**
486 * Used by date() and time() to adjust the time output.
487 * @access public
488 * @param int $ts the time in date('YmdHis') format
489 * @param mixed $tz adjust the time by this amount (default false)
490 * @return int
491
492 */
493 function userAdjust( $ts, $tz = false ) {
494 global $wgUser, $wgLocalTZoffset;
495
496 if (!$tz) {
497 $tz = $wgUser->getOption( 'timecorrection' );
498 }
499
500 if ( $tz === '' ) {
501 $hrDiff = isset( $wgLocalTZoffset ) ? $wgLocalTZoffset : 0;
502 $minDiff = 0;
503 } elseif ( strpos( $tz, ':' ) !== false ) {
504 $tzArray = explode( ':', $tz );
505 $hrDiff = intval($tzArray[0]);
506 $minDiff = intval($hrDiff < 0 ? -$tzArray[1] : $tzArray[1]);
507 } else {
508 $hrDiff = intval( $tz );
509 }
510 if ( 0 == $hrDiff && 0 == $minDiff ) { return $ts; }
511
512 $t = mktime( (
513 (int)substr( $ts, 8, 2) ) + $hrDiff, # Hours
514 (int)substr( $ts, 10, 2 ) + $minDiff, # Minutes
515 (int)substr( $ts, 12, 2 ), # Seconds
516 (int)substr( $ts, 4, 2 ), # Month
517 (int)substr( $ts, 6, 2 ), # Day
518 (int)substr( $ts, 0, 4 ) ); #Year
519 return date( 'YmdHis', $t );
520 }
521
522 /**
523 * This is meant to be used by time(), date(), and timeanddate() to get
524 * the date preference they're supposed to use, it should be used in
525 * all children.
526 *
527 *<code>
528 * function timeanddate([...], $format = true) {
529 * $datePreference = $this->dateFormat($format);
530 * [...]
531 *</code>
532 *
533 * @param mixed $usePrefs: if true, the user's preference is used
534 * if false, the site/language default is used
535 * if int/string, assumed to be a format.
536 * @return string
537 */
538 function dateFormat( $usePrefs = true ) {
539 global $wgUser;
540
541 if( is_bool( $usePrefs ) ) {
542 if( $usePrefs ) {
543 $datePreference = $wgUser->getOption( 'date' );
544 } else {
545 $options = $this->getDefaultUserOptions();
546 $datePreference = (string)$options['date'];
547 }
548 } else {
549 $datePreference = (string)$usePrefs;
550 }
551
552 // return int
553 if( $datePreference == '' ) {
554 return MW_DATE_DEFAULT;
555 }
556
557 return $datePreference;
558 }
559
560 /**
561 * @access public
562 * @param mixed $ts the time format which needs to be turned into a
563 * date('YmdHis') format with wfTimestamp(TS_MW,$ts)
564 * @param bool $adj whether to adjust the time output according to the
565 * user configured offset ($timecorrection)
566 * @param mixed $format true to use user's date format preference
567 * @param string $timecorrection the time offset as returned by
568 * validateTimeZone() in Special:Preferences
569 * @return string
570 */
571 function date( $ts, $adj = false, $format = true, $timecorrection = false ) {
572 global $wgUser, $wgAmericanDates;
573
574 if ( $adj ) { $ts = $this->userAdjust( $ts, $timecorrection ); }
575
576 $datePreference = $this->dateFormat( $format );
577 if( $datePreference == MW_DATE_DEFAULT ) {
578 $datePreference = $wgAmericanDates ? MW_DATE_MDY : MW_DATE_DMY;
579 }
580
581 $month = $this->formatMonth( substr( $ts, 4, 2 ), $datePreference );
582 $day = $this->formatDay( substr( $ts, 6, 2 ), $datePreference );
583 $year = $this->formatNum( substr( $ts, 0, 4 ), true );
584
585 switch( $datePreference ) {
586 case MW_DATE_DMY: return "$day $month $year";
587 case MW_DATE_YMD: return "$year $month $day";
588 case MW_DATE_ISO: return substr($ts, 0, 4). '-' . substr($ts, 4, 2). '-' .substr($ts, 6, 2);
589 default: return "$month $day, $year";
590 }
591 }
592
593 /**
594 * @access public
595 * @param mixed $ts the time format which needs to be turned into a
596 * date('YmdHis') format with wfTimestamp(TS_MW,$ts)
597 * @param bool $adj whether to adjust the time output according to the
598 * user configured offset ($timecorrection)
599 * @param mixed $format true to use user's date format preference
600 * @param string $timecorrection the time offset as returned by
601 * validateTimeZone() in Special:Preferences
602 * @return string
603 */
604 function time( $ts, $adj = false, $format = true, $timecorrection = false ) {
605 global $wgUser;
606
607 if ( $adj ) { $ts = $this->userAdjust( $ts, $timecorrection ); }
608 $datePreference = $this->dateFormat( $format );
609
610 $sep = ($datePreference == MW_DATE_ISO)
611 ? ':'
612 : $this->timeSeparator( $format );
613
614 $t = substr( $ts, 8, 2 ) . $sep . substr( $ts, 10, 2 );
615
616 if ( $datePreference == MW_DATE_ISO ) {
617 $t .= $sep . substr( $ts, 12, 2 );
618 }
619 return $t;
620 }
621
622 /**
623 * Default separator character between hours, minutes, and seconds.
624 * Will be used by Language::time() for non-ISO formats.
625 * (ISO will always use a colon.)
626 * @return string
627 */
628 function timeSeparator( $format ) {
629 return ':';
630 }
631
632 /**
633 * String to insert between the time and the date in a combined
634 * string. Should include any relevant whitespace.
635 * @return string
636 */
637 function timeDateSeparator( $format ) {
638 return ', ';
639 }
640
641 /**
642 * Return true if the time should display before the date.
643 * @return bool
644 * @access private
645 */
646 function timeBeforeDate() {
647 return true;
648 }
649
650 function formatMonth( $month, $format ) {
651 return $this->getMonthName( $month );
652 }
653
654 function formatDay( $day, $format ) {
655 return $this->formatNum( 0 + $day );
656 }
657
658 /**
659 * @access public
660 * @param mixed $ts the time format which needs to be turned into a
661 * date('YmdHis') format with wfTimestamp(TS_MW,$ts)
662 * @param bool $adj whether to adjust the time output according to the
663 * user configured offset ($timecorrection)
664
665 * @param mixed $format what format to return, if it's false output the
666 * default one (default true)
667 * @param string $timecorrection the time offset as returned by
668 * validateTimeZone() in Special:Preferences
669 * @return string
670 */
671 function timeanddate( $ts, $adj = false, $format = true, $timecorrection = false) {
672 global $wgUser;
673
674 $datePreference = $this->dateFormat($format);
675 switch ( $datePreference ) {
676 case MW_DATE_ISO: return $this->date( $ts, $adj, $format, $timecorrection ) . ' ' .
677 $this->time( $ts, $adj, $format, $timecorrection );
678 default:
679 $time = $this->time( $ts, $adj, $format, $timecorrection );
680 $sep = $this->timeDateSeparator( $datePreference );
681 $date = $this->date( $ts, $adj, $format, $timecorrection );
682 return $this->timeBeforeDate( $datePreference )
683 ? $time . $sep . $date
684 : $date . $sep . $time;
685 }
686 }
687
688 function getMessage( $key ) {
689 global $wgAllMessagesEn;
690 return @$wgAllMessagesEn[$key];
691 }
692
693 function getAllMessages() {
694 global $wgAllMessagesEn;
695 return $wgAllMessagesEn;
696 }
697
698 function iconv( $in, $out, $string ) {
699 # For most languages, this is a wrapper for iconv
700 return iconv( $in, $out, $string );
701 }
702
703 function ucfirst( $string ) {
704 # For most languages, this is a wrapper for ucfirst()
705 return ucfirst( $string );
706 }
707
708 function uc( $str ) {
709 return strtoupper( $str );
710 }
711
712 function lcfirst( $s ) {
713 return strtolower( $s{0} ). substr( $s, 1 );
714 }
715
716 function lc( $str ) {
717 return strtolower( $str );
718 }
719
720 function checkTitleEncoding( $s ) {
721 global $wgInputEncoding;
722
723 # Check for UTF-8 URLs; Internet Explorer produces these if you
724 # type non-ASCII chars in the URL bar or follow unescaped links.
725 $ishigh = preg_match( '/[\x80-\xff]/', $s);
726 $isutf = ($ishigh ? preg_match( '/^([\x00-\x7f]|[\xc0-\xdf][\x80-\xbf]|' .
727 '[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xf7][\x80-\xbf]{3})+$/', $s ) : true );
728
729 if( ($wgInputEncoding != 'utf-8') and $ishigh and $isutf )
730 return @iconv( 'UTF-8', $wgInputEncoding, $s );
731
732 if( ($wgInputEncoding == 'utf-8') and $ishigh and !$isutf )
733 return utf8_encode( $s );
734
735 # Other languages can safely leave this function, or replace
736 # it with one to detect and convert another legacy encoding.
737 return $s;
738 }
739
740 /**
741 * Some languages have special punctuation to strip out
742 * or characters which need to be converted for MySQL's
743 * indexing to grok it correctly. Make such changes here.
744 *
745 * @param string $in
746 * @return string
747 */
748 function stripForSearch( $in ) {
749 return strtolower( $in );
750 }
751
752 function convertForSearchResult( $termsArray ) {
753 # some languages, e.g. Chinese, need to do a conversion
754 # in order for search results to be displayed correctly
755 return $termsArray;
756 }
757
758 /**
759 * Get the first character of a string. In ASCII, return
760 * first byte of the string. UTF8 and others have to
761 * overload this.
762 *
763 * @param string $s
764 * @return string
765 */
766 function firstChar( $s ) {
767 return $s[0];
768 }
769
770 function initEncoding() {
771 # Some languages may have an alternate char encoding option
772 # (Esperanto X-coding, Japanese furigana conversion, etc)
773 # If this language is used as the primary content language,
774 # an override to the defaults can be set here on startup.
775 #global $wgInputEncoding, $wgOutputEncoding, $wgEditEncoding;
776 }
777
778 function setAltEncoding() {
779 # Some languages may have an alternate char encoding option
780 # (Esperanto X-coding, Japanese furigana conversion, etc)
781 # If 'altencoding' is checked in user prefs, this gives a
782 # chance to swap out the default encoding settings.
783 #global $wgInputEncoding, $wgOutputEncoding, $wgEditEncoding;
784 }
785
786 function recodeForEdit( $s ) {
787 # For some languages we'll want to explicitly specify
788 # which characters make it into the edit box raw
789 # or are converted in some way or another.
790 # Note that if wgOutputEncoding is different from
791 # wgInputEncoding, this text will be further converted
792 # to wgOutputEncoding.
793 global $wgInputEncoding, $wgEditEncoding;
794 if( $wgEditEncoding == '' or
795 $wgEditEncoding == $wgInputEncoding ) {
796 return $s;
797 } else {
798 return $this->iconv( $wgInputEncoding, $wgEditEncoding, $s );
799 }
800 }
801
802 function recodeInput( $s ) {
803 # Take the previous into account.
804 global $wgInputEncoding, $wgOutputEncoding, $wgEditEncoding;
805 if($wgEditEncoding != "") {
806 $enc = $wgEditEncoding;
807 } else {
808 $enc = $wgOutputEncoding;
809 }
810 if( $enc == $wgInputEncoding ) {
811 return $s;
812 } else {
813 return $this->iconv( $enc, $wgInputEncoding, $s );
814 }
815 }
816
817 /**
818 * For right-to-left language support
819 *
820 * @return bool
821 */
822 function isRTL() { return false; }
823
824 /**
825 * To allow "foo[[bar]]" to extend the link over the whole word "foobar"
826 *
827 * @return bool
828 */
829 function linkPrefixExtension() { return false; }
830
831
832 function &getMagicWords() {
833 global $wgMagicWordsEn;
834 return $wgMagicWordsEn;
835 }
836
837 # Fill a MagicWord object with data from here
838 function getMagic( &$mw ) {
839 $raw = $this->getMagicWords();
840
841 wfRunHooks( 'LanguageGetMagic', array( &$raw ) );
842
843 if( !isset( $raw[$mw->mId] ) ) {
844 # Fall back to English if local list is incomplete
845 $raw =& Language::getMagicWords();
846 }
847 $rawEntry = $raw[$mw->mId];
848 $mw->mCaseSensitive = $rawEntry[0];
849 $mw->mSynonyms = array_slice( $rawEntry, 1 );
850 }
851
852 /**
853 * Italic is unsuitable for some languages
854 *
855 * @access public
856 *
857 * @param string $text The text to be emphasized.
858 * @return string
859 */
860 function emphasize( $text ) {
861 return "<em>$text</em>";
862 }
863
864 /**
865 * This function enables formatting of numbers, it should only come
866 * into effect when the $wgTranslateNumerals variable is TRUE.
867 *
868 * Normally we output all numbers in plain en_US style, that is
869 * 293,291.235 for twohundredninetythreethousand-twohundredninetyone
870 * point twohundredthirtyfive. However this is not sutable for all
871 * languages, some such as Pakaran want ੨੯੩,੨੯੫.੨੩੫ and others such as
872 * Icelandic just want to use commas instead of dots, and dots instead
873 * of commas like "293.291,235".
874 *
875 * An example of this function being called:
876 * <code>
877 * wfMsg( 'message', $wgLang->formatNum( $num ) )
878 * </code>
879 *
880 * See LanguageGu.php for the Gujarati implementation and
881 * LanguageIs.php for the , => . and . => , implementation.
882 *
883 * @todo check if it's viable to use localeconv() for the decimal
884 * seperator thing.
885 * @access public
886 * @param mixed $number the string to be formatted, should be an integer or
887 * a floating point number.
888 * @param bool $year are we being passed a year? (turns off commafication)
889 * @return mixed whatever we're fed if it's a year, a string otherwise.
890 */
891 function formatNum( $number, $year = false ) {
892 return $year ? $number : $this->commafy($number);
893 }
894
895 /**
896 * Adds commas to a given number
897 *
898 * @param mixed $_
899 * @return string
900 */
901 function commafy($_) {
902 return strrev((string)preg_replace('/(\d{3})(?=\d)(?!\d*\.)/','$1,',strrev($_)));
903 }
904
905 /**
906 * For the credit list in includes/Credits.php (action=credits)
907 *
908 * @param array $l
909 * @return string
910 */
911 function listToText( $l ) {
912 $s = '';
913 $m = count($l) - 1;
914 for ($i = $m; $i >= 0; $i--) {
915 if ($i == $m) {
916 $s = $l[$i];
917 } else if ($i == $m - 1) {
918 $s = $l[$i] . ' ' . wfMsg('and') . ' ' . $s;
919 } else {
920 $s = $l[$i] . ', ' . $s;
921 }
922 }
923 return $s;
924 }
925
926 # Crop a string from the beginning or end to a certain number of bytes.
927 # (Bytes are used because our storage has limited byte lengths for some
928 # columns in the database.) Multibyte charsets will need to make sure that
929 # only whole characters are included!
930 #
931 # $length does not include the optional ellipsis.
932 # If $length is negative, snip from the beginning
933 function truncate( $string, $length, $ellipsis = '' ) {
934 if( $length == 0 ) {
935 return $ellipsis;
936 }
937 if ( strlen( $string ) <= abs( $length ) ) {
938 return $string;
939 }
940 if( $length > 0 ) {
941 $string = substr( $string, 0, $length );
942 return $string . $ellipsis;
943 } else {
944 $string = substr( $string, $length );
945 return $ellipsis . $string;
946 }
947 }
948
949 /**
950 * Grammatical transformations, needed for inflected languages
951 * Invoked by putting {{grammar:case|word}} in a message
952 *
953 * @param string $word
954 * @param string $case
955 * @return string
956 */
957 function convertGrammar( $word, $case ) {
958 return $word;
959 }
960
961 /**
962 * Plural form transformations, needed for some languages.
963 * For example, where are 3 form of plural in Russian and Polish,
964 * depending on "count mod 10". See [[w:Plural]]
965 * For English it is pretty simple.
966 *
967 * Invoked by putting {{plural:count|wordform1|wordform2}}
968 * or {{plural:count|wordform1|wordform2|wordform3}}
969 *
970 * Example: {{plural:{{NUMBEROFARTICLES}}|article|articles}}
971 *
972 * @param integer $count
973 * @param string $wordform1
974 * @param string $wordform2
975 * @param string $wordform3 (optional)
976 * @return string
977 */
978 function convertPlural( $count, $wordform1, $wordform2, $wordform3) {
979 return $count == '1' ? $wordform1 : $wordform2;
980 }
981
982 /**
983 * For translaing of expiry times
984 * @param string The validated block time in English
985 * @return Somehow translated block time
986 * @see LanguageFi.php for example implementation
987 */
988 function translateBlockExpiry( $str ) {
989
990 $scBlockExpiryOptions = wfMsg( 'ipboptions' );
991
992 if ( $scBlockExpiryOptions == '-') {
993 return $str;
994 }
995
996 foreach (explode(',', $scBlockExpiryOptions) as $option) {
997 if ( strpos($option, ":") === false )
998 continue;
999 list($show, $value) = explode(":", $option);
1000 if ( strcmp ( $str, $value) == 0 )
1001 return '<span title="' . htmlspecialchars($str). '">' .
1002 htmlspecialchars( trim( $show ) ) . '</span>';
1003 }
1004
1005 return $str;
1006 }
1007
1008 /**
1009 * languages like Chinese need to be segmented in order for the diff
1010 * to be of any use
1011 *
1012 * @param string $text
1013 * @return string
1014 */
1015 function segmentForDiff( $text ) {
1016 return $text;
1017 }
1018
1019 /**
1020 * and unsegment to show the result
1021 *
1022 * @param string $text
1023 * @return string
1024 */
1025 function unsegmentForDiff( $text ) {
1026 return $text;
1027 }
1028
1029 # convert text to different variants of a language.
1030 function convert( $text, $isTitle = false) {
1031 return $this->mConverter->convert($text, $isTitle);
1032 }
1033
1034 /**
1035 * Perform output conversion on a string, and encode for safe HTML output.
1036 * @param string $text
1037 * @param bool $isTitle -- wtf?
1038 * @return string
1039 * @todo this should get integrated somewhere sane
1040 */
1041 function convertHtml( $text, $isTitle = false ) {
1042 return htmlspecialchars( $this->convert( $text, $isTitle ) );
1043 }
1044
1045 function convertCategoryKey( $key ) {
1046 return $this->mConverter->convertCategoryKey( $key );
1047 }
1048
1049 /**
1050 * get the list of variants supported by this langauge
1051 * see sample implementation in LanguageZh.php
1052 *
1053 * @return array an array of language codes
1054 */
1055 function getVariants() {
1056 return $this->mConverter->getVariants();
1057 }
1058
1059
1060 function getPreferredVariant() {
1061 return $this->mConverter->getPreferredVariant();
1062 }
1063
1064 /**
1065 * if a language supports multiple variants, it is
1066 * possible that non-existing link in one variant
1067 * actually exists in another variant. this function
1068 * tries to find it. See e.g. LanguageZh.php
1069 *
1070 * @param string $link the name of the link
1071 * @param mixed $nt the title object of the link
1072 * @return null the input parameters may be modified upon return
1073 */
1074 function findVariantLink( &$link, &$nt ) {
1075 $this->mConverter->findVariantLink($link, $nt);
1076 }
1077
1078 /**
1079 * returns language specific options used by User::getPageRenderHash()
1080 * for example, the preferred language variant
1081 *
1082 * @return string
1083 * @access public
1084 */
1085 function getExtraHashOptions() {
1086 return $this->mConverter->getExtraHashOptions();
1087 }
1088
1089 /**
1090 * for languages that support multiple variants, the title of an
1091 * article may be displayed differently in different variants. this
1092 * function returns the apporiate title defined in the body of the article.
1093 *
1094 * @return string
1095 */
1096 function getParsedTitle() {
1097 return $this->mConverter->getParsedTitle();
1098 }
1099
1100 /**
1101 * Enclose a string with the "no conversion" tag. This is used by
1102 * various functions in the Parser
1103 *
1104 * @param string $text text to be tagged for no conversion
1105 * @return string the tagged text
1106 */
1107 function markNoConversion( $text ) {
1108 return $this->mConverter->markNoConversion( $text );
1109 }
1110
1111 /**
1112 * A regular expression to match legal word-trailing characters
1113 * which should be merged onto a link of the form [[foo]]bar.
1114 *
1115 * @return string
1116 * @access public
1117 */
1118 function linkTrail() {
1119 return $this->getMessage( 'linktrail' );
1120 }
1121
1122 function getLangObj() {
1123 return $this;
1124 }
1125
1126 /**
1127 * Get the RFC 3066 code for this language object
1128 */
1129 function getCode() {
1130 return str_replace( '_', '-', strtolower( substr( get_class( $this ), 8 ) ) );
1131 }
1132
1133
1134 }
1135
1136 # FIXME: Merge all UTF-8 support code into Language base class.
1137 # We no longer support Latin-1 charset.
1138 require_once( 'LanguageUtf8.php' );
1139
1140 # This should fail gracefully if there's not a localization available
1141 wfSuppressWarnings();
1142 // Preload base classes to work around APC/PHP5 bug
1143 include_once( 'Language' . str_replace( '-', '_', ucfirst( $wgLanguageCode ) ) . '.deps.php' );
1144 include_once( 'Language' . str_replace( '-', '_', ucfirst( $wgLanguageCode ) ) . '.php' );
1145 wfRestoreWarnings();
1146
1147 }
1148 ?>