[BUGFIX] DataMapFactory must detect TCA "type" and "internal_type" 27/24627/8
authorAlexander Schnitzler <alex.schnitzler@typovision.de>
Sat, 12 Oct 2013 12:09:15 +0000 (14:09 +0200)
committerAnja Leichsenring <aleichsenring@ab-softlab.de>
Sun, 13 Oct 2013 10:47:05 +0000 (12:47 +0200)
When building the column maps inside DataMapFactory
the column configurations "type" and "internal_type"
are not considered at all. This is necessary for
several follow up patches improving the handling
of e.g. mm_match_fields.

Releases: 6.2
Resolves: #52723
Change-Id: Id7bc9a8ae9d46a01c1f5fef92f7e7ec5a1e3eb60
Reviewed-on: https://review.typo3.org/24627
Reviewed-by: Sascha Egerer
Tested-by: Sascha Egerer
Reviewed-by: Anja Leichsenring
Tested-by: Anja Leichsenring
typo3/sysext/core/Classes/DataHandling/TableColumnSubType.php [new file with mode: 0644]
typo3/sysext/core/Classes/DataHandling/TableColumnType.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Persistence/Generic/Mapper/ColumnMap.php
typo3/sysext/extbase/Classes/Persistence/Generic/Mapper/DataMapFactory.php
typo3/sysext/extbase/Tests/Unit/Persistence/Generic/Mapper/DataMapFactoryTest.php

diff --git a/typo3/sysext/core/Classes/DataHandling/TableColumnSubType.php b/typo3/sysext/core/Classes/DataHandling/TableColumnSubType.php
new file mode 100644 (file)
index 0000000..b8066c7
--- /dev/null
@@ -0,0 +1,54 @@
+<?php
+namespace TYPO3\CMS\Core\DataHandling;
+/***************************************************************
+ * Copyright notice
+ *
+ * (c) 2013 Sebastian Fischer <typo3@evoweb.de>
+ * All rights reserved
+ *
+ * This script is part of the TYPO3 project. The TYPO3 project is
+ * free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * The GNU General Public License can be found at
+ * http://www.gnu.org/copyleft/gpl.html.
+ *
+ * This script is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+/**
+ * Enumeration object for tca internal type
+ *
+ * @package TYPO3\CMS\Core
+ */
+class TableColumnSubType extends \TYPO3\CMS\Core\Type\Enumeration {
+       const __default = self::DEFAULT_TYPE;
+
+       /**
+        * Constants reflecting the table column sub type
+        */
+       const DEFAULT_TYPE = '';
+
+       const DB = 'DB';
+       const FILE = 'FILE';
+       const FILE_REFERENCE = 'FILE_REFERENCE';
+       const FOLDER = 'FOLDER';
+
+       /**
+        * @param mixed $subType
+        */
+       public function __construct($subType = NULL) {
+               if ($subType !== NULL) {
+                       $subType = strtoupper((string) $subType);
+               }
+
+               parent::__construct($subType);
+       }
+}
\ No newline at end of file
diff --git a/typo3/sysext/core/Classes/DataHandling/TableColumnType.php b/typo3/sysext/core/Classes/DataHandling/TableColumnType.php
new file mode 100644 (file)
index 0000000..a54b421
--- /dev/null
@@ -0,0 +1,59 @@
+<?php
+namespace TYPO3\CMS\Core\DataHandling;
+/***************************************************************
+ * Copyright notice
+ *
+ * (c) 2013 Sebastian Fischer <typo3@evoweb.de>
+ * All rights reserved
+ *
+ * This script is part of the TYPO3 project. The TYPO3 project is
+ * free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * The GNU General Public License can be found at
+ * http://www.gnu.org/copyleft/gpl.html.
+ *
+ * This script is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+/**
+ * Enumeration object for tca type
+ *
+ * @package TYPO3\CMS\Core
+ */
+class TableColumnType extends \TYPO3\CMS\Core\Type\Enumeration {
+       const __default = self::INPUT;
+
+       /**
+        * Constants reflecting the table column type
+        */
+       const INPUT = 'INPUT';
+       const TEXT = 'TEXT';
+       const CHECK = 'CHECK';
+       const RADIO = 'RADIO';
+       const SELECT = 'SELECT';
+       const GROUP = 'GROUP';
+       const NONE = 'NONE';
+       const PASSTHROUGH = 'PASSTHROUGH';
+       const USER = 'USER';
+       const FLEX = 'FLEX';
+       const INLINE = 'INLINE';
+
+       /**
+        * @param mixed $type
+        */
+       public function __construct($type = NULL) {
+               if ($type !== NULL) {
+                       $type = strtoupper((string) $type);
+               }
+
+               parent::__construct($type);
+       }
+}
\ No newline at end of file
index f7e9e6d..773cd5b 100644 (file)
@@ -31,7 +31,6 @@ namespace TYPO3\CMS\Extbase\Persistence\Generic\Mapper;
  * A column map to map a column configured in $TCA on a property of a domain object.
  */
 class ColumnMap {
-
        /**
         * Constants reflecting the type of relation
         */
@@ -171,6 +170,16 @@ class ColumnMap {
        protected $dateTimeStorageFormat;
 
        /**
+        * @var \TYPO3\CMS\Core\DataHandling\TableColumnType
+        */
+       protected $type;
+
+       /**
+        * @var \TYPO3\CMS\Core\DataHandling\TableColumnSubType
+        */
+       protected $internalType;
+
+       /**
         * Constructs a Column Map
         *
         * @param string $columnName The column name
@@ -392,4 +401,32 @@ class ColumnMap {
        public function getDateTimeStorageFormat() {
                return $this->dateTimeStorageFormat;
        }
+
+       /**
+        * @param \TYPO3\CMS\Core\DataHandling\TableColumnSubType $internalType
+        */
+       public function setInternalType($internalType) {
+               $this->internalType = $internalType;
+       }
+
+       /**
+        * @return \TYPO3\CMS\Core\DataHandling\TableColumnSubType
+        */
+       public function getInternalType() {
+               return $this->internalType;
+       }
+
+       /**
+        * @param \TYPO3\CMS\Core\DataHandling\TableColumnType $type
+        */
+       public function setType($type) {
+               $this->type = $type;
+       }
+
+       /**
+        * @return \TYPO3\CMS\Core\DataHandling\TableColumnType
+        */
+       public function getType() {
+               return $this->type;
+       }
 }
index 92ed44a..0225282 100644 (file)
@@ -27,6 +27,8 @@ namespace TYPO3\CMS\Extbase\Persistence\Generic\Mapper;
  *
  *  This copyright notice MUST APPEAR in all copies of the script!
  ***************************************************************/
+use TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap;
+
 /**
  * A factory for a data map to map a single table configured in $TCA on a domain object.
  */
@@ -146,6 +148,7 @@ class DataMapFactory implements \TYPO3\CMS\Core\SingletonInterface {
                        // if (in_array($propertyName, $classPropertyNames)) { // TODO Enable check for property existance
                        $columnMap = $this->createColumnMap($columnName, $propertyName);
                        $propertyMetaData = $this->reflectionService->getClassSchema($className)->getProperty($propertyName);
+                       $columnMap = $this->setType($columnMap, $columnDefinition['config']);
                        $columnMap = $this->setRelations($columnMap, $columnDefinition['config'], $propertyMetaData);
                        $columnMap = $this->setFieldEvaluations($columnMap, $columnDefinition['config']);
                        $dataMap->addColumnMap($columnMap);
@@ -267,15 +270,31 @@ class DataMapFactory implements \TYPO3\CMS\Core\SingletonInterface {
        }
 
        /**
+        * Set the table column type
+        *
+        * @param ColumnMap $columnMap
+        * @param array $columnConfiguration
+        * @return ColumnMap
+        */
+       protected function setType(ColumnMap $columnMap, $columnConfiguration) {
+               $tableColumnType = (isset($columnConfiguration['type'])) ? $columnConfiguration['type'] : NULL;
+               $columnMap->setType(\TYPO3\CMS\Core\DataHandling\TableColumnType::cast($tableColumnType));
+               $tableColumnSubType = (isset($columnConfiguration['internal_type'])) ? $columnConfiguration['internal_type'] : NULL;
+               $columnMap->setInternalType(\TYPO3\CMS\Core\DataHandling\TableColumnSubType::cast($tableColumnSubType));
+
+               return $columnMap;
+       }
+
+       /**
         * This method tries to determine the type of type of relation to other tables and sets it based on
         * the $TCA column configuration
         *
-        * @param \TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap $columnMap The column map
+        * @param ColumnMap $columnMap The column map
         * @param string $columnConfiguration The column configuration from $TCA
         * @param array $propertyMetaData The property metadata as delivered by the reflection service
-        * @return \TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap
+        * @return ColumnMap
         */
-       protected function setRelations(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap $columnMap, $columnConfiguration, $propertyMetaData) {
+       protected function setRelations(ColumnMap $columnMap, $columnConfiguration, $propertyMetaData) {
                if (isset($columnConfiguration)) {
                        if (isset($columnConfiguration['MM'])) {
                                $columnMap = $this->setManyToManyRelation($columnMap, $columnConfiguration);
@@ -284,11 +303,11 @@ class DataMapFactory implements \TYPO3\CMS\Core\SingletonInterface {
                        } elseif (isset($propertyMetaData['type']) && strpbrk($propertyMetaData['type'], '_\\') !== FALSE) {
                                $columnMap = $this->setOneToOneRelation($columnMap, $columnConfiguration);
                        } else {
-                               $columnMap->setTypeOfRelation(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap::RELATION_NONE);
+                               $columnMap->setTypeOfRelation(ColumnMap::RELATION_NONE);
                        }
 
                } else {
-                       $columnMap->setTypeOfRelation(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap::RELATION_NONE);
+                       $columnMap->setTypeOfRelation(ColumnMap::RELATION_NONE);
                }
                return $columnMap;
        }
@@ -317,12 +336,12 @@ class DataMapFactory implements \TYPO3\CMS\Core\SingletonInterface {
         * This method sets the configuration for a 1:1 relation based on
         * the $TCA column configuration
         *
-        * @param string|\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap $columnMap The column map
+        * @param string|ColumnMap $columnMap The column map
         * @param string $columnConfiguration The column configuration from $TCA
-        * @return \TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap
+        * @return ColumnMap
         */
-       protected function setOneToOneRelation(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap $columnMap, $columnConfiguration) {
-               $columnMap->setTypeOfRelation(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap::RELATION_HAS_ONE);
+       protected function setOneToOneRelation(ColumnMap $columnMap, $columnConfiguration) {
+               $columnMap->setTypeOfRelation(ColumnMap::RELATION_HAS_ONE);
                $columnMap->setChildTableName($columnConfiguration['foreign_table']);
                $columnMap->setChildTableWhereStatement($columnConfiguration['foreign_table_where']);
                $columnMap->setChildSortByFieldName($columnConfiguration['foreign_sortby']);
@@ -338,12 +357,12 @@ class DataMapFactory implements \TYPO3\CMS\Core\SingletonInterface {
         * This method sets the configuration for a 1:n relation based on
         * the $TCA column configuration
         *
-        * @param string|\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap $columnMap The column map
+        * @param string|ColumnMap $columnMap The column map
         * @param string $columnConfiguration The column configuration from $TCA
-        * @return \TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap
+        * @return ColumnMap
         */
-       protected function setOneToManyRelation(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap $columnMap, $columnConfiguration) {
-               $columnMap->setTypeOfRelation(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap::RELATION_HAS_MANY);
+       protected function setOneToManyRelation(ColumnMap $columnMap, $columnConfiguration) {
+               $columnMap->setTypeOfRelation(ColumnMap::RELATION_HAS_MANY);
                $columnMap->setChildTableName($columnConfiguration['foreign_table']);
                $columnMap->setChildTableWhereStatement($columnConfiguration['foreign_table_where']);
                $columnMap->setChildSortByFieldName($columnConfiguration['foreign_sortby']);
@@ -359,14 +378,14 @@ class DataMapFactory implements \TYPO3\CMS\Core\SingletonInterface {
         * This method sets the configuration for a m:n relation based on
         * the $TCA column configuration
         *
-        * @param string|\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap $columnMap The column map
+        * @param string|ColumnMap $columnMap The column map
         * @param string $columnConfiguration The column configuration from $TCA
         * @throws \TYPO3\CMS\Extbase\Persistence\Generic\Exception\UnsupportedRelationException
-        * @return \TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap
+        * @return ColumnMap
         */
-       protected function setManyToManyRelation(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap $columnMap, $columnConfiguration) {
+       protected function setManyToManyRelation(ColumnMap $columnMap, $columnConfiguration) {
                if (isset($columnConfiguration['MM'])) {
-                       $columnMap->setTypeOfRelation(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap::RELATION_HAS_AND_BELONGS_TO_MANY);
+                       $columnMap->setTypeOfRelation(ColumnMap::RELATION_HAS_AND_BELONGS_TO_MANY);
                        $columnMap->setChildTableName($columnConfiguration['foreign_table']);
                        $columnMap->setChildTableWhereStatement($columnConfiguration['foreign_table_where']);
                        $columnMap->setRelationTableName($columnConfiguration['MM']);
@@ -401,10 +420,9 @@ class DataMapFactory implements \TYPO3\CMS\Core\SingletonInterface {
         * @param string $columnName
         * @param string $propertyName
         *
-        * @return \TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap
+        * @return ColumnMap
         */
        protected function createColumnMap($columnName, $propertyName) {
                return $this->objectManager->get('TYPO3\\CMS\\Extbase\\Persistence\\Generic\\Mapper\\ColumnMap', $columnName, $propertyName);
        }
-
 }
index c70b731..639d6b8 100644 (file)
@@ -1,6 +1,5 @@
 <?php
 namespace TYPO3\CMS\Extbase\Tests\Unit\Persistence\Generic\Mapper;
-
 /***************************************************************
  *  Copyright notice
  *
@@ -27,6 +26,12 @@ namespace TYPO3\CMS\Extbase\Tests\Unit\Persistence\Generic\Mapper;
  *
  *  This copyright notice MUST APPEAR in all copies of the script!
  ***************************************************************/
+
+use TYPO3\CMS\Core\Tests\AccessibleObjectInterface;
+use TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap;
+use TYPO3\CMS\Core\DataHandling\TableColumnType;
+use TYPO3\CMS\Core\DataHandling\TableColumnSubType;
+
 class DataMapFactoryTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
 
        /**
@@ -444,4 +449,47 @@ class DataMapFactoryTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
                );
        }
 
+       /**
+        * @return array
+        */
+       public function tcaConfigurationsContainingTypeAndInternalType() {
+               return array(
+                       array(array('type' => 'input'), TableColumnType::INPUT, NULL),
+                       array(array('type' => 'text'), TableColumnType::TEXT, NULL),
+                       array(array('type' => 'check'), TableColumnType::CHECK, NULL),
+                       array(array('type' => 'radio'), TableColumnType::RADIO, NULL),
+                       array(array('type' => 'select'), TableColumnType::SELECT, NULL),
+                       array(array('type' => 'group', 'internal_type' => 'db'), TableColumnType::GROUP, TableColumnSubType::DB),
+                       array(array('type' => 'group', 'internal_type' => 'file'), TableColumnType::GROUP, TableColumnSubType::FILE),
+                       array(array('type' => 'group', 'internal_type' => 'file_reference'), TableColumnType::GROUP, TableColumnSubType::FILE_REFERENCE),
+                       array(array('type' => 'group', 'internal_type' => 'folder'), TableColumnType::GROUP, TableColumnSubType::FOLDER),
+                       array(array('type' => 'none'), TableColumnType::NONE, NULL),
+                       array(array('type' => 'passthrough'), TableColumnType::PASSTHROUGH, NULL),
+                       array(array('type' => 'user'), TableColumnType::USER, NULL),
+                       array(array('type' => 'flex'), TableColumnType::FLEX, NULL),
+                       array(array('type' => 'inline'), TableColumnType::INLINE, NULL),
+               );
+       }
+
+       /**
+        * @test
+        * @dataProvider tcaConfigurationsContainingTypeAndInternalType
+        *
+        * @param array $columnConfiguration
+        * @param string $type
+        * @param string $internalType
+        */
+       public function setTypeDetectsTypeAndInternalTypeProperly(array $columnConfiguration, $type, $internalType) {
+               /** @var $dataMapFactory \TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapFactory | AccessibleObjectInterface */
+               $dataMapFactory = $this->getAccessibleMock('TYPO3\\CMS\\Extbase\\Persistence\\Generic\\Mapper\\DataMapFactory', array('dummy'));
+               $dataMapFactory->_set('objectManager', $this->objectManager);
+
+               /** @var \TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap $columnMap */
+               $columnMap = $this->getAccessibleMock('TYPO3\CMS\Extbase\Persistence\Generic\Mapper\ColumnMap', array('dummy'), array(), '', FALSE);
+
+               $dataMapFactory->_call('setType', $columnMap, $columnConfiguration);
+
+               $this->assertEquals($type, (string) $columnMap->getType());
+               $this->assertEquals($internalType, (string) $columnMap->getInternalType());
+       }
 }