[TASK] Backport Flow property mapper
authorThomas Maroschik <tmaroschik@dfau.de>
Sat, 13 Apr 2013 11:21:18 +0000 (13:21 +0200)
committerChristian Kuhn <lolli@schwarzbu.ch>
Sat, 13 Apr 2013 14:48:47 +0000 (16:48 +0200)
In order to be in sync with Flow again the property mapper has been
backported again.

Resolves: #47182
Releases: 6.1
Change-Id: I28712c643da54d203549f503a7721a14b0c8eb29
Reviewed-on: https://review.typo3.org/19906
Reviewed-by: Christian Kuhn
Tested-by: Christian Kuhn
Reviewed-by: Andreas Wolf
Reviewed-by: Anja Leichsenring
Tested-by: Anja Leichsenring
Reviewed-by: Wouter Wolters
Tested-by: Wouter Wolters
31 files changed:
typo3/sysext/extbase/Classes/Property/PropertyMapper.php
typo3/sysext/extbase/Classes/Property/PropertyMappingConfiguration.php
typo3/sysext/extbase/Classes/Property/PropertyMappingConfigurationBuilder.php
typo3/sysext/extbase/Classes/Property/PropertyMappingConfigurationInterface.php
typo3/sysext/extbase/Classes/Property/TypeConverter/AbstractTypeConverter.php
typo3/sysext/extbase/Classes/Property/TypeConverter/ArrayConverter.php
typo3/sysext/extbase/Classes/Property/TypeConverter/BooleanConverter.php
typo3/sysext/extbase/Classes/Property/TypeConverter/DateTimeConverter.php
typo3/sysext/extbase/Classes/Property/TypeConverter/FloatConverter.php
typo3/sysext/extbase/Classes/Property/TypeConverter/IntegerConverter.php
typo3/sysext/extbase/Classes/Property/TypeConverter/ObjectStorageConverter.php
typo3/sysext/extbase/Classes/Property/TypeConverter/PersistentObjectConverter.php
typo3/sysext/extbase/Classes/Property/TypeConverter/StringConverter.php
typo3/sysext/extbase/Classes/Property/TypeConverterInterface.php
typo3/sysext/extbase/Classes/Service/TypeHandlingService.php
typo3/sysext/extbase/Classes/Utility/Exception/InvalidTypeException.php [new file with mode: 0644]
typo3/sysext/extbase/Classes/Utility/TypeHandlingUtility.php [new file with mode: 0644]
typo3/sysext/extbase/Tests/Fixture/ClassWithSetters.php
typo3/sysext/extbase/Tests/Fixture/ClassWithSettersAndConstructor.php
typo3/sysext/extbase/Tests/Unit/BaseTestCase.php
typo3/sysext/extbase/Tests/Unit/Property/PropertyMapperTest.php
typo3/sysext/extbase/Tests/Unit/Property/PropertyMappingConfigurationBuilderTest.php
typo3/sysext/extbase/Tests/Unit/Property/PropertyMappingConfigurationTest.php
typo3/sysext/extbase/Tests/Unit/Property/TypeConverter/ArrayConverterTest.php
typo3/sysext/extbase/Tests/Unit/Property/TypeConverter/BooleanConverterTest.php
typo3/sysext/extbase/Tests/Unit/Property/TypeConverter/DateTimeConverterTest.php
typo3/sysext/extbase/Tests/Unit/Property/TypeConverter/FloatConverterTest.php
typo3/sysext/extbase/Tests/Unit/Property/TypeConverter/IntegerConverterTest.php
typo3/sysext/extbase/Tests/Unit/Property/TypeConverter/PersistentObjectConverterTest.php
typo3/sysext/extbase/Tests/Unit/Property/TypeConverter/StringConverterTest.php
typo3/sysext/extbase/Tests/Unit/Service/TypeHandlingServiceTest.php

index 9c17525..22745b2 100644 (file)
@@ -40,11 +40,6 @@ class PropertyMapper implements \TYPO3\CMS\Core\SingletonInterface {
        protected $configurationBuilder;
 
        /**
        protected $configurationBuilder;
 
        /**
-        * @var \TYPO3\CMS\Extbase\Service\TypeHandlingService
-        */
-       protected $typeHandlingService;
-
-       /**
         * A multi-dimensional array which stores the Type Converters available in the system.
         * It has the following structure:
         * 1. Dimension: Source Type
         * A multi-dimensional array which stores the Type Converters available in the system.
         * It has the following structure:
         * 1. Dimension: Source Type
@@ -80,14 +75,6 @@ class PropertyMapper implements \TYPO3\CMS\Core\SingletonInterface {
        }
 
        /**
        }
 
        /**
-        * @param \TYPO3\CMS\Extbase\Service\TypeHandlingService $typeHandlingService
-        * @return void
-        */
-       public function injectTypeHandlingService(\TYPO3\CMS\Extbase\Service\TypeHandlingService $typeHandlingService) {
-               $this->typeHandlingService = $typeHandlingService;
-       }
-
-       /**
         * Lifecycle method, called after all dependencies have been injected.
         * Here, the typeConverter array gets initialized.
         *
         * Lifecycle method, called after all dependencies have been injected.
         * Here, the typeConverter array gets initialized.
         *
@@ -123,7 +110,12 @@ class PropertyMapper implements \TYPO3\CMS\Core\SingletonInterface {
                $currentPropertyPath = array();
                $this->messages = new \TYPO3\CMS\Extbase\Error\Result();
                try {
                $currentPropertyPath = array();
                $this->messages = new \TYPO3\CMS\Extbase\Error\Result();
                try {
-                       return $this->doMapping($source, $targetType, $configuration, $currentPropertyPath);
+                       $result = $this->doMapping($source, $targetType, $configuration, $currentPropertyPath);
+                       if ($result instanceof \TYPO3\CMS\Extbase\Error\Error) {
+                               return NULL;
+                       }
+
+                       return $result;
                } catch (\Exception $e) {
                        throw new \TYPO3\CMS\Extbase\Property\Exception('Exception while property mapping at property path "' . implode('.', $currentPropertyPath) . '":' . $e->getMessage(), 1297759968, $e);
                }
                } catch (\Exception $e) {
                        throw new \TYPO3\CMS\Extbase\Property\Exception('Exception while property mapping at property path "' . implode('.', $currentPropertyPath) . '":' . $e->getMessage(), 1297759968, $e);
                }
@@ -150,42 +142,58 @@ class PropertyMapper implements \TYPO3\CMS\Core\SingletonInterface {
         * @return mixed an instance of $targetType
         */
        protected function doMapping($source, $targetType, \TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface $configuration, &$currentPropertyPath) {
         * @return mixed an instance of $targetType
         */
        protected function doMapping($source, $targetType, \TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface $configuration, &$currentPropertyPath) {
-               if ($source === NULL) {
-                       $source = '';
-               }
-               // This is needed to correctly convert old class names to new ones
-               // This compatibility layer will be removed with 7.0
-               $targetType = \TYPO3\CMS\Core\Core\ClassLoader::getClassNameForAlias($targetType);
                if (is_object($source)) {
                if (is_object($source)) {
+                       // This is needed to correctly convert old class names to new ones
+                       // This compatibility layer will be removed with 7.0
+                       $targetType = \TYPO3\CMS\Core\Core\ClassLoader::getClassNameForAlias($targetType);
                        $targetType = $this->parseCompositeType($targetType);
                        if ($source instanceof $targetType) {
                                return $source;
                        }
                }
                        $targetType = $this->parseCompositeType($targetType);
                        if ($source instanceof $targetType) {
                                return $source;
                        }
                }
+
+               if ($source === NULL) {
+                       $source = '';
+               }
+
                $typeConverter = $this->findTypeConverter($source, $targetType, $configuration);
                $typeConverter = $this->findTypeConverter($source, $targetType, $configuration);
+               $targetType = $typeConverter->getTargetTypeForSource($source, $targetType, $configuration);
+
                if (!is_object($typeConverter) || !$typeConverter instanceof \TYPO3\CMS\Extbase\Property\TypeConverterInterface) {
                        throw new \TYPO3\CMS\Extbase\Property\Exception\TypeConverterException('Type converter for "' . $source . '" -> "' . $targetType . '" not found.');
                }
                if (!is_object($typeConverter) || !$typeConverter instanceof \TYPO3\CMS\Extbase\Property\TypeConverterInterface) {
                        throw new \TYPO3\CMS\Extbase\Property\Exception\TypeConverterException('Type converter for "' . $source . '" -> "' . $targetType . '" not found.');
                }
+
                $convertedChildProperties = array();
                foreach ($typeConverter->getSourceChildPropertiesToBeConverted($source) as $sourcePropertyName => $sourcePropertyValue) {
                        $targetPropertyName = $configuration->getTargetPropertyName($sourcePropertyName);
                $convertedChildProperties = array();
                foreach ($typeConverter->getSourceChildPropertiesToBeConverted($source) as $sourcePropertyName => $sourcePropertyValue) {
                        $targetPropertyName = $configuration->getTargetPropertyName($sourcePropertyName);
+                       if ($configuration->shouldSkip($targetPropertyName)) {
+                               continue;
+                       }
+
                        if (!$configuration->shouldMap($targetPropertyName)) {
                        if (!$configuration->shouldMap($targetPropertyName)) {
+                               if ($configuration->shouldSkipUnknownProperties()) {
+                                       continue;
+                               }
                                throw new \TYPO3\CMS\Extbase\Property\Exception\InvalidPropertyMappingConfigurationException('It is not allowed to map property "' . $targetPropertyName . '". You need to use $propertyMappingConfiguration->allowProperties(\'' . $targetPropertyName . '\') to enable mapping of this property.', 1355155913);
                        }
                                throw new \TYPO3\CMS\Extbase\Property\Exception\InvalidPropertyMappingConfigurationException('It is not allowed to map property "' . $targetPropertyName . '". You need to use $propertyMappingConfiguration->allowProperties(\'' . $targetPropertyName . '\') to enable mapping of this property.', 1355155913);
                        }
+
                        $targetPropertyType = $typeConverter->getTypeOfChildProperty($targetType, $targetPropertyName, $configuration);
                        $targetPropertyType = $typeConverter->getTypeOfChildProperty($targetType, $targetPropertyName, $configuration);
+
                        $subConfiguration = $configuration->getConfigurationFor($targetPropertyName);
                        $subConfiguration = $configuration->getConfigurationFor($targetPropertyName);
+
                        $currentPropertyPath[] = $targetPropertyName;
                        $targetPropertyValue = $this->doMapping($sourcePropertyValue, $targetPropertyType, $subConfiguration, $currentPropertyPath);
                        array_pop($currentPropertyPath);
                        $currentPropertyPath[] = $targetPropertyName;
                        $targetPropertyValue = $this->doMapping($sourcePropertyValue, $targetPropertyType, $subConfiguration, $currentPropertyPath);
                        array_pop($currentPropertyPath);
-                       if ($targetPropertyValue !== NULL) {
+                       if (!($targetPropertyValue instanceof \TYPO3\CMS\Extbase\Error\Error)) {
                                $convertedChildProperties[$targetPropertyName] = $targetPropertyValue;
                        }
                }
                $result = $typeConverter->convertFrom($source, $targetType, $convertedChildProperties, $configuration);
                                $convertedChildProperties[$targetPropertyName] = $targetPropertyValue;
                        }
                }
                $result = $typeConverter->convertFrom($source, $targetType, $convertedChildProperties, $configuration);
+
                if ($result instanceof \TYPO3\CMS\Extbase\Error\Error) {
                        $this->messages->forProperty(implode('.', $currentPropertyPath))->addError($result);
                if ($result instanceof \TYPO3\CMS\Extbase\Error\Error) {
                        $this->messages->forProperty(implode('.', $currentPropertyPath))->addError($result);
-                       $result = NULL;
                }
                }
+
                return $result;
        }
 
                return $result;
        }
 
@@ -203,22 +211,28 @@ class PropertyMapper implements \TYPO3\CMS\Core\SingletonInterface {
                if ($configuration->getTypeConverter() !== NULL) {
                        return $configuration->getTypeConverter();
                }
                if ($configuration->getTypeConverter() !== NULL) {
                        return $configuration->getTypeConverter();
                }
+
                $sourceType = $this->determineSourceType($source);
                $sourceType = $this->determineSourceType($source);
+
                if (!is_string($targetType)) {
                        throw new \TYPO3\CMS\Extbase\Property\Exception\InvalidTargetException('The target type was no string, but of type "' . gettype($targetType) . '"', 1297941727);
                }
                if (!is_string($targetType)) {
                        throw new \TYPO3\CMS\Extbase\Property\Exception\InvalidTargetException('The target type was no string, but of type "' . gettype($targetType) . '"', 1297941727);
                }
+
                $targetType = $this->parseCompositeType($targetType);
                $converter = NULL;
                $targetType = $this->parseCompositeType($targetType);
                $converter = NULL;
-               if ($this->typeHandlingService->isSimpleType($targetType)) {
+
+               if (\TYPO3\CMS\Extbase\Utility\TypeHandlingUtility::isSimpleType($targetType)) {
                        if (isset($this->typeConverters[$sourceType][$targetType])) {
                                $converter = $this->findEligibleConverterWithHighestPriority($this->typeConverters[$sourceType][$targetType], $source, $targetType);
                        }
                } else {
                        $converter = $this->findFirstEligibleTypeConverterInObjectHierarchy($source, $sourceType, $targetType);
                }
                        if (isset($this->typeConverters[$sourceType][$targetType])) {
                                $converter = $this->findEligibleConverterWithHighestPriority($this->typeConverters[$sourceType][$targetType], $source, $targetType);
                        }
                } else {
                        $converter = $this->findFirstEligibleTypeConverterInObjectHierarchy($source, $sourceType, $targetType);
                }
+
                if ($converter === NULL) {
                        throw new \TYPO3\CMS\Extbase\Property\Exception\TypeConverterException('No converter found which can be used to convert from "' . $sourceType . '" to "' . $targetType . '".');
                }
                if ($converter === NULL) {
                        throw new \TYPO3\CMS\Extbase\Property\Exception\TypeConverterException('No converter found which can be used to convert from "' . $sourceType . '" to "' . $targetType . '".');
                }
+
                return $converter;
        }
 
                return $converter;
        }
 
@@ -235,9 +249,11 @@ class PropertyMapper implements \TYPO3\CMS\Core\SingletonInterface {
                if (!class_exists($targetClass) && !interface_exists($targetClass)) {
                        throw new \TYPO3\CMS\Extbase\Property\Exception\InvalidTargetException('Could not find a suitable type converter for "' . $targetClass . '" because no such class or interface exists.', 1297948764);
                }
                if (!class_exists($targetClass) && !interface_exists($targetClass)) {
                        throw new \TYPO3\CMS\Extbase\Property\Exception\InvalidTargetException('Could not find a suitable type converter for "' . $targetClass . '" because no such class or interface exists.', 1297948764);
                }
+
                if (!isset($this->typeConverters[$sourceType])) {
                        return NULL;
                }
                if (!isset($this->typeConverters[$sourceType])) {
                        return NULL;
                }
+
                $convertersForSource = $this->typeConverters[$sourceType];
                if (isset($convertersForSource[$targetClass])) {
                        $converter = $this->findEligibleConverterWithHighestPriority($convertersForSource[$targetClass], $source, $targetClass);
                $convertersForSource = $this->typeConverters[$sourceType];
                if (isset($convertersForSource[$targetClass])) {
                        $converter = $this->findEligibleConverterWithHighestPriority($convertersForSource[$targetClass], $source, $targetClass);
@@ -245,17 +261,21 @@ class PropertyMapper implements \TYPO3\CMS\Core\SingletonInterface {
                                return $converter;
                        }
                }
                                return $converter;
                        }
                }
+
                foreach (class_parents($targetClass) as $parentClass) {
                        if (!isset($convertersForSource[$parentClass])) {
                                continue;
                        }
                foreach (class_parents($targetClass) as $parentClass) {
                        if (!isset($convertersForSource[$parentClass])) {
                                continue;
                        }
+
                        $converter = $this->findEligibleConverterWithHighestPriority($convertersForSource[$parentClass], $source, $targetClass);
                        if ($converter !== NULL) {
                                return $converter;
                        }
                }
                        $converter = $this->findEligibleConverterWithHighestPriority($convertersForSource[$parentClass], $source, $targetClass);
                        if ($converter !== NULL) {
                                return $converter;
                        }
                }
+
                $converters = $this->getConvertersForInterfaces($convertersForSource, class_implements($targetClass));
                $converter = $this->findEligibleConverterWithHighestPriority($converters, $source, $targetClass);
                $converters = $this->getConvertersForInterfaces($convertersForSource, class_implements($targetClass));
                $converter = $this->findEligibleConverterWithHighestPriority($converters, $source, $targetClass);
+
                if ($converter !== NULL) {
                        return $converter;
                }
                if ($converter !== NULL) {
                        return $converter;
                }
index 0ad17e6..32965e0 100644 (file)
@@ -21,13 +21,13 @@ namespace TYPO3\CMS\Extbase\Property;
  * The TYPO3 project - inspiring people to share!                         *
  *                                                                        */
 
  * The TYPO3 project - inspiring people to share!                         *
  *                                                                        */
 
+use TYPO3\CMS\Core\Core\ClassLoader;
+
 /**
  * Concrete configuration object for the PropertyMapper.
  *
  * @api
  */
 /**
  * Concrete configuration object for the PropertyMapper.
  *
  * @api
  */
-use TYPO3\CMS\Core\Core\ClassLoader;
-
 class PropertyMappingConfiguration implements \TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface {
 
        /**
 class PropertyMappingConfiguration implements \TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface {
 
        /**
@@ -53,13 +53,6 @@ class PropertyMappingConfiguration implements \TYPO3\CMS\Extbase\Property\Proper
        protected $subConfigurationForProperty = array();
 
        /**
        protected $subConfigurationForProperty = array();
 
        /**
-        * The parent PropertyMappingConfiguration. If a configuration value for the current entry is not found, we propagate the question to the parent.
-        *
-        * @var \TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface
-        */
-       protected $parentConfiguration;
-
-       /**
         * Keys which should be renamed
         *
         * @var array
         * Keys which should be renamed
         *
         * @var array
@@ -79,6 +72,13 @@ class PropertyMappingConfiguration implements \TYPO3\CMS\Extbase\Property\Proper
        protected $propertiesToBeMapped = array();
 
        /**
        protected $propertiesToBeMapped = array();
 
        /**
+        * List of property names to be skipped during property mapping
+        *
+        * @var array
+        */
+       protected $propertiesToSkip = array();
+
+       /**
         * List of disallowed property names which will be ignored while property mapping
         *
         * @var array
         * List of disallowed property names which will be ignored while property mapping
         *
         * @var array
@@ -86,22 +86,18 @@ class PropertyMappingConfiguration implements \TYPO3\CMS\Extbase\Property\Proper
        protected $propertiesNotToBeMapped = array();
 
        /**
        protected $propertiesNotToBeMapped = array();
 
        /**
-        * If TRUE, unknown properties will be mapped.
+        * If TRUE, unknown properties will be skipped during property mapping
         *
         * @var boolean
         */
         *
         * @var boolean
         */
-       protected $mapUnknownProperties = FALSE;
+       protected $skipUnknownProperties = FALSE;
 
        /**
 
        /**
-        * Set the parent PropertyMappingConfiguration. Only used internally!
-        *
-        * @param \TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface $parentConfiguration
+        * If TRUE, unknown properties will be mapped.
         *
         *
-        * @return void
+        * @var boolean
         */
         */
-       protected function setParent(\TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface $parentConfiguration) {
-               $this->parentConfiguration = $parentConfiguration;
-       }
+       protected $mapUnknownProperties = FALSE;
 
        /**
         * The behavior is as follows:
 
        /**
         * The behavior is as follows:
@@ -119,23 +115,38 @@ class PropertyMappingConfiguration implements \TYPO3\CMS\Extbase\Property\Proper
                if (isset($this->propertiesNotToBeMapped[$propertyName])) {
                        return FALSE;
                }
                if (isset($this->propertiesNotToBeMapped[$propertyName])) {
                        return FALSE;
                }
+
                if (isset($this->propertiesToBeMapped[$propertyName])) {
                        return TRUE;
                }
                if (isset($this->propertiesToBeMapped[$propertyName])) {
                        return TRUE;
                }
+
                if (isset($this->subConfigurationForProperty[self::PROPERTY_PATH_PLACEHOLDER])) {
                        return TRUE;
                }
                if (isset($this->subConfigurationForProperty[self::PROPERTY_PATH_PLACEHOLDER])) {
                        return TRUE;
                }
+
                return $this->mapUnknownProperties;
        }
 
        /**
                return $this->mapUnknownProperties;
        }
 
        /**
+        * Check if the given $propertyName should be skipped during mapping.
+        *
+        * @param string $propertyName
+        * @return boolean
+        * @api
+        */
+       public function shouldSkip($propertyName) {
+               return isset($this->propertiesToSkip[$propertyName]);
+       }
+
+       /**
         * Allow all properties in property mapping, even unknown ones.
         *
         * Allow all properties in property mapping, even unknown ones.
         *
-        * @return void
+        * @return \TYPO3\CMS\Extbase\Property\PropertyMappingConfiguration this
         * @api
         */
        public function allowAllProperties() {
                $this->mapUnknownProperties = TRUE;
         * @api
         */
        public function allowAllProperties() {
                $this->mapUnknownProperties = TRUE;
+               return $this;
        }
 
        /**
        }
 
        /**
@@ -151,6 +162,23 @@ class PropertyMappingConfiguration implements \TYPO3\CMS\Extbase\Property\Proper
                foreach (func_get_args() as $propertyName) {
                        $this->propertiesToBeMapped[$propertyName] = $propertyName;
                }
                foreach (func_get_args() as $propertyName) {
                        $this->propertiesToBeMapped[$propertyName] = $propertyName;
                }
+               return $this;
+       }
+
+       /**
+        * Skip a list of specific properties. All arguments of
+        * skipProperties are used here (varargs).
+        *
+        * Example: skipProperties('unused', 'dummy')
+        *
+        * @return \TYPO3\CMS\Extbase\Property\PropertyMappingConfiguration this
+        * @api
+        */
+       public function skipProperties() {
+               foreach (func_get_args() as $propertyName) {
+                       $this->propertiesToSkip[$propertyName] = $propertyName;
+               }
+               return $this;
        }
 
        /**
        }
 
        /**
@@ -159,28 +187,55 @@ class PropertyMappingConfiguration implements \TYPO3\CMS\Extbase\Property\Proper
         *
         * Example: allowAllPropertiesExcept('password', 'userGroup')
         *
         *
         * Example: allowAllPropertiesExcept('password', 'userGroup')
         *
-        * @return void
+        * @return \TYPO3\CMS\Extbase\Property\PropertyMappingConfiguration this
         * @api
         */
        public function allowAllPropertiesExcept() {
                $this->mapUnknownProperties = TRUE;
         * @api
         */
        public function allowAllPropertiesExcept() {
                $this->mapUnknownProperties = TRUE;
+
                foreach (func_get_args() as $propertyName) {
                        $this->propertiesNotToBeMapped[$propertyName] = $propertyName;
                }
                foreach (func_get_args() as $propertyName) {
                        $this->propertiesNotToBeMapped[$propertyName] = $propertyName;
                }
+               return $this;
+       }
+
+       /**
+        * When this is enabled, properties that are disallowed will be skipped
+        * instead of triggering an error during mapping.
+        *
+        * @return \TYPO3\CMS\Extbase\Property\PropertyMappingConfiguration this
+        * @api
+        */
+       public function skipUnknownProperties() {
+               $this->skipUnknownProperties = TRUE;
+               return $this;
+       }
+
+       /**
+        * Whether unknown (unconfigured) properties should be skipped during
+        * mapping, instead if causing an error.
+        *
+        * @return boolean
+        * @api
+        */
+       public function shouldSkipUnknownProperties() {
+               return $this->skipUnknownProperties;
        }
 
        /**
         * Returns the sub-configuration for the passed $propertyName. Must ALWAYS return a valid configuration object!
         *
         * @param string $propertyName
        }
 
        /**
         * Returns the sub-configuration for the passed $propertyName. Must ALWAYS return a valid configuration object!
         *
         * @param string $propertyName
-        *
         * @return \TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface the property mapping configuration for the given $propertyName.
         * @api
         */
        public function getConfigurationFor($propertyName) {
                if (isset($this->subConfigurationForProperty[$propertyName])) {
                        return $this->subConfigurationForProperty[$propertyName];
         * @return \TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface the property mapping configuration for the given $propertyName.
         * @api
         */
        public function getConfigurationFor($propertyName) {
                if (isset($this->subConfigurationForProperty[$propertyName])) {
                        return $this->subConfigurationForProperty[$propertyName];
+               } elseif (isset($this->subConfigurationForProperty[self::PROPERTY_PATH_PLACEHOLDER])) {
+                       return $this->subConfigurationForProperty[self::PROPERTY_PATH_PLACEHOLDER];
                }
                }
+
                return new \TYPO3\CMS\Extbase\Property\PropertyMappingConfiguration();
        }
 
                return new \TYPO3\CMS\Extbase\Property\PropertyMappingConfiguration();
        }
 
@@ -188,7 +243,6 @@ class PropertyMappingConfiguration implements \TYPO3\CMS\Extbase\Property\Proper
         * Maps the given $sourcePropertyName to a target property name.
         *
         * @param string $sourcePropertyName
         * Maps the given $sourcePropertyName to a target property name.
         *
         * @param string $sourcePropertyName
-        *
         * @return string property name of target
         * @api
         */
         * @return string property name of target
         * @api
         */
@@ -202,7 +256,6 @@ class PropertyMappingConfiguration implements \TYPO3\CMS\Extbase\Property\Proper
        /**
         * @param string $typeConverterClassName
         * @param string $key
        /**
         * @param string $typeConverterClassName
         * @param string $key
-        *
         * @return mixed configuration value for the specific $typeConverterClassName. Can be used by Type Converters to fetch converter-specific configuration.
         * @api
         */
         * @return mixed configuration value for the specific $typeConverterClassName. Can be used by Type Converters to fetch converter-specific configuration.
         * @api
         */
@@ -210,6 +263,7 @@ class PropertyMappingConfiguration implements \TYPO3\CMS\Extbase\Property\Proper
                if (!isset($this->configuration[$typeConverterClassName][$key])) {
                        return NULL;
                }
                if (!isset($this->configuration[$typeConverterClassName][$key])) {
                        return NULL;
                }
+
                return $this->configuration[$typeConverterClassName][$key];
        }
 
                return $this->configuration[$typeConverterClassName][$key];
        }
 
@@ -218,12 +272,12 @@ class PropertyMappingConfiguration implements \TYPO3\CMS\Extbase\Property\Proper
         *
         * @param string $sourcePropertyName
         * @param string $targetPropertyName
         *
         * @param string $sourcePropertyName
         * @param string $targetPropertyName
-        *
-        * @return void
+        * @return \TYPO3\CMS\Extbase\Property\PropertyMappingConfiguration this
         * @api
         */
        public function setMapping($sourcePropertyName, $targetPropertyName) {
                $this->mapping[$sourcePropertyName] = $targetPropertyName;
         * @api
         */
        public function setMapping($sourcePropertyName, $targetPropertyName) {
                $this->mapping[$sourcePropertyName] = $targetPropertyName;
+               return $this;
        }
 
        /**
        }
 
        /**
@@ -231,15 +285,17 @@ class PropertyMappingConfiguration implements \TYPO3\CMS\Extbase\Property\Proper
         *
         * @param string $typeConverter class name of type converter
         * @param array $options
         *
         * @param string $typeConverter class name of type converter
         * @param array $options
-        *
-        * @return void
+        * @return \TYPO3\CMS\Extbase\Property\PropertyMappingConfiguration this
         * @api
         */
        public function setTypeConverterOptions($typeConverter, array $options) {
                if (strpos($typeConverter, '_') !== FALSE) {
                        $typeConverter = ClassLoader::getClassNameForAlias($typeConverter);
                }
         * @api
         */
        public function setTypeConverterOptions($typeConverter, array $options) {
                if (strpos($typeConverter, '_') !== FALSE) {
                        $typeConverter = ClassLoader::getClassNameForAlias($typeConverter);
                }
-               $this->configuration[$typeConverter] = $options;
+               foreach ($this->getTypeConvertersWithParentClasses($typeConverter) as $typeConverter) {
+                       $this->configuration[$typeConverter] = $options;
+               }
+               return $this;
        }
 
        /**
        }
 
        /**
@@ -248,15 +304,33 @@ class PropertyMappingConfiguration implements \TYPO3\CMS\Extbase\Property\Proper
         * @param string $typeConverter class name of type converter
         * @param string $optionKey
         * @param mixed $optionValue
         * @param string $typeConverter class name of type converter
         * @param string $optionKey
         * @param mixed $optionValue
-        *
-        * @return void
+        * @return \TYPO3\CMS\Extbase\Property\PropertyMappingConfiguration this
         * @api
         */
        public function setTypeConverterOption($typeConverter, $optionKey, $optionValue) {
                if (strpos($typeConverter, '_') !== FALSE) {
                        $typeConverter = ClassLoader::getClassNameForAlias($typeConverter);
                }
         * @api
         */
        public function setTypeConverterOption($typeConverter, $optionKey, $optionValue) {
                if (strpos($typeConverter, '_') !== FALSE) {
                        $typeConverter = ClassLoader::getClassNameForAlias($typeConverter);
                }
-               $this->configuration[$typeConverter][$optionKey] = $optionValue;
+               foreach ($this->getTypeConvertersWithParentClasses($typeConverter) as $typeConverter) {
+                       $this->configuration[$typeConverter][$optionKey] = $optionValue;
+               }
+               return $this;
+       }
+
+       /**
+        * Get type converter classes including parents for the given type converter
+        *
+        * When setting an option on a subclassed type converter, this option must also be set on
+        * all its parent type converters.
+        *
+        * @param string $typeConverter The type converter class
+        * @return array Class names of type converters
+        */
+       protected function getTypeConvertersWithParentClasses($typeConverter) {
+               $typeConverterClasses = class_parents($typeConverter);
+               $typeConverterClasses = $typeConverterClasses === FALSE ? array() : $typeConverterClasses;
+               $typeConverterClasses[] = $typeConverter;
+               return $typeConverterClasses;
        }
 
        /**
        }
 
        /**
@@ -265,7 +339,6 @@ class PropertyMappingConfiguration implements \TYPO3\CMS\Extbase\Property\Proper
         * $configuration->forProperty('foo.bar')->setTypeConverterOption(....)
         *
         * @param string $propertyPath
         * $configuration->forProperty('foo.bar')->setTypeConverterOption(....)
         *
         * @param string $propertyPath
-        *
         * @return \TYPO3\CMS\Extbase\Property\PropertyMappingConfiguration (or a subclass thereof)
         * @api
         */
         * @return \TYPO3\CMS\Extbase\Property\PropertyMappingConfiguration (or a subclass thereof)
         * @api
         */
@@ -278,18 +351,21 @@ class PropertyMappingConfiguration implements \TYPO3\CMS\Extbase\Property\Proper
         * Traverse the property configuration. Only used by forProperty().
         *
         * @param array $splittedPropertyPath
         * Traverse the property configuration. Only used by forProperty().
         *
         * @param array $splittedPropertyPath
-        *
         * @return \TYPO3\CMS\Extbase\Property\PropertyMappingConfiguration (or a subclass thereof)
         */
        public function traverseProperties(array $splittedPropertyPath) {
                if (count($splittedPropertyPath) === 0) {
                        return $this;
                }
         * @return \TYPO3\CMS\Extbase\Property\PropertyMappingConfiguration (or a subclass thereof)
         */
        public function traverseProperties(array $splittedPropertyPath) {
                if (count($splittedPropertyPath) === 0) {
                        return $this;
                }
+
                $currentProperty = array_shift($splittedPropertyPath);
                if (!isset($this->subConfigurationForProperty[$currentProperty])) {
                        $type = get_class($this);
                $currentProperty = array_shift($splittedPropertyPath);
                if (!isset($this->subConfigurationForProperty[$currentProperty])) {
                        $type = get_class($this);
-                       $this->subConfigurationForProperty[$currentProperty] = new $type();
-                       $this->subConfigurationForProperty[$currentProperty]->setParent($this);
+                       if (isset($this->subConfigurationForProperty[self::PROPERTY_PATH_PLACEHOLDER])) {
+                               $this->subConfigurationForProperty[$currentProperty] = clone $this->subConfigurationForProperty[self::PROPERTY_PATH_PLACEHOLDER];
+                       } else {
+                               $this->subConfigurationForProperty[$currentProperty] = new $type;
+                       }
                }
                return $this->subConfigurationForProperty[$currentProperty]->traverseProperties($splittedPropertyPath);
        }
                }
                return $this->subConfigurationForProperty[$currentProperty]->traverseProperties($splittedPropertyPath);
        }
@@ -308,12 +384,12 @@ class PropertyMappingConfiguration implements \TYPO3\CMS\Extbase\Property\Proper
         * Set a type converter which should be used for this specific conversion.
         *
         * @param \TYPO3\CMS\Extbase\Property\TypeConverterInterface $typeConverter
         * Set a type converter which should be used for this specific conversion.
         *
         * @param \TYPO3\CMS\Extbase\Property\TypeConverterInterface $typeConverter
-        *
-        * @return void
+        * @return \TYPO3\CMS\Extbase\Property\PropertyMappingConfiguration this
         * @api
         */
        public function setTypeConverter(\TYPO3\CMS\Extbase\Property\TypeConverterInterface $typeConverter) {
                $this->typeConverter = $typeConverter;
         * @api
         */
        public function setTypeConverter(\TYPO3\CMS\Extbase\Property\TypeConverterInterface $typeConverter) {
                $this->typeConverter = $typeConverter;
+               return $this;
        }
 }
 
        }
 }
 
index e449e20..404cd80 100644 (file)
@@ -22,8 +22,6 @@ namespace TYPO3\CMS\Extbase\Property;
  *                                                                        */
 /**
  * This builder creates the default configuration for Property Mapping, if no configuration has been passed to the Property Mapper.
  *                                                                        */
 /**
  * This builder creates the default configuration for Property Mapping, if no configuration has been passed to the Property Mapper.
- *
- * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
  */
 class PropertyMappingConfigurationBuilder implements \TYPO3\CMS\Core\SingletonInterface {
 
  */
 class PropertyMappingConfigurationBuilder implements \TYPO3\CMS\Core\SingletonInterface {
 
@@ -34,14 +32,16 @@ class PropertyMappingConfigurationBuilder implements \TYPO3\CMS\Core\SingletonIn
         * @return \TYPO3\CMS\Extbase\Property\PropertyMappingConfiguration
         */
        public function build($type = 'TYPO3\\CMS\\Extbase\\Property\\PropertyMappingConfiguration') {
         * @return \TYPO3\CMS\Extbase\Property\PropertyMappingConfiguration
         */
        public function build($type = 'TYPO3\\CMS\\Extbase\\Property\\PropertyMappingConfiguration') {
+               /** @var $configuration \TYPO3\CMS\Extbase\Property\PropertyMappingConfiguration */
                $configuration = new $type();
                $configuration = new $type();
+
                $configuration->setTypeConverterOptions('TYPO3\\CMS\\Extbase\\Property\\TypeConverter\\PersistentObjectConverter', array(
                        \TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED => TRUE,
                        \TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_MODIFICATION_ALLOWED => TRUE
                ));
                $configuration->allowAllProperties();
                $configuration->setTypeConverterOptions('TYPO3\\CMS\\Extbase\\Property\\TypeConverter\\PersistentObjectConverter', array(
                        \TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED => TRUE,
                        \TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_MODIFICATION_ALLOWED => TRUE
                ));
                $configuration->allowAllProperties();
+
                return $configuration;
        }
 }
                return $configuration;
        }
 }
-
 ?>
\ No newline at end of file
 ?>
\ No newline at end of file
index 94b94f4..a539fdd 100644 (file)
@@ -35,7 +35,16 @@ interface PropertyMappingConfigurationInterface {
         * @return boolean
         * @api
         */
         * @return boolean
         * @api
         */
-       public function shouldMap($propertyName);
+       public function shouldSkip($propertyName);
+
+       /**
+        * Whether unknown (unconfigured) properties should be skipped during
+        * mapping, instead if causing an error.
+        *
+        * @return boolean
+        * @api
+        */
+       public function shouldSkipUnknownProperties();
 
        /**
         * Returns the sub-configuration for the passed $propertyName. Must ALWAYS return a valid configuration object!
 
        /**
         * Returns the sub-configuration for the passed $propertyName. Must ALWAYS return a valid configuration object!
index 585fd42..94feed6 100644 (file)
@@ -28,7 +28,6 @@ namespace TYPO3\CMS\Extbase\Property\TypeConverter;
  * - set $priority
  * - implement convertFrom()
  *
  * - set $priority
  * - implement convertFrom()
  *
- * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
  * @api
  */
 abstract class AbstractTypeConverter implements \TYPO3\CMS\Extbase\Property\TypeConverterInterface, \TYPO3\CMS\Core\SingletonInterface {
  * @api
  */
 abstract class AbstractTypeConverter implements \TYPO3\CMS\Extbase\Property\TypeConverterInterface, \TYPO3\CMS\Core\SingletonInterface {
@@ -94,6 +93,19 @@ abstract class AbstractTypeConverter implements \TYPO3\CMS\Extbase\Property\Type
        }
 
        /**
        }
 
        /**
+        * Returns the $originalTargetType unchanged in this implementation.
+        *
+        * @param mixed $source the source data
+        * @param string $originalTargetType the type we originally want to convert to
+        * @param \TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface $configuration
+        * @return string
+        * @api
+        */
+       public function getTargetTypeForSource($source, $originalTargetType, \TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface $configuration = NULL) {
+               return $originalTargetType;
+       }
+
+       /**
         * Return the priority of this TypeConverter. TypeConverters with a high priority are chosen before low priority.
         *
         * @return integer
         * Return the priority of this TypeConverter. TypeConverters with a high priority are chosen before low priority.
         *
         * @return integer
@@ -118,7 +130,7 @@ abstract class AbstractTypeConverter implements \TYPO3\CMS\Extbase\Property\Type
        /**
         * Returns an empty list of sub property names
         *
        /**
         * Returns an empty list of sub property names
         *
-        * @param mixed $source (unused)
+        * @param mixed $source
         * @return array<string>
         * @api
         */
         * @return array<string>
         * @api
         */
@@ -138,5 +150,4 @@ abstract class AbstractTypeConverter implements \TYPO3\CMS\Extbase\Property\Type
        public function getTypeOfChildProperty($targetType, $propertyName, \TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface $configuration) {
        }
 }
        public function getTypeOfChildProperty($targetType, $propertyName, \TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface $configuration) {
        }
 }
-
 ?>
\ No newline at end of file
 ?>
\ No newline at end of file
index 44837ae..9f5c777 100644 (file)
@@ -23,10 +23,9 @@ namespace TYPO3\CMS\Extbase\Property\TypeConverter;
 /**
  * Converter which transforms arrays to arrays.
  *
 /**
  * Converter which transforms arrays to arrays.
  *
- * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
  * @api
  */
  * @api
  */
-class ArrayConverter extends \TYPO3\CMS\Extbase\Property\TypeConverter\AbstractTypeConverter implements \TYPO3\CMS\Core\SingletonInterface {
+class ArrayConverter extends \TYPO3\CMS\Extbase\Property\TypeConverter\AbstractTypeConverter {
 
        /**
         * @var array<string>
 
        /**
         * @var array<string>
@@ -57,5 +56,4 @@ class ArrayConverter extends \TYPO3\CMS\Extbase\Property\TypeConverter\AbstractT
                return $source;
        }
 }
                return $source;
        }
 }
-
 ?>
\ No newline at end of file
 ?>
\ No newline at end of file
index 1f04b90..d0661ad 100644 (file)
@@ -23,10 +23,9 @@ namespace TYPO3\CMS\Extbase\Property\TypeConverter;
 /**
  * Converter which transforms simple types to a boolean, by simply casting it.
  *
 /**
  * Converter which transforms simple types to a boolean, by simply casting it.
  *
- * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
  * @api
  */
  * @api
  */
-class BooleanConverter extends \TYPO3\CMS\Extbase\Property\TypeConverter\AbstractTypeConverter implements \TYPO3\CMS\Core\SingletonInterface {
+class BooleanConverter extends \TYPO3\CMS\Extbase\Property\TypeConverter\AbstractTypeConverter {
 
        /**
         * @var array<string>
 
        /**
         * @var array<string>
@@ -57,5 +56,4 @@ class BooleanConverter extends \TYPO3\CMS\Extbase\Property\TypeConverter\Abstrac
                return (boolean) $source;
        }
 }
                return (boolean) $source;
        }
 }
-
 ?>
\ No newline at end of file
 ?>
\ No newline at end of file
index eba963e..dd25cc4 100644 (file)
@@ -23,33 +23,44 @@ namespace TYPO3\CMS\Extbase\Property\TypeConverter;
 /**
  * Converter which transforms from different input formats into DateTime objects.
  *
 /**
  * Converter which transforms from different input formats into DateTime objects.
  *
- * Source can be either a string or an array.
- * The date string is expected to be formatted according to DEFAULT_DATE_FORMAT
- * But the default date format can be overridden in the initialize*Action() method like this:
- * $this->arguments['<argumentName>']
- * ->getPropertyMappingConfiguration()
- * ->forProperty('<propertyName>') // this line can be skipped in order to specify the format for all properties
- * ->setTypeConverterOption('TYPO3\\CMS\\Extbase\\Property\\TypeConverter\\DateTimeConverter', \TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter::CONFIGURATION_DATE_FORMAT, '<dateFormat>');
+ * Source can be either a string or an array. The date string is expected to be formatted
+ * according to DEFAULT_DATE_FORMAT.
  *
  *
- * If the source is of type array, it is possible to override the format in the source:
- * array(
- * 'date' => '<dateString>',
- * 'dateFormat' => '<dateFormat>'
- * );
+ * But the default date format can be overridden in the initialize*Action() method like this::
  *
  *
- * By using an array as source you can also override time and timezone of the created DateTime object:
- * array(
- * 'date' => '<dateString>',
- * 'hour' => '<hour>', // integer
- * 'minute' => '<minute>', // integer
- * 'seconds' => '<seconds>', // integer
- * 'timezone' => '<timezone>', // string, see http://www.php.net/manual/timezones.php
- * );
+ *  $this->arguments['<argumentName>']
+ *    ->getPropertyMappingConfiguration()
+ *    ->forProperty('<propertyName>') // this line can be skipped in order to specify the format for all properties
+ *    ->setTypeConverterOption('TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter', \TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter::CONFIGURATION_DATE_FORMAT, '<dateFormat>');
+ *
+ * If the source is of type array, it is possible to override the format in the source::
+ *
+ *  array(
+ *   'date' => '<dateString>',
+ *   'dateFormat' => '<dateFormat>'
+ *  );
+ *
+ * By using an array as source you can also override time and timezone of the created DateTime object::
+ *
+ *  array(
+ *   'date' => '<dateString>',
+ *   'hour' => '<hour>', // integer
+ *   'minute' => '<minute>', // integer
+ *   'seconds' => '<seconds>', // integer
+ *   'timezone' => '<timezone>', // string, see http://www.php.net/manual/timezones.php
+ *  );
+ *
+ * As an alternative to providing the date as string, you might supply day, month and year as array items each::
+ *
+ *  array(
+ *   'day' => '<day>', // integer
+ *   'month' => '<month>', // integer
+ *   'year' => '<year>', // integer
+ *  );
  *
  *
- * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
  * @api
  */
  * @api
  */
-class DateTimeConverter extends \TYPO3\CMS\Extbase\Property\TypeConverter\AbstractTypeConverter implements \TYPO3\CMS\Core\SingletonInterface {
+class DateTimeConverter extends \TYPO3\CMS\Extbase\Property\TypeConverter\AbstractTypeConverter {
 
        /**
         * @var string
 
        /**
         * @var string
@@ -58,9 +69,7 @@ class DateTimeConverter extends \TYPO3\CMS\Extbase\Property\TypeConverter\Abstra
 
        /**
         * The default date format is "YYYY-MM-DDT##:##:##+##:##", for example "2005-08-15T15:52:01+00:00"
 
        /**
         * The default date format is "YYYY-MM-DDT##:##:##+##:##", for example "2005-08-15T15:52:01+00:00"
-        * according to the W3C standard
-        *
-        * @see http://www.w3.org/TR/NOTE-datetime.html
+        * according to the W3C standard @see http://www.w3.org/TR/NOTE-datetime.html
         *
         * @var string
         */
         *
         * @var string
         */
@@ -69,7 +78,7 @@ class DateTimeConverter extends \TYPO3\CMS\Extbase\Property\TypeConverter\Abstra
        /**
         * @var array<string>
         */
        /**
         * @var array<string>
         */
-       protected $sourceTypes = array('string', 'integer','array');
+       protected $sourceTypes = array('string', 'integer', 'array');
 
        /**
         * @var string
 
        /**
         * @var string
@@ -86,7 +95,6 @@ class DateTimeConverter extends \TYPO3\CMS\Extbase\Property\TypeConverter\Abstra
         *
         * @param string $source
         * @param string $targetType
         *
         * @param string $source
         * @param string $targetType
-        *
         * @return boolean
         */
        public function canConvertFrom($source, $targetType) {
         * @return boolean
         */
        public function canConvertFrom($source, $targetType) {
@@ -105,11 +113,10 @@ class DateTimeConverter extends \TYPO3\CMS\Extbase\Property\TypeConverter\Abstra
        /**
         * Converts $source to a \DateTime using the configured dateFormat
         *
        /**
         * Converts $source to a \DateTime using the configured dateFormat
         *
-        * @param string|integer|array $source the string to be converted to a DateTime object
+        * @param string|integer|array $source the string to be converted to a \DateTime object
         * @param string $targetType must be "DateTime"
         * @param array $convertedChildProperties not used currently
         * @param \TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface $configuration
         * @param string $targetType must be "DateTime"
         * @param array $convertedChildProperties not used currently
         * @param \TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface $configuration
-        *
         * @return \DateTime
         * @throws \TYPO3\CMS\Extbase\Property\Exception\TypeConverterException
         */
         * @return \DateTime
         * @throws \TYPO3\CMS\Extbase\Property\Exception\TypeConverterException
         */
@@ -139,7 +146,7 @@ class DateTimeConverter extends \TYPO3\CMS\Extbase\Property\TypeConverter\Abstra
                if ($dateAsString === '') {
                        return NULL;
                }
                if ($dateAsString === '') {
                        return NULL;
                }
-               if (ctype_digit($dateAsString) && (!is_array($source) || !isset($source['dateFormat'])) && $configuration === NULL) {
+               if (ctype_digit($dateAsString) && $configuration === NULL && (!is_array($source) || !isset($source['dateFormat']))) {
                        $dateFormat = 'U';
                }
                if (is_array($source) && isset($source['timezone']) && strlen($source['timezone']) !== 0) {
                        $dateFormat = 'U';
                }
                if (is_array($source) && isset($source['timezone']) && strlen($source['timezone']) !== 0) {
@@ -153,10 +160,7 @@ class DateTimeConverter extends \TYPO3\CMS\Extbase\Property\TypeConverter\Abstra
                        $date = $targetType::createFromFormat($dateFormat, $dateAsString);
                }
                if ($date === FALSE) {
                        $date = $targetType::createFromFormat($dateFormat, $dateAsString);
                }
                if ($date === FALSE) {
-                       return new \TYPO3\CMS\Extbase\Error\Error('The date "%s" was not recognized (for format "%s").', 1307719788, array(
-                               $dateAsString,
-                               $dateFormat
-                       ));
+                       return new \TYPO3\CMS\Extbase\Validation\Error('The date "%s" was not recognized (for format "%s").', 1307719788, array($dateAsString, $dateFormat));
                }
                if (is_array($source)) {
                        $this->overrideTimeIfSpecified($date, $source);
                }
                if (is_array($source)) {
                        $this->overrideTimeIfSpecified($date, $source);
@@ -166,15 +170,13 @@ class DateTimeConverter extends \TYPO3\CMS\Extbase\Property\TypeConverter\Abstra
 
        /**
         * Returns whether date information (day, month, year) are present as keys in $source.
 
        /**
         * Returns whether date information (day, month, year) are present as keys in $source.
-        *
-        * @param array $source
-        *
-        * @return boolean
+        * @param $source
+        * @return bool
         */
        protected function isDatePartKeysProvided(array $source) {
         */
        protected function isDatePartKeysProvided(array $source) {
-               return isset($source['day']) && ctype_digit((string)$source['day'])
-                       && isset($source['month']) && ctype_digit((string)$source['month'])
-                       && isset($source['year']) && ctype_digit((string)$source['year']);
+               return isset($source['day']) && ctype_digit($source['day'])
+                       && isset($source['month']) && ctype_digit($source['month'])
+                       && isset($source['year']) && ctype_digit($source['year']);
        }
 
        /**
        }
 
        /**
@@ -182,7 +184,6 @@ class DateTimeConverter extends \TYPO3\CMS\Extbase\Property\TypeConverter\Abstra
         * If no format is specified in the mapping configuration DEFAULT_DATE_FORMAT is used.
         *
         * @param \TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface $configuration
         * If no format is specified in the mapping configuration DEFAULT_DATE_FORMAT is used.
         *
         * @param \TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface $configuration
-        *
         * @return string
         * @throws \TYPO3\CMS\Extbase\Property\Exception\InvalidPropertyMappingConfigurationException
         */
         * @return string
         * @throws \TYPO3\CMS\Extbase\Property\Exception\InvalidPropertyMappingConfigurationException
         */
@@ -204,19 +205,17 @@ class DateTimeConverter extends \TYPO3\CMS\Extbase\Property\TypeConverter\Abstra
         *
         * @param \DateTime $date
         * @param array $source
         *
         * @param \DateTime $date
         * @param array $source
-        *
         * @return void
         */
        protected function overrideTimeIfSpecified(\DateTime $date, array $source) {
                if (!isset($source['hour']) && !isset($source['minute']) && !isset($source['second'])) {
                        return;
                }
         * @return void
         */
        protected function overrideTimeIfSpecified(\DateTime $date, array $source) {
                if (!isset($source['hour']) && !isset($source['minute']) && !isset($source['second'])) {
                        return;
                }
-
                $hour = isset($source['hour']) ? (integer)$source['hour'] : 0;
                $minute = isset($source['minute']) ? (integer)$source['minute'] : 0;
                $second = isset($source['second']) ? (integer)$source['second'] : 0;
                $date->setTime($hour, $minute, $second);
        }
                $hour = isset($source['hour']) ? (integer)$source['hour'] : 0;
                $minute = isset($source['minute']) ? (integer)$source['minute'] : 0;
                $second = isset($source['second']) ? (integer)$source['second'] : 0;
                $date->setTime($hour, $minute, $second);
        }
-}
 
 
+}
 ?>
\ No newline at end of file
 ?>
\ No newline at end of file
index a39790e..d5966c9 100644 (file)
@@ -21,17 +21,18 @@ namespace TYPO3\CMS\Extbase\Property\TypeConverter;
  * The TYPO3 project - inspiring people to share!                         *
  *                                                                        */
 /**
  * The TYPO3 project - inspiring people to share!                         *
  *                                                                        */
 /**
- * Converter which transforms a simple type to a float, by simply casting it.
+ * Converter which transforms a simple type to a float.
+ *
+ * This is basically done by simply casting it.
  *
  *
- * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
  * @api
  */
  * @api
  */
-class FloatConverter extends \TYPO3\CMS\Extbase\Property\TypeConverter\AbstractTypeConverter implements \TYPO3\CMS\Core\SingletonInterface {
+class FloatConverter extends \TYPO3\CMS\Extbase\Property\TypeConverter\AbstractTypeConverter {
 
        /**
         * @var array<string>
         */
 
        /**
         * @var array<string>
         */
-       protected $sourceTypes = array('string');
+       protected $sourceTypes = array('float', 'integer', 'string');
 
        /**
         * @var string
 
        /**
         * @var string
@@ -46,16 +47,23 @@ class FloatConverter extends \TYPO3\CMS\Extbase\Property\TypeConverter\AbstractT
        /**
         * Actually convert from $source to $targetType, by doing a typecast.
         *
        /**
         * Actually convert from $source to $targetType, by doing a typecast.
         *
-        * @param string $source
+        * @param mixed $source
         * @param string $targetType
         * @param array $convertedChildProperties
         * @param \TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface $configuration
         * @param string $targetType
         * @param array $convertedChildProperties
         * @param \TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface $configuration
-        * @return float
+        * @return float|\TYPO3\CMS\Extbase\Error\Error
         * @api
         */
        public function convertFrom($source, $targetType, array $convertedChildProperties = array(), \TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface $configuration = NULL) {
         * @api
         */
        public function convertFrom($source, $targetType, array $convertedChildProperties = array(), \TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface $configuration = NULL) {
-               return (double) $source;
+               if ($source === NULL || strlen($source) === 0) {
+                       return NULL;
+               }
+               // We won't backport the full flavored locale parsing of floats from Flow here
+
+               if (!is_numeric($source)) {
+                       return new \TYPO3\CMS\Extbase\Error\Error('"%s" cannot be converted to a float value.', 1332934124, array($source));
+               }
+               return (float) $source;
        }
 }
        }
 }
-
 ?>
\ No newline at end of file
 ?>
\ No newline at end of file
index 6d0ff9d..dfe6081 100644 (file)
@@ -23,7 +23,6 @@ namespace TYPO3\CMS\Extbase\Property\TypeConverter;
 /**
  * Converter which transforms a simple type to an integer, by simply casting it.
  *
 /**
  * Converter which transforms a simple type to an integer, by simply casting it.
  *
- * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
  * @api
  */
 class IntegerConverter extends \TYPO3\CMS\Extbase\Property\TypeConverter\AbstractTypeConverter implements \TYPO3\CMS\Core\SingletonInterface {
  * @api
  */
 class IntegerConverter extends \TYPO3\CMS\Extbase\Property\TypeConverter\AbstractTypeConverter implements \TYPO3\CMS\Core\SingletonInterface {
@@ -46,16 +45,21 @@ class IntegerConverter extends \TYPO3\CMS\Extbase\Property\TypeConverter\Abstrac
        /**
         * Actually convert from $source to $targetType, in fact a noop here.
         *
        /**
         * Actually convert from $source to $targetType, in fact a noop here.
         *
-        * @param integer $source
+        * @param integer|string $source
         * @param string $targetType
         * @param array $convertedChildProperties
         * @param \TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface $configuration
         * @param string $targetType
         * @param array $convertedChildProperties
         * @param \TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface $configuration
-        * @return integer
+        * @return integer|\TYPO3\CMS\Extbase\Error\Error
         * @api
         */
        public function convertFrom($source, $targetType, array $convertedChildProperties = array(), \TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface $configuration = NULL) {
         * @api
         */
        public function convertFrom($source, $targetType, array $convertedChildProperties = array(), \TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface $configuration = NULL) {
-               return (integer) $source;
+               if ($source === NULL || strlen($source) === 0) {
+                       return NULL;
+               }
+               if (!is_numeric($source)) {
+                       return new \TYPO3\CMS\Extbase\Error\Error('"%s" is no integer.', 1332933658, array($source));
+               }
+               return (integer)$source;
        }
 }
        }
 }
-
 ?>
\ No newline at end of file
 ?>
\ No newline at end of file
index a7c53e7..734d324 100644 (file)
@@ -20,26 +20,14 @@ namespace TYPO3\CMS\Extbase\Property\TypeConverter;
  *                                                                        *
  * The TYPO3 project - inspiring people to share!                         *
  *                                                                        */
  *                                                                        *
  * The TYPO3 project - inspiring people to share!                         *
  *                                                                        */
+
 /**
 /**
- * Converter which transforms arrays to arrays.
+ * Converter which transforms simple types to a ObjectStorage.
  *
  *
- * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
  * @api
  * @api
+ * @todo Implement functionality for converting collection properties.
  */
  */
-class ObjectStorageConverter extends \TYPO3\CMS\Extbase\Property\TypeConverter\AbstractTypeConverter implements \TYPO3\CMS\Core\SingletonInterface {
-
-       /**
-        * @var \TYPO3\CMS\Extbase\Service\TypeHandlingService
-        */
-       protected $typeHandlingService;
-
-       /**
-        * @param \TYPO3\CMS\Extbase\Service\TypeHandlingService $typeHandlingService
-        * @return void
-        */
-       public function injectTypeHandlingService(\TYPO3\CMS\Extbase\Service\TypeHandlingService $typeHandlingService) {
-               $this->typeHandlingService = $typeHandlingService;
-       }
+class ObjectStorageConverter extends AbstractTypeConverter {
 
        /**
         * @var array<string>
 
        /**
         * @var array<string>
@@ -57,27 +45,14 @@ class ObjectStorageConverter extends \TYPO3\CMS\Extbase\Property\TypeConverter\A
        protected $priority = 1;
 
        /**
        protected $priority = 1;
 
        /**
-        * Returns the source, if it is an array, otherwise an empty array.
+        * Actually convert from $source to $targetType, taking into account the fully
+        * built $convertedChildProperties and $configuration.
         *
         * @param mixed $source
         *
         * @param mixed $source
-        * @return array
-        * @api
-        */
-       public function getSourceChildPropertiesToBeConverted($source) {
-               if (is_array($source)) {
-                       return $source;
-               }
-               return array();
-       }
-
-       /**
-        * Actually convert from $source to $targetType, in fact a noop here.
-        *
-        * @param array $source
         * @param string $targetType
         * @param array $convertedChildProperties
         * @param \TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface $configuration
         * @param string $targetType
         * @param array $convertedChildProperties
         * @param \TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface $configuration
-        * @return array
+        * @return \TYPO3\CMS\Extbase\Persistence\ObjectStorage
         * @api
         */
        public function convertFrom($source, $targetType, array $convertedChildProperties = array(), \TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface $configuration = NULL) {
         * @api
         */
        public function convertFrom($source, $targetType, array $convertedChildProperties = array(), \TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface $configuration = NULL) {
@@ -89,6 +64,20 @@ class ObjectStorageConverter extends \TYPO3\CMS\Extbase\Property\TypeConverter\A
        }
 
        /**
        }
 
        /**
+        * Returns the source, if it is an array, otherwise an empty array.
+        *
+        * @param mixed $source
+        * @return array
+        * @api
+        */
+       public function getSourceChildPropertiesToBeConverted($source) {
+               if (is_array($source)) {
+                       return $source;
+               }
+               return array();
+       }
+
+       /**
         * Return the type of a given sub-property inside the $targetType
         *
         * @param string $targetType
         * Return the type of a given sub-property inside the $targetType
         *
         * @param string $targetType
@@ -98,9 +87,8 @@ class ObjectStorageConverter extends \TYPO3\CMS\Extbase\Property\TypeConverter\A
         * @api
         */
        public function getTypeOfChildProperty($targetType, $propertyName, \TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface $configuration) {
         * @api
         */
        public function getTypeOfChildProperty($targetType, $propertyName, \TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface $configuration) {
-               $parsedTargetType = $this->typeHandlingService->parseType($targetType);
+               $parsedTargetType = \TYPO3\CMS\Extbase\Utility\TypeHandlingUtility::parseType($targetType);
                return $parsedTargetType['elementType'];
        }
 }
                return $parsedTargetType['elementType'];
        }
 }
-
 ?>
\ No newline at end of file
 ?>
\ No newline at end of file
index d330f84..c14ec2f 100644 (file)
@@ -28,17 +28,27 @@ namespace TYPO3\CMS\Extbase\Property\TypeConverter;
  *
  * - If the input has an identity property and NO additional properties, we fetch the object from persistence.
  * - If the input has an identity property AND additional properties, we fetch the object from persistence,
  *
  * - If the input has an identity property and NO additional properties, we fetch the object from persistence.
  * - If the input has an identity property AND additional properties, we fetch the object from persistence,
- * create a clone on it, and set the sub-properties. We only do this if the configuration option "CONFIGURATION_MODIFICATION_ALLOWED" is TRUE.
+ *   and set the sub-properties. We only do this if the configuration option "CONFIGURATION_MODIFICATION_ALLOWED" is TRUE.
  * - If the input has NO identity property, but additional properties, we create a new object and return it.
  * - If the input has NO identity property, but additional properties, we create a new object and return it.
- * However, we only do this if the configuration option "CONFIGURATION_CREATION_ALLOWED" is TRUE.
+ *   However, we only do this if the configuration option "CONFIGURATION_CREATION_ALLOWED" is TRUE.
  *
  *
- * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
  * @api
  */
 class PersistentObjectConverter extends \TYPO3\CMS\Extbase\Property\TypeConverter\AbstractTypeConverter implements \TYPO3\CMS\Core\SingletonInterface {
 
  * @api
  */
 class PersistentObjectConverter extends \TYPO3\CMS\Extbase\Property\TypeConverter\AbstractTypeConverter implements \TYPO3\CMS\Core\SingletonInterface {
 
+       /**
+        * @var integer
+        */
        const CONFIGURATION_MODIFICATION_ALLOWED = 1;
        const CONFIGURATION_MODIFICATION_ALLOWED = 1;
+
+       /**
+        * @var integer
+        */
        const CONFIGURATION_CREATION_ALLOWED = 2;
        const CONFIGURATION_CREATION_ALLOWED = 2;
+
+       /**
+        * @var integer
+        */
        const CONFIGURATION_TARGET_TYPE = 3;
 
        /**
        const CONFIGURATION_TARGET_TYPE = 3;
 
        /**
@@ -103,9 +113,7 @@ class PersistentObjectConverter extends \TYPO3\CMS\Extbase\Property\TypeConverte
         * @return boolean
         */
        public function canConvertFrom($source, $targetType) {
         * @return boolean
         */
        public function canConvertFrom($source, $targetType) {
-               $isValueObject = is_subclass_of($targetType, 'TYPO3\\CMS\\Extbase\\DomainObject\\AbstractValueObject');
-               $isEntity = is_subclass_of($targetType, 'TYPO3\\CMS\\Extbase\\DomainObject\\AbstractEntity');
-               return $isEntity || $isValueObject;
+               return is_subclass_of($targetType, 'TYPO3\\CMS\\Extbase\\DomainObject\\AbstractDomainObject');
        }
 
        /**
        }
 
        /**
@@ -121,6 +129,9 @@ class PersistentObjectConverter extends \TYPO3\CMS\Extbase\Property\TypeConverte
                if (isset($source['__identity'])) {
                        unset($source['__identity']);
                }
                if (isset($source['__identity'])) {
                        unset($source['__identity']);
                }
+               if (isset($source['__type'])) {
+                       unset($source['__type']);
+               }
                return $source;
        }
 
                return $source;
        }
 
@@ -138,6 +149,7 @@ class PersistentObjectConverter extends \TYPO3\CMS\Extbase\Property\TypeConverte
                if ($configuredTargetType !== NULL) {
                        return $configuredTargetType;
                }
                if ($configuredTargetType !== NULL) {
                        return $configuredTargetType;
                }
+
                $schema = $this->reflectionService->getClassSchema($targetType);
                if (!$schema->hasProperty($propertyName)) {
                        throw new \TYPO3\CMS\Extbase\Property\Exception\InvalidTargetException('Property "' . $propertyName . '" was not found in target object of type "' . $targetType . '".', 1297978366);
                $schema = $this->reflectionService->getClassSchema($targetType);
                if (!$schema->hasProperty($propertyName)) {
                        throw new \TYPO3\CMS\Extbase\Property\Exception\InvalidTargetException('Property "' . $propertyName . '" was not found in target object of type "' . $targetType . '".', 1297978366);
@@ -159,8 +171,19 @@ class PersistentObjectConverter extends \TYPO3\CMS\Extbase\Property\TypeConverte
         */
        public function convertFrom($source, $targetType, array $convertedChildProperties = array(), \TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface $configuration = NULL) {
                if (is_array($source)) {
         */
        public function convertFrom($source, $targetType, array $convertedChildProperties = array(), \TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface $configuration = NULL) {
                if (is_array($source)) {
+                       if (
+                               class_exists($targetType)
+                               && is_subclass_of($targetType, 'TYPO3\\CMS\\Extbase\\DomainObject\\AbstractValueObject')
+                       ) {
+                               // Unset identity for valueobject to use constructor mapping, since the identity is determined from
+                               // constructor arguments
+                               unset($source['__identity']);
+                       }
                        $object = $this->handleArrayData($source, $targetType, $convertedChildProperties, $configuration);
                } elseif (is_string($source)) {
                        $object = $this->handleArrayData($source, $targetType, $convertedChildProperties, $configuration);
                } elseif (is_string($source)) {
+                       if ($source === '' || $source === '0') {
+                               return NULL;
+                       }
                        $object = $this->fetchObjectFromPersistence($source, $targetType);
                } else {
                        throw new \InvalidArgumentException('Only strings and arrays are accepted.', 1305630314);
                        $object = $this->fetchObjectFromPersistence($source, $targetType);
                } else {
                        throw new \InvalidArgumentException('Only strings and arrays are accepted.', 1305630314);
@@ -168,9 +191,16 @@ class PersistentObjectConverter extends \TYPO3\CMS\Extbase\Property\TypeConverte
                foreach ($convertedChildProperties as $propertyName => $propertyValue) {
                        $result = \TYPO3\CMS\Extbase\Reflection\ObjectAccess::setProperty($object, $propertyName, $propertyValue);
                        if ($result === FALSE) {
                foreach ($convertedChildProperties as $propertyName => $propertyValue) {
                        $result = \TYPO3\CMS\Extbase\Reflection\ObjectAccess::setProperty($object, $propertyName, $propertyValue);
                        if ($result === FALSE) {
-                               throw new \TYPO3\CMS\Extbase\Property\Exception\InvalidTargetException('Property "' . $propertyName . '" could not be set in target object of type "' . $targetType . '".', 1297935345);
+                               $exceptionMessage = sprintf(
+                                       'Property "%s" having a value of type "%s" could not be set in target object of type "%s". Make sure that the property is accessible properly, for example via an appropriate setter method.',
+                                       $propertyName,
+                                       (is_object($propertyValue) ? get_class($propertyValue) : gettype($propertyValue)),
+                                       $targetType
+                               );
+                               throw new \TYPO3\CMS\Extbase\Property\Exception\InvalidTargetException($exceptionMessage, 1297935345);
                        }
                }
                        }
                }
+
                return $object;
        }
 
                return $object;
        }
 
@@ -187,19 +217,17 @@ class PersistentObjectConverter extends \TYPO3\CMS\Extbase\Property\TypeConverte
        protected function handleArrayData(array $source, $targetType, array &$convertedChildProperties, \TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface $configuration = NULL) {
                if (isset($source['__identity'])) {
                        $object = $this->fetchObjectFromPersistence($source['__identity'], $targetType);
        protected function handleArrayData(array $source, $targetType, array &$convertedChildProperties, \TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface $configuration = NULL) {
                if (isset($source['__identity'])) {
                        $object = $this->fetchObjectFromPersistence($source['__identity'], $targetType);
-                       if (count($source) > 1) {
-                               if ($configuration === NULL || $configuration->getConfigurationValue('TYPO3\\CMS\\Extbase\\Property\\TypeConverter\\PersistentObjectConverter', self::CONFIGURATION_MODIFICATION_ALLOWED) !== TRUE) {
-                                       throw new \TYPO3\CMS\Extbase\Property\Exception\InvalidPropertyMappingConfigurationException('Modification of persistent objects not allowed. To enable this, you need to set the PropertyMappingConfiguration Value "CONFIGURATION_MODIFICATION_ALLOWED" to TRUE.', 1297932028);
-                               }
-                               $object = clone $object;
+
+                       if (count($source) > 1 && ($configuration === NULL || $configuration->getConfigurationValue('TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter', self::CONFIGURATION_MODIFICATION_ALLOWED) !== TRUE)) {
+                               throw new \TYPO3\CMS\Extbase\Property\Exception\InvalidPropertyMappingConfigurationException('Modification of persistent objects not allowed. To enable this, you need to set the PropertyMappingConfiguration Value "CONFIGURATION_MODIFICATION_ALLOWED" to TRUE.', 1297932028);
                        }
                        }
-                       return $object;
                } else {
                        if ($configuration === NULL || $configuration->getConfigurationValue('TYPO3\\CMS\\Extbase\\Property\\TypeConverter\\PersistentObjectConverter', self::CONFIGURATION_CREATION_ALLOWED) !== TRUE) {
                                throw new \TYPO3\CMS\Extbase\Property\Exception\InvalidPropertyMappingConfigurationException('Creation of objects not allowed. To enable this, you need to set the PropertyMappingConfiguration Value "CONFIGURATION_CREATION_ALLOWED" to TRUE');
                        }
                } else {
                        if ($configuration === NULL || $configuration->getConfigurationValue('TYPO3\\CMS\\Extbase\\Property\\TypeConverter\\PersistentObjectConverter', self::CONFIGURATION_CREATION_ALLOWED) !== TRUE) {
                                throw new \TYPO3\CMS\Extbase\Property\Exception\InvalidPropertyMappingConfigurationException('Creation of objects not allowed. To enable this, you need to set the PropertyMappingConfiguration Value "CONFIGURATION_CREATION_ALLOWED" to TRUE');
                        }
-                       return $this->buildObject($convertedChildProperties, $targetType);
+                       $object = $this->buildObject($convertedChildProperties, $targetType);
                }
                }
+               return $object;
        }
 
        /**
        }
 
        /**
@@ -217,9 +245,11 @@ class PersistentObjectConverter extends \TYPO3\CMS\Extbase\Property\TypeConverte
                } else {
                        throw new \TYPO3\CMS\Extbase\Property\Exception\InvalidSourceException('The identity property "' . $identity . '" is no UID.', 1297931020);
                }
                } else {
                        throw new \TYPO3\CMS\Extbase\Property\Exception\InvalidSourceException('The identity property "' . $identity . '" is no UID.', 1297931020);
                }
+
                if ($object === NULL) {
                        throw new \TYPO3\CMS\Extbase\Property\Exception\TargetNotFoundException('Object with identity "' . print_r($identity, TRUE) . '" not found.', 1297933823);
                }
                if ($object === NULL) {
                        throw new \TYPO3\CMS\Extbase\Property\Exception\TargetNotFoundException('Object with identity "' . print_r($identity, TRUE) . '" not found.', 1297933823);
                }
+
                return $object;
        }
 
                return $object;
        }
 
index 7ea8259..fee8ae9 100644 (file)
@@ -23,7 +23,6 @@ namespace TYPO3\CMS\Extbase\Property\TypeConverter;
 /**
  * Converter which transforms simple types to a string.
  *
 /**
  * Converter which transforms simple types to a string.
  *
- * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
  * @api
  */
 class StringConverter extends \TYPO3\CMS\Extbase\Property\TypeConverter\AbstractTypeConverter implements \TYPO3\CMS\Core\SingletonInterface {
  * @api
  */
 class StringConverter extends \TYPO3\CMS\Extbase\Property\TypeConverter\AbstractTypeConverter implements \TYPO3\CMS\Core\SingletonInterface {
@@ -31,7 +30,7 @@ class StringConverter extends \TYPO3\CMS\Extbase\Property\TypeConverter\Abstract
        /**
         * @var array<string>
         */
        /**
         * @var array<string>
         */
-       protected $sourceTypes = array('string');
+       protected $sourceTypes = array('string', 'integer');
 
        /**
         * @var string
 
        /**
         * @var string
@@ -55,7 +54,7 @@ class StringConverter extends \TYPO3\CMS\Extbase\Property\TypeConverter\Abstract
         * @api
         */
        public function convertFrom($source, $targetType, array $convertedChildProperties = array(), \TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface $configuration = NULL) {
         * @api
         */
        public function convertFrom($source, $targetType, array $convertedChildProperties = array(), \TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface $configuration = NULL) {
-               return $source;
+               return (string) $source;
        }
 }
 
        }
 }
 
index ad92709..a4c46e8 100644 (file)
@@ -25,7 +25,6 @@ namespace TYPO3\CMS\Extbase\Property;
  *
  * All Type Converters should have NO INTERNAL STATE, such that they can be used as singletons and multiple times in succession (as this improves performance dramatically).
  *
  *
  * All Type Converters should have NO INTERNAL STATE, such that they can be used as singletons and multiple times in succession (as this improves performance dramatically).
  *
- * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
  * @api
  */
 interface TypeConverterInterface {
  * @api
  */
 interface TypeConverterInterface {
@@ -49,6 +48,17 @@ interface TypeConverterInterface {
        public function getSupportedTargetType();
 
        /**
        public function getSupportedTargetType();
 
        /**
+        * Returns the type for a given source, depending on e.g. the __type setting or other properties.
+        *
+        * @param mixed $source the source data
+        * @param string $originalTargetType the type we originally want to convert to
+        * @param \TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface $configuration
+        * @return string
+        * @api
+        */
+       public function getTargetTypeForSource($source, $originalTargetType, PropertyMappingConfigurationInterface $configuration = NULL);
+
+       /**
         * Return the priority of this TypeConverter. TypeConverters with a high priority are chosen before low priority.
         *
         * @return integer
         * Return the priority of this TypeConverter. TypeConverters with a high priority are chosen before low priority.
         *
         * @return integer
@@ -94,19 +104,19 @@ interface TypeConverterInterface {
         *
         * The return value can be one of three types:
         * - an arbitrary object, or a simple type (which has been created while mapping).
         *
         * The return value can be one of three types:
         * - an arbitrary object, or a simple type (which has been created while mapping).
-        * This is the normal case.
+        *   This is the normal case.
         * - NULL, indicating that this object should *not* be mapped (i.e. a "File Upload" Converter could return NULL if no file has been uploaded, and a silent failure should occur.
         * - NULL, indicating that this object should *not* be mapped (i.e. a "File Upload" Converter could return NULL if no file has been uploaded, and a silent failure should occur.
-        * - An instance of \TYPO3\CMS\Extbase\Error\Error - This will be a user-visible error message lateron.
-        * Furthermore, it should throw an Exception if an unexpected failure occured or a configuration issue happened.
+        * - An instance of \TYPO3\CMS\Extbase\Error\Error -- This will be a user-visible error message later on.
+        * Furthermore, it should throw an Exception if an unexpected failure (like a security error) occurred or a configuration issue happened.
         *
         * @param mixed $source
         * @param string $targetType
         * @param array $convertedChildProperties
         * @param \TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface $configuration
         *
         * @param mixed $source
         * @param string $targetType
         * @param array $convertedChildProperties
         * @param \TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface $configuration
-        * @return mixed the target type
+        * @return mixed|\TYPO3\CMS\Extbase\Error\Error the target type, or an error object if a user-error occurred
+        * @throws \TYPO3\CMS\Extbase\Property\Exception\TypeConverterException thrown in case a developer error occurred
         * @api
         */
        public function convertFrom($source, $targetType, array $convertedChildProperties = array(), \TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface $configuration = NULL);
 }
         * @api
         */
        public function convertFrom($source, $targetType, array $convertedChildProperties = array(), \TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface $configuration = NULL);
 }
-
 ?>
\ No newline at end of file
 ?>
\ No newline at end of file
index a62c144..23262c9 100644 (file)
@@ -27,20 +27,24 @@ namespace TYPO3\CMS\Extbase\Service;
  *
  *  This copyright notice MUST APPEAR in all copies of the script!
  ***************************************************************/
  *
  *  This copyright notice MUST APPEAR in all copies of the script!
  ***************************************************************/
+
+use TYPO3\CMS\Extbase\Utility\TypeHandlingUtility;
+
 /**
  * PHP type handling functions
 /**
  * PHP type handling functions
+ * @deprecated since 6.1, will be removed two versions later
  */
 class TypeHandlingService implements \TYPO3\CMS\Core\SingletonInterface {
 
        /**
         * A property type parse pattern.
         */
  */
 class TypeHandlingService implements \TYPO3\CMS\Core\SingletonInterface {
 
        /**
         * A property type parse pattern.
         */
-       const PARSE_TYPE_PATTERN = '/^\\\\?(?P<type>integer|int|float|double|boolean|bool|string|DateTime|Tx_[a-zA-Z0-9_]+|[A-Z][a-zA-Z0-9\\\\_]+|array|ArrayObject|SplObjectStorage)(?:<(?P<elementType>[a-zA-Z0-9\\\\_]+)>)?/';
+       const PARSE_TYPE_PATTERN = TypeHandlingUtility::PARSE_TYPE_PATTERN;
 
        /**
         * A type pattern to detect literal types.
         */
 
        /**
         * A type pattern to detect literal types.
         */
-       const LITERAL_TYPE_PATTERN = '/^(?:integer|int|float|double|boolean|bool|string)$/';
+       const LITERAL_TYPE_PATTERN = TypeHandlingUtility::LITERAL_TYPE_PATTERN;
 
        /**
         * Adds (defines) a specific property and its type.
 
        /**
         * Adds (defines) a specific property and its type.
@@ -50,26 +54,7 @@ class TypeHandlingService implements \TYPO3\CMS\Core\SingletonInterface {
         * @return array An array with information about the type
         */
        public function parseType($type) {
         * @return array An array with information about the type
         */
        public function parseType($type) {
-               $matches = array();
-               if (preg_match(self::PARSE_TYPE_PATTERN, $type, $matches)) {
-                       $type = self::normalizeType($matches['type']);
-                       $elementType = isset($matches['elementType']) ? self::normalizeType($matches['elementType']) : NULL;
-                       if ($elementType !== NULL && !in_array($type, array('array', 'ArrayObject', 'SplObjectStorage', 'TYPO3\\CMS\\Extbase\\Persistence\\ObjectStorage', 'Tx_Extbase_Persistence_ObjectStorage'))) {
-                               throw new \InvalidArgumentException(
-                                       'Type "' . $type . '" must not have an element type hint (' . $elementType . ').',
-                                       1309255650
-                               );
-                       }
-                       return array(
-                               'type' => $type,
-                               'elementType' => $elementType
-                       );
-               } else {
-                       throw new \InvalidArgumentException(
-                               'Invalid type encountered: ' . var_export($type, TRUE),
-                               1309255651
-                       );
-               }
+               return TypeHandlingUtility::parseType($type);
        }
 
        /**
        }
 
        /**
@@ -82,19 +67,7 @@ class TypeHandlingService implements \TYPO3\CMS\Core\SingletonInterface {
         * @return string unified data type
         */
        public function normalizeType($type) {
         * @return string unified data type
         */
        public function normalizeType($type) {
-               switch ($type) {
-                       case 'int':
-                               $type = 'integer';
-                               break;
-                       case 'bool':
-                               $type = 'boolean';
-                               break;
-                       case 'double':
-                               $type = 'float';
-                               break;
-               }
-               $type = ltrim($type, '\\');
-               return $type;
+               return TypeHandlingUtility::normalizeType($type);
        }
 
        /**
        }
 
        /**
@@ -104,7 +77,7 @@ class TypeHandlingService implements \TYPO3\CMS\Core\SingletonInterface {
         * @return boolean
         */
        public function isLiteral($type) {
         * @return boolean
         */
        public function isLiteral($type) {
-               return preg_match(self::LITERAL_TYPE_PATTERN, $type) === 1;
+               return TypeHandlingUtility::isLiteral($type);
        }
 
        /**
        }
 
        /**
@@ -114,7 +87,7 @@ class TypeHandlingService implements \TYPO3\CMS\Core\SingletonInterface {
         * @return boolean
         */
        public function isSimpleType($type) {
         * @return boolean
         */
        public function isSimpleType($type) {
-               return in_array(self::normalizeType($type), array('array', 'string', 'float', 'integer', 'boolean'), TRUE);
+               return TypeHandlingUtility::isSimpleType($type);
        }
 }
 
        }
 }
 
diff --git a/typo3/sysext/extbase/Classes/Utility/Exception/InvalidTypeException.php b/typo3/sysext/extbase/Classes/Utility/Exception/InvalidTypeException.php
new file mode 100644 (file)
index 0000000..b9fcb0f
--- /dev/null
@@ -0,0 +1,31 @@
+<?php
+namespace TYPO3\CMS\Extbase\Utility\Exception;
+
+/*                                                                        *
+ * This script belongs to the Extbase framework                           *
+ *                                                                        *
+ * It is free software; you can redistribute it and/or modify it under    *
+ * the terms of the GNU Lesser General Public License as published by the *
+ * Free Software Foundation, either version 3 of the License, or (at your *
+ * option) any later version.                                             *
+ *                                                                        *
+ * This script is distributed in the hope that it will be useful, but     *
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN-    *
+ * TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser       *
+ * General Public License for more details.                               *
+ *                                                                        *
+ * You should have received a copy of the GNU Lesser General Public       *
+ * License along with the script.                                         *
+ * If not, see http://www.gnu.org/licenses/lgpl.html                      *
+ *                                                                        *
+ * The TYPO3 project - inspiring people to share!                         *
+ *                                                                        */
+
+/**
+ * An Invalid Type Exception
+ *
+ */
+class InvalidTypeException extends \TYPO3\CMS\Extbase\Exception {
+
+}
+?>
\ No newline at end of file
diff --git a/typo3/sysext/extbase/Classes/Utility/TypeHandlingUtility.php b/typo3/sysext/extbase/Classes/Utility/TypeHandlingUtility.php
new file mode 100644 (file)
index 0000000..4fec71a
--- /dev/null
@@ -0,0 +1,153 @@
+<?php
+namespace TYPO3\CMS\Extbase\Utility;
+
+/*                                                                        *
+ * This script belongs to the TYPO3 Flow framework.                       *
+ *                                                                        *
+ * It is free software; you can redistribute it and/or modify it under    *
+ * the terms of the GNU Lesser General Public License, either version 3   *
+ * of the License, or (at your option) any later version.                 *
+ *                                                                        *
+ * The TYPO3 project - inspiring people to share!                         *
+ *                                                                        */
+
+/**
+ * PHP type handling functions
+ *
+ */
+class TypeHandlingUtility {
+
+       /**
+        * A property type parse pattern.
+        */
+       const PARSE_TYPE_PATTERN = '/^\\\\?(?P<type>integer|int|float|double|boolean|bool|string|DateTime|Tx_[a-zA-Z0-9_]+|[A-Z][a-zA-Z0-9\\\\_]+|object|array|ArrayObject|SplObjectStorage|TYPO3\\\\CMS\\\\Extbase\\\\Persistence\\\\ObjectStorage|Tx_Extbase_Persistence_ObjectStorage)(?:<\\\\?(?P<elementType>[a-zA-Z0-9\\\\_]+)>)?/';
+
+       /**
+        * A type pattern to detect literal types.
+        */
+       const LITERAL_TYPE_PATTERN = '/^(?:integer|int|float|double|boolean|bool|string)$/';
+
+       /**
+        * @var array
+        */
+       static protected $collectionTypes = array('array', 'ArrayObject', 'SplObjectStorage', 'TYPO3\\CMS\\Extbase\\Persistence\\ObjectStorage', 'Tx_Extbase_Persistence_ObjectStorage');
+
+       /**
+        * Returns an array with type information, including element type for
+        * collection types (array, SplObjectStorage, ...)
+        *
+        * @param string $type Type of the property (see PARSE_TYPE_PATTERN)
+        * @return array An array with information about the type
+        * @throws \TYPO3\CMS\Extbase\Utility\Exception\InvalidTypeException
+        */
+       static public function parseType($type) {
+               $matches = array();
+               if (preg_match(self::PARSE_TYPE_PATTERN, $type, $matches)) {
+                       $type = self::normalizeType($matches['type']);
+                       $elementType = isset($matches['elementType']) ? self::normalizeType($matches['elementType']) : NULL;
+
+                       if ($elementType !== NULL && !self::isCollectionType($type)) {
+                               throw new \TYPO3\CMS\Extbase\Utility\Exception\InvalidTypeException('Found an invalid element type declaration in %s. Type "' . $type . '" must not have an element type hint (' . $elementType . ').', 1264093642);
+                       }
+
+                       return array(
+                               'type' => $type,
+                               'elementType' => $elementType
+                       );
+               } else {
+                       throw new \TYPO3\CMS\Extbase\Utility\Exception\InvalidTypeException('Found an invalid element type declaration in %s. A type "' . var_export($type, TRUE) . '" does not exist.', 1264093630);
+               }
+       }
+
+       /**
+        * Normalize data types so they match the PHP type names:
+        *  int -> integer
+        *  double -> float
+        *  bool -> boolean
+        *
+        * @param string $type Data type to unify
+        * @return string unified data type
+        */
+       static public function normalizeType($type) {
+               switch ($type) {
+                       case 'int':
+                               $type = 'integer';
+                               break;
+                       case 'bool':
+                               $type = 'boolean';
+                               break;
+                       case 'double':
+                               $type = 'float';
+                               break;
+               }
+               return $type;
+       }
+
+       /**
+        * Returns TRUE if the $type is a literal.
+        *
+        * @param string $type
+        * @return boolean
+        */
+       static public function isLiteral($type) {
+               return preg_match(self::LITERAL_TYPE_PATTERN, $type) === 1;
+       }
+
+       /**
+        * Returns TRUE if the $type is a simple type.
+        *
+        * @param string $type
+        * @return boolean
+        */
+       static public function isSimpleType($type) {
+               return in_array(self::normalizeType($type), array('array', 'string', 'float', 'integer', 'boolean'), TRUE);
+       }
+
+       /**
+        * Returns TRUE if the $type is a collection type.
+        *
+        * @param string $type
+        * @return boolean
+        */
+       static public function isCollectionType($type) {
+               if (in_array($type, self::$collectionTypes, TRUE)) {
+                       return TRUE;
+               }
+
+               if (class_exists($type) === TRUE || interface_exists($type) === TRUE) {
+                       foreach (self::$collectionTypes as $collectionType) {
+                               if (is_subclass_of($type, $collectionType) === TRUE) {
+                                       return TRUE;
+                               }
+                       }
+
+                               // is_subclass_of does not check for interfaces in PHP < 5.3.7
+                       if (version_compare(PHP_VERSION, '5.3.7', '<') === TRUE) {
+                               foreach (self::$collectionTypes as $collectionType) {
+                                       if (in_array($collectionType, class_implements($type)) === TRUE) {
+                                               return TRUE;
+                                       }
+                               }
+                       }
+               }
+
+               return FALSE;
+       }
+
+       /**
+        * Converts a hex encoded string into binary data
+        *
+        * @param string $hexadecimalData A hex encoded string of data
+        * @return string A binary string decoded from the input
+        */
+       static public function hex2bin($hexadecimalData) {
+               $binaryData = '';
+               $length = strlen($hexadecimalData);
+               for ($i = 0; $i < $length; $i += 2) {
+                       $binaryData .=  pack('C', hexdec(substr($hexadecimalData, $i, 2)));
+               }
+               return $binaryData;
+       }
+}
+
+?>
\ No newline at end of file
index d7cdf26..2e33ac8 100644 (file)
@@ -23,7 +23,6 @@ namespace TYPO3\CMS\Extbase\Tests\Fixture;
 /**
  * A dummy class with setters for testing data mapping
  *
 /**
  * A dummy class with setters for testing data mapping
  *
- * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
  */
 class ClassWithSetters {
 
  */
 class ClassWithSetters {
 
@@ -47,26 +46,16 @@ class ClassWithSetters {
         */
        public $property4;
 
         */
        public $property4;
 
-       /**
-        * @param mixed $value
-        */
        public function setProperty3($value) {
                $this->property3 = $value;
        }
 
        public function setProperty3($value) {
                $this->property3 = $value;
        }
 
-       /**
-        * @param mixed $value
-        */
        protected function setProperty4($value) {
                $this->property4 = $value;
        }
 
        protected function setProperty4($value) {
                $this->property4 = $value;
        }
 
-       /**
-        * @return mixed
-        */
        public function getProperty2() {
                return $this->property2;
        }
 }
        public function getProperty2() {
                return $this->property2;
        }
 }
-
 ?>
\ No newline at end of file
 ?>
\ No newline at end of file
index c383ea3..423684b 100644 (file)
@@ -23,7 +23,6 @@ namespace TYPO3\CMS\Extbase\Tests\Fixture;
 /**
  * A dummy class with setters for testing data mapping
  *
 /**
  * A dummy class with setters for testing data mapping
  *
- * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
  */
 class ClassWithSettersAndConstructor {
 
  */
 class ClassWithSettersAndConstructor {
 
@@ -37,33 +36,20 @@ class ClassWithSettersAndConstructor {
         */
        protected $property2;
 
         */
        protected $property2;
 
-       /**
-        * @param mixed $property1
-        */
        public function __construct($property1) {
                $this->property1 = $property1;
        }
 
        public function __construct($property1) {
                $this->property1 = $property1;
        }
 
-       /**
-        * @return mixed
-        */
        public function getProperty1() {
                return $this->property1;
        }
 
        public function getProperty1() {
                return $this->property1;
        }
 
-       /**
-        * @return mixed
-        */
        public function getProperty2() {
                return $this->property2;
        }
 
        public function getProperty2() {
                return $this->property2;
        }
 
-       /**
-        * @param mixed $property2
-        */
        public function setProperty2($property2) {
                $this->property2 = $property2;
        }
 }
        public function setProperty2($property2) {
                $this->property2 = $property2;
        }
 }
-
-?>
\ No newline at end of file
+?>
index ef022bd..190324e 100644 (file)
@@ -48,6 +48,41 @@ abstract class BaseTestCase extends \TYPO3\CMS\Core\Tests\UnitTestCase {
                $this->objectManager = clone $objectManager;
                parent::runBare();
        }
                $this->objectManager = clone $objectManager;
                parent::runBare();
        }
+
+       /**
+        * Injects $dependency into property $name of $target
+        *
+        * This is a convenience method for setting a protected or private property in
+        * a test subject for the purpose of injecting a dependency.
+        *
+        * @param object $target The instance which needs the dependency
+        * @param string $name Name of the property to be injected
+        * @param object $dependency The dependency to inject – usually an object but can also be any other type
+        * @return void
+        * @throws \RuntimeException
+        * @throws \InvalidArgumentException
+        */
+       protected function inject($target, $name, $dependency) {
+               if (!is_object($target)) {
+                       throw new \InvalidArgumentException('Wrong type for argument $target, must be object.');
+               }
+
+               $objectReflection = new \ReflectionObject($target);
+               $methodNamePart = strtoupper($name[0]) . substr($name, 1);
+               if ($objectReflection->hasMethod('set' . $methodNamePart)) {
+                       $methodName = 'set' . $methodNamePart;
+                       $target->$methodName($dependency);
+               } elseif ($objectReflection->hasMethod('inject' . $methodNamePart)) {
+                       $methodName = 'inject' . $methodNamePart;
+                       $target->$methodName($dependency);
+               } elseif ($objectReflection->hasProperty($name)) {
+                       $property = $objectReflection->getProperty($name);
+                       $property->setAccessible(TRUE);
+                       $property->setValue($target, $dependency);
+               } else {
+                       throw new \RuntimeException('Could not inject ' . $name . ' into object of type ' . get_class($target));
+               }
+       }
 }
 
 ?>
\ No newline at end of file
 }
 
 ?>
\ No newline at end of file
index 0a524ea..56ea25a 100644 (file)
@@ -20,6 +20,9 @@ namespace TYPO3\CMS\Extbase\Tests\Unit\Property;
  *                                                                        *
  * The TYPO3 project - inspiring people to share!                         *
  *                                                                        */
  *                                                                        *
  * The TYPO3 project - inspiring people to share!                         *
  *                                                                        */
+
+require_once (__DIR__ . '/../../Fixture/ClassWithSetters.php');
+
 /**
  * Testcase for the Property Mapper
  *
 /**
  * Testcase for the Property Mapper
  *
@@ -124,7 +127,6 @@ class PropertyMapperTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
 
        /**
         * Simple type conversion
 
        /**
         * Simple type conversion
-        *
         * @return array
         */
        public function dataProviderForFindTypeConverter() {
         * @return array
         */
        public function dataProviderForFindTypeConverter() {
@@ -163,11 +165,7 @@ class PropertyMapperTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
         * @param mixed $expectedTypeConverter
         */
        public function findTypeConverterShouldReturnHighestPriorityTypeConverterForSimpleType($source, $targetType, $typeConverters, $expectedTypeConverter) {
         * @param mixed $expectedTypeConverter
         */
        public function findTypeConverterShouldReturnHighestPriorityTypeConverterForSimpleType($source, $targetType, $typeConverters, $expectedTypeConverter) {
-               $mockTypeHandlingService = $this->getMock('TYPO3\\CMS\\Extbase\\Service\\TypeHandlingService');
-               $mockTypeHandlingService->expects($this->any())->method('isSimpleType')->will($this->returnValue(TRUE));
-               /** @var \TYPO3\CMS\Extbase\Property\PropertyMapper|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface */
-               $propertyMapper = $this->getAccessibleMock('TYPO3\\CMS\\Extbase\\Property\\PropertyMapper', array('dummy'));
-               $propertyMapper->_set('typeHandlingService', $mockTypeHandlingService);
+               $propertyMapper = $this->getAccessibleMock('TYPO3\CMS\Extbase\Property\PropertyMapper', array('dummy'));
                $propertyMapper->_set('typeConverters', $typeConverters);
                $actualTypeConverter = $propertyMapper->_call('findTypeConverter', $source, $targetType, $this->mockConfiguration);
                $this->assertSame($expectedTypeConverter, $actualTypeConverter->_name);
                $propertyMapper->_set('typeConverters', $typeConverters);
                $actualTypeConverter = $propertyMapper->_call('findTypeConverter', $source, $targetType, $this->mockConfiguration);
                $this->assertSame($expectedTypeConverter, $actualTypeConverter->_name);
@@ -178,13 +176,26 @@ class PropertyMapperTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
         */
        public function dataProviderForObjectTypeConverters() {
                $data = array();
         */
        public function dataProviderForObjectTypeConverters() {
                $data = array();
-               $className1 = uniqid('F3_FLOW3_Testclass1_', FALSE);
-               $className2 = uniqid('F3_FLOW3_Testclass2_', FALSE);
-               $className3 = uniqid('F3_FLOW3_Testclass3_', FALSE);
-               $interfaceName1 = uniqid('F3_FLOW3_TestInterface1_', FALSE);
-               $interfaceName2 = uniqid('F3_FLOW3_TestInterface2_', FALSE);
-               $interfaceName3 = uniqid('F3_FLOW3_TestInterface3_', FALSE);
-               eval("\n\t\t\tinterface {$interfaceName2} {}\n\t\t\tinterface {$interfaceName1} {}\n\n\t\t\tinterface {$interfaceName3} extends {$interfaceName2} {}\n\n\t\t\tclass {$className1} implements {$interfaceName1} {}\n\t\t\tclass {$className2} extends {$className1} {}\n\t\t\tclass {$className3} extends {$className2} implements {$interfaceName3} {}\n\t\t");
+
+               $className1 = uniqid('TYPO3_Flow_Testclass1_', FALSE);
+               $className2 = uniqid('TYPO3_Flow_Testclass2_', FALSE);
+               $className3 = uniqid('TYPO3_Flow_Testclass3_', FALSE);
+
+               $interfaceName1 = uniqid('TYPO3_Flow_TestInterface1_', FALSE);
+               $interfaceName2 = uniqid('TYPO3_Flow_TestInterface2_', FALSE);
+               $interfaceName3 = uniqid('TYPO3_Flow_TestInterface3_', FALSE);
+
+               eval("
+                       interface $interfaceName2 {}
+                       interface $interfaceName1 {}
+
+                       interface $interfaceName3 extends $interfaceName2 {}
+
+                       class $className1 implements $interfaceName1 {}
+                       class $className2 extends $className1 {}
+                       class $className3 extends $className2 implements $interfaceName3 {}
+               ");
+
                // The most specific converter should win
                $data[] = array(
                        'target' => $className3,
                // The most specific converter should win
                $data[] = array(
                        'target' => $className3,
@@ -192,11 +203,13 @@ class PropertyMapperTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
                        'typeConverters' => array(
                                $className2 => array(0 => $this->getMockTypeConverter('Class2Converter')),
                                $className3 => array(0 => $this->getMockTypeConverter('Class3Converter')),
                        'typeConverters' => array(
                                $className2 => array(0 => $this->getMockTypeConverter('Class2Converter')),
                                $className3 => array(0 => $this->getMockTypeConverter('Class3Converter')),
+
                                $interfaceName1 => array(0 => $this->getMockTypeConverter('Interface1Converter')),
                                $interfaceName2 => array(0 => $this->getMockTypeConverter('Interface2Converter')),
                                $interfaceName1 => array(0 => $this->getMockTypeConverter('Interface1Converter')),
                                $interfaceName2 => array(0 => $this->getMockTypeConverter('Interface2Converter')),
-                               $interfaceName3 => array(0 => $this->getMockTypeConverter('Interface3Converter'))
+                               $interfaceName3 => array(0 => $this->getMockTypeConverter('Interface3Converter')),
                        )
                );
                        )
                );
+
                // In case the most specific converter does not want to handle this conversion, the second one is taken.
                $data[] = array(
                        'target' => $className3,
                // In case the most specific converter does not want to handle this conversion, the second one is taken.
                $data[] = array(
                        'target' => $className3,
@@ -204,11 +217,13 @@ class PropertyMapperTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
                        'typeConverters' => array(
                                $className2 => array(0 => $this->getMockTypeConverter('Class2Converter')),
                                $className3 => array(0 => $this->getMockTypeConverter('Class3Converter', FALSE)),
                        'typeConverters' => array(
                                $className2 => array(0 => $this->getMockTypeConverter('Class2Converter')),
                                $className3 => array(0 => $this->getMockTypeConverter('Class3Converter', FALSE)),
+
                                $interfaceName1 => array(0 => $this->getMockTypeConverter('Interface1Converter')),
                                $interfaceName2 => array(0 => $this->getMockTypeConverter('Interface2Converter')),
                                $interfaceName1 => array(0 => $this->getMockTypeConverter('Interface1Converter')),
                                $interfaceName2 => array(0 => $this->getMockTypeConverter('Interface2Converter')),
-                               $interfaceName3 => array(0 => $this->getMockTypeConverter('Interface3Converter'))
+                               $interfaceName3 => array(0 => $this->getMockTypeConverter('Interface3Converter')),
                        )
                );
                        )
                );
+
                // In case there is no most-specific-converter, we climb ub the type hierarchy
                $data[] = array(
                        'target' => $className3,
                // In case there is no most-specific-converter, we climb ub the type hierarchy
                $data[] = array(
                        'target' => $className3,
@@ -217,41 +232,48 @@ class PropertyMapperTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
                                $className2 => array(0 => $this->getMockTypeConverter('Class2Converter'), 10 => $this->getMockTypeConverter('Class2Converter-HighPriority'))
                        )
                );
                                $className2 => array(0 => $this->getMockTypeConverter('Class2Converter'), 10 => $this->getMockTypeConverter('Class2Converter-HighPriority'))
                        )
                );
+
                // If no parent class converter wants to handle it, we ask for all interface converters.
                $data[] = array(
                        'target' => $className3,
                        'expectedConverter' => 'Interface1Converter',
                        'typeConverters' => array(
                                $className2 => array(0 => $this->getMockTypeConverter('Class2Converter', FALSE), 10 => $this->getMockTypeConverter('Class2Converter-HighPriority', FALSE)),
                // If no parent class converter wants to handle it, we ask for all interface converters.
                $data[] = array(
                        'target' => $className3,
                        'expectedConverter' => 'Interface1Converter',
                        'typeConverters' => array(
                                $className2 => array(0 => $this->getMockTypeConverter('Class2Converter', FALSE), 10 => $this->getMockTypeConverter('Class2Converter-HighPriority', FALSE)),
+
                                $interfaceName1 => array(4 => $this->getMockTypeConverter('Interface1Converter')),
                                $interfaceName2 => array(1 => $this->getMockTypeConverter('Interface2Converter')),
                                $interfaceName1 => array(4 => $this->getMockTypeConverter('Interface1Converter')),
                                $interfaceName2 => array(1 => $this->getMockTypeConverter('Interface2Converter')),
-                               $interfaceName3 => array(2 => $this->getMockTypeConverter('Interface3Converter'))
+                               $interfaceName3 => array(2 => $this->getMockTypeConverter('Interface3Converter')),
                        )
                );
                        )
                );
+
                // If two interface converters have the same priority, an exception is thrown.
                $data[] = array(
                        'target' => $className3,
                        'expectedConverter' => 'Interface1Converter',
                        'typeConverters' => array(
                                $className2 => array(0 => $this->getMockTypeConverter('Class2Converter', FALSE), 10 => $this->getMockTypeConverter('Class2Converter-HighPriority', FALSE)),
                // If two interface converters have the same priority, an exception is thrown.
                $data[] = array(
                        'target' => $className3,
                        'expectedConverter' => 'Interface1Converter',
                        'typeConverters' => array(
                                $className2 => array(0 => $this->getMockTypeConverter('Class2Converter', FALSE), 10 => $this->getMockTypeConverter('Class2Converter-HighPriority', FALSE)),
+
                                $interfaceName1 => array(4 => $this->getMockTypeConverter('Interface1Converter')),
                                $interfaceName2 => array(2 => $this->getMockTypeConverter('Interface2Converter')),
                                $interfaceName1 => array(4 => $this->getMockTypeConverter('Interface1Converter')),
                                $interfaceName2 => array(2 => $this->getMockTypeConverter('Interface2Converter')),
-                               $interfaceName3 => array(2 => $this->getMockTypeConverter('Interface3Converter'))
+                               $interfaceName3 => array(2 => $this->getMockTypeConverter('Interface3Converter')),
                        ),
                        'shouldFailWithException' => 'TYPO3\\CMS\\Extbase\\Property\\Exception\\DuplicateTypeConverterException'
                );
                        ),
                        'shouldFailWithException' => 'TYPO3\\CMS\\Extbase\\Property\\Exception\\DuplicateTypeConverterException'
                );
+
                // If no interface converter wants to handle it, a converter for "object" is looked up.
                $data[] = array(
                        'target' => $className3,
                        'expectedConverter' => 'GenericObjectConverter-HighPriority',
                        'typeConverters' => array(
                                $className2 => array(0 => $this->getMockTypeConverter('Class2Converter', FALSE), 10 => $this->getMockTypeConverter('Class2Converter-HighPriority', FALSE)),
                // If no interface converter wants to handle it, a converter for "object" is looked up.
                $data[] = array(
                        'target' => $className3,
                        'expectedConverter' => 'GenericObjectConverter-HighPriority',
                        'typeConverters' => array(
                                $className2 => array(0 => $this->getMockTypeConverter('Class2Converter', FALSE), 10 => $this->getMockTypeConverter('Class2Converter-HighPriority', FALSE)),
+
                                $interfaceName1 => array(4 => $this->getMockTypeConverter('Interface1Converter', FALSE)),
                                $interfaceName2 => array(3 => $this->getMockTypeConverter('Interface2Converter', FALSE)),
                                $interfaceName3 => array(2 => $this->getMockTypeConverter('Interface3Converter', FALSE)),
                                'object' => array(1 => $this->getMockTypeConverter('GenericObjectConverter'), 10 => $this->getMockTypeConverter('GenericObjectConverter-HighPriority'))
                                $interfaceName1 => array(4 => $this->getMockTypeConverter('Interface1Converter', FALSE)),
                                $interfaceName2 => array(3 => $this->getMockTypeConverter('Interface2Converter', FALSE)),
                                $interfaceName3 => array(2 => $this->getMockTypeConverter('Interface3Converter', FALSE)),
                                'object' => array(1 => $this->getMockTypeConverter('GenericObjectConverter'), 10 => $this->getMockTypeConverter('GenericObjectConverter-HighPriority'))
-                       )
+                       ),
                );
                );
+
                // If the target is no valid class name and no simple type, an exception is thrown
                $data[] = array(
                        'target' => 'SomeNotExistingClassName',
                // If the target is no valid class name and no simple type, an exception is thrown
                $data[] = array(
                        'target' => 'SomeNotExistingClassName',
@@ -259,6 +281,7 @@ class PropertyMapperTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
                        'typeConverters' => array(),
                        'shouldFailWithException' => 'TYPO3\\CMS\\Extbase\\Property\\Exception\\InvalidTargetException'
                );
                        'typeConverters' => array(),
                        'shouldFailWithException' => 'TYPO3\\CMS\\Extbase\\Property\\Exception\\InvalidTargetException'
                );
+
                // if the type converter is not found, we expect an exception
                $data[] = array(
                        'target' => $className3,
                // if the type converter is not found, we expect an exception
                $data[] = array(
                        'target' => $className3,
@@ -266,6 +289,7 @@ class PropertyMapperTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
                        'typeConverters' => array(),
                        'shouldFailWithException' => 'TYPO3\\CMS\\Extbase\\Property\\Exception\\TypeConverterException'
                );
                        'typeConverters' => array(),
                        'shouldFailWithException' => 'TYPO3\\CMS\\Extbase\\Property\\Exception\\TypeConverterException'
                );
+
                // If The target type is no string, we expect an exception.
                $data[] = array(
                        'target' => new \stdClass(),
                // If The target type is no string, we expect an exception.
                $data[] = array(
                        'target' => new \stdClass(),
@@ -288,11 +312,7 @@ class PropertyMapperTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
         * @return void
         */
        public function findTypeConverterShouldReturnConverterForTargetObjectIfItExists($targetClass, $expectedTypeConverter, $typeConverters, $shouldFailWithException = FALSE) {
         * @return void
         */
        public function findTypeConverterShouldReturnConverterForTargetObjectIfItExists($targetClass, $expectedTypeConverter, $typeConverters, $shouldFailWithException = FALSE) {
-               $mockTypeHandlingService = $this->getMock('TYPO3\\CMS\\Extbase\\Service\\TypeHandlingService');
-               $mockTypeHandlingService->expects($this->any())->method('isSimpleType')->will($this->returnValue(FALSE));
-               /** @var \TYPO3\CMS\Extbase\Property\PropertyMapper|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface */
-               $propertyMapper = $this->getAccessibleMock('TYPO3\\CMS\\Extbase\\Property\\PropertyMapper', array('dummy'));
-               $propertyMapper->injectTypeHandlingService($mockTypeHandlingService);
+               $propertyMapper = $this->getAccessibleMock('TYPO3\CMS\Extbase\Property\PropertyMapper', array('dummy'));
                $propertyMapper->_set('typeConverters', array('string' => $typeConverters));
                try {
                        $actualTypeConverter = $propertyMapper->_call('findTypeConverter', 'someSourceString', $targetClass, $this->mockConfiguration);
                $propertyMapper->_set('typeConverters', array('string' => $typeConverters));
                try {
                        $actualTypeConverter = $propertyMapper->_call('findTypeConverter', 'someSourceString', $targetClass, $this->mockConfiguration);
@@ -310,29 +330,26 @@ class PropertyMapperTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
 
        /**
         * @test
 
        /**
         * @test
-        * @author Sebastian Kurfürst <sebastian@typo3.org>
         */
        public function convertShouldAskConfigurationBuilderForDefaultConfiguration() {
         */
        public function convertShouldAskConfigurationBuilderForDefaultConfiguration() {
-               $mockTypeHandlingService = $this->getMock('TYPO3\\CMS\\Extbase\\Service\\TypeHandlingService');
-               $mockTypeHandlingService->expects($this->any())->method('isSimpleType')->will($this->returnValue(TRUE));
-               /** @var \TYPO3\CMS\Extbase\Property\PropertyMapper|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface */
-               $propertyMapper = $this->getAccessibleMock('TYPO3\\CMS\\Extbase\\Property\\PropertyMapper', array('dummy'));
-               $propertyMapper->injectTypeHandlingService($mockTypeHandlingService);
-               $propertyMapper->injectPropertyMappingConfigurationBuilder($this->mockConfigurationBuilder);
+               $propertyMapper = $this->getAccessibleMock('TYPO3\CMS\Extbase\Property\PropertyMapper', array('dummy'));
+               $this->inject($propertyMapper, 'configurationBuilder', $this->mockConfigurationBuilder);
+
                $this->mockConfigurationBuilder->expects($this->once())->method('build')->will($this->returnValue($this->mockConfiguration));
                $this->mockConfigurationBuilder->expects($this->once())->method('build')->will($this->returnValue($this->mockConfiguration));
+
                $converter = $this->getMockTypeConverter('string2string');
                $typeConverters = array(
                        'string' => array(
                                'string' => array(10 => $converter)
                        )
                );
                $converter = $this->getMockTypeConverter('string2string');
                $typeConverters = array(
                        'string' => array(
                                'string' => array(10 => $converter)
                        )
                );
+
                $propertyMapper->_set('typeConverters', $typeConverters);
                $this->assertEquals('string2string', $propertyMapper->convert('source', 'string'));
        }
 
        /**
         * @test
                $propertyMapper->_set('typeConverters', $typeConverters);
                $this->assertEquals('string2string', $propertyMapper->convert('source', 'string'));
        }
 
        /**
         * @test
-        * @author Sebastian Kurfürst <sebastian@typo3.org>
         */
        public function findFirstEligibleTypeConverterInObjectHierarchyShouldReturnNullIfSourceTypeIsUnknown() {
                /** @var \TYPO3\CMS\Extbase\Property\PropertyMapper|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface */
         */
        public function findFirstEligibleTypeConverterInObjectHierarchyShouldReturnNullIfSourceTypeIsUnknown() {
                /** @var \TYPO3\CMS\Extbase\Property\PropertyMapper|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface */
@@ -343,25 +360,66 @@ class PropertyMapperTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
        /**
         * @test
         */
        /**
         * @test
         */
-       public function convertReturnsSourceUnchangedIfAlreadyConverted() {
-               $source = new \ArrayObject();
-               $targetType = 'ArrayObject';
+       public function doMappingReturnsSourceUnchangedIfAlreadyConverted() {
+               $source = new \TYPO3\CMS\Extbase\Persistence\ObjectStorage();
+               $targetType = 'TYPO3\CMS\Extbase\Persistence\ObjectStorage';
                $propertyPath = '';
                $propertyPath = '';
-               $propertyMapper = new \TYPO3\CMS\Extbase\Property\PropertyMapper();
-               $this->assertSame($source, $propertyMapper->convert($source, $targetType, $this->mockConfiguration, $propertyPath));
+               $propertyMapper = $this->getAccessibleMock('TYPO3\CMS\Extbase\Property\PropertyMapper', array('dummy'));
+               $this->assertSame($source, $propertyMapper->_callRef('doMapping', $source, $targetType, $this->mockConfiguration, $propertyPath));
        }
 
        /**
         * @test
         */
        }
 
        /**
         * @test
         */
-       public function convertReturnsSourceUnchangedIfAlreadyConvertedToCompositeType() {
-               $source = new \ArrayObject();
-               $targetType = 'ArrayObject<SomeEntity>';
+       public function doMappingReturnsSourceUnchangedIfAlreadyConvertedToCompositeType() {
+               $source = new \TYPO3\CMS\Extbase\Persistence\ObjectStorage();
+               $targetType = 'TYPO3\CMS\Extbase\Persistence\ObjectStorage<SomeEntity>';
                $propertyPath = '';
                $propertyPath = '';
-               $propertyMapper = new \TYPO3\CMS\Extbase\Property\PropertyMapper();
-               $this->assertSame($source, $propertyMapper->convert($source, $targetType, $this->mockConfiguration, $propertyPath));
+               $propertyMapper = $this->getAccessibleMock('TYPO3\CMS\Extbase\Property\PropertyMapper', array('dummy'));
+               $this->assertSame($source, $propertyMapper->_callRef('doMapping', $source, $targetType, $this->mockConfiguration, $propertyPath));
        }
 
        }
 
+       /**
+        * @test
+        */
+       public function convertSkipsPropertiesIfConfiguredTo() {
+               $source = array('firstProperty' => 1, 'secondProperty' => 2);
+               $typeConverters = array(
+                       'array' => array(
+                               'stdClass' => array(10 => $this->getMockTypeConverter('array2object', TRUE, $source, 'integer'))
+                       ),
+                       'integer' => array(
+                               'integer' => array(10 => $this->getMockTypeConverter('integer2integer'))
+                       )
+               );
+               $configuration = new \TYPO3\CMS\Extbase\Property\PropertyMappingConfiguration();
+
+               $propertyMapper = $this->getAccessibleMock('TYPO3\CMS\Extbase\Property\PropertyMapper', array('dummy'));
+               $propertyMapper->_set('typeConverters', $typeConverters);
+
+               $propertyMapper->convert($source, 'stdClass', $configuration->allowProperties('firstProperty')->skipProperties('secondProperty'));
+       }
+
+       /**
+        * @test
+        */
+       public function convertSkipsUnknownPropertiesIfConfiguredTo() {
+               $source = array('firstProperty' => 1, 'secondProperty' => 2);
+               $typeConverters = array(
+                       'array' => array(
+                               'stdClass' => array(10 => $this->getMockTypeConverter('array2object', TRUE, $source, 'integer'))
+                       ),
+                       'integer' => array(
+                               'integer' => array(10 => $this->getMockTypeConverter('integer2integer'))
+                       )
+               );
+               $configuration = new \TYPO3\CMS\Extbase\Property\PropertyMappingConfiguration();
+
+               $propertyMapper = $this->getAccessibleMock('TYPO3\CMS\Extbase\Property\PropertyMapper', array('dummy'));
+               $propertyMapper->_set('typeConverters', $typeConverters);
+
+               $propertyMapper->convert($source, 'stdClass', $configuration->allowProperties('firstProperty')->skipUnknownProperties());
+       }
 }
 
 ?>
\ No newline at end of file
 }
 
 ?>
\ No newline at end of file
index b9aab11..63437ca 100644 (file)
@@ -20,10 +20,12 @@ namespace TYPO3\CMS\Extbase\Tests\Unit\Property;
  *                                                                        *
  * The TYPO3 project - inspiring people to share!                         *
  *                                                                        */
  *                                                                        *
  * The TYPO3 project - inspiring people to share!                         *
  *                                                                        */
+
+require_once (__DIR__ . '/../../Fixture/ClassWithSetters.php');
+
 /**
  * Testcase for the Property Mapper
  *
 /**
  * Testcase for the Property Mapper
  *
- * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
  * @covers \TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationBuilder
  */
 class PropertyMappingConfigurationBuilderTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
  * @covers \TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationBuilder
  */
 class PropertyMappingConfigurationBuilderTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
@@ -39,12 +41,12 @@ class PropertyMappingConfigurationBuilderTest extends \TYPO3\CMS\Extbase\Tests\U
 
        /**
         * @test
 
        /**
         * @test
-        * @author Sebastian Kurfürst <sebastian@typo3.org>
         */
        public function getTargetPropertyNameShouldReturnTheUnmodifiedPropertyNameWithoutConfiguration() {
                $defaultConfiguration = $this->propertyMappingConfigurationBuilder->build();
                $this->assertTrue($defaultConfiguration->getConfigurationValue('TYPO3\\CMS\\Extbase\\Property\\TypeConverter\\PersistentObjectConverter', \TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED));
                $this->assertTrue($defaultConfiguration->getConfigurationValue('TYPO3\\CMS\\Extbase\\Property\\TypeConverter\\PersistentObjectConverter', \TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_MODIFICATION_ALLOWED));
         */
        public function getTargetPropertyNameShouldReturnTheUnmodifiedPropertyNameWithoutConfiguration() {
                $defaultConfiguration = $this->propertyMappingConfigurationBuilder->build();
                $this->assertTrue($defaultConfiguration->getConfigurationValue('TYPO3\\CMS\\Extbase\\Property\\TypeConverter\\PersistentObjectConverter', \TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED));
                $this->assertTrue($defaultConfiguration->getConfigurationValue('TYPO3\\CMS\\Extbase\\Property\\TypeConverter\\PersistentObjectConverter', \TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_MODIFICATION_ALLOWED));
+
                $this->assertNull($defaultConfiguration->getConfigurationFor('foo')->getConfigurationValue('TYPO3\\CMS\\Extbase\\Property\\TypeConverter\\PersistentObjectConverter', \TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED));
                $this->assertNull($defaultConfiguration->getConfigurationFor('foo')->getConfigurationValue('TYPO3\\CMS\\Extbase\\Property\\TypeConverter\\PersistentObjectConverter', \TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_MODIFICATION_ALLOWED));
        }
                $this->assertNull($defaultConfiguration->getConfigurationFor('foo')->getConfigurationValue('TYPO3\\CMS\\Extbase\\Property\\TypeConverter\\PersistentObjectConverter', \TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED));
                $this->assertNull($defaultConfiguration->getConfigurationFor('foo')->getConfigurationValue('TYPO3\\CMS\\Extbase\\Property\\TypeConverter\\PersistentObjectConverter', \TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_MODIFICATION_ALLOWED));
        }
index c225add..d614c9c 100644 (file)
@@ -20,6 +20,9 @@ namespace TYPO3\CMS\Extbase\Tests\Unit\Property;
  *                                                                        *
  * The TYPO3 project - inspiring people to share!                         *
  *                                                                        */
  *                                                                        *
  * The TYPO3 project - inspiring people to share!                         *
  *                                                                        */
+
+require_once (__DIR__ . '/../../Fixture/ClassWithSetters.php');
+
 /**
  * Testcase for the Property Mapper
  *
 /**
  * Testcase for the Property Mapper
  *
@@ -32,6 +35,9 @@ class PropertyMappingConfigurationTest extends \TYPO3\CMS\Extbase\Tests\Unit\Bas
         */
        protected $propertyMappingConfiguration;
 
         */
        protected $propertyMappingConfiguration;
 
+       /**
+        * Initialization
+        */
        public function setUp() {
                $this->propertyMappingConfiguration = new \TYPO3\CMS\Extbase\Property\PropertyMappingConfiguration();
        }
        public function setUp() {
                $this->propertyMappingConfiguration = new \TYPO3\CMS\Extbase\Property\PropertyMappingConfiguration();
        }
@@ -82,48 +88,44 @@ class PropertyMappingConfigurationTest extends \TYPO3\CMS\Extbase\Tests\Unit\Bas
                $this->propertyMappingConfiguration->allowAllPropertiesExcept('someSourceProperty', 'someOtherProperty');
                $this->assertFalse($this->propertyMappingConfiguration->shouldMap('someSourceProperty'));
                $this->assertFalse($this->propertyMappingConfiguration->shouldMap('someOtherProperty'));
                $this->propertyMappingConfiguration->allowAllPropertiesExcept('someSourceProperty', 'someOtherProperty');
                $this->assertFalse($this->propertyMappingConfiguration->shouldMap('someSourceProperty'));
                $this->assertFalse($this->propertyMappingConfiguration->shouldMap('someOtherProperty'));
+
                $this->assertTrue($this->propertyMappingConfiguration->shouldMap('someOtherPropertyWhichHasNotBeenConfigured'));
        }
 
        /**
                $this->assertTrue($this->propertyMappingConfiguration->shouldMap('someOtherPropertyWhichHasNotBeenConfigured'));
        }
 
        /**
-        * DataProvider for typeConfiguration tests
-        * @return array
+        * @test
+        * @covers \TYPO3\CMS\Extbase\Property\PropertyMappingConfiguration::shouldSkip
         */
         */
-       public function provideTypeConverterSettings () {
-               return array(
-                       // kept for historical reasons, this test was the initial one
-                       'dummy data' => array(
-                               'someConverter',
-                               'someConverter',
-                               array('k1' => 'v1', 'k2' => 'v2')
-                       ),
-                       'typeConverterName oldschool' => array(
-                               'Tx_Extbase_Property_TypeConverter_DateTimeConverter',
-                               'TYPO3\\CMS\\Extbase\\Property\\TypeConverter\\DateTimeConverter',
-                               array('k1' => 'v1', 'k2' => 'v2')
-                       ),
-                       'typeConverterName namespaced' => array(
-                               'TYPO3\\CMS\\Extbase\\Property\\TypeConverter\\DateTimeConverter',
-                               'TYPO3\\CMS\\Extbase\\Property\\TypeConverter\\DateTimeConverter',
-                               array('k1' => 'v1', 'k2' => 'v2')
-                       )
-               );
+       public function shouldSkipReturnsFalseByDefault() {
+               $this->assertFalse($this->propertyMappingConfiguration->shouldSkip('someSourceProperty'));
+               $this->assertFalse($this->propertyMappingConfiguration->shouldSkip('someOtherSourceProperty'));
+       }
+
+       /**
+        * @test
+        * @covers \TYPO3\CMS\Extbase\Property\PropertyMappingConfiguration::shouldSkip
+        */
+       public function shouldSkipReturnsTrueIfConfigured() {
+               $this->propertyMappingConfiguration->skipProperties('someSourceProperty', 'someOtherSourceProperty');
+               $this->assertTrue($this->propertyMappingConfiguration->shouldSkip('someSourceProperty'));
+               $this->assertTrue($this->propertyMappingConfiguration->shouldSkip('someOtherSourceProperty'));
        }
 
        /**
        }
 
        /**
-        * @dataProvider provideTypeConverterSettings
         * @test
         */
         * @test
         */
-       public function setTypeConverterOptionsCanBeRetrievedAgain($converterName, $converterClass, $values) {
-               $this->propertyMappingConfiguration->setTypeConverterOptions($converterName, $values);
-               $this->assertEquals($values['k1'], $this->propertyMappingConfiguration->getConfigurationValue($converterClass, 'k1'));
-               $this->assertEquals($values['k2'], $this->propertyMappingConfiguration->getConfigurationValue($converterClass, 'k2'));
+       public function setTypeConverterOptionsCanBeRetrievedAgain() {
+               $mockTypeConverterClass = $this->getMockClass('TYPO3\CMS\Extbase\Property\TypeConverterInterface');
+
+               $this->propertyMappingConfiguration->setTypeConverterOptions($mockTypeConverterClass, array('k1' => 'v1', 'k2' => 'v2'));
+               $this->assertEquals('v1', $this->propertyMappingConfiguration->getConfigurationValue($mockTypeConverterClass, 'k1'));
+               $this->assertEquals('v2', $this->propertyMappingConfiguration->getConfigurationValue($mockTypeConverterClass, 'k2'));
        }
 
        /**
         * @test
         */
        }
 
        /**
         * @test
         */
-       public function inexistentTypeConverterOptionsReturnNull() {
+       public function nonexistentTypeConverterOptionsReturnNull() {
                $this->assertNull($this->propertyMappingConfiguration->getConfigurationValue('foo', 'bar'));
        }
 
                $this->assertNull($this->propertyMappingConfiguration->getConfigurationValue('foo', 'bar'));
        }
 
@@ -131,20 +133,24 @@ class PropertyMappingConfigurationTest extends \TYPO3\CMS\Extbase\Tests\Unit\Bas
         * @test
         */
        public function setTypeConverterOptionsShouldOverrideAlreadySetOptions() {
         * @test
         */
        public function setTypeConverterOptionsShouldOverrideAlreadySetOptions() {
-               $this->propertyMappingConfiguration->setTypeConverterOptions('someConverter', array('k1' => 'v1', 'k2' => 'v2'));
-               $this->propertyMappingConfiguration->setTypeConverterOptions('someConverter', array('k3' => 'v3'));
-               $this->assertEquals('v3', $this->propertyMappingConfiguration->getConfigurationValue('someConverter', 'k3'));
-               $this->assertNull($this->propertyMappingConfiguration->getConfigurationValue('someConverter', 'k2'));
+               $mockTypeConverterClass = $this->getMockClass('TYPO3\CMS\Extbase\Property\TypeConverterInterface');
+               $this->propertyMappingConfiguration->setTypeConverterOptions($mockTypeConverterClass, array('k1' => 'v1', 'k2' => 'v2'));
+               $this->propertyMappingConfiguration->setTypeConverterOptions($mockTypeConverterClass, array('k3' => 'v3'));
+
+               $this->assertEquals('v3', $this->propertyMappingConfiguration->getConfigurationValue($mockTypeConverterClass, 'k3'));
+               $this->assertNull($this->propertyMappingConfiguration->getConfigurationValue($mockTypeConverterClass, 'k2'));
        }
 
        /**
         * @test
         */
        public function setTypeConverterOptionShouldOverrideAlreadySetOptions() {
        }
 
        /**
         * @test
         */
        public function setTypeConverterOptionShouldOverrideAlreadySetOptions() {
-               $this->propertyMappingConfiguration->setTypeConverterOptions('someConverter', array('k1' => 'v1', 'k2' => 'v2'));
-               $this->propertyMappingConfiguration->setTypeConverterOption('someConverter', 'k1', 'v3');
-               $this->assertEquals('v3', $this->propertyMappingConfiguration->getConfigurationValue('someConverter', 'k1'));
-               $this->assertEquals('v2', $this->propertyMappingConfiguration->getConfigurationValue('someConverter', 'k2'));
+               $mockTypeConverterClass = $this->getMockClass('TYPO3\CMS\Extbase\Property\TypeConverterInterface');
+               $this->propertyMappingConfiguration->setTypeConverterOptions($mockTypeConverterClass, array('k1' => 'v1', 'k2' => 'v2'));
+               $this->propertyMappingConfiguration->setTypeConverterOption($mockTypeConverterClass, 'k1', 'v3');
+
+               $this->assertEquals('v3', $this->propertyMappingConfiguration->getConfigurationValue($mockTypeConverterClass, 'k1'));
+               $this->assertEquals('v2', $this->propertyMappingConfiguration->getConfigurationValue($mockTypeConverterClass, 'k2'));
        }
 
        /**
        }
 
        /**
@@ -169,6 +175,7 @@ class PropertyMappingConfigurationTest extends \TYPO3\CMS\Extbase\Tests\Unit\Bas
        protected function buildChildConfigurationForSingleProperty() {
                $childConfiguration = $this->propertyMappingConfiguration->forProperty('key1.key2');
                $childConfiguration->setTypeConverterOption('someConverter', 'foo', 'specialChildConverter');
        protected function buildChildConfigurationForSingleProperty() {
                $childConfiguration = $this->propertyMappingConfiguration->forProperty('key1.key2');
                $childConfiguration->setTypeConverterOption('someConverter', 'foo', 'specialChildConverter');
+
                return $childConfiguration;
        }
 
                return $childConfiguration;
        }
 
@@ -182,13 +189,62 @@ class PropertyMappingConfigurationTest extends \TYPO3\CMS\Extbase\Tests\Unit\Bas
        }
 
        /**
        }
 
        /**
+        * @return array Signature: $methodToTestForFluentInterface [, $argumentsForMethod = array() ]
+        */
+       public function fluentInterfaceMethodsDataProvider() {
+               $mockTypeConverterClass = $this->getMockClass('TYPO3\CMS\Extbase\Property\TypeConverterInterface');
+
+               return array(
+                       array('allowAllProperties'),
+                       array('allowProperties'),
+                       array('allowAllPropertiesExcept'),
+                       array('setMapping', array('k1', 'k1a')),
+                       array('setTypeConverterOptions', array($mockTypeConverterClass, array('k1' => 'v1', 'k2' => 'v2'))),
+                       array('setTypeConverterOption', array($mockTypeConverterClass, 'k1', 'v3')),
+                       array('setTypeConverter', array($this->getMock('TYPO3\CMS\Extbase\Property\TypeConverterInterface'))),
+               );
+       }
+
+       /**
+        * @test
+        * @dataProvider fluentInterfaceMethodsDataProvider
+        */
+       public function respectiveMethodsProvideFluentInterface($methodToTestForFluentInterface, array $argumentsForMethod = array()) {
+               $actualResult = call_user_func_array(array($this->propertyMappingConfiguration, $methodToTestForFluentInterface), $argumentsForMethod);
+               $this->assertSame($this->propertyMappingConfiguration, $actualResult);
+       }
+
+       /**
+        * @test
+        */
+       public function forPropertyWithAsteriskAllowsArbitraryPropertyNamesWithGetConfigurationFor() {
+                       // using stdClass so that class_parents() in getTypeConvertersWithParentClasses() is happy
+               $this->propertyMappingConfiguration->forProperty('items.*')->setTypeConverterOptions('stdClass', array('k1' => 'v1'));
+
+               $configuration = $this->propertyMappingConfiguration->getConfigurationFor('items')->getConfigurationFor('6');
+               $this->assertSame('v1', $configuration->getConfigurationValue('stdClass', 'k1'));
+       }
+
+       /**
         * @test
         */
         * @test
         */
-       public function shouldMapAllowsArbitraryPropertiesWhenConfiguredWithAsterisk() {
-               $this->propertyMappingConfiguration->forProperty('items.*')->setTypeConverterOptions('someConverter', array('k1' => 'v1'));
+       public function forPropertyWithAsteriskAllowsArbitraryPropertyNamesWithForProperty() {
+                       // using stdClass so that class_parents() in getTypeConvertersWithParentClasses() is happy
+               $this->propertyMappingConfiguration->forProperty('items.*.foo')->setTypeConverterOptions('stdClass', array('k1' => 'v1'));
+
+               $configuration = $this->propertyMappingConfiguration->forProperty('items.6.foo');
+               $this->assertSame('v1', $configuration->getConfigurationValue('stdClass', 'k1'));
+       }
+
+       /**
+        * @test
+        */
+       public function forPropertyWithAsteriskAllowsArbitraryPropertyNamesWithShouldMap() {
+               $this->propertyMappingConfiguration->forProperty('items.*')->setTypeConverterOptions('stdClass', array('k1' => 'v1'));
+
                $configuration = $this->propertyMappingConfiguration->forProperty('items');
                $configuration = $this->propertyMappingConfiguration->forProperty('items');
-               $this->assertTrue($configuration->shouldMap(uniqid()));
+               $this->assertTrue($configuration->shouldMap(6));
        }
        }
-}
 
 
+}
 ?>
\ No newline at end of file
 ?>
\ No newline at end of file
index 3615a56..57d5127 100644 (file)
@@ -23,7 +23,6 @@ namespace TYPO3\CMS\Extbase\Tests\Unit\Property\TypeConverter;
 /**
  * Testcase for the Array converter
  *
 /**
  * Testcase for the Array converter
  *
- * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
  */
 class ArrayConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
 
  */
 class ArrayConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
 
@@ -38,7 +37,6 @@ class ArrayConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
 
        /**
         * @test
 
        /**
         * @test
-        * @author Bastian Waidelich <bastian@typo3.org>
         */
        public function checkMetadata() {
                $this->assertEquals(array('array'), $this->converter->getSupportedSourceTypes(), 'Source types do not match');
         */
        public function checkMetadata() {
                $this->assertEquals(array('array'), $this->converter->getSupportedSourceTypes(), 'Source types do not match');
@@ -48,12 +46,10 @@ class ArrayConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
 
        /**
         * @test
 
        /**
         * @test
-        * @author Bastian Waidelich <bastian@typo3.org>
         */
        public function convertFromDoesNotModifyTheSourceArray() {
                $sourceArray = array('Foo' => 'Bar', 'Baz');
                $this->assertEquals($sourceArray, $this->converter->convertFrom($sourceArray, 'array'));
        }
 }
         */
        public function convertFromDoesNotModifyTheSourceArray() {
                $sourceArray = array('Foo' => 'Bar', 'Baz');
                $this->assertEquals($sourceArray, $this->converter->convertFrom($sourceArray, 'array'));
        }
 }
-
 ?>
\ No newline at end of file
 ?>
\ No newline at end of file
index 8f7ceda..3aab78c 100644 (file)
@@ -23,7 +23,6 @@ namespace TYPO3\CMS\Extbase\Tests\Unit\Property\TypeConverter;
 /**
  * Testcase for the Boolean converter
  *
 /**
  * Testcase for the Boolean converter
  *
- * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
  */
 class BooleanConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
 
  */
 class BooleanConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
 
@@ -38,7 +37,6 @@ class BooleanConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
 
        /**
         * @test
 
        /**
         * @test
-        * @author Bastian Waidelich <bastian@typo3.org>
         */
        public function checkMetadata() {
                $this->assertEquals(array('boolean', 'string'), $this->converter->getSupportedSourceTypes(), 'Source types do not match');
         */
        public function checkMetadata() {
                $this->assertEquals(array('boolean', 'string'), $this->converter->getSupportedSourceTypes(), 'Source types do not match');
@@ -48,7 +46,6 @@ class BooleanConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
 
        /**
         * @test
 
        /**
         * @test
-        * @author Bastian Waidelich <bastian@typo3.org>
         */
        public function convertFromDoesNotModifyTheBooleanSource() {
                $source = TRUE;
         */
        public function convertFromDoesNotModifyTheBooleanSource() {
                $source = TRUE;
@@ -57,7 +54,6 @@ class BooleanConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
 
        /**
         * @test
 
        /**
         * @test
-        * @author Bastian Waidelich <bastian@typo3.org>
         */
        public function convertFromCastsSourceStringToBoolean() {
                $source = 'true';
         */
        public function convertFromCastsSourceStringToBoolean() {
                $source = 'true';
@@ -66,12 +62,10 @@ class BooleanConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
 
        /**
         * @test
 
        /**
         * @test
-        * @author Bastian Waidelich <bastian@typo3.org>
         */
        public function convertFromCastsNumericSourceStringToBoolean() {
                $source = '1';
                $this->assertSame(TRUE, $this->converter->convertFrom($source, 'boolean'));
        }
 }
         */
        public function convertFromCastsNumericSourceStringToBoolean() {
                $source = '1';
                $this->assertSame(TRUE, $this->converter->convertFrom($source, 'boolean'));
        }
 }
-
 ?>
\ No newline at end of file
 ?>
\ No newline at end of file
index fdf836e..b728d3b 100644 (file)
@@ -23,7 +23,6 @@ namespace TYPO3\CMS\Extbase\Tests\Unit\Property\TypeConverter;
 /**
  * Testcase for the DateTime converter
  *
 /**
  * Testcase for the DateTime converter
  *
- * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
  * @covers \TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter<extended>
  */
 class DateTimeConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
  * @covers \TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter<extended>
  */
 class DateTimeConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
@@ -39,7 +38,6 @@ class DateTimeConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
 
        /**
         * @test
 
        /**
         * @test
-        * @author Bastian Waidelich <bastian@typo3.org>
         */
        public function checkMetadata() {
                $this->assertEquals(array('string', 'integer', 'array'), $this->converter->getSupportedSourceTypes(), 'Source types do not match');
         */
        public function checkMetadata() {
                $this->assertEquals(array('string', 'integer', 'array'), $this->converter->getSupportedSourceTypes(), 'Source types do not match');
@@ -47,12 +45,11 @@ class DateTimeConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
                $this->assertEquals(1, $this->converter->getPriority(), 'Priority does not match');
        }
 
                $this->assertEquals(1, $this->converter->getPriority(), 'Priority does not match');
        }
 
-       /**
-        * String to DateTime testcases  *
-        */
+
+       /** String to DateTime testcases  **/
+
        /**
         * @test
        /**
         * @test
-        * @author Bastian Waidelich <bastian@typo3.org>
         */
        public function canConvertFromReturnsFalseIfTargetTypeIsNotDateTime() {
                $this->assertFalse($this->converter->canConvertFrom('Foo', 'SomeOtherType'));
         */
        public function canConvertFromReturnsFalseIfTargetTypeIsNotDateTime() {
                $this->assertFalse($this->converter->canConvertFrom('Foo', 'SomeOtherType'));
@@ -60,7 +57,6 @@ class DateTimeConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
 
        /**
         * @test
 
        /**
         * @test
-        * @author Bastian Waidelich <bastian@typo3.org>
         */
        public function canConvertFromReturnsTrueIfSourceTypeIsAString() {
                $this->assertTrue($this->converter->canConvertFrom('Foo', 'DateTime'));
         */
        public function canConvertFromReturnsTrueIfSourceTypeIsAString() {
                $this->assertTrue($this->converter->canConvertFrom('Foo', 'DateTime'));
@@ -68,7 +64,6 @@ class DateTimeConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
 
        /**
         * @test
 
        /**
         * @test
-        * @author Bastian Waidelich <bastian@typo3.org>
         */
        public function canConvertFromReturnsTrueIfSourceTypeIsAnEmptyString() {
                $this->assertTrue($this->converter->canConvertFrom('', 'DateTime'));
         */
        public function canConvertFromReturnsTrueIfSourceTypeIsAnEmptyString() {
                $this->assertTrue($this->converter->canConvertFrom('', 'DateTime'));
@@ -76,7 +71,6 @@ class DateTimeConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
 
        /**
         * @test
 
        /**
         * @test
-        * @author Bastian Waidelich <bastian@typo3.org>
         */
        public function convertFromReturnsErrorIfGivenStringCantBeConverted() {
                $error = $this->converter->convertFrom('1980-12-13', 'DateTime');
         */
        public function convertFromReturnsErrorIfGivenStringCantBeConverted() {
                $error = $this->converter->convertFrom('1980-12-13', 'DateTime');
@@ -85,7 +79,6 @@ class DateTimeConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
 
        /**
         * @test
 
        /**
         * @test
-        * @author Bastian Waidelich <bastian@typo3.org>
         */
        public function convertFromProperlyConvertsStringWithDefaultDateFormat() {
                $expectedResult = '1980-12-13T20:15:07+01:23';
         */
        public function convertFromProperlyConvertsStringWithDefaultDateFormat() {
                $expectedResult = '1980-12-13T20:15:07+01:23';
@@ -96,12 +89,16 @@ class DateTimeConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
 
        /**
         * @test
 
        /**
         * @test
-        * @author Bastian Waidelich <bastian@typo3.org>
         */
        public function convertFromUsesDefaultDateFormatIfItIsNotConfigured() {
                $expectedResult = '1980-12-13T20:15:07+01:23';
         */
        public function convertFromUsesDefaultDateFormatIfItIsNotConfigured() {
                $expectedResult = '1980-12-13T20:15:07+01:23';
-               $mockMappingConfiguration = $this->getMock('TYPO3\\CMS\\Extbase\\Property\\PropertyMappingConfigurationInterface');
-               $mockMappingConfiguration->expects($this->atLeastOnce())->method('getConfigurationValue')->with('TYPO3\\CMS\\Extbase\\Property\\TypeConverter\\DateTimeConverter', \TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter::CONFIGURATION_DATE_FORMAT)->will($this->returnValue(NULL));
+               $mockMappingConfiguration = $this->getMock('TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface');
+               $mockMappingConfiguration
+                               ->expects($this->atLeastOnce())
+                               ->method('getConfigurationValue')
+                               ->with('TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter', \TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter::CONFIGURATION_DATE_FORMAT)
+                               ->will($this->returnValue(NULL));
+
                $date = $this->converter->convertFrom($expectedResult, 'DateTime', array(), $mockMappingConfiguration);
                $actualResult = $date->format(\TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter::DEFAULT_DATE_FORMAT);
                $this->assertSame($expectedResult, $actualResult);
                $date = $this->converter->convertFrom($expectedResult, 'DateTime', array(), $mockMappingConfiguration);
                $actualResult = $date->format(\TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter::DEFAULT_DATE_FORMAT);
                $this->assertSame($expectedResult, $actualResult);
@@ -118,7 +115,6 @@ class DateTimeConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
        /**
         * @return array
         * @see convertFromStringTests()
        /**
         * @return array
         * @see convertFromStringTests()
-        * @author Bastian Waidelich <bastian@typo3.org>
         */
        public function convertFromStringDataProvider() {
                return array(
         */
        public function convertFromStringDataProvider() {
                return array(
@@ -139,12 +135,15 @@ class DateTimeConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
         * @param boolean $isValid TRUE if the conversion is expected to be successful, otherwise FALSE
         * @test
         * @dataProvider convertFromStringDataProvider
         * @param boolean $isValid TRUE if the conversion is expected to be successful, otherwise FALSE
         * @test
         * @dataProvider convertFromStringDataProvider
-        * @author Bastian Waidelich <bastian@typo3.org>
         */
        public function convertFromStringTests($source, $dateFormat, $isValid) {
                if ($dateFormat !== NULL) {
         */
        public function convertFromStringTests($source, $dateFormat, $isValid) {
                if ($dateFormat !== NULL) {
-                       $mockMappingConfiguration = $this->getMock('TYPO3\\CMS\\Extbase\\Property\\PropertyMappingConfigurationInterface');
-                       $mockMappingConfiguration->expects($this->atLeastOnce())->method('getConfigurationValue')->with('TYPO3\\CMS\\Extbase\\Property\\TypeConverter\\DateTimeConverter', \TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter::CONFIGURATION_DATE_FORMAT)->will($this->returnValue($dateFormat));
+                       $mockMappingConfiguration = $this->getMock('TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface');
+                       $mockMappingConfiguration
+                                       ->expects($this->atLeastOnce())
+                                       ->method('getConfigurationValue')
+                                       ->with('TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter', \TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter::CONFIGURATION_DATE_FORMAT)
+                                       ->will($this->returnValue($dateFormat));
                } else {
                        $mockMappingConfiguration = NULL;
                }
                } else {
                        $mockMappingConfiguration = NULL;
                }
@@ -154,6 +153,7 @@ class DateTimeConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
                        return;
                }
                $this->assertInstanceOf('DateTime', $date);
                        return;
                }
                $this->assertInstanceOf('DateTime', $date);
+
                if ($dateFormat === NULL) {
                        $dateFormat = \TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter::DEFAULT_DATE_FORMAT;
                }
                if ($dateFormat === NULL) {
                        $dateFormat = \TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter::DEFAULT_DATE_FORMAT;
                }
@@ -184,9 +184,7 @@ class DateTimeConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
 
        }
 
 
        }
 
-       /**
-        * Array to DateTime testcases  *
-        */
+       /** Array to DateTime testcases  **/
 
        /**
         * @test
 
        /**
         * @test
@@ -202,7 +200,6 @@ class DateTimeConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
 
        /**
         * @test
 
        /**
         * @test
-        * @author Bastian Waidelich <bastian@typo3.org>
         */
        public function canConvertFromReturnsTrueIfSourceTypeIsAnArray() {
                $this->assertTrue($this->converter->canConvertFrom(array(), 'DateTime'));
         */
        public function canConvertFromReturnsTrueIfSourceTypeIsAnArray() {
                $this->assertTrue($this->converter->canConvertFrom(array(), 'DateTime'));
@@ -210,7 +207,6 @@ class DateTimeConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
 
        /**
         * @test
 
        /**
         * @test
-        * @author Bastian Waidelich <bastian@typo3.org>
         */
        public function convertFromReturnsErrorIfGivenArrayCantBeConverted() {
                $error = $this->converter->convertFrom(array('date' => '1980-12-13'), 'DateTime');
         */
        public function convertFromReturnsErrorIfGivenArrayCantBeConverted() {
                $error = $this->converter->convertFrom(array('date' => '1980-12-13'), 'DateTime');
@@ -220,7 +216,6 @@ class DateTimeConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
        /**
         * @test
         * @expectedException \TYPO3\CMS\Extbase\Property\Exception\TypeConverterException
        /**
         * @test
         * @expectedException \TYPO3\CMS\Extbase\Property\Exception\TypeConverterException
-        * @author Bastian Waidelich <bastian@typo3.org>
         */
        public function convertFromThrowsExceptionIfGivenArrayDoesNotSpecifyTheDate() {
                $this->converter->convertFrom(array('hour' => '12', 'minute' => '30'), 'DateTime');
         */
        public function convertFromThrowsExceptionIfGivenArrayDoesNotSpecifyTheDate() {
                $this->converter->convertFrom(array('hour' => '12', 'minute' => '30'), 'DateTime');
@@ -228,7 +223,6 @@ class DateTimeConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
 
        /**
         * @test
 
        /**
         * @test
-        * @author Bastian Waidelich <bastian@typo3.org>
         */
        public function convertFromProperlyConvertsArrayWithDefaultDateFormat() {
                $expectedResult = '1980-12-13T20:15:07+01:23';
         */
        public function convertFromProperlyConvertsArrayWithDefaultDateFormat() {
                $expectedResult = '1980-12-13T20:15:07+01:23';
@@ -263,7 +257,23 @@ class DateTimeConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
 
        /**
         * @test
 
        /**
         * @test
-        * @author Bastian Waidelich <bastian@typo3.org>
+        */
+       public function convertFromProperlyConvertsArrayWithDateAsArray() {
+               $source = array('day' => '13', 'month' => '10', 'year' => '2010');
+               $mappingConfiguration = new \TYPO3\CMS\Extbase\Property\PropertyMappingConfiguration();
+               $mappingConfiguration->setTypeConverterOption(
+                               'TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter',
+                               \TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter::CONFIGURATION_DATE_FORMAT,
+                               'Y-m-d'
+               );
+
+               $date = $this->converter->convertFrom($source, 'DateTime', array(), $mappingConfiguration);
+               $actualResult = $date->format('Y-m-d');
+               $this->assertSame('2010-10-13', $actualResult);
+       }
+
+       /**
+        * @test
         */
        public function convertFromAllowsToOverrideTheTime() {
                $source = array(
         */
        public function convertFromAllowsToOverrideTheTime() {
                $source = array(
@@ -271,7 +281,7 @@ class DateTimeConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
                        'dateFormat' => 'Y-m-d',
                        'hour' => '12',
                        'minute' => '30',
                        'dateFormat' => 'Y-m-d',
                        'hour' => '12',
                        'minute' => '30',
-                       'second' => '59'
+                       'second' => '59',
                );
                $date = $this->converter->convertFrom($source, 'DateTime');
                $this->assertSame('2011-06-16', $date->format('Y-m-d'));
                );
                $date = $this->converter->convertFrom($source, 'DateTime');
                $this->assertSame('2011-06-16', $date->format('Y-m-d'));
@@ -282,13 +292,12 @@ class DateTimeConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
 
        /**
         * @test
 
        /**
         * @test
-        * @author Bastian Waidelich <bastian@typo3.org>
         */
        public function convertFromAllowsToOverrideTheTimezone() {
                $source = array(
                        'date' => '2011-06-16 12:30:59',
                        'dateFormat' => 'Y-m-d H:i:s',
         */
        public function convertFromAllowsToOverrideTheTimezone() {
                $source = array(
                        'date' => '2011-06-16 12:30:59',
                        'dateFormat' => 'Y-m-d H:i:s',
-                       'timezone' => 'Atlantic/Reykjavik'
+                       'timezone' => 'Atlantic/Reykjavik',
                );
                $date = $this->converter->convertFrom($source, 'DateTime');
                $this->assertSame('2011-06-16', $date->format('Y-m-d'));
                );
                $date = $this->converter->convertFrom($source, 'DateTime');
                $this->assertSame('2011-06-16', $date->format('Y-m-d'));
@@ -301,13 +310,12 @@ class DateTimeConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
        /**
         * @test
         * @expectedException \TYPO3\CMS\Extbase\Property\Exception\TypeConverterException
        /**
         * @test
         * @expectedException \TYPO3\CMS\Extbase\Property\Exception\TypeConverterException
-        * @author Bastian Waidelich <bastian@typo3.org>
         */
        public function convertFromThrowsExceptionIfSpecifiedTimezoneIsInvalid() {
                $source = array(
                        'date' => '2011-06-16',
                        'dateFormat' => 'Y-m-d',
         */
        public function convertFromThrowsExceptionIfSpecifiedTimezoneIsInvalid() {
                $source = array(
                        'date' => '2011-06-16',
                        'dateFormat' => 'Y-m-d',
-                       'timezone' => 'Invalid/Timezone'
+                       'timezone' => 'Invalid/Timezone',
                );
                $this->converter->convertFrom($source, 'DateTime');
        }
                );
                $this->converter->convertFrom($source, 'DateTime');
        }
@@ -315,7 +323,6 @@ class DateTimeConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
        /**
         * @test
         * @expectedException \TYPO3\CMS\Extbase\Property\Exception\TypeConverterException
        /**
         * @test
         * @expectedException \TYPO3\CMS\Extbase\Property\Exception\TypeConverterException
-        * @author Sebastian Kurfürst <sebastian@typo3.org>
         */
        public function convertFromArrayThrowsExceptionForEmptyArray() {
                $this->converter->convertFrom(array(), 'DateTime', array(), NULL);
         */
        public function convertFromArrayThrowsExceptionForEmptyArray() {
                $this->converter->convertFrom(array(), 'DateTime', array(), NULL);
@@ -323,7 +330,6 @@ class DateTimeConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
 
        /**
         * @test
 
        /**
         * @test
-        * @author Sebastian Kurfürst <sebastian@typo3.org>
         */
        public function convertFromArrayReturnsNullForEmptyDate() {
                $this->assertNull($this->converter->convertFrom(array('date' => ''), 'DateTime', array(), NULL));
         */
        public function convertFromArrayReturnsNullForEmptyDate() {
                $this->assertNull($this->converter->convertFrom(array('date' => ''), 'DateTime', array(), NULL));
@@ -332,7 +338,6 @@ class DateTimeConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
        /**
         * @return array
         * @see convertFromArrayTests()
        /**
         * @return array
         * @see convertFromArrayTests()
-        * @author Bastian Waidelich <bastian@typo3.org>
         */
        public function convertFromArrayDataProvider() {
                return array(
         */
        public function convertFromArrayDataProvider() {
                return array(
@@ -354,28 +359,52 @@ class DateTimeConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
         * @param boolean $isValid TRUE if the conversion is expected to be successful, otherwise FALSE
         * @test
         * @dataProvider convertFromArrayDataProvider
         * @param boolean $isValid TRUE if the conversion is expected to be successful, otherwise FALSE
         * @test
         * @dataProvider convertFromArrayDataProvider
-        * @author Bastian Waidelich <bastian@typo3.org>
         */
        public function convertFromArrayTests(array $source, $isValid) {
                $dateFormat = isset($source['dateFormat']) && strlen($source['dateFormat']) > 0 ? $source['dateFormat'] : NULL;
                if ($dateFormat !== NULL) {
         */
        public function convertFromArrayTests(array $source, $isValid) {
                $dateFormat = isset($source['dateFormat']) && strlen($source['dateFormat']) > 0 ? $source['dateFormat'] : NULL;
                if ($dateFormat !== NULL) {
-                       $mockMappingConfiguration = $this->getMock('TYPO3\\CMS\\Extbase\\Property\\PropertyMappingConfigurationInterface');
-                       $mockMappingConfiguration->expects($this->atLeastOnce())->method('getConfigurationValue')->with('TYPO3\\CMS\\Extbase\\Property\\TypeConverter\\DateTimeConverter', \TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter::CONFIGURATION_DATE_FORMAT)->will($this->returnValue($dateFormat));
+                       $mockMappingConfiguration = $this->getMock('TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface');
+                       $mockMappingConfiguration
+                                       ->expects($this->atLeastOnce())
+                                       ->method('getConfigurationValue')
+                                       ->with('TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter', \TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter::CONFIGURATION_DATE_FORMAT)
+                                       ->will($this->returnValue($dateFormat));
                } else {
                        $mockMappingConfiguration = NULL;
                }
                $date = $this->converter->convertFrom($source, 'DateTime', array(), $mockMappingConfiguration);
                } else {
                        $mockMappingConfiguration = NULL;
                }
                $date = $this->converter->convertFrom($source, 'DateTime', array(), $mockMappingConfiguration);
+
                if ($isValid !== TRUE) {
                        $this->assertInstanceOf('TYPO3\\CMS\\Extbase\\Error\\Error', $date);
                        return;
                }
                if ($isValid !== TRUE) {
                        $this->assertInstanceOf('TYPO3\\CMS\\Extbase\\Error\\Error', $date);
                        return;
                }
+
                $this->assertInstanceOf('DateTime', $date);
                if ($dateFormat === NULL) {
                        $dateFormat = \TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter::DEFAULT_DATE_FORMAT;
                }
                $this->assertInstanceOf('DateTime', $date);
                if ($dateFormat === NULL) {
                        $dateFormat = \TYPO3\CMS\Extbase\Property\TypeConverter\DateTimeConverter::DEFAULT_DATE_FORMAT;
                }
-               $dateAsString = isset($source['date']) ? $source['date'] : '';
-               $this->assertSame(strval($dateAsString), $date->format($dateFormat));
+               $dateAsString = isset($source['date']) ? strval($source['date']) : '';
+               $this->assertSame($dateAsString, $date->format($dateFormat));
        }
        }
-}
 
 
+       /**
+        * @test
+        */
+       public function convertFromSupportsDateTimeSubClasses() {
+               $className = 'DateTimeSubClass' . md5(uniqid(mt_rand(), TRUE));
+               eval('
+                       class ' . $className . ' extends \\DateTime {
+                               public static function createFromFormat($format, $time, $timezone = NULL) {
+                                       return new ' . $className . '();
+                               }
+                               public function foo() { return "Bar"; }
+                       }
+               ');
+               $date = $this->converter->convertFrom('2005-08-15T15:52:01+00:00', $className);
+
+               $this->assertInstanceOf($className, $date);
+               $this->assertSame('Bar', $date->foo());
+       }
+
+}
 ?>
\ No newline at end of file
 ?>
\ No newline at end of file
index 7ab3f28..086bf57 100644 (file)
@@ -23,7 +23,6 @@ namespace TYPO3\CMS\Extbase\Tests\Unit\Property\TypeConverter;
 /**
  * Testcase for the Float converter
  *
 /**
  * Testcase for the Float converter
  *
- * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
  * @covers \TYPO3\CMS\Extbase\Property\TypeConverter\FloatConverter<extended>
  */
 class FloatConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
  * @covers \TYPO3\CMS\Extbase\Property\TypeConverter\FloatConverter<extended>
  */
 class FloatConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
@@ -39,17 +38,15 @@ class FloatConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
 
        /**
         * @test
 
        /**
         * @test
-        * @author Sebastian Kurfürst <sebastian@typo3.org>
         */
        public function checkMetadata() {
         */
        public function checkMetadata() {
-               $this->assertEquals(array('string'), $this->converter->getSupportedSourceTypes(), 'Source types do not match');
+               $this->assertEquals(array('float', 'integer', 'string'), $this->converter->getSupportedSourceTypes(), 'Source types do not match');
                $this->assertEquals('float', $this->converter->getSupportedTargetType(), 'Target type does not match');
                $this->assertEquals(1, $this->converter->getPriority(), 'Priority does not match');
        }
 
        /**
         * @test
                $this->assertEquals('float', $this->converter->getSupportedTargetType(), 'Target type does not match');
                $this->assertEquals(1, $this->converter->getPriority(), 'Priority does not match');
        }
 
        /**
         * @test
-        * @author Sebastian Kurfürst <sebastian@typo3.org>
         */
        public function convertFromShouldCastTheStringToFloat() {
                $this->assertSame(1.5, $this->converter->convertFrom('1.5', 'float'));
         */
        public function convertFromShouldCastTheStringToFloat() {
                $this->assertSame(1.5, $this->converter->convertFrom('1.5', 'float'));
@@ -57,7 +54,27 @@ class FloatConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
 
        /**
         * @test
 
        /**
         * @test
-        * @author Sebastian Kurfürst <sebastian@typo3.org>
+        */
+       public function convertFromReturnsNullIfEmptyStringSpecified() {
+               $this->assertNull($this->converter->convertFrom('', 'float'));
+       }
+
+       /**
+        * @test
+        */
+       public function convertFromShouldAcceptIntegers() {
+               $this->assertSame((float)123, $this->converter->convertFrom(123, 'float'));
+       }
+
+       /**
+        * @test
+        */
+       public function convertFromReturnsAnErrorIfSpecifiedStringIsNotNumeric() {
+               $this->assertInstanceOf('TYPO3\CMS\Extbase\Error\Error', $this->converter->convertFrom('not numeric', 'float'));
+       }
+
+       /**
+        * @test
         */
        public function canConvertFromShouldReturnTrue() {
                $this->assertTrue($this->converter->canConvertFrom('1.5', 'float'));
         */
        public function canConvertFromShouldReturnTrue() {
                $this->assertTrue($this->converter->canConvertFrom('1.5', 'float'));
@@ -65,11 +82,23 @@ class FloatConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
 
        /**
         * @test
 
        /**
         * @test
-        * @author Sebastian Kurfürst <sebastian@typo3.org>
+        */
+       public function canConvertFromShouldReturnTrueForAnEmptyValue() {
+               $this->assertTrue($this->converter->canConvertFrom('', 'integer'));
+       }
+
+       /**
+        * @test
+        */
+       public function canConvertFromShouldReturnTrueForANullValue() {
+               $this->assertTrue($this->converter->canConvertFrom(NULL, 'integer'));
+       }
+
+       /**
+        * @test
         */
        public function getSourceChildPropertiesToBeConvertedShouldReturnEmptyArray() {
                $this->assertEquals(array(), $this->converter->getSourceChildPropertiesToBeConverted('myString'));
        }
 }
         */
        public function getSourceChildPropertiesToBeConvertedShouldReturnEmptyArray() {
                $this->assertEquals(array(), $this->converter->getSourceChildPropertiesToBeConverted('myString'));
        }
 }
-
 ?>
\ No newline at end of file
 ?>
\ No newline at end of file
index 21b80b7..b1110da 100644 (file)
@@ -23,7 +23,6 @@ namespace TYPO3\CMS\Extbase\Tests\Unit\Property\TypeConverter;
 /**
  * Testcase for the Integer converter
  *
 /**
  * Testcase for the Integer converter
  *
- * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
  * @covers \TYPO3\CMS\Extbase\Property\TypeConverter\IntegerConverter<extended>
  */
 class IntegerConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
  * @covers \TYPO3\CMS\Extbase\Property\TypeConverter\IntegerConverter<extended>
  */
 class IntegerConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
@@ -39,7 +38,6 @@ class IntegerConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
 
        /**
         * @test
 
        /**
         * @test
-        * @author Sebastian Kurfürst <sebastian@typo3.org>
         */
        public function checkMetadata() {
                $this->assertEquals(array('integer', 'string'), $this->converter->getSupportedSourceTypes(), 'Source types do not match');
         */
        public function checkMetadata() {
                $this->assertEquals(array('integer', 'string'), $this->converter->getSupportedSourceTypes(), 'Source types do not match');
@@ -49,7 +47,6 @@ class IntegerConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
 
        /**
         * @test
 
        /**
         * @test
-        * @author Sebastian Kurfürst <sebastian@typo3.org>
         */
        public function convertFromShouldCastTheStringToInteger() {
                $this->assertSame(15, $this->converter->convertFrom('15', 'integer'));
         */
        public function convertFromShouldCastTheStringToInteger() {
                $this->assertSame(15, $this->converter->convertFrom('15', 'integer'));
@@ -57,7 +54,6 @@ class IntegerConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
 
        /**
         * @test
 
        /**
         * @test
-        * @author Bastian Waidelich <bastian@typo3.org>
         */
        public function convertFromDoesNotModifyIntegers() {
                $source = 123;
         */
        public function convertFromDoesNotModifyIntegers() {
                $source = 123;
@@ -66,7 +62,20 @@ class IntegerConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
 
        /**
         * @test
 
        /**
         * @test
-        * @author Sebastian Kurfürst <sebastian@typo3.org>
+        */
+       public function convertFromReturnsNullIfEmptyStringSpecified() {
+               $this->assertNull($this->converter->convertFrom('', 'integer'));
+       }
+
+       /**
+        * @test
+        */
+       public function convertFromReturnsAnErrorIfSpecifiedStringIsNotNumeric() {
+               $this->assertInstanceOf('TYPO3\CMS\Extbase\Error\Error', $this->converter->convertFrom('not numeric', 'integer'));
+       }
+
+       /**
+        * @test
         */
        public function canConvertFromShouldReturnTrueForANumericStringSource() {
                $this->assertTrue($this->converter->canConvertFrom('15', 'integer'));
         */
        public function canConvertFromShouldReturnTrueForANumericStringSource() {
                $this->assertTrue($this->converter->canConvertFrom('15', 'integer'));
@@ -74,7 +83,6 @@ class IntegerConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
 
        /**
         * @test
 
        /**
         * @test
-        * @author Bastian Waidelich <bastian@typo3.org>
         */
        public function canConvertFromShouldReturnTrueForAnIntegerSource() {
                $this->assertTrue($this->converter->canConvertFrom(123, 'integer'));
         */
        public function canConvertFromShouldReturnTrueForAnIntegerSource() {
                $this->assertTrue($this->converter->canConvertFrom(123, 'integer'));
@@ -82,11 +90,23 @@ class IntegerConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
 
        /**
         * @test
 
        /**
         * @test
-        * @author Sebastian Kurfürst <sebastian@typo3.org>
+        */
+       public function canConvertFromShouldReturnTrueForAnEmptyValue() {
+               $this->assertTrue($this->converter->canConvertFrom('', 'integer'));
+       }
+
+       /**
+        * @test
+        */
+       public function canConvertFromShouldReturnTrueForANullValue() {
+               $this->assertTrue($this->converter->canConvertFrom(NULL, 'integer'));
+       }
+
+       /**
+        * @test
         */
        public function getSourceChildPropertiesToBeConvertedShouldReturnEmptyArray() {
                $this->assertEquals(array(), $this->converter->getSourceChildPropertiesToBeConverted('myString'));
        }
 }
         */
        public function getSourceChildPropertiesToBeConvertedShouldReturnEmptyArray() {
                $this->assertEquals(array(), $this->converter->getSourceChildPropertiesToBeConverted('myString'));
        }
 }
-
 ?>
\ No newline at end of file
 ?>
\ No newline at end of file
index cd2a095..f6095fb 100644 (file)
@@ -20,10 +20,13 @@ namespace TYPO3\CMS\Extbase\Tests\Unit\Property\TypeConverter;
  *                                                                        *
  * The TYPO3 project - inspiring people to share!                         *
  *                                                                        */
  *                                                                        *
  * The TYPO3 project - inspiring people to share!                         *
  *                                                                        */
+
+require_once (__DIR__ . '/../../../Fixture/ClassWithSetters.php');
+require_once (__DIR__ . '/../../../Fixture/ClassWithSettersAndConstructor.php');
+
 /**
 /**
- * Testcase for the String to String converter
+ * Testcase for the PersistentObjectConverter
  *
  *
- * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
  * @covers \TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter<extended>
  */
 class PersistentObjectConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
  * @covers \TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter<extended>
  */
 class PersistentObjectConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
@@ -34,24 +37,34 @@ class PersistentObjectConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTe
        protected $converter;
 
        protected $mockReflectionService;
        protected $converter;
 
        protected $mockReflectionService;
-
        protected $mockPersistenceManager;
        protected $mockPersistenceManager;
-
        protected $mockObjectManager;
 
        public function setUp() {
                $this->converter = new \TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter();
        protected $mockObjectManager;
 
        public function setUp() {
                $this->converter = new \TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter();
-               $this->mockReflectionService = $this->getMock('TYPO3\\CMS\\Extbase\\Reflection\\ReflectionService');
-               $this->converter->injectReflectionService($this->mockReflectionService);
-               $this->mockPersistenceManager = $this->getMock('TYPO3\\CMS\\Extbase\\Persistence\\PersistenceManagerInterface');
-               $this->converter->injectPersistenceManager($this->mockPersistenceManager);
-               $this->mockObjectManager = $this->getMock('TYPO3\\CMS\\Extbase\\Object\\ObjectManagerInterface');
-               $this->converter->injectObjectManager($this->mockObjectManager);
+               $this->mockReflectionService = $this->getMock('TYPO3\CMS\Extbase\Reflection\ReflectionService');
+               $this->inject($this->converter, 'reflectionService', $this->mockReflectionService);
+
+               $this->mockPersistenceManager = $this->getMock('TYPO3\CMS\Extbase\Persistence\PersistenceManagerInterface');
+               $this->inject($this->converter, 'persistenceManager', $this->mockPersistenceManager);
+
+               $this->mockObjectManager = $this->getMock('TYPO3\CMS\Extbase\Object\ObjectManagerInterface');
+               $this->mockObjectManager->expects($this->any())
+                       ->method('get')
+                       ->will($this->returnCallback(function() {
+                                       $args = func_get_args();
+                                       $reflectionClass = new \ReflectionClass(array_shift($args));
+                                       if (empty($args)) {
+                                               return $reflectionClass->newInstance();
+                                       } else {
+                                               return $reflectionClass->newInstanceArgs($args);
+                                       }
+                               }));
+               $this->inject($this->converter, 'objectManager', $this->mockObjectManager);
        }
 
        /**
         * @test
        }
 
        /**
         * @test
-        * @author Sebastian Kurfürst <sebastian@typo3.org>
         */
        public function checkMetadata() {
                $this->assertEquals(array('string', 'array'), $this->converter->getSupportedSourceTypes(), 'Source types do not match');
         */
        public function checkMetadata() {
                $this->assertEquals(array('string', 'array'), $this->converter->getSupportedSourceTypes(), 'Source types do not match');
@@ -59,26 +72,20 @@ class PersistentObjectConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTe
                $this->assertEquals(1, $this->converter->getPriority(), 'Priority does not match');
        }
 
                $this->assertEquals(1, $this->converter->getPriority(), 'Priority does not match');
        }
 
-       /**
-        * @return array
-        */
        public function dataProviderForCanConvert() {
                return array(
                        array(TRUE, FALSE, TRUE),
                        // is entity => can convert
                        array(FALSE, TRUE, TRUE),
                        // is valueobject => can convert
        public function dataProviderForCanConvert() {
                return array(
                        array(TRUE, FALSE, TRUE),
                        // is entity => can convert
                        array(FALSE, TRUE, TRUE),
                        // is valueobject => can convert
-                       array(FALSE, FALSE, FALSE)
+                       array(FALSE, FALSE, FALSE),
+                       // is no entity and no value object => can not convert
                );
        }
 
        /**
         * @test
         * @dataProvider dataProviderForCanConvert
                );
        }
 
        /**
         * @test
         * @dataProvider dataProviderForCanConvert
-        * @author Sebastian Kurfürst <sebastian@typo3.org>
-        * @param boolean $isEntity
-        * @param boolean $isValueObject
-        * @param mixed $expected
         */
        public function canConvertFromReturnsTrueIfClassIsTaggedWithEntityOrValueObject($isEntity, $isValueObject, $expected) {
                $className = uniqid('Test_Class');
         */
        public function canConvertFromReturnsTrueIfClassIsTaggedWithEntityOrValueObject($isEntity, $isValueObject, $expected) {
                $className = uniqid('Test_Class');
@@ -93,17 +100,7 @@ class PersistentObjectConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTe
        }
 
        /**
        }
 
        /**
-        * test
-        *
-        * @author Sebastian Kurfürst <sebastian@typo3.org>
-        */
-       public function getPropertyNamesReturnsEmptyArray() {
-               $this->assertEquals(array(), $this->converter->getPropertyNames('myString'));
-       }
-
-       /**
         * @test
         * @test
-        * @author Sebastian Kurfürst <sebastian@typo3.org>
         */
        public function getSourceChildPropertiesToBeConvertedReturnsAllPropertiesExceptTheIdentityProperty() {
                $source = array(
         */
        public function getSourceChildPropertiesToBeConvertedReturnsAllPropertiesExceptTheIdentityProperty() {
                $source = array(
@@ -120,11 +117,11 @@ class PersistentObjectConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTe
 
        /**
         * @test
 
        /**
         * @test
-        * @author Sebastian Kurfürst <sebastian@typo3.org>
         */
        public function getTypeOfChildPropertyShouldUseReflectionServiceToDetermineType() {
                $mockSchema = $this->getMockBuilder('TYPO3\\CMS\\Extbase\\Reflection\\ClassSchema')->disableOriginalConstructor()->getMock();
                $this->mockReflectionService->expects($this->any())->method('getClassSchema')->with('TheTargetType')->will($this->returnValue($mockSchema));
         */
        public function getTypeOfChildPropertyShouldUseReflectionServiceToDetermineType() {
                $mockSchema = $this->getMockBuilder('TYPO3\\CMS\\Extbase\\Reflection\\ClassSchema')->disableOriginalConstructor()->getMock();
                $this->mockReflectionService->expects($this->any())->method('getClassSchema')->with('TheTargetType')->will($this->returnValue($mockSchema));
+
                $mockSchema->expects($this->any())->method('hasProperty')->with('thePropertyName')->will($this->returnValue(TRUE));
                $mockSchema->expects($this->any())->method('getProperty')->with('thePropertyName')->will($this->returnValue(array(
                        'type' => 'TheTypeOfSubObject',
                $mockSchema->expects($this->any())->method('hasProperty')->with('thePropertyName')->will($this->returnValue(TRUE));
                $mockSchema->expects($this->any())->method('getProperty')->with('thePropertyName')->will($this->returnValue(array(
                        'type' => 'TheTypeOfSubObject',
@@ -136,54 +133,65 @@ class PersistentObjectConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTe
 
        /**
         * @test
 
        /**
         * @test
-        * @author Sebastian Kurfürst <sebastian@typo3.org>
         */
        public function getTypeOfChildPropertyShouldUseConfiguredTypeIfItWasSet() {
                $this->mockReflectionService->expects($this->never())->method('getClassSchema');
         */
        public function getTypeOfChildPropertyShouldUseConfiguredTypeIfItWasSet() {
                $this->mockReflectionService->expects($this->never())->method('getClassSchema');
+
                $configuration = $this->buildConfiguration(array());
                $configuration = $this->buildConfiguration(array());
-               $configuration->forProperty('thePropertyName')->setTypeConverterOption('TYPO3\\CMS\\Extbase\\Property\\TypeConverter\\PersistentObjectConverter', \TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_TARGET_TYPE, 'Foo\\Bar');
-               $this->assertEquals('Foo\\Bar', $this->converter->getTypeOfChildProperty('foo', 'thePropertyName', $configuration));
+               $configuration->forProperty('thePropertyName')->setTypeConverterOption('TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter', \TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_TARGET_TYPE, 'Foo\Bar');
+               $this->assertEquals('Foo\Bar', $this->converter->getTypeOfChildProperty('foo', 'thePropertyName', $configuration));
+       }
+
+       /**
+        * @test
+        */
+       public function convertFromShouldFetchObjectFromPersistenceIfUuidStringIsGiven() {
+               $identifier = '17';
+               $object = new \stdClass();
+
+               $this->mockPersistenceManager->expects($this->any())->method('getObjectByIdentifier')->with($identifier)->will($this->returnValue($object));
+               $this->assertSame($object, $this->converter->convertFrom($identifier, 'MySpecialType'));
        }
 
        /**
         * @test
        }
 
        /**
         * @test
-        * @author Sebastian Kurfürst <sebastian@typo3.org>
         */
        public function convertFromShouldFetchObjectFromPersistenceIfuidStringIsGiven() {
                $identifier = '17';
                $object = new \stdClass();
         */
        public function convertFromShouldFetchObjectFromPersistenceIfuidStringIsGiven() {
                $identifier = '17';
                $object = new \stdClass();
-               $this->mockPersistenceManager->expects($this->once())->method('getObjectByIdentifier')->with($identifier)->will($this->returnValue($object));
+
+               $this->mockPersistenceManager->expects($this->any())->method('getObjectByIdentifier')->with($identifier)->will($this->returnValue($object));
                $this->assertSame($object, $this->converter->convertFrom($identifier, 'MySpecialType'));
        }
 
        /**
         * @test
                $this->assertSame($object, $this->converter->convertFrom($identifier, 'MySpecialType'));
        }
 
        /**
         * @test
-        * @author Sebastian Kurfürst <sebastian@typo3.org>
         */
        public function convertFromShouldFetchObjectFromPersistenceIfOnlyIdentityArrayGiven() {
                $identifier = '12345';
                $object = new \stdClass();
         */
        public function convertFromShouldFetchObjectFromPersistenceIfOnlyIdentityArrayGiven() {
                $identifier = '12345';
                $object = new \stdClass();
+
                $source = array(
                        '__identity' => $identifier
                );
                $source = array(
                        '__identity' => $identifier
                );
-               $this->mockPersistenceManager->expects($this->once())->method('getObjectByIdentifier')->with($identifier)->will($this->returnValue($object));
+               $this->mockPersistenceManager->expects($this->any())->method('getObjectByIdentifier')->with($identifier)->will($this->returnValue($object));
                $this->assertSame($object, $this->converter->convertFrom($source, 'MySpecialType'));
        }
 
        /**
         * @test
                $this->assertSame($object, $this->converter->convertFrom($source, 'MySpecialType'));
        }
 
        /**
         * @test
-        * @author Sebastian Kurfürst <sebastian@typo3.org>
         * @expectedException \TYPO3\CMS\Extbase\Property\Exception\InvalidPropertyMappingConfigurationException
         */
        public function convertFromShouldThrowExceptionIfObjectNeedsToBeModifiedButConfigurationIsNotSet() {
                $identifier = '12345';
                $object = new \stdClass();
                $object->someProperty = 'asdf';
         * @expectedException \TYPO3\CMS\Extbase\Property\Exception\InvalidPropertyMappingConfigurationException
         */
        public function convertFromShouldThrowExceptionIfObjectNeedsToBeModifiedButConfigurationIsNotSet() {
                $identifier = '12345';
                $object = new \stdClass();
                $object->someProperty = 'asdf';
+
                $source = array(
                        '__identity' => $identifier,
                        'foo' => 'bar'
                );
                $source = array(
                        '__identity' => $identifier,
                        'foo' => 'bar'
                );
-               $this->mockPersistenceManager->expects($this->once())->method('getObjectByIdentifier')->with($identifier)->will($this->returnValue($object));
+               $this->mockPersistenceManager->expects($this->any())->method('getObjectByIdentifier')->with($identifier)->will($this->returnValue($object));
                $this->converter->convertFrom($source, 'MySpecialType');
        }
 
                $this->converter->convertFrom($source, 'MySpecialType');
        }
 
@@ -198,55 +206,62 @@ class PersistentObjectConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTe
        }
 
        /**
        }
 
        /**
-        * @test
-        * @author Sebastian Kurfürst <sebastian@typo3.org>
-        */
-       public function convertFromShouldCloneTheFetchedObjectIfObjectNeedsToBeModified() {
-               $identifier = '12345';
-               $object = new \TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSetters();
-               $object->someProperty = 'asdf';
-               $source = array(
-                       '__identity' => $identifier,
-                       'foo' => 'bar'
-               );
-               $convertedChildProperties = array(
-                       'property1' => 'someConvertedValue'
-               );
-               $this->mockPersistenceManager->expects($this->once())->method('getObjectByIdentifier')->with($identifier)->will($this->returnValue($object));
-               $configuration = $this->buildConfiguration(array(\TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_MODIFICATION_ALLOWED => TRUE));
-               $actual = $this->converter->convertFrom($source, 'MySpecialType', $convertedChildProperties, $configuration);
-               $this->assertNotSame($object, $actual, 'The object has not been cloned.');
-               $this->assertEquals('asdf', $actual->someProperty, 'The object somehow lost its current state.');
-               $this->assertEquals('someConvertedValue', $actual->property1, 'The sub properties have not been set.');
-       }
-
-       /**
         * @param integer $numberOfResults
         * @param Matcher $howOftenIsGetFirstCalled
         * @return \stdClass
         * @param integer $numberOfResults
         * @param Matcher $howOftenIsGetFirstCalled
         * @return \stdClass
-        * @author Bastian Waidelich <bastian@typo3.org>
-        * @author Sebastian Kurfürst <sebastian@typo3.org>
         */
        public function setupMockQuery($numberOfResults, $howOftenIsGetFirstCalled) {
                $mockClassSchema = $this->getMock('TYPO3\\CMS\\Extbase\\Reflection\\ClassSchema', array(), array('Dummy'));
         */
        public function setupMockQuery($numberOfResults, $howOftenIsGetFirstCalled) {
                $mockClassSchema = $this->getMock('TYPO3\\CMS\\Extbase\\Reflection\\ClassSchema', array(), array('Dummy'));
-               $mockClassSchema->expects($this->once())->method('getIdentityProperties')->will($this->returnValue(array('key1' => 'someType')));
-               $this->mockReflectionService->expects($this->once())->method('getClassSchema')->with('SomeType')->will($this->returnValue($mockClassSchema));
-               $mockConstraint = $this->getMockBuilder('Tx_Extbase_Persistence_Generic_Qom_Comparison')->disableOriginalConstructor()->getMock();
+               $mockClassSchema->expects($this->any())->method('getIdentityProperties')->will($this->returnValue(array('key1' => 'someType')));
+               $this->mockReflectionService->expects($this->any())->method('getClassSchema')->with('SomeType')->will($this->returnValue($mockClassSchema));
+
+               $mockConstraint = $this->getMockBuilder('TYPO3\CMS\Extbase\Persistence\Generic\Qom\Comparison')->disableOriginalConstructor()->getMock();
+
                $mockObject = new \stdClass();
                $mockQuery = $this->getMock('TYPO3\\CMS\\Extbase\\Persistence\\QueryInterface');
                $mockQueryResult = $this->getMock('TYPO3\\CMS\\Extbase\\Persistence\\QueryResultInterface');
                $mockObject = new \stdClass();
                $mockQuery = $this->getMock('TYPO3\\CMS\\Extbase\\Persistence\\QueryInterface');
                $mockQueryResult = $this->getMock('TYPO3\\CMS\\Extbase\\Persistence\\QueryResultInterface');
-               $mockQueryResult->expects($this->once())->method('count')->will($this->returnValue($numberOfResults));
+               $mockQueryResult->expects($this->any())->method('count')->will($this->returnValue($numberOfResults));
                $mockQueryResult->expects($howOftenIsGetFirstCalled)->method('getFirst')->will($this->returnValue($mockObject));
                $mockQueryResult->expects($howOftenIsGetFirstCalled)->method('getFirst')->will($this->returnValue($mockObject));
-               $mockQuery->expects($this->once())->method('equals')->with('key1', 'value1')->will($this->returnValue($mockConstraint));
-               $mockQuery->expects($this->once())->method('matching')->with($mockConstraint)->will($this->returnValue($mockQuery));
-               $mockQuery->expects($this->once())->method('execute')->will($this->returnValue($mockQueryResult));
-               $this->mockPersistenceManager->expects($this->once())->method('createQueryForType')->with('SomeType')->will($this->returnValue($mockQuery));
+               $mockQuery->expects($this->any())->method('equals')->with('key1', 'value1')->will($this->returnValue($mockConstraint));
+               $mockQuery->expects($this->any())->method('matching')->with($mockConstraint)->will($this->returnValue($mockQuery));
+               $mockQuery->expects($this->any())->method('execute')->will($this->returnValue($mockQueryResult));
+
+               $this->mockPersistenceManager->expects($this->any())->method('createQueryForType')->with('SomeType')->will($this->returnValue($mockQuery));
+
                return $mockObject;
        }
 
        /**
         * @test
                return $mockObject;
        }
 
        /**
         * @test
-        * @author Sebastian Kurfürst <sebastian@typo3.org>
+        * @expectedException \TYPO3\CMS\Extbase\Property\Exception\TargetNotFoundException
+        */
+       public function convertFromShouldReturnExceptionIfNoMatchingObjectWasFound() {
+               $this->setupMockQuery(0, $this->never());
+               $this->mockReflectionService->expects($this->never())->method('getClassSchema');
+
+               $source = array(
+                       '__identity' => 123
+               );
+               $actual = $this->converter->convertFrom($source, 'SomeType');
+               $this->assertNull($actual);
+       }
+
+       /**
+        * @test
+        * @expectedException \TYPO3\CMS\Extbase\Property\Exception\DuplicateObjectException
+        */
+       public function convertFromShouldThrowExceptionIfMoreThanOneObjectWasFound() {
+               $this->setupMockQuery(2, $this->never());
+
+               $source = array(
+                       '__identity' => 666
+               );
+               $this->mockPersistenceManager->expects($this->any())->method('getObjectByIdentifier')->with(666)->will($this->throwException(new \TYPO3\CMS\Extbase\Property\Exception\DuplicateObjectException));
+               $this->converter->convertFrom($source, 'SomeType');
+       }
+
+       /**
+        * @test
         * @expectedException \TYPO3\CMS\Extbase\Property\Exception\InvalidPropertyMappingConfigurationException
         */
        public function convertFromShouldThrowExceptionIfObjectNeedsToBeCreatedButConfigurationIsNotSet() {
         * @expectedException \TYPO3\CMS\Extbase\Property\Exception\InvalidPropertyMappingConfigurationException
         */
        public function convertFromShouldThrowExceptionIfObjectNeedsToBeCreatedButConfigurationIsNotSet() {
@@ -258,42 +273,26 @@ class PersistentObjectConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTe
 
        /**
         * @test
 
        /**
         * @test
-        * @author Sebastian Kurfürst <sebastian@typo3.org>
         */
        public function convertFromShouldCreateObject() {
                $source = array(
                        'propertyX' => 'bar'
                );
         */
        public function convertFromShouldCreateObject() {
                $source = array(
                        'propertyX' => 'bar'
                );
-               $object = new \TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSetters();
                $convertedChildProperties = array(
                        'property1' => 'bar'
                );
                $convertedChildProperties = array(
                        'property1' => 'bar'
                );
-               $this->mockObjectManager->expects($this->once())->method('get')->with('TYPO3\\CMS\\Extbase\\Tests\\Fixture\\ClassWithSetters')->will($this->returnValue($object));
-               $this->mockReflectionService->expects($this->once())->method('getMethodParameters')->with('TYPO3\\CMS\\Extbase\\Tests\\Fixture\\ClassWithSetters', '__construct')->will($this->returnValue(array()));
-               $configuration = $this->buildConfiguration(array(\TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED => TRUE));
-               $result = $this->converter->convertFrom($source, 'TYPO3\\CMS\\Extbase\\Tests\\Fixture\\ClassWithSetters', $convertedChildProperties, $configuration);
-               $this->assertSame($object, $result);
-       }
+               $expectedObject = new \TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSetters();
+               $expectedObject->property1 = 'bar';
 
 
-       /**
-        * @test
-        */
-       public function convertFromForModelWithoutConstructorCreatesObject() {
-               $className = 'TYPO3\\CMS\\Extbase\\Tests\\Fixture\\ClassWithSetters';
-               $source = array('propertyX' => 'bar');
-               $model = new $className();
-               $convertedChildProperties = array('property1' => 'bar');
-               $this->mockObjectManager->expects($this->once())->method('get')->with($className)->will($this->returnValue($model));
+               $this->mockReflectionService->expects($this->any())->method('getMethodParameters')->with('TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSetters', '__construct')->will($this->throwException(new \ReflectionException()));
+               $this->mockObjectManager->expects($this->any())->method('getClassNameByObjectName')->with('TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSetters')->will($this->returnValue('TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSetters'));
                $configuration = $this->buildConfiguration(array(\TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED => TRUE));
                $configuration = $this->buildConfiguration(array(\TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED => TRUE));
-               $reflectionException = new \ReflectionException('Method ' . $className . '::__construct() does not exist');
-               $this->mockReflectionService->expects($this->once())->method('getMethodParameters')->with($className, '__construct')->will($this->throwException($reflectionException));
-               $result = $this->converter->convertFrom($source, $className, $convertedChildProperties, $configuration);
-               $this->assertSame($model, $result);
+               $result = $this->converter->convertFrom($source, 'TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSetters', $convertedChildProperties, $configuration);
+               $this->assertEquals($expectedObject, $result);
        }
 
        /**
         * @test
        }
 
        /**
         * @test
-        * @author Sebastian Kurfürst <sebastian@typo3.org>
         * @expectedException \TYPO3\CMS\Extbase\Property\Exception\InvalidTargetException
         */
        public function convertFromShouldThrowExceptionIfPropertyOnTargetObjectCouldNotBeSet() {
         * @expectedException \TYPO3\CMS\Extbase\Property\Exception\InvalidTargetException
         */
        public function convertFromShouldThrowExceptionIfPropertyOnTargetObjectCouldNotBeSet() {
@@ -304,8 +303,8 @@ class PersistentObjectConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTe
                $convertedChildProperties = array(
                        'propertyNotExisting' => 'bar'
                );
                $convertedChildProperties = array(
                        'propertyNotExisting' => 'bar'
                );
-               $this->mockObjectManager->expects($this->once())->method('get')->with('TYPO3\\CMS\\Extbase\\Tests\\Fixture\\ClassWithSetters')->will($this->returnValue($object));
-               $this->mockReflectionService->expects($this->once())->method('getMethodParameters')->with('TYPO3\\CMS\\Extbase\\Tests\\Fixture\\ClassWithSetters', '__construct')->will($this->returnValue(array()));
+               $this->mockObjectManager->expects($this->any())->method('get')->with('TYPO3\\CMS\\Extbase\\Tests\\Fixture\\ClassWithSetters')->will($this->returnValue($object));
+               $this->mockReflectionService->expects($this->any())->method('getMethodParameters')->with('TYPO3\\CMS\\Extbase\\Tests\\Fixture\\ClassWithSetters', '__construct')->will($this->returnValue(array()));
                $configuration = $this->buildConfiguration(array(\TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED => TRUE));
                $result = $this->converter->convertFrom($source, 'TYPO3\\CMS\\Extbase\\Tests\\Fixture\\ClassWithSetters', $convertedChildProperties, $configuration);
                $this->assertSame($object, $result);
                $configuration = $this->buildConfiguration(array(\TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED => TRUE));
                $result = $this->converter->convertFrom($source, 'TYPO3\\CMS\\Extbase\\Tests\\Fixture\\ClassWithSetters', $convertedChildProperties, $configuration);
                $this->assertSame($object, $result);
@@ -313,48 +312,48 @@ class PersistentObjectConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTe
 
        /**
         * @test
 
        /**
         * @test
-        * @author Sebastian Kurfürst <sebastian@typo3.org>
         */
        public function convertFromShouldCreateObjectWhenThereAreConstructorParameters() {
                $source = array(
                        'propertyX' => 'bar'
                );
         */
        public function convertFromShouldCreateObjectWhenThereAreConstructorParameters() {
                $source = array(
                        'propertyX' => 'bar'
                );
-               $object = new \TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSettersAndConstructor('param1');
                $convertedChildProperties = array(
                        'property1' => 'param1',
                        'property2' => 'bar'
                );
                $convertedChildProperties = array(
                        'property1' => 'param1',
                        'property2' => 'bar'
                );
-               $this->mockObjectManager->expects($this->once())->method('get')->with('TYPO3\\CMS\\Extbase\\Tests\\Fixture\\ClassWithSettersAndConstructor', 'param1')->will($this->returnValue($object));
-               $this->mockReflectionService->expects($this->once())->method('getMethodParameters')->with('TYPO3\\CMS\\Extbase\\Tests\\Fixture\\ClassWithSettersAndConstructor', '__construct')->will($this->returnValue(array(
+               $expectedObject = new \TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSettersAndConstructor('param1');
+               $expectedObject->setProperty2('bar');
+
+               $this->mockReflectionService->expects($this->any())->method('getMethodParameters')->with('TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSettersAndConstructor', '__construct')->will($this->returnValue(array(
                        'property1' => array('optional' => FALSE)
                )));
                        'property1' => array('optional' => FALSE)
                )));
+               $this->mockObjectManager->expects($this->any())->method('getClassNameByObjectName')->with('TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSettersAndConstructor')->will($this->returnValue('TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSettersAndConstructor'));
                $configuration = $this->buildConfiguration(array(\TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED => TRUE));
                $configuration = $this->buildConfiguration(array(\TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED => TRUE));
-               $result = $this->converter->convertFrom($source, 'TYPO3\\CMS\\Extbase\\Tests\\Fixture\\ClassWithSettersAndConstructor', $convertedChildProperties, $configuration);
-               $this->assertSame($object, $result);
-               $this->assertEquals('bar', $object->getProperty2());
+               $result = $this->converter->convertFrom($source, 'TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSettersAndConstructor', $convertedChildProperties, $configuration);
+               $this->assertEquals($expectedObject, $result);
+               $this->assertEquals('bar', $expectedObject->getProperty2());
        }
 
        /**
         * @test
        }
 
        /**
         * @test
-        * @author Sebastian Kurfürst <sebastian@typo3.org>
         */
        public function convertFromShouldCreateObjectWhenThereAreOptionalConstructorParameters() {
                $source = array(
                        'propertyX' => 'bar'
                );
         */
        public function convertFromShouldCreateObjectWhenThereAreOptionalConstructorParameters() {
                $source = array(
                        'propertyX' => 'bar'
                );
-               $object = new \TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSettersAndConstructor('param1');
-               $this->mockObjectManager->expects($this->once())->method('get')->with('TYPO3\\CMS\\Extbase\\Tests\\Fixture\\ClassWithSettersAndConstructor', 'thisIsTheDefaultValue')->will($this->returnValue($object));
-               $this->mockReflectionService->expects($this->once())->method('getMethodParameters')->with('TYPO3\\CMS\\Extbase\\Tests\\Fixture\\ClassWithSettersAndConstructor', '__construct')->will($this->returnValue(array(
+               $expectedObject = new \TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSettersAndConstructor('thisIsTheDefaultValue');
+
+               $this->mockReflectionService->expects($this->any())->method('getMethodParameters')->with('TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSettersAndConstructor', '__construct')->will($this->returnValue(array(
                        'property1' => array('optional' => TRUE, 'defaultValue' => 'thisIsTheDefaultValue')
                )));
                        'property1' => array('optional' => TRUE, 'defaultValue' => 'thisIsTheDefaultValue')
                )));
+               $this->mockObjectManager->expects($this->any())->method('getClassNameByObjectName')->with('TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSettersAndConstructor')->will($this->returnValue('TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSettersAndConstructor'));
                $configuration = $this->buildConfiguration(array(\TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED => TRUE));
                $configuration = $this->buildConfiguration(array(\TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED => TRUE));
-               $result = $this->converter->convertFrom($source, 'TYPO3\\CMS\\Extbase\\Tests\\Fixture\\ClassWithSettersAndConstructor', array(), $configuration);
-               $this->assertSame($object, $result);
+               $result = $this->converter->convertFrom($source, 'TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSettersAndConstructor', array(), $configuration);
+               $this->assertEquals($expectedObject, $result);
        }
 
        /**
         * @test
        }
 
        /**
         * @test
-        * @author Sebastian Kurfürst <sebastian@typo3.org>
         * @expectedException \TYPO3\CMS\Extbase\Property\Exception\InvalidTargetException
         */
        public function convertFromShouldThrowExceptionIfRequiredConstructorParameterWasNotFound() {
         * @expectedException \TYPO3\CMS\Extbase\Property\Exception\InvalidTargetException
         */
        public function convertFromShouldThrowExceptionIfRequiredConstructorParameterWasNotFound() {
@@ -365,13 +364,24 @@ class PersistentObjectConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTe
                $convertedChildProperties = array(
                        'property2' => 'bar'
                );
                $convertedChildProperties = array(
                        'property2' => 'bar'
                );
-               $this->mockReflectionService->expects($this->once())->method('getMethodParameters')->with('TYPO3\\CMS\\Extbase\\Tests\\Fixture\\ClassWithSettersAndConstructor', '__construct')->will($this->returnValue(array(
+
+               $this->mockReflectionService->expects($this->any())->method('getMethodParameters')->with('TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSettersAndConstructor', '__construct')->will($this->returnValue(array(
                        'property1' => array('optional' => FALSE)
                )));
                        'property1' => array('optional' => FALSE)
                )));
+               $this->mockObjectManager->expects($this->any())->method('getClassNameByObjectName')->with('TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSettersAndConstructor')->will($this->returnValue('TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSettersAndConstructor'));
                $configuration = $this->buildConfiguration(array(\TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED => TRUE));
                $configuration = $this->buildConfiguration(array(\TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED => TRUE));
-               $result = $this->converter->convertFrom($source, 'TYPO3\\CMS\\Extbase\\Tests\\Fixture\\ClassWithSettersAndConstructor', $convertedChildProperties, $configuration);
+               $result = $this->converter->convertFrom($source, 'TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSettersAndConstructor', $convertedChildProperties, $configuration);
                $this->assertSame($object, $result);
        }
                $this->assertSame($object, $result);
        }
-}
 
 
+       /**
+        * @test
+        */
+       public function convertFromShouldReturnNullForEmptyString() {
+               $source = '';
+               $result = $this->converter->convertFrom($source, 'TYPO3\CMS\Extbase\Tests\Fixture\ClassWithSettersAndConstructor');
+               $this->assertNull($result);
+       }
+
+}
 ?>
\ No newline at end of file
 ?>
\ No newline at end of file
index 12d90b0..3bb6f09 100644 (file)
@@ -23,7 +23,6 @@ namespace TYPO3\CMS\Extbase\Tests\Unit\Property\TypeConverter;
 /**
  * Testcase for the String converter
  *
 /**
  * Testcase for the String converter
  *
- * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
  * @covers \TYPO3\CMS\Extbase\Property\TypeConverter\StringConverter<extended>
  */
 class StringConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
  * @covers \TYPO3\CMS\Extbase\Property\TypeConverter\StringConverter<extended>
  */
 class StringConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
@@ -39,17 +38,15 @@ class StringConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
 
        /**
         * @test
 
        /**
         * @test
-        * @author Sebastian Kurfürst <sebastian@typo3.org>
         */
        public function checkMetadata() {
         */
        public function checkMetadata() {
-               $this->assertEquals(array('string'), $this->converter->getSupportedSourceTypes(), 'Source types do not match');
+               $this->assertEquals(array('string', 'integer'), $this->converter->getSupportedSourceTypes(), 'Source types do not match');
                $this->assertEquals('string', $this->converter->getSupportedTargetType(), 'Target type does not match');
                $this->assertEquals(1, $this->converter->getPriority(), 'Priority does not match');
        }
 
        /**
         * @test
                $this->assertEquals('string', $this->converter->getSupportedTargetType(), 'Target type does not match');
                $this->assertEquals(1, $this->converter->getPriority(), 'Priority does not match');
        }
 
        /**
         * @test
-        * @author Sebastian Kurfürst <sebastian@typo3.org>
         */
        public function convertFromShouldReturnSourceString() {
                $this->assertEquals('myString', $this->converter->convertFrom('myString', 'string'));
         */
        public function convertFromShouldReturnSourceString() {
                $this->assertEquals('myString', $this->converter->convertFrom('myString', 'string'));
@@ -57,7 +54,6 @@ class StringConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
 
        /**
         * @test
 
        /**
         * @test
-        * @author Sebastian Kurfürst <sebastian@typo3.org>
         */
        public function canConvertFromShouldReturnTrue() {
                $this->assertTrue($this->converter->canConvertFrom('myString', 'string'));
         */
        public function canConvertFromShouldReturnTrue() {
                $this->assertTrue($this->converter->canConvertFrom('myString', 'string'));
@@ -65,11 +61,9 @@ class StringConverterTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
 
        /**
         * @test
 
        /**
         * @test
-        * @author Sebastian Kurfürst <sebastian@typo3.org>
         */
        public function getSourceChildPropertiesToBeConvertedShouldReturnEmptyArray() {
                $this->assertEquals(array(), $this->converter->getSourceChildPropertiesToBeConverted('myString'));
        }
 }
         */
        public function getSourceChildPropertiesToBeConvertedShouldReturnEmptyArray() {
                $this->assertEquals(array(), $this->converter->getSourceChildPropertiesToBeConverted('myString'));
        }
 }
-
 ?>
\ No newline at end of file
 ?>
\ No newline at end of file
index c366a84..7e329ed 100644 (file)
@@ -43,7 +43,7 @@ class TypeHandlingServiceTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase
 
        /**
         * @test
 
        /**
         * @test
-        * @expectedException \InvalidArgumentException
+        * @expectedException \TYPO3\CMS\Extbase\Utility\Exception\InvalidTypeException
         */
        public function parseTypeThrowsExceptionOnInvalidType() {
                $this->typeHandlingService->parseType('something not a type');
         */
        public function parseTypeThrowsExceptionOnInvalidType() {
                $this->typeHandlingService->parseType('something not a type');
@@ -51,7 +51,7 @@ class TypeHandlingServiceTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase
 
        /**
         * @test
 
        /**
         * @test
-        * @expectedException \InvalidArgumentException
+        * @expectedException \TYPO3\CMS\Extbase\Utility\Exception\InvalidTypeException
         * @author Karsten Dambekalns <karsten@typo3.org>
         */
        public function parseTypeThrowsExceptionOnInvalidElementTypeHint() {
         * @author Karsten Dambekalns <karsten@typo3.org>
         */
        public function parseTypeThrowsExceptionOnInvalidElementTypeHint() {