Skip to content

Commit 3e030dc

Browse files
committed
[LiveComponent] Remove conflict with symfony/type-info:<7.3, add compatibility layer
1 parent e5f36d3 commit 3e030dc

File tree

3 files changed

+61
-8
lines changed

3 files changed

+61
-8
lines changed

src/LiveComponent/composer.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@
5757
},
5858
"conflict": {
5959
"symfony/config": "<5.4.0",
60-
"symfony/type-info": "<7.3",
6160
"symfony/property-info": "~7.0.0"
6261
},
6362
"config": {

src/LiveComponent/src/LiveComponentHydrator.php

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
use Symfony\UX\LiveComponent\Metadata\LiveComponentMetadataFactory;
3838
use Symfony\UX\LiveComponent\Metadata\LivePropMetadata;
3939
use Symfony\UX\LiveComponent\Util\DehydratedProps;
40+
use Symfony\UX\LiveComponent\Util\TypeHelper;
4041
use Symfony\UX\TwigComponent\ComponentAttributes;
4142
use Twig\Environment;
4243
use Twig\Runtime\EscaperRuntime;
@@ -314,7 +315,7 @@ public function hydrateValue(mixed $value, LivePropMetadata|LegacyLivePropMetada
314315
}
315316

316317
$isCollection = false;
317-
foreach ($type->traverse() as $t) {
318+
foreach (TypeHelper::traverse($type) as $t) {
318319
if ($isCollection = $type instanceof CollectionType) {
319320
$isCollection = true;
320321
$type = $type->getCollectionValueType();
@@ -363,7 +364,7 @@ public function hydrateValue(mixed $value, LivePropMetadata|LegacyLivePropMetada
363364
return $this->hydrateObjectValue($value, $propMetadata->getType(), $propMetadata->allowsNull(), $propMetadata->getFormat(), $parentObject::class, $propMetadata->getName(), $parentObject);
364365
} else {
365366
$collectionValueType = null;
366-
foreach ($type->traverse() as $t) {
367+
foreach (TypeHelper::traverse($type) as $t) {
367368
if ($t instanceof CollectionType) {
368369
$collectionValueType = $t->getCollectionValueType();
369370

@@ -372,7 +373,7 @@ public function hydrateValue(mixed $value, LivePropMetadata|LegacyLivePropMetada
372373
}
373374

374375
if ($collectionValueType) {
375-
foreach ($collectionValueType->traverse() as $t) {
376+
foreach (TypeHelper::traverse($collectionValueType) as $t) {
376377
if ($t instanceof ObjectType) {
377378
foreach ($value as $key => $objectItem) {
378379
$value[$key] = $this->hydrateObjectValue($objectItem, $t->getClassName(), true, $propMetadata->getFormat(), $parentObject::class, \sprintf('%s.%s', $propMetadata->getName(), $key), $parentObject);
@@ -387,7 +388,7 @@ public function hydrateValue(mixed $value, LivePropMetadata|LegacyLivePropMetada
387388
return self::coerceStringValue($value, $type, $type->isNullable());
388389
}
389390

390-
foreach ($type->traverse() as $t) {
391+
foreach (TypeHelper::traverse($type) as $t) {
391392
if ($t instanceof ObjectType) {
392393
return $this->hydrateObjectValue($value, $t->getClassName(), $type->isNullable(), $propMetadata->getFormat(), $parentObject::class, $propMetadata->getName(), $parentObject);
393394
}
@@ -573,15 +574,15 @@ private function dehydrateValue(mixed $value, LivePropMetadata|LegacyLivePropMet
573574
} else {
574575
$collectionValueType = null;
575576

576-
foreach ($propMetadata->getType()?->traverse() ?? [] as $t) {
577+
foreach ($propMetadata->getType() ? TypeHelper::traverse($propMetadata->getType()) : [] as $t) {
577578
if ($t instanceof CollectionType) {
578579
$collectionValueType = $t->getCollectionValueType();
579580

580581
break;
581582
}
582583
}
583584

584-
foreach ($collectionValueType?->traverse() ?? [] as $t) {
585+
foreach ($collectionValueType ? TypeHelper::traverse($collectionValueType) : [] as $t) {
585586
if ($t instanceof ObjectType) {
586587
foreach ($value as $key => $objectItem) {
587588
if (!$t->accepts($objectItem)) {
@@ -618,7 +619,7 @@ private function dehydrateValue(mixed $value, LivePropMetadata|LegacyLivePropMet
618619

619620
return $this->dehydrateObjectValue($value, $propMetadata->getType(), $propMetadata->getFormat(), $parentObject);
620621
} else {
621-
foreach ($propMetadata->getType()?->traverse() ?? [] as $t) {
622+
foreach ($propMetadata->getType() ? TypeHelper::traverse($propMetadata->getType()) : [] as $t) {
622623
if ($t instanceof ObjectType) {
623624
return $this->dehydrateObjectValue($value, $t->getClassName(), $propMetadata->getFormat(), $parentObject);
624625
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\UX\LiveComponent\Util;
13+
14+
use Symfony\Component\TypeInfo\Type;
15+
use Symfony\Component\TypeInfo\Type\CompositeTypeInterface;
16+
use Symfony\Component\TypeInfo\Type\WrappingTypeInterface;
17+
18+
/**
19+
* @author Hugo Alliaume <hugo@alliau.me>
20+
*
21+
* @internal
22+
*/
23+
final class TypeHelper
24+
{
25+
/**
26+
* TODO: To remove when supporting symfony/type-info >=7.3 only.
27+
*
28+
* Traverses the whole type tree.
29+
*
30+
* @return iterable<Type>
31+
*/
32+
public static function traverse(Type $type, bool $traverseComposite = true, bool $traverseWrapped = true): iterable
33+
{
34+
if (method_exists($type, 'traverse')) {
35+
yield from $type->traverse($traverseComposite, $traverseWrapped);
36+
} else {
37+
yield $type;
38+
39+
if ($type instanceof CompositeTypeInterface && $traverseComposite) {
40+
foreach ($type->getTypes() as $innerType) {
41+
yield $innerType;
42+
}
43+
44+
// prevent yielding twice when having a type that is both composite and wrapped
45+
return;
46+
}
47+
48+
if ($type instanceof WrappingTypeInterface && $traverseWrapped) {
49+
yield $type->getWrappedType();
50+
}
51+
}
52+
}
53+
}

0 commit comments

Comments
 (0)