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