PageRenderTime 49ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/protected/extensions/doctrine/vendors/Symfony/Component/Serializer/Normalizer/GetSetMethodNormalizer.php

https://bitbucket.org/NordLabs/yiidoctrine
PHP | 155 lines | 82 code | 20 blank | 53 comment | 9 complexity | 1fd7262c7ec96fd348c15b6fe9dc35fe MD5 | raw file
Possible License(s): BSD-2-Clause, LGPL-2.1, BSD-3-Clause
  1. <?php
  2. namespace Symfony\Component\Serializer\Normalizer;
  3. use Symfony\Component\Serializer\Exception\RuntimeException;
  4. /*
  5. * This file is part of the Symfony framework.
  6. *
  7. * (c) Fabien Potencier <fabien@symfony.com>
  8. *
  9. * This source file is subject to the MIT license that is bundled
  10. * with this source code in the file LICENSE.
  11. */
  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
  33. {
  34. /**
  35. * {@inheritdoc}
  36. */
  37. public function normalize($object, $format = null)
  38. {
  39. $reflectionObject = new \ReflectionObject($object);
  40. $reflectionMethods = $reflectionObject->getMethods(\ReflectionMethod::IS_PUBLIC);
  41. $attributes = array();
  42. foreach ($reflectionMethods as $method) {
  43. if ($this->isGetMethod($method)) {
  44. $attributeName = strtolower(substr($method->getName(), 3));
  45. $attributeValue = $method->invoke($object);
  46. if (null !== $attributeValue && !is_scalar($attributeValue)) {
  47. $attributeValue = $this->serializer->normalize($attributeValue, $format);
  48. }
  49. $attributes[$attributeName] = $attributeValue;
  50. }
  51. }
  52. return $attributes;
  53. }
  54. /**
  55. * {@inheritdoc}
  56. */
  57. public function denormalize($data, $class, $format = null)
  58. {
  59. $reflectionClass = new \ReflectionClass($class);
  60. $constructor = $reflectionClass->getConstructor();
  61. if ($constructor) {
  62. $constructorParameters = $constructor->getParameters();
  63. $params = array();
  64. foreach ($constructorParameters as $constructorParameter) {
  65. $paramName = strtolower($constructorParameter->getName());
  66. if (isset($data[$paramName])) {
  67. $params[] = $data[$paramName];
  68. // don't run set for a parameter passed to the constructor
  69. unset($data[$paramName]);
  70. } elseif (!$constructorParameter->isOptional()) {
  71. throw new RuntimeException(
  72. 'Cannot create an instance of '.$class.
  73. ' from serialized data because its constructor requires '.
  74. 'parameter "'.$constructorParameter->getName().
  75. '" to be present.');
  76. }
  77. }
  78. $object = $reflectionClass->newInstanceArgs($params);
  79. } else {
  80. $object = new $class;
  81. }
  82. foreach ($data as $attribute => $value) {
  83. $setter = 'set'.$attribute;
  84. if (method_exists($object, $setter)) {
  85. $object->$setter($value);
  86. }
  87. }
  88. return $object;
  89. }
  90. /**
  91. * {@inheritDoc}
  92. */
  93. public function supportsNormalization($data, $format = null)
  94. {
  95. return is_object($data) && $this->supports(get_class($data));
  96. }
  97. /**
  98. * {@inheritDoc}
  99. */
  100. public function supportsDenormalization($data, $type, $format = null)
  101. {
  102. return $this->supports($type);
  103. }
  104. /**
  105. * Checks if the given class has any get{Property} method.
  106. *
  107. * @param string $class
  108. * @return Boolean
  109. */
  110. private function supports($class)
  111. {
  112. $class = new \ReflectionClass($class);
  113. $methods = $class->getMethods(\ReflectionMethod::IS_PUBLIC);
  114. foreach ($methods as $method) {
  115. if ($this->isGetMethod($method)) {
  116. return true;
  117. }
  118. }
  119. return false;
  120. }
  121. /**
  122. * Checks if a method's name is get.* and can be called without parameters.
  123. *
  124. * @param ReflectionMethod $method the method to check
  125. * @return Boolean whether the method is a getter.
  126. */
  127. private function isGetMethod(\ReflectionMethod $method)
  128. {
  129. return (
  130. 0 === strpos($method->getName(), 'get') &&
  131. 3 < strlen($method->getName()) &&
  132. 0 === $method->getNumberOfRequiredParameters()
  133. );
  134. }
  135. }