TranslationConfigurationProvider.php 8.95 KB
Newer Older
1
<?php
2

3
/*
4
 * This file is part of the TYPO3 CMS project.
5
 *
6
7
8
 * It is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License, either version 2
 * of the License, or any later version.
9
 *
10
11
 * For the full copyright and license information, please read the
 * LICENSE.txt file that was distributed with this source code.
12
 *
13
14
 * The TYPO3 project - inspiring people to share!
 */
Nicole Cordes's avatar
Nicole Cordes committed
15

16
17
namespace TYPO3\CMS\Backend\Configuration;

Nicole Cordes's avatar
Nicole Cordes committed
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
24
use TYPO3\CMS\Core\Exception\SiteNotFoundException;
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;
Nicole Cordes's avatar
Nicole Cordes committed
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
35
class TranslationConfigurationProvider
{
36
37
    protected array $systemLanguageCache = [];

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
43
44
45
46
     *
     * @param int $pageId Page id (used to get TSconfig configuration setting flag and label for default language)
     * @return array Array with languages (uid, title, ISOcode, flagIcon)
     */
    public function getSystemLanguages($pageId = 0)
    {
47
48
49
        if (isset($this->systemLanguageCache[$pageId])) {
            return $this->systemLanguageCache[$pageId];
        }
50
51
52
53
54
55
56
57
58
59
        $allSystemLanguages = [];
        $siteFinder = GeneralUtility::makeInstance(SiteFinder::class);
        if ($pageId === 0) {
            // Used for e.g. filelist, where there is no site selected
            // This also means that there is no "-1" (All Languages) selectable.
            $sites = $siteFinder->getAllSites();
            foreach ($sites as $site) {
                $allSystemLanguages = $this->addSiteLanguagesToConsolidatedList(
                    $allSystemLanguages,
                    $site->getAvailableLanguages($this->getBackendUserAuthentication()),
60
61
                    $site,
                    true
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
                );
            }
        } else {
            try {
                $site = $siteFinder->getSiteByPageId((int)$pageId);
            } catch (SiteNotFoundException $e) {
                $site = new NullSite();
            }
            $siteLanguages = $site->getAvailableLanguages($this->getBackendUserAuthentication(), true);
            if (!isset($siteLanguages[0])) {
                $siteLanguages[0] = $site->getDefaultLanguage();
            }
            $allSystemLanguages = $this->addSiteLanguagesToConsolidatedList(
                $allSystemLanguages,
                $siteLanguages,
77
78
                $site,
                false
79
            );
80
        }
81
        ksort($allSystemLanguages);
82
        $this->systemLanguageCache[$pageId] = $allSystemLanguages;
83
84
        return $allSystemLanguages;
    }
85

86
    protected function addSiteLanguagesToConsolidatedList(array $allSystemLanguages, array $languagesOfSpecificSite, SiteInterface $site, bool $includeSiteSuffix): array
87
88
89
90
91
92
93
94
95
    {
        foreach ($languagesOfSpecificSite as $language) {
            $languageId = $language->getLanguageId();
            if (isset($allSystemLanguages[$languageId])) {
                // Language already provided by another site, just add the label separately
                $allSystemLanguages[$languageId]['title'] .= ', ' . $language->getTitle() . ' [Site: ' . $site->getIdentifier() . ']';
            } else {
                $allSystemLanguages[$languageId] = [
                    'uid' => $languageId,
96
                    'title' => $language->getTitle() . ($includeSiteSuffix ? ' [Site: ' . $site->getIdentifier() . ']' : ''),
97
98
99
100
                    'ISOcode' => $language->getTwoLetterIsoCode(),
                    'flagIcon' => $language->getFlagIdentifier(),
                ];
            }
101
        }
102
        return $allSystemLanguages;
103
    }
104

105
106
107
108
109
110
111
112
    /**
     * Information about translation for an element
     * Will overlay workspace version of record too!
     *
     * @param string $table Table name
     * @param int $uid Record uid
     * @param int $languageUid Language uid. If 0, then all languages are selected.
     * @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
115
116
117
118
119
120
121
122
123
124
125
126
     * @return mixed Array with information or error message as a string.
     */
    public function translationInfo($table, $uid, $languageUid = 0, array $row = null, $selFieldList = '')
    {
        if (!$GLOBALS['TCA'][$table] || !$uid) {
            return 'No table "' . $table . '" or no UID value';
        }
        if ($row === null) {
            $row = BackendUtility::getRecordWSOL($table, $uid);
        }
        if (!is_array($row)) {
            return 'Record "' . $table . '_' . $uid . '" was not found';
        }
127
        if (!BackendUtility::isTableLocalizable($table)) {
128
129
            return 'Translation is not supported for this table!';
        }
130
        if ($row[$GLOBALS['TCA'][$table]['ctrl']['languageField']] > 0) {
131
132
            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']] . '")';
        }
133
        if ($row[$GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField']] != 0) {
134
135
136
            return 'Record "' . $table . '_' . $uid . '" seems to be a translation already (has a relation to record "' . $row[$GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField']] . '")';
        }
        // Look for translations of this record, index by language field value:
137
138
139
140
141
142
143
144
        if (!empty($selFieldList)) {
            if (is_array($selFieldList)) {
                $selectFields = $selFieldList;
            } else {
                $selectFields = GeneralUtility::trimExplode(',', $selFieldList);
            }
        } else {
            $selectFields = ['uid', $GLOBALS['TCA'][$table]['ctrl']['languageField']];
145
        }
146
        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($table);
147
148
149
        $queryBuilder->getRestrictions()
            ->removeAll()
            ->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
158
159
160
161
                    $queryBuilder->createNamedParameter($uid, \PDO::PARAM_INT)
                ),
                $queryBuilder->expr()->eq(
                    'pid',
                    $queryBuilder->createNamedParameter(
162
                        $row['pid'],
163
164
165
                        \PDO::PARAM_INT
                    )
                )
166
            );
167
        if (!$languageUid) {
168
169
            $queryBuilder->andWhere(
                $queryBuilder->expr()->gt(
170
                    $GLOBALS['TCA'][$table]['ctrl']['languageField'],
171
172
173
                    $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT)
                )
            );
174
        } else {
175
176
177
            $queryBuilder
                ->andWhere(
                    $queryBuilder->expr()->eq(
178
                        $GLOBALS['TCA'][$table]['ctrl']['languageField'],
179
180
181
                        $queryBuilder->createNamedParameter($languageUid, \PDO::PARAM_INT)
                    )
                );
182
183
184
        }
        $translationRecords = $queryBuilder
            ->execute()
185
            ->fetchAllAssociative();
186

187
188
        $translations = [];
        $translationsErrors = [];
189
        foreach ($translationRecords as $translationRecord) {
190
191
            if (!isset($translations[$translationRecord[$GLOBALS['TCA'][$table]['ctrl']['languageField']]])) {
                $translations[$translationRecord[$GLOBALS['TCA'][$table]['ctrl']['languageField']]] = $translationRecord;
192
            } else {
193
                $translationsErrors[$translationRecord[$GLOBALS['TCA'][$table]['ctrl']['languageField']]][] = $translationRecord;
194
195
            }
        }
196
        return [
197
198
            'table' => $table,
            'uid' => $uid,
199
200
            'CType' => $row['CType'] ?? '',
            'sys_language_uid' => $row[$GLOBALS['TCA'][$table]['ctrl']['languageField'] ?? null] ?? null,
201
202
            'translations' => $translations,
            'excessive_translations' => $translationsErrors
203
        ];
204
    }
205

206
207
208
209
    protected function getBackendUserAuthentication(): BackendUserAuthentication
    {
        return $GLOBALS['BE_USER'];
    }
210
}