/** * Convert the given $source to $targetType depending on the MediaTypeConverterInterface::CONFIGURATION_MEDIA_TYPE property mapping configuration * * @param string $source the raw request body * @param string $targetType must be "array" * @param array $convertedChildProperties * @param PropertyMappingConfigurationInterface $configuration * @return array * @api */ public function convertFrom($source, $targetType, array $convertedChildProperties = [], PropertyMappingConfigurationInterface $configuration = null) { $mediaType = null; if ($configuration !== null) { $mediaType = $configuration->getConfigurationValue(MediaTypeConverterInterface::class, MediaTypeConverterInterface::CONFIGURATION_MEDIA_TYPE); } if ($mediaType === null) { $mediaType = MediaTypeConverterInterface::DEFAULT_MEDIA_TYPE; } return $this->convertMediaType($source, $mediaType); }
/** * Convert the given $source to $targetType depending on the MediaTypeConverterInterface::CONFIGURATION_MEDIA_TYPE property mapping configuration * * @param string $source the raw request body * @param string $targetType must be "array" * @param array $convertedChildProperties * @param PropertyMappingConfigurationInterface $configuration * @return array * @api */ public function convertFrom($source, $targetType, array $convertedChildProperties = array(), PropertyMappingConfigurationInterface $configuration = NULL) { $mediaType = NULL; if ($configuration !== NULL) { $mediaType = $configuration->getConfigurationValue('TYPO3\\Flow\\Property\\TypeConverter\\MediaTypeConverterInterface', MediaTypeConverterInterface::CONFIGURATION_MEDIA_TYPE); } if ($mediaType === NULL) { $mediaType = MediaTypeConverterInterface::DEFAULT_MEDIA_TYPE; } return $this->convertMediaType($source, $mediaType); }
/** * Actually convert from $source to $targetType, taking into account the fully * built $convertedChildProperties and $configuration. * * 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. * - 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 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 PropertyMappingConfigurationInterface $configuration * @return mixed|Error the target type, or an error object if a user-error occurred * @throws TypeConverterException thrown in case a developer error occurred * @api */ public function convertFrom($source, $targetType, array $convertedChildProperties = [], PropertyMappingConfigurationInterface $configuration = null) { $result = []; $convertElements = $configuration->getConfigurationValue(ArrayTypeConverter::class, self::CONFIGURATION_CONVERT_ELEMENTS); foreach ($source as $element) { if ($convertElements === true) { $element = $this->propertyMapper->convert($element, 'array', $configuration); } $result[] = $element; } return $result; }
/** * Actually convert from $source to $targetType, taking into account the fully * built $convertedChildProperties and $configuration. * * 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. * - 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\Flow\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 PropertyMappingConfigurationInterface $configuration * @return mixed|\TYPO3\Flow\Error\Error the target type, or an error object if a user-error occurred * @throws \TYPO3\Flow\Property\Exception\TypeConverterException thrown in case a developer error occurred * @api */ public function convertFrom($source, $targetType, array $convertedChildProperties = array(), PropertyMappingConfigurationInterface $configuration = NULL) { $result = array(); $convertElements = $configuration->getConfigurationValue(\TYPO3\Flow\Persistence\Doctrine\ArrayTypeConverter::class, self::CONFIGURATION_CONVERT_ELEMENTS); foreach ($source as $element) { if ($convertElements === TRUE) { $element = $this->propertyMapper->convert($element, 'array', $configuration); } $result[] = $element; } return $result; }
/** * @test */ public function convertFromSetsRemovedContentShownContextPropertyFromConfigurationForContextPathSource() { $contextPath = '/foo/bar@user-demo'; $nodePath = '/foo/bar'; $mockNode = $this->setUpNodeWithNodeType($nodePath); $this->mockConverterConfiguration->expects($this->any())->method('getConfigurationValue')->with('TYPO3\\TYPO3CR\\TypeConverter\\NodeConverter', NodeConverter::REMOVED_CONTENT_SHOWN)->will($this->returnValue(true)); $result = $this->nodeConverter->convertFrom($contextPath, null, array(), $this->mockConverterConfiguration); $this->assertSame($mockNode, $result); $contextProperties = $mockNode->getContext()->getProperties(); $this->assertArrayHasKey('removedContentShown', $contextProperties, 'removedContentShown context property should be set'); $this->assertTrue($contextProperties['removedContentShown'], 'removedContentShown context property should be TRUE'); }
/** * @param \TYPO3\Flow\Property\PropertyMappingConfigurationInterface $configuration * @return string * @throws \TYPO3\Flow\Property\Exception\InvalidPropertyMappingConfigurationException */ protected function getConfiguredStringDelimiter(\TYPO3\Flow\Property\PropertyMappingConfigurationInterface $configuration = NULL) { if ($configuration === NULL) { return self::DEFAULT_STRING_DELIMITER; } $stringDelimiter = $configuration->getConfigurationValue('TYPO3\\Flow\\Property\\TypeConverter\\ArrayConverter', self::CONFIGURATION_STRING_DELIMITER); if ($stringDelimiter === NULL) { return self::DEFAULT_STRING_DELIMITER; } elseif (!is_string($stringDelimiter)) { throw new \TYPO3\Flow\Property\Exception\InvalidPropertyMappingConfigurationException('CONFIGURATION_STRING_DELIMITER must be of type string, "' . (is_object($stringDelimiter) ? get_class($stringDelimiter) : gettype($stringDelimiter)) . '" given', 1368433339); } return $stringDelimiter; }
/** * @param mixed $source * @param string $targetType * @param array $convertedChildProperties * @param \TYPO3\Flow\Property\PropertyMappingConfigurationInterface $configuration * @return object the target type */ public function convertFrom($source, $targetType, array $convertedChildProperties = array(), \TYPO3\Flow\Property\PropertyMappingConfigurationInterface $configuration = NULL) { if ($source === '') { return NULL; } // TODO: Check if we find a typo3.org user that match if (filter_var($source, FILTER_VALIDATE_EMAIL)) { $source = array('email' => $source); } else { if (!strpos(' ', $source)) { $source = array('username' => $source); } else { $source = array('name' => $source); } } /** @var \TYPO3\Flow\Mvc\Controller\MvcPropertyMappingConfiguration $configuration */ $configuration->allowAllProperties(); $configuration->setTypeConverterOption('TYPO3\\Flow\\Property\\TypeConverter\\PersistentObjectConverter', \TYPO3\Flow\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED, TRUE); return $this->propertyMapper->convert($source, $targetType, $configuration); }
/** * @test */ public function convertFromSetsRemovedContentShownContextPropertyFromConfigurationForContextPathSource() { $contextPath = '/foo/bar@user-demo'; $mockLiveWorkspace = $this->getMockBuilder('TYPO3\\TYPO3CR\\Domain\\Model\\Workspace')->disableOriginalConstructor()->getMock(); $mockNode = $this->getMock('TYPO3\\TYPO3CR\\Domain\\Model\\NodeInterface'); $mockContext = $this->getMockBuilder('TYPO3\\TYPO3CR\\Domain\\Service\\Context')->disableOriginalConstructor()->getMock(); $mockContext->expects($this->any())->method('getWorkspace')->will($this->returnValue($mockLiveWorkspace)); $mockContext->expects($this->any())->method('getNodeByIdentifier')->with($contextPath)->will($this->returnValue($mockNode)); $this->mockConverterConfiguration->expects($this->any())->method('getConfigurationValue')->with('TYPO3\\TYPO3CR\\TypeConverter\\NodeConverter', NodeConverter::REMOVED_CONTENT_SHOWN)->will($this->returnValue(TRUE)); $this->mockContextFactory->expects($this->any())->method('create')->with($this->callback(function ($properties) { Assert::assertTrue(isset($properties['removedContentShown']), 'removedContentShown context property should be set'); Assert::assertTrue($properties['removedContentShown'], 'removedContentShown context property should be TRUE'); return TRUE; }))->will($this->returnValue($mockContext)); $this->nodeConverter->convertFrom($contextPath, NULL, array(), $this->mockConverterConfiguration); }
/** * Actually convert from $source to $targetType, taking into account the fully * built $convertedChildProperties and $configuration. * * 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. * - 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\Flow\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 PropertyMappingConfigurationInterface $configuration * @return mixed|\TYPO3\Flow\Error\Error the target type, or an error object if a user-error occurred * @throws \TYPO3\Flow\Property\Exception\TypeConverterException thrown in case a developer error occurred * @api */ public function convertFrom($source, $targetType, array $convertedChildProperties = array(), PropertyMappingConfigurationInterface $configuration = null) { $arguments = []; if (array_key_exists('attributes', $source)) { $arguments = array_merge($arguments, $source['attributes']); } if (array_key_exists('relationships', $source)) { $arguments = array_merge($arguments, $source['relationships']); foreach (array_keys($source['relationships']) as $relationshipName) { $configuration->forProperty($relationshipName)->allowProperties('data'); $configuration->forProperty($relationshipName . '.data')->allowAllProperties(); } } if (array_key_exists('id', $source)) { if ($arguments) { $arguments['__identity'] = $source['id']; } else { $arguments = $source['id']; } } return $this->propertyMapper->convert($arguments, $this->exposableTypeMap->getClassName($source['type']), $configuration); }
/** * Creates the context for the nodes based on the given workspace. * * @param string $workspaceName * @param PropertyMappingConfigurationInterface $configuration * @return \TYPO3\TYPO3CR\Domain\Service\Context */ protected function createContext($workspaceName, PropertyMappingConfigurationInterface $configuration = NULL) { $invisibleContentShown = FALSE; $removedContentShown = FALSE; if ($workspaceName !== 'live') { $invisibleContentShown = TRUE; if ($configuration !== NULL && $configuration->getConfigurationValue('TYPO3\\TYPO3CR\\TypeConverter\\NodeConverter', self::REMOVED_CONTENT_SHOWN) === TRUE) { $removedContentShown = TRUE; } } return $this->contextFactory->create(array('workspaceName' => $workspaceName, 'invisibleContentShown' => $invisibleContentShown, 'removedContentShown' => $removedContentShown)); }
/** * @test * @dataProvider contentTypesBodiesAndExpectedUnifiedArguments */ public function convertTests($mediaType, $requestBody, array $expectedResult) { $this->mockPropertyMappingConfiguration->expects($this->atLeastOnce())->method('getConfigurationValue')->with('TYPO3\\Flow\\Property\\TypeConverter\\MediaTypeConverterInterface', MediaTypeConverterInterface::CONFIGURATION_MEDIA_TYPE)->will($this->returnValue($mediaType)); $actualResult = $this->mediaTypeConverter->convertFrom($requestBody, 'array', array(), $this->mockPropertyMappingConfiguration); $this->assertSame($expectedResult, $actualResult); }
/** * Determines the default date format to use for the conversion. * If no format is specified in the mapping configuration DEFAULT_DATE_FORMAT is used. * * @param \TYPO3\Flow\Property\PropertyMappingConfigurationInterface $configuration * @return string * @throws \TYPO3\Flow\Property\Exception\InvalidPropertyMappingConfigurationException */ protected function getDefaultDateFormat(\TYPO3\Flow\Property\PropertyMappingConfigurationInterface $configuration = null) { if ($configuration === null) { return self::DEFAULT_DATE_FORMAT; } $dateFormat = $configuration->getConfigurationValue(\TYPO3\Flow\Property\TypeConverter\DateTimeConverter::class, self::CONFIGURATION_DATE_FORMAT); if ($dateFormat === null) { return self::DEFAULT_DATE_FORMAT; } elseif ($dateFormat !== null && !is_string($dateFormat)) { throw new \TYPO3\Flow\Property\Exception\InvalidPropertyMappingConfigurationException('CONFIGURATION_DATE_FORMAT must be of type string, "' . (is_object($dateFormat) ? get_class($dateFormat) : gettype($dateFormat)) . '" given', 1307719569); } return $dateFormat; }
/** * Determines the format to use for the conversion from array to string. * * If no format is specified in the mapping configuration DEFAULT_ARRAY_FORMAT is used. * * @param \TYPO3\Flow\Property\PropertyMappingConfigurationInterface $configuration * @return string * @throws \TYPO3\Flow\Property\Exception\InvalidPropertyMappingConfigurationException */ protected function getArrayFormat(\TYPO3\Flow\Property\PropertyMappingConfigurationInterface $configuration = NULL) { if ($configuration === NULL) { return self::DEFAULT_ARRAY_FORMAT; } $arrayFormat = $configuration->getConfigurationValue(\TYPO3\Flow\Property\TypeConverter\StringConverter::class, self::CONFIGURATION_ARRAY_FORMAT); if ($arrayFormat === NULL) { return self::DEFAULT_ARRAY_FORMAT; } elseif (!is_string($arrayFormat)) { throw new \TYPO3\Flow\Property\Exception\InvalidPropertyMappingConfigurationException('CONFIGURATION_ARRAY_FORMAT must be of type string, "' . (is_object($arrayFormat) ? get_class($arrayFormat) : gettype($arrayFormat)) . '" given', 1404228995); } return $arrayFormat; }
/** * Get the collection name this resource will be stored in. Default will be ResourceManager::DEFAULT_PERSISTENT_COLLECTION_NAME * The propertyMappingConfiguration CONFIGURATION_COLLECTION_NAME will directly override the default. Then if CONFIGURATION_ALLOW_COLLECTION_OVERRIDE is TRUE * and __collectionName is in the $source this will finally be the value. * * @param array $source * @param PropertyMappingConfigurationInterface $configuration * @return string * @throws InvalidPropertyMappingConfigurationException */ protected function getCollectionName($source, PropertyMappingConfigurationInterface $configuration = null) { if ($configuration === null) { return ResourceManager::DEFAULT_PERSISTENT_COLLECTION_NAME; } $collectionName = $configuration->getConfigurationValue(\TYPO3\Flow\Resource\ResourceTypeConverter::class, self::CONFIGURATION_COLLECTION_NAME) ?: ResourceManager::DEFAULT_PERSISTENT_COLLECTION_NAME; if (isset($source['__collectionName']) && $source['__collectionName'] !== '') { $collectionName = $source['__collectionName']; } if ($this->resourceManager->getCollection($collectionName) === null) { throw new InvalidPropertyMappingConfigurationException(sprintf('The selected resource collection named "%s" does not exist, a resource could not be imported.', $collectionName), 1416687475); } return $collectionName; }
/** * Prepares the context properties for the nodes based on the given workspace and dimensions * * @param string $workspaceName * @param PropertyMappingConfigurationInterface $configuration * @param array $dimensions * @return array */ protected function prepareContextProperties($workspaceName, PropertyMappingConfigurationInterface $configuration = null, array $dimensions = null) { $contextProperties = array('workspaceName' => $workspaceName, 'invisibleContentShown' => false, 'removedContentShown' => false); if ($workspaceName !== 'live') { $contextProperties['invisibleContentShown'] = true; if ($configuration !== null && $configuration->getConfigurationValue('TYPO3\\TYPO3CR\\TypeConverter\\NodeConverter', self::REMOVED_CONTENT_SHOWN) === true) { $contextProperties['removedContentShown'] = true; } } if ($dimensions !== null) { $contextProperties['dimensions'] = $dimensions; } return $contextProperties; }
/** * @param PropertyMappingConfigurationInterface $configuration * @return string * @throws InvalidPropertyMappingConfigurationException */ protected function getResourceExportType(PropertyMappingConfigurationInterface $configuration = NULL) { if ($configuration === NULL) { return self::DEFAULT_RESOURCE_EXPORT_TYPE; } $exportType = $configuration->getConfigurationValue('TYPO3\\Flow\\Property\\TypeConverter\\ArrayConverter', self::CONFIGURATION_RESOURCE_EXPORT_TYPE); if ($exportType === NULL) { return self::DEFAULT_RESOURCE_EXPORT_TYPE; } elseif (!is_string($exportType)) { throw new InvalidPropertyMappingConfigurationException(sprintf('RESOURCE_EXPORT_TYPE must be of type string, "%s" given', is_object($exportType) ? get_class($exportType) : gettype($exportType)), 1404313373); } return $exportType; }
/** * @param array $source * @param PropertyMappingConfigurationInterface $configuration * @return Resource|Error */ protected function handleHashAndData(array $source, PropertyMappingConfigurationInterface $configuration = NULL) { $hash = NULL; $resource = FALSE; $givenResourceIdentity = NULL; if (isset($source['__identity'])) { $givenResourceIdentity = $source['__identity']; unset($source['__identity']); $resource = $this->persistenceManager->getObjectByIdentifier($givenResourceIdentity, 'TYPO3\\Flow\\Resource\\Resource'); if ($resource instanceof \TYPO3\Flow\Resource\Resource) { return $resource; } if ($configuration->getConfigurationValue('TYPO3\\Flow\\Resource\\ResourceTypeConverter', self::CONFIGURATION_IDENTITY_CREATION_ALLOWED) !== TRUE) { throw new \TYPO3\Flow\Property\Exception\InvalidPropertyMappingConfigurationException('Creation of resource objects with identity not allowed. To enable this, you need to set the PropertyMappingConfiguration Value "CONFIGURATION_IDENTITY_CREATION_ALLOWED" to TRUE'); } } if (isset($source['hash']) && preg_match('/[0-9a-f]{40}/', $source['hash'])) { $hash = $source['hash']; } if ($hash !== NULL) { $resourcePointer = $this->persistenceManager->getObjectByIdentifier($hash, 'TYPO3\\Flow\\Resource\\ResourcePointer'); if ($resourcePointer) { $resource = new Resource(); $resource->setFilename($source['filename']); $resource->setResourcePointer($resourcePointer); } } if ($resource === NULL) { if (isset($source['data'])) { $resource = $this->resourceManager->createResourceFromContent($source['data'], $source['filename']); } elseif ($hash !== NULL) { $resource = $this->resourceManager->importResource($configuration->getConfigurationValue('TYPO3\\Flow\\Resource\\ResourceTypeConverter', self::CONFIGURATION_RESOURCE_LOAD_PATH) . '/' . $hash); if (is_array($source) && isset($source['filename'])) { $resource->setFilename($source['filename']); } } } if ($resource instanceof \TYPO3\Flow\Resource\Resource) { if ($givenResourceIdentity !== NULL) { $this->setIdentity($resource, $givenResourceIdentity); } return $resource; } else { return new Error('The resource manager could not create a Resource instance.', 1404312901); } }
/** * Determine the type converter to be used. If no converter has been found, an exception is raised. * * @param mixed $source * @param string $targetType * @param \TYPO3\Flow\Property\PropertyMappingConfigurationInterface $configuration * @return \TYPO3\Flow\Property\TypeConverterInterface Type Converter which should be used to convert between $source and $targetType. * @throws \TYPO3\Flow\Property\Exception\TypeConverterException * @throws \TYPO3\Flow\Property\Exception\InvalidTargetException */ protected function findTypeConverter($source, $targetType, \TYPO3\Flow\Property\PropertyMappingConfigurationInterface $configuration) { if ($configuration->getTypeConverter() !== null) { return $configuration->getTypeConverter(); } if (!is_string($targetType)) { throw new \TYPO3\Flow\Property\Exception\InvalidTargetException('The target type was no string, but of type "' . gettype($targetType) . '"', 1297941727); } $normalizedTargetType = TypeHandling::normalizeType($targetType); $truncatedTargetType = TypeHandling::truncateElementType($normalizedTargetType); $converter = null; $sourceTypes = $this->determineSourceTypes($source); foreach ($sourceTypes as $sourceType) { if (TypeHandling::isSimpleType($truncatedTargetType)) { if (isset($this->typeConverters[$sourceType][$truncatedTargetType])) { $converter = $this->findEligibleConverterWithHighestPriority($this->typeConverters[$sourceType][$truncatedTargetType], $source, $normalizedTargetType); } } else { $converter = $this->findFirstEligibleTypeConverterInObjectHierarchy($source, $sourceType, $normalizedTargetType); } if ($converter !== null) { return $converter; } } throw new \TYPO3\Flow\Property\Exception\TypeConverterException('No converter found which can be used to convert from "' . implode('" or "', $sourceTypes) . '" to "' . $normalizedTargetType . '".'); }
/** * Convert an object from $source to an \TYPO3\Media\Domain\Model\AssetInterface implementation * * @param mixed $source * @param string $targetType must implement 'TYPO3\Media\Domain\Model\AssetInterface' * @param array $convertedChildProperties * @param PropertyMappingConfigurationInterface $configuration * @return \TYPO3\Flow\Validation\Error|\TYPO3\Media\Domain\Model\AssetInterface The converted asset, a Validation Error or NULL * @throws \TYPO3\Flow\Property\Exception\InvalidTargetException */ public function convertFrom($source, $targetType, array $convertedChildProperties = array(), PropertyMappingConfigurationInterface $configuration = null) { $object = null; if (is_string($source) && $source !== '') { $source = array('__identity' => $source); } if (isset($convertedChildProperties['resource']) && $convertedChildProperties['resource'] instanceof Resource) { $resource = $convertedChildProperties['resource']; if (isset($this->resourcesAlreadyConvertedToAssets[$resource->getSha1()])) { $object = $this->resourcesAlreadyConvertedToAssets[$resource->getSha1()]; } // This is pretty late to override the targetType, but usually you want to determine the model type from the resource when a new resource was uploaded... $targetType = $this->applyModelMappingStrategy($targetType, $resource, $source); } if ($object === null) { if ($configuration !== null && $configuration->getConfigurationValue(self::class, self::CONFIGURATION_ONE_PER_RESOURCE) === true && isset($convertedChildProperties['resource'])) { $resource = $convertedChildProperties['resource']; $possibleAsset = $this->assetRepository->findOneByResourceSha1($resource->getSha1()); if ($possibleAsset !== null) { $this->resourceManager->deleteResource($resource); return $possibleAsset; } } $object = parent::convertFrom($source, $targetType, $convertedChildProperties, $configuration); } if ($object instanceof AssetInterface) { $object = $this->applyTypeSpecificHandling($object, $source, $convertedChildProperties, $configuration); if ($object !== null) { $this->resourcesAlreadyConvertedToAssets[$object->getResource()->getSha1()] = $object; if (isset($resource) && $resource !== $object->getResource()) { $this->resourceManager->deleteResource($resource); } } } return $object; }
/** * Determines the target type based on the source's (optional) __type key. * * @param mixed $source * @param string $originalTargetType * @param \TYPO3\Flow\Property\PropertyMappingConfigurationInterface $configuration * @return string * @throws \TYPO3\Flow\Property\Exception\InvalidDataTypeException * @throws \TYPO3\Flow\Property\Exception\InvalidPropertyMappingConfigurationException * @throws \InvalidArgumentException */ public function getTargetTypeForSource($source, $originalTargetType, \TYPO3\Flow\Property\PropertyMappingConfigurationInterface $configuration = NULL) { $targetType = $originalTargetType; if (is_array($source) && array_key_exists('__type', $source)) { $targetType = $source['__type']; if ($configuration === NULL) { throw new \InvalidArgumentException('A property mapping configuration must be given, not NULL.', 1326277369); } if ($configuration->getConfigurationValue('TYPO3\\Flow\\Property\\TypeConverter\\ObjectConverter', self::CONFIGURATION_OVERRIDE_TARGET_TYPE_ALLOWED) !== TRUE) { throw new \TYPO3\Flow\Property\Exception\InvalidPropertyMappingConfigurationException('Override of target type not allowed. To enable this, you need to set the PropertyMappingConfiguration Value "CONFIGURATION_OVERRIDE_TARGET_TYPE_ALLOWED" to TRUE.', 1317050430); } // FIXME: The following check and the checkInheritanceChainWithoutIsA() method should be removed if we raise the PHP requirement to 5.3.9 or higher if (version_compare(phpversion(), '5.3.8', '>')) { if ($targetType !== $originalTargetType && is_a($targetType, $originalTargetType, TRUE) === FALSE) { throw new \TYPO3\Flow\Property\Exception\InvalidDataTypeException('The given type "' . $targetType . '" is not a subtype of "' . $originalTargetType . '".', 1317048056); } } else { $targetType = $this->checkInheritanceChainWithoutIsA($targetType, $originalTargetType); } } return $targetType; }
/** * Handle the case if $source is an array. * * @param array $source * @param string $targetType * @param array $convertedChildProperties * @param PropertyMappingConfigurationInterface $configuration * @return object|TargetNotFoundError * @throws InvalidPropertyMappingConfigurationException */ protected function handleArrayData(array $source, $targetType, array &$convertedChildProperties, PropertyMappingConfigurationInterface $configuration = NULL) { if (!isset($source['__identity'])) { if ($configuration === NULL || $configuration->getConfigurationValue('TYPO3\\Flow\\Property\\TypeConverter\\PersistentObjectConverter', self::CONFIGURATION_CREATION_ALLOWED) !== TRUE) { throw new InvalidPropertyMappingConfigurationException('Creation of objects not allowed. To enable this, you need to set the PropertyMappingConfiguration Value "CONFIGURATION_CREATION_ALLOWED" to TRUE'); } $object = $this->buildObject($convertedChildProperties, $targetType); } elseif ($configuration !== NULL && $configuration->getConfigurationValue('TYPO3\\Flow\\Property\\TypeConverter\\PersistentObjectConverter', self::CONFIGURATION_IDENTITY_CREATION_ALLOWED) === TRUE) { $object = $this->fetchObjectFromPersistence($source['__identity'], $targetType); if ($object === NULL) { $object = $this->buildObject($convertedChildProperties, $targetType); $this->setIdentity($object, $source['__identity']); } } else { $object = $this->fetchObjectFromPersistence($source['__identity'], $targetType); if ($object === NULL) { return new TargetNotFoundError(sprintf('Object of type %s with identity "%s" not found.', $targetType, print_r($source['__identity'], TRUE)), 1412283038); } if (count($convertedChildProperties) > 0 && ($configuration === NULL || $configuration->getConfigurationValue('TYPO3\\Flow\\Property\\TypeConverter\\PersistentObjectConverter', self::CONFIGURATION_MODIFICATION_ALLOWED) !== TRUE)) { throw new 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; }
/** * Determines the target type based on the source's (optional) __type key. * * @param mixed $source * @param string $originalTargetType * @param PropertyMappingConfigurationInterface $configuration * @return string * @throws InvalidDataTypeException * @throws InvalidPropertyMappingConfigurationException * @throws \InvalidArgumentException */ public function getTargetTypeForSource($source, $originalTargetType, PropertyMappingConfigurationInterface $configuration = NULL) { $targetType = $originalTargetType; if (is_array($source) && array_key_exists('__type', $source)) { $targetType = $source['__type']; if ($configuration === NULL) { throw new \InvalidArgumentException('A property mapping configuration must be given, not NULL.', 1326277369); } if ($configuration->getConfigurationValue(\TYPO3\Flow\Property\TypeConverter\ObjectConverter::class, self::CONFIGURATION_OVERRIDE_TARGET_TYPE_ALLOWED) !== TRUE) { throw new InvalidPropertyMappingConfigurationException('Override of target type not allowed. To enable this, you need to set the PropertyMappingConfiguration Value "CONFIGURATION_OVERRIDE_TARGET_TYPE_ALLOWED" to TRUE.', 1317050430); } if ($targetType !== $originalTargetType && is_a($targetType, $originalTargetType, TRUE) === FALSE) { throw new InvalidDataTypeException('The given type "' . $targetType . '" is not a subtype of "' . $originalTargetType . '".', 1317048056); } } return $targetType; }
/** * Helper method to collect configuration for this class. * * @param \TYPO3\Flow\Property\PropertyMappingConfigurationInterface $configuration * @param array $configurationKeys * @return array */ protected function getConfigurationKeysAndValues(\TYPO3\Flow\Property\PropertyMappingConfigurationInterface $configuration, array $configurationKeys) { $keysAndValues = array(); foreach ($configurationKeys as $configurationKey) { $keysAndValues[$configurationKey] = $configuration->getConfigurationValue('TYPO3\\Flow\\Property\\TypeConverter\\FloatConverter', $configurationKey); } return $keysAndValues; }
/** * Handle the case if $source is an array. * * @param array $source * @param string $targetType * @param array $convertedChildProperties * @param PropertyMappingConfigurationInterface $configuration * @return object|TargetNotFoundError * @throws InvalidPropertyMappingConfigurationException */ protected function handleArrayData(array $source, $targetType, array &$convertedChildProperties, PropertyMappingConfigurationInterface $configuration = null) { if (!isset($source['__identity'])) { if ($this->reflectionService->isClassAnnotatedWith($targetType, \TYPO3\Flow\Annotations\ValueObject::class) === true) { // Allow creation for ValueObjects by default, but prevent if explicitly disallowed if ($configuration !== null && $configuration->getConfigurationValue(\TYPO3\Flow\Property\TypeConverter\PersistentObjectConverter::class, self::CONFIGURATION_CREATION_ALLOWED) === false) { throw new InvalidPropertyMappingConfigurationException('Creation of value objects not allowed. To enable this, you need to set the PropertyMappingConfiguration Value "CONFIGURATION_CREATION_ALLOWED" to TRUE'); } } elseif ($configuration === null || $configuration->getConfigurationValue(\TYPO3\Flow\Property\TypeConverter\PersistentObjectConverter::class, self::CONFIGURATION_CREATION_ALLOWED) !== true) { throw new InvalidPropertyMappingConfigurationException('Creation of objects not allowed. To enable this, you need to set the PropertyMappingConfiguration Value "CONFIGURATION_CREATION_ALLOWED" to TRUE'); } $object = $this->buildObject($convertedChildProperties, $targetType); } elseif ($configuration !== null && $configuration->getConfigurationValue(\TYPO3\Flow\Property\TypeConverter\PersistentObjectConverter::class, self::CONFIGURATION_IDENTITY_CREATION_ALLOWED) === true) { $object = $this->fetchObjectFromPersistence($source['__identity'], $targetType); if ($object === null) { $object = $this->buildObject($convertedChildProperties, $targetType); $this->setIdentity($object, $source['__identity']); } } else { $object = $this->fetchObjectFromPersistence($source['__identity'], $targetType); if ($object === null) { return new TargetNotFoundError(sprintf('Object of type %s with identity "%s" not found.', $targetType, print_r($source['__identity'], true)), 1412283038); } if (count($convertedChildProperties) > 0 && ($configuration === null || $configuration->getConfigurationValue(\TYPO3\Flow\Property\TypeConverter\PersistentObjectConverter::class, self::CONFIGURATION_MODIFICATION_ALLOWED) !== true)) { throw new 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; }
/** * Handle the case if $source is an array. * * @param array $source * @param string $targetType * @param array $convertedChildProperties * @param \TYPO3\Flow\Property\PropertyMappingConfigurationInterface $configuration * @return object * @throws \TYPO3\Flow\Property\Exception\InvalidDataTypeException * @throws \TYPO3\Flow\Property\Exception\InvalidPropertyMappingConfigurationException */ protected function handleArrayData(array $source, $targetType, array &$convertedChildProperties, \TYPO3\Flow\Property\PropertyMappingConfigurationInterface $configuration = NULL) { $effectiveTargetType = $targetType; if (isset($source['__identity'])) { $object = $this->fetchObjectFromPersistence($source['__identity'], $effectiveTargetType); if (count($source) > 1 && ($configuration === NULL || $configuration->getConfigurationValue('TYPO3\\Flow\\Property\\TypeConverter\\PersistentObjectConverter', self::CONFIGURATION_MODIFICATION_ALLOWED) !== TRUE)) { throw new \TYPO3\Flow\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); } } else { if ($configuration === NULL || $configuration->getConfigurationValue('TYPO3\\Flow\\Property\\TypeConverter\\PersistentObjectConverter', self::CONFIGURATION_CREATION_ALLOWED) !== TRUE) { throw new \TYPO3\Flow\Property\Exception\InvalidPropertyMappingConfigurationException('Creation of objects not allowed. To enable this, you need to set the PropertyMappingConfiguration Value "CONFIGURATION_CREATION_ALLOWED" to TRUE'); } $object = $this->buildObject($convertedChildProperties, $effectiveTargetType); } if ($effectiveTargetType !== $targetType && !$object instanceof $targetType) { throw new \TYPO3\Flow\Property\Exception\InvalidDataTypeException('The given type "' . $effectiveTargetType . '" is not a subtype of "' . $targetType . '"', 1317048056); } return $object; }
/** * Helper method to collect configuration for this class. * * @param PropertyMappingConfigurationInterface $configuration * @param array $configurationKeys * @return array */ protected function getConfigurationKeysAndValues(PropertyMappingConfigurationInterface $configuration, array $configurationKeys) { $keysAndValues = []; foreach ($configurationKeys as $configurationKey) { $keysAndValues[$configurationKey] = $configuration->getConfigurationValue(FloatConverter::class, $configurationKey); } return $keysAndValues; }