comparison vendor/symfony/serializer/Normalizer/GetSetMethodNormalizer.php @ 0:4c8ae668cc8c

Initial import (non-working)
author Chris Cannam
date Wed, 29 Nov 2017 16:09:58 +0000
parents
children 1fec387a4317
comparison
equal deleted inserted replaced
-1:000000000000 0:4c8ae668cc8c
1 <?php
2
3 /*
4 * This file is part of the Symfony package.
5 *
6 * (c) Fabien Potencier <fabien@symfony.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12 namespace Symfony\Component\Serializer\Normalizer;
13
14 /**
15 * Converts between objects with getter and setter methods and arrays.
16 *
17 * The normalization process looks at all public methods and calls the ones
18 * which have a name starting with get and take no parameters. The result is a
19 * map from property names (method name stripped of the get prefix and converted
20 * to lower case) to property values. Property values are normalized through the
21 * serializer.
22 *
23 * The denormalization first looks at the constructor of the given class to see
24 * if any of the parameters have the same name as one of the properties. The
25 * constructor is then called with all parameters or an exception is thrown if
26 * any required parameters were not present as properties. Then the denormalizer
27 * walks through the given map of property names to property values to see if a
28 * setter method exists for any of the properties. If a setter exists it is
29 * called with the property value. No automatic denormalization of the value
30 * takes place.
31 *
32 * @author Nils Adermann <naderman@naderman.de>
33 * @author Kévin Dunglas <dunglas@gmail.com>
34 */
35 class GetSetMethodNormalizer extends AbstractObjectNormalizer
36 {
37 private static $setterAccessibleCache = array();
38
39 /**
40 * {@inheritdoc}
41 */
42 public function supportsNormalization($data, $format = null)
43 {
44 return parent::supportsNormalization($data, $format) && $this->supports(get_class($data));
45 }
46
47 /**
48 * {@inheritdoc}
49 */
50 public function supportsDenormalization($data, $type, $format = null)
51 {
52 return parent::supportsDenormalization($data, $type, $format) && $this->supports($type);
53 }
54
55 /**
56 * Checks if the given class has any get{Property} method.
57 *
58 * @param string $class
59 *
60 * @return bool
61 */
62 private function supports($class)
63 {
64 $class = new \ReflectionClass($class);
65 $methods = $class->getMethods(\ReflectionMethod::IS_PUBLIC);
66 foreach ($methods as $method) {
67 if ($this->isGetMethod($method)) {
68 return true;
69 }
70 }
71
72 return false;
73 }
74
75 /**
76 * Checks if a method's name is get.* or is.*, and can be called without parameters.
77 *
78 * @param \ReflectionMethod $method the method to check
79 *
80 * @return bool whether the method is a getter or boolean getter
81 */
82 private function isGetMethod(\ReflectionMethod $method)
83 {
84 $methodLength = strlen($method->name);
85
86 return
87 !$method->isStatic() &&
88 (
89 ((0 === strpos($method->name, 'get') && 3 < $methodLength) ||
90 (0 === strpos($method->name, 'is') && 2 < $methodLength)) &&
91 0 === $method->getNumberOfRequiredParameters()
92 )
93 ;
94 }
95
96 /**
97 * {@inheritdoc}
98 */
99 protected function extractAttributes($object, $format = null, array $context = array())
100 {
101 $reflectionObject = new \ReflectionObject($object);
102 $reflectionMethods = $reflectionObject->getMethods(\ReflectionMethod::IS_PUBLIC);
103
104 $attributes = array();
105 foreach ($reflectionMethods as $method) {
106 if (!$this->isGetMethod($method)) {
107 continue;
108 }
109
110 $attributeName = lcfirst(substr($method->name, 0 === strpos($method->name, 'is') ? 2 : 3));
111
112 if ($this->isAllowedAttribute($object, $attributeName)) {
113 $attributes[] = $attributeName;
114 }
115 }
116
117 return $attributes;
118 }
119
120 /**
121 * {@inheritdoc}
122 */
123 protected function getAttributeValue($object, $attribute, $format = null, array $context = array())
124 {
125 $ucfirsted = ucfirst($attribute);
126
127 $getter = 'get'.$ucfirsted;
128 if (is_callable(array($object, $getter))) {
129 return $object->$getter();
130 }
131
132 $isser = 'is'.$ucfirsted;
133 if (is_callable(array($object, $isser))) {
134 return $object->$isser();
135 }
136 }
137
138 /**
139 * {@inheritdoc}
140 */
141 protected function setAttributeValue($object, $attribute, $value, $format = null, array $context = array())
142 {
143 $setter = 'set'.ucfirst($attribute);
144 $key = get_class($object).':'.$setter;
145
146 if (!isset(self::$setterAccessibleCache[$key])) {
147 self::$setterAccessibleCache[$key] = is_callable(array($object, $setter)) && !(new \ReflectionMethod($object, $setter))->isStatic();
148 }
149
150 if (self::$setterAccessibleCache[$key]) {
151 $object->$setter($value);
152 }
153 }
154 }