Skip to content

Commit c976cf1

Browse files
committed
Add NormalizersConfiguration and enhance configuration handling
Introduced `NormalizersConfiguration` to manage normalizers setup. Refactored existing code to leverage shared utility methods like `Arr::isArrayOfClassStrings` for validation. Updated configurations and exception handling to support normalizers alongside serializers.
1 parent c109a8d commit c976cf1

File tree

9 files changed

+168
-55
lines changed

9 files changed

+168
-55
lines changed

clover.xml

Lines changed: 64 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<coverage generated="1735672752">
3-
<project timestamp="1735672752">
2+
<coverage generated="1735677140">
3+
<project timestamp="1735677140">
44
<package name="Nuxtifyts\PhpDto\Attributes\Property">
55
<file name="/Users/faroukbraik/Dev/php-dto/src/Attributes/Property/Aliases.php">
66
<class name="Nuxtifyts\PhpDto\Attributes\Property\Aliases" namespace="Nuxtifyts\PhpDto\Attributes\Property">
@@ -267,48 +267,69 @@
267267
<package name="Nuxtifyts\PhpDto\Configuration">
268268
<file name="/Users/faroukbraik/Dev/php-dto/src/Configuration/DataConfiguration.php">
269269
<class name="Nuxtifyts\PhpDto\Configuration\DataConfiguration" namespace="Nuxtifyts\PhpDto\Configuration">
270-
<metrics complexity="4" methods="2" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="9" coveredstatements="2" elements="11" coveredelements="2"/>
270+
<metrics complexity="4" methods="2" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="13" coveredstatements="2" elements="15" coveredelements="2"/>
271271
</class>
272272
<line num="12" type="method" name="__construct" visibility="protected" complexity="1" crap="2" count="0"/>
273-
<line num="15" type="stmt" count="0"/>
274-
<line num="22" type="method" name="getInstance" visibility="public" complexity="3" crap="6.80" count="3"/>
275-
<line num="26" type="stmt" count="3"/>
276-
<line num="27" type="stmt" count="3"/>
277-
<line num="30" type="stmt" count="0"/>
273+
<line num="16" type="stmt" count="0"/>
274+
<line num="23" type="method" name="getInstance" visibility="public" complexity="3" crap="8.21" count="8"/>
275+
<line num="27" type="stmt" count="8"/>
276+
<line num="28" type="stmt" count="8"/>
278277
<line num="31" type="stmt" count="0"/>
279278
<line num="32" type="stmt" count="0"/>
280279
<line num="33" type="stmt" count="0"/>
281280
<line num="34" type="stmt" count="0"/>
282281
<line num="35" type="stmt" count="0"/>
283-
<metrics loc="38" ncloc="33" classes="1" methods="2" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="9" coveredstatements="2" elements="11" coveredelements="2"/>
282+
<line num="36" type="stmt" count="0"/>
283+
<line num="37" type="stmt" count="0"/>
284+
<line num="38" type="stmt" count="0"/>
285+
<line num="39" type="stmt" count="0"/>
286+
<line num="40" type="stmt" count="0"/>
287+
<metrics loc="43" ncloc="38" classes="1" methods="2" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="13" coveredstatements="2" elements="15" coveredelements="2"/>
284288
</file>
285-
<file name="/Users/faroukbraik/Dev/php-dto/src/Configuration/SerializersConfiguration.php">
286-
<class name="Nuxtifyts\PhpDto\Configuration\SerializersConfiguration" namespace="Nuxtifyts\PhpDto\Configuration">
287-
<metrics complexity="7" methods="2" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="20" coveredstatements="0" elements="22" coveredelements="0"/>
289+
<file name="/Users/faroukbraik/Dev/php-dto/src/Configuration/NormalizersConfiguration.php">
290+
<class name="Nuxtifyts\PhpDto\Configuration\NormalizersConfiguration" namespace="Nuxtifyts\PhpDto\Configuration">
291+
<metrics complexity="6" methods="2" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="14" coveredstatements="0" elements="16" coveredelements="0"/>
288292
</class>
289293
<line num="20" type="method" name="__construct" visibility="protected" complexity="1" crap="2" count="0"/>
290-
<line num="29" type="stmt" count="0"/>
291-
<line num="36" type="method" name="getInstance" visibility="public" complexity="6" crap="42" count="0"/>
294+
<line num="28" type="stmt" count="0"/>
295+
<line num="35" type="method" name="getInstance" visibility="public" complexity="5" crap="30" count="0"/>
296+
<line num="39" type="stmt" count="0"/>
292297
<line num="40" type="stmt" count="0"/>
293-
<line num="41" type="stmt" count="0"/>
298+
<line num="43" type="stmt" count="0"/>
294299
<line num="44" type="stmt" count="0"/>
295300
<line num="45" type="stmt" count="0"/>
296301
<line num="46" type="stmt" count="0"/>
297302
<line num="47" type="stmt" count="0"/>
303+
<line num="51" type="stmt" count="0"/>
304+
<line num="52" type="stmt" count="0"/>
305+
<line num="54" type="stmt" count="0"/>
306+
<line num="58" type="stmt" count="0"/>
307+
<line num="59" type="stmt" count="0"/>
308+
<line num="60" type="stmt" count="0"/>
309+
<metrics loc="63" ncloc="54" classes="1" methods="2" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="14" coveredstatements="0" elements="16" coveredelements="0"/>
310+
</file>
311+
<file name="/Users/faroukbraik/Dev/php-dto/src/Configuration/SerializersConfiguration.php">
312+
<class name="Nuxtifyts\PhpDto\Configuration\SerializersConfiguration" namespace="Nuxtifyts\PhpDto\Configuration">
313+
<metrics complexity="6" methods="2" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="15" coveredstatements="0" elements="17" coveredelements="0"/>
314+
</class>
315+
<line num="21" type="method" name="__construct" visibility="protected" complexity="1" crap="2" count="0"/>
316+
<line num="30" type="stmt" count="0"/>
317+
<line num="37" type="method" name="getInstance" visibility="public" complexity="5" crap="30" count="0"/>
318+
<line num="41" type="stmt" count="0"/>
319+
<line num="42" type="stmt" count="0"/>
320+
<line num="45" type="stmt" count="0"/>
321+
<line num="46" type="stmt" count="0"/>
322+
<line num="47" type="stmt" count="0"/>
298323
<line num="48" type="stmt" count="0"/>
299324
<line num="49" type="stmt" count="0"/>
300-
<line num="53" type="stmt" count="0"/>
325+
<line num="50" type="stmt" count="0"/>
301326
<line num="54" type="stmt" count="0"/>
302327
<line num="55" type="stmt" count="0"/>
303-
<line num="56" type="stmt" count="0"/>
304328
<line num="57" type="stmt" count="0"/>
305-
<line num="58" type="stmt" count="0"/>
306-
<line num="59" type="stmt" count="0"/>
307329
<line num="61" type="stmt" count="0"/>
308-
<line num="65" type="stmt" count="0"/>
309-
<line num="66" type="stmt" count="0"/>
310-
<line num="67" type="stmt" count="0"/>
311-
<metrics loc="70" ncloc="61" classes="1" methods="2" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="20" coveredstatements="0" elements="22" coveredelements="0"/>
330+
<line num="62" type="stmt" count="0"/>
331+
<line num="63" type="stmt" count="0"/>
332+
<metrics loc="66" ncloc="57" classes="1" methods="2" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="15" coveredstatements="0" elements="17" coveredelements="0"/>
312333
</file>
313334
</package>
314335
<package name="Nuxtifyts\PhpDto\Contexts">
@@ -768,11 +789,13 @@
768789
</file>
769790
<file name="/Users/faroukbraik/Dev/php-dto/src/Exceptions/DataConfigurationException.php">
770791
<class name="Nuxtifyts\PhpDto\Exceptions\DataConfigurationException" namespace="Nuxtifyts\PhpDto\Exceptions">
771-
<metrics complexity="1" methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="1" coveredstatements="0" elements="2" coveredelements="0"/>
792+
<metrics complexity="2" methods="2" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="2" coveredstatements="0" elements="4" coveredelements="0"/>
772793
</class>
773-
<line num="11" type="method" name="invalidBaseSerializers" visibility="public" complexity="1" crap="2" count="0"/>
774-
<line num="13" type="stmt" count="0"/>
775-
<metrics loc="16" ncloc="16" classes="1" methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="1" coveredstatements="0" elements="2" coveredelements="0"/>
794+
<line num="13" type="method" name="invalidBaseSerializers" visibility="public" complexity="1" crap="2" count="0"/>
795+
<line num="15" type="stmt" count="0"/>
796+
<line num="18" type="method" name="invalidBaseNormalizers" visibility="public" complexity="1" crap="2" count="0"/>
797+
<line num="20" type="stmt" count="0"/>
798+
<metrics loc="23" ncloc="23" classes="1" methods="2" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="2" coveredstatements="0" elements="4" coveredelements="0"/>
776799
</file>
777800
<file name="/Users/faroukbraik/Dev/php-dto/src/Exceptions/DataCreationException.php">
778801
<class name="Nuxtifyts\PhpDto\Exceptions\DataCreationException" namespace="Nuxtifyts\PhpDto\Exceptions">
@@ -1068,25 +1091,22 @@
10681091
<package name="Nuxtifyts\PhpDto\Normalizers\Concerns">
10691092
<file name="/Users/faroukbraik/Dev/php-dto/src/Normalizers/Concerns/HasNormalizers.php">
10701093
<class name="Nuxtifyts\PhpDto\Normalizers\Concerns\HasNormalizers" namespace="Nuxtifyts\PhpDto\Normalizers\Concerns">
1071-
<metrics complexity="5" methods="3" coveredmethods="3" conditionals="0" coveredconditionals="0" statements="13" coveredstatements="13" elements="16" coveredelements="16"/>
1094+
<metrics complexity="5" methods="3" coveredmethods="3" conditionals="0" coveredconditionals="0" statements="10" coveredstatements="10" elements="13" coveredelements="13"/>
10721095
</class>
10731096
<line num="19" type="method" name="normalizeValue" visibility="protected" complexity="3" crap="3" count="43"/>
10741097
<line num="21" type="stmt" count="43"/>
10751098
<line num="22" type="stmt" count="43"/>
10761099
<line num="24" type="stmt" count="43"/>
10771100
<line num="25" type="stmt" count="39"/>
10781101
<line num="29" type="stmt" count="7"/>
1079-
<line num="35" type="method" name="allNormalizer" visibility="protected" complexity="1" crap="1" count="44"/>
1080-
<line num="37" type="stmt" count="44"/>
1081-
<line num="38" type="stmt" count="44"/>
1102+
<line num="37" type="method" name="allNormalizer" visibility="protected" complexity="1" crap="1" count="44"/>
10821103
<line num="39" type="stmt" count="44"/>
10831104
<line num="40" type="stmt" count="44"/>
10841105
<line num="41" type="stmt" count="44"/>
10851106
<line num="42" type="stmt" count="44"/>
1086-
<line num="43" type="stmt" count="44"/>
1087-
<line num="49" type="method" name="normalizers" visibility="protected" complexity="1" crap="1" count="39"/>
1088-
<line num="51" type="stmt" count="39"/>
1089-
<metrics loc="54" ncloc="43" classes="1" methods="3" coveredmethods="3" conditionals="0" coveredconditionals="0" statements="13" coveredstatements="13" elements="16" coveredelements="16"/>
1107+
<line num="48" type="method" name="normalizers" visibility="protected" complexity="1" crap="1" count="39"/>
1108+
<line num="50" type="stmt" count="39"/>
1109+
<metrics loc="53" ncloc="38" classes="1" methods="3" coveredmethods="3" conditionals="0" coveredconditionals="0" statements="10" coveredstatements="10" elements="13" coveredelements="13"/>
10901110
</file>
10911111
</package>
10921112
<package name="Nuxtifyts\PhpDto\Pipelines\DeserializePipeline">
@@ -1467,12 +1487,18 @@
14671487
<package name="Nuxtifyts\PhpDto\Support">
14681488
<file name="/Users/faroukbraik/Dev/php-dto/src/Support/Arr.php">
14691489
<class name="Nuxtifyts\PhpDto\Support\Arr" namespace="Nuxtifyts\PhpDto\Support">
1470-
<metrics complexity="2" methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="2" coveredstatements="0" elements="3" coveredelements="0"/>
1490+
<metrics complexity="4" methods="2" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="7" coveredstatements="0" elements="9" coveredelements="0"/>
14711491
</class>
14721492
<line num="14" type="method" name="getArray" visibility="public" complexity="2" crap="6" count="0"/>
14731493
<line num="16" type="stmt" count="0"/>
14741494
<line num="18" type="stmt" count="0"/>
1475-
<metrics loc="21" ncloc="14" classes="1" methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="2" coveredstatements="0" elements="3" coveredelements="0"/>
1495+
<line num="25" type="method" name="isArrayOfClassStrings" visibility="public" complexity="2" crap="6" count="0"/>
1496+
<line num="27" type="stmt" count="0"/>
1497+
<line num="28" type="stmt" count="0"/>
1498+
<line num="29" type="stmt" count="0"/>
1499+
<line num="30" type="stmt" count="0"/>
1500+
<line num="31" type="stmt" count="0"/>
1501+
<metrics loc="34" ncloc="23" classes="1" methods="2" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="7" coveredstatements="0" elements="9" coveredelements="0"/>
14761502
</file>
14771503
<file name="/Users/faroukbraik/Dev/php-dto/src/Support/Passable.php">
14781504
<class name="Nuxtifyts\PhpDto\Support\Passable" namespace="Nuxtifyts\PhpDto\Support">
@@ -1503,6 +1529,6 @@
15031529
<metrics loc="47" ncloc="30" classes="1" methods="3" coveredmethods="3" conditionals="0" coveredconditionals="0" statements="6" coveredstatements="6" elements="9" coveredelements="9"/>
15041530
</file>
15051531
</package>
1506-
<metrics files="66" loc="3604" ncloc="3041" classes="54" methods="143" coveredmethods="107" conditionals="0" coveredconditionals="0" statements="953" coveredstatements="838" elements="1096" coveredelements="945"/>
1532+
<metrics files="67" loc="3687" ncloc="3107" classes="55" methods="147" coveredmethods="107" conditionals="0" coveredconditionals="0" statements="969" coveredstatements="835" elements="1116" coveredelements="942"/>
15071533
</project>
15081534
</coverage>

src/Concerns/CloneableData.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public function with(mixed ...$args): static
3636
? $this->cloneInstanceWithConstructorCall($context, $value)
3737
: $this->cloneInstanceWithoutConstructorCall($context, $value);
3838
} catch (Throwable $t) {
39-
throw DataCreationException::unableToCloneInstanceWithNewData($t);
39+
throw DataCreationException::unableToCloneInstanceWithNewData(static::class, $t);
4040
}
4141
}
4242

src/Configuration/DataConfiguration.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ class DataConfiguration implements Configuration
1111

1212
protected function __construct(
1313
protected(set) SerializersConfiguration $serializers,
14+
protected(set) NormalizersConfiguration $normalizers,
1415
) {
1516
}
1617

@@ -31,6 +32,10 @@ public static function getInstance(
3132
serializers: SerializersConfiguration::getInstance(
3233
Arr::getArray($config ?? [], 'serializers'),
3334
$forceCreate
35+
),
36+
normalizers: NormalizersConfiguration::getInstance(
37+
Arr::getArray($config ?? [], 'normalizers'),
38+
$forceCreate
3439
)
3540
);
3641
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?php
2+
3+
namespace Nuxtifyts\PhpDto\Configuration;
4+
5+
use Nuxtifyts\PhpDto\Exceptions\DataConfigurationException;
6+
use Nuxtifyts\PhpDto\Normalizers\ArrayAccessNormalizer;
7+
use Nuxtifyts\PhpDto\Normalizers\ArrayNormalizer;
8+
use Nuxtifyts\PhpDto\Normalizers\JsonStringNormalizer;
9+
use Nuxtifyts\PhpDto\Normalizers\Normalizer;
10+
use Nuxtifyts\PhpDto\Normalizers\StdClassNormalizer;
11+
use Nuxtifyts\PhpDto\Support\Arr;
12+
13+
class NormalizersConfiguration implements Configuration
14+
{
15+
protected static ?self $instance = null;
16+
17+
/**
18+
* @param array<array-key, class-string<Normalizer>> $baseNormalizers
19+
*/
20+
protected function __construct(
21+
protected(set) array $baseNormalizers = [
22+
JsonStringNormalizer::class,
23+
StdClassNormalizer::class,
24+
ArrayAccessNormalizer::class,
25+
ArrayNormalizer::class,
26+
]
27+
) {
28+
}
29+
30+
/**
31+
* @param ?array<array-key, mixed> $config
32+
*
33+
* @throws DataConfigurationException
34+
*/
35+
public static function getInstance(
36+
?array $config = null,
37+
bool $forceCreate = false
38+
): self {
39+
if (self::$instance && !$forceCreate) {
40+
return self::$instance;
41+
}
42+
43+
$baseNormalizers = $config['baseNormalizers'] ?? [
44+
JsonStringNormalizer::class,
45+
StdClassNormalizer::class,
46+
ArrayAccessNormalizer::class,
47+
ArrayNormalizer::class,
48+
];
49+
50+
if (
51+
!is_array($baseNormalizers)
52+
|| !Arr::isArrayOfClassStrings($baseNormalizers, Normalizer::class)
53+
) {
54+
throw DataConfigurationException::invalidBaseNormalizers();
55+
}
56+
/** @var array<array-key, class-string<Normalizer>> $baseNormalizers */
57+
58+
return self::$instance = new self(
59+
baseNormalizers: $baseNormalizers
60+
);
61+
}
62+
}

src/Configuration/SerializersConfiguration.php

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Nuxtifyts\PhpDto\Serializers\DateTimeSerializer;
1010
use Nuxtifyts\PhpDto\Serializers\ScalarTypeSerializer;
1111
use Nuxtifyts\PhpDto\Serializers\Serializer;
12+
use Nuxtifyts\PhpDto\Support\Arr;
1213

1314
class SerializersConfiguration implements Configuration
1415
{
@@ -51,12 +52,7 @@ public static function getInstance(
5152

5253
if (
5354
!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-
)
55+
|| !Arr::isArrayOfClassStrings($baseSerializers, Serializer::class)
6056
) {
6157
throw DataConfigurationException::invalidBaseSerializers();
6258
}

src/Exceptions/DataConfigurationException.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,15 @@ class DataConfigurationException extends Exception
88
{
99
protected const int INVALID_BASE_SERIALIZERS = 10000;
1010

11+
protected const int INVALID_BASE_NORMALIZERS = 20000;
12+
1113
public static function invalidBaseSerializers(): self
1214
{
1315
return new self('Invalid base serializers', self::INVALID_BASE_SERIALIZERS);
1416
}
17+
18+
public static function invalidBaseNormalizers(): self
19+
{
20+
return new self('Invalid base normalizers', self::INVALID_BASE_NORMALIZERS);
21+
}
1522
}

src/Normalizers/Concerns/HasNormalizers.php

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,19 @@
22

33
namespace Nuxtifyts\PhpDto\Normalizers\Concerns;
44

5+
use Nuxtifyts\PhpDto\Configuration\DataConfiguration;
56
use Nuxtifyts\PhpDto\Data;
6-
use Nuxtifyts\PhpDto\Normalizers\ArrayAccessNormalizer;
7-
use Nuxtifyts\PhpDto\Normalizers\ArrayNormalizer;
8-
use Nuxtifyts\PhpDto\Normalizers\JsonStringNormalizer;
7+
use Nuxtifyts\PhpDto\Exceptions\DataConfigurationException;
98
use Nuxtifyts\PhpDto\Normalizers\Normalizer;
10-
use Nuxtifyts\PhpDto\Normalizers\StdClassNormalizer;
119

1210
trait HasNormalizers
1311
{
1412
/**
1513
* @param class-string<Data> $class
1614
*
1715
* @return array<string, mixed>|false
16+
*
17+
* @throws DataConfigurationException
1818
*/
1919
protected static function normalizeValue(mixed $value, string $class): array|false
2020
{
@@ -30,16 +30,15 @@ protected static function normalizeValue(mixed $value, string $class): array|fal
3030
}
3131

3232
/**
33-
* @return non-empty-array<int<0, max>, class-string<Normalizer>>
33+
* @return list<class-string<Normalizer>>
34+
*
35+
* @throws DataConfigurationException
3436
*/
3537
final protected static function allNormalizer(): array
3638
{
3739
return array_values(array_unique([
3840
...static::normalizers(),
39-
JsonStringNormalizer::class,
40-
StdClassNormalizer::class,
41-
ArrayAccessNormalizer::class,
42-
ArrayNormalizer::class,
41+
...DataConfiguration::getInstance()->normalizers->baseNormalizers,
4342
]));
4443
}
4544

src/Support/Arr.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,17 @@ public static function getArray(array $array, string $key, array $default = []):
1717

1818
return is_array($value) ? $value : $default;
1919
}
20+
21+
/**
22+
* @param array<array-key, mixed> $array
23+
* @param class-string<object> $classString
24+
*/
25+
public static function isArrayOfClassStrings(array $array, string $classString): bool
26+
{
27+
return array_all(
28+
$array,
29+
static fn (mixed $value): bool => is_string($value)
30+
&& is_subclass_of($value, $classString)
31+
);
32+
}
2033
}

0 commit comments

Comments
 (0)