master

laravel/framework

Last updated at: 29/12/2023 09:23

ResourceResponse.php

TLDR

This file, ResourceResponse.php, is a part of the Demo Projects project. It is located at src/Illuminate/Http/Resources/Json/ResourceResponse.php. It defines a class called ResourceResponse which implements the Responsable interface. The class is used to create an HTTP response that represents a resource.

Methods

__construct

This method is the constructor of the ResourceResponse class. It accepts a resource as a parameter and assigns it to the resource property.

toResponse

This method creates an HTTP response that represents the resource. It takes a Request object as a parameter and returns an instance of JsonResponse. It uses the wrap method to wrap the data if necessary and calculates the appropriate status code for the response.

wrap

This protected method is used to wrap the given data if necessary. It takes the data, with array, and additional array as parameters and returns an array. This method checks if the data is an instance of Collection and converts it to an array if it is. It then checks if the default wrapper exists and the data is unwrapped, and wraps the data accordingly. If there is additional information and the data is unwrapped, it wraps the data using 'data' as the key if the default wrapper is not present. Finally, it merges the wrapped data with the with and additional arrays using array_merge_recursive.

haveDefaultWrapperAndDataIsUnwrapped

This protected method is used to determine if the default wrapper exists and the data is unwrapped. It takes the data as a parameter and returns a boolean value. It checks if the default wrapper exists and if the data does not contain the default wrapper as a key.

haveAdditionalInformationAndDataIsUnwrapped

This protected method is used to determine if "with" data has been added and the data is unwrapped. It takes the data, with array, and additional array as parameters and returns a boolean value. It checks if either the with or additional arrays are not empty and if the data does not contain the default wrapper as a key.

wrapper

This protected method is used to get the default data wrapper for the resource. It returns a string representing the default wrapper. It uses the ::$wrap static property of the resource class to get the default wrapper.

calculateStatus

This protected method is used to calculate the appropriate status code for the response. It returns an integer value representing the status code. It checks if the resource is an instance of Model and if the model was recently created, and returns 201 if true, otherwise returns 200.

<?php

namespace Illuminate\Http\Resources\Json;

use Illuminate\Contracts\Support\Responsable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;

class ResourceResponse implements Responsable
{
    /**
     * The underlying resource.
     *
     * @var mixed
     */
    public $resource;

    /**
     * Create a new resource response.
     *
     * @param  mixed  $resource
     * @return void
     */
    public function __construct($resource)
    {
        $this->resource = $resource;
    }

    /**
     * Create an HTTP response that represents the object.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function toResponse($request)
    {
        return tap(response()->json(
            $this->wrap(
                $this->resource->resolve($request),
                $this->resource->with($request),
                $this->resource->additional
            ),
            $this->calculateStatus(),
            [],
            $this->resource->jsonOptions()
        ), function ($response) use ($request) {
            $response->original = $this->resource->resource;

            $this->resource->withResponse($request, $response);
        });
    }

    /**
     * Wrap the given data if necessary.
     *
     * @param  \Illuminate\Support\Collection|array  $data
     * @param  array  $with
     * @param  array  $additional
     * @return array
     */
    protected function wrap($data, $with = [], $additional = [])
    {
        if ($data instanceof Collection) {
            $data = $data->all();
        }

        if ($this->haveDefaultWrapperAndDataIsUnwrapped($data)) {
            $data = [$this->wrapper() => $data];
        } elseif ($this->haveAdditionalInformationAndDataIsUnwrapped($data, $with, $additional)) {
            $data = [($this->wrapper() ?? 'data') => $data];
        }

        return array_merge_recursive($data, $with, $additional);
    }

    /**
     * Determine if we have a default wrapper and the given data is unwrapped.
     *
     * @param  array  $data
     * @return bool
     */
    protected function haveDefaultWrapperAndDataIsUnwrapped($data)
    {
        return $this->wrapper() && ! array_key_exists($this->wrapper(), $data);
    }

    /**
     * Determine if "with" data has been added and our data is unwrapped.
     *
     * @param  array  $data
     * @param  array  $with
     * @param  array  $additional
     * @return bool
     */
    protected function haveAdditionalInformationAndDataIsUnwrapped($data, $with, $additional)
    {
        return (! empty($with) || ! empty($additional)) &&
               (! $this->wrapper() ||
                ! array_key_exists($this->wrapper(), $data));
    }

    /**
     * Get the default data wrapper for the resource.
     *
     * @return string
     */
    protected function wrapper()
    {
        return get_class($this->resource)::$wrap;
    }

    /**
     * Calculate the appropriate status code for the response.
     *
     * @return int
     */
    protected function calculateStatus()
    {
        return $this->resource->resource instanceof Model &&
               $this->resource->resource->wasRecentlyCreated ? 201 : 200;
    }
}