Browse Source

Merge pull request #4005 from ADmad/3.0-view-accessor

3.0 - WIP - Added accessor method getView() to ViewVarsTrait.
ADmad 11 years ago
parent
commit
49bd217b5d

+ 6 - 10
src/Controller/Controller.php

@@ -179,7 +179,7 @@ class Controller implements EventListener {
  *
  * @var string
  */
-	public $viewClass = 'Cake\View\View';
+	public $viewClass = null;
 
 /**
  * The path to this controllers view templates.
@@ -384,12 +384,6 @@ class Controller implements EventListener {
 		if (isset($request->params['pass'])) {
 			$this->passedArgs = $request->params['pass'];
 		}
-		if (!empty($request->params['return']) && $request->params['return'] == 1) {
-			$this->autoRender = false;
-		}
-		if (!empty($request->params['bare'])) {
-			$this->autoLayout = false;
-		}
 	}
 
 /**
@@ -577,6 +571,10 @@ class Controller implements EventListener {
  * @link http://book.cakephp.org/2.0/en/controllers.html#Controller::render
  */
 	public function render($view = null, $layout = null) {
+		if (!empty($this->request->params['bare'])) {
+			$this->getView()->autoLayout = false;
+		}
+
 		$event = $this->dispatchEvent('Controller.beforeRender');
 		if ($event->result instanceof Response) {
 			$this->autoRender = false;
@@ -587,10 +585,8 @@ class Controller implements EventListener {
 			return $this->response;
 		}
 
-		$this->View = $this->createView();
-
 		$this->autoRender = false;
-		$this->response->body($this->View->render($view, $layout));
+		$this->response->body($this->getView()->render($view, $layout));
 		return $this->response;
 	}
 

+ 3 - 2
src/View/Cell.php

@@ -78,7 +78,7 @@ abstract class Cell {
  *
  * @var string
  */
-	public $viewClass = 'Cake\View\View';
+	public $viewClass = null;
 
 /**
  * The theme name that will be used to render.
@@ -153,7 +153,8 @@ abstract class Cell {
 			$template = $this->template;
 		}
 
-		$this->View = $this->createView();
+		$this->View = null;
+		$this->getView();
 
 		$this->View->layout = false;
 		$className = explode('\\', get_class($this));

+ 14 - 0
src/View/View.php

@@ -321,10 +321,24 @@ class View {
 			$this->response = new Response();
 		}
 		$this->Blocks = new ViewBlock();
+		$this->initialize();
 		$this->loadHelpers();
 	}
 
 /**
+ * Initialization hook method.
+ *
+ * Properties like $helpers etc. cannot be initialized statically in your custom
+ * view class as they are overwritten by values from controller in constructor.
+ * So this method allows you to manipulate them as required after view instance
+ * is constructed.
+ *
+ * @return void
+ */
+	public function initialize() {
+	}
+
+/**
  * Renders a piece of PHP with provided parameters and returns HTML, XML, or any other string.
  *
  * This realizes the concept of Elements, (or "partial layouts") and the $params array is used to send

+ 35 - 1
src/View/ViewVarsTrait.php

@@ -32,10 +32,44 @@ trait ViewVarsTrait {
 	public $viewVars = [];
 
 /**
+ * Get view instance
+ *
+ * @param string $viewClass View class name or null to use $viewClass
+ * @return \Cake\View\View
+ */
+	public function getView($viewClass = null) {
+		if ($viewClass === null && $this->View) {
+			return $this->View;
+		}
+
+		if ($viewClass === null) {
+			$viewClass = $this->viewClass;
+		}
+		if ($viewClass === null) {
+			$viewClass = App::className('App', 'View', 'View');
+			if ($viewClass === false) {
+				$viewClass = 'Cake\View\View';
+			}
+		}
+		if ($viewClass === 'View') {
+			$viewClass = 'Cake\View\View';
+		}
+
+		$this->viewClass = $viewClass;
+		$className = App::className($this->viewClass, 'View', 'View');
+
+		if ($this->View && $this->View instanceof $className) {
+			return $this->View;
+		}
+
+		return $this->View = $this->createView();
+	}
+
+/**
  * Constructs the view class instance based on object properties.
  *
  * @param string $viewClass Optional namespaced class name of the View class to instantiate.
- * @return View
+ * @return Cake\View\View
  */
 	public function createView($viewClass = null) {
 		if ($viewClass === null) {

+ 2 - 0
tests/TestCase/Controller/ControllerTest.php

@@ -362,9 +362,11 @@ class ControllerTest extends TestCase {
 		$this->assertRegExp('/posts index/', (string)$result);
 
 		$Controller->view = 'index';
+		$Controller->getView()->hasRendered = false;
 		$result = $Controller->render();
 		$this->assertRegExp('/posts index/', (string)$result);
 
+		$Controller->getView()->hasRendered = false;
 		$result = $Controller->render('/Element/test_element');
 		$this->assertRegExp('/this is the test element/', (string)$result);
 		$Controller->view = null;

+ 20 - 3
tests/TestCase/View/ViewTest.php

@@ -26,6 +26,7 @@ use Cake\Routing\Router;
 use Cake\TestSuite\TestCase;
 use Cake\View\Helper;
 use Cake\View\View;
+use TestApp\View\AppView;
 
 /**
  * ViewPostsController class
@@ -98,7 +99,11 @@ class ThemePostsController extends Controller {
  * TestView class
  *
  */
-class TestView extends View {
+class TestView extends AppView {
+
+	public function initialize() {
+		$this->loadHelper('Html', ['mykey' => 'myval']);
+	}
 
 /**
  * getViewFileName method
@@ -972,6 +977,17 @@ class ViewTest extends TestCase {
 	}
 
 /**
+ * Test manipulating class properties in initialize()
+ *
+ * @return void
+ */
+	public function testInitialize() {
+		$View = new TestView();
+		$config = $View->Html->config();
+		$this->assertEquals('myval', $config['mykey']);
+	}
+
+/**
  * Test the correct triggering of helper callbacks
  *
  * @return void
@@ -1100,14 +1116,15 @@ class ViewTest extends TestCase {
  * @return void
  */
 	public function testRenderLoadHelper() {
-		$this->PostsController->helpers = array('Session', 'Html', 'Form', 'Number');
+		$this->PostsController->helpers = array('Session', 'Form', 'Number');
 		$View = $this->PostsController->createView('Cake\Test\TestCase\View\TestView');
 
 		$result = $View->render('index', false);
 		$this->assertEquals('posts index', $result);
 
 		$attached = $View->helpers()->loaded();
-		$this->assertEquals(array('Session', 'Html', 'Form', 'Number'), $attached);
+		// HtmlHelper is loaded in TestView::initialize()
+		$this->assertEquals(array('Html', 'Session', 'Form', 'Number'), $attached);
 
 		$this->PostsController->helpers = array('Html', 'Form', 'Number', 'TestPlugin.PluggedHelper');
 		$View = $this->PostsController->createView('Cake\Test\TestCase\View\TestView');

+ 1 - 1
tests/TestCase/View/ViewVarsTraitTest.php

@@ -133,7 +133,7 @@ class ViewVarsTraitTest extends TestCase {
 		$result = $this->subject->viewOptions();
 
 		$this->assertTrue(is_array($result));
-		$this->assertTrue(empty($resulit));
+		$this->assertTrue(empty($result));
 	}
 
 }

+ 1 - 0
tests/test_app/Plugin/TestPlugin/src/Controller/TestsController.php

@@ -31,6 +31,7 @@ class TestsController extends TestPluginAppController {
 
 	public function some_method() {
 		$this->response->body(25);
+		return $this->response;
 	}
 
 }

+ 2 - 1
tests/test_app/TestApp/Controller/OrangeSessionTestController.php

@@ -38,9 +38,10 @@ class OrangeSessionTestController extends Controller {
 /**
  * session_id method
  *
- * @return void
+ * @return \Cake\Network\Session
  */
 	public function session_id() {
 		$this->response->body($this->Session->id());
+		return $this->response;
 	}
 }

+ 10 - 5
tests/test_app/TestApp/Controller/RequestActionController.php

@@ -77,30 +77,33 @@ class RequestActionController extends AppController {
  */
 	public function paginate_request_action() {
 		$data = $this->paginate();
+		$this->autoRender = false;
 	}
 
 /**
  * post pass, testing post passing
  *
- * @return array
+ * @return \Cake\Network\Reponse
  */
 	public function post_pass() {
 		$this->response->body(json_encode($this->request->data));
+		return $this->response;
 	}
 
 /**
  * query pass, testing query passing
  *
- * @return array
+ * @return \Cake\Network\Reponse
  */
 	public function query_pass() {
 		$this->response->body(json_encode($this->request->query));
+		return $this->response;
 	}
 
 /**
  * test param passing and parsing.
  *
- * @return void
+ * @return \Cake\Network\Reponse
  */
 	public function params_pass() {
 		$this->response->body(json_encode([
@@ -109,12 +112,13 @@ class RequestActionController extends AppController {
 			'url' => $this->request->url,
 			'contentType' => $this->request->env('CONTENT_TYPE'),
 		]));
+		return $this->response;
 	}
 
 /**
  * param check method.
  *
- * @return void
+ * @return \Cake\Network\Reponse
  */
 	public function param_check() {
 		$this->autoRender = false;
@@ -123,12 +127,13 @@ class RequestActionController extends AppController {
 			$content = 'return found';
 		}
 		$this->response->body($content);
+		return $this->response;
 	}
 
 /**
  * Tests session transmission
  *
- * @return void
+ * @return \Cake\Network\Reponse
  */
 	public function session_test() {
 		$this->response->body($this->request->session()->read('foo'));

+ 2 - 1
tests/test_app/TestApp/Controller/SessionTestController.php

@@ -38,9 +38,10 @@ class SessionTestController extends Controller {
 /**
  * session_id method
  *
- * @return void
+ * @return \Cake\Network\Response
  */
 	public function session_id() {
 		$this->response->body($this->Session->id());
+		return $this->response;
 	}
 }

+ 1 - 0
tests/test_app/TestApp/Controller/TestsAppsController.php

@@ -37,6 +37,7 @@ class TestsAppsController extends AppController {
 
 	public function some_method() {
 		$this->response->body(5);
+		return $this->response;
 	}
 
 	public function set_action() {

+ 23 - 0
tests/test_app/TestApp/View/AppView.php

@@ -0,0 +1,23 @@
+<?php
+/**
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link          http://cakephp.org CakePHP(tm) Project
+ * @since         3.0.0
+ * @license       http://www.opensource.org/licenses/mit-license.php MIT License
+ */
+namespace TestApp\View;
+
+use Cake\View\View;
+
+/**
+ * App View class
+ *
+ */
+class AppView extends View {
+}