Skip to content
Snippets Groups Projects
Commit efa92819 authored by Guenter Hipler's avatar Guenter Hipler Committed by Demian Katz
Browse files

Added support for text domains in translation.

parent 2032ca28
Branches
Tags
No related merge requests found
......@@ -289,6 +289,30 @@ class Bootstrapper
return false;
}
/**
* Support method for initLanguage() -- look up all text domains.
*
* @return array
*/
protected function getTextDomains()
{
$base = APPLICATION_PATH;
$local = LOCAL_OVERRIDE_DIR;
$languagePathParts = ["$base/languages"];
if (!empty($local)) {
$languagePathParts[] = "$local/languages";
}
$languagePathParts[] = "$base/themes/*/languages";
$domains = [];
foreach ($languagePathParts as $current) {
$places = glob($current . '/*', GLOB_ONLYDIR | GLOB_NOSORT);
$domains = array_merge($domains, array_map('basename', $places));
}
return array_unique($domains);
}
/**
* Set up language handling.
*
......@@ -325,11 +349,18 @@ class Bootstrapper
if (!in_array($language, array_keys($config->Languages->toArray()))) {
$language = $config->Site->language;
}
try {
$sm->get('VuFind\Translator')
->addTranslationFile('ExtendedIni', null, 'default', $language)
->setLocale($language);
$translator = $sm->get('VuFind\Translator');
$translator->setLocale($language)
->addTranslationFile('ExtendedIni', null, 'default', $language);
foreach ($this->getTextDomains() as $domain) {
// Set up text domains using the domain name as the filename;
// this will help the ExtendedIni loader dynamically locate
// the appropriate files.
$translator->addTranslationFile(
'ExtendedIni', $domain, $domain, $language
);
}
} catch (\Zend\Mvc\Exception\BadMethodCallException $e) {
if (!extension_loaded('intl')) {
throw new \Exception(
......
......@@ -107,12 +107,11 @@ class ExtendedIni implements FileLoaderInterface
* Load method defined by FileLoaderInterface.
*
* @param string $locale Locale to read from language file
* @param string $filename Language file to read (not used)
* @param string $filename Relative base path for language file (used for
* loading text domains; optional)
*
* @return TextDomain
* @throws InvalidArgumentException
*
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function load($locale, $filename)
{
......@@ -120,12 +119,12 @@ class ExtendedIni implements FileLoaderInterface
$this->resetLoadedFiles();
// Load base data:
$data = $this->loadLanguageFile($locale . '.ini');
$data = $this->loadLanguageLocale($locale, $filename);
// Load fallback data, if any:
if (!empty($this->fallbackLocales)) {
foreach ($this->fallbackLocales as $fallbackLocale) {
$newData = $this->loadLanguageFile($fallbackLocale . '.ini');
$newData = $this->loadLanguageLocale($fallbackLocale, $filename);
$newData->merge($data);
$data = $newData;
}
......@@ -134,6 +133,21 @@ class ExtendedIni implements FileLoaderInterface
return $data;
}
/**
* Get the language file name for a language and domain
*
* @param string $locale Locale name
* @param string $domain Text domain (if any)
*
* @return string
*/
public function getLanguageFilename($locale, $domain)
{
return empty($domain)
? $locale . '.ini'
: $domain . '/' . $locale . '.ini';
}
/**
* Reset the loaded file list.
*
......@@ -160,14 +174,33 @@ class ExtendedIni implements FileLoaderInterface
return false;
}
/**
* Load the language file for a given locale and domain.
*
* @param string $locale Locale name
* @param string $domain Text domain (if any)
*
* @return TextDomain
*/
protected function loadLanguageLocale($locale, $domain)
{
$filename = $this->getLanguageFilename($locale, $domain);
// Load the language file, and throw a fatal exception if it's missing
// and we're not dealing with text domains. A missing base file is an
// unexpected, fatal error; a missing domain-specific file is more likely
// due to the possibility of incomplete translations.
return $this->loadLanguageFile($filename, empty($domain));
}
/**
* Search the path stack for language files and merge them together.
*
* @param string $filename Name of file to search path stack for.
* @param string $filename Name of file to search path stack for.
* @param bool $failOnError If true, throw an exception when file not found.
*
* @return TextDomain
*/
protected function loadLanguageFile($filename)
protected function loadLanguageFile($filename, $failOnError = true)
{
// Don't load a file that has already been loaded:
if ($this->checkAndMarkLoadedFile($filename)) {
......@@ -189,7 +222,13 @@ class ExtendedIni implements FileLoaderInterface
}
}
if ($data === false) {
throw new InvalidArgumentException("Ini file '{$filename}' not found");
// Should we throw an exception? If not, return an empty result:
if ($failOnError) {
throw new InvalidArgumentException(
"Ini file '{$filename}' not found"
);
}
return new TextDomain();
}
return $data;
......
......@@ -125,8 +125,11 @@ trait TranslatorAwareTrait
*/
protected function translateString($str, $tokens = [], $default = null)
{
$msg = null === $this->translator
? $str : $this->translator->translate($str);
// Figure out the text domain for the string:
list($domain, $str) = $this->extractTextDomain($str);
$msg = (null === $this->translator)
? $str : $this->translator->translate($str, $domain);
// Did the translation fail to change anything? If so, use default:
if (null !== $default && $msg == $str) {
......@@ -145,4 +148,21 @@ trait TranslatorAwareTrait
return $msg;
}
/**
* Given a translation string with or without a text domain, return an
* array with the raw string and the text domain separated.
*
* @param string $str String to parse
*
* @return array
*/
protected function extractTextDomain($str)
{
$parts = explode('::', $str);
if (count($parts) == 2) {
return $parts;
}
return ['default', $str];
}
}
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment