namespace Symfony\Component\Serializer\Normalizer;
-use Symfony\Component\Serializer\Exception\CircularReferenceException;
-use Symfony\Component\Serializer\Exception\LogicException;
-use Symfony\Component\Serializer\Exception\RuntimeException;
-
/**
* Converts between objects and arrays by mapping properties.
*
* @author Matthieu Napoli <matthieu@mnapoli.fr>
* @author Kévin Dunglas <dunglas@gmail.com>
*/
-class PropertyNormalizer extends AbstractNormalizer
+class PropertyNormalizer extends AbstractObjectNormalizer
{
/**
* {@inheritdoc}
- *
- * @throws CircularReferenceException
*/
- public function normalize($object, $format = null, array $context = array())
+ public function supportsNormalization($data, $format = null)
{
- if ($this->isCircularReference($object, $context)) {
- return $this->handleCircularReference($object);
- }
-
- $reflectionObject = new \ReflectionObject($object);
- $attributes = array();
- $allowedAttributes = $this->getAllowedAttributes($object, $context, true);
+ return parent::supportsNormalization($data, $format) && $this->supports(get_class($data));
+ }
- foreach ($reflectionObject->getProperties() as $property) {
- if (in_array($property->name, $this->ignoredAttributes) || $property->isStatic()) {
- continue;
- }
+ /**
+ * {@inheritdoc}
+ */
+ public function supportsDenormalization($data, $type, $format = null)
+ {
+ return parent::supportsDenormalization($data, $type, $format) && $this->supports($type);
+ }
- if (false !== $allowedAttributes && !in_array($property->name, $allowedAttributes)) {
- continue;
- }
+ /**
+ * Checks if the given class has any non-static property.
+ *
+ * @param string $class
+ *
+ * @return bool
+ */
+ private function supports($class)
+ {
+ $class = new \ReflectionClass($class);
- // Override visibility
- if (!$property->isPublic()) {
- $property->setAccessible(true);
+ // We look for at least one non-static property
+ foreach ($class->getProperties() as $property) {
+ if (!$property->isStatic()) {
+ return true;
}
+ }
- $attributeValue = $property->getValue($object);
-
- if (isset($this->callbacks[$property->name])) {
- $attributeValue = call_user_func($this->callbacks[$property->name], $attributeValue);
- }
- if (null !== $attributeValue && !is_scalar($attributeValue)) {
- if (!$this->serializer instanceof NormalizerInterface) {
- throw new LogicException(sprintf('Cannot normalize attribute "%s" because injected serializer is not a normalizer', $property->name));
- }
+ return false;
+ }
- $attributeValue = $this->serializer->normalize($attributeValue, $format, $context);
- }
+ /**
+ * {@inheritdoc}
+ */
+ protected function isAllowedAttribute($classOrObject, $attribute, $format = null, array $context = array())
+ {
+ if (!parent::isAllowedAttribute($classOrObject, $attribute, $format, $context)) {
+ return false;
+ }
- $propertyName = $property->name;
- if ($this->nameConverter) {
- $propertyName = $this->nameConverter->normalize($propertyName);
+ try {
+ $reflectionProperty = new \ReflectionProperty(is_string($classOrObject) ? $classOrObject : get_class($classOrObject), $attribute);
+ if ($reflectionProperty->isStatic()) {
+ return false;
}
-
- $attributes[$propertyName] = $attributeValue;
+ } catch (\ReflectionException $reflectionException) {
+ return false;
}
- return $attributes;
+ return true;
}
/**
* {@inheritdoc}
- *
- * @throws RuntimeException
*/
- public function denormalize($data, $class, $format = null, array $context = array())
+ protected function extractAttributes($object, $format = null, array $context = array())
{
- $allowedAttributes = $this->getAllowedAttributes($class, $context, true);
- $data = $this->prepareForDenormalization($data);
-
- $reflectionClass = new \ReflectionClass($class);
- $object = $this->instantiateObject($data, $class, $context, $reflectionClass, $allowedAttributes);
+ $reflectionObject = new \ReflectionObject($object);
+ $attributes = array();
- foreach ($data as $propertyName => $value) {
- if ($this->nameConverter) {
- $propertyName = $this->nameConverter->denormalize($propertyName);
+ foreach ($reflectionObject->getProperties() as $property) {
+ if (!$this->isAllowedAttribute($object, $property->name)) {
+ continue;
}
- $allowed = $allowedAttributes === false || in_array($propertyName, $allowedAttributes);
- $ignored = in_array($propertyName, $this->ignoredAttributes);
- if ($allowed && !$ignored && $reflectionClass->hasProperty($propertyName)) {
- $property = $reflectionClass->getProperty($propertyName);
-
- if ($property->isStatic()) {
- continue;
- }
-
- // Override visibility
- if (!$property->isPublic()) {
- $property->setAccessible(true);
- }
-
- $property->setValue($object, $value);
- }
+ $attributes[] = $property->name;
}
- return $object;
+ return $attributes;
}
/**
* {@inheritdoc}
*/
- public function supportsNormalization($data, $format = null)
+ protected function getAttributeValue($object, $attribute, $format = null, array $context = array())
{
- return is_object($data) && !$data instanceof \Traversable && $this->supports(get_class($data));
+ try {
+ $reflectionProperty = new \ReflectionProperty(get_class($object), $attribute);
+ } catch (\ReflectionException $reflectionException) {
+ return;
+ }
+
+ // Override visibility
+ if (!$reflectionProperty->isPublic()) {
+ $reflectionProperty->setAccessible(true);
+ }
+
+ return $reflectionProperty->getValue($object);
}
/**
* {@inheritdoc}
*/
- public function supportsDenormalization($data, $type, $format = null)
+ protected function setAttributeValue($object, $attribute, $value, $format = null, array $context = array())
{
- return class_exists($type) && $this->supports($type);
- }
+ try {
+ $reflectionProperty = new \ReflectionProperty(get_class($object), $attribute);
+ } catch (\ReflectionException $reflectionException) {
+ return;
+ }
- /**
- * Checks if the given class has any non-static property.
- *
- * @param string $class
- *
- * @return bool
- */
- private function supports($class)
- {
- $class = new \ReflectionClass($class);
+ if ($reflectionProperty->isStatic()) {
+ return;
+ }
- // We look for at least one non-static property
- foreach ($class->getProperties() as $property) {
- if (!$property->isStatic()) {
- return true;
- }
+ // Override visibility
+ if (!$reflectionProperty->isPublic()) {
+ $reflectionProperty->setAccessible(true);
}
- return false;
+ $reflectionProperty->setValue($object, $value);
}
}