[BUGFIX] Make language module accessible without internet connection
[Packages/TYPO3.CMS.git] / typo3 / sysext / lang / Classes / Service / TranslationService.php
1 <?php
2 namespace TYPO3\CMS\Lang\Service;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use TYPO3\CMS\Core\SingletonInterface;
18 use TYPO3\CMS\Core\Utility\GeneralUtility;
19 use TYPO3\CMS\Extbase\SignalSlot\Dispatcher;
20 use TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException;
21 use TYPO3\CMS\Extensionmanager\Utility\Repository\Helper;
22
23 /**
24 * Translation service
25 */
26 class TranslationService implements SingletonInterface
27 {
28 /**
29 * Status codes for AJAX response
30 */
31 const TRANSLATION_NOT_AVAILABLE = 0;
32 const TRANSLATION_AVAILABLE = 1;
33 const TRANSLATION_FAILED = 2;
34 const TRANSLATION_OK = 3;
35 const TRANSLATION_INVALID = 4;
36 const TRANSLATION_UPDATED = 5;
37
38 /**
39 * @var \TYPO3\CMS\Lang\Service\TerService
40 */
41 protected $terService;
42
43 /**
44 * @var \TYPO3\CMS\Extbase\SignalSlot\Dispatcher
45 */
46 protected $signalSlotDispatcher;
47
48 /**
49 * @var string
50 */
51 protected $mirrorUrl = '';
52
53 /**
54 * @param \TYPO3\CMS\Lang\Service\TerService $terService
55 */
56 public function injectTerService(TerService $terService)
57 {
58 $this->terService = $terService;
59 }
60
61 /**
62 * @param \TYPO3\CMS\Extbase\SignalSlot\Dispatcher $signalSlotDispatcher
63 */
64 public function injectSignalSlotDispatcher(Dispatcher $signalSlotDispatcher)
65 {
66 $this->signalSlotDispatcher = $signalSlotDispatcher;
67 }
68
69 /**
70 * @param \TYPO3\CMS\Extensionmanager\Utility\Repository\Helper $helper The helper
71 */
72 public function injectRepositoryHelper(Helper $helper)
73 {
74 try {
75 $this->mirrorUrl = $helper->getMirrors(false)->getMirrorUrl();
76 } catch (ExtensionManagerException $e) {
77 $this->mirrorUrl = '';
78 }
79 }
80
81 /**
82 * Update translation for given extension
83 *
84 * @param string $extensionKey The extension key
85 * @param mixed $locales Comma separated list or array of locales
86 * @return array Update information
87 */
88 public function updateTranslation($extensionKey, $locales)
89 {
90 if (is_string($locales)) {
91 $locales = GeneralUtility::trimExplode(',', $locales);
92 }
93 $locales = array_flip((array) $locales);
94 foreach ($locales as $locale => $key) {
95 $state = static::TRANSLATION_INVALID;
96 $error = '';
97 try {
98 $state = $this->updateTranslationForExtension($extensionKey, $locale);
99 } catch (\Exception $exception) {
100 $error = $exception->getMessage();
101 }
102 $locales[$locale] = array(
103 'state' => $state,
104 'error' => $error,
105 );
106 }
107 return $locales;
108 }
109
110 /**
111 * Update the translation for an extension
112 *
113 * @param string $extensionKey The extension key
114 * @param string $locale Locale to update
115 * @return int Translation state
116 * @throws \Exception
117 */
118 protected function updateTranslationForExtension($extensionKey, $locale)
119 {
120 if (empty($extensionKey) || empty($locale)) {
121 return static::TRANSLATION_INVALID;
122 }
123
124 $mirrorUrl = $this->getMirrorUrl($extensionKey);
125 if (empty($mirrorUrl)) {
126 throw new \Exception('Not able to fetch languages files due to missing mirror url.', 1461248062);
127 }
128
129 $state = static::TRANSLATION_FAILED;
130
131 $updateResult = $this->terService->updateTranslation($extensionKey, $locale, $mirrorUrl);
132 if ($updateResult === true) {
133 $state = static::TRANSLATION_UPDATED;
134 }
135 return $state;
136 }
137
138 /**
139 * Returns the mirror URL for a given extension.
140 *
141 * @param string $extensionKey
142 * @return string
143 */
144 protected function getMirrorUrl($extensionKey)
145 {
146 $this->signalSlotDispatcher->dispatch(
147 __CLASS__,
148 'postProcessMirrorUrl',
149 array(
150 'extensionKey' => $extensionKey,
151 'mirrorUrl' => &$this->mirrorUrl,
152 )
153 );
154
155 return $this->mirrorUrl;
156 }
157 }