Index: Defines.php =================================================================== RCS file: /cvsroot/wikipedia/phase3/includes/Defines.php,v retrieving revision 1.33 diff -u -r1.33 Defines.php --- Defines.php 27 Sep 2005 19:48:54 -0000 1.33 +++ Defines.php 9 Oct 2005 17:27:42 -0000 @@ -138,4 +138,12 @@ define( 'MW_DATE_ISO', 'ISO 8601' ); /**#@-*/ +/**#@+ + * Language detection selectors; + * see $wgDetectLanguage and User::detectLanguage() + */ +define( 'LANG_USE_CONTENT', '0' ); #no detection +define( 'LANG_PREFER_CONTENT', '1' ); #use content language if accepted +define( 'LANG_PREFER_CLIENT', '2' ); #use language most preferred by the client +/**#@-*/ ?> Index: DefaultSettings.php =================================================================== RCS file: /cvsroot/wikipedia/phase3/includes/DefaultSettings.php,v retrieving revision 1.377 diff -u -r1.377 DefaultSettings.php --- DefaultSettings.php 24 Sep 2005 00:49:55 -0000 1.377 +++ DefaultSettings.php 9 Oct 2005 17:27:45 -0000 @@ -511,6 +511,16 @@ /** Site language code, should be one of ./languages/Language(.*).php */ $wgLanguageCode = 'en'; +/** +* Configures language detection for anonymous users. +* Detection is based on the Accept-Language HTTP header. +* +* LANG_USE_CONTENT: always use the content language if not logged in +* LANG_PREFER_CONTENT: if the content language is in the Accept-Language header, use it. +* LANG_PREFER_CLIENT: use the language most prefered by the client (first in the list in Accept-Language). +*/ +$wgDetectLanguage = LANG_USE_CONTENT; + /** Treat language links as magic connectors, not inline links */ $wgInterwikiMagic = true; Index: OutputPage.php =================================================================== RCS file: /cvsroot/wikipedia/phase3/includes/OutputPage.php,v retrieving revision 1.244 diff -u -r1.244 OutputPage.php --- OutputPage.php 6 Oct 2005 14:20:45 -0000 1.244 +++ OutputPage.php 9 Oct 2005 17:27:47 -0000 @@ -349,14 +349,17 @@ } function sendCacheControl() { - global $wgUseSquid, $wgUseESI; + global $wgUseSquid, $wgUseESI, $wgDetectLanguage; if ($this->mETag) header("ETag: $this->mETag"); # don't serve compressed data to clients who can't handle it # maintain different caches for logged-in users and non-logged in ones - header( 'Vary: Accept-Encoding, Cookie' ); + # if language detection is enabled, use different caches for different languages + if ($wgDetectLanguage) header( 'Vary: Accept-Encoding, Cookie, Accept-Language' ); + else header( 'Vary: Accept-Encoding, Cookie' ); + if( !$this->uncacheableBecauseRequestvars() && $this->mEnableClientCache ) { if( $wgUseSquid && ! isset( $_COOKIE[ini_get( 'session.name') ] ) && ! $this->isPrintable() && $this->mSquidMaxage != 0 ) Index: User.php =================================================================== RCS file: /cvsroot/wikipedia/phase3/includes/User.php,v retrieving revision 1.185 diff -u -r1.185 User.php --- User.php 8 Oct 2005 20:15:36 -0000 1.185 +++ User.php 9 Oct 2005 17:27:50 -0000 @@ -328,14 +328,109 @@ /** * default language setting + * + * TODO: avoid calling detectLanguage for + * logged in users! */ - $variant = $wgContLang->getPreferredVariant(); + $variant = User::detectLanguage(); $defOpt['variant'] = $variant; $defOpt['language'] = $variant; return $defOpt; } - + + /** + * Detect the default language, according to $wgDetectLanguage. + * If $wgDetectLanguage is LANG_USE_CONTENT, this just returns + * the content language code. Otherwise, it tries to match + * the HTTP_ACCEPT_LANGUAGE header sent by the browser to an + * interface language. + * + * @return string the language code + * @static + * @access private + */ + function detectLanguage() { + global $wgDetectLanguage, $wgContLang; + + /** + * get content language + */ + $contLang = $wgContLang->getPreferredVariant(); + + if (!$wgDetectLanguage) { + return $contLang; + } + + /** + * get accepted languages from Accept-Languages + * HTTP header. + */ + $l= $_SERVER["HTTP_ACCEPT_LANGUAGE"]; + + if (empty($l)) return $contLang; + + $l= split(',',$l); + + /** + * normalize accepted languages + */ + $languages= array(); + foreach ($l as $lan) { + $lan= trim($lan); + + $idx= strpos($lan,';'); + if ($idx !== false) { + #HACK: qualifiers are ignored, order is relevant! + $lan= substr($lan,0,$idx); + $lan= trim($lan); + } + + $languages[]= $lan; + + $idx= strpos($lan,'-'); + if ($idx !== false) { + $lan= substr($lan,0,$idx); + $languages[]= $lan; + } + } + + /** + * see if the content language is accepted by the + * client. + */ + if ( ($wgDetectLanguage == LANG_PREFER_CONTENT) + && in_array($contLang,$languages) ) { + return $contLang; + } + + /** + * look for a language that is acceptable to the client + * and known to the wiki. + */ + $known = $wgContLang->getLanguageNames(); + foreach($known as $code => $name) { + /** + * TODO: only accept languages for which an implementation exists. + * this is disabled, because it's slow. Note that this code is + * executed for every page request! + */ + /* + global $IP; + $langfile="$IP/languages/Language".str_replace('-', '_', ucfirst($code)).".php"; + if(!file_exists($langfile)) { + continue; + } + */ + + if (in_array($code,$languages)) { + return $code; + } + } + + return $contLang; + } + /** * Get a given default option value. *