‪TYPO3CMS  11.5
LocalizationController.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
20 use Psr\EventDispatcher\EventDispatcherInterface;
21 use Psr\Http\Message\ResponseInterface;
22 use Psr\Http\Message\ServerRequestInterface;
26 use TYPO3\CMS\Backend\Utility\BackendUtility;
35 
42 {
46  public const ‪ACTION_COPY = 'copyFromLanguage';
47 
51  public const ‪ACTION_LOCALIZE = 'localize';
52 
56  protected ‪$iconFactory;
57 
62 
66  protected ‪$eventDispatcher;
67 
71  public function ‪__construct()
72  {
73  $this->iconFactory = GeneralUtility::makeInstance(IconFactory::class);
74  $this->localizationRepository = GeneralUtility::makeInstance(LocalizationRepository::class);
75  $this->eventDispatcher = GeneralUtility::makeInstance(EventDispatcherInterface::class);
76  }
77 
84  public function ‪getUsedLanguagesInPage(ServerRequestInterface $request): ResponseInterface
85  {
86  $params = $request->getQueryParams();
87  if (!isset($params['pageId'], $params['languageId'])) {
88  return new ‪JsonResponse(null, 400);
89  }
90 
91  $pageId = (int)$params['pageId'];
92  $languageId = (int)$params['languageId'];
93 
94  $translationProvider = GeneralUtility::makeInstance(TranslationConfigurationProvider::class);
95  $systemLanguages = $translationProvider->getSystemLanguages($pageId);
96 
97  $availableLanguages = [];
98 
99  // First check whether column has localized records
100  $elementsInColumnCount = $this->localizationRepository->getLocalizedRecordCount($pageId, $languageId);
101  $result = [];
102  if ($elementsInColumnCount !== 0) {
103  // check elements in column - empty if source records do not exist anymore
104  $result = $this->localizationRepository->fetchOriginLanguage($pageId, $languageId);
105  if ($result !== []) {
106  $availableLanguages[] = $systemLanguages[$result['sys_language_uid']];
107  }
108  }
109  if ($elementsInColumnCount === 0 || $result === []) {
110  $fetchedAvailableLanguages = $this->localizationRepository->fetchAvailableLanguages($pageId, $languageId);
111  foreach ($fetchedAvailableLanguages as $language) {
112  if (isset($systemLanguages[$language['sys_language_uid']])) {
113  $availableLanguages[] = $systemLanguages[$language['sys_language_uid']];
114  }
115  }
116  }
117  // Language "All" should not appear as a source of translations (see bug 92757) and keys should be sequential
118  $availableLanguages = array_values(
119  array_filter($availableLanguages, static function (array $languageRecord): bool {
120  return (int)$languageRecord['uid'] !== -1;
121  })
122  );
123 
124  // Pre-render all flag icons
125  foreach ($availableLanguages as &$language) {
126  if ($language['flagIcon'] === 'empty-empty') {
127  $language['flagIcon'] = '';
128  } else {
129  $language['flagIcon'] = $this->iconFactory->getIcon($language['flagIcon'], ‪Icon::SIZE_SMALL)->render();
130  }
131  }
132 
133  return new JsonResponse($availableLanguages);
134  }
135 
142  public function ‪getRecordLocalizeSummary(ServerRequestInterface $request): ResponseInterface
143  {
144  $params = $request->getQueryParams();
145  if (!isset($params['pageId'], $params['destLanguageId'], $params['languageId'])) {
146  return new JsonResponse(null, 400);
147  }
148 
149  $pageId = (int)$params['pageId'];
150  $destLanguageId = (int)$params['destLanguageId'];
151  $languageId = (int)$params['languageId'];
152 
153  $records = [];
154  $result = $this->localizationRepository->getRecordsToCopyDatabaseResult(
155  $pageId,
156  $destLanguageId,
157  $languageId,
158  '*'
159  );
160 
161  $flatRecords = [];
162  while ($row = $result->fetchAssociative()) {
163  BackendUtility::workspaceOL('tt_content', $row, -99, true);
164  if (!$row || ‪VersionState::cast($row['t3ver_state'])->equals(‪VersionState::DELETE_PLACEHOLDER)) {
165  continue;
166  }
167  $colPos = $row['colPos'];
168  if (!isset($records[$colPos])) {
169  $records[$colPos] = [];
170  }
171  $records[$colPos][] = [
172  'icon' => $this->iconFactory->getIconForRecord('tt_content', $row, ‪Icon::SIZE_SMALL)->render(),
173  'title' => $row[‪$GLOBALS['TCA']['tt_content']['ctrl']['label']],
174  'uid' => $row['uid'],
175  ];
176  $flatRecords[] = $row;
177  }
178 
179  return new JsonResponse([
180  'records' => $records,
181  'columns' => $this->‪getPageColumns($pageId, $flatRecords, $params),
182  ]);
183  }
184 
189  public function ‪localizeRecords(ServerRequestInterface $request): ResponseInterface
190  {
191  $params = $request->getQueryParams();
192  if (!isset($params['pageId'], $params['srcLanguageId'], $params['destLanguageId'], $params['action'], $params['uidList'])) {
193  return new JsonResponse(null, 400);
194  }
195 
196  if ($params['action'] !== static::ACTION_COPY && $params['action'] !== static::ACTION_LOCALIZE) {
197  $response = new Response('php://temp', 400, ['Content-Type' => 'application/json; charset=utf-8']);
198  $response->getBody()->write('Invalid action "' . $params['action'] . '" called.');
199  return $response;
200  }
201 
202  // Filter transmitted but invalid uids
203  $params['uidList'] = $this->‪filterInvalidUids(
204  (int)$params['pageId'],
205  (int)$params['destLanguageId'],
206  (int)$params['srcLanguageId'],
207  $params['uidList']
208  );
209 
210  $this->‪process($params);
211 
212  return new JsonResponse([]);
213  }
214 
225  protected function ‪filterInvalidUids(
226  int $pageId,
227  int $destLanguageId,
228  int $srcLanguageId,
229  array $transmittedUidList
230  ): array {
231  // Get all valid uids that can be processed
232  $validUidList = $this->localizationRepository->getRecordsToCopyDatabaseResult(
233  $pageId,
234  $destLanguageId,
235  $srcLanguageId,
236  'uid'
237  );
238 
239  return array_intersect(array_unique($transmittedUidList), array_column($validUidList->fetchAllAssociative(), 'uid'));
240  }
241 
247  protected function ‪process($params): void
248  {
249  $destLanguageId = (int)$params['destLanguageId'];
250 
251  // Build command map
252  $cmd = [
253  'tt_content' => [],
254  ];
255 
256  if (isset($params['uidList']) && is_array($params['uidList'])) {
257  foreach ($params['uidList'] as $currentUid) {
258  if ($params['action'] === static::ACTION_LOCALIZE) {
259  $cmd['tt_content'][$currentUid] = [
260  'localize' => $destLanguageId,
261  ];
262  } else {
263  $cmd['tt_content'][$currentUid] = [
264  'copyToLanguage' => $destLanguageId,
265  ];
266  }
267  }
268  }
269 
270  $dataHandler = GeneralUtility::makeInstance(DataHandler::class);
271  $dataHandler->start([], $cmd);
272  $dataHandler->process_cmdmap();
273  }
274 
281  protected function ‪getPageColumns(int $pageId, array $flatRecords, array $params): array
282  {
283  $columns = [];
284  $backendLayoutView = GeneralUtility::makeInstance(BackendLayoutView::class);
285  $backendLayout = $backendLayoutView->getBackendLayoutForPage($pageId);
286 
287  foreach ($backendLayout->getUsedColumns() as $columnPos => $columnLabel) {
288  $columns[$columnPos] = ‪$GLOBALS['LANG']->sL($columnLabel);
289  }
290 
291  $event = GeneralUtility::makeInstance(AfterPageColumnsSelectedForLocalizationEvent::class, $columns, array_values($backendLayout->getColumnPositionNumbers()), $backendLayout, $flatRecords, $params);
292  $this->eventDispatcher->dispatch($event);
293 
294  return [
295  'columns' => $event->getColumns(),
296  'columnList' => $event->getColumnList(),
297  ];
298  }
299 }
‪TYPO3\CMS\Core\DataHandling\DataHandler
Definition: DataHandler.php:86
‪TYPO3\CMS\Core\Imaging\Icon\SIZE_SMALL
‪const SIZE_SMALL
Definition: Icon.php:30
‪TYPO3\CMS\Backend\Controller\Page\LocalizationController\getPageColumns
‪array getPageColumns(int $pageId, array $flatRecords, array $params)
Definition: LocalizationController.php:278
‪TYPO3\CMS\Backend\Controller\Event\AfterPageColumnsSelectedForLocalizationEvent
Definition: AfterPageColumnsSelectedForLocalizationEvent.php:30
‪TYPO3\CMS\Core\Imaging\Icon
Definition: Icon.php:26
‪TYPO3\CMS\Backend\Controller\Page\LocalizationController\__construct
‪__construct()
Definition: LocalizationController.php:68
‪TYPO3\CMS\Backend\Domain\Repository\Localization\LocalizationRepository
Definition: LocalizationRepository.php:36
‪TYPO3\CMS\Backend\Controller\Page\LocalizationController\getUsedLanguagesInPage
‪ResponseInterface getUsedLanguagesInPage(ServerRequestInterface $request)
Definition: LocalizationController.php:81
‪TYPO3\CMS\Core\Imaging\IconFactory
Definition: IconFactory.php:34
‪TYPO3\CMS\Backend\Controller\Page\LocalizationController\getRecordLocalizeSummary
‪ResponseInterface getRecordLocalizeSummary(ServerRequestInterface $request)
Definition: LocalizationController.php:139
‪TYPO3\CMS\Core\Versioning\VersionState\DELETE_PLACEHOLDER
‪const DELETE_PLACEHOLDER
Definition: VersionState.php:61
‪TYPO3\CMS\Backend\Controller\Page
Definition: LocalizationController.php:18
‪TYPO3\CMS\Backend\Controller\Page\LocalizationController\$iconFactory
‪IconFactory $iconFactory
Definition: LocalizationController.php:55
‪TYPO3\CMS\Core\Type\Enumeration\cast
‪static static cast($value)
Definition: Enumeration.php:186
‪TYPO3\CMS\Core\Http\Response
Definition: Response.php:30
‪TYPO3\CMS\Backend\Controller\Page\LocalizationController
Definition: LocalizationController.php:42
‪TYPO3\CMS\Backend\Controller\Page\LocalizationController\ACTION_LOCALIZE
‪const ACTION_LOCALIZE
Definition: LocalizationController.php:51
‪TYPO3\CMS\Core\Versioning\VersionState
Definition: VersionState.php:24
‪TYPO3\CMS\Backend\Configuration\TranslationConfigurationProvider
Definition: TranslationConfigurationProvider.php:37
‪TYPO3\CMS\Backend\View\BackendLayoutView
Definition: BackendLayoutView.php:37
‪TYPO3\CMS\Core\Http\JsonResponse
Definition: JsonResponse.php:28
‪TYPO3\CMS\Backend\Controller\Page\LocalizationController\ACTION_COPY
‪const ACTION_COPY
Definition: LocalizationController.php:46
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Backend\Controller\Page\LocalizationController\$eventDispatcher
‪EventDispatcherInterface $eventDispatcher
Definition: LocalizationController.php:63
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:50
‪TYPO3\CMS\Backend\Controller\Page\LocalizationController\process
‪process($params)
Definition: LocalizationController.php:244
‪TYPO3\CMS\Backend\Controller\Page\LocalizationController\$localizationRepository
‪LocalizationRepository $localizationRepository
Definition: LocalizationController.php:59
‪TYPO3\CMS\Backend\Controller\Page\LocalizationController\localizeRecords
‪ResponseInterface localizeRecords(ServerRequestInterface $request)
Definition: LocalizationController.php:186
‪TYPO3\CMS\Backend\Controller\Page\LocalizationController\filterInvalidUids
‪array filterInvalidUids(int $pageId, int $destLanguageId, int $srcLanguageId, array $transmittedUidList)
Definition: LocalizationController.php:222