Browse Source

Fix issue where abstract or interface controllers
would be constructed by Dispatcher.
Tests added.
Fixes #2048

mark_story 14 years ago
parent
commit
4810518c7d
2 changed files with 48 additions and 1 deletions
  1. 5 1
      lib/Cake/Routing/Dispatcher.php
  2. 43 0
      lib/Cake/Test/Case/Routing/DispatcherTest.php

+ 5 - 1
lib/Cake/Routing/Dispatcher.php

@@ -159,7 +159,11 @@ class Dispatcher {
 		if (!$ctrlClass) {
 			return false;
 		}
-		return new $ctrlClass($request, $response);
+		$reflection = new ReflectionClass($ctrlClass);
+		if ($reflection->isAbstract() || $reflection->isInterface()) {
+			return false;
+		}
+		return $reflection->newInstance($request, $response);
 	}
 
 /**

+ 43 - 0
lib/Cake/Test/Case/Routing/DispatcherTest.php

@@ -64,6 +64,14 @@ class TestDispatcher extends Dispatcher {
 class MyPluginAppController extends AppController {
 }
 
+abstract class DispatcherTestAbstractController extends Controller {
+	abstract public function index();
+}
+
+interface DispatcherTestInterfaceController {
+	public function index();
+}
+
 /**
  * MyPluginController class
  *
@@ -681,6 +689,41 @@ class DispatcherTest extends CakeTestCase {
 	}
 
 /**
+ * testMissingControllerInterface method
+ *
+ * @expectedException MissingControllerException
+ * @expectedExceptionMessage Controller class DispatcherTestInterfaceController could not be found.
+ * @return void
+ */
+	public function testMissingControllerInterface() {
+		Router::connect('/:controller/:action/*');
+
+		$Dispatcher = new TestDispatcher();
+		Configure::write('App.baseUrl', '/index.php');
+		$url = new CakeRequest('dispatcher_test_interface/index');
+		$response = $this->getMock('CakeResponse');
+
+		$controller = $Dispatcher->dispatch($url, $response, array('return' => 1));
+	}
+
+/**
+ * testMissingControllerInterface method
+ *
+ * @expectedException MissingControllerException
+ * @expectedExceptionMessage Controller class DispatcherTestAbstractController could not be found.
+ * @return void
+ */
+	public function testMissingControllerAbstract() {
+		Router::connect('/:controller/:action/*');
+
+		$Dispatcher = new TestDispatcher();
+		Configure::write('App.baseUrl', '/index.php');
+		$url = new CakeRequest('dispatcher_test_abstract/index');
+		$response = $this->getMock('CakeResponse');
+
+		$controller = $Dispatcher->dispatch($url, $response, array('return' => 1));
+	}
+/**
  * testDispatch method
  *
  * @return void