[TASK] Doctrine: Introduce backend query context to exclude Placeholders 27/47827/3
authorMorton Jonuschat <m.jonuschat@mojocode.de>
Wed, 20 Apr 2016 18:37:57 +0000 (20:37 +0200)
committerWouter Wolters <typo3@wouterwolters.nl>
Wed, 27 Apr 2016 17:22:10 +0000 (19:22 +0200)
This patch adds a new query context BACKEND_NO_VERSIONING_PLACEHOLDERS
that de-selects versioning placeholders from other workspaces in the
same way that BackendUtility::versioningPlaceholdersClause() does. Usage
as follows:

$queryBuilder
  ->getQueryContext()
  ->setContext(QueryContextType::BACKEND_NO_VERSIONING_PLACEHOLDERS)
  ->setCurrentWorkspace(4);

Releases: master
Resolves: #75821
Change-Id: Iaa238f3da803c6d2dd23f0240cb2c409a39eec58
Reviewed-on: https://review.typo3.org/47827
Reviewed-by: Jonathan IROULIN <joniroutypo3@gmail.com>
Tested-by: Jonathan IROULIN <joniroutypo3@gmail.com>
Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl>
Tested-by: Wouter Wolters <typo3@wouterwolters.nl>
typo3/sysext/core/Classes/Database/Query/QueryContextType.php
typo3/sysext/core/Classes/Database/Query/QueryRestrictionBuilder.php
typo3/sysext/core/Tests/Unit/Database/Query/QueryRestrictionBuilderTest.php

index 6ca782d..8b20d79 100644 (file)
@@ -30,6 +30,7 @@ class QueryContextType extends \TYPO3\CMS\Core\Type\Enumeration
     const UNRESTRICTED = 'UNRESTRICTED';
     const FRONTEND = 'FRONTEND';
     const BACKEND = 'BACKEND';
+    const BACKEND_NO_VERSIONING_PLACEHOLDERS = 'BACKEND_NO_VERSIONING_PLACEHOLDERS';
 
     /**
      * @param mixed $type
index 4d6c560..66ba323 100644 (file)
@@ -91,6 +91,7 @@ class QueryRestrictionBuilder
             case QueryContextType::FRONTEND:
                 return $this->getFrontendVisibilityRestrictions();
             case QueryContextType::BACKEND:
+            case QueryContextType::BACKEND_NO_VERSIONING_PLACEHOLDERS:
                 return $this->getBackendVisibilityConstraints();
             case QueryContextType::UNRESTRICTED:
                 return $this->expressionBuilder->andX();
@@ -212,12 +213,23 @@ class QueryRestrictionBuilder
             }
 
             if (!$includeDeleted && !empty($tableConfig['delete'])) {
-                $tablePrefix = empty($tableAlias) ? $tableName : $tableAlias;
                 $constraints[] = $this->expressionBuilder->eq(
                     $tablePrefix . '.' . $tableConfig['delete'],
                     0
                 );
             }
+
+            if ($queryContext->getContext() === QueryContextType::BACKEND_NO_VERSIONING_PLACEHOLDERS
+                && !empty($tableConfig['versioningWS'])
+            ) {
+                $constraints[] = $this->expressionBuilder->orX(
+                    $expressionBuilder->lte(
+                        $tablePrefix . '.t3ver_state',
+                        new VersionState(VersionState::DEFAULT_STATE)
+                    ),
+                    $expressionBuilder->eq($tablePrefix . '.t3ver_wsid', $queryContext->getCurrentWorkspace())
+                );
+            }
         }
 
         return $expressionBuilder->andX(...$constraints);
index 2f55572..bf0ce97 100644 (file)
@@ -105,7 +105,7 @@ class QueryRestrictionBuilderTest extends UnitTestCase
      */
     public function getFrontendVisibilityRestrictionsSkipsUnconfiguredTables()
     {
-        $this->queryContext->setContext('frontend');
+        $this->queryContext->setContext(QueryContextType::FRONTEND);
 
         $subject = GeneralUtility::makeInstance(
             QueryRestrictionBuilder::class,
@@ -122,7 +122,7 @@ class QueryRestrictionBuilderTest extends UnitTestCase
      */
     public function getFrontendVisibilityRestrictionsWithDefaultSettings()
     {
-        $this->queryContext->setContext('frontend')
+        $this->queryContext->setContext(QueryContextType::FRONTEND)
             ->setAccessTime(1459706700)
             ->setTableConfigs(['pages' => $this->defaultTableConfig]);
 
@@ -151,7 +151,7 @@ class QueryRestrictionBuilderTest extends UnitTestCase
      */
     public function getFrontendVisibilityRestrictionsWithUserGroups()
     {
-        $this->queryContext->setContext('frontend')
+        $this->queryContext->setContext(QueryContextType::FRONTEND)
             ->setAccessTime(1459706700)
             ->setMemberGroups([1, 2])
             ->setTableConfigs(['pages' => $this->defaultTableConfig]);
@@ -181,7 +181,7 @@ class QueryRestrictionBuilderTest extends UnitTestCase
      */
     public function getFrontendVisibilityRestrictionsWithVersioningPreview()
     {
-        $this->queryContext->setContext('frontend')
+        $this->queryContext->setContext(QueryContextType::FRONTEND)
             ->setAccessTime(1459706700)
             ->setIncludePlaceholders(true)
             ->setTableConfigs(['pages' => $this->defaultTableConfig]);
@@ -203,7 +203,7 @@ class QueryRestrictionBuilderTest extends UnitTestCase
      */
     public function getFrontendVisibilityRestrictionsWithVersioningPreviewAndNoPreviewSet()
     {
-        $this->queryContext->setContext('frontend')
+        $this->queryContext->setContext(QueryContextType::FRONTEND)
             ->setAccessTime(1459706700)
             ->setIncludePlaceholders(true)
             ->setIncludeVersionedRecords(true)
@@ -232,7 +232,7 @@ class QueryRestrictionBuilderTest extends UnitTestCase
      */
     public function getFrontendVisibilityRestrictionsWithoutDisabledColumn()
     {
-        $this->queryContext->setContext('frontend')
+        $this->queryContext->setContext(QueryContextType::FRONTEND)
             ->setAccessTime(1459706700)
             ->setTableConfigs(['pages' => [
                 'versioningWS' => true,
@@ -268,7 +268,7 @@ class QueryRestrictionBuilderTest extends UnitTestCase
      */
     public function getFrontendVisibilityRestrictionsWithoutStarttimeColumn()
     {
-        $this->queryContext->setContext('frontend')
+        $this->queryContext->setContext(QueryContextType::FRONTEND)
             ->setAccessTime(1459706700)
             ->setTableConfigs([
                 'pages' => [
@@ -306,7 +306,7 @@ class QueryRestrictionBuilderTest extends UnitTestCase
      */
     public function getFrontendVisibilityRestrictionsWithoutEndtimeColumn()
     {
-        $this->queryContext->setContext('frontend')
+        $this->queryContext->setContext(QueryContextType::FRONTEND)
             ->setAccessTime(1459706700)
             ->setTableConfigs([
                 'pages' => [
@@ -344,7 +344,7 @@ class QueryRestrictionBuilderTest extends UnitTestCase
      */
     public function getFrontendVisibilityRestrictionsWithoutUsergroupsColumn()
     {
-        $this->queryContext->setContext('frontend')
+        $this->queryContext->setContext(QueryContextType::FRONTEND)
             ->setAccessTime(1459706700)
             ->setTableConfigs([
                 'pages' => [
@@ -382,7 +382,7 @@ class QueryRestrictionBuilderTest extends UnitTestCase
      */
     public function getFrontendVisibilityRestrictionsWithIgnoreEnableFieldsSet()
     {
-        $this->queryContext->setContext('frontend')
+        $this->queryContext->setContext(QueryContextType::FRONTEND)
             ->setAccessTime(1459706700)
             ->setTableConfigs(['pages' => $this->defaultTableConfig])
             ->setIgnoreEnableFields(true);
@@ -438,7 +438,7 @@ class QueryRestrictionBuilderTest extends UnitTestCase
      */
     public function getFrontendVisibilityRestrictionsWithSelectiveIgnoreEnableFieldsSet(array $ignoreFields)
     {
-        $this->queryContext->setContext('frontend')
+        $this->queryContext->setContext(QueryContextType::FRONTEND)
             ->setAccessTime(1459706700)
             ->setTableConfigs(['pages' => $this->defaultTableConfig])
             ->setIgnoreEnableFields(true)
@@ -472,7 +472,7 @@ class QueryRestrictionBuilderTest extends UnitTestCase
      */
     public function getFrontendVisibilityRestrictionsForMultipleTablesWithDefaultSettings()
     {
-        $this->queryContext->setContext('frontend')
+        $this->queryContext->setContext(QueryContextType::FRONTEND)
             ->setAccessTime(1459706700)
             ->setTableConfigs([
                 'pages' => $this->defaultTableConfig,
@@ -517,7 +517,7 @@ class QueryRestrictionBuilderTest extends UnitTestCase
      */
     public function getFrontendVisibilityRestrictionsForMultipleTablesWithIgnoreEnableFields()
     {
-        $this->queryContext->setContext('frontend')
+        $this->queryContext->setContext(QueryContextType::FRONTEND)
             ->setAccessTime(1459706700)
             ->setTableConfigs([
                 'pages' => $this->defaultTableConfig,
@@ -545,7 +545,7 @@ class QueryRestrictionBuilderTest extends UnitTestCase
      */
     public function getFrontendVisibilityRestrictionsForMultipleTablesWithDifferentEnableColumns()
     {
-        $this->queryContext->setContext('frontend')
+        $this->queryContext->setContext(QueryContextType::FRONTEND)
             ->setAccessTime(1459706700)
             ->setTableConfigs([
                 'pages' => $this->defaultTableConfig,
@@ -586,7 +586,7 @@ class QueryRestrictionBuilderTest extends UnitTestCase
      */
     public function getFrontendVisibilityRestrictionsForJoinedTablesWithDefaultSettings()
     {
-        $this->queryContext->setContext('frontend')
+        $this->queryContext->setContext(QueryContextType::FRONTEND)
             ->setAccessTime(1459706700)
             ->setTableConfigs([
                 'pages' => $this->defaultTableConfig,
@@ -631,7 +631,7 @@ class QueryRestrictionBuilderTest extends UnitTestCase
      */
     public function getFrontendVisibilityRestrictionsForJoinedTablesWithIgnoreEnableFields()
     {
-        $this->queryContext->setContext('frontend')
+        $this->queryContext->setContext(QueryContextType::FRONTEND)
             ->setAccessTime(1459706700)
             ->setTableConfigs([
                 'pages' => $this->defaultTableConfig,
@@ -659,7 +659,7 @@ class QueryRestrictionBuilderTest extends UnitTestCase
      */
     public function getFrontendVisibilityRestrictionsForJoinedTablesWithDifferentEnableColumns()
     {
-        $this->queryContext->setContext('frontend')
+        $this->queryContext->setContext(QueryContextType::FRONTEND)
             ->setAccessTime(1459706700)
             ->setTableConfigs([
                 'pages' => $this->defaultTableConfig,
@@ -700,7 +700,7 @@ class QueryRestrictionBuilderTest extends UnitTestCase
      */
     public function getBackendVisibilityRestrictionsSkipsUnconfiguredTables()
     {
-        $this->queryContext->setContext('backend');
+        $this->queryContext->setContext(QueryContextType::BACKEND);
 
         $subject = GeneralUtility::makeInstance(
             QueryRestrictionBuilder::class,
@@ -717,7 +717,7 @@ class QueryRestrictionBuilderTest extends UnitTestCase
      */
     public function getBackendVisibilityRestrictionsWithDefaultSettings()
     {
-        $this->queryContext->setContext('backend')
+        $this->queryContext->setContext(QueryContextType::BACKEND)
             ->setAccessTime(1459706700)
             ->setTableConfigs(['pages' => $this->defaultTableConfig]);
 
@@ -743,7 +743,7 @@ class QueryRestrictionBuilderTest extends UnitTestCase
      */
     public function getBackendVisibilityRestrictionsWithoutDisabledColumn()
     {
-        $this->queryContext->setContext('backend')
+        $this->queryContext->setContext(QueryContextType::BACKEND)
             ->setAccessTime(1459706700)
             ->setTableConfigs(['pages' => [
                 'versioningWS' => true,
@@ -776,7 +776,7 @@ class QueryRestrictionBuilderTest extends UnitTestCase
      */
     public function getBackendVisibilityRestrictionsWithoutStarttimeColumn()
     {
-        $this->queryContext->setContext('backend')
+        $this->queryContext->setContext(QueryContextType::BACKEND)
             ->setAccessTime(1459706700)
             ->setTableConfigs([
                 'pages' => [
@@ -811,7 +811,7 @@ class QueryRestrictionBuilderTest extends UnitTestCase
      */
     public function getBackendVisibilityRestrictionsWithoutEndtimeColumn()
     {
-        $this->queryContext->setContext('backend')
+        $this->queryContext->setContext(QueryContextType::BACKEND)
             ->setAccessTime(1459706700)
             ->setTableConfigs([
                 'pages' => [
@@ -846,7 +846,7 @@ class QueryRestrictionBuilderTest extends UnitTestCase
      */
     public function getBackendVisibilityRestrictionsWithIgnoreEnableFieldsSet()
     {
-        $this->queryContext->setContext('backend')
+        $this->queryContext->setContext(QueryContextType::BACKEND)
             ->setAccessTime(1459706700)
             ->setTableConfigs(['pages' => $this->defaultTableConfig])
             ->setIgnoreEnableFields(true);
@@ -868,7 +868,7 @@ class QueryRestrictionBuilderTest extends UnitTestCase
      */
     public function getBackendVisibilityRestrictionsWithIncludeDeletedSet()
     {
-        $this->queryContext->setContext('backend')
+        $this->queryContext->setContext(QueryContextType::BACKEND)
             ->setAccessTime(1459706700)
             ->setTableConfigs(['pages' => $this->defaultTableConfig])
             ->setIncludeDeleted(true);
@@ -892,9 +892,37 @@ class QueryRestrictionBuilderTest extends UnitTestCase
     /**
      * @test
      */
+    public function getBackendVisibilityRestrictionsWithNoVersionPlaceholdersContext()
+    {
+        $this->queryContext->setContext(QueryContextType::BACKEND_NO_VERSIONING_PLACEHOLDERS)
+            ->setCurrentWorkspace(4)
+            ->setAccessTime(1459706700)
+            ->setTableConfigs(['pages' => $this->defaultTableConfig]);
+
+        $subject = GeneralUtility::makeInstance(
+            QueryRestrictionBuilder::class,
+            ['pages' => ''],
+            $this->expressionBuilder,
+            $this->queryContext
+        );
+
+        $expectedSql = join(' AND ', [
+            'disabled' => '("pages"."hidden" = 0)',
+            'starttime' => '("pages"."starttime" <= 1459706700)',
+            'endtime' => '(("pages"."endtime" = 0) OR ("pages"."endtime" > 1459706700))',
+            'deleted' => '("pages"."deleted" = 0)',
+            'placeholders' => '(("pages"."t3ver_state" <= 0) OR ("pages"."t3ver_wsid" = 4))',
+        ]);
+
+        $this->assertSame($expectedSql, (string)$subject->getVisibilityConstraints());
+    }
+
+    /**
+     * @test
+     */
     public function getBackendVisibilityRestrictionsWithoutRestrictions()
     {
-        $this->queryContext->setContext('backend')
+        $this->queryContext->setContext(QueryContextType::BACKEND)
             ->setAccessTime(1459706700)
             ->setTableConfigs(['pages' => $this->defaultTableConfig])
             ->setIncludeDeleted(true)