Skip to content
This repository was archived by the owner on Sep 6, 2025. It is now read-only.

Commit 27c54cf

Browse files
authored
Merge pull request #4 from hellofresh/hotfix/jms-vector-handling
Added support for Vector FQCN and Vector as root for deserialization
2 parents fbee62c + 078c4f1 commit 27c54cf

File tree

3 files changed

+161
-13
lines changed

3 files changed

+161
-13
lines changed

src/Serializer/Type/VectorHandler.php

Lines changed: 45 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,42 @@
55
use Collections\Vector;
66
use Collections\VectorInterface;
77
use JMS\Serializer\Context;
8+
use JMS\Serializer\GenericDeserializationVisitor;
89
use JMS\Serializer\GraphNavigator;
910
use JMS\Serializer\Handler\SubscribingHandlerInterface;
11+
use JMS\Serializer\Metadata\ClassMetadata;
1012
use JMS\Serializer\VisitorInterface;
1113

1214
class VectorHandler implements SubscribingHandlerInterface
1315
{
1416
public static function getSubscribingMethods()
1517
{
16-
return [
17-
[
18-
'direction' => GraphNavigator::DIRECTION_SERIALIZATION,
19-
'format' => 'json',
20-
'type' => 'Vector',
21-
'method' => 'serializeCollection'
22-
],
23-
[
24-
'direction' => GraphNavigator::DIRECTION_DESERIALIZATION,
25-
'format' => 'json',
26-
'type' => 'Vector',
27-
'method' => 'deserializeCollection'
28-
]
18+
$formats = ['json', 'xml', 'yml'];
19+
$collectionTypes = [
20+
'Vector',
21+
Vector::class,
2922
];
23+
24+
$methods = [];
25+
foreach ($collectionTypes as $type) {
26+
foreach ($formats as $format) {
27+
$methods[] = [
28+
'direction' => GraphNavigator::DIRECTION_SERIALIZATION,
29+
'type' => $type,
30+
'format' => $format,
31+
'method' => 'serializeCollection',
32+
];
33+
34+
$methods[] = [
35+
'direction' => GraphNavigator::DIRECTION_DESERIALIZATION,
36+
'type' => $type,
37+
'format' => $format,
38+
'method' => 'deserializeCollection',
39+
];
40+
}
41+
}
42+
43+
return $methods;
3044
}
3145

3246
public function serializeCollection(
@@ -46,6 +60,24 @@ public function deserializeCollection(VisitorInterface $visitor, $data, array $t
4660
// See above.
4761
$type['name'] = 'array';
4862

63+
// When there is not root set for the visitor we need to handle the vector result setting
64+
// manually this is related to https://github.com/schmittjoh/serializer/issues/95
65+
$isRoot = null === $visitor->getResult();
66+
if ($isRoot && $visitor instanceof GenericDeserializationVisitor) {
67+
$metadata = new ClassMetadata(Vector::class);
68+
$vector = new Vector();
69+
70+
$visitor->startVisitingObject($metadata, $vector, $type, $context);
71+
72+
$array = $visitor->visitArray($data, $type, $context);
73+
$vector->setAll($array);
74+
75+
$visitor->endVisitingObject($metadata, $vector, $type, $context);
76+
77+
return $vector;
78+
}
79+
80+
// No a root so just return the vector
4981
return new Vector($visitor->visitArray($data, $type, $context));
5082
}
5183
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
namespace HelloFresh\Tests\Engine\Serializer\Type;
4+
5+
use JMS\Serializer\SerializerBuilder;
6+
use PHPUnit\Framework\TestCase;
7+
use JMS\Serializer\Serializer;
8+
9+
abstract class JMSSerializerHandlerTestCase extends TestCase
10+
{
11+
/**
12+
* @var Serializer
13+
*/
14+
protected $serializer;
15+
16+
protected function setUp()
17+
{
18+
parent::setUp();
19+
20+
$this->serializer = $this->createSerializer();
21+
}
22+
23+
/**
24+
* Create a serializer instance.
25+
*
26+
* @return Serializer
27+
*/
28+
protected function createSerializer()
29+
{
30+
$builder = new SerializerBuilder();
31+
$builder->addDefaultHandlers();
32+
$builder->addDefaultDeserializationVisitors();
33+
$builder->addDefaultSerializationVisitors();
34+
35+
$this->configureBuilder($builder);
36+
37+
return $builder->build();
38+
}
39+
40+
/**
41+
* Configure the serializer builder for the test case.
42+
*
43+
* @param SerializerBuilder $builder
44+
* @return void
45+
*/
46+
abstract protected function configureBuilder(SerializerBuilder $builder);
47+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<?php
2+
3+
namespace HelloFresh\Tests\Engine\Serializer\Type;
4+
5+
use Collections\Vector;
6+
use HelloFresh\Engine\Serializer\Type\VectorHandler;
7+
use JMS\Serializer\Handler\HandlerRegistryInterface;
8+
use JMS\Serializer\SerializerBuilder;
9+
10+
class VectorHandlerTest extends JMSSerializerHandlerTestCase
11+
{
12+
/**
13+
* @dataProvider providerTypes
14+
* @param string $type
15+
*/
16+
public function testJsonSerializationAndDeserializationRootLevel($type)
17+
{
18+
$expectedVector = new Vector(['foo', 'bar']);
19+
$expectedJson = '["foo", "bar"]';
20+
21+
$this->assertJsonStringEqualsJsonString(
22+
$expectedJson,
23+
$this->serializer->serialize($expectedVector, 'json')
24+
);
25+
26+
$this->assertEquals(
27+
$expectedVector,
28+
$this->serializer->deserialize($expectedJson, $type, 'json')
29+
);
30+
}
31+
32+
/**
33+
* @dataProvider providerTypes
34+
* @param string $type
35+
*/
36+
public function testJsonSerializationAndDeserializationChildLevel($type)
37+
{
38+
$expectedVector = [ 'details' => new Vector(['foo', 'bar']) ];
39+
$expectedJson = '{ "details": ["foo", "bar"] }';
40+
41+
$this->assertJsonStringEqualsJsonString(
42+
$expectedJson,
43+
$this->serializer->serialize($expectedVector, 'json')
44+
);
45+
46+
$this->assertEquals(
47+
$expectedVector,
48+
$this->serializer->deserialize($expectedJson, sprintf('array<string,%s>', $type), 'json')
49+
);
50+
}
51+
52+
public function providerTypes()
53+
{
54+
return [
55+
['Vector'],
56+
[Vector::class],
57+
];
58+
}
59+
60+
/**
61+
* @inheritdoc
62+
*/
63+
protected function configureBuilder(SerializerBuilder $builder)
64+
{
65+
$builder->configureHandlers(function (HandlerRegistryInterface $registry) {
66+
$registry->registerSubscribingHandler(new VectorHandler());
67+
});
68+
}
69+
}

0 commit comments

Comments
 (0)