ChainEncoder.php 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  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\Encoder;
  11. use Symfony\Component\Serializer\Exception\RuntimeException;
  12. /**
  13. * Encoder delegating the decoding to a chain of encoders.
  14. *
  15. * @author Jordi Boggiano <j.boggiano@seld.be>
  16. * @author Johannes M. Schmitt <schmittjoh@gmail.com>
  17. * @author Lukas Kahwe Smith <smith@pooteeweet.org>
  18. *
  19. * @final
  20. */
  21. class ChainEncoder implements ContextAwareEncoderInterface
  22. {
  23. protected $encoders = [];
  24. protected $encoderByFormat = [];
  25. public function __construct(array $encoders = [])
  26. {
  27. $this->encoders = $encoders;
  28. }
  29. /**
  30. * {@inheritdoc}
  31. */
  32. final public function encode($data, string $format, array $context = [])
  33. {
  34. return $this->getEncoder($format, $context)->encode($data, $format, $context);
  35. }
  36. /**
  37. * {@inheritdoc}
  38. */
  39. public function supportsEncoding(string $format, array $context = []): bool
  40. {
  41. try {
  42. $this->getEncoder($format, $context);
  43. } catch (RuntimeException $e) {
  44. return false;
  45. }
  46. return true;
  47. }
  48. /**
  49. * Checks whether the normalization is needed for the given format.
  50. */
  51. public function needsNormalization(string $format, array $context = []): bool
  52. {
  53. $encoder = $this->getEncoder($format, $context);
  54. if (!$encoder instanceof NormalizationAwareInterface) {
  55. return true;
  56. }
  57. if ($encoder instanceof self) {
  58. return $encoder->needsNormalization($format, $context);
  59. }
  60. return false;
  61. }
  62. /**
  63. * Gets the encoder supporting the format.
  64. *
  65. * @throws RuntimeException if no encoder is found
  66. */
  67. private function getEncoder(string $format, array $context): EncoderInterface
  68. {
  69. if (isset($this->encoderByFormat[$format])
  70. && isset($this->encoders[$this->encoderByFormat[$format]])
  71. ) {
  72. return $this->encoders[$this->encoderByFormat[$format]];
  73. }
  74. foreach ($this->encoders as $i => $encoder) {
  75. if ($encoder->supportsEncoding($format, $context)) {
  76. $this->encoderByFormat[$format] = $i;
  77. return $encoder;
  78. }
  79. }
  80. throw new RuntimeException(sprintf('No encoder found for format "%s".', $format));
  81. }
  82. }