vendor/jms/serializer/src/JMS/Serializer/Serializer.php line 166

Open in your IDE?
  1. <?php
  2. namespace JMS\Serializer;
  3. use JMS\Serializer\Construction\ObjectConstructorInterface;
  4. use JMS\Serializer\ContextFactory\DefaultDeserializationContextFactory;
  5. use JMS\Serializer\ContextFactory\DefaultSerializationContextFactory;
  6. use JMS\Serializer\ContextFactory\DeserializationContextFactoryInterface;
  7. use JMS\Serializer\ContextFactory\SerializationContextFactoryInterface;
  8. use JMS\Serializer\EventDispatcher\EventDispatcherInterface;
  9. use JMS\Serializer\Exception\RuntimeException;
  10. use JMS\Serializer\Exception\UnsupportedFormatException;
  11. use JMS\Serializer\Expression\ExpressionEvaluatorInterface;
  12. use JMS\Serializer\Handler\HandlerRegistryInterface;
  13. use Metadata\MetadataFactoryInterface;
  14. use PhpCollection\MapInterface;
  15. /**
  16.  * Serializer Implementation.
  17.  *
  18.  * @author Johannes M. Schmitt <schmittjoh@gmail.com>
  19.  */
  20. class Serializer implements SerializerInterfaceArrayTransformerInterface
  21. {
  22.     private $factory;
  23.     private $handlerRegistry;
  24.     private $objectConstructor;
  25.     private $dispatcher;
  26.     private $typeParser;
  27.     /** @var \PhpCollection\MapInterface */
  28.     private $serializationVisitors;
  29.     /** @var \PhpCollection\MapInterface */
  30.     private $deserializationVisitors;
  31.     private $navigator;
  32.     /**
  33.      * @var SerializationContextFactoryInterface
  34.      */
  35.     private $serializationContextFactory;
  36.     /**
  37.      * @var DeserializationContextFactoryInterface
  38.      */
  39.     private $deserializationContextFactory;
  40.     /**
  41.      * Constructor.
  42.      *
  43.      * @param \Metadata\MetadataFactoryInterface $factory
  44.      * @param Handler\HandlerRegistryInterface $handlerRegistry
  45.      * @param Construction\ObjectConstructorInterface $objectConstructor
  46.      * @param \PhpCollection\MapInterface $serializationVisitors of VisitorInterface
  47.      * @param \PhpCollection\MapInterface $deserializationVisitors of VisitorInterface
  48.      * @param EventDispatcher\EventDispatcherInterface $dispatcher
  49.      * @param TypeParser $typeParser
  50.      * @param ExpressionEvaluatorInterface|null $expressionEvaluator
  51.      */
  52.     public function __construct(
  53.         MetadataFactoryInterface $factory,
  54.         HandlerRegistryInterface $handlerRegistry,
  55.         ObjectConstructorInterface $objectConstructor,
  56.         MapInterface $serializationVisitors,
  57.         MapInterface $deserializationVisitors,
  58.         EventDispatcherInterface $dispatcher null,
  59.         TypeParser $typeParser null,
  60.         ExpressionEvaluatorInterface $expressionEvaluator null
  61.     )
  62.     {
  63.         $this->factory $factory;
  64.         $this->handlerRegistry $handlerRegistry;
  65.         $this->objectConstructor $objectConstructor;
  66.         $this->dispatcher $dispatcher;
  67.         $this->typeParser $typeParser ?: new TypeParser();
  68.         $this->serializationVisitors $serializationVisitors;
  69.         $this->deserializationVisitors $deserializationVisitors;
  70.         $this->navigator = new GraphNavigator($this->factory$this->handlerRegistry$this->objectConstructor$this->dispatcher$expressionEvaluator);
  71.         $this->serializationContextFactory = new DefaultSerializationContextFactory();
  72.         $this->deserializationContextFactory = new DefaultDeserializationContextFactory();
  73.     }
  74.     public function serialize($data$formatSerializationContext $context null)
  75.     {
  76.         if (null === $context) {
  77.             $context $this->serializationContextFactory->createSerializationContext();
  78.         }
  79.         return $this->serializationVisitors->get($format)
  80.             ->map(function (VisitorInterface $visitor) use ($context$data$format) {
  81.                 $type $context->getInitialType() !== null $this->typeParser->parse($context->getInitialType()) : null;
  82.                 $this->visit($visitor$context$visitor->prepare($data), $format$type);
  83.                 return $visitor->getResult();
  84.             })
  85.             ->getOrThrow(new UnsupportedFormatException(sprintf('The format "%s" is not supported for serialization.'$format)));
  86.     }
  87.     public function deserialize($data$type$formatDeserializationContext $context null)
  88.     {
  89.         if (null === $context) {
  90.             $context $this->deserializationContextFactory->createDeserializationContext();
  91.         }
  92.         return $this->deserializationVisitors->get($format)
  93.             ->map(function (VisitorInterface $visitor) use ($context$data$format$type) {
  94.                 $preparedData $visitor->prepare($data);
  95.                 $navigatorResult $this->visit($visitor$context$preparedData$format$this->typeParser->parse($type));
  96.                 return $this->handleDeserializeResult($visitor->getResult(), $navigatorResult);
  97.             })
  98.             ->getOrThrow(new UnsupportedFormatException(sprintf('The format "%s" is not supported for deserialization.'$format)));
  99.     }
  100.     /**
  101.      * {@InheritDoc}
  102.      */
  103.     public function toArray($dataSerializationContext $context null)
  104.     {
  105.         if (null === $context) {
  106.             $context $this->serializationContextFactory->createSerializationContext();
  107.         }
  108.         return $this->serializationVisitors->get('json')
  109.             ->map(function (JsonSerializationVisitor $visitor) use ($context$data) {
  110.                 $type $context->getInitialType() !== null $this->typeParser->parse($context->getInitialType()) : null;
  111.                 $this->visit($visitor$context$data'json'$type);
  112.                 $result $this->convertArrayObjects($visitor->getRoot());
  113.                 if (!\is_array($result)) {
  114.                     throw new RuntimeException(sprintf(
  115.                         'The input data of type "%s" did not convert to an array, but got a result of type "%s".',
  116.                         \is_object($data) ? \get_class($data) : \gettype($data),
  117.                         \is_object($result) ? \get_class($result) : \gettype($result)
  118.                     ));
  119.                 }
  120.                 return $result;
  121.             })
  122.             ->get();
  123.     }
  124.     /**
  125.      * {@InheritDoc}
  126.      */
  127.     public function fromArray(array $data$typeDeserializationContext $context null)
  128.     {
  129.         if (null === $context) {
  130.             $context $this->deserializationContextFactory->createDeserializationContext();
  131.         }
  132.         return $this->deserializationVisitors->get('json')
  133.             ->map(function (JsonDeserializationVisitor $visitor) use ($data$type$context) {
  134.                 $navigatorResult $this->visit($visitor$context$data'json'$this->typeParser->parse($type));
  135.                 return $this->handleDeserializeResult($visitor->getResult(), $navigatorResult);
  136.             })
  137.             ->get();
  138.     }
  139.     private function visit(VisitorInterface $visitorContext $context$data$format, array $type null)
  140.     {
  141.         $context->initialize(
  142.             $format,
  143.             $visitor,
  144.             $this->navigator,
  145.             $this->factory
  146.         );
  147.         $visitor->setNavigator($this->navigator);
  148.         return $this->navigator->accept($data$type$context);
  149.     }
  150.     private function handleDeserializeResult($visitorResult$navigatorResult)
  151.     {
  152.         // This is a special case if the root is handled by a callback on the object itself.
  153.         if (null === $visitorResult && null !== $navigatorResult) {
  154.             return $navigatorResult;
  155.         }
  156.         return $visitorResult;
  157.     }
  158.     private function convertArrayObjects($data)
  159.     {
  160.         if ($data instanceof \ArrayObject || $data instanceof \stdClass) {
  161.             $data = (array)$data;
  162.         }
  163.         if (\is_array($data)) {
  164.             foreach ($data as $k => $v) {
  165.                 $data[$k] = $this->convertArrayObjects($v);
  166.             }
  167.         }
  168.         return $data;
  169.     }
  170.     /**
  171.      * @return MetadataFactoryInterface
  172.      */
  173.     public function getMetadataFactory()
  174.     {
  175.         return $this->factory;
  176.     }
  177.     /**
  178.      * @param SerializationContextFactoryInterface $serializationContextFactory
  179.      *
  180.      * @return self
  181.      */
  182.     public function setSerializationContextFactory(SerializationContextFactoryInterface $serializationContextFactory)
  183.     {
  184.         $this->serializationContextFactory $serializationContextFactory;
  185.         return $this;
  186.     }
  187.     /**
  188.      * @param DeserializationContextFactoryInterface $deserializationContextFactory
  189.      *
  190.      * @return self
  191.      */
  192.     public function setDeserializationContextFactory(DeserializationContextFactoryInterface $deserializationContextFactory)
  193.     {
  194.         $this->deserializationContextFactory $deserializationContextFactory;
  195.         return $this;
  196.     }
  197. }