Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 11bc151

Browse filesBrowse files
committed
Add a Controller function to make it easy to return json
If the serializer component is enabled it is used to generate the json data, if not the standard `json_encode` function is used
1 parent 83b53f4 commit 11bc151
Copy full SHA for 11bc151

File tree

4 files changed

+117
-21
lines changed
Filter options

4 files changed

+117
-21
lines changed

‎src/Symfony/Bundle/FrameworkBundle/Controller/Controller.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Controller/Controller.php
+24Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@
1111

1212
namespace Symfony\Bundle\FrameworkBundle\Controller;
1313

14+
use Symfony\Bundle\FrameworkBundle\Response\JsonSerializedResponse;
1415
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
1516
use Symfony\Component\DependencyInjection\ContainerAwareTrait;
17+
use Symfony\Component\HttpFoundation\JsonResponse;
1618
use Symfony\Component\HttpFoundation\Response;
1719
use Symfony\Component\HttpFoundation\RedirectResponse;
1820
use Symfony\Component\HttpFoundation\StreamedResponse;
@@ -97,6 +99,28 @@ protected function redirectToRoute($route, array $parameters = array(), $status
9799
return $this->redirect($this->generateUrl($route, $parameters), $status);
98100
}
99101

102+
/**
103+
* Returns a JsonResponse that uses the serializer component if enabled, or json_encode.
104+
*
105+
* @param mixed $data The response data
106+
* @param int $status The status code to use for the Response
107+
* @param array $headers Array of extra headers to add
108+
* @param array $context Context to pass to serializer when using serializer component
109+
*
110+
* @return JsonResponse
111+
*/
112+
protected function json($data, $status = 200, $headers = array(), $context = array())
113+
{
114+
if ($this->container->has('serializer')) {
115+
$json = $this->container->get('serializer')->serialize($data, 'json', array_merge($context, array(
116+
'json_encode_options' => JsonResponse::DEFAULT_ENCODING_OPTIONS
117+
)));
118+
return new JsonResponse($json, $status, $headers, true);
119+
}
120+
121+
return new JsonResponse($data, $status, $headers);
122+
}
123+
100124
/**
101125
* Adds a flash message to the current session for type.
102126
*

‎src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerTest.php
+54Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,18 @@
1111

1212
namespace Symfony\Bundle\FrameworkBundle\Tests\Controller;
1313

14+
use Symfony\Bundle\FrameworkBundle\Response\JsonSerializedResponse;
1415
use Symfony\Bundle\FrameworkBundle\Tests\TestCase;
1516
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
1617
use Symfony\Component\DependencyInjection\ContainerInterface;
18+
use Symfony\Component\HttpFoundation\JsonResponse;
1719
use Symfony\Component\HttpFoundation\Request;
1820
use Symfony\Component\HttpFoundation\RequestStack;
1921
use Symfony\Component\HttpFoundation\Response;
2022
use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken;
2123
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
2224
use Symfony\Component\Security\Core\User\User;
25+
use Symfony\Component\Serializer\SerializerInterface;
2326

2427
class ControllerTest extends TestCase
2528
{
@@ -124,6 +127,52 @@ private function getContainerWithTokenStorage($token = null)
124127

125128
return $container;
126129
}
130+
131+
public function testJson()
132+
{
133+
$container = $this->getMock(ContainerInterface::class);
134+
$container
135+
->expects($this->once())
136+
->method('has')
137+
->with('serializer')
138+
->will($this->returnValue(false));
139+
140+
$controller = new TestController();
141+
$controller->setContainer($container);
142+
143+
$response = $controller->json(array());
144+
$this->assertInstanceOf(JsonResponse::class, $response);
145+
$this->assertEquals('[]', $response->getContent());
146+
}
147+
148+
public function testJsonWithSerializer()
149+
{
150+
$container = $this->getMock(ContainerInterface::class);
151+
$container
152+
->expects($this->once())
153+
->method('has')
154+
->with('serializer')
155+
->will($this->returnValue(true));
156+
157+
$serializer = $this->getMock(SerializerInterface::class);
158+
$serializer
159+
->expects($this->once())
160+
->method('serialize')
161+
->will($this->returnValue('[]'));
162+
163+
$container
164+
->expects($this->once())
165+
->method('get')
166+
->with('serializer')
167+
->will($this->returnValue($serializer));
168+
169+
$controller = new TestController();
170+
$controller->setContainer($container);
171+
172+
$response = $controller->json(array());
173+
$this->assertInstanceOf(JsonResponse::class, $response);
174+
$this->assertEquals('[]', $response->getContent());
175+
}
127176
}
128177

129178
class TestController extends Controller
@@ -137,4 +186,9 @@ public function getUser()
137186
{
138187
return parent::getUser();
139188
}
189+
190+
public function json($data, $status = 200, $headers = array(), $context = array())
191+
{
192+
return parent::json($data, $status, $headers, $context);
193+
}
140194
}

‎src/Symfony/Component/HttpFoundation/JsonResponse.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/HttpFoundation/JsonResponse.php
+27-21Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -29,24 +29,27 @@ class JsonResponse extends Response
2929

3030
// Encode <, >, ', &, and " for RFC4627-compliant JSON, which may also be embedded into HTML.
3131
// 15 === JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT
32-
protected $encodingOptions = 15;
32+
const DEFAULT_ENCODING_OPTIONS = 15;
33+
34+
protected $encodingOptions = self::DEFAULT_ENCODING_OPTIONS;
3335

3436
/**
3537
* Constructor.
3638
*
3739
* @param mixed $data The response data
3840
* @param int $status The response status code
3941
* @param array $headers An array of response headers
42+
* @param boolean $preEncoded If the data is already a JSON string
4043
*/
41-
public function __construct($data = null, $status = 200, $headers = array())
44+
public function __construct($data = null, $status = 200, $headers = array(), $preEncoded = false)
4245
{
4346
parent::__construct('', $status, $headers);
4447

4548
if (null === $data) {
4649
$data = new \ArrayObject();
4750
}
4851

49-
$this->setData($data);
52+
$this->setData($data, $preEncoded);
5053
}
5154

5255
/**
@@ -88,34 +91,37 @@ public function setCallback($callback = null)
8891
* Sets the data to be sent as JSON.
8992
*
9093
* @param mixed $data
94+
* @param boolean $preEncoded If the data is already a JSON string
9195
*
9296
* @return JsonResponse
9397
*
9498
* @throws \InvalidArgumentException
9599
*/
96-
public function setData($data = array())
100+
public function setData($data = array(), $preEncoded = false)
97101
{
98-
if (defined('HHVM_VERSION')) {
99-
// HHVM does not trigger any warnings and let exceptions
100-
// thrown from a JsonSerializable object pass through.
101-
// If only PHP did the same...
102-
$data = json_encode($data, $this->encodingOptions);
103-
} else {
104-
try {
105-
// PHP 5.4 and up wrap exceptions thrown by JsonSerializable
106-
// objects in a new exception that needs to be removed.
107-
// Fortunately, PHP 5.5 and up do not trigger any warning anymore.
102+
if (!$preEncoded) {
103+
if (defined('HHVM_VERSION')) {
104+
// HHVM does not trigger any warnings and let exceptions
105+
// thrown from a JsonSerializable object pass through.
106+
// If only PHP did the same...
108107
$data = json_encode($data, $this->encodingOptions);
109-
} catch (\Exception $e) {
110-
if ('Exception' === get_class($e) && 0 === strpos($e->getMessage(), 'Failed calling ')) {
111-
throw $e->getPrevious() ?: $e;
108+
} else {
109+
try {
110+
// PHP 5.4 and up wrap exceptions thrown by JsonSerializable
111+
// objects in a new exception that needs to be removed.
112+
// Fortunately, PHP 5.5 and up do not trigger any warning anymore.
113+
$data = json_encode($data, $this->encodingOptions);
114+
} catch (\Exception $e) {
115+
if ('Exception' === get_class($e) && 0 === strpos($e->getMessage(), 'Failed calling ')) {
116+
throw $e->getPrevious() ?: $e;
117+
}
118+
throw $e;
112119
}
113-
throw $e;
114120
}
115-
}
116121

117-
if (JSON_ERROR_NONE !== json_last_error()) {
118-
throw new \InvalidArgumentException(json_last_error_msg());
122+
if (JSON_ERROR_NONE !== json_last_error()) {
123+
throw new \InvalidArgumentException(json_last_error_msg());
124+
}
119125
}
120126

121127
$this->data = $data;

‎src/Symfony/Component/HttpFoundation/Tests/JsonResponseTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/HttpFoundation/Tests/JsonResponseTest.php
+12Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,18 @@ public function testConstructorWithCustomContentType()
7575
$this->assertSame('application/vnd.acme.blog-v1+json', $response->headers->get('Content-Type'));
7676
}
7777

78+
public function testConstructorWithPreEncoded()
79+
{
80+
$response = new JsonResponse('1', 200, array(), true);
81+
$this->assertEquals('1', $response->getContent());
82+
83+
$response = new JsonResponse('[1]', 200, array(), true);
84+
$this->assertEquals('[1]', $response->getContent());
85+
86+
$response = new JsonResponse('true', 200, array(), true);
87+
$this->assertEquals('true', $response->getContent());
88+
}
89+
7890
public function testCreate()
7991
{
8092
$response = JsonResponse::create(array('foo' => 'bar'), 204);

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.