From 2ecea176f087b667050b4bb4c6e243f200d5b8c0 Mon Sep 17 00:00:00 2001 From: "benoit.condaminet" Date: Tue, 25 Nov 2025 16:29:25 +0100 Subject: [PATCH] fix: force value on readonly property in inherited classes --- src/Factory/ZddMessageFactory.php | 5 +++++ ...ummyMessageWithInheritedReadonlyProperty.php | 7 +++++++ .../DummyMessageWithReadonlyProperty.php | 13 +++++++++++++ tests/Unit/ZddMessageFactoryTest.php | 17 +++++++++++++++++ 4 files changed, 42 insertions(+) create mode 100644 tests/Fixtures/App/Messages/DummyMessageWithInheritedReadonlyProperty.php create mode 100644 tests/Fixtures/App/Messages/DummyMessageWithReadonlyProperty.php diff --git a/src/Factory/ZddMessageFactory.php b/src/Factory/ZddMessageFactory.php index 8d3a832..a2b6adb 100644 --- a/src/Factory/ZddMessageFactory.php +++ b/src/Factory/ZddMessageFactory.php @@ -43,6 +43,11 @@ private function forcePropertyValue(object $object, string $property, mixed $val $reflectionClass = new \ReflectionClass($object); $reflectionProperty = $reflectionClass->getProperty($property); + // Readonly properties can only be set on the declaring class in case of inheritance + if ($reflectionProperty->isReadOnly()) { + $reflectionProperty = $reflectionProperty->getDeclaringClass()->getProperty($property); + } + $reflectionProperty->setAccessible(true); $reflectionProperty->setValue($object, $value); } diff --git a/tests/Fixtures/App/Messages/DummyMessageWithInheritedReadonlyProperty.php b/tests/Fixtures/App/Messages/DummyMessageWithInheritedReadonlyProperty.php new file mode 100644 index 0000000..22c074d --- /dev/null +++ b/tests/Fixtures/App/Messages/DummyMessageWithInheritedReadonlyProperty.php @@ -0,0 +1,7 @@ +content = $content; + } +} diff --git a/tests/Unit/ZddMessageFactoryTest.php b/tests/Unit/ZddMessageFactoryTest.php index 4f7c0dc..cb18815 100644 --- a/tests/Unit/ZddMessageFactoryTest.php +++ b/tests/Unit/ZddMessageFactoryTest.php @@ -9,6 +9,7 @@ use Yousign\ZddMessageBundle\Factory\ZddMessageFactory; use Yousign\ZddMessageBundle\Tests\Fixtures\App\Messages\Config\MessageConfig; use Yousign\ZddMessageBundle\Tests\Fixtures\App\Messages\DummyMessageWithAllManagedTypes; +use Yousign\ZddMessageBundle\Tests\Fixtures\App\Messages\DummyMessageWithInheritedReadonlyProperty; use Yousign\ZddMessageBundle\Tests\Fixtures\App\Messages\DummyMessageWithNullableNumberProperty; use Yousign\ZddMessageBundle\Tests\Fixtures\App\Messages\DummyMessageWithPrivateConstructor; use Yousign\ZddMessageBundle\Tests\Fixtures\App\Messages\Input\Locale; @@ -44,6 +45,22 @@ public function testItGeneratesSerializedMessageWithNullAndNotNullableProperties self::assertNull($propertyNumber->value); } + public function testItGeneratesSerializedMessageForDummyMessageWithInheritedReadonlyProperty(): void + { + $zddMessage = $this->zddMessageFactory->create(DummyMessageWithInheritedReadonlyProperty::class); + + self::assertSame( + $this->getSerializer()->serialize(new DummyMessageWithInheritedReadonlyProperty('Hello World!')), + $zddMessage->serializedMessage() + ); + + self::assertEquals(1, $zddMessage->propertyList()->count()); + self::assertTrue($zddMessage->propertyList()->has('content')); + $property = $zddMessage->propertyList()->get('content'); + self::assertSame('string', $property->type); + self::assertSame('Hello World!', $property->value); + } + public function testItGeneratesSerializedMessageForDummyMessageWithPrivateConstructor(): void { $zddMessage = $this->zddMessageFactory->create(DummyMessageWithPrivateConstructor::class);