From 67c0b2d045feda1f776ff2a1d85fe132b6023c56 Mon Sep 17 00:00:00 2001 From: CaMer0n Date: Fri, 10 Sep 2010 01:01:48 +0000 Subject: [PATCH] Port 0.7 language handling changes to 0.8 --- class2.php | 226 ++---------------------- e107_handlers/e107_class.php | 19 +- e107_handlers/language_class.php | 289 ++++++++++++++++++++++++++++++- 3 files changed, 310 insertions(+), 224 deletions(-) diff --git a/class2.php b/class2.php index 3b7299209..e4c91be1b 100644 --- a/class2.php +++ b/class2.php @@ -223,6 +223,7 @@ $e107_paths = compact('ADMIN_DIRECTORY', 'FILES_DIRECTORY', 'IMAGES_DIRECTORY', $sql_info = compact('mySQLserver', 'mySQLuser', 'mySQLpassword', 'mySQLdefaultdb', 'mySQLprefix'); $e107 = e107::getInstance()->initCore($e107_paths, realpath(dirname(__FILE__)), $sql_info, varset($E107_CONFIG, array())); + // MOVED TO $e107->set_request() //$inArray = array("'", ';', '/**/', '/UNION/', '/SELECT/', 'AS '); //if (strpos($_SERVER['PHP_SELF'], 'trackback') === false) @@ -236,40 +237,7 @@ $e107 = e107::getInstance()->initCore($e107_paths, realpath(dirname(__FILE__)), // } //} -/** - * set CHARSET for backward compatibility - */ -//define('CHARSET', 'utf-8'); moved to e107->set_constants() -// remove ajax_used=1 from query string to avoid SELF problems, ajax should always be detected via e_AJAX_REQUEST constant -// MOVED TO $e107->prepare_request() -//$_SERVER['QUERY_STRING'] = str_replace(array('ajax_used=1', '&&'), array('', '&'), $_SERVER['QUERY_STRING']); - -// -// G: Retrieve Query data from URI -// (Until this point, we have no idea what the user wants to do) -// - -// MOVED TO $e107->set_request() -//if (strpos($_SERVER['QUERY_STRING'], ']') && preg_match("#\[(.*?)](.*)#", $_SERVER['QUERY_STRING'], $matches)) -//{ -// define('e_MENU', $matches[1]); -// $e_QUERY = $matches[2]; -// if(strlen(e_MENU) == 2) // language code ie. [fr] -// { -// require_once(e_HANDLER."language_class.php"); -// $slng = new language; -// define('e_LANCODE', true); -// $_GET['elan'] = $slng->convert(e_MENU); -// } -// -//} -//else -//{ -// define('e_MENU', ''); -// $e_QUERY = $_SERVER['QUERY_STRING']; -// define('e_LANCODE', ''); -//} // // Start the parser; use it to grab the full query string @@ -447,7 +415,11 @@ $menu_pref = e107::getConfig('menu')->getPref(); //extract menu prefs -$sql->db_Mark_Time('(Extracting Core Prefs Done)'); +// $sql->db_Mark_Time('(Extracting Core Prefs Done)'); + +$sql->db_Mark_Time('Start: Init Language and detect changes'); + +e107::getLanguage()->detect(); // // M: Subdomain and Language Selection @@ -462,44 +434,15 @@ define('e_COOKIE', $pref['cookie_name']); //define('SITEURLBASE', ($pref['ssl_enabled'] == '1' ? 'https://' : 'http://').$_SERVER['HTTP_HOST']); //define('SITEURL', SITEURLBASE.e_HTTP); -/* - * FIXME - pack all Language related code below to Language handler (new or extend the existing one) - */ - -// let the subdomain determine the language (when enabled). -if(varset($pref['multilanguage_subdomain']) && ($pref['user_tracking'] == 'session') && e_DOMAIN && MULTILANG_SUBDOMAIN !== FALSE) -{ - $mtmp = explode("\n", $pref['multilanguage_subdomain']); - foreach($mtmp as $val) - { - if(e_DOMAIN == trim($val)) - { - $domain_active = TRUE; - break; - } - } - - if($domain_active || ($pref['multilanguage_subdomain'] == '1')) - { - e107_ini_set('session.cookie_domain', '.'.e_DOMAIN); - require_once(e_HANDLER.'language_class.php'); - $slng = new language; - if(!e_SUBDOMAIN) - { - $GLOBALS['elan'] = $pref['sitelanguage']; - } - elseif($eln = $slng->convert(e_SUBDOMAIN)) - { - $GLOBALS['elan'] = $eln; - } - } -} // start a session if session based login is enabled -if ($pref['user_tracking'] == 'session') +// if ($pref['user_tracking'] == 'session') { session_start(); + + + if (!isset($_SESSION['challenge'])) { // New session // Create a unique challenge string for CHAP login @@ -564,153 +507,22 @@ if($pref['redirectsiteurl'] && $pref['siteurl']) { } } -// $page = substr(strrchr($_SERVER['PHP_SELF'], '/'), 1); -// define('e_PAGE', $page); +/** + * Set the User's Language + */ +$sql->db_Mark_Time('Start: Set User Language'); +e107::getLanguage()->set(); // set e_LANGUAGE, USERLAN, Language Session / Cookies etc. requires $pref; -// sort out the users language selection -if (isset($_POST['setlanguage']) || isset($_GET['elan']) || isset($GLOBALS['elan'])) +if(varset($pref['multilanguage']) && (e_LANGUAGE != $pref['sitelanguage'])) { - // query support, for language selection splash pages. etc - if($_GET['elan']) - { - $_POST['sitelanguage'] = str_replace(array(".", "/", "%"), "", $_GET['elan']); - } - if($GLOBALS['elan'] && !isset($_POST['sitelanguage'])) - { - $_POST['sitelanguage'] = $GLOBALS['elan']; - } - - $sql->mySQLlanguage = $_POST['sitelanguage']; - $sql2->mySQLlanguage = $_POST['sitelanguage']; - - session_set('e107language_'.e_COOKIE, $_POST['sitelanguage'], time() + 86400); - if ($pref['user_tracking'] != 'session' && (strpos(e_SELF, ADMINDIR) === false)) - { - $locat = ((!$_GET['elan'] && e_QUERY) || (e_QUERY && e_LANCODE)) ? e_SELF.'?'.e_QUERY : e_SELF; - header('Location:'.$locat); - exit(); - } - + $sql->mySQLlanguage = e_LANGUAGE; + $sql2->mySQLlanguage = e_LANGUAGE; } -$user_language=''; -// Multi-language options. -if (isset($pref['multilanguage']) && $pref['multilanguage']) -{ - if ($pref['user_tracking'] == 'session') - { - $user_language = (array_key_exists('e107language_'.e_COOKIE, $_SESSION) ? $_SESSION['e107language_'.e_COOKIE] : ''); - $sql->mySQLlanguage = ($user_language) ? $user_language : ""; - $sql2->mySQLlanguage = $sql->mySQLlanguage; - } - else - { - $user_language = (isset($_COOKIE['e107language_'.e_COOKIE]) ? $_COOKIE['e107language_'.e_COOKIE] : ''); - $sql->mySQLlanguage = ($user_language ? $user_language : ''); - $sql2->mySQLlanguage = $sql->mySQLlanguage; - } -} - -// Get Language List for rights checking. -if( ! $tmplan = getcachedvars('language-list')) -{ - $handle = opendir(e_LANGUAGEDIR); - while ($file = readdir($handle)) - { - // add only if e_LANGUAGEDIR.e_LANGUAGE/e_LANGUAGE - if ($file != '.' && $file != '..' && is_readable(e_LANGUAGEDIR.$file.'/'.$file.'.php')) - { - $lanlist[] = $file; - } - } - closedir($handle); - $tmplan = implode(',', $lanlist); - cachevars('language-list', $tmplan); -} -// Save language flat list -define('e_LANLIST', $tmplan); - -// Set $language fallback to $pref['sitelanguage'] for the time being -$language = $pref['sitelanguage']; - -// Get user language choice -//TODO Force no multilingual sites to keep there preset languages? if (varset($pref['multilanguage'])) -//{ - if ($pref['user_tracking'] == 'session') - { - $user_language = (array_key_exists('e107language_'.$pref['cookie_name'], $_SESSION) ? $_SESSION['e107language_'.$pref['cookie_name']] : ''); - } - else - { - $_SESSION = array(); //remove PHP notice - $user_language = (isset($_COOKIE['e107language_'.$pref['cookie_name']])) ? $_COOKIE['e107language_'.$pref['cookie_name']] : ''; - } - // Strip $user_language - //allow [a-z][A-Z][0-9]_ - $user_language = preg_replace('#[^\w]#', '', $user_language); - - // Is user language choice available? - if( ! in_array($user_language, $lanlist)) - { - // Reset session - if(isset($_SESSION)) - { - unset($_SESSION['e107language_'.$pref['cookie_name']]); - } - // Reset cookie - if(isset($_COOKIE['e107language_'.$pref['cookie_name']])) - { - unset($_COOKIE['e107language_'.$pref['cookie_name']]); - } - $user_language = ''; - } - else - { - $language = $user_language; - } - - // Ensure db got the proper language - default is empty - if (varset($pref['multilanguage'])) - { - $sql->mySQLlanguage = $user_language; - $sql2->mySQLlanguage = $user_language; - } -//} - -// We should have the language by now -define('e_LANGUAGE', $language); - -// Keep USERLAN for backward compatibility -define('USERLAN', e_LANGUAGE); - //TODO do it only once and with the proper function e107_include_once(e_LANGUAGEDIR.e_LANGUAGE.'/'.e_LANGUAGE.'.php'); e107_include_once(e_LANGUAGEDIR.e_LANGUAGE."/".e_LANGUAGE.'_custom.php'); -// Now we know the site CHARSET, define how to handle utf-8 as necessary -// CHARSET is UTF-8, thus initCharset() is used in e_parse() constructor -// $tp->initCharset(); - -if($pref['sitelanguage'] != e_LANGUAGE && varset($pref['multilanguage']) && !$pref['multilanguage_subdomain']) -{ - list($clc) = explode("_",CORE_LC); - define('e_LAN', strtolower($clc)); - define('e_LANQRY', '['.e_LAN.']'); - unset($clc); -} -else -{ - /** - * @ignore - */ - define('e_LAN', false); - /** - * @ignore - */ - define('e_LANQRY', false); -} -$sql->db_Mark_Time('(Start: Pref/multilang done)'); - // // N: misc setups: online user tracking, cache // @@ -1879,7 +1691,7 @@ if(!isset($_E107['no_online']) && varset($pref['track_online'])) e107::getOnline()->goOnline($pref['track_online'], $pref['flood_protect']); } -function cookie($name, $value, $expire=0, $path = '/', $domain = '', $secure = 0) +function cookie($name, $value, $expire=0, $path = e_HTTP, $domain = '', $secure = 0) { setcookie($name, $value, $expire, $path, $domain, $secure); } diff --git a/e107_handlers/e107_class.php b/e107_handlers/e107_class.php index b7667bafa..4730d1fe9 100644 --- a/e107_handlers/e107_class.php +++ b/e107_handlers/e107_class.php @@ -185,6 +185,7 @@ class e107 'user_class' => '{e_HANDLER}userclass_class.php', 'userlogin' => '{e_HANDLER}login.php', 'xmlClass' => '{e_HANDLER}xml_class.php', + 'language' => '{e_HANDLER}language_class.php' ); /** @@ -1094,6 +1095,16 @@ class e107 { return self::getSingleton('notify', true); } + + /** + * Retrieve Language handler singleton object + * + * @return language + */ + public static function getLanguage() + { + return self::getSingleton('language', true); + } /** * Retrieve Xml handler singleton or new instance object @@ -2158,19 +2169,11 @@ class e107 { define('e_MENU', $matches[1]); $e_QUERY = $matches[2]; - if(strlen(e_MENU) == 2) // language code ie. [fr] - { - require_once(e_HANDLER."language_class.php"); - $slng = new language; - define('e_LANCODE', true); - $_GET['elan'] = $slng->convert(e_MENU); - } } else { define('e_MENU', ''); $e_QUERY = $_SERVER['QUERY_STRING']; - define('e_LANCODE', ''); } $e_QUERY = str_replace("&","&", self::getParser()->post_toForm($e_QUERY)); diff --git a/e107_handlers/language_class.php b/e107_handlers/language_class.php index 121c1c210..2f52dd75c 100644 --- a/e107_handlers/language_class.php +++ b/e107_handlers/language_class.php @@ -3,15 +3,21 @@ + ----------------------------------------------------------------------------+ | e107 website system - Language Class. | -| $Source: /cvs_backup/e107_0.8/e107_handlers/language_class.php,v $ +| $URL$ | $Revision$ -| $Date$ +| $Id$ | $Author$ +----------------------------------------------------------------------------+ */ class language{ +// http://www.loc.gov/standards/iso639-2/php/code_list.php + +// Valid Language Pack Names are shown directly below on the right. + var $detect = FALSE; + var $e_language = 'English'; // replaced later with $pref + var $list = array( "aa" => "Afar", "ab" => "Abkhazian", @@ -111,7 +117,7 @@ class language{ "ng" => "Ndonga", "ne" => "Nepali", "nl" => "Dutch", - "nb" => "Norwegian", + "no" => "Norwegian", "ny" => "Chichewa", "or" => "Oriya", @@ -208,36 +214,301 @@ class language{ "Turkish" => "Türkçe" ); -// --- Converts iso to language-name and visa-versa. ---------------- - + /** + * Converts iso to language-name and visa-versa. + * @param object $data + * @return + */ function convert($data){ if(strlen($data) > 2) { $tmp = array_flip($this->list); - return $tmp[$data]; + return isset($tmp[$data]) ? $tmp[$data] : FALSE; } else { - return $this->list[$data]; + return (isset($this->list[$data])) ? $this->list[$data] : FALSE; } } // ------------------------------------------------------------------- + /** + * Check if a Language is installed and valid + * @param object $lang - Language to check. eg. 'es' or 'Spanish' + * @return FALSE or the name of the valid Language + */ + function isValid($lang='') + { + global $pref; + + if(!$lang) + { + return $pref['sitelanguage']; + } + + if(strpos($lang,"debug")!==FALSE) + { + return FALSE; + } + + if(strlen($lang)== 2) + { + $iso = $lang; + $lang = $this->convert($lang); + } + else + { + $iso = $this->convert($lang); + } + + if($iso==FALSE || $lang==FALSE) + { + $diz = ($lang) ? $lang : $iso; + trigger_error("The selected language (".$diz.") is invalid. See e107_handlers/language_class.php for a list of valid languages. ", E_USER_ERROR); + return FALSE; + } + + if(is_readable(e_LANGUAGEDIR.$lang.'/'.$lang.'.php')) + { + return $lang; + } + else + { + trigger_error("The selected language (".$lang.") was not found.", E_USER_ERROR); + return FALSE; + } + + return FALSE; + } + + /** + * Check if the specified domain has multi-language subdomains enabled. + * @return + */ + function isLangDomain($domain='') + { + if(!$domain) + { + return FALSE; + } + + global $pref; + $mtmp = explode("\n", $pref['multilanguage_subdomain']); + foreach($mtmp as $val) + { + if($domain == trim($val)) + { + return TRUE; + } + } + + return FALSE; + + } + + /** + * Return a list of Installed Language Packs + * @return array + */ + function installed() + { + $handle = opendir(e_LANGUAGEDIR); + $lanlist = array(); + while ($file = readdir($handle)) + { + if ($file != '.' && $file != '..' && is_readable(e_LANGUAGEDIR.$file.'/'.$file.'.php')) + { + $lanlist[] = $file; + } + } + closedir($handle); + + $filtered = array_intersect($lanlist,$this->list); + + return $filtered; + } + + + /** + * Convert a Language to its Native title. eg. 'Spanish' becomes 'Español' + * @param string $lang + * @return string + */ function toNative($lang) { return ($this->names[$lang]) ? $this->names[$lang] : $lang; } - + /** + * Convert the current URL to a multi-lang for the specified language. + * eg. 'http://www.mydomain.com' becomes 'http://es.mydomain.com' + * @param string $language eg. 'Spanish' + * @return URL + */ function subdomainUrl($language) { global $pref; $codelnk = ($language == $pref['sitelanguage']) ? "www" : $this->convert($language); - $urlval = str_replace($_SERVER['HTTP_HOST'],$codelnk.".".e_DOMAIN,e_SELF); + + // $urlval = str_replace($_SERVER['HTTP_HOST'],$codelnk.".".e_DOMAIN,e_SELF); + + $urlval = (e_QUERY) + ? str_replace($_SERVER['HTTP_HOST'], $codelnk.'.'.e_DOMAIN, e_SELF).'?'.e_QUERY + : str_replace($_SERVER['HTTP_HOST'], $codelnk.'.'.e_DOMAIN, e_SELF); + return $urlval; } + + + + /** + * Detect a Language Change + * 1. Parked (sub)Domain eg. http://es.mydomain.com (Preferred for SEO) + * 2. e_MENU Query eg. /index.php?[es] + * 3. $_GET['elan'] eg. /index.php?elan=es + * 4. $_POST['sitelanguage'] eg. + * 5. $GLOBALS['elan'] eg. isLangDomain(e_DOMAIN) && (defset('MULTILANG_SUBDOMAIN') !== FALSE)) + { + $detect_language = (e_SUBDOMAIN) ? $this->isValid(e_SUBDOMAIN) : $pref['sitelanguage']; + e107_ini_set("session.cookie_domain", ".".e_DOMAIN); // Must be before session_start() + define('MULTILANG_SUBDOMAIN',TRUE); + } + elseif(e_MENU && ($detect_language = $this->isValid(e_MENU))) // + { + define("e_LANCODE",TRUE); + + } + elseif(isset($_GET['elan']) && ($detect_language = $this->isValid($_GET['elan']))) // eg: /index.php?elan=Spanish + { + // Do nothing + } + elseif(isset($_POST['setlanguage']) && ($detect_language = $this->isValid($_POST['sitelanguage']))) + { + // Do nothing + } + + elseif(isset($GLOBALS['elan']) && ($detect_language = $this->isValid($GLOBALS['elan']))) + { + // Do nothing + } + else + { + $detect_language = FALSE; // ie. No Change. + } + + e107_ini_set("session.cookie_path", e_HTTP); + + $this->detect = $detect_language; + return $detect_language; + } + + + + /** + * Set the Language (Constants, $_SESSION and $_COOKIE) for the current page. + * @return + */ + function set() + { + global $pref; + + if($this->detect) // Language-Change Trigger Detected. + { + if(!varset($_SESSION['e_language']) || (($_SESSION['e_language'] != $this->detect) && $this->isValid($_SESSION['e_language']))) + { + $_SESSION['e_language'] = $this->detect; + // echo "Assigning Session Language"; + } + + if(varset($_COOKIE['e107_language'])!=$this->detect && (defset('MULTILANG_SUBDOMAIN') != TRUE)) + { + setcookie('e107_language', $this->detect, time() + 86400, e_HTTP); + $_COOKIE['e107_language'] = $this->detect; // Used only when a user returns to the site. Not used during this session. + } + else // Multi-lang SubDomains should ignore cookies and remove old ones if they exist. + { + if(isset($_COOKIE['e107_language'])) + { + unset($_COOKIE['e107_language']); + } + } + + $user_language = $this->detect; + } + else // No Language-change Trigger Detected. + { + if(varset($_SESSION['e_language'])!='') + { + $user_language = $_SESSION['e_language']; + } + elseif(isset($_COOKIE['e107_language']) && ($user_language = $this->isValid($_COOKIE['e107_language']))) + { + $_SESSION['e_language'] = $user_language; + } + else + { + $user_language = $pref['sitelanguage']; + + if(isset($_SESSION['e_language'])) + { + unset($_SESSION['e_language']); + } + + if(isset($_COOKIE['e107_language'])) + { + unset($_COOKIE['e107_language']); + } + } + } + + $this->e_language = $user_language; + $this->setDefs(); + return; + } + + + + /** + * Set Language-specific Constants + * @param string $language + * @return + */ + function setDefs() + { + global $pref; + + $language = $this->e_language; + + if(!isset($_SESSION['language-list'])) + { + $_SESSION['language-list'] = implode(',',$this->installed()); + } + + define('e_LANLIST', $_SESSION['language-list']); + define('e_LANGUAGE', $language); + define('USERLAN', $language); // Keep USERLAN for backward compatibility + $iso = $this->convert($language); + define("e_LAN", $iso); + + // Below is for BC + if(defined('e_LANCODE') && varset($pref['multilanguage']) && ($language != $pref['sitelanguage'])) + { + define("e_LANQRY", "[".$iso."]"); + } + else + { + define("e_LANCODE", ''); + define("e_LANQRY", FALSE); + } + } + }