public function convertFrom($source, $targetType, array $convertedChildProperties = [], PropertyMappingConfigurationInterface $configuration = null)
{
if (is_array($source)) {
if ($this->reflectionService->isClassAnnotatedWith($targetType, ValueObject::class)) {
if (isset($source['__identity']) && count($source) > 1) {
// @TODO fix that in the URI building and transfer VOs as values instead as with their identities
// Unset identity for value objects to use constructor mapping, since the identity is determined from
// property values after construction
unset($source['__identity']);
}
}
$object = $this->handleArrayData($source, $targetType, $convertedChildProperties, $configuration);
if ($object instanceof TargetNotFoundError) {
return $object;
}
} elseif (is_string($source)) {
if ($source === '') {
return null;
}
$object = $this->fetchObjectFromPersistence($source, $targetType);
if ($object === null) {
return new TargetNotFoundError(sprintf('Object of type "%s" with identity "%s" not found.', $targetType, $source), 1412283033);
}
} else {
throw new \InvalidArgumentException('Only strings and arrays are accepted.', 1305630314);
}
$objectConstructorArguments = $this->getConstructorArgumentsForClass(TypeHandling::getTypeForValue($object));
foreach ($convertedChildProperties as $propertyName => $propertyValue) {
// We need to check for "immutable" constructor arguments that have no setter and remove them.
if (isset($objectConstructorArguments[$propertyName]) && !ObjectAccess::isPropertySettable($object, $propertyName)) {
$currentPropertyValue = ObjectAccess::getProperty($object, $propertyName);
if ($currentPropertyValue === $propertyValue) {
continue;
} else {
$exceptionMessage = sprintf('Property "%s" having a value of type "%s" could not be set in target object of type "%s". The property has no setter and is not equal to the value in the object, in that case it would have been skipped.', $propertyName, is_object($propertyValue) ? TypeHandling::getTypeForValue($propertyValue) : gettype($propertyValue), $targetType);
throw new InvalidTargetException($exceptionMessage, 1421498771);
}
}
$result = ObjectAccess::setProperty($object, $propertyName, $propertyValue);
if ($result === false) {
$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) ? TypeHandling::getTypeForValue($propertyValue) : gettype($propertyValue), $targetType);
throw new InvalidTargetException($exceptionMessage, 1297935345);
}
}
return $object;
}