annotate vendor/zendframework/zend-diactoros/src/Response/JsonResponse.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents c2387f117808
children
rev   line source
Chris@0 1 <?php
Chris@0 2 /**
Chris@12 3 * @see https://github.com/zendframework/zend-diactoros for the canonical source repository
Chris@12 4 * @copyright Copyright (c) 2015-2017 Zend Technologies USA Inc. (http://www.zend.com)
Chris@0 5 * @license https://github.com/zendframework/zend-diactoros/blob/master/LICENSE.md New BSD License
Chris@0 6 */
Chris@0 7
Chris@0 8 namespace Zend\Diactoros\Response;
Chris@0 9
Chris@0 10 use InvalidArgumentException;
Chris@0 11 use Zend\Diactoros\Response;
Chris@0 12 use Zend\Diactoros\Stream;
Chris@0 13
Chris@16 14 use function is_object;
Chris@16 15 use function is_resource;
Chris@16 16 use function json_encode;
Chris@16 17 use function json_last_error;
Chris@16 18 use function json_last_error_msg;
Chris@16 19 use function sprintf;
Chris@16 20
Chris@16 21 use const JSON_ERROR_NONE;
Chris@16 22
Chris@0 23 /**
Chris@0 24 * JSON response.
Chris@0 25 *
Chris@0 26 * Allows creating a response by passing data to the constructor; by default,
Chris@0 27 * serializes the data to JSON, sets a status code of 200 and sets the
Chris@0 28 * Content-Type header to application/json.
Chris@0 29 */
Chris@0 30 class JsonResponse extends Response
Chris@0 31 {
Chris@0 32 use InjectContentTypeTrait;
Chris@0 33
Chris@0 34 /**
Chris@0 35 * Default flags for json_encode; value of:
Chris@0 36 *
Chris@0 37 * <code>
Chris@0 38 * JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT | JSON_UNESCAPED_SLASHES
Chris@0 39 * </code>
Chris@0 40 *
Chris@0 41 * @const int
Chris@0 42 */
Chris@0 43 const DEFAULT_JSON_FLAGS = 79;
Chris@0 44
Chris@0 45 /**
Chris@12 46 * @var mixed
Chris@12 47 */
Chris@12 48 private $payload;
Chris@12 49
Chris@12 50 /**
Chris@12 51 * @var int
Chris@12 52 */
Chris@12 53 private $encodingOptions;
Chris@12 54
Chris@12 55 /**
Chris@0 56 * Create a JSON response with the given data.
Chris@0 57 *
Chris@0 58 * Default JSON encoding is performed with the following options, which
Chris@0 59 * produces RFC4627-compliant JSON, capable of embedding into HTML.
Chris@0 60 *
Chris@0 61 * - JSON_HEX_TAG
Chris@0 62 * - JSON_HEX_APOS
Chris@0 63 * - JSON_HEX_AMP
Chris@0 64 * - JSON_HEX_QUOT
Chris@0 65 * - JSON_UNESCAPED_SLASHES
Chris@0 66 *
Chris@0 67 * @param mixed $data Data to convert to JSON.
Chris@0 68 * @param int $status Integer status code for the response; 200 by default.
Chris@0 69 * @param array $headers Array of headers to use at initialization.
Chris@0 70 * @param int $encodingOptions JSON encoding options to use.
Chris@0 71 * @throws InvalidArgumentException if unable to encode the $data to JSON.
Chris@0 72 */
Chris@0 73 public function __construct(
Chris@0 74 $data,
Chris@0 75 $status = 200,
Chris@0 76 array $headers = [],
Chris@0 77 $encodingOptions = self::DEFAULT_JSON_FLAGS
Chris@0 78 ) {
Chris@12 79 $this->setPayload($data);
Chris@12 80 $this->encodingOptions = $encodingOptions;
Chris@12 81
Chris@12 82 $json = $this->jsonEncode($data, $this->encodingOptions);
Chris@12 83 $body = $this->createBodyFromJson($json);
Chris@0 84
Chris@0 85 $headers = $this->injectContentType('application/json', $headers);
Chris@0 86
Chris@0 87 parent::__construct($body, $status, $headers);
Chris@0 88 }
Chris@0 89
Chris@0 90 /**
Chris@12 91 * @return mixed
Chris@12 92 */
Chris@12 93 public function getPayload()
Chris@12 94 {
Chris@12 95 return $this->payload;
Chris@12 96 }
Chris@12 97
Chris@12 98 /**
Chris@12 99 * @param $data
Chris@12 100 *
Chris@12 101 * @return JsonResponse
Chris@12 102 */
Chris@12 103 public function withPayload($data)
Chris@12 104 {
Chris@12 105 $new = clone $this;
Chris@12 106 $new->setPayload($data);
Chris@12 107 return $this->updateBodyFor($new);
Chris@12 108 }
Chris@12 109
Chris@12 110 /**
Chris@12 111 * @return int
Chris@12 112 */
Chris@12 113 public function getEncodingOptions()
Chris@12 114 {
Chris@12 115 return $this->encodingOptions;
Chris@12 116 }
Chris@12 117
Chris@12 118 /**
Chris@12 119 * @param int $encodingOptions
Chris@12 120 *
Chris@12 121 * @return JsonResponse
Chris@12 122 */
Chris@12 123 public function withEncodingOptions($encodingOptions)
Chris@12 124 {
Chris@12 125 $new = clone $this;
Chris@12 126 $new->encodingOptions = $encodingOptions;
Chris@12 127 return $this->updateBodyFor($new);
Chris@12 128 }
Chris@12 129
Chris@12 130 /**
Chris@12 131 * @param string $json
Chris@12 132 *
Chris@12 133 * @return Stream
Chris@12 134 */
Chris@12 135 private function createBodyFromJson($json)
Chris@12 136 {
Chris@12 137 $body = new Stream('php://temp', 'wb+');
Chris@12 138 $body->write($json);
Chris@12 139 $body->rewind();
Chris@12 140
Chris@12 141 return $body;
Chris@12 142 }
Chris@12 143
Chris@12 144 /**
Chris@0 145 * Encode the provided data to JSON.
Chris@0 146 *
Chris@0 147 * @param mixed $data
Chris@0 148 * @param int $encodingOptions
Chris@0 149 * @return string
Chris@0 150 * @throws InvalidArgumentException if unable to encode the $data to JSON.
Chris@0 151 */
Chris@0 152 private function jsonEncode($data, $encodingOptions)
Chris@0 153 {
Chris@0 154 if (is_resource($data)) {
Chris@0 155 throw new InvalidArgumentException('Cannot JSON encode resources');
Chris@0 156 }
Chris@0 157
Chris@0 158 // Clear json_last_error()
Chris@0 159 json_encode(null);
Chris@0 160
Chris@0 161 $json = json_encode($data, $encodingOptions);
Chris@0 162
Chris@0 163 if (JSON_ERROR_NONE !== json_last_error()) {
Chris@0 164 throw new InvalidArgumentException(sprintf(
Chris@0 165 'Unable to encode data to JSON in %s: %s',
Chris@0 166 __CLASS__,
Chris@0 167 json_last_error_msg()
Chris@0 168 ));
Chris@0 169 }
Chris@0 170
Chris@0 171 return $json;
Chris@0 172 }
Chris@12 173
Chris@12 174 /**
Chris@12 175 * @param $data
Chris@12 176 */
Chris@12 177 private function setPayload($data)
Chris@12 178 {
Chris@12 179 if (is_object($data)) {
Chris@12 180 $data = clone $data;
Chris@12 181 }
Chris@12 182
Chris@12 183 $this->payload = $data;
Chris@12 184 }
Chris@12 185
Chris@12 186 /**
Chris@12 187 * Update the response body for the given instance.
Chris@12 188 *
Chris@12 189 * @param self $toUpdate Instance to update.
Chris@12 190 * @return JsonResponse Returns a new instance with an updated body.
Chris@12 191 */
Chris@12 192 private function updateBodyFor(self $toUpdate)
Chris@12 193 {
Chris@12 194 $json = $this->jsonEncode($toUpdate->payload, $toUpdate->encodingOptions);
Chris@12 195 $body = $this->createBodyFromJson($json);
Chris@12 196 return $toUpdate->withBody($body);
Chris@12 197 }
Chris@0 198 }