bug #15339 [Serializer] Fix 2 bugs regarding private setters (dunglas)

This PR was merged into the 2.7 branch.

Discussion
----------

[Serializer] Fix 2 bugs regarding private setters

| Q             | A
| ------------- | ---
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | n/a
| License       | MIT
| Doc PR        | n/a

Fix two bugs reported in b5990be491 (commitcomment-12301266)

1. Arguments set in the constructor was not properly removed from `$data`
2. `GetSetMethodNormalizer` was calling private setters, throwing an exception

cc @StanAngeloff

Commits
-------

65e9f26 [Serializer] Fix bugs reported in b5990be491 (commitcomment-12301266)
This commit is contained in:
Fabien Potencier 2015-07-23 04:30:43 +02:00
commit ee98096db0
3 changed files with 51 additions and 4 deletions

View File

@ -291,7 +291,7 @@ abstract class AbstractNormalizer extends SerializerAwareNormalizer implements N
*
* @throws RuntimeException
*/
protected function instantiateObject(array $data, $class, array &$context, \ReflectionClass $reflectionClass, $allowedAttributes)
protected function instantiateObject(array &$data, $class, array &$context, \ReflectionClass $reflectionClass, $allowedAttributes)
{
if (
isset($context['object_to_populate']) &&

View File

@ -102,6 +102,7 @@ class GetSetMethodNormalizer extends AbstractNormalizer
$reflectionClass = new \ReflectionClass($class);
$object = $this->instantiateObject($normalizedData, $class, $context, $reflectionClass, $allowedAttributes);
$classMethods = get_class_methods($object);
foreach ($normalizedData as $attribute => $value) {
if ($this->nameConverter) {
$attribute = $this->nameConverter->denormalize($attribute);
@ -113,7 +114,7 @@ class GetSetMethodNormalizer extends AbstractNormalizer
if ($allowed && !$ignored) {
$setter = 'set'.ucfirst($attribute);
if (method_exists($object, $setter)) {
if (in_array($setter, $classMethods)) {
$object->$setter($value);
}
}

View File

@ -228,6 +228,12 @@ class GetSetMethodNormalizerTest extends \PHPUnit_Framework_TestCase
$this->assertEquals('bar', $obj->getBar());
}
public function testConstructorWArgWithPrivateMutator()
{
$obj = $this->normalizer->denormalize(array('foo' => 'bar'), __NAMESPACE__.'\ObjectConstructorArgsWithPrivateMutatorDummy', 'any');
$this->assertEquals('bar', $obj->getFoo());
}
public function testGroupsNormalize()
{
$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
@ -511,8 +517,8 @@ class GetSetMethodNormalizerTest extends \PHPUnit_Framework_TestCase
public function testDenormalizeNonExistingAttribute()
{
$this->assertEquals(
new PropertyDummy(),
$this->normalizer->denormalize(array('non_existing' => true), __NAMESPACE__.'\PropertyDummy')
new GetSetDummy(),
$this->normalizer->denormalize(array('non_existing' => true), __NAMESPACE__.'\GetSetDummy')
);
}
@ -520,6 +526,12 @@ class GetSetMethodNormalizerTest extends \PHPUnit_Framework_TestCase
{
$this->assertFalse($this->normalizer->supportsNormalization(new \ArrayObject()));
}
public function testPrivateSetter()
{
$obj = $this->normalizer->denormalize(array('foo' => 'foobar'), __NAMESPACE__.'\ObjectWithPrivateSetterDummy');
$this->assertEquals('bar', $obj->getFoo());
}
}
class GetSetDummy
@ -726,3 +738,37 @@ class GetCamelizedDummy
return $this->bar_foo;
}
}
class ObjectConstructorArgsWithPrivateMutatorDummy
{
private $foo;
public function __construct($foo)
{
$this->setFoo($foo);
}
public function getFoo()
{
return $this->foo;
}
private function setFoo($foo)
{
$this->foo = $foo;
}
}
class ObjectWithPrivateSetterDummy
{
private $foo = 'bar';
public function getFoo()
{
return $this->foo;
}
private function setFoo($foo)
{
}
}