Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

3.0 request action #939

Merged
merged 7 commits into from Nov 7, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 1 addition & 4 deletions lib/Cake/Controller/Component.php
@@ -1,8 +1,5 @@
<?php <?php
/** /**
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org) * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* *
Expand All @@ -11,11 +8,11 @@
* *
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org) * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project * @link http://cakephp.org CakePHP(tm) Project
* @package Cake.Controller
* @since CakePHP(tm) v 1.2 * @since CakePHP(tm) v 1.2
* @license MIT License (http://www.opensource.org/licenses/mit-license.php) * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/ */
namespace Cake\Controller; namespace Cake\Controller;

use Cake\Core\Object; use Cake\Core\Object;


/** /**
Expand Down
2 changes: 1 addition & 1 deletion lib/Cake/Controller/Component/RequestHandlerComponent.php
Expand Up @@ -262,7 +262,7 @@ public function beforeRedirect(Controller $controller, $url, $status = null, $ex
$code = key($statusCode); $code = key($statusCode);
$this->response->statusCode($code); $this->response->statusCode($code);
} }
$this->response->body($this->requestAction($url, array('return', 'bare' => false))); $this->response->body($controller->requestAction($url, array('return', 'bare' => false)));
$this->response->send(); $this->response->send();
$this->_stop(); $this->_stop();
} }
Expand Down
2 changes: 2 additions & 0 deletions lib/Cake/Controller/Controller.php
Expand Up @@ -25,6 +25,7 @@
use Cake\Network\Request; use Cake\Network\Request;
use Cake\Network\Response; use Cake\Network\Response;
use Cake\Routing\Router; use Cake\Routing\Router;
use Cake\Routing\RequestActionTrait;
use Cake\Utility\ClassRegistry; use Cake\Utility\ClassRegistry;
use Cake\Utility\Inflector; use Cake\Utility\Inflector;
use Cake\Utility\MergeVariablesTrait; use Cake\Utility\MergeVariablesTrait;
Expand Down Expand Up @@ -65,6 +66,7 @@
class Controller extends Object implements EventListener { class Controller extends Object implements EventListener {


use MergeVariablesTrait; use MergeVariablesTrait;
use RequestActionTrait;


/** /**
* The name of this controller. Controller names are plural, named after the model they manipulate. * The name of this controller. Controller names are plural, named after the model they manipulate.
Expand Down
73 changes: 0 additions & 73 deletions lib/Cake/Core/Object.php
Expand Up @@ -15,10 +15,6 @@
namespace Cake\Core; namespace Cake\Core;


use Cake\Log\LogTrait; use Cake\Log\LogTrait;
use Cake\Network\Request;
use Cake\Network\Response;
use Cake\Routing\Dispatcher;
use Cake\Routing\Router;
use Cake\Utility\Hash; use Cake\Utility\Hash;


/** /**
Expand Down Expand Up @@ -49,75 +45,6 @@ public function toString() {
return get_class($this); return get_class($this);
} }


/**
* Calls a controller's method from any location. Can be used to connect controllers together
* or tie plugins into a main application. requestAction can be used to return rendered views
* or fetch the return value from controller actions.
*
* Under the hood this method uses Router::reverse() to convert the $url parameter 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['query']` for
* GET data. The `$extra['post']` parameter allows POST data simulation.
*
* @param string|array $url String or array-based url. Unlike other url arrays in CakePHP, this
* url will not automatically handle passed arguments in the $url parameter.
* @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 passed arguments.
* @return mixed Boolean true or false on success/failure, or contents
* of rendered action if 'return' is set in $extra.
*/
public function requestAction($url, $extra = array()) {
if (empty($url)) {
return false;
}
if (($index = array_search('return', $extra)) !== false) {
$extra['return'] = 0;
$extra['autoRender'] = 1;
unset($extra[$index]);
}
$extra = array_merge(
['autoRender' => 0, 'return' => 1, 'bare' => 1, 'requested' => 1],
$extra
);
$post = $query = [];
if (isset($extra['post'])) {
$post = $extra['post'];
}
if (isset($extra['query'])) {
$query = $extra['query'];
}
unset($extra['post'], $extra['query']);

if (is_string($url) && strpos($url, FULL_BASE_URL) === 0) {
$url = Router::normalize(str_replace(FULL_BASE_URL, '', $url));
}
if (is_string($url)) {
$params = array(
'url' => $url
);
} elseif (is_array($url)) {
$params = array_merge($url, [
'pass' => [],
'base' => false,
'url' => Router::reverse($url)
]);
}
if (!empty($post)) {
$params['post'] = $post;
}
if (!empty($query)) {
$params['query'] = $query;
}
$request = new Request($params);
$dispatcher = new Dispatcher();
$result = $dispatcher->dispatch($request, new Response(), $extra);
Router::popRequest();
return $result;
}

/** /**
* Calls a method on this object with the given parameters. Provides an OO wrapper * Calls a method on this object with the given parameters. Provides an OO wrapper
* for `call_user_func_array` * for `call_user_func_array`
Expand Down
13 changes: 10 additions & 3 deletions lib/Cake/Network/Request.php
Expand Up @@ -39,7 +39,7 @@ class Request implements \ArrayAccess {
'plugin' => null, 'plugin' => null,
'controller' => null, 'controller' => null,
'action' => null, 'action' => null,
'pass' => array(), 'pass' => [],
); );


/** /**
Expand All @@ -49,14 +49,21 @@ class Request implements \ArrayAccess {
* *
* @var array * @var array
*/ */
public $data = array(); public $data = [];


/** /**
* Array of querystring arguments * Array of querystring arguments
* *
* @var array * @var array
*/ */
public $query = array(); public $query = [];

/**
* Array of cookie data.
*
* @var array
*/
public $cookies = [];


/** /**
* The url string used for the request. * The url string used for the request.
Expand Down
125 changes: 125 additions & 0 deletions lib/Cake/Routing/RequestActionTrait.php
@@ -0,0 +1,125 @@
<?php
/**
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @since CakePHP(tm) v 3.0.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
namespace Cake\Routing;

use Cake\Network\Request;
use Cake\Network\Response;
use Cake\Routing\Dispatcher;
use Cake\Routing\Router;

/**
* Provides the requestAction() method for doing sub-requests
*
* @package Cake.Routing
*/
trait RequestActionTrait {

/**
* Calls a controller's method from any location. Can be used to connect controllers together
* or tie plugins into a main application. requestAction can be used to return rendered views
* or fetch the return value from controller actions.
*
* Under the hood this method uses Router::reverse() to convert the $url parameter into a string
* URL. You should use URL formats that are compatible with Router::reverse()
*
* ### Examples
*
* A basic example getting the return value of the controller action:
*
* {{{
* $variables = $this->requestAction('/articles/popular');
* }}}
*
* A basic example of request action to fetch a rendered page without the layout.
*
* {{{
* $viewHtml = $this->requestAction('/articles/popular', ['return']);
* }}}
*
* You can also pass the URL as an array:
*
* {{{
* $vars = $this->requestAction(['controller' => 'articles', 'action' => 'popular']);
* }}}
*
* ### Passing other request data
*
* You can pass POST, GET, COOKIE and other data into the request using the apporpriate keys.
* Cookies can be passed using the `cookies` key. Get parameters can be set with `query` and post
* data can be sent using the `post` key.
*
* {{{
* $vars = $this->requestAction('/articles/popular', [
* 'query' => ['page' = > 1],
* 'cookies' => ['remember_me' => 1],
* ]);
* }}}
*
* @param string|array $url String or array-based url. Unlike other url arrays in CakePHP, this
* url will not automatically handle passed arguments in the $url parameter.
* @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 passed arguments.
* @return mixed Boolean true or false on success/failure, or contents
* of rendered action if 'return' is set in $extra.
*/
public function requestAction($url, $extra = array()) {
if (empty($url)) {
return false;
}
if (($index = array_search('return', $extra)) !== false) {
$extra['return'] = 0;
$extra['autoRender'] = 1;
unset($extra[$index]);
}
$extra = array_merge(
['autoRender' => 0, 'return' => 1, 'bare' => 1, 'requested' => 1],
$extra
);
$post = $query = [];
if (isset($extra['post'])) {
$post = $extra['post'];
}
if (isset($extra['query'])) {
$query = $extra['query'];
}
unset($extra['post'], $extra['query']);

if (is_string($url) && strpos($url, FULL_BASE_URL) === 0) {
$url = Router::normalize(str_replace(FULL_BASE_URL, '', $url));
}
if (is_string($url)) {
$params = [
'url' => $url
];
} elseif (is_array($url)) {
$params = array_merge($url, [
'pass' => [],
'base' => false,
'url' => Router::reverse($url)
]);
}
if (!empty($post)) {
$params['post'] = $post;
}
if (!empty($query)) {
$params['query'] = $query;
}
$request = new Request($params);
$dispatcher = new Dispatcher();
$result = $dispatcher->dispatch($request, new Response(), $extra);
Router::popRequest();
return $result;
}

}
Expand Up @@ -94,14 +94,14 @@ public function testSessionIdConsistentAcrossRequestAction() {
$Session->check('Test'); $Session->check('Test');
$this->assertTrue(isset($_SESSION)); $this->assertTrue(isset($_SESSION));


$Object = new Object(); $Controller = new Controller();
$Session = new SessionComponent($this->ComponentCollection); $Session = new SessionComponent($this->ComponentCollection);
$expected = $Session->id(); $expected = $Session->id();


$result = $Object->requestAction('/session_test/session_id'); $result = $Controller->requestAction('/session_test/session_id');
$this->assertEquals($expected, $result); $this->assertEquals($expected, $result);


$result = $Object->requestAction('/orange_session_test/session_id'); $result = $Controller->requestAction('/orange_session_test/session_id');
$this->assertEquals($expected, $result); $this->assertEquals($expected, $result);
} }


Expand Down