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