Browse Source

Merge pull request #9525 from cakephp/requestaction-fix

Fix requestAction() not working with middleware.
José Lorenzo Rodríguez 9 years ago
parent
commit
bdbe2ba894

+ 20 - 0
src/Routing/RequestActionTrait.php

@@ -17,6 +17,8 @@ use Cake\Core\Configure;
 use Cake\Network\Request;
 use Cake\Network\Response;
 use Cake\Network\Session;
+use Cake\Routing\Filter\ControllerFactoryFilter;
+use Cake\Routing\Filter\RoutingFilter;
 
 /**
  * Provides the requestAction() method for doing sub-requests
@@ -154,6 +156,24 @@ trait RequestActionTrait
         $request = new Request($params);
         $request->addParams($extra);
         $dispatcher = DispatcherFactory::create();
+
+        // If an application is using PSR7 middleware,
+        // we need to 'fix' their missing dispatcher filters.
+        $needed = [
+            'routing' => RoutingFilter::class,
+            'controller' => ControllerFactoryFilter::class
+        ];
+        foreach ($dispatcher->filters() as $filter) {
+            if ($filter instanceof RoutingFilter) {
+                unset($needed['routing']);
+            }
+            if ($filter instanceof ControllerFactoryFilter) {
+                unset($needed['controller']);
+            }
+        }
+        foreach ($needed as $class) {
+            $dispatcher->addFilter(new $class);
+        }
         $result = $dispatcher->dispatch($request, new Response());
         Router::popRequest();
 

+ 15 - 1
tests/TestCase/Routing/RequestActionTraitTest.php

@@ -25,7 +25,6 @@ use Cake\Utility\Security;
  */
 class RequestActionTraitTest extends TestCase
 {
-
     /**
      * fixtures
      *
@@ -421,4 +420,19 @@ class RequestActionTraitTest extends TestCase
         );
         $this->assertEquals('bar', $result);
     }
+
+    /**
+     * requestAction relies on both the RoutingFilter and ControllerFactory
+     * filters being connected. Ensure it can correct the missing state.
+     *
+     * @return void
+     */
+    public function testRequestActionAddsRequiredFilters()
+    {
+        DispatcherFactory::clear();
+
+        $result = $this->object->requestAction('/request_action/test_request_action');
+        $expected = 'This is a test';
+        $this->assertEquals($expected, $result);
+    }
 }