Skip to content

Commit e560d20

Browse files
author
Enno Woortmann
committed
Skip optional values which were not provided in the data in the serialization result to avoid generating incompatible serialized values due to NULL fields (fixes #76)
1 parent 872363d commit e560d20

File tree

4 files changed

+101
-1
lines changed

4 files changed

+101
-1
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
}
1212
],
1313
"require": {
14-
"wol-soft/php-json-schema-model-generator-production": "^0.18.0",
14+
"wol-soft/php-json-schema-model-generator-production": "^0.18.1",
1515
"wol-soft/php-micro-template": "^1.3.2",
1616

1717
"php": ">=7.2",

src/SchemaProcessor/PostProcessor/Internal/SerializationPostProcessor.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@
88
use PHPModelGenerator\Filter\TransformingFilterInterface;
99
use PHPModelGenerator\Interfaces\SerializationInterface;
1010
use PHPModelGenerator\Model\GeneratorConfiguration;
11+
use PHPModelGenerator\Model\Property\Property;
12+
use PHPModelGenerator\Model\Property\PropertyInterface;
13+
use PHPModelGenerator\Model\Property\PropertyType;
1114
use PHPModelGenerator\Model\Schema;
15+
use PHPModelGenerator\Model\SchemaDefinition\JsonSchema;
1216
use PHPModelGenerator\Model\Validator\AdditionalPropertiesValidator;
1317
use PHPModelGenerator\Model\Validator\FilterValidator;
1418
use PHPModelGenerator\Model\Validator\PatternPropertiesValidator;
@@ -40,6 +44,7 @@ public function process(Schema $schema, GeneratorConfiguration $generatorConfigu
4044

4145
$this->addSerializeFunctionsForTransformingFilters($schema, $generatorConfiguration);
4246
$this->addSerializationHookMethod($schema, $generatorConfiguration);
47+
$this->addSkipNotProvidedPropertiesMap($schema, $generatorConfiguration);
4348

4449
$this->addPatternPropertiesSerialization($schema, $generatorConfiguration);
4550

@@ -229,4 +234,36 @@ public function getCode(): string
229234
}
230235
);
231236
}
237+
238+
private function addSkipNotProvidedPropertiesMap(
239+
Schema $schema,
240+
GeneratorConfiguration $generatorConfiguration
241+
): void {
242+
if ($generatorConfiguration->isImplicitNullAllowed()) {
243+
return;
244+
}
245+
246+
$skipNotProvidedValues = array_map(
247+
static function (PropertyInterface $property): string {
248+
return $property->getAttribute(true);
249+
},
250+
array_filter(
251+
$schema->getProperties(),
252+
static function (PropertyInterface $property): bool {
253+
return !$property->isRequired() && !$property->getDefaultValue();
254+
}
255+
)
256+
);
257+
258+
$schema->addProperty(
259+
(new Property(
260+
'skipNotProvidedPropertiesMap',
261+
new PropertyType('array'),
262+
new JsonSchema(__FILE__, []),
263+
'Values which might be skipped for serialization if not provided'
264+
))
265+
->setDefaultValue($skipNotProvidedValues)
266+
->setInternal(true)
267+
);
268+
}
232269
}

tests/Issues/Issue/Issue76Test.php

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PHPModelGenerator\Tests\Issues\Issue;
6+
7+
use PHPModelGenerator\Model\GeneratorConfiguration;
8+
use PHPModelGenerator\Tests\Issues\AbstractIssueTest;
9+
10+
class Issue76Test extends AbstractIssueTest
11+
{
12+
public function testSerializeWithImplicitNullEnabledIncludesAllFields(): void
13+
{
14+
$className = $this->generateClassFromFile(
15+
'optionalPropertySerialization.json',
16+
(new GeneratorConfiguration())->setSerialization(true)
17+
);
18+
19+
$object = new $className(['property1' => 'Hello']);
20+
21+
$this->assertEqualsCanonicalizing(
22+
['property1' => 'Hello', 'property2' => null, 'property3' => 'Moin'],
23+
$object->toArray()
24+
);
25+
}
26+
27+
public function testSerializeSkipsNotProvidedOptionalProperties(): void
28+
{
29+
$className = $this->generateClassFromFile(
30+
'optionalPropertySerialization.json',
31+
(new GeneratorConfiguration())->setSerialization(true)->setImmutable(false),
32+
false,
33+
false
34+
);
35+
36+
$object = new $className(['property1' => 'Hello']);
37+
38+
$this->assertEqualsCanonicalizing(['property1' => 'Hello', 'property3' => 'Moin'], $object->toArray());
39+
$object->setProperty2('World');
40+
$this->assertEqualsCanonicalizing(
41+
['property1' => 'Hello', 'property2' => 'World', 'property3' => 'Moin'],
42+
$object->toArray()
43+
);
44+
}
45+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"type": "object",
3+
"properties": {
4+
"property1": {
5+
"type": "string"
6+
},
7+
"property2": {
8+
"type": "string"
9+
},
10+
"property3": {
11+
"type": "string",
12+
"default": "Moin"
13+
}
14+
},
15+
"required": [
16+
"property1"
17+
]
18+
}

0 commit comments

Comments
 (0)