Skip to content

Commit

Permalink
Fix requestAction post simulation.
Browse files Browse the repository at this point in the history
POST data should not trigger notice errors.
Also fix issue where POST data could not be simulated with a
string URL.

Fixes #2248
  • Loading branch information
markstory committed Nov 13, 2011
1 parent a7fcb0a commit 9347ca2
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 8 deletions.
22 changes: 17 additions & 5 deletions lib/Cake/Core/Object.php
Expand Up @@ -55,8 +55,18 @@ public function toString() {
* 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.
*/
Expand All @@ -74,16 +84,18 @@ public function requestAction($url, $extra = array()) {
$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);
} elseif (is_array($url)) {
$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();
Expand Down
29 changes: 26 additions & 3 deletions lib/Cake/Test/Case/Core/ObjectTest.php
Expand Up @@ -115,7 +115,7 @@ public function paginate_request_action() {
* @return array
*/
public function post_pass() {
return $this->data;
return $this->request->data;
}

/**
Expand Down Expand Up @@ -609,11 +609,12 @@ public function testRequestActionParamParseAndPass() {
}

/**
* 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(
Expand All @@ -636,4 +637,26 @@ public function testRequestActionPostPassing() {

$_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);
}
}

0 comments on commit 9347ca2

Please sign in to comment.