ArrayDenormalizer.php 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\Serializer\Normalizer;
  11. use Symfony\Component\Serializer\Exception\BadMethodCallException;
  12. use Symfony\Component\Serializer\Exception\InvalidArgumentException;
  13. use Symfony\Component\Serializer\Exception\NotNormalizableValueException;
  14. use Symfony\Component\Serializer\SerializerAwareInterface;
  15. use Symfony\Component\Serializer\SerializerInterface;
  16. /**
  17. * Denormalizes arrays of objects.
  18. *
  19. * @author Alexander M. Turek <me@derrabus.de>
  20. *
  21. * @final
  22. */
  23. class ArrayDenormalizer implements ContextAwareDenormalizerInterface, SerializerAwareInterface, CacheableSupportsMethodInterface
  24. {
  25. /**
  26. * @var SerializerInterface|DenormalizerInterface
  27. */
  28. private $serializer;
  29. /**
  30. * {@inheritdoc}
  31. *
  32. * @throws NotNormalizableValueException
  33. *
  34. * @return array
  35. */
  36. public function denormalize($data, string $type, string $format = null, array $context = [])
  37. {
  38. if (null === $this->serializer) {
  39. throw new BadMethodCallException('Please set a serializer before calling denormalize()!');
  40. }
  41. if (!\is_array($data)) {
  42. throw new InvalidArgumentException('Data expected to be an array, '.get_debug_type($data).' given.');
  43. }
  44. if ('[]' !== substr($type, -2)) {
  45. throw new InvalidArgumentException('Unsupported class: '.$type);
  46. }
  47. $serializer = $this->serializer;
  48. $type = substr($type, 0, -2);
  49. $builtinType = isset($context['key_type']) ? $context['key_type']->getBuiltinType() : null;
  50. foreach ($data as $key => $value) {
  51. if (null !== $builtinType && !('is_'.$builtinType)($key)) {
  52. throw new NotNormalizableValueException(sprintf('The type of the key "%s" must be "%s" ("%s" given).', $key, $builtinType, get_debug_type($key)));
  53. }
  54. $data[$key] = $serializer->denormalize($value, $type, $format, $context);
  55. }
  56. return $data;
  57. }
  58. /**
  59. * {@inheritdoc}
  60. */
  61. public function supportsDenormalization($data, string $type, string $format = null, array $context = []): bool
  62. {
  63. if (null === $this->serializer) {
  64. throw new BadMethodCallException(sprintf('The serializer needs to be set to allow "%s()" to be used.', __METHOD__));
  65. }
  66. return '[]' === substr($type, -2)
  67. && $this->serializer->supportsDenormalization($data, substr($type, 0, -2), $format, $context);
  68. }
  69. /**
  70. * {@inheritdoc}
  71. */
  72. public function setSerializer(SerializerInterface $serializer)
  73. {
  74. if (!$serializer instanceof DenormalizerInterface) {
  75. throw new InvalidArgumentException('Expected a serializer that also implements DenormalizerInterface.');
  76. }
  77. $this->serializer = $serializer;
  78. }
  79. /**
  80. * {@inheritdoc}
  81. */
  82. public function hasCacheableSupportsMethod(): bool
  83. {
  84. return $this->serializer instanceof CacheableSupportsMethodInterface && $this->serializer->hasCacheableSupportsMethod();
  85. }
  86. }