Index: units/languages/languages_item.php =================================================================== --- units/languages/languages_item.php (revision 13203) +++ units/languages/languages_item.php (working copy) @@ -56,17 +56,126 @@ return number_format($number, $precision, $this->GetDBField('DecimalPoint'), $this->GetDBField('ThousandSep')); } + /** + * Returns language id based on HTTP header "Accept-Language" + * + * @return int + */ + function processAcceptLanguage() + { + if (!array_key_exists('HTTP_ACCEPT_LANGUAGE', $_SERVER) || !$_SERVER['HTTP_ACCEPT_LANGUAGE']) { + return false; + } + + $accepted_languages = Array (); + $language_string = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']); + + foreach ($language_string as $mixed_language) { + if (strpos($mixed_language, ';') !== false) { + list ($language_locale, $language_quality) = explode(';', $mixed_language); + $language_quality = (float)substr($language_quality, 2); // format "q=4.45" + } + else { + $language_locale = $mixed_language; + $language_quality = 1.00; + } + + $accepted_languages[ trim($language_locale) ] = trim($language_quality); + } + + arsort($accepted_languages, SORT_NUMERIC); + + foreach ($accepted_languages as $language_locale => $language_quality) { + $language_id = $this->getAvailableLanguage($language_locale); + + if ($language_id) { + return $language_id; + } + } + + return false; + } + + /** + * Returns language ID based on given locale + * + * @param string $locale + * @return int + */ + function getAvailableLanguage($locale) + { + $cache_key = 'available_languages[%LangSerial%]'; + $available_languages = $this->Application->getCache($cache_key); + + if ($available_languages === false) { + $this->Conn->nextQueryCachable = true; + $sql = 'SELECT LanguageId, LOWER(Locale) AS Locale + FROM ' . TABLE_PREFIX . 'Language + WHERE Enabled = 1'; + $available_languages = $this->Conn->GetCol($sql, 'Locale'); + $this->Application->setCache($cache_key, $available_languages); + } + + if (strpos($locale, '-') !== false) { + // exact language match requested + return array_key_exists($locale, $available_languages) ? $available_languages[$locale] : false; + } + + // partial (like "en" matches "en-GB" and "en-US") language match required + foreach ($available_languages as $language_code => $language_id) { + list ($language_code, ) = explode('-', $language_code); + + if ($locale == $language_code) { + return $language_id; + } + } + + return false; + } + + /** + * Checks, that url is empty + * + * @return bool + */ + function isEmptyUrl() + { + if ($this->Application->RewriteURLs()) { + return !$this->Application->GetVar('_mod_rw_url_'); + } + + return !count($this->Application->HttpQuery->Get); + } + function Load($id, $id_field_name=null) { $default = false; if ($id == 'default') { - $id = 1; - $id_field_name = 'PrimaryLang'; $default = true; + $res = parent::Load(1, 'PrimaryLang', true); + + if ( + !$this->Application->isAdmin && $this->isEmptyUrl() && + $this->Application->ConfigValue('UseContentLanguageNegotiation') + ) { + $language_id = $this->processAcceptLanguage(); + + if ($language_id != $this->GetID()) { + // redirect to same page with found language + $url_params = Array ( + 'm_cat_id' => 0, 'm_cat_page' => 1, + 'm_lang' => $language_id, 'm_opener' => 's', + 'pass' => 'm' + ); + + $this->Application->Redirect('', $url_params); + } + } } + else { + $res = parent::Load($id, $id_field_name, true); + } - $res = parent::Load($id, $id_field_name, true); - if ($default) { if (!$res) { if ($this->Application->isAdmin) { @@ -86,6 +195,7 @@ $this->Application->SetVar('lang.current_id', $this->GetID() ); $this->Application->SetVar('m_lang', $this->GetID() ); } + return $res; } } \ No newline at end of file Index: units/helpers/mod_rewrite_helper.php =================================================================== --- units/helpers/mod_rewrite_helper.php (revision 13203) +++ units/helpers/mod_rewrite_helper.php (working copy) @@ -245,9 +245,9 @@ function InitAll() { + $this->Application->VerifyThemeId(); $this->Application->VerifyLanguageId(); $this->Application->Phrases->Init('phrases'); - $this->Application->VerifyThemeId(); } /** Index: kernel/utility/unit_config_reader.php =================================================================== --- kernel/utility/unit_config_reader.php (revision 13203) +++ kernel/utility/unit_config_reader.php (working copy) @@ -92,6 +92,7 @@ // output related 'UseModRewrite', + 'UseContentLanguageNegotiation', 'UseOutputCompression', 'OutputCompressionLevel', 'Config_Server_Time', Index: kernel/utility/http_query.php =================================================================== --- kernel/utility/http_query.php (revision 13203) +++ kernel/utility/http_query.php (working copy) @@ -234,10 +234,6 @@ function AfterInit() { -// $vars = $this->processQueryString($this->Get(ENV_VAR_NAME)); -// $this->AddParams($vars); -// $this->convertPostEvents(); - // if ($this->Application->RewriteURLs()) { if ($this->Application->RewriteURLs() || $this->Get('_mod_rw_url_')) { if (defined('DEBUG_MODE') && $this->Application->isDebugMode()) { $this->Application->Debugger->profileStart('url_parsing'); @@ -250,8 +246,8 @@ } } else { - $this->Application->VerifyLanguageId(); $this->Application->VerifyThemeId(); + $this->Application->VerifyLanguageId(); } } @@ -375,7 +371,9 @@ $module_params['editing_mode'] = ''; } - $env = $this->Application->BuildEnv( $this->Get('t'), $module_params, $passed, false, false ); + $module_params['__URLENCODE__'] = 1; + + $env = $this->Application->BuildEnv( $this->Get('t'), $module_params, $passed, false, false); $this->Set(ENV_VAR_NAME, $env); $_REQUEST['env'] = $_GET['env'] = $env; // for capability with old in-portal code } Index: install/upgrades.sql =================================================================== --- install/upgrades.sql (revision 13203) +++ install/upgrades.sql (working copy) @@ -1710,4 +1710,6 @@ cv.GroupDisplayOrder = (SELECT ca7.GroupDisplayOrder FROM <%TABLE_PREFIX%>ConfigurationAdmin ca7 WHERE ca7.VariableName = cv.VariableName), cv.`Install` = (SELECT ca8.`Install` FROM <%TABLE_PREFIX%>ConfigurationAdmin ca8 WHERE ca8.VariableName = cv.VariableName); -DROP TABLE ConfigurationAdmin; \ No newline at end of file +DROP TABLE ConfigurationAdmin; + +INSERT INTO ConfigurationValues VALUES(DEFAULT, 'UseContentLanguageNegotiation', '0', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsWebsite', 'la_config_UseContentLanguageNegotiation', 'checkbox', '', '', 10.021, 0, 0); \ No newline at end of file Index: install/install_data.sql =================================================================== --- install/install_data.sql (revision 13203) +++ install/install_data.sql (working copy) @@ -32,6 +32,7 @@ INSERT INTO ConfigurationValues VALUES(DEFAULT, 'PageHitCounter', '0', 'In-Portal', 'in-portal:configure_advanced', '', '', '', NULL, NULL, 0, 0, 0); INSERT INTO ConfigurationValues VALUES(DEFAULT, 'Site_Path', '/', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsWebsite', 'la_config_PathToWebsite', 'text', '', '', 10.01, 0, 1); INSERT INTO ConfigurationValues VALUES(DEFAULT, 'UseModRewrite', '0', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsWebsite', 'la_config_use_modrewrite', 'checkbox', '', '', 10.02, 0, 1); +INSERT INTO ConfigurationValues VALUES(DEFAULT, 'UseContentLanguageNegotiation', '0', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsWebsite', 'la_config_UseContentLanguageNegotiation', 'checkbox', '', '', 10.021, 0, 0); INSERT INTO ConfigurationValues VALUES(DEFAULT, 'cms_DefaultDesign', '#default_design#', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsWebsite', 'la_config_DefaultDesignTemplate', 'text', NULL, NULL, 10.03, 0, 0); INSERT INTO ConfigurationValues VALUES(DEFAULT, 'ErrorTemplate', 'error_notfound', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsWebsite', 'la_config_error_template', 'text', '', '', 10.04, 0, 0); INSERT INTO ConfigurationValues VALUES(DEFAULT, 'NoPermissionTemplate', 'no_permission', 'In-Portal', 'in-portal:configure_advanced', 'la_section_SettingsWebsite', 'la_config_nopermission_template', 'text', '', '', 10.05, 0, 0);