Index: trunk/tools/ToolserverI18N/TsIntuition.php |
— | — | @@ -1217,11 +1217,48 @@ |
1218 | 1218 | } |
1219 | 1219 | |
1220 | 1220 | /** |
| 1221 | + * Return a list of acceptable languages from an Accept-Language header |
| 1222 | + * @param $acceptLanguage String List of language tags, as given in |
| 1223 | + * http Accept-Language header (omit to fetch from $_SERVER['HTTP_ACCEPT_LANGUAGE']) |
| 1224 | + * @return array sorted with the candidate languages as keys and q-values asvalues. |
| 1225 | + */ |
| 1226 | + static function acceptableLanguages($acceptLanguage = false) { |
| 1227 | + if ( $acceptLanguage === false ) { |
| 1228 | + $acceptLanguage = @$_SERVER['HTTP_ACCEPT_LANGUAGE']; |
| 1229 | + } |
| 1230 | + |
| 1231 | + $acceptableLanguages = array(); |
| 1232 | + |
| 1233 | + //Accept-Language: 1#( language-range [ ";" "q" "=" qvalue ] ) |
| 1234 | + //The list of elements is separated by comma and optional LWS |
| 1235 | + $languages = explode( ',', $acceptLanguage ); |
| 1236 | + foreach ( $languages as $language ) { |
| 1237 | + $language = trim( $language ); // Remove optional LWS |
| 1238 | + |
| 1239 | + // Extract the language-range and q-value |
| 1240 | + if ( !preg_match( '/^([A-Za-z]{1,8}(?:-[A-Za-z]{1,8})*|\*)(?:\s*;\s*q\s*=\s*([01](?:\.[0-9]{0,3})?))?$/', $language, $m ) ) |
| 1241 | + continue; |
| 1242 | + |
| 1243 | + // We are not interested in the total match. |
| 1244 | + array_shift( $m ); |
| 1245 | + $m[] = 1; // Default q-value is 1 |
| 1246 | + list( $languageRange, $qvalue ) = $m; |
| 1247 | + |
| 1248 | + $acceptableLanguages[$languageRange] = $qvalue; |
| 1249 | + } |
| 1250 | + |
| 1251 | + arsort( $acceptableLanguages, SORT_NUMERIC ); // This is not an stable sort, but it isn't needed |
| 1252 | + |
| 1253 | + return $acceptableLanguages; |
| 1254 | + } |
| 1255 | + |
| 1256 | + /** |
1221 | 1257 | * Check language choice tree in the following order: |
1222 | 1258 | * - First: Construct override |
1223 | 1259 | * - Second: Parameter override |
1224 | 1260 | * - Third: Saved cookie |
1225 | | - * - Fourth: Nothing (default stays) |
| 1261 | + * - Fourth: Preferences from Accept-Language header |
| 1262 | + * - Fifth: English (default stays) |
1226 | 1263 | * |
1227 | 1264 | * @private |
1228 | 1265 | * |
— | — | @@ -1238,7 +1275,35 @@ |
1239 | 1276 | if ( !$set && isset( $_COOKIE[ $this->cookieNames['userlang'] ] ) ) { |
1240 | 1277 | $set = $this->setLang( $_COOKIE[ $this->cookieNames['userlang'] ] ); |
1241 | 1278 | } |
| 1279 | + |
1242 | 1280 | if ( !$set ) { |
| 1281 | + $acceptableLanguages = self::acceptableLanguages(); |
| 1282 | + foreach ( $acceptableLanguages as $lang => $q ) { |
| 1283 | + |
| 1284 | + if ( $lang == '*' ) { |
| 1285 | + /* We choose the first available language which is not in $acceptableLanguages |
| 1286 | + * The special * range matches every tag not matched by any other range, languages |
| 1287 | + * present in $acceptableLanguages will either have a lower q-value, or be missing |
| 1288 | + * from availableLanguages. |
| 1289 | + * The order will be the one in the i18n file: en, af, ar... |
| 1290 | + */ |
| 1291 | + |
| 1292 | + foreach ( $this->availableLanguages as $lang => $true ) { |
| 1293 | + if (! isset( $acceptableLanguages[$lang] ) ) { |
| 1294 | + $set = $lang; |
| 1295 | + break; |
| 1296 | + } |
| 1297 | + } |
| 1298 | + if ( $set ) |
| 1299 | + break; |
| 1300 | + } elseif ( isset( $this->availableLanguages[$lang] ) ) { |
| 1301 | + $set = $lang; |
| 1302 | + break; |
| 1303 | + } |
| 1304 | + } |
| 1305 | + } |
| 1306 | + |
| 1307 | + if ( !$set ) { |
1243 | 1308 | $set = $this->setLang( 'en' ); |
1244 | 1309 | } |
1245 | 1310 | return $set; |