From 50ec08f9bd6c6ee19b787249434cd22956b215af Mon Sep 17 00:00:00 2001 From: mark_story Date: Thu, 17 Nov 2011 22:24:49 -0500 Subject: [PATCH] Adding support for array serialize values. Using an array for 'serialize' gives a set of view vars to convert into the view output. --- lib/Cake/Test/Case/View/JsonViewTest.php | 19 ++++++++++++++++++ lib/Cake/Test/Case/View/XmlViewTest.php | 22 +++++++++++++++++++++ lib/Cake/View/JsonView.php | 25 +++++++++++++++++++++--- lib/Cake/View/XmlView.php | 25 +++++++++++++++++++++--- 4 files changed, 85 insertions(+), 6 deletions(-) diff --git a/lib/Cake/Test/Case/View/JsonViewTest.php b/lib/Cake/Test/Case/View/JsonViewTest.php index a3b0c5ef3..fe4caedd0 100644 --- a/lib/Cake/Test/Case/View/JsonViewTest.php +++ b/lib/Cake/Test/Case/View/JsonViewTest.php @@ -47,6 +47,25 @@ class JsonViewTest extends CakeTestCase { $this->assertIdentical('application/json', $Response->type()); } +/** + * Test render with an array in serialize + * + * @return void + */ + public function testRenderWithoutViewMultiple() { + $Request = new CakeRequest(); + $Response = new CakeResponse(); + $Controller = new Controller($Request, $Response); + $data = array('no' => 'nope', 'user' => 'fake', 'list' => array('item1', 'item2')); + $Controller->set($data); + $Controller->set('serialize', array('no', 'user')); + $View = new JsonView($Controller); + $output = $View->render(false); + + $this->assertIdentical(json_encode(array('no' =>$data['no'], 'user' => $data['user'])), $output); + $this->assertIdentical('application/json', $Response->type()); + } + /** * testRenderWithView method * diff --git a/lib/Cake/Test/Case/View/XmlViewTest.php b/lib/Cake/Test/Case/View/XmlViewTest.php index 1d667fd78..9937e04ac 100644 --- a/lib/Cake/Test/Case/View/XmlViewTest.php +++ b/lib/Cake/Test/Case/View/XmlViewTest.php @@ -48,6 +48,28 @@ class XmlViewTest extends CakeTestCase { $this->assertIdentical('application/xml', $Response->type()); } +/** + * Test render with an array in serialize + * + * @return void + */ + public function testRenderWithoutViewMultiple() { + $Request = new CakeRequest(); + $Response = new CakeResponse(); + $Controller = new Controller($Request, $Response); + $data = array('no' => 'nope', 'user' => 'fake', 'list' => array('item1', 'item2')); + $Controller->set($data); + $Controller->set('serialize', array('no', 'user')); + $View = new XmlView($Controller); + $output = $View->render(false); + + $expected = array( + 'response' => array('no' =>$data['no'], 'user' => $data['user']) + ); + $this->assertIdentical(Xml::build($expected)->asXML(), $output); + $this->assertIdentical('application/xml', $Response->type()); + } + /** * testRenderWithView method * diff --git a/lib/Cake/View/JsonView.php b/lib/Cake/View/JsonView.php index 4d5e1a215..14e9326f9 100644 --- a/lib/Cake/View/JsonView.php +++ b/lib/Cake/View/JsonView.php @@ -28,8 +28,20 @@ App::uses('View', 'View'); * When the view is rendered, the `$posts` view variable will be serialized * into JSON. * - * If you don't use the `serialize` key, you will need a view + layout just like a - * normal view. + * You can also define `'serialize'` as an array. This will create a top level object containing + * all the named view variables: + * + * {{{ + * $this->set(compact('posts', 'users', 'stuff')); + * $this->set('serialize', array('posts', 'users')); + * }}} + * + * The above would generate a JSON object that looks like: + * + * `{"posts": [...], "users": [...]}` + * + * If you don't use the `serialize` key, you will need a view. You can use extended + * views to provide layout like functionality. * * @package Cake.View * @since CakePHP(tm) v 2.1.0 @@ -73,7 +85,14 @@ class JsonView extends View { public function render($view = null, $layout = null) { if (isset($this->viewVars['serialize'])) { $serialize = $this->viewVars['serialize']; - $data = isset($this->viewVars[$serialize]) ? $this->viewVars[$serialize] : null; + if (is_array($serialize)) { + $data = array(); + foreach ($serialize as $key) { + $data[$key] = $this->viewVars[$key]; + } + } else { + $data = isset($this->viewVars[$serialize]) ? $this->viewVars[$serialize] : null; + } return $this->output = json_encode($data); } if ($view !== false && $viewFileName = $this->_getViewFileName($view)) { diff --git a/lib/Cake/View/XmlView.php b/lib/Cake/View/XmlView.php index 8770267da..25f01184e 100644 --- a/lib/Cake/View/XmlView.php +++ b/lib/Cake/View/XmlView.php @@ -31,8 +31,20 @@ App::uses('Xml', 'Utility'); * * **Note** The view variable you specify must be compatible with Xml::fromArray(). * - * If you don't use the `serialize` key, you will need a view + layout just like a - * normal view. + * You can also define `'serialize'` as an array. This will create an additional + * top level element named `` containing all the named view variables: + * + * {{{ + * $this->set(compact('posts', 'users', 'stuff')); + * $this->set('serialize', array('posts', 'users')); + * }}} + * + * The above would generate a XML object that looks like: + * + * `......` + * + * If you don't use the `serialize` key, you will need a view. You can use extended + * views to provide layout like functionality. * * @package Cake.View * @since CakePHP(tm) v 2.1.0 @@ -74,7 +86,14 @@ class XmlView extends View { public function render($view = null, $layout = null) { if (isset($this->viewVars['serialize'])) { $serialize = $this->viewVars['serialize']; - $data = isset($this->viewVars[$serialize]) ? $this->viewVars[$serialize] : null; + if (is_array($serialize)) { + $data = array('response' => array()); + foreach ($serialize as $key) { + $data['response'][$key] = $this->viewVars[$key]; + } + } else { + $data = isset($this->viewVars[$serialize]) ? $this->viewVars[$serialize] : null; + } return $this->output = Xml::fromArray($data)->asXML(); } if ($view !== false && $viewFileName = $this->_getViewFileName($view)) {