Skip to content

Commit

Permalink
[8.x] Avoid constructor call when fetching resource JSON options (#40261
Browse files Browse the repository at this point in the history
)

* Avoid constructor call when fetching json options

* Update CollectsResources.php

* Update CollectsResources.php

Co-authored-by: Taylor Otwell <taylor@laravel.com>
  • Loading branch information
philcross and taylorotwell committed Jan 5, 2022
1 parent 8c293f9 commit 424f97a
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 1 deletion.
9 changes: 8 additions & 1 deletion src/Illuminate/Http/Resources/CollectsResources.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use Illuminate\Pagination\AbstractPaginator;
use Illuminate\Support\Collection;
use Illuminate\Support\Str;
use ReflectionClass;

trait CollectsResources
{
Expand Down Expand Up @@ -63,7 +64,13 @@ public function jsonOptions()
{
$collects = $this->collects();

return $collects ? (new $collects([]))->jsonOptions() : 0;
if (! $collects) {
return 0;
}

return (new ReflectionClass($collects))
->newInstanceWithoutConstructor()
->jsonOptions();
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

namespace Illuminate\Tests\Integration\Http\Fixtures;

use Illuminate\Http\Resources\Json\JsonResource;

class PostResourceWithJsonOptionsAndTypeHints extends JsonResource
{
public function __construct(Post $resource)
{
parent::__construct($resource);
}

public function toArray($request)
{
return [
'id' => $this->id,
'title' => $this->title,
'reading_time' => $this->reading_time,
];
}

public function jsonOptions()
{
return JSON_PRESERVE_ZERO_FRACTION;
}
}
21 changes: 21 additions & 0 deletions tests/Integration/Http/ResourceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
use Illuminate\Tests\Integration\Http\Fixtures\PostResourceWithAnonymousResourceCollectionWithPaginationInformation;
use Illuminate\Tests\Integration\Http\Fixtures\PostResourceWithExtraData;
use Illuminate\Tests\Integration\Http\Fixtures\PostResourceWithJsonOptions;
use Illuminate\Tests\Integration\Http\Fixtures\PostResourceWithJsonOptionsAndTypeHints;
use Illuminate\Tests\Integration\Http\Fixtures\PostResourceWithOptionalAppendedAttributes;
use Illuminate\Tests\Integration\Http\Fixtures\PostResourceWithOptionalData;
use Illuminate\Tests\Integration\Http\Fixtures\PostResourceWithOptionalMerging;
Expand Down Expand Up @@ -555,6 +556,26 @@ public function testResourcesMayCustomizeJsonOptionsOnPaginatedResponse()
);
}

public function testResourcesMayCustomizeJsonOptionsWithTypeHintedConstructor()
{
Route::get('/', function () {
return new PostResourceWithJsonOptionsAndTypeHints(new Post([
'id' => 5,
'title' => 'Test Title',
'reading_time' => 3.0,
]));
});

$response = $this->withoutExceptionHandling()->get(
'/', ['Accept' => 'application/json']
);

$this->assertEquals(
'{"data":{"id":5,"title":"Test Title","reading_time":3.0}}',
$response->baseResponse->content()
);
}

public function testCustomHeadersMayBeSetOnResponses()
{
Route::get('/', function () {
Expand Down

0 comments on commit 424f97a

Please sign in to comment.