From 2320d7f9689a1f92245ff69a6cf4c1684a4c8e94 Mon Sep 17 00:00:00 2001
From: Gleb Levitin <gleb.levitin@dkd.de>
Date: Sun, 4 Dec 2016 10:20:42 +0100
Subject: [PATCH] [BUGFIX] Fix injured workspace encapsulation in record
 localize summary.

This patch resolves problem with the injured workspace encapsulation
for removed records while fetching the record localize summary in page
module within a workspace.

Resolves: #78841
Releases: master, 8.7
Change-Id: I734a32c7b52ed4a2a3ab49c63d45df46472a99a4
Reviewed-on: https://review.typo3.org/50881
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Oliver Hader <oliver.hader@typo3.org>
Tested-by: Oliver Hader <oliver.hader@typo3.org>
---
 .../Page/LocalizationController.php           |  6 ++
 .../Controller/Page/Fixtures/pages.xml        | 17 ++++
 .../Fixtures/tt_content-danish-language.xml   |  3 +
 .../Fixtures/tt_content-default-language.xml  |  3 +
 .../Page/LocalizationControllerTest.php       | 88 ++++++++++++++++++-
 5 files changed, 115 insertions(+), 2 deletions(-)
 create mode 100644 typo3/sysext/backend/Tests/Functional/Controller/Page/Fixtures/pages.xml

diff --git a/typo3/sysext/backend/Classes/Controller/Page/LocalizationController.php b/typo3/sysext/backend/Classes/Controller/Page/LocalizationController.php
index 3d53abef65b3..5f9fabd0b6f9 100644
--- a/typo3/sysext/backend/Classes/Controller/Page/LocalizationController.php
+++ b/typo3/sysext/backend/Classes/Controller/Page/LocalizationController.php
@@ -18,10 +18,12 @@ use Psr\Http\Message\ResponseInterface;
 use Psr\Http\Message\ServerRequestInterface;
 use TYPO3\CMS\Backend\Configuration\TranslationConfigurationProvider;
 use TYPO3\CMS\Backend\Domain\Repository\Localization\LocalizationRepository;
+use TYPO3\CMS\Backend\Utility\BackendUtility;
 use TYPO3\CMS\Core\DataHandling\DataHandler;
 use TYPO3\CMS\Core\Imaging\Icon;
 use TYPO3\CMS\Core\Imaging\IconFactory;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Core\Versioning\VersionState;
 
 /**
  * LocalizationController handles the AJAX requests for record localization
@@ -137,6 +139,10 @@ class LocalizationController
         );
 
         while ($row = $result->fetch()) {
+            BackendUtility::workspaceOL('tt_content', $row, -99, true);
+            if (!$row || VersionState::cast($row['t3ver_state'])->equals(VersionState::DELETE_PLACEHOLDER)) {
+                continue;
+            }
             $records[] = [
                 'icon' => $this->iconFactory->getIconForRecord('tt_content', $row, Icon::SIZE_SMALL)->render(),
                 'title' => $row[$GLOBALS['TCA']['tt_content']['ctrl']['label']],
diff --git a/typo3/sysext/backend/Tests/Functional/Controller/Page/Fixtures/pages.xml b/typo3/sysext/backend/Tests/Functional/Controller/Page/Fixtures/pages.xml
new file mode 100644
index 000000000000..77692105d449
--- /dev/null
+++ b/typo3/sysext/backend/Tests/Functional/Controller/Page/Fixtures/pages.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<dataset>
+	<pages>
+		<uid>1</uid>
+		<pid>0</pid>
+		<title>Localization</title>
+		<deleted>0</deleted>
+		<perms_everybody>15</perms_everybody>
+	</pages>
+	<pages>
+		<uid>2</uid>
+		<pid>0</pid>
+		<title>Localization 2</title>
+		<deleted>0</deleted>
+		<perms_everybody>15</perms_everybody>
+	</pages>
+</dataset>
\ No newline at end of file
diff --git a/typo3/sysext/backend/Tests/Functional/Controller/Page/Fixtures/tt_content-danish-language.xml b/typo3/sysext/backend/Tests/Functional/Controller/Page/Fixtures/tt_content-danish-language.xml
index 80dc69c1e969..7d12f98a9178 100644
--- a/typo3/sysext/backend/Tests/Functional/Controller/Page/Fixtures/tt_content-danish-language.xml
+++ b/typo3/sysext/backend/Tests/Functional/Controller/Page/Fixtures/tt_content-danish-language.xml
@@ -9,6 +9,7 @@
 		<t3ver_oid>0</t3ver_oid>
 		<t3ver_wsid>0</t3ver_wsid>
 		<header>Test indhold 1</header>
+		<sorting>1</sorting>
 	</tt_content>
 	<tt_content>
 		<uid>5</uid>
@@ -19,6 +20,7 @@
 		<t3ver_oid>0</t3ver_oid>
 		<t3ver_wsid>0</t3ver_wsid>
 		<header>Test indhold 2</header>
+		<sorting>2</sorting>
 	</tt_content>
 	<tt_content>
 		<uid>6</uid>
@@ -29,5 +31,6 @@
 		<t3ver_oid>0</t3ver_oid>
 		<t3ver_wsid>0</t3ver_wsid>
 		<header>Test indhold 3</header>
+		<sorting>3</sorting>
 	</tt_content>
 </dataset>
\ No newline at end of file
diff --git a/typo3/sysext/backend/Tests/Functional/Controller/Page/Fixtures/tt_content-default-language.xml b/typo3/sysext/backend/Tests/Functional/Controller/Page/Fixtures/tt_content-default-language.xml
index 6471b8479e35..5a0eb54d8933 100644
--- a/typo3/sysext/backend/Tests/Functional/Controller/Page/Fixtures/tt_content-default-language.xml
+++ b/typo3/sysext/backend/Tests/Functional/Controller/Page/Fixtures/tt_content-default-language.xml
@@ -7,6 +7,7 @@
 		<deleted>0</deleted>
 		<t3ver_oid>0</t3ver_oid>
 		<t3ver_wsid>0</t3ver_wsid>
+		<sorting>1</sorting>
 	</tt_content>
 	<tt_content>
 		<uid>2</uid>
@@ -15,6 +16,7 @@
 		<deleted>0</deleted>
 		<t3ver_oid>0</t3ver_oid>
 		<t3ver_wsid>0</t3ver_wsid>
+		<sorting>2</sorting>
 	</tt_content>
 	<tt_content>
 		<uid>3</uid>
@@ -23,5 +25,6 @@
 		<deleted>0</deleted>
 		<t3ver_oid>0</t3ver_oid>
 		<t3ver_wsid>0</t3ver_wsid>
+		<sorting>3</sorting>
 	</tt_content>
 </dataset>
\ No newline at end of file
diff --git a/typo3/sysext/backend/Tests/Functional/Controller/Page/LocalizationControllerTest.php b/typo3/sysext/backend/Tests/Functional/Controller/Page/LocalizationControllerTest.php
index bc3172395016..509231f8ee4f 100644
--- a/typo3/sysext/backend/Tests/Functional/Controller/Page/LocalizationControllerTest.php
+++ b/typo3/sysext/backend/Tests/Functional/Controller/Page/LocalizationControllerTest.php
@@ -18,6 +18,10 @@ use TYPO3\CMS\Backend\Controller\Page\LocalizationController;
 use TYPO3\CMS\Core\Core\Bootstrap;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\DataHandling\DataHandler;
+use TYPO3\CMS\Core\Http\Response;
+use TYPO3\CMS\Core\Http\ServerRequest;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\TestingFramework\Core\Functional\Framework\DataHandling\ActionService;
 
 /**
  * Test case for TYPO3\CMS\Backend\Controller\Page\LocalizationController
@@ -29,6 +33,21 @@ class LocalizationControllerTest extends \TYPO3\TestingFramework\Core\Functional
      */
     protected $subject;
 
+    /**
+     * @var \TYPO3\TestingFramework\Core\Functional\Framework\DataHandling\ActionService
+     */
+    protected $actionService;
+
+    /**
+     * @var \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
+     */
+    protected $backendUser;
+
+    /**
+     * @var array
+     */
+    protected $coreExtensionsToLoad = ['workspaces'];
+
     /**
      * Sets up this test case.
      */
@@ -36,10 +55,13 @@ class LocalizationControllerTest extends \TYPO3\TestingFramework\Core\Functional
     {
         parent::setUp();
 
-        $this->setUpBackendUserFromFixture(1);
+        $this->backendUser = $this->setUpBackendUserFromFixture(1);
+        $this->backendUser->workspace = 0;
+
         Bootstrap::getInstance()->initializeLanguageObject();
+        $this->actionService = GeneralUtility::makeInstance(ActionService::class);
 
-        $this->importDataSet(ORIGINAL_ROOT . 'typo3/sysext/backend/Tests/Functional/Fixtures/pages.xml');
+        $this->importDataSet(__DIR__ . '/Fixtures/pages.xml');
         $this->importDataSet('PACKAGE:typo3/testing-framework/Resources/Core/Functional/Fixtures/sys_language.xml');
         $this->importDataSet(ORIGINAL_ROOT . 'typo3/sysext/backend/Tests/Functional/Controller/Page/Fixtures/tt_content-default-language.xml');
 
@@ -366,4 +388,66 @@ class LocalizationControllerTest extends \TYPO3\TestingFramework\Core\Functional
             ->fetchAll();
         $this->assertEquals($expectedResults, $results);
     }
+
+    /**
+     * @test
+     */
+    public function recordLocalizeSummaryRespectsWorkspaceEncapsulationForDeletedRecords()
+    {
+        // Delete record 2 within workspace 1
+        $this->backendUser->workspace = 1;
+        $this->actionService->deleteRecord('tt_content', 2);
+
+        $expectedRecordUidList = [
+            ['uid' => 1],
+            ['uid' => 3]
+        ];
+
+        $this->assertEquals($expectedRecordUidList, $this->getReducedRecordLocalizeSummary());
+    }
+
+    /**
+     * @test
+     */
+    public function recordLocalizeSummaryRespectsWorkspaceEncapsulationForMovedRecords()
+    {
+        // Move record 2 to page 2 within workspace 1
+        $this->backendUser->workspace = 1;
+        $this->actionService->moveRecord('tt_content', 2, 2);
+
+        $expectedRecordUidList = [
+            ['uid' => 1],
+            ['uid' => 3]
+        ];
+
+        $this->assertEquals($expectedRecordUidList, $this->getReducedRecordLocalizeSummary());
+    }
+
+    /**
+     * Get record localized summary list reduced to list of uids
+     *
+     * @return array
+     */
+    protected function getReducedRecordLocalizeSummary()
+    {
+        $request = (new ServerRequest())->withQueryParams([
+            'pageId'         => 1, // page uid, the records are stored on
+            'colPos'         => 0, // column position, the records are to be taken from
+            'destLanguageId' => 1, // destination language uid
+            'languageId'     => 0  // source language uid
+        ]);
+
+        $recordLocalizeSummaryResponse = $this->subject->getRecordLocalizeSummary($request, new Response());
+
+        // Reduce the fetched record summary to list of uids
+        if ($recordLocalizeSummary = json_decode((string) $recordLocalizeSummaryResponse->getBody(), true)) {
+            foreach ($recordLocalizeSummary as &$record) {
+                if (is_array($record)) {
+                    $record = array_intersect_key($record, ['uid' => '']);
+                }
+            }
+        }
+
+        return $recordLocalizeSummary;
+    }
 }
-- 
GitLab