PropertyNormalizer.php 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\Serializer\Normalizer;
  11. /**
  12. * Converts between objects and arrays by mapping properties.
  13. *
  14. * The normalization process looks for all the object's properties (public and private).
  15. * The result is a map from property names to property values. Property values
  16. * are normalized through the serializer.
  17. *
  18. * The denormalization first looks at the constructor of the given class to see
  19. * if any of the parameters have the same name as one of the properties. The
  20. * constructor is then called with all parameters or an exception is thrown if
  21. * any required parameters were not present as properties. Then the denormalizer
  22. * walks through the given map of property names to property values to see if a
  23. * property with the corresponding name exists. If found, the property gets the value.
  24. *
  25. * @author Matthieu Napoli <matthieu@mnapoli.fr>
  26. * @author Kévin Dunglas <dunglas@gmail.com>
  27. */
  28. class PropertyNormalizer extends AbstractObjectNormalizer
  29. {
  30. /**
  31. * {@inheritdoc}
  32. */
  33. public function supportsNormalization($data, $format = null)
  34. {
  35. return parent::supportsNormalization($data, $format) && $this->supports(get_class($data));
  36. }
  37. /**
  38. * {@inheritdoc}
  39. */
  40. public function supportsDenormalization($data, $type, $format = null)
  41. {
  42. return parent::supportsDenormalization($data, $type, $format) && $this->supports($type);
  43. }
  44. /**
  45. * Checks if the given class has any non-static property.
  46. *
  47. * @param string $class
  48. *
  49. * @return bool
  50. */
  51. private function supports($class)
  52. {
  53. $class = new \ReflectionClass($class);
  54. // We look for at least one non-static property
  55. foreach ($class->getProperties() as $property) {
  56. if (!$property->isStatic()) {
  57. return true;
  58. }
  59. }
  60. return false;
  61. }
  62. /**
  63. * {@inheritdoc}
  64. */
  65. protected function isAllowedAttribute($classOrObject, $attribute, $format = null, array $context = array())
  66. {
  67. if (!parent::isAllowedAttribute($classOrObject, $attribute, $format, $context)) {
  68. return false;
  69. }
  70. try {
  71. $reflectionProperty = new \ReflectionProperty(is_string($classOrObject) ? $classOrObject : get_class($classOrObject), $attribute);
  72. if ($reflectionProperty->isStatic()) {
  73. return false;
  74. }
  75. } catch (\ReflectionException $reflectionException) {
  76. return false;
  77. }
  78. return true;
  79. }
  80. /**
  81. * {@inheritdoc}
  82. */
  83. protected function extractAttributes($object, $format = null, array $context = array())
  84. {
  85. $reflectionObject = new \ReflectionObject($object);
  86. $attributes = array();
  87. foreach ($reflectionObject->getProperties() as $property) {
  88. if (!$this->isAllowedAttribute($object, $property->name)) {
  89. continue;
  90. }
  91. $attributes[] = $property->name;
  92. }
  93. return $attributes;
  94. }
  95. /**
  96. * {@inheritdoc}
  97. */
  98. protected function getAttributeValue($object, $attribute, $format = null, array $context = array())
  99. {
  100. try {
  101. $reflectionProperty = new \ReflectionProperty(get_class($object), $attribute);
  102. } catch (\ReflectionException $reflectionException) {
  103. return;
  104. }
  105. // Override visibility
  106. if (!$reflectionProperty->isPublic()) {
  107. $reflectionProperty->setAccessible(true);
  108. }
  109. return $reflectionProperty->getValue($object);
  110. }
  111. /**
  112. * {@inheritdoc}
  113. */
  114. protected function setAttributeValue($object, $attribute, $value, $format = null, array $context = array())
  115. {
  116. try {
  117. $reflectionProperty = new \ReflectionProperty(get_class($object), $attribute);
  118. } catch (\ReflectionException $reflectionException) {
  119. return;
  120. }
  121. if ($reflectionProperty->isStatic()) {
  122. return;
  123. }
  124. // Override visibility
  125. if (!$reflectionProperty->isPublic()) {
  126. $reflectionProperty->setAccessible(true);
  127. }
  128. $reflectionProperty->setValue($object, $value);
  129. }
  130. }