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.

108 lines
3.5KB

  1. <?php
  2. /**
  3. * @link http://www.yiiframework.com/
  4. * @copyright Copyright (c) 2008 Yii Software LLC
  5. * @license http://www.yiiframework.com/license/
  6. */
  7. namespace yii\web;
  8. use Yii;
  9. use yii\base\Component;
  10. use yii\helpers\Json;
  11. /**
  12. * JsonResponseFormatter formats the given data into a JSON or JSONP response content.
  13. *
  14. * It is used by [[Response]] to format response data.
  15. *
  16. * To configure properties like [[encodeOptions]] or [[prettyPrint]], you can configure the `response`
  17. * application component like the following:
  18. *
  19. * ```php
  20. * 'response' => [
  21. * // ...
  22. * 'formatters' => [
  23. * \yii\web\Response::FORMAT_JSON => [
  24. * 'class' => 'yii\web\JsonResponseFormatter',
  25. * 'prettyPrint' => YII_DEBUG, // use "pretty" output in debug mode
  26. * // ...
  27. * ],
  28. * ],
  29. * ],
  30. * ```
  31. *
  32. * @author Qiang Xue <qiang.xue@gmail.com>
  33. * @since 2.0
  34. */
  35. class JsonResponseFormatter extends Component implements ResponseFormatterInterface
  36. {
  37. /**
  38. * @var boolean whether to use JSONP response format. When this is true, the [[Response::data|response data]]
  39. * must be an array consisting of `data` and `callback` members. The latter should be a JavaScript
  40. * function name while the former will be passed to this function as a parameter.
  41. */
  42. public $useJsonp = false;
  43. /**
  44. * @var integer the encoding options passed to [[Json::encode()]]. For more details please refer to
  45. * <http://www.php.net/manual/en/function.json-encode.php>.
  46. * Default is `JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE`.
  47. * This property has no effect, when [[useJsonp]] is `true`.
  48. * @since 2.0.7
  49. */
  50. public $encodeOptions = 320;
  51. /**
  52. * @var bool whether to format the output in a readable "pretty" format. This can be useful for debugging purpose.
  53. * If this is true, `JSON_PRETTY_PRINT` will be added to [[encodeOptions]].
  54. * Defaults to `false`.
  55. * This property has no effect, when [[useJsonp]] is `true`.
  56. * @since 2.0.7
  57. */
  58. public $prettyPrint = false;
  59. /**
  60. * Formats the specified response.
  61. * @param Response $response the response to be formatted.
  62. */
  63. public function format($response)
  64. {
  65. if ($this->useJsonp) {
  66. $this->formatJsonp($response);
  67. } else {
  68. $this->formatJson($response);
  69. }
  70. }
  71. /**
  72. * Formats response data in JSON format.
  73. * @param Response $response
  74. */
  75. protected function formatJson($response)
  76. {
  77. $response->getHeaders()->set('Content-Type', 'application/json; charset=UTF-8');
  78. if ($response->data !== null) {
  79. $options = $this->encodeOptions;
  80. if ($this->prettyPrint) {
  81. $options |= JSON_PRETTY_PRINT;
  82. }
  83. $response->content = Json::encode($response->data, $options);
  84. }
  85. }
  86. /**
  87. * Formats response data in JSONP format.
  88. * @param Response $response
  89. */
  90. protected function formatJsonp($response)
  91. {
  92. $response->getHeaders()->set('Content-Type', 'application/javascript; charset=UTF-8');
  93. if (is_array($response->data) && isset($response->data['data'], $response->data['callback'])) {
  94. $response->content = sprintf('%s(%s);', $response->data['callback'], Json::htmlEncode($response->data['data']));
  95. } elseif ($response->data !== null) {
  96. $response->content = '';
  97. Yii::warning("The 'jsonp' response requires that the data be an array consisting of both 'data' and 'callback' elements.", __METHOD__);
  98. }
  99. }
  100. }