Merge "IcuCollation::$tailoringFirstLetters: 'sv', 'vi' verified"
[lhc/web/wiklou.git] / languages / Language.php
index 5538ac8..42883b5 100644 (file)
@@ -44,7 +44,6 @@ if ( function_exists( 'mb_strtoupper' ) ) {
  * @ingroup Language
  */
 class FakeConverter {
-
        /**
         * @var Language
         */
@@ -349,12 +348,12 @@ class Language {
        public static function isValidBuiltInCode( $code ) {
 
                if ( !is_string( $code ) ) {
-                       $type = gettype( $code );
-                       if ( $type === 'object' ) {
+                       if ( is_object( $code ) ) {
                                $addmsg = " of class " . get_class( $code );
                        } else {
                                $addmsg = '';
                        }
+                       $type = gettype( $code );
                        throw new MWException( __METHOD__ . " must be passed a string, $type given$addmsg" );
                }
 
@@ -531,7 +530,7 @@ class Language {
        /**
         * Resets all of the namespace caches. Mainly used for testing
         */
-       public function resetNamespaces( ) {
+       public function resetNamespaces() {
                $this->namespaceNames = null;
                $this->mNamespaceIds = null;
                $this->namespaceAliases = null;
@@ -3007,6 +3006,18 @@ class Language {
                return $number;
        }
 
+       /**
+        * Front-end for non-commafied formatNum
+        *
+        * @param mixed $number the string to be formatted, should be an integer
+        *        or a floating point number.
+        * @since 1.21
+        * @return string
+        */
+       public function formatNumNoSeparators( $number ) {
+               return $this->formatNum( $number, true );
+       }
+
        /**
         * @param $number string
         * @return string
@@ -3067,7 +3078,7 @@ class Language {
                                if ( $start < 0 ) {
                                        $start = 0;
                                }
-                               $groupedNumber = substr( $number , $start, $end -$start ) . $groupedNumber ;
+                               $groupedNumber = substr( $number, $start, $end -$start ) . $groupedNumber ;
                                $end = $start;
                                if ( $numMatches > 1 ) {
                                        // use the last pattern for the rest of the number
@@ -3520,18 +3531,19 @@ class Language {
                        return '';
                }
 
-               // Handle explicit 0= and 1= forms
+               // Handle explicit n=pluralform cases
                foreach ( $forms as $index => $form ) {
-                       if ( isset( $form[1] ) && $form[1] === '=' ) {
-                               if ( $form[0] === (string) $count ) {
-                                       return substr( $form, 2 );
+                       if ( preg_match( '/\d+=/i', $form ) ) {
+                               $pos = strpos( $form, '=' );
+                               if ( substr( $form, 0, $pos ) === (string) $count ) {
+                                       return substr( $form, $pos + 1 );
                                }
                                unset( $forms[$index] );
                        }
                }
                $forms = array_values( $forms );
 
-               $pluralForm = $this->getPluralForm( $count );
+               $pluralForm = $this->getPluralRuleIndexNumber( $count );
                $pluralForm = min( $pluralForm, count( $forms ) - 1 );
                return $forms[$pluralForm];
        }
@@ -3971,6 +3983,45 @@ class Language {
                }
        }
 
+       /**
+        * Get the ordered list of fallback languages, ending with the fallback
+        * language chain for the site language.
+        *
+        * @since 1.21
+        * @param $code string Language code
+        * @return array
+        */
+       public static function getFallbacksIncludingSiteLanguage( $code ) {
+               global $wgLanguageCode;
+
+               // Usually, we will only store a tiny number of fallback chains, so we
+               // keep them in static memory.
+               static $fallbackLanguageCache = array();
+               $cacheKey = "{$code}-{$wgLanguageCode}";
+
+               if ( !array_key_exists( $cacheKey, $fallbackLanguageCache ) ) {
+                       $fallbacks = self::getFallbacksFor( $code );
+
+                       // Take the final 'en' off of the array before splicing
+                       if ( end( $fallbacks ) === 'en' ) {
+                               array_pop( $fallbacks );
+                       }
+                       // Append the site's fallback chain
+                       $siteFallbacks = self::getFallbacksFor( $wgLanguageCode );
+
+                       // Eliminate any languages already included in the chain
+                       $siteFallbacks = array_intersect( array_diff( $siteFallbacks, $fallbacks ), $siteFallbacks );
+                       if ( $siteFallbacks ) {
+                               $fallbacks = array_merge( $fallbacks, $siteFallbacks );
+                       }
+                       if ( end( $fallbacks ) !== 'en' ) {
+                               $fallbacks[] = 'en';
+                       }
+                       $fallbackLanguageCache[$cacheKey] = $fallbacks;
+               }
+               return $fallbackLanguageCache[$cacheKey];
+       }
+
        /**
         * Get all messages for a given language
         * WARNING: this may take a long time. If you just need all message *keys*
@@ -4358,7 +4409,7 @@ class Language {
        /**
         * Get the plural rules for the language
         * @since 1.20
-        * @return array Associative array with plural form, and plural rule as key-value pairs
+        * @return array Associative array with plural form number and plural rule as key-value pairs
         */
        public function getPluralRules() {
                $pluralRules = self::$dataCache->getItem( strtolower( $this->mCode ), 'pluralRules' );
@@ -4375,13 +4426,48 @@ class Language {
        }
 
        /**
-        * Find the plural form matching to the given number
-        * It return the form index.
-        * @return int The index of the plural form
+        * Get the plural rule types for the language
+        * @since 1.21
+        * @return array Associative array with plural form number and plural rule type as key-value pairs
         */
-       private function getPluralForm( $number ) {
+       public function getPluralRuleTypes() {
+               $pluralRuleTypes = self::$dataCache->getItem( strtolower( $this->mCode ), 'pluralRuleTypes' );
+               $fallbacks = Language::getFallbacksFor( $this->mCode );
+               if ( !$pluralRuleTypes ) {
+                       foreach ( $fallbacks as $fallbackCode ) {
+                               $pluralRuleTypes = self::$dataCache->getItem( strtolower( $fallbackCode ), 'pluralRuleTypes' );
+                               if ( $pluralRuleTypes ) {
+                                       break;
+                               }
+                       }
+               }
+               return $pluralRuleTypes;
+       }
+
+       /**
+        * Find the index number of the plural rule appropriate for the given number
+        * @return int The index number of the plural rule
+        */
+       public function getPluralRuleIndexNumber( $number ) {
                $pluralRules = $this->getCompiledPluralRules();
                $form = CLDRPluralRuleEvaluator::evaluateCompiled( $number, $pluralRules );
                return $form;
        }
+
+       /**
+        * Find the plural rule type appropriate for the given number
+        * For example, if the language is set to Arabic, getPluralType(5) should
+        * return 'few'.
+        * @since 1.21
+        * @return string The name of the plural rule type, e.g. one, two, few, many
+        */
+       public function getPluralRuleType( $number ) {
+               $index = $this->getPluralRuleIndexNumber( $number );
+               $pluralRuleTypes = $this->getPluralRuleTypes();
+               if ( isset( $pluralRuleTypes[$index] ) ) {
+                       return $pluralRuleTypes[$index];
+               } else {
+                       return 'other';
+               }
+       }
 }