Browse Source

Fix requestAction post simulation.

POST data should not trigger notice errors.
Also fix issue where POST data could not be simulated with a
string URL.

Fixes #2248
mark_story 14 years ago
parent
commit
9347ca2dc8
2 changed files with 43 additions and 8 deletions
  1. 17 5
      lib/Cake/Core/Object.php
  2. 26 3
      lib/Cake/Test/Case/Core/ObjectTest.php

+ 17 - 5
lib/Cake/Core/Object.php

@@ -55,8 +55,18 @@ class Object {
  * or tie plugins into a main application. requestAction can be used to return rendered views
  * or fetch the return value from controller actions.
  *
- * @param mixed $url String or array-based url.
- * @param array $extra if array includes the key "return" it sets the AutoRender to true.
+ * Under the hood this method uses Router::reverse() to convert the $url parmeter into a string
+ * URL.  You should use URL formats that are compatible with Router::reverse()
+ *
+ * #### Passing POST and GET data
+ *
+ * POST and GET data can be simulated in requestAction.  Use `$extra['url']` for
+ * GET data.  The `$extra['data']` parameter allows POST data simulation.
+ *
+ * @param mixed $url String or array-based url.  Unlike other url arrays in CakePHP, this
+ *    url will not automatically handle passed and named arguments in the $url paramenter.
+ * @param array $extra if array includes the key "return" it sets the AutoRender to true.  Can
+ *    also be used to submit GET/POST data, and named/passed arguments.
  * @return mixed Boolean true or false on success/failure, or contents
  *    of rendered action if 'return' is set in $extra.
  */
@@ -74,6 +84,8 @@ class Object {
 			$extra['url'] = array();
 		}
 		$extra = array_merge(array('autoRender' => 0, 'return' => 1, 'bare' => 1, 'requested' => 1), $extra);
+		$data = isset($extra['data']) ? $extra['data'] : null;
+		unset($extra['data']);
 
 		if (is_string($url)) {
 			$request = new CakeRequest($url);
@@ -81,9 +93,9 @@ class Object {
 			$params = $url + array('pass' => array(), 'named' => array(), 'base' => false);
 			$params = array_merge($params, $extra);
 			$request = new CakeRequest(Router::reverse($params), false);
-			if (isset($params['data'])) {
-				$request->data = $params['data'];
-			}
+		}
+		if (isset($data)) {
+			$request->data = $data;
 		}
 
 		$dispatcher = new Dispatcher();

+ 26 - 3
lib/Cake/Test/Case/Core/ObjectTest.php

@@ -115,7 +115,7 @@ class RequestActionController extends Controller {
  * @return array
  */
 	public function post_pass() {
-		return $this->data;
+		return $this->request->data;
 	}
 
 /**
@@ -609,11 +609,12 @@ class ObjectTest extends CakeTestCase {
 	}
 
 /**
- * test requestAction and POST parameter passing, and not passing when url is an array.
+ * test that requestAction does not fish data out of the POST
+ * superglobal.
  *
  * @return void
  */
-	public function testRequestActionPostPassing() {
+	public function testRequestActionNoPostPassing() {
 		$_tmp = $_POST;
 
 		$_POST = array('data' => array(
@@ -636,4 +637,26 @@ class ObjectTest extends CakeTestCase {
 
 		$_POST = $_tmp;
 	}
+
+/**
+ * Test requestAction with post data.
+ *
+ * @return void
+ */
+	public function testRequestActionPostWithData() {
+		$data = array(
+			'Post' => array('id' => 2)
+		);
+		$result = $this->object->requestAction(
+			array('controller' => 'request_action', 'action' => 'post_pass'),
+			array('data' => $data)
+		);
+		$this->assertEquals($data, $result);
+
+		$result = $this->object->requestAction(
+			'/request_action/post_pass',
+			array('data' => $data)
+		);
+		$this->assertEquals($data, $result);
+	}
 }