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