From 95619c2c94bc56a4b4965f95f043632cc141fa8b Mon Sep 17 00:00:00 2001 From: Maxime Steinhausser Date: Fri, 27 Jul 2018 13:24:39 +0200 Subject: [PATCH] Fix Enum constraint deserialization --- .../Symfony/Validator/Constraint/Enum.php | 18 ++++++++++++++++++ .../Symfony/Validator/Constraint/EnumTest.php | 15 +++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/src/Bridge/Symfony/Validator/Constraint/Enum.php b/src/Bridge/Symfony/Validator/Constraint/Enum.php index 0e186221..23608099 100644 --- a/src/Bridge/Symfony/Validator/Constraint/Enum.php +++ b/src/Bridge/Symfony/Validator/Constraint/Enum.php @@ -95,4 +95,22 @@ public function getRequiredOptions() { return ['class']; } + + /** + * Fixup deserialized enum instances by replacing them with actual multiton instances, + * so strict comparison works. + * + * {@inheritdoc} + */ + public function __wakeup() + { + if (!$this->asValue && \is_array($this->choices)) { + $this->choices = array_map(function (EnumInterface $enum): EnumInterface { + /** @var string|EnumInterface $enumClass */ + $enumClass = \get_class($enum); + + return $enumClass::get($enum->getValue()); + }, $this->choices); + } + } } diff --git a/tests/Unit/Bridge/Symfony/Validator/Constraint/EnumTest.php b/tests/Unit/Bridge/Symfony/Validator/Constraint/EnumTest.php index 1cb4e40e..048e8bfb 100644 --- a/tests/Unit/Bridge/Symfony/Validator/Constraint/EnumTest.php +++ b/tests/Unit/Bridge/Symfony/Validator/Constraint/EnumTest.php @@ -72,4 +72,19 @@ public function testInvalidChoiceOptionThrowsDefinitionException() { new Enum(['class' => SimpleEnum::class, 'choices' => ['bar']]); } + + public function testDeserializingConstraintRespectsMultitonInstance() + { + $constraint = new Enum(['class' => SimpleEnum::class, 'choices' => [ + SimpleEnum::FIRST, + SimpleEnum::SECOND, + ]]); + + $constraint = unserialize(serialize($constraint)); + + $this->assertSame([ + SimpleEnum::get(SimpleEnum::FIRST), + SimpleEnum::get(SimpleEnum::SECOND), + ], $constraint->choices); + } }