1 | <?php |
||||||
2 | |||||||
3 | namespace Backend\Modules\Locale\Engine; |
||||||
4 | |||||||
5 | use Common\Uri as CommonUri; |
||||||
6 | use Backend\Core\Engine\Authentication as BackendAuthentication; |
||||||
7 | use Backend\Core\Language\Language as BL; |
||||||
8 | use Backend\Core\Engine\Model as BackendModel; |
||||||
9 | use SpoonFilter; |
||||||
10 | |||||||
11 | /** |
||||||
12 | * In this file we store all generic functions that we will be using in the locale module |
||||||
13 | */ |
||||||
14 | class Model |
||||||
15 | { |
||||||
16 | /** |
||||||
17 | * @var array The possible locale types |
||||||
18 | */ |
||||||
19 | public const TYPES = [ |
||||||
20 | 'act', |
||||||
21 | 'err', |
||||||
22 | 'lbl', |
||||||
23 | 'msg', |
||||||
24 | ]; |
||||||
25 | |||||||
26 | 3 | public static function buildCache(string $language, string $application): void |
|||||
27 | { |
||||||
28 | 3 | $cacheBuilder = new CacheBuilder(BackendModel::get('database')); |
|||||
29 | 3 | $cacheBuilder->buildCache($language, $application); |
|||||
30 | 3 | } |
|||||
31 | |||||||
32 | public static function buildUrlQueryByFilter(array $filter): string |
||||||
33 | { |
||||||
34 | $query = http_build_query($filter, null, '&', PHP_QUERY_RFC3986); |
||||||
35 | if ($query != '') { |
||||||
36 | $query = '&' . $query; |
||||||
37 | } |
||||||
38 | |||||||
39 | return $query; |
||||||
40 | } |
||||||
41 | |||||||
42 | public static function createXMLForExport(array $items): string |
||||||
43 | { |
||||||
44 | $charset = BackendModel::getContainer()->getParameter('kernel.charset'); |
||||||
45 | $xml = new \DOMDocument('1.0', $charset); |
||||||
46 | |||||||
47 | // set some properties |
||||||
48 | $xml->preserveWhiteSpace = false; |
||||||
49 | $xml->formatOutput = true; |
||||||
50 | |||||||
51 | // locale root element |
||||||
52 | $root = $xml->createElement('locale'); |
||||||
53 | $xml->appendChild($root); |
||||||
54 | |||||||
55 | // loop applications |
||||||
56 | foreach ($items as $application => $modules) { |
||||||
57 | // create application element |
||||||
58 | $applicationElement = $xml->createElement($application); |
||||||
59 | $root->appendChild($applicationElement); |
||||||
60 | |||||||
61 | // loop modules |
||||||
62 | foreach ($modules as $module => $types) { |
||||||
63 | // create application element |
||||||
64 | $moduleElement = $xml->createElement($module); |
||||||
65 | $applicationElement->appendChild($moduleElement); |
||||||
66 | |||||||
67 | // loop types |
||||||
68 | foreach ($types as $type => $items) { |
||||||
69 | // loop items |
||||||
70 | foreach ($items as $name => $translations) { |
||||||
71 | // create application element |
||||||
72 | $itemElement = $xml->createElement('item'); |
||||||
73 | $moduleElement->appendChild($itemElement); |
||||||
74 | |||||||
75 | // attributes |
||||||
76 | $itemElement->setAttribute('type', self::getTypeName($type)); |
||||||
77 | $itemElement->setAttribute('name', $name); |
||||||
78 | |||||||
79 | // loop translations |
||||||
80 | foreach ($translations as $translation) { |
||||||
81 | // create translation |
||||||
82 | $translationElement = $xml->createElement('translation'); |
||||||
83 | $itemElement->appendChild($translationElement); |
||||||
84 | |||||||
85 | // attributes |
||||||
86 | $translationElement->setAttribute('language', $translation['language']); |
||||||
87 | |||||||
88 | // set content |
||||||
89 | $translationElement->appendChild(new \DOMCdataSection($translation['value'])); |
||||||
90 | } |
||||||
91 | } |
||||||
92 | } |
||||||
93 | } |
||||||
94 | } |
||||||
95 | |||||||
96 | return $xml->saveXML(); |
||||||
97 | } |
||||||
98 | |||||||
99 | /** |
||||||
100 | * Delete (multiple) items from locale |
||||||
101 | * |
||||||
102 | * @param int[] $ids The id(s) to delete. |
||||||
103 | */ |
||||||
104 | public static function delete(array $ids): void |
||||||
105 | { |
||||||
106 | // loop and cast to integers |
||||||
107 | foreach ($ids as &$id) { |
||||||
108 | $id = (int) $id; |
||||||
109 | } |
||||||
110 | |||||||
111 | // create an array with an equal amount of questionmarks as ids provided |
||||||
112 | $idPlaceHolders = array_fill(0, count($ids), '?'); |
||||||
113 | |||||||
114 | // delete records |
||||||
115 | BackendModel::getContainer()->get('database')->delete( |
||||||
116 | 'locale', |
||||||
117 | 'id IN (' . implode(', ', $idPlaceHolders) . ')', |
||||||
118 | $ids |
||||||
119 | ); |
||||||
120 | |||||||
121 | // rebuild cache |
||||||
122 | self::buildCache(BL::getWorkingLanguage(), 'Backend'); |
||||||
123 | self::buildCache(BL::getWorkingLanguage(), 'Frontend'); |
||||||
124 | } |
||||||
125 | |||||||
126 | public static function exists(int $id): bool |
||||||
127 | { |
||||||
128 | return (bool) BackendModel::getContainer()->get('database')->getVar( |
||||||
129 | 'SELECT 1 |
||||||
130 | FROM locale |
||||||
131 | WHERE id = ? |
||||||
132 | LIMIT 1', |
||||||
133 | [$id] |
||||||
134 | ); |
||||||
135 | } |
||||||
136 | |||||||
137 | public static function existsByName( |
||||||
138 | string $name, |
||||||
139 | string $type, |
||||||
140 | string $module, |
||||||
141 | string $language, |
||||||
142 | string $application, |
||||||
143 | int $excludedId = null |
||||||
144 | ): bool { |
||||||
145 | // get database |
||||||
146 | $database = BackendModel::getContainer()->get('database'); |
||||||
147 | |||||||
148 | // return |
||||||
149 | if ($excludedId !== null) { |
||||||
150 | return (bool) $database->getVar( |
||||||
151 | 'SELECT 1 |
||||||
152 | FROM locale |
||||||
153 | WHERE name = ? AND type = ? AND module = ? AND language = ? AND application = ? AND id != ? |
||||||
154 | LIMIT 1', |
||||||
155 | [$name, $type, $module, $language, $application, $excludedId] |
||||||
156 | ); |
||||||
157 | } |
||||||
158 | |||||||
159 | return (bool) BackendModel::getContainer()->get('database')->getVar( |
||||||
160 | 'SELECT 1 |
||||||
161 | FROM locale |
||||||
162 | WHERE name = ? AND type = ? AND module = ? AND language = ? AND application = ? |
||||||
163 | LIMIT 1', |
||||||
164 | [$name, $type, $module, $language, $application] |
||||||
165 | ); |
||||||
166 | } |
||||||
167 | |||||||
168 | public static function get(int $id): array |
||||||
169 | { |
||||||
170 | // fetch record from database |
||||||
171 | $record = (array) BackendModel::getContainer()->get('database')->getRecord( |
||||||
172 | 'SELECT * FROM locale WHERE id = ?', |
||||||
173 | [$id] |
||||||
174 | ); |
||||||
175 | |||||||
176 | // actions are urlencoded |
||||||
177 | if ($record['type'] === 'act') { |
||||||
178 | $record['value'] = urldecode($record['value']); |
||||||
179 | } |
||||||
180 | |||||||
181 | return $record; |
||||||
182 | } |
||||||
183 | |||||||
184 | public static function getByName( |
||||||
185 | string $name, |
||||||
186 | string $type, |
||||||
187 | string $module, |
||||||
188 | string $language, |
||||||
189 | string $application |
||||||
190 | ): int { |
||||||
191 | return BackendModel::getContainer()->get('database')->getVar( |
||||||
192 | 'SELECT l.id |
||||||
193 | FROM locale AS l |
||||||
194 | WHERE name = ? AND type = ? AND module = ? AND language = ? AND application = ?', |
||||||
195 | [$name, $type, $module, $language, $application] |
||||||
196 | ); |
||||||
197 | } |
||||||
198 | |||||||
199 | public static function getLanguagesForMultiCheckbox(bool $includeInterfaceLanguages = false): array |
||||||
200 | { |
||||||
201 | // get working languages |
||||||
202 | $aLanguages = BL::getWorkingLanguages(); |
||||||
203 | |||||||
204 | // add the interface languages if needed |
||||||
205 | if ($includeInterfaceLanguages) { |
||||||
206 | $aLanguages = array_merge($aLanguages, BL::getInterfaceLanguages()); |
||||||
207 | } |
||||||
208 | |||||||
209 | // create a new array to redefine the languages for the multicheckbox |
||||||
210 | $languages = []; |
||||||
211 | |||||||
212 | // loop the languages |
||||||
213 | foreach ($aLanguages as $key => $lang) { |
||||||
214 | // add to array |
||||||
215 | $languages[$key]['value'] = $key; |
||||||
216 | $languages[$key]['label'] = $lang; |
||||||
217 | } |
||||||
218 | |||||||
219 | return $languages; |
||||||
220 | } |
||||||
221 | |||||||
222 | public static function getTranslations( |
||||||
223 | $application, |
||||||
224 | string $module, |
||||||
225 | array $types, |
||||||
226 | array $languages, |
||||||
227 | string $name, |
||||||
228 | string $value |
||||||
229 | ): array { |
||||||
230 | // create an array for the languages, surrounded by quotes (example: 'en') |
||||||
231 | $aLanguages = []; |
||||||
232 | foreach ($languages as $key => $val) { |
||||||
233 | $aLanguages[$key] = '\'' . $val . '\''; |
||||||
234 | } |
||||||
235 | |||||||
236 | // surround the types with quotes |
||||||
237 | foreach ($types as $key => $val) { |
||||||
238 | $types[$key] = '\'' . $val . '\''; |
||||||
239 | } |
||||||
240 | |||||||
241 | // get database |
||||||
242 | $database = BackendModel::getContainer()->get('database'); |
||||||
243 | |||||||
244 | // build the query |
||||||
245 | $query = |
||||||
246 | 'SELECT l.id, l.application, l.module, l.type, l.name, l.value, l.language, UNIX_TIMESTAMP(l.edited_on) as edited_on |
||||||
247 | FROM locale AS l |
||||||
248 | WHERE |
||||||
249 | l.language IN (' . implode(',', $aLanguages) . ') AND |
||||||
250 | l.name LIKE ? AND |
||||||
251 | l.value LIKE ? AND |
||||||
252 | l.type IN (' . implode(',', $types) . ')'; |
||||||
253 | |||||||
254 | // add the parameters |
||||||
255 | $parameters = ['%' . $name . '%', '%' . $value . '%']; |
||||||
256 | |||||||
257 | // add module to the query if needed |
||||||
258 | if ($module) { |
||||||
259 | $query .= ' AND l.module = ?'; |
||||||
260 | $parameters[] = $module; |
||||||
261 | } |
||||||
262 | |||||||
263 | // add module to the query if needed |
||||||
264 | if ($application) { |
||||||
265 | $query .= ' AND l.application = ?'; |
||||||
266 | $parameters[] = $application; |
||||||
267 | } |
||||||
268 | |||||||
269 | // get the translations |
||||||
270 | $translations = (array) $database->getRecords($query, $parameters); |
||||||
271 | |||||||
272 | // create an array for the sorted translations |
||||||
273 | $sortedTranslations = []; |
||||||
274 | |||||||
275 | // loop translations |
||||||
276 | foreach ($translations as $translation) { |
||||||
277 | // add to the sorted array |
||||||
278 | $sortedTranslations[$translation['type']][$translation['name']][$translation['module']][$translation['language']] = [ |
||||||
279 | 'id' => $translation['id'], |
||||||
280 | 'value' => $translation['value'], |
||||||
281 | 'edited_on' => $translation['edited_on'], |
||||||
282 | 'application' => $translation['application'], |
||||||
283 | ]; |
||||||
284 | } |
||||||
285 | |||||||
286 | // create an array to use in the datagrid |
||||||
287 | $dataGridTranslations = []; |
||||||
288 | |||||||
289 | // an id that is used for in the datagrid, this is not the id of the translation! |
||||||
290 | $id = 0; |
||||||
291 | |||||||
292 | // save the number of languages so this has not to be executed x number of times |
||||||
293 | $numberOfLanguages = count($languages); |
||||||
294 | |||||||
295 | // loop the sorted translations |
||||||
296 | foreach ($sortedTranslations as $type => $references) { |
||||||
297 | // create array for each type |
||||||
298 | $dataGridTranslations[$type] = []; |
||||||
299 | |||||||
300 | foreach ($references as $reference => $translation) { |
||||||
301 | // loop modules |
||||||
302 | foreach ($translation as $module => $t) { |
||||||
303 | // create translation (and increase id) |
||||||
304 | // we init the application here so it appears in front of the datagrid |
||||||
305 | $trans = [ |
||||||
306 | 'application' => '', |
||||||
307 | 'module' => $module, |
||||||
308 | 'name' => $reference, |
||||||
309 | 'id' => $id++, |
||||||
310 | ]; |
||||||
311 | |||||||
312 | // reset this var for every language |
||||||
313 | $edited_on = ''; |
||||||
314 | |||||||
315 | foreach ($languages as $lang) { |
||||||
316 | // if the translation exists the for this language, fill it up |
||||||
317 | // else leave a space for the empty field |
||||||
318 | if (isset($t[$lang])) { |
||||||
319 | $trans[$lang] = $t[$lang]['value']; |
||||||
320 | $trans['application'] = $t[$lang]['application']; |
||||||
321 | |||||||
322 | // only alter edited_on if the date of a previously added date of another |
||||||
323 | // language is smaller |
||||||
324 | if ($edited_on < $t[$lang]['edited_on']) { |
||||||
325 | $edited_on = $t[$lang]['edited_on']; |
||||||
326 | } |
||||||
327 | |||||||
328 | if ($numberOfLanguages == 1) { |
||||||
329 | $trans['translation_id'] = $t[$lang]['id']; |
||||||
330 | } else { |
||||||
331 | $trans['translation_id_' . $lang] = $t[$lang]['id']; |
||||||
332 | } |
||||||
333 | } else { |
||||||
334 | $trans[$lang] = ''; |
||||||
335 | |||||||
336 | if ($numberOfLanguages == 1) { |
||||||
337 | $trans['translation_id'] = ''; |
||||||
338 | } else { |
||||||
339 | $trans['translation_id_' . $lang] = ''; |
||||||
340 | } |
||||||
341 | } |
||||||
342 | } |
||||||
343 | // at the end of the array, add the generated edited_on date |
||||||
344 | $trans['edited_on'] = $edited_on; |
||||||
345 | |||||||
346 | // add the translation to the array |
||||||
347 | $dataGridTranslations[$type][] = $trans; |
||||||
348 | } |
||||||
349 | } |
||||||
350 | } |
||||||
351 | |||||||
352 | return $dataGridTranslations; |
||||||
353 | } |
||||||
354 | |||||||
355 | 1 | public static function getTypeName(string $type): string |
|||||
356 | { |
||||||
357 | // get full type name |
||||||
358 | switch ($type) { |
||||||
359 | 1 | case 'act': |
|||||
360 | 1 | $type = 'action'; |
|||||
361 | 1 | break; |
|||||
362 | 1 | case 'err': |
|||||
363 | 1 | $type = 'error'; |
|||||
364 | 1 | break; |
|||||
365 | 1 | case 'lbl': |
|||||
366 | 1 | $type = 'label'; |
|||||
367 | 1 | break; |
|||||
368 | 1 | case 'msg': |
|||||
369 | 1 | $type = 'message'; |
|||||
370 | 1 | break; |
|||||
371 | } |
||||||
372 | |||||||
373 | 1 | return $type; |
|||||
374 | } |
||||||
375 | |||||||
376 | public static function getTypesForDropDown(): array |
||||||
377 | { |
||||||
378 | $labels = static::TYPES; |
||||||
379 | |||||||
380 | // loop and build labels |
||||||
381 | foreach ($labels as &$row) { |
||||||
382 | $row = SpoonFilter::ucfirst(BL::msg(mb_strtoupper($row), 'Core')); |
||||||
383 | } |
||||||
384 | |||||||
385 | // build array |
||||||
386 | return array_combine(static::TYPES, $labels); |
||||||
387 | } |
||||||
388 | |||||||
389 | public static function getTypesForMultiCheckbox(): array |
||||||
390 | { |
||||||
391 | $labels = static::TYPES; |
||||||
392 | |||||||
393 | // loop and build labels |
||||||
394 | foreach ($labels as &$row) { |
||||||
395 | $row = SpoonFilter::ucfirst(BL::msg(mb_strtoupper($row), 'Core')); |
||||||
396 | } |
||||||
397 | |||||||
398 | // build array |
||||||
399 | $aTypes = array_combine(static::TYPES, $labels); |
||||||
400 | |||||||
401 | // create a new array to redefine the types for the multicheckbox |
||||||
402 | $types = []; |
||||||
403 | |||||||
404 | // loop the languages |
||||||
405 | foreach ($aTypes as $key => $type) { |
||||||
406 | // add to array |
||||||
407 | $types[$key]['value'] = $key; |
||||||
408 | $types[$key]['label'] = $type; |
||||||
409 | } |
||||||
410 | |||||||
411 | // return the redefined array |
||||||
412 | return $types; |
||||||
413 | } |
||||||
414 | |||||||
415 | 1 | public static function importXML( |
|||||
416 | \SimpleXMLElement $xml, |
||||||
417 | bool $overwriteConflicts = false, |
||||||
418 | array $frontendLanguages = null, |
||||||
419 | array $backendLanguages = null, |
||||||
420 | int $userId = null, |
||||||
421 | string $date = null |
||||||
422 | ): array { |
||||||
423 | $statistics = [ |
||||||
424 | 1 | 'total' => 0, |
|||||
425 | 'imported' => 0, |
||||||
426 | ]; |
||||||
427 | |||||||
428 | // set defaults if necessary |
||||||
429 | // we can't simply use these right away, because this function is also calls by the installer, |
||||||
430 | // which does not have Backend-functions |
||||||
431 | 1 | if ($frontendLanguages === null) { |
|||||
432 | $frontendLanguages = array_keys(BL::getWorkingLanguages()); |
||||||
433 | } |
||||||
434 | 1 | if ($backendLanguages === null) { |
|||||
435 | $backendLanguages = array_keys(BL::getInterfaceLanguages()); |
||||||
436 | } |
||||||
437 | 1 | if ($userId === null) { |
|||||
438 | $userId = BackendAuthentication::getUser()->getUserId(); |
||||||
439 | } |
||||||
440 | 1 | if ($date === null) { |
|||||
441 | $date = BackendModel::getUTCDate(); |
||||||
442 | } |
||||||
443 | |||||||
444 | // get database instance |
||||||
445 | 1 | $database = BackendModel::getContainer()->get('database'); |
|||||
446 | |||||||
447 | // possible values |
||||||
448 | 1 | $possibleApplications = ['Frontend', 'Backend']; |
|||||
449 | 1 | $possibleModules = (array) $database->getColumn('SELECT m.name FROM modules AS m'); |
|||||
450 | |||||||
451 | // types |
||||||
452 | 1 | $possibleTypes = []; |
|||||
453 | 1 | foreach (static::TYPES as $type) { |
|||||
454 | 1 | $possibleTypes[$type] = self::getTypeName($type); |
|||||
455 | } |
||||||
456 | |||||||
457 | // install English translations anyhow, they're fallback |
||||||
458 | $possibleLanguages = [ |
||||||
459 | 1 | 'Frontend' => array_unique(array_merge(['en'], $frontendLanguages)), |
|||||
460 | 1 | 'Backend' => array_unique(array_merge(['en'], $backendLanguages)), |
|||||
461 | ]; |
||||||
462 | |||||||
463 | // current locale items (used to check for conflicts) |
||||||
464 | 1 | $currentLocale = (array) $database->getColumn( |
|||||
465 | 1 | 'SELECT CONCAT(application, module, type, language, name) |
|||||
466 | FROM locale' |
||||||
467 | ); |
||||||
468 | |||||||
469 | // applications |
||||||
470 | 1 | foreach ($xml as $application => $modules) { |
|||||
471 | // application does not exist |
||||||
472 | 1 | if (!in_array($application, $possibleApplications, true)) { |
|||||
473 | continue; |
||||||
474 | } |
||||||
475 | |||||||
476 | // modules |
||||||
477 | 1 | foreach ($modules as $module => $items) { |
|||||
478 | // module does not exist |
||||||
479 | 1 | if (!in_array($module, $possibleModules, true)) { |
|||||
480 | continue; |
||||||
481 | } |
||||||
482 | |||||||
483 | // items |
||||||
484 | 1 | foreach ($items as $item) { |
|||||
485 | // attributes |
||||||
486 | 1 | $attributes = $item->attributes(); |
|||||
0 ignored issues
–
show
|
|||||||
487 | 1 | $type = SpoonFilter::getValue($attributes['type'], $possibleTypes, ''); |
|||||
488 | 1 | $name = SpoonFilter::ucfirst(SpoonFilter::getValue($attributes['name'], null, '')); |
|||||
489 | |||||||
490 | // missing attributes |
||||||
491 | 1 | if ($type == '' || $name == '') { |
|||||
492 | continue; |
||||||
493 | } |
||||||
494 | |||||||
495 | // real type (shortened) |
||||||
496 | 1 | $type = array_search($type, $possibleTypes); |
|||||
497 | |||||||
498 | // translations |
||||||
499 | 1 | foreach ($item->translation as $translation) { |
|||||
500 | // statistics |
||||||
501 | 1 | ++$statistics['total']; |
|||||
502 | |||||||
503 | // attributes |
||||||
504 | 1 | $attributes = $translation->attributes(); |
|||||
0 ignored issues
–
show
The method
attributes() does not exist on null .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces. This is most likely a typographical error or the method has been renamed.
Loading history...
|
|||||||
505 | 1 | $language = SpoonFilter::getValue( |
|||||
506 | 1 | $attributes['language'], |
|||||
507 | 1 | $possibleLanguages[$application], |
|||||
508 | 1 | '' |
|||||
509 | ); |
||||||
510 | |||||||
511 | // language does not exist |
||||||
512 | 1 | if ($language == '') { |
|||||
513 | 1 | continue; |
|||||
514 | } |
||||||
515 | |||||||
516 | // the actual translation |
||||||
517 | 1 | $translation = (string) $translation; |
|||||
518 | |||||||
519 | // locale item |
||||||
520 | 1 | $locale = []; |
|||||
521 | 1 | $locale['user_id'] = $userId; |
|||||
522 | 1 | $locale['language'] = $language; |
|||||
523 | 1 | $locale['application'] = $application; |
|||||
524 | 1 | $locale['module'] = $module; |
|||||
525 | 1 | $locale['type'] = $type; |
|||||
526 | 1 | $locale['name'] = $name; |
|||||
527 | 1 | $locale['value'] = $translation; |
|||||
528 | 1 | $locale['edited_on'] = $date; |
|||||
529 | |||||||
530 | // check if translation does not yet exist, or if the translation can be overridden |
||||||
531 | 1 | if (!in_array($application . $module . $type . $language . $name, $currentLocale) |
|||||
532 | 1 | || $overwriteConflicts |
|||||
533 | ) { |
||||||
534 | 1 | $database->execute( |
|||||
535 | 1 | 'INSERT INTO locale (user_id, language, application, module, type, name, value, edited_on) |
|||||
536 | VALUES (?, ?, ?, ?, ?, ?, ?, ?) |
||||||
537 | ON DUPLICATE KEY UPDATE user_id = ?, value = ?, edited_on = ?', |
||||||
538 | [ |
||||||
539 | 1 | $locale['user_id'], |
|||||
540 | 1 | $locale['language'], |
|||||
541 | 1 | $locale['application'], |
|||||
542 | 1 | $locale['module'], |
|||||
543 | 1 | $locale['type'], |
|||||
544 | 1 | $locale['name'], |
|||||
545 | 1 | $locale['value'], |
|||||
546 | 1 | $locale['edited_on'], |
|||||
547 | 1 | $locale['user_id'], |
|||||
548 | 1 | $locale['value'], |
|||||
549 | 1 | $locale['edited_on'], |
|||||
550 | ] |
||||||
551 | ); |
||||||
552 | |||||||
553 | // statistics |
||||||
554 | 1 | ++$statistics['imported']; |
|||||
555 | } |
||||||
556 | } |
||||||
557 | } |
||||||
558 | } |
||||||
559 | } |
||||||
560 | |||||||
561 | // rebuild cache |
||||||
562 | 1 | foreach ($possibleApplications as $application) { |
|||||
563 | 1 | foreach ($possibleLanguages[$application] as $language) { |
|||||
564 | 1 | self::buildCache($language, $application); |
|||||
565 | } |
||||||
566 | } |
||||||
567 | |||||||
568 | 1 | return $statistics; |
|||||
569 | } |
||||||
570 | |||||||
571 | public static function insert(array $item): int |
||||||
572 | { |
||||||
573 | // actions should be urlized |
||||||
574 | if ($item['type'] == 'act' && urldecode($item['value']) != $item['value']) { |
||||||
575 | $item['value'] = CommonUri::getUrl( |
||||||
576 | $item['value'] |
||||||
577 | ); |
||||||
578 | } |
||||||
579 | |||||||
580 | // insert item |
||||||
581 | $item['id'] = (int) BackendModel::getContainer()->get('database')->insert('locale', $item); |
||||||
582 | |||||||
583 | // rebuild the cache |
||||||
584 | self::buildCache($item['language'], $item['application']); |
||||||
585 | |||||||
586 | // return the new id |
||||||
587 | return $item['id']; |
||||||
588 | } |
||||||
589 | |||||||
590 | public static function update(array $item): int |
||||||
591 | { |
||||||
592 | // actions should be urlized |
||||||
593 | if ($item['type'] == 'act' && urldecode($item['value']) != $item['value']) { |
||||||
594 | $item['value'] = CommonUri::getUrl( |
||||||
595 | $item['value'] |
||||||
596 | ); |
||||||
597 | } |
||||||
598 | |||||||
599 | // update category |
||||||
600 | $updated = BackendModel::getContainer()->get('database')->update('locale', $item, 'id = ?', [$item['id']]); |
||||||
601 | |||||||
602 | // rebuild the cache |
||||||
603 | self::buildCache($item['language'], $item['application']); |
||||||
604 | |||||||
605 | return $updated; |
||||||
606 | } |
||||||
607 | } |
||||||
608 |
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.
This is most likely a typographical error or the method has been renamed.