-
Notifications
You must be signed in to change notification settings - Fork 11
Add support for dynamic handlers #51
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -92,12 +92,19 @@ private function generateCodeForClass( | |
| ModelPath $modelPath, | ||
| array $stack = [], | ||
| ): string { | ||
| /** @var class-string $className */ | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we should do this in the metadata. i did liip/metadata-parser#58
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i tagged 2.1.1 of metadata-parser. can you please remove this (and the one in SerializerGenerator) and see if phpstan sees things correctly with the newest parser?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That worked for this case, but now there is an issue in the SerializerGenerator and the DeserializerGenerator I think we'd have to map this property to a So I guess we have to "force" a docblock type somewhere. Should I take care of this in the metadata-parser, or rather in this repo?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can see the necessary changes in this commit: 4f7570e
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. oh, once we start touching, everything starts to move... i think we should fix it in metadata, that would make the most sense. if you have time to look into it, best would be to test it in context of the serializer to see if we have more places that need to be fixed.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure, I'll take care of fixing it in the metadata-parser then
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed via liip/metadata-parser#59
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Update to latest version via db394fe |
||
| $className = $classMetadata->getClassName(); | ||
| $handler = $this->configuration->findDeserializerHandlerForClass($className); | ||
| if (null !== $handler) { | ||
| return $this->templating->renderAssignJsonDataToField((string) $modelPath, $handler->generateDeserializeExpression($className, (string) $arrayPath)); | ||
| } | ||
|
|
||
| $discriminatorMetadata = $classMetadata->getDiscriminatorMetadata(); | ||
| if (null !== $discriminatorMetadata && $discriminatorMetadata->baseClass == $classMetadata->getClassName()) { | ||
| if (null !== $discriminatorMetadata && $discriminatorMetadata->baseClass == $className) { | ||
| return $this->generateCodeForDiscriminatorClass($classMetadata, $arrayPath, $modelPath, $stack); | ||
| } | ||
|
|
||
| $stack[$classMetadata->getClassName()] = ($stack[$classMetadata->getClassName()] ?? 0) + 1; | ||
| $stack[$className] = ($stack[$className] ?? 0) + 1; | ||
|
|
||
| $constructorArgumentNames = []; | ||
| $overwrittenNames = []; | ||
|
|
@@ -136,7 +143,7 @@ private function generateCodeForClass( | |
| continue; | ||
| } | ||
| if ($definition->isRequired()) { | ||
| $msg = \sprintf('Unknown constructor argument "%s". Class %s only has properties that tell how to handle %s.', $definition->getName(), $classMetadata->getClassName(), implode(', ', array_keys($constructorArgumentNames))); | ||
| $msg = \sprintf('Unknown constructor argument "%s". Class %s only has properties that tell how to handle %s.', $definition->getName(), $className, implode(', ', array_keys($constructorArgumentNames))); | ||
| if ($overwrittenNames) { | ||
| $msg .= \sprintf(' Multiple definitions for fields %s seen - the last one overwrites previous ones.', implode(', ', array_keys($overwrittenNames))); | ||
| } | ||
|
|
@@ -148,7 +155,7 @@ private function generateCodeForClass( | |
| $code .= $this->templating->renderUnset(array_values($constructorArgumentNames)); | ||
| } | ||
|
|
||
| return $this->templating->renderClass((string) $modelPath, $classMetadata->getClassName(), $constructorArguments, $code, $initCode); | ||
| return $this->templating->renderClass((string) $modelPath, $className, $constructorArguments, $code, $initCode); | ||
| } | ||
|
|
||
| /** | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| <?php | ||
|
|
||
| declare(strict_types=1); | ||
|
|
||
| namespace Liip\Serializer; | ||
|
|
||
| interface DeserializerHandlerInterface | ||
| { | ||
| /** | ||
| * Generate the PHP code to deserialize the object from the value. | ||
| * | ||
| * This method is called while generating the code for the deserializer, not at runtime of deserialization. You need | ||
| * to generate PHP code that can be included into the deserialization function generated by the Liip serializer. | ||
| * Use the $arrayPath to access the data structure that the object was serialized to. Use $className to know which | ||
| * object to instantiate. | ||
| * | ||
| * @param class-string $className | ||
| * @param string $arrayPath Contains a PHP expression for the property value, e.g. "$model->id" | ||
| */ | ||
|
dbu marked this conversation as resolved.
|
||
| public function generateDeserializeExpression(string $className, string $arrayPath): string; | ||
|
|
||
| /** | ||
| * @return class-string[] | ||
| */ | ||
| public function getDeserializationClasses(): array; | ||
|
dbu marked this conversation as resolved.
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| <?php | ||
|
|
||
| declare(strict_types=1); | ||
|
|
||
| namespace Liip\Serializer; | ||
|
|
||
| interface SerializerHandlerInterface | ||
| { | ||
| /** | ||
| * Generate the PHP code to serialize the value from the object. | ||
| * | ||
| * This method is called while generating the code for the serializer, not at runtime of serialization. You need | ||
| * to generate PHP code that can be included into the serialization function generated by the Liip serializer. | ||
| * Use the $modelPath to access the object and return the value for the json array. Use $className to know which | ||
| * class is serialized. | ||
| * | ||
| * @param class-string $className | ||
| * @param string $modelPath Contains a PHP expression for the raw array value, e.g. $array['id'] | ||
| */ | ||
| public function generateSerializeExpression(string $className, string $modelPath): string; | ||
|
|
||
| /** | ||
| * @return class-string[] | ||
| */ | ||
| public function getSerializationClasses(): array; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| <?php | ||
|
|
||
| declare(strict_types=1); | ||
|
|
||
| namespace Tests\Liip\Serializer\Fixtures; | ||
|
|
||
| class CustomType | ||
| { | ||
| public string $key = 'static value'; | ||
|
|
||
| public function __construct(public readonly string $value) | ||
| { | ||
| } | ||
|
|
||
| public function getValue(): string | ||
| { | ||
| return $this->value; | ||
| } | ||
|
|
||
| public static function fromString(string $value): self | ||
| { | ||
| return new self($value); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| <?php | ||
|
|
||
| declare(strict_types=1); | ||
|
|
||
| namespace Tests\Liip\Serializer\Fixtures; | ||
|
|
||
| use Liip\Serializer\DeserializerHandlerInterface; | ||
| use Liip\Serializer\SerializerHandlerInterface; | ||
|
|
||
| class CustomTypeHandler implements SerializerHandlerInterface, DeserializerHandlerInterface | ||
| { | ||
| public function generateSerializeExpression(string $className, string $modelPath): string | ||
| { | ||
| return $modelPath.'->getValue()'; | ||
| } | ||
|
|
||
| public function generateDeserializeExpression(string $className, string $arrayPath): string | ||
| { | ||
| return '\\'.CustomType::class.'::fromString('.$arrayPath.')'; | ||
| } | ||
|
|
||
| public function getDeserializationClasses(): array | ||
| { | ||
| return [CustomType::class]; | ||
| } | ||
|
|
||
| public function getSerializationClasses(): array | ||
| { | ||
| return [CustomType::class]; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| <?php | ||
|
|
||
| declare(strict_types=1); | ||
|
|
||
| namespace Tests\Liip\Serializer\Fixtures; | ||
|
|
||
| use JMS\Serializer\Annotation as Serializer; | ||
|
|
||
| class ModelWithCustomType | ||
| { | ||
| public ?CustomType $value = null; | ||
|
|
||
| #[Serializer\Type('array<'.CustomType::class.'>')] | ||
| public ?array $values = null; | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.