Mercurial > hg > isophonics-drupal-site
comparison vendor/symfony/serializer/Normalizer/AbstractObjectNormalizer.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 |
---|---|
11 | 11 |
12 namespace Symfony\Component\Serializer\Normalizer; | 12 namespace Symfony\Component\Serializer\Normalizer; |
13 | 13 |
14 use Symfony\Component\PropertyAccess\Exception\InvalidArgumentException; | 14 use Symfony\Component\PropertyAccess\Exception\InvalidArgumentException; |
15 use Symfony\Component\Serializer\Encoder\JsonEncoder; | 15 use Symfony\Component\Serializer\Encoder\JsonEncoder; |
16 use Symfony\Component\Serializer\Exception\ExtraAttributesException; | |
16 use Symfony\Component\Serializer\Exception\LogicException; | 17 use Symfony\Component\Serializer\Exception\LogicException; |
17 use Symfony\Component\Serializer\Exception\UnexpectedValueException; | 18 use Symfony\Component\Serializer\Exception\NotNormalizableValueException; |
18 use Symfony\Component\PropertyInfo\PropertyTypeExtractorInterface; | 19 use Symfony\Component\PropertyInfo\PropertyTypeExtractorInterface; |
19 use Symfony\Component\PropertyInfo\Type; | 20 use Symfony\Component\PropertyInfo\Type; |
20 use Symfony\Component\Serializer\Mapping\AttributeMetadataInterface; | 21 use Symfony\Component\Serializer\Mapping\AttributeMetadataInterface; |
21 use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface; | 22 use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface; |
22 use Symfony\Component\Serializer\NameConverter\NameConverterInterface; | 23 use Symfony\Component\Serializer\NameConverter\NameConverterInterface; |
28 */ | 29 */ |
29 abstract class AbstractObjectNormalizer extends AbstractNormalizer | 30 abstract class AbstractObjectNormalizer extends AbstractNormalizer |
30 { | 31 { |
31 const ENABLE_MAX_DEPTH = 'enable_max_depth'; | 32 const ENABLE_MAX_DEPTH = 'enable_max_depth'; |
32 const DEPTH_KEY_PATTERN = 'depth_%s::%s'; | 33 const DEPTH_KEY_PATTERN = 'depth_%s::%s'; |
34 const DISABLE_TYPE_ENFORCEMENT = 'disable_type_enforcement'; | |
33 | 35 |
34 private $propertyTypeExtractor; | 36 private $propertyTypeExtractor; |
35 private $attributesCache = array(); | 37 private $attributesCache = array(); |
38 private $cache = array(); | |
36 | 39 |
37 public function __construct(ClassMetadataFactoryInterface $classMetadataFactory = null, NameConverterInterface $nameConverter = null, PropertyTypeExtractorInterface $propertyTypeExtractor = null) | 40 public function __construct(ClassMetadataFactoryInterface $classMetadataFactory = null, NameConverterInterface $nameConverter = null, PropertyTypeExtractorInterface $propertyTypeExtractor = null) |
38 { | 41 { |
39 parent::__construct($classMetadataFactory, $nameConverter); | 42 parent::__construct($classMetadataFactory, $nameConverter); |
40 | 43 |
44 /** | 47 /** |
45 * {@inheritdoc} | 48 * {@inheritdoc} |
46 */ | 49 */ |
47 public function supportsNormalization($data, $format = null) | 50 public function supportsNormalization($data, $format = null) |
48 { | 51 { |
49 return is_object($data) && !$data instanceof \Traversable; | 52 return \is_object($data) && !$data instanceof \Traversable; |
50 } | 53 } |
51 | 54 |
52 /** | 55 /** |
53 * {@inheritdoc} | 56 * {@inheritdoc} |
54 */ | 57 */ |
89 foreach ($stack as $attribute => $attributeValue) { | 92 foreach ($stack as $attribute => $attributeValue) { |
90 if (!$this->serializer instanceof NormalizerInterface) { | 93 if (!$this->serializer instanceof NormalizerInterface) { |
91 throw new LogicException(sprintf('Cannot normalize attribute "%s" because the injected serializer is not a normalizer', $attribute)); | 94 throw new LogicException(sprintf('Cannot normalize attribute "%s" because the injected serializer is not a normalizer', $attribute)); |
92 } | 95 } |
93 | 96 |
94 $data = $this->updateData($data, $attribute, $this->serializer->normalize($attributeValue, $format, $context)); | 97 $data = $this->updateData($data, $attribute, $this->serializer->normalize($attributeValue, $format, $this->createChildContext($context, $attribute))); |
95 } | 98 } |
96 | 99 |
97 return $data; | 100 return $data; |
98 } | 101 } |
99 | 102 |
123 } | 126 } |
124 | 127 |
125 return $allowedAttributes; | 128 return $allowedAttributes; |
126 } | 129 } |
127 | 130 |
131 if (isset($context['attributes'])) { | |
132 return $this->extractAttributes($object, $format, $context); | |
133 } | |
134 | |
128 if (isset($this->attributesCache[$class])) { | 135 if (isset($this->attributesCache[$class])) { |
129 return $this->attributesCache[$class]; | 136 return $this->attributesCache[$class]; |
130 } | 137 } |
131 | 138 |
132 return $this->attributesCache[$class] = $this->extractAttributes($object, $format, $context); | 139 return $this->attributesCache[$class] = $this->extractAttributes($object, $format, $context); |
158 /** | 165 /** |
159 * {@inheritdoc} | 166 * {@inheritdoc} |
160 */ | 167 */ |
161 public function supportsDenormalization($data, $type, $format = null) | 168 public function supportsDenormalization($data, $type, $format = null) |
162 { | 169 { |
163 return class_exists($type); | 170 return isset($this->cache[$type]) ? $this->cache[$type] : $this->cache[$type] = class_exists($type); |
164 } | 171 } |
165 | 172 |
166 /** | 173 /** |
167 * {@inheritdoc} | 174 * {@inheritdoc} |
168 */ | 175 */ |
169 public function denormalize($data, $class, $format = null, array $context = array()) | 176 public function denormalize($data, $class, $format = null, array $context = array()) |
170 { | 177 { |
171 if (!isset($context['cache_key'])) { | 178 if (!isset($context['cache_key'])) { |
172 $context['cache_key'] = $this->getCacheKey($format, $context); | 179 $context['cache_key'] = $this->getCacheKey($format, $context); |
173 } | 180 } |
181 | |
174 $allowedAttributes = $this->getAllowedAttributes($class, $context, true); | 182 $allowedAttributes = $this->getAllowedAttributes($class, $context, true); |
175 $normalizedData = $this->prepareForDenormalization($data); | 183 $normalizedData = $this->prepareForDenormalization($data); |
184 $extraAttributes = array(); | |
176 | 185 |
177 $reflectionClass = new \ReflectionClass($class); | 186 $reflectionClass = new \ReflectionClass($class); |
178 $object = $this->instantiateObject($normalizedData, $class, $context, $reflectionClass, $allowedAttributes, $format); | 187 $object = $this->instantiateObject($normalizedData, $class, $context, $reflectionClass, $allowedAttributes, $format); |
179 | 188 |
180 foreach ($normalizedData as $attribute => $value) { | 189 foreach ($normalizedData as $attribute => $value) { |
181 if ($this->nameConverter) { | 190 if ($this->nameConverter) { |
182 $attribute = $this->nameConverter->denormalize($attribute); | 191 $attribute = $this->nameConverter->denormalize($attribute); |
183 } | 192 } |
184 | 193 |
185 if (($allowedAttributes !== false && !in_array($attribute, $allowedAttributes)) || !$this->isAllowedAttribute($class, $attribute, $format, $context)) { | 194 if ((false !== $allowedAttributes && !in_array($attribute, $allowedAttributes)) || !$this->isAllowedAttribute($class, $attribute, $format, $context)) { |
195 if (isset($context[self::ALLOW_EXTRA_ATTRIBUTES]) && !$context[self::ALLOW_EXTRA_ATTRIBUTES]) { | |
196 $extraAttributes[] = $attribute; | |
197 } | |
198 | |
186 continue; | 199 continue; |
187 } | 200 } |
188 | 201 |
189 $value = $this->validateAndDenormalize($class, $attribute, $value, $format, $context); | 202 $value = $this->validateAndDenormalize($class, $attribute, $value, $format, $context); |
190 try { | 203 try { |
191 $this->setAttributeValue($object, $attribute, $value, $format, $context); | 204 $this->setAttributeValue($object, $attribute, $value, $format, $context); |
192 } catch (InvalidArgumentException $e) { | 205 } catch (InvalidArgumentException $e) { |
193 throw new UnexpectedValueException($e->getMessage(), $e->getCode(), $e); | 206 throw new NotNormalizableValueException($e->getMessage(), $e->getCode(), $e); |
194 } | 207 } |
208 } | |
209 | |
210 if (!empty($extraAttributes)) { | |
211 throw new ExtraAttributesException($extraAttributes); | |
195 } | 212 } |
196 | 213 |
197 return $object; | 214 return $object; |
198 } | 215 } |
199 | 216 |
217 * @param string|null $format | 234 * @param string|null $format |
218 * @param array $context | 235 * @param array $context |
219 * | 236 * |
220 * @return mixed | 237 * @return mixed |
221 * | 238 * |
222 * @throws UnexpectedValueException | 239 * @throws NotNormalizableValueException |
223 * @throws LogicException | 240 * @throws LogicException |
224 */ | 241 */ |
225 private function validateAndDenormalize($currentClass, $attribute, $data, $format, array $context) | 242 private function validateAndDenormalize($currentClass, $attribute, $data, $format, array $context) |
226 { | 243 { |
227 if (null === $this->propertyTypeExtractor || null === $types = $this->propertyTypeExtractor->getTypes($currentClass, $attribute)) { | 244 if (null === $this->propertyTypeExtractor || null === $types = $this->propertyTypeExtractor->getTypes($currentClass, $attribute)) { |
251 if (Type::BUILTIN_TYPE_OBJECT === $builtinType) { | 268 if (Type::BUILTIN_TYPE_OBJECT === $builtinType) { |
252 if (!$this->serializer instanceof DenormalizerInterface) { | 269 if (!$this->serializer instanceof DenormalizerInterface) { |
253 throw new LogicException(sprintf('Cannot denormalize attribute "%s" for class "%s" because injected serializer is not a denormalizer', $attribute, $class)); | 270 throw new LogicException(sprintf('Cannot denormalize attribute "%s" for class "%s" because injected serializer is not a denormalizer', $attribute, $class)); |
254 } | 271 } |
255 | 272 |
256 if ($this->serializer->supportsDenormalization($data, $class, $format)) { | 273 $childContext = $this->createChildContext($context, $attribute); |
257 return $this->serializer->denormalize($data, $class, $format, $context); | 274 if ($this->serializer->supportsDenormalization($data, $class, $format, $childContext)) { |
275 return $this->serializer->denormalize($data, $class, $format, $childContext); | |
258 } | 276 } |
259 } | 277 } |
260 | 278 |
261 // JSON only has a Number type corresponding to both int and float PHP types. | 279 // JSON only has a Number type corresponding to both int and float PHP types. |
262 // PHP's json_encode, JavaScript's JSON.stringify, Go's json.Marshal as well as most other JSON encoders convert | 280 // PHP's json_encode, JavaScript's JSON.stringify, Go's json.Marshal as well as most other JSON encoders convert |
271 if (call_user_func('is_'.$builtinType, $data)) { | 289 if (call_user_func('is_'.$builtinType, $data)) { |
272 return $data; | 290 return $data; |
273 } | 291 } |
274 } | 292 } |
275 | 293 |
276 throw new UnexpectedValueException(sprintf('The type of the "%s" attribute for class "%s" must be one of "%s" ("%s" given).', $attribute, $currentClass, implode('", "', array_keys($expectedTypes)), gettype($data))); | 294 if (!empty($context[self::DISABLE_TYPE_ENFORCEMENT])) { |
295 return $data; | |
296 } | |
297 | |
298 throw new NotNormalizableValueException(sprintf('The type of the "%s" attribute for class "%s" must be one of "%s" ("%s" given).', $attribute, $currentClass, implode('", "', array_keys($expectedTypes)), gettype($data))); | |
277 } | 299 } |
278 | 300 |
279 /** | 301 /** |
280 * Sets an attribute and apply the name converter if necessary. | 302 * Sets an attribute and apply the name converter if necessary. |
281 * | 303 * |