Skip to content

Commit

Permalink
bug #64 Fix Enum constraint deserialization (ogizanagi)
Browse files Browse the repository at this point in the history
This PR was merged into the 1.x-dev branch.

Discussion
----------

Fix Enum constraint deserialization

When the constraint is serialized (to be cached) and the `choice` option is provided (and expecting enum instances and not just values), deserialization of the choice option will not use `EnumInterface::get()` and thus won't create the proper multiton instances, making strict comparisons fail.
This fixes it by replacing deserialized instances by proper ones.

Commits
-------

95619c2 Fix Enum constraint deserialization
  • Loading branch information
ogizanagi committed Jul 27, 2018
2 parents 49ecce2 + 95619c2 commit d9744c1
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 0 deletions.
18 changes: 18 additions & 0 deletions src/Bridge/Symfony/Validator/Constraint/Enum.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
}
15 changes: 15 additions & 0 deletions tests/Unit/Bridge/Symfony/Validator/Constraint/EnumTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}

0 comments on commit d9744c1

Please sign in to comment.