Commit | Line | Data |
---|---|---|
11ade432 AE |
1 | <?php |
2 | namespace wcf\data\language; | |
11ade432 AE |
3 | use wcf\data\language\category\LanguageCategory; |
4 | use wcf\data\language\category\LanguageCategoryEditor; | |
5 | use wcf\data\language\item\LanguageItemEditor; | |
6 | use wcf\data\language\item\LanguageItemList; | |
931f6597 | 7 | use wcf\data\DatabaseObjectEditor; |
42c2d229 | 8 | use wcf\data\IEditableCachedObject; |
b401cd0d | 9 | use wcf\system\cache\builder\LanguageCacheBuilder; |
11ade432 | 10 | use wcf\system\database\util\PreparedStatementConditionBuilder; |
6286572b | 11 | use wcf\system\exception\SystemException; |
3b6c3ca4 | 12 | use wcf\system\io\AtomicWriter; |
11ade432 | 13 | use wcf\system\language\LanguageFactory; |
ac9b0f6e | 14 | use wcf\system\Regex; |
11ade432 | 15 | use wcf\system\WCF; |
25e5c0cf | 16 | use wcf\util\DirectoryUtil; |
37a3683e | 17 | use wcf\util\FileUtil; |
6286572b AE |
18 | use wcf\util\StringUtil; |
19 | use wcf\util\XML; | |
11ade432 AE |
20 | |
21 | /** | |
22 | * Provides functions to edit languages. | |
a17de04e | 23 | * |
11ade432 | 24 | * @author Alexander Ebert |
4bef7e27 | 25 | * @copyright 2001-2016 WoltLab GmbH |
11ade432 AE |
26 | * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php> |
27 | * @package com.woltlab.wcf | |
28 | * @subpackage data.language | |
9f959ced | 29 | * @category Community Framework |
4bef7e27 MS |
30 | * |
31 | * @method Language getDecoratedObject() | |
32 | * @mixin Language | |
11ade432 | 33 | */ |
42c2d229 | 34 | class LanguageEditor extends DatabaseObjectEditor implements IEditableCachedObject { |
11ade432 | 35 | /** |
4bef7e27 | 36 | * @inheritDoc |
11ade432 | 37 | */ |
4bef7e27 | 38 | protected static $baseClass = Language::class; |
11ade432 AE |
39 | |
40 | /** | |
4bef7e27 | 41 | * @inheritDoc |
a17de04e | 42 | */ |
11ade432 AE |
43 | public function delete() { |
44 | parent::delete(); | |
45 | ||
46 | self::deleteLanguageFiles($this->languageID); | |
47 | } | |
48 | ||
49 | /** | |
50 | * Updates the language files for the given category. | |
a17de04e | 51 | * |
4bef7e27 | 52 | * @param LanguageCategory $languageCategory |
11ade432 | 53 | */ |
2d2cf979 | 54 | public function updateCategory(LanguageCategory $languageCategory) { |
4bef7e27 | 55 | $this->writeLanguageFiles([$languageCategory->languageCategoryID]); |
11ade432 AE |
56 | } |
57 | ||
58 | /** | |
59 | * Write the languages files. | |
a17de04e | 60 | * |
7a23a706 | 61 | * @param integer[] $languageCategoryIDs |
11ade432 | 62 | */ |
2d2cf979 | 63 | protected function writeLanguageFiles(array $languageCategoryIDs) { |
11ade432 | 64 | $conditions = new PreparedStatementConditionBuilder(); |
4bef7e27 MS |
65 | $conditions->add("languageID = ?", [$this->languageID]); |
66 | $conditions->add("languageCategoryID IN (?)", [$languageCategoryIDs]); | |
11ade432 | 67 | |
2d2cf979 | 68 | // get language items |
d726f13d | 69 | $sql = "SELECT languageItem, languageItemValue, languageCustomItemValue, |
2d2cf979 AE |
70 | languageUseCustomValue, languageCategoryID |
71 | FROM wcf".WCF_N."_language_item | |
11ade432 AE |
72 | ".$conditions; |
73 | $statement = WCF::getDB()->prepareStatement($sql); | |
74 | $statement->execute($conditions->getParameters()); | |
4bef7e27 | 75 | $items = []; |
2d2cf979 AE |
76 | while ($row = $statement->fetchArray()) { |
77 | $languageCategoryID = $row['languageCategoryID']; | |
78 | if (!isset($items[$languageCategoryID])) { | |
4bef7e27 | 79 | $items[$languageCategoryID] = []; |
2d2cf979 | 80 | } |
b8e1429f | 81 | |
2d2cf979 AE |
82 | $items[$languageCategoryID][$row['languageItem']] = ($row['languageUseCustomValue']) ? $row['languageCustomItemValue'] : $row['languageItemValue']; |
83 | } | |
84 | ||
85 | foreach ($items as $languageCategoryID => $languageItems) { | |
86 | $category = LanguageFactory::getInstance()->getCategoryByID($languageCategoryID); | |
87 | if ($category === null) { | |
88 | continue; | |
b8e1429f AE |
89 | } |
90 | ||
3b6c3ca4 TD |
91 | $filename = WCF_DIR.'language/'.$this->languageID.'_'.$category->languageCategory.'.php'; |
92 | $writer = new AtomicWriter($filename); | |
93 | ||
94 | $writer->write("<?php\n/**\n* WoltLab Community Framework\n* language: ".$this->languageCode."\n* encoding: UTF-8\n* category: ".$category->languageCategory."\n* generated at ".gmdate("r")."\n* \n* DO NOT EDIT THIS FILE\n*/\n"); | |
2d2cf979 | 95 | foreach ($languageItems as $languageItem => $languageItemValue) { |
3b6c3ca4 | 96 | $writer->write("\$this->items['".$languageItem."'] = '".str_replace("'", "\'", $languageItemValue)."';\n"); |
11ade432 | 97 | |
2d2cf979 AE |
98 | // compile dynamic language variables |
99 | if ($category->languageCategory != 'wcf.global' && strpos($languageItemValue, '{') !== false) { | |
3b6c3ca4 TD |
100 | $writer->write("\$this->dynamicItems['".$languageItem."'] = '"); |
101 | ||
2d2cf979 | 102 | $output = LanguageFactory::getInstance()->getScriptingCompiler()->compileString($languageItem, $languageItemValue); |
3b6c3ca4 TD |
103 | $writer->write(str_replace("'", "\'", $output['template'])); |
104 | ||
105 | $writer->write("';\n"); | |
11ade432 AE |
106 | } |
107 | } | |
2d2cf979 | 108 | |
3b6c3ca4 TD |
109 | $writer->flush(); |
110 | $writer->close(); | |
1232bce2 | 111 | FileUtil::makeWritable($filename); |
11ade432 AE |
112 | } |
113 | } | |
114 | ||
23af949d JML |
115 | /** |
116 | * Exports this language. | |
6f37a5f5 MS |
117 | * |
118 | * @param integer[] $packageIDArray | |
119 | * @param boolean $exportCustomValues | |
23af949d | 120 | */ |
4bef7e27 | 121 | public function export($packageIDArray = [], $exportCustomValues = false) { |
23af949d | 122 | $conditions = new PreparedStatementConditionBuilder(); |
4bef7e27 | 123 | $conditions->add("language_item.languageID = ?", [$this->languageID]); |
23af949d JML |
124 | |
125 | // bom | |
126 | echo "\xEF\xBB\xBF"; | |
127 | ||
128 | // header | |
da13ec66 | 129 | echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<language xmlns=\"http://www.woltlab.com\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.woltlab.com http://www.woltlab.com/XSD/maelstrom/language.xsd\" languagecode=\"".$this->languageCode."\" languagename=\"".$this->languageName."\" countrycode=\"".$this->countryCode."\">\n"; |
23af949d JML |
130 | |
131 | // get items | |
4bef7e27 | 132 | $items = []; |
15fa2802 | 133 | if (!empty($packageIDArray)) { |
4bef7e27 | 134 | $conditions->add("language_item.packageID IN (?)", [$packageIDArray]); |
23af949d | 135 | } |
cba29a87 | 136 | |
f1c1fc65 AE |
137 | $sql = "SELECT languageItem, " . ($exportCustomValues ? "CASE WHEN languageUseCustomValue > 0 THEN languageCustomItemValue ELSE languageItemValue END AS languageItemValue" : "languageItemValue") . ", languageCategory |
138 | FROM wcf".WCF_N."_language_item language_item | |
139 | LEFT JOIN wcf".WCF_N."_language_category language_category | |
140 | ON (language_category.languageCategoryID = language_item.languageCategoryID) | |
141 | ".$conditions; | |
23af949d JML |
142 | $statement = WCF::getDB()->prepareStatement($sql); |
143 | $statement->execute($conditions->getParameters()); | |
144 | while ($row = $statement->fetchArray()) { | |
145 | $items[$row['languageCategory']][$row['languageItem']] = $row['languageItemValue']; | |
146 | } | |
147 | ||
148 | // sort categories | |
149 | ksort($items); | |
150 | ||
151 | foreach ($items as $category => $categoryItems) { | |
152 | // sort items | |
153 | ksort($categoryItems); | |
154 | ||
155 | // category header | |
156 | echo "\t<category name=\"".$category."\">\n"; | |
157 | ||
158 | // items | |
159 | foreach ($categoryItems as $item => $value) { | |
160 | echo "\t\t<item name=\"".$item."\"><![CDATA[".StringUtil::escapeCDATA($value)."]]></item>\n"; | |
161 | } | |
162 | ||
163 | // category footer | |
164 | echo "\t</category>\n"; | |
165 | } | |
166 | ||
167 | // footer | |
168 | echo "</language>"; | |
169 | } | |
170 | ||
11ade432 AE |
171 | /** |
172 | * Imports language items from an XML file into this language. | |
173 | * Updates the relevant language files automatically. | |
a17de04e | 174 | * |
4bef7e27 | 175 | * @param XML $xml |
11ade432 AE |
176 | * @param integer $packageID |
177 | * @param boolean $updateFiles | |
6b4766db | 178 | * @param boolean $updateExistingItems |
11ade432 | 179 | */ |
6b4766db | 180 | public function updateFromXML(XML $xml, $packageID, $updateFiles = true, $updateExistingItems = true) { |
11ade432 | 181 | $xpath = $xml->xpath(); |
4bef7e27 | 182 | $usedCategories = []; |
11ade432 AE |
183 | |
184 | // fetch categories | |
185 | $categories = $xpath->query('/ns:language/ns:category'); | |
186 | foreach ($categories as $category) { | |
187 | $usedCategories[$category->getAttribute('name')] = 0; | |
188 | } | |
189 | ||
15fa2802 | 190 | if (empty($usedCategories)) return; |
11ade432 AE |
191 | |
192 | // select existing categories | |
193 | $conditions = new PreparedStatementConditionBuilder(); | |
4bef7e27 | 194 | $conditions->add("languageCategory IN (?)", [array_keys($usedCategories)]); |
11ade432 AE |
195 | |
196 | $sql = "SELECT languageCategoryID, languageCategory | |
197 | FROM wcf".WCF_N."_language_category | |
198 | ".$conditions; | |
199 | $statement = WCF::getDB()->prepareStatement($sql); | |
200 | $statement->execute($conditions->getParameters()); | |
201 | while ($row = $statement->fetchArray()) { | |
202 | $usedCategories[$row['languageCategory']] = $row['languageCategoryID']; | |
203 | } | |
204 | ||
205 | // create new categories | |
206 | foreach ($usedCategories as $categoryName => $categoryID) { | |
207 | if ($categoryID) continue; | |
208 | ||
4bef7e27 | 209 | $category = LanguageCategoryEditor::create([ |
11ade432 | 210 | 'languageCategory' => $categoryName |
4bef7e27 | 211 | ]); |
11ade432 AE |
212 | $usedCategories[$categoryName] = $category->languageCategoryID; |
213 | } | |
214 | ||
215 | // loop through categories to import items | |
4bef7e27 | 216 | $itemData = []; |
11ade432 AE |
217 | foreach ($categories as $category) { |
218 | $categoryName = $category->getAttribute('name'); | |
219 | $categoryID = $usedCategories[$categoryName]; | |
220 | ||
221 | // loop through items | |
222 | $elements = $xpath->query('child::*', $category); | |
223 | foreach ($elements as $element) { | |
224 | $itemName = $element->getAttribute('name'); | |
225 | $itemValue = $element->nodeValue; | |
226 | ||
3663a153 AE |
227 | $itemData[] = $this->languageID; |
228 | $itemData[] = $itemName; | |
229 | $itemData[] = $itemValue; | |
230 | $itemData[] = $categoryID; | |
6da165c5 | 231 | if ($packageID) $itemData[] = ($packageID == -1) ? PACKAGE_ID : $packageID; |
11ade432 AE |
232 | } |
233 | } | |
234 | ||
3663a153 AE |
235 | if (!empty($itemData)) { |
236 | // insert/update a maximum of 50 items per run (prevents issues with max_allowed_packet) | |
237 | $step = ($packageID) ? 5 : 4; | |
6b4766db | 238 | WCF::getDB()->beginTransaction(); |
3663a153 AE |
239 | for ($i = 0, $length = count($itemData); $i < $length; $i += 50 * $step) { |
240 | $parameters = array_slice($itemData, $i, 50 * $step); | |
241 | $repeat = count($parameters) / $step; | |
242 | ||
6b4766db | 243 | $sql = "INSERT".(!$updateExistingItems ? " IGNORE" : "")." INTO wcf".WCF_N."_language_item |
8aea75d5 | 244 | (languageID, languageItem, languageItemValue, languageCategoryID". ($packageID ? ", packageID" : "") . ") |
6b4766db AE |
245 | VALUES ".substr(str_repeat('(?, ?, ?, ?'. ($packageID ? ', ?' : '') .'), ', $repeat), 0, -2); |
246 | ||
247 | if ($updateExistingItems) { | |
6da165c5 | 248 | if ($packageID > 0) { |
5de7fea7 AE |
249 | // do not update anything if language item is owned by a different package |
250 | $sql .= " ON DUPLICATE KEY | |
251 | UPDATE languageUseCustomValue = IF(packageID = ".$packageID.", IF(languageItemValue = VALUES(languageItemValue), languageUseCustomValue, 0), languageUseCustomValue), | |
252 | languageItemValue = IF(packageID = ".$packageID.", IF(languageItemOriginIsSystem = 0, languageItemValue, VALUES(languageItemValue)), languageItemValue), | |
253 | languageCategoryID = IF(packageID = ".$packageID.", VALUES(languageCategoryID), languageCategoryID)"; | |
254 | } | |
255 | else { | |
6da165c5 | 256 | // skip package id check during WCFSetup (packageID = 0) or if using the ACP form (packageID = -1) |
5de7fea7 AE |
257 | $sql .= " ON DUPLICATE KEY |
258 | UPDATE languageUseCustomValue = IF(languageItemValue = VALUES(languageItemValue), languageUseCustomValue, 0), | |
259 | languageItemValue = IF(languageItemOriginIsSystem = 0, languageItemValue, VALUES(languageItemValue)), | |
260 | languageCategoryID = VALUES(languageCategoryID)"; | |
261 | } | |
6b4766db AE |
262 | } |
263 | ||
3663a153 AE |
264 | $statement = WCF::getDB()->prepareStatement($sql); |
265 | $statement->execute($parameters); | |
11ade432 | 266 | } |
6b4766db | 267 | WCF::getDB()->commitTransaction(); |
11ade432 AE |
268 | } |
269 | ||
270 | // update the relevant language files | |
271 | if ($updateFiles) { | |
272 | self::deleteLanguageFiles($this->languageID); | |
273 | } | |
274 | ||
275 | // delete relevant template compilations | |
276 | $this->deleteCompiledTemplates(); | |
277 | } | |
278 | ||
279 | /** | |
280 | * Deletes the language cache. | |
a17de04e | 281 | * |
39bea7dd MS |
282 | * @param string $languageID |
283 | * @param string $category | |
11ade432 | 284 | */ |
e730016d | 285 | public static function deleteLanguageFiles($languageID = '.*', $category = '.*') { |
25e5c0cf AE |
286 | if ($category != '.*') $category = preg_quote($category, '~'); |
287 | if ($languageID != '.*') $languageID = intval($languageID); | |
e3369fd2 | 288 | |
e730016d | 289 | DirectoryUtil::getInstance(WCF_DIR.'language/')->removePattern(new Regex($languageID.'_'.$category.'\.php$')); |
11ade432 AE |
290 | } |
291 | ||
292 | /** | |
293 | * Deletes relevant template compilations. | |
294 | */ | |
295 | public function deleteCompiledTemplates() { | |
296 | // templates | |
ac9b0f6e | 297 | DirectoryUtil::getInstance(WCF_DIR.'templates/compiled/')->removePattern(new Regex('.*_'.$this->languageID.'_.*\.php$')); |
11ade432 | 298 | // acp templates |
ac9b0f6e | 299 | DirectoryUtil::getInstance(WCF_DIR.'acp/templates/compiled/')->removePattern(new Regex('.*_'.$this->languageID.'_.*\.php$')); |
11ade432 AE |
300 | } |
301 | ||
302 | /** | |
303 | * Updates all language files of the given package id. | |
304 | */ | |
305 | public static function updateAll() { | |
306 | self::deleteLanguageFiles(); | |
307 | } | |
308 | ||
309 | /** | |
310 | * Takes an XML object and returns the specific language code. | |
a17de04e | 311 | * |
4bef7e27 | 312 | * @param XML $xml |
a17de04e | 313 | * @return string |
2b770bdd | 314 | * @throws SystemException |
11ade432 AE |
315 | */ |
316 | public static function readLanguageCodeFromXML(XML $xml) { | |
317 | $rootNode = $xml->xpath()->query('/ns:language')->item(0); | |
318 | $attributes = $xml->xpath()->query('attribute::*', $rootNode); | |
319 | foreach ($attributes as $attribute) { | |
320 | if ($attribute->name == 'languagecode') { | |
321 | return $attribute->value; | |
322 | } | |
323 | } | |
324 | ||
4fe0b42b | 325 | throw new SystemException("missing attribute 'languagecode' in language file"); |
11ade432 AE |
326 | } |
327 | ||
a74df36b MW |
328 | /** |
329 | * Takes an XML object and returns the specific language name. | |
a17de04e | 330 | * |
4bef7e27 | 331 | * @param XML $xml |
a74df36b | 332 | * @return string language name |
2b770bdd | 333 | * @throws SystemException |
a74df36b MW |
334 | */ |
335 | public static function readLanguageNameFromXML(XML $xml) { | |
336 | $rootNode = $xml->xpath()->query('/ns:language')->item(0); | |
337 | $attributes = $xml->xpath()->query('attribute::*', $rootNode); | |
338 | foreach ($attributes as $attribute) { | |
339 | if ($attribute->name == 'languagename') { | |
340 | return $attribute->value; | |
341 | } | |
342 | } | |
343 | ||
344 | throw new SystemException("missing attribute 'languagename' in language file"); | |
345 | } | |
346 | ||
6675b340 AE |
347 | /** |
348 | * Takes an XML object and returns the specific country code. | |
a17de04e | 349 | * |
4bef7e27 | 350 | * @param XML $xml |
6675b340 | 351 | * @return string country code |
2b770bdd | 352 | * @throws SystemException |
6675b340 AE |
353 | */ |
354 | public static function readCountryCodeFromXML(XML $xml) { | |
355 | $rootNode = $xml->xpath()->query('/ns:language')->item(0); | |
356 | $attributes = $xml->xpath()->query('attribute::*', $rootNode); | |
357 | foreach ($attributes as $attribute) { | |
358 | if ($attribute->name == 'countrycode') { | |
359 | return $attribute->value; | |
360 | } | |
361 | } | |
362 | ||
363 | throw new SystemException("missing attribute 'countrycode' in language file"); | |
364 | } | |
365 | ||
11ade432 AE |
366 | /** |
367 | * Imports language items from an XML file into a new or a current language. | |
368 | * Updates the relevant language files automatically. | |
a17de04e | 369 | * |
d00afef8 | 370 | * @param XML $xml |
11ade432 | 371 | * @param integer $packageID |
d00afef8 | 372 | * @param Language $source |
4bef7e27 | 373 | * @return LanguageEditor |
11ade432 | 374 | */ |
d00afef8 | 375 | public static function importFromXML(XML $xml, $packageID, Language $source = null) { |
11ade432 AE |
376 | $languageCode = self::readLanguageCodeFromXML($xml); |
377 | ||
378 | // try to find an existing language with the given language code | |
61022658 | 379 | $language = LanguageFactory::getInstance()->getLanguageByCode($languageCode); |
11ade432 AE |
380 | |
381 | // create new language | |
382 | if ($language === null) { | |
6675b340 | 383 | $countryCode = self::readCountryCodeFromXML($xml); |
a74df36b | 384 | $languageName = self::readLanguageNameFromXML($xml); |
4bef7e27 | 385 | $language = self::create([ |
6675b340 | 386 | 'countryCode' => $countryCode, |
a74df36b MW |
387 | 'languageCode' => $languageCode, |
388 | 'languageName' => $languageName | |
4bef7e27 | 389 | ]); |
d00afef8 MW |
390 | |
391 | if ($source) { | |
392 | $sourceEditor = new LanguageEditor($source); | |
393 | $sourceEditor->copy($language); | |
394 | } | |
11ade432 AE |
395 | } |
396 | ||
397 | // import xml | |
398 | $languageEditor = new LanguageEditor($language); | |
399 | $languageEditor->updateFromXML($xml, $packageID); | |
400 | ||
401 | // return language object | |
402 | return $languageEditor; | |
403 | } | |
404 | ||
405 | /** | |
406 | * Copies all language variables from current language to language specified as $destination. | |
407 | * Caution: This method expects that target language does not have any items! | |
408 | * | |
73df94ae | 409 | * @param Language $destination |
a17de04e | 410 | */ |
11ade432 AE |
411 | public function copy(Language $destination) { |
412 | $sql = "INSERT INTO wcf".WCF_N."_language_item | |
413 | (languageID, languageItem, languageItemValue, languageItemOriginIsSystem, languageCategoryID, packageID) | |
414 | SELECT ?, languageItem, languageItemValue, languageItemOriginIsSystem, languageCategoryID, packageID | |
415 | FROM wcf".WCF_N."_language_item | |
416 | WHERE languageID = ?"; | |
417 | $statement = WCF::getDB()->prepareStatement($sql); | |
4bef7e27 | 418 | $statement->execute([ |
11ade432 AE |
419 | $destination->languageID, |
420 | $this->languageID | |
4bef7e27 | 421 | ]); |
11ade432 AE |
422 | } |
423 | ||
424 | /** | |
425 | * Updates the language items of a language category. | |
426 | * | |
4bef7e27 MS |
427 | * @param array $items |
428 | * @param LanguageCategory $category | |
429 | * @param integer $packageID | |
430 | * @param array $useCustom | |
11ade432 | 431 | */ |
4bef7e27 | 432 | public function updateItems(array $items, LanguageCategory $category, $packageID = PACKAGE_ID, array $useCustom = []) { |
15fa2802 | 433 | if (empty($items)) return; |
11ade432 AE |
434 | |
435 | // find existing language items | |
436 | $languageItemList = new LanguageItemList(); | |
4bef7e27 MS |
437 | $languageItemList->getConditionBuilder()->add("language_item.languageItem IN (?)", [array_keys($items)]); |
438 | $languageItemList->getConditionBuilder()->add("languageID = ?", [$this->languageID]); | |
11ade432 AE |
439 | $languageItemList->readObjects(); |
440 | ||
58e1d71f | 441 | foreach ($languageItemList->getObjects() as $languageItem) { |
11ade432 | 442 | $languageItemEditor = new LanguageItemEditor($languageItem); |
4bef7e27 | 443 | $languageItemEditor->update([ |
11ade432 AE |
444 | 'languageCustomItemValue' => $items[$languageItem->languageItem], |
445 | 'languageUseCustomValue' => (isset($useCustom[$languageItem->languageItem])) ? 1 : 0 | |
4bef7e27 | 446 | ]); |
11ade432 AE |
447 | |
448 | // remove updated items, leaving items to be created within | |
449 | unset($items[$languageItem->languageItem]); | |
450 | } | |
451 | ||
452 | // create remaining items | |
15fa2802 | 453 | if (!empty($items)) { |
11ade432 AE |
454 | // bypass LanguageItemEditor::create() for performance reasons |
455 | $sql = "INSERT INTO wcf".WCF_N."_language_item | |
456 | (languageID, languageItem, languageItemValue, languageItemOriginIsSystem, languageCategoryID, packageID) | |
457 | VALUES (?, ?, ?, ?, ?, ?)"; | |
458 | $statement = WCF::getDB()->prepareStatement($sql); | |
459 | ||
460 | foreach ($items as $itemName => $itemValue) { | |
4bef7e27 | 461 | $statement->execute([ |
11ade432 AE |
462 | $this->languageID, |
463 | $itemName, | |
464 | $itemValue, | |
465 | 0, | |
466 | $category->languageCategoryID, | |
467 | $packageID | |
4bef7e27 | 468 | ]); |
11ade432 AE |
469 | } |
470 | } | |
471 | ||
472 | // update the relevant language files | |
4879676b | 473 | self::deleteLanguageFiles($this->languageID, $category->languageCategory); |
11ade432 AE |
474 | |
475 | // delete relevant template compilations | |
476 | $this->deleteCompiledTemplates(); | |
477 | } | |
478 | ||
479 | /** | |
480 | * Sets current language as default language. | |
481 | */ | |
482 | public function setAsDefault() { | |
483 | // remove default flag from all languages | |
484 | $sql = "UPDATE wcf".WCF_N."_language | |
485 | SET isDefault = ?"; | |
486 | $statement = WCF::getDB()->prepareStatement($sql); | |
4bef7e27 | 487 | $statement->execute([0]); |
11ade432 AE |
488 | |
489 | // set current language as default language | |
4bef7e27 | 490 | $this->update(['isDefault' => 1]); |
11ade432 AE |
491 | |
492 | $this->clearCache(); | |
493 | } | |
494 | ||
495 | /** | |
496 | * Clears language cache. | |
a17de04e | 497 | */ |
11ade432 | 498 | public function clearCache() { |
b401cd0d | 499 | LanguageCacheBuilder::getInstance()->reset(); |
11ade432 AE |
500 | } |
501 | ||
11ade432 AE |
502 | /** |
503 | * Enables the multilingualism feature for given languages. | |
504 | * | |
505 | * @param array $languageIDs | |
506 | */ | |
4bef7e27 | 507 | public static function enableMultilingualism(array $languageIDs = []) { |
11ade432 AE |
508 | $sql = "UPDATE wcf".WCF_N."_language |
509 | SET hasContent = ?"; | |
510 | $statement = WCF::getDB()->prepareStatement($sql); | |
4bef7e27 | 511 | $statement->execute([0]); |
11ade432 | 512 | |
15fa2802 | 513 | if (!empty($languageIDs)) { |
11ade432 | 514 | $sql = ''; |
4bef7e27 | 515 | $statementParameters = []; |
11ade432 AE |
516 | foreach ($languageIDs as $languageID) { |
517 | if (!empty($sql)) $sql .= ','; | |
518 | $sql .= '?'; | |
519 | $statementParameters[] = $languageID; | |
520 | } | |
521 | ||
522 | $sql = "UPDATE wcf".WCF_N."_language | |
523 | SET hasContent = ? | |
524 | WHERE languageID IN (".$sql.")"; | |
525 | $statement = WCF::getDB()->prepareStatement($sql); | |
526 | array_unshift($statementParameters, 1); | |
527 | $statement->execute($statementParameters); | |
528 | } | |
529 | } | |
42c2d229 MS |
530 | |
531 | /** | |
4bef7e27 | 532 | * @inheritDoc |
42c2d229 MS |
533 | */ |
534 | public static function resetCache() { | |
535 | LanguageFactory::getInstance()->clearCache(); | |
536 | } | |
11ade432 | 537 | } |