merged master
[lhc/web/wiklou.git] / languages / Language.php
index 1ef5a74..fdea3d8 100644 (file)
@@ -139,6 +139,22 @@ class Language {
                'hijri-calendar-m10', 'hijri-calendar-m11', 'hijri-calendar-m12'
        );
 
+       /**
+        * @since 1.20
+        * @var array
+        */
+       static public $durationIntervals = array(
+               'millennia' => 31557600000,
+               'centuries' => 3155760000,
+               'decades' => 315576000,
+               'years' => 31557600, // 86400 * 365.25
+               'weeks' => 604800,
+               'days' => 86400,
+               'hours' => 3600,
+               'minutes' => 60,
+               'seconds' => 1,
+       );
+
        /**
         * Get a cached language object for a given language code
         * @param $code String
@@ -229,6 +245,17 @@ class Language {
         * @return bool
         */
        public static function isValidBuiltInCode( $code ) {
+
+               if( !is_string($code) ) {
+                       $type = gettype( $code );
+                       if( $type === 'object' ) {
+                               $addmsg = " of class " . get_class( $code );
+                       } else {
+                               $addmsg = '';
+                       }
+                       throw new MWException( __METHOD__ . " must be passed a string, $type given$addmsg" );
+               }
+
                return preg_match( '/^[a-z0-9-]+$/i', $code );
        }
 
@@ -376,6 +403,16 @@ class Language {
         */
        public function setNamespaces( array $namespaces ) {
                $this->namespaceNames = $namespaces;
+               $this->mNamespaceIds = null;
+       }
+
+       /**
+        * Resets all of the namespace caches. Mainly used for testing
+        */
+       public function resetNamespaces( ) {
+               $this->namespaceNames = null;
+               $this->mNamespaceIds = null;
+               $this->namespaceAliases = null;
        }
 
        /**
@@ -556,7 +593,6 @@ class Language {
         */
        function getVariantname( $code, $usemsg = true ) {
                $msg = "variantname-$code";
-               list( $rootCode ) = explode( '-', $code );
                if ( $usemsg && wfMessage( $msg )->exists() ) {
                        return $this->getMessageFromDB( $msg );
                }
@@ -685,9 +721,9 @@ class Language {
         *              Use null for autonyms (native names)
         * @param $include string:
         *              'all' all available languages
-        *              'mw' only if the language is defined in MediaWiki or wgExtraLanguageNames
+        *              'mw' only if the language is defined in MediaWiki or wgExtraLanguageNames (default)
         *              'mwfile' only if the language is in 'mw' *and* has a message file
-        * @return array|bool: language code => language name, false if $include is wrong
+        * @return array: language code => language name
         * @since 1.20
         */
        public static function fetchLanguageNames( $inLanguage = null, $include = 'mw' ) {
@@ -725,9 +761,7 @@ class Language {
                        $returnMw[$coreCode] = $names[$coreCode];
                }
 
-               if( $include === 'mw' ) {
-                       return $returnMw;
-               } elseif( $include === 'mwfile' ) {
+               if( $include === 'mwfile' ) {
                        $namesMwFile = array();
                        # We do this using a foreach over the codes instead of a directory
                        # loop so that messages files in extensions will work correctly.
@@ -738,7 +772,8 @@ class Language {
                        }
                        return $namesMwFile;
                }
-               return false;
+               # 'mw' option; default if it's not one of the other two options (all/mwfile)
+               return $returnMw;
        }
 
        /**
@@ -1909,6 +1944,63 @@ class Language {
                return $this->sprintfDate( $df, $ts );
        }
 
+       /**
+        * Takes a number of seconds and turns it into a text using values such as hours and minutes.
+        *
+        * @since 1.20
+        *
+        * @param integer $seconds The amount of seconds.
+        * @param array $chosenIntervals The intervals to enable.
+        *
+        * @return string
+        */
+       public function formatDuration( $seconds, array $chosenIntervals = array() ) {
+               $intervals = $this->getDurationIntervals( $seconds, $chosenIntervals );
+
+               $segments = array();
+
+               foreach ( $intervals as $intervalName => $intervalValue ) {
+                       $message = new Message( 'duration-' . $intervalName, array( $intervalValue ) );
+                       $segments[] = $message->inLanguage( $this )->escaped();
+               }
+
+               return $this->listToText( $segments );
+       }
+
+       /**
+        * Takes a number of seconds and returns an array with a set of corresponding intervals.
+        * For example 65 will be turned into array( minutes => 1, seconds => 5 ).
+        *
+        * @since 1.20
+        *
+        * @param integer $seconds The amount of seconds.
+        * @param array $chosenIntervals The intervals to enable.
+        *
+        * @return array
+        */
+       public function getDurationIntervals( $seconds, array $chosenIntervals = array() ) {
+               if ( empty( $chosenIntervals ) ) {
+                       $chosenIntervals = array( 'millennia', 'centuries', 'decades', 'years', 'days', 'hours', 'minutes', 'seconds' );
+               }
+
+               $intervals = array_intersect_key( self::$durationIntervals, array_flip( $chosenIntervals ) );
+               $sortedNames = array_keys( $intervals );
+               $smallestInterval = array_pop( $sortedNames );
+
+               $segments = array();
+
+               foreach ( $intervals as $name => $length ) {
+                       $value = floor( $seconds / $length );
+
+                       if ( $value > 0 || ( $name == $smallestInterval && empty( $segments ) ) ) {
+                               $seconds -= $value * $length;
+                               $segments[$name] = $value;
+                       }
+               }
+
+               return $segments;
+       }
+
        /**
         * Internal helper function for userDate(), userTime() and userTimeAndDate()
         *
@@ -2636,12 +2728,26 @@ class Language {
        }
 
        /**
-        * An arrow, depending on the language direction
+        * An arrow, depending on the language direction.
         *
+        * @param $direction String: the direction of the arrow: forwards (default), backwards, left, right, up, down.
         * @return string
         */
-       function getArrow() {
-               return $this->isRTL() ? '←' : '→';
+       function getArrow( $direction = 'forwards' ) {
+               switch ( $direction ) {
+               case 'forwards':
+                       return $this->isRTL() ? '←' : '→';
+               case 'backwards':
+                       return $this->isRTL() ? '→' : '←';
+               case 'left':
+                       return '←';
+               case 'right':
+                       return '→';
+               case 'up':
+                       return '↑';
+               case 'down':
+                       return '↓';
+               }
        }
 
        /**
@@ -3234,7 +3340,18 @@ class Language {
                }
                return $word;
        }
-
+       /**
+        * Get the grammar forms for the content language
+        * @return array of grammar forms
+        * @since 1.20
+        */
+       function getGrammarForms() {
+               global $wgGrammarForms;
+               if ( isset( $wgGrammarForms[$this->getCode()] ) && is_array( $wgGrammarForms[$this->getCode()] ) ) {
+                        return $wgGrammarForms[$this->getCode()];
+               }
+               return array();
+       }
        /**
         * Provides an alternative text depending on specified gender.
         * Usage {{gender:username|masculine|feminine|neutral}}.