/**
  * Handle the case if $source is an array.
  *
  * @param array $source
  * @param string $targetType
  * @param array $convertedChildProperties
  * @param \TYPO3\FLOW3\Property\PropertyMappingConfigurationInterface $configuration
  * @return object
  * @throws \TYPO3\FLOW3\Property\Exception\InvalidDataTypeException
  * @throws \TYPO3\FLOW3\Property\Exception\InvalidPropertyMappingConfigurationException
  */
 protected function handleArrayData(array $source, $targetType, array &$convertedChildProperties, \TYPO3\FLOW3\Property\PropertyMappingConfigurationInterface $configuration = NULL)
 {
     $effectiveTargetType = $targetType;
     if (isset($source['__type'])) {
         if ($configuration->getConfigurationValue('TYPO3\\FLOW3\\Property\\TypeConverter\\PersistentObjectConverter', self::CONFIGURATION_OVERRIDE_TARGET_TYPE_ALLOWED) !== TRUE) {
             throw new \TYPO3\FLOW3\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);
         }
         $effectiveTargetType = $source['__type'];
     }
     if (isset($source['__identity'])) {
         $object = $this->fetchObjectFromPersistence($source['__identity'], $effectiveTargetType);
         if (count($source) > 1 && ($configuration === NULL || $configuration->getConfigurationValue('TYPO3\\FLOW3\\Property\\TypeConverter\\PersistentObjectConverter', self::CONFIGURATION_MODIFICATION_ALLOWED) !== TRUE)) {
             throw new \TYPO3\FLOW3\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\\FLOW3\\Property\\TypeConverter\\PersistentObjectConverter', self::CONFIGURATION_CREATION_ALLOWED) !== TRUE) {
             throw new \TYPO3\FLOW3\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\FLOW3\Property\Exception\InvalidDataTypeException('The given type "' . $effectiveTargetType . '" is not a subtype of "' . $targetType . '"', 1317048056);
     }
     return $object;
 }
Example #2
0
 /**
  * Helper method to collect configuration for this class.
  *
  * @param \TYPO3\FLOW3\Property\PropertyMappingConfigurationInterface $configuration
  * @param array $configurationKeys
  * @return array
  */
 protected function getConfigurationKeysAndValues(\TYPO3\FLOW3\Property\PropertyMappingConfigurationInterface $configuration, array $configurationKeys)
 {
     $keysAndValues = array();
     foreach ($configurationKeys as $configurationKey) {
         $keysAndValues[$configurationKey] = $configuration->getConfigurationValue('TYPO3\\FLOW3\\Property\\TypeConverter\\FloatConverter', $configurationKey);
     }
     return $keysAndValues;
 }
Example #3
0
 /**
  * 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\FLOW3\Property\PropertyMappingConfigurationInterface $configuration
  * @return \TYPO3\FLOW3\Property\TypeConverterInterface Type Converter which should be used to convert between $source and $targetType.
  * @throws \TYPO3\FLOW3\Property\Exception\TypeConverterException
  * @throws \TYPO3\FLOW3\Property\Exception\InvalidTargetException
  */
 protected function findTypeConverter($source, $targetType, \TYPO3\FLOW3\Property\PropertyMappingConfigurationInterface $configuration)
 {
     if ($configuration->getTypeConverter() !== NULL) {
         return $configuration->getTypeConverter();
     }
     $sourceType = $this->determineSourceType($source);
     if (!is_string($targetType)) {
         throw new \TYPO3\FLOW3\Property\Exception\InvalidTargetException('The target type was no string, but of type "' . gettype($targetType) . '"', 1297941727);
     }
     if (strpos($targetType, '<') !== FALSE) {
         $targetType = substr($targetType, 0, strpos($targetType, '<'));
     }
     $converter = NULL;
     if (\TYPO3\FLOW3\Utility\TypeHandling::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 ($converter === NULL) {
         throw new \TYPO3\FLOW3\Property\Exception\TypeConverterException('No converter found which can be used to convert from "' . $sourceType . '" to "' . $targetType . '".');
     }
     return $converter;
 }
Example #4
0
 /**
  * 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\FLOW3\Property\PropertyMappingConfigurationInterface $configuration
  * @return string
  * @throws \TYPO3\FLOW3\Property\Exception\InvalidPropertyMappingConfigurationException
  */
 protected function getDefaultDateFormat(\TYPO3\FLOW3\Property\PropertyMappingConfigurationInterface $configuration = NULL)
 {
     if ($configuration === NULL) {
         return self::DEFAULT_DATE_FORMAT;
     }
     $dateFormat = $configuration->getConfigurationValue('TYPO3\\FLOW3\\Property\\TypeConverter\\DateTimeConverter', self::CONFIGURATION_DATE_FORMAT);
     if ($dateFormat === NULL) {
         return self::DEFAULT_DATE_FORMAT;
     } elseif ($dateFormat !== NULL && !is_string($dateFormat)) {
         throw new \TYPO3\FLOW3\Property\Exception\InvalidPropertyMappingConfigurationException('CONFIGURATION_DATE_FORMAT must be of type string, "' . (is_object($dateFormat) ? get_class($dateFormat) : gettype($dateFormat)) . '" given', 1307719569);
     }
     return $dateFormat;
 }
 /**
  * Converts the specified node path into a Node.
  *
  * The node path must be an absolute context node path and can be specified as a string or as an array item with the
  * key "__contextNodePath". The latter case is for updating existing nodes.
  *
  * This conversion method does not support / allow creation of new nodes because new nodes should be created through
  * the createNode() method of an existing reference node.
  *
  * Also note that the context's "current node" is not affected by this object converter, you will need to set it to
  * whatever node your "current" node is, if any.
  *
  * All elements in the source array which start with two underscores (like __contextNodePath) are specially treated
  * by this converter.
  *
  * All elements in the source array which start with a *single underscore (like _hidden) are *directly* set on the Node
  * object.
  *
  * All other elements, not being prefixed with underscore, are properties of the node.
  *
  * @param string|array $source Either a string or array containing the absolute context node path which identifies the node. For example "/sites/mysitecom/homepage/about@user-admin"
  * @param string $targetType not used
  * @param array $subProperties not used
  * @param \TYPO3\FLOW3\Property\PropertyMappingConfigurationInterface $configuration not used
  * @return mixed An object or \TYPO3\FLOW3\Error\Error if the input format is not supported or could not be converted for other reasons
  * @throws \Exception
  */
 public function convertFrom($source, $targetType, array $subProperties = array(), \TYPO3\FLOW3\Property\PropertyMappingConfigurationInterface $configuration = NULL)
 {
     if (is_string($source)) {
         $source = array('__contextNodePath' => $source);
     }
     if (!is_array($source) || !isset($source['__contextNodePath'])) {
         return new Error('Could not convert ' . gettype($source) . ' to Node object, a valid absolute context node path as a string or array is expected.', 1302879936);
     }
     preg_match(NodeInterface::MATCH_PATTERN_CONTEXTPATH, $source['__contextNodePath'], $matches);
     if (!isset($matches['NodePath'])) {
         return new Error('Could not convert array to Node object because the node path was invalid.', 1285162903);
     }
     $nodePath = $matches['NodePath'];
     if ($this->nodeRepository->getContext() === NULL) {
         $workspaceName = isset($matches['WorkspaceName']) ? $matches['WorkspaceName'] : 'live';
         $contentContext = new ContentContext($workspaceName);
         $this->nodeRepository->setContext($contentContext);
     } else {
         $contentContext = $this->nodeRepository->getContext();
         $workspaceName = $contentContext->getWorkspace()->getName();
     }
     if ($workspaceName !== 'live') {
         $contentContext->setInvisibleContentShown(TRUE);
         if ($configuration->getConfigurationValue('TYPO3\\TYPO3\\Routing\\NodeObjectConverter', self::REMOVED_CONTENT_SHOWN) === TRUE) {
             $contentContext->setRemovedContentShown(TRUE);
         }
     }
     $workspace = $contentContext->getWorkspace(FALSE);
     if (!$workspace) {
         return new Error(sprintf('Could not convert %s to Node object because the workspace "%s" as specified in the context node path does not exist.', $source['__contextNodePath'], $workspaceName), 1285162905);
     }
     $currentAccessModeFromContext = $contentContext->isInaccessibleContentShown();
     $contentContext->setInaccessibleContentShown(TRUE);
     $node = $contentContext->getNode($nodePath);
     $contentContext->setInaccessibleContentShown($currentAccessModeFromContext);
     if (!$node) {
         return new Error(sprintf('Could not convert array to Node object because the node "%s" does not exist.', $nodePath), 1285162908);
     }
     $contentTypeProperties = $node->getContentType()->getProperties();
     foreach ($source as $nodePropertyKey => $nodePropertyValue) {
         if (substr($nodePropertyKey, 0, 2) === '__') {
             continue;
         }
         if ($nodePropertyKey[0] === '_') {
             $propertyName = substr($nodePropertyKey, 1);
             // TODO: Hack: we need to create DateTime objects for some properties of Node
             if (($propertyName === 'hiddenBeforeDateTime' || $propertyName === 'hiddenAfterDateTime') && is_string($nodePropertyValue)) {
                 if ($nodePropertyValue !== '') {
                     $nodePropertyValue = \DateTime::createFromFormat('!Y-m-d', $nodePropertyValue);
                 } else {
                     $nodePropertyValue = NULL;
                 }
             }
             \TYPO3\FLOW3\Reflection\ObjectAccess::setProperty($node, $propertyName, $nodePropertyValue);
         } else {
             if (!isset($contentTypeProperties[$nodePropertyKey])) {
                 throw new \Exception('TODO: content type XY does not have a property YY according to the schema');
             }
             if (isset($contentTypeProperties[$nodePropertyKey]['type'])) {
                 $targetType = $contentTypeProperties[$nodePropertyKey]['type'];
                 if ($this->objectManager->isRegistered($targetType)) {
                     $nodePropertyValue = $this->propertyMapper->convert(json_decode($nodePropertyValue, TRUE), $targetType);
                 }
             }
             $node->setProperty($nodePropertyKey, $nodePropertyValue);
         }
     }
     return $node;
 }
Example #6
0
 /**
  * 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
  * @throws \TYPO3\FLOW3\Property\Exception\InvalidTargetException
  * @throws \TYPO3\FLOW3\Property\Exception\InvalidDataTypeException
  * @throws \TYPO3\FLOW3\Property\Exception\InvalidPropertyMappingConfigurationException
  */
 public function convertFrom($source, $targetType, array $convertedChildProperties = array(), \TYPO3\FLOW3\Property\PropertyMappingConfigurationInterface $configuration = NULL)
 {
     $effectiveTargetType = $targetType;
     if (isset($source['__type'])) {
         if ($configuration->getConfigurationValue('TYPO3\\FLOW3\\Property\\TypeConverter\\ObjectConverter', self::CONFIGURATION_OVERRIDE_TARGET_TYPE_ALLOWED) !== TRUE) {
             throw new \TYPO3\FLOW3\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.', 1317051258);
         }
         $effectiveTargetType = $source['__type'];
     }
     $object = $this->buildObject($convertedChildProperties, $effectiveTargetType);
     if ($effectiveTargetType !== $targetType && !$object instanceof $targetType) {
         throw new \TYPO3\FLOW3\Property\Exception\InvalidDataTypeException('The given type "' . $source['__type'] . '" is not a subtype of "' . $targetType . '"', 1317051266);
     }
     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 . '" having a value of type "' . (is_object($propertyValue) ? get_class($propertyValue) : gettype($propertyValue)) . '" could not be set in target object of type "' . $targetType . '".', 1304538165);
         }
     }
     return $object;
 }