From 039ff6fc8eba752f5522f1aa6d3d5cef92ef812f Mon Sep 17 00:00:00 2001 From: Tom Van Looy Date: Mon, 12 Mar 2012 19:46:28 +0100 Subject: [PATCH] allow more control on GetSetMethodNormalizer by using callback functions and an ignoreAttributes list --- .../Normalizer/GetSetMethodNormalizer.php | 35 ++++++ .../Normalizer/GetSetMethodNormalizerTest.php | 102 ++++++++++++++++++ 2 files changed, 137 insertions(+) diff --git a/src/Symfony/Component/Serializer/Normalizer/GetSetMethodNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/GetSetMethodNormalizer.php index b9da47002d..921a861937 100644 --- a/src/Symfony/Component/Serializer/Normalizer/GetSetMethodNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/GetSetMethodNormalizer.php @@ -35,6 +35,34 @@ use Symfony\Component\Serializer\Exception\RuntimeException; */ class GetSetMethodNormalizer extends SerializerAwareNormalizer implements NormalizerInterface, DenormalizerInterface { + protected $callbacks = array(); + protected $ignoredAttributes = array(); + + /** + * Set normalization callbacks + * + * @param array $callbacks help normalize the result + */ + public function setCallbacks(array $callbacks) + { + foreach ($callbacks as $attribute => $callback) { + if (!is_callable($callback)) { + throw new \InvalidArgumentException(sprintf('The given callback for attribute "%s" is not callable.', $attribute)); + } + } + $this->callbacks = $callbacks; + } + + /** + * Set ignored attributes for normalization + * + * @param array $ignoredAttributes + */ + public function setIgnoredAttributes(array $ignoredAttributes) + { + $this->ignoredAttributes = $ignoredAttributes; + } + /** * {@inheritdoc} */ @@ -48,7 +76,14 @@ class GetSetMethodNormalizer extends SerializerAwareNormalizer implements Normal if ($this->isGetMethod($method)) { $attributeName = lcfirst(substr($method->getName(), 3)); + if (in_array($attributeName, $this->ignoredAttributes)) { + continue; + } + $attributeValue = $method->invoke($object); + if (array_key_exists($attributeName, $this->callbacks)) { + $attributeValue = call_user_func($this->callbacks[$attributeName], $attributeValue); + } if (null !== $attributeValue && !is_scalar($attributeValue)) { $attributeValue = $this->serializer->normalize($attributeValue, $format); } diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/GetSetMethodNormalizerTest.php b/src/Symfony/Component/Serializer/Tests/Normalizer/GetSetMethodNormalizerTest.php index e8cebb1f7c..fd0c5daf03 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/GetSetMethodNormalizerTest.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/GetSetMethodNormalizerTest.php @@ -51,6 +51,108 @@ class GetSetMethodNormalizerTest extends \PHPUnit_Framework_TestCase $this->assertEquals('foo', $obj->getFoo()); $this->assertEquals('bar', $obj->getBar()); } + + /** + * @dataProvider provideCallbacks + */ + public function testCallbacks($callbacks, $value, $result, $message) + { + $this->normalizer->setCallbacks($callbacks); + + $obj = new GetConstructorDummy('', $value); + + $this->assertEquals( + $result, + $this->normalizer->normalize($obj, 'any'), + $message + ); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testUncallableCallbacks() + { + $this->normalizer->setCallbacks(array('bar' => null)); + + $obj = new GetConstructorDummy('baz', 'quux'); + + $this->normalizer->normalize($obj, 'any'); + } + + public function testIgnoredAttributes() + { + $this->normalizer->setIgnoredAttributes(array('foo', 'bar')); + + $obj = new GetSetDummy; + $obj->setFoo('foo'); + $obj->setBar('bar'); + + $this->assertEquals( + array('fooBar' => 'foobar'), + $this->normalizer->normalize($obj, 'any') + ); + } + + public function provideCallbacks() + { + return array( + array( + array( + 'bar' => function ($bar) { + return 'baz'; + }, + ), + 'baz', + array('foo' => '', 'bar' => 'baz'), + 'Change a string', + ), + array( + array( + 'bar' => function ($bar) { + return null; + }, + ), + 'baz', + array('foo' => '', 'bar' => null), + 'Null an item' + ), + array( + array( + 'bar' => function ($bar) { + return $bar->format('d-m-Y H:i:s'); + }, + ), + new \DateTime('2011-09-10 06:30:00'), + array('foo' => '', 'bar' => '10-09-2011 06:30:00'), + 'Format a date', + ), + array( + array( + 'bar' => function ($bars) { + $foos = ''; + foreach ($bars as $bar) { + $foos .= $bar->getFoo(); + } + return $foos; + }, + ), + array(new GetConstructorDummy('baz', ''), new GetConstructorDummy('quux', '')), + array('foo' => '', 'bar' => 'bazquux'), + 'Collect a property', + ), + array( + array( + 'bar' => function ($bars) { + return count($bars); + }, + ), + array(new GetConstructorDummy('baz', ''), new GetConstructorDummy('quux', '')), + array('foo' => '', 'bar' => 2), + 'Count a property', + ), + ); + } } class GetSetDummy