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