/Classes/Property/TypeConverter/ObjectConverter.php
https://github.com/arbyte/FLOW3-X-TYPO3.FLOW3 · PHP · 176 lines · 73 code · 20 blank · 83 comment · 12 complexity · 07db818b74e09aa360ab99048dffe7d2 MD5 · raw file
- <?php
- namespace TYPO3\FLOW3\Property\TypeConverter;
- /* *
- * This script belongs to the FLOW3 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! *
- * */
- use TYPO3\FLOW3\Annotations as FLOW3;
- /**
- * This converter transforms arrays to simple objects (POPO) by setting properties.
- *
- * @api
- * @FLOW3\Scope("singleton")
- */
- class ObjectConverter extends \TYPO3\FLOW3\Property\TypeConverter\AbstractTypeConverter {
- /**
- * @var integer
- */
- const CONFIGURATION_TARGET_TYPE = 3;
- /**
- * @var array
- */
- protected $sourceTypes = array('array');
- /**
- * @var strng
- */
- protected $targetType = 'object';
- /**
- * @var integer
- */
- protected $priority = 0;
- /**
- * @var \TYPO3\FLOW3\Object\ObjectManagerInterface
- */
- protected $objectManager;
- /**
- * @var \TYPO3\FLOW3\Reflection\ReflectionService
- */
- protected $reflectionService;
- /**
- * @param \TYPO3\FLOW3\Object\ObjectManagerInterface $objectManager
- * @return void
- */
- public function injectObjectManager(\TYPO3\FLOW3\Object\ObjectManagerInterface $objectManager) {
- $this->objectManager = $objectManager;
- }
- /**
- * @param \TYPO3\FLOW3\Reflection\ReflectionService $reflectionService
- * @return void
- */
- public function injectReflectionService(\TYPO3\FLOW3\Reflection\ReflectionService $reflectionService) {
- $this->reflectionService = $reflectionService;
- }
- /**
- * Only convert non-persistent types
- *
- * @param mixed $source
- * @param string $targetType
- * @return boolean
- */
- public function canConvertFrom($source, $targetType) {
- $isValueObject = $this->reflectionService->isClassTaggedWith($targetType, 'valueobject');
- $isEntity = $this->reflectionService->isClassTaggedWith($targetType, 'entity');
- return !($isEntity || $isValueObject);
- }
- /**
- * Convert all properties in the source array
- *
- * @param mixed $source
- * @return array
- */
- public function getSourceChildPropertiesToBeConverted($source) {
- return $source;
- }
- /**
- * The type of a property is determined by the reflection service.
- *
- * @param string $targetType
- * @param string $propertyName
- * @param \TYPO3\FLOW3\Property\PropertyMappingConfigurationInterface $configuration
- * @return string
- */
- public function getTypeOfChildProperty($targetType, $propertyName, \TYPO3\FLOW3\Property\PropertyMappingConfigurationInterface $configuration) {
- $configuredTargetType = $configuration->getConfigurationFor($propertyName)->getConfigurationValue('TYPO3\FLOW3\Property\TypeConverter\ObjectConverter', self::CONFIGURATION_TARGET_TYPE);
- if ($configuredTargetType !== NULL) {
- return $configuredTargetType;
- }
- if ($this->reflectionService->hasMethod($targetType, \TYPO3\FLOW3\Reflection\ObjectAccess::buildSetterMethodName($propertyName))) {
- $methodParameters = $this->reflectionService->getMethodParameters($targetType, \TYPO3\FLOW3\Reflection\ObjectAccess::buildSetterMethodName($propertyName));
- $methodParameter = current($methodParameters);
- if (!isset($methodParameter['type'])) {
- throw new \TYPO3\FLOW3\Property\Exception\InvalidTargetException('Setter for property "' . $propertyName . '" had no type hint or documentation in target object of type "' . $targetType . '".', 1303379158);
- } else {
- return $methodParameter['type'];
- }
- } else {
- $methodParameters = $this->reflectionService->getMethodParameters($targetType, '__construct');
- if (isset($methodParameters[$propertyName]) && isset($methodParameters[$propertyName]['type'])) {
- return $methodParameters[$propertyName]['type'];
- } else {
- throw new \TYPO3\FLOW3\Property\Exception\InvalidTargetException('Property "' . $propertyName . '" had no setter or constructor argument in target object of type "' . $targetType . '".', 1303379126);
- }
- }
- }
- /**
- * Convert an object from $source to an object.
- *
- * @param mixed $source
- * @param string $targetType
- * @param array $convertedChildProperties
- * @param \TYPO3\FLOW3\Property\PropertyMappingConfigurationInterface $configuration
- * @return object the target type
- */
- public function convertFrom($source, $targetType, array $convertedChildProperties = array(), \TYPO3\FLOW3\Property\PropertyMappingConfigurationInterface $configuration = NULL) {
- $object = $this->buildObject($convertedChildProperties, $targetType);
- foreach ($convertedChildProperties as $propertyName => $propertyValue) {
- $result = \TYPO3\FLOW3\Reflection\ObjectAccess::setProperty($object, $propertyName, $propertyValue);
- if ($result === FALSE) {
- throw new \TYPO3\FLOW3\Property\Exception\InvalidTargetException('Property "' . $propertyName . '" could not be set in target object of type "' . $targetType . '".', 1304538165);
- }
- }
- return $object;
- }
- /**
- * Builds a new instance of $objectType with the given $possibleConstructorArgumentValues.
- * If constructor argument values are missing from the given array the method looks for a
- * default value in the constructor signature.
- *
- * Furthermore, the constructor arguments are removed from $possibleConstructorArgumentValues
- *
- * @param array &$possibleConstructorArgumentValues
- * @param string $objectType
- * @return object The created instance
- * @throws \TYPO3\FLOW3\Property\Exception\InvalidTargetException if a required constructor argument is missing
- */
- protected function buildObject(array &$possibleConstructorArgumentValues, $objectType) {
- $constructorSignature = $this->reflectionService->getMethodParameters($objectType, '__construct');
- $constructorArguments = array();
- foreach ($constructorSignature as $constructorArgumentName => $constructorArgumentInformation) {
- if (array_key_exists($constructorArgumentName, $possibleConstructorArgumentValues)) {
- $constructorArguments[] = $possibleConstructorArgumentValues[$constructorArgumentName];
- unset($possibleConstructorArgumentValues[$constructorArgumentName]);
- } elseif ($constructorArgumentInformation['optional'] === TRUE) {
- $constructorArguments[] = $constructorArgumentInformation['defaultValue'];
- } else {
- throw new \TYPO3\FLOW3\Property\Exception\InvalidTargetException('Missing constructor argument "' . $constructorArgumentName . '" for object of type "' . $objectType . '".' , 1304538168);
- }
- }
- return call_user_func_array(array($this->objectManager, 'create'), array_merge(array($objectType), $constructorArguments));
- }
- }
- ?>