/lib/ezc/Translation/src/translation.php

https://bitbucket.org/crevillo/enetcall · PHP · 197 lines · 69 code · 6 blank · 122 comment · 8 complexity · d58b3b2a085f9ce76d6799ac4703aab2 MD5 · raw file

  1. <?php
  2. /**
  3. * @copyright Copyright (C) 2005-2010 eZ Systems AS. All rights reserved.
  4. * @license http://ez.no/licenses/new_bsd New BSD License
  5. * @version //autogentag//
  6. * @filesource
  7. * @package Translation
  8. */
  9. /**
  10. * ezcTranslation is a container that holds the translated strings for a
  11. * specific context.
  12. *
  13. * ezcTranslation objects are returned by the ezcTranslationManager for every
  14. * requested context.
  15. *
  16. * For an example see {@link ezcTranslationManager}.
  17. *
  18. * @package Translation
  19. * @version //autogentag//
  20. * @mainclass
  21. */
  22. class ezcTranslation
  23. {
  24. /**
  25. * Contains an array where the key is the original string (often
  26. * English) and the element is an object of the class
  27. * ezcTranslationData (a struct).
  28. *
  29. * @var array(string=>ezcTranslationData)
  30. */
  31. private $translationMap;
  32. /**
  33. * Constructs the ezcTranslation object.
  34. *
  35. * The constructor receives an array containing the translation elements,
  36. * and builds up an internal map between the original string and the
  37. * accompanying translation data.
  38. *
  39. * @param array(ezcTranslationData) $data
  40. */
  41. function __construct( array $data )
  42. {
  43. $this->translationMap = array();
  44. foreach ( $data as $translationElement )
  45. {
  46. $this->translationMap[$translationElement->original] = $translationElement;
  47. }
  48. }
  49. /**
  50. * Returns the replacement for the key $key from the parameters $params.
  51. *
  52. * The params array is an associative array in the form array('key'=>'value').
  53. *
  54. * This is a callback function used by the getTranslation() method for each
  55. * matched parameter in the translated string.
  56. *
  57. * @param string $key
  58. * @param array $params
  59. * @return string
  60. */
  61. private function parameterCallback( $key, array $params )
  62. {
  63. if ( !isset( $params[strtolower( $key )] ) )
  64. {
  65. throw new ezcTranslationParameterMissingException( $key );
  66. }
  67. $string = $params[strtolower( $key )];
  68. // We use ctype_upper() here to check if the first character of the key
  69. // is an uppercase letter. If it is then we make the first character of
  70. // the returned translation also an upper case character. With this
  71. // mechanism we can correctly upper case translated strings if word
  72. // order changes. See
  73. // {@link ezcTranslationTest::testGetStringWithParameters} for an
  74. // example of this.
  75. if ( ctype_upper( $key[0] ) )
  76. {
  77. $string = ucfirst( $string );
  78. }
  79. return $string;
  80. }
  81. /**
  82. * Returns the translated version of the original string $key.
  83. *
  84. * This method returns a translated string and substitutes the parameters $param
  85. * in the localized string.
  86. *
  87. * @throws ezcTranslationKeyNotAvailableException when the key is not
  88. * available in the translation definitions
  89. * @throws ezcTranslationParameterMissingException when not enough
  90. * parameters are passed for a parameterized string
  91. * @param string $key
  92. * @param array(string=>string) $params
  93. * @return string
  94. */
  95. public function getTranslation( $key, array $params = array() )
  96. {
  97. if ( !isset( $this->translationMap[$key] ) )
  98. {
  99. throw new ezcTranslationKeyNotAvailableException( $key );
  100. }
  101. $translatedString = $this->translationMap[$key]->translation;
  102. // Little optimization to prevent preg if not needed, it bails out too
  103. // if there is just a percent sign in the string without a valid
  104. // parameter-identifier, but we can live with that.
  105. if ( strstr( $translatedString, '%' ) === false )
  106. {
  107. return $translatedString;
  108. }
  109. // So we do have a possibility of a parameterized string, replace those
  110. // with the parameters. The callback function can actually throw an
  111. // exception to tell that there was a missing parameter.
  112. return (string) preg_replace( '@%(([A-Za-z][a-z_]*[a-z])|[1-9])@e', '$this->parameterCallback("\\1", $params)', $translatedString );
  113. }
  114. /**
  115. * Returns the replacement for the key $key from the parameters $params.
  116. *
  117. * The params array is an associative array in the form array('key'=>'value').
  118. *
  119. * This is a callback function used by the compileTranslation() method for each
  120. * matched parameter in the translated string.
  121. *
  122. * @param string $key
  123. * @param array $params
  124. * @return string
  125. */
  126. private function parameterCallbackCompile( $key, array $params )
  127. {
  128. if ( !isset( $params[strtolower( $key )] ) )
  129. {
  130. throw new ezcTranslationParameterMissingException( $key );
  131. }
  132. // We use ctype_upper() here to check if the first character of the key
  133. // is an uppercase letter. If it is then we make the first character of
  134. // the returned translation also an upper case character. With this
  135. // mechanism we can correctly upper case translated strings if word
  136. // order changes. See
  137. // {@link ezcTranslationTest::testGetStringWithParameters} for an
  138. // example of this.
  139. if ( ctype_upper( $key[0] ) )
  140. {
  141. $string = "' . ucfirst(". $params[strtolower( $key )] . ") . '";
  142. }
  143. else
  144. {
  145. $string = "' . ". $params[strtolower( $key )] . " . '";
  146. }
  147. return $string;
  148. }
  149. /**
  150. * Returns the translated version of the original string $key.
  151. *
  152. * This method returns a translated string and substitutes the parameters $param
  153. * in the localized string with PHP code to place the variable data into
  154. * the string at a later moment. Instead of the values for each of the
  155. * parameters, an expression to get to the data should be sumbitted into
  156. * the $params array.
  157. *
  158. * <code>
  159. * echo $translation->compileTranslation( "Hello #%nr", array( "nr" => '$this->send->nr' ) );
  160. * </code>
  161. *
  162. * Will return something like:
  163. * <code>
  164. * 'Hallo #' . $this->send->nr . ''
  165. * </code>
  166. *
  167. * @param string $key
  168. * @param array(string=>string) $params
  169. * @return string
  170. */
  171. public function compileTranslation( $key, array $params = array() )
  172. {
  173. if ( !isset( $this->translationMap[$key] ) )
  174. {
  175. throw new ezcTranslationKeyNotAvailableException( $key );
  176. }
  177. $translatedString = var_export( $this->translationMap[$key]->translation, true );
  178. // Little optimization to prevent preg if not needed, it bails out too
  179. // if there is just a percent sign in the string without a valid
  180. // parameter-identifier, but we can live with that.
  181. if ( strstr( $translatedString, '%' ) === false )
  182. {
  183. return $translatedString;
  184. }
  185. // So we do have a possibility of a parameterized string, replace those
  186. // with the parameters. The callback function can actually throw an
  187. // exception to tell that there was a missing parameter.
  188. return (string) preg_replace( '@%(([A-Za-z][a-z_]*[a-z])|[1-9])@e', '$this->parameterCallbackCompile("\\1", $params)', $translatedString );
  189. }
  190. }
  191. ?>