diff --git a/html/class_passwordRecovery.inc b/html/class_passwordRecovery.inc index b1df2ec180043b26bc1b42a50abec52971dcc50b..569fdb62c5a69a91364a288c34ba91e799c79177 100644 --- a/html/class_passwordRecovery.inc +++ b/html/class_passwordRecovery.inc @@ -95,7 +95,7 @@ class standAlonePage { } if ($this->interactive) { - initLanguage(); + Language::init(); if (session::global_is_set('plist')) { session::global_un_set('plist'); @@ -345,7 +345,7 @@ class passwordRecovery extends standAlonePage { $smarty->append('css_files', get_template_path('login.css')); $lang = session::global_get('lang'); $smarty->assign('lang', preg_replace('/_.*$/', '', $lang)); - $smarty->assign('rtl', language_is_rtl($lang)); + $smarty->assign('rtl', Language::isRTL($lang)); $smarty->display(get_template_path('headers.tpl')); $smarty->assign('version', FD_VERSION); diff --git a/html/index.php b/html/index.php index 88803a518eb68feadb84ef0c9ec1bb2868121f6a..bfed93af400f078bef92b2df64939dc844c0edbd 100644 --- a/html/index.php +++ b/html/index.php @@ -90,7 +90,7 @@ function displayLogin() $smarty->assign("usePrototype", "false"); $smarty->assign("date", date("l, dS F Y H:i:s O")); $smarty->assign("lang", preg_replace('/_.*$/', '', $lang)); - $smarty->assign("rtl", language_is_rtl($lang)); + $smarty->assign("rtl", Language::isRTL($lang)); $smarty->display (get_template_path('headers.tpl')); $smarty->assign("version", FD_VERSION); @@ -180,7 +180,7 @@ if (!(is_dir($smarty->compile_dir) && is_writable($smarty->compile_dir))) { /* Check for old files in compile directory */ clean_smarty_compile_dir($smarty->compile_dir); -initLanguage(); +Language::init(); $smarty->assign ('focusfield', 'username'); @@ -318,7 +318,7 @@ class Index { session::global_set('ui', $ui); /* User might have its own language, re-run initLanguage */ - $plistReloaded = initLanguage(); + $plistReloaded = Language::init(); /* We need a fully loaded plist and config to test account expiration */ if (!$plistReloaded) { diff --git a/html/main.php b/html/main.php index 856a64e6bc97dacbb263c7d086c997db46597529..33ee1bfe8a05cc9f4f084392ed093023a6e6b833 100644 --- a/html/main.php +++ b/html/main.php @@ -98,7 +98,7 @@ if (!session::global_is_set('CurrentMainBase')) { session::global_set('CurrentMainBase', get_base_from_people($ui->dn)); } -initLanguage(); +Language::init(); /* Prepare plugin list */ $plist = load_plist(); @@ -232,9 +232,9 @@ if (isset($_GET['reset'])) { /* show web frontend */ $smarty->assign ("date", date("l, dS F Y H:i:s O")); $lang = session::global_get('lang'); -$smarty->assign ("lang", preg_replace('/_.*$/', '', $lang)); -$smarty->assign ("rtl", language_is_rtl($lang)); -$smarty->assign ("must", '<span class="must">*</span>'); +$smarty->assign ('lang', preg_replace('/_.*$/', '', $lang)); +$smarty->assign ('rtl', Language::isRTL($lang)); +$smarty->assign ('must', '<span class="must">*</span>'); if (isset($plug)) { $plug = "?plug=$plug"; } else { diff --git a/html/setup.php b/html/setup.php index 6c77f663c1bb307f367a83e07f6cdd6fa990bb02..183840d0c1f609a3127e91d591b984f3d56f4c27 100644 --- a/html/setup.php +++ b/html/setup.php @@ -78,12 +78,12 @@ if (isset($_POST['lang_selected']) && $_POST['lang_selected'] != '') { $lang .= '.UTF-8'; } } else { - $lang = get_browser_language(); + $lang = Language::detect(); } -initLanguage($lang); +Language::init($lang); -$smarty->assign("rtl", language_is_rtl($lang)); +$smarty->assign("rtl", Language::isRTL($lang)); $smarty->assign("must", '<span class="must">*</span>'); /* Minimal config */ @@ -99,7 +99,6 @@ $ui = new fake_userinfo(); $display = ""; require_once("../setup/main.inc"); -$smarty->assign("rtl", language_is_rtl($lang)); $smarty->assign("date", date("l, dS F Y H:i:s O")); $header = $smarty->fetch(get_template_path('headers.tpl')); diff --git a/include/accept-to-gettext.inc b/include/accept-to-gettext.inc index 259510bb1b0aad7684785acbb7310b06f16158af..3f2a3b23d64857758cac9c1357c564588464d3ea 100644 --- a/include/accept-to-gettext.inc +++ b/include/accept-to-gettext.inc @@ -3,7 +3,7 @@ * accept-to-gettext.inc -- convert information in 'Accept-*' headers to * gettext language identifiers. * Copyright (c) 2003, Wouter Verhelst <wouter@debian.org> - * Copyright (c) 2012-2016, FusionDirectory + * Copyright (c) 2012-2018, FusionDirectory * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -115,7 +115,7 @@ function parse_gettext_lang ($str) } } -function al2gt($gettextlangs, $mime) +function al2gt($gettextlangs) { /* Check if ACCEPT_LANGUAGE isset */ if (empty($_SERVER["HTTP_ACCEPT_LANGUAGE"])) { @@ -177,15 +177,6 @@ function al2gt($gettextlangs, $mime) return NULL; } - /* We must re-parse the gettext-string now, since we may have found it - * through a "*" qualifier.*/ - list ($lang, $country, $char) = parse_gettext_lang($max_lang); - if (!headers_sent()) { - header("Content-Language: $lang".(empty($country) ? "" : "-$country")); - if (!empty($char)) { - header("Content-Type: $mime; charset=$char"); - } - } return $max_lang; } ?> diff --git a/include/class_Language.inc b/include/class_Language.inc new file mode 100644 index 0000000000000000000000000000000000000000..dba0321e38de732bff51c1ed12ab5f418927fb28 --- /dev/null +++ b/include/class_Language.inc @@ -0,0 +1,250 @@ +<?php + +/* + This code is part of FusionDirectory (http://www.fusiondirectory.org/) + Copyright (C) 2017-2018 FusionDirectory + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +/*! + * \file class_Language.inc + * Source code for the class Language + */ + +/*! + * \brief This class contains all the function needed to manage languages + */ +class Language +{ + /*! + * \brief Initialize language configuration + * + * \param string $lang Language locale to use, defaults to self::detect() + */ + public static function init($lang = NULL) + { + global $BASE_DIR; + + if ($lang === NULL) { + $lang = static::detect(); + } + + putenv('LANGUAGE='); + putenv("LANG=$lang"); + $langset = setlocale(LC_ALL, $lang); + if ($langset === FALSE) { + trigger_error('Setting locale to '.$lang.' failed'); + } + $GLOBALS['t_language'] = $lang; + $GLOBALS['t_gettext_message_dir'] = $BASE_DIR.'/locale/'; + static::setHeaders($lang, 'text/html'); + + /* Set the text domain as 'fusiondirectory' */ + $domain = 'fusiondirectory'; + bindtextdomain($domain, LOCALE_DIR); + textdomain($domain); + if ($_SERVER['REQUEST_METHOD'] != 'POST') { + @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, $lang, 'Setting language to'); + } + + $ret = FALSE; + + /* Reset plist cache if language changed */ + if ((!session::global_is_set('lang')) || (session::global_get('lang') != $lang)) { + $ret = TRUE; + if (session::global_is_set('plist')) { + if ($_SERVER['REQUEST_METHOD'] != 'POST') { + @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, session::global_get('lang'), 'Plist already loaded with language'); + } + session::global_un_set('plist'); + session::global_set('lang', $lang); + load_plist(); + } + } + + session::global_set('lang', $lang); + return $ret; + } + + /*! + * \brief Determine which language to show to the user + * + * Determines which language should be used to present fusiondirectory content + * to the user. It does so by looking at several possibilites and returning + * the first setting that can be found. + * + * -# Language configured by the user + * -# Global configured language + * -# Language as returned by al2gt (as configured in the browser) + * + * \return string gettext locale string + */ + public static function detect() + { + global $config; + + /* Try to use users primary language */ + $ui = get_userinfo(); + if (isset($ui) && ($ui !== NULL) && ($ui->language != '')) { + return $ui->language.'.UTF-8'; + } + + /* Check for global language settings in configuration */ + if (isset($config) && ($config->get_cfg_value('language') != '')) { + $lang = $config->get_cfg_value('language'); + if (!preg_match('/utf/i', $lang)) { + $lang .= '.UTF-8'; + } + return $lang; + } + + /* Load supported languages */ + $languages = static::list(); + + /* Move supported languages to flat list */ + $langs = array(); + foreach (array_keys($languages) as $lang) { + $langs[] = $lang.'.UTF-8'; + } + + /* Return gettext based string */ + return al2gt($langs); + } + + /*! + * \brief Get the language for the user connecting + * + * \param boolean $languages_in_own_language FALSE + * + * \param boolean $strip_region_tag FALSE + */ + public static function list($languages_in_own_language = FALSE, $strip_region_tag = FALSE) + { + /* locales in english */ + $tmp_english = array( + 'ar' => 'Arabic', + 'ca_ES' => 'Catalan', + 'cs_CZ' => 'Czech', + 'de_DE' => 'German', + 'el_GR' => 'Greek', + 'en_US' => 'English', + 'es_CO' => 'Colombian Spanish', + 'es_ES' => 'Spanish', + 'es_VE' => 'Venezuelan', + 'fa_IR' => 'Persian', + 'fi_FI' => 'Finnish', + 'fr_FR' => 'French', + 'hu_HU' => 'Hungarian', + 'id' => 'Indonesian', + 'it_IT' => 'Italian', + 'ja' => 'Japanese', + 'ko' => 'Korean', + 'lv' => 'Latvian', + 'nb' => 'Norwegian BokmÃ¥l', + 'nl_NL' => 'Dutch', + 'pl_PL' => 'Polish', + 'pt' => 'Portuguese', + 'pt_BR' => 'Brazilian', + 'ru_RU' => 'Russian', + 'tr_TR' => 'Turkish', + 'vi_VN' => 'Vietnamese', + 'sv_SE' => 'Swedish', + 'zh_CN' => 'Chinese', + ); + + $ret = array(); + if ($languages_in_own_language) { + /* locales in their own language */ + $tmp_ownlang = array( + 'ar' => 'عربية', + 'ca_ES' => 'Català ', + 'cs_CZ' => 'ÄŒesky', + 'de_DE' => 'Deutsch', + 'el_GR' => 'ελληνικά', + 'en_US' => 'English', + 'es_CO' => 'Español Colombiano', + 'es_ES' => 'Español', + 'es_VE' => 'Castellano', + 'fa_IR' => 'پارسی', + 'fi_FI' => 'Suomi', + 'fr_FR' => 'Français', + 'hu_HU' => 'Magyar', + 'id' => 'Bahasa Indonesia', + 'it_IT' => 'Italiano', + 'ja' => '日本語', + 'ko' => '한êµì–´', + 'lv' => 'LatvieÅ¡u valoda', + 'nb' => 'Norsk bokmÃ¥l', + 'nl_NL' => 'Nederlands', + 'pl_PL' => 'Polski', + 'pt' => 'Português', + 'pt_BR' => 'Português (Brasil)', + 'ru_RU' => 'руÑÑкий Ñзык', + 'tr_TR' => 'Türkçe', + 'vi_VN' => 'Tiếng Việt', + 'sv_SE' => 'Svenska', + 'zh_CN' => '䏿–‡, 汉è¯, 漢語', + ); + + foreach ($tmp_english as $key => $name) { + $label = _($name)." (".$tmp_ownlang[$key].")"; + if ($strip_region_tag) { + $ret[preg_replace("/^([^_]*).*$/", "\\1", $key)] = $label; + } else { + $ret[$key] = $label; + } + } + } else { + foreach ($tmp_english as $key => $name) { + if ($strip_region_tag) { + $ret[preg_replace("/^([^_]*).*/", "\\1", $key)] = _($name); + } else { + $ret[$key] = _($name); + } + } + } + + asort($ret); + return $ret; + } + + /*! + * \brief Returns TRUE if $lang is a right to left language ($lang should match /.._..(\.UTF-8)?/) + */ + public static function isRTL ($lang) + { + $lang = preg_replace('/\.UTF-8$/', '', $lang); + + if (preg_match('/^fa_/', $lang)) { + return TRUE; + } + return FALSE; + } + + public static function setHeaders($language, $mime) + { + list ($lang, $country, $char) = parse_gettext_lang($language); + + if (!headers_sent()) { + header("Content-Language: $lang".(empty($country) ? '' : "-$country")); + if (!empty($char)) { + header("Content-Type: $mime; charset=$char"); + } + } else { + trigger_error('Could not set language '.$lang.' header, headers already sent'); + } + } +} diff --git a/include/class_config.inc b/include/class_config.inc index 7f094e8c5ef56dc5ed27118410cab639764a0eec..6251bb6369ffc5ded10b4eab41c1e0f338482d24 100644 --- a/include/class_config.inc +++ b/include/class_config.inc @@ -419,7 +419,7 @@ class config timezone::setDefaultTimezoneFromConfig(); - initLanguage(); + Language::init(); } /*! diff --git a/include/functions.inc b/include/functions.inc index 5cb77efbf7bf5dcae8cd41b9fd94671bc0c0b390..0a025c0011db90b2243cd4fe716798ae126405ff 100644 --- a/include/functions.inc +++ b/include/functions.inc @@ -248,50 +248,6 @@ function DEBUG($level, $line, $function, $file, $data, $info = '') } } - -/*! - * \brief Determine which language to show to the user - * - * Determines which language should be used to present fusiondirectory content - * to the user. It does so by looking at several possibilites and returning - * the first setting that can be found. - * - * -# Language configured by the user - * -# Global configured language - * -# Language as returned by al2gt (as configured in the browser) - * - * \return string gettext locale string - */ -function get_browser_language() -{ - /* Try to use users primary language */ - global $config; - $ui = get_userinfo(); - if (isset($ui) && ($ui !== NULL) && ($ui->language != '')) { - return $ui->language.'.UTF-8'; - } - - /* Check for global language settings in configuration */ - if (isset($config) && ($config->get_cfg_value('language') != '')) { - $lang = $config->get_cfg_value('language'); - if (!preg_match('/utf/i', $lang)) { - $lang .= '.UTF-8'; - } - return $lang; - } - - /* Load supported languages */ - $gosa_languages = get_languages(); - - /* Move supported languages to flat list */ - $langs = array(); - foreach (array_keys($gosa_languages) as $lang) { - $langs[] = $lang.'.UTF-8'; - } - /* Return gettext based string */ - return al2gt($langs, 'text/html'); -} - /*! * \brief Return themed path for specified base file * @@ -2107,116 +2063,6 @@ function check_schema($cfg) return $checks; } -/*! - * \brief Get the language for the user connecting - * - * \param boolean $languages_in_own_language FALSE - * - * \param boolean $strip_region_tag FALSE - */ -function get_languages($languages_in_own_language = FALSE, $strip_region_tag = FALSE) -{ - /* locales in english */ - $tmp_english = array( - "ar" => "Arabic", - "ca_ES" => "Catalan", - "cs_CZ" => "Czech", - "de_DE" => "German", - "el_GR" => "Greek", - "en_US" => "English", - "es_CO" => "Colombian Spanish", - "es_ES" => "Spanish", - "es_VE" => "Venezuelan", - "fa_IR" => "Persian", - "fi_FI" => "Finnish", - "fr_FR" => "French", - "hu_HU" => "Hungarian", - "id" => "Indonesian", - "it_IT" => "Italian", - "ja" => "Japanese", - "ko" => "Korean", - "lv" => "Latvian", - "nb" => "Norwegian BokmÃ¥l", - "nl_NL" => "Dutch", - "pl_PL" => "Polish", - "pt" => "Portuguese", - "pt_BR" => "Brazilian", - "ru_RU" => "Russian", - "tr_TR" => "Turkish", - "vi_VN" => "Vietnamese", - "sv_SE" => "Swedish", - "zh_CN" => "Chinese", - ); - - $ret = array(); - if ($languages_in_own_language) { - /* locales in their own language */ - $tmp_ownlang = array( - "ar" => "عربية", - "ca_ES" => "Català ", - "cs_CZ" => "ÄŒesky", - "de_DE" => "Deutsch", - "el_GR" => "ελληνικά", - "en_US" => "English", - "es_CO" => "Español Colombiano", - "es_ES" => "Español", - "es_VE" => "Castellano", - "fa_IR" => "پارسی", - "fi_FI" => "Suomi", - "fr_FR" => "Français", - "hu_HU" => "Magyar", - "id" => "Bahasa Indonesia", - "it_IT" => "Italiano", - "ja" => "日本語", - "ko" => "한êµì–´", - "lv" => "LatvieÅ¡u valoda", - "nb" => "Norsk bokmÃ¥l", - "nl_NL" => "Nederlands", - "pl_PL" => "Polski", - "pt" => "Português", - "pt_BR" => "Português (Brasil)", - "ru_RU" => "руÑÑкий Ñзык", - "tr_TR" => "Türkçe", - "vi_VN" => "Tiếng Việt", - "sv_SE" => "Svenska", - "zh_CN" => "䏿–‡, 汉è¯, 漢語", - ); - - foreach ($tmp_english as $key => $name) { - $label = _($name)." (".$tmp_ownlang[$key].")"; - if ($strip_region_tag) { - $ret[preg_replace("/^([^_]*).*$/", "\\1", $key)] = $label; - } else { - $ret[$key] = $label; - } - } - } else { - foreach ($tmp_english as $key => $name) { - if ($strip_region_tag) { - $ret[preg_replace("/^([^_]*).*/", "\\1", $key)] = _($name); - } else { - $ret[$key] = _($name); - } - } - } - - asort($ret); - return $ret; -} - -/*! - * \brief Returns TRUE if $lang is a right to left language ($lang should match /.._..(\.UTF-8)?/) - */ -function language_is_rtl ($lang) -{ - $lang = preg_replace('/\.UTF-8$/', '', $lang); - - if (preg_match('/^fa_/', $lang)) { - return TRUE; - } - return FALSE; -} - /*! * \brief Returns contents of the given POST variable and check magic quotes settings @@ -2567,52 +2413,6 @@ function load_all_classes() } } - -/*! - * \brief Initialize language configuration - * - * \param string $lang Language locale to use, defaults to get_browser_language - */ -function initLanguage($lang = NULL) -{ - global $BASE_DIR; - if ($lang === NULL) { - $lang = get_browser_language(); - } - - putenv('LANGUAGE='); - putenv("LANG=$lang"); - setlocale(LC_ALL, $lang); - $GLOBALS['t_language'] = $lang; - $GLOBALS['t_gettext_message_dir'] = $BASE_DIR.'/locale/'; - - /* Set the text domain as 'fusiondirectory' */ - $domain = 'fusiondirectory'; - bindtextdomain($domain, LOCALE_DIR); - textdomain($domain); - if ($_SERVER['REQUEST_METHOD'] != 'POST') { - @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, $lang, 'Setting language to'); - } - - $ret = FALSE; - - /* Reset plist cache if language changed */ - if ((!session::global_is_set('lang')) || (session::global_get('lang') != $lang)) { - $ret = TRUE; - if (session::global_is_set('plist')) { - if ($_SERVER['REQUEST_METHOD'] != 'POST') { - @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, session::global_get('lang'), 'Plist already loaded with language'); - } - session::global_un_set('plist'); - session::global_set('lang', $lang); - load_plist(); - } - } - - session::global_set('lang', $lang); - return $ret; -} - if (!function_exists('ldap_escape')) { /* This bloc is for PHP<5.6 */ define('LDAP_ESCAPE_FILTER', 0x01); diff --git a/plugins/config/class_configInLdap.inc b/plugins/config/class_configInLdap.inc index 336b64ce94f99fa6b3a248f0fc1ae68975e6e035..8d7731196c16f4724a09c92204b3e0a8e5891b88 100644 --- a/plugins/config/class_configInLdap.inc +++ b/plugins/config/class_configInLdap.inc @@ -451,7 +451,7 @@ class configInLdap extends simplePlugin global $config; $attributesInfo = static::getAttributesInfo(); /* Languages */ - $languages = get_languages(TRUE); + $languages = Language::list(TRUE); $languages = array_merge(array("" => _("Automatic")), $languages); $attributesInfo['look_n_feel']['attrs'][0]->setChoices(array_keys($languages), array_values($languages)); /* Timezones */ diff --git a/plugins/personal/generic/class_user.inc b/plugins/personal/generic/class_user.inc index 231cf96f6b385ade56f1edd3d273df3d25edb0a5..b57fc5c18b252c8e1c68618e7df6b71c1000ac06 100644 --- a/plugins/personal/generic/class_user.inc +++ b/plugins/personal/generic/class_user.inc @@ -304,7 +304,7 @@ class user extends simplePlugin static function getAttributesInfo () { global $config; - $languages = array_merge(array('' => ''), get_languages(TRUE)); + $languages = array_merge(array('' => ''), Language::list(TRUE)); $attributesInfo = array( 'perso' => array( 'name' => _('Personal information'), diff --git a/setup/class_setupStepLanguage.inc b/setup/class_setupStepLanguage.inc index 7e5b666cf2d6948afa33103a41af7f04be26b51d..16fed600b545356758327ade3a38aca79b5ecde4 100644 --- a/setup/class_setupStepLanguage.inc +++ b/setup/class_setupStepLanguage.inc @@ -50,7 +50,7 @@ class setupStepLanguage extends setupStep function __construct($parent) { parent::__construct($parent); - $this->lang = get_browser_language(); + $this->lang = Language::detect(); $this->attributesAccess['lang_selected']->setSize(20); } @@ -64,7 +64,7 @@ class setupStepLanguage extends setupStep function execute() { - $languages = get_languages(TRUE); + $languages = Language::list(TRUE); $languages = array_merge(array("" => _("Automatic")), $languages); $this->attributesAccess['lang_selected']->setChoices(array_keys($languages), array_values($languages)); return parent::execute();