|
26 | 26 | */
|
27 | 27 | class ObjectNormalizer extends AbstractNormalizer
|
28 | 28 | {
|
| 29 | + private static $attributesCache = array(); |
| 30 | + |
29 | 31 | /**
|
30 | 32 | * @var PropertyAccessorInterface
|
31 | 33 | */
|
@@ -58,42 +60,7 @@ public function normalize($object, $format = null, array $context = array())
|
58 | 60 | }
|
59 | 61 |
|
60 | 62 | $data = array();
|
61 |
| - $attributes = $this->getAllowedAttributes($object, $context, true); |
62 |
| - |
63 |
| - // If not using groups, detect manually |
64 |
| - if (false === $attributes) { |
65 |
| - $attributes = array(); |
66 |
| - |
67 |
| - // methods |
68 |
| - $reflClass = new \ReflectionClass($object); |
69 |
| - foreach ($reflClass->getMethods(\ReflectionMethod::IS_PUBLIC) as $reflMethod) { |
70 |
| - if ( |
71 |
| - !$reflMethod->isStatic() && |
72 |
| - !$reflMethod->isConstructor() && |
73 |
| - !$reflMethod->isDestructor() && |
74 |
| - 0 === $reflMethod->getNumberOfRequiredParameters() |
75 |
| - ) { |
76 |
| - $name = $reflMethod->getName(); |
77 |
| - |
78 |
| - if (strpos($name, 'get') === 0 || strpos($name, 'has') === 0) { |
79 |
| - // getters and hassers |
80 |
| - $attributes[lcfirst(substr($name, 3))] = true; |
81 |
| - } elseif (strpos($name, 'is') === 0) { |
82 |
| - // issers |
83 |
| - $attributes[lcfirst(substr($name, 2))] = true; |
84 |
| - } |
85 |
| - } |
86 |
| - } |
87 |
| - |
88 |
| - // properties |
89 |
| - foreach ($reflClass->getProperties(\ReflectionProperty::IS_PUBLIC) as $reflProperty) { |
90 |
| - if (!$reflProperty->isStatic()) { |
91 |
| - $attributes[$reflProperty->getName()] = true; |
92 |
| - } |
93 |
| - } |
94 |
| - |
95 |
| - $attributes = array_keys($attributes); |
96 |
| - } |
| 63 | + $attributes = $this->getAttributes($object, $context); |
97 | 64 |
|
98 | 65 | foreach ($attributes as $attribute) {
|
99 | 66 | if (in_array($attribute, $this->ignoredAttributes)) {
|
@@ -162,4 +129,64 @@ public function denormalize($data, $class, $format = null, array $context = arra
|
162 | 129 |
|
163 | 130 | return $object;
|
164 | 131 | }
|
| 132 | + |
| 133 | + /** |
| 134 | + * Gets and caches attributes for this class and context. |
| 135 | + * |
| 136 | + * @param object $object |
| 137 | + * @param array $context |
| 138 | + * |
| 139 | + * @return array |
| 140 | + */ |
| 141 | + private function getAttributes($object, array $context) |
| 142 | + { |
| 143 | + $key = sprintf('%s-%s', get_class($object), serialize($context)); |
| 144 | + |
| 145 | + if (isset(self::$attributesCache[$key])) { |
| 146 | + return self::$attributesCache[$key]; |
| 147 | + } |
| 148 | + |
| 149 | + $allowedAttributes = $this->getAllowedAttributes($object, $context, true); |
| 150 | + |
| 151 | + if (false !== $allowedAttributes) { |
| 152 | + return self::$attributesCache[$key] = $allowedAttributes; |
| 153 | + } |
| 154 | + |
| 155 | + // If not using groups, detect manually |
| 156 | + $attributes = array(); |
| 157 | + |
| 158 | + // methods |
| 159 | + $reflClass = new \ReflectionClass($object); |
| 160 | + foreach ($reflClass->getMethods(\ReflectionMethod::IS_PUBLIC) as $reflMethod) { |
| 161 | + if ( |
| 162 | + $reflMethod->getNumberOfRequiredParameters() !== 0 || |
| 163 | + $reflMethod->isStatic() || |
| 164 | + $reflMethod->isConstructor() || |
| 165 | + $reflMethod->isDestructor() |
| 166 | + ) { |
| 167 | + continue; |
| 168 | + } |
| 169 | + |
| 170 | + $name = $reflMethod->getName(); |
| 171 | + |
| 172 | + if (strpos($name, 'get') === 0 || strpos($name, 'has') === 0) { |
| 173 | + // getters and hassers |
| 174 | + $attributes[lcfirst(substr($name, 3))] = true; |
| 175 | + } elseif (strpos($name, 'is') === 0) { |
| 176 | + // issers |
| 177 | + $attributes[lcfirst(substr($name, 2))] = true; |
| 178 | + } |
| 179 | + } |
| 180 | + |
| 181 | + // properties |
| 182 | + foreach ($reflClass->getProperties(\ReflectionProperty::IS_PUBLIC) as $reflProperty) { |
| 183 | + if ($reflProperty->isStatic()) { |
| 184 | + continue; |
| 185 | + } |
| 186 | + |
| 187 | + $attributes[$reflProperty->getName()] = true; |
| 188 | + } |
| 189 | + |
| 190 | + return self::$attributesCache[$key] = array_keys($attributes); |
| 191 | + } |
165 | 192 | }
|
0 commit comments