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 ![]() |
|||||||
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
![]() |
|||||||
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
![]() |
|||||||
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. ![]() |
|||||||
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