From 894c5c108d7fbc5bd3b6f245849116b78157a816 Mon Sep 17 00:00:00 2001 From: Liangent Date: Mon, 28 May 2012 18:51:53 +0800 Subject: [PATCH] Tweak Accept-Language sorting method to respect RFC 3282. Now in Accept-Language handling (in the language converter), languages appearing earlier in the list are treated as more preferred languages (variants). Change-Id: Ic50d01f52dce1ae1f4f4e747d5f8b8399ca03b0b --- includes/WebRequest.php | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/includes/WebRequest.php b/includes/WebRequest.php index 39c1b1ba3c..7d0dd4a13f 100644 --- a/includes/WebRequest.php +++ b/includes/WebRequest.php @@ -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; } -- 2.20.1