diff --git a/src/LiveComponent/src/Util/QueryStringPropsExtractor.php b/src/LiveComponent/src/Util/QueryStringPropsExtractor.php index d94dbb92f23..101a885bf03 100644 --- a/src/LiveComponent/src/Util/QueryStringPropsExtractor.php +++ b/src/LiveComponent/src/Util/QueryStringPropsExtractor.php @@ -12,8 +12,10 @@ namespace Symfony\UX\LiveComponent\Util; use Symfony\Component\HttpFoundation\Request; +use Symfony\UX\LiveComponent\Exception\HydrationException; use Symfony\UX\LiveComponent\LiveComponentHydrator; use Symfony\UX\LiveComponent\Metadata\LiveComponentMetadata; +use Symfony\UX\LiveComponent\Metadata\LivePropMetadata; /** * @author Nicolas Rigaud @@ -46,12 +48,21 @@ public function extract(Request $request, LiveComponentMetadata $metadata, objec if (\is_array($value) && $this->isNumericIndexedArray($value)) { // Sort numeric array ksort($value); - } elseif (('' === $value) && (!$livePropMetadata->isBuiltIn() || 'array' === $livePropMetadata->getType())) { + } elseif ('' === $value && null !== $livePropMetadata->getType() && (!$livePropMetadata->isBuiltIn() || 'array' === $livePropMetadata->getType())) { // Cast empty string to empty array for objects and arrays $value = []; } - $data[$livePropMetadata->getName()] = $this->hydrator->hydrateValue($value, $livePropMetadata, $component); + try { + $hydratedValue = $this->hydrator->hydrateValue($value, $livePropMetadata, $component); + + if ($this->isValueTypeConsistent($hydratedValue, $livePropMetadata)) { + // Only set data if hydrated value type is consistent with prop metadata type + $data[$livePropMetadata->getName()] = $hydratedValue; + } + } catch (HydrationException) { + // Skip hydration errors (e.g. with objects) + } } } } @@ -63,4 +74,14 @@ private function isNumericIndexedArray(array $array): bool { return 0 === \count(array_filter(array_keys($array), 'is_string')); } + + private function isValueTypeConsistent(mixed $value, LivePropMetadata $livePropMetadata): bool + { + $propType = $livePropMetadata->getType(); + + return + \in_array($propType, [null, 'mixed']) + || $livePropMetadata->isBuiltIn() && ('\is_'.$propType)($value) + || !$livePropMetadata->isBuiltIn() && $value instanceof $propType; + } }