mirror of
https://github.com/yiisoft/yii2.git
synced 2025-12-01 23:51:12 +08:00
implementation of Response tied to actions
Result of a discussion with @qiangxue - there is not global Yii::$app->response anymore, every action has dedicated response class - implementation allows using HMVC pattern now, nested actions do not interfer
This commit is contained in:
@@ -41,17 +41,27 @@ class Action extends Component
|
|||||||
* @var Controller the controller that owns this action
|
* @var Controller the controller that owns this action
|
||||||
*/
|
*/
|
||||||
public $controller;
|
public $controller;
|
||||||
|
/**
|
||||||
|
* @var Response
|
||||||
|
*/
|
||||||
private $_response;
|
private $_response;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Response|\yii\console\Response|\yii\web\Response
|
||||||
|
*/
|
||||||
public function getResponse()
|
public function getResponse()
|
||||||
{
|
{
|
||||||
if ($this->_response === null) {
|
if ($this->_response === null) {
|
||||||
$this->_response = Yii::$app->createResponse();
|
// TODO use applications response factory here
|
||||||
|
//$this->_response = new Response();
|
||||||
}
|
}
|
||||||
return $this->_response;
|
return $this->_response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Response $response
|
||||||
|
*/
|
||||||
public function setResponse($response)
|
public function setResponse($response)
|
||||||
{
|
{
|
||||||
$this->_response = $response;
|
$this->_response = $response;
|
||||||
@@ -92,8 +102,6 @@ class Action extends Component
|
|||||||
throw new InvalidConfigException(get_class($this) . ' must define a "run()" method.');
|
throw new InvalidConfigException(get_class($this) . ' must define a "run()" method.');
|
||||||
}
|
}
|
||||||
$args = $this->controller->bindActionParams($this, $params);
|
$args = $this->controller->bindActionParams($this, $params);
|
||||||
$response = $this->getResponse();
|
return call_user_func_array(array($this, 'run'), $args);
|
||||||
$response->result = call_user_func_array(array($this, 'run'), $args);
|
|
||||||
return $response;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -155,8 +155,6 @@ abstract class Application extends Module
|
|||||||
*/
|
*/
|
||||||
abstract public function handleRequest($request);
|
abstract public function handleRequest($request);
|
||||||
|
|
||||||
public abstract function createResponse();
|
|
||||||
|
|
||||||
private $_runtimePath;
|
private $_runtimePath;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -110,22 +110,38 @@ class Controller extends Component
|
|||||||
if ($action !== null) {
|
if ($action !== null) {
|
||||||
$oldAction = $this->action;
|
$oldAction = $this->action;
|
||||||
$this->action = $action;
|
$this->action = $action;
|
||||||
$result = null;
|
|
||||||
// TODO beforeAction may also create a response somehow.
|
|
||||||
if ($this->module->beforeAction($action)) {
|
if ($this->module->beforeAction($action)) {
|
||||||
if ($this->beforeAction($action)) {
|
if ($this->beforeAction($action)) {
|
||||||
$result = $action->runWithParams($params);
|
$result = $action->runWithParams($params);
|
||||||
|
if ($result !== null) {
|
||||||
|
$this->handleActionResult($result, $action);
|
||||||
|
}
|
||||||
$this->afterAction($action);
|
$this->afterAction($action);
|
||||||
}
|
}
|
||||||
$this->module->afterAction($action);
|
$this->module->afterAction($action);
|
||||||
}
|
}
|
||||||
$this->action = $oldAction;
|
$this->action = $oldAction;
|
||||||
return $result;
|
return $action->getResponse();
|
||||||
} else {
|
} else {
|
||||||
throw new InvalidRouteException('Unable to resolve the request: ' . $this->getUniqueId() . '/' . $id);
|
throw new InvalidRouteException('Unable to resolve the request: ' . $this->getUniqueId() . '/' . $id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the return value of an action
|
||||||
|
* @param mixed $result
|
||||||
|
* @param Action $action
|
||||||
|
*/
|
||||||
|
protected abstract function handleActionResult(&$result, $action);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Response the response object of the current action. null if no action is running
|
||||||
|
*/
|
||||||
|
public function getResponse()
|
||||||
|
{
|
||||||
|
return $this->action !== null ? $this->action->getResponse() : null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runs a request specified in terms of a route.
|
* Runs a request specified in terms of a route.
|
||||||
* The route can be either an ID of an action within this controller or a complete route consisting
|
* The route can be either an ID of an action within this controller or a complete route consisting
|
||||||
|
|||||||
@@ -44,8 +44,6 @@ class InlineAction extends Action
|
|||||||
public function runWithParams($params)
|
public function runWithParams($params)
|
||||||
{
|
{
|
||||||
$args = $this->controller->bindActionParams($this, $params);
|
$args = $this->controller->bindActionParams($this, $params);
|
||||||
$response = $this->getResponse();
|
return call_user_func_array(array($this->controller, $this->actionMethod), $args);
|
||||||
$response->result = call_user_func_array(array($this->controller, $this->actionMethod), $args);
|
|
||||||
return $response;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -571,7 +571,7 @@ abstract class Module extends Component
|
|||||||
* If the route is empty, the method will use [[defaultRoute]].
|
* If the route is empty, the method will use [[defaultRoute]].
|
||||||
* @param string $route the route that specifies the action.
|
* @param string $route the route that specifies the action.
|
||||||
* @param array $params the parameters to be passed to the action
|
* @param array $params the parameters to be passed to the action
|
||||||
* @return mixed the result of the action.
|
* @return Response the resulting response of the action.
|
||||||
* @throws InvalidRouteException if the requested route cannot be resolved into an action successfully
|
* @throws InvalidRouteException if the requested route cannot be resolved into an action successfully
|
||||||
*/
|
*/
|
||||||
public function runAction($route, $params = array())
|
public function runAction($route, $params = array())
|
||||||
@@ -582,9 +582,9 @@ abstract class Module extends Component
|
|||||||
list($controller, $actionID) = $parts;
|
list($controller, $actionID) = $parts;
|
||||||
$oldController = Yii::$app->controller;
|
$oldController = Yii::$app->controller;
|
||||||
Yii::$app->controller = $controller;
|
Yii::$app->controller = $controller;
|
||||||
$result = $controller->runAction($actionID, $params);
|
$response = $controller->runAction($actionID, $params);
|
||||||
Yii::$app->controller = $oldController;
|
Yii::$app->controller = $oldController;
|
||||||
return $result;
|
return $response;
|
||||||
} else {
|
} else {
|
||||||
throw new InvalidRouteException('Unable to resolve the request "' . trim($this->getUniqueId() . '/' . $route, '/') . '".');
|
throw new InvalidRouteException('Unable to resolve the request "' . trim($this->getUniqueId() . '/' . $route, '/') . '".');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -88,39 +88,13 @@ class Application extends \yii\base\Application
|
|||||||
* Handles the specified request.
|
* Handles the specified request.
|
||||||
* @param Request $request the request to be handled
|
* @param Request $request the request to be handled
|
||||||
* @return Response the resulting response
|
* @return Response the resulting response
|
||||||
|
* @throws Exception if the route is invalid
|
||||||
*/
|
*/
|
||||||
public function handleRequest($request)
|
public function handleRequest($request)
|
||||||
{
|
{
|
||||||
list ($route, $params) = $request->resolve();
|
list ($route, $params) = $request->resolve();
|
||||||
$result = $this->runAction($route, $params);
|
|
||||||
$response = $this->getResponse();
|
|
||||||
$response->exitStatus = (int)$result;
|
|
||||||
return $response;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the response component.
|
|
||||||
* @return Response the response component
|
|
||||||
*/
|
|
||||||
public function createResponse()
|
|
||||||
{
|
|
||||||
return new Response();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Runs a controller action specified by a route.
|
|
||||||
* This method parses the specified route and creates the corresponding child module(s), controller and action
|
|
||||||
* instances. It then calls [[Controller::runAction()]] to run the action with the given parameters.
|
|
||||||
* If the route is empty, the method will use [[defaultRoute]].
|
|
||||||
* @param string $route the route that specifies the action.
|
|
||||||
* @param array $params the parameters to be passed to the action
|
|
||||||
* @return integer the status code returned by the action execution. 0 means normal, and other values mean abnormal.
|
|
||||||
* @throws Exception if the route is invalid
|
|
||||||
*/
|
|
||||||
public function runAction($route, $params = array())
|
|
||||||
{
|
|
||||||
try {
|
try {
|
||||||
return parent::runAction($route, $params);
|
return $this->runAction($route, $params);
|
||||||
} catch (InvalidRouteException $e) {
|
} catch (InvalidRouteException $e) {
|
||||||
throw new Exception(\Yii::t('yii', 'Unknown command "{command}".', array('{command}' => $route)), 0, $e);
|
throw new Exception(\Yii::t('yii', 'Unknown command "{command}".', array('{command}' => $route)), 0, $e);
|
||||||
}
|
}
|
||||||
@@ -152,9 +126,6 @@ class Application extends \yii\base\Application
|
|||||||
'request' => array(
|
'request' => array(
|
||||||
'class' => 'yii\console\Request',
|
'class' => 'yii\console\Request',
|
||||||
),
|
),
|
||||||
'response' => array(
|
|
||||||
'class' => 'yii\console\Response',
|
|
||||||
),
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -134,6 +134,16 @@ class Controller extends \yii\base\Controller
|
|||||||
return $args;
|
return $args;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the return value of an action
|
||||||
|
* @param mixed $result
|
||||||
|
* @param Action $action
|
||||||
|
*/
|
||||||
|
protected function handleActionResult(&$result, $action)
|
||||||
|
{
|
||||||
|
$action->getResponse()->exitStatus = (int)$result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Formats a string with ANSI codes
|
* Formats a string with ANSI codes
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -65,8 +65,7 @@ class Application extends \yii\base\Application
|
|||||||
$params = array_splice($this->catchAll, 1);
|
$params = array_splice($this->catchAll, 1);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
$response = $this->runAction($route, $params);
|
return $this->runAction($route, $params);
|
||||||
return $response;
|
|
||||||
} catch (InvalidRouteException $e) {
|
} catch (InvalidRouteException $e) {
|
||||||
throw new HttpException(404, $e->getMessage(), $e->getCode(), $e);
|
throw new HttpException(404, $e->getMessage(), $e->getCode(), $e);
|
||||||
}
|
}
|
||||||
@@ -107,15 +106,6 @@ class Application extends \yii\base\Application
|
|||||||
return $this->getComponent('request');
|
return $this->getComponent('request');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the response component.
|
|
||||||
* @return Response the response component
|
|
||||||
*/
|
|
||||||
public function createResponse()
|
|
||||||
{
|
|
||||||
return new Response();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the session component.
|
* Returns the session component.
|
||||||
* @return Session the session component
|
* @return Session the session component
|
||||||
@@ -154,9 +144,6 @@ class Application extends \yii\base\Application
|
|||||||
'request' => array(
|
'request' => array(
|
||||||
'class' => 'yii\web\Request',
|
'class' => 'yii\web\Request',
|
||||||
),
|
),
|
||||||
'response' => array(
|
|
||||||
'class' => 'yii\web\Response',
|
|
||||||
),
|
|
||||||
'session' => array(
|
'session' => array(
|
||||||
'class' => 'yii\web\Session',
|
'class' => 'yii\web\Session',
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
namespace yii\web;
|
namespace yii\web;
|
||||||
|
|
||||||
use Yii;
|
use Yii;
|
||||||
|
use yii\base\Action;
|
||||||
use yii\base\InlineAction;
|
use yii\base\InlineAction;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -61,6 +62,16 @@ class Controller extends \yii\base\Controller
|
|||||||
return $args;
|
return $args;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the return value of an action
|
||||||
|
* @param mixed $result
|
||||||
|
* @param Action $action
|
||||||
|
*/
|
||||||
|
protected function handleActionResult(&$result, $action)
|
||||||
|
{
|
||||||
|
$action->getResponse()->setContent($result);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a URL using the given route and parameters.
|
* Creates a URL using the given route and parameters.
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user