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