Skip to main content
Drupal API
User account menu
  • Log in

Breadcrumb

  1. Drupal Core 11.1.x
  2. AbstractNormalizer.php

function AbstractNormalizer::instantiateObject

Instantiates an object using constructor parameters when needed.

This method also allows to denormalize data into an existing object if it is present in the context with the object_to_populate. This object is removed from the context before being returned to avoid side effects when recursively normalizing an object graph.

Throws

RuntimeException

MissingConstructorArgumentsException

2 calls to AbstractNormalizer::instantiateObject()
AbstractObjectNormalizer::instantiateObject in vendor/symfony/serializer/Normalizer/AbstractObjectNormalizer.php
Instantiates an object using constructor parameters when needed.
AbstractObjectNormalizer::instantiateObject in vendor/symfony/serializer/Normalizer/AbstractObjectNormalizer.php
Instantiates an object using constructor parameters when needed.
1 method overrides AbstractNormalizer::instantiateObject()
AbstractObjectNormalizer::instantiateObject in vendor/symfony/serializer/Normalizer/AbstractObjectNormalizer.php
Instantiates an object using constructor parameters when needed.

File

vendor/symfony/serializer/Normalizer/AbstractNormalizer.php, line 312

Class

AbstractNormalizer
Normalizer implementation.

Namespace

Symfony\Component\Serializer\Normalizer

Code

protected function instantiateObject(array &$data, string $class, array &$context, \ReflectionClass $reflectionClass, array|bool $allowedAttributes, ?string $format = null) : object {
    if (null !== ($object = $this->extractObjectToPopulate($class, $context, self::OBJECT_TO_POPULATE))) {
        unset($context[self::OBJECT_TO_POPULATE]);
        return $object;
    }
    // clean up even if no match
    unset($context[static::OBJECT_TO_POPULATE]);
    $constructor = $this->getConstructor($data, $class, $context, $reflectionClass, $allowedAttributes);
    if ($constructor) {
        $context['has_constructor'] = true;
        if (true !== $constructor->isPublic()) {
            return $reflectionClass->newInstanceWithoutConstructor();
        }
        $constructorParameters = $constructor->getParameters();
        $missingConstructorArguments = [];
        $params = [];
        $unsetKeys = [];
        foreach ($constructorParameters as $constructorParameter) {
            $paramName = $constructorParameter->name;
            $attributeContext = $this->getAttributeDenormalizationContext($class, $paramName, $context);
            $key = $this->nameConverter ? $this->nameConverter
                ->normalize($paramName, $class, $format, $context) : $paramName;
            $allowed = false === $allowedAttributes || \in_array($paramName, $allowedAttributes, true);
            $ignored = !$this->isAllowedAttribute($class, $paramName, $format, $context);
            if ($constructorParameter->isVariadic()) {
                if ($allowed && !$ignored && (isset($data[$key]) || \array_key_exists($key, $data))) {
                    if (!\is_array($data[$key])) {
                        throw new RuntimeException(\sprintf('Cannot create an instance of "%s" from serialized data because the variadic parameter "%s" can only accept an array.', $class, $constructorParameter->name));
                    }
                    $variadicParameters = [];
                    foreach ($data[$key] as $parameterKey => $parameterData) {
                        try {
                            $variadicParameters[$parameterKey] = $this->denormalizeParameter($reflectionClass, $constructorParameter, $paramName, $parameterData, $attributeContext, $format);
                        } catch (NotNormalizableValueException $exception) {
                            if (!isset($context['not_normalizable_value_exceptions'])) {
                                throw $exception;
                            }
                            $context['not_normalizable_value_exceptions'][] = $exception;
                            $params[$paramName] = $parameterData;
                        }
                    }
                    $params = array_merge(array_values($params), $variadicParameters);
                    $unsetKeys[] = $key;
                }
            }
            elseif ($allowed && !$ignored && (isset($data[$key]) || \array_key_exists($key, $data))) {
                $parameterData = $data[$key];
                if (null === $parameterData && $constructorParameter->allowsNull()) {
                    $params[$paramName] = null;
                    $unsetKeys[] = $key;
                    continue;
                }
                try {
                    $params[$paramName] = $this->denormalizeParameter($reflectionClass, $constructorParameter, $paramName, $parameterData, $attributeContext, $format);
                } catch (NotNormalizableValueException $exception) {
                    if (!isset($context['not_normalizable_value_exceptions'])) {
                        throw $exception;
                    }
                    $context['not_normalizable_value_exceptions'][] = $exception;
                    $params[$paramName] = $parameterData;
                }
                $unsetKeys[] = $key;
            }
            elseif (\array_key_exists($key, $context[static::DEFAULT_CONSTRUCTOR_ARGUMENTS][$class] ?? [])) {
                $params[$paramName] = $context[static::DEFAULT_CONSTRUCTOR_ARGUMENTS][$class][$key];
            }
            elseif (\array_key_exists($key, $this->defaultContext[self::DEFAULT_CONSTRUCTOR_ARGUMENTS][$class] ?? [])) {
                $params[$paramName] = $this->defaultContext[self::DEFAULT_CONSTRUCTOR_ARGUMENTS][$class][$key];
            }
            elseif ($constructorParameter->isDefaultValueAvailable()) {
                $params[$paramName] = $constructorParameter->getDefaultValue();
            }
            elseif (!($context[self::REQUIRE_ALL_PROPERTIES] ?? $this->defaultContext[self::REQUIRE_ALL_PROPERTIES] ?? false) && $constructorParameter->hasType() && $constructorParameter->getType()
                ->allowsNull()) {
                $params[$paramName] = null;
            }
            else {
                if (!isset($context['not_normalizable_value_exceptions'])) {
                    $missingConstructorArguments[] = $constructorParameter->name;
                    continue;
                }
                $constructorParameterType = 'unknown';
                $reflectionType = $constructorParameter->getType();
                if ($reflectionType instanceof \ReflectionNamedType) {
                    $constructorParameterType = $reflectionType->getName();
                }
                $exception = NotNormalizableValueException::createForUnexpectedDataType(\sprintf('Failed to create object because the class misses the "%s" property.', $constructorParameter->name), null, [
                    $constructorParameterType,
                ], $attributeContext['deserialization_path'] ?? null, true);
                $context['not_normalizable_value_exceptions'][] = $exception;
            }
        }
        if ($missingConstructorArguments) {
            throw new MissingConstructorArgumentsException(\sprintf('Cannot create an instance of "%s" from serialized data because its constructor requires the following parameters to be present : "$%s".', $class, implode('", "$', $missingConstructorArguments)), 0, null, $missingConstructorArguments, $class);
        }
        if (!$constructor->isConstructor()) {
            $instance = $constructor->invokeArgs(null, $params);
            // do not set a parameter that has been set in the constructor
            foreach ($unsetKeys as $key) {
                unset($data[$key]);
            }
            return $instance;
        }
        try {
            $instance = $reflectionClass->newInstanceArgs($params);
            // do not set a parameter that has been set in the constructor
            foreach ($unsetKeys as $key) {
                unset($data[$key]);
            }
            return $instance;
        } catch (\TypeError $e) {
            if (!isset($context['not_normalizable_value_exceptions'])) {
                throw $e;
            }
            return $reflectionClass->newInstanceWithoutConstructor();
        }
    }
    unset($context['has_constructor']);
    if (!$reflectionClass->isInstantiable()) {
        throw NotNormalizableValueException::createForUnexpectedDataType(\sprintf('Failed to create object because the class "%s" is not instantiable.', $class), $data, [
            'unknown',
        ], $context['deserialization_path'] ?? null);
    }
    return new $class();
}

API Navigation

  • Drupal Core 11.1.x
  • Topics
  • Classes
  • Functions
  • Constants
  • Globals
  • Files
  • Namespaces
  • Deprecated
  • Services
RSS feed
Powered by Drupal