From fb5af92c8129673bf5f03f774b7b73abe48d8c22 Mon Sep 17 00:00:00 2001 From: Hanne Moa <hanne.moa@uninett.no> Date: Tue, 25 Oct 2016 11:40:26 +0200 Subject: [PATCH] Fix loading of domain from modules --- lib/SimpleSAML/Locale/Localization.php | 95 +++++++++++++++----------- lib/SimpleSAML/XHTML/Template.php | 47 ++++++++++--- 2 files changed, 96 insertions(+), 46 deletions(-) diff --git a/lib/SimpleSAML/Locale/Localization.php b/lib/SimpleSAML/Locale/Localization.php index fc307aa16..a8278ca4d 100644 --- a/lib/SimpleSAML/Locale/Localization.php +++ b/lib/SimpleSAML/Locale/Localization.php @@ -83,6 +83,34 @@ class Localization } + /** + * Get the default locale dir for a specific module aka. domain + * + * @param string $domain Name of module/domain + */ + public function getDomainLocaleDir($domain) + { + $localeDir = $this->configuration->resolvePath('modules') . '/' . $domain . '/locales'; + return $localeDir; + } + + + /* + * Add a new translation domain from a module + * (We're assuming that each domain only exists in one place) + * + * @param string $module Module name + * @param string $localeDir Absolute path if the module is housed elsewhere + */ + public function addModuleDomain($module, $localeDir = null) + { + if (!$localeDir) { + $localeDir = $this->getDomainLocaleDir($module); + } + $this->addDomain($localeDir, $module); + } + + /* * Add a new translation domain * (We're assuming that each domain only exists in one place) @@ -93,6 +121,8 @@ class Localization public function addDomain($localeDir, $domain) { $this->localeDomainMap[$domain] = $localeDir; + \SimpleSAML\Logger::debug("Localization: load domain '$domain' at '$localeDir'"); + $this->loadGettextGettextFromPO($domain); } /* @@ -107,6 +137,7 @@ class Localization $langcode = $langcode[0]; $localeDir = $this->localeDomainMap[$domain]; $langPath = $localeDir.'/'.$langcode.'/LC_MESSAGES/'; + \SimpleSAML\Logger::debug("Trying langpath for '$langcode' as '$langPath'"); if (is_dir($langPath) && is_readable($langPath)) { return $langPath; } @@ -119,7 +150,6 @@ class Localization $error = "Localization not found for langcode '$langcode' at '$langPath', falling back to langcode '". $defLangcode."'"; \SimpleSAML\Logger::error($_SERVER['PHP_SELF'].' - '.$error); - return $langPath; } @@ -130,20 +160,40 @@ class Localization } + /** + * Setup the translator + */ + private function setupTranslator() + { + $this->translator = new Translator(); + $this->translator->register(); + } + + /** * Load translation domain from Gettext/Gettext using .po * + * Note: Since Twig I18N does not support domains, all loaded files are + * merged. Use contexts if identical strings need to be disambiguated. + * * @param string $domain Name of domain + * @param boolean $catchException Whether to catch an exception on error or return early + * + * @throws \Exception If something is wrong with the locale file for the domain and activated language */ - private function loadGettextGettextFromPO($domain = self::DEFAULT_DOMAIN) + private function loadGettextGettextFromPO($domain = self::DEFAULT_DOMAIN, $catchException = true) { - $this->translator = new Translator(); - $this->translator->register(); try { $langPath = $this->getLangPath($domain); } catch (\Exception $e) { - // bail out! - return; + $error = "Something wrong with path '$langPath', cannot load domain '$domain'"; + \SimpleSAML\Logger::error($_SERVER['PHP_SELF'].' - '.$error); + if ($catchException) { + // bail out! + return; + } else { + throw $e; + } } $poFile = $domain.'.po'; $poPath = $langPath.$poFile; @@ -181,9 +231,9 @@ class Localization return; } + $this->setupTranslator(); // setup default domain $this->addDomain($this->localeDir, self::DEFAULT_DOMAIN); - $this->activateDomain(self::DEFAULT_DOMAIN); } /** @@ -194,35 +244,4 @@ class Localization return $this->localeDomainMap; } - - /** - * Set which translation domain to use - * - * @param string $domain Name of domain - */ - public function activateDomain($domain) - { - \SimpleSAML\Logger::debug("Localization: activate domain"); - $this->loadGettextGettextFromPO($domain); - $this->currentDomain = $domain; - } - - - /** - * Get current translation domain - */ - public function getCurrentDomain() - { - return $this->currentDomain ? $this->currentDomain : self::DEFAULT_DOMAIN; - } - - - /** - * Go back to default translation domain - */ - public function restoreDefaultDomain() - { - $this->loadGettextGettextFromPO(self::DEFAULT_DOMAIN); - $this->currentDomain = self::DEFAULT_DOMAIN; - } } diff --git a/lib/SimpleSAML/XHTML/Template.php b/lib/SimpleSAML/XHTML/Template.php index 35b740c4a..97c17d466 100644 --- a/lib/SimpleSAML/XHTML/Template.php +++ b/lib/SimpleSAML/XHTML/Template.php @@ -71,6 +71,12 @@ class SimpleSAML_XHTML_Template private $twig_namespace = \Twig_Loader_Filesystem::MAIN_NAMESPACE; + /* + * Current module, if any + */ + private $module; + + /** * Constructor * @@ -84,6 +90,8 @@ class SimpleSAML_XHTML_Template $this->template = $template; // TODO: do not remove the slash from the beginning, change the templates instead! $this->data['baseurlpath'] = ltrim($this->configuration->getBasePath(), '/'); + $result = $this->findModuleAndTemplateName($template); + $this->module = $result[0]; $this->translator = new SimpleSAML\Locale\Translate($configuration, $defaultDictionary); $this->localization = new \SimpleSAML\Locale\Localization($configuration); $this->twig = $this->setupTwig(); @@ -165,6 +173,12 @@ class SimpleSAML_XHTML_Template return false; } + + // load extra i18n domains + if ($this->module) { + $this->localization->addModuleDomain($this->module); + } + $options = array( 'cache' => $cache, 'auto_reload' => $auto_reload, @@ -337,6 +351,28 @@ class SimpleSAML_XHTML_Template } + /** + * Find module the template is in, if any + * + * @param string $template The relative path from the theme directory to the template file. + * + * @return array An array with the name of the module and template + */ + private function findModuleAndTemplateName($template) + { + $tmp = explode(':', $template, 2); + if (count($tmp) === 2) { + $templateModule = $tmp[0]; + $templateName = $tmp[1]; + } else { + $templateModule = null; + $templateName = $tmp[0]; + } + + return array($templateModule, $templateName); + } + + /** * Find template path. * @@ -356,14 +392,9 @@ class SimpleSAML_XHTML_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]; - } + $result = $this->findModuleAndTemplateName($template); + $templateModule = $result[0] ? $result[0] : 'default'; + $templateName = $result[1]; $tmp = explode(':', $this->configuration->getString('theme.use', 'default'), 2); if (count($tmp) === 2) { -- GitLab