Merge "Tweak Accept-Language sorting method to respect RFC 3282."
authorPlatonides <platonides@gmail.com>
Mon, 28 May 2012 16:33:07 +0000 (16:33 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Mon, 28 May 2012 16:33:07 +0000 (16:33 +0000)
includes/WebRequest.php

index 39c1b1b..7d0dd4a 100644 (file)
@@ -981,7 +981,8 @@ HTML;
 
        /**
         * Parse the Accept-Language header sent by the client into an array
-        * @return array array( languageCode => q-value ) sorted by q-value in descending order
+        * @return array array( languageCode => q-value ) sorted by q-value in descending order then
+        *                                                appearing time in the header in ascending order.
         * May contain the "language" '*', which applies to languages other than those explicitly listed.
         * This is aligned with rfc2616 section 14.4
         */
@@ -1004,19 +1005,25 @@ HTML;
                        return array();
                }
 
-               // Create a list like "en" => 0.8
-               $langs = array_combine( $lang_parse[1], $lang_parse[4] );
+               $langcodes = $lang_parse[1];
+               $qvalues = $lang_parse[4];
+               $indices = range( 0, count( $lang_parse[1] ) - 1 );
                // Set default q factor to 1
-               foreach ( $langs as $lang => $val ) {
-                       if ( $val === '' ) {
-                               $langs[$lang] = 1;
-                       } elseif ( $val == 0 ) {
-                               unset($langs[$lang]);
+               foreach ( $indices as $index ) {
+                       if ( $qvalues[$index] === '' ) {
+                               $qvalues[$index] = 1;
+                       } elseif ( $qvalues[$index] == 0 ) {
+                               $langcodes[$index] = '';
                        }
                }
 
                // Sort list
-               arsort( $langs, SORT_NUMERIC );
+               array_multisort( $qvalues, SORT_DESC, SORT_NUMERIC, $indices, $langcodes );
+               // Create a list like "en" => 0.8
+               $langs = array_combine( $langcodes, $qvalues );
+               if ( isset( $langs[''] ) ) {
+                       unset( $langs[''] );
+               }
                return $langs;
        }