diff --git a/src/Transformers/DataTransformer.php b/src/Transformers/DataTransformer.php index bddb4de2a..a10b2f558 100644 --- a/src/Transformers/DataTransformer.php +++ b/src/Transformers/DataTransformer.php @@ -76,6 +76,10 @@ protected function resolvePayload(TransformableData $data): array $name = $property->name; + if ($property->type->isOptional && ! array_key_exists($name, get_object_vars($data))) { + continue; + } + if (! $this->shouldIncludeProperty($name, $data->{$name}, $trees)) { continue; } diff --git a/tests/ValidationTest.php b/tests/ValidationTest.php index 9917cf620..20180e222 100644 --- a/tests/ValidationTest.php +++ b/tests/ValidationTest.php @@ -2379,3 +2379,15 @@ public static function rules(ValidationContext $context): array ->assertOk(['success' => true, 'id' => 1]) ->assertErrors(['success' => true]); })->skip('V4: The rule inferrers need to be rewritten/removed for this, we need to first add attribute rules and then decide require stuff'); + +it('can validate an optional but nonexists attribute', function () { + $dataClass = new class () extends Data { + public array|null|Optional $property; + }; + + expect($dataClass::from()->toArray())->toBe([]); + expect($dataClass::from([])->toArray())->toBe([]); + expect($dataClass::from(['property' => null])->toArray())->toBe(['property' => null]); + expect($dataClass::from(['property' => []])->toArray())->toBe(['property' => []]); + expect($dataClass::validateAndCreate([])->toArray())->toBe([]); +});