From d7a7cb2c34d151ca090050ded5d500074a21fb98 Mon Sep 17 00:00:00 2001 From: Vasek Purchart Date: Fri, 23 Nov 2018 18:12:28 +0100 Subject: [PATCH] support for JMS Serializer 2 --- composer.json | 2 +- src/Enum/EnumSerializerHandler.php | 105 +++++++++++------------ tests/Enum/EnumSerializerHandlerTest.php | 8 +- tests/Enum/data/User.php | 24 ++++++ 4 files changed, 79 insertions(+), 60 deletions(-) diff --git a/composer.json b/composer.json index 61b88ec..f0ebeb8 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,7 @@ "require": { "php": "~7.2", "consistence/consistence": "~1.0", - "jms/serializer": "^1.4.2" + "jms/serializer": "~2.0" }, "require-dev": { "consistence/coding-standard": "3.5", diff --git a/src/Enum/EnumSerializerHandler.php b/src/Enum/EnumSerializerHandler.php index 705931d..df77ecd 100644 --- a/src/Enum/EnumSerializerHandler.php +++ b/src/Enum/EnumSerializerHandler.php @@ -9,11 +9,11 @@ use Consistence\Enum\MultiEnum; use Consistence\Type\ArrayType\ArrayType; use Consistence\Type\Type; -use JMS\Serializer\AbstractVisitor; use JMS\Serializer\Context; -use JMS\Serializer\GraphNavigator; +use JMS\Serializer\GraphNavigatorInterface; use JMS\Serializer\Metadata\PropertyMetadata; -use JMS\Serializer\VisitorInterface; +use JMS\Serializer\Visitor\DeserializationVisitorInterface; +use JMS\Serializer\Visitor\SerializationVisitorInterface; use Traversable; class EnumSerializerHandler implements \JMS\Serializer\Handler\SubscribingHandlerInterface @@ -35,13 +35,13 @@ public static function getSubscribingMethods(): array $methods = []; foreach ($formats as $format) { $methods[] = [ - 'direction' => GraphNavigator::DIRECTION_SERIALIZATION, + 'direction' => GraphNavigatorInterface::DIRECTION_SERIALIZATION, 'type' => self::TYPE_ENUM, 'format' => $format, 'method' => 'serializeEnum', ]; $methods[] = [ - 'direction' => GraphNavigator::DIRECTION_DESERIALIZATION, + 'direction' => GraphNavigatorInterface::DIRECTION_DESERIALIZATION, 'type' => self::TYPE_ENUM, 'format' => $format, 'method' => 'deserializeEnum', @@ -52,29 +52,28 @@ public static function getSubscribingMethods(): array } /** - * @param \JMS\Serializer\VisitorInterface $visitor + * @param \JMS\Serializer\Visitor\SerializationVisitorInterface $visitor * @param \Consistence\Enum\Enum $enum * @param mixed[] $type * @param \JMS\Serializer\Context $context * @return mixed */ - public function serializeEnum(VisitorInterface $visitor, Enum $enum, array $type, Context $context) + public function serializeEnum(SerializationVisitorInterface $visitor, Enum $enum, array $type, Context $context) { try { - return $this->serializeEnumValue($visitor, $enum, $type, $context); + return $this->serializeEnumValue($visitor, $enum, $type); } catch (\Consistence\JmsSerializer\Enum\MappedClassMismatchException $e) { throw new \Consistence\JmsSerializer\Enum\SerializationInvalidValueException($this->getPropertyPath($context), $e); } } /** - * @param \JMS\Serializer\VisitorInterface $visitor + * @param \JMS\Serializer\Visitor\SerializationVisitorInterface $visitor * @param \Consistence\Enum\Enum $enum * @param mixed[] $type - * @param \JMS\Serializer\Context $context * @return mixed */ - private function serializeEnumValue(VisitorInterface $visitor, Enum $enum, array $type, Context $context) + private function serializeEnumValue(SerializationVisitorInterface $visitor, Enum $enum, array $type) { if ($this->hasEnumClassParameter($type)) { $mappedEnumClass = $this->getEnumClass($type); @@ -98,47 +97,33 @@ private function serializeEnumValue(VisitorInterface $visitor, Enum $enum, array ], ], ]; - return $visitor->visitArray(array_values($enum->getEnums()), $arrayValueType, $context); + return $visitor->visitArray(array_values($enum->getEnums()), $arrayValueType); } } - return $this->serializationVisitType($visitor, $enum, $type, $context); + return $this->serializationVisitType($visitor, $enum, $type); } /** - * @param \JMS\Serializer\VisitorInterface $visitor + * @param \JMS\Serializer\Visitor\SerializationVisitorInterface $visitor * @param \Consistence\Enum\Enum $enum * @param mixed[] $typeMetadata - * @param \JMS\Serializer\Context $context * @return mixed */ - private function serializationVisitType(VisitorInterface $visitor, Enum $enum, array $typeMetadata, Context $context) + private function serializationVisitType(SerializationVisitorInterface $visitor, Enum $enum, array $typeMetadata) { $value = $enum->getValue(); $valueType = EnumValueType::get(Type::getType($value)); - return $this->visitType($visitor, $value, $valueType, $typeMetadata, $context); - } - - /** - * @param \JMS\Serializer\VisitorInterface $visitor - * @param mixed $data - * @param \Consistence\JmsSerializer\Enum\EnumValueType $dataType - * @param mixed[] $typeMetadata - * @param \JMS\Serializer\Context $context - * @return mixed - */ - private function visitType(VisitorInterface $visitor, $data, EnumValueType $dataType, array $typeMetadata, Context $context) - { switch (true) { - case $dataType->equalsValue(EnumValueType::INTEGER): - return $visitor->visitInteger($data, $typeMetadata, $context); - case $dataType->equalsValue(EnumValueType::STRING): - return $visitor->visitString($data, $typeMetadata, $context); - case $dataType->equalsValue(EnumValueType::FLOAT): - return $visitor->visitDouble($data, $typeMetadata, $context); - case $dataType->equalsValue(EnumValueType::BOOLEAN): - return $visitor->visitBoolean($data, $typeMetadata, $context); + case $valueType->equalsValue(EnumValueType::INTEGER): + return $visitor->visitInteger($value, $typeMetadata); + case $valueType->equalsValue(EnumValueType::STRING): + return $visitor->visitString($value, $typeMetadata); + case $valueType->equalsValue(EnumValueType::FLOAT): + return $visitor->visitDouble($value, $typeMetadata); + case $valueType->equalsValue(EnumValueType::BOOLEAN): + return $visitor->visitBoolean($value, $typeMetadata); // @codeCoverageIgnoreStart // should never happen, other types are not allowed in Enums default: @@ -148,31 +133,30 @@ private function visitType(VisitorInterface $visitor, $data, EnumValueType $data } /** - * @param \JMS\Serializer\VisitorInterface $visitor + * @param \JMS\Serializer\Visitor\DeserializationVisitorInterface $visitor * @param mixed $data * @param mixed[] $type * @param \JMS\Serializer\Context $context * @return \Consistence\Enum\Enum */ - public function deserializeEnum(VisitorInterface $visitor, $data, array $type, Context $context): Enum + public function deserializeEnum(DeserializationVisitorInterface $visitor, $data, array $type, Context $context): Enum { try { - return $this->deserializeEnumValue($visitor, $data, $type, $context); + return $this->deserializeEnumValue($visitor, $data, $type); } catch (\Consistence\Enum\InvalidEnumValueException $e) { - throw new \Consistence\JmsSerializer\Enum\DeserializationInvalidValueException($this->getFieldPath($visitor, $context), $e); + throw new \Consistence\JmsSerializer\Enum\DeserializationInvalidValueException($this->getFieldPath($context), $e); } catch (\Consistence\JmsSerializer\Enum\NotIterableValueException $e) { - throw new \Consistence\JmsSerializer\Enum\DeserializationInvalidValueException($this->getFieldPath($visitor, $context), $e); + throw new \Consistence\JmsSerializer\Enum\DeserializationInvalidValueException($this->getFieldPath($context), $e); } } /** - * @param \JMS\Serializer\VisitorInterface $visitor + * @param \JMS\Serializer\Visitor\DeserializationVisitorInterface $visitor * @param mixed $data * @param mixed[] $type - * @param \JMS\Serializer\Context $context * @return \Consistence\Enum\Enum */ - private function deserializeEnumValue(VisitorInterface $visitor, $data, array $type, Context $context): Enum + private function deserializeEnumValue(DeserializationVisitorInterface $visitor, $data, array $type): Enum { $enumClass = $this->getEnumClass($type); if ($this->hasAsSingleParameter($type)) { @@ -186,30 +170,43 @@ private function deserializeEnumValue(VisitorInterface $visitor, $data, array $t throw new \Consistence\JmsSerializer\Enum\NotIterableValueException($data); } foreach ($data as $item) { - $singleEnums[] = $singleEnumClass::get($this->deserializationVisitType($visitor, $item, $type, $context)); + $singleEnums[] = $singleEnumClass::get($this->deserializationVisitType($visitor, $item, $type)); } return $enumClass::getMultiByEnums($singleEnums); } - return $enumClass::get($this->deserializationVisitType($visitor, $data, $type, $context)); + return $enumClass::get($this->deserializationVisitType($visitor, $data, $type)); } /** - * @param \JMS\Serializer\VisitorInterface $visitor + * @param \JMS\Serializer\Visitor\DeserializationVisitorInterface $visitor * @param mixed $data * @param mixed[] $typeMetadata - * @param \JMS\Serializer\Context $context * @return mixed */ - private function deserializationVisitType(VisitorInterface $visitor, $data, array $typeMetadata, Context $context) + private function deserializationVisitType(DeserializationVisitorInterface $visitor, $data, array $typeMetadata) { $deserializationType = $this->findDeserializationType($typeMetadata); if ($deserializationType === null) { return $data; } - return $this->visitType($visitor, $data, $deserializationType, $typeMetadata, $context); + switch (true) { + case $deserializationType->equalsValue(EnumValueType::INTEGER): + return $visitor->visitInteger($data, $typeMetadata); + case $deserializationType->equalsValue(EnumValueType::STRING): + return $visitor->visitString($data, $typeMetadata); + case $deserializationType->equalsValue(EnumValueType::FLOAT): + return $visitor->visitDouble($data, $typeMetadata); + case $deserializationType->equalsValue(EnumValueType::BOOLEAN): + return $visitor->visitBoolean($data, $typeMetadata); + // @codeCoverageIgnoreStart + // should never happen, other types are not allowed in Enums + default: + throw new \Exception('Unexpected type'); + } + // @codeCoverageIgnoreEnd } /** @@ -303,16 +300,12 @@ private function getPropertyPath(Context $context): string return $path; } - private function getFieldPath(VisitorInterface $visitor, Context $context): string + private function getFieldPath(Context $context): string { $path = ''; foreach ($context->getMetadataStack() as $element) { if ($element instanceof PropertyMetadata) { $name = ($element->serializedName !== null) ? $element->serializedName : $element->name; - if ($visitor instanceof AbstractVisitor) { - $name = $visitor->getNamingStrategy()->translateName($element); - } - $path = $name . self::PATH_FIELD_SEPARATOR . $path; } } diff --git a/tests/Enum/EnumSerializerHandlerTest.php b/tests/Enum/EnumSerializerHandlerTest.php index ef79ba1..6cdbae9 100644 --- a/tests/Enum/EnumSerializerHandlerTest.php +++ b/tests/Enum/EnumSerializerHandlerTest.php @@ -4,6 +4,7 @@ namespace Consistence\JmsSerializer\Enum; +use Consistence\Type\Type; use JMS\Serializer\Handler\HandlerRegistry; use JMS\Serializer\Serializer; use JMS\Serializer\SerializerBuilder; @@ -124,11 +125,12 @@ public function testDeserializeEnumFromXml(): void public function testDeserializeJsonTypes($value, $serializedValue): void { $serializer = $this->getSerializer(); + $type = Type::getType($value); $user = $serializer->deserialize(sprintf('{ - "type_enum": %s - }', $serializedValue), User::class, 'json'); + "%s": %s + }', $type, $serializedValue), User::class, 'json'); $this->assertInstanceOf(User::class, $user); - $this->assertSame(TypeEnum::get($value), $user->typeEnum); + $this->assertSame(TypeEnum::get($value), $user->$type); } public function testSerializeMultiEnum(): void diff --git a/tests/Enum/data/User.php b/tests/Enum/data/User.php index 0c4e1f1..f1e4932 100644 --- a/tests/Enum/data/User.php +++ b/tests/Enum/data/User.php @@ -87,4 +87,28 @@ class User */ public $typeEnumWithType; + /** + * @JMS\Type("enum") + * @var \Consistence\JmsSerializer\Enum\TypeEnum + */ + public $string; + + /** + * @JMS\Type("enum") + * @var \Consistence\JmsSerializer\Enum\TypeEnum + */ + public $int; + + /** + * @JMS\Type("enum") + * @var \Consistence\JmsSerializer\Enum\TypeEnum + */ + public $bool; + + /** + * @JMS\Type("enum") + * @var \Consistence\JmsSerializer\Enum\TypeEnum + */ + public $float; + }