[ Index ]

PHP Cross Reference of phpBB-3.3.14-deutsch

title

Body

[close]

/vendor/symfony/http-foundation/ -> JsonResponse.php (source)

   1  <?php
   2  
   3  /*
   4   * This file is part of the Symfony package.
   5   *
   6   * (c) Fabien Potencier <fabien@symfony.com>
   7   *
   8   * For the full copyright and license information, please view the LICENSE
   9   * file that was distributed with this source code.
  10   */
  11  
  12  namespace Symfony\Component\HttpFoundation;
  13  
  14  /**
  15   * Response represents an HTTP response in JSON format.
  16   *
  17   * Note that this class does not force the returned JSON content to be an
  18   * object. It is however recommended that you do return an object as it
  19   * protects yourself against XSSI and JSON-JavaScript Hijacking.
  20   *
  21   * @see https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/AJAX_Security_Cheat_Sheet.md#always-return-json-with-an-object-on-the-outside
  22   *
  23   * @author Igor Wiedler <igor@wiedler.ch>
  24   */
  25  class JsonResponse extends Response
  26  {
  27      protected $data;
  28      protected $callback;
  29  
  30      // Encode <, >, ', &, and " characters in the JSON, making it also safe to be embedded into HTML.
  31      // 15 === JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT
  32      const DEFAULT_ENCODING_OPTIONS = 15;
  33  
  34      protected $encodingOptions = self::DEFAULT_ENCODING_OPTIONS;
  35  
  36      /**
  37       * @param mixed $data    The response data
  38       * @param int   $status  The response status code
  39       * @param array $headers An array of response headers
  40       * @param bool  $json    If the data is already a JSON string
  41       */
  42      public function __construct($data = null, $status = 200, $headers = [], $json = false)
  43      {
  44          parent::__construct('', $status, $headers);
  45  
  46          if (null === $data) {
  47              $data = new \ArrayObject();
  48          }
  49  
  50          $json ? $this->setJson($data) : $this->setData($data);
  51      }
  52  
  53      /**
  54       * Factory method for chainability.
  55       *
  56       * Example:
  57       *
  58       *     return JsonResponse::create(['key' => 'value'])
  59       *         ->setSharedMaxAge(300);
  60       *
  61       * @param mixed $data    The JSON response data
  62       * @param int   $status  The response status code
  63       * @param array $headers An array of response headers
  64       *
  65       * @return static
  66       */
  67      public static function create($data = null, $status = 200, $headers = [])
  68      {
  69          return new static($data, $status, $headers);
  70      }
  71  
  72      /**
  73       * Factory method for chainability.
  74       *
  75       * Example:
  76       *
  77       *     return JsonResponse::fromJsonString('{"key": "value"}')
  78       *         ->setSharedMaxAge(300);
  79       *
  80       * @param string|null $data    The JSON response string
  81       * @param int         $status  The response status code
  82       * @param array       $headers An array of response headers
  83       *
  84       * @return static
  85       */
  86      public static function fromJsonString($data = null, $status = 200, $headers = [])
  87      {
  88          return new static($data, $status, $headers, true);
  89      }
  90  
  91      /**
  92       * Sets the JSONP callback.
  93       *
  94       * @param string|null $callback The JSONP callback or null to use none
  95       *
  96       * @return $this
  97       *
  98       * @throws \InvalidArgumentException When the callback name is not valid
  99       */
 100      public function setCallback($callback = null)
 101      {
 102          if (null !== $callback) {
 103              // partially taken from https://geekality.net/2011/08/03/valid-javascript-identifier/
 104              // partially taken from https://github.com/willdurand/JsonpCallbackValidator
 105              //      JsonpCallbackValidator is released under the MIT License. See https://github.com/willdurand/JsonpCallbackValidator/blob/v1.1.0/LICENSE for details.
 106              //      (c) William Durand <william.durand1@gmail.com>
 107              $pattern = '/^[$_\p{L}][$_\p{L}\p{Mn}\p{Mc}\p{Nd}\p{Pc}\x{200C}\x{200D}]*(?:\[(?:"(?:\\\.|[^"\\\])*"|\'(?:\\\.|[^\'\\\])*\'|\d+)\])*?$/u';
 108              $reserved = [
 109                  'break', 'do', 'instanceof', 'typeof', 'case', 'else', 'new', 'var', 'catch', 'finally', 'return', 'void', 'continue', 'for', 'switch', 'while',
 110                  'debugger', 'function', 'this', 'with', 'default', 'if', 'throw', 'delete', 'in', 'try', 'class', 'enum', 'extends', 'super',  'const', 'export',
 111                  'import', 'implements', 'let', 'private', 'public', 'yield', 'interface', 'package', 'protected', 'static', 'null', 'true', 'false',
 112              ];
 113              $parts = explode('.', $callback);
 114              foreach ($parts as $part) {
 115                  if (!preg_match($pattern, $part) || \in_array($part, $reserved, true)) {
 116                      throw new \InvalidArgumentException('The callback name is not valid.');
 117                  }
 118              }
 119          }
 120  
 121          $this->callback = $callback;
 122  
 123          return $this->update();
 124      }
 125  
 126      /**
 127       * Sets a raw string containing a JSON document to be sent.
 128       *
 129       * @param string $json
 130       *
 131       * @return $this
 132       *
 133       * @throws \InvalidArgumentException
 134       */
 135      public function setJson($json)
 136      {
 137          $this->data = $json;
 138  
 139          return $this->update();
 140      }
 141  
 142      /**
 143       * Sets the data to be sent as JSON.
 144       *
 145       * @param mixed $data
 146       *
 147       * @return $this
 148       *
 149       * @throws \InvalidArgumentException
 150       */
 151      public function setData($data = [])
 152      {
 153          if (\defined('HHVM_VERSION')) {
 154              // HHVM does not trigger any warnings and let exceptions
 155              // thrown from a JsonSerializable object pass through.
 156              // If only PHP did the same...
 157              $data = json_encode($data, $this->encodingOptions);
 158          } else {
 159              if (!interface_exists('JsonSerializable', false)) {
 160                  set_error_handler(function () { return false; });
 161                  try {
 162                      $data = @json_encode($data, $this->encodingOptions);
 163                  } finally {
 164                      restore_error_handler();
 165                  }
 166              } else {
 167                  try {
 168                      $data = json_encode($data, $this->encodingOptions);
 169                  } catch (\Exception $e) {
 170                      if ('Exception' === \get_class($e) && 0 === strpos($e->getMessage(), 'Failed calling ')) {
 171                          throw $e->getPrevious() ?: $e;
 172                      }
 173                      throw $e;
 174                  }
 175  
 176                  if (\PHP_VERSION_ID >= 70300 && (\JSON_THROW_ON_ERROR & $this->encodingOptions)) {
 177                      return $this->setJson($data);
 178                  }
 179              }
 180          }
 181  
 182          if (\JSON_ERROR_NONE !== json_last_error()) {
 183              throw new \InvalidArgumentException(json_last_error_msg());
 184          }
 185  
 186          return $this->setJson($data);
 187      }
 188  
 189      /**
 190       * Returns options used while encoding data to JSON.
 191       *
 192       * @return int
 193       */
 194      public function getEncodingOptions()
 195      {
 196          return $this->encodingOptions;
 197      }
 198  
 199      /**
 200       * Sets options used while encoding data to JSON.
 201       *
 202       * @param int $encodingOptions
 203       *
 204       * @return $this
 205       */
 206      public function setEncodingOptions($encodingOptions)
 207      {
 208          $this->encodingOptions = (int) $encodingOptions;
 209  
 210          return $this->setData(json_decode($this->data));
 211      }
 212  
 213      /**
 214       * Updates the content and headers according to the JSON data and callback.
 215       *
 216       * @return $this
 217       */
 218      protected function update()
 219      {
 220          if (null !== $this->callback) {
 221              // Not using application/javascript for compatibility reasons with older browsers.
 222              $this->headers->set('Content-Type', 'text/javascript');
 223  
 224              return $this->setContent(sprintf('/**/%s(%s);', $this->callback, $this->data));
 225          }
 226  
 227          // Only set the header when there is none or when it equals 'text/javascript' (from a previous update with callback)
 228          // in order to not overwrite a custom definition.
 229          if (!$this->headers->has('Content-Type') || 'text/javascript' === $this->headers->get('Content-Type')) {
 230              $this->headers->set('Content-Type', 'application/json');
 231          }
 232  
 233          return $this->setContent($this->data);
 234      }
 235  }


Generated: Mon Nov 25 19:05:08 2024 Cross-referenced by PHPXref 0.7.1