PoItem.php 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. <?php
  2. /**
  3. * @file
  4. * Definition of Drupal\Component\Gettext\PoItem.
  5. */
  6. /**
  7. * PoItem handles one translation.
  8. */
  9. class PoItem {
  10. /**
  11. * The language code this translation is in.
  12. *
  13. * @var string
  14. */
  15. private $_langcode;
  16. /**
  17. * The context this translation belongs to.
  18. *
  19. * @var string
  20. */
  21. private $_context = '';
  22. /**
  23. * The source string or array of strings if it has plurals.
  24. *
  25. * @var string|array
  26. *
  27. * @see $_plural
  28. */
  29. private $_source;
  30. /**
  31. * Flag indicating if this translation has plurals.
  32. *
  33. * @var boolean
  34. */
  35. private $_plural;
  36. /**
  37. * The comment of this translation.
  38. *
  39. * @var string
  40. */
  41. private $_comment;
  42. /**
  43. * The text group of this translation.
  44. *
  45. * @var string
  46. */
  47. private $_textgroup;
  48. /**
  49. * The translation string or array of strings if it has plurals.
  50. *
  51. * @var string|array
  52. *
  53. * @see $_plural
  54. */
  55. private $_translation;
  56. /**
  57. * Get the language code of the currently used language.
  58. *
  59. * @return string
  60. * The translation language code.
  61. */
  62. public function getLangcode() {
  63. return $this->_langcode;
  64. }
  65. /**
  66. * Set the language code of the current language.
  67. *
  68. * @param string $langcode
  69. * The translation language code.
  70. */
  71. public function setLangcode($langcode) {
  72. $this->_langcode = $langcode;
  73. }
  74. /**
  75. * Get the translation group of this translation.
  76. *
  77. * @return string
  78. * The translation text group.
  79. */
  80. public function getTextgroup() {
  81. return empty($this->_textgroup) ? 'default' : $this->_textgroup;
  82. }
  83. /**
  84. * Set the translation group of this translation.
  85. *
  86. * @param string $textgroup
  87. * The translation text group.
  88. */
  89. public function setTextgroup($textgroup) {
  90. $this->_textgroup = $textgroup;
  91. }
  92. /**
  93. * Get the context this translation belongs to.
  94. *
  95. * @return string
  96. * The translation context.
  97. */
  98. public function getContext() {
  99. return $this->_context;
  100. }
  101. /**
  102. * Set the context this translation belongs to.
  103. */
  104. public function setContext($context) {
  105. $this->_context = $context;
  106. }
  107. /**
  108. * Get the source string(s) if the translation has plurals.
  109. *
  110. * @return string|array
  111. * Translation source string(s).
  112. */
  113. public function getSource() {
  114. return $this->_source;
  115. }
  116. /**
  117. * Set the source string(s) if the translation has plurals.
  118. *
  119. * @param string|array
  120. * Translation source string(s).
  121. */
  122. public function setSource($source) {
  123. $this->_source = $source;
  124. }
  125. /**
  126. * Get the translation string(s) if the translation has plurals.
  127. *
  128. * @return string|array
  129. * Translation string(s).
  130. */
  131. public function getTranslation() {
  132. return $this->_translation;
  133. }
  134. /**
  135. * Set the translation string(s) if the translation has plurals.
  136. */
  137. public function setTranslation($translation) {
  138. $this->_translation = $translation;
  139. }
  140. /**
  141. * Set if the translation has plural values.
  142. *
  143. * @param bool $plural
  144. * The translation plural flag.
  145. */
  146. public function setPlural($plural) {
  147. $this->_plural = $plural;
  148. }
  149. /**
  150. * Get if the translation has plural values.
  151. *
  152. * @return integer $plural
  153. * The translation plural flag.
  154. */
  155. public function isPlural() {
  156. return $this->_plural;
  157. }
  158. /**
  159. * Get the comment of this translation.
  160. *
  161. * @return string
  162. * The translation comment.
  163. */
  164. public function getComment() {
  165. return $this->_comment;
  166. }
  167. /**
  168. * Set the comment of this translation.
  169. *
  170. * @param string $comment
  171. * The translation comment.
  172. */
  173. public function setComment($comment) {
  174. $this->_comment = $comment;
  175. }
  176. /**
  177. * Create the PoItem from a structured array.
  178. *
  179. * @param array $values
  180. * Keyed array with translation data.
  181. */
  182. public function setFromArray(array $values = array()) {
  183. if (isset($values['context'])) {
  184. $this->setContext($values['context']);
  185. }
  186. if (isset($values['source'])) {
  187. $this->setSource($values['source']);
  188. }
  189. if (isset($values['translation'])) {
  190. $this->setTranslation($values['translation']);
  191. }
  192. if (isset($values['comment'])) {
  193. $this->setComment($values['comment']);
  194. }
  195. if (isset($this->_source) && count($this->_source) > 1) {
  196. $this->setPlural(count($this->_translation) > 1);
  197. }
  198. }
  199. /**
  200. * Output the PoItem as a string.
  201. *
  202. * @return string
  203. * PO item string value.
  204. */
  205. public function __toString() {
  206. return $this->formatItem();
  207. }
  208. /**
  209. * Format the POItem as a string.
  210. *
  211. * @return string
  212. * Formatted PO item.
  213. */
  214. private function formatItem() {
  215. $output = '';
  216. // Format string context.
  217. if (!empty($this->_context)) {
  218. $output .= 'msgctxt ' . $this->formatString($this->_context);
  219. }
  220. // Format translation.
  221. if ($this->_plural) {
  222. $output .= $this->formatPlural();
  223. }
  224. else {
  225. $output .= $this->formatSingular();
  226. }
  227. // Add one empty line to separate the translations.
  228. $output .= "\n";
  229. return $output;
  230. }
  231. /**
  232. * Formats a plural translation.
  233. *
  234. * @return string
  235. * Gettext formatted plural translation.
  236. */
  237. private function formatPlural() {
  238. $output = '';
  239. // Format source strings.
  240. $output .= 'msgid ' . $this->formatString($this->_source[0]);
  241. $output .= 'msgid_plural ' . $this->formatString($this->_source[1]);
  242. foreach ($this->_translation as $i => $trans) {
  243. if (isset($this->_translation[$i])) {
  244. $output .= 'msgstr[' . $i . '] ' . $this->formatString($trans);
  245. }
  246. else {
  247. $output .= 'msgstr[' . $i . '] ""' . "\n";
  248. }
  249. }
  250. return $output;
  251. }
  252. /**
  253. * Formats a singular translation.
  254. *
  255. * @return string
  256. * Gettext formatted singular translation.
  257. */
  258. private function formatSingular() {
  259. $output = '';
  260. $output .= 'msgid ' . $this->formatString($this->_source);
  261. $output .= 'msgstr ' . (isset($this->_translation) ? $this->formatString($this->_translation) : '""');
  262. return $output;
  263. }
  264. /**
  265. * Formats a string for output on multiple lines.
  266. *
  267. * @param string $string
  268. * A string.
  269. *
  270. * @return string
  271. * Gettext formatted multi-line string.
  272. */
  273. private function formatString($string) {
  274. // Escape characters for processing.
  275. $string = addcslashes($string, "\0..\37\\\"");
  276. // Always include a line break after the explicit \n line breaks from
  277. // the source string. Otherwise wrap at 70 chars to accommodate the extra
  278. // format overhead too.
  279. $parts = explode("\n", wordwrap(str_replace('\n', "\\n\n", $string), 70, " \n"));
  280. // Multiline string should be exported starting with a "" and newline to
  281. // have all lines aligned on the same column.
  282. if (count($parts) > 1) {
  283. return "\"\"\n\"" . implode("\"\n\"", $parts) . "\"\n";
  284. }
  285. // Single line strings are output on the same line.
  286. else {
  287. return "\"$parts[0]\"\n";
  288. }
  289. }
  290. }