Skip to content

Commit cfcf0d9

Browse files
committed
Serialize associative arrays as objects instead of arrays
1 parent 484ad0f commit cfcf0d9

14 files changed

+456
-19
lines changed

src/ConcreteType.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
*/
1515
final class ConcreteType
1616
{
17+
public bool $associative = false;
18+
1719
public function __construct(public string $name, public bool $isBuiltIn)
1820
{
1921
}

src/DefinitionProvider.php

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ final class DefinitionProvider
2626
private PropertyTypeResolver $propertyTypeResolver;
2727
private bool $serializePublicMethods;
2828
private ConstructorResolver $constructorResolver;
29+
private bool $serializeMapsAsObjects;
2930

3031
public function __construct(
3132
?DefaultCasterRepository $defaultCasterRepository = null,
@@ -34,6 +35,7 @@ public function __construct(
3435
?PropertyTypeResolver $propertyTypeResolver = null,
3536
bool $serializePublicMethods = true,
3637
?ConstructorResolver $constructorResolver = null,
38+
bool $serializeMapsAsObjects = false,
3739
)
3840
{
3941
$this->defaultCasters = $defaultCasterRepository ?? DefaultCasterRepository::builtIn();
@@ -42,6 +44,7 @@ public function __construct(
4244
$this->propertyTypeResolver = $propertyTypeResolver ?? new NaivePropertyTypeResolver();
4345
$this->serializePublicMethods = $serializePublicMethods;
4446
$this->constructorResolver = $constructorResolver ?? new AttributeConstructorResolver();
47+
$this->serializeMapsAsObjects = $serializeMapsAsObjects;
4548
}
4649

4750
/**
@@ -146,6 +149,7 @@ private function stringifyConstructor(ReflectionMethod $constructor): string
146149
public function provideSerializationDefinition(string $className): ClassSerializationDefinition
147150
{
148151
$reflection = new ReflectionClass($className);
152+
$constructor = $this->constructorResolver->resolveConstructor($reflection);
149153
$objectSettings = $this->resolveObjectSettings($reflection);
150154
$classAttributes = $reflection->getAttributes();
151155
$properties = [];
@@ -173,7 +177,7 @@ public function provideSerializationDefinition(string $className): ClassSerializ
173177
PropertySerializationDefinition::TYPE_METHOD,
174178
$methodName,
175179
$this->resolveSerializers($returnType, $attributes),
176-
PropertyType::fromReflectionType($returnType),
180+
$this->propertyTypeResolver->typeFromMethod($method),
177181
$returnType->allowsNull(),
178182
$this->resolveKeys($key, $attributes),
179183
$typeSpecifier?->key,
@@ -204,7 +208,7 @@ public function provideSerializationDefinition(string $className): ClassSerializ
204208
PropertySerializationDefinition::TYPE_PROPERTY,
205209
$property->getName(),
206210
$serializers,
207-
PropertyType::fromReflectionType($propertyType),
211+
$this->propertyTypeResolver->typeFromProperty($property, $constructor),
208212
$propertyType->allowsNull(),
209213
$this->resolveKeys($key, $attributes),
210214
$typeSpecifier?->key,
@@ -307,6 +311,11 @@ public function hasSerializerFor(string $name): bool
307311
return $this->defaultSerializers->serializerForType($name) !== null;
308312
}
309313

314+
public function areMapsSerializedAsObjects(): bool
315+
{
316+
return $this->serializeMapsAsObjects;
317+
}
318+
310319
/**
311320
* @param ReflectionAttribute[] $attributes
312321
*
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace EventSauce\ObjectHydrator\Fixtures;
6+
7+
use EventSauce\ObjectHydrator\PropertyCasters\CastToArrayWithKey;
8+
use EventSauce\ObjectHydrator\PropertyCasters\CastToType;
9+
10+
final class ClassThatHasMultipleCastersOnMapProperty
11+
{
12+
/**
13+
* @param array<string, array<string, string>> $map
14+
*/
15+
public function __construct(
16+
#[CastToType('array')]
17+
#[CastToArrayWithKey('second_level')]
18+
#[CastToArrayWithKey('first_level')]
19+
public array $map,
20+
) {
21+
}
22+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace EventSauce\ObjectHydrator\Fixtures;
6+
7+
final class ClassThatSpecifiesArrayWithIntegerKeys
8+
{
9+
/**
10+
* @param array<int, string> $arrayWithIntegerKeys
11+
*/
12+
public function __construct(
13+
public array $arrayWithIntegerKeys,
14+
) {
15+
}
16+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace EventSauce\ObjectHydrator\Fixtures;
6+
7+
use EventSauce\ObjectHydrator\Fixtures\ClassWithCamelCaseProperty as CamelClass;
8+
9+
final class ClassThatSpecifiesArraysWithDocComments
10+
{
11+
/**
12+
* @param array<string, CamelClass> $mapWithObjects
13+
* @param array<string, int> $mapWithScalars
14+
* @param array<string, array<string, string>> $mapWithAssociativeArrays
15+
* @param array<int, string> $listWithTypeHint
16+
*/
17+
public function __construct(
18+
public array $mapWithObjects,
19+
public array $mapWithScalars,
20+
public array $mapWithAssociativeArrays,
21+
public array $listWithoutTypeHint,
22+
public array $listWithTypeHint,
23+
) {
24+
}
25+
26+
/**
27+
* @return array<string, CamelClass>
28+
*/
29+
public function methodMapWithObjects(): array
30+
{
31+
return $this->mapWithObjects;
32+
}
33+
34+
/**
35+
* @return array<string, int>
36+
*/
37+
public function methodMapWithScalars(): array
38+
{
39+
return $this->mapWithScalars;
40+
}
41+
42+
/**
43+
* @return array<string, array<string, string>>
44+
*/
45+
public function methodMapWithAssociativeArrays(): array
46+
{
47+
return $this->mapWithAssociativeArrays;
48+
}
49+
50+
public function methodListWithoutTypeHint(): array
51+
{
52+
return $this->listWithoutTypeHint;
53+
}
54+
55+
/**
56+
* @return array<int, string>
57+
*/
58+
public function methodListWithTypeHint(): array
59+
{
60+
return $this->listWithTypeHint;
61+
}
62+
}

src/FixturesFor81/ClassWithEnumArrayProperty.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<?php
22

3+
declare(strict_types=1);
4+
35
namespace EventSauce\ObjectHydrator\FixturesFor81;
46

57
final class ClassWithEnumArrayProperty

0 commit comments

Comments
 (0)