translateBlockExpiry: Duration is block expiry minus current time
[lhc/web/wiklou.git] / languages / Language.php
index 0e91e2e..68727bb 100644 (file)
@@ -2100,17 +2100,15 @@ class Language {
                $data = explode( '|', $tz, 3 );
 
                if ( $data[0] == 'ZoneInfo' ) {
-                       MediaWiki\suppressWarnings();
-                       $userTZ = timezone_open( $data[2] );
-                       MediaWiki\restoreWarnings();
-                       if ( $userTZ !== false ) {
-                               $date = date_create( $ts, timezone_open( 'UTC' ) );
-                               date_timezone_set( $date, $userTZ );
-                               $date = date_format( $date, 'YmdHis' );
-                               return $date;
+                       try {
+                               $userTZ = new DateTimeZone( $data[2] );
+                               $date = new DateTime( $ts, new DateTimeZone( 'UTC' ) );
+                               $date->setTimezone( $userTZ );
+                               return $date->format( 'YmdHis' );
+                       } catch ( Exception $e ) {
+                               // Unrecognized timezone, default to 'Offset' with the stored offset.
+                               $data[0] = 'Offset';
                        }
-                       # Unrecognized timezone, default to 'Offset' with the stored offset.
-                       $data[0] = 'Offset';
                }
 
                if ( $data[0] == 'System' || $tz == '' ) {
@@ -2580,7 +2578,7 @@ class Language {
 
        /**
         * @param string $key
-        * @return array|null
+        * @return string|null
         */
        public function getMessage( $key ) {
                return self::$dataCache->getSubitem( $this->mCode, 'messages', $key );
@@ -3737,6 +3735,43 @@ class Language {
                        return $wgGrammarForms[$this->getCode()][$case][$word];
                }
 
+               $grammarTransformations = $this->getGrammarTransformations();
+
+               if ( isset( $grammarTransformations[$case] ) ) {
+                       $forms = $grammarTransformations[$case];
+
+                       // Some names of grammar rules are aliases for other rules.
+                       // In such cases the value is a string rather than object,
+                       // so load the actual rules.
+                       if ( is_string( $forms ) ) {
+                               $forms = $grammarTransformations[$forms];
+                       }
+
+                       foreach ( array_values( $forms ) as $rule ) {
+                               $form = $rule[0];
+
+                               if ( $form === '@metadata' ) {
+                                       continue;
+                               }
+
+                               $replacement = $rule[1];
+
+                               $regex = '/' . addcslashes( $form, '/' ) . '/u';
+                               $patternMatches = preg_match( $regex, $word );
+
+                               if ( $patternMatches === false ) {
+                                       wfLogWarning(
+                                               'An error occurred while processing grammar. ' .
+                                               "Word: '$word'. Regex: /$form/."
+                                       );
+                               } elseif ( $patternMatches === 1 ) {
+                                       $word = preg_replace( $regex, $replacement, $word );
+
+                                       break;
+                               }
+                       }
+               }
+
                return $word;
        }
 
@@ -3940,10 +3975,11 @@ class Language {
         *
         * @param string $str The validated block duration in English
         * @param User $user User object to use timezone from or null for $wgUser
+        * @param int $now Current timestamp, for formatting relative block durations
         * @return string Somehow translated block duration
         * @see LanguageFi.php for example implementation
         */
-       function translateBlockExpiry( $str, User $user = null ) {
+       function translateBlockExpiry( $str, User $user = null, $now = 0 ) {
                $duration = SpecialBlock::getSuggestedDurations( $this );
                foreach ( $duration as $show => $value ) {
                        if ( strcmp( $str, $value ) == 0 ) {
@@ -3960,12 +3996,13 @@ class Language {
                }
 
                // If all else fails, return a standard duration or timestamp description.
-               $time = strtotime( $str, 0 );
+               $time = strtotime( $str, $now );
                if ( $time === false ) { // Unknown format. Return it as-is in case.
                        return $str;
-               } elseif ( $time !== strtotime( $str, 1 ) ) { // It's a relative timestamp.
-                       // $time is relative to 0 so it's a duration length.
-                       return $this->formatDuration( $time );
+               } elseif ( $time !== strtotime( $str, $now + 1 ) ) { // It's a relative timestamp.
+                       // The result differs based on current time, so the difference
+                       // is a fixed duration length.
+                       return $this->formatDuration( $time - $now );
                } else { // It's an absolute timestamp.
                        if ( $time === 0 ) {
                                // wfTimestamp() handles 0 as current time instead of epoch.