From 7fad03490056615b32c3c0833d24c45af828c312 Mon Sep 17 00:00:00 2001 From: Benni Mack <benni@typo3.org> Date: Tue, 2 Jun 2020 19:47:15 +0200 Subject: [PATCH] [BUGFIX] Ensure proper encapsulation of comparisons with QueryBuilder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When using a TCA table without deleted, or any other enablefields except "endtime", then the SQL query is built in a wrong fashion both in PageRepository and BackendUtility. Thee source of this disaster is inproper encapsulation in parenthesis when comparisons are build. Instead of simply adding a manual "()" around the or() comparisons, this change adjusts CompositionExpresion to properly add corresponding parenthesis, which ensure this in every case and avoid missing usages. A couple of tests are adjusted to properly reflect this change. Resolves: #89616 Releases: main Change-Id: I4aed140cbca5b4b40dfacd459a4c3aa30549b582 Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/76481 Tested-by: core-ci <typo3@b13.com> Tested-by: Benni Mack <benni@typo3.org> Tested-by: Susanne Moog <look@susi.dev> Tested-by: Stefan Bürk <stefan@buerk.tech> Reviewed-by: Benni Mack <benni@typo3.org> Reviewed-by: Susanne Moog <look@susi.dev> Reviewed-by: Stefan Bürk <stefan@buerk.tech> --- .../Functional/Utility/BackendUtilityTest.php | 111 ++++++++++++++++-- .../Query/Expression/CompositeExpression.php | 2 +- .../Domain/Repository/PageRepositoryTest.php | 12 +- .../BackendUserAuthenticationTest.php | 10 +- .../Unit/Database/Query/QueryBuilderTest.php | 18 +-- .../DefaultRestrictionContainerTest.php | 2 +- .../Restriction/EndTimeRestrictionTest.php | 2 +- .../FrontendGroupRestrictionTest.php | 4 +- .../FrontendRestrictionContainerTest.php | 18 +-- .../LimitToTablesRestrictionContainerTest.php | 2 +- .../PagePermissionRestrictionTest.php | 4 +- .../Restriction/WorkspaceRestrictionTest.php | 8 +- .../BackendWorkspaceRestrictionTest.php | 8 +- .../FrontendWorkspaceRestrictionTest.php | 6 +- .../Storage/Typo3DbQueryParserTest.php | 84 +++++++++++-- 15 files changed, 225 insertions(+), 66 deletions(-) diff --git a/typo3/sysext/backend/Tests/Functional/Utility/BackendUtilityTest.php b/typo3/sysext/backend/Tests/Functional/Utility/BackendUtilityTest.php index 6c621433fd8f..4538ceca9f01 100644 --- a/typo3/sysext/backend/Tests/Functional/Utility/BackendUtilityTest.php +++ b/typo3/sysext/backend/Tests/Functional/Utility/BackendUtilityTest.php @@ -17,10 +17,14 @@ declare(strict_types=1); namespace TYPO3\CMS\Backend\Tests\Functional\Utility; +use Doctrine\DBAL\Platforms\PostgreSQLPlatform; +use Doctrine\DBAL\Platforms\SqlitePlatform; use TYPO3\CMS\Backend\Utility\BackendUtility; use TYPO3\CMS\Core\Authentication\BackendUserAuthentication; use TYPO3\CMS\Core\Core\Bootstrap; +use TYPO3\CMS\Core\Database\ConnectionPool; use TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait; +use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase; class BackendUtilityTest extends FunctionalTestCase @@ -33,13 +37,15 @@ class BackendUtilityTest extends FunctionalTestCase 'DE' => ['id' => 2, 'title' => 'German', 'locale' => 'de_DE.UTF8'], ]; + protected BackendUserAuthentication $backendUser; + public function setUp(): void { parent::setUp(); $this->importCSVDataSet(__DIR__ . '/../Fixtures/pages.csv'); $this->importCSVDataSet(__DIR__ . '/../Fixtures/tt_content.csv'); $this->importCSVDataSet(__DIR__ . '/../Fixtures/be_users.csv'); - $this->setUpBackendUser(1); + $this->backendUser = $this->setUpBackendUser(1); Bootstrap::initializeLanguageObject(); } @@ -48,8 +54,7 @@ class BackendUtilityTest extends FunctionalTestCase */ public function givenPageIdCanBeExpanded(): void { - $backendUser = $this->getBackendUser(); - $backendUser->groupData['webmounts'] = '1'; + $this->backendUser->groupData['webmounts'] = '1'; BackendUtility::openPageTree(5, false); @@ -58,7 +63,7 @@ class BackendUtilityTest extends FunctionalTestCase '1_1' => '1', '1_0' => '1', ]; - $actualSiteHash = $backendUser->uc['BackendComponents']['States']['Pagetree']['stateHash']; + $actualSiteHash = $this->backendUser->uc['BackendComponents']['States']['Pagetree']['stateHash']; self::assertSame($expectedSiteHash, $actualSiteHash); } @@ -67,8 +72,7 @@ class BackendUtilityTest extends FunctionalTestCase */ public function otherBranchesCanBeClosedWhenOpeningPage(): void { - $backendUser = $this->getBackendUser(); - $backendUser->groupData['webmounts'] = '1'; + $this->backendUser->groupData['webmounts'] = '1'; BackendUtility::openPageTree(5, false); BackendUtility::openPageTree(4, true); @@ -81,7 +85,7 @@ class BackendUtilityTest extends FunctionalTestCase '1_1' => '1', '1_0' => '1', ]; - $actualSiteHash = $backendUser->uc['BackendComponents']['States']['Pagetree']['stateHash']; + $actualSiteHash = $this->backendUser->uc['BackendComponents']['States']['Pagetree']['stateHash']; self::assertSame($expectedSiteHash, $actualSiteHash); } @@ -141,8 +145,97 @@ class BackendUtilityTest extends FunctionalTestCase ); } - private function getBackendUser(): BackendUserAuthentication + public function enableFieldsStatementIsCorrectDataProvider(): array { - return $GLOBALS['BE_USER']; + // Expected sql should contain identifier escaped in mysql/mariadb identifier quotings "`", which are + // replaced by corresponding quoting values for other database systems. + return [ + 'disabled' => [ + [ + 'disabled' => 'disabled', + ], + false, + ' AND `${tableName}`.`disabled` = 0', + ], + 'starttime' => [ + [ + 'starttime' => 'starttime', + ], + false, + ' AND `${tableName}`.`starttime` <= 1234567890', + ], + 'endtime' => [ + [ + 'endtime' => 'endtime', + ], + false, + ' AND ((`${tableName}`.`endtime` = 0) OR (`${tableName}`.`endtime` > 1234567890))', + ], + 'disabled, starttime, endtime' => [ + [ + 'disabled' => 'disabled', + 'starttime' => 'starttime', + 'endtime' => 'endtime', + ], + false, + ' AND ((`${tableName}`.`disabled` = 0) AND (`${tableName}`.`starttime` <= 1234567890) AND (((`${tableName}`.`endtime` = 0) OR (`${tableName}`.`endtime` > 1234567890))))', + ], + 'disabled inverted' => [ + [ + 'disabled' => 'disabled', + ], + true, + ' AND `${tableName}`.`disabled` <> 0', + ], + 'starttime inverted' => [ + [ + 'starttime' => 'starttime', + ], + true, + ' AND ((`${tableName}`.`starttime` <> 0) AND (`${tableName}`.`starttime` > 1234567890))', + ], + 'endtime inverted' => [ + [ + 'endtime' => 'endtime', + ], + true, + ' AND ((`${tableName}`.`endtime` <> 0) AND (`${tableName}`.`endtime` <= 1234567890))', + ], + 'disabled, starttime, endtime inverted' => [ + [ + 'disabled' => 'disabled', + 'starttime' => 'starttime', + 'endtime' => 'endtime', + ], + true, + ' AND ((`${tableName}`.`disabled` <> 0) OR (((`${tableName}`.`starttime` <> 0) AND (`${tableName}`.`starttime` > 1234567890))) OR (((`${tableName}`.`endtime` <> 0) AND (`${tableName}`.`endtime` <= 1234567890))))', + ], + ]; + } + + /** + * @param array $enableColumns + * @param bool $inverted + * @param string $expectation + * + * @test + * @dataProvider enableFieldsStatementIsCorrectDataProvider + */ + public function enableFieldsStatementIsCorrect(array $enableColumns, bool $inverted, string $expectation): void + { + $platform = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionByName(ConnectionPool::DEFAULT_CONNECTION_NAME)->getDatabasePlatform(); + $tableName = uniqid('table'); + $GLOBALS['TCA'][$tableName]['ctrl']['enablecolumns'] = $enableColumns; + $GLOBALS['SIM_ACCESS_TIME'] = 1234567890; + $statement = BackendUtility::BEenableFields($tableName, $inverted); + $replaces = [ + '${tableName}' => $tableName, + ]; + // replace mysql identifier quotings with sqlite identifier qotings in expected sql string + if ($platform instanceof SqlitePlatform || $platform instanceof PostgreSQLPlatform) { + $replaces['`'] = '"'; + } + $expectation = str_replace(array_keys($replaces), array_values($replaces), $expectation); + self::assertSame($expectation, $statement); } } diff --git a/typo3/sysext/core/Classes/Database/Query/Expression/CompositeExpression.php b/typo3/sysext/core/Classes/Database/Query/Expression/CompositeExpression.php index dfd312585a5b..5ffc73212770 100644 --- a/typo3/sysext/core/Classes/Database/Query/Expression/CompositeExpression.php +++ b/typo3/sysext/core/Classes/Database/Query/Expression/CompositeExpression.php @@ -194,6 +194,6 @@ class CompositeExpression extends \Doctrine\DBAL\Query\Expression\CompositeExpre if ($this->count() === 1) { return (string)$this->parts[0]; } - return '(' . implode(') ' . $this->type . ' (', $this->parts) . ')'; + return '((' . implode(') ' . $this->type . ' (', $this->parts) . '))'; } } diff --git a/typo3/sysext/core/Tests/Functional/Domain/Repository/PageRepositoryTest.php b/typo3/sysext/core/Tests/Functional/Domain/Repository/PageRepositoryTest.php index 7c56fe219645..a4b4f784feca 100644 --- a/typo3/sysext/core/Tests/Functional/Domain/Repository/PageRepositoryTest.php +++ b/typo3/sysext/core/Tests/Functional/Domain/Repository/PageRepositoryTest.php @@ -394,7 +394,7 @@ class PageRepositoryTest extends FunctionalTestCase $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('pages'); $expectedSQL = sprintf( - ' AND (%s = 0) AND ((%s = 0) OR (%s = 2)) AND (%s <> 255)', + ' AND ((%s = 0) AND (((%s = 0) OR (%s = 2))) AND (%s <> 255))', $connection->quoteIdentifier('pages.deleted'), $connection->quoteIdentifier('pages.t3ver_wsid'), $connection->quoteIdentifier('pages.t3ver_wsid'), @@ -415,7 +415,7 @@ class PageRepositoryTest extends FunctionalTestCase $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('pages'); $expectedSQL = sprintf( - ' AND ((%s = 0) AND (%s <= 0) AND (%s = 0) AND ((%s = 0) OR (%s = 4)) AND (%s = 0) AND (%s <= 1451779200) AND ((%s = 0) OR (%s > 1451779200))) AND (%s <> 255)', + ' AND ((((%s = 0) AND (%s <= 0) AND (%s = 0) AND (((%s = 0) OR (%s = 4))) AND (%s = 0) AND (%s <= 1451779200) AND (((%s = 0) OR (%s > 1451779200))))) AND (%s <> 255))', $connection->quoteIdentifier('pages.deleted'), $connection->quoteIdentifier('pages.t3ver_state'), $connection->quoteIdentifier('pages.t3ver_wsid'), @@ -529,12 +529,12 @@ class PageRepositoryTest extends FunctionalTestCase self::assertThat( $conditions, - self::stringContains(' AND (' . $connection->quoteIdentifier($table . '.t3ver_state') . ' <= 0)'), + self::stringContains(' AND ((' . $connection->quoteIdentifier($table . '.t3ver_state') . ' <= 0) '), 'Versioning placeholders' ); self::assertThat( $conditions, - self::stringContains(' AND ((' . $connection->quoteIdentifier($table . '.t3ver_oid') . ' = 0) OR (' . $connection->quoteIdentifier($table . '.t3ver_state') . ' = 4))'), + self::stringContains(' AND (((' . $connection->quoteIdentifier($table . '.t3ver_oid') . ' = 0) OR (' . $connection->quoteIdentifier($table . '.t3ver_state') . ' = 4)))'), 'Records with online version' ); } @@ -565,7 +565,7 @@ class PageRepositoryTest extends FunctionalTestCase ); self::assertThat( $conditions, - self::stringContains(' AND ((' . $connection->quoteIdentifier($table . '.t3ver_oid') . ' = 0) OR (' . $connection->quoteIdentifier($table . '.t3ver_state') . ' = 4))'), + self::stringContains(' AND (((' . $connection->quoteIdentifier($table . '.t3ver_oid') . ' = 0) OR (' . $connection->quoteIdentifier($table . '.t3ver_state') . ' = 4)))'), 'Records from online versions' ); } @@ -591,7 +591,7 @@ class PageRepositoryTest extends FunctionalTestCase self::assertThat( $conditions, - self::stringContains(' AND ((' . $connection->quoteIdentifier($table . '.t3ver_wsid') . ' = 0) OR (' . $connection->quoteIdentifier($table . '.t3ver_wsid') . ' = 2))'), + self::stringContains(' AND ((((' . $connection->quoteIdentifier($table . '.t3ver_wsid') . ' = 0) OR (' . $connection->quoteIdentifier($table . '.t3ver_wsid') . ' = 2)))'), 'No versioning placeholders' ); } diff --git a/typo3/sysext/core/Tests/Unit/Authentication/BackendUserAuthenticationTest.php b/typo3/sysext/core/Tests/Unit/Authentication/BackendUserAuthenticationTest.php index bef98e1b56a5..a67ed5824ea0 100644 --- a/typo3/sysext/core/Tests/Unit/Authentication/BackendUserAuthenticationTest.php +++ b/typo3/sysext/core/Tests/Unit/Authentication/BackendUserAuthenticationTest.php @@ -659,16 +659,16 @@ class BackendUserAuthenticationTest extends UnitTestCase 2, false, [], - ' ((`pages`.`perms_everybody` & 2 = 2) OR' . - ' ((`pages`.`perms_userid` = 123) AND (`pages`.`perms_user` & 2 = 2)))', + ' (((`pages`.`perms_everybody` & 2 = 2) OR' . + ' (((`pages`.`perms_userid` = 123) AND (`pages`.`perms_user` & 2 = 2)))))', ], 'for user with groups' => [ 8, false, [1, 2], - ' ((`pages`.`perms_everybody` & 8 = 8) OR' . - ' ((`pages`.`perms_userid` = 123) AND (`pages`.`perms_user` & 8 = 8))' . - ' OR ((`pages`.`perms_groupid` IN (1, 2)) AND (`pages`.`perms_group` & 8 = 8)))', + ' (((`pages`.`perms_everybody` & 8 = 8) OR' . + ' (((`pages`.`perms_userid` = 123) AND (`pages`.`perms_user` & 8 = 8)))' . + ' OR (((`pages`.`perms_groupid` IN (1, 2)) AND (`pages`.`perms_group` & 8 = 8)))))', ], ]; } diff --git a/typo3/sysext/core/Tests/Unit/Database/Query/QueryBuilderTest.php b/typo3/sysext/core/Tests/Unit/Database/Query/QueryBuilderTest.php index ce4ca0e681e2..2aea13b50ee0 100644 --- a/typo3/sysext/core/Tests/Unit/Database/Query/QueryBuilderTest.php +++ b/typo3/sysext/core/Tests/Unit/Database/Query/QueryBuilderTest.php @@ -961,7 +961,7 @@ class QueryBuilderTest extends UnitTestCase ->from('pages') ->where('uid=1'); - $expectedSQL = 'SELECT * FROM pages WHERE (uid=1) AND ((pages.deleted = 0) AND (pages.hidden = 0))'; + $expectedSQL = 'SELECT * FROM pages WHERE (uid=1) AND (((pages.deleted = 0) AND (pages.hidden = 0)))'; $this->connection->executeQuery($expectedSQL, Argument::cetera()) ->willReturn($this->prophesize(Result::class)->reveal()); @@ -1008,7 +1008,7 @@ class QueryBuilderTest extends UnitTestCase ->from('pages') ->where('uid=1'); - $expectedSQL = 'SELECT COUNT(uid) FROM pages WHERE (uid=1) AND ((pages.deleted = 0) AND (pages.hidden = 0))'; + $expectedSQL = 'SELECT COUNT(uid) FROM pages WHERE (uid=1) AND (((pages.deleted = 0) AND (pages.hidden = 0)))'; $this->connection->executeQuery($expectedSQL, Argument::cetera()) ->willReturn($this->prophesize(Result::class)->reveal()); @@ -1053,7 +1053,7 @@ class QueryBuilderTest extends UnitTestCase ->from('pages') ->where('uid=1'); - $expectedSQL = 'SELECT * FROM pages WHERE (uid=1) AND ((pages.deleted = 0) AND (pages.hidden = 0))'; + $expectedSQL = 'SELECT * FROM pages WHERE (uid=1) AND (((pages.deleted = 0) AND (pages.hidden = 0)))'; self::assertSame($expectedSQL, $subject->getSQL()); $subject->getRestrictions()->removeAll()->add(new DeletedRestriction()); @@ -1110,7 +1110,7 @@ class QueryBuilderTest extends UnitTestCase $subject->resetRestrictions(); - $expectedSQL = 'SELECT * FROM pages WHERE (uid=1) AND ((pages.deleted = 0) AND (pages.hidden = 0))'; + $expectedSQL = 'SELECT * FROM pages WHERE (uid=1) AND (((pages.deleted = 0) AND (pages.hidden = 0)))'; $this->connection->executeQuery($expectedSQL, Argument::cetera()) ->willReturn($this->prophesize(Result::class)->reveal()); @@ -1246,7 +1246,7 @@ class QueryBuilderTest extends UnitTestCase ->from('pages') ->where('uid=1'); - $expectedSQL = 'SELECT * FROM pages WHERE (uid=1) AND ((pages.deleted = 0) AND (pages.hidden = 0))'; + $expectedSQL = 'SELECT * FROM pages WHERE (uid=1) AND (((pages.deleted = 0) AND (pages.hidden = 0)))'; self::assertSame($expectedSQL, $subject->getSQL()); $clonedQueryBuilder = clone $subject; @@ -1255,7 +1255,7 @@ class QueryBuilderTest extends UnitTestCase //change cloned QueryBuilder $clonedQueryBuilder->count('*'); - $expectedCountSQL = 'SELECT COUNT(*) FROM pages WHERE (uid=1) AND ((pages.deleted = 0) AND (pages.hidden = 0))'; + $expectedCountSQL = 'SELECT COUNT(*) FROM pages WHERE (uid=1) AND (((pages.deleted = 0) AND (pages.hidden = 0)))'; self::assertSame($expectedCountSQL, $clonedQueryBuilder->getSQL()); //check if the original QueryBuilder has not changed @@ -1478,7 +1478,7 @@ class QueryBuilderTest extends UnitTestCase ->where($expressionBuilder->eq('uid', 1)); $this->connection->executeQuery( - 'SELECT * FROM pages LEFT JOIN tt_content content ON pages.uid = content.pid WHERE (uid = 1) AND ((pages.deleted = 0) AND (pages.hidden = 0))', + 'SELECT * FROM pages LEFT JOIN tt_content content ON pages.uid = content.pid WHERE (uid = 1) AND (((pages.deleted = 0) AND (pages.hidden = 0)))', Argument::cetera() )->willReturn($this->prophesize(Result::class)->reveal()); @@ -1578,7 +1578,7 @@ class QueryBuilderTest extends UnitTestCase ->where($expressionBuilder->eq('uid', 1)); $this->connection->executeQuery( - 'SELECT * FROM pages LEFT JOIN tt_content content ON (pages.uid = content.pid) AND ((content.deleted = 0) AND (content.hidden = 0)) WHERE (uid = 1) AND ((pages.deleted = 0) AND (pages.hidden = 0))', + 'SELECT * FROM pages LEFT JOIN tt_content content ON ((pages.uid = content.pid) AND (((content.deleted = 0) AND (content.hidden = 0)))) WHERE (uid = 1) AND (((pages.deleted = 0) AND (pages.hidden = 0)))', Argument::cetera() )->willReturn($this->prophesize(Result::class)->reveal()); @@ -1627,7 +1627,7 @@ class QueryBuilderTest extends UnitTestCase ->where($expressionBuilder->eq('uid', 1)); $this->connection->executeQuery( - 'SELECT * FROM tt_content RIGHT JOIN pages pages ON (pages.uid = tt_content.pid) AND ((tt_content.deleted = 0) AND (tt_content.hidden = 0)) WHERE (uid = 1) AND ((pages.deleted = 0) AND (pages.hidden = 0))', + 'SELECT * FROM tt_content RIGHT JOIN pages pages ON ((pages.uid = tt_content.pid) AND (((tt_content.deleted = 0) AND (tt_content.hidden = 0)))) WHERE (uid = 1) AND (((pages.deleted = 0) AND (pages.hidden = 0)))', Argument::cetera() )->willReturn($this->prophesize(Result::class)->reveal()); diff --git a/typo3/sysext/core/Tests/Unit/Database/Query/Restriction/DefaultRestrictionContainerTest.php b/typo3/sysext/core/Tests/Unit/Database/Query/Restriction/DefaultRestrictionContainerTest.php index 45cae38374ed..28461547bc43 100644 --- a/typo3/sysext/core/Tests/Unit/Database/Query/Restriction/DefaultRestrictionContainerTest.php +++ b/typo3/sysext/core/Tests/Unit/Database/Query/Restriction/DefaultRestrictionContainerTest.php @@ -39,6 +39,6 @@ class DefaultRestrictionContainerTest extends AbstractRestrictionTestCase $expression = $subject->buildExpression(['aTable' => 'aTable'], $this->expressionBuilder); $expression = $this->expressionBuilder->and($expression); - self::assertSame('("aTable"."deleted" = 0) AND ("aTable"."myHiddenField" = 0) AND ("aTable"."myStartTimeField" <= 123) AND (("aTable"."myEndTimeField" = 0) OR ("aTable"."myEndTimeField" > 123))', (string)$expression); + self::assertSame('(("aTable"."deleted" = 0) AND ("aTable"."myHiddenField" = 0) AND ("aTable"."myStartTimeField" <= 123) AND ((("aTable"."myEndTimeField" = 0) OR ("aTable"."myEndTimeField" > 123))))', (string)$expression); } } diff --git a/typo3/sysext/core/Tests/Unit/Database/Query/Restriction/EndTimeRestrictionTest.php b/typo3/sysext/core/Tests/Unit/Database/Query/Restriction/EndTimeRestrictionTest.php index d49fe7edf7f9..ddb487b1dd3e 100644 --- a/typo3/sysext/core/Tests/Unit/Database/Query/Restriction/EndTimeRestrictionTest.php +++ b/typo3/sysext/core/Tests/Unit/Database/Query/Restriction/EndTimeRestrictionTest.php @@ -53,6 +53,6 @@ class EndTimeRestrictionTest extends AbstractRestrictionTestCase $subject = new EndTimeRestriction(42); $expression = $subject->buildExpression(['aTable' => 'aTable'], $this->expressionBuilder); - self::assertSame('("aTable"."myEndTimeField" = 0) OR ("aTable"."myEndTimeField" > 42)', (string)$expression); + self::assertSame('(("aTable"."myEndTimeField" = 0) OR ("aTable"."myEndTimeField" > 42))', (string)$expression); } } diff --git a/typo3/sysext/core/Tests/Unit/Database/Query/Restriction/FrontendGroupRestrictionTest.php b/typo3/sysext/core/Tests/Unit/Database/Query/Restriction/FrontendGroupRestrictionTest.php index a421568868b8..7192d4de1bfc 100644 --- a/typo3/sysext/core/Tests/Unit/Database/Query/Restriction/FrontendGroupRestrictionTest.php +++ b/typo3/sysext/core/Tests/Unit/Database/Query/Restriction/FrontendGroupRestrictionTest.php @@ -33,7 +33,7 @@ class FrontendGroupRestrictionTest extends AbstractRestrictionTestCase ]; $subject = new FrontendGroupRestriction([]); $expression = $subject->buildExpression(['aTable' => 'aTable'], $this->expressionBuilder); - self::assertSame('("aTable"."myGroupField" IS NULL) OR ("aTable"."myGroupField" = \'\') OR ("aTable"."myGroupField" = \'0\')', (string)$expression); + self::assertSame('(("aTable"."myGroupField" IS NULL) OR ("aTable"."myGroupField" = \'\') OR ("aTable"."myGroupField" = \'0\'))', (string)$expression); } /** @@ -48,6 +48,6 @@ class FrontendGroupRestrictionTest extends AbstractRestrictionTestCase ]; $subject = new FrontendGroupRestriction([2, 3]); $expression = $subject->buildExpression(['aTable' => 'aTable'], $this->expressionBuilder); - self::assertSame('("aTable"."myGroupField" IS NULL) OR ("aTable"."myGroupField" = \'\') OR ("aTable"."myGroupField" = \'0\') OR (FIND_IN_SET(\'2\', "aTable"."myGroupField")) OR (FIND_IN_SET(\'3\', "aTable"."myGroupField"))', (string)$expression); + self::assertSame('(("aTable"."myGroupField" IS NULL) OR ("aTable"."myGroupField" = \'\') OR ("aTable"."myGroupField" = \'0\') OR (FIND_IN_SET(\'2\', "aTable"."myGroupField")) OR (FIND_IN_SET(\'3\', "aTable"."myGroupField")))', (string)$expression); } } diff --git a/typo3/sysext/core/Tests/Unit/Database/Query/Restriction/FrontendRestrictionContainerTest.php b/typo3/sysext/core/Tests/Unit/Database/Query/Restriction/FrontendRestrictionContainerTest.php index a94b67973dc3..241ff6a3af18 100644 --- a/typo3/sysext/core/Tests/Unit/Database/Query/Restriction/FrontendRestrictionContainerTest.php +++ b/typo3/sysext/core/Tests/Unit/Database/Query/Restriction/FrontendRestrictionContainerTest.php @@ -39,7 +39,7 @@ class FrontendRestrictionContainerTest extends AbstractRestrictionTestCase 'hiddenPagePreview' => false, 'hiddenRecordPreview' => false, 'frontendUserGroups' => [0, -1], - 'expectedSQL' => '("aTable"."deleted" = 0) AND (("aTable"."t3ver_wsid" = 0) AND (("aTable"."t3ver_oid" = 0) OR ("aTable"."t3ver_state" = 4))) AND ("aTable"."myHiddenField" = 0) AND ("aTable"."myStartTimeField" <= 42) AND (("aTable"."myEndTimeField" = 0) OR ("aTable"."myEndTimeField" > 42)) AND (("aTable"."myGroupField" IS NULL) OR ("aTable"."myGroupField" = \'\') OR ("aTable"."myGroupField" = \'0\') OR (FIND_IN_SET(\'0\', "aTable"."myGroupField")) OR (FIND_IN_SET(\'-1\', "aTable"."myGroupField")))', + 'expectedSQL' => '(("aTable"."deleted" = 0) AND ((("aTable"."t3ver_wsid" = 0) AND ((("aTable"."t3ver_oid" = 0) OR ("aTable"."t3ver_state" = 4))))) AND ("aTable"."myHiddenField" = 0) AND ("aTable"."myStartTimeField" <= 42) AND ((("aTable"."myEndTimeField" = 0) OR ("aTable"."myEndTimeField" > 42))) AND ((("aTable"."myGroupField" IS NULL) OR ("aTable"."myGroupField" = \'\') OR ("aTable"."myGroupField" = \'0\') OR (FIND_IN_SET(\'0\', "aTable"."myGroupField")) OR (FIND_IN_SET(\'-1\', "aTable"."myGroupField")))))', ], 'Live, with hidden record preview' => [ 'tableName' => 'aTable', @@ -48,7 +48,7 @@ class FrontendRestrictionContainerTest extends AbstractRestrictionTestCase 'hiddenPagePreview' => true, 'hiddenRecordPreview' => true, 'frontendUserGroups' => [0, -1], - 'expectedSQL' => '("aTable"."deleted" = 0) AND (("aTable"."t3ver_wsid" = 0) AND (("aTable"."t3ver_oid" = 0) OR ("aTable"."t3ver_state" = 4))) AND ("aTable"."myStartTimeField" <= 42) AND (("aTable"."myEndTimeField" = 0) OR ("aTable"."myEndTimeField" > 42)) AND (("aTable"."myGroupField" IS NULL) OR ("aTable"."myGroupField" = \'\') OR ("aTable"."myGroupField" = \'0\') OR (FIND_IN_SET(\'0\', "aTable"."myGroupField")) OR (FIND_IN_SET(\'-1\', "aTable"."myGroupField")))', + 'expectedSQL' => '(("aTable"."deleted" = 0) AND ((("aTable"."t3ver_wsid" = 0) AND ((("aTable"."t3ver_oid" = 0) OR ("aTable"."t3ver_state" = 4))))) AND ("aTable"."myStartTimeField" <= 42) AND ((("aTable"."myEndTimeField" = 0) OR ("aTable"."myEndTimeField" > 42))) AND ((("aTable"."myGroupField" IS NULL) OR ("aTable"."myGroupField" = \'\') OR ("aTable"."myGroupField" = \'0\') OR (FIND_IN_SET(\'0\', "aTable"."myGroupField")) OR (FIND_IN_SET(\'-1\', "aTable"."myGroupField")))))', ], 'Workspace, with WS preview' => [ 'tableName' => 'aTable', @@ -57,7 +57,7 @@ class FrontendRestrictionContainerTest extends AbstractRestrictionTestCase 'hiddenPagePreview' => false, 'hiddenRecordPreview' => false, 'frontendUserGroups' => [0, -1], - 'expectedSQL' => '("aTable"."deleted" = 0) AND (("aTable"."t3ver_wsid" IN (0, 1)) AND (("aTable"."t3ver_oid" = 0) OR ("aTable"."t3ver_state" = 4))) AND ("aTable"."myHiddenField" = 0) AND ("aTable"."myStartTimeField" <= 42) AND (("aTable"."myEndTimeField" = 0) OR ("aTable"."myEndTimeField" > 42)) AND (("aTable"."myGroupField" IS NULL) OR ("aTable"."myGroupField" = \'\') OR ("aTable"."myGroupField" = \'0\') OR (FIND_IN_SET(\'0\', "aTable"."myGroupField")) OR (FIND_IN_SET(\'-1\', "aTable"."myGroupField")))', + 'expectedSQL' => '(("aTable"."deleted" = 0) AND ((("aTable"."t3ver_wsid" IN (0, 1)) AND ((("aTable"."t3ver_oid" = 0) OR ("aTable"."t3ver_state" = 4))))) AND ("aTable"."myHiddenField" = 0) AND ("aTable"."myStartTimeField" <= 42) AND ((("aTable"."myEndTimeField" = 0) OR ("aTable"."myEndTimeField" > 42))) AND ((("aTable"."myGroupField" IS NULL) OR ("aTable"."myGroupField" = \'\') OR ("aTable"."myGroupField" = \'0\') OR (FIND_IN_SET(\'0\', "aTable"."myGroupField")) OR (FIND_IN_SET(\'-1\', "aTable"."myGroupField")))))', ], 'Workspace, with WS preview and hidden record preview' => [ 'tableName' => 'aTable', @@ -66,7 +66,7 @@ class FrontendRestrictionContainerTest extends AbstractRestrictionTestCase 'hiddenPagePreview' => true, 'hiddenRecordPreview' => true, 'frontendUserGroups' => [0, -1], - 'expectedSQL' => '("aTable"."deleted" = 0) AND (("aTable"."t3ver_wsid" IN (0, 1)) AND (("aTable"."t3ver_oid" = 0) OR ("aTable"."t3ver_state" = 4))) AND ("aTable"."myStartTimeField" <= 42) AND (("aTable"."myEndTimeField" = 0) OR ("aTable"."myEndTimeField" > 42)) AND (("aTable"."myGroupField" IS NULL) OR ("aTable"."myGroupField" = \'\') OR ("aTable"."myGroupField" = \'0\') OR (FIND_IN_SET(\'0\', "aTable"."myGroupField")) OR (FIND_IN_SET(\'-1\', "aTable"."myGroupField")))', + 'expectedSQL' => '(("aTable"."deleted" = 0) AND ((("aTable"."t3ver_wsid" IN (0, 1)) AND ((("aTable"."t3ver_oid" = 0) OR ("aTable"."t3ver_state" = 4))))) AND ("aTable"."myStartTimeField" <= 42) AND ((("aTable"."myEndTimeField" = 0) OR ("aTable"."myEndTimeField" > 42))) AND ((("aTable"."myGroupField" IS NULL) OR ("aTable"."myGroupField" = \'\') OR ("aTable"."myGroupField" = \'0\') OR (FIND_IN_SET(\'0\', "aTable"."myGroupField")) OR (FIND_IN_SET(\'-1\', "aTable"."myGroupField")))))', ], 'Live page, no preview' => [ 'tableName' => 'pages', @@ -75,7 +75,7 @@ class FrontendRestrictionContainerTest extends AbstractRestrictionTestCase 'hiddenPagePreview' => false, 'hiddenRecordPreview' => false, 'frontendUserGroups' => [0, -1], - 'expectedSQL' => '("pages"."deleted" = 0) AND (("pages"."t3ver_wsid" = 0) AND (("pages"."t3ver_oid" = 0) OR ("pages"."t3ver_state" = 4))) AND ("pages"."hidden" = 0) AND ("pages"."starttime" <= 42) AND (("pages"."endtime" = 0) OR ("pages"."endtime" > 42)) AND (("pages"."fe_group" IS NULL) OR ("pages"."fe_group" = \'\') OR ("pages"."fe_group" = \'0\') OR (FIND_IN_SET(\'0\', "pages"."fe_group")) OR (FIND_IN_SET(\'-1\', "pages"."fe_group")))', + 'expectedSQL' => '(("pages"."deleted" = 0) AND ((("pages"."t3ver_wsid" = 0) AND ((("pages"."t3ver_oid" = 0) OR ("pages"."t3ver_state" = 4))))) AND ("pages"."hidden" = 0) AND ("pages"."starttime" <= 42) AND ((("pages"."endtime" = 0) OR ("pages"."endtime" > 42))) AND ((("pages"."fe_group" IS NULL) OR ("pages"."fe_group" = \'\') OR ("pages"."fe_group" = \'0\') OR (FIND_IN_SET(\'0\', "pages"."fe_group")) OR (FIND_IN_SET(\'-1\', "pages"."fe_group")))))', ], 'Live page, with hidden page preview' => [ 'tableName' => 'pages', @@ -84,7 +84,7 @@ class FrontendRestrictionContainerTest extends AbstractRestrictionTestCase 'hiddenPagePreview' => true, 'hiddenRecordPreview' => true, 'frontendUserGroups' => [0, -1], - 'expectedSQL' => '("pages"."deleted" = 0) AND (("pages"."t3ver_wsid" = 0) AND (("pages"."t3ver_oid" = 0) OR ("pages"."t3ver_state" = 4))) AND ("pages"."starttime" <= 42) AND (("pages"."endtime" = 0) OR ("pages"."endtime" > 42)) AND (("pages"."fe_group" IS NULL) OR ("pages"."fe_group" = \'\') OR ("pages"."fe_group" = \'0\') OR (FIND_IN_SET(\'0\', "pages"."fe_group")) OR (FIND_IN_SET(\'-1\', "pages"."fe_group")))', + 'expectedSQL' => '(("pages"."deleted" = 0) AND ((("pages"."t3ver_wsid" = 0) AND ((("pages"."t3ver_oid" = 0) OR ("pages"."t3ver_state" = 4))))) AND ("pages"."starttime" <= 42) AND ((("pages"."endtime" = 0) OR ("pages"."endtime" > 42))) AND ((("pages"."fe_group" IS NULL) OR ("pages"."fe_group" = \'\') OR ("pages"."fe_group" = \'0\') OR (FIND_IN_SET(\'0\', "pages"."fe_group")) OR (FIND_IN_SET(\'-1\', "pages"."fe_group")))))', ], 'Workspace page, with WS preview' => [ 'tableName' => 'pages', @@ -93,7 +93,7 @@ class FrontendRestrictionContainerTest extends AbstractRestrictionTestCase 'hiddenPagePreview' => false, 'hiddenRecordPreview' => false, 'frontendUserGroups' => [0, -1], - 'expectedSQL' => '("pages"."deleted" = 0) AND (("pages"."t3ver_wsid" IN (0, 1)) AND (("pages"."t3ver_oid" = 0) OR ("pages"."t3ver_state" = 4))) AND ("pages"."hidden" = 0) AND ("pages"."starttime" <= 42) AND (("pages"."endtime" = 0) OR ("pages"."endtime" > 42)) AND (("pages"."fe_group" IS NULL) OR ("pages"."fe_group" = \'\') OR ("pages"."fe_group" = \'0\') OR (FIND_IN_SET(\'0\', "pages"."fe_group")) OR (FIND_IN_SET(\'-1\', "pages"."fe_group")))', + 'expectedSQL' => '(("pages"."deleted" = 0) AND ((("pages"."t3ver_wsid" IN (0, 1)) AND ((("pages"."t3ver_oid" = 0) OR ("pages"."t3ver_state" = 4))))) AND ("pages"."hidden" = 0) AND ("pages"."starttime" <= 42) AND ((("pages"."endtime" = 0) OR ("pages"."endtime" > 42))) AND ((("pages"."fe_group" IS NULL) OR ("pages"."fe_group" = \'\') OR ("pages"."fe_group" = \'0\') OR (FIND_IN_SET(\'0\', "pages"."fe_group")) OR (FIND_IN_SET(\'-1\', "pages"."fe_group")))))', ], 'Workspace page, with WS preview and hidden pages preview' => [ 'tableName' => 'pages', @@ -102,7 +102,7 @@ class FrontendRestrictionContainerTest extends AbstractRestrictionTestCase 'hiddenPagePreview' => true, 'hiddenRecordPreview' => true, 'frontendUserGroups' => [0, -1], - 'expectedSQL' => '("pages"."deleted" = 0) AND (("pages"."t3ver_wsid" IN (0, 1)) AND (("pages"."t3ver_oid" = 0) OR ("pages"."t3ver_state" = 4))) AND ("pages"."starttime" <= 42) AND (("pages"."endtime" = 0) OR ("pages"."endtime" > 42)) AND (("pages"."fe_group" IS NULL) OR ("pages"."fe_group" = \'\') OR ("pages"."fe_group" = \'0\') OR (FIND_IN_SET(\'0\', "pages"."fe_group")) OR (FIND_IN_SET(\'-1\', "pages"."fe_group")))', + 'expectedSQL' => '(("pages"."deleted" = 0) AND ((("pages"."t3ver_wsid" IN (0, 1)) AND ((("pages"."t3ver_oid" = 0) OR ("pages"."t3ver_state" = 4))))) AND ("pages"."starttime" <= 42) AND ((("pages"."endtime" = 0) OR ("pages"."endtime" > 42))) AND ((("pages"."fe_group" IS NULL) OR ("pages"."fe_group" = \'\') OR ("pages"."fe_group" = \'0\') OR (FIND_IN_SET(\'0\', "pages"."fe_group")) OR (FIND_IN_SET(\'-1\', "pages"."fe_group")))))', ], 'Live, no preview with alias' => [ 'tableName' => 'aTable', @@ -111,7 +111,7 @@ class FrontendRestrictionContainerTest extends AbstractRestrictionTestCase 'hiddenPagePreview' => false, 'hiddenRecordPreview' => false, 'frontendUserGroups' => [0, -1], - 'expectedSQL' => '("a"."deleted" = 0) AND (("a"."t3ver_wsid" = 0) AND (("a"."t3ver_oid" = 0) OR ("a"."t3ver_state" = 4))) AND ("a"."myHiddenField" = 0) AND ("a"."myStartTimeField" <= 42) AND (("a"."myEndTimeField" = 0) OR ("a"."myEndTimeField" > 42)) AND (("a"."myGroupField" IS NULL) OR ("a"."myGroupField" = \'\') OR ("a"."myGroupField" = \'0\') OR (FIND_IN_SET(\'0\', "a"."myGroupField")) OR (FIND_IN_SET(\'-1\', "a"."myGroupField")))', + 'expectedSQL' => '(("a"."deleted" = 0) AND ((("a"."t3ver_wsid" = 0) AND ((("a"."t3ver_oid" = 0) OR ("a"."t3ver_state" = 4))))) AND ("a"."myHiddenField" = 0) AND ("a"."myStartTimeField" <= 42) AND ((("a"."myEndTimeField" = 0) OR ("a"."myEndTimeField" > 42))) AND ((("a"."myGroupField" IS NULL) OR ("a"."myGroupField" = \'\') OR ("a"."myGroupField" = \'0\') OR (FIND_IN_SET(\'0\', "a"."myGroupField")) OR (FIND_IN_SET(\'-1\', "a"."myGroupField")))))', ], ]; } diff --git a/typo3/sysext/core/Tests/Unit/Database/Query/Restriction/LimitToTablesRestrictionContainerTest.php b/typo3/sysext/core/Tests/Unit/Database/Query/Restriction/LimitToTablesRestrictionContainerTest.php index 327e5930bdd9..5e00a89b05f3 100644 --- a/typo3/sysext/core/Tests/Unit/Database/Query/Restriction/LimitToTablesRestrictionContainerTest.php +++ b/typo3/sysext/core/Tests/Unit/Database/Query/Restriction/LimitToTablesRestrictionContainerTest.php @@ -52,7 +52,7 @@ class LimitToTablesRestrictionContainerTest extends AbstractRestrictionTestCase $subject->addForTables(new DefaultRestrictionContainer(), ['bt']); $expression = $subject->buildExpression(['aTable' => 'aTable', 'bTable' => 'bTable', 'bt' => 'bTable'], $this->expressionBuilder); - self::assertSame('("bt"."deleted" = 0) AND ("bt"."hidden" = 0)', (string)$expression); + self::assertSame('(("bt"."deleted" = 0) AND ("bt"."hidden" = 0))', (string)$expression); } /** diff --git a/typo3/sysext/core/Tests/Unit/Database/Query/Restriction/PagePermissionRestrictionTest.php b/typo3/sysext/core/Tests/Unit/Database/Query/Restriction/PagePermissionRestrictionTest.php index c841c9d54a31..ec13799a9651 100644 --- a/typo3/sysext/core/Tests/Unit/Database/Query/Restriction/PagePermissionRestrictionTest.php +++ b/typo3/sysext/core/Tests/Unit/Database/Query/Restriction/PagePermissionRestrictionTest.php @@ -111,7 +111,7 @@ class PagePermissionRestrictionTest extends AbstractRestrictionTestCase $aspect = $this->getPreparedUserAspect(true, false, 2, [13, 14, 15, 16]); $subject = new PagePermissionRestriction($aspect, Permission::PAGE_SHOW); $expression = $subject->buildExpression(['pages' => 'pages'], $this->expressionBuilder); - self::assertEquals('("pages"."perms_everybody" & 1 = 1) OR (("pages"."perms_userid" = 2) AND ("pages"."perms_user" & 1 = 1)) OR (("pages"."perms_groupid" IN (13, 14, 15, 16)) AND ("pages"."perms_group" & 1 = 1))', (string)$expression); + self::assertEquals('(("pages"."perms_everybody" & 1 = 1) OR ((("pages"."perms_userid" = 2) AND ("pages"."perms_user" & 1 = 1))) OR ((("pages"."perms_groupid" IN (13, 14, 15, 16)) AND ("pages"."perms_group" & 1 = 1))))', (string)$expression); } /** @@ -122,6 +122,6 @@ class PagePermissionRestrictionTest extends AbstractRestrictionTestCase $aspect = $this->getPreparedUserAspect(true, false, 42, [13, 14, 15, 16]); $subject = new PagePermissionRestriction($aspect, Permission::PAGE_DELETE); $expression = $subject->buildExpression(['pages' => 'pages'], $this->expressionBuilder); - self::assertEquals('("pages"."perms_everybody" & 4 = 4) OR (("pages"."perms_userid" = 42) AND ("pages"."perms_user" & 4 = 4)) OR (("pages"."perms_groupid" IN (13, 14, 15, 16)) AND ("pages"."perms_group" & 4 = 4))', (string)$expression); + self::assertEquals('(("pages"."perms_everybody" & 4 = 4) OR ((("pages"."perms_userid" = 42) AND ("pages"."perms_user" & 4 = 4))) OR ((("pages"."perms_groupid" IN (13, 14, 15, 16)) AND ("pages"."perms_group" & 4 = 4))))', (string)$expression); } } diff --git a/typo3/sysext/core/Tests/Unit/Database/Query/Restriction/WorkspaceRestrictionTest.php b/typo3/sysext/core/Tests/Unit/Database/Query/Restriction/WorkspaceRestrictionTest.php index 2b4c27b09867..3df2568b1d2f 100644 --- a/typo3/sysext/core/Tests/Unit/Database/Query/Restriction/WorkspaceRestrictionTest.php +++ b/typo3/sysext/core/Tests/Unit/Database/Query/Restriction/WorkspaceRestrictionTest.php @@ -31,7 +31,7 @@ class WorkspaceRestrictionTest extends AbstractRestrictionTestCase ]; $subject = new WorkspaceRestriction(0); $expression = $subject->buildExpression(['aTable' => 'aTable'], $this->expressionBuilder); - self::assertSame('("aTable"."t3ver_wsid" = 0) AND (("aTable"."t3ver_oid" = 0) OR ("aTable"."t3ver_state" = 4))', (string)$expression); + self::assertSame('(("aTable"."t3ver_wsid" = 0) AND ((("aTable"."t3ver_oid" = 0) OR ("aTable"."t3ver_state" = 4))))', (string)$expression); } /** @@ -44,7 +44,7 @@ class WorkspaceRestrictionTest extends AbstractRestrictionTestCase ]; $subject = new WorkspaceRestriction(42); $expression = $subject->buildExpression(['aTable' => 'aTable'], $this->expressionBuilder); - self::assertSame('("aTable"."t3ver_wsid" IN (0, 42)) AND (("aTable"."t3ver_oid" = 0) OR ("aTable"."t3ver_state" = 4))', (string)$expression); + self::assertSame('(("aTable"."t3ver_wsid" IN (0, 42)) AND ((("aTable"."t3ver_oid" = 0) OR ("aTable"."t3ver_state" = 4))))', (string)$expression); } /** @@ -83,7 +83,7 @@ class WorkspaceRestrictionTest extends AbstractRestrictionTestCase ]; $subject = new WorkspaceRestriction(42, true); $expression = $subject->buildExpression(['aTable' => 'aTable'], $this->expressionBuilder); - self::assertSame('("aTable"."t3ver_wsid" IN (0, 42)) AND ("t3ver_state" <> 2)', (string)$expression); + self::assertSame('(("aTable"."t3ver_wsid" IN (0, 42)) AND ("t3ver_state" <> 2))', (string)$expression); } /** * @test @@ -95,6 +95,6 @@ class WorkspaceRestrictionTest extends AbstractRestrictionTestCase ]; $subject = new WorkspaceRestriction(0, true); $expression = $subject->buildExpression(['aTable' => 'aTable'], $this->expressionBuilder); - self::assertSame('("aTable"."t3ver_wsid" = 0) AND ("t3ver_state" <> 2)', (string)$expression); + self::assertSame('(("aTable"."t3ver_wsid" = 0) AND ("t3ver_state" <> 2))', (string)$expression); } } diff --git a/typo3/sysext/core/Tests/UnitDeprecated/Database/Query/Restriction/BackendWorkspaceRestrictionTest.php b/typo3/sysext/core/Tests/UnitDeprecated/Database/Query/Restriction/BackendWorkspaceRestrictionTest.php index 2c4baf126edc..2c465753a315 100644 --- a/typo3/sysext/core/Tests/UnitDeprecated/Database/Query/Restriction/BackendWorkspaceRestrictionTest.php +++ b/typo3/sysext/core/Tests/UnitDeprecated/Database/Query/Restriction/BackendWorkspaceRestrictionTest.php @@ -32,7 +32,7 @@ class BackendWorkspaceRestrictionTest extends AbstractRestrictionTestCase ]; $subject = new BackendWorkspaceRestriction(0); $expression = $subject->buildExpression(['aTable' => 'aTable'], $this->expressionBuilder); - self::assertSame('("aTable"."t3ver_wsid" = 0) OR ("aTable"."t3ver_state" <= 0)', (string)$expression); + self::assertSame('(("aTable"."t3ver_wsid" = 0) OR ("aTable"."t3ver_state" <= 0))', (string)$expression); } /** @@ -45,7 +45,7 @@ class BackendWorkspaceRestrictionTest extends AbstractRestrictionTestCase ]; $subject = new BackendWorkspaceRestriction(42); $expression = $subject->buildExpression(['aTable' => 'aTable'], $this->expressionBuilder); - self::assertSame('("aTable"."t3ver_wsid" = 42) OR ("aTable"."t3ver_state" <= 0)', (string)$expression); + self::assertSame('(("aTable"."t3ver_wsid" = 42) OR ("aTable"."t3ver_state" <= 0))', (string)$expression); } /** @@ -58,7 +58,7 @@ class BackendWorkspaceRestrictionTest extends AbstractRestrictionTestCase ]; $subject = new BackendWorkspaceRestriction(0, false); $expression = $subject->buildExpression(['aTable' => 'aTable'], $this->expressionBuilder); - self::assertSame('("aTable"."t3ver_wsid" = 0) AND ("aTable"."t3ver_oid" = 0)', (string)$expression); + self::assertSame('(("aTable"."t3ver_wsid" = 0) AND ("aTable"."t3ver_oid" = 0))', (string)$expression); } /** @@ -71,6 +71,6 @@ class BackendWorkspaceRestrictionTest extends AbstractRestrictionTestCase ]; $subject = new BackendWorkspaceRestriction(42, false); $expression = $subject->buildExpression(['aTable' => 'aTable'], $this->expressionBuilder); - self::assertSame('("aTable"."t3ver_wsid" = 42) AND ("aTable"."t3ver_oid" > 0)', (string)$expression); + self::assertSame('(("aTable"."t3ver_wsid" = 42) AND ("aTable"."t3ver_oid" > 0))', (string)$expression); } } diff --git a/typo3/sysext/core/Tests/UnitDeprecated/Database/Query/Restriction/FrontendWorkspaceRestrictionTest.php b/typo3/sysext/core/Tests/UnitDeprecated/Database/Query/Restriction/FrontendWorkspaceRestrictionTest.php index 3fbe100dbaef..1cbc08ccf906 100644 --- a/typo3/sysext/core/Tests/UnitDeprecated/Database/Query/Restriction/FrontendWorkspaceRestrictionTest.php +++ b/typo3/sysext/core/Tests/UnitDeprecated/Database/Query/Restriction/FrontendWorkspaceRestrictionTest.php @@ -39,7 +39,7 @@ class FrontendWorkspaceRestrictionTest extends AbstractRestrictionTestCase $subject = new FrontendWorkspaceRestriction(0); $expression = $subject->buildExpression(['aTable' => 'aTable'], $this->expressionBuilder); - self::assertSame('("aTable"."t3ver_state" <= 0) AND ("aTable"."t3ver_oid" = 0)', (string)$expression); + self::assertSame('(("aTable"."t3ver_state" <= 0) AND ("aTable"."t3ver_oid" = 0))', (string)$expression); } /** @@ -57,7 +57,7 @@ class FrontendWorkspaceRestrictionTest extends AbstractRestrictionTestCase $subject = new FrontendWorkspaceRestriction(42, true); $expression = $subject->buildExpression(['aTable' => 'aTable'], $this->expressionBuilder); - self::assertSame('(("aTable"."t3ver_wsid" = 0) OR ("aTable"."t3ver_wsid" = 42)) AND ("aTable"."t3ver_oid" = 0)', (string)$expression); + self::assertSame('(((("aTable"."t3ver_wsid" = 0) OR ("aTable"."t3ver_wsid" = 42))) AND ("aTable"."t3ver_oid" = 0))', (string)$expression); } /** @@ -75,6 +75,6 @@ class FrontendWorkspaceRestrictionTest extends AbstractRestrictionTestCase $subject = new FrontendWorkspaceRestriction(42, true, false); $expression = $subject->buildExpression(['aTable' => 'aTable'], $this->expressionBuilder); - self::assertSame('("aTable"."t3ver_wsid" = 0) OR ("aTable"."t3ver_wsid" = 42)', (string)$expression); + self::assertSame('(("aTable"."t3ver_wsid" = 0) OR ("aTable"."t3ver_wsid" = 42))', (string)$expression); } } diff --git a/typo3/sysext/extbase/Tests/Unit/Persistence/Generic/Storage/Typo3DbQueryParserTest.php b/typo3/sysext/extbase/Tests/Unit/Persistence/Generic/Storage/Typo3DbQueryParserTest.php index 6cc5f08785ef..0acbfcb46850 100644 --- a/typo3/sysext/extbase/Tests/Unit/Persistence/Generic/Storage/Typo3DbQueryParserTest.php +++ b/typo3/sysext/extbase/Tests/Unit/Persistence/Generic/Storage/Typo3DbQueryParserTest.php @@ -442,7 +442,7 @@ class Typo3DbQueryParserTest extends UnitTestCase $mockTypo3DbQueryParser->_set('queryBuilder', $queryBuilderProphet->reveal()); $compositeExpression = $mockTypo3DbQueryParser->_call('getLanguageStatement', $table, $table, $querySettings); - $expectedSql = '(' . $table . '.sys_language_uid = -1) OR ((' . $table . '.sys_language_uid = 2) AND (' . $table . '.l10n_parent IN (SELECT ' . $table . '_dl.uid FROM ' . $table . ' ' . $table . '_dl WHERE (' . $table . '_dl.l10n_parent = 0) AND (' . $table . '_dl.sys_language_uid = 0)))) OR ((' . $table . '.sys_language_uid = 0) AND (' . $table . '.uid NOT IN (SELECT ' . $table . '_to.l10n_parent FROM ' . $table . ' ' . $table . '_dl, ' . $table . ' ' . $table . '_to WHERE (' . $table . '_to.l10n_parent > 0) AND (' . $table . '_to.sys_language_uid = 2))))'; + $expectedSql = '((' . $table . '.sys_language_uid = -1) OR (((' . $table . '.sys_language_uid = 2) AND (' . $table . '.l10n_parent IN (SELECT ' . $table . '_dl.uid FROM ' . $table . ' ' . $table . '_dl WHERE ((' . $table . '_dl.l10n_parent = 0) AND (' . $table . '_dl.sys_language_uid = 0)))))) OR (((' . $table . '.sys_language_uid = 0) AND (' . $table . '.uid NOT IN (SELECT ' . $table . '_to.l10n_parent FROM ' . $table . ' ' . $table . '_dl, ' . $table . ' ' . $table . '_to WHERE ((' . $table . '_to.l10n_parent > 0) AND (' . $table . '_to.sys_language_uid = 2)))))))'; self::assertSame($expectedSql, $compositeExpression->__toString()); } @@ -468,7 +468,7 @@ class Typo3DbQueryParserTest extends UnitTestCase $queryBuilderProphet = $this->getQueryBuilderProphetWithQueryBuilderForSubselect(); $mockTypo3DbQueryParser->_set('queryBuilder', $queryBuilderProphet->reveal()); $compositeExpression= $mockTypo3DbQueryParser->_call('getLanguageStatement', $table, $table, $querySettings); - $expectedSql = '(' . $table . '.sys_language_uid = -1) OR ((' . $table . '.sys_language_uid = 2) AND (' . $table . '.l10n_parent IN (SELECT ' . $table . '_dl.uid FROM ' . $table . ' ' . $table . '_dl WHERE (' . $table . '_dl.l10n_parent = 0) AND (' . $table . '_dl.sys_language_uid = 0) AND (' . $table . '_dl.deleted = 0)))) OR ((' . $table . '.sys_language_uid = 0) AND (' . $table . '.uid NOT IN (SELECT ' . $table . '_to.l10n_parent FROM ' . $table . ' ' . $table . '_dl, ' . $table . ' ' . $table . '_to WHERE (' . $table . '_to.l10n_parent > 0) AND (' . $table . '_to.sys_language_uid = 2) AND ((' . $table . '_dl.deleted = 0) AND (' . $table . '_to.deleted = 0)))))'; + $expectedSql = '((' . $table . '.sys_language_uid = -1) OR (((' . $table . '.sys_language_uid = 2) AND (' . $table . '.l10n_parent IN (SELECT ' . $table . '_dl.uid FROM ' . $table . ' ' . $table . '_dl WHERE ((' . $table . '_dl.l10n_parent = 0) AND (' . $table . '_dl.sys_language_uid = 0) AND (' . $table . '_dl.deleted = 0)))))) OR (((' . $table . '.sys_language_uid = 0) AND (' . $table . '.uid NOT IN (SELECT ' . $table . '_to.l10n_parent FROM ' . $table . ' ' . $table . '_dl, ' . $table . ' ' . $table . '_to WHERE ((' . $table . '_to.l10n_parent > 0) AND (' . $table . '_to.sys_language_uid = 2) AND (((' . $table . '_dl.deleted = 0) AND (' . $table . '_to.deleted = 0)))))))))'; self::assertSame($expectedSql, $compositeExpression->__toString()); } @@ -496,7 +496,7 @@ class Typo3DbQueryParserTest extends UnitTestCase $mockTypo3DbQueryParser->_set('queryBuilder', $queryBuilderProphet->reveal()); $compositeExpression = $mockTypo3DbQueryParser->_call('getLanguageStatement', $table, $table, $querySettings); - $expectedSql = '(' . $table . '.sys_language_uid = -1) OR ((' . $table . '.sys_language_uid = 2) AND (' . $table . '.l10n_parent IN (SELECT ' . $table . '_dl.uid FROM ' . $table . ' ' . $table . '_dl WHERE (' . $table . '_dl.l10n_parent = 0) AND (' . $table . '_dl.sys_language_uid = 0) AND (' . $table . '_dl.deleted = 0)))) OR ((' . $table . '.sys_language_uid = 0) AND (' . $table . '.uid NOT IN (SELECT ' . $table . '_to.l10n_parent FROM ' . $table . ' ' . $table . '_dl, ' . $table . ' ' . $table . '_to WHERE (' . $table . '_to.l10n_parent > 0) AND (' . $table . '_to.sys_language_uid = 2) AND ((' . $table . '_dl.deleted = 0) AND (' . $table . '_to.deleted = 0)))))'; + $expectedSql = '((' . $table . '.sys_language_uid = -1) OR (((' . $table . '.sys_language_uid = 2) AND (' . $table . '.l10n_parent IN (SELECT ' . $table . '_dl.uid FROM ' . $table . ' ' . $table . '_dl WHERE ((' . $table . '_dl.l10n_parent = 0) AND (' . $table . '_dl.sys_language_uid = 0) AND (' . $table . '_dl.deleted = 0)))))) OR (((' . $table . '.sys_language_uid = 0) AND (' . $table . '.uid NOT IN (SELECT ' . $table . '_to.l10n_parent FROM ' . $table . ' ' . $table . '_dl, ' . $table . ' ' . $table . '_to WHERE ((' . $table . '_to.l10n_parent > 0) AND (' . $table . '_to.sys_language_uid = 2) AND (((' . $table . '_dl.deleted = 0) AND (' . $table . '_to.deleted = 0)))))))))'; self::assertSame($expectedSql, $compositeExpression->__toString()); } @@ -593,12 +593,12 @@ class Typo3DbQueryParserTest extends UnitTestCase return [ 'in be: include all' => ['BE', true, [], true, ''], 'in be: ignore enable fields but do not include deleted' => ['BE', true, [], false, 'tx_foo_table.deleted_column=0'], - 'in be: respect enable fields but include deleted' => ['BE', false, [], true, '(tx_foo_table.disabled_column = 0) AND (tx_foo_table.starttime_column <= 1451779200)'], - 'in be: respect enable fields and do not include deleted' => ['BE', false, [], false, '(tx_foo_table.disabled_column = 0) AND (tx_foo_table.starttime_column <= 1451779200) AND tx_foo_table.deleted_column=0'], + 'in be: respect enable fields but include deleted' => ['BE', false, [], true, '((tx_foo_table.disabled_column = 0) AND (tx_foo_table.starttime_column <= 1451779200))'], + 'in be: respect enable fields and do not include deleted' => ['BE', false, [], false, '((tx_foo_table.disabled_column = 0) AND (tx_foo_table.starttime_column <= 1451779200)) AND tx_foo_table.deleted_column=0'], 'in fe: include all' => ['FE', true, [], true, ''], 'in fe: ignore enable fields but do not include deleted' => ['FE', true, [], false, 'tx_foo_table.deleted_column=0'], - 'in fe: ignore only starttime and do not include deleted' => ['FE', true, ['starttime'], false, '(tx_foo_table.deleted_column = 0) AND (tx_foo_table.disabled_column = 0)'], - 'in fe: respect enable fields and do not include deleted' => ['FE', false, [], false, '(tx_foo_table.deleted_column = 0) AND (tx_foo_table.disabled_column = 0) AND (tx_foo_table.starttime_column <= 1451779200)'], + 'in fe: ignore only starttime and do not include deleted' => ['FE', true, ['starttime'], false, '((tx_foo_table.deleted_column = 0) AND (tx_foo_table.disabled_column = 0))'], + 'in fe: respect enable fields and do not include deleted' => ['FE', false, [], false, '((tx_foo_table.deleted_column = 0) AND (tx_foo_table.disabled_column = 0) AND (tx_foo_table.starttime_column <= 1451779200))'], ]; } @@ -664,9 +664,9 @@ class Typo3DbQueryParserTest extends UnitTestCase { return [ 'in be: respectEnableFields=false' => ['BE', false, ''], - 'in be: respectEnableFields=true' => ['BE', true, '(tx_foo_table.disabled_column = 0) AND (tx_foo_table.starttime_column <= 1451779200) AND tx_foo_table.deleted_column=0'], + 'in be: respectEnableFields=true' => ['BE', true, '((tx_foo_table.disabled_column = 0) AND (tx_foo_table.starttime_column <= 1451779200)) AND tx_foo_table.deleted_column=0'], 'in FE: respectEnableFields=false' => ['FE', false, ''], - 'in FE: respectEnableFields=true' => ['FE', true, '(tx_foo_table.deleted_column = 0) AND (tx_foo_table.disabled_column = 0) AND (tx_foo_table.starttime_column <= 1451779200)'], + 'in FE: respectEnableFields=true' => ['FE', true, '((tx_foo_table.deleted_column = 0) AND (tx_foo_table.disabled_column = 0) AND (tx_foo_table.starttime_column <= 1451779200))'], ]; } @@ -726,6 +726,72 @@ class Typo3DbQueryParserTest extends UnitTestCase unset($GLOBALS['TCA'][$tableName]); } + public function providerForRespectEnableFieldsWithOnlyEndtime() + { + return [ + 'in be: respectEnableFields=false' => ['BE', false, false, ''], + 'in be: respectEnableFields=true' => ['BE', true, true, '((tx_foo_table.endtime_column = 0) OR (tx_foo_table.endtime_column > 1451779200)) AND tx_foo_table.deleted_column=0'], + 'in be: respectEnableFields=true and includeDeleted=false' => ['BE', true, false, '((tx_foo_table.endtime_column = 0) OR (tx_foo_table.endtime_column > 1451779200))'], + 'in FE: respectEnableFields=false' => ['FE', false, false, ''], + 'in FE: respectEnableFields=true' => ['FE', true, true, '((tx_foo_table.endtime_column = 0) OR (tx_foo_table.endtime_column > 1451779200)) AND tx_foo_table.deleted_column=0'], + 'in FE: respectEnableFields=true and includeDeleted=false' => ['FE', true, false, '((tx_foo_table.endtime_column = 0) OR (tx_foo_table.endtime_column > 1451779200))'], + ]; + } + + /** + * @test + * @dataProvider providerForRespectEnableFieldsWithOnlyEndtime + */ + public function respectEnableFieldsSettingGeneratesCorrectStatementWithOnlyEndTime($mode, $respectEnableFields, $respectDeletedElements, $expectedSql) + { + $tableName = 'tx_foo_table'; + $GLOBALS['TCA'][$tableName]['ctrl'] = [ + 'enablecolumns' => [ + 'endtime' => 'endtime_column', + ], + 'delete' => 'deleted_column', + ]; + if (!$respectDeletedElements) { + unset($GLOBALS['TCA'][$tableName]['ctrl']['delete']); + } + // simulate time for backend enable fields + $GLOBALS['SIM_ACCESS_TIME'] = 1451779200; + // simulate time for frontend (PageRepository) enable fields + $dateAspect = new DateTimeAspect(new \DateTimeImmutable('3.1.2016')); + $context = new Context(['date' => $dateAspect]); + GeneralUtility::setSingletonInstance(Context::class, $context); + + $connectionProphet = $this->prophesize(Connection::class); + $connectionProphet->quoteIdentifier(Argument::cetera())->willReturnArgument(0); + $connectionProphet->getExpressionBuilder(Argument::cetera())->willReturn( + GeneralUtility::makeInstance(ExpressionBuilder::class, $connectionProphet->reveal()) + ); + $queryBuilderProphet = $this->prophesize(QueryBuilder::class); + $queryBuilderProphet->expr()->willReturn( + GeneralUtility::makeInstance(ExpressionBuilder::class, $connectionProphet->reveal()) + ); + $queryBuilderProphet->createNamedParameter(Argument::cetera())->willReturnArgument(0); + + $connectionPoolProphet = $this->prophesize(ConnectionPool::class); + $connectionPoolProphet->getQueryBuilderForTable(Argument::any())->willReturn($queryBuilderProphet->reveal()); + $connectionPoolProphet->getConnectionForTable(Argument::any())->willReturn($connectionProphet->reveal()); + GeneralUtility::addInstance(ConnectionPool::class, $connectionPoolProphet->reveal()); + GeneralUtility::addInstance(ConnectionPool::class, $connectionPoolProphet->reveal()); + + /** @var \TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings $mockQuerySettings */ + $mockQuerySettings = $this->getMockBuilder(Typo3QuerySettings::class) + ->setMethods(['dummy']) + ->disableOriginalConstructor() + ->getMock(); + $mockQuerySettings->setIgnoreEnableFields(!$respectEnableFields); + $mockQuerySettings->setIncludeDeleted(!$respectEnableFields); + + $mockTypo3DbQueryParser = $this->getAccessibleMock(Typo3DbQueryParser::class, ['dummy'], [], '', false); + $actualSql = $mockTypo3DbQueryParser->_call('getVisibilityConstraintStatement', $mockQuerySettings, $tableName, $tableName); + self::assertSame($expectedSql, $actualSql); + unset($GLOBALS['TCA'][$tableName]); + } + /** * @test */ -- GitLab