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