‪TYPO3CMS  ‪main
PersistentObjectConverter.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
20 use Symfony\Component\PropertyInfo\Type;
30 
44 {
49 
54 
58  protected ‪$persistenceManager;
59 
64  {
65  $this->persistenceManager = ‪$persistenceManager;
66  }
67 
74  public function ‪getSourceChildPropertiesToBeConverted($source): array
75  {
76  if (is_string($source) || is_int($source)) {
77  return [];
78  }
79  if (isset($source['__identity'])) {
80  unset($source['__identity']);
81  }
82  return parent::getSourceChildPropertiesToBeConverted($source);
83  }
84 
92  public function ‪getTypeOfChildProperty($targetType, string $propertyName, PropertyMappingConfigurationInterface $configuration): string
93  {
94  $configuredTargetType = $configuration->getConfigurationFor($propertyName)->getConfigurationValue(\‪TYPO3\CMS\‪Extbase\Property\TypeConverter\PersistentObjectConverter::class, self::CONFIGURATION_TARGET_TYPE);
95  if ($configuredTargetType !== null) {
96  return $configuredTargetType;
97  }
98 
99  $schema = $this->reflectionService->getClassSchema($targetType);
100  if (!$schema->hasProperty($propertyName)) {
101  throw new InvalidTargetException('Property "' . $propertyName . '" was not found in target object of type "' . $targetType . '".', 1297978366);
102  }
103  $primaryType = $schema->getProperty($propertyName)->getPrimaryType();
104  if (!$primaryType instanceof Type) {
105  throw ‪NoPropertyTypesException::create($targetType, $propertyName);
106  }
107 
108  $type = $primaryType->getClassName() ?? $primaryType->getBuiltinType();
109  if ($primaryType->isCollection() && $primaryType->getCollectionValueTypes() !== []) {
110  $primaryCollectionValueType = $primaryType->getCollectionValueTypes()[0];
111  $collectionValueType = $primaryCollectionValueType->getClassName() ?? $primaryCollectionValueType->getBuiltinType();
112  $type .= '<' . $collectionValueType . '>';
113  }
114 
115  return $type;
116  }
117 
127  public function ‪convertFrom($source, string $targetType, array $convertedChildProperties = [], PropertyMappingConfigurationInterface $configuration = null): ?object
128  {
129  if (is_array($source)) {
130  if (
131  class_exists($targetType)
132  && is_subclass_of($targetType, AbstractValueObject::class)
133  ) {
134  // Unset identity for valueobject to use constructor mapping, since the identity is determined from
135  // constructor arguments
136  unset($source['__identity']);
137  }
138  $object = $this->‪handleArrayData($source, $targetType, $convertedChildProperties, $configuration);
139  } elseif (is_string($source) || is_int($source)) {
140  if (empty($source)) {
141  return null;
142  }
143  $object = $this->‪fetchObjectFromPersistence($source, $targetType);
144  } else {
145  // todo: this case is impossible as this converter is never called with a source that is not an integer, a string or an array
146  throw new \InvalidArgumentException('Only integers, strings and arrays are accepted.', 1305630314);
147  }
148  foreach ($convertedChildProperties as $propertyName => $propertyValue) {
149  $result = ‪ObjectAccess::setProperty($object, $propertyName, $propertyValue);
150  if ($result === false) {
151  $exceptionMessage = sprintf(
152  '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.',
153  $propertyName,
154  get_debug_type($propertyValue),
155  $targetType
156  );
157  throw new InvalidTargetException($exceptionMessage, 1297935345);
158  }
159  }
160 
161  return $object;
162  }
163 
169  protected function ‪handleArrayData(array $source, string $targetType, array &$convertedChildProperties, PropertyMappingConfigurationInterface $configuration = null): object
170  {
171  if (isset($source['__identity'])) {
172  $object = $this->‪fetchObjectFromPersistence($source['__identity'], $targetType);
173 
174  if (count($source) > 1 && ($configuration === null || $configuration->getConfigurationValue(\‪TYPO3\CMS\‪Extbase\Property\TypeConverter\PersistentObjectConverter::class, self::CONFIGURATION_MODIFICATION_ALLOWED) !== true)) {
175  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);
176  }
177  } else {
178  if ($configuration === null || $configuration->getConfigurationValue(\‪TYPO3\CMS\‪Extbase\Property\TypeConverter\PersistentObjectConverter::class, self::CONFIGURATION_CREATION_ALLOWED) !== true) {
179  throw new InvalidPropertyMappingConfigurationException(
180  'Creation of objects not allowed. To enable this, you need to set the PropertyMappingConfiguration Value "CONFIGURATION_CREATION_ALLOWED" to TRUE',
181  1476044961
182  );
183  }
184  $object = $this->‪buildObject($convertedChildProperties, $targetType);
185  }
186  return $object;
187  }
188 
196  protected function ‪fetchObjectFromPersistence($identity, string $targetType): object
197  {
198  if (ctype_digit((string)$identity)) {
199  $object = $this->persistenceManager->getObjectByIdentifier($identity, $targetType);
200  } else {
201  throw new InvalidSourceException('The identity property "' . $identity . '" is no UID.', 1297931020);
202  }
203 
204  if ($object === null) {
205  throw new TargetNotFoundException(sprintf('Object of type %s with identity "%s" not found.', $targetType, print_r($identity, true)), 1297933823);
206  }
207 
208  return $object;
209  }
210 }
‪TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface\getConfigurationValue
‪mixed getConfigurationValue($typeConverterClassName, $key)
‪TYPO3\CMS\Extbase\Property\TypeConverter\ObjectConverter\buildObject
‪object buildObject(array &$possibleConstructorArgumentValues, string $objectType)
Definition: ObjectConverter.php:203
‪TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter\getSourceChildPropertiesToBeConverted
‪getSourceChildPropertiesToBeConverted($source)
Definition: PersistentObjectConverter.php:73
‪TYPO3\CMS\Extbase\Persistence\PersistenceManagerInterface
Definition: PersistenceManagerInterface.php:24
‪TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface\getConfigurationFor
‪TYPO3 CMS Extbase Property PropertyMappingConfigurationInterface getConfigurationFor($propertyName)
‪TYPO3\CMS\Extbase\Annotation
Definition: IgnoreValidation.php:18
‪TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter\getTypeOfChildProperty
‪getTypeOfChildProperty($targetType, string $propertyName, PropertyMappingConfigurationInterface $configuration)
Definition: PersistentObjectConverter.php:91
‪TYPO3\CMS\Extbase\Reflection\ObjectAccess\setProperty
‪static bool setProperty(object|array &$subject, string $propertyName, mixed $propertyValue)
Definition: ObjectAccess.php:158
‪TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter\$persistenceManager
‪TYPO3 CMS Extbase Persistence PersistenceManagerInterface $persistenceManager
Definition: PersistentObjectConverter.php:57
‪TYPO3
‪TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter\convertFrom
‪object null convertFrom($source, string $targetType, array $convertedChildProperties=[], PropertyMappingConfigurationInterface $configuration=null)
Definition: PersistentObjectConverter.php:126
‪TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter\fetchObjectFromPersistence
‪fetchObjectFromPersistence($identity, string $targetType)
Definition: PersistentObjectConverter.php:195
‪TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter\handleArrayData
‪handleArrayData(array $source, string $targetType, array &$convertedChildProperties, PropertyMappingConfigurationInterface $configuration=null)
Definition: PersistentObjectConverter.php:168
‪TYPO3\CMS\Extbase\Reflection\ClassSchema\Exception\NoPropertyTypesException
Definition: NoPropertyTypesException.php:24
‪TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface
Definition: PropertyMappingConfigurationInterface.php:22
‪TYPO3\CMS\Extbase\Reflection\ObjectAccess
Definition: ObjectAccess.php:39
‪TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter\injectPersistenceManager
‪injectPersistenceManager(PersistenceManagerInterface $persistenceManager)
Definition: PersistentObjectConverter.php:62
‪TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter\CONFIGURATION_CREATION_ALLOWED
‪const CONFIGURATION_CREATION_ALLOWED
Definition: PersistentObjectConverter.php:53
‪TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter
Definition: PersistentObjectConverter.php:44
‪TYPO3\CMS\Extbase\Property\TypeConverter
Definition: AbstractFileFolderConverter.php:18
‪TYPO3\CMS\Extbase\DomainObject\AbstractValueObject
Definition: AbstractValueObject.php:26
‪TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter\CONFIGURATION_MODIFICATION_ALLOWED
‪const CONFIGURATION_MODIFICATION_ALLOWED
Definition: PersistentObjectConverter.php:48
‪TYPO3\CMS\Extbase\Property\TypeConverter\ObjectConverter
Definition: ObjectConverter.php:36
‪TYPO3\CMS\Extbase\Property\Exception\InvalidPropertyMappingConfigurationException
Definition: InvalidPropertyMappingConfigurationException.php:25
‪TYPO3\CMS\Extbase\Property\Exception\InvalidTargetException
Definition: InvalidTargetException.php:25
‪TYPO3\CMS\Extbase\Reflection\ClassSchema\Exception\NoPropertyTypesException\create
‪static create(string $className, string $propertyName)
Definition: NoPropertyTypesException.php:25
‪TYPO3\CMS\Extbase\Property\Exception\TargetNotFoundException
Definition: TargetNotFoundException.php:25
‪TYPO3\CMS\Extbase\Property\Exception\InvalidSourceException
Definition: InvalidSourceException.php:25