/integration-tests/performance-test-engine/vendor/symfony/symfony/src/Symfony/Component/Serializer/Normalizer/GetSetMethodNormalizer.php

https://github.com/societies/SOCIETIES-Platform · PHP · 190 lines · 103 code · 24 blank · 63 comment · 12 complexity · 521ae607ababbd7fa037a0085c89a71f MD5 · raw file

  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. use Symfony\Component\Serializer\Exception\RuntimeException;
  12. /**
  13. * Converts between objects with getter and setter methods and arrays.
  14. *
  15. * The normalization process looks at all public methods and calls the ones
  16. * which have a name starting with get and take no parameters. The result is a
  17. * map from property names (method name stripped of the get prefix and converted
  18. * to lower case) to property values. Property values are normalized through the
  19. * serializer.
  20. *
  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. * setter method exists for any of the properties. If a setter exists it is
  27. * called with the property value. No automatic denormalization of the value
  28. * takes place.
  29. *
  30. * @author Nils Adermann <naderman@naderman.de>
  31. */
  32. class GetSetMethodNormalizer extends SerializerAwareNormalizer implements NormalizerInterface, DenormalizerInterface
  33. {
  34. protected $callbacks = array();
  35. protected $ignoredAttributes = array();
  36. /**
  37. * Set normalization callbacks
  38. *
  39. * @param array $callbacks help normalize the result
  40. */
  41. public function setCallbacks(array $callbacks)
  42. {
  43. foreach ($callbacks as $attribute => $callback) {
  44. if (!is_callable($callback)) {
  45. throw new \InvalidArgumentException(sprintf('The given callback for attribute "%s" is not callable.', $attribute));
  46. }
  47. }
  48. $this->callbacks = $callbacks;
  49. }
  50. /**
  51. * Set ignored attributes for normalization
  52. *
  53. * @param array $ignoredAttributes
  54. */
  55. public function setIgnoredAttributes(array $ignoredAttributes)
  56. {
  57. $this->ignoredAttributes = $ignoredAttributes;
  58. }
  59. /**
  60. * {@inheritdoc}
  61. */
  62. public function normalize($object, $format = null)
  63. {
  64. $reflectionObject = new \ReflectionObject($object);
  65. $reflectionMethods = $reflectionObject->getMethods(\ReflectionMethod::IS_PUBLIC);
  66. $attributes = array();
  67. foreach ($reflectionMethods as $method) {
  68. if ($this->isGetMethod($method)) {
  69. $attributeName = lcfirst(substr($method->name, 3));
  70. if (in_array($attributeName, $this->ignoredAttributes)) {
  71. continue;
  72. }
  73. $attributeValue = $method->invoke($object);
  74. if (array_key_exists($attributeName, $this->callbacks)) {
  75. $attributeValue = call_user_func($this->callbacks[$attributeName], $attributeValue);
  76. }
  77. if (null !== $attributeValue && !is_scalar($attributeValue)) {
  78. $attributeValue = $this->serializer->normalize($attributeValue, $format);
  79. }
  80. $attributes[$attributeName] = $attributeValue;
  81. }
  82. }
  83. return $attributes;
  84. }
  85. /**
  86. * {@inheritdoc}
  87. */
  88. public function denormalize($data, $class, $format = null)
  89. {
  90. $reflectionClass = new \ReflectionClass($class);
  91. $constructor = $reflectionClass->getConstructor();
  92. if ($constructor) {
  93. $constructorParameters = $constructor->getParameters();
  94. $params = array();
  95. foreach ($constructorParameters as $constructorParameter) {
  96. $paramName = lcfirst($constructorParameter->name);
  97. if (isset($data[$paramName])) {
  98. $params[] = $data[$paramName];
  99. // don't run set for a parameter passed to the constructor
  100. unset($data[$paramName]);
  101. } elseif (!$constructorParameter->isOptional()) {
  102. throw new RuntimeException(
  103. 'Cannot create an instance of '.$class.
  104. ' from serialized data because its constructor requires '.
  105. 'parameter "'.$constructorParameter->name.
  106. '" to be present.');
  107. }
  108. }
  109. $object = $reflectionClass->newInstanceArgs($params);
  110. } else {
  111. $object = new $class;
  112. }
  113. foreach ($data as $attribute => $value) {
  114. $setter = 'set'.$attribute;
  115. if (method_exists($object, $setter)) {
  116. $object->$setter($value);
  117. }
  118. }
  119. return $object;
  120. }
  121. /**
  122. * {@inheritDoc}
  123. */
  124. public function supportsNormalization($data, $format = null)
  125. {
  126. return is_object($data) && $this->supports(get_class($data));
  127. }
  128. /**
  129. * {@inheritDoc}
  130. */
  131. public function supportsDenormalization($data, $type, $format = null)
  132. {
  133. return $this->supports($type);
  134. }
  135. /**
  136. * Checks if the given class has any get{Property} method.
  137. *
  138. * @param string $class
  139. * @return Boolean
  140. */
  141. private function supports($class)
  142. {
  143. $class = new \ReflectionClass($class);
  144. $methods = $class->getMethods(\ReflectionMethod::IS_PUBLIC);
  145. foreach ($methods as $method) {
  146. if ($this->isGetMethod($method)) {
  147. return true;
  148. }
  149. }
  150. return false;
  151. }
  152. /**
  153. * Checks if a method's name is get.* and can be called without parameters.
  154. *
  155. * @param ReflectionMethod $method the method to check
  156. * @return Boolean whether the method is a getter.
  157. */
  158. private function isGetMethod(\ReflectionMethod $method)
  159. {
  160. return (
  161. 0 === strpos($method->name, 'get') &&
  162. 3 < strlen($method->name) &&
  163. 0 === $method->getNumberOfRequiredParameters()
  164. );
  165. }
  166. }