diff --git a/src/Concerns/ResponsableData.php b/src/Concerns/ResponsableData.php index 33578544..05d6133e 100644 --- a/src/Concerns/ResponsableData.php +++ b/src/Concerns/ResponsableData.php @@ -58,7 +58,7 @@ public function toResponse($request) } return new JsonResponse( - data: $this->transform($contextFactory), + data: $this->jsonSerializeWithTransformationContext($contextFactory), status: $this->calculateResponseStatus($request), ); } diff --git a/src/Concerns/TransformableData.php b/src/Concerns/TransformableData.php index b18f3c2b..2468f730 100644 --- a/src/Concerns/TransformableData.php +++ b/src/Concerns/TransformableData.php @@ -14,6 +14,8 @@ trait TransformableData { + protected null|TransformationContextFactory|TransformationContext $_jsonSerializeContextOnce = null; + public function transform( null|TransformationContextFactory|TransformationContext $transformationContext = null, ): array { @@ -51,12 +53,25 @@ public function toArray(): array public function toJson($options = 0): string { - return json_encode($this->transform(), $options); + return json_encode($this->jsonSerialize(), $options); } public function jsonSerialize(): array { - return $this->transform(); + $transformationContext = $this->_jsonSerializeContextOnce; + + if ($this->_jsonSerializeContextOnce) { + $this->_jsonSerializeContextOnce = null; + } + + return $this->transform($transformationContext); + } + + public function jsonSerializeWithTransformationContext(null|TransformationContextFactory|TransformationContext $transformationContext): array + { + $this->_jsonSerializeContextOnce = $transformationContext; + + return $this->jsonSerialize(); } public static function castUsing(array $arguments) diff --git a/src/Contracts/TransformableData.php b/src/Contracts/TransformableData.php index f2b93245..2314b408 100644 --- a/src/Contracts/TransformableData.php +++ b/src/Contracts/TransformableData.php @@ -23,5 +23,7 @@ public function toJson($options = 0): string; public function jsonSerialize(): array; + public function jsonSerializeWithTransformationContext(null|TransformationContextFactory|TransformationContext $transformationContext): array; + public static function castUsing(array $arguments); } diff --git a/tests/ResponseTest.php b/tests/ResponseTest.php new file mode 100644 index 00000000..6c2a5049 --- /dev/null +++ b/tests/ResponseTest.php @@ -0,0 +1,18 @@ + 'Hello from serialize', + ]; + } + }; + + expect($data->toResponse(request())->getContent())->toBe('{"string":"Hello from serialize"}'); +}); diff --git a/tests/TransformationTest.php b/tests/TransformationTest.php index d158213c..e60d2afa 100644 --- a/tests/TransformationTest.php +++ b/tests/TransformationTest.php @@ -133,6 +133,21 @@ public function __construct( ->toEqual(json_encode(SimpleData::from('Hello'))); }); +it('calls jsonSerialize when toJson is invoked', function () { + + $data = new class extends Data + { + public function jsonSerialize(): array + { + return [ + 'string' => 'Hello from serialize', + ]; + } + }; + + expect($data->toJson())->toBe('{"string":"Hello from serialize"}'); +}); + it('can use a custom transformer for a data object and/or data collectable', function () { $nestedData = new class (42, 'Hello World') extends Data { public function __construct(