euromark 12 年 前
コミット
d9f317e0d4
3 ファイル変更179 行追加0 行削除
  1. 88 0
      Test/Case/View/AjaxViewTest.php
  2. 1 0
      Test/test_app/View/Items/ajax/index.ctp
  3. 90 0
      View/AjaxView.php

+ 88 - 0
Test/Case/View/AjaxViewTest.php

@@ -0,0 +1,88 @@
+<?php
+/**
+ * PHP 5
+ *
+ * Licensed under The MIT License
+ * For full copyright and license information, please see the LICENSE.txt
+ * Redistributions of files must retain the above copyright notice
+ *
+ * @author        Mark Scherer
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
+ */
+
+App::uses('Controller', 'Controller');
+App::uses('CakeRequest', 'Network');
+App::uses('CakeResponse', 'Network');
+App::uses('AjaxView', 'Tools.View');
+
+/**
+ * AjaxViewTest
+ *
+ */
+class AjaxViewTest extends CakeTestCase {
+
+	public $Ajax;
+
+	/**
+	 * AjaxViewTest::setUp()
+	 *
+	 * @return void
+	 */
+	public function setUp() {
+		parent::setUp();
+
+		$this->Ajax = new AjaxView();
+
+		App::build(array(
+			'View' => array(CakePlugin::path('Tools') . 'Test' . DS . 'test_app' . DS . 'View' . DS)
+		), App::RESET);
+	}
+
+	/**
+	 * AjaxViewTest::testSerialize()
+	 *
+	 * @return void
+	 */
+	public function testSerialize() {
+		$Request = new CakeRequest();
+		$Response = new CakeResponse();
+		$Controller = new Controller($Request, $Response);
+		$items = array(
+			array('title' => 'Title One', 'link' => 'http://example.org/one', 'author' => 'one@example.org', 'description' => 'Content one'),
+			array('title' => 'Title Two', 'link' => 'http://example.org/two', 'author' => 'two@example.org', 'description' => 'Content two'),
+		);
+		$Controller->set(array('items' => $items, '_serialize' => array('items')));
+		$View = new AjaxView($Controller);
+		$result = $View->render(false);
+
+		$this->assertSame('application/json', $Response->type());
+		$expected = array('error' => null, 'content' => null, 'items' => $items);
+		$expected = json_encode($expected);
+		$this->assertTextEquals($expected, $result);
+	}
+
+	/**
+	 * AjaxViewTest::testSerialize()
+	 *
+	 * @return void
+	 */
+	public function testRenderWithSerialize() {
+		$Request = new CakeRequest();
+		$Response = new CakeResponse();
+		$Controller = new Controller($Request, $Response);
+		$items = array(
+			array('title' => 'Title One', 'link' => 'http://example.org/one', 'author' => 'one@example.org', 'description' => 'Content one'),
+			array('title' => 'Title Two', 'link' => 'http://example.org/two', 'author' => 'two@example.org', 'description' => 'Content two'),
+		);
+		$Controller->set(array('items' => $items, '_serialize' => 'items'));
+		$View = new AjaxView($Controller);
+		$View->viewPath = 'Items';
+		$result = $View->render('index');
+
+		$this->assertSame('application/json', $Response->type());
+		$expected = array('error' => null, 'content' => 'My Index Test ctp', 'items' => $items);
+		$expected = json_encode($expected);
+		$this->assertTextEquals($expected, $result);
+	}
+
+}

+ 1 - 0
Test/test_app/View/Items/ajax/index.ctp

@@ -0,0 +1 @@
+My Index Test ctp

+ 90 - 0
View/AjaxView.php

@@ -0,0 +1,90 @@
+<?php
+App::uses('View', 'View');
+
+/**
+ * A view to handle AJAX requests.
+ *
+ * Expects all incoming requests to be of extension "json" and that the expected result
+ * will also be in JSON format.
+ *
+ * @author Mark Scherer
+ * @license MIT
+ */
+class AjaxView extends View {
+
+	/**
+	 * The subdirectory. AJAX views are always in ajax.
+	 *
+	 * @var string
+	 */
+	public $subDir = 'ajax';
+
+	/**
+	 * Name of layout to use with this View.
+	 *
+	 * @var string
+	 */
+	public $layout = false;
+
+	/**
+	 * Constructor
+	 *
+	 * @param Controller $controller
+	 */
+	public function __construct(Controller $controller = null) {
+		parent::__construct($controller);
+		// Unfortunately, layout gets overwritten via passed Controller attribute
+		if ($this->layout === 'default' || $this->layout === 'ajax') {
+			$this->layout = false;
+		}
+
+		if (isset($controller->response) && $controller->response instanceof CakeResponse) {
+			$controller->response->type('json');
+		}
+	}
+
+	/**
+	 * Renders a JSON view.
+	 *
+	 * @param string $view The view being rendered.
+	 * @param string $layout The layout being rendered.
+	 * @return string The rendered view.
+	 */
+	public function render($view = null, $layout = null) {
+		$response = array(
+			'error' => null,
+			'content' => null,
+		);
+
+		if ($view !== false && $this->_getViewFileName($view)) {
+			$response['content'] = parent::render($view, $layout);
+		}
+		if (isset($this->viewVars['_serialize'])) {
+			$response = $this->_serialize($response, $this->viewVars['_serialize']);
+		}
+		return json_encode($response);
+	}
+
+	/**
+	 * Serialize view vars
+	 *
+	 * @param array $serialize The viewVars that need to be serialized
+	 * @return string The serialized data
+	 */
+	protected function _serialize($response, $serialize) {
+		if (is_array($serialize)) {
+			foreach ($serialize as $alias => $key) {
+				if (is_numeric($alias)) {
+					$alias = $key;
+				}
+				if (array_key_exists($key, $this->viewVars)) {
+					$response[$alias] = $this->viewVars[$key];
+				}
+			}
+		} else {
+			$response[$serialize] = isset($this->viewVars[$serialize]) ? $this->viewVars[$serialize] : null;
+		}
+		return $response;
+	}
+
+}