[TASK] Fix CGL errors
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Classes / Controller / Page / LocalizationController.php
1 <?php
2 namespace TYPO3\CMS\Backend\Controller\Page;
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 Psr\Http\Message\ResponseInterface;
18 use Psr\Http\Message\ServerRequestInterface;
19 use TYPO3\CMS\Backend\Configuration\TranslationConfigurationProvider;
20 use TYPO3\CMS\Backend\Utility\BackendUtility;
21 use TYPO3\CMS\Core\DataHandling\DataHandler;
22 use TYPO3\CMS\Core\Imaging\Icon;
23 use TYPO3\CMS\Core\Imaging\IconFactory;
24 use TYPO3\CMS\Core\Utility\GeneralUtility;
25
26 /**
27 * LocalizationController handles the AJAX requests for record localization
28 */
29 class LocalizationController
30 {
31 /**
32 * @var IconFactory
33 */
34 protected $iconFactory;
35
36 /**
37 * Constructor
38 */
39 public function __construct()
40 {
41 $this->iconFactory = GeneralUtility::makeInstance(IconFactory::class);
42 }
43
44 /**
45 * Get used languages in a colPos of a page
46 *
47 * @param ServerRequestInterface $request
48 * @param ResponseInterface $response
49 * @return ResponseInterface
50 */
51 public function getUsedLanguagesInPageAndColumn(ServerRequestInterface $request, ResponseInterface $response)
52 {
53 $params = $request->getQueryParams();
54 if (!isset($params['pageId'], $params['colPos'], $params['languageId'])) {
55 $response = $response->withStatus(500);
56 return $response;
57 }
58
59 $pageId = (int)$params['pageId'];
60 $colPos = (int)$params['colPos'];
61 $languageId = (int)$params['languageId'];
62 $databaseConnection = $this->getDatabaseConnection();
63 $backendUser = $this->getBackendUser();
64
65 /** @var TranslationConfigurationProvider $translationProvider */
66 $translationProvider = GeneralUtility::makeInstance(TranslationConfigurationProvider::class);
67 $systemLanguages = $translationProvider->getSystemLanguages($pageId);
68
69 $availableLanguages = [];
70 $availableLanguages[0] = $systemLanguages[0];
71
72 $excludeQueryPart = BackendUtility::deleteClause('tt_content')
73 . BackendUtility::versioningPlaceholderClause('tt_content');
74
75 // First check whether column is empty and then load additional languages
76 $elementsInColumnCount = $databaseConnection->exec_SELECTcountRows(
77 'uid',
78 'tt_content',
79 'tt_content.sys_language_uid=' . (int)$languageId
80 . ' AND tt_content.colPos = ' . (int)$colPos
81 . ' AND tt_content.pid=' . (int)$pageId
82 . $excludeQueryPart
83 );
84 $additionalWhere = '';
85 if (!$backendUser->isAdmin()) {
86 $additionalWhere .= ' AND sys_language.hidden=0';
87
88 if (!empty($backendUser->user['allowed_languages'])) {
89 $additionalWhere .= ' AND sys_language.uid IN(' . $databaseConnection->cleanIntList($backendUser->user['allowed_languages']) . ')';
90 }
91 }
92 if ($elementsInColumnCount === 0) {
93 $res = $databaseConnection->exec_SELECTquery(
94 'sys_language.uid',
95 'tt_content,sys_language',
96 'tt_content.sys_language_uid=sys_language.uid'
97 . ' AND tt_content.colPos = ' . (int)$colPos
98 . ' AND tt_content.pid=' . (int)$pageId
99 . ' AND sys_language.uid <> ' . (int)$languageId
100 . $additionalWhere
101 . $excludeQueryPart,
102 'tt_content.sys_language_uid',
103 'sys_language.title'
104 );
105 while ($row = $databaseConnection->sql_fetch_assoc($res)) {
106 if (isset($systemLanguages[$row['uid']])) {
107 $availableLanguages[] = $systemLanguages[$row['uid']];
108 }
109 }
110 $databaseConnection->sql_free_result($res);
111 }
112
113 // Pre-render all flag icons
114 foreach ($availableLanguages as &$language) {
115 if ($language['flagIcon'] === 'empty-empty') {
116 $language['flagIcon'] = '';
117 } else {
118 $language['flagIcon'] = $this->iconFactory->getIcon($language['flagIcon'], Icon::SIZE_SMALL)->render();
119 }
120 }
121
122 $response->getBody()->write(json_encode($availableLanguages));
123 return $response;
124 }
125
126 /**
127 * Get a prepared summary of records being translated
128 *
129 * @param ServerRequestInterface $request
130 * @param ResponseInterface $response
131 * @return ResponseInterface
132 */
133 public function getRecordLocalizeSummary(ServerRequestInterface $request, ResponseInterface $response)
134 {
135 $params = $request->getQueryParams();
136 if (!isset($params['pageId'], $params['colPos'], $params['languageId'])) {
137 $response = $response->withStatus(500);
138 return $response;
139 }
140
141 $records = [];
142 $databaseConnection = $this->getDatabaseConnection();
143 $res = $this->getRecordsToCopyDatabaseResult($params['pageId'], $params['colPos'], $params['languageId'], '*');
144 while ($row = $databaseConnection->sql_fetch_assoc($res)) {
145 $records[] = [
146 'icon' => $this->iconFactory->getIconForRecord('tt_content', $row, Icon::SIZE_SMALL)->render(),
147 'title' => $row[$GLOBALS['TCA']['tt_content']['ctrl']['label']],
148 'uid' => $row['uid']
149 ];
150 }
151 $databaseConnection->sql_free_result($res);
152
153 $response->getBody()->write(json_encode($records));
154 return $response;
155 }
156
157 /**
158 * @param ServerRequestInterface $request
159 * @param ResponseInterface $response
160 * @return ResponseInterface
161 */
162 public function getRecordUidsToCopy(ServerRequestInterface $request, ResponseInterface $response)
163 {
164 $params = $request->getQueryParams();
165 if (!isset($params['pageId'], $params['colPos'], $params['languageId'])) {
166 $response = $response->withStatus(500);
167 return $response;
168 }
169
170 $pageId = (int)$params['pageId'];
171 $colPos = (int)$params['colPos'];
172 $languageId = (int)$params['languageId'];
173 $databaseConnection = $this->getDatabaseConnection();
174
175 $res = $this->getRecordsToCopyDatabaseResult($pageId, $colPos, $languageId, 'uid');
176 $uids = [];
177 while ($row = $databaseConnection->sql_fetch_assoc($res)) {
178 $uids[] = (int)$row['uid'];
179 }
180 $databaseConnection->sql_free_result($res);
181
182 $response->getBody()->write(json_encode($uids));
183 return $response;
184 }
185
186 /**
187 * @param ServerRequestInterface $request
188 * @param ResponseInterface $response
189 * @return ResponseInterface
190 */
191 public function localizeRecords(ServerRequestInterface $request, ResponseInterface $response)
192 {
193 $params = $request->getQueryParams();
194 if (!isset($params['pageId'], $params['srcLanguageId'], $params['destLanguageId'], $params['action'], $params['uidList'])) {
195 $response = $response->withStatus(500);
196 return $response;
197 }
198
199 if ($params['action'] !== 'copyFromLanguage' && $params['action'] !== 'localize') {
200 $response->getBody()->write('Invalid action "' . $params['action'] . '" called.');
201 $response = $response->withStatus(500);
202 return $response;
203 }
204
205 $pageId = (int)$params['pageId'];
206 $srcLanguageId = (int)$params['srcLanguageId'];
207 $destLanguageId = (int)$params['destLanguageId'];
208 $params['uidList'] = array_reverse($params['uidList']);
209
210 // Build command map
211 $cmd = [
212 'tt_content' => []
213 ];
214
215 for ($i = 0, $count = count($params['uidList']); $i < $count; ++$i) {
216 $currentUid = $params['uidList'][$i];
217
218 if ($params['action'] === 'localize') {
219 if ($srcLanguageId === 0) {
220 $cmd['tt_content'][$currentUid] = [
221 'localize' => $destLanguageId
222 ];
223 } else {
224 $cmd['tt_content'][$currentUid] = [
225 'copy' => [
226 'action' => 'paste',
227 'target' => $pageId,
228 'update' => [
229 'sys_language_uid' => $destLanguageId
230 ]
231 ]
232 ];
233 }
234 } else {
235 $cmd['tt_content'][$currentUid] = [
236 'copy' => [
237 'action' => 'paste',
238 'target' => $pageId,
239 'update' => [
240 'sys_language_uid' => $destLanguageId,
241 'l18n_parent' => 0
242 ]
243 ]
244 ];
245 }
246 }
247
248 /** @var DataHandler $dataHandler */
249 $dataHandler = GeneralUtility::makeInstance(DataHandler::class);
250 $dataHandler->start([], $cmd);
251 $dataHandler->process_cmdmap();
252
253 $response->getBody()->write(json_encode([]));
254 return $response;
255 }
256
257 /**
258 * Get records for copy process
259 *
260 * @param int $pageId
261 * @param int $colPos
262 * @param int $languageId
263 * @param string $fields
264 * @return bool|\mysqli_result|object
265 */
266 protected function getRecordsToCopyDatabaseResult($pageId, $colPos, $languageId, $fields = '*')
267 {
268 return $this->getDatabaseConnection()->exec_SELECTquery(
269 $fields,
270 'tt_content',
271 'tt_content.sys_language_uid=' . (int)$languageId
272 . ' AND tt_content.colPos = ' . (int)$colPos
273 . ' AND tt_content.pid=' . (int)$pageId
274 . BackendUtility::deleteClause('tt_content')
275 . BackendUtility::versioningPlaceholderClause('tt_content'),
276 '',
277 'tt_content.sorting'
278 );
279 }
280
281 /**
282 * Returns the current BE user.
283 *
284 * @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
285 */
286 protected function getBackendUser()
287 {
288 return $GLOBALS['BE_USER'];
289 }
290
291 /**
292 * Returns the database connection
293 *
294 * @return \TYPO3\CMS\Core\Database\DatabaseConnection
295 */
296 protected function getDatabaseConnection()
297 {
298 return $GLOBALS['TYPO3_DB'];
299 }
300 }