Commit 62365d3f authored by Georg Ringer's avatar Georg Ringer Committed by Benni Mack
Browse files

[FEATURE] Show only sys_languages in Backend which are available

Instead of rendering all languages, only the ones provided by the
site module are now shown in forms of the FormEngine, in the List
module, the Info->Translation Overview and the Page module.

Fallbacks to pseudo sites are considered if no site configuration
for a page / page tree exists.

Resolves: #85164
Releases: master
Change-Id: I95b394cd3a31773e62f7e2cc40197aceb97705d8
Reviewed-on: https://review.typo3.org/57672


Reviewed-by: Christian Kuhn's avatarChristian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn's avatarChristian Kuhn <lolli@schwarzbu.ch>
Tested-by: default avatarTYPO3com <no-reply@typo3.com>
Reviewed-by: Benni Mack's avatarBenni Mack <benni@typo3.org>
Tested-by: Benni Mack's avatarBenni Mack <benni@typo3.org>
parent 58892e77
...@@ -34,15 +34,18 @@ use TYPO3\CMS\Core\Database\ConnectionPool; ...@@ -34,15 +34,18 @@ use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Database\Query\QueryBuilder; use TYPO3\CMS\Core\Database\Query\QueryBuilder;
use TYPO3\CMS\Core\Database\Query\Restriction\BackendWorkspaceRestriction; use TYPO3\CMS\Core\Database\Query\Restriction\BackendWorkspaceRestriction;
use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction; use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
use TYPO3\CMS\Core\Database\Query\Restriction\HiddenRestriction;
use TYPO3\CMS\Core\Database\ReferenceIndex; use TYPO3\CMS\Core\Database\ReferenceIndex;
use TYPO3\CMS\Core\DataHandling\DataHandler; use TYPO3\CMS\Core\DataHandling\DataHandler;
use TYPO3\CMS\Core\Exception\SiteNotFoundException;
use TYPO3\CMS\Core\Http\HtmlResponse; use TYPO3\CMS\Core\Http\HtmlResponse;
use TYPO3\CMS\Core\Http\RedirectResponse; use TYPO3\CMS\Core\Http\RedirectResponse;
use TYPO3\CMS\Core\Imaging\Icon; use TYPO3\CMS\Core\Imaging\Icon;
use TYPO3\CMS\Core\Messaging\FlashMessage; use TYPO3\CMS\Core\Messaging\FlashMessage;
use TYPO3\CMS\Core\Messaging\FlashMessageService; use TYPO3\CMS\Core\Messaging\FlashMessageService;
use TYPO3\CMS\Core\Page\PageRenderer; use TYPO3\CMS\Core\Page\PageRenderer;
use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
use TYPO3\CMS\Core\Site\PseudoSiteFinder;
use TYPO3\CMS\Core\Site\SiteFinder;
use TYPO3\CMS\Core\Type\Bitmask\Permission; use TYPO3\CMS\Core\Type\Bitmask\Permission;
use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\HttpUtility; use TYPO3\CMS\Core\Utility\HttpUtility;
...@@ -2219,15 +2222,15 @@ class EditDocumentController ...@@ -2219,15 +2222,15 @@ class EditDocumentController
if ($table === 'pages') { if ($table === 'pages') {
$row = BackendUtility::getRecord($table, $uid, $GLOBALS['TCA']['pages']['ctrl']['transOrigPointerField']); $row = BackendUtility::getRecord($table, $uid, $GLOBALS['TCA']['pages']['ctrl']['transOrigPointerField']);
// Ensure the check is always done against the default language page // Ensure the check is always done against the default language page
$langRows = $this->getLanguages( $availableLanguages = $this->getLanguages(
(int)$row[$GLOBALS['TCA']['pages']['ctrl']['transOrigPointerField']] ?: $uid, (int)$row[$GLOBALS['TCA']['pages']['ctrl']['transOrigPointerField']] ?: $uid,
$table $table
); );
} else { } else {
$langRows = $this->getLanguages((int)$pid, $table); $availableLanguages = $this->getLanguages((int)$pid, $table);
} }
// Page available in other languages than default language? // Page available in other languages than default language?
if (is_array($langRows) && count($langRows) > 1) { if (count($availableLanguages) > 1) {
$rowsByLang = []; $rowsByLang = [];
$fetchFields = 'uid,' . $languageField . ',' . $transOrigPointerField; $fetchFields = 'uid,' . $languageField . ',' . $transOrigPointerField;
// Get record in current language // Get record in current language
...@@ -2290,41 +2293,42 @@ class EditDocumentController ...@@ -2290,41 +2293,42 @@ class EditDocumentController
} }
$languageMenu = $this->moduleTemplate->getDocHeaderComponent()->getMenuRegistry()->makeMenu(); $languageMenu = $this->moduleTemplate->getDocHeaderComponent()->getMenuRegistry()->makeMenu();
$languageMenu->setIdentifier('_langSelector'); $languageMenu->setIdentifier('_langSelector');
foreach ($langRows as $lang) { foreach ($availableLanguages as $language) {
if ($this->getBackendUser()->checkLanguageAccess($lang['uid'])) { $languageId = $language->getLanguageId();
$newTranslation = isset($rowsByLang[$lang['uid']]) ? '' : ' [' . htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.new')) . ']'; $selectorOptionLabel = $language->getTitle();
// Create url for creating a localized record // Create url for creating a localized record
$addOption = true; $addOption = true;
$href = ''; $href = '';
if ($newTranslation) { if (!isset($rowsByLang[$languageId])) {
$redirectUrl = (string)$uriBuilder->buildUriFromRoute('record_edit', [ // Translation in this language does not exist
'justLocalized' => $table . ':' . $rowsByLang[0]['uid'] . ':' . $lang['uid'], $selectorOptionLabel .= ' [' . htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.new')) . ']';
'returnUrl' => $this->retUrl $redirectUrl = (string)$uriBuilder->buildUriFromRoute('record_edit', [
]); 'justLocalized' => $table . ':' . $rowsByLang[0]['uid'] . ':' . $languageId,
'returnUrl' => $this->retUrl
if (array_key_exists(0, $rowsByLang)) { ]);
$href = BackendUtility::getLinkToDataHandlerAction(
'&cmd[' . $table . '][' . $rowsByLang[0]['uid'] . '][localize]=' . $lang['uid'], if (array_key_exists(0, $rowsByLang)) {
$redirectUrl $href = BackendUtility::getLinkToDataHandlerAction(
); '&cmd[' . $table . '][' . $rowsByLang[0]['uid'] . '][localize]=' . $languageId,
} else { $redirectUrl
$addOption = false; );
}
} else { } else {
$href = (string)$uriBuilder->buildUriFromRoute('record_edit', [ $addOption = false;
'edit[' . $table . '][' . $rowsByLang[$lang['uid']]['uid'] . ']' => 'edit',
'returnUrl' => $this->retUrl
]);
} }
if ($addOption) { } else {
$menuItem = $languageMenu->makeMenuItem() $href = (string)$uriBuilder->buildUriFromRoute('record_edit', [
->setTitle($lang['title'] . $newTranslation) 'edit[' . $table . '][' . $rowsByLang[$languageId]['uid'] . ']' => 'edit',
->setHref($href); 'returnUrl' => $this->retUrl
if ((int)$lang['uid'] === $currentLanguage) { ]);
$menuItem->setActive(true); }
} if ($addOption) {
$languageMenu->addMenuItem($menuItem); $menuItem = $languageMenu->makeMenuItem()
->setTitle($selectorOptionLabel)
->setHref($href);
if ($languageId === $currentLanguage) {
$menuItem->setActive(true);
} }
$languageMenu->addMenuItem($menuItem);
} }
} }
$this->moduleTemplate->getDocHeaderComponent()->getMenuRegistry()->addMenu($languageMenu); $this->moduleTemplate->getDocHeaderComponent()->getMenuRegistry()->addMenu($languageMenu);
...@@ -2414,88 +2418,51 @@ class EditDocumentController ...@@ -2414,88 +2418,51 @@ class EditDocumentController
} }
/** /**
* Returns sys_language records available for record translations on given page. * Returns languages available for record translations on given page.
* *
* @param int $id Page id: If zero, the query will select all sys_language records from root level which are NOT * @param int $id Page id: If zero, the query will select all sys_language records from root level which are NOT
* hidden. If set to another value, the query will select all sys_language records that has a * hidden. If set to another value, the query will select all sys_language records that has a
* translation record on that page (and is not hidden, unless you are admin user) * translation record on that page (and is not hidden, unless you are admin user)
* @param string $table For pages we want all languages, for other records the languages of the page translations * @param string $table For pages we want all languages, for other records the languages of the page translations
* @return array Language records including faked record for default language * @return SiteLanguage[] Language
*/ */
protected function getLanguages(int $id, string $table = ''): array protected function getLanguages(int $id, string $table): array
{ {
$languageService = $this->getLanguageService(); try {
$modPageTsConfig = BackendUtility::getPagesTSconfig($id)['mod.']['SHARED.'] ?? []; $site = GeneralUtility::makeInstance(SiteFinder::class)->getSiteByPageId($id);
// Fallback non sprite-configuration } catch (SiteNotFoundException $e) {
if (preg_match('/\\.gif$/', $modPageTsConfig['defaultLanguageFlag'] ?? '')) { // Check for a pseudo site
$modPageTsConfig['defaultLanguageFlag'] = str_replace( $site = GeneralUtility::makeInstance(PseudoSiteFinder::class)->getSiteByPageId($id);
'.gif', }
'',
$modPageTsConfig['defaultLanguageFlag'] // Fetch the current translations of this page, to only show the ones where there is a page translation
); $allLanguages = $site->getAvailableLanguages($this->getBackendUser(), false, $id);
} if ($table !== 'pages' && $id > 0) {
$languages = [ $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('pages');
0 => [ $queryBuilder->getRestrictions()->removeAll()
'uid' => 0,
'pid' => 0,
'hidden' => 0,
'title' => $modPageTsConfig['defaultLanguageLabel'] !== ''
? $modPageTsConfig['defaultLanguageLabel'] . ' (' . $languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_mod_web_list.xlf:defaultLanguage') . ')'
: $languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_mod_web_list.xlf:defaultLanguage'),
'flag' => $modPageTsConfig['defaultLanguageFlag']
]
];
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable('sys_language');
$queryBuilder->select('s.uid', 's.pid', 's.hidden', 's.title', 's.flag')
->from('sys_language', 's')
->groupBy('s.uid', 's.pid', 's.hidden', 's.title', 's.flag', 's.sorting')
->orderBy('s.sorting');
if ($id) {
$queryBuilder->getRestrictions()
->removeAll()
->add(GeneralUtility::makeInstance(DeletedRestriction::class)) ->add(GeneralUtility::makeInstance(DeletedRestriction::class))
->add(GeneralUtility::makeInstance(BackendWorkspaceRestriction::class)); ->add(GeneralUtility::makeInstance(BackendWorkspaceRestriction::class));
$statement = $queryBuilder->select('uid', $GLOBALS['TCA']['pages']['ctrl']['languageField'])
if (!$this->getBackendUser()->isAdmin()) { ->from('pages')
$queryBuilder->getRestrictions()->add(GeneralUtility::makeInstance(HiddenRestriction::class)); ->where(
$queryBuilder->expr()->eq(
$GLOBALS['TCA']['pages']['ctrl']['transOrigPointerField'],
$queryBuilder->createNamedParameter($id, \PDO::PARAM_INT)
)
)
->execute();
$availableLanguages = [
0 => $allLanguages[0]
];
while ($row = $statement->fetch()) {
$languageId = (int)$row[$GLOBALS['TCA']['pages']['ctrl']['languageField']];
if (isset($allLanguages[$languageId])) {
$availableLanguages[$languageId] = $allLanguages[$languageId];
}
} }
return $availableLanguages;
$this->joinPagesTranslationsForActiveLanguage($queryBuilder, $table, $id);
}
$result = $queryBuilder->execute();
while ($row = $result->fetch()) {
$languages[$row['uid']] = $row;
}
return $languages;
}
/**
* @param QueryBuilder $queryBuilder
* @param string $table
* @param int $id
*/
public function joinPagesTranslationsForActiveLanguage(QueryBuilder $queryBuilder, string $table, int $id)
{
// Add join with pages translations to only show active languages
if ($table !== 'pages') {
$queryBuilder->from('pages', 'o')
->where(
$queryBuilder->expr()->eq(
'o.' . $GLOBALS['TCA']['pages']['ctrl']['languageField'],
$queryBuilder->quoteIdentifier('s.uid')
),
$queryBuilder->expr()->eq(
'o.' . $GLOBALS['TCA']['pages']['ctrl']['transOrigPointerField'],
$queryBuilder->createNamedParameter($id, \PDO::PARAM_INT)
)
);
} }
return $allLanguages;
} }
/** /**
......
...@@ -31,13 +31,13 @@ use TYPO3\CMS\Core\Database\ConnectionPool; ...@@ -31,13 +31,13 @@ use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Database\Query\QueryBuilder; use TYPO3\CMS\Core\Database\Query\QueryBuilder;
use TYPO3\CMS\Core\Database\Query\Restriction\BackendWorkspaceRestriction; use TYPO3\CMS\Core\Database\Query\Restriction\BackendWorkspaceRestriction;
use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction; use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
use TYPO3\CMS\Core\Database\Query\Restriction\HiddenRestriction;
use TYPO3\CMS\Core\DataHandling\DataHandler; use TYPO3\CMS\Core\DataHandling\DataHandler;
use TYPO3\CMS\Core\Http\HtmlResponse; use TYPO3\CMS\Core\Http\HtmlResponse;
use TYPO3\CMS\Core\Imaging\Icon; use TYPO3\CMS\Core\Imaging\Icon;
use TYPO3\CMS\Core\Imaging\IconFactory; use TYPO3\CMS\Core\Imaging\IconFactory;
use TYPO3\CMS\Core\Localization\LanguageService; use TYPO3\CMS\Core\Localization\LanguageService;
use TYPO3\CMS\Core\Page\PageRenderer; use TYPO3\CMS\Core\Page\PageRenderer;
use TYPO3\CMS\Core\Site\Entity\SiteInterface;
use TYPO3\CMS\Core\Type\Bitmask\Permission; use TYPO3\CMS\Core\Type\Bitmask\Permission;
use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\MathUtility; use TYPO3\CMS\Core\Utility\MathUtility;
...@@ -374,6 +374,10 @@ class PageLayoutController ...@@ -374,6 +374,10 @@ class PageLayoutController
$parsedBody = $request->getParsedBody(); $parsedBody = $request->getParsedBody();
$queryParams = $request->getQueryParams(); $queryParams = $request->getQueryParams();
/** @var SiteInterface $currentSite */
$currentSite = $request->getAttribute('site');
$availableLanguages = $currentSite->getAvailableLanguages($this->getBackendUser(), false, $this->id);
$lang = $this->getLanguageService(); $lang = $this->getLanguageService();
// MENU-ITEMS: // MENU-ITEMS:
$this->MOD_MENU = [ $this->MOD_MENU = [
...@@ -391,83 +395,35 @@ class PageLayoutController ...@@ -391,83 +395,35 @@ class PageLayoutController
$this->modSharedTSconfig['properties'] = $pageTsConfig['mod.']['SHARED.'] ?? []; $this->modSharedTSconfig['properties'] = $pageTsConfig['mod.']['SHARED.'] ?? [];
$this->modTSconfig['properties'] = $pageTsConfig['mod.']['web_layout.'] ?? []; $this->modTSconfig['properties'] = $pageTsConfig['mod.']['web_layout.'] ?? [];
// First, select all localized page records on the current page. Each represents a possibility for a language on the page. Add these to language selector. // First, select all localized page records on the current page.
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_language'); // Each represents a possibility for a language on the page. Add these to language selector.
$queryBuilder->getRestrictions()->removeAll();
if ($this->id) { if ($this->id) {
$queryBuilder->select('sys_language.uid AS uid', 'sys_language.title AS title') // Compile language data for pid != 0 only. The language drop-down is not shown on pid 0
->from('sys_language') // since pid 0 can't be localized.
->join( $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('pages');
'sys_language', $queryBuilder->getRestrictions()->removeAll()
'pages', ->add(GeneralUtility::makeInstance(DeletedRestriction::class))
'pages', ->add(GeneralUtility::makeInstance(BackendWorkspaceRestriction::class));
$queryBuilder->expr()->eq( $statement = $queryBuilder->select('uid', $GLOBALS['TCA']['pages']['ctrl']['languageField'])
'sys_language.uid', ->from('pages')
$queryBuilder->quoteIdentifier('pages.' . $GLOBALS['TCA']['pages']['ctrl']['languageField'])
)
)
->where( ->where(
$queryBuilder->expr()->eq( $queryBuilder->expr()->eq(
'pages.deleted', $GLOBALS['TCA']['pages']['ctrl']['transOrigPointerField'],
$queryBuilder->createNamedParameter(0, \PDO::PARAM_INT)
),
$queryBuilder->expr()->eq(
'pages.' . $GLOBALS['TCA']['pages']['ctrl']['transOrigPointerField'],
$queryBuilder->createNamedParameter($this->id, \PDO::PARAM_INT) $queryBuilder->createNamedParameter($this->id, \PDO::PARAM_INT)
),
$queryBuilder->expr()->orX(
$queryBuilder->expr()->gte(
'pages.t3ver_state',
$queryBuilder->createNamedParameter(
(string)new VersionState(VersionState::DEFAULT_STATE),
\PDO::PARAM_INT
)
),
$queryBuilder->expr()->eq(
'pages.t3ver_wsid',
$queryBuilder->createNamedParameter($this->getBackendUser()->workspace, \PDO::PARAM_INT)
)
)
)
->groupBy(
'pages.' . $GLOBALS['TCA']['pages']['ctrl']['languageField'],
'sys_language.uid',
'sys_language.pid',
'sys_language.tstamp',
'sys_language.hidden',
'sys_language.title',
'sys_language.language_isocode',
'sys_language.static_lang_isocode',
'sys_language.flag',
'sys_language.sorting'
)
->orderBy('sys_language.sorting');
if (!$this->getBackendUser()->isAdmin()) {
$queryBuilder->andWhere(
$queryBuilder->expr()->eq(
'sys_language.hidden',
$queryBuilder->createNamedParameter(0, \PDO::PARAM_INT)
) )
); )->execute();
while ($pageTranslation = $statement->fetch()) {
$languageId = $pageTranslation[$GLOBALS['TCA']['pages']['ctrl']['languageField']];
if (isset($availableLanguages[$languageId])) {
$this->MOD_MENU['language'][$languageId] = $availableLanguages[$languageId]->getTitle();
}
} }
$statement = $queryBuilder->execute(); // Override the label
} else { if (isset($availableLanguages[0])) {
$queryBuilder->getRestrictions()->add(GeneralUtility::makeInstance(HiddenRestriction::class)); $this->MOD_MENU['language'][0] = $availableLanguages[0]->getTitle();
$statement = $queryBuilder->select('uid', 'title')
->from('sys_language')
->orderBy('sorting')
->execute();
}
while ($lRow = $statement->fetch()) {
if ($this->getBackendUser()->checkLanguageAccess($lRow['uid'])) {
$this->MOD_MENU['language'][$lRow['uid']] = $lRow['title'];
} }
} }
// Setting alternative default label: // Initialize the available actions
if ((!empty($this->modSharedTSconfig['properties']['defaultLanguageLabel']) || !empty($this->modTSconfig['properties']['defaultLanguageLabel'])) && isset($this->MOD_MENU['language'][0])) {
$this->MOD_MENU['language'][0] = $this->modTSconfig['properties']['defaultLanguageLabel'] ? $this->modTSconfig['properties']['defaultLanguageLabel'] : $this->modSharedTSconfig['properties']['defaultLanguageLabel'];
}
// Initialize the avaiable actions
$actions = $this->initActions(); $actions = $this->initActions();
// Clean up settings // Clean up settings
$this->MOD_SETTINGS = BackendUtility::getModuleData($this->MOD_MENU, $parsedBody['SET'] ?? $queryParams['SET'] ?? [], $this->moduleName); $this->MOD_SETTINGS = BackendUtility::getModuleData($this->MOD_MENU, $parsedBody['SET'] ?? $queryParams['SET'] ?? [], $this->moduleName);
......
...@@ -15,10 +15,13 @@ namespace TYPO3\CMS\Backend\Form\FormDataProvider; ...@@ -15,10 +15,13 @@ namespace TYPO3\CMS\Backend\Form\FormDataProvider;
*/ */
use TYPO3\CMS\Backend\Form\FormDataProviderInterface; use TYPO3\CMS\Backend\Form\FormDataProviderInterface;
use TYPO3\CMS\Core\Database\ConnectionPool; use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
use TYPO3\CMS\Core\Exception\SiteNotFoundException;
use TYPO3\CMS\Core\Localization\LanguageService; use TYPO3\CMS\Core\Localization\LanguageService;
use TYPO3\CMS\Core\Messaging\FlashMessage; use TYPO3\CMS\Core\Messaging\FlashMessage;
use TYPO3\CMS\Core\Messaging\FlashMessageService; use TYPO3\CMS\Core\Messaging\FlashMessageService;
use TYPO3\CMS\Core\Site\PseudoSiteFinder;
use TYPO3\CMS\Core\Site\SiteFinder;
use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\GeneralUtility;
/** /**
...@@ -35,61 +38,31 @@ class DatabaseSystemLanguageRows implements FormDataProviderInterface ...@@ -35,61 +38,31 @@ class DatabaseSystemLanguageRows implements FormDataProviderInterface
*/ */
public function addData(array $result) public function addData(array $result)
{ {
$languageService = $this->getLanguageService(); $pageIdDefaultLanguage = $result['defaultLanguagePageRow']['uid'] ?? $result['effectivePid'];
try {
$pageTs = $result['pageTsConfig']; $site = GeneralUtility::makeInstance(SiteFinder::class)->getSiteByPageId($pageIdDefaultLanguage);
$defaultLanguageLabel = $languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_mod_web_list.xlf:defaultLanguage'); } catch (SiteNotFoundException $e) {
if (isset($pageTs['mod.']['SHARED.']['defaultLanguageLabel'])) { // Check for a pseudo site
$defaultLanguageLabel = $pageTs['mod.']['SHARED.']['defaultLanguageLabel'] . ' (' . $languageService->sL($defaultLanguageLabel) . ')'; $site = GeneralUtility::makeInstance(PseudoSiteFinder::class)->getSiteByPageId($pageIdDefaultLanguage);
}
$defaultLanguageFlag = 'empty-empty';
if (isset($pageTs['mod.']['SHARED.']['defaultLanguageFlag'])) {
$defaultLanguageFlag = 'flags-' . $pageTs['mod.']['SHARED.']['defaultLanguageFlag'];
} }
$languages = $site->getAvailableLanguages($this->getBackendUser(), true, $pageIdDefaultLanguage);
$languageRows = [ $languageRows = [];
-1 => [ foreach ($languages as $language) {
// -1: "All" languages $languageId = $language->getLanguageId();
'uid' => -1, if ($languageId > 0) {
'title' => $languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_mod_web_list.xlf:multipleLanguages'), $iso = $language->getTwoLetterIsoCode();
// Same as for 0, but iso is used in flex form context only and duplication handled there
// @todo: Maybe drop this if flex form language handling is extracted?
'iso' => 'DEF',
'flagIconIdentifier' => 'flags-multiple',
],
0 => [
// 0: "Default" language
'uid' => 0,
'title' => $defaultLanguageLabel,
// Default "DEF" is a fallback preparation for flex form iso codes "lDEF"
// @todo: Maybe drop this if flex form language handling is extracted?
'iso' => 'DEF',
'flagIconIdentifier' => $defaultLanguageFlag,
],
];
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable('sys_language');
$queryBuilder->getRestrictions()->removeAll();
$queryResult = $queryBuilder
->select('uid', 'title', 'language_isocode', 'flag')
->from('sys_language')
->where($queryBuilder->expr()->eq('pid', $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT)))
->orderBy('sorting')
->execute();
while ($row = $queryResult->fetch()) {
$uid = $row['uid'];
$languageRows[$uid] = [
'uid' => $uid,
'title' => $row['title'],
'flagIconIdentifier' => 'flags-' . $row['flag'],
];
if (!empty($row['language_isocode'])) {
$languageRows[$uid]['iso'] = $row['language_isocode'];
} else { } else {
$iso = 'DEF';
}
$languageRows[$languageId] = [
'uid' => $languageId,
'title' => $language->getTitle(),
'iso' => $iso,
'flagIconIdentifier' => $language->getFlagIdentifier()
];
if (empty($iso)) {
// No iso code could be found. This is currently possible in the system but discouraged. // No iso code could be found. This is currently possible in the system but discouraged.
// So, code within FormEngine has to be suited to work with an empty iso code. However, // So, code within FormEngine has to be suited to work with an empty iso code. However,
// it may impact certain multi language scenarios, so we add a flash message hinting for // it may impact certain multi language scenarios, so we add a flash message hinting for
...@@ -99,35 +72,40 @@ class DatabaseSystemLanguageRows implements FormDataProviderInterface ...@@ -99,35 +72,40 @@ class DatabaseSystemLanguageRows implements FormDataProviderInterface
// @todo: This could be relaxed again if flex form language handling is extracted, // @todo: This could be relaxed again if flex form language handling is extracted,
// @todo: since the rest of the FormEngine code does not rely on iso code? // @todo: since the rest of the FormEngine code does not rely on iso code?
$message = sprintf( $message = sprintf(
$languageService->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:error.missingLanguageIsocode'), $this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:error.missingLanguageIsocode'),
$row['title'], $language->getTwoLetterIsoCode(),
$uid $languageId
); );
/** @var FlashMessage $flashMessage */ /** @var FlashMessage $flashMessage */
$flashMessage = GeneralUtility::makeInstance( $flashMessage = GeneralUtility::makeInstance(
FlashMessage::class, FlashMessage::class,
$message, $message,
'', '',
FlashMessage::ERROR FlashMessage::ERROR
); );
/** @var $flashMessageService FlashMessageService */ /** @var $flashMessageService FlashMessageService */
$flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class); $flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class);
$defaultFlashMessageQueue = $flashMessageService->getMessageQueueByIdentifier