From 1708cda8960085265bf5eecafb52ba0549dedac0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Andr=C3=A9=20Buchmann?= <a.buchmann@zeroseven.de>
Date: Thu, 12 May 2022 16:08:46 +0200
Subject: [PATCH] [BUGFIX] Apply empty values in language-overlay

Some default fields (e.g. tt_content.bodytext) can contain null values.
TYPO3 first fetches the data in the default language and then overlays
the rows data with the translation values. The overlay method inspects
each array item with the php isset() function. This validates not only
the existence of the array key, but also the values. null and
false values evaluated as false. Empty strings evaluate as true.
This leads to inconsistent output in the frontend.

The overlay now valides only the array key existence and applies also
empty values.

Resolves: #97616
Releases: main, 11.5, 10.4
Change-Id: I4b01c52e9ac7adde786b3395bce870bc0a354b58
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/74834
Tested-by: core-ci <typo3@b13.com>
Tested-by: Oliver Klee <typo3-coding@oliverklee.de>
Tested-by: Benni Mack <benni@typo3.org>
Reviewed-by: Oliver Klee <typo3-coding@oliverklee.de>
Reviewed-by: Benni Mack <benni@typo3.org>
---
 .../Domain/Repository/PageRepository.php      |  2 +-
 .../Domain/Repository/PageRepositoryTest.php  | 21 +++++++++++++++++++
 .../core/Tests/Functional/Fixtures/pages.csv  |  6 ++++++
 3 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/typo3/sysext/core/Classes/Domain/Repository/PageRepository.php b/typo3/sysext/core/Classes/Domain/Repository/PageRepository.php
index 5ba233649c56..4dd0cfe0fd51 100644
--- a/typo3/sysext/core/Classes/Domain/Repository/PageRepository.php
+++ b/typo3/sysext/core/Classes/Domain/Repository/PageRepository.php
@@ -687,7 +687,7 @@ class PageRepository implements LoggerAwareInterface
                             $row['_ORIG_pid'] = $olrow['_ORIG_pid'];
                         }
                         foreach ($row as $fN => $fV) {
-                            if ($fN !== 'uid' && $fN !== 'pid' && isset($olrow[$fN])) {
+                            if ($fN !== 'uid' && $fN !== 'pid' && array_key_exists($fN, $olrow)) {
                                 $row[$fN] = $olrow[$fN];
                             } elseif ($fN === 'uid') {
                                 $row['_LOCALIZED_UID'] = $olrow['uid'];
diff --git a/typo3/sysext/core/Tests/Functional/Domain/Repository/PageRepositoryTest.php b/typo3/sysext/core/Tests/Functional/Domain/Repository/PageRepositoryTest.php
index 3fbb19dd930b..240d219e740e 100644
--- a/typo3/sysext/core/Tests/Functional/Domain/Repository/PageRepositoryTest.php
+++ b/typo3/sysext/core/Tests/Functional/Domain/Repository/PageRepositoryTest.php
@@ -614,4 +614,25 @@ class PageRepositoryTest extends FunctionalTestCase
         self::assertFalse(isset($row['_PAGES_OVERLAY_UID']));
         self::assertFalse(isset($row['_PAGES_OVERLAY_LANGUAGE']));
     }
+
+    /**
+     * @test
+     */
+    public function getLanguageOverlayResolvesContentWithNullInValues(): void
+    {
+        $context = new Context();
+        $context->setAspect('language', new LanguageAspect(1, 1, LanguageAspect::OVERLAYS_ON_WITH_FLOATING, [0]));
+        $subject = new PageRepository($context);
+        $record = $subject->getRawRecord('tt_content', 1);
+        self::assertSame('Default Content #1', $record['header']);
+        $overlaidRecord = $subject->getLanguageOverlay('tt_content', $record);
+        self::assertSame(2, (int)$overlaidRecord['_LOCALIZED_UID']);
+        self::assertSame('Translated Content #1', $overlaidRecord['header']);
+
+        // Check if "bodytext" is actually overlaid with a NULL value
+        $record = $subject->getRawRecord('tt_content', 3);
+        $overlaidRecord = $subject->getLanguageOverlay('tt_content', $record);
+        self::assertSame('Translated #2', $overlaidRecord['header']);
+        self::assertNull($overlaidRecord['bodytext']);
+    }
 }
diff --git a/typo3/sysext/core/Tests/Functional/Fixtures/pages.csv b/typo3/sysext/core/Tests/Functional/Fixtures/pages.csv
index 3841a3baeadb..486a00b3c5a3 100644
--- a/typo3/sysext/core/Tests/Functional/Fixtures/pages.csv
+++ b/typo3/sysext/core/Tests/Functional/Fixtures/pages.csv
@@ -22,3 +22,9 @@ pages,,,,,,,,,,,,,,,
 ,1002,1000,root translation,0,,0,0,0,0,0,1,1001,1,0,0
 ,1003,1000,Mount default language,0,,0,0,0,0,0,0,0,7,1001,1
 ,1004,1000,Mount translation,0,,0,0,0,0,0,1,1003,7,1001,1
+tt_content,,,,,,,,,,,,,,,,
+,uid,pid,header,bodytext,sys_language_uid,l18n_parent,,,,,,,,,,
+,1,1,"Default Content #1","<p>Say thanks for HTML in the DB</p>",0,0,,,,,,,,,,
+,2,1,"Translated Content #1","<p>Grazie por HTML en la database</p>",1,1,,,,,,,,,,
+,3,1,"Default Content #2","<p>Could be anything</p>",0,0,,,,,,,,,,
+,4,1,"Translated #2","\NULL",1,3,,,,,,,,,,
\ No newline at end of file
-- 
GitLab