From 01465531745c930797664f14549ab917b51bd8e5 Mon Sep 17 00:00:00 2001
From: Nicole Cordes <typo3@cordes.co>
Date: Wed, 22 Nov 2017 12:28:37 +0100
Subject: [PATCH] [BUGFIX] Fix language of placeholder for relations

When a parent record (e.g. tt_content) has inline relations
(e.g. sys_file_reference)and these relations show a placeholder
for records related to them (e.g. sys_file and sys_file_metadata)
then we need to pass the context of the language so that
the placeholders are shown in the correct language.

We now do so by putting the value of the language field
of the parent record into the data set and update it
in case child records are also translatable.

This way when going down the list of children, we always
know the language id of the last applicable parent element,
even if one element in between was not translatable (e.g. sys_file)

If we know the language, we can pick the correct record uid
out of the list of possible related uids, instead of
just picking the first one.

Furthermore the language field for sys_file_metadata is removed from
editor form as the language is set by GET parameter already.

Change-Id: I64c97c8080196599e85b95e09e7eb89701670fa4
Resolves: #75040
Releases: master, 8.7
Reviewed-on: https://review.typo3.org/54831
Reviewed-by: Nicole Cordes <typo3@cordes.co>
Tested-by: Nicole Cordes <typo3@cordes.co>
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Andreas Wolf <andreas.wolf@typo3.org>
Tested-by: Andreas Wolf <andreas.wolf@typo3.org>
---
 .../FormDataProvider/TcaInputPlaceholders.php | 60 +++++++++++++++++++
 .../Configuration/TCA/sys_file_metadata.php   |  9 +--
 .../Tca/FileMetadataVisibleFieldsTest.php     |  5 --
 3 files changed, 65 insertions(+), 9 deletions(-)

diff --git a/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaInputPlaceholders.php b/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaInputPlaceholders.php
index b3e932e95f69..2e75a5df62d5 100644
--- a/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaInputPlaceholders.php
+++ b/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaInputPlaceholders.php
@@ -14,9 +14,11 @@ namespace TYPO3\CMS\Backend\Form\FormDataProvider;
  * The TYPO3 project - inspiring people to share!
  */
 
+use Doctrine\DBAL\Connection;
 use TYPO3\CMS\Backend\Form\FormDataCompiler;
 use TYPO3\CMS\Backend\Form\FormDataGroup\TcaInputPlaceholderRecord;
 use TYPO3\CMS\Backend\Form\FormDataProviderInterface;
+use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Localization\LanguageService;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 
@@ -119,7 +121,18 @@ class TcaInputPlaceholders implements FormDataProviderInterface
         }
 
         if (!empty($possibleUids) && !empty($fieldNameArray)) {
+            if (count($possibleUids) > 1
+                && !empty($GLOBALS['TCA'][$foreignTableName]['ctrl']['languageField'])
+                && isset($result['currentSysLanguage'])
+            ) {
+                $possibleUids = $this->getPossibleUidsByCurrentSysLanguage($possibleUids, $foreignTableName, $result['currentSysLanguage']);
+            }
             $relatedFormData = $this->getRelatedFormData($foreignTableName, $possibleUids[0], $fieldNameArray[0]);
+            if (!empty($GLOBALS['TCA'][$result['tableName']]['ctrl']['languageField'])
+                && (isset($result['databaseRow'][$GLOBALS['TCA'][$result['tableName']]['ctrl']['languageField']]))
+            ) {
+                $relatedFormData['currentSysLanguage'] = $result['databaseRow'][$GLOBALS['TCA'][$result['tableName']]['ctrl']['languageField']][0];
+            }
             $value = $this->getPlaceholderValue($fieldNameArray, $relatedFormData, $recursionLevel + 1);
         }
 
@@ -202,6 +215,53 @@ class TcaInputPlaceholders implements FormDataProviderInterface
         return $allowedTable;
     }
 
+    /**
+     * E.g. sys_file is not translatable, thus the uid of the translation of it's metadata has to be retrieved here.
+     *
+     * Get the uid of e.g. a file metadata entry for a given sys_language_uid and the possible translated data.
+     * If there is no translation available, return the uid of default language.
+     * If there is no value at all, return the "possible uids".
+     *
+     * @param array $possibleUids
+     * @param string $foreignTableName
+     * @param int $currentLanguage
+     * @return array
+     */
+    protected function getPossibleUidsByCurrentSysLanguage(array $possibleUids, $foreignTableName, $currentLanguage)
+    {
+        $languageField = $GLOBALS['TCA'][$foreignTableName]['ctrl']['languageField'];
+        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($foreignTableName);
+        $possibleRecords = $queryBuilder->select('uid', $languageField)
+            ->from($foreignTableName)
+            ->where(
+                $queryBuilder->expr()->in(
+                    'uid',
+                    $queryBuilder->createNamedParameter($possibleUids, Connection::PARAM_INT_ARRAY)
+                ),
+                $queryBuilder->expr()->in(
+                    $languageField,
+                    $queryBuilder->createNamedParameter([$currentLanguage, 0], Connection::PARAM_INT_ARRAY)
+                )
+            )
+            ->groupBy($languageField)
+            ->execute()
+            ->fetchAll();
+
+        if (!empty($possibleRecords)) {
+            // Either only one record or first record matches language
+            if (count($possibleRecords) === 1
+                || (int)$possibleRecords[0][$languageField] === (int)$currentLanguage
+            ) {
+                return [$possibleRecords[0]['uid']];
+            }
+
+            // Language of second record matches language
+            return [$possibleRecords[1]['uid']];
+        }
+
+        return $possibleUids;
+    }
+
     /**
      * @return LanguageService
      */
diff --git a/typo3/sysext/core/Configuration/TCA/sys_file_metadata.php b/typo3/sysext/core/Configuration/TCA/sys_file_metadata.php
index 4803d81491b0..a0ea62c11ad5 100644
--- a/typo3/sysext/core/Configuration/TCA/sys_file_metadata.php
+++ b/typo3/sysext/core/Configuration/TCA/sys_file_metadata.php
@@ -153,15 +153,16 @@ return [
     'types' => [
         '1' => ['showitem' => '
             --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:general,
-                fileinfo, title, description, alternative,
-            --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:language,
-                --palette--;;language,
+                fileinfo, title, description, alternative, --palette--;;language,
             --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:categories,
                 categories,
             --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:extended,
         ']
     ],
     'palettes' => [
-        'language' => ['showitem' => 'sys_language_uid, l10n_parent'],
+        'language' => [
+            'showitem' => 'sys_language_uid, l10n_parent',
+            'isHiddenPalette' => true,
+        ],
     ]
 ];
diff --git a/typo3/sysext/filemetadata/Tests/Functional/Tca/FileMetadataVisibleFieldsTest.php b/typo3/sysext/filemetadata/Tests/Functional/Tca/FileMetadataVisibleFieldsTest.php
index fd92a4a2f08d..fb0818728b2d 100644
--- a/typo3/sysext/filemetadata/Tests/Functional/Tca/FileMetadataVisibleFieldsTest.php
+++ b/typo3/sysext/filemetadata/Tests/Functional/Tca/FileMetadataVisibleFieldsTest.php
@@ -31,7 +31,6 @@ class FileMetadataVisibleFieldsTest extends \TYPO3\TestingFramework\Core\Functio
      */
     protected static $fileMetadataFields = [
         File::FILETYPE_UNKNOWN => [
-            'sys_language_uid',
             'title',
             'description',
             'ranking',
@@ -52,7 +51,6 @@ class FileMetadataVisibleFieldsTest extends \TYPO3\TestingFramework\Core\Functio
             'categories',
         ],
         File::FILETYPE_TEXT => [
-            'sys_language_uid',
             'title',
             'description',
             'ranking',
@@ -74,7 +72,6 @@ class FileMetadataVisibleFieldsTest extends \TYPO3\TestingFramework\Core\Functio
             'categories',
         ],
         File::FILETYPE_IMAGE => [
-            'sys_language_uid',
             'title',
             'description',
             'ranking',
@@ -101,7 +98,6 @@ class FileMetadataVisibleFieldsTest extends \TYPO3\TestingFramework\Core\Functio
             'categories',
         ],
         File::FILETYPE_AUDIO => [
-            'sys_language_uid',
             'title',
             'description',
             'ranking',
@@ -123,7 +119,6 @@ class FileMetadataVisibleFieldsTest extends \TYPO3\TestingFramework\Core\Functio
             'categories',
         ],
         File::FILETYPE_VIDEO => [
-            'sys_language_uid',
             'title',
             'description',
             'ranking',
-- 
GitLab