Mercurial > hg > isophonics-drupal-site
comparison vendor/symfony/serializer/Normalizer/AbstractNormalizer.php @ 14:1fec387a4317
Update Drupal core to 8.5.2 via Composer
author | Chris Cannam |
---|---|
date | Mon, 23 Apr 2018 09:46:53 +0100 |
parents | 7a779792577d |
children | c2387f117808 |
comparison
equal
deleted
inserted
replaced
13:5fb285c0d0e3 | 14:1fec387a4317 |
---|---|
25 * | 25 * |
26 * @author Kévin Dunglas <dunglas@gmail.com> | 26 * @author Kévin Dunglas <dunglas@gmail.com> |
27 */ | 27 */ |
28 abstract class AbstractNormalizer extends SerializerAwareNormalizer implements NormalizerInterface, DenormalizerInterface, SerializerAwareInterface | 28 abstract class AbstractNormalizer extends SerializerAwareNormalizer implements NormalizerInterface, DenormalizerInterface, SerializerAwareInterface |
29 { | 29 { |
30 use ObjectToPopulateTrait; | |
31 | |
30 const CIRCULAR_REFERENCE_LIMIT = 'circular_reference_limit'; | 32 const CIRCULAR_REFERENCE_LIMIT = 'circular_reference_limit'; |
31 const OBJECT_TO_POPULATE = 'object_to_populate'; | 33 const OBJECT_TO_POPULATE = 'object_to_populate'; |
32 const GROUPS = 'groups'; | 34 const GROUPS = 'groups'; |
35 const ATTRIBUTES = 'attributes'; | |
36 const ALLOW_EXTRA_ATTRIBUTES = 'allow_extra_attributes'; | |
33 | 37 |
34 /** | 38 /** |
35 * @var int | 39 * @var int |
36 */ | 40 */ |
37 protected $circularReferenceLimit = 1; | 41 protected $circularReferenceLimit = 1; |
66 */ | 70 */ |
67 protected $camelizedAttributes = array(); | 71 protected $camelizedAttributes = array(); |
68 | 72 |
69 /** | 73 /** |
70 * Sets the {@link ClassMetadataFactoryInterface} to use. | 74 * Sets the {@link ClassMetadataFactoryInterface} to use. |
71 * | |
72 * @param ClassMetadataFactoryInterface|null $classMetadataFactory | |
73 * @param NameConverterInterface|null $nameConverter | |
74 */ | 75 */ |
75 public function __construct(ClassMetadataFactoryInterface $classMetadataFactory = null, NameConverterInterface $nameConverter = null) | 76 public function __construct(ClassMetadataFactoryInterface $classMetadataFactory = null, NameConverterInterface $nameConverter = null) |
76 { | 77 { |
77 $this->classMetadataFactory = $classMetadataFactory; | 78 $this->classMetadataFactory = $classMetadataFactory; |
78 $this->nameConverter = $nameConverter; | 79 $this->nameConverter = $nameConverter; |
79 } | 80 } |
80 | 81 |
81 /** | 82 /** |
82 * Set circular reference limit. | 83 * Set circular reference limit. |
83 * | 84 * |
84 * @param int $circularReferenceLimit limit of iterations for the same object | 85 * @param int $circularReferenceLimit Limit of iterations for the same object |
85 * | 86 * |
86 * @return self | 87 * @return self |
87 */ | 88 */ |
88 public function setCircularReferenceLimit($circularReferenceLimit) | 89 public function setCircularReferenceLimit($circularReferenceLimit) |
89 { | 90 { |
107 } | 108 } |
108 | 109 |
109 /** | 110 /** |
110 * Set normalization callbacks. | 111 * Set normalization callbacks. |
111 * | 112 * |
112 * @param callable[] $callbacks help normalize the result | 113 * @param callable[] $callbacks Help normalize the result |
113 * | 114 * |
114 * @return self | 115 * @return self |
115 * | 116 * |
116 * @throws InvalidArgumentException if a non-callable callback is set | 117 * @throws InvalidArgumentException if a non-callable callback is set |
117 */ | 118 */ |
118 public function setCallbacks(array $callbacks) | 119 public function setCallbacks(array $callbacks) |
119 { | 120 { |
120 foreach ($callbacks as $attribute => $callback) { | 121 foreach ($callbacks as $attribute => $callback) { |
121 if (!is_callable($callback)) { | 122 if (!\is_callable($callback)) { |
122 throw new InvalidArgumentException(sprintf( | 123 throw new InvalidArgumentException(sprintf( |
123 'The given callback for attribute "%s" is not callable.', | 124 'The given callback for attribute "%s" is not callable.', |
124 $attribute | 125 $attribute |
125 )); | 126 )); |
126 } | 127 } |
131 } | 132 } |
132 | 133 |
133 /** | 134 /** |
134 * Set ignored attributes for normalization and denormalization. | 135 * Set ignored attributes for normalization and denormalization. |
135 * | 136 * |
136 * @param array $ignoredAttributes | |
137 * | |
138 * @return self | 137 * @return self |
139 */ | 138 */ |
140 public function setIgnoredAttributes(array $ignoredAttributes) | 139 public function setIgnoredAttributes(array $ignoredAttributes) |
141 { | 140 { |
142 $this->ignoredAttributes = $ignoredAttributes; | 141 $this->ignoredAttributes = $ignoredAttributes; |
186 * @throws CircularReferenceException | 185 * @throws CircularReferenceException |
187 */ | 186 */ |
188 protected function handleCircularReference($object) | 187 protected function handleCircularReference($object) |
189 { | 188 { |
190 if ($this->circularReferenceHandler) { | 189 if ($this->circularReferenceHandler) { |
191 return call_user_func($this->circularReferenceHandler, $object); | 190 return \call_user_func($this->circularReferenceHandler, $object); |
192 } | 191 } |
193 | 192 |
194 throw new CircularReferenceException(sprintf('A circular reference has been detected when serializing the object of class "%s" (configured limit: %d)', get_class($object), $this->circularReferenceLimit)); | 193 throw new CircularReferenceException(sprintf('A circular reference has been detected when serializing the object of class "%s" (configured limit: %d)', \get_class($object), $this->circularReferenceLimit)); |
195 } | 194 } |
196 | 195 |
197 /** | 196 /** |
198 * Gets attributes to normalize using groups. | 197 * Gets attributes to normalize using groups. |
199 * | 198 * |
203 * | 202 * |
204 * @return string[]|AttributeMetadataInterface[]|bool | 203 * @return string[]|AttributeMetadataInterface[]|bool |
205 */ | 204 */ |
206 protected function getAllowedAttributes($classOrObject, array $context, $attributesAsString = false) | 205 protected function getAllowedAttributes($classOrObject, array $context, $attributesAsString = false) |
207 { | 206 { |
208 if (!$this->classMetadataFactory || !isset($context[static::GROUPS]) || !is_array($context[static::GROUPS])) { | 207 if (!$this->classMetadataFactory) { |
208 return false; | |
209 } | |
210 | |
211 $groups = false; | |
212 if (isset($context[static::GROUPS]) && \is_array($context[static::GROUPS])) { | |
213 $groups = $context[static::GROUPS]; | |
214 } elseif (!isset($context[static::ALLOW_EXTRA_ATTRIBUTES]) || $context[static::ALLOW_EXTRA_ATTRIBUTES]) { | |
209 return false; | 215 return false; |
210 } | 216 } |
211 | 217 |
212 $allowedAttributes = array(); | 218 $allowedAttributes = array(); |
213 foreach ($this->classMetadataFactory->getMetadataFor($classOrObject)->getAttributesMetadata() as $attributeMetadata) { | 219 foreach ($this->classMetadataFactory->getMetadataFor($classOrObject)->getAttributesMetadata() as $attributeMetadata) { |
214 $name = $attributeMetadata->getName(); | 220 $name = $attributeMetadata->getName(); |
215 | 221 |
216 if ( | 222 if ( |
217 count(array_intersect($attributeMetadata->getGroups(), $context[static::GROUPS])) && | 223 (false === $groups || array_intersect($attributeMetadata->getGroups(), $groups)) && |
218 $this->isAllowedAttribute($classOrObject, $name, null, $context) | 224 $this->isAllowedAttribute($classOrObject, $name, null, $context) |
219 ) { | 225 ) { |
220 $allowedAttributes[] = $attributesAsString ? $name : $attributeMetadata; | 226 $allowedAttributes[] = $attributesAsString ? $name : $attributeMetadata; |
221 } | 227 } |
222 } | 228 } |
234 * | 240 * |
235 * @return bool | 241 * @return bool |
236 */ | 242 */ |
237 protected function isAllowedAttribute($classOrObject, $attribute, $format = null, array $context = array()) | 243 protected function isAllowedAttribute($classOrObject, $attribute, $format = null, array $context = array()) |
238 { | 244 { |
239 return !in_array($attribute, $this->ignoredAttributes); | 245 if (in_array($attribute, $this->ignoredAttributes)) { |
246 return false; | |
247 } | |
248 | |
249 if (isset($context[self::ATTRIBUTES][$attribute])) { | |
250 // Nested attributes | |
251 return true; | |
252 } | |
253 | |
254 if (isset($context[self::ATTRIBUTES]) && is_array($context[self::ATTRIBUTES])) { | |
255 return in_array($attribute, $context[self::ATTRIBUTES], true); | |
256 } | |
257 | |
258 return true; | |
240 } | 259 } |
241 | 260 |
242 /** | 261 /** |
243 * Normalizes the given data to an array. It's particularly useful during | 262 * Normalizes the given data to an array. It's particularly useful during |
244 * the denormalization process. | 263 * the denormalization process. |
286 * | 305 * |
287 * @return object | 306 * @return object |
288 * | 307 * |
289 * @throws RuntimeException | 308 * @throws RuntimeException |
290 */ | 309 */ |
291 protected function instantiateObject(array &$data, $class, array &$context, \ReflectionClass $reflectionClass, $allowedAttributes/*, $format = null*/) | 310 protected function instantiateObject(array &$data, $class, array &$context, \ReflectionClass $reflectionClass, $allowedAttributes/*, string $format = null*/) |
292 { | 311 { |
293 if (func_num_args() >= 6) { | 312 if (\func_num_args() >= 6) { |
294 $format = func_get_arg(5); | 313 $format = \func_get_arg(5); |
295 } else { | 314 } else { |
296 if (__CLASS__ !== get_class($this)) { | 315 if (__CLASS__ !== \get_class($this)) { |
297 $r = new \ReflectionMethod($this, __FUNCTION__); | 316 $r = new \ReflectionMethod($this, __FUNCTION__); |
298 if (__CLASS__ !== $r->getDeclaringClass()->getName()) { | 317 if (__CLASS__ !== $r->getDeclaringClass()->getName()) { |
299 @trigger_error(sprintf('Method %s::%s() will have a 6th `$format = null` argument in version 4.0. Not defining it is deprecated since 3.2.', get_class($this), __FUNCTION__), E_USER_DEPRECATED); | 318 @trigger_error(sprintf('Method %s::%s() will have a 6th `string $format = null` argument in version 4.0. Not defining it is deprecated since Symfony 3.2.', get_class($this), __FUNCTION__), E_USER_DEPRECATED); |
300 } | 319 } |
301 } | 320 } |
302 | 321 |
303 $format = null; | 322 $format = null; |
304 } | 323 } |
305 | 324 |
306 if ( | 325 if (null !== $object = $this->extractObjectToPopulate($class, $context, static::OBJECT_TO_POPULATE)) { |
307 isset($context[static::OBJECT_TO_POPULATE]) && | |
308 is_object($context[static::OBJECT_TO_POPULATE]) && | |
309 $context[static::OBJECT_TO_POPULATE] instanceof $class | |
310 ) { | |
311 $object = $context[static::OBJECT_TO_POPULATE]; | |
312 unset($context[static::OBJECT_TO_POPULATE]); | 326 unset($context[static::OBJECT_TO_POPULATE]); |
313 | 327 |
314 return $object; | 328 return $object; |
315 } | 329 } |
316 | 330 |
321 $params = array(); | 335 $params = array(); |
322 foreach ($constructorParameters as $constructorParameter) { | 336 foreach ($constructorParameters as $constructorParameter) { |
323 $paramName = $constructorParameter->name; | 337 $paramName = $constructorParameter->name; |
324 $key = $this->nameConverter ? $this->nameConverter->normalize($paramName) : $paramName; | 338 $key = $this->nameConverter ? $this->nameConverter->normalize($paramName) : $paramName; |
325 | 339 |
326 $allowed = $allowedAttributes === false || in_array($paramName, $allowedAttributes); | 340 $allowed = false === $allowedAttributes || \in_array($paramName, $allowedAttributes); |
327 $ignored = in_array($paramName, $this->ignoredAttributes); | 341 $ignored = !$this->isAllowedAttribute($class, $paramName, $format, $context); |
328 if (method_exists($constructorParameter, 'isVariadic') && $constructorParameter->isVariadic()) { | 342 if (method_exists($constructorParameter, 'isVariadic') && $constructorParameter->isVariadic()) { |
329 if ($allowed && !$ignored && (isset($data[$key]) || array_key_exists($key, $data))) { | 343 if ($allowed && !$ignored && (isset($data[$key]) || array_key_exists($key, $data))) { |
330 if (!is_array($data[$paramName])) { | 344 if (!\is_array($data[$paramName])) { |
331 throw new RuntimeException(sprintf('Cannot create an instance of %s from serialized data because the variadic parameter %s can only accept an array.', $class, $constructorParameter->name)); | 345 throw new RuntimeException(sprintf('Cannot create an instance of %s from serialized data because the variadic parameter %s can only accept an array.', $class, $constructorParameter->name)); |
332 } | 346 } |
333 | 347 |
334 $params = array_merge($params, $data[$paramName]); | 348 $params = array_merge($params, $data[$paramName]); |
335 } | 349 } |
339 if (null !== $constructorParameter->getClass()) { | 353 if (null !== $constructorParameter->getClass()) { |
340 if (!$this->serializer instanceof DenormalizerInterface) { | 354 if (!$this->serializer instanceof DenormalizerInterface) { |
341 throw new LogicException(sprintf('Cannot create an instance of %s from serialized data because the serializer inject in "%s" is not a denormalizer', $constructorParameter->getClass(), static::class)); | 355 throw new LogicException(sprintf('Cannot create an instance of %s from serialized data because the serializer inject in "%s" is not a denormalizer', $constructorParameter->getClass(), static::class)); |
342 } | 356 } |
343 $parameterClass = $constructorParameter->getClass()->getName(); | 357 $parameterClass = $constructorParameter->getClass()->getName(); |
344 $parameterData = $this->serializer->denormalize($parameterData, $parameterClass, $format, $context); | 358 $parameterData = $this->serializer->denormalize($parameterData, $parameterClass, $format, $this->createChildContext($context, $paramName)); |
345 } | 359 } |
346 } catch (\ReflectionException $e) { | 360 } catch (\ReflectionException $e) { |
347 throw new RuntimeException(sprintf('Could not determine the class of the parameter "%s".', $key), 0, $e); | 361 throw new RuntimeException(sprintf('Could not determine the class of the parameter "%s".', $key), 0, $e); |
348 } | 362 } |
349 | 363 |
370 } | 384 } |
371 } | 385 } |
372 | 386 |
373 return new $class(); | 387 return new $class(); |
374 } | 388 } |
389 | |
390 /** | |
391 * @param array $parentContext | |
392 * @param string $attribute | |
393 * | |
394 * @return array | |
395 * | |
396 * @internal | |
397 */ | |
398 protected function createChildContext(array $parentContext, $attribute) | |
399 { | |
400 if (isset($parentContext[self::ATTRIBUTES][$attribute])) { | |
401 $parentContext[self::ATTRIBUTES] = $parentContext[self::ATTRIBUTES][$attribute]; | |
402 } else { | |
403 unset($parentContext[self::ATTRIBUTES]); | |
404 } | |
405 | |
406 return $parentContext; | |
407 } | |
375 } | 408 } |