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