[BUGFIX] Replace PHP 7.2 deprecated each()
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Classes / Configuration / TranslationConfigurationProvider.php
1 <?php
2 namespace TYPO3\CMS\Backend\Configuration;
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\Backend\Utility\BackendUtility;
18 use TYPO3\CMS\Core\Database\ConnectionPool;
19 use TYPO3\CMS\Core\Database\Query\Restriction\BackendWorkspaceRestriction;
20 use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
21 use TYPO3\CMS\Core\Localization\LanguageService;
22 use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
23 use TYPO3\CMS\Core\Utility\GeneralUtility;
24
25 /**
26 * Contains translation tools
27 */
28 class TranslationConfigurationProvider
29 {
30 /**
31 * @return LanguageService
32 */
33 protected function getLanguageService()
34 {
35 return $GLOBALS['LANG'];
36 }
37
38 /**
39 * Returns array of system languages
40 * The property flagIcon returns a string <flags-xx>.
41 *
42 * @param int $pageId Page id (used to get TSconfig configuration setting flag and label for default language)
43 * @return array Array with languages (uid, title, ISOcode, flagIcon)
44 */
45 public function getSystemLanguages($pageId = 0)
46 {
47 $modSharedTSconfig = BackendUtility::getModTSconfig($pageId, 'mod.SHARED');
48
49 // default language and "all languages" are always present
50 $languages = [
51 // 0: default language
52 0 => [
53 'uid' => 0,
54 'title' => $this->getDefaultLanguageLabel($modSharedTSconfig),
55 'ISOcode' => 'DEF',
56 'flagIcon' => $this->getDefaultLanguageFlag($modSharedTSconfig),
57 ],
58 // -1: all languages
59 -1 => [
60 'uid' => -1,
61 'title' => $this->getLanguageService()->getLL('multipleLanguages'),
62 'ISOcode' => 'DEF',
63 'flagIcon' => 'flags-multiple',
64 ],
65 ];
66
67 // add the additional languages from database records
68 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_language');
69 $languageRecords = $queryBuilder
70 ->select('*')
71 ->from('sys_language')
72 ->orderBy('sorting')
73 ->execute()
74 ->fetchAll();
75 foreach ($languageRecords as $languageRecord) {
76 $languages[$languageRecord['uid']] = $languageRecord;
77 // @todo: this should probably resolve language_isocode too and throw a deprecation if not filled
78 if ($languageRecord['static_lang_isocode'] && ExtensionManagementUtility::isLoaded('static_info_tables')) {
79 $staticLangRow = BackendUtility::getRecord('static_languages', $languageRecord['static_lang_isocode'], 'lg_iso_2');
80 if ($staticLangRow['lg_iso_2']) {
81 $languages[$languageRecord['uid']]['ISOcode'] = $staticLangRow['lg_iso_2'];
82 }
83 }
84 if ($languageRecord['flag'] !== '') {
85 $languages[$languageRecord['uid']]['flagIcon'] = 'flags-' . $languageRecord['flag'];
86 }
87 }
88 return $languages;
89 }
90
91 /**
92 * Information about translation for an element
93 * Will overlay workspace version of record too!
94 *
95 * @param string $table Table name
96 * @param int $uid Record uid
97 * @param int $languageUid Language uid. If 0, then all languages are selected.
98 * @param array $row The record to be translated
99 * @param string $selFieldList Select fields for the query which fetches the translations of the current record
100 * @return mixed Array with information or error message as a string.
101 */
102 public function translationInfo($table, $uid, $languageUid = 0, array $row = null, $selFieldList = '')
103 {
104 if (!$GLOBALS['TCA'][$table] || !$uid) {
105 return 'No table "' . $table . '" or no UID value';
106 }
107 if ($row === null) {
108 $row = BackendUtility::getRecordWSOL($table, $uid);
109 }
110 if (!is_array($row)) {
111 return 'Record "' . $table . '_' . $uid . '" was not found';
112 }
113 if (!BackendUtility::isTableLocalizable($table)) {
114 return 'Translation is not supported for this table!';
115 }
116 if ($row[$GLOBALS['TCA'][$table]['ctrl']['languageField']] > 0) {
117 return 'Record "' . $table . '_' . $uid . '" seems to be a translation already (has a language value "' . $row[$GLOBALS['TCA'][$table]['ctrl']['languageField']] . '", relation to record "' . $row[$GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField']] . '")';
118 }
119 if ($row[$GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField']] != 0) {
120 return 'Record "' . $table . '_' . $uid . '" seems to be a translation already (has a relation to record "' . $row[$GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField']] . '")';
121 }
122 // Look for translations of this record, index by language field value:
123 if (!$selFieldList) {
124 $selFieldList = 'uid,' . $GLOBALS['TCA'][$table]['ctrl']['languageField'];
125 }
126 $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($table);
127 $queryBuilder->getRestrictions()
128 ->removeAll()
129 ->add(GeneralUtility::makeInstance(DeletedRestriction::class))
130 ->add(GeneralUtility::makeInstance(BackendWorkspaceRestriction::class));
131 $queryBuilder
132 ->select(...GeneralUtility::trimExplode(',', $selFieldList))
133 ->from($table)
134 ->where(
135 $queryBuilder->expr()->eq(
136 $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField'],
137 $queryBuilder->createNamedParameter($uid, \PDO::PARAM_INT)
138 ),
139 $queryBuilder->expr()->eq(
140 'pid',
141 $queryBuilder->createNamedParameter(
142 $row['pid'],
143 \PDO::PARAM_INT
144 )
145 )
146 );
147 if (!$languageUid) {
148 $queryBuilder->andWhere(
149 $queryBuilder->expr()->gt(
150 $GLOBALS['TCA'][$table]['ctrl']['languageField'],
151 $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT)
152 )
153 );
154 } else {
155 $queryBuilder
156 ->andWhere(
157 $queryBuilder->expr()->eq(
158 $GLOBALS['TCA'][$table]['ctrl']['languageField'],
159 $queryBuilder->createNamedParameter($languageUid, \PDO::PARAM_INT)
160 )
161 );
162 }
163 $translationRecords = $queryBuilder
164 ->execute()
165 ->fetchAll();
166
167 $translations = [];
168 $translationsErrors = [];
169 foreach ($translationRecords as $translationRecord) {
170 if (!isset($translations[$translationRecord[$GLOBALS['TCA'][$table]['ctrl']['languageField']]])) {
171 $translations[$translationRecord[$GLOBALS['TCA'][$table]['ctrl']['languageField']]] = $translationRecord;
172 } else {
173 $translationsErrors[$translationRecord[$GLOBALS['TCA'][$table]['ctrl']['languageField']]][] = $translationRecord;
174 }
175 }
176 return [
177 'table' => $table,
178 'uid' => $uid,
179 'CType' => $row['CType'],
180 'sys_language_uid' => $row[$GLOBALS['TCA'][$table]['ctrl']['languageField']],
181 'translations' => $translations,
182 'excessive_translations' => $translationsErrors
183 ];
184 }
185
186 /**
187 * Returns the table in which translations for input table is found.
188 *
189 * @param string $table The table name
190 * @return string
191 * @deprecated since TYPO3 v9, will be removed in TYPO3 v10 as foreign translation table is not supported anymore
192 */
193 public function getTranslationTable($table)
194 {
195 trigger_error('getTranslationTable() will be removed in TYPO3 v10, as the translation table is always the same as the original table.', E_USER_DEPRECATED);
196 return BackendUtility::isTableLocalizable($table) ? $table : '';
197 }
198
199 /**
200 * Returns TRUE, if the input table has localization enabled and done so with records from the same table
201 *
202 * @param string $table The table name
203 * @return bool
204 * @deprecated since TYPO3 v9, will be removed in TYPO3 v10 as foreign translation table is not supported anymore
205 */
206 public function isTranslationInOwnTable($table)
207 {
208 trigger_error('isTranslationInOwnTable() will be removed in TYPO3 v10, as the translation table is always the same as the original table.', E_USER_DEPRECATED);
209 return $GLOBALS['TCA'][$table]['ctrl']['languageField'] && $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField'];
210 }
211
212 /**
213 * Returns foreign translation table, if any.
214 * Since TYPO3 v9, even "pages" translations are stored in the same table, having this method return always
215 * empty, as with other tables as well.
216 *
217 * @param string $table The table name
218 * @return string Translation foreign table
219 * @deprecated since TYPO3 v9, will be removed in TYPO3 v10 as foreign translation table is not supported anymore
220 */
221 public function foreignTranslationTable($table)
222 {
223 trigger_error('foreignTranslationTable() will be removed in TYPO3 v10, as the translation table is always the same as the original table.', E_USER_DEPRECATED);
224 return '';
225 }
226
227 /**
228 * @param array $modSharedTSconfig
229 * @return string
230 */
231 protected function getDefaultLanguageFlag(array $modSharedTSconfig)
232 {
233 if (strlen($modSharedTSconfig['properties']['defaultLanguageFlag'])) {
234 $defaultLanguageFlag = 'flags-' . $modSharedTSconfig['properties']['defaultLanguageFlag'];
235 } else {
236 $defaultLanguageFlag = 'empty-empty';
237 }
238 return $defaultLanguageFlag;
239 }
240
241 /**
242 * @param array $modSharedTSconfig
243 * @return string
244 */
245 protected function getDefaultLanguageLabel(array $modSharedTSconfig)
246 {
247 if (strlen($modSharedTSconfig['properties']['defaultLanguageLabel'])) {
248 $defaultLanguageLabel = $modSharedTSconfig['properties']['defaultLanguageLabel'] . ' (' . $this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_mod_web_list.xlf:defaultLanguage') . ')';
249 } else {
250 $defaultLanguageLabel = $this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_mod_web_list.xlf:defaultLanguage');
251 }
252 return $defaultLanguageLabel;
253 }
254 }