[BUGFIX] FollowUp: Fix signal returns for associated signal arguments
[Packages/TYPO3.CMS.git] / typo3 / sysext / lang / Classes / Service / UpdateTranslationService.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 /**
18 * Update languages service
19 */
20 class UpdateTranslationService {
21
22 /**
23 * Status codes for AJAX response
24 */
25 const TRANSLATION_NOT_AVAILABLE = 0;
26 const TRANSLATION_AVAILABLE = 1;
27 const TRANSLATION_FAILED = 2;
28 const TRANSLATION_OK = 3;
29 const TRANSLATION_INVALID = 4;
30 const TRANSLATION_UPDATED = 5;
31
32 /**
33 * @var \TYPO3\CMS\Lang\Domain\Repository\LanguageRepository
34 * @inject
35 */
36 protected $languageRepository;
37
38 /**
39 * @var \TYPO3\CMS\Extensionmanager\Utility\Repository\Helper
40 * @inject
41 */
42 protected $repositoryHelper;
43
44 /**
45 * @var \TYPO3\CMS\Lang\Utility\Connection\Ter
46 * @inject
47 */
48 protected $terConnection;
49
50 /**
51 * @var \TYPO3\CMS\Extbase\SignalSlot\Dispatcher
52 * @inject
53 */
54 protected $signalSlotDispatcher;
55
56 /**
57 * @var array
58 */
59 protected $translationStates = array();
60
61 /**
62 * Update translation for given extension
63 *
64 * @param string $extension The extension key
65 * @param string $locales Comma separated list of locales to update
66 * @return array
67 */
68 public function updateTranslation($extension, $locales) {
69 if (is_string($locales)) {
70 $locales = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $locales);
71 }
72 $locales = array_flip((array) $locales);
73
74 foreach ($locales as $locale => $key) {
75 $state = static::TRANSLATION_INVALID;
76 try {
77 $state = $this->getTranslationStateForExtension($extension, $locale);
78 if ($state === static::TRANSLATION_AVAILABLE) {
79 $state = $this->updateTranslationForExtension($extension, $locale);
80 }
81 } catch (\Exception $exception) {
82 $error = $exception->getMessage();
83 }
84 $locales[$locale] = array(
85 'state' => $state,
86 'error' => $error,
87 );
88 }
89 return $locales;
90 }
91
92 /**
93 * Returns the translation state for an extension
94 *
95 * @param string $extensionKey The extension key
96 * @param string $locale Locale to return
97 * @return integer Translation state
98 */
99 protected function getTranslationStateForExtension($extensionKey, $locale) {
100 if (empty($extensionKey) || empty($locale)) {
101 return static::TRANSLATION_INVALID;
102 }
103
104 $identifier = $extensionKey . '-' . $locale;
105 if (isset($this->translationStates[$identifier])) {
106 return $this->translationStates[$identifier];
107 }
108
109 $selectedLanguages = $this->languageRepository->findSelected();
110 if (empty($selectedLanguages) || !is_array($selectedLanguages)) {
111 return static::TRANSLATION_INVALID;
112 }
113
114 $mirrorUrl = $this->getMirrorUrl($extensionKey);
115 $status = $this->terConnection->fetchTranslationStatus($extensionKey, $mirrorUrl);
116
117 foreach ($selectedLanguages as $language) {
118 $stateLocale = $language->getLocale();
119 $stateIdentifier = $extensionKey . '-' . $stateLocale;
120 $this->translationStates[$stateIdentifier] = static::TRANSLATION_INVALID;
121
122 if (empty($status[$stateLocale]) || !is_array($status[$stateLocale])) {
123 $this->translationStates[$stateIdentifier] = static::TRANSLATION_NOT_AVAILABLE;
124 continue;
125 }
126
127 $md5 = $this->getTranslationFileMd5($extensionKey, $stateLocale);
128 if ($md5 !== $status[$stateLocale]['md5']) {
129 $this->translationStates[$stateIdentifier] = static::TRANSLATION_AVAILABLE;
130 continue;
131 }
132
133 $this->translationStates[$stateIdentifier] = static::TRANSLATION_OK;
134 }
135
136 return $this->translationStates[$identifier];
137 }
138
139 /**
140 * Returns the md5 of a translation file
141 *
142 * @param string $extensionKey The extension key
143 * @param string $locale The locale
144 * @return string The md5 value
145 */
146 protected function getTranslationFileMd5($extensionKey, $locale) {
147 if (empty($extensionKey) || empty($locale)) {
148 return '';
149 }
150 $fileName = PATH_site . 'typo3temp' . DIRECTORY_SEPARATOR . $extensionKey . '-l10n-' . $locale . '.zip';
151 if (is_file($fileName)) {
152 return md5_file($fileName);
153 }
154 return '';
155 }
156
157 /**
158 * Update the translation for an extension
159 *
160 * @param string $extensionKey The extension key
161 * @param string $locale Locale to update
162 * @return integer Translation state
163 */
164 protected function updateTranslationForExtension($extensionKey, $locale) {
165 if (empty($extensionKey) || empty($locale)) {
166 return static::TRANSLATION_INVALID;
167 }
168
169 $state = static::TRANSLATION_FAILED;
170 $mirrorUrl = $this->getMirrorUrl($extensionKey);
171 $updateResult = $this->terConnection->updateTranslation($extensionKey, $locale, $mirrorUrl);
172 if ($updateResult === TRUE) {
173 $state = static::TRANSLATION_UPDATED;
174 }
175
176 return $state;
177 }
178
179 /**
180 * Returns the mirror URL for a given extension.
181 *
182 * @param string $extensionKey
183 * @return string
184 */
185 protected function getMirrorUrl($extensionKey) {
186 $mirrorUrl = $this->repositoryHelper->getMirrors()->getMirrorUrl();
187
188 $mirrorUrl = $this->emitPostProcessMirrorUrlSignal($extensionKey, $mirrorUrl);
189
190 return $mirrorUrl;
191 }
192
193 /**
194 * Emits a signal after the mirror URL of an extension was fetched
195 *
196 * @param string $extensionKey
197 * @param string $mirrorUrl
198 * @return string Modified mirror url
199 */
200 protected function emitPostProcessMirrorUrlSignal($extensionKey, $mirrorUrl) {
201 $this->signalSlotDispatcher->dispatch(
202 __CLASS__,
203 'postProcessMirrorUrl',
204 array(
205 $extensionKey,
206 &$mirrorUrl,
207 )
208 );
209 return $mirrorUrl;
210 }
211
212 }