Skip to content

Commit d043cc2

Browse files
committed
[LiveComponent] Add uid support for hydration
1 parent ab44abf commit d043cc2

File tree

4 files changed

+51
-0
lines changed

4 files changed

+51
-0
lines changed

src/LiveComponent/CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# CHANGELOG
22

3+
## 2.24.0
4+
5+
- Add support for [Symfony UID](https://symfony.com/doc/current/components/uid.html) hydration/dehydration
6+
37
## 2.23.0
48

59
- Allow configuring the secret used to compute fingerprints and checksums.

src/LiveComponent/composer.json

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
"symfony/security-bundle": "^5.4|^6.0|^7.0",
5151
"symfony/serializer": "^5.4|^6.0|^7.0",
5252
"symfony/twig-bundle": "^5.4|^6.0|^7.0",
53+
"symfony/uid": "^5.4|^6.0|^7.0",
5354
"symfony/validator": "^5.4|^6.0|^7.0",
5455
"zenstruck/browser": "^1.2.0",
5556
"zenstruck/foundry": "^2.0"

src/LiveComponent/src/LiveComponentHydrator.php

+13
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
use Symfony\Component\Serializer\Exception\ExceptionInterface as SerializerExceptionInterface;
2323
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
2424
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
25+
use Symfony\Component\Uid\AbstractUid;
2526
use Symfony\UX\LiveComponent\Attribute\AsLiveComponent;
2627
use Symfony\UX\LiveComponent\Attribute\LiveProp;
2728
use Symfony\UX\LiveComponent\Exception\HydrationException;
@@ -505,6 +506,10 @@ private function dehydrateObjectValue(object $value, string $classType, ?string
505506
return $value->value;
506507
}
507508

509+
if ($value instanceof AbstractUid) {
510+
return (string) $value;
511+
}
512+
508513
foreach ($this->hydrationExtensions as $extension) {
509514
if ($extension->supports($classType)) {
510515
return $extension->dehydrate($value);
@@ -553,6 +558,14 @@ private function hydrateObjectValue(mixed $value, string $className, bool $allow
553558
return new $className($value);
554559
}
555560

561+
if (is_a($className, AbstractUid::class, true)) {
562+
if (!\is_string($value)) {
563+
throw new BadRequestHttpException(\sprintf('The model path "%s" was sent an invalid data type "%s" for a uuid.', $propertyPathForError, get_debug_type($value)));
564+
}
565+
566+
return $className::fromString($value);
567+
}
568+
556569
foreach ($this->hydrationExtensions as $extension) {
557570
if ($extension->supports($className)) {
558571
return $extension->hydrate($value, $className);

src/LiveComponent/tests/Integration/LiveComponentHydratorTest.php

+33
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313

1414
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
1515
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
16+
use Symfony\Component\Uid\Ulid;
17+
use Symfony\Component\Uid\Uuid;
18+
use Symfony\Component\Uid\UuidV4;
1619
use Symfony\UX\LiveComponent\Attribute\LiveProp;
1720
use Symfony\UX\LiveComponent\Exception\HydrationException;
1821
use Symfony\UX\LiveComponent\Metadata\LiveComponentMetadata;
@@ -1372,6 +1375,36 @@ public function modifyDateProp(LiveProp $prop): LiveProp
13721375
})
13731376
;
13741377
}];
1378+
1379+
yield 'Uuid: (de)hydrates correctly' => [function () {
1380+
$uuid = new UuidV4('ffdb229c-13e6-4bc4-939e-c8e73958104c');
1381+
1382+
return HydrationTest::create(new class {
1383+
#[LiveProp]
1384+
public Uuid $id;
1385+
})
1386+
->mountWith(['id' => $uuid])
1387+
->assertDehydratesTo(['id' => 'ffdb229c-13e6-4bc4-939e-c8e73958104c'])
1388+
->assertObjectAfterHydration(function (object $object) {
1389+
self::assertEquals(new UuidV4('ffdb229c-13e6-4bc4-939e-c8e73958104c'), $object->id);
1390+
})
1391+
;
1392+
}];
1393+
1394+
yield 'Ulid: (de)hydrates correctly' => [function () {
1395+
$uuid = new Ulid('01AN4Z07BY79KA1307SR9X4MV3');
1396+
1397+
return HydrationTest::create(new class {
1398+
#[LiveProp]
1399+
public Ulid $id;
1400+
})
1401+
->mountWith(['id' => $uuid])
1402+
->assertDehydratesTo(['id' => '01AN4Z07BY79KA1307SR9X4MV3'])
1403+
->assertObjectAfterHydration(function (object $object) {
1404+
self::assertEquals(new Ulid('01AN4Z07BY79KA1307SR9X4MV3'), $object->id);
1405+
})
1406+
;
1407+
}];
13751408
}
13761409

13771410
public function testHydrationWithInvalidDate(): void

0 commit comments

Comments
 (0)