X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=CRM%2FCore%2FI18n.php;h=af6c536d5518eaab19fe82c2ab17eb520a7a0179;hb=9ab99c19a4663b23a3175405e07b27b6eadafcd8;hp=889d88ae4591981608e4f44a29dd7c8815a1116a;hpb=a70a27f6e4be1cff604b9d9b94952d846a909842;p=civicrm-core.git diff --git a/CRM/Core/I18n.php b/CRM/Core/I18n.php index 889d88ae45..af6c536d55 100644 --- a/CRM/Core/I18n.php +++ b/CRM/Core/I18n.php @@ -1,7 +1,7 @@ _phpgettext = new CRM_Core_I18n_NativeGettext(); + $this->_extensioncache['civicrm'] = 'civicrm'; return; } // Otherwise, use PHP-gettext + // we support both the old file hierarchy format and the new: + // pre-4.5: civicrm/l10n/xx_XX/civicrm.mo + // post-4.5: civicrm/l10n/xx_XX/LC_MESSAGES/civicrm.mo require_once 'PHPgettext/streams.php'; require_once 'PHPgettext/gettext.php'; - $streamer = new FileReader($config->gettextResourceDir . $locale . DIRECTORY_SEPARATOR . 'civicrm.mo'); + $mo_file = $config->gettextResourceDir . $locale . DIRECTORY_SEPARATOR . 'LC_MESSAGES' . DIRECTORY_SEPARATOR . 'civicrm.mo'; + + if (! file_exists($mo_file)) { + // fallback to pre-4.5 mode + $mo_file = $config->gettextResourceDir . $locale . DIRECTORY_SEPARATOR . 'civicrm.mo'; + } + + $streamer = new FileReader($mo_file); $this->_phpgettext = new gettext_reader($streamer); + $this->_extensioncache['civicrm'] = $this->_phpgettext; } } @@ -106,7 +126,7 @@ class CRM_Core_I18n { static $enabled = NULL; if (!$all) { - $all = CRM_Core_I18n_PseudoConstant::languages(); + $all = CRM_Contact_BAO_Contact::buildOptions('preferred_language'); // check which ones are available; add them to $all if not there already $config = CRM_Core_Config::singleton(); @@ -229,9 +249,18 @@ class CRM_Core_I18n { $context = NULL; } + // gettext domain for extensions + $domain_changed = FALSE; + if (! empty($params['domain']) && $this->_phpgettext) { + if ($this->setGettextDomain($params['domain'])) { + $domain_changed = TRUE; + } + } + // do all wildcard translations first $config = CRM_Core_Config::singleton(); - $stringTable = CRM_Utils_Array::value($config->lcMessages, + $stringTable = CRM_Utils_Array::value( + $config->lcMessages, $config->localeCustomStrings ); @@ -246,15 +275,13 @@ class CRM_Core_I18n { } } - if (!$exactMatch && + if ( + !$exactMatch && isset($stringTable['enabled']['wildcardMatch']) ) { $search = array_keys($stringTable['enabled']['wildcardMatch']); $replace = array_values($stringTable['enabled']['wildcardMatch']); - $text = str_replace($search, - $replace, - $text - ); + $text = str_replace($search, $replace, $text); } // dont translate if we've done exactMatch already @@ -303,6 +330,10 @@ class CRM_Core_I18n { $text = addcslashes($text, "'"); } + if ($domain_changed) { + $this->setGettextDomain('civicrm'); + } + return $text; } @@ -361,6 +392,63 @@ class CRM_Core_I18n { } } + /** + * Binds a gettext domain, wrapper over bindtextdomain(). + * + * @param $key Key of the extension (can be 'civicrm', or 'org.example.foo'). + * + * @return Boolean True if the domain was changed for an extension. + */ + function setGettextDomain($key) { + /* No domain changes for en_US */ + if (! $this->_phpgettext) { + return FALSE; + } + + // It's only necessary to find/bind once + if (! isset($this->_extensioncache[$key])) { + $config = CRM_Core_Config::singleton(); + + try { + $mapper = CRM_Extension_System::singleton()->getMapper(); + $path = $mapper->keyToBasePath($key); + $info = $mapper->keyToInfo($key); + $domain = $info->file; + + if ($this->_nativegettext) { + bindtextdomain($domain, $path . DIRECTORY_SEPARATOR . 'l10n'); + bind_textdomain_codeset($domain, 'UTF-8'); + $this->_extensioncache[$key] = $domain; + } + else { + // phpgettext + $mo_file = $path . DIRECTORY_SEPARATOR . 'l10n' . DIRECTORY_SEPARATOR . $config->lcMessages . DIRECTORY_SEPARATOR . 'LC_MESSAGES' . DIRECTORY_SEPARATOR . $domain . '.mo'; + $streamer = new FileReader($mo_file); + $this->_extensioncache[$key] = new gettext_reader($streamer); + } + } + catch (CRM_Extension_Exception $e) { + // Intentionally not translating this string to avoid possible infinit loops + // Only developers should see this string, if they made a mistake in their ts() usage. + CRM_Core_Session::setStatus('Unknown extension key in a translation string: ' . $key, '', 'error'); + $this->_extensioncache[$key] = FALSE; + } + } + + if (isset($this->_extensioncache[$key]) && $this->_extensioncache[$key]) { + if ($this->_nativegettext) { + textdomain($this->_extensioncache[$key]); + } + else { + $this->_phpgettext = $this->_extensioncache[$key]; + } + + return TRUE; + } + + return FALSE; + } + /** * Static instance provider - return the instance for the current locale. */