Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/Illuminate/Http/Resources/Json/JsonResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@ class JsonResource implements ArrayAccess, JsonSerializable, Responsable, UrlRou
*/
public static $wrap = 'data';

/**
* Whether to force wrapping even if $wrap key exists in resource data.
*
* @var bool
*/
public static bool $forceWrap = false;

/**
* Create a new resource instance.
*
Expand Down
6 changes: 5 additions & 1 deletion src/Illuminate/Http/Resources/Json/ResourceResponse.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,12 @@ protected function wrap($data, $with = [], $additional = [])
* @param array $data
* @return bool
*/
protected function haveDefaultWrapperAndDataIsUnwrapped($data)
protected function haveDefaultWrapperAndDataIsUnwrapped(array $data): bool
{
if ($this->resource instanceof JsonResource && $this->resource::$forceWrap) {
return $this->wrapper() !== null;
}

return $this->wrapper() && ! array_key_exists($this->wrapper(), $data);
}

Expand Down
55 changes: 55 additions & 0 deletions tests/Integration/Http/ResourceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1853,6 +1853,61 @@ public function testItThrowsNoErrorInStrictModeWhenResourceIsPaginated()
}
}

public function testResourceSkipsWrappingWhenDataKeyExists()
{
$resource = new class(['id' => 5, 'title' => 'Test', 'data' => 'some data']) extends JsonResource
{
public static $wrap = 'data';
};

$response = $resource->toResponse(request());
$content = json_decode($response->getContent(), true);

$this->assertEquals([
'id' => 5,
'title' => 'Test',
'data' => 'some data',
], $content);
}

public function testResourceWrapsWhenDataKeyDoesNotExist()
{
$resource = new class(['id' => 5, 'title' => 'Test']) extends JsonResource
{
public static $wrap = 'data';
};

$response = $resource->toResponse(request());
$content = json_decode($response->getContent(), true);

$this->assertEquals([
'data' => [
'id' => 5,
'title' => 'Test',
],
], $content);
}

public function testResourceForceWrapOverridesDataKeyCheck()
{
$resource = new class(['id' => 5, 'title' => 'Test', 'data' => 'some data']) extends JsonResource
{
public static $wrap = 'data';
public static bool $forceWrap = true;
};

$response = $resource->toResponse(request());
$content = json_decode($response->getContent(), true);

$this->assertEquals([
'data' => [
'id' => 5,
'title' => 'Test',
'data' => 'some data',
],
], $content);
}

private function assertJsonResourceResponse($data, $expectedJson)
{
Route::get('/', function () use ($data) {
Expand Down