diff --git a/config-templates/config.php b/config-templates/config.php index 224b85670af9ec5253e365b22f02537a7fdea7ab..49a981d204b05ad3a7785e8b91b8d948ddab1c63 100644 --- a/config-templates/config.php +++ b/config-templates/config.php @@ -423,9 +423,9 @@ $config = array( 'language.cookie.lifetime' => (60 * 60 * 24 * 900), /** - * Custom getLanguage function called from SimpleSAML_XHTML_Template::getLanguage(). + * Custom getLanguage function called from SimpleSAML\Locale\Language::getLanguage(). * Function should return language code of one of the available languages or NULL. - * See SimpleSAML_XHTML_Template::getLanguage() source code for more info. + * See SimpleSAML\Locale\Language::getLanguage() source code for more info. * * This option can be used to implement a custom function for determining * the default language for the user. diff --git a/lib/SimpleSAML/Locale/Language.php b/lib/SimpleSAML/Locale/Language.php new file mode 100644 index 0000000000000000000000000000000000000000..7d22791916a15eade2a2a6f70402d86c69422477 --- /dev/null +++ b/lib/SimpleSAML/Locale/Language.php @@ -0,0 +1,263 @@ +<?php + +/** + * Choosing the language to localize to for our minimalistic XHTML PHP based template system. + * + * @author Andreas Ă…kre Solberg, UNINETT AS. <andreas.solberg@uninett.no> + * @author Hanne Moa, UNINETT AS. <hanne.moa@uninett.no> + * @package SimpleSAMLphp + */ + +namespace SimpleSAML\Locale; + +use SimpleSAML\Utils\HTTP; + +class Language +{ + + /** + * This is the default language map. It is used to map languages codes from the user agent to other language codes. + */ + private static $defaultLanguageMap = array('nb' => 'no'); + + private $configuration = null; + private $availableLanguages = array('en'); + private $language = null; + + + /** + * HTTP GET language parameter name. + */ + private $languageParameterName = 'language'; + + + /** + * Constructor + * + * @param \SimpleSAML_Configuration $configuration Configuration object + */ + public function __construct(\SimpleSAML_Configuration $configuration) + { + $this->configuration = $configuration; + + $this->availableLanguages = $this->configuration->getArray('language.available', array('en')); + + $this->languageParameterName = $this->configuration->getString('language.parameter.name', 'language'); + if (isset($_GET[$this->languageParameterName])) { + $this->setLanguage( + $_GET[$this->languageParameterName], + $this->configuration->getBoolean('language.parameter.setcookie', true) + ); + } + } + + + /** + * This method will set a cookie for the user's browser to remember what language was selected. + * + * @param string $language Language code for the language to set. + * @param boolean $setLanguageCookie Whether to set the language cookie or not. Defaults to true. + */ + public function setLanguage($language, $setLanguageCookie = true) + { + $language = strtolower($language); + if (in_array($language, $this->availableLanguages, true)) { + $this->language = $language; + if ($setLanguageCookie === true) { + Language::setLanguageCookie($language); + } + } + } + + + /** + * This method will return the language selected by the user, or the default language. It looks first for a cached + * language code, then checks for a language cookie, then it tries to calculate the preferred language from HTTP + * headers. + * + * @return string The language selected by the user according to the processing rules specified, or the default + * language in any other case. + */ + public function getLanguage() + { + // language is set in object + if (isset($this->language)) { + return $this->language; + } + + // run custom getLanguage function if defined + $customFunction = $this->configuration->getArray('language.get_language_function', null); + if (isset($customFunction)) { + assert('is_callable($customFunction)'); + $customLanguage = call_user_func($customFunction, $this); + if ($customLanguage !== null && $customLanguage !== false) { + return $customLanguage; + } + } + + // language is provided in a stored cookie + $languageCookie = Language::getLanguageCookie(); + if ($languageCookie !== null) { + $this->language = $languageCookie; + return $languageCookie; + } + + // check if we can find a good language from the Accept-Language HTTP header + $httpLanguage = $this->getHTTPLanguage(); + if ($httpLanguage !== null) { + return $httpLanguage; + } + + // language is not set, and we get the default language from the configuration + return $this->getDefaultLanguage(); + } + + + /** + * Get the language parameter name. + * + * @return string The language parameter name. + */ + public function getLanguageParameterName() + { + return $this->languageParameterName; + } + + + /** + * This method returns the preferred language for the user based on the Accept-Language HTTP header. + * + * @return string The preferred language based on the Accept-Language HTTP header, or null if none of the languages + * in the header is available. + */ + private function getHTTPLanguage() + { + $languageScore = HTTP::getAcceptLanguage(); + + // for now we only use the default language map. We may use a configurable language map in the future + $languageMap = self::$defaultLanguageMap; + + // find the available language with the best score + $bestLanguage = null; + $bestScore = -1.0; + + foreach ($languageScore as $language => $score) { + + // apply the language map to the language code + if (array_key_exists($language, $languageMap)) { + $language = $languageMap[$language]; + } + + if (!in_array($language, $this->availableLanguages, true)) { + // skip this language - we don't have it + continue; + } + + /* Some user agents use very limited precicion of the quality value, but order the elements in descending + * order. Therefore we rely on the order of the output from getAcceptLanguage() matching the order of the + * languages in the header when two languages have the same quality. + */ + if ($score > $bestScore) { + $bestLanguage = $language; + $bestScore = $score; + } + } + + return $bestLanguage; + } + + + /** + * Return the default language according to configuration. + * + * @return string The default language that has been configured. Defaults to english if not configured. + */ + public function getDefaultLanguage() + { + return $this->configuration->getString('language.default', 'en'); + } + + + /** + * Return a list of all languages available. + * + * @return array An array holding all the languages available. + */ + public function getLanguageList() + { + $thisLang = $this->getLanguage(); + $lang = array(); + foreach ($this->availableLanguages as $nl) { + $lang[$nl] = ($nl == $thisLang); + } + return $lang; + } + + + /** + * Check whether a language is right-to-left or not. + * + * @return boolean True if the language is right-to-left, false otherwise. + */ + public function isLanguageRTL() + { + $rtlLanguages = $this->configuration->getArray('language.rtl', array()); + $thisLang = $this->getLanguage(); + if (in_array($thisLang, $rtlLanguages)) { + return true; + } + return false; + } + + + /** + * Retrieve the user-selected language from a cookie. + * + * @return string|null The selected language or null if unset. + */ + public static function getLanguageCookie() + { + $config = \SimpleSAML_Configuration::getInstance(); + $availableLanguages = $config->getArray('language.available', array('en')); + $name = $config->getString('language.cookie.name', 'language'); + + if (isset($_COOKIE[$name])) { + $language = strtolower((string) $_COOKIE[$name]); + if (in_array($language, $availableLanguages, true)) { + return $language; + } + } + + return null; + } + + + /** + * This method will attempt to set the user-selected language in a cookie. It will do nothing if the language + * specified is not in the list of available languages, or the headers have already been sent to the browser. + * + * @param string $language The language set by the user. + */ + public static function setLanguageCookie($language) + { + assert('is_string($language)'); + + $language = strtolower($language); + $config = \SimpleSAML_Configuration::getInstance(); + $availableLanguages = $config->getArray('language.available', array('en')); + + if (!in_array($language, $availableLanguages, true) || headers_sent()) { + return; + } + + $name = $config->getString('language.cookie.name', 'language'); + $params = array( + 'lifetime' => ($config->getInteger('language.cookie.lifetime', 60 * 60 * 24 * 900)), + 'domain' => ($config->getString('language.cookie.domain', null)), + 'path' => ($config->getString('language.cookie.path', '/')), + 'httponly' => false, + ); + + HTTP::setCookie($name, $language, $params, false); + } +} diff --git a/lib/SimpleSAML/Locale/Translate.php b/lib/SimpleSAML/Locale/Translate.php new file mode 100644 index 0000000000000000000000000000000000000000..ebbac327575e74acf27c6274234ebf8ce02bf190 --- /dev/null +++ b/lib/SimpleSAML/Locale/Translate.php @@ -0,0 +1,446 @@ +<?php + +/** + * The translation-relevant bits from our original minimalistic XHTML PHP based template system. + * + * @author Andreas Ă…kre Solberg, UNINETT AS. <andreas.solberg@uninett.no> + * @author Hanne Moa, UNINETT AS. <hanne.moa@uninett.no> + * @package SimpleSAMLphp + */ + +namespace SimpleSAML\Locale; + +class Translate +{ + + /** + * The configuration to be used for this translator. + * + * @var \SimpleSAML_Configuration + */ + private $configuration; + + private $langtext = array(); + + /** + * Associative array of dictionaries. + */ + private $dictionaries = array(); + + /** + * The default dictionary. + */ + private $defaultDictionary = null; + + /** + * The language object we'll use internally. + * + * @var \SimpleSAML\Locale\Language + */ + private $language; + + + /** + * Constructor + * + * @param \SimpleSAML_Configuration $configuration Configuration object + * @param string|null $defaultDictionary The default dictionary where tags will come from. + */ + public function __construct(\SimpleSAML_Configuration $configuration, $defaultDictionary = null) + { + $this->configuration = $configuration; + $this->language = new Language($configuration); + + if ($defaultDictionary !== null && substr($defaultDictionary, -4) === '.php') { + // TODO: drop this entire if clause for 2.0 + // for backwards compatibility - print warning + $backtrace = debug_backtrace(); + $where = $backtrace[0]['file'].':'.$backtrace[0]['line']; + \SimpleSAML_Logger::warning( + 'Deprecated use of new SimpleSAML\Locale\Translate(...) at '.$where. + '. The last parameter is now a dictionary name, which should not end in ".php".' + ); + + $this->defaultDictionary = substr($defaultDictionary, 0, -4); + } else { + $this->defaultDictionary = $defaultDictionary; + } + } + + + /** + * Return the internal language object used by this translator. + * + * @return \SimpleSAML\Locale\Language + */ + public function getLanguage() + { + return $this->language; + } + + + /** + * This method retrieves a dictionary with the name given. + * + * @param string $name The name of the dictionary, as the filename in the dictionary directory, without the + * '.php' ending. + * + * @return array An associative array with the dictionary. + */ + private function getDictionary($name) + { + assert('is_string($name)'); + + if (!array_key_exists($name, $this->dictionaries)) { + $sepPos = strpos($name, ':'); + if ($sepPos !== false) { + $module = substr($name, 0, $sepPos); + $fileName = substr($name, $sepPos + 1); + $dictDir = \SimpleSAML_Module::getModuleDir($module).'/dictionaries/'; + } else { + $dictDir = $this->configuration->getPathValue('dictionarydir', 'dictionaries/'); + $fileName = $name; + } + + $this->dictionaries[$name] = $this->readDictionaryFile($dictDir.$fileName); + } + + return $this->dictionaries[$name]; + } + + + /** + * This method retrieves a tag as an array with language => string mappings. + * + * @param string $tag The tag name. The tag name can also be on the form '{<dictionary>:<tag>}', to retrieve a tag + * from the specific dictionary. + * + * @return array An associative array with language => string mappings, or null if the tag wasn't found. + */ + public function getTag($tag) + { + assert('is_string($tag)'); + + // first check translations loaded by the includeInlineTranslation and includeLanguageFile methods + if (array_key_exists($tag, $this->langtext)) { + return $this->langtext[$tag]; + } + + // check whether we should use the default dictionary or a dictionary specified in the tag + if (substr($tag, 0, 1) === '{' && preg_match('/^{((?:\w+:)?\w+?):(.*)}$/D', $tag, $matches)) { + $dictionary = $matches[1]; + $tag = $matches[2]; + } else { + $dictionary = $this->defaultDictionary; + if ($dictionary === null) { + // we don't have any dictionary to load the tag from + return null; + } + } + + $dictionary = $this->getDictionary($dictionary); + if (!array_key_exists($tag, $dictionary)) { + return null; + } + + return $dictionary[$tag]; + } + + + /** + * Retrieve the preferred translation of a given text. + * + * @param array $translations The translations, as an associative array with language => text mappings. + * + * @return string The preferred translation. + * + * @throws \Exception If there's no suitable translation. + */ + public function getPreferredTranslation($translations) + { + assert('is_array($translations)'); + + // look up translation of tag in the selected language + $selected_language = $this->language->getLanguage(); + if (array_key_exists($selected_language, $translations)) { + return $translations[$selected_language]; + } + + // look up translation of tag in the default language + $default_language = $this->language->getDefaultLanguage(); + if (array_key_exists($default_language, $translations)) { + return $translations[$default_language]; + } + + // check for english translation + if (array_key_exists('en', $translations)) { + return $translations['en']; + } + + // pick the first translation available + if (count($translations) > 0) { + $languages = array_keys($translations); + return $translations[$languages[0]]; + } + + // we don't have anything to return + throw new \Exception('Nothing to return from translation.'); + } + + + /** + * Translate the name of an attribute. + * + * @param string $name The attribute name. + * + * @return string The translated attribute name, or the original attribute name if no translation was found. + */ + public function getAttributeTranslation($name) + { + // normalize attribute name + $normName = strtolower($name); + $normName = str_replace(":", "_", $normName); + + // check for an extra dictionary + $extraDict = $this->configuration->getString('attributes.extradictionary', null); + if ($extraDict !== null) { + $dict = $this->getDictionary($extraDict); + if (array_key_exists($normName, $dict)) { + return $this->getPreferredTranslation($dict[$normName]); + } + } + + // search the default attribute dictionary + $dict = $this->getDictionary('attributes'); + if (array_key_exists('attribute_'.$normName, $dict)) { + return $this->getPreferredTranslation($dict['attribute_'.$normName]); + } + + // no translations found + return $name; + } + + + /** + * Translate a tag into the current language, with a fallback to english. + * + * This function is used to look up a translation tag in dictionaries, and return the translation into the current + * language. If no translation into the current language can be found, english will be tried, and if that fails, + * placeholder text will be returned. + * + * An array can be passed as the tag. In that case, the array will be assumed to be on the form (language => text), + * and will be used as the source of translations. + * + * This function can also do replacements into the translated tag. It will search the translated tag for the keys + * provided in $replacements, and replace any found occurrences with the value of the key. + * + * @param string|array $tag A tag name for the translation which should be looked up, or an array with + * (language => text) mappings. + * @param array $replacements An associative array of keys that should be replaced with values in the + * translated string. + * @param boolean $fallbackdefault Default translation to use as a fallback if no valid translation was found. + * + * @return string The translated tag, or a placeholder value if the tag wasn't found. + */ + public function t( + $tag, + $replacements = array(), + $fallbackdefault = true, + $oldreplacements = array(), // TODO: remove this for 2.0 + $striptags = false // TODO: remove this for 2.0 + ) { + if (!is_array($replacements)) { + // TODO: remove this entire if for 2.0 + + // old style call to t(...). Print warning to log + $backtrace = debug_backtrace(); + $where = $backtrace[0]['file'].':'.$backtrace[0]['line']; + \SimpleSAML_Logger::warning( + 'Deprecated use of SimpleSAML_Template::t(...) at '.$where. + '. Please update the code to use the new style of parameters.' + ); + + // for backwards compatibility + if (!$replacements && $this->getTag($tag) === null) { + \SimpleSAML_Logger::warning( + 'Code which uses $fallbackdefault === FALSE should be updated to use the getTag() method instead.' + ); + return null; + } + + $replacements = $oldreplacements; + } + + if (is_array($tag)) { + $tagData = $tag; + } else { + $tagData = $this->getTag($tag); + if ($tagData === null) { + // tag not found + \SimpleSAML_Logger::info('Template: Looking up ['.$tag.']: not translated at all.'); + return $this->getStringNotTranslated($tag, $fallbackdefault); + } + } + + $translated = $this->getPreferredTranslation($tagData); + + foreach ($replacements as $k => $v) { + // try to translate if no replacement is given + if ($v == null) { + $v = $this->t($k); + } + $translated = str_replace($k, $v, $translated); + } + return $translated; + } + + + /** + * Return the string that should be used when no translation was found. + * + * @param string $tag A name tag of the string that should be returned. + * @param boolean $fallbacktag If set to true and string was not found in any languages, return the tag itself. If + * false return null. + * + * @return string The string that should be used, or the tag name if $fallbacktag is set to false. + */ + private function getStringNotTranslated($tag, $fallbacktag) + { + if ($fallbacktag) { + return 'not translated ('.$tag.')'; + } else { + return $tag; + } + } + + + /** + * Include a translation inline instead of putting translations in dictionaries. This function is recommended to be + * used ONLU from variable data, or when the translation is already provided by an external source, as a database + * or in metadata. + * + * @param string $tag The tag that has a translation + * @param array|string $translation The translation array + * + * @throws \Exception If $translation is neither a string nor an array. + */ + public function includeInlineTranslation($tag, $translation) + { + if (is_string($translation)) { + $translation = array('en' => $translation); + } elseif (!is_array($translation)) { + throw new \Exception("Inline translation should be string or array. Is ".gettype($translation)." now!"); + } + + \SimpleSAML_Logger::debug('Template: Adding inline language translation for tag ['.$tag.']'); + $this->langtext[$tag] = $translation; + } + + + /** + * Include a language file from the dictionaries directory. + * + * @param string $file File name of dictionary to include + * @param \SimpleSAML_Configuration|null $otherConfig Optionally provide a different configuration object than the + * one provided in the constructor to be used to find the directory of the dictionary. This allows to combine + * dictionaries inside the SimpleSAMLphp main code distribution together with external dictionaries. Defaults to + * null. + */ + public function includeLanguageFile($file, $otherConfig = null) + { + if (!empty($otherConfig)) { + $filebase = $otherConfig->getPathValue('dictionarydir', 'dictionaries/'); + } else { + $filebase = $this->configuration->getPathValue('dictionarydir', 'dictionaries/'); + } + + $lang = $this->readDictionaryFile($filebase.$file); + \SimpleSAML_Logger::debug('Template: Merging language array. Loading ['.$file.']'); + $this->langtext = array_merge($this->langtext, $lang); + } + + + /** + * Read a dictionary file in JSON format. + * + * @param string $filename The absolute path to the dictionary file, minus the .definition.json ending. + * + * @return array An array holding all the translations in the file. + */ + private function readDictionaryJSON($filename) + { + $definitionFile = $filename.'.definition.json'; + assert('file_exists($definitionFile)'); + + $fileContent = file_get_contents($definitionFile); + $lang = json_decode($fileContent, true); + + if (empty($lang)) { + \SimpleSAML_Logger::error('Invalid dictionary definition file ['.$definitionFile.']'); + return array(); + } + + $translationFile = $filename.'.translation.json'; + if (file_exists($translationFile)) { + $fileContent = file_get_contents($translationFile); + $moreTrans = json_decode($fileContent, true); + if (!empty($moreTrans)) { + $lang = array_merge_recursive($lang, $moreTrans); + } + } + + return $lang; + } + + + /** + * Read a dictionary file in PHP format. + * + * @param string $filename The absolute path to the dictionary file. + * + * @return array An array holding all the translations in the file. + */ + private function readDictionaryPHP($filename) + { + $phpFile = $filename.'.php'; + assert('file_exists($phpFile)'); + + $lang = null; + include($phpFile); + if (isset($lang)) { + return $lang; + } + + return array(); + } + + + /** + * Read a dictionary file. + * + * @param string $filename The absolute path to the dictionary file. + * + * @return array An array holding all the translations in the file. + */ + private function readDictionaryFile($filename) + { + assert('is_string($filename)'); + + \SimpleSAML_Logger::debug('Template: Reading ['.$filename.']'); + + $jsonFile = $filename.'.definition.json'; + if (file_exists($jsonFile)) { + return $this->readDictionaryJSON($filename); + } + + $phpFile = $filename.'.php'; + if (file_exists($phpFile)) { + return $this->readDictionaryPHP($filename); + } + + \SimpleSAML_Logger::error( + $_SERVER['PHP_SELF'].' - Template: Could not find dictionary file at ['.$filename.']' + ); + return array(); + } +} diff --git a/lib/SimpleSAML/XHTML/Template.php b/lib/SimpleSAML/XHTML/Template.php index ab20e116982aa3d7746bffdfb3dc5b706e2b609b..1f365346bdf7080a47c057d25841bf2ea7e38dc0 100644 --- a/lib/SimpleSAML/XHTML/Template.php +++ b/lib/SimpleSAML/XHTML/Template.php @@ -1,711 +1,336 @@ <?php + /** * A minimalistic XHTML PHP based template system implemented for SimpleSAMLphp. * * @author Andreas Ă…kre Solberg, UNINETT AS. <andreas.solberg@uninett.no> * @package SimpleSAMLphp */ -class SimpleSAML_XHTML_Template { +class SimpleSAML_XHTML_Template +{ /** - * This is the default language map. It is used to map languages codes from the user agent to - * other language codes. + * The data associated with this template, accessible within the template itself. + * + * @var array */ - private static $defaultLanguageMap = array('nb' => 'no'); - - - private $configuration = null; - private $template = 'default.php'; - private $availableLanguages = array('en'); - private $language = null; - - private $langtext = array(); - - public $data = null; - + public $data = array(); /** - * Associative array of dictionaries. + * A translator instance configured to work with this template. + * + * @var \SimpleSAML\Locale\Translate */ - private $dictionaries = array(); - + private $translator; /** - * The default dictionary. + * The configuration to use in this template. + * + * @var SimpleSAML_Configuration */ - private $defaultDictionary = NULL; - + private $configuration; /** - * HTTP GET language parameter name. + * The file to load in this template. + * + * @var string */ - private $languageParameterName = 'language'; + private $template = 'default.php'; /** * Constructor * - * @param $configuration Configuration object - * @param $template Which template file to load - * @param $defaultDictionary The default dictionary where tags will come from. + * @param SimpleSAML_Configuration $configuration Configuration object + * @param string $template Which template file to load + * @param string|null $defaultDictionary The default dictionary where tags will come from. */ - function __construct(SimpleSAML_Configuration $configuration, $template, $defaultDictionary = NULL) { + public function __construct(SimpleSAML_Configuration $configuration, $template, $defaultDictionary = null) + { $this->configuration = $configuration; $this->template = $template; - $this->data['baseurlpath'] = $this->configuration->getBaseURL(); - - $this->availableLanguages = $this->configuration->getArray('language.available', array('en')); - - $this->languageParameterName = $this->configuration->getString('language.parameter.name', 'language'); - if (isset($_GET[$this->languageParameterName])) { - $this->setLanguage($_GET[$this->languageParameterName], $this->configuration->getBoolean('language.parameter.setcookie', TRUE)); - } - - if($defaultDictionary !== NULL && substr($defaultDictionary, -4) === '.php') { - // For backwards compatibility - print warning - $backtrace = debug_backtrace(); - $where = $backtrace[0]['file'] . ':' . $backtrace[0]['line']; - SimpleSAML_Logger::warning('Deprecated use of new SimpleSAML_Template(...) at ' . $where . - '. The last parameter is now a dictionary name, which should not end in ".php".'); - - $this->defaultDictionary = substr($defaultDictionary, 0, -4); - } else { - $this->defaultDictionary = $defaultDictionary; - } - } - - - /** - * setLanguage() will set a cookie for the user's browser to remember what language - * was selected - * - * @param $language Language code for the language to set. - */ - public function setLanguage($language, $setLanguageCookie = TRUE) { - $language = strtolower($language); - if (in_array($language, $this->availableLanguages, TRUE)) { - $this->language = $language; - if ($setLanguageCookie === TRUE) { - SimpleSAML_XHTML_Template::setLanguageCookie($language); - } - } - } - - /** - * getLanguage() will return the language selected by the user, or the default language - * This function first looks for a cached language code, - * then checks for a language cookie, - * then it tries to calculate the preferred language from HTTP headers. - * Last it returns the default language. - */ - public function getLanguage() { - - // Language is set in object - if (isset($this->language)) { - return $this->language; - } - - // Run custom getLanguage function if defined - $customFunction = $this->configuration->getArray('language.get_language_function', NULL); - if (isset($customFunction)) { - assert('is_callable($customFunction)'); - $customLanguage = call_user_func($customFunction, $this); - if ($customLanguage !== NULL && $customLanguage !== FALSE) { - return $customLanguage; - } - } - - // Language is provided in a stored COOKIE - $languageCookie = SimpleSAML_XHTML_Template::getLanguageCookie(); - if ($languageCookie !== NULL) { - $this->language = $languageCookie; - return $languageCookie; - } - - // Check if we can find a good language from the Accept-Language http header - $httpLanguage = $this->getHTTPLanguage(); - if ($httpLanguage !== NULL) { - return $httpLanguage; - } - - // Language is not set, and we get the default language from the configuration - return $this->getDefaultLanguage(); + $this->translator = new SimpleSAML\Locale\Translate($configuration, $defaultDictionary = null); } /** - * This function gets the prefered language for the user based on the Accept-Language http header. + * Return the internal translator object used by this template. * - * @return The prefered language based on the Accept-Language http header, or NULL if none of the - * languages in the header were available. + * @return \SimpleSAML\Locale\Translate The translator that will be used with this template. */ - private function getHTTPLanguage() { - $languageScore = \SimpleSAML\Utils\HTTP::getAcceptLanguage(); - - /* For now we only use the default language map. We may use a configurable language map - * in the future. - */ - $languageMap = self::$defaultLanguageMap; - - // Find the available language with the best score - $bestLanguage = NULL; - $bestScore = -1.0; - - foreach($languageScore as $language => $score) { - - // Apply the language map to the language code - if(array_key_exists($language, $languageMap)) { - $language = $languageMap[$language]; - } - - if(!in_array($language, $this->availableLanguages, TRUE)) { - // Skip this language - we don't have it - continue; - } - - /* Some user agents use very limited precicion of the quality value, but order the - * elements in descending order. Therefore we rely on the order of the output from - * getAcceptLanguage() matching the order of the languages in the header when two - * languages have the same quality. - */ - if($score > $bestScore) { - $bestLanguage = $language; - $bestScore = $score; - } - } - - return $bestLanguage; + public function getTranslator() + { + return $this->translator; } /** - * Returns the language default (from configuration) + * Show the template to the user. */ - private function getDefaultLanguage() { - return $this->configuration->getString('language.default', 'en'); + public function show() + { + $filename = $this->findTemplatePath($this->template); + require($filename); } - /** - * Returns a list of all available languages. - */ - private function getLanguageList() { - $thisLang = $this->getLanguage(); - $lang = array(); - foreach ($this->availableLanguages AS $nl) { - $lang[$nl] = ($nl == $thisLang); - } - return $lang; - } /** - * Return TRUE if language is Right-to-Left. - */ - private function isLanguageRTL() { - $rtlLanguages = $this->configuration->getArray('language.rtl', array()); - $thisLang = $this->getLanguage(); - if (in_array($thisLang, $rtlLanguages)) { - return TRUE; - } - return FALSE; - } - - /** - * Includs a file relative to the template base directory. - * This function can be used to include headers and footers etc. + * Find template path. * - */ - private function includeAtTemplateBase($file) { - $data = $this->data; - - $filename = $this->findTemplatePath($file); - - include($filename); - } - - - /** - * Retrieve a dictionary. + * This function locates the given template based on the template name. It will first search for the template in + * the current theme directory, and then the default theme. * - * This function retrieves a dictionary with the given name. + * The template name may be on the form <module name>:<template path>, in which case it will search for the + * template file in the given module. * - * @param $name The name of the dictionary, as the filename in the dictionary directory, - * without the '.php'-ending. - * @return An associative array with the dictionary. - */ - private function getDictionary($name) { - assert('is_string($name)'); - - if(!array_key_exists($name, $this->dictionaries)) { - $sepPos = strpos($name, ':'); - if($sepPos !== FALSE) { - $module = substr($name, 0, $sepPos); - $fileName = substr($name, $sepPos + 1); - $dictDir = SimpleSAML_Module::getModuleDir($module) . '/dictionaries/'; - } else { - $dictDir = $this->configuration->getPathValue('dictionarydir', 'dictionaries/'); - $fileName = $name; - } - $this->dictionaries[$name] = $this->readDictionaryFile($dictDir . $fileName); - } - - return $this->dictionaries[$name]; - } - - - /** - * Retrieve a tag. + * @param string $template The relative path from the theme directory to the template file. * - * This function retrieves a tag as an array with language => string mappings. + * @return string The absolute path to the template file. * - * @param $tag The tag name. The tag name can also be on the form '{<dictionary>:<tag>}', to retrieve - * a tag from the specific dictionary. - * @return As associative array with language => string mappings, or NULL if the tag wasn't found. + * @throws Exception If the template file couldn't be found. */ - public function getTag($tag) { - assert('is_string($tag)'); - - // First check translations loaded by the includeInlineTranslation and includeLanguageFile methods - if(array_key_exists($tag, $this->langtext)) { - return $this->langtext[$tag]; - } + private function findTemplatePath($template) + { + assert('is_string($template)'); - // Check whether we should use the default dictionary or a dictionary specified in the tag - if(substr($tag, 0, 1) === '{' && preg_match('/^{((?:\w+:)?\w+?):(.*)}$/D', $tag, $matches)) { - $dictionary = $matches[1]; - $tag = $matches[2]; + $tmp = explode(':', $template, 2); + if (count($tmp) === 2) { + $templateModule = $tmp[0]; + $templateName = $tmp[1]; } else { - $dictionary = $this->defaultDictionary; - if($dictionary === NULL) { - // We don't have any dictionary to load the tag from - return NULL; - } + $templateModule = 'default'; + $templateName = $tmp[0]; } - $dictionary = $this->getDictionary($dictionary); - if(!array_key_exists($tag, $dictionary)) { - return NULL; + $tmp = explode(':', $this->configuration->getString('theme.use', 'default'), 2); + if (count($tmp) === 2) { + $themeModule = $tmp[0]; + $themeName = $tmp[1]; + } else { + $themeModule = null; + $themeName = $tmp[0]; } - return $dictionary[$tag]; - } - - - /** - * Retrieve the preferred translation of a given text. - * - * @param $translations The translations, as an associative array with language => text mappings. - * @return The preferred translation. - */ - public function getTranslation($translations) { - assert('is_array($translations)'); + // first check the current theme + if ($themeModule !== null) { + // .../module/<themeModule>/themes/<themeName>/<templateModule>/<templateName> - // Look up translation of tag in the selected language - $selected_language = $this->getLanguage(); - if (array_key_exists($selected_language, $translations)) { - return $translations[$selected_language]; + $filename = SimpleSAML_Module::getModuleDir($themeModule). + '/themes/'.$themeName.'/'.$templateModule.'/'.$templateName; + } elseif ($templateModule !== 'default') { + // .../module/<templateModule>/templates/<themeName>/<templateName> + $filename = SimpleSAML_Module::getModuleDir($templateModule).'/templates/'.$templateName; + } else { + // .../templates/<theme>/<templateName> + $filename = $this->configuration->getPathValue('templatedir', 'templates/').$templateName; } - // Look up translation of tag in the default language - $default_language = $this->getDefaultLanguage(); - if(array_key_exists($default_language, $translations)) { - return $translations[$default_language]; + if (file_exists($filename)) { + return $filename; } - // Check for english translation - if(array_key_exists('en', $translations)) { - return $translations['en']; + // not found in current theme + SimpleSAML_Logger::debug( + $_SERVER['PHP_SELF'].' - Template: Could not find template file ['. $template.'] at ['. + $filename.'] - now trying the base template' + ); + + // try default theme + if ($templateModule !== 'default') { + // .../module/<templateModule>/templates/<templateName> + $filename = SimpleSAML_Module::getModuleDir($templateModule).'/templates/'.$templateName; + } else { + // .../templates/<templateName> + $filename = $this->configuration->getPathValue('templatedir', 'templates/').'/'.$templateName; } - // Pick the first translation available - if(count($translations) > 0) { - $languages = array_keys($translations); - return $translations[$languages[0]]; + if (file_exists($filename)) { + return $filename; } - // We don't have anything to return - throw new Exception('Nothing to return from translation.'); + // not found in default template - log error and throw exception + $error = 'Template: Could not find template file ['.$template.'] at ['.$filename.']'; + SimpleSAML_Logger::critical($_SERVER['PHP_SELF'].' - '.$error); + + throw new Exception($error); } - /** - * Translate a attribute name. - * - * @param string $name The attribute name. - * @return string The translated attribute name, or the original attribute name if no translation was found. + /* + * Deprecated methods of this interface, all of them should go away. */ - public function getAttributeTranslation($name) { - - // Normalize attribute name - $normName = strtolower($name); - $normName = str_replace(":", "_", $normName); - - // Check for an extra dictionary - $extraDict = $this->configuration->getString('attributes.extradictionary', NULL); - if ($extraDict !== NULL) { - $dict = $this->getDictionary($extraDict); - if (array_key_exists($normName, $dict)) { - return $this->getTranslation($dict[$normName]); - } - } - - // Search the default attribute dictionary - $dict = $this->getDictionary('attributes'); - if (array_key_exists('attribute_' . $normName, $dict)) { - return $this->getTranslation($dict['attribute_' . $normName]); - } - - // No translations found - return $name; - } /** - * Translate a tag into the current language, with a fallback to english. + * @param $name * - * This function is used to look up a translation tag in dictionaries, and return the - * translation into the current language. If no translation into the current language can be - * found, english will be tried, and if that fails, placeholder text will be returned. - * - * An array can be passed as the tag. In that case, the array will be assumed to be on the - * form (language => text), and will be used as the source of translations. - * - * This function can also do replacements into the translated tag. It will search the - * translated tag for the keys provided in $replacements, and replace any found occurances - * with the value of the key. - * - * @param string|array $tag A tag name for the translation which should be looked up, or an - * array with (language => text) mappings. - * @param array $replacements An associative array of keys that should be replaced with - * values in the translated string. - * @return string The translated tag, or a placeholder value if the tag wasn't found. + * @return string + * @deprecated This method will be removed in SSP 2.0. Please use \SimpleSAML\Locale\Language::getLanguage() + * instead. */ - public function t($tag, $replacements = array(), $fallbackdefault = true, $oldreplacements = array(), $striptags = FALSE) { - if(!is_array($replacements)) { - - // Old style call to t(...). Print warning to log. - $backtrace = debug_backtrace(); - $where = $backtrace[0]['file'] . ':' . $backtrace[0]['line']; - SimpleSAML_Logger::warning('Deprecated use of SimpleSAML_Template::t(...) at ' . $where . - '. Please update the code to use the new style of parameters.'); - - // For backwards compatibility - if(!$replacements && $this->getTag($tag) === NULL) { - SimpleSAML_Logger::warning('Code which uses $fallbackdefault === FALSE shouls be' . - ' updated to use the getTag-method instead.'); - return NULL; - } + public function getAttributeTranslation($name) + { + return $this->translator->getAttributeTranslation($name); + } - $replacements = $oldreplacements; - } - if(is_array($tag)) { - $tagData = $tag; - } else { - $tagData = $this->getTag($tag); - if($tagData === NULL) { - // Tag not found - SimpleSAML_Logger::info('Template: Looking up [' . $tag . ']: not translated at all.'); - return $this->t_not_translated($tag, $fallbackdefault); - } - } + /** + * @return string + * @deprecated This method will be removed in SSP 2.0. Please use \SimpleSAML\Locale\Language::getLanguage() + * instead. + */ + public function getLanguage() + { + return $this->translator->getLanguage()->getLanguage(); + } - $translated = $this->getTranslation($tagData); - foreach ($replacements as $k => $v) { - // try to translate if no replacement is given - if ($v == NULL) $v = $this->t($k); - $translated = str_replace($k, $v, $translated); - } - return $translated; + /** + * @param $language + * @param bool $setLanguageCookie + * @deprecated This method will be removed in SSP 2.0. Please use \SimpleSAML\Locale\Language::setLanguage() + * instead. + */ + public function setLanguage($language, $setLanguageCookie = true) + { + $this->translator->getLanguage()->setLanguage($language, $setLanguageCookie); } /** - * Return the string that should be used when no translation was found. - * - * @param $tag A name tag of the string that should be returned. - * @param $fallbacktag If set to TRUE and string was not found in any languages, return - * the tag it self. If FALSE return NULL. + * @return null|string + * @deprecated This method will be removed in SSP 2.0. Please use \SimpleSAML\Locale\Language::getLanguageCookie() + * instead. */ - private function t_not_translated($tag, $fallbacktag) { - if ($fallbacktag) { - return 'not translated (' . $tag . ')'; - } else { - return $tag; - } + public static function getLanguageCookie() + { + return \SimpleSAML\Locale\Language::getLanguageCookie(); } /** - * You can include translation inline instead of putting translation - * in dictionaries. This function is reccomended to only be used from dynamic - * data, or when the translation is already provided from an external source, as - * a database or in metadata. - * - * @param $tag The tag that has a translation - * @param $translation The translation array + * @param $language + * @deprecated This method will be removed in SSP 2.0. Please use \SimpleSAML\Locale\Language::setLanguageCookie() + * instead. */ - public function includeInlineTranslation($tag, $translation) { - if (is_string($translation)) { - $translation = array('en' => $translation); - } elseif (!is_array($translation)) { - throw new Exception("Inline translation should be string or array. Is " . gettype($translation) . " now!"); - } - SimpleSAML_Logger::debug('Template: Adding inline language translation for tag [' . $tag . ']'); - $this->langtext[$tag] = $translation; + public static function setLanguageCookie($language) + { + \SimpleSAML\Locale\Language::setLanguageCookie($language); } /** - * Include language file from the dictionaries directory. - * - * @param $file File name of dictionary to include - * @param $otherConfig Optionally provide a different configuration object than - * the one provided in the constructor to be used to find the dictionary directory. - * This enables the possiblity of combining dictionaries inside SimpleSAMLphp - * distribution with external dictionaries. + * Wraps Language->getLanguageList */ - public function includeLanguageFile($file, $otherConfig = null) { - $filebase = null; - if (!empty($otherConfig)) { - $filebase = $otherConfig->getPathValue('dictionarydir', 'dictionaries/'); - } else { - $filebase = $this->configuration->getPathValue('dictionarydir', 'dictionaries/'); - } - - $lang = $this->readDictionaryFile($filebase . $file); - SimpleSAML_Logger::debug('Template: Merging language array. Loading [' . $file . ']'); - $this->langtext = array_merge($this->langtext, $lang); + private function getLanguageList() { + return $this->translator->getLanguage()->getLanguageList(); } /** - * Read a dictionary file in json format. + * @param $tag * - * @param string $filename The absolute path to the dictionary file, minus the .definition.json ending. - * @return array The translation array from the file. + * @return array + * @deprecated This method will be removed in SSP 2.0. Please use \SimpleSAML\Locale\Translate::getTag() instead. */ - private function readDictionaryJSON($filename) { - $definitionFile = $filename . '.definition.json'; - assert('file_exists($definitionFile)'); - - $fileContent = file_get_contents($definitionFile); - $lang = json_decode($fileContent, TRUE); - - if (empty($lang)) { - SimpleSAML_Logger::error('Invalid dictionary definition file [' . $definitionFile . ']'); - return array(); - } - - $translationFile = $filename . '.translation.json'; - if (file_exists($translationFile)) { - $fileContent = file_get_contents($translationFile); - $moreTrans = json_decode($fileContent, TRUE); - if (!empty($moreTrans)) { - $lang = self::lang_merge($lang, $moreTrans); - } - } - - return $lang; + public function getTag($tag) + { + return $this->translator->getTag($tag); } /** - * Read a dictionary file in PHP format. + * Temporary wrapper for SimpleSAML\Locale\Translate::getPreferredTranslation(). * - * @param string $filename The absolute path to the dictionary file. - * @return array The translation array from the file. + * @deprecated This method will be removed in SSP 2.0. Please use + * SimpleSAML\Locale\Translate::getPreferredTranslation() instead. */ - private function readDictionaryPHP($filename) { - $phpFile = $filename . '.php'; - assert('file_exists($phpFile)'); - - $lang = NULL; - include($phpFile); - if (isset($lang)) { - return $lang; - } - - return array(); + public function getTranslation($translations) + { + return $this->translator->getPreferredTranslation($translations); } /** - * Read a dictionary file. + * Includes a file relative to the template base directory. + * This function can be used to include headers and footers etc. * - * @param $filename The absolute path to the dictionary file. - * @return The translation array which was found in the dictionary file. */ - private function readDictionaryFile($filename) { - assert('is_string($filename)'); - - SimpleSAML_Logger::debug('Template: Reading [' . $filename . ']'); - - $jsonFile = $filename . '.definition.json'; - if (file_exists($jsonFile)) { - return $this->readDictionaryJSON($filename); - } - + private function includeAtTemplateBase($file) { + $data = $this->data; - $phpFile = $filename . '.php'; - if (file_exists($phpFile)) { - return $this->readDictionaryPHP($filename); - } + $filename = $this->findTemplatePath($file); - SimpleSAML_Logger::error($_SERVER['PHP_SELF'].' - Template: Could not find template file [' . $this->template . '] at [' . $filename . ']'); - return array(); + include($filename); } - // Merge two translation arrays - public static function lang_merge($def, $lang) { - foreach($def AS $key => $value) { - if (array_key_exists($key, $lang)) - $def[$key] = array_merge($value, $lang[$key]); - } - return $def; + /** + * Wraps Translate->includeInlineTranslation() + * + * @see \SimpleSAML\Locale\Translate::includeInlineTranslation() + * @deprecated This method will be removed in SSP 2.0. Please use + * \SimpleSAML\Locale\Translate::includeInlineTranslation() instead. + */ + public function includeInlineTranslation($tag, $translation) + { + $this->translator->includeInlineTranslation($tag, $translation); } /** - * Show the template to the user. + * @param $file + * @param null $otherConfig + * @deprecated This method will be removed in SSP 2.0. Please use + * \SimpleSAML\Locale\Translate::includeLanguageFile() instead. */ - public function show() { - - $filename = $this->findTemplatePath($this->template); - require($filename); + public function includeLanguageFile($file, $otherConfig = null) + { + $this->translator->includeLanguageFile($file, $otherConfig); } /** - * Find template path. - * - * This function locates the given template based on the template name. - * It will first search for the template in the current theme directory, and - * then the default theme. - * - * The template name may be on the form <module name>:<template path>, in which case - * it will search for the template file in the given module. - * - * An error will be thrown if the template file couldn't be found. - * - * @param string $template The relative path from the theme directory to the template file. - * @return string The absolute path to the template file. + * Wrap Language->isLanguageRTL */ - private function findTemplatePath($template) { - assert('is_string($template)'); - - $tmp = explode(':', $template, 2); - if (count($tmp) === 2) { - $templateModule = $tmp[0]; - $templateName = $tmp[1]; - } else { - $templateModule = 'default'; - $templateName = $tmp[0]; - } - - $tmp = explode(':', $this->configuration->getString('theme.use', 'default'), 2); - if (count($tmp) === 2) { - $themeModule = $tmp[0]; - $themeName = $tmp[1]; - } else { - $themeModule = NULL; - $themeName = $tmp[0]; - } - - - // First check the current theme - if ($themeModule !== NULL) { - // .../module/<themeModule>/themes/<themeName>/<templateModule>/<templateName> - - $filename = SimpleSAML_Module::getModuleDir($themeModule) . '/themes/' . $themeName . '/' . $templateModule . '/' . $templateName; - } elseif ($templateModule !== 'default') { - // .../module/<templateModule>/templates/<themeName>/<templateName> - $filename = SimpleSAML_Module::getModuleDir($templateModule) . '/templates/' . $templateName; - } else { - // .../templates/<theme>/<templateName> - $filename = $this->configuration->getPathValue('templatedir', 'templates/') . $templateName; - } - - if (file_exists($filename)) { - return $filename; - } - - - // Not found in current theme - SimpleSAML_Logger::debug($_SERVER['PHP_SELF'].' - Template: Could not find template file [' . - $template . '] at [' . $filename . '] - now trying the base template'); - - - // Try default theme - if ($templateModule !== 'default') { - // .../module/<templateModule>/templates/<templateName> - $filename = SimpleSAML_Module::getModuleDir($templateModule) . '/templates/' . $templateName; - } else { - // .../templates/<templateName> - $filename = $this->configuration->getPathValue('templatedir', 'templates/') . '/' . $templateName; - } - - if (file_exists($filename)) { - return $filename; - } - - - // Not found in default template - log error and throw exception - $error = 'Template: Could not find template file [' . $template . '] at [' . $filename . ']'; - SimpleSAML_Logger::critical($_SERVER['PHP_SELF'] . ' - ' . $error); - - throw new Exception($error); + private function isLanguageRTL() { + return $this->translator->getLanguage()->isLanguageRTL(); } /** - * Retrieve the user-selected language from a cookie. + * Merge two translation arrays. * - * @return string|NULL The language, or NULL if unset. + * @param array $def The array holding string definitions. + * @param array $lang The array holding translations for every string. + * @return array The recursive merge of both arrays. + * @deprecated This method will be removed in SimpleSAMLphp 2.0. Please use array_merge_recursive() instead. */ - public static function getLanguageCookie() { - $config = SimpleSAML_Configuration::getInstance(); - $availableLanguages = $config->getArray('language.available', array('en')); - $name = $config->getString('language.cookie.name', 'language'); - - if (isset($_COOKIE[$name])) { - $language = strtolower((string)$_COOKIE[$name]); - if (in_array($language, $availableLanguages, TRUE)) { - return $language; + public static function lang_merge($def, $lang) + { + foreach ($def as $key => $value) { + if (array_key_exists($key, $lang)) { + $def[$key] = array_merge($value, $lang[$key]); } } - - return NULL; + return $def; } /** - * Set the user-selected language in a cookie. + * Wrap Language->t to translate tag into the current language, with a fallback to english. * - * @param string $language The language. + * @see \SimpleSAML\Locale\Translate::t() + * @deprecated This method will be removed in SSP 2.0. Please use \SimpleSAML\Locale\Translate::t() instead. */ - public static function setLanguageCookie($language) { - assert('is_string($language)'); - - $language = strtolower($language); - $config = SimpleSAML_Configuration::getInstance(); - $availableLanguages = $config->getArray('language.available', array('en')); - - if (!in_array($language, $availableLanguages, TRUE) || headers_sent()) { - return; - } - - $name = $config->getString('language.cookie.name', 'language'); - $params = array( - 'lifetime' => ($config->getInteger('language.cookie.lifetime', 60*60*24*900)), - 'domain' => ($config->getString('language.cookie.domain', NULL)), - 'path' => ($config->getString('language.cookie.path', '/')), - 'httponly' => FALSE, - ); - - \SimpleSAML\Utils\HTTP::setCookie($name, $language, $params, FALSE); + public function t( + $tag, + $replacements = array(), + $fallbackdefault = true, + $oldreplacements = array(), + $striptags = false + ) { + return $this->translator->t($tag, $replacements, $fallbackdefault, $oldreplacements, $striptags); } - } diff --git a/modules/consent/templates/consentform.php b/modules/consent/templates/consentform.php index 198dd8d72e56439d63332bf3c18be70618fb587f..d32a1a1289fa29b2a29e7f32a9cfdfab623c0eb5 100644 --- a/modules/consent/templates/consentform.php +++ b/modules/consent/templates/consentform.php @@ -72,7 +72,7 @@ if (array_key_exists('descr_purpose', $this->data['dstMetadata'])) { '{consent:consent:consent_purpose}', array( 'SPNAME' => $dstName, - 'SPDESC' => $this->getTranslation( + 'SPDESC' => $this->getTranslator()->getPreferredTranslation( SimpleSAML\Utils\Arrays::arrayize( $this->data['dstMetadata']['descr_purpose'], 'en' @@ -139,6 +139,8 @@ if ($this->data['sppp'] !== false) { */ function present_attributes($t, $attributes, $nameParent) { + $translator = $t->getTranslator(); + $alternate = array('odd', 'even'); $i = 0; $summary = 'summary="' . $t->t('{consent:consent:table_summary}') . '"'; @@ -155,7 +157,7 @@ function present_attributes($t, $attributes, $nameParent) foreach ($attributes as $name => $value) { $nameraw = $name; - $name = $t->getAttributeTranslation($parentStr . $nameraw); + $name = $translator->getAttributeTranslation($parentStr . $nameraw); if (preg_match('/^child_/', $nameraw)) { // insert child table diff --git a/modules/consentAdmin/templates/consentadmin.php b/modules/consentAdmin/templates/consentadmin.php index 496d5145280279baae13a1059e20010d395d70e7..015c44e2807ba71736fbcbcb7d59ee9b6b3a051a 100644 --- a/modules/consentAdmin/templates/consentadmin.php +++ b/modules/consentAdmin/templates/consentadmin.php @@ -1,7 +1,7 @@ <?php $this->includeAtTemplateBase('includes/header.php'); ?> <!-- default theme --> <?php -$this->includeLanguageFile('attributes.php'); // attribute listings translated by this dictionary +$this->getTranslator()->includeLanguageFile('attributes.php'); // attribute listings translated by this dictionary ?> @@ -72,8 +72,8 @@ span.showhide { $hide_text = $this->t('hide'); $attributes_text = $this->t('attributes_text'); foreach ($spList AS $spName => $spValues) { - $this->includeInlineTranslation('spname', $spValues['name']); - $this->includeInlineTranslation('spdescription', $spValues['description']); + $this->getTranslator()->includeInlineTranslation('spname', $spValues['name']); + $this->getTranslator()->includeInlineTranslation('spdescription', $spValues['description']); if (!is_null($spValues['serviceurl'])) { $htmlSpName = '<a href="' . $spValues['serviceurl'] . '" style="color: black; font-weight: bold;">' . htmlspecialchars($this->t('spname', array(), false, true)) . '</a>'; } else { @@ -101,7 +101,7 @@ TRSTART; if (isset($this->data['attribute_' . htmlspecialchars(strtolower($name)) ])) { $name = $this->data['attribute_' . htmlspecialchars(strtolower($name))]; } - $name = $this->getAttributeTranslation($name); // translate + $name = $this->getTranslator()->getAttributeTranslation($name); // translate if (sizeof($value) > 1) { echo "<li>" . htmlspecialchars($name) . ":\n<ul>\n"; foreach ($value AS $v) { diff --git a/modules/consentAdmin/www/consentAdmin.php b/modules/consentAdmin/www/consentAdmin.php index 717fa3c28c7971446afc74776f2002aa834d44b4..a6b3df9a2ede14f3a37bbfa65800835257151fd1 100644 --- a/modules/consentAdmin/www/consentAdmin.php +++ b/modules/consentAdmin/www/consentAdmin.php @@ -205,8 +205,9 @@ $template_sp_content = array(); // Init template $template = new SimpleSAML_XHTML_Template($config, 'consentAdmin:consentadmin.php', 'consentAdmin:consentadmin'); -$sp_empty_name = $template->getTag('sp_empty_name'); -$sp_empty_description = $template->getTag('sp_empty_description'); +$translator = $template->getTranslator(); +$sp_empty_name = $translator->getTag('sp_empty_name'); +$sp_empty_description = $translator->getTag('sp_empty_description'); // Process consents for all SP foreach ($all_sp_metadata as $sp_entityid => $sp_values) { diff --git a/modules/core/lib/Auth/Process/LanguageAdaptor.php b/modules/core/lib/Auth/Process/LanguageAdaptor.php index 347a1fd4a0bc4b0ce303a2d4662a80d986517fdf..cbc9478e2beac57fd980f0ecb0c8644a660a0952 100644 --- a/modules/core/lib/Auth/Process/LanguageAdaptor.php +++ b/modules/core/lib/Auth/Process/LanguageAdaptor.php @@ -44,7 +44,7 @@ class sspmod_core_Auth_Process_LanguageAdaptor extends SimpleSAML_Auth_Processin if (array_key_exists($this->langattr, $attributes)) $attrlang = $attributes[$this->langattr][0]; - $lang = SimpleSAML_XHTML_Template::getLanguageCookie(); + $lang = SimpleSAML\Locale\Language::getLanguageCookie(); if (isset($attrlang)) @@ -55,7 +55,7 @@ class sspmod_core_Auth_Process_LanguageAdaptor extends SimpleSAML_Auth_Processin if (isset($attrlang) && !isset($lang)) { // Language set in attribute but not in cookie - update cookie - SimpleSAML_XHTML_Template::setLanguageCookie($attrlang); + SimpleSAML\Locale\Language::setLanguageCookie($attrlang); } elseif (!isset($attrlang) && isset($lang)) { // Language set in cookie, but not in attribute. Update attribute $request['Attributes'][$this->langattr] = array($lang); diff --git a/modules/core/templates/frontpage_federation.tpl.php b/modules/core/templates/frontpage_federation.tpl.php index c4e18d247204b194545efacc70a2337c7d1440b9..d69843206c9a55661173f3b9f9cefdc7be506c3c 100644 --- a/modules/core/templates/frontpage_federation.tpl.php +++ b/modules/core/templates/frontpage_federation.tpl.php @@ -54,11 +54,13 @@ if (is_array($this->data['metaentries']['hosted']) && count($this->data['metaent echo '<br />Index: '.$hm['metadata-index']; } if (!empty($hm['name'])) { - echo '<br /><strong>'.$this->getTranslation(SimpleSAML\Utils\Arrays::arrayize($hm['name'], 'en')). + echo '<br /><strong>'. + $this->getTranslator()->getPreferredTranslation(SimpleSAML\Utils\Arrays::arrayize($hm['name'], 'en')). '</strong>'; } if (!empty($hm['descr'])) { - echo '<br /><strong>'.$this->getTranslation(SimpleSAML\Utils\Arrays::arrayize($hm['descr'], 'en')). + echo '<br /><strong>'. + $this->getTranslator()->getPreferredTranslation(SimpleSAML\Utils\Arrays::arrayize($hm['descr'], 'en')). '</strong>'; } @@ -84,11 +86,13 @@ if (is_array($this->data['metaentries']['remote']) && count($this->data['metaent ) ).'">'); if (!empty($entry['name'])) { - echo htmlspecialchars($this->getTranslation(SimpleSAML\Utils\Arrays::arrayize($entry['name'], 'en'))); + echo htmlspecialchars($this->getTranslator()->getPreferredTranslation( + SimpleSAML\Utils\Arrays::arrayize($entry['name'], 'en') + )); } elseif (!empty($entry['OrganizationDisplayName'])) { - echo htmlspecialchars( - $this->getTranslation(SimpleSAML\Utils\Arrays::arrayize($entry['OrganizationDisplayName'], 'en')) - ); + echo htmlspecialchars($this->getTranslator()->getPreferredTranslation( + SimpleSAML\Utils\Arrays::arrayize($entry['OrganizationDisplayName'], 'en') + )); } else { echo htmlspecialchars($entry['entityid']); } diff --git a/modules/core/templates/logout-iframe.php b/modules/core/templates/logout-iframe.php index e6d041e6c1878419681c41485b0100949f944fb3..e71c2f266a5aecebe0406398f3a74e496046e7bf 100644 --- a/modules/core/templates/logout-iframe.php +++ b/modules/core/templates/logout-iframe.php @@ -42,7 +42,7 @@ foreach ($SPs as $assocId => $sp) { } if ($from !== NULL) { - $from = $this->getTranslation($from); + $from = $this->getTranslator()->getPreferredTranslation($from); } @@ -99,7 +99,7 @@ echo '<table id="slostatustable">'; foreach ($SPs AS $assocId => $sp) { if (isset($sp['core:Logout-IFrame:Name'])) { - $spName = $this->getTranslation($sp['core:Logout-IFrame:Name']); + $spName = $this->getTranslator()->getPreferredTranslation($sp['core:Logout-IFrame:Name']); } else { $spName = $assocId; } diff --git a/modules/discopower/templates/disco-tpl.php b/modules/discopower/templates/disco-tpl.php index 752badc741ed5f08d37966aac2077dc36d44cc0c..8f1e4e279ee7fbbfcc9a4320374a5550198911f5 100644 --- a/modules/discopower/templates/disco-tpl.php +++ b/modules/discopower/templates/disco-tpl.php @@ -84,13 +84,13 @@ function getTranslatedName($t, $metadata) { $displayName = $metadata['UIInfo']['DisplayName']; assert('is_array($displayName)'); // Should always be an array of language code -> translation if (!empty($displayName)) { - return $t->getTranslation($displayName); + return $t->getTranslator()->getPreferredTranslation($displayName); } } if (array_key_exists('name', $metadata)) { if (is_array($metadata['name'])) { - return $t->getTranslation($metadata['name']); + return $t->getTranslator()->getPreferredTranslation($metadata['name']); } else { return $metadata['name']; } diff --git a/templates/includes/attributes.php b/templates/includes/attributes.php index 2f960c46c0bd2209264b9d1934e2750eeaaf44f5..48eb0cc78c9c9b4d509d3f2d7d16863bb8225115 100644 --- a/templates/includes/attributes.php +++ b/templates/includes/attributes.php @@ -30,7 +30,7 @@ function present_assoc($attr) { } } -function present_attributes($t, $attributes, $nameParent) { +function present_attributes(SimpleSAML_XHTML_Template $t, $attributes, $nameParent) { $alternate = array('odd', 'even'); $i = 0; $parentStr = (strlen($nameParent) > 0)? strtolower($nameParent) . '_': ''; @@ -40,7 +40,7 @@ function present_attributes($t, $attributes, $nameParent) { foreach ($attributes as $name => $value) { $nameraw = $name; - $name = $t->getAttributeTranslation($parentStr . $nameraw); + $name = $t->getTranslator()->getAttributeTranslation($parentStr . $nameraw); if (preg_match('/^child_/', $nameraw)) { $parentName = preg_replace('/^child_/', '', $nameraw); diff --git a/templates/includes/header.php b/templates/includes/header.php index 4d07f1d37de7857b3245568416bdf4a31d02a745..f0c4e4df3ea3567cc0f47bb2796c022711af74c9 100644 --- a/templates/includes/header.php +++ b/templates/includes/header.php @@ -191,7 +191,7 @@ if($onLoad !== '') { if ($current) { $textarray[] = $langnames[$lang]; } else { - $textarray[] = '<a href="' . htmlspecialchars(\SimpleSAML\Utils\HTTP::addURLParameters(\SimpleSAML\Utils\HTTP::getSelfURL(), array($this->languageParameterName => $lang))) . '">' . + $textarray[] = '<a href="' . htmlspecialchars(\SimpleSAML\Utils\HTTP::addURLParameters(\SimpleSAML\Utils\HTTP::getSelfURL(), array($this->getTranslator()->getLanguage()->getLanguageParameterName() => $lang))) . '">' . $langnames[$lang] . '</a>'; } } diff --git a/templates/logout.php b/templates/logout.php index 885f3a54b768a42900159dde64c032421de88500..0672ce7259115e49ae0c80d9e1eafc390ca7dd45 100644 --- a/templates/logout.php +++ b/templates/logout.php @@ -9,7 +9,7 @@ $this->includeAtTemplateBase('includes/header.php'); echo('<h2>' . $this->data['header'] . '</h2>'); echo('<p>' . $this->t('{logout:logged_out_text}') . '</p>'); -if($this->getTag($this->data['text']) !== NULL) { +if($this->getTranslator()->getTag($this->data['text']) !== NULL) { $this->data['text'] = $this->t($this->data['text']); } echo('<p>[ <a href="' . htmlspecialchars($this->data['link']) . '">' . diff --git a/templates/selectidp-dropdown.php b/templates/selectidp-dropdown.php index 1bb13def6b42009c7ed04f60869cae8ded7153bc..b9c3b73a7a682b4c2348e13503e7a93fdea0ffb0 100644 --- a/templates/selectidp-dropdown.php +++ b/templates/selectidp-dropdown.php @@ -9,12 +9,18 @@ $this->includeAtTemplateBase('includes/header.php'); foreach ($this->data['idplist'] as $idpentry) { if (!empty($idpentry['name'])) { - $this->includeInlineTranslation('idpname_'.$idpentry['entityid'], $idpentry['name']); + $this->getTranslator()->includeInlineTranslation( + 'idpname_'.$idpentry['entityid'], + $idpentry['name'] + ); } elseif (!empty($idpentry['OrganizationDisplayName'])) { - $this->includeInlineTranslation('idpname_'.$idpentry['entityid'], $idpentry['OrganizationDisplayName']); + $this->getTranslator()->includeInlineTranslation( + 'idpname_'.$idpentry['entityid'], + $idpentry['OrganizationDisplayName'] + ); } if (!empty($idpentry['description'])) { - $this->includeInlineTranslation('idpdesc_'.$idpentry['entityid'], $idpentry['description']); + $this->getTranslator()->includeInlineTranslation('idpdesc_'.$idpentry['entityid'], $idpentry['description']); } } ?> @@ -28,6 +34,7 @@ foreach ($this->data['idplist'] as $idpentry) { <select id="dropdownlist" name="idpentityid"> <?php usort($this->data['idplist'], function ($idpentry1, $idpentry2) { + // TODO: this is only compatible with PHP >= 5.4, fix compat with 5.3! return strcmp($this->t('idpname_'.$idpentry1['entityid']), $this->t('idpname_'.$idpentry2['entityid'])); }); diff --git a/templates/selectidp-links.php b/templates/selectidp-links.php index 079e8be664fb089875e76a790ee6353715a7e3ed..b8f2d6e3d89d6c6dd40244993108b3e1d8bfcded 100644 --- a/templates/selectidp-links.php +++ b/templates/selectidp-links.php @@ -8,12 +8,15 @@ $this->data['autofocus'] = 'preferredidp'; $this->includeAtTemplateBase('includes/header.php'); foreach ($this->data['idplist'] as $idpentry) { if (isset($idpentry['name'])) { - $this->includeInlineTranslation('idpname_'.$idpentry['entityid'], $idpentry['name']); + $this->getTranslator()->includeInlineTranslation('idpname_'.$idpentry['entityid'], $idpentry['name']); } elseif (isset($idpentry['OrganizationDisplayName'])) { - $this->includeInlineTranslation('idpname_'.$idpentry['entityid'], $idpentry['OrganizationDisplayName']); + $this->getTranslator()->includeInlineTranslation( + 'idpname_'.$idpentry['entityid'], + $idpentry['OrganizationDisplayName'] + ); } if (isset($idpentry['description'])) { - $this->includeInlineTranslation('idpdesc_'.$idpentry['entityid'], $idpentry['description']); + $this->getTranslator()->includeInlineTranslation('idpdesc_'.$idpentry['entityid'], $idpentry['description']); } } ?> diff --git a/templates/status.php b/templates/status.php index 23f8877182644e2b34ac6ca440d22a978b76dcd2..25b6e020792418f7801ddc3b1ee0dccf87b0a6fc 100644 --- a/templates/status.php +++ b/templates/status.php @@ -1,6 +1,6 @@ <?php if (array_key_exists('header', $this->data)) { - if ($this->getTag($this->data['header']) !== null) { + if ($this->getTranslator()->getTag($this->data['header']) !== null) { $this->data['header'] = $this->t($this->data['header']); } }