1 <?php
2 3 4 5 6 7 8
9
10 defined('JPATH_PLATFORM') or die;
11
12 use Joomla\Registry\Registry;
13
14 jimport('joomla.filesystem.folder');
15
16 17 18 19 20
21 class JInstallerAdapterLanguage extends JInstallerAdapter
22 {
23 24 25 26 27 28
29 protected $core = false;
30
31 32 33 34 35 36 37 38
39 protected function copyBaseFiles()
40 {
41
42 }
43
44 45 46 47 48 49 50
51 protected function setupInstallPaths()
52 {
53
54 }
55
56 57 58 59 60 61 62 63
64 protected function storeExtension()
65 {
66
67 }
68
69 70 71 72 73 74 75 76 77 78 79
80 public function install()
81 {
82 $source = $this->parent->getPath('source');
83
84 if (!$source)
85 {
86 $this->parent
87 ->setPath(
88 'source',
89 ($this->parent->extension->client_id ? JPATH_ADMINISTRATOR : JPATH_SITE) . '/language/' . $this->parent->extension->element
90 );
91 }
92
93 $this->setManifest($this->parent->getManifest());
94
95
96 if ($cname = (string) $this->getManifest()->attributes()->client)
97 {
98
99 $client = JApplicationHelper::getClientInfo($cname, true);
100
101 if ($client === null)
102 {
103 $this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT', JText::sprintf('JLIB_INSTALLER_ERROR_UNKNOWN_CLIENT_TYPE', $cname)));
104
105 return false;
106 }
107
108 $basePath = $client->path;
109 $clientId = $client->id;
110 $element = $this->getManifest()->files;
111
112 return $this->_install($cname, $basePath, $clientId, $element);
113 }
114 else
115 {
116
117 $cname = 'site';
118 $basePath = JPATH_SITE;
119 $clientId = 0;
120 $element = $this->getManifest()->files;
121
122 return $this->_install($cname, $basePath, $clientId, $element);
123 }
124 }
125
126 127 128 129 130 131 132 133 134 135 136 137
138 protected function _install($cname, $basePath, $clientId, &$element)
139 {
140 $this->setManifest($this->parent->getManifest());
141
142
143
144 $name = JFilterInput::getInstance()->clean((string) $this->getManifest()->name, 'cmd');
145 $this->set('name', $name);
146
147
148 $tag = (string) $this->getManifest()->tag;
149
150
151 if (!$tag)
152 {
153 $this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT', JText::_('JLIB_INSTALLER_ERROR_NO_LANGUAGE_TAG')));
154
155 return false;
156 }
157
158 $this->set('tag', $tag);
159
160
161 $this->parent->setPath('extension_site', $basePath . '/language/' . $tag);
162
163
164 if ($element && count($element->children()))
165 {
166 $files = $element->children();
167
168 foreach ($files as $file)
169 {
170 if ((string) $file->attributes()->file === 'meta')
171 {
172 $this->core = true;
173 break;
174 }
175 }
176 }
177
178
179 $created = false;
180
181 if (!file_exists($this->parent->getPath('extension_site')))
182 {
183 if (!$created = JFolder::create($this->parent->getPath('extension_site')))
184 {
185 $this->parent
186 ->abort(
187 JText::sprintf(
188 'JLIB_INSTALLER_ABORT',
189 JText::sprintf('JLIB_INSTALLER_ERROR_CREATE_FOLDER_FAILED', $this->parent->getPath('extension_site'))
190 )
191 );
192
193 return false;
194 }
195 }
196 else
197 {
198
199 $updateElement = $this->getManifest()->update;
200
201
202 if ($updateElement || $this->parent->isUpgrade())
203 {
204
205 return $this->update();
206 }
207 elseif (!$this->parent->isOverwrite())
208 {
209
210
211 if (file_exists($this->parent->getPath('extension_site')))
212 {
213
214 JLog::add(
215 JText::sprintf('JLIB_INSTALLER_ABORT', JText::sprintf('JLIB_INSTALLER_ERROR_FOLDER_IN_USE', $this->parent->getPath('extension_site'))),
216 JLog::WARNING, 'jerror'
217 );
218 }
219 else
220 {
221
222 JLog::add(
223 JText::sprintf('JLIB_INSTALLER_ABORT', JText::sprintf('JLIB_INSTALLER_ERROR_FOLDER_IN_USE', $this->parent->getPath('extension_administrator'))),
224 JLog::WARNING, 'jerror'
225 );
226 }
227
228 return false;
229 }
230 }
231
232 233 234 235 236
237 if ($created)
238 {
239 $this->parent->pushStep(array('type' => 'folder', 'path' => $this->parent->getPath('extension_site')));
240 }
241
242
243 if ($this->parent->parseFiles($element) === false)
244 {
245
246 $this->parent->abort();
247
248 return false;
249 }
250
251
252 $this->parent->parseMedia($this->getManifest()->media);
253
254
255 $this->parent->setPath('extension_site', $basePath . '/language/pdf_fonts');
256 $overwrite = $this->parent->setOverwrite(true);
257
258 if ($this->parent->parseFiles($this->getManifest()->fonts) === false)
259 {
260
261 $this->parent->abort();
262
263 return false;
264 }
265
266 $this->parent->setOverwrite($overwrite);
267
268
269 $description = (string) $this->getManifest()->description;
270
271 if ($description)
272 {
273 $this->parent->set('message', JText::_($description));
274 }
275 else
276 {
277 $this->parent->set('message', '');
278 }
279
280
281 $row = JTable::getInstance('extension');
282 $row->set('name', $this->get('name'));
283 $row->set('type', 'language');
284 $row->set('element', $this->get('tag'));
285
286
287 $row->set('folder', '');
288 $row->set('enabled', 1);
289 $row->set('protected', 0);
290 $row->set('access', 0);
291 $row->set('client_id', $clientId);
292 $row->set('params', $this->parent->getParams());
293 $row->set('manifest_cache', $this->parent->generateManifestCache());
294
295 if (!$row->check() || !$row->store())
296 {
297
298 $this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT', $row->getError()));
299
300 return false;
301 }
302
303
304 if ((int) $clientId === 0)
305 {
306
307 $siteLanguageManifest = JLanguageHelper::parseXMLLanguageFile(JPATH_SITE . '/language/' . $this->tag . '/' . $this->tag . '.xml');
308
309
310 $contentLanguageTitle = $siteLanguageManifest['name'];
311
312
313 $contentLanguageNativeTitle = $contentLanguageTitle;
314
315
316 if (isset($siteLanguageManifest['nativeName']) && $siteLanguageManifest['nativeName'])
317 {
318 $contentLanguageNativeTitle = $siteLanguageManifest['nativeName'];
319 }
320
321
322 if ($contentLanguageNativeTitle === $contentLanguageTitle)
323 {
324 if (file_exists(JPATH_INSTALLATION . '/language/' . $this->tag . '/' . $this->tag . '.xml'))
325 {
326 $installationLanguage = new JLanguage($this->tag);
327 $installationLanguage->load('', JPATH_INSTALLATION);
328
329 if ($installationLanguage->hasKey('INSTL_DEFAULTLANGUAGE_NATIVE_LANGUAGE_NAME'))
330 {
331
332 $defaultLanguage = new JLanguage('en-GB');
333 $defaultLanguage->load('', JPATH_INSTALLATION);
334
335 $defaultLanguageNativeTitle = $defaultLanguage->_('INSTL_DEFAULTLANGUAGE_NATIVE_LANGUAGE_NAME');
336 $installationLanguageNativeTitle = $installationLanguage->_('INSTL_DEFAULTLANGUAGE_NATIVE_LANGUAGE_NAME');
337
338 if ($defaultLanguageNativeTitle !== $installationLanguageNativeTitle)
339 {
340 $contentLanguageNativeTitle = $installationLanguage->_('INSTL_DEFAULTLANGUAGE_NATIVE_LANGUAGE_NAME');
341 }
342 }
343 }
344 }
345
346
347 $languageData = array(
348 'lang_id' => 0,
349 'lang_code' => $this->tag,
350 'title' => $contentLanguageTitle,
351 'title_native' => $contentLanguageNativeTitle,
352 'sef' => $this->getSefString($this->tag),
353 'image' => strtolower(str_replace('-', '_', $this->tag)),
354 'published' => 0,
355 'ordering' => 0,
356 'access' => (int) JFactory::getConfig()->get('access', 1),
357 'description' => '',
358 'metakey' => '',
359 'metadesc' => '',
360 'sitename' => '',
361 );
362
363 $tableLanguage = JTable::getInstance('language');
364
365 if (!$tableLanguage->bind($languageData) || !$tableLanguage->check() || !$tableLanguage->store() || !$tableLanguage->reorder())
366 {
367 JLog::add(
368 JText::sprintf('JLIB_INSTALLER_WARNING_UNABLE_TO_INSTALL_CONTENT_LANGUAGE', $siteLanguageManifest['name'], $tableLanguage->getError()),
369 JLog::NOTICE,
370 'jerror'
371 );
372 }
373 }
374
375
376 $update = JTable::getInstance('update');
377 $uid = $update->find(array('element' => $this->get('tag'), 'type' => 'language', 'folder' => ''));
378
379 if ($uid)
380 {
381 $update->delete($uid);
382 }
383
384
385 JFactory::getCache()->clean('com_languages');
386
387 return $row->get('extension_id');
388 }
389
390
391 392 393 394 395 396 397 398 399 400 401 402 403 404
405 protected function getSefString($itemLanguageTag)
406 {
407 $langs = explode('-', $itemLanguageTag);
408 $prefixToFind = $langs[0];
409 $numberPrefixesFound = 0;
410
411
412 $db = JFactory::getDbo();
413 $query = $db->getQuery(true)
414 ->select($db->qn('sef'))
415 ->from($db->qn('#__languages'));
416 $db->setQuery($query);
417
418 $siteLanguages = $db->loadObjectList();
419
420 foreach ($siteLanguages as $siteLang)
421 {
422 if ($siteLang->sef === $prefixToFind)
423 {
424 $numberPrefixesFound++;
425 }
426 }
427
428 return $numberPrefixesFound === 0 ? $prefixToFind : strtolower($itemLanguageTag);
429 }
430
431 432 433 434 435 436 437
438 public function update()
439 {
440 $xml = $this->parent->getManifest();
441
442 $this->setManifest($xml);
443
444 $cname = $xml->attributes()->client;
445
446
447 $client = JApplicationHelper::getClientInfo($cname, true);
448
449 if ($client === null || (empty($cname) && $cname !== 0))
450 {
451 $this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT', JText::sprintf('JLIB_INSTALLER_ERROR_UNKNOWN_CLIENT_TYPE', $cname)));
452
453 return false;
454 }
455
456 $basePath = $client->path;
457 $clientId = $client->id;
458
459
460
461 $name = (string) $this->getManifest()->name;
462 $name = JFilterInput::getInstance()->clean($name, 'cmd');
463 $this->set('name', $name);
464
465
466 $tag = (string) $xml->tag;
467
468
469 if (!$tag)
470 {
471 $this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT', JText::_('JLIB_INSTALLER_ERROR_NO_LANGUAGE_TAG')));
472
473 return false;
474 }
475
476 $this->set('tag', $tag);
477
478
479 $this->parent->setPath('extension_site', $basePath . '/language/' . $tag);
480
481
482 if (count($xml->files->children()))
483 {
484 foreach ($xml->files->children() as $file)
485 {
486 if ((string) $file->attributes()->file === 'meta')
487 {
488 $this->core = true;
489 break;
490 }
491 }
492 }
493
494
495 if ($this->parent->parseFiles($xml->files) === false)
496 {
497
498 $this->parent->abort();
499
500 return false;
501 }
502
503
504 $this->parent->parseMedia($xml->media);
505
506
507 $this->parent->setPath('extension_site', $basePath . '/language/pdf_fonts');
508 $overwrite = $this->parent->setOverwrite(true);
509
510 if ($this->parent->parseFiles($xml->fonts) === false)
511 {
512
513 $this->parent->abort();
514
515 return false;
516 }
517
518 $this->parent->setOverwrite($overwrite);
519
520
521 $this->parent->set('message', (string) $xml->description);
522
523 524 525 526 527
528
529
530 $update = JTable::getInstance('update');
531 $uid = $update->find(array('element' => $this->get('tag'), 'type' => 'language', 'client_id' => $clientId));
532
533 if ($uid)
534 {
535 $update->delete($uid);
536 }
537
538
539 $row = JTable::getInstance('extension');
540 $eid = $row->find(array('element' => $this->get('tag'), 'type' => 'language', 'client_id' => $clientId));
541
542 if ($eid)
543 {
544 $row->load($eid);
545 }
546 else
547 {
548
549
550
551 $row->set('folder', '');
552 $row->set('enabled', 1);
553 $row->set('protected', 0);
554 $row->set('access', 0);
555 $row->set('client_id', $clientId);
556 $row->set('params', $this->parent->getParams());
557 }
558
559 $row->set('name', $this->get('name'));
560 $row->set('type', 'language');
561 $row->set('element', $this->get('tag'));
562 $row->set('manifest_cache', $this->parent->generateManifestCache());
563
564
565 JFactory::getCache()->clean('com_languages');
566
567 if (!$row->check() || !$row->store())
568 {
569
570 $this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT', $row->getError()));
571
572 return false;
573 }
574
575 return $row->get('extension_id');
576 }
577
578 579 580 581 582 583 584 585 586
587 public function uninstall($eid)
588 {
589
590 $extension = JTable::getInstance('extension');
591 $extension->load($eid);
592
593
594 $client = JApplicationHelper::getClientInfo($extension->get('client_id'));
595
596
597 $element = $extension->get('element');
598
599 if (empty($element))
600 {
601 JLog::add(JText::_('JLIB_INSTALLER_ERROR_LANG_UNINSTALL_ELEMENT_EMPTY'), JLog::WARNING, 'jerror');
602
603 return false;
604 }
605
606
607 $protected = $extension->get('protected');
608
609 if ($protected == 1)
610 {
611 JLog::add(JText::_('JLIB_INSTALLER_ERROR_LANG_UNINSTALL_PROTECTED'), JLog::WARNING, 'jerror');
612
613 return false;
614 }
615
616
617 $params = JComponentHelper::getParams('com_languages');
618
619 if ($params->get($client->name) === $element)
620 {
621 JLog::add(JText::_('JLIB_INSTALLER_ERROR_LANG_UNINSTALL_DEFAULT'), JLog::WARNING, 'jerror');
622
623 return false;
624 }
625
626 627 628 629
630 if ($extension->package_id && !$this->parent->isPackageUninstall() && !$this->canUninstallPackageChild($extension->package_id))
631 {
632 JLog::add(JText::sprintf('JLIB_INSTALLER_ERROR_CANNOT_UNINSTALL_CHILD_OF_PACKAGE', $extension->name), JLog::WARNING, 'jerror');
633
634 return false;
635 }
636
637
638 $path = $client->path . '/language/' . $element;
639
640
641 $this->parent->setPath('source', $path);
642
643
644 $this->parent->findManifest();
645 $this->setManifest($this->parent->getManifest());
646 $this->parent->removeFiles($this->getManifest()->media);
647
648
649 if (!JFolder::exists($path))
650 {
651
652 $extension->delete();
653 JLog::add(JText::_('JLIB_INSTALLER_ERROR_LANG_UNINSTALL_PATH_EMPTY'), JLog::WARNING, 'jerror');
654
655 return false;
656 }
657
658 if (!JFolder::delete($path))
659 {
660
661 JLog::add(JText::_('JLIB_INSTALLER_ERROR_LANG_UNINSTALL_DIRECTORY'), JLog::WARNING, 'jerror');
662
663 return false;
664 }
665
666
667 $extension->delete();
668
669
670 $db = JFactory::getDbo();
671 $query = $db->getQuery(true)
672 ->from('#__users')
673 ->select('*');
674 $db->setQuery($query);
675 $users = $db->loadObjectList();
676
677 if ($client->name === 'administrator')
678 {
679 $param_name = 'admin_language';
680 }
681 else
682 {
683 $param_name = 'language';
684 }
685
686 $count = 0;
687
688 foreach ($users as $user)
689 {
690 $registry = new Registry($user->params);
691
692 if ($registry->get($param_name) === $element)
693 {
694 $registry->set($param_name, '');
695 $query->clear()
696 ->update('#__users')
697 ->set('params=' . $db->quote($registry))
698 ->where('id=' . (int) $user->id);
699 $db->setQuery($query);
700 $db->execute();
701 $count++;
702 }
703 }
704
705
706 JFactory::getCache()->clean('com_languages');
707
708 if (!empty($count))
709 {
710 JLog::add(JText::plural('JLIB_INSTALLER_NOTICE_LANG_RESET_USERS', $count), JLog::NOTICE, 'jerror');
711 }
712
713
714 return true;
715 }
716
717 718 719 720 721 722 723 724
725 public function discover()
726 {
727 $results = array();
728 $site_languages = JFolder::folders(JPATH_SITE . '/language');
729 $admin_languages = JFolder::folders(JPATH_ADMINISTRATOR . '/language');
730
731 foreach ($site_languages as $language)
732 {
733 if (file_exists(JPATH_SITE . '/language/' . $language . '/' . $language . '.xml'))
734 {
735 $manifest_details = JInstaller::parseXMLInstallFile(JPATH_SITE . '/language/' . $language . '/' . $language . '.xml');
736 $extension = JTable::getInstance('extension');
737 $extension->set('type', 'language');
738 $extension->set('client_id', 0);
739 $extension->set('element', $language);
740 $extension->set('folder', '');
741 $extension->set('name', $language);
742 $extension->set('state', -1);
743 $extension->set('manifest_cache', json_encode($manifest_details));
744 $extension->set('params', '{}');
745 $results[] = $extension;
746 }
747 }
748
749 foreach ($admin_languages as $language)
750 {
751 if (file_exists(JPATH_ADMINISTRATOR . '/language/' . $language . '/' . $language . '.xml'))
752 {
753 $manifest_details = JInstaller::parseXMLInstallFile(JPATH_ADMINISTRATOR . '/language/' . $language . '/' . $language . '.xml');
754 $extension = JTable::getInstance('extension');
755 $extension->set('type', 'language');
756 $extension->set('client_id', 1);
757 $extension->set('element', $language);
758 $extension->set('folder', '');
759 $extension->set('name', $language);
760 $extension->set('state', -1);
761 $extension->set('manifest_cache', json_encode($manifest_details));
762 $extension->set('params', '{}');
763 $results[] = $extension;
764 }
765 }
766
767 return $results;
768 }
769
770 771 772 773 774 775 776 777
778 public function discover_install()
779 {
780
781 $client = JApplicationHelper::getClientInfo($this->parent->extension->client_id);
782 $short_element = $this->parent->extension->element;
783 $manifestPath = $client->path . '/language/' . $short_element . '/' . $short_element . '.xml';
784 $this->parent->manifest = $this->parent->isManifest($manifestPath);
785 $this->parent->setPath('manifest', $manifestPath);
786 $this->parent->setPath('source', $client->path . '/language/' . $short_element);
787 $this->parent->setPath('extension_root', $this->parent->getPath('source'));
788 $manifest_details = JInstaller::parseXMLInstallFile($this->parent->getPath('manifest'));
789 $this->parent->extension->manifest_cache = json_encode($manifest_details);
790 $this->parent->extension->state = 0;
791 $this->parent->extension->name = $manifest_details['name'];
792 $this->parent->extension->enabled = 1;
793
794
795 try
796 {
797 $this->parent->extension->check();
798 $this->parent->extension->store();
799 }
800 catch (RuntimeException $e)
801 {
802 JLog::add(JText::_('JLIB_INSTALLER_ERROR_LANG_DISCOVER_STORE_DETAILS'), JLog::WARNING, 'jerror');
803
804 return false;
805 }
806
807
808 JFactory::getCache()->clean('com_languages');
809
810 return $this->parent->extension->get('extension_id');
811 }
812
813 814 815 816 817 818 819
820 public function refreshManifestCache()
821 {
822 $client = JApplicationHelper::getClientInfo($this->parent->extension->client_id);
823 $manifestPath = $client->path . '/language/' . $this->parent->extension->element . '/' . $this->parent->extension->element . '.xml';
824 $this->parent->manifest = $this->parent->isManifest($manifestPath);
825 $this->parent->setPath('manifest', $manifestPath);
826 $manifest_details = JInstaller::parseXMLInstallFile($this->parent->getPath('manifest'));
827 $this->parent->extension->manifest_cache = json_encode($manifest_details);
828 $this->parent->extension->name = $manifest_details['name'];
829
830 if ($this->parent->extension->store())
831 {
832 return true;
833 }
834 else
835 {
836 JLog::add(JText::_('JLIB_INSTALLER_ERROR_MOD_REFRESH_MANIFEST_CACHE'), JLog::WARNING, 'jerror');
837
838 return false;
839 }
840 }
841 }
842
843 844 845 846 847 848 849
850 class JInstallerLanguage extends JInstallerAdapterLanguage
851 {
852 }
853