From 290b53ea9f8bd8f80840cb428657bbb4da422dc3 Mon Sep 17 00:00:00 2001 From: Tom Homer Date: Fri, 8 Dec 2017 09:20:42 -0500 Subject: [PATCH 1/2] Partial Fix for COM_getLanguageFromURL Fix for issue #819 - COM_getLanguageFromURL renamed to _getLanguageFromURL. Now should only be called by core - Unfortunately COM_getLanguage needs to get called almost right away when a visitor visits a page. This means if the language is not already set from a previous visit _getLanguageFromURL is required to guess at the language. Code still needs to be added to guess the language id for url_routing - Fix for switch language block to not display if user not allowed to change language. - Added to $_URL class that allows item (like a article or plugin) to set the id for the url and the language. This means no guessing by switch language block anymore - New code for plugins that uses $_URL class to support an item that has multiple languages (like topics, articles, staticpage). This may break multi-language support a bit for any other plugins that support this type of feature --- public_html/article.php | 11 ++ public_html/index.php | 10 ++ public_html/lib-common.php | 165 ++++++++++++++++-------------- public_html/staticpages/index.php | 10 ++ public_html/switchlang.php | 89 +++------------- system/classes/url.class.php | 62 +++++++++++ 6 files changed, 201 insertions(+), 146 deletions(-) diff --git a/public_html/article.php b/public_html/article.php index b17e46ea8..4cf65146e 100644 --- a/public_html/article.php +++ b/public_html/article.php @@ -111,6 +111,17 @@ function extractExternalLinks($text) { COM_handle404(); } +// If user is allowed to switch languages +if ($_CONF['allow_user_language'] == 1) { + // Let's figure out if page is for specific language + // If so let URL class know in case user changes language + $article_lang = COM_getLanguageIdForObject($sid); + if (!empty($sid) AND !empty($article_lang)) { + $_URL->setItemInfo($sid, $article_lang); + } +} + + // Get topic TOPIC_getTopic('article', $sid); diff --git a/public_html/index.php b/public_html/index.php index b6f48ab3b..a67831a49 100644 --- a/public_html/index.php +++ b/public_html/index.php @@ -118,6 +118,16 @@ function fixTopic(&$A, $tid_list) $page = (int) Geeklog\Input::get('page', 0); } +// If user is allowed to switch languages +if ($_CONF['allow_user_language'] == 1) { + // Let's figure out if topic is for specific language + // If so let URL class know in case user changes language + $topic_lang = COM_getLanguageIdForObject($topic); + if (!empty($topic) AND !empty($topic_lang)) { + $_URL->setItemInfo($topic, $topic_lang); + } +} + if ($topic_check === '-') { $topic_check = ''; } diff --git a/public_html/lib-common.php b/public_html/lib-common.php index 71eec33f7..328f027f7 100644 --- a/public_html/lib-common.php +++ b/public_html/lib-common.php @@ -6682,7 +6682,7 @@ function COM_getLanguage() // 1. Try to get language from URL // $langFile = COM_getLanguageFromBrowser(); - Removed line as it doesn't work with the switch language block (that uses phpblock_switch_language) for some setups when a language cookie is set, need to check that first. - $langFile = COM_getLanguageFromURL(); + $langFile = _getLanguageFromURL(); if (empty($langFile)) { if (!empty($_USER['language'])) { @@ -6710,6 +6710,89 @@ function COM_getLanguage() return $langFile; } +/** + * Get language name from current URL + * Note: This function starts with _ therefore it should only call from within core + * + * + * @return string e.g., 'english', 'japanese', ... + * @note code provided by hiroron + */ +function _getLanguageFromURL() +{ + global $_CONF, $_URL; + + $retval = ''; + + // If user is allowed to switch languages + if ($_CONF['allow_user_language'] == 1) { + $langId = ''; + // Need to see if language is set for url + if (!$_URL->itemSet()) { + // THERE ARE ISSUES with this and figuring out the language from the URL may be incorrect if for example "_en" is found elsewhere in the url (see https://github.com/Geeklog-Core/geeklog/issues/819) + // This is used if the anonymous user visits the page directly to figure out what language to display the site in. + // If the user is logged in or has a language cookie already set (by the switch language block) from before then that language is taken (done at the beginning of lib-common) + + // We need to figure out if there is a specific language specified in the url + // Since COM_getLanguage is called right at the beginning of lib-common we don't have the option of setting the $_URL language before hand + // so we must make our best guess based on the type of URL (normal, rewritten, routing) + + $url = COM_getCurrentURL(); + + if ($_CONF['url_rewrite']) { + if ($_CONF['url_routing']) { + // url_routing = 1 - enabled with index.php + // url_routing = 2 - enabled without index.php + + + + + + } else { + // for "rewritten" URLs we assume that the first parameter after + // [NG]the script name is the ID, e.g. /article.php/story-id-here_en + // 2017 fix hiroron /index.php/topic/home_ja or /index.php?topic=home_ja + $p = explode('/', $url); + $parts = count($p); + for ($i = 0; $i < $parts; $i++) { + if (strrpos($p[$i], '.php') !== false) { + for ($j = $i; $j < $parts; $j++) { + if (isset($p[$j])) { + $l = strrpos($p[$j], '_'); + if ($l !== false) { + $langId = substr($p[$j], $l + 1); + break; + } + } + } + break; + } + } + } + } else { // URL contains '?' or '&' + $url = explode('&', $url); + $urlpart = $url[0]; + $l = strrpos($urlpart, '_'); + if ($l !== false) { + $langId = substr($urlpart, $l + 1); + } + } + } else { + // This is used mainly by the switch language block (after the visitor has been on the site already) + // The item also had a chance to update $_URL with the correct language since if this code is executed it has most likely been called after lib-common has been loaded + $langId = $_URL->getLanguage(); // If empty no language is assumed + } + if (!empty($langId)) { + if (isset($_CONF['language_files']) && is_array($_CONF['language_files']) && + array_key_exists($langId, $_CONF['language_files'])) { + $retval = $_CONF['language_files'][$langId]; + } + } + } + + return $retval; +} + /** * Determine the language of the object from the id * @@ -6821,11 +6904,11 @@ function COM_getLangSQL($field, $type = 'WHERE', $table = '') */ function phpblock_switch_language() { - global $_CONF; + global $_CONF, $_URL; $retval = ''; - if (empty($_CONF['languages']) || empty($_CONF['language_files']) || + if ($_CONF['allow_user_language'] == 0 || empty($_CONF['languages']) || empty($_CONF['language_files']) || (count($_CONF['languages']) !== count($_CONF['language_files'])) ) { return $retval; @@ -6835,6 +6918,8 @@ function phpblock_switch_language() $langId = COM_getLanguageId($lang); $newLang = ''; $newLangId = ''; + // Figure out if we need to include language + $itemId = $_URL->getId(); if (count($_CONF['languages']) === 2) { foreach ($_CONF['languages'] as $key => $value) { @@ -6845,7 +6930,7 @@ function phpblock_switch_language() } } - $switchUrl = COM_buildURL($_CONF['site_url'] . '/switchlang.php?lang=' . $newLangId); + $switchUrl = COM_buildURL($_CONF['site_url'] . '/switchlang.php?lang=' . $newLangId . '&itemid' . $itemId); $retval .= COM_createLink($newLang, $switchUrl); } else { $retval .= '
' . LB; + $retval .= '' . LB; $retval .= '