[TASK] Migrate Extbase Typo3DbBackend to Context API 01/57401/5
authorBenni Mack <benni@typo3.org>
Thu, 28 Jun 2018 05:27:39 +0000 (07:27 +0200)
committerAndreas Fernandez <a.fernandez@scripting-base.de>
Mon, 2 Jul 2018 06:36:13 +0000 (08:36 +0200)
Due to the introduction of Contexts, it is now possible
for Extbase to use the global context and to modify
it to set up a new instance of "PageRepository"
with just a context initialized. This way,
dependencies to $BE_USER and $TSFE->sys_page
are removed.

In further steps, the method should actually just work
with the context object which should be handed in,
however, some more work regarding language handling
has to be implemented first.

Resolves: #85413
Releases: master
Change-Id: If657d25943d92a69a754a29c22461d43b97c4095
Reviewed-on: https://review.typo3.org/57401
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl>
Tested-by: Wouter Wolters <typo3@wouterwolters.nl>
Reviewed-by: Andreas Fernandez <a.fernandez@scripting-base.de>
Tested-by: Andreas Fernandez <a.fernandez@scripting-base.de>
typo3/sysext/extbase/Classes/Persistence/Generic/Storage/Typo3DbBackend.php
typo3/sysext/extbase/Tests/Unit/Persistence/Generic/Storage/Typo3DbBackendTest.php

index 484d7c0..692e014 100644 (file)
@@ -17,7 +17,8 @@ namespace TYPO3\CMS\Extbase\Persistence\Generic\Storage;
 use Doctrine\DBAL\DBALException;
 use Doctrine\DBAL\Platforms\SQLServerPlatform;
 use TYPO3\CMS\Backend\Utility\BackendUtility;
-use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
+use TYPO3\CMS\Core\Context\Context;
+use TYPO3\CMS\Core\Context\WorkspaceAspect;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Database\Query\QueryBuilder;
 use TYPO3\CMS\Core\Database\Query\Restriction\FrontendRestrictionContainer;
@@ -54,13 +55,6 @@ class Typo3DbBackend implements BackendInterface, SingletonInterface
     protected $dataMapper;
 
     /**
-     * The TYPO3 page repository. Used for language and workspace overlay
-     *
-     * @var PageRepository
-     */
-    protected $pageRepository;
-
-    /**
      * @var ConfigurationManagerInterface
      */
     protected $configurationManager;
@@ -563,34 +557,32 @@ class Typo3DbBackend implements BackendInterface, SingletonInterface
             return $rows;
         }
 
-        $pageRepository = $this->getPageRepository();
-        if (is_object($this->getTSFE())) {
-            if ($workspaceUid !== null) {
-                $pageRepository->versioningWorkspaceId = $workspaceUid;
-            }
+        $context = $this->objectManager->get(Context::class);
+        if ($workspaceUid === null) {
+            $workspaceUid = $context->getPropertyFromAspect('workspace', 'id');
         } else {
-            if ($workspaceUid === null) {
-                $workspaceUid = $this->getBeUser()->workspace;
-            }
-            $pageRepository->versioningWorkspaceId = $workspaceUid;
+            // A custom query is needed, so a custom context is cloned
+            $workspaceUid = (int)$workspaceUid;
+            $context = clone $context;
+            $context->setAspect('workspace', $this->objectManager->get(WorkspaceAspect::class, $workspaceUid));
         }
+        $pageRepository = $this->objectManager->get(PageRepository::class, $context);
 
         // Fetches the move-placeholder in case it is supported
         // by the table and if there's only one row in the result set
         // (applying this to all rows does not work, since the sorting
         // order would be destroyed and possible limits not met anymore)
-        if (!empty($pageRepository->versioningWorkspaceId)
+        if (!empty($workspaceUid)
             && BackendUtility::isTableWorkspaceEnabled($tableName)
             && count($rows) === 1
         ) {
-            $versionId = $pageRepository->versioningWorkspaceId;
             $queryBuilder = $this->connectionPool->getQueryBuilderForTable($tableName);
             $queryBuilder->getRestrictions()->removeAll();
             $movePlaceholder = $queryBuilder->select($tableName . '.*')
                 ->from($tableName)
                 ->where(
                     $queryBuilder->expr()->eq('t3ver_state', $queryBuilder->createNamedParameter(3, \PDO::PARAM_INT)),
-                    $queryBuilder->expr()->eq('t3ver_wsid', $queryBuilder->createNamedParameter($versionId, \PDO::PARAM_INT)),
+                    $queryBuilder->expr()->eq('t3ver_wsid', $queryBuilder->createNamedParameter($workspaceUid, \PDO::PARAM_INT)),
                     $queryBuilder->expr()->eq('t3ver_move_id', $queryBuilder->createNamedParameter($rows[0]['uid'], \PDO::PARAM_INT))
                 )
                 ->setMaxResults(1)
@@ -652,22 +644,6 @@ class Typo3DbBackend implements BackendInterface, SingletonInterface
     }
 
     /**
-     * @return PageRepository
-     */
-    protected function getPageRepository()
-    {
-        if (!$this->pageRepository instanceof PageRepository) {
-            if ($this->environmentService->isEnvironmentInFrontendMode() && is_object($this->getTSFE())) {
-                $this->pageRepository = $this->getTSFE()->sys_page;
-            } else {
-                $this->pageRepository = GeneralUtility::makeInstance(PageRepository::class);
-            }
-        }
-
-        return $this->pageRepository;
-    }
-
-    /**
      * Clear the TYPO3 page cache for the given record.
      * If the record lies on a page, then we clear the cache of this page.
      * If the record has no PID column, we clear the cache of the current page as best-effort.
@@ -747,12 +723,4 @@ class Typo3DbBackend implements BackendInterface, SingletonInterface
     {
         return $GLOBALS['TSFE'] ?? null;
     }
-
-    /**
-     * @return BackendUserAuthentication|null
-     */
-    protected function getBeUser()
-    {
-        return $GLOBALS['BE_USER'] ?? null;
-    }
 }
index 6822dac..8d54e36 100644 (file)
@@ -16,11 +16,15 @@ namespace TYPO3\CMS\Extbase\Tests\Unit\Persistence\Generic\Storage;
 
 use Doctrine\DBAL\Driver\Statement;
 use Prophecy\Argument;
+use TYPO3\CMS\Core\Context\Context;
+use TYPO3\CMS\Core\Context\WorkspaceAspect;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Database\Query\Expression\ExpressionBuilder;
 use TYPO3\CMS\Core\Database\Query\QueryBuilder;
 use TYPO3\CMS\Core\Database\Query\Restriction\FrontendRestrictionContainer;
+use TYPO3\CMS\Extbase\Object\ObjectManager;
 use TYPO3\CMS\Extbase\Service\EnvironmentService;
+use TYPO3\CMS\Frontend\Page\PageRepository;
 
 /**
  * Test case
@@ -152,15 +156,25 @@ class Typo3DbBackendTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
             ->getMock();
 
         $workspaceUid = 2;
+
+        $objectManagerMock = $this->getMockBuilder(ObjectManager::class)
+            ->disableOriginalConstructor()
+            ->getMock();
         $sourceMock = new \TYPO3\CMS\Extbase\Persistence\Generic\Qom\Selector('tx_foo', 'Tx_Foo');
-        /** @var $pageRepositoryMock \TYPO3\CMS\Frontend\Page\PageRepository|\PHPUnit_Framework_MockObject_MockObject */
-        $pageRepositoryMock = $this->getMockBuilder(\TYPO3\CMS\Frontend\Page\PageRepository::class)
+        /** @var $pageRepositoryMock PageRepository|\PHPUnit_Framework_MockObject_MockObject */
+        $pageRepositoryMock = $this->getMockBuilder(PageRepository::class)
             ->setMethods(['movePlhOL', 'getWorkspaceVersionOfRecord'])
             ->disableOriginalConstructor()
             ->getMock();
         $pageRepositoryMock->expects($this->once())->method('getWorkspaceVersionOfRecord')->with($workspaceUid, 'tx_foo', '42')->will($this->returnValue($workspaceVersion));
+        $pageRepositoryMock->versioningWorkspaceId = $workspaceUid;
+        $context = new Context([
+            'workspace' => new WorkspaceAspect($workspaceUid)
+        ]);
+        $objectManagerMock->expects($this->at(0))->method('get')->with(Context::class)->willReturn($context);
+        $objectManagerMock->expects($this->at(1))->method('get')->with(PageRepository::class, $context)->willReturn($pageRepositoryMock);
         $mockTypo3DbBackend = $this->getAccessibleMock(\TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbBackend::class, ['dummy'], [], '', false);
-        $mockTypo3DbBackend->_set('pageRepository', $pageRepositoryMock);
-        $this->assertSame([$comparisonRow], $mockTypo3DbBackend->_call('doLanguageAndWorkspaceOverlay', $sourceMock, [$row], $mockQuerySettings, $workspaceUid));
+        $mockTypo3DbBackend->injectObjectManager($objectManagerMock);
+        $this->assertSame([$comparisonRow], $mockTypo3DbBackend->_call('doLanguageAndWorkspaceOverlay', $sourceMock, [$row], $mockQuerySettings));
     }
 }