1<?php 2 3declare(strict_types=1); 4 5namespace JMS\Serializer\Handler; 6 7use Doctrine\Common\Collections\ArrayCollection; 8use Doctrine\Common\Collections\Collection; 9use JMS\Serializer\DeserializationContext; 10use JMS\Serializer\GraphNavigatorInterface; 11use JMS\Serializer\SerializationContext; 12use JMS\Serializer\Visitor\DeserializationVisitorInterface; 13use JMS\Serializer\Visitor\SerializationVisitorInterface; 14 15final class ArrayCollectionHandler implements SubscribingHandlerInterface 16{ 17 /** 18 * @var bool 19 */ 20 private $initializeExcluded = true; 21 22 public function __construct(bool $initializeExcluded = true) 23 { 24 $this->initializeExcluded = $initializeExcluded; 25 } 26 27 /** 28 * {@inheritdoc} 29 */ 30 public static function getSubscribingMethods() 31 { 32 $methods = []; 33 $formats = ['json', 'xml', 'yml']; 34 $collectionTypes = [ 35 'ArrayCollection', 36 'Doctrine\Common\Collections\ArrayCollection', 37 'Doctrine\ORM\PersistentCollection', 38 'Doctrine\ODM\MongoDB\PersistentCollection', 39 'Doctrine\ODM\PHPCR\PersistentCollection', 40 ]; 41 42 foreach ($collectionTypes as $type) { 43 foreach ($formats as $format) { 44 $methods[] = [ 45 'direction' => GraphNavigatorInterface::DIRECTION_SERIALIZATION, 46 'type' => $type, 47 'format' => $format, 48 'method' => 'serializeCollection', 49 ]; 50 51 $methods[] = [ 52 'direction' => GraphNavigatorInterface::DIRECTION_DESERIALIZATION, 53 'type' => $type, 54 'format' => $format, 55 'method' => 'deserializeCollection', 56 ]; 57 } 58 } 59 60 return $methods; 61 } 62 63 /** 64 * @return array|\ArrayObject 65 */ 66 public function serializeCollection(SerializationVisitorInterface $visitor, Collection $collection, array $type, SerializationContext $context) 67 { 68 // We change the base type, and pass through possible parameters. 69 $type['name'] = 'array'; 70 71 $context->stopVisiting($collection); 72 73 if (false === $this->initializeExcluded) { 74 $exclusionStrategy = $context->getExclusionStrategy(); 75 if (null !== $exclusionStrategy && $exclusionStrategy->shouldSkipClass($context->getMetadataFactory()->getMetadataForClass(\get_class($collection)), $context)) { 76 $context->startVisiting($collection); 77 78 return $visitor->visitArray([], $type, $context); 79 } 80 } 81 $result = $visitor->visitArray($collection->toArray(), $type); 82 83 $context->startVisiting($collection); 84 return $result; 85 } 86 87 /** 88 * @param mixed $data 89 */ 90 public function deserializeCollection(DeserializationVisitorInterface $visitor, $data, array $type, DeserializationContext $context): ArrayCollection 91 { 92 // See above. 93 $type['name'] = 'array'; 94 95 return new ArrayCollection($visitor->visitArray($data, $type)); 96 } 97} 98