[BUGFIX] Fix injured workspace encapsulation in record localize summary. 81/50881/14
authorGleb Levitin <gleb.levitin@dkd.de>
Sun, 4 Dec 2016 09:20:42 +0000 (10:20 +0100)
committerOliver Hader <oliver.hader@typo3.org>
Thu, 30 Nov 2017 15:49:44 +0000 (16:49 +0100)
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>
typo3/sysext/backend/Classes/Controller/Page/LocalizationController.php
typo3/sysext/backend/Tests/Functional/Controller/Page/Fixtures/pages.xml [new file with mode: 0644]
typo3/sysext/backend/Tests/Functional/Controller/Page/Fixtures/tt_content-danish-language.xml
typo3/sysext/backend/Tests/Functional/Controller/Page/Fixtures/tt_content-default-language.xml
typo3/sysext/backend/Tests/Functional/Controller/Page/LocalizationControllerTest.php

index 3d53abe..5f9fabd 100644 (file)
@@ -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 (file)
index 0000000..7769210
--- /dev/null
@@ -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
index 80dc69c..7d12f98 100644 (file)
@@ -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
index 6471b84..5a0eb54 100644 (file)
@@ -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
index bc31723..509231f 100644 (file)
@@ -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
@@ -30,16 +34,34 @@ 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.
      */
     protected function setUp()
     {
         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;
+    }
 }