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