diff --git a/src/Symfony/Component/HttpFoundation/JsonResponse.php b/src/Symfony/Component/HttpFoundation/JsonResponse.php index ef668fdf7b..2f756e8c59 100644 --- a/src/Symfony/Component/HttpFoundation/JsonResponse.php +++ b/src/Symfony/Component/HttpFoundation/JsonResponse.php @@ -18,6 +18,9 @@ namespace Symfony\Component\HttpFoundation; */ class JsonResponse extends Response { + protected $data; + protected $callback; + /** * Constructor. * @@ -28,24 +31,10 @@ class JsonResponse extends Response */ public function __construct($data = array(), $status = 200, $headers = array(), $jsonp = '') { - // root should be JSON object, not array - if (is_array($data) && 0 === count($data)) { - $data = new \ArrayObject(); - } + parent::__construct('', $status, $headers); - $content = json_encode($data); - $contentType = 'application/json'; - if (!empty($jsonp)) { - $content = sprintf('%s(%s);', $jsonp, $content); - // Not using application/javascript for compatibility reasons with older browsers. - $contentType = 'text/javascript'; - } - - parent::__construct( - $content, - $status, - array_merge(array('Content-Type' => $contentType), $headers) - ); + $this->setData($data); + $this->setCallback($jsonp); } /** @@ -57,4 +46,56 @@ class JsonResponse extends Response { return new static($data, $status, $headers, $jsonp = ''); } + + /** + * Sets the JSONP callback. + * + * @param string $callback + * + * @return JsonResponse + */ + public function setCallback($callback) + { + $this->callback = $callback; + + return $this->update(); + } + + /** + * Sets the data to be sent as json. + * + * @param mixed $data + * + * @return JsonResponse + */ + public function setData($data = array()) + { + // root should be JSON object, not array + if (is_array($data) && 0 === count($data)) { + $data = new \ArrayObject(); + } + + $this->data = json_encode($data); + + return $this->update(); + } + + /** + * Updates the content and headers according to the json data and callback. + * + * @return JsonResponse + */ + protected function update() + { + $content = $this->data; + $this->headers->set('Content-Type', 'application/json', false); + + if (!empty($this->callback)) { + $content = sprintf('%s(%s);', $this->callback, $content); + // Not using application/javascript for compatibility reasons with older browsers. + $this->headers->set('Content-Type', 'text/javascript', true); + } + + return $this->setContent($content); + } } diff --git a/tests/Symfony/Tests/Component/HttpFoundation/JsonResponseTest.php b/tests/Symfony/Tests/Component/HttpFoundation/JsonResponseTest.php index 51c33e91ea..ca7687d1af 100644 --- a/tests/Symfony/Tests/Component/HttpFoundation/JsonResponseTest.php +++ b/tests/Symfony/Tests/Component/HttpFoundation/JsonResponseTest.php @@ -15,6 +15,8 @@ use Symfony\Component\HttpFoundation\JsonResponse; /** * @covers Symfony\Component\HttpFoundation\JsonResponse::__construct + * @covers Symfony\Component\HttpFoundation\JsonResponse::setData + * @covers Symfony\Component\HttpFoundation\JsonResponse::setCallback */ class JsonResponseTest extends \PHPUnit_Framework_TestCase { @@ -94,4 +96,12 @@ class JsonResponseTest extends \PHPUnit_Framework_TestCase $this->assertEquals('callback({"foo":"bar"});', $response->getContent()); $this->assertEquals('text/javascript', $response->headers->get('Content-Type')); } + + public function testSetCallback() + { + $response = JsonResponse::create(array('foo' => 'bar'))->setCallback('callback'); + + $this->assertEquals('callback({"foo":"bar"});', $response->getContent()); + $this->assertEquals('text/javascript', $response->headers->get('Content-Type')); + } }