Skip to content

Commit 75c2651

Browse files
committed
Refactor configuration and serializers logic
Introduce `DataConfiguration` and `SerializersConfiguration` for managing serializers and configurations dynamically. Centralize serializer registration and improve type handling across contexts while replacing hardcoded lists with configurable options. Add `DataConfigurationException` for robust error handling.
1 parent 23be380 commit 75c2651

File tree

11 files changed

+181
-27
lines changed

11 files changed

+181
-27
lines changed

src/Configuration/Configuration.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
namespace Nuxtifyts\PhpDto\Configuration;
4+
5+
use Nuxtifyts\PhpDto\Exceptions\DataConfigurationException;
6+
7+
interface Configuration
8+
{
9+
/**
10+
* @param ?array<string, mixed> $config
11+
*
12+
* @throws DataConfigurationException
13+
*/
14+
public static function getInstance(
15+
?array $config = null,
16+
bool $forceCreate = false
17+
): self;
18+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
namespace Nuxtifyts\PhpDto\Configuration;
4+
5+
use Nuxtifyts\PhpDto\Exceptions\DataConfigurationException;
6+
use Nuxtifyts\PhpDto\Support\Arr;
7+
8+
class DataConfiguration implements Configuration
9+
{
10+
protected static ?self $instance = null;
11+
12+
protected function __construct(
13+
protected(set) SerializersConfiguration $serializers,
14+
) {
15+
}
16+
17+
/**
18+
* @param array<array-key, mixed> $config
19+
*
20+
* @throws DataConfigurationException
21+
*/
22+
public static function getInstance(
23+
?array $config = null,
24+
bool $forceCreate = false
25+
): self {
26+
if (self::$instance && !$forceCreate) {
27+
return self::$instance;
28+
}
29+
30+
return self::$instance = new self(
31+
serializers: SerializersConfiguration::getInstance(
32+
Arr::getArray($config ?? [], 'serializers'),
33+
$forceCreate
34+
)
35+
);
36+
}
37+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<?php
2+
3+
namespace Nuxtifyts\PhpDto\Configuration;
4+
5+
use Nuxtifyts\PhpDto\Exceptions\DataConfigurationException;
6+
use Nuxtifyts\PhpDto\Serializers\ArraySerializer;
7+
use Nuxtifyts\PhpDto\Serializers\BackedEnumSerializer;
8+
use Nuxtifyts\PhpDto\Serializers\DataSerializer;
9+
use Nuxtifyts\PhpDto\Serializers\DateTimeSerializer;
10+
use Nuxtifyts\PhpDto\Serializers\ScalarTypeSerializer;
11+
use Nuxtifyts\PhpDto\Serializers\Serializer;
12+
13+
class SerializersConfiguration implements Configuration
14+
{
15+
protected static ?self $instance = null;
16+
17+
/**
18+
* @param array<array-key, class-string<Serializer>> $baseSerializers
19+
*/
20+
protected function __construct(
21+
protected(set) array $baseSerializers = [
22+
ArraySerializer::class,
23+
DataSerializer::class,
24+
DateTimeSerializer::class,
25+
BackedEnumSerializer::class,
26+
ScalarTypeSerializer::class,
27+
],
28+
) {
29+
}
30+
31+
/**
32+
* @param ?array<array-key, mixed> $config
33+
*
34+
* @throws DataConfigurationException
35+
*/
36+
public static function getInstance(
37+
?array $config = null,
38+
bool $forceCreate = false
39+
): self {
40+
if (self::$instance && !$forceCreate) {
41+
return self::$instance;
42+
}
43+
44+
$baseSerializers = $config['baseSerializers'] ?? [
45+
ArraySerializer::class,
46+
DataSerializer::class,
47+
DateTimeSerializer::class,
48+
BackedEnumSerializer::class,
49+
ScalarTypeSerializer::class,
50+
];
51+
52+
if (
53+
!is_array($baseSerializers)
54+
|| array_any(
55+
$baseSerializers,
56+
static fn (mixed $baseSerializer): bool =>
57+
!is_string($baseSerializer)
58+
|| !is_subclass_of($baseSerializer, Serializer::class)
59+
)
60+
) {
61+
throw DataConfigurationException::invalidBaseSerializers();
62+
}
63+
/** @var array<array-key, class-string<Serializer>> $baseSerializers */
64+
65+
return self::$instance = new self(
66+
baseSerializers: $baseSerializers
67+
);
68+
}
69+
}

src/Contexts/PropertyContext.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Nuxtifyts\PhpDto\DataCiphers\CipherConfig;
1616
use Nuxtifyts\PhpDto\DataRefiners\DataRefiner;
1717
use Nuxtifyts\PhpDto\Enums\Property\Type;
18+
use Nuxtifyts\PhpDto\Exceptions\DataConfigurationException;
1819
use Nuxtifyts\PhpDto\Exceptions\DataCreationException;
1920
use Nuxtifyts\PhpDto\Exceptions\DeserializeException;
2021
use Nuxtifyts\PhpDto\Exceptions\SerializeException;
@@ -173,6 +174,7 @@ public function getFilteredSubTypeContexts(Type $type, Type ...$additionalTypes)
173174
* @return list<Serializer>
174175
*
175176
* @throws UnknownTypeException
177+
* @throws DataConfigurationException
176178
*/
177179
protected function resolveSerializers(): array
178180
{
@@ -184,6 +186,7 @@ protected function resolveSerializers(): array
184186
*
185187
* @throws DeserializeException
186188
* @throws UnknownTypeException
189+
* @throws DataConfigurationException
187190
*/
188191
public function deserializeFrom(array $value): mixed
189192
{

src/Contexts/TypeContext.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
use Nuxtifyts\PhpDto\Contracts\BaseData as BaseDataContract;
1111
use Nuxtifyts\PhpDto\Data;
1212
use Nuxtifyts\PhpDto\Enums\Property\Type;
13+
use Nuxtifyts\PhpDto\Exceptions\DataConfigurationException;
14+
use Nuxtifyts\PhpDto\Exceptions\UnknownTypeException;
1315
use Nuxtifyts\PhpDto\Exceptions\UnsupportedTypeException;
1416
use Nuxtifyts\PhpDto\Serializers\Concerns\HasSerializers;
1517
use Nuxtifyts\PhpDto\Serializers\Serializer;
@@ -212,6 +214,9 @@ private static function getPropertyStringTypes(ReflectionProperty $property): ar
212214

213215
/**
214216
* @return list<Serializer>
217+
*
218+
* @throws DataConfigurationException
219+
* @throws UnknownTypeException
215220
*/
216221
protected function resolveSerializers(): array
217222
{
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
namespace Nuxtifyts\PhpDto\Exceptions;
4+
5+
use Exception;
6+
7+
class DataConfigurationException extends Exception
8+
{
9+
protected const int INVALID_BASE_SERIALIZERS = 10000;
10+
11+
public static function invalidBaseSerializers(): self
12+
{
13+
return new self('Invalid base serializers', self::INVALID_BASE_SERIALIZERS);
14+
}
15+
}

src/Serializers/ArraySerializer.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ protected function deserializeItem(mixed $item, PropertyContext $property): ?arr
6565
foreach ($typeContext->subTypeSerializers() as $serializer) {
6666
try {
6767
if ($serializer instanceof SerializesArrayOfItems) {
68-
// @phpstan-ignore-next-line
6968
return $serializer->deserializeArrayOfItems($property, $item);
7069
}
7170
} catch (Exception) {

src/Serializers/Concerns/HasSerializers.php

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,13 @@
22

33
namespace Nuxtifyts\PhpDto\Serializers\Concerns;
44

5+
use Nuxtifyts\PhpDto\Configuration\DataConfiguration;
56
use Nuxtifyts\PhpDto\Contexts\PropertyContext;
67
use Nuxtifyts\PhpDto\Contexts\TypeContext;
78
use Nuxtifyts\PhpDto\Enums\Property\Type;
89
use Nuxtifyts\PhpDto\Exceptions\UnknownTypeException;
9-
use Nuxtifyts\PhpDto\Serializers\ArraySerializer;
10-
use Nuxtifyts\PhpDto\Serializers\BackedEnumSerializer;
11-
use Nuxtifyts\PhpDto\Serializers\DataSerializer;
12-
use Nuxtifyts\PhpDto\Serializers\DateTimeSerializer;
13-
use Nuxtifyts\PhpDto\Serializers\ScalarTypeSerializer;
1410
use Nuxtifyts\PhpDto\Serializers\Serializer;
11+
use Nuxtifyts\PhpDto\Exceptions\DataConfigurationException;
1512

1613
trait HasSerializers
1714
{
@@ -24,6 +21,7 @@ trait HasSerializers
2421
* @return list<Serializer>
2522
*
2623
* @throws UnknownTypeException
24+
* @throws DataConfigurationException
2725
*/
2826
protected function getSerializersFromPropertyContext(
2927
PropertyContext $propertyContext
@@ -35,14 +33,17 @@ protected function getSerializersFromPropertyContext(
3533
array_column($propertyContext->types, 'value'),
3634
array_column($serializer::supportedTypes(), 'value')
3735
)) ? new $serializer() : null,
38-
self::serializersList()
36+
DataConfiguration::getInstance()->serializers->baseSerializers
3937
))) ?: throw UnknownTypeException::unknownType(...$propertyContext->types);
4038
}
4139

4240
/**
4341
* @param TypeContext<Type> $typeContext
4442
*
4543
* @return list<Serializer>
44+
*
45+
* @throws UnknownTypeException
46+
* @throws DataConfigurationException
4647
*/
4748
protected function getSerializersFromTypeContext(
4849
TypeContext $typeContext,
@@ -54,28 +55,15 @@ protected function getSerializersFromTypeContext(
5455
array_column($typeContext->arrayElementTypes, 'value'),
5556
array_column($serializer::supportedTypes(), 'value')
5657
)) ? new $serializer() : null,
57-
self::serializersList()
58-
)));
59-
}
60-
61-
/**
62-
* @return list<class-string<Serializer>>
63-
*/
64-
protected static function serializersList(): array
65-
{
66-
return [
67-
ArraySerializer::class,
68-
DataSerializer::class,
69-
DateTimeSerializer::class,
70-
BackedEnumSerializer::class,
71-
ScalarTypeSerializer::class,
72-
];
58+
DataConfiguration::getInstance()->serializers->baseSerializers
59+
))) ?: throw UnknownTypeException::unknownType(...$typeContext->arrayElementTypes);
7360
}
7461

7562
/**
7663
* @return list<Serializer>
7764
*
7865
* @throws UnknownTypeException
66+
* @throws DataConfigurationException
7967
*/
8068
public function serializers(): array
8169
{

src/Serializers/Concerns/SerializesArrayOfItems.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
trait SerializesArrayOfItems
1414
{
1515
/**
16-
* @return array<string, ?array<array-key, mixed>>
16+
* @return array<array-key, ?array<array-key, mixed>>
1717
*
1818
* @throws SerializeException
1919
*/
@@ -38,7 +38,7 @@ public function serializeArrayOfItems(
3838
}
3939

4040
/**
41-
* @param array<string, mixed> $data
41+
* @param array<array-key, mixed> $data
4242
*
4343
* @return ?array<array-key, mixed>
4444
*

src/Serializers/Contracts/SerializesArrayOfItems.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
interface SerializesArrayOfItems
1010
{
1111
/**
12-
* @return array<string, ?array<array-key, mixed>>
12+
* @return array<array-key, ?array<array-key, mixed>>
1313
*
1414
* @throws SerializeException
1515
*/
@@ -19,7 +19,7 @@ public function serializeArrayOfItems(
1919
): array;
2020

2121
/**
22-
* @param array<string, mixed> $data
22+
* @param array<array-key, mixed> $data
2323
*
2424
* @return ?array<array-key, mixed>
2525
*

src/Support/Arr.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
namespace Nuxtifyts\PhpDto\Support;
4+
5+
final readonly class Arr
6+
{
7+
/**
8+
* @param array<array-key, mixed> $array
9+
* @param string $key
10+
* @param array<array-key, mixed> $default
11+
*
12+
* @return array<array-key, mixed>
13+
*/
14+
public static function getArray(array $array, string $key, array $default = []): array
15+
{
16+
$value = $array[$key] ?? null;
17+
18+
return is_array($value) ? $value : $default;
19+
}
20+
}

0 commit comments

Comments
 (0)