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