diff --git a/src/Attributes/Hidden.php b/src/Attributes/Hidden.php new file mode 100644 index 00000000..f55f5405 --- /dev/null +++ b/src/Attributes/Hidden.php @@ -0,0 +1,10 @@ + $attribute instanceof Computed ); + $hidden = $attributes->contains( + fn (object $attribute) => $attribute instanceof Hidden + ); + return new self( name: $property->name, className: $property->class, @@ -74,6 +80,7 @@ className: $property->class, fn (object $attribute) => $attribute instanceof WithoutValidation ) && ! $computed, computed: $computed, + hidden: $hidden, isPromoted: $property->isPromoted(), isReadonly: $property->isReadOnly(), hasDefaultValue: $property->isPromoted() ? $hasDefaultValue : $property->hasDefaultValue(), diff --git a/src/Transformers/DataTransformer.php b/src/Transformers/DataTransformer.php index 736f2b09..bddb4de2 100644 --- a/src/Transformers/DataTransformer.php +++ b/src/Transformers/DataTransformer.php @@ -70,6 +70,10 @@ protected function resolvePayload(TransformableData $data): array $payload = []; foreach ($dataClass->properties as $property) { + if ($property->hidden) { + continue; + } + $name = $property->name; if (! $this->shouldIncludeProperty($name, $data->{$name}, $trees)) { diff --git a/tests/DataTest.php b/tests/DataTest.php index d4f5ecca..eadd88a1 100644 --- a/tests/DataTest.php +++ b/tests/DataTest.php @@ -10,6 +10,7 @@ use Inertia\LazyProp; use Spatie\LaravelData\Attributes\Computed; use Spatie\LaravelData\Attributes\DataCollectionOf; +use Spatie\LaravelData\Attributes\Hidden; use Spatie\LaravelData\Attributes\MapOutputName; use Spatie\LaravelData\Attributes\Validation\Min; use Spatie\LaravelData\Attributes\WithCast; @@ -2386,6 +2387,27 @@ public function __construct( ->toThrow(CannotSetComputedValue::class); }); +it('can have a hidden value', function () { + $dataObject = new class ('', '') extends Data { + public function __construct( + public string $show, + #[Hidden] + public string $hidden, + ) { + } + }; + + expect($dataObject::from(['show' => 'Yes', 'hidden' => 'No'])) + ->show->toBe('Yes') + ->hidden->toBe('No'); + + expect($dataObject::validateAndCreate(['show' => 'Yes', 'hidden' => 'No'])) + ->show->toBe('Yes') + ->hidden->toBe('No'); + + expect($dataObject::from(['show' => 'Yes', 'hidden' => 'No'])->toArray())->toBe(['show' => 'Yes']); +}); + it('throws a readable exception message when the constructor fails', function ( array $data, string $message, diff --git a/tests/Support/DataPropertyTest.php b/tests/Support/DataPropertyTest.php index 83716197..6e354a5a 100644 --- a/tests/Support/DataPropertyTest.php +++ b/tests/Support/DataPropertyTest.php @@ -2,6 +2,7 @@ use Spatie\LaravelData\Attributes\Computed; use Spatie\LaravelData\Attributes\DataCollectionOf; +use Spatie\LaravelData\Attributes\Hidden; use Spatie\LaravelData\Attributes\MapInputName; use Spatie\LaravelData\Attributes\MapOutputName; use Spatie\LaravelData\Attributes\WithCast; @@ -152,6 +153,21 @@ public function __construct( )->toBeTrue(); }); +it('can check if a property is hidden', function () { + expect( + resolveHelper(new class () { + public string $property; + })->hidden + )->toBeFalse(); + + expect( + resolveHelper(new class () { + #[Hidden] + public string $property; + })->hidden + )->toBeTrue(); +}); + it('wont throw an error if non existing attribute is used on a data class property', function () { expect(NonExistingPropertyAttributeData::from(['property' => 'hello'])->property)->toEqual('hello') ->and(PhpStormAttributeData::from(['property' => 'hello'])->property)->toEqual('hello')