02e3d1c588fd1b7108f58a50cbc46c64f9955ebc
[Packages/TYPO3.CMS.git] / typo3 / sysext / lang / Classes / Controller / LanguageController.php
1 <?php
2 namespace TYPO3\CMS\Lang\Controller;
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 use TYPO3\CMS\Backend\Template\Components\ButtonBar;
17 use TYPO3\CMS\Backend\Template\Components\Menu\Menu;
18 use TYPO3\CMS\Backend\Template\Components\Menu\MenuItem;
19 use TYPO3\CMS\Backend\View\BackendTemplateView;
20 use TYPO3\CMS\Core\Imaging\Icon;
21 use TYPO3\CMS\Core\Utility\GeneralUtility;
22 use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
23 use TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder;
24 use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
25
26 /**
27 * Language controller
28 */
29 class LanguageController extends ActionController
30 {
31 /**
32 * @var string
33 */
34 protected $defaultViewObjectName = BackendTemplateView::class;
35
36 /**
37 * @var BackendTemplateView
38 */
39 protected $view;
40
41 /**
42 * @var \TYPO3\CMS\Lang\Domain\Repository\LanguageRepository
43 */
44 protected $languageRepository;
45
46 /**
47 * @var \TYPO3\CMS\Lang\Domain\Repository\ExtensionRepository
48 */
49 protected $extensionRepository;
50
51 /**
52 * @var \TYPO3\CMS\Lang\Service\TranslationService
53 */
54 protected $translationService;
55
56 /**
57 * @var \TYPO3\CMS\Lang\Service\RegistryService
58 */
59 protected $registryService;
60
61 /**
62 * @param \TYPO3\CMS\Lang\Domain\Repository\LanguageRepository $languageRepository
63 */
64 public function injectLanguageRepository(\TYPO3\CMS\Lang\Domain\Repository\LanguageRepository $languageRepository)
65 {
66 $this->languageRepository = $languageRepository;
67 }
68
69 /**
70 * @param \TYPO3\CMS\Lang\Domain\Repository\ExtensionRepository $extensionRepository
71 */
72 public function injectExtensionRepository(\TYPO3\CMS\Lang\Domain\Repository\ExtensionRepository $extensionRepository)
73 {
74 $this->extensionRepository = $extensionRepository;
75 }
76
77 /**
78 * @param \TYPO3\CMS\Lang\Service\TranslationService $translationService
79 */
80 public function injectTranslationService(\TYPO3\CMS\Lang\Service\TranslationService $translationService)
81 {
82 $this->translationService = $translationService;
83 }
84
85 /**
86 * @param \TYPO3\CMS\Lang\Service\RegistryService $registryService
87 */
88 public function injectRegistryService(\TYPO3\CMS\Lang\Service\RegistryService $registryService)
89 {
90 $this->registryService = $registryService;
91 }
92
93 /**
94 * List languages
95 *
96 * @return void
97 */
98 public function listLanguagesAction()
99 {
100 $this->prepareDocHeaderMenu();
101 $this->prepareDocHeaderButtons();
102
103 $languages = $this->languageRepository->findAll();
104 $this->view->assign('languages', $languages);
105 }
106
107 /**
108 * List translations
109 *
110 * @return void
111 */
112 public function listTranslationsAction()
113 {
114 $this->prepareDocHeaderMenu();
115
116 $languages = $this->languageRepository->findSelected();
117 $this->view->assign('languages', $languages);
118 }
119
120 /**
121 * Returns the translations
122 *
123 * @return void
124 */
125 public function getTranslationsAction()
126 {
127 $this->view->assign('extensions', $this->extensionRepository->findAll());
128 $this->view->assign('languages', $this->languageRepository->findSelected());
129 }
130
131 /**
132 * Fetch all translations for given locale
133 *
134 * @param array $data The request data
135 * @return void
136 */
137 public function updateLanguageAction(array $data)
138 {
139 $numberOfExtensionsToUpdate = 10;
140 $response = array(
141 'success' => false,
142 'progress' => 0,
143 );
144 if (!empty($data['locale'])) {
145 $allCount = 0;
146 for ($i = 0; $i < $numberOfExtensionsToUpdate; $i++) {
147 $offset = (int)$data['count'] * $numberOfExtensionsToUpdate + $i;
148 $extension = $this->extensionRepository->findOneByOffset($offset);
149 if (empty($extension)) {
150 // No more extensions to update
151 break;
152 }
153 if ($allCount === 0) {
154 $allCount = (int)$this->extensionRepository->countAll();
155 }
156 $extensionKey = $extension->getKey();
157 $result = $this->translationService->updateTranslation($extensionKey, $data['locale']);
158 $progress = round((($offset + 1) * 100) / $allCount, 2);
159 $response['result'][$data['locale']][$extensionKey] = $result[$data['locale']];
160 if (empty($result[$extensionKey][$data['locale']]['error'])) {
161 $response['success'] = true;
162 } else {
163 // Could not update an extension, stop here!
164 $response['success'] = false;
165 break;
166 }
167 }
168 }
169 if ($response['success']) {
170 $this->registryService->set($data['locale'], $GLOBALS['EXEC_TIME']);
171 $response['timestamp'] = $GLOBALS['EXEC_TIME'];
172 $response['progress'] = $progress > 100 ? 100 : $progress;
173 }
174 $this->view->assign('response', $response);
175 }
176
177 /**
178 * Fetch the translation for given extension and locale
179 *
180 * @param array $data The request data
181 * @return void
182 */
183 public function updateTranslationAction(array $data)
184 {
185 $response = array('success' => false);
186 if (!empty($data['extension']) && !empty($data['locale'])) {
187 $result = $this->translationService->updateTranslation($data['extension'], $data['locale']);
188 if (empty($result[$data['extension']][$data['locale']]['error'])) {
189 $response = array(
190 'success' => true,
191 'result' => $result,
192 );
193 }
194 }
195 $this->view->assign('response', $response);
196 }
197
198 /**
199 * Activate a language
200 *
201 * @param array $data The request data
202 * @return void
203 */
204 public function activateLanguageAction(array $data)
205 {
206 $response = array('success' => false);
207 if (!empty($data['locale'])) {
208 $response = $this->languageRepository->activateByLocale($data['locale']);
209 }
210 $this->view->assign('response', $response);
211 }
212
213 /**
214 * Deactivate a language
215 *
216 * @param array $data The request data
217 * @return void
218 */
219 public function deactivateLanguageAction(array $data)
220 {
221 $response = array('success' => false);
222 if (!empty($data['locale'])) {
223 $response = $this->languageRepository->deactivateByLocale($data['locale']);
224 }
225 $this->view->assign('response', $response);
226 }
227
228 /**
229 * DocHeaderMenu
230 */
231 protected function prepareDocHeaderMenu()
232 {
233 $this->view->getModuleTemplate()->setModuleName('typo3-module-lang');
234 $this->view->getModuleTemplate()->setModuleId('typo3-module-lang');
235
236 $this->view->getModuleTemplate()->getPageRenderer()->loadRequireJsModule('TYPO3/CMS/Lang/LanguageModule');
237
238 $extensionKey = 'lang';
239 $addJsInlineLabels = [
240 'flashmessage.error',
241 'flashmessage.information',
242 'flashmessage.success',
243 'flashmessage.multipleErrors',
244 'flashmessage.updateComplete',
245 'flashmessage.canceled',
246 'flashmessage.languageActivated',
247 'flashmessage.languageDeactivated',
248 'flashmessage.noLanguageActivated',
249 'flashmessage.errorOccurred',
250 'table.processing',
251 'table.search',
252 'table.loadingRecords',
253 'table.zeroRecords',
254 'table.emptyTable',
255 'table.dateFormat',
256 ];
257 foreach ($addJsInlineLabels as $key) {
258 $label = LocalizationUtility::translate($key, $extensionKey);
259 $this->view->getModuleTemplate()->getPageRenderer()->addInlineLanguageLabel($key, $label);
260 }
261
262 $uriBuilder = $this->objectManager->get(UriBuilder::class);
263 $uriBuilder->setRequest($this->request);
264
265 /** @var Menu $menu */
266 $menu = GeneralUtility::makeInstance(Menu::class);
267 $menu->setIdentifier('_languageMenu');
268 $menu->setLabel($this->getLanguageService()->sL('LLL:EXT:lang/locallang_general.xlf:LGL.language', true));
269
270 /** @var MenuItem $languageListMenuItem */
271 $languageListMenuItem = GeneralUtility::makeInstance(MenuItem::class);
272 $action = 'listLanguages';
273 $isActive = $this->request->getControllerActionName() === $action ? true : false;
274 $languageListMenuItem->setTitle($this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang.xlf:header.languages'));
275 $uri = $uriBuilder->reset()->uriFor('listLanguages', array(), 'Language');
276 $languageListMenuItem->setHref($uri)->setActive($isActive);
277
278 /** @var MenuItem $translationMenuItem */
279 $translationMenuItem = GeneralUtility::makeInstance(MenuItem::class);
280 $action = 'listTranslations';
281 $isActive = $this->request->getControllerActionName() === $action ? true : false;
282 $translationMenuItem->setTitle($this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang.xlf:header.translations'));
283 $uri = $uriBuilder->reset()->uriFor('listTranslations', array(), 'Language');
284 $translationMenuItem->setHref($uri)->setActive($isActive);
285
286 $menu->addMenuItem($languageListMenuItem);
287 $menu->addMenuItem($translationMenuItem);
288 $this->view->getModuleTemplate()->getDocHeaderComponent()->getMenuRegistry()->addMenu($menu);
289 $this->view->getModuleTemplate()->setFlashMessageQueue($this->controllerContext->getFlashMessageQueue());
290 }
291
292 /**
293 * Returns LanguageService
294 *
295 * @return \TYPO3\CMS\Lang\LanguageService
296 */
297 protected function getLanguageService()
298 {
299 return $GLOBALS['LANG'];
300 }
301
302 /**
303 * DocHeaderButtons
304 */
305 protected function prepareDocHeaderButtons()
306 {
307 // @todo: the html structure needed to operate the buttons correctly is broken now.
308 // @todo: LanguageModule.js and backend.css -> div.typo3-module-lang div.menuItems
309
310 $downloadAllButton = $this->view->getModuleTemplate()->getDocHeaderComponent()->getButtonBar()->makeLinkButton()
311 ->setIcon($this->view->getModuleTemplate()->getIconFactory()->getIcon('actions-system-extension-download', Icon::SIZE_SMALL))
312 ->setTitle($this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang.xlf:button.downloadAll'))
313 ->setClasses('menuItem updateItem t3js-button-update')
314 ->setDataAttributes(['action' => 'updateActiveLanguages'])
315 ->setHref('#');
316 $this->view->getModuleTemplate()->getDocHeaderComponent()->getButtonBar()->addButton($downloadAllButton, ButtonBar::BUTTON_POSITION_LEFT);
317
318 $cancelButton = $this->view->getModuleTemplate()->getDocHeaderComponent()->getButtonBar()->makeLinkButton()
319 ->setIcon($this->view->getModuleTemplate()->getIconFactory()->getIcon('actions-document-close', Icon::SIZE_SMALL))
320 ->setTitle($this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang.xlf:button.cancel'))
321 ->setClasses('menuItem cancelItem disabled t3js-button-cancel')
322 ->setDataAttributes(['action' => 'cancelLanguageUpdate'])
323 ->setHref('#');
324
325 $this->view->getModuleTemplate()->getDocHeaderComponent()->getButtonBar()->addButton($cancelButton, ButtonBar::BUTTON_POSITION_LEFT);
326 }
327 }