Permalink
Browse files

Fixing issues with request stack not being used correctly

when there are requestAction requests being performed.
Adding Router::popRequest() to allow manipulation of request stack
so nested requestAction or serial requestAction calls work correctly.
Fixes #1906
  • Loading branch information...
1 parent 3014d3f commit fdacc9de1612c03c9462363c1bc05c2232dbfae8 @markstory markstory committed Aug 13, 2011
View
@@ -87,7 +87,9 @@ public function requestAction($url, $extra = array()) {
}
$dispatcher = new Dispatcher();
- return $dispatcher->dispatch($request, new CakeResponse(), $extra);
+ $result = $dispatcher->dispatch($request, new CakeResponse(), $extra);
+ Router::popRequest();
+ return $result;
}
/**
@@ -517,6 +517,9 @@ private static function __parseExtension($url) {
* parameters as the current request parameters that are merged with url arrays
* created later in the request.
*
+ * Nested requests will create a stack of requests. You can remove requests using
+ * Router::popRequest(). This is done automatically when using Object::requestAction().
+ *
* Will accept either a CakeRequest object or an array of arrays. Support for
* accepting arrays may be removed in the future.
*
@@ -535,6 +538,17 @@ public static function setRequestInfo($request) {
}
}
+/**
+ * Pops a request off of the request stack. Used when doing requestAction
+ *
+ * @return CakeRequest The request removed from the stack.
+ * @see Router::setRequestInfo()
+ * @see Object::requestAction()
+ */
+ public static function popRequest() {
+ return array_pop(self::$_requests);
+ }
+
/**
* Get the either the current request object, or the first one.
*
@@ -675,12 +689,7 @@ public static function url($url = null, $full = false) {
$path = array('base' => null);
if (!empty(self::$_requests)) {
- $currentRequest = self::$_requests[count(self::$_requests) - 1];
- if (!empty($currentRequest->params['requested'])) {
- $request = self::$_requests[0];
- } else {
- $request = $currentRequest;
- }
+ $request = self::$_requests[count(self::$_requests) - 1];
$params = $request->params;
$path = array('base' => $request->base, 'here' => $request->here);
}
@@ -463,12 +463,14 @@ public function testRequestAction() {
'views' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS),
'controllers' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Controller' . DS)
), true);
+ $this->assertNull(Router::getRequest(), 'request stack should be empty.');
+
$result = $this->object->requestAction('');
$this->assertFalse($result);
$result = $this->object->requestAction('/request_action/test_request_action');
$expected = 'This is a test';
- $this->assertEqual($expected, $result);;
+ $this->assertEqual($expected, $result);
$result = $this->object->requestAction('/request_action/another_ra_test/2/5');
$expected = 7;
@@ -488,6 +490,8 @@ public function testRequestAction() {
$result = $this->object->requestAction('/request_action/normal_request_action');
$expected = 'Hello World';
$this->assertEqual($expected, $result);
+
+ $this->assertNull(Router::getRequest(), 'requests were not popped off the stack, this will break url generation');
}
/**
@@ -2298,6 +2298,35 @@ public function testSetRequestInfoLegacy() {
$this->assertEqual($result->webroot, '/');
}
+/**
+ * Test that Router::url() uses the first request
+ */
+ public function testUrlWithRequestAction() {
+ $firstRequest = new CakeRequest('/posts/index');
+ $firstRequest->addParams(array(
+ 'plugin' => null,
+ 'controller' => 'posts',
+ 'action' => 'index'
+ ))->addPaths(array('base' => ''));
+
+ $secondRequest = new CakeRequest('/posts/index');
+ $secondRequest->addParams(array(
+ 'requested' => 1,
+ 'plugin' => null,
+ 'controller' => 'comments',
+ 'action' => 'listing'
+ ))->addPaths(array('base' => ''));
+
+ Router::setRequestInfo($firstRequest);
+ Router::setRequestInfo($secondRequest);
+
+ $result = Router::url(array('base' => false));
+ $this->assertEquals('/comments/listing', $result, 'with second requests, the last should win.');
+
+ Router::popRequest();
+ $result = Router::url(array('base' => false));
+ $this->assertEquals('/posts', $result, 'with second requests, the last should win.');
+ }
/**
* test that a route object returning a full url is not modified.
*

0 comments on commit fdacc9d

Please sign in to comment.