diff --git a/src/LiveComponent/src/DependencyInjection/LiveComponentExtension.php b/src/LiveComponent/src/DependencyInjection/LiveComponentExtension.php index 7638a02b9ef..2e168c9d5bb 100644 --- a/src/LiveComponent/src/DependencyInjection/LiveComponentExtension.php +++ b/src/LiveComponent/src/DependencyInjection/LiveComponentExtension.php @@ -101,7 +101,7 @@ function (ChildDefinition $definition, AsLiveComponent $attribute) { tagged_iterator(LiveComponentBundle::HYDRATION_EXTENSION_TAG), new Reference('property_accessor'), new Reference('ux.live_component.metadata_factory'), - new Reference('serializer'), + new Reference('serializer', ContainerInterface::NULL_ON_INVALID_REFERENCE), '%kernel.secret%', ]) ; diff --git a/src/LiveComponent/src/LiveComponentHydrator.php b/src/LiveComponent/src/LiveComponentHydrator.php index a66c14d0d45..fdb2d272b68 100644 --- a/src/LiveComponent/src/LiveComponentHydrator.php +++ b/src/LiveComponent/src/LiveComponentHydrator.php @@ -50,8 +50,8 @@ public function __construct( private iterable $hydrationExtensions, private PropertyAccessorInterface $propertyAccessor, private LiveComponentMetadataFactory $liveComponentMetadataFactory, - private NormalizerInterface|DenormalizerInterface $normalizer, - private string $secret + private NormalizerInterface|DenormalizerInterface|null $serializer, + private string $secret, ) { } @@ -357,8 +357,14 @@ private function dehydrateValue(mixed $value, LivePropMetadata $propMetadata, ob if (!interface_exists(NormalizerInterface::class)) { throw new \LogicException(sprintf('The LiveProp "%s" on component "%s" has "useSerializerForHydration: true", but the Serializer component is not installed. Try running "composer require symfony/serializer".', $propMetadata->getName(), $parentObject::class)); } + if (null === $this->serializer) { + throw new \LogicException(sprintf('The LiveProp "%s" on component "%s" has "useSerializerForHydration: true", but no serializer has been set.', $propMetadata->getName(), $parentObject::class)); + } + if (!$this->serializer instanceof NormalizerInterface) { + throw new \LogicException(sprintf('The LiveProp "%s" on component "%s" has "useSerializerForHydration: true", but the given serializer does not implement NormalizerInterface.', $propMetadata->getName(), $parentObject::class)); + } - return $this->normalizer->normalize($value, 'json', $propMetadata->serializationContext()); + return $this->serializer->normalize($value, 'json', $propMetadata->serializationContext()); } if (\is_bool($value) || null === $value || is_numeric($value) || \is_string($value)) { @@ -438,8 +444,14 @@ private function hydrateValue(mixed $value, LivePropMetadata $propMetadata, obje if (!interface_exists(DenormalizerInterface::class)) { throw new \LogicException(sprintf('The LiveProp "%s" on component "%s" has "useSerializerForHydration: true", but the Serializer component is not installed. Try running "composer require symfony/serializer".', $propMetadata->getName(), $parentObject::class)); } + if (null === $this->serializer) { + throw new \LogicException(sprintf('The LiveProp "%s" on component "%s" has "useSerializerForHydration: true", but no serializer has been set.', $propMetadata->getName(), $parentObject::class)); + } + if (!$this->serializer instanceof DenormalizerInterface) { + throw new \LogicException(sprintf('The LiveProp "%s" on component "%s" has "useSerializerForHydration: true", but the given serializer does not implement DenormalizerInterface.', $propMetadata->getName(), $parentObject::class)); + } - return $this->normalizer->denormalize($value, $propMetadata->getType(), 'json', $propMetadata->serializationContext()); + return $this->serializer->denormalize($value, $propMetadata->getType(), 'json', $propMetadata->serializationContext()); } if ($propMetadata->collectionValueType() && Type::BUILTIN_TYPE_OBJECT === $propMetadata->collectionValueType()->getBuiltinType()) {