vendor/symfony/serializer/Normalizer/MimeMessageNormalizer.php line 44

Open in your IDE?
  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\Mime\Address;
  12. use Symfony\Component\Mime\Header\HeaderInterface;
  13. use Symfony\Component\Mime\Header\Headers;
  14. use Symfony\Component\Mime\Header\UnstructuredHeader;
  15. use Symfony\Component\Mime\Message;
  16. use Symfony\Component\Mime\Part\AbstractPart;
  17. use Symfony\Component\Mime\RawMessage;
  18. use Symfony\Component\Serializer\SerializerAwareInterface;
  19. use Symfony\Component\Serializer\SerializerInterface;
  20. /**
  21. * Normalize Mime message classes.
  22. *
  23. * It forces the use of a PropertyNormalizer instance for normalization
  24. * of all data objects composing a Message.
  25. *
  26. * Emails using resources for any parts are not serializable.
  27. */
  28. final class MimeMessageNormalizer implements NormalizerInterface, DenormalizerInterface, SerializerAwareInterface, CacheableSupportsMethodInterface
  29. {
  30. private $serializer;
  31. private $normalizer;
  32. private $headerClassMap;
  33. private $headersProperty;
  34. public function __construct(PropertyNormalizer $normalizer)
  35. {
  36. $this->normalizer = $normalizer;
  37. $this->headerClassMap = (new \ReflectionClassConstant(Headers::class, 'HEADER_CLASS_MAP'))->getValue();
  38. $this->headersProperty = new \ReflectionProperty(Headers::class, 'headers');
  39. $this->headersProperty->setAccessible(true);
  40. }
  41. public function setSerializer(SerializerInterface $serializer)
  42. {
  43. $this->serializer = $serializer;
  44. $this->normalizer->setSerializer($serializer);
  45. }
  46. /**
  47. * {@inheritdoc}
  48. */
  49. public function normalize($object, ?string $format = null, array $context = [])
  50. {
  51. if ($object instanceof Headers) {
  52. $ret = [];
  53. foreach ($this->headersProperty->getValue($object) as $name => $header) {
  54. $ret[$name] = $this->serializer->normalize($header, $format, $context);
  55. }
  56. return $ret;
  57. }
  58. $ret = $this->normalizer->normalize($object, $format, $context);
  59. if ($object instanceof AbstractPart) {
  60. $ret['class'] = \get_class($object);
  61. unset($ret['seekable'], $ret['cid'], $ret['handle']);
  62. }
  63. if ($object instanceof RawMessage && \array_key_exists('message', $ret) && null === $ret['message']) {
  64. unset($ret['message']);
  65. }
  66. return $ret;
  67. }
  68. /**
  69. * {@inheritdoc}
  70. */
  71. public function denormalize($data, string $type, ?string $format = null, array $context = [])
  72. {
  73. if (Headers::class === $type) {
  74. $ret = [];
  75. foreach ($data as $headers) {
  76. foreach ($headers as $header) {
  77. $ret[] = $this->serializer->denormalize($header, $this->headerClassMap[strtolower($header['name'])] ?? UnstructuredHeader::class, $format, $context);
  78. }
  79. }
  80. return new Headers(...$ret);
  81. }
  82. if (AbstractPart::class === $type) {
  83. $type = $data['class'];
  84. unset($data['class']);
  85. $data['headers'] = $this->serializer->denormalize($data['headers'], Headers::class, $format, $context);
  86. }
  87. return $this->normalizer->denormalize($data, $type, $format, $context);
  88. }
  89. /**
  90. * {@inheritdoc}
  91. */
  92. public function supportsNormalization($data, ?string $format = null): bool
  93. {
  94. return $data instanceof Message || $data instanceof Headers || $data instanceof HeaderInterface || $data instanceof Address || $data instanceof AbstractPart;
  95. }
  96. /**
  97. * {@inheritdoc}
  98. */
  99. public function supportsDenormalization($data, string $type, ?string $format = null): bool
  100. {
  101. return is_a($type, Message::class, true) || Headers::class === $type || AbstractPart::class === $type;
  102. }
  103. /**
  104. * {@inheritdoc}
  105. */
  106. public function hasCacheableSupportsMethod(): bool
  107. {
  108. return __CLASS__ === static::class;
  109. }
  110. }