[BUGFIX] Invalid relations of MM records in workspaces 24/28624/4
authorOliver Hader <oliver@typo3.org>
Fri, 21 Mar 2014 21:11:58 +0000 (22:11 +0100)
committerOliver Hader <oliver.hader@typo3.org>
Sat, 22 Mar 2014 00:59:38 +0000 (01:59 +0100)
The basic problem with MM (ManyToMany) relations in workspaces is
that the intermediate table (MM table) does not have any
information about actually being a reference in a particular
workspace - there is no "t3ver_wsid" field. Thus, the meaning of
a relation needs to be determined from the entities on both sides
of the relation. The following is possible:

* both sides are live -> valid in live only
* exactly one side is versioned -> valid in a workspace only
* both sides are versioned -> valid in a workspace only

The difficulties now start with versioning one side first and
after some time the other side - thus the relation with exactly
one version and one live entity needs to be turned into an entry
pointing to both versions.

Resolves: #57169
Releases: 6.2
Change-Id: Idb043d520c30f15e85d54a016e52690f5f05cedc
Reviewed-on: https://review.typo3.org/28624
Reviewed-by: Oliver Hader
Tested-by: Oliver Hader
16 files changed:
typo3/sysext/core/Classes/DataHandling/DataHandler.php
typo3/sysext/core/Classes/Database/RelationHandler.php
typo3/sysext/core/Tests/Functional/DataHandling/Framework/ActionService.php
typo3/sysext/workspaces/Tests/Functional/DataHandling/ManyToMany/AbstractActionTestCase.php
typo3/sysext/workspaces/Tests/Functional/DataHandling/ManyToMany/Modify/ActionTest.php
typo3/sysext/workspaces/Tests/Functional/DataHandling/ManyToMany/Modify/DataSet/createCategoryNCreateRelation.csv
typo3/sysext/workspaces/Tests/Functional/DataHandling/ManyToMany/Modify/DataSet/createContentNCreateRelation.csv
typo3/sysext/workspaces/Tests/Functional/DataHandling/ManyToMany/Modify/DataSet/modifyBothsOfRelation.csv
typo3/sysext/workspaces/Tests/Functional/DataHandling/ManyToMany/Publish/ActionTest.php
typo3/sysext/workspaces/Tests/Functional/DataHandling/ManyToMany/Publish/DataSet/createCategoryNCreateRelation.csv
typo3/sysext/workspaces/Tests/Functional/DataHandling/ManyToMany/Publish/DataSet/createContentNCreateRelation.csv
typo3/sysext/workspaces/Tests/Functional/DataHandling/ManyToMany/Publish/DataSet/modifyBothsOfRelation.csv
typo3/sysext/workspaces/Tests/Functional/DataHandling/ManyToMany/PublishAll/ActionTest.php
typo3/sysext/workspaces/Tests/Functional/DataHandling/ManyToMany/PublishAll/DataSet/createCategoryNCreateRelation.csv
typo3/sysext/workspaces/Tests/Functional/DataHandling/ManyToMany/PublishAll/DataSet/createContentNCreateRelation.csv
typo3/sysext/workspaces/Tests/Functional/DataHandling/ManyToMany/PublishAll/DataSet/modifyBothsOfRelation.csv

index d38c970..a519426 100644 (file)
@@ -3347,6 +3347,7 @@ class DataHandler {
                                                $dbAnalysis->itemArray[$index]['id'] = $this->localize($item['table'], $item['id'], $language);
                                        }
                                }
+                               $dbAnalysis->purgeItemArray();
                                $value = implode(',', $dbAnalysis->getValueArray($prependName));
                        } elseif ($language > 0 && $localizeChildren === FALSE && $localizationMode === 'select' && $inlineSubType === 'mm') {
                                foreach ($dbAnalysis->itemArray as $index => $item) {
@@ -3358,8 +3359,10 @@ class DataHandler {
                                                unset($dbAnalysis->itemArray[$index]);
                                        }
                                }
+                               $dbAnalysis->purgeItemArray();
                                $value = implode(',', $dbAnalysis->getValueArray($prependName));
                        } elseif ($mmTable) {
+                               $dbAnalysis->purgeItemArray();
                                $value = implode(',', $dbAnalysis->getValueArray($prependName));
                        }
                        // Setting the value in this array will notify the remapListedDBRecords() function that this field MAY need references to be corrected
@@ -5054,6 +5057,29 @@ class DataHandler {
                                $set = TRUE;
                        }
                }
+               if (!empty($conf['MM'])) {
+                       // Purge invalid items (live/version)
+                       $dbAnalysis->purgeItemArray();
+                       if ($dbAnalysis->isPurged()) {
+                               $set = TRUE;
+                       }
+
+                       // If record has been versioned/copied in this process, handle invalid relations of the live record
+                       $liveId = BackendUtility::getLiveVersionIdOfRecord($table, $MM_localUid);
+                       if (!empty($this->copyMappingArray_merged[$table])) {
+                               $originalId = array_search($MM_localUid, $this->copyMappingArray_merged[$table]);
+                       }
+                       if (!empty($liveId) && !empty($originalId) && (int)$liveId === (int)$originalId) {
+                               $liveRelations = $this->createRelationHandlerInstance();
+                               $liveRelations->setWorkspaceId(0);
+                               $liveRelations->start('', $allowedTables, $conf['MM'], $liveId, $table, $conf);
+                               // Purge invalid relations in the live workspace ("0")
+                               $liveRelations->purgeItemArray(0);
+                               if ($liveRelations->isPurged()) {
+                                       $liveRelations->writeMM($conf['MM'], $liveId, $prependName);
+                               }
+                       }
+               }
                // If a change has been done, set the new value(s)
                if ($set) {
                        if ($conf['MM']) {
index 002ad9a..f2b0182 100644 (file)
@@ -229,6 +229,16 @@ class RelationHandler {
        protected $useLiveReferenceIds = TRUE;
 
        /**
+        * @var int
+        */
+       protected $workspaceId;
+
+       /**
+        * @var bool
+        */
+       protected $purged = FALSE;
+
+       /**
         * This array will be filled by getFromDB().
         *
         * @var array
@@ -236,6 +246,36 @@ class RelationHandler {
        public $results = array();
 
        /**
+        * Gets the current workspace id.
+        *
+        * @return int
+        */
+       public function getWorkspaceId() {
+               if (!isset($this->workspaceId)) {
+                       $this->workspaceId = (int)$GLOBALS['BE_USER']->workspace;
+               }
+               return $this->workspaceId;
+       }
+
+       /**
+        * Sets the current workspace id.
+        *
+        * @param int $workspaceId
+        */
+       public function setWorkspaceId($workspaceId) {
+               $this->workspaceId = (int)$workspaceId;
+       }
+
+       /**
+        * Whether item array has been purged in this instance.
+        *
+        * @return bool
+        */
+       public function isPurged() {
+               return $this->purged;
+       }
+
+       /**
         * Initialization of the class.
         *
         * @param string $itemlist List of group/select items
@@ -311,9 +351,11 @@ class RelationHandler {
                if ($MMtable) {
                        if ($MMuid) {
                                $this->readMM($MMtable, $MMuid);
+                               $this->purgeItemArray();
                        } else {
                                // Revert to readList() for new records in order to load possible default values from $itemlist
                                $this->readList($itemlist, $conf);
+                               $this->purgeItemArray();
                        }
                } elseif ($MMuid && $conf['foreign_field']) {
                        // If not MM but foreign_field, the read the records by the foreign_field
@@ -1095,7 +1137,7 @@ class RelationHandler {
                        /** @var $refIndexObj \TYPO3\CMS\Core\Database\ReferenceIndex */
                        $refIndexObj = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Database\\ReferenceIndex');
                        if (BackendUtility::isTableWorkspaceEnabled($table)) {
-                               $refIndexObj->setWorkspaceId($GLOBALS['BE_USER']->workspace);
+                               $refIndexObj->setWorkspaceId($this->getWorkspaceId());
                        }
                        $statisticsArray = $refIndexObj->updateRefIndexTable($table, $id);
                }
@@ -1103,6 +1145,119 @@ class RelationHandler {
        }
 
        /**
+        * @param NULL|int $workspaceId
+        * @return bool
+        */
+       public function purgeItemArray($workspaceId = NULL) {
+               $itemArrayHasBeenPurged = FALSE;
+
+               if ($workspaceId === NULL) {
+                       $workspaceId = $this->getWorkspaceId();
+               } else {
+                       $workspaceId = (int)$workspaceId;
+               }
+
+               // Ensure, only live relations are in the items Array
+               if ($workspaceId === 0) {
+                       $purgeCallback = 'purgeVersionedIds';
+               // Otherwise, ensure that live relations are purged if version exists
+               } else {
+                       $purgeCallback = 'purgeLiveVersionedIds';
+               }
+
+               foreach ($this->tableArray as $itemTableName => $itemIds) {
+                       if (!count($itemIds)) {
+                               continue;
+                       }
+                       $purgedItemIds = call_user_func(array($this, $purgeCallback), $itemTableName, $itemIds);
+                       $removedItemIds = array_diff($itemIds, $purgedItemIds);
+                       foreach ($removedItemIds as $removedItemId) {
+                               $this->removeFromItemArray($itemTableName, $removedItemId);
+                       }
+                       $this->tableArray[$itemTableName] = $purgedItemIds;
+                       if (count($removedItemIds)) {
+                               $itemArrayHasBeenPurged = TRUE;
+                       }
+               }
+
+               $this->purged = ($this->purged || $itemArrayHasBeenPurged);
+               return $itemArrayHasBeenPurged;
+       }
+
+       /**
+        * Purges ids that are versioned.
+        *
+        * @param string $tableName
+        * @param array $ids
+        * @return array
+        */
+       protected function purgeVersionedIds($tableName, array $ids) {
+               $ids = $this->getDatabaseConnection()->cleanIntArray($ids);
+               $ids = array_combine($ids, $ids);
+
+               $versions = $this->getDatabaseConnection()->exec_SELECTgetRows(
+                       'uid,t3ver_oid,t3ver_state',
+                       $tableName,
+                       'pid=-1 AND t3ver_oid IN (' . implode(',', $ids) . ') AND t3ver_wsid<>0',
+                       '',
+                       't3ver_state DESC'
+               );
+
+               if (!empty($versions)) {
+                       foreach ($versions as $version) {
+                               $versionId = $version['uid'];
+                               if (isset($ids[$versionId])) {
+                                       unset($ids[$versionId]);
+                               }
+                       }
+               }
+
+               return array_values($ids);
+       }
+
+       /**
+        * Purges ids that are live but have an accordant version.
+        *
+        * @param string $tableName
+        * @param array $ids
+        * @return array
+        */
+       protected function purgeLiveVersionedIds($tableName, array $ids) {
+               $ids = $this->getDatabaseConnection()->cleanIntArray($ids);
+               $ids = array_combine($ids, $ids);
+
+               $versions = $this->getDatabaseConnection()->exec_SELECTgetRows(
+                       'uid,t3ver_oid,t3ver_state',
+                       $tableName,
+                       'pid=-1 AND t3ver_oid IN (' . implode(',', $ids) . ') AND t3ver_wsid<>0',
+                       '',
+                       't3ver_state DESC'
+               );
+
+               if (!empty($versions)) {
+                       foreach ($versions as $version) {
+                               $versionId = $version['uid'];
+                               $liveId = $version['t3ver_oid'];
+                               if (isset($ids[$liveId]) && isset($ids[$versionId])) {
+                                       unset($ids[$liveId]);
+                               }
+                       }
+               }
+
+               return array_values($ids);
+       }
+
+       protected function removeFromItemArray($tableName, $id) {
+               foreach ($this->itemArray as $index => $item) {
+                       if ($item['table'] === $tableName && (string)$item['id'] === (string)$id) {
+                               unset($this->itemArray[$index]);
+                               return TRUE;
+                       }
+               }
+               return FALSE;
+       }
+
+       /**
         * Checks, if we're looking from the "other" side, the symmetric side, to a symmetric relation.
         *
         * @param string $parentUid The uid of the parent record
@@ -1223,7 +1378,14 @@ class RelationHandler {
                if ($liveDefaultId === NULL) {
                        $liveDefaultId = $id;
                }
-               return $liveDefaultId;
+               return (int)$liveDefaultId;
+       }
+
+       /**
+        * @return DatabaseConnection
+        */
+       protected function getDatabaseConnection() {
+               return $GLOBALS['TYPO3_DB'];
        }
 
 }
index c6f4ee5..afe5f7d 100644 (file)
@@ -66,7 +66,9 @@ class ActionService {
                $previousUid = NULL;
                foreach ($tableRecordData as $tableName => $recordData) {
                        $recordData = $this->resolvePreviousUid($recordData, $currentUid);
-                       $recordData['pid'] = $pageId;
+                       if (!isset($recordData['pid'])) {
+                               $recordData['pid'] = $pageId;
+                       }
                        $currentUid = uniqid('NEW');
                        $newTableIds[$tableName][] = $currentUid;
                        $dataMap[$tableName][$currentUid] = $recordData;
index 8fb80f2..5055bc2 100644 (file)
@@ -133,7 +133,7 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
                $newTableIds = $this->actionService->createNewRecords(
                        self::VALUE_PageId,
                        array(
-                               self::TABLE_Category => array('title' => 'Testing #1'),
+                               self::TABLE_Category => array('pid' => 0, 'title' => 'Testing #1'),
                                self::TABLE_Content => array('header' => 'Testing #1', 'categories' => '__previousUid'),
                        )
                );
@@ -150,7 +150,7 @@ abstract class AbstractActionTestCase extends \TYPO3\CMS\Core\Tests\Functional\D
                        self::VALUE_PageId,
                        array(
                                self::TABLE_Content => array('header' => 'Testing #1',),
-                               self::TABLE_Category => array('title' => 'Testing #1', 'items' => 'tt_content___previousUid'),
+                               self::TABLE_Category => array('pid' => 0, 'title' => 'Testing #1', 'items' => 'tt_content___previousUid'),
                        )
                );
                $this->recordIds['newContentId'] = $newTableIds[self::TABLE_Content][0];
index b860a64..c17ad98 100644 (file)
@@ -113,15 +113,12 @@ class ActionTest extends \TYPO3\CMS\Workspaces\Tests\Functional\DataHandling\Man
                parent::createCategoryAndAddRelation();
                $this->assertAssertionDataSet('createCategoryNAddRelation');
 
-               // @todo Does not work due to the core bug of not setting the reference field in the MM record
-               /*
-                       $responseContent = $this->getFrontendResponse(self::VALUE_PageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
-                       $this->assertResponseContentHasRecords($responseContent, self::TABLE_Category, 'title', 'Testing #1');
-                       $this->assertResponseContentStructureHasRecords(
-                               $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdFirst, 'categories',
-                               self::TABLE_Category, 'title', 'Testing #1'
-                       );
-               */
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Category, 'title', 'Testing #1');
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdFirst, 'categories',
+                       self::TABLE_Category, 'title', 'Testing #1'
+               );
        }
 
        /**
@@ -134,15 +131,10 @@ class ActionTest extends \TYPO3\CMS\Workspaces\Tests\Functional\DataHandling\Man
 
                $responseContent = $this->getFrontendResponse(self::VALUE_PageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
                $this->assertResponseContentHasRecords($responseContent, self::TABLE_Content, 'header', 'Testing #1');
-
-               // @todo New category is not resolved in new content element due to core bug
-               // The frontend query ignores pid=-1 and thus the specific workspace record in sys_category:33
-               /*
-                       $this->assertResponseContentStructureHasRecords(
-                               $responseContent, self::TABLE_Content . ':' . $this->recordIds['newContentId'], 'categories',
-                               self::TABLE_Category, 'title', 'Testing #1'
-                       );
-               */
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . $this->recordIds['newContentId'], 'categories',
+                       self::TABLE_Category, 'title', 'Testing #1'
+               );
        }
 
        /**
@@ -250,14 +242,7 @@ class ActionTest extends \TYPO3\CMS\Workspaces\Tests\Functional\DataHandling\Man
                $responseContent = $this->getFrontendResponse(self::VALUE_PageId, 0, self::VALUE_BackendUserId, self::VALUE_WorkspaceId)->getResponseContent();
                $this->assertResponseContentStructureHasRecords(
                        $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdFirst, 'categories',
-                       self::TABLE_Category, 'title', 'Category A'
-                       // @todo Actually it should be twice "Category A" since the category got copied
-                       // The frontend query ignores pid=-1 and thus the specific workspace record in sys_category:33
-                       // SELECT sys_category.* FROM sys_category JOIN sys_category_record_mm ON sys_category_record_mm.uid_local = sys_category.uid WHERE sys_category.uid IN (33,28,29)
-                       // AND sys_category_record_mm.uid_foreign=297 AND (sys_category.sys_language_uid IN (0,-1))
-                       // AND sys_category.deleted=0 AND (sys_category.t3ver_wsid=0 OR sys_category.t3ver_wsid=1) AND sys_category.pid<>-1
-                       // ORDER BY sys_category_record_mm.sorting_foreign
-                       // self::TABLE_Category, 'title', array('Category A', 'Category A')
+                       self::TABLE_Category, 'title', array('Category A', 'Category A (copy 1)')
                );
        }
 
index f0b53b0..5168218 100644 (file)
@@ -4,8 +4,8 @@ sys_category
 ,29,0,512,0,0,0,0,0,0,0,0,"Category B",0,0
 ,30,0,768,0,0,0,0,0,0,0,0,"Category C",0,0
 ,31,0,1024,0,0,0,0,0,0,0,0,"Category A.A",28,0
-,32,89,256,0,0,0,1,1,0,0,0,"Testing #1",0,0
-,33,-1,256,0,0,0,1,-1,0,32,0,"Testing #1",0,0
+,32,0,128,0,0,0,1,1,0,0,0,"Testing #1",0,0
+,33,-1,128,0,0,0,1,-1,0,32,0,"Testing #1",0,0
 sys_category_record_mm
 ,uid_local,uid_foreign,tablenames,sorting,sorting_foreign,fieldname
 ,28,297,tt_content,0,1,categories
index d250972..ece7c72 100644 (file)
@@ -4,8 +4,8 @@ sys_category
 ,29,0,512,0,0,0,0,0,0,0,0,"Category B",0,0
 ,30,0,768,0,0,0,0,0,0,0,0,"Category C",0,0
 ,31,0,1024,0,0,0,0,0,0,0,0,"Category A.A",28,0
-,32,89,256,0,0,0,1,1,0,0,0,"Testing #1",0,0
-,33,-1,256,0,0,0,1,-1,0,32,0,"Testing #1",0,0
+,32,0,128,0,0,0,1,1,0,0,0,"Testing #1",0,0
+,33,-1,128,0,0,0,1,-1,0,32,0,"Testing #1",0,0
 sys_category_record_mm
 ,uid_local,uid_foreign,tablenames,sorting,sorting_foreign,fieldname
 ,28,297,tt_content,0,1,categories
index d7a1d05..565a096 100644 (file)
@@ -11,12 +11,10 @@ sys_category_record_mm
 ,29,297,tt_content,0,2,categories
 ,29,298,tt_content,0,1,categories
 ,30,298,tt_content,0,2,categories
-,32,297,tt_content,1,0,categories
 ,32,299,tt_content,0,1,categories
-,28,299,tt_content,0,2,categories
-,29,299,tt_content,0,3,categories
+,29,299,tt_content,0,2,categories
 tt_content
 ,uid,pid,sorting,deleted,sys_language_uid,l18n_parent,t3ver_wsid,t3ver_state,t3ver_stage,t3ver_oid,t3ver_move_id,header,image,categories
 ,297,89,256,0,0,0,0,0,0,0,0,"Regular Element #1",,2
 ,298,89,512,0,0,0,0,0,0,0,0,"Regular Element #2",,2
-,299,-1,256,0,0,0,1,0,0,297,0,"Testing #1",0,3
+,299,-1,256,0,0,0,1,0,0,297,0,"Testing #1",0,2
index e2ef414..0b5bcaf 100644 (file)
@@ -118,15 +118,12 @@ class ActionTest extends \TYPO3\CMS\Workspaces\Tests\Functional\DataHandling\Man
                $this->actionService->publishRecord(self::TABLE_Category, $this->recordIds['newCategoryId']);
                $this->assertAssertionDataSet('createCategoryNAddRelation');
 
-               // @todo Does not work due to the core bug of not setting the reference field in the MM record
-               /*
-                       $responseContent = $this->getFrontendResponse(self::VALUE_PageId, 0)->getResponseContent();
-                       $this->assertResponseContentHasRecords($responseContent, self::TABLE_Category, 'title', 'Testing #1');
-                       $this->assertResponseContentStructureHasRecords(
-                               $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdFirst, 'categories',
-                               self::TABLE_Category, 'title', 'Testing #1'
-                       );
-               */
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, 0)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Category, 'title', 'Testing #1');
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdFirst, 'categories',
+                       self::TABLE_Category, 'title', 'Testing #1'
+               );
        }
 
        /**
@@ -145,15 +142,10 @@ class ActionTest extends \TYPO3\CMS\Workspaces\Tests\Functional\DataHandling\Man
 
                $responseContent = $this->getFrontendResponse(self::VALUE_PageId, 0)->getResponseContent();
                $this->assertResponseContentHasRecords($responseContent, self::TABLE_Content, 'header', 'Testing #1');
-
-               // @todo New category is not resolved in new content element due to core bug
-               // The frontend query ignores pid=-1 and thus the specific workspace record in sys_category:33
-               /*
-                       $this->assertResponseContentStructureHasRecords(
-                               $responseContent, self::TABLE_Content . ':' . $this->recordIds['newContentId'], 'categories',
-                               self::TABLE_Category, 'title', 'Testing #1'
-                       );
-               */
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . $this->recordIds['newContentId'], 'categories',
+                       self::TABLE_Category, 'title', 'Testing #1'
+               );
        }
 
        /**
@@ -280,14 +272,7 @@ class ActionTest extends \TYPO3\CMS\Workspaces\Tests\Functional\DataHandling\Man
                $responseContent = $this->getFrontendResponse(self::VALUE_PageId, 0)->getResponseContent();
                $this->assertResponseContentStructureHasRecords(
                        $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdFirst, 'categories',
-                       self::TABLE_Category, 'title', 'Category A'
-                       // @todo Actually it should be twice "Category A" since the category got copied
-                       // The frontend query ignores pid=-1 and thus the specific workspace record in sys_category:33
-                       // SELECT sys_category.* FROM sys_category JOIN sys_category_record_mm ON sys_category_record_mm.uid_local = sys_category.uid WHERE sys_category.uid IN (33,28,29)
-                       // AND sys_category_record_mm.uid_foreign=297 AND (sys_category.sys_language_uid IN (0,-1))
-                       // AND sys_category.deleted=0 AND (sys_category.t3ver_wsid=0 OR sys_category.t3ver_wsid=1) AND sys_category.pid<>-1
-                       // ORDER BY sys_category_record_mm.sorting_foreign
-                       // self::TABLE_Category, 'title', array('Category A', 'Category A')
+                       self::TABLE_Category, 'title', array('Category A', 'Category A (copy 1)')
                );
        }
 
index c6cc00f..7c33d08 100644 (file)
@@ -4,7 +4,7 @@ sys_category
 ,29,0,512,0,0,0,0,0,0,0,0,"Category B",0,0
 ,30,0,768,0,0,0,0,0,0,0,0,"Category C",0,0
 ,31,0,1024,0,0,0,0,0,0,0,0,"Category A.A",28,0
-,32,89,256,0,0,0,0,0,0,0,0,"Testing #1",0,0
+,32,0,128,0,0,0,0,0,0,0,0,"Testing #1",0,0
 sys_category_record_mm
 ,uid_local,uid_foreign,tablenames,sorting,sorting_foreign,fieldname
 ,28,297,tt_content,0,1,categories
index 550db2f..f6b8729 100644 (file)
@@ -4,7 +4,7 @@ sys_category
 ,29,0,512,0,0,0,0,0,0,0,0,"Category B",0,0
 ,30,0,768,0,0,0,0,0,0,0,0,"Category C",0,0
 ,31,0,1024,0,0,0,0,0,0,0,0,"Category A.A",28,0
-,32,89,256,0,0,0,0,0,0,0,0,"Testing #1",0,0
+,32,0,128,0,0,0,0,0,0,0,0,"Testing #1",0,0
 sys_category_record_mm
 ,uid_local,uid_foreign,tablenames,sorting,sorting_foreign,fieldname
 ,28,297,tt_content,0,1,categories
index 858b03f..7bc2f61 100644 (file)
@@ -11,12 +11,10 @@ sys_category_record_mm
 ,29,299,tt_content,0,2,categories
 ,29,298,tt_content,0,1,categories
 ,30,298,tt_content,0,2,categories
-,28,299,tt_content,1,0,categories
 ,28,297,tt_content,0,1,categories
-,32,297,tt_content,0,2,categories
-,29,297,tt_content,0,3,categories
+,29,297,tt_content,0,2,categories
 tt_content
 ,uid,pid,sorting,deleted,sys_language_uid,l18n_parent,t3ver_wsid,t3ver_state,t3ver_stage,t3ver_oid,t3ver_move_id,header,image,categories
-,297,89,256,0,0,0,0,0,0,0,0,"Testing #1",0,3
+,297,89,256,0,0,0,0,0,0,0,0,"Testing #1",0,2
 ,298,89,512,0,0,0,0,0,0,0,0,"Regular Element #2",,2
 ,299,-1,256,0,0,0,0,0,0,297,0,"Regular Element #1",,2
index 1c36171..22bb166 100644 (file)
@@ -118,15 +118,12 @@ class ActionTest extends \TYPO3\CMS\Workspaces\Tests\Functional\DataHandling\Man
                $this->actionService->publishWorkspace(self::VALUE_WorkspaceId);
                $this->assertAssertionDataSet('createCategoryNAddRelation');
 
-               // @todo Does not work due to the core bug of not setting the reference field in the MM record
-               /*
-                       $responseContent = $this->getFrontendResponse(self::VALUE_PageId, 0)->getResponseContent();
-                       $this->assertResponseContentHasRecords($responseContent, self::TABLE_Category, 'title', 'Testing #1');
-                       $this->assertResponseContentStructureHasRecords(
-                               $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdFirst, 'categories',
-                               self::TABLE_Category, 'title', 'Testing #1'
-                       );
-               */
+               $responseContent = $this->getFrontendResponse(self::VALUE_PageId, 0)->getResponseContent();
+               $this->assertResponseContentHasRecords($responseContent, self::TABLE_Category, 'title', 'Testing #1');
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdFirst, 'categories',
+                       self::TABLE_Category, 'title', 'Testing #1'
+               );
        }
 
        /**
@@ -140,15 +137,10 @@ class ActionTest extends \TYPO3\CMS\Workspaces\Tests\Functional\DataHandling\Man
 
                $responseContent = $this->getFrontendResponse(self::VALUE_PageId, 0)->getResponseContent();
                $this->assertResponseContentHasRecords($responseContent, self::TABLE_Content, 'header', 'Testing #1');
-
-               // @todo New category is not resolved in new content element due to core bug
-               // The frontend query ignores pid=-1 and thus the specific workspace record in sys_category:33
-               /*
-                       $this->assertResponseContentStructureHasRecords(
-                               $responseContent, self::TABLE_Content . ':' . $this->recordIds['newContentId'], 'categories',
-                               self::TABLE_Category, 'title', 'Testing #1'
-                       );
-               */
+               $this->assertResponseContentStructureHasRecords(
+                       $responseContent, self::TABLE_Content . ':' . $this->recordIds['newContentId'], 'categories',
+                       self::TABLE_Category, 'title', 'Testing #1'
+               );
        }
 
        /**
@@ -264,14 +256,7 @@ class ActionTest extends \TYPO3\CMS\Workspaces\Tests\Functional\DataHandling\Man
                $responseContent = $this->getFrontendResponse(self::VALUE_PageId, 0)->getResponseContent();
                $this->assertResponseContentStructureHasRecords(
                        $responseContent, self::TABLE_Content . ':' . self::VALUE_ContentIdFirst, 'categories',
-                       self::TABLE_Category, 'title', 'Category A'
-                       // @todo Actually it should be twice "Category A" since the category got copied
-                       // The frontend query ignores pid=-1 and thus the specific workspace record in sys_category:33
-                       // SELECT sys_category.* FROM sys_category JOIN sys_category_record_mm ON sys_category_record_mm.uid_local = sys_category.uid WHERE sys_category.uid IN (33,28,29)
-                       // AND sys_category_record_mm.uid_foreign=297 AND (sys_category.sys_language_uid IN (0,-1))
-                       // AND sys_category.deleted=0 AND (sys_category.t3ver_wsid=0 OR sys_category.t3ver_wsid=1) AND sys_category.pid<>-1
-                       // ORDER BY sys_category_record_mm.sorting_foreign
-                       // self::TABLE_Category, 'title', array('Category A', 'Category A')
+                       self::TABLE_Category, 'title', array('Category A', 'Category A (copy 1)')
                );
        }
 
index c6cc00f..7c33d08 100644 (file)
@@ -4,7 +4,7 @@ sys_category
 ,29,0,512,0,0,0,0,0,0,0,0,"Category B",0,0
 ,30,0,768,0,0,0,0,0,0,0,0,"Category C",0,0
 ,31,0,1024,0,0,0,0,0,0,0,0,"Category A.A",28,0
-,32,89,256,0,0,0,0,0,0,0,0,"Testing #1",0,0
+,32,0,128,0,0,0,0,0,0,0,0,"Testing #1",0,0
 sys_category_record_mm
 ,uid_local,uid_foreign,tablenames,sorting,sorting_foreign,fieldname
 ,28,297,tt_content,0,1,categories
index 550db2f..f6b8729 100644 (file)
@@ -4,7 +4,7 @@ sys_category
 ,29,0,512,0,0,0,0,0,0,0,0,"Category B",0,0
 ,30,0,768,0,0,0,0,0,0,0,0,"Category C",0,0
 ,31,0,1024,0,0,0,0,0,0,0,0,"Category A.A",28,0
-,32,89,256,0,0,0,0,0,0,0,0,"Testing #1",0,0
+,32,0,128,0,0,0,0,0,0,0,0,"Testing #1",0,0
 sys_category_record_mm
 ,uid_local,uid_foreign,tablenames,sorting,sorting_foreign,fieldname
 ,28,297,tt_content,0,1,categories
index 858b03f..7bc2f61 100644 (file)
@@ -11,12 +11,10 @@ sys_category_record_mm
 ,29,299,tt_content,0,2,categories
 ,29,298,tt_content,0,1,categories
 ,30,298,tt_content,0,2,categories
-,28,299,tt_content,1,0,categories
 ,28,297,tt_content,0,1,categories
-,32,297,tt_content,0,2,categories
-,29,297,tt_content,0,3,categories
+,29,297,tt_content,0,2,categories
 tt_content
 ,uid,pid,sorting,deleted,sys_language_uid,l18n_parent,t3ver_wsid,t3ver_state,t3ver_stage,t3ver_oid,t3ver_move_id,header,image,categories
-,297,89,256,0,0,0,0,0,0,0,0,"Testing #1",0,3
+,297,89,256,0,0,0,0,0,0,0,0,"Testing #1",0,2
 ,298,89,512,0,0,0,0,0,0,0,0,"Regular Element #2",,2
 ,299,-1,256,0,0,0,0,0,0,297,0,"Regular Element #1",,2