[!!!][BUGFIX] Remove support for TCA setting 'foreign_selector'
authorHelmut Hummel <helmut.hummel@typo3.org>
Fri, 14 Dec 2012 10:53:07 +0000 (11:53 +0100)
committerAnja Leichsenring <aleichsenring@ab-softlab.de>
Fri, 8 Mar 2013 09:58:54 +0000 (10:58 +0100)
The TCA setting 'foreign_selector' is a UI feature which can be
configured for field in a relation table, when this table
is editable using the IRRE feature. Then a selector box
is rendered making it possible to select records from a child
table.

In this scenario the relation table itself may contain other
editable fields, which should be represented by a domain model.

The latter is currently not possible with Extbase because
'foreign_selector' triggers the DataMapper to resolve a
many to many relation to the child table.

Solution is to remove this behaviour and let the DataMapper
resolve the one to many relation to the relation table.

Find a test setup at https://gist.github.com/4284545

Change-Id: I2d8366f9ce54470999c1b02ad2098359f5aaa6b3
Fixes: #10770
Releases: 6.0, 6.1
Reviewed-on: https://review.typo3.org/17159
Reviewed-by: Thomas Maroschik
Reviewed-by: Sebastian Michaelsen
Tested-by: Sebastian Michaelsen
Reviewed-by: Marc Bastian Heinrichs
Tested-by: Marc Bastian Heinrichs
Reviewed-by: Wouter Wolters
Tested-by: Wouter Wolters
Reviewed-by: Arjen Hoekema
Tested-by: Arjen Hoekema
Reviewed-by: Anja Leichsenring
Tested-by: Anja Leichsenring
typo3/sysext/extbase/Classes/Persistence/Generic/Mapper/DataMapFactory.php
typo3/sysext/extbase/Tests/Unit/Persistence/Generic/Mapper/DataMapFactoryTest.php

index d954dad..12ac9c7 100644 (file)
@@ -165,6 +165,7 @@ class DataMapFactory implements \TYPO3\CMS\Core\SingletonInterface {
                $tcaColumnsDefinition = $this->getColumnsDefinition($tableName);
                $tcaColumnsDefinition = \TYPO3\CMS\Core\Utility\GeneralUtility::array_merge_recursive_overrule($tcaColumnsDefinition, $columnMapping);
                // TODO Is this is too powerful?
+
                foreach ($tcaColumnsDefinition as $columnName => $columnDefinition) {
                        if (isset($columnDefinition['mapOnProperty'])) {
                                $propertyName = $columnDefinition['mapOnProperty'];
@@ -304,7 +305,7 @@ class DataMapFactory implements \TYPO3\CMS\Core\SingletonInterface {
         */
        protected function setRelations(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap $columnMap, $columnConfiguration, $propertyMetaData) {
                if (isset($columnConfiguration)) {
-                       if (isset($columnConfiguration['MM']) || isset($columnConfiguration['foreign_selector'])) {
+                       if (isset($columnConfiguration['MM'])) {
                                $columnMap = $this->setManyToManyRelation($columnMap, $columnConfiguration);
                        } elseif (isset($propertyMetaData['elementType'])) {
                                $columnMap = $this->setOneToManyRelation($columnMap, $columnConfiguration);
@@ -313,6 +314,7 @@ class DataMapFactory implements \TYPO3\CMS\Core\SingletonInterface {
                        } else {
                                $columnMap->setTypeOfRelation(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap::RELATION_NONE);
                        }
+
                } else {
                        $columnMap->setTypeOfRelation(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap::RELATION_NONE);
                }
@@ -371,8 +373,8 @@ class DataMapFactory implements \TYPO3\CMS\Core\SingletonInterface {
         * @return \TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap
         */
        protected function setManyToManyRelation(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap $columnMap, $columnConfiguration) {
-               $columnMap->setTypeOfRelation(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap::RELATION_HAS_AND_BELONGS_TO_MANY);
                if (isset($columnConfiguration['MM'])) {
+                       $columnMap->setTypeOfRelation(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap::RELATION_HAS_AND_BELONGS_TO_MANY);
                        $columnMap->setChildTableName($columnConfiguration['foreign_table']);
                        $columnMap->setChildTableWhereStatement($columnConfiguration['foreign_table_where']);
                        $columnMap->setRelationTableName($columnConfiguration['MM']);
@@ -392,17 +394,6 @@ class DataMapFactory implements \TYPO3\CMS\Core\SingletonInterface {
                                $columnMap->setChildKeyFieldName('uid_foreign');
                                $columnMap->setChildSortByFieldName('sorting');
                        }
-               } elseif (isset($columnConfiguration['foreign_selector'])) {
-                       $columns = $this->getColumnsDefinition($columnConfiguration['foreign_table']);
-                       $childKeyFieldName = $columnConfiguration['foreign_selector'];
-                       $columnMap->setChildTableName($columns[$childKeyFieldName]['config']['foreign_table']);
-                       $columnMap->setRelationTableName($columnConfiguration['foreign_table']);
-                       $columnMap->setParentKeyFieldName($columnConfiguration['foreign_field']);
-                       $columnMap->setChildKeyFieldName($childKeyFieldName);
-                       $columnMap->setChildSortByFieldName($columnConfiguration['foreign_sortby']);
-                       if (!empty($columnConfiguration['foreign_table_field'])) {
-                               $columnMap->setParentTableFieldName($columnConfiguration['foreign_table_field']);
-                       }
                } else {
                        throw new \TYPO3\CMS\Extbase\Persistence\Generic\Exception\UnsupportedRelationException('The given information to build a many-to-many-relation was not sufficient. Check your TCA definitions. mm-relations with IRRE must have at least a defined "MM" or "foreign_selector".', 1268817963);
                }
@@ -411,6 +402,7 @@ class DataMapFactory implements \TYPO3\CMS\Core\SingletonInterface {
                }
                return $columnMap;
        }
+
 }
 
 ?>
\ No newline at end of file
index 9d39142..ce56a21 100644 (file)
@@ -193,28 +193,6 @@ class DataMapFactoryTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
        /**
         * @test
         */
-       public function setRelationsDetectsManyToManyRelationOfTypeInlineWithForeignSelector() {
-               $mockColumnMap = $this->getMock('TYPO3\\CMS\\Extbase\\Persistence\\Generic\\Mapper\\ColumnMap', array(), array(), '', FALSE);
-               $columnConfiguration = array(
-                       'type' => 'inline',
-                       'foreign_table' => 'tx_myextension_mm',
-                       'foreign_field' => 'uid_local',
-                       'foreign_selector' => 'uid_foreign'
-               );
-               $propertyMetaData = array(
-                       'type' => 'TYPO3\\CMS\\Extbase\\Persistence\\ObjectStorage',
-                       'elementType' => 'Tx_Myext_Domain_Model_Foo'
-               );
-               $mockDataMapFactory = $this->getAccessibleMock('TYPO3\\CMS\\Extbase\\Persistence\\Generic\\Mapper\\DataMapFactory', array('setOneToOneRelation', 'setOneToManyRelation', 'setManyToManyRelation'), array(), '', FALSE);
-               $mockDataMapFactory->expects($this->never())->method('setOneToOneRelation');
-               $mockDataMapFactory->expects($this->never())->method('setOneToManyRelation');
-               $mockDataMapFactory->expects($this->once())->method('setManyToManyRelation');
-               $mockDataMapFactory->_callRef('setRelations', $mockColumnMap, $columnConfiguration, $propertyMetaData);
-       }
-
-       /**
-        * @test
-        */
        public function columnMapIsInitializedWithManyToManyRelationOfTypeSelect() {
                $leftColumnsDefinition = array(
                        'rights' => array(
@@ -296,89 +274,6 @@ class DataMapFactoryTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
        /**
         * @test
         */
-       public function columnMapIsInitializedWithManyToManyRelationOfTypeInlineAndForeignSelector() {
-               $leftColumnsDefinition = array(
-                       'rights' => array(
-                               'type' => 'inline',
-                               'foreign_table' => 'tx_myextension_mm',
-                               'foreign_field' => 'uid_local',
-                               'foreign_selector' => 'uid_foreign',
-                               'foreign_sortby' => 'sorting'
-                       )
-               );
-               $relationTableColumnsDefiniton = array(
-                       'uid_local' => array(
-                               'config' => array('foreign_table' => 'tx_myextension_localtable')
-                       ),
-                       'uid_foreign' => array(
-                               'config' => array('foreign_table' => 'tx_myextension_righttable')
-                       )
-               );
-               $rightColumnsDefinition = array(
-                       'lefts' => array(
-                               'type' => 'inline',
-                               'foreign_table' => 'tx_myextension_mm',
-                               'foreign_field' => 'uid_foreign',
-                               'foreign_selector' => 'uid_local',
-                               'foreign_sortby' => 'sorting_foreign'
-                       )
-               );
-               $mockColumnMap = $this->getMock('TYPO3\\CMS\\Extbase\\Persistence\\Generic\\Mapper\\ColumnMap', array(), array(), '', FALSE);
-               $mockColumnMap->expects($this->once())->method('setTypeOfRelation')->with($this->equalTo(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap::RELATION_HAS_AND_BELONGS_TO_MANY));
-               $mockColumnMap->expects($this->once())->method('setRelationTableName')->with($this->equalTo('tx_myextension_mm'));
-               $mockColumnMap->expects($this->once())->method('setChildTableName')->with($this->equalTo('tx_myextension_righttable'));
-               $mockColumnMap->expects($this->never())->method('setChildTableWhereStatement');
-               $mockColumnMap->expects($this->once())->method('setChildSortByFieldName')->with($this->equalTo('sorting'));
-               $mockColumnMap->expects($this->once())->method('setParentKeyFieldName')->with($this->equalTo('uid_local'));
-               $mockColumnMap->expects($this->never())->method('setParentTableFieldName');
-               $mockColumnMap->expects($this->never())->method('setRelationTableMatchFields');
-               $mockColumnMap->expects($this->never())->method('setRelationTableInsertFields');
-               $mockDataMapFactory = $this->getAccessibleMock('TYPO3\\CMS\\Extbase\\Persistence\\Generic\\Mapper\\DataMapFactory', array('getColumnsDefinition'), array(), '', FALSE);
-               $mockDataMapFactory->expects($this->once())->method('getColumnsDefinition')->with($this->equalTo('tx_myextension_mm'))->will($this->returnValue($relationTableColumnsDefiniton));
-               $mockDataMapFactory->_callRef('setManyToManyRelation', $mockColumnMap, $leftColumnsDefinition['rights']);
-       }
-
-       /**
-        * @test
-        */
-       public function columnMapIsInitializedWithManyToManyRelationOfTypeInlineAndForeignSelectorWithForeignTableField() {
-               $leftColumnsDefinition = array(
-                       'rights' => array(
-                               'type' => 'inline',
-                               'foreign_table' => 'tx_myextension_mm',
-                               'foreign_field' => 'uid_local',
-                               'foreign_selector' => 'uid_foreign',
-                               'foreign_table_field' => 'tx_myextension_localtable',
-                               'foreign_sortby' => 'sorting'
-                       )
-               );
-               $relationTableColumnsDefinition = array(
-                       'uid_local' => array(
-                               'config' => array('foreign_table' => 'tx_myextension_localtable')
-                       ),
-                       'uid_foreign' => array(
-                               'config' => array('foreign_table' => 'tx_myextension_righttable')
-                       )
-               );
-               $mockColumnMap = $this->getMock('TYPO3\\CMS\\Extbase\\Persistence\\Generic\\Mapper\\ColumnMap', array(), array(), '', FALSE);
-               $mockColumnMap->expects($this->once())->method('setTypeOfRelation')->with($this->equalTo(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap::RELATION_HAS_AND_BELONGS_TO_MANY));
-               $mockColumnMap->expects($this->once())->method('setRelationTableName')->with($this->equalTo('tx_myextension_mm'));
-               $mockColumnMap->expects($this->once())->method('setChildTableName')->with($this->equalTo('tx_myextension_righttable'));
-               $mockColumnMap->expects($this->never())->method('setChildTableWhereStatement');
-               $mockColumnMap->expects($this->once())->method('setChildSortbyFieldName')->with($this->equalTo('sorting'));
-               $mockColumnMap->expects($this->once())->method('setParentKeyFieldName')->with($this->equalTo('uid_local'));
-               $mockColumnMap->expects($this->once())->method('setParentTableFieldName')->with($this->equalTo('tx_myextension_localtable'));
-               $mockColumnMap->expects($this->never())->method('setRelationTableMatchFields');
-               $mockColumnMap->expects($this->never())->method('setRelationTableInsertFields');
-
-               $mockDataMapFactory = $this->getMock($this->buildAccessibleProxy('TYPO3\\CMS\\Extbase\\Persistence\\Generic\\Mapper\\DataMapFactory'), array('getColumnsDefinition'), array(), '', FALSE);
-               $mockDataMapFactory->expects($this->once())->method('getColumnsDefinition')->with($this->equalTo('tx_myextension_mm'))->will($this->returnValue($relationTableColumnsDefinition));
-               $mockDataMapFactory->_callRef('setManyToManyRelation', $mockColumnMap, $leftColumnsDefinition['rights']);
-       }
-
-       /**
-        * @test
-        */
        public function columnMapIsInitializedWithManyToManyRelationWithoutPidColumn() {
                $leftColumnsDefinition = array(
                        'rights' => array(