Mercurial > hg > isophonics-drupal-site
comparison core/modules/locale/src/PoDatabaseWriter.php @ 0:4c8ae668cc8c
Initial import (non-working)
author | Chris Cannam |
---|---|
date | Wed, 29 Nov 2017 16:09:58 +0000 |
parents | |
children | c2387f117808 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4c8ae668cc8c |
---|---|
1 <?php | |
2 | |
3 namespace Drupal\locale; | |
4 | |
5 use Drupal\Component\Gettext\PoHeader; | |
6 use Drupal\Component\Gettext\PoItem; | |
7 use Drupal\Component\Gettext\PoReaderInterface; | |
8 use Drupal\Component\Gettext\PoWriterInterface; | |
9 | |
10 /** | |
11 * Gettext PO writer working with the locale module database. | |
12 */ | |
13 class PoDatabaseWriter implements PoWriterInterface { | |
14 | |
15 /** | |
16 * An associative array indicating what data should be overwritten, if any. | |
17 * | |
18 * Elements of the array: | |
19 * - override_options | |
20 * - not_customized: boolean indicating that not customized strings should | |
21 * be overwritten. | |
22 * - customized: boolean indicating that customized strings should be | |
23 * overwritten. | |
24 * - customized: the strings being imported should be saved as customized. | |
25 * One of LOCALE_CUSTOMIZED or LOCALE_NOT_CUSTOMIZED. | |
26 * | |
27 * @var array | |
28 */ | |
29 private $options; | |
30 | |
31 /** | |
32 * Language code of the language being written to the database. | |
33 * | |
34 * @var string | |
35 */ | |
36 private $langcode; | |
37 | |
38 /** | |
39 * Header of the po file written to the database. | |
40 * | |
41 * @var \Drupal\Component\Gettext\PoHeader | |
42 */ | |
43 private $header; | |
44 | |
45 /** | |
46 * Associative array summarizing the number of changes done. | |
47 * | |
48 * Keys for the array: | |
49 * - additions: number of source strings newly added | |
50 * - updates: number of translations updated | |
51 * - deletes: number of translations deleted | |
52 * - skips: number of strings skipped due to disallowed HTML | |
53 * | |
54 * @var array | |
55 */ | |
56 private $report; | |
57 | |
58 /** | |
59 * Constructor, initialize reporting array. | |
60 */ | |
61 public function __construct() { | |
62 $this->setReport(); | |
63 } | |
64 | |
65 /** | |
66 * {@inheritdoc} | |
67 */ | |
68 public function getLangcode() { | |
69 return $this->langcode; | |
70 } | |
71 | |
72 /** | |
73 * {@inheritdoc} | |
74 */ | |
75 public function setLangcode($langcode) { | |
76 $this->langcode = $langcode; | |
77 } | |
78 | |
79 /** | |
80 * Get the report of the write operations. | |
81 */ | |
82 public function getReport() { | |
83 return $this->report; | |
84 } | |
85 | |
86 /** | |
87 * Set the report array of write operations. | |
88 * | |
89 * @param array $report | |
90 * Associative array with result information. | |
91 */ | |
92 public function setReport($report = []) { | |
93 $report += [ | |
94 'additions' => 0, | |
95 'updates' => 0, | |
96 'deletes' => 0, | |
97 'skips' => 0, | |
98 'strings' => [], | |
99 ]; | |
100 $this->report = $report; | |
101 } | |
102 | |
103 /** | |
104 * Get the options used by the writer. | |
105 */ | |
106 public function getOptions() { | |
107 return $this->options; | |
108 } | |
109 | |
110 /** | |
111 * Set the options for the current writer. | |
112 */ | |
113 public function setOptions(array $options) { | |
114 if (!isset($options['overwrite_options'])) { | |
115 $options['overwrite_options'] = []; | |
116 } | |
117 $options['overwrite_options'] += [ | |
118 'not_customized' => FALSE, | |
119 'customized' => FALSE, | |
120 ]; | |
121 $options += [ | |
122 'customized' => LOCALE_NOT_CUSTOMIZED, | |
123 ]; | |
124 $this->options = $options; | |
125 } | |
126 | |
127 /** | |
128 * {@inheritdoc} | |
129 */ | |
130 public function getHeader() { | |
131 return $this->header; | |
132 } | |
133 | |
134 /** | |
135 * Implements Drupal\Component\Gettext\PoMetadataInterface::setHeader(). | |
136 * | |
137 * Sets the header and configure Drupal accordingly. | |
138 * | |
139 * Before being able to process the given header we need to know in what | |
140 * context this database write is done. For this the options must be set. | |
141 * | |
142 * A langcode is required to set the current header's PluralForm. | |
143 * | |
144 * @param \Drupal\Component\Gettext\PoHeader $header | |
145 * Header metadata. | |
146 * | |
147 * @throws Exception | |
148 */ | |
149 public function setHeader(PoHeader $header) { | |
150 $this->header = $header; | |
151 $locale_plurals = \Drupal::state()->get('locale.translation.plurals') ?: []; | |
152 | |
153 // Check for options. | |
154 $options = $this->getOptions(); | |
155 if (empty($options)) { | |
156 throw new \Exception('Options should be set before assigning a PoHeader.'); | |
157 } | |
158 $overwrite_options = $options['overwrite_options']; | |
159 | |
160 // Check for langcode. | |
161 $langcode = $this->langcode; | |
162 if (empty($langcode)) { | |
163 throw new \Exception('Langcode should be set before assigning a PoHeader.'); | |
164 } | |
165 | |
166 if (array_sum($overwrite_options) || empty($locale_plurals[$langcode]['plurals'])) { | |
167 // Get and store the plural formula if available. | |
168 $plural = $header->getPluralForms(); | |
169 if (isset($plural) && $p = $header->parsePluralForms($plural)) { | |
170 list($nplurals, $formula) = $p; | |
171 \Drupal::service('locale.plural.formula')->setPluralFormula($langcode, $nplurals, $formula); | |
172 } | |
173 } | |
174 } | |
175 | |
176 /** | |
177 * {@inheritdoc} | |
178 */ | |
179 public function writeItem(PoItem $item) { | |
180 if ($item->isPlural()) { | |
181 $item->setSource(implode(LOCALE_PLURAL_DELIMITER, $item->getSource())); | |
182 $item->setTranslation(implode(LOCALE_PLURAL_DELIMITER, $item->getTranslation())); | |
183 } | |
184 $this->importString($item); | |
185 } | |
186 | |
187 /** | |
188 * {@inheritdoc} | |
189 */ | |
190 public function writeItems(PoReaderInterface $reader, $count = -1) { | |
191 $forever = $count == -1; | |
192 while (($count-- > 0 || $forever) && ($item = $reader->readItem())) { | |
193 $this->writeItem($item); | |
194 } | |
195 } | |
196 | |
197 /** | |
198 * Imports one string into the database. | |
199 * | |
200 * @param \Drupal\Component\Gettext\PoItem $item | |
201 * The item being imported. | |
202 * | |
203 * @return int | |
204 * The string ID of the existing string modified or the new string added. | |
205 */ | |
206 private function importString(PoItem $item) { | |
207 // Initialize overwrite options if not set. | |
208 $this->options['overwrite_options'] += [ | |
209 'not_customized' => FALSE, | |
210 'customized' => FALSE, | |
211 ]; | |
212 $overwrite_options = $this->options['overwrite_options']; | |
213 $customized = $this->options['customized']; | |
214 | |
215 $context = $item->getContext(); | |
216 $source = $item->getSource(); | |
217 $translation = $item->getTranslation(); | |
218 | |
219 // Look up the source string and any existing translation. | |
220 $strings = \Drupal::service('locale.storage')->getTranslations([ | |
221 'language' => $this->langcode, | |
222 'source' => $source, | |
223 'context' => $context, | |
224 ]); | |
225 $string = reset($strings); | |
226 | |
227 if (!empty($translation)) { | |
228 // Skip this string unless it passes a check for dangerous code. | |
229 if (!locale_string_is_safe($translation)) { | |
230 \Drupal::logger('locale')->error('Import of string "%string" was skipped because of disallowed or malformed HTML.', ['%string' => $translation]); | |
231 $this->report['skips']++; | |
232 return 0; | |
233 } | |
234 elseif ($string) { | |
235 $string->setString($translation); | |
236 if ($string->isNew()) { | |
237 // No translation in this language. | |
238 $string->setValues([ | |
239 'language' => $this->langcode, | |
240 'customized' => $customized, | |
241 ]); | |
242 $string->save(); | |
243 $this->report['additions']++; | |
244 } | |
245 elseif ($overwrite_options[$string->customized ? 'customized' : 'not_customized']) { | |
246 // Translation exists, only overwrite if instructed. | |
247 $string->customized = $customized; | |
248 $string->save(); | |
249 $this->report['updates']++; | |
250 } | |
251 $this->report['strings'][] = $string->getId(); | |
252 return $string->lid; | |
253 } | |
254 else { | |
255 // No such source string in the database yet. | |
256 $string = \Drupal::service('locale.storage')->createString(['source' => $source, 'context' => $context]) | |
257 ->save(); | |
258 \Drupal::service('locale.storage')->createTranslation([ | |
259 'lid' => $string->getId(), | |
260 'language' => $this->langcode, | |
261 'translation' => $translation, | |
262 'customized' => $customized, | |
263 ])->save(); | |
264 | |
265 $this->report['additions']++; | |
266 $this->report['strings'][] = $string->getId(); | |
267 return $string->lid; | |
268 } | |
269 } | |
270 elseif ($string && !$string->isNew() && $overwrite_options[$string->customized ? 'customized' : 'not_customized']) { | |
271 // Empty translation, remove existing if instructed. | |
272 $string->delete(); | |
273 $this->report['deletes']++; | |
274 $this->report['strings'][] = $string->lid; | |
275 return $string->lid; | |
276 } | |
277 } | |
278 | |
279 } |