Commit a6363e85 authored by Benni Mack's avatar Benni Mack Committed by Susanne Moog
Browse files

[BUGFIX] Do not check for pid=-1 when evaluating workspace records

TYPO3 Core handles the result of database queries in a lot of different
ways to filter out workspace records.

With "versioning support v1" (= without workspaces), the identifier was
usually "pid = -1" to filter out records that should not be displayed in
live results.

With workspaces, there are other, better ways to identify versioned via
the following fields:
- t3ver_state (what kind of versioned record is there)
- t3ver_oid (if the versioned record points to a live record)
- t3ver_wsid (the workspace ID)

The "pid" field was kept as misuse, but fine for most of the database
queries. Since we now have Doctrine DBAL, and Restrictions, the Core
API can now be unified to actually check for "t3ver_oid>0" instead of
"pid<>-1" to identify a versioned record.

All places in TYPO3 Core now does not check for "pid<>-1" anymore for
tables that are workspace-aware.

In the future, it is then possible to get rid of the "pid=-1" value when
writing versioned records, streamlining the API effectively, to find one
proper way to query and write records.

This change does not modify any other places in TYPO3 Core where
Workspace Records are written, but only cleans up the API to only
consider "t3ver_oid" instead of "pid", avoiding the mis-use of "pid".

Most queries can then be handled by simply checking:
- t3ver_wsid=0 AND deleted=0 for only fetching live records
- t3ver_wsid IN (0,12) AND t3ver_oid=0 to find all live records,
  and draft placeholders, to do overlays then

Resolves: #89122
Releases: master
Change-Id: I781d1ae440fe944e6c8c99d02884a6eb0c1be0a7
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/61641

Tested-by: Oliver Hader's avatarOliver Hader <oliver.hader@typo3.org>
Tested-by: default avatarTYPO3com <noreply@typo3.com>
Tested-by: Susanne Moog's avatarSusanne Moog <look@susi.dev>
Reviewed-by: Oliver Hader's avatarOliver Hader <oliver.hader@typo3.org>
Reviewed-by: Susanne Moog's avatarSusanne Moog <look@susi.dev>
parent e3822a57
......@@ -636,7 +636,7 @@ class EditDocumentController
// Setting a blank editconf array for a new record:
$this->editconf = [];
// Determine related page ID for regular live context
if ($nRec['pid'] != -1) {
if ($nRec['t3ver_oid'] > 0) {
if ($insertRecordOnTop) {
$relatedPageId = $nRec['pid'];
} else {
......@@ -681,7 +681,7 @@ class EditDocumentController
// Setting a blank editconf array for a new record:
$this->editconf = [];
if ($nRec['pid'] != -1) {
if ((int)$nRec['t3ver_oid'] === 0) {
$relatedPageId = -$nRec['uid'];
} else {
$relatedPageId = -$nRec['t3ver_oid'];
......@@ -2301,7 +2301,7 @@ class EditDocumentController
// Check for versioning support of the table:
if ($tableSupportsVersioning) {
// If the record is already a version of "something" pass it by.
if ($reqRecord['pid'] == -1) {
if ($reqRecord['t3ver_oid'] > 0) {
// (If it turns out not to be a version of the current workspace there will be trouble, but
// that is handled inside DataHandler then and in the interface it would clearly be an error of
// links if the user accesses such a scenario)
......
......@@ -1375,15 +1375,7 @@ abstract class AbstractItemProvider
$table = $result['tableName'];
$row = $result['databaseRow'];
$uid = $row['uid'];
if (!empty($result['processedTca']['ctrl']['versioningWS'])
&& $result['pid'] === -1
) {
if (empty($row['t3ver_oid'])) {
throw new \UnexpectedValueException(
'No t3ver_oid found for record ' . $row['uid'] . ' on table ' . $table,
1440066481
);
}
if (BackendUtility::isTableWorkspaceEnabled($table) && (int)$row['t3ver_oid'] > 0) {
$uid = $row['t3ver_oid'];
}
return $uid;
......
......@@ -393,6 +393,9 @@ class EvaluateDisplayConditions implements FormDataProviderInterface
);
}
$namedConditionArray['uid'] = $databaseRow['uid'];
if (array_key_exists('t3ver_oid', $databaseRow)) {
$namedConditionArray['t3ver_oid'] = $databaseRow['t3ver_oid'];
}
if (array_key_exists('pid', $databaseRow)) {
$namedConditionArray['pid'] = $databaseRow['pid'];
}
......@@ -890,9 +893,7 @@ class EvaluateDisplayConditions implements FormDataProviderInterface
$isNewRecord = !((int)$condition['uid'] > 0);
// Detection of version can be done by detecting the workspace of the user
$isUserInWorkspace = $this->getBackendUser()->workspace > 0;
if ((array_key_exists('pid', $condition) && (int)$condition['pid'] === -1)
|| (array_key_exists('_ORIG_pid', $condition) && (int)$condition['_ORIG_pid'] === -1)
) {
if ((int)($condition['t3ver_oid'] ?? 0) > 0) {
$isRecordDetectedAsVersion = true;
} else {
$isRecordDetectedAsVersion = false;
......@@ -900,7 +901,7 @@ class EvaluateDisplayConditions implements FormDataProviderInterface
// New records in a workspace are not handled as a version record
// if it's no new version, we detect versions like this:
// * if user is in workspace: always TRUE
// * if editor is in live ws: only TRUE if pid == -1
// * if editor is in live ws: only TRUE if t3ver_oid > 0
$result = ($isUserInWorkspace || $isRecordDetectedAsVersion) && !$isNewRecord;
if (!$condition['isVersion']) {
$result = !$result;
......
......@@ -228,7 +228,7 @@ class PageTreeRepository
// In case this is a record from a workspace
// The uid+pid of the live-version record is fetched
// This is done in order to avoid fetching records again (e.g. via BackendUtility::workspaceOL()
if ($parentPageId === -1) {
if ((int)$pageRecord['t3ver_oid'] > 0) {
// When a move pointer is found, the pid+sorting of the MOVE_PLACEHOLDER should be used (this is the
// workspace record holding this information), also the t3ver_state is set to the MOVE_PLACEHOLDER
// because the record is then added
......
......@@ -3373,7 +3373,6 @@ class BackendUtility
$queryBuilder
->from($table)
->where(
$queryBuilder->expr()->eq('pid', $queryBuilder->createNamedParameter(-1, \PDO::PARAM_INT)),
$queryBuilder->expr()->neq('uid', $queryBuilder->createNamedParameter($uid, \PDO::PARAM_INT)),
$queryBuilder->expr()->eq('t3ver_oid', $queryBuilder->createNamedParameter($uid, \PDO::PARAM_INT))
)
......@@ -3633,10 +3632,6 @@ class BackendUtility
$row = $queryBuilder
->from($table)
->where(
$queryBuilder->expr()->eq(
'pid',
$queryBuilder->createNamedParameter(-1, \PDO::PARAM_INT)
),
$queryBuilder->expr()->eq(
't3ver_oid',
$queryBuilder->createNamedParameter($uid, \PDO::PARAM_INT)
......@@ -3687,7 +3682,7 @@ class BackendUtility
$liveVersionId = null;
if (self::isTableWorkspaceEnabled($table)) {
$currentRecord = self::getRecord($table, $uid, 'pid,t3ver_oid');
if (is_array($currentRecord) && $currentRecord['pid'] == -1) {
if (is_array($currentRecord) && (int)$currentRecord['t3ver_oid'] > 0) {
$liveVersionId = $currentRecord['t3ver_oid'];
}
}
......@@ -3725,8 +3720,8 @@ class BackendUtility
$workspaceId = static::getBackendUserAuthentication()->workspace;
}
$workspaceId = (int)$workspaceId;
$pidOperator = $workspaceId === 0 ? '!=' : '=';
$whereClause = ' AND ' . $table . '.t3ver_wsid=' . $workspaceId . ' AND ' . $table . '.pid' . $pidOperator . '-1';
$comparison = $workspaceId === 0 ? '=' : '>';
$whereClause = ' AND ' . $table . '.t3ver_wsid=' . $workspaceId . ' AND ' . $table . '.t3ver_oid' . $comparison . '0';
}
return $whereClause;
}
......@@ -3777,10 +3772,6 @@ class BackendUtility
->select(...GeneralUtility::trimExplode(',', $fields, true))
->from($table)
->where(
$queryBuilder->expr()->neq(
'pid',
$queryBuilder->createNamedParameter(-1, \PDO::PARAM_INT)
),
$queryBuilder->expr()->eq(
't3ver_state',
$queryBuilder->createNamedParameter(
......
......@@ -3763,7 +3763,7 @@ class EvaluateDisplayConditionsTest extends UnitTestCase
'VERSION:IS:TRUE',
[
'uid' => 42,
'pid' => -1,
't3ver_oid' => 12,
],
true,
],
......@@ -3771,7 +3771,7 @@ class EvaluateDisplayConditionsTest extends UnitTestCase
'VERSION:IS:FALSE',
[
'uid' => 42,
'pid' => 1,
't3ver_oid' => 0,
],
true,
],
......
......@@ -378,11 +378,11 @@ class BackendUserAuthentication extends AbstractUserAuthentication
$checkRec = BackendUtility::getRecord(
'pages',
$id,
'pid,t3ver_oid,'
't3ver_oid,'
. $GLOBALS['TCA']['pages']['ctrl']['transOrigPointerField'] . ','
. $GLOBALS['TCA']['pages']['ctrl']['languageField']
);
if ($checkRec['pid'] == -1) {
if ((int)$checkRec['t3ver_oid'] > 0) {
$id = (int)$checkRec['t3ver_oid'];
}
// if current rec is a translation then get uid from l10n_parent instead
......@@ -906,10 +906,9 @@ class BackendUserAuthentication extends AbstractUserAuthentication
);
}
if (is_array($recData)) {
// We are testing a "version" (identified by a pid of -1): it can be edited provided
// We are testing a "version" (identified by having a t3ver_oid): it can be edited provided
// that workspace matches and versioning is enabled for the table.
if ((int)$recData['pid'] === -1) {
// No versioning, basic error, inconsistency even! Such records should not have a pid of -1!
if ((int)($recData['t3ver_oid'] ?? 0) > 0) {
if ((int)$recData['t3ver_wsid'] !== $this->workspace) {
// So does workspace match?
return 'Workspace ID of record didn\'t match current workspace';
......@@ -953,7 +952,7 @@ class BackendUserAuthentication extends AbstractUserAuthentication
$recData = BackendUtility::getRecord($table, $recData, 'uid,pid,t3ver_oid,t3ver_wsid,t3ver_stage');
}
if (is_array($recData)) {
if ((int)$recData['pid'] === -1) {
if ((int)$recData['t3ver_oid'] > 0) {
return $this->workspaceCannotEditRecord($table, $recData);
}
return 'Not an offline version';
......
......@@ -6460,7 +6460,7 @@ class DataHandler implements LoggerAwareInterface
return [
'header' => BackendUtility::getRecordTitle($table, $row),
'pid' => $row['pid'],
'event_pid' => $this->eventPid($table, isset($row['_ORIG_pid']) ? $row['t3ver_oid'] : $row['uid'], $row['pid']),
'event_pid' => $this->eventPid($table, ((int)($row['t3ver_oid'] ?? 0) > 0 ? $row['t3ver_oid'] : $row['uid']), $row['pid']),
't3ver_state' => BackendUtility::isTableWorkspaceEnabled($table) ? $row['t3ver_state'] : '',
'_ORIG_pid' => $row['_ORIG_pid']
];
......
......@@ -78,7 +78,7 @@ class PlainDataResolver
public function __construct($tableName, array $liveIds, array $sortingStatement = null)
{
$this->tableName = $tableName;
$this->liveIds = $this->reindex($liveIds);
$this->liveIds = $this->reindex($this->sanitizeIds($liveIds));
$this->sortingStatement = $sortingStatement;
}
......@@ -164,6 +164,7 @@ class PlainDataResolver
*/
public function processVersionOverlays(array $ids)
{
$ids = $this->sanitizeIds($ids);
if (empty($this->workspaceId) || !$this->isWorkspaceEnabled() || empty($ids)) {
return $ids;
}
......@@ -180,7 +181,6 @@ class PlainDataResolver
->select('uid', 't3ver_oid', 't3ver_state')
->from($this->tableName)
->where(
$queryBuilder->expr()->eq('pid', $queryBuilder->createNamedParameter(-1, \PDO::PARAM_INT)),
$queryBuilder->expr()->in(
't3ver_oid',
$queryBuilder->createNamedParameter($ids, Connection::PARAM_INT_ARRAY)
......@@ -218,6 +218,7 @@ class PlainDataResolver
*/
public function processVersionMovePlaceholders(array $ids)
{
$ids = $this->sanitizeIds($ids);
// Early return on insufficient data-set
if (empty($this->workspaceId) || !$this->isWorkspaceEnabled() || empty($ids)) {
return $ids;
......@@ -232,7 +233,6 @@ class PlainDataResolver
->select('uid', 't3ver_move_id')
->from($this->tableName)
->where(
$queryBuilder->expr()->neq('pid', $queryBuilder->createNamedParameter(-1, \PDO::PARAM_INT)),
$queryBuilder->expr()->eq(
't3ver_state',
$queryBuilder->createNamedParameter((string)VersionState::MOVE_PLACEHOLDER, \PDO::PARAM_INT)
......@@ -274,6 +274,7 @@ class PlainDataResolver
*/
public function processSorting(array $ids)
{
$ids = $this->sanitizeIds($ids);
// Early return on missing sorting statement or insufficient data-set
if (empty($this->sortingStatement) || count($ids) < 2) {
return $ids;
......@@ -317,6 +318,7 @@ class PlainDataResolver
*/
public function applyLiveIds(array $ids)
{
$ids = $this->sanitizeIds($ids);
if (!$this->keepLiveIds || !$this->isWorkspaceEnabled() || empty($ids)) {
return $ids;
}
......@@ -368,6 +370,17 @@ class PlainDataResolver
return $ids;
}
/**
* Removes empty values (null, '0', 0, false).
*
* @param int[] $ids
* @return array
*/
protected function sanitizeIds(array $ids): array
{
return array_filter($ids);
}
/**
* @return bool
*/
......
......@@ -77,11 +77,11 @@ class BackendWorkspaceRestriction implements QueryRestrictionInterface
)
);
} else {
$comparisonExpression = $this->workspaceId === 0 ? 'neq' : 'eq';
$comparisonExpression = $this->workspaceId === 0 ? 'eq' : 'gt';
$constraints[] = $workspaceIdExpression;
$constraints[] = $expressionBuilder->{$comparisonExpression}(
$tableAlias . '.pid',
-1
$tableAlias . '.t3ver_oid',
0
);
}
}
......
......@@ -85,7 +85,7 @@ class FrontendWorkspaceRestriction implements QueryRestrictionInterface
}
// Filter out versioned records
if ($this->enforceLiveRowsOnly) {
$constraints[] = $expressionBuilder->neq($tableAlias . '.pid', -1);
$constraints[] = $expressionBuilder->eq($tableAlias . '.t3ver_oid', 0);
}
}
}
......
......@@ -72,12 +72,12 @@ class WorkspaceRestriction implements QueryRestrictionInterface
[0, $this->workspaceId]
);
}
// Always filter out "pid=-1" records
// Always filter out versioned records that have an "offline" record
$constraints[] = $expressionBuilder->andX(
$workspaceIdExpression,
$expressionBuilder->neq(
$tableAlias . '.pid',
-1
$expressionBuilder->eq(
$tableAlias . '.t3ver_oid',
0
)
);
}
......
......@@ -974,9 +974,9 @@ class RelationHandler
$foreign_table . '.t3ver_wsid',
$queryBuilder->createNamedParameter([0, (int)$this->getWorkspaceId()], Connection::PARAM_INT_ARRAY)
),
$queryBuilder->expr()->neq(
$foreign_table . '.pid',
$queryBuilder->createNamedParameter(-1, \PDO::PARAM_INT)
$queryBuilder->expr()->eq(
$foreign_table . '.t3ver_oid',
$queryBuilder->createNamedParameter(0, \PDO::PARAM_INT)
)
);
}
......@@ -1451,6 +1451,7 @@ class RelationHandler
*/
protected function purgeVersionedIds($tableName, array $ids)
{
$ids = $this->sanitizeIds($ids);
$ids = array_combine($ids, $ids);
$connection = $this->getConnectionForTableName($tableName);
$maxBindParameters = PlatformInformation::getMaxBindParameters($connection->getDatabasePlatform());
......@@ -1461,10 +1462,6 @@ class RelationHandler
$result = $queryBuilder->select('uid', 't3ver_oid', 't3ver_state')
->from($tableName)
->where(
$queryBuilder->expr()->eq(
'pid',
$queryBuilder->createNamedParameter(-1, \PDO::PARAM_INT)
),
$queryBuilder->expr()->in(
't3ver_oid',
$queryBuilder->createNamedParameter($chunk, Connection::PARAM_INT_ARRAY)
......@@ -1497,6 +1494,7 @@ class RelationHandler
*/
protected function purgeLiveVersionedIds($tableName, array $ids)
{
$ids = $this->sanitizeIds($ids);
$ids = array_combine($ids, $ids);
$connection = $this->getConnectionForTableName($tableName);
$maxBindParameters = PlatformInformation::getMaxBindParameters($connection->getDatabasePlatform());
......@@ -1507,10 +1505,6 @@ class RelationHandler
$result = $queryBuilder->select('uid', 't3ver_oid', 't3ver_state')
->from($tableName)
->where(
$queryBuilder->expr()->eq(
'pid',
$queryBuilder->createNamedParameter(-1, \PDO::PARAM_INT)
),
$queryBuilder->expr()->in(
't3ver_oid',
$queryBuilder->createNamedParameter($chunk, Connection::PARAM_INT_ARRAY)
......@@ -1544,6 +1538,7 @@ class RelationHandler
*/
protected function purgeDeletePlaceholder($tableName, array $ids)
{
$ids = $this->sanitizeIds($ids);
$ids = array_combine($ids, $ids);
$connection = $this->getConnectionForTableName($tableName);
$maxBindParameters = PlatformInformation::getMaxBindParameters($connection->getDatabasePlatform());
......@@ -1554,10 +1549,6 @@ class RelationHandler
$result = $queryBuilder->select('uid', 't3ver_oid', 't3ver_state')
->from($tableName)
->where(
$queryBuilder->expr()->eq(
'pid',
$queryBuilder->createNamedParameter(-1, \PDO::PARAM_INT)
),
$queryBuilder->expr()->in(
't3ver_oid',
$queryBuilder->createNamedParameter($chunk, Connection::PARAM_INT_ARRAY)
......@@ -1662,6 +1653,17 @@ class RelationHandler
return (int)$liveDefaultId;
}
/**
* Removes empty values (null, '0', 0, false).
*
* @param int[] $ids
* @return array
*/
protected function sanitizeIds(array $ids): array
{
return array_filter($ids);
}
/**
* @param string $tableName
* @param int[] $ids
......
......@@ -1604,7 +1604,6 @@ class PageRepository implements LoggerAwareInterface
$row = $queryBuilder->select(...GeneralUtility::trimExplode(',', $fields, true))
->from($table)
->where(
$queryBuilder->expr()->neq('pid', $queryBuilder->createNamedParameter(-1, \PDO::PARAM_INT)),
$queryBuilder->expr()->eq(
't3ver_state',
$queryBuilder->createNamedParameter(
......@@ -1657,7 +1656,6 @@ class PageRepository implements LoggerAwareInterface
$newrow = $queryBuilder->select(...GeneralUtility::trimExplode(',', $fields, true))
->from($table)
->where(
$queryBuilder->expr()->eq('pid', $queryBuilder->createNamedParameter(-1, \PDO::PARAM_INT)),
$queryBuilder->expr()->eq(
't3ver_oid',
$queryBuilder->createNamedParameter($uid, \PDO::PARAM_INT)
......@@ -1683,7 +1681,6 @@ class PageRepository implements LoggerAwareInterface
if (is_array($newrow)) {
$queryBuilder->where(
$queryBuilder->expr()->eq('pid', $queryBuilder->createNamedParameter(-1, \PDO::PARAM_INT)),
$queryBuilder->expr()->eq(
't3ver_oid',
$queryBuilder->createNamedParameter($uid, \PDO::PARAM_INT)
......
.. include:: ../../Includes.txt
=========================================================================
Important: #89122 - Unified evaluation of versioned records in workspaces
=========================================================================
See :issue:`89122`
Description
===========
TYPO3 Core handled the result of database queries in a lot of different ways to filter out workspace records.
In previous versions, where versioned records without workspaces (incremental versions) was supported, the main
identifier was always to check for records that are "Offline" - by checking via the "pid" field of database records,
that they are set to "-1".
With workspaces, there are other, better ways to identify versioned via the following fields:
- t3ver_state (what kind of versioned record it is - new version, moved record, deleted version)
- t3ver_oid (if the versioned record points to a live record)
- t3ver_wsid (the workspace ID, a relation to a sys_workspace record)
The "pid" field was kept as misuse, but fine for most of the database queries. With the unified database abstraction
layer based on Doctrine DBAL and enriched via Query Restrictions, TYPO3 Core now checks for t3ver_state, t3ver_wsid
and t3ver_oid to identify versioned records.
This is already achieved with any database query by using the WorkspaceRestrictions in place. Extension authors
should use Doctrine DBAL and apply workspace restrictions by default.
If this is not possible when building custom queries without restrictions, it is recommended to check for:
- t3ver_oid>0 = identifying a versioned record that has a counterpart in the live workspace
- t3ver_wsid=13 - identifying a versioned record or placeholder that resides in a specific workspace (in this case "13")
- t3ver_state IN (0,-1) AND t3ver_wisd IN (0,13) - to fetch records including "new record" placeholders
Checking for "pid = -1" is not recommended anymore - using the restrictoins and custom query information can be
used in previous TYPO3 versions already.
.. index:: Database, ext:workspaces
......@@ -55,7 +55,7 @@ class BackendWorkspaceRestrictionTest extends AbstractRestrictionTestCase
];
$subject = new BackendWorkspaceRestriction(0, false);
$expression = $subject->buildExpression(['aTable' => 'aTable'], $this->expressionBuilder);
$this->assertSame('("aTable"."t3ver_wsid" = 0) AND ("aTable"."pid" <> -1)', (string)$expression);
$this->assertSame('("aTable"."t3ver_wsid" = 0) AND ("aTable"."t3ver_oid" = 0)', (string)$expression);
}
/**
......@@ -68,6 +68,6 @@ class BackendWorkspaceRestrictionTest extends AbstractRestrictionTestCase
];
$subject = new BackendWorkspaceRestriction(42, false);
$expression = $subject->buildExpression(['aTable' => 'aTable'], $this->expressionBuilder);
$this->assertSame('("aTable"."t3ver_wsid" = 42) AND ("aTable"."pid" = -1)', (string)$expression);
$this->assertSame('("aTable"."t3ver_wsid" = 42) AND ("aTable"."t3ver_oid" > 0)', (string)$expression);
}
}
......@@ -37,7 +37,7 @@ class FrontendRestrictionContainerTest extends AbstractRestrictionTestCase
'hiddenPagePreview' => false,
'hiddenRecordPreview' => false,
'frontendUserGroups' => [0, -1],
'expectedSQL' => '("aTable"."deleted" = 0) AND (("aTable"."t3ver_state" <= 0) AND ("aTable"."pid" <> -1)) 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_state" <= 0) AND ("aTable"."t3ver_oid" = 0)) 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',
......@@ -46,7 +46,7 @@ class FrontendRestrictionContainerTest extends AbstractRestrictionTestCase
'hiddenPagePreview' => true,
'hiddenRecordPreview' => true,
'frontendUserGroups' => [0, -1],
'expectedSQL' => '("aTable"."deleted" = 0) AND (("aTable"."t3ver_state" <= 0) AND ("aTable"."pid" <> -1)) 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_state" <= 0) AND ("aTable"."t3ver_oid" = 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' => [
'tableName' => 'aTable',
......@@ -55,7 +55,7 @@ class FrontendRestrictionContainerTest extends AbstractRestrictionTestCase
'hiddenPagePreview' => false,
'hiddenRecordPreview' => false,
'frontendUserGroups' => [0, -1],
'expectedSQL' => '("aTable"."deleted" = 0) AND ((("aTable"."t3ver_wsid" = 0) OR ("aTable"."t3ver_wsid" = 1)) AND ("aTable"."pid" <> -1)) 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) OR ("aTable"."t3ver_wsid" = 1)) AND ("aTable"."t3ver_oid" = 0)) 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',
......@@ -64,7 +64,7 @@ class FrontendRestrictionContainerTest extends AbstractRestrictionTestCase
'hiddenPagePreview' => true,
'hiddenRecordPreview' => true,
'frontendUserGroups' => [0, -1],
'expectedSQL' => '("aTable"."deleted" = 0) AND ((("aTable"."t3ver_wsid" = 0) OR ("aTable"."t3ver_wsid" = 1)) AND ("aTable"."pid" <> -1)) 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) OR ("aTable"."t3ver_wsid" = 1)) AND ("aTable"."t3ver_oid" = 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 page, no preview' => [
'tableName' => 'pages',
......@@ -73,7 +73,7 @@ class FrontendRestrictionContainerTest extends AbstractRestrictionTestCase
'hiddenPagePreview' => false,
'hiddenRecordPreview' => false,
'frontendUserGroups' => [0, -1],
'expectedSQL' => '("pages"."deleted" = 0) AND (("pages"."t3ver_state" <= 0) AND ("pages"."pid" <> -1)) 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_state" <= 0) AND ("pages"."t3ver_oid" = 0)) 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',
......@@ -82,7 +82,7 @@ class FrontendRestrictionContainerTest extends AbstractRestrictionTestCase
'hiddenPagePreview' => true,
'hiddenRecordPreview' => true,
'frontendUserGroups' => [0, -1],
'expectedSQL' => '("pages"."deleted" = 0) AND (("pages"."t3ver_state" <= 0) AND ("pages"."pid" <> -1)) 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_state" <= 0) AND ("pages"."t3ver_oid" = 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' => [
'tableName' => 'pages',
......@@ -91,7 +91,7 @@ class FrontendRestrictionContainerTest extends AbstractRestrictionTestCase
'hiddenPagePreview' => false,
'hiddenRecordPreview' => false,
'frontendUserGroups' => [0, -1],
'expectedSQL' => '("pages"."deleted" = 0) AND ("pages"."pid" <> -1) 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_oid" = 0) 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',
......@@ -100,7 +100,7 @@ class FrontendRestrictionContainerTest extends AbstractRestrictionTestCase
'hiddenPagePreview' => true,
'hiddenRecordPreview' => true,
'frontendUserGroups' => [0, -1],
'expectedSQL' => '("pages"."deleted" = 0) AND ("pages"."pid" <> -1) 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_oid" = 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, no preview with alias' => [
'tableName' => 'aTable',
......@@ -109,7 +109,7 @@ class FrontendRestrictionContainerTest extends AbstractRestrictionTestCase
'hiddenPagePreview' => false,
'hiddenRecordPreview' => false,
'frontendUserGroups' => [0, -1],
'expectedSQL' => '("a"."deleted" = 0) AND (("a"."t3ver_state" <= 0) AND ("a"."pid" <> -1)) 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_state" <= 0) AND ("a"."t3ver_oid" = 0)) 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")))'
],
];
}
......
......@@ -39,7 +39,7 @@ class FrontendWorkspaceRestrictionTest extends AbstractRestrictionTestCase