schmittjoh /
serializer
| 1 | <?php |
||||||
| 2 | |||||||
| 3 | declare(strict_types=1); |
||||||
| 4 | |||||||
| 5 | namespace JMS\Serializer\Handler; |
||||||
| 6 | |||||||
| 7 | use Doctrine\Common\Collections\ArrayCollection; |
||||||
| 8 | use Doctrine\Common\Collections\Collection; |
||||||
| 9 | use Doctrine\ODM\MongoDB\PersistentCollection as MongoPersistentCollection; |
||||||
|
0 ignored issues
–
show
|
|||||||
| 10 | use Doctrine\ODM\PHPCR\PersistentCollection as PhpcrPersistentCollection; |
||||||
| 11 | use Doctrine\ORM\PersistentCollection as OrmPersistentCollection; |
||||||
| 12 | use Doctrine\Persistence\ManagerRegistry; |
||||||
| 13 | use JMS\Serializer\DeserializationContext; |
||||||
| 14 | use JMS\Serializer\GraphNavigatorInterface; |
||||||
| 15 | use JMS\Serializer\Metadata\PropertyMetadata; |
||||||
| 16 | use JMS\Serializer\SerializationContext; |
||||||
| 17 | use JMS\Serializer\Type\Type; |
||||||
| 18 | use JMS\Serializer\Visitor\DeserializationVisitorInterface; |
||||||
| 19 | use JMS\Serializer\Visitor\SerializationVisitorInterface; |
||||||
| 20 | |||||||
| 21 | /** |
||||||
| 22 | 329 | * @phpstan-import-type TypeArray from Type |
|||||
| 23 | */ |
||||||
| 24 | 329 | final class ArrayCollectionHandler implements SubscribingHandlerInterface |
|||||
| 25 | 329 | { |
|||||
| 26 | public const COLLECTION_TYPES = [ |
||||||
| 27 | 329 | 'ArrayCollection', |
|||||
| 28 | ArrayCollection::class, |
||||||
| 29 | 329 | OrmPersistentCollection::class, |
|||||
| 30 | 329 | MongoPersistentCollection::class, |
|||||
| 31 | PhpcrPersistentCollection::class, |
||||||
| 32 | 329 | ]; |
|||||
| 33 | |||||||
| 34 | /** |
||||||
| 35 | * @var bool |
||||||
| 36 | */ |
||||||
| 37 | private $initializeExcluded; |
||||||
| 38 | |||||||
| 39 | 329 | /** |
|||||
| 40 | 329 | * @var ManagerRegistry|null |
|||||
| 41 | 329 | */ |
|||||
| 42 | 329 | private $managerRegistry; |
|||||
| 43 | 329 | ||||||
| 44 | 329 | public function __construct( |
|||||
| 45 | 329 | bool $initializeExcluded = true, |
|||||
| 46 | ?ManagerRegistry $managerRegistry = null |
||||||
| 47 | ) { |
||||||
| 48 | 329 | $this->initializeExcluded = $initializeExcluded; |
|||||
| 49 | 329 | $this->managerRegistry = $managerRegistry; |
|||||
| 50 | 329 | } |
|||||
| 51 | 329 | ||||||
| 52 | 329 | /** |
|||||
| 53 | * {@inheritdoc} |
||||||
| 54 | */ |
||||||
| 55 | public static function getSubscribingMethods() |
||||||
| 56 | { |
||||||
| 57 | 329 | $methods = []; |
|||||
| 58 | $formats = ['json', 'xml']; |
||||||
| 59 | |||||||
| 60 | 9 | foreach (self::COLLECTION_TYPES as $type) { |
|||||
| 61 | foreach ($formats as $format) { |
||||||
| 62 | $methods[] = [ |
||||||
| 63 | 9 | 'direction' => GraphNavigatorInterface::DIRECTION_SERIALIZATION, |
|||||
| 64 | 'type' => $type, |
||||||
| 65 | 9 | 'format' => $format, |
|||||
| 66 | 'method' => 'serializeCollection', |
||||||
| 67 | 9 | ]; |
|||||
| 68 | |||||||
| 69 | $methods[] = [ |
||||||
| 70 | 'direction' => GraphNavigatorInterface::DIRECTION_DESERIALIZATION, |
||||||
| 71 | 'type' => $type, |
||||||
| 72 | 'format' => $format, |
||||||
| 73 | 'method' => 'deserializeCollection', |
||||||
| 74 | ]; |
||||||
| 75 | 9 | } |
|||||
| 76 | } |
||||||
| 77 | 9 | ||||||
| 78 | 9 | return $methods; |
|||||
| 79 | } |
||||||
| 80 | |||||||
| 81 | 6 | /** |
|||||
| 82 | * @param TypeArray $type |
||||||
|
0 ignored issues
–
show
The type
JMS\Serializer\Handler\TypeArray was not found. Maybe you did not declare it correctly or list all dependencies?
The issue could also be caused by a filter entry in the build configuration.
If the path has been excluded in your configuration, e.g. filter:
dependency_paths: ["lib/*"]
For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths Loading history...
|
|||||||
| 83 | * |
||||||
| 84 | 6 | * @return array|\ArrayObject |
|||||
| 85 | */ |
||||||
| 86 | 6 | public function serializeCollection(SerializationVisitorInterface $visitor, Collection $collection, array $type, SerializationContext $context) |
|||||
| 87 | { |
||||||
| 88 | // We change the base type, and pass through possible parameters. |
||||||
| 89 | $type['name'] = 'array'; |
||||||
| 90 | |||||||
| 91 | $context->stopVisiting($collection); |
||||||
| 92 | |||||||
| 93 | if (false === $this->initializeExcluded) { |
||||||
| 94 | $exclusionStrategy = $context->getExclusionStrategy(); |
||||||
| 95 | if (null !== $exclusionStrategy && $exclusionStrategy->shouldSkipClass($context->getMetadataFactory()->getMetadataForClass(\get_class($collection)), $context)) { |
||||||
|
0 ignored issues
–
show
It seems like
$context->getMetadataFac...get_class($collection)) can also be of type Metadata\ClassHierarchyMetadata and null; however, parameter $metadata of JMS\Serializer\Exclusion...face::shouldSkipClass() does only seem to accept JMS\Serializer\Metadata\ClassMetadata, maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
| 96 | $context->startVisiting($collection); |
||||||
| 97 | |||||||
| 98 | return $visitor->visitArray([], $type); |
||||||
| 99 | } |
||||||
| 100 | } |
||||||
| 101 | |||||||
| 102 | $result = $visitor->visitArray($collection->toArray(), $type); |
||||||
| 103 | |||||||
| 104 | $context->startVisiting($collection); |
||||||
| 105 | |||||||
| 106 | return $result; |
||||||
| 107 | } |
||||||
| 108 | |||||||
| 109 | /** |
||||||
| 110 | * @param mixed $data |
||||||
| 111 | * @param TypeArray $type |
||||||
| 112 | */ |
||||||
| 113 | public function deserializeCollection( |
||||||
| 114 | DeserializationVisitorInterface $visitor, |
||||||
| 115 | $data, |
||||||
| 116 | array $type, |
||||||
| 117 | DeserializationContext $context |
||||||
| 118 | ): Collection { |
||||||
| 119 | // See above. |
||||||
| 120 | $type['name'] = 'array'; |
||||||
| 121 | |||||||
| 122 | $elements = new ArrayCollection($visitor->visitArray($data, $type)); |
||||||
| 123 | |||||||
| 124 | if (null === $this->managerRegistry) { |
||||||
| 125 | return $elements; |
||||||
| 126 | } |
||||||
| 127 | |||||||
| 128 | $propertyMetadata = $context->getMetadataStack()->top(); |
||||||
| 129 | if (!$propertyMetadata instanceof PropertyMetadata) { |
||||||
| 130 | return $elements; |
||||||
| 131 | } |
||||||
| 132 | |||||||
| 133 | $objectManager = $this->managerRegistry->getManagerForClass($propertyMetadata->class); |
||||||
| 134 | if (null === $objectManager) { |
||||||
| 135 | return $elements; |
||||||
| 136 | } |
||||||
| 137 | |||||||
| 138 | $classMetadata = $objectManager->getClassMetadata($propertyMetadata->class); |
||||||
| 139 | $currentObject = $visitor->getCurrentObject(); |
||||||
|
0 ignored issues
–
show
The method
getCurrentObject() does not exist on JMS\Serializer\Visitor\D...izationVisitorInterface. Since it exists in all sub-types, consider adding an abstract or default implementation to JMS\Serializer\Visitor\D...izationVisitorInterface.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
| 140 | |||||||
| 141 | if ( |
||||||
| 142 | array_key_exists('name', $propertyMetadata->type) |
||||||
| 143 | && in_array($propertyMetadata->type['name'], self::COLLECTION_TYPES) |
||||||
| 144 | && $classMetadata->isCollectionValuedAssociation($propertyMetadata->name) |
||||||
| 145 | ) { |
||||||
| 146 | $existingCollection = $classMetadata->getFieldValue($currentObject, $propertyMetadata->name); |
||||||
|
0 ignored issues
–
show
The method
getFieldValue() does not exist on Doctrine\Persistence\Mapping\ClassMetadata. Did you maybe mean getFieldNames()?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces. This is most likely a typographical error or the method has been renamed. Loading history...
|
|||||||
| 147 | if (!$existingCollection instanceof OrmPersistentCollection) { |
||||||
| 148 | return $elements; |
||||||
| 149 | } |
||||||
| 150 | |||||||
| 151 | foreach ($elements as $element) { |
||||||
| 152 | if (!$existingCollection->contains($element)) { |
||||||
| 153 | $existingCollection->add($element); |
||||||
| 154 | } |
||||||
| 155 | } |
||||||
| 156 | |||||||
| 157 | foreach ($existingCollection as $collectionElement) { |
||||||
| 158 | if (!$elements->contains($collectionElement)) { |
||||||
| 159 | $existingCollection->removeElement($collectionElement); |
||||||
| 160 | } |
||||||
| 161 | } |
||||||
| 162 | |||||||
| 163 | return $existingCollection; |
||||||
| 164 | } |
||||||
| 165 | |||||||
| 166 | return $elements; |
||||||
| 167 | } |
||||||
| 168 | } |
||||||
| 169 |
The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g.
excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths