From 5fd4787e58a16d110f508864044d3d3d1c842b7a Mon Sep 17 00:00:00 2001 From: Jochen Rau Date: Tue, 20 Oct 2009 21:38:16 +0000 Subject: [PATCH] [~TASK] Extbase: Refactored Dispatcher. Moved initialization of cache and reflection to separate methods to decrease cohesion. [~TASK] Extbase (MVC): Refactored classes and unit tests of Abstract Controller, Argument and Arguments. Moved creation of new Argument to separate method in Arguments class. Decoupled constructor from object initialization to improve testability. [~TASK] Extbase (MVC): Backported some changes to Argument performed in FLOW3. Second parameter of Argument constructor is now required. [~TASK] Extbase (Persistence): Refactored ObjectStorage to remove duplicated code. [+TASK] Extbase (Persistence): Refactored method setRelations() to single level of responsibility. this will enable to implement handling of mm relations defined with IRRE. [+FEATURE] Extbase (Persistence): If a property is an ObjectStorage and annotated with @lazy a LazyObjectStorage is instanciated instead. [~BUGFIX] Extbase (Persistence): The sorting field is now prefixed with the table name. Related to #4470. --- typo3/sysext/extbase/Classes/Dispatcher.php | 59 ++++-- .../MVC/Controller/AbstractController.php | 11 +- .../Classes/MVC/Controller/Argument.php | 21 +- .../Classes/MVC/Controller/Arguments.php | 19 +- .../Classes/Persistence/Mapper/DataMap.php | 138 +++++++++----- .../Classes/Persistence/Mapper/DataMapper.php | 34 +++- .../Classes/Persistence/ObjectStorage.php | 38 ++-- .../Persistence/QOM/QueryObjectModel.php | 2 +- .../Persistence/Storage/Typo3DbBackend.php | 10 +- .../AbstractController_testcase.php | 22 +-- .../MVC/Controller/Argument_testcase.php | 30 ++- .../MVC/Controller/Arguments_testcase.php | 180 +++++++++--------- .../Storage/Typo3DbBackend_testcase.php | 19 +- .../Validation/ValidatorResolver_testcase.php | 6 +- 14 files changed, 372 insertions(+), 217 deletions(-) mode change 100755 => 100644 typo3/sysext/extbase/Classes/MVC/Controller/AbstractController.php diff --git a/typo3/sysext/extbase/Classes/Dispatcher.php b/typo3/sysext/extbase/Classes/Dispatcher.php index d84ba1b8a6c1..83962e3facd4 100644 --- a/typo3/sysext/extbase/Classes/Dispatcher.php +++ b/typo3/sysext/extbase/Classes/Dispatcher.php @@ -51,6 +51,11 @@ class Tx_Extbase_Dispatcher { */ protected static $configurationManager; + /** + * @var t3lib_cache_Manager + */ + protected $cacheManager; + /** * @var Tx_Extbase_Reflection_Service */ @@ -100,6 +105,9 @@ class Tx_Extbase_Dispatcher { $request = $requestBuilder->build(); $response = t3lib_div::makeInstance('Tx_Extbase_MVC_Web_Response'); + $this->initializeCache(); + $this->initializeReflection(); + // Request hash service $requestHashService = t3lib_div::makeInstance('Tx_Extbase_Security_Channel_RequestHashService'); // singleton $requestHashService->verifyRequest($request); @@ -164,6 +172,37 @@ class Tx_Extbase_Dispatcher { } self::$extbaseFrameworkConfiguration = self::$configurationManager->getFrameworkConfiguration($configuration); } + + /** + * Initializes the cache framework + * + * @return void + */ + public function initializeCache() { + $this->cacheManager = $GLOBALS['typo3CacheManager']; + try { + $this->cacheManager->getCache('cache_extbase_reflection'); + } catch (t3lib_cache_exception_NoSuchCache $exception) { + $GLOBALS['typo3CacheFactory']->create( + 'cache_extbase_reflection', + 't3lib_cache_frontend_VariableFrontend', + $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['cache_extbase_reflection']['backend'], + $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['cache_extbase_reflection']['options'] + ); + } + } + + /** + * Initializes the Reflection Service + * + * @return void + * @see initialize() + */ + public function initializeReflection() { + self::$reflectionService = t3lib_div::makeInstance('Tx_Extbase_Reflection_Service'); + self::$reflectionService->setCache($this->cacheManager->getCache('cache_extbase_reflection')); + self::$reflectionService->initialize($availableClassNames); + } /** * Builds and returns a controller @@ -177,7 +216,6 @@ class Tx_Extbase_Dispatcher { if (!$controller instanceof Tx_Extbase_MVC_Controller_ControllerInterface) { throw new Tx_Extbase_MVC_Exception_InvalidController('Invalid controller "' . $request->getControllerObjectName() . '". The controller must implement the Tx_Extbase_MVC_Controller_ControllerInterface.', 1202921619); } - self::$reflectionService = t3lib_div::makeInstance('Tx_Extbase_Reflection_Service'); $propertyMapper = t3lib_div::makeInstance('Tx_Extbase_Property_Mapper'); $propertyMapper->injectReflectionService(self::$reflectionService); $controller->injectPropertyMapper($propertyMapper); @@ -187,24 +225,6 @@ class Tx_Extbase_Dispatcher { $flashMessages->reset(); $controller->injectFlashMessages($flashMessages); - /** @var $cacheManager t3lib_cache_Manager */ - $cacheManager = $GLOBALS['typo3CacheManager']; - - try { - self::$reflectionService->setCache($cacheManager->getCache('cache_extbase_reflection')); - } catch (t3lib_cache_exception_NoSuchCache $exception) { - - $GLOBALS['typo3CacheFactory']->create( - 'cache_extbase_reflection', - 't3lib_cache_frontend_VariableFrontend', - $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['cache_extbase_reflection']['backend'], - $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['cache_extbase_reflection']['options'] - ); - self::$reflectionService->setCache($cacheManager->getCache('cache_extbase_reflection')); - } - if (!self::$reflectionService->isInitialized()) { - self::$reflectionService->initialize(); - } $objectManager = t3lib_div::makeInstance('Tx_Extbase_Object_Manager'); $validatorResolver = t3lib_div::makeInstance('Tx_Extbase_Validation_ValidatorResolver'); $validatorResolver->injectObjectManager($objectManager); @@ -223,6 +243,7 @@ class Tx_Extbase_Dispatcher { public static function getPersistenceManager() { if (self::$persistenceManager === NULL) { $dataMapper = t3lib_div::makeInstance('Tx_Extbase_Persistence_Mapper_DataMapper'); // singleton + $dataMapper->injectReflectionService(self::$reflectionService); $storageBackend = t3lib_div::makeInstance('Tx_Extbase_Persistence_Storage_Typo3DbBackend', $GLOBALS['TYPO3_DB']); // singleton $storageBackend->injectDataMapper($dataMapper); diff --git a/typo3/sysext/extbase/Classes/MVC/Controller/AbstractController.php b/typo3/sysext/extbase/Classes/MVC/Controller/AbstractController.php old mode 100755 new mode 100644 index 20e6fbd7f8f9..1c19ab8a2214 --- a/typo3/sysext/extbase/Classes/MVC/Controller/AbstractController.php +++ b/typo3/sysext/extbase/Classes/MVC/Controller/AbstractController.php @@ -115,11 +115,20 @@ abstract class Tx_Extbase_MVC_Controller_AbstractController implements Tx_Extbas * Constructs the controller. */ public function __construct() { + $this->initializeObjects(); + list(, $this->extensionName) = explode('_', get_class($this)); + } + + /** + * Initializes objects this class depends on + * + * @return void + */ + protected function initializeObjects() { $this->objectManager = t3lib_div::makeInstance('Tx_Extbase_Object_Manager'); $this->arguments = t3lib_div::makeInstance('Tx_Extbase_MVC_Controller_Arguments'); $this->arguments->injectPersistenceManager(Tx_Extbase_Dispatcher::getPersistenceManager()); $this->arguments->injectQueryFactory(t3lib_div::makeInstance('Tx_Extbase_Persistence_QueryFactory')); - list(, $this->extensionName) = explode('_', get_class($this)); } /** diff --git a/typo3/sysext/extbase/Classes/MVC/Controller/Argument.php b/typo3/sysext/extbase/Classes/MVC/Controller/Argument.php index fcc59e9adf9c..3483ba9912c7 100644 --- a/typo3/sysext/extbase/Classes/MVC/Controller/Argument.php +++ b/typo3/sysext/extbase/Classes/MVC/Controller/Argument.php @@ -66,7 +66,7 @@ class Tx_Extbase_MVC_Controller_Argument { * Data type of this argument's value * @var string */ - protected $dataType = 'Text'; + protected $dataType = NULL; /** * If the data type is an object, the class schema of the data type class is resolved @@ -125,13 +125,23 @@ class Tx_Extbase_MVC_Controller_Argument { * @throws InvalidArgumentException if $name is not a string or empty * @api */ - public function __construct($name, $dataType = 'Text') { + public function __construct($name, $dataType) { + if (!is_string($name)) throw new InvalidArgumentException('$name must be of type string, ' . gettype($name) . ' given.', 1187951688); + if (strlen($name) === 0) throw new InvalidArgumentException('$name must be a non-empty string, ' . strlen($name) . ' characters given.', 1232551853); + $this->name = $name; + $this->dataType = $dataType; + } + + /** + * Initializes this object + * + * @return void + */ + public function initializeObject() { $this->reflectionService = t3lib_div::makeInstance('Tx_Extbase_Reflection_Service'); $this->propertyMapper = t3lib_div::makeInstance('Tx_Extbase_Property_Mapper'); $this->propertyMapper->injectReflectionService($this->reflectionService); - if (!is_string($name) || strlen($name) < 1) throw new InvalidArgumentException('$name must be of type string, ' . gettype($name) . ' given.', 1187951688); - $this->name = $name; - $this->setDataType($dataType); + $this->dataTypeClassSchema = $this->reflectionService->getClassSchema($this->dataType); } /** @@ -197,7 +207,6 @@ class Tx_Extbase_MVC_Controller_Argument { */ public function setDataType($dataType) { $this->dataType = $dataType; - $this->dataTypeClassSchema = $this->reflectionService->getClassSchema($this->dataType); return $this; } diff --git a/typo3/sysext/extbase/Classes/MVC/Controller/Arguments.php b/typo3/sysext/extbase/Classes/MVC/Controller/Arguments.php index c73326943367..b016f39ae2d7 100644 --- a/typo3/sysext/extbase/Classes/MVC/Controller/Arguments.php +++ b/typo3/sysext/extbase/Classes/MVC/Controller/Arguments.php @@ -151,14 +151,27 @@ class Tx_Extbase_MVC_Controller_Arguments extends ArrayObject { * @return Tx_Extbase_MVC_Controller_Argument The new argument */ public function addNewArgument($name, $dataType = 'Text', $isRequired = FALSE, $defaultValue = NULL) { - $argument = new Tx_Extbase_MVC_Controller_Argument($name, $dataType); - $argument->injectPersistenceManager($this->persistenceManager); - $argument->injectQueryFactory($this->queryFactory); + $argument = $this->createArgument($name, $dataType); $argument->setRequired($isRequired); $argument->setDefaultValue($defaultValue); $this->addArgument($argument); return $argument; } + + /** + * Creates a new argument. This is a replacement for $this->objectFactory->create() of FLOW3. + * + * @param string $name Name of the argument + * @param string $dataType Name of one of the built-in data types + * @return Tx_Extbase_MVC_Controller_Argument The created argument + */ + protected function createArgument($name, $dataType) { + $argument = new Tx_Extbase_MVC_Controller_Argument($name, $dataType); + $argument->injectPersistenceManager($this->persistenceManager); + $argument->injectQueryFactory($this->queryFactory); + $argument->initializeObject(); + return $argument; + } /** * Adds the specified controller argument to this composite object. diff --git a/typo3/sysext/extbase/Classes/Persistence/Mapper/DataMap.php b/typo3/sysext/extbase/Classes/Persistence/Mapper/DataMap.php index d3c3805be00f..37878d23e89c 100644 --- a/typo3/sysext/extbase/Classes/Persistence/Mapper/DataMap.php +++ b/typo3/sysext/extbase/Classes/Persistence/Mapper/DataMap.php @@ -118,14 +118,15 @@ class Tx_Extbase_Persistence_Mapper_DataMap { $columns = $GLOBALS['TCA'][$this->getTableName()]['columns']; $this->addCommonColumns(); if (is_array($columns)) { - foreach ($columns as $columnName => $columnConfiguration) { + foreach ($columns as $columnName => $columnDefinition) { + $columnConfiguration = $columnDefinition['config']; if (!empty($mapping[$columnName]['mapOnProperty'])) { $propertyName = $mapping[$columnName]['mapOnProperty']; } else { $propertyName = Tx_Extbase_Utility_Extension::convertUnderscoredToLowerCamelCase($columnName); } - if (isset($mapping[$columnName]['foreignClass']) && !isset($columnConfiguration['config']['foreign_class'])) { - $columnConfiguration['config']['foreign_class'] = $mapping[$columnName]['foreignClass']; + if (isset($mapping[$columnName]['foreignClass']) && !isset($columnConfiguration['foreign_class'])) { + $columnConfiguration['foreign_class'] = $mapping[$columnName]['foreignClass']; } $columnMap = new Tx_Extbase_Persistence_Mapper_ColumnMap($columnName, $propertyName); $this->setPropertyType($columnMap, $columnConfiguration); @@ -173,19 +174,19 @@ class Tx_Extbase_Persistence_Mapper_DataMap { * @return void */ protected function setPropertyType(Tx_Extbase_Persistence_Mapper_ColumnMap &$columnMap, $columnConfiguration) { - $evalConfiguration = t3lib_div::trimExplode(',', $columnConfiguration['config']['eval']); + $evalConfiguration = t3lib_div::trimExplode(',', $columnConfiguration['eval']); if (in_array('date', $evalConfiguration) || in_array('datetime', $evalConfiguration)) { $columnMap->setPropertyType(Tx_Extbase_Persistence_PropertyType::DATE); - } elseif ($columnConfiguration['config']['type'] === 'check' && empty($columnConfiguration['config']['items'])) { + } elseif ($columnConfiguration['type'] === 'check' && empty($columnConfiguration['items'])) { $columnMap->setPropertyType(Tx_Extbase_Persistence_PropertyType::BOOLEAN); } elseif (in_array('int', $evalConfiguration)) { $columnMap->setPropertyType(Tx_Extbase_Persistence_PropertyType::LONG); } elseif (in_array('double2', $evalConfiguration)) { $columnMap->setPropertyType(Tx_Extbase_Persistence_PropertyType::DOUBLE); } else { - if (isset($columnConfiguration['config']['foreign_table'])) { - if (isset($columnConfiguration['config']['loadingStrategy'])) { - $columnMap->setLoadingStrategy($columnConfiguration['config']['loadingStrategy']); + if (isset($columnConfiguration['foreign_table'])) { + if (isset($columnConfiguration['loadingStrategy'])) { + $columnMap->setLoadingStrategy($columnConfiguration['loadingStrategy']); } else { $columnMap->setLoadingStrategy(Tx_Extbase_Persistence_Mapper_ColumnMap::STRATEGY_EAGER); } @@ -205,46 +206,91 @@ class Tx_Extbase_Persistence_Mapper_DataMap { * @return void */ protected function setRelations(Tx_Extbase_Persistence_Mapper_ColumnMap &$columnMap, $columnConfiguration) { - if (isset($columnConfiguration['config']) && $columnConfiguration['config']['type'] !== 'passthrough') { - if (isset($columnConfiguration['config']['foreign_table']) && !isset($columnConfiguration['config']['MM'])) { - if ($columnConfiguration['config']['maxitems'] == 1) { - $columnMap->setTypeOfRelation(Tx_Extbase_Persistence_Mapper_ColumnMap::RELATION_HAS_ONE); + if (isset($columnConfiguration) && $columnConfiguration['type'] !== 'passthrough') { + if (isset($columnConfiguration['foreign_table']) && !isset($columnConfiguration['MM']) && !isset($columnConfiguration['foreign_label'])) { + if ($columnConfiguration['maxitems'] == 1) { + $this->setOneToOneRelation($columnMap, $columnConfiguration); } else { - $columnMap->setTypeOfRelation(Tx_Extbase_Persistence_Mapper_ColumnMap::RELATION_HAS_MANY); + $this->setOneToManyRelation($columnMap, $columnConfiguration); } - $columnMap->setChildClassName($this->determineChildClassName($columnConfiguration)); - $columnMap->setChildTableName($columnConfiguration['config']['foreign_table']); - $columnMap->setChildTableWhereStatement($columnConfiguration['config']['foreign_table_where']); - $columnMap->setChildSortbyFieldName($columnConfiguration['config']['foreign_sortby']); - $columnMap->setDeleteChildObjectsState($columnConfiguration['config']['deleteRelationsWithParent']); - $columnMap->setParentKeyFieldName($columnConfiguration['config']['foreign_field']); - $columnMap->setParentTableFieldName($columnConfiguration['config']['foreign_table_field']); - } elseif (array_key_exists('MM', $columnConfiguration['config'])) { + } elseif ($columnConfiguration['type'] === 'inline' && isset($columnConfiguration['foreign_table']) && isset($columnConfiguration['foreign_label'])) { + $this->setManyToManyRelation($columnMap, $columnConfiguration); + } elseif ($columnConfiguration['type'] !== 'inline' && isset($columnConfiguration['MM'])) { // TODO support for MM_insert_fields and MM_match_fields - $columnMap->setTypeOfRelation(Tx_Extbase_Persistence_Mapper_ColumnMap::RELATION_HAS_AND_BELONGS_TO_MANY); - $columnMap->setChildClassName($this->determineChildClassName($columnConfiguration)); - $columnMap->setChildTableName($columnConfiguration['config']['foreign_table']); - $columnMap->setRelationTableName($columnConfiguration['config']['MM']); - if (is_array($columnConfiguration['config']['MM_match_fields'])) { - $columnMap->setRelationTableMatchFields($columnConfiguration['config']['MM_match_fields']); - } - $columnMap->setRelationTableWhereStatement($columnConfiguration['config']['MM_table_where']); - // TODO We currently do not support multi table relationships - if ($columnConfiguration['config']['MM_opposite_field']) { - $columnMap->setParentKeyFieldName('uid_foreign'); - $columnMap->setChildKeyFieldName('uid_local'); - $columnMap->setChildSortByFieldName('sorting_foreign'); - } else { - $columnMap->setParentKeyFieldName('uid_local'); - $columnMap->setChildKeyFieldName('uid_foreign'); - $columnMap->setChildSortByFieldName('sorting'); - } + $this->setManyToManyRelation($columnMap, $columnConfiguration); } else { $columnMap->setTypeOfRelation(Tx_Extbase_Persistence_Mapper_ColumnMap::RELATION_NONE); } } } + /** + * This method sets the configuration for a 1:1 relation based on + * the $TCA column configuration + * + * @param string $columnMap The column map + * @param string $columnConfiguration The column configuration from $TCA + * @return void + */ + protected function setOneToOneRelation(Tx_Extbase_Persistence_Mapper_ColumnMap &$columnMap, $columnConfiguration) { + $columnMap->setTypeOfRelation(Tx_Extbase_Persistence_Mapper_ColumnMap::RELATION_HAS_ONE); + $columnMap->setChildClassName($this->determineChildClassName($columnConfiguration)); + $columnMap->setChildTableName($columnConfiguration['foreign_table']); + $columnMap->setChildTableWhereStatement($columnConfiguration['foreign_table_where']); + $columnMap->setChildSortbyFieldName($columnConfiguration['foreign_sortby']); + $columnMap->setDeleteChildObjectsState($columnConfiguration['deleteRelationsWithParent']); + $columnMap->setParentKeyFieldName($columnConfiguration['foreign_field']); + $columnMap->setParentTableFieldName($columnConfiguration['foreign_table_field']); + } + + /** + * This method sets the configuration for a 1:n relation based on + * the $TCA column configuration + * + * @param string $columnMap The column map + * @param string $columnConfiguration The column configuration from $TCA + * @return void + */ + protected function setOneToManyRelation(Tx_Extbase_Persistence_Mapper_ColumnMap &$columnMap, $columnConfiguration) { + $columnMap->setTypeOfRelation(Tx_Extbase_Persistence_Mapper_ColumnMap::RELATION_HAS_MANY); + $columnMap->setChildClassName($this->determineChildClassName($columnConfiguration)); + $columnMap->setChildTableName($columnConfiguration['foreign_table']); + $columnMap->setChildTableWhereStatement($columnConfiguration['foreign_table_where']); + $columnMap->setChildSortbyFieldName($columnConfiguration['foreign_sortby']); + $columnMap->setDeleteChildObjectsState($columnConfiguration['deleteRelationsWithParent']); + $columnMap->setParentKeyFieldName($columnConfiguration['foreign_field']); + $columnMap->setParentTableFieldName($columnConfiguration['foreign_table_field']); + } + + /** + * This method sets the configuration for a m:n relation based on + * the $TCA column configuration + * + * @param string $columnMap The column map + * @param string $columnConfiguration The column configuration from $TCA + * @return void + */ + protected function setManyToManyRelation(Tx_Extbase_Persistence_Mapper_ColumnMap &$columnMap, $columnConfiguration) { + $columnMap->setTypeOfRelation(Tx_Extbase_Persistence_Mapper_ColumnMap::RELATION_HAS_AND_BELONGS_TO_MANY); + $columnMap->setChildClassName($this->determineChildClassName($columnConfiguration)); + $columnMap->setChildTableName($columnConfiguration['foreign_table']); + $columnMap->setRelationTableName($columnConfiguration['MM']); + if (is_array($columnConfiguration['MM_match_fields'])) { + $columnMap->setRelationTableMatchFields($columnConfiguration['MM_match_fields']); + } + $columnMap->setRelationTableWhereStatement($columnConfiguration['MM_table_where']); + // TODO We currently do not support multi table relationships + if ($columnConfiguration['MM_opposite_field']) { + $columnMap->setParentKeyFieldName('uid_foreign'); + $columnMap->setChildKeyFieldName('uid_local'); + $columnMap->setChildSortByFieldName('sorting_foreign'); + } else { + $columnMap->setParentKeyFieldName('uid_local'); + $columnMap->setChildKeyFieldName('uid_foreign'); + $columnMap->setChildSortByFieldName('sorting'); + } + } + /** * This function determines the child class name. It can either be defined as foreign_class in the column configuration (TCA) * or it must be defined in the extbase framework configuration (reverse mapping from tableName to className). @@ -254,15 +300,17 @@ class Tx_Extbase_Persistence_Mapper_DataMap { */ protected function determineChildClassName($columnConfiguration) { $foreignClassName = ''; - if (is_string($columnConfiguration['config']['foreign_class']) && (strlen($columnConfiguration['config']['foreign_class']) > 0)) { - $foreignClassName = $columnConfiguration['config']['foreign_class']; + if (is_string($columnConfiguration['foreign_class']) && (strlen($columnConfiguration['foreign_class']) > 0)) { + $foreignClassName = $columnConfiguration['foreign_class']; } else { $extbaseSettings = Tx_Extbase_Dispatcher::getExtbaseFrameworkConfiguration(); // TODO Apply a cache to increase performance (profile first) - foreach ($extbaseSettings['persistence']['classes'] as $className => $classConfiguration) { - if ($classConfiguration['mapping']['tableName'] === $columnConfiguration['config']['foreign_table']) { - $foreignClassName = $className; - break; + if (is_array($extbaseSettings['persistence']['classes'])) { + foreach ($extbaseSettings['persistence']['classes'] as $className => $classConfiguration) { + if ($classConfiguration['mapping']['tableName'] === $columnConfiguration['foreign_table']) { + $foreignClassName = $className; + break; + } } } } diff --git a/typo3/sysext/extbase/Classes/Persistence/Mapper/DataMapper.php b/typo3/sysext/extbase/Classes/Persistence/Mapper/DataMapper.php index 4c4235e9cdf7..8278d94f739d 100644 --- a/typo3/sysext/extbase/Classes/Persistence/Mapper/DataMapper.php +++ b/typo3/sysext/extbase/Classes/Persistence/Mapper/DataMapper.php @@ -36,6 +36,11 @@ class Tx_Extbase_Persistence_Mapper_DataMapper implements t3lib_Singleton { */ protected $identityMap; + /** + * @var Tx_Extbase_Reflection_Service + */ + protected $reflectionService; + /** * @var Tx_Extbase_Persistence_QOM_QueryObjectModelFactory */ @@ -100,6 +105,16 @@ class Tx_Extbase_Persistence_Mapper_DataMapper implements t3lib_Singleton { $this->QOMFactory = $persistenceManager->getBackend()->getQOMFactory(); $this->persistenceSession = $persistenceManager->getSession(); } + + /** + * Injects the Reflection Service + * + * @param Tx_Extbase_Reflection_Service + * @return void + */ + public function injectReflectionService(Tx_Extbase_Reflection_Service $reflectionService) { + $this->reflectionService = $reflectionService; + } /** * Maps the (aggregate root) rows and registers them as reconstituted @@ -217,6 +232,8 @@ class Tx_Extbase_Persistence_Mapper_DataMapper implements t3lib_Singleton { protected function mapRelatedObjects(Tx_Extbase_DomainObject_AbstractEntity $parentObject, $propertyName, Tx_Extbase_Persistence_RowInterface $row, Tx_Extbase_Persistence_Mapper_ColumnMap $columnMap) { $dataMap = $this->getDataMap(get_class($parentObject)); $columnMap = $dataMap->getColumnMap($propertyName); + $targetClassSchema = $this->reflectionService->getClassSchema(get_class($parentObject)); + $propertyMetaData = $targetClassSchema->getProperty($propertyName); $fieldValue = $row[$columnMap->getColumnName()]; if ($columnMap->getLoadingStrategy() === Tx_Extbase_Persistence_Mapper_ColumnMap::STRATEGY_LAZY_PROXY) { $result = t3lib_div::makeInstance('Tx_Extbase_Persistence_LazyLoadingProxy', $parentObject, $propertyName, $fieldValue, $columnMap); @@ -229,18 +246,21 @@ class Tx_Extbase_Persistence_Mapper_DataMapper implements t3lib_Singleton { $query->getQuerySettings()->setRespectStoragePage(FALSE); $result = current($query->matching($query->withUid((int)$fieldValue))->execute()); } elseif (($columnMap->getTypeOfRelation() === Tx_Extbase_Persistence_Mapper_ColumnMap::RELATION_HAS_MANY) || ($columnMap->getTypeOfRelation() === Tx_Extbase_Persistence_Mapper_ColumnMap::RELATION_HAS_AND_BELONGS_TO_MANY)) { - if ($columnMap->getLoadingStrategy() === Tx_Extbase_Persistence_Mapper_ColumnMap::STRATEGY_LAZY_STORAGE) { - $objectStorage = new Tx_Extbase_Persistence_LazyObjectStorage($parentObject, $propertyName, $fieldValue, $columnMap); + if ($propertyMetaData['lazy'] === TRUE || $columnMap->getLoadingStrategy() === Tx_Extbase_Persistence_Mapper_ColumnMap::STRATEGY_LAZY_STORAGE) { + $result = new Tx_Extbase_Persistence_LazyObjectStorage($parentObject, $propertyName, $fieldValue, $columnMap); } else { - $objectStorage = new Tx_Extbase_Persistence_ObjectStorage(); - if (!empty($fieldValue)) { - $objects = $this->fetchRelatedObjects($parentObject, $propertyName, $fieldValue, $columnMap); + $objects = $this->fetchRelatedObjects($parentObject, $propertyName, $fieldValue, $columnMap); + if ($propertyMetaData['type'] === 'ArrayObject') { + $result = new ArrayObject($objects); + } elseif ($propertyMetaData['type'] === 'Tx_Extbase_Persistence_ObjectStorage' || $propertyMetaData['type'] === 'Tx_Extbase_Persistence_LazyObjectStorage') { + $result = new Tx_Extbase_Persistence_ObjectStorage(); foreach ($objects as $object) { - $objectStorage->attach($object); + $result->attach($object); } + } else { + $result = $objects; } } - $result = $objectStorage; } } return $result; diff --git a/typo3/sysext/extbase/Classes/Persistence/ObjectStorage.php b/typo3/sysext/extbase/Classes/Persistence/ObjectStorage.php index 5de0ace642ba..05625b042263 100644 --- a/typo3/sysext/extbase/Classes/Persistence/ObjectStorage.php +++ b/typo3/sysext/extbase/Classes/Persistence/ObjectStorage.php @@ -133,7 +133,7 @@ class Tx_Extbase_Persistence_ObjectStorage implements Iterator, Countable, Array * @return boolean TRUE if the given offset exists; otherwise FALSE */ public function offsetExists($offset) { - if (!is_object($offset)) throw new Tx_Extbase_MVC_Exception_InvalidArgumentType('Expected parameter to be an object, ' . gettype($offset) . ' given'); + $this->isObject($offset); $this->initializeStorage(); return isset($this->storage[spl_object_hash($offset)]); } @@ -145,7 +145,7 @@ class Tx_Extbase_Persistence_ObjectStorage implements Iterator, Countable, Array * @return void */ public function offsetUnset($offset) { - if (!is_object($offset)) throw new Tx_Extbase_MVC_Exception_InvalidArgumentType('Expected parameter to be an object, ' . gettype($offset) . ' given'); + $this->isObject($offset); $this->initializeStorage(); unset($this->storage[spl_object_hash($offset)]); } @@ -157,7 +157,7 @@ class Tx_Extbase_Persistence_ObjectStorage implements Iterator, Countable, Array * @return Object The object */ public function offsetGet($offset) { - if (!is_object($offset)) throw new Tx_Extbase_MVC_Exception_InvalidArgumentType('Expected parameter to be an object, ' . gettype($offset) . ' given'); + $this->isObject($offset); $this->initializeStorage(); return isset($this->storage[spl_object_hash($offset)]) ? $this->storage[spl_object_hash($offset)] : NULL; } @@ -169,7 +169,7 @@ class Tx_Extbase_Persistence_ObjectStorage implements Iterator, Countable, Array * @return boolean TRUE|FALSE Returns TRUE if the storage contains the object; otherwise FALSE */ public function contains($object) { - if (!is_object($object)) throw new Tx_Extbase_MVC_Exception_InvalidArgumentType('Expected parameter to be an object, ' . gettype($object) . ' given'); + $this->isObject($object); $this->initializeStorage(); return array_key_exists(spl_object_hash($object), $this->storage); } @@ -181,7 +181,7 @@ class Tx_Extbase_Persistence_ObjectStorage implements Iterator, Countable, Array * @return void */ public function attach($object, $value = NULL) { - if (!is_object($object)) throw new Tx_Extbase_MVC_Exception_InvalidArgumentType('Expected parameter to be an object, ' . gettype($object) . ' given'); + $this->isObject($object); $this->initializeStorage(); if (!$this->contains($object)) { if ($value === NULL) { @@ -199,7 +199,7 @@ class Tx_Extbase_Persistence_ObjectStorage implements Iterator, Countable, Array * @return void */ public function detach($object) { - if (!is_object($object)) throw new Tx_Extbase_MVC_Exception_InvalidArgumentType('Expected parameter to be an object, ' . gettype($object) . ' given'); + $this->isObject($object); $this->initializeStorage(); unset($this->storage[spl_object_hash($object)]); } @@ -211,13 +211,11 @@ class Tx_Extbase_Persistence_ObjectStorage implements Iterator, Countable, Array * @return void */ public function addAll($objects) { - if (is_array($objects) || ($objects instanceof Tx_Extbase_Persistence_ObjectStorage)) { + if (is_array($objects) || $objects instanceof Iterator) { $this->initializeStorage(); foreach ($objects as $object) { $this->attach($object); } - } else { - throw new Tx_Extbase_MVC_Exception_InvalidArgumentType('Expected parameter to be an array, ' . gettype($object) . ' given'); } } @@ -228,11 +226,25 @@ class Tx_Extbase_Persistence_ObjectStorage implements Iterator, Countable, Array * @return void */ public function removeAll($objects) { - if (!is_array($object)) throw new Tx_Extbase_MVC_Exception_InvalidArgumentType('Expected parameter to be an array, ' . gettype($object) . ' given'); - $this->initializeStorage(); - foreach ($objects as $object) { - $this->detach($object); + if (is_array($objects) || $objects instanceof Iterator) { + $this->initializeStorage(); + foreach ($objects as $object) { + $this->detach($object); + } + } + } + + /** + * Checks, if the given value is an object and throws an exception if not + * + * @param string $value The value to be tested + * @return bool TRUE, if the given value is an object + */ + protected function isObject($value) { + if (!is_object($value)) { + throw new Tx_Extbase_MVC_Exception_InvalidArgumentType('Expected parameter to be an object, ' . gettype($offset) . ' given'); } + return TRUE; } /** diff --git a/typo3/sysext/extbase/Classes/Persistence/QOM/QueryObjectModel.php b/typo3/sysext/extbase/Classes/Persistence/QOM/QueryObjectModel.php index 034acd6c4509..396f85ad1ba7 100644 --- a/typo3/sysext/extbase/Classes/Persistence/QOM/QueryObjectModel.php +++ b/typo3/sysext/extbase/Classes/Persistence/QOM/QueryObjectModel.php @@ -120,7 +120,7 @@ class Tx_Extbase_Persistence_QOM_QueryObjectModel implements Tx_Extbase_Persiste * @param array $orderings * @param array $columns */ - public function __construct(Tx_Extbase_Persistence_QOM_SourceInterface $selectorOrSource, $constraint, array $orderings, array $columns) { + public function __construct(Tx_Extbase_Persistence_QOM_SourceInterface $selectorOrSource, $constraint, array $orderings = array(), array $columns = array()) { $this->source = $selectorOrSource; $this->constraint = $constraint; $this->orderings = $orderings; diff --git a/typo3/sysext/extbase/Classes/Persistence/Storage/Typo3DbBackend.php b/typo3/sysext/extbase/Classes/Persistence/Storage/Typo3DbBackend.php index 8cfd6409baf1..8fdd2cc5bd3a 100644 --- a/typo3/sysext/extbase/Classes/Persistence/Storage/Typo3DbBackend.php +++ b/typo3/sysext/extbase/Classes/Persistence/Storage/Typo3DbBackend.php @@ -362,6 +362,7 @@ class Tx_Extbase_Persistence_Storage_Typo3DbBackend implements Tx_Extbase_Persis * @return void */ protected function parseConstraint(Tx_Extbase_Persistence_QOM_ConstraintInterface $constraint = NULL, Tx_Extbase_Persistence_QOM_SourceInterface $source, array &$sql, array &$parameters, array $boundVariableValues) { + if ($constraint === NULL) return; if ($constraint instanceof Tx_Extbase_Persistence_QOM_AndInterface) { $sql['where'][] = '('; $this->parseConstraint($constraint->getConstraint1(), $source, $sql, $parameters, $boundVariableValues); @@ -578,10 +579,11 @@ class Tx_Extbase_Persistence_Storage_Typo3DbBackend implements Tx_Extbase_Persis throw new Tx_Extbase_Persistence_Exception_UnsupportedOrder('Unsupported order encountered.', 1242816074); } $tableName = $operand->getSelectorName(); - if ((strlen($tableName) == 0) && (source instanceof Tx_Extbase_Persistence_QOM_SelectorInterface)) { - $tableName = $source->getSelectorName(); - } - $columnName = $this->dataMapper->convertPropertyNameToColumnName($operand->getPropertyName(), $tableName); + $className = ''; + if ($source instanceof Tx_Extbase_Persistence_QOM_SelectorInterface) { + $className = $source->getNodeTypeName(); + } + $columnName = $this->dataMapper->convertPropertyNameToColumnName($operand->getPropertyName(), $className); if (strlen($tableName) > 0) { $sql['orderings'][] = $tableName . '.' . $columnName . ' ' . $order; } else { diff --git a/typo3/sysext/extbase/Tests/MVC/Controller/AbstractController_testcase.php b/typo3/sysext/extbase/Tests/MVC/Controller/AbstractController_testcase.php index d398cb785e67..030507a63d89 100644 --- a/typo3/sysext/extbase/Tests/MVC/Controller/AbstractController_testcase.php +++ b/typo3/sysext/extbase/Tests/MVC/Controller/AbstractController_testcase.php @@ -30,10 +30,10 @@ class Tx_Extbase_MVC_Controller_AbstractController_testcase extends Tx_Extbase_B /** * @test */ - public function initializeObjectSetsCurrentPackage() { + public function theExtensionNameIsInitialized() { $extensionName = uniqid('Test'); - $controller = $this->getMock('Tx_Extbase_MVC_Controller_AbstractController', array(), array(), 'Tx_' . $extensionName . '_Controller'); - $this->assertSame($extensionName, $this->readAttribute($controller, 'extensionName')); + $controller = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Controller_AbstractController'), array('initializeObjects'), array(), 'Tx_' . $extensionName . '_Controller'); + $this->assertSame($extensionName, $controller->_get('extensionName')); } /** @@ -58,7 +58,7 @@ class Tx_Extbase_MVC_Controller_AbstractController_testcase extends Tx_Extbase_B $mockResponse = $this->getMock('Tx_Extbase_MVC_Web_Response'); - $controller = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Controller_AbstractController'), array('initializeArguments', 'initializeControllerArgumentsBaseValidators', 'mapRequestArgumentsToControllerArguments'), array()); + $controller = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Controller_AbstractController'), array('initializeArguments', 'initializeControllerArgumentsBaseValidators', 'mapRequestArgumentsToControllerArguments'), array(), '', FALSE); $controller->processRequest($mockRequest, $mockResponse); } @@ -144,18 +144,18 @@ class Tx_Extbase_MVC_Controller_AbstractController_testcase extends Tx_Extbase_B $mockValidatorResolver->expects($this->at(0))->method('getBaseValidatorConjunction')->with('FooType')->will($this->returnValue($mockValidators['foo'])); $mockValidatorResolver->expects($this->at(1))->method('getBaseValidatorConjunction')->with('BarType')->will($this->returnValue(NULL)); - $mockArgumentFoo = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array(), array('foo')); + $mockArgumentFoo = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array(), array('foo'), '', FALSE); $mockArgumentFoo->expects($this->once())->method('getDataType')->will($this->returnValue('FooType')); $mockArgumentFoo->expects($this->once())->method('setValidator')->with($mockValidators['foo']); - - $mockArgumentBar = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array(), array('bar')); + + $mockArgumentBar = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array(), array('bar'), '', FALSE); $mockArgumentBar->expects($this->once())->method('getDataType')->will($this->returnValue('BarType')); $mockArgumentBar->expects($this->never())->method('setValidator'); - + $mockArguments = new Tx_Extbase_MVC_Controller_Arguments(); $mockArguments->addArgument($mockArgumentFoo); $mockArguments->addArgument($mockArgumentBar); - + $controller = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Controller_AbstractController'), array('dummy'), array(), '', FALSE); $controller->_set('arguments', $mockArguments); $controller->injectValidatorResolver($mockValidatorResolver); @@ -168,9 +168,9 @@ class Tx_Extbase_MVC_Controller_AbstractController_testcase extends Tx_Extbase_B public function mapRequestArgumentsToControllerArgumentsPreparesInformationAndValidatorsAndMapsAndValidates() { $mockValidator = new Tx_Extbase_MVC_Controller_ArgumentsValidator(); // FIXME see original FLOW3 code - $mockArgumentFoo = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array(), array('foo')); + $mockArgumentFoo = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array(), array('foo'), '', FALSE); $mockArgumentFoo->expects($this->any())->method('getName')->will($this->returnValue('foo')); - $mockArgumentBar = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array(), array('bar')); + $mockArgumentBar = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array(), array('bar'), '', FALSE); $mockArgumentBar->expects($this->any())->method('getName')->will($this->returnValue('bar')); $mockArguments = new Tx_Extbase_MVC_Controller_Arguments(); diff --git a/typo3/sysext/extbase/Tests/MVC/Controller/Argument_testcase.php b/typo3/sysext/extbase/Tests/MVC/Controller/Argument_testcase.php index 5ad2d6449f61..f000b80ee1e3 100644 --- a/typo3/sysext/extbase/Tests/MVC/Controller/Argument_testcase.php +++ b/typo3/sysext/extbase/Tests/MVC/Controller/Argument_testcase.php @@ -72,7 +72,7 @@ class Tx_Extbase_MVC_Controller_Argument_testcase extends Tx_Extbase_BaseTestCas /** * @test */ - public function setValueTriesToConvertAnUIDIntoTheRealObjectIfTheDataTypeClassSchemaIsSet() { + public function setValueTriesToConvertAnUidIntoTheRealObjectIfTheDataTypeClassSchemaIsSet() { $object = new StdClass(); $argument = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_MVC_Controller_Argument'), array('findObjectByUid'), array(), '', FALSE); @@ -101,9 +101,31 @@ class Tx_Extbase_MVC_Controller_Argument_testcase extends Tx_Extbase_BaseTestCas /** * @test */ - public function defaultDataTypeIsText() { - $argument = new Tx_Extbase_MVC_Controller_Argument('SomeArgument'); - $this->assertSame('Text', $argument->getDataType()); + public function dataTypeValidatorCanBeAFullClassName() { + $this->markTestIncomplete(); + + $this->mockObjectManager->expects($this->once())->method('isObjectRegistered')->with('Tx_Extbase_Validation_Validator_TextValidator')->will($this->returnValue(TRUE)); + $this->mockObjectManager->expects($this->any())->method('getObject')->with('Tx_Extbase_Validation_Validator_TextValidator')->will($this->returnValue($this->getMock('Tx_Extbase_Validation_Validator_TextValidator'))); + + $argument = new Tx_Extbase_MVC_Controller_Argument('SomeArgument', 'Tx_Extbase_Validation_Validator_TextValidator'); + $argument->injectObjectManager($this->mockObjectManager); + + $this->assertType('Tx_Extbase_Validation_Validator_TextValidator', $argument->getDatatypeValidator(), 'The returned datatype validator is not a text validator as expected.'); + } + + /** + * @test + */ + public function dataTypeValidatorCanBeAShortName() { + $this->markTestIncomplete(); + + $this->mockObjectManager->expects($this->once())->method('isObjectRegistered')->with('Tx_Extbase_Validation_Validator_TextValidator')->will($this->returnValue(TRUE)); + $this->mockObjectManager->expects($this->any())->method('getObject')->with('Tx_Extbase_Validation_Validator_TextValidator')->will($this->returnValue($this->getMock('Tx_Extbase_Validation_Validator_TextValidator'))); + + $argument = new Tx_Extbase_MVC_Controller_Argument('SomeArgument', 'Text'); + $argument->injectObjectManager($this->mockObjectManager); + + $this->assertType('Tx_Extbase_Validation_Validator_TextValidator', $argument->getDatatypeValidator(), 'The returned datatype validator is not a text validator as expected.'); } /** diff --git a/typo3/sysext/extbase/Tests/MVC/Controller/Arguments_testcase.php b/typo3/sysext/extbase/Tests/MVC/Controller/Arguments_testcase.php index 8d8efbced3c2..69a3f07d553b 100644 --- a/typo3/sysext/extbase/Tests/MVC/Controller/Arguments_testcase.php +++ b/typo3/sysext/extbase/Tests/MVC/Controller/Arguments_testcase.php @@ -29,7 +29,6 @@ class Tx_Extbase_MVC_Controller_Arguments_testcase extends Tx_Extbase_BaseTestCa /** * @test - * @author Robert Lemke */ public function argumentsObjectIsOfScopePrototype() { $arguments1 = $this->objectManager->getObject('Tx_Extbase_MVC_Controller_Arguments'); @@ -39,11 +38,10 @@ class Tx_Extbase_MVC_Controller_Arguments_testcase extends Tx_Extbase_BaseTestCa /** * @test - * @author Robert Lemke */ public function addingAnArgumentManuallyWorks() { $arguments = $this->objectManager->getObject('Tx_Extbase_MVC_Controller_Arguments'); - $newArgument = $this->objectManager->getObject('Tx_Extbase_MVC_Controller_Argument', 'argumentName1234'); + $newArgument = $this->objectManager->getObject('Tx_Extbase_MVC_Controller_Argument', 'argumentName1234', 'dummyValue'); $arguments->addArgument($newArgument); $this->assertSame($newArgument, $arguments->getArgument('argumentName1234'), 'The added and retrieved argument is not the same.'); @@ -51,61 +49,60 @@ class Tx_Extbase_MVC_Controller_Arguments_testcase extends Tx_Extbase_BaseTestCa /** * @test - * @author Robert Lemke */ public function addingAnArgumentReplacesArgumentWithSameName() { - $arguments = $this->objectManager->getObject('Tx_Extbase_MVC_Controller_Arguments'); + $arguments = new Tx_Extbase_MVC_Controller_Arguments; - $firstArgument = $this->objectManager->getObject('Tx_Extbase_MVC_Controller_Argument', 'argumentName1234'); - $arguments->addArgument($firstArgument); + $mockFirstArgument = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array('getName'), array(), '', FALSE); + $mockFirstArgument->expects($this->any())->method('getName')->will($this->returnValue('argumentName1234')); + $arguments->addArgument($mockFirstArgument); - $secondArgument = $this->objectManager->getObject('Tx_Extbase_MVC_Controller_Argument', 'argumentName1234'); - $arguments->addArgument($secondArgument); + $mockSecondArgument = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array('getName'), array(), '', FALSE); + $mockSecondArgument->expects($this->any())->method('getName')->will($this->returnValue('argumentName1234')); + $arguments->addArgument($mockSecondArgument); - $this->assertSame($secondArgument, $arguments->getArgument('argumentName1234'), 'The added and retrieved argument is not the same.'); + $this->assertSame($mockSecondArgument, $arguments->getArgument('argumentName1234'), 'The added and retrieved argument is not the same.'); } /** * @test - * @author Robert Lemke */ public function addNewArgumentProvidesFluentInterface() { - $arguments = $this->objectManager->getObject('Tx_Extbase_MVC_Controller_Arguments'); - $arguments->injectPersistenceManager($this->getMock('Tx_Extbase_Persistence_Manager', array(), array(), '', FALSE)); - $arguments->injectQueryFactory($this->getMock('Tx_Extbase_Persistence_QueryFactory')); - - $newArgument = $arguments->addNewArgument('someArgument'); + $mockArgument = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array(), array(), '', FALSE); + $mockArguments = $this->getMock('Tx_Extbase_MVC_Controller_Arguments', array('createArgument')); + $mockArguments->expects($this->any())->method('createArgument')->will($this->returnValue($mockArgument)); + + $newArgument = $mockArguments->addNewArgument('someArgument'); $this->assertType('Tx_Extbase_MVC_Controller_Argument', $newArgument, 'addNewArgument() did not return an argument object.'); } /** * @test - * @author Robert Lemke */ public function addingArgumentThroughArrayAccessWorks() { - $arguments = $this->objectManager->getObject('Tx_Extbase_MVC_Controller_Arguments'); - $argument = $this->objectManager->getObject('Tx_Extbase_MVC_Controller_Argument', 'argumentName1234'); - $arguments[] = $argument; + $mockArgument = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array('getName'), array(), '', FALSE); + $mockArgument->expects($this->any())->method('getName')->will($this->returnValue('argumentName1234')); + $arguments = new Tx_Extbase_MVC_Controller_Arguments; + + $arguments[] = $mockArgument; $this->assertTrue($arguments->hasArgument('argumentName1234'), 'Added argument does not exist.'); - $this->assertSame($argument, $arguments->getArgument('argumentName1234'), 'Added and retrieved arguments are not the same.'); + $this->assertSame($mockArgument, $arguments->getArgument('argumentName1234'), 'Added and retrieved arguments are not the same.'); } /** * @test - * @author Robert Lemke */ public function retrievingArgumentThroughArrayAccessWorks() { - $arguments = $this->objectManager->getObject('Tx_Extbase_MVC_Controller_Arguments'); - $arguments->injectPersistenceManager($this->getMock('Tx_Extbase_Persistence_Manager', array(), array(), '', FALSE)); - $arguments->injectQueryFactory($this->getMock('Tx_Extbase_Persistence_QueryFactory')); + $mockArgument = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array('getName'), array(), '', FALSE); + $mockArgument->expects($this->any())->method('getName')->will($this->returnValue('argumentName1234')); + $arguments = new Tx_Extbase_MVC_Controller_Arguments; - $newArgument = $arguments->addNewArgument('someArgument'); - $this->assertSame($newArgument, $arguments['someArgument'], 'Argument retrieved by array access is not the one we added.'); + $arguments[] = $mockArgument; + $this->assertSame($mockArgument, $arguments['argumentName1234'], 'Argument retrieved by array access is not the one we added.'); } /** * @test - * @author Robert Lemke */ public function getArgumentWithNonExistingArgumentNameThrowsException() { $arguments = $this->objectManager->getObject('Tx_Extbase_MVC_Controller_Arguments'); @@ -118,45 +115,53 @@ class Tx_Extbase_MVC_Controller_Arguments_testcase extends Tx_Extbase_BaseTestCa /** * @test - * @author Robert Lemke */ public function issetReturnsCorrectResult() { - $arguments = $this->objectManager->getObject('Tx_Extbase_MVC_Controller_Arguments'); - $arguments->injectPersistenceManager($this->getMock('Tx_Extbase_Persistence_Manager', array(), array(), '', FALSE)); - $arguments->injectQueryFactory($this->getMock('Tx_Extbase_Persistence_QueryFactory')); + $mockArgument = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array('getName'), array(), '', FALSE); + $mockArgument->expects($this->any())->method('getName')->will($this->returnValue('argumentName1234')); + $arguments = new Tx_Extbase_MVC_Controller_Arguments; - $this->assertFalse(isset($arguments['someArgument']), 'isset() did not return FALSE.'); - $arguments->addNewArgument('someArgument'); - $this->assertTrue(isset($arguments['someArgument']), 'isset() did not return TRUE.'); + $this->assertFalse(isset($arguments['argumentName1234']), 'isset() did not return FALSE.'); + $arguments[] = $mockArgument; + $this->assertTrue(isset($arguments['argumentName1234']), 'isset() did not return TRUE.'); } /** * @test - * @author Robert Lemke */ public function getArgumentNamesReturnsNamesOfAddedArguments() { - $arguments = $this->objectManager->getObject('Tx_Extbase_MVC_Controller_Arguments'); - $arguments->injectPersistenceManager($this->getMock('Tx_Extbase_Persistence_Manager', array(), array(), '', FALSE)); - $arguments->injectQueryFactory($this->getMock('Tx_Extbase_Persistence_QueryFactory')); - $arguments->addNewArgument('first'); - $arguments->addNewArgument('second'); - $arguments->addNewArgument('third'); - - $expectedArgumentNames = array('first', 'second', 'third'); + $mockArgument1 = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array('getName'), array(), '', FALSE); + $mockArgument1->expects($this->any())->method('getName')->will($this->returnValue('argumentName1')); + $mockArgument2 = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array('getName'), array(), '', FALSE); + $mockArgument2->expects($this->any())->method('getName')->will($this->returnValue('argumentName2')); + $mockArgument3 = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array('getName'), array(), '', FALSE); + $mockArgument3->expects($this->any())->method('getName')->will($this->returnValue('argumentName3')); + $arguments = new Tx_Extbase_MVC_Controller_Arguments; + $arguments[] = $mockArgument1; + $arguments[] = $mockArgument2; + $arguments[] = $mockArgument3; + + $expectedArgumentNames = array('argumentName1', 'argumentName2', 'argumentName3'); $this->assertEquals($expectedArgumentNames, $arguments->getArgumentNames(), 'Returned argument names were not as expected.'); } /** * @test - * @author Robert Lemke */ public function getArgumentShortNamesReturnsShortNamesOfAddedArguments() { - $arguments = $this->objectManager->getObject('Tx_Extbase_MVC_Controller_Arguments'); - $arguments->injectPersistenceManager($this->getMock('Tx_Extbase_Persistence_Manager', array(), array(), '', FALSE)); - $arguments->injectQueryFactory($this->getMock('Tx_Extbase_Persistence_QueryFactory')); - $arguments->addNewArgument('first')->setShortName('a'); - $arguments->addNewArgument('second')->setShortName('b'); - $arguments->addNewArgument('third')->setShortName('c'); + $mockArgument1 = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array('getName', 'getShortName'), array(), '', FALSE); + $mockArgument1->expects($this->any())->method('getName')->will($this->returnValue('argumentName1')); + $mockArgument1->expects($this->any())->method('getShortName')->will($this->returnValue('a')); + $mockArgument2 = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array('getName', 'getShortName'), array(), '', FALSE); + $mockArgument2->expects($this->any())->method('getName')->will($this->returnValue('argumentName2')); + $mockArgument2->expects($this->any())->method('getShortName')->will($this->returnValue('b')); + $mockArgument3 = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array('getName', 'getShortName'), array(), '', FALSE); + $mockArgument3->expects($this->any())->method('getName')->will($this->returnValue('argumentName3')); + $mockArgument3->expects($this->any())->method('getShortName')->will($this->returnValue('c')); + $arguments = new Tx_Extbase_MVC_Controller_Arguments; + $arguments[] = $mockArgument1; + $arguments[] = $mockArgument2; + $arguments[] = $mockArgument3; $expectedShortNames = array('a', 'b', 'c'); $this->assertEquals($expectedShortNames, $arguments->getArgumentShortNames(), 'Returned argument short names were not as expected.'); @@ -164,60 +169,56 @@ class Tx_Extbase_MVC_Controller_Arguments_testcase extends Tx_Extbase_BaseTestCa /** * @test - * @author Robert Lemke */ public function addNewArgumentCreatesAndAddsNewArgument() { - $arguments = $this->objectManager->getObject('Tx_Extbase_MVC_Controller_Arguments'); - $arguments->injectPersistenceManager($this->getMock('Tx_Extbase_Persistence_Manager', array(), array(), '', FALSE)); - $arguments->injectQueryFactory($this->getMock('Tx_Extbase_Persistence_QueryFactory')); + $mockArgument = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array('getName'), array(), '', FALSE); + $mockArgument->expects($this->any())->method('getName')->will($this->returnValue('dummyName')); + $mockArguments = $this->getMock('Tx_Extbase_MVC_Controller_Arguments', array('createArgument')); + $mockArguments->expects($this->any())->method('createArgument')->with($this->equalTo('dummyName'))->will($this->returnValue($mockArgument)); - $addedArgument = $arguments->addNewArgument('dummyName'); + $addedArgument = $mockArguments->addNewArgument('dummyName'); $this->assertType('Tx_Extbase_MVC_Controller_Argument', $addedArgument, 'addNewArgument() either did not add a new argument or did not return it.'); - $retrievedArgument = $arguments['dummyName']; + $retrievedArgument = $mockArguments['dummyName']; $this->assertSame($addedArgument, $retrievedArgument, 'The added and the retrieved argument are not the same.'); - - $this->assertEquals('dummyName', $addedArgument->getName(), 'The name of the added argument is not as expected.'); } /** * @test - * @author Robert Lemke */ public function addNewArgumentAssumesTextDataTypeByDefault() { - $arguments = $this->objectManager->getObject('Tx_Extbase_MVC_Controller_Arguments'); - $arguments->injectPersistenceManager($this->getMock('Tx_Extbase_Persistence_Manager', array(), array(), '', FALSE)); - $arguments->injectQueryFactory($this->getMock('Tx_Extbase_Persistence_QueryFactory')); + $mockArgument = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array('getName'), array(), '', FALSE); + $mockArgument->expects($this->any())->method('getName')->will($this->returnValue('dummyName')); + $mockArguments = $this->getMock('Tx_Extbase_MVC_Controller_Arguments', array('createArgument')); + $mockArguments->expects($this->any())->method('createArgument')->with($this->equalTo('dummyName'), $this->equalTo('Text'))->will($this->returnValue($mockArgument)); - $addedArgument = $arguments->addNewArgument('dummyName'); - $this->assertEquals('Text', $addedArgument->getDataType(), 'addNewArgument() did not create an argument of type "Text" by default.'); + $addedArgument = $mockArguments->addNewArgument('dummyName'); } /** * @test - * @author Andreas Förthner */ public function addNewArgumentCanAddArgumentsMarkedAsRequired() { - $arguments = $this->objectManager->getObject('Tx_Extbase_MVC_Controller_Arguments'); - $arguments->injectPersistenceManager($this->getMock('Tx_Extbase_Persistence_Manager', array(), array(), '', FALSE)); - $arguments->injectQueryFactory($this->getMock('Tx_Extbase_Persistence_QueryFactory')); + $mockArgument = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array('getName', 'setRequired'), array(), '', FALSE); + $mockArgument->expects($this->any())->method('getName')->will($this->returnValue('dummyName')); + $mockArgument->expects($this->any())->method('setRequired')->with(TRUE); + $mockArguments = $this->getMock('Tx_Extbase_MVC_Controller_Arguments', array('createArgument')); + $mockArguments->expects($this->any())->method('createArgument')->with($this->equalTo('dummyName'), $this->equalTo('Text'))->will($this->returnValue($mockArgument)); - $addedArgument = $arguments->addNewArgument('dummyName', 'Text', TRUE); - $this->assertTrue($addedArgument->isRequired(), 'addNewArgument() did not create an argument that is marked as required.'); + $addedArgument = $mockArguments->addNewArgument('dummyName', 'Text', TRUE); } /** * @test - * @author Sebastian Kurfürst */ public function addNewArgumentCanAddArgumentsMarkedAsOptionalWithDefaultValues() { - $arguments = $this->objectManager->getObject('Tx_Extbase_MVC_Controller_Arguments'); - $arguments->injectPersistenceManager($this->getMock('Tx_Extbase_Persistence_Manager', array(), array(), '', FALSE)); - $arguments->injectQueryFactory($this->getMock('Tx_Extbase_Persistence_QueryFactory')); + $mockArgument = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array('getName', 'setRequired'), array(), '', FALSE); + $mockArgument->expects($this->any())->method('getName')->will($this->returnValue('dummyName')); + $mockArgument->expects($this->any())->method('setRequired')->with(TRUE); + $mockArguments = $this->getMock('Tx_Extbase_MVC_Controller_Arguments', array('createArgument')); + $mockArguments->expects($this->any())->method('createArgument')->with($this->equalTo('dummyName'), $this->equalTo('Text'))->will($this->returnValue($mockArgument)); - $defaultValue = 'Default Value 42'; - $addedArgument = $arguments->addNewArgument('dummyName', 'Text', FALSE, $defaultValue); - $this->assertEquals($defaultValue, $addedArgument->getValue(), 'addNewArgument() did not store the default value in the argument.'); + $addedArgument = $mockArguments->addNewArgument('dummyName', 'Text', TRUE); } /** @@ -227,8 +228,6 @@ class Tx_Extbase_MVC_Controller_Arguments_testcase extends Tx_Extbase_BaseTestCa */ public function callingInvalidMethodThrowsException() { $arguments = $this->objectManager->getObject('Tx_Extbase_MVC_Controller_Arguments'); - $arguments->injectPersistenceManager($this->getMock('Tx_Extbase_Persistence_Manager', array(), array(), '', FALSE)); - $arguments->injectQueryFactory($this->getMock('Tx_Extbase_Persistence_QueryFactory')); $arguments->nonExistingMethod(); } @@ -237,18 +236,17 @@ class Tx_Extbase_MVC_Controller_Arguments_testcase extends Tx_Extbase_BaseTestCa * @author Christopher Hlubek */ public function removeAllClearsAllArguments() { - $arguments = $this->objectManager->getObject('Tx_Extbase_MVC_Controller_Arguments'); - $arguments->injectPersistenceManager($this->getMock('Tx_Extbase_Persistence_Manager', array(), array(), '', FALSE)); - $arguments->injectQueryFactory($this->getMock('Tx_Extbase_Persistence_QueryFactory')); - $arguments->addNewArgument('foo'); - + $mockArgument1 = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array('getName', 'getShortName'), array(), '', FALSE); + $mockArgument1->expects($this->any())->method('getName')->will($this->returnValue('argumentName1')); + $mockArgument2 = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array('getName', 'getShortName'), array(), '', FALSE); + $mockArgument2->expects($this->any())->method('getName')->will($this->returnValue('argumentName2')); + $arguments = new Tx_Extbase_MVC_Controller_Arguments; + $arguments[] = $mockArgument1; + $arguments[] = $mockArgument2; + + $this->assertTrue($arguments->hasArgument('argumentName2')); $arguments->removeAll(); - - $this->assertFalse($arguments->hasArgument('foo')); - - $arguments->addNewArgument('bar'); - - $this->assertTrue($arguments->hasArgument('bar')); + $this->assertFalse($arguments->hasArgument('argumentName2')); } } ?> \ No newline at end of file diff --git a/typo3/sysext/extbase/Tests/Persistence/Storage/Typo3DbBackend_testcase.php b/typo3/sysext/extbase/Tests/Persistence/Storage/Typo3DbBackend_testcase.php index 98f67c6d73fe..d59a54e5ed9b 100644 --- a/typo3/sysext/extbase/Tests/Persistence/Storage/Typo3DbBackend_testcase.php +++ b/typo3/sysext/extbase/Tests/Persistence/Storage/Typo3DbBackend_testcase.php @@ -161,25 +161,27 @@ class Tx_Extbase_Persistence_Storage_Typo3DbBackend_testcase extends Tx_Extbase_ public function orderStatementGenerationWorks() { $mockPropertyValue = $this->getMock('Tx_Extbase_Persistence_QOM_PropertyValue', array('getPropertyName', 'getSelectorname'), array(), '', FALSE); $mockPropertyValue->expects($this->once())->method('getPropertyName')->will($this->returnValue('fooProperty')); - $mockPropertyValue->expects($this->once())->method('getSelectorName')->will($this->returnValue('tx_myext_bar')); + $mockPropertyValue->expects($this->once())->method('getSelectorName')->will($this->returnValue('tx_myext_tablenamefromproperty')); $mockOrdering1 = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_Persistence_QOM_Ordering'), array('getOrder', 'getOperand'), array(), '', FALSE); $mockOrdering1->expects($this->once())->method('getOrder')->will($this->returnValue(Tx_Extbase_Persistence_QOM_QueryObjectModelConstantsInterface::JCR_ORDER_ASCENDING)); $mockOrdering1->expects($this->once())->method('getOperand')->will($this->returnValue($mockPropertyValue)); $orderings = array($mockOrdering1); - $mockSource = $this->getMock('Tx_Extbase_Persistence_QOM_Selector', array(), array(), '', FALSE); + $mockSource = $this->getMock('Tx_Extbase_Persistence_QOM_Selector', array('getSelectorName', 'getNodeTypeName'), array(), '', FALSE); + $mockSource->expects($this->any())->method('getSelectorName')->will($this->returnValue('tx_myext_tablename')); + $mockSource->expects($this->any())->method('getNodeTypeName')->will($this->returnValue('Tx_MyExt_ClassName')); $mockDataMapper = $this->getMock('Tx_Extbase_Persistence_Mapper_DataMapper', array('convertPropertyNameToColumnName'), array(), '', FALSE); - $mockDataMapper->expects($this->once())->method('convertPropertyNameToColumnName')->with('fooProperty', 'tx_myext_bar')->will($this->returnValue('bar_field')); + $mockDataMapper->expects($this->once())->method('convertPropertyNameToColumnName')->with('fooProperty', 'Tx_MyExt_ClassName')->will($this->returnValue('converted_fieldname')); $sql = array(); $mockTypo3DbBackend = $this->getMock($this->buildAccessibleProxy('Tx_Extbase_Persistence_Storage_Typo3DbBackend'), array('parserOrderings'), array(), '', FALSE); $mockTypo3DbBackend->_set('dataMapper', $mockDataMapper); $mockTypo3DbBackend->_callRef('parseOrderings', $orderings, $mockSource, $sql); - - $expecedSql = array('orderings' => array('tx_myext_bar.bar_field ASC')); - $this->assertEquals($expecedSql, $sql); + + $expecedSql = array('orderings' => array('tx_myext_tablenamefromproperty.converted_fieldname ASC')); + $this->assertSame($expecedSql, $sql); } /** @@ -196,8 +198,9 @@ class Tx_Extbase_Persistence_Storage_Typo3DbBackend_testcase extends Tx_Extbase_ $mockOrdering1->expects($this->once())->method('getOperand')->will($this->returnValue($mockPropertyValue)); $orderings = array($mockOrdering1); - $mockSource = $this->getMock('Tx_Extbase_Persistence_QOM_Selector', array(), array(), '', FALSE); - + $mockSource = $this->getMock('Tx_Extbase_Persistence_QOM_Selector', array('getSelectorName', 'getNodeTypeName'), array(), '', FALSE); + $mockSource->expects($this->any())->method('getSelectorName')->will($this->returnValue('tx_myext_tablename')); + $mockDataMapper = $this->getMock('Tx_Extbase_Persistence_Mapper_DataMapper', array('convertPropertyNameToColumnName'), array(), '', FALSE); $mockDataMapper->expects($this->never())->method('convertPropertyNameToColumnName'); diff --git a/typo3/sysext/extbase/Tests/Validation/ValidatorResolver_testcase.php b/typo3/sysext/extbase/Tests/Validation/ValidatorResolver_testcase.php index 18726a0e8234..70db280ace00 100644 --- a/typo3/sysext/extbase/Tests/Validation/ValidatorResolver_testcase.php +++ b/typo3/sysext/extbase/Tests/Validation/ValidatorResolver_testcase.php @@ -180,10 +180,8 @@ class Tx_Extbase_Validation_ValidatorResolver_testcase extends Tx_Extbase_BaseTe $mockObjectFactory = $this->getMock('Tx_Extbase_Object_FactoryInterface'); $mockArguments = new Tx_Extbase_MVC_Controller_Arguments(); - $mockArguments->addArgument(new Tx_Extbase_MVC_Controller_Argument('arg1')); - $mockArguments->addArgument(new Tx_Extbase_MVC_Controller_Argument('arg2')); - - $mockArguments['arg2'] = $this->getMock('Tx_Extbase_MVC_Controller_Argument', array(), array(), '', FALSE); + $mockArguments->addArgument(new Tx_Extbase_MVC_Controller_Argument('arg1', 'dummyValue')); + $mockArguments->addArgument(new Tx_Extbase_MVC_Controller_Argument('arg2', 'dummyValue')); $validatorResolver = $this->getMock('Tx_Extbase_Validation_ValidatorResolver', array('createValidator')); $validatorResolver->expects($this->at(0))->method('createValidator')->with('Conjunction')->will($this->returnValue($conjunction1)); -- 2.20.1