4 * This file is part of the Symfony package.
6 * (c) Fabien Potencier <fabien@symfony.com>
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
12 namespace Symfony\Component\Serializer\Normalizer;
15 * Converts between objects and arrays by mapping properties.
17 * The normalization process looks for all the object's properties (public and private).
18 * The result is a map from property names to property values. Property values
19 * are normalized through the serializer.
21 * The denormalization first looks at the constructor of the given class to see
22 * if any of the parameters have the same name as one of the properties. The
23 * constructor is then called with all parameters or an exception is thrown if
24 * any required parameters were not present as properties. Then the denormalizer
25 * walks through the given map of property names to property values to see if a
26 * property with the corresponding name exists. If found, the property gets the value.
28 * @author Matthieu Napoli <matthieu@mnapoli.fr>
29 * @author Kévin Dunglas <dunglas@gmail.com>
31 class PropertyNormalizer extends AbstractObjectNormalizer
33 private $cache = array();
38 public function supportsNormalization($data, $format = null)
40 return parent::supportsNormalization($data, $format) && (isset($this->cache[$type = \get_class($data)]) ? $this->cache[$type] : $this->cache[$type] = $this->supports($type));
46 public function supportsDenormalization($data, $type, $format = null)
48 return parent::supportsDenormalization($data, $type, $format) && (isset($this->cache[$type]) ? $this->cache[$type] : $this->cache[$type] = $this->supports($type));
52 * Checks if the given class has any non-static property.
54 * @param string $class
58 private function supports($class)
60 $class = new \ReflectionClass($class);
62 // We look for at least one non-static property
64 foreach ($class->getProperties() as $property) {
65 if (!$property->isStatic()) {
69 } while ($class = $class->getParentClass());
77 protected function isAllowedAttribute($classOrObject, $attribute, $format = null, array $context = array())
79 if (!parent::isAllowedAttribute($classOrObject, $attribute, $format, $context)) {
84 $reflectionProperty = $this->getReflectionProperty($classOrObject, $attribute);
85 if ($reflectionProperty->isStatic()) {
88 } catch (\ReflectionException $reflectionException) {
98 protected function extractAttributes($object, $format = null, array $context = array())
100 $reflectionObject = new \ReflectionObject($object);
101 $attributes = array();
104 foreach ($reflectionObject->getProperties() as $property) {
105 if (!$this->isAllowedAttribute($reflectionObject->getName(), $property->name)) {
109 $attributes[] = $property->name;
111 } while ($reflectionObject = $reflectionObject->getParentClass());
119 protected function getAttributeValue($object, $attribute, $format = null, array $context = array())
122 $reflectionProperty = $this->getReflectionProperty($object, $attribute);
123 } catch (\ReflectionException $reflectionException) {
127 // Override visibility
128 if (!$reflectionProperty->isPublic()) {
129 $reflectionProperty->setAccessible(true);
132 return $reflectionProperty->getValue($object);
138 protected function setAttributeValue($object, $attribute, $value, $format = null, array $context = array())
141 $reflectionProperty = $this->getReflectionProperty($object, $attribute);
142 } catch (\ReflectionException $reflectionException) {
146 if ($reflectionProperty->isStatic()) {
150 // Override visibility
151 if (!$reflectionProperty->isPublic()) {
152 $reflectionProperty->setAccessible(true);
155 $reflectionProperty->setValue($object, $value);
159 * @param string|object $classOrObject
160 * @param string $attribute
162 * @return \ReflectionProperty
164 * @throws \ReflectionException
166 private function getReflectionProperty($classOrObject, $attribute)
168 $reflectionClass = new \ReflectionClass($classOrObject);
171 return $reflectionClass->getProperty($attribute);
172 } catch (\ReflectionException $e) {
173 if (!$reflectionClass = $reflectionClass->getParentClass()) {