Browse Source

Merge pull request #3679 from markstory/issue-3665

3.0 - Fix plugin controllers not getting the correct modelClass.
José Lorenzo Rodríguez 12 years ago
parent
commit
3d403073a4

+ 21 - 6
src/Controller/Controller.php

@@ -89,6 +89,8 @@ class Controller implements EventListener {
 /**
  * The name of this controller. Controller names are plural, named after the model they manipulate.
  *
+ * Set automatically using conventions in Controller::__construct().
+ *
  * @var string
  * @link http://book.cakephp.org/2.0/en/controllers.html#controller-attributes
  */
@@ -216,8 +218,21 @@ class Controller implements EventListener {
 	public $methods = array();
 
 /**
+ * The path to this controllers view templates.
+ * Example `Articles`
+ *
+ * Set automatically using conventions in Controller::__construct().
+ *
+ * @var string
+ */
+	public $viewPath;
+
+/**
  * Constructor.
  *
+ * Sets a number of properties based on conventions if they are empty. To override the
+ * conventions CakePHP uses you can define properties in your class declaration.
+ *
  * @param \Cake\Network\Request $request Request object for this controller. Can be null for testing,
  *  but expect that features that use the request parameters will not work.
  * @param \Cake\Network\Response $response Response object for this controller.
@@ -240,13 +255,9 @@ class Controller implements EventListener {
 			$this->viewPath = $viewPath;
 		}
 
-		$this->_setModelClass($this->name);
-		$this->modelFactory('Table', ['Cake\ORM\TableRegistry', 'get']);
-
 		$childMethods = get_class_methods($this);
-		$parentMethods = get_class_methods('Cake\Controller\Controller');
-
-		$this->methods = array_diff($childMethods, $parentMethods);
+		$baseMethods = get_class_methods('Cake\Controller\Controller');
+		$this->methods = array_diff($childMethods, $baseMethods);
 
 		if ($request instanceof Request) {
 			$this->setRequest($request);
@@ -254,6 +265,10 @@ class Controller implements EventListener {
 		if ($response instanceof Response) {
 			$this->response = $response;
 		}
+
+		$this->modelFactory('Table', ['Cake\ORM\TableRegistry', 'get']);
+		$modelClass = ($this->plugin ? $this->plugin . '.' : '') . $this->name;
+		$this->_setModelClass($modelClass);
 	}
 
 /**

+ 3 - 1
src/Model/ModelAwareTrait.php

@@ -29,7 +29,9 @@ trait ModelAwareTrait {
  * This object's primary model class name. Should be a plural form.
  * CakePHP will not inflect the name.
  *
- * Example: For a object named 'Comments', the modelClass would be 'Comments'
+ * Example: For a object named 'Comments', the modelClass would be 'Comments'.
+ * Plugin classes should use `Plugin.Comments` style names to correctly load
+ * models from the correct plugin.
  *
  * @var string
  */

+ 22 - 6
tests/TestCase/Controller/ControllerTest.php

@@ -219,6 +219,7 @@ class ControllerTest extends TestCase {
 		parent::setUp();
 
 		App::objects('Plugin', null, false);
+		Configure::write('App.namespace', 'TestApp');
 		Router::reload();
 	}
 
@@ -238,7 +239,6 @@ class ControllerTest extends TestCase {
  * @return void
  */
 	public function testTableAutoload() {
-		Configure::write('App.namespace', 'TestApp');
 		$request = new Request('controller_posts/index');
 		$response = $this->getMock('Cake\Network\Response');
 		$Controller = new Controller($request, $response);
@@ -256,7 +256,6 @@ class ControllerTest extends TestCase {
  * @return void
  */
 	public function testLoadModel() {
-		Configure::write('App.namespace', 'TestApp');
 		$request = new Request('controller_posts/index');
 		$response = $this->getMock('Cake\Network\Response');
 		$Controller = new Controller($request, $response);
@@ -277,7 +276,6 @@ class ControllerTest extends TestCase {
  * @return void
  */
 	public function testLoadModelInPlugins() {
-		Configure::write('App.namespace', 'TestApp');
 		Plugin::load('TestPlugin');
 
 		$Controller = new TestPluginController();
@@ -294,12 +292,32 @@ class ControllerTest extends TestCase {
 	}
 
 /**
+ * Test that the constructor sets modelClass properly.
+ *
+ * @return void
+ */
+	public function testConstructSetModelClass() {
+		Plugin::load('TestPlugin');
+
+		$request = new Request();
+		$response = new Response();
+		$controller = new \TestApp\Controller\PostsController($request, $response);
+		$this->assertEquals('Posts', $controller->modelClass);
+
+		$controller = new \TestApp\Controller\Admin\PostsController($request, $response);
+		$this->assertEquals('Posts', $controller->modelClass);
+
+		$request->params['plugin'] = 'TestPlugin';
+		$controller = new \TestPlugin\Controller\Admin\CommentsController($request, $response);
+		$this->assertEquals('TestPlugin.Comments', $controller->modelClass);
+	}
+
+/**
  * testConstructClassesWithComponents method
  *
  * @return void
  */
 	public function testConstructClassesWithComponents() {
-		Configure::write('App.namespace', 'TestApp');
 		Plugin::load('TestPlugin');
 
 		$Controller = new TestPluginController(new Request(), new Response());
@@ -315,7 +333,6 @@ class ControllerTest extends TestCase {
  * @return void
  */
 	public function testRender() {
-		Configure::write('App.namespace', 'TestApp');
 		Plugin::load('TestPlugin');
 
 		$request = new Request('controller_posts/index');
@@ -342,7 +359,6 @@ class ControllerTest extends TestCase {
  * @return void
  */
 	public function testBeforeRenderCallbackChangingViewClass() {
-		Configure::write('App.namespace', 'TestApp');
 		$Controller = new Controller(new Request, new Response());
 
 		$Controller->eventManager()->attach(function ($event) {

+ 0 - 2
tests/test_app/Plugin/TestPlugin/Controller/TestPluginController.php

@@ -22,8 +22,6 @@ namespace TestPlugin\Controller;
 
 class TestPluginController extends TestPluginAppController {
 
-	public $uses = array();
-
 	public function index() {
 		$this->autoRender = false;
 	}

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

@@ -21,8 +21,6 @@ namespace TestPlugin\Controller;
 
 class TestsController extends TestPluginAppController {
 
-	public $uses = array();
-
 	public $helpers = array('TestPlugin.OtherHelper', 'Html');
 
 	public $components = array('TestPlugin.Plugins');