Merge pull request #5983 from relldoesphp/CRM-16544
[civicrm-core.git] / CRM / Core / I18n.php
index ee83f8bb75276fb3d833fadbf51999b91d26c7ab..a36389ec7f14a9d9039895b29dc433b0877f105c 100644 (file)
@@ -3,7 +3,7 @@
  +--------------------------------------------------------------------+
  | CiviCRM version 4.6                                                |
  +--------------------------------------------------------------------+
- | Copyright CiviCRM LLC (c) 2004-2014                                |
+ | Copyright CiviCRM LLC (c) 2004-2015                                |
  +--------------------------------------------------------------------+
  | This file is a part of CiviCRM.                                    |
  |                                                                    |
  | GNU Affero General Public License or the licensing of CiviCRM,     |
  | see the CiviCRM license FAQ at http://civicrm.org/licensing        |
  +--------------------------------------------------------------------+
-*/
+ */
 
 /**
  *
  * @package CRM
- * @copyright CiviCRM LLC (c) 2004-2014
+ * @copyright CiviCRM LLC (c) 2004-2015
  * $Id$
  *
  */
@@ -55,8 +55,8 @@ class CRM_Core_I18n {
   /**
    * A locale-based constructor that shouldn't be called from outside of this class (use singleton() instead).
    *
-   * @param $locale
-   *   String the base of this certain object's existence.
+   * @param string $locale
+   *   the base of this certain object's existence.
    *
    * @return \CRM_Core_I18n
    */
@@ -95,7 +95,7 @@ class CRM_Core_I18n {
 
       $mo_file = $config->gettextResourceDir . $locale . DIRECTORY_SEPARATOR . 'LC_MESSAGES' . DIRECTORY_SEPARATOR . 'civicrm.mo';
 
-      if (! file_exists($mo_file)) {
+      if (!file_exists($mo_file)) {
         // fallback to pre-4.5 mode
         $mo_file = $config->gettextResourceDir . $locale . DIRECTORY_SEPARATOR . 'civicrm.mo';
       }
@@ -109,7 +109,8 @@ class CRM_Core_I18n {
   /**
    * Returns whether gettext is running natively or using PHP-Gettext.
    *
-   * @return bool True if gettext is native
+   * @return bool
+   *   True if gettext is native
    */
   public function isNative() {
     return $this->_nativegettext;
@@ -118,10 +119,11 @@ class CRM_Core_I18n {
   /**
    * Return languages available in this instance of CiviCRM.
    *
-   * @param $justEnabled
-   *   Boolean whether to return all languages or just the enabled ones.
+   * @param bool $justEnabled
+   *   whether to return all languages or just the enabled ones.
    *
-   * @return             array    of code/language name mappings
+   * @return array
+   *   Array of code/language name mappings
    */
   public static function languages($justEnabled = FALSE) {
     static $all = NULL;
@@ -150,7 +152,9 @@ class CRM_Core_I18n {
         if ($code == 'en_US') {
           continue;
         }
-        if (!in_array($code, $codes))unset($all[$code]);
+        if (!in_array($code, $codes)) {
+          unset($all[$code]);
+        }
       }
     }
 
@@ -172,11 +176,11 @@ class CRM_Core_I18n {
   /**
    * Replace arguments in a string with their values. Arguments are represented by % followed by their number.
    *
-   * @param $str
-   *   String source string.
-   * @param mixed arguments, can be passed in an array or through single variables
+   * @param string $str
+   *   source string.
    *
-   * @return      string  modified string
+   * @return string
+   *   modified string
    */
   public function strarg($str) {
     $tr = array();
@@ -210,12 +214,14 @@ class CRM_Core_I18n {
    *   - count - The item count for plural mode (3rd parameter of ngettext())
    *   - context - gettext context of that string (for homonym handling)
    *
-   * @param $text
-   *   String the original string.
-   * @param $params
-   *   Array the params of the translation (if any).
-   *
-   * @return        string  the translated string
+   * @param string $text
+   *   the original string.
+   * @param array $params
+   *   The params of the translation (if any).
+   *   - domain: string|array a list of translation domains to search (in order)
+   *   - context: string
+   * @return string
+   *   the translated string
    */
   public function crm_translate($text, $params = array()) {
     if (isset($params['escape'])) {
@@ -237,6 +243,7 @@ class CRM_Core_I18n {
       return $text;
     }
 
+    $plural = $count = NULL;
     if (isset($params['plural'])) {
       $plural = $params['plural'];
       unset($params['plural']);
@@ -253,10 +260,69 @@ class CRM_Core_I18n {
       $context = NULL;
     }
 
+    if (isset($params['domain'])) {
+      $domain = $params['domain'];
+      unset($params['domain']);
+    }
+    else {
+      $domain = NULL;
+    }
+
+    $raw = !empty($params['raw']);
+    unset($params['raw']);
+
+    if (!empty($domain)) {
+      // It might be prettier to cast to an array, but this is high-traffic stuff.
+      if (is_array($domain)) {
+        foreach ($domain as $d) {
+          $candidate = $this->crm_translate_raw($text, $d, $count, $plural, $context);
+          if ($candidate != $text) {
+            $text = $candidate;
+            break;
+          }
+        }
+      }
+      else {
+        $text = $this->crm_translate_raw($text, $domain, $count, $plural, $context);
+      }
+    }
+    else {
+      $text = $this->crm_translate_raw($text, NULL, $count, $plural, $context);
+    }
+
+    // replace the numbered %1, %2, etc. params if present
+    if (count($params) && !$raw) {
+      $text = $this->strarg($text, $params);
+    }
+
+    // escape SQL if we were asked for it
+    if (isset($escape) and ($escape == 'sql')) {
+      $text = CRM_Core_DAO::escapeString($text);
+    }
+
+    // escape for JavaScript (if requested)
+    if (isset($escape) and ($escape == 'js')) {
+      $text = addcslashes($text, "'");
+    }
+
+    return $text;
+  }
+
+  /**
+   * Lookup the raw translation of a string (without any extra escaping or interpolation).
+   *
+   * @param string $text
+   * @param string|NULL $domain
+   * @param int|NULL $count
+   * @param string $plural
+   * @param string $context
+   * @return mixed|string|translated
+   */
+  protected function crm_translate_raw($text, $domain, $count, $plural, $context) {
     // gettext domain for extensions
     $domain_changed = FALSE;
-    if (! empty($params['domain']) && $this->_phpgettext) {
-      if ($this->setGettextDomain($params['domain'])) {
+    if (!empty($domain) && $this->_phpgettext) {
+      if ($this->setGettextDomain($domain)) {
         $domain_changed = TRUE;
       }
     }
@@ -283,9 +349,9 @@ class CRM_Core_I18n {
       !$exactMatch &&
       isset($stringTable['enabled']['wildcardMatch'])
     ) {
-      $search  = array_keys($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
@@ -319,21 +385,6 @@ class CRM_Core_I18n {
       }
     }
 
-    // replace the numbered %1, %2, etc. params if present
-    if (count($params)) {
-      $text = $this->strarg($text, $params);
-    }
-
-    // escape SQL if we were asked for it
-    if (isset($escape) and ($escape == 'sql')) {
-      $text = CRM_Core_DAO::escapeString($text);
-    }
-
-    // escape for JavaScript (if requested)
-    if (isset($escape) and ($escape == 'js')) {
-      $text = addcslashes($text, "'");
-    }
-
     if ($domain_changed) {
       $this->setGettextDomain('civicrm');
     }
@@ -344,10 +395,11 @@ class CRM_Core_I18n {
   /**
    * Translate a string to the current locale.
    *
-   * @param $string
-   *   String this string should be translated.
+   * @param string $string
+   *   this string should be translated.
    *
-   * @return         string  the translated string
+   * @return string
+   *   the translated string
    */
   public function translate($string) {
     return ($this->_phpgettext) ? $this->_phpgettext->translate($string) : $string;
@@ -356,14 +408,14 @@ class CRM_Core_I18n {
   /**
    * Localize (destructively) array values.
    *
-   * @param $array
-   *   Array the array for localization (in place).
-   * @param $params
-   *   Array an array of additional parameters.
+   * @param array $array
+   *   the array for localization (in place).
+   * @param array $params
+   *   an array of additional parameters.
    *
-   * @return        void
+   * @return void
    */
-  function localizeArray(
+  public function localizeArray(
     &$array,
     $params = array()
   ) {
@@ -383,10 +435,10 @@ class CRM_Core_I18n {
   /**
    * Localize (destructively) array elements with keys of 'title'.
    *
-   * @param $array
-   *   Array the array for localization (in place).
+   * @param array $array
+   *   the array for localization (in place).
    *
-   * @return        void
+   * @return void
    */
   public function localizeTitles(&$array) {
     foreach ($array as $key => $value) {
@@ -406,16 +458,17 @@ class CRM_Core_I18n {
    * @param $key
    *   Key of the extension (can be 'civicrm', or 'org.example.foo').
    *
-   * @return Boolean True if the domain was changed for an extension.
+   * @return Bool
+   *   True if the domain was changed for an extension.
    */
   public function setGettextDomain($key) {
     /* No domain changes for en_US */
-    if (! $this->_phpgettext) {
+    if (!$this->_phpgettext) {
       return FALSE;
     }
 
     // It's only necessary to find/bind once
-    if (! isset($this->_extensioncache[$key])) {
+    if (!isset($this->_extensioncache[$key])) {
       $config = CRM_Core_Config::singleton();
 
       try {
@@ -460,6 +513,8 @@ class CRM_Core_I18n {
 
   /**
    * Static instance provider - return the instance for the current locale.
+   *
+   * @return CRM_Core_I18n
    */
   public static function &singleton() {
     static $singleton = array();
@@ -475,7 +530,8 @@ class CRM_Core_I18n {
   /**
    * Set the LC_TIME locale if it's not set already (for a given language choice).
    *
-   * @return string  the final LC_TIME that got set
+   * @return string
+   *   the final LC_TIME that got set
    */
   public static function setLcTime() {
     static $locales = array();
@@ -489,6 +545,7 @@ class CRM_Core_I18n {
 
     return $locales[$tsLocale];
   }
+
 }
 
 /**
@@ -496,10 +553,11 @@ class CRM_Core_I18n {
  *
  * @param $text
  *   String string for translating.
- * @param $params
+ * @param array $params
  *   Array an array of additional parameters.
  *
- * @return         string  the translated string
+ * @return string
+ *   the translated string
  */
 function ts($text, $params = array()) {
   static $config = NULL;