allow more control on GetSetMethodNormalizer by using callback functions and an ignoreAttributes list

This commit is contained in:
Tom Van Looy 2012-03-12 19:46:28 +01:00
parent 13aa515d65
commit 039ff6fc8e
2 changed files with 137 additions and 0 deletions

View File

@ -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);
}

View File

@ -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