nginxsonarrradarrplexorganizrdashboardbookmarkapplication-dashboardmuximuxlandingpagestartpagelandinghtpcserverhomepagesabnzbdheimdallembycouchpotatonzbget
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
183 lines
4.7 KiB
183 lines
4.7 KiB
<?php
|
|
/**
|
|
* @see https://github.com/zendframework/zend-diactoros for the canonical source repository
|
|
* @copyright Copyright (c) 2015-2018 Zend Technologies USA Inc. (http://www.zend.com)
|
|
* @license https://github.com/zendframework/zend-diactoros/blob/master/LICENSE.md New BSD License
|
|
*/
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Zend\Diactoros\Response;
|
|
|
|
use Zend\Diactoros\Exception;
|
|
use Zend\Diactoros\Response;
|
|
use Zend\Diactoros\Stream;
|
|
|
|
use function is_object;
|
|
use function is_resource;
|
|
use function json_encode;
|
|
use function json_last_error;
|
|
use function json_last_error_msg;
|
|
use function sprintf;
|
|
|
|
use const JSON_ERROR_NONE;
|
|
|
|
/**
|
|
* JSON response.
|
|
*
|
|
* Allows creating a response by passing data to the constructor; by default,
|
|
* serializes the data to JSON, sets a status code of 200 and sets the
|
|
* Content-Type header to application/json.
|
|
*/
|
|
class JsonResponse extends Response
|
|
{
|
|
use InjectContentTypeTrait;
|
|
|
|
/**
|
|
* Default flags for json_encode; value of:
|
|
*
|
|
* <code>
|
|
* JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT | JSON_UNESCAPED_SLASHES
|
|
* </code>
|
|
*
|
|
* @const int
|
|
*/
|
|
const DEFAULT_JSON_FLAGS = 79;
|
|
|
|
/**
|
|
* @var mixed
|
|
*/
|
|
private $payload;
|
|
|
|
/**
|
|
* @var int
|
|
*/
|
|
private $encodingOptions;
|
|
|
|
/**
|
|
* Create a JSON response with the given data.
|
|
*
|
|
* Default JSON encoding is performed with the following options, which
|
|
* produces RFC4627-compliant JSON, capable of embedding into HTML.
|
|
*
|
|
* - JSON_HEX_TAG
|
|
* - JSON_HEX_APOS
|
|
* - JSON_HEX_AMP
|
|
* - JSON_HEX_QUOT
|
|
* - JSON_UNESCAPED_SLASHES
|
|
*
|
|
* @param mixed $data Data to convert to JSON.
|
|
* @param int $status Integer status code for the response; 200 by default.
|
|
* @param array $headers Array of headers to use at initialization.
|
|
* @param int $encodingOptions JSON encoding options to use.
|
|
* @throws Exception\InvalidArgumentException if unable to encode the $data to JSON.
|
|
*/
|
|
public function __construct(
|
|
$data,
|
|
int $status = 200,
|
|
array $headers = [],
|
|
int $encodingOptions = self::DEFAULT_JSON_FLAGS
|
|
) {
|
|
$this->setPayload($data);
|
|
$this->encodingOptions = $encodingOptions;
|
|
|
|
$json = $this->jsonEncode($data, $this->encodingOptions);
|
|
$body = $this->createBodyFromJson($json);
|
|
|
|
$headers = $this->injectContentType('application/json', $headers);
|
|
|
|
parent::__construct($body, $status, $headers);
|
|
}
|
|
|
|
/**
|
|
* @return mixed
|
|
*/
|
|
public function getPayload()
|
|
{
|
|
return $this->payload;
|
|
}
|
|
|
|
/**
|
|
* @param mixed $data
|
|
*/
|
|
public function withPayload($data) : JsonResponse
|
|
{
|
|
$new = clone $this;
|
|
$new->setPayload($data);
|
|
return $this->updateBodyFor($new);
|
|
}
|
|
|
|
public function getEncodingOptions() : int
|
|
{
|
|
return $this->encodingOptions;
|
|
}
|
|
|
|
public function withEncodingOptions(int $encodingOptions) : JsonResponse
|
|
{
|
|
$new = clone $this;
|
|
$new->encodingOptions = $encodingOptions;
|
|
return $this->updateBodyFor($new);
|
|
}
|
|
|
|
private function createBodyFromJson(string $json) : Stream
|
|
{
|
|
$body = new Stream('php://temp', 'wb+');
|
|
$body->write($json);
|
|
$body->rewind();
|
|
|
|
return $body;
|
|
}
|
|
|
|
/**
|
|
* Encode the provided data to JSON.
|
|
*
|
|
* @param mixed $data
|
|
* @throws Exception\InvalidArgumentException if unable to encode the $data to JSON.
|
|
*/
|
|
private function jsonEncode($data, int $encodingOptions) : string
|
|
{
|
|
if (is_resource($data)) {
|
|
throw new Exception\InvalidArgumentException('Cannot JSON encode resources');
|
|
}
|
|
|
|
// Clear json_last_error()
|
|
json_encode(null);
|
|
|
|
$json = json_encode($data, $encodingOptions);
|
|
|
|
if (JSON_ERROR_NONE !== json_last_error()) {
|
|
throw new Exception\InvalidArgumentException(sprintf(
|
|
'Unable to encode data to JSON in %s: %s',
|
|
__CLASS__,
|
|
json_last_error_msg()
|
|
));
|
|
}
|
|
|
|
return $json;
|
|
}
|
|
|
|
/**
|
|
* @param mixed $data
|
|
*/
|
|
private function setPayload($data) : void
|
|
{
|
|
if (is_object($data)) {
|
|
$data = clone $data;
|
|
}
|
|
|
|
$this->payload = $data;
|
|
}
|
|
|
|
/**
|
|
* Update the response body for the given instance.
|
|
*
|
|
* @param self $toUpdate Instance to update.
|
|
* @return JsonResponse Returns a new instance with an updated body.
|
|
*/
|
|
private function updateBodyFor(JsonResponse $toUpdate) : JsonResponse
|
|
{
|
|
$json = $this->jsonEncode($toUpdate->payload, $toUpdate->encodingOptions);
|
|
$body = $this->createBodyFromJson($json);
|
|
return $toUpdate->withBody($body);
|
|
}
|
|
}
|
|
|