diff --git a/src/Illuminate/Http/Resources/Json/JsonResource.php b/src/Illuminate/Http/Resources/Json/JsonResource.php index f98f2cb53e45..f55fc71461e7 100644 --- a/src/Illuminate/Http/Resources/Json/JsonResource.php +++ b/src/Illuminate/Http/Resources/Json/JsonResource.php @@ -111,7 +111,7 @@ protected static function newCollection($resource) */ public function resolve($request = null) { - $data = $this->toArray( + $data = $this->toAttributes( $request ?: Container::getInstance()->make('request') ); @@ -124,6 +124,17 @@ public function resolve($request = null) return $this->filter((array) $data); } + /** + * Transform the resource into an array. + * + * @param \Illuminate\Http\Request $request + * @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable + */ + public function toAttributes(Request $request) + { + return $this->toArray($request); + } + /** * Transform the resource into an array. * diff --git a/src/Illuminate/Http/Resources/Json/ResourceCollection.php b/src/Illuminate/Http/Resources/Json/ResourceCollection.php index 81cfc1bd3181..025ab9b95f42 100644 --- a/src/Illuminate/Http/Resources/Json/ResourceCollection.php +++ b/src/Illuminate/Http/Resources/Json/ResourceCollection.php @@ -96,9 +96,9 @@ public function count(): int * @param \Illuminate\Http\Request $request * @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable */ - public function toArray(Request $request) + public function toAttributes(Request $request) { - return $this->collection->map->toArray($request)->all(); + return $this->collection->map->resolve($request)->all(); } /** diff --git a/src/Illuminate/Http/Resources/JsonApi/AnonymousResourceCollection.php b/src/Illuminate/Http/Resources/JsonApi/AnonymousResourceCollection.php index 4f66aad50947..ebc314652249 100644 --- a/src/Illuminate/Http/Resources/JsonApi/AnonymousResourceCollection.php +++ b/src/Illuminate/Http/Resources/JsonApi/AnonymousResourceCollection.php @@ -35,7 +35,7 @@ public function with($request) * @return array */ #[\Override] - public function toArray(Request $request) + public function toAttributes(Request $request) { return $this->collection ->map(fn ($resource) => $resource->resolveResourceData($request)) diff --git a/src/Illuminate/Http/Resources/JsonApi/Concerns/ResolvesJsonApiElements.php b/src/Illuminate/Http/Resources/JsonApi/Concerns/ResolvesJsonApiElements.php index 909fb7c4416c..67469fd9c656 100644 --- a/src/Illuminate/Http/Resources/JsonApi/Concerns/ResolvesJsonApiElements.php +++ b/src/Illuminate/Http/Resources/JsonApi/Concerns/ResolvesJsonApiElements.php @@ -6,8 +6,10 @@ use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\Relation; use Illuminate\Http\Request; +use Illuminate\Http\Resources\Json\JsonResource; use Illuminate\Http\Resources\JsonApi\Exceptions\ResourceIdentificationException; use Illuminate\Http\Resources\JsonApi\JsonApiResource; +use Illuminate\Support\Arr; use Illuminate\Support\Collection; use Illuminate\Support\Str; use JsonSerializable; @@ -53,6 +55,10 @@ public function resolveResourceData(Request $request): array */ protected function resolveResourceIdentifier(Request $request): string { + if (! is_null($resourceId = $this->toId($request))) { + return $resourceId; + } + if (! $this->resource instanceof Model) { throw ResourceIdentificationException::attemptingToDetermineIdFor($this); } @@ -68,6 +74,10 @@ protected function resolveResourceIdentifier(Request $request): string */ protected function resolveResourceType(Request $request): string { + if (! is_null($resourceType = $this->toType($request))) { + return $resourceType; + } + if (! $this->resource instanceof Model) { throw ResourceIdentificationException::attemptingToDetermineTypeFor($this); } @@ -83,7 +93,7 @@ protected function resolveResourceType(Request $request): string */ protected function resolveResourceAttributes(Request $request): array { - $data = $this->toArray($request); + $data = $this->toAttributes($request); if ($data instanceof Arrayable) { $data = $data->toArray(); @@ -92,6 +102,7 @@ protected function resolveResourceAttributes(Request $request): array } $data = (new Collection($data)) + ->mapWithKeys(fn ($value, $key) => is_int($key) ? [$value => $this->resource->{$value}] : [$key => $value]) ->transform(fn ($value) => value($value, $request)) ->all(); @@ -168,12 +179,17 @@ public function resolveIncludedResources(Request $request): array $relations = new Collection; foreach ($this->loadedRelationshipsMap as $relation => $uniqueKey) { - $resource = rescue(fn () => $relation->toResource(), new JsonApiResource($relation), false); + $resourceInstance = rescue(fn () => $relation->toResource(), new JsonApiResource($relation), false); + + if (! $resourceInstance instanceof JsonApiResource && + $resourceInstance instanceof JsonResource) { + $resourceInstance = new JsonApiResource($resourceInstance->resource); + } $relations->push([ 'id' => $uniqueKey[1], 'type' => $uniqueKey[0], - 'attributes' => $resource->toArray($request), + 'attributes' => Arr::get($resourceInstance->resolve($request), 'data.attributes', []), ]); } @@ -189,7 +205,7 @@ public function resolveIncludedResources(Request $request): array */ protected function resolveResourceLinks(Request $request): array { - return $this->links($request); + return $this->toLinks($request); } /** @@ -199,7 +215,7 @@ protected function resolveResourceLinks(Request $request): array */ protected function resolveResourceMetaInformation(Request $request): array { - return $this->meta($request); + return $this->toMeta($request); } /** diff --git a/src/Illuminate/Http/Resources/JsonApi/JsonApiResource.php b/src/Illuminate/Http/Resources/JsonApi/JsonApiResource.php index 0c592876a3fb..b595332790d0 100644 --- a/src/Illuminate/Http/Resources/JsonApi/JsonApiResource.php +++ b/src/Illuminate/Http/Resources/JsonApi/JsonApiResource.php @@ -54,21 +54,21 @@ public static function configure(?string $version = null, array $ext = [], array /** * Get the resource's ID. * - * @return string + * @return string|null */ - public function id(Request $request) + public function toId(Request $request) { - return $this->resolveResourceIdentifier($request); + return null; } /** * Get the resource's type. * - * @return string + * @return string|null */ - public function type(Request $request) + public function toType(Request $request) { - return $this->resolveResourceType($request); + return null; } /** @@ -76,7 +76,7 @@ public function type(Request $request) * * @return array */ - public function links(Request $request) + public function toLinks(Request $request) { return $this->jsonApiLinks; } @@ -86,7 +86,7 @@ public function links(Request $request) * * @return array */ - public function meta(Request $request) + public function toMeta(Request $request) { return $this->jsonApiMeta; } diff --git a/tests/Integration/Http/Resources/JsonApi/JsonApiResourceTest.php b/tests/Integration/Http/Resources/JsonApi/JsonApiResourceTest.php index ac95b9af7813..c86b3a5bd261 100644 --- a/tests/Integration/Http/Resources/JsonApi/JsonApiResourceTest.php +++ b/tests/Integration/Http/Resources/JsonApi/JsonApiResourceTest.php @@ -166,7 +166,7 @@ public function toArray(Request $request) class UserApiResource extends JsonApiResource { - public function toArray(Request $request) + public function toAttributes(Request $request) { return [ 'name' => $this->name, @@ -186,11 +186,11 @@ public function user() class PostApiResource extends JsonApiResource { - public function toArray(Request $request) + public function toAttributes(Request $request) { return [ - 'title' => $this->title, - 'content' => $this->content, + 'title', + 'content', ]; } }