Passed
Push — master ( d39f54...dfcbf4 )
by
unknown
19:21 queued 05:02
created

getSystemLanguages()   B

Complexity

Conditions 6
Paths 7

Size

Total Lines 39
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 28
c 0
b 0
f 0
dl 0
loc 39
rs 8.8497
cc 6
nc 7
nop 1
1
<?php
2
3
/*
4
 * This file is part of the TYPO3 CMS project.
5
 *
6
 * It is free software; you can redistribute it and/or modify it under
7
 * the terms of the GNU General Public License, either version 2
8
 * of the License, or any later version.
9
 *
10
 * For the full copyright and license information, please read the
11
 * LICENSE.txt file that was distributed with this source code.
12
 *
13
 * The TYPO3 project - inspiring people to share!
14
 */
15
16
namespace TYPO3\CMS\Backend\Configuration;
17
18
use TYPO3\CMS\Backend\Utility\BackendUtility;
19
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
20
use TYPO3\CMS\Core\Database\ConnectionPool;
21
use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
22
use TYPO3\CMS\Core\Database\Query\Restriction\WorkspaceRestriction;
23
use TYPO3\CMS\Core\Exception\SiteNotFoundException;
24
use TYPO3\CMS\Core\Site\Entity\NullSite;
25
use TYPO3\CMS\Core\Site\Entity\SiteInterface;
26
use TYPO3\CMS\Core\Site\SiteFinder;
27
use TYPO3\CMS\Core\Utility\GeneralUtility;
28
29
/**
30
 * Contains translation tools
31
 *
32
 * @internal The whole class is subject to be removed, fetch all language info from the current site object.
33
 */
34
class TranslationConfigurationProvider
35
{
36
    protected array $systemLanguageCache = [];
37
38
    /**
39
     * Returns array of languages given for a specific site (or "nullSite" if on page=0)
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
        if (isset($this->systemLanguageCache[$pageId])) {
48
            return $this->systemLanguageCache[$pageId];
49
        }
50
        $allSystemLanguages = [];
51
        $siteFinder = GeneralUtility::makeInstance(SiteFinder::class);
52
        if ($pageId === 0) {
53
            // Used for e.g. filelist, where there is no site selected
54
            // This also means that there is no "-1" (All Languages) selectable.
55
            $sites = $siteFinder->getAllSites();
56
            foreach ($sites as $site) {
57
                $allSystemLanguages = $this->addSiteLanguagesToConsolidatedList(
58
                    $allSystemLanguages,
59
                    $site->getAvailableLanguages($this->getBackendUserAuthentication()),
60
                    $site,
61
                    true
62
                );
63
            }
64
        } else {
65
            try {
66
                $site = $siteFinder->getSiteByPageId((int)$pageId);
67
            } catch (SiteNotFoundException $e) {
68
                $site = new NullSite();
69
            }
70
            $siteLanguages = $site->getAvailableLanguages($this->getBackendUserAuthentication(), true);
71
            if (!isset($siteLanguages[0])) {
72
                $siteLanguages[0] = $site->getDefaultLanguage();
73
            }
74
            $allSystemLanguages = $this->addSiteLanguagesToConsolidatedList(
75
                $allSystemLanguages,
76
                $siteLanguages,
77
                $site,
78
                false
79
            );
80
        }
81
        ksort($allSystemLanguages);
82
        $this->systemLanguageCache[$pageId] = $allSystemLanguages;
83
        return $allSystemLanguages;
84
    }
85
86
    protected function addSiteLanguagesToConsolidatedList(array $allSystemLanguages, array $languagesOfSpecificSite, SiteInterface $site, bool $includeSiteSuffix): array
87
    {
88
        foreach ($languagesOfSpecificSite as $language) {
89
            $languageId = $language->getLanguageId();
90
            if (isset($allSystemLanguages[$languageId])) {
91
                // Language already provided by another site, just add the label separately
92
                $allSystemLanguages[$languageId]['title'] .= ', ' . $language->getTitle() . ' [Site: ' . $site->getIdentifier() . ']';
93
            } else {
94
                $allSystemLanguages[$languageId] = [
95
                    'uid' => $languageId,
96
                    'title' => $language->getTitle() . ($includeSiteSuffix ? ' [Site: ' . $site->getIdentifier() . ']' : ''),
97
                    'ISOcode' => $language->getTwoLetterIsoCode(),
98
                    'flagIcon' => $language->getFlagIdentifier(),
99
                ];
100
            }
101
        }
102
        return $allSystemLanguages;
103
    }
104
105
    /**
106
     * Information about translation for an element
107
     * Will overlay workspace version of record too!
108
     *
109
     * @param string $table Table name
110
     * @param int $uid Record uid
111
     * @param int $languageUid Language uid. If 0, then all languages are selected.
112
     * @param array $row The record to be translated
113
     * @param array|string $selFieldList Select fields for the query which fetches the translations of the current record
114
     * @return mixed Array with information or error message as a string.
115
     */
116
    public function translationInfo($table, $uid, $languageUid = 0, array $row = null, $selFieldList = '')
117
    {
118
        if (!$GLOBALS['TCA'][$table] || !$uid) {
119
            return 'No table "' . $table . '" or no UID value';
120
        }
121
        if ($row === null) {
122
            $row = BackendUtility::getRecordWSOL($table, $uid);
123
        }
124
        if (!is_array($row)) {
0 ignored issues
show
introduced by
The condition is_array($row) is always true.
Loading history...
125
            return 'Record "' . $table . '_' . $uid . '" was not found';
126
        }
127
        if (!BackendUtility::isTableLocalizable($table)) {
128
            return 'Translation is not supported for this table!';
129
        }
130
        if ($row[$GLOBALS['TCA'][$table]['ctrl']['languageField']] > 0) {
131
            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']] . '")';
132
        }
133
        if ($row[$GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField']] != 0) {
134
            return 'Record "' . $table . '_' . $uid . '" seems to be a translation already (has a relation to record "' . $row[$GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField']] . '")';
135
        }
136
        // Look for translations of this record, index by language field value:
137
        if (!empty($selFieldList)) {
138
            if (is_array($selFieldList)) {
139
                $selectFields = $selFieldList;
140
            } else {
141
                $selectFields = GeneralUtility::trimExplode(',', $selFieldList);
142
            }
143
        } else {
144
            $selectFields = ['uid', $GLOBALS['TCA'][$table]['ctrl']['languageField']];
145
        }
146
        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($table);
147
        $queryBuilder->getRestrictions()
148
            ->removeAll()
149
            ->add(GeneralUtility::makeInstance(DeletedRestriction::class))
150
            ->add(GeneralUtility::makeInstance(WorkspaceRestriction::class, $this->getBackendUserAuthentication()->workspace));
151
        $queryBuilder
152
            ->select(...$selectFields)
153
            ->from($table)
154
            ->where(
155
                $queryBuilder->expr()->eq(
156
                    $GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField'],
157
                    $queryBuilder->createNamedParameter($uid, \PDO::PARAM_INT)
158
                ),
159
                $queryBuilder->expr()->eq(
160
                    'pid',
161
                    $queryBuilder->createNamedParameter(
162
                        $row['pid'],
163
                        \PDO::PARAM_INT
164
                    )
165
                )
166
            );
167
        if (!$languageUid) {
168
            $queryBuilder->andWhere(
169
                $queryBuilder->expr()->gt(
170
                    $GLOBALS['TCA'][$table]['ctrl']['languageField'],
171
                    $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT)
172
                )
173
            );
174
        } else {
175
            $queryBuilder
176
                ->andWhere(
177
                    $queryBuilder->expr()->eq(
178
                        $GLOBALS['TCA'][$table]['ctrl']['languageField'],
179
                        $queryBuilder->createNamedParameter($languageUid, \PDO::PARAM_INT)
180
                    )
181
                );
182
        }
183
        $translationRecords = $queryBuilder
184
            ->execute()
185
            ->fetchAll();
186
187
        $translations = [];
188
        $translationsErrors = [];
189
        foreach ($translationRecords as $translationRecord) {
190
            if (!isset($translations[$translationRecord[$GLOBALS['TCA'][$table]['ctrl']['languageField']]])) {
191
                $translations[$translationRecord[$GLOBALS['TCA'][$table]['ctrl']['languageField']]] = $translationRecord;
192
            } else {
193
                $translationsErrors[$translationRecord[$GLOBALS['TCA'][$table]['ctrl']['languageField']]][] = $translationRecord;
194
            }
195
        }
196
        return [
197
            'table' => $table,
198
            'uid' => $uid,
199
            'CType' => $row['CType'] ?? '',
200
            'sys_language_uid' => $row[$GLOBALS['TCA'][$table]['ctrl']['languageField'] ?? null] ?? null,
201
            'translations' => $translations,
202
            'excessive_translations' => $translationsErrors
203
        ];
204
    }
205
206
    protected function getBackendUserAuthentication(): BackendUserAuthentication
207
    {
208
        return $GLOBALS['BE_USER'];
209
    }
210
}
211