Commit 5a72523a by Qiang Xue

console commands.

parent a9b02d4e
......@@ -45,44 +45,20 @@ class Action extends Component
}
/**
* Normalizes the input parameters for the action.
* The parameters will later be passed to the `run()` method of the action.
* This method is mainly called by the controller when running an action.
* @param array $params the input parameters in terms of name-value pairs.
* @return array|boolean the normalized parameters, or false if the input parameters are invalid.
* Runs this action with the specified parameters.
* This method is mainly invoked by the controller.
* @param array $params action parameters
* @return integer the exit status (0 means normal, non-zero means abnormal).
*/
public function normalizeParams($params)
public function runWithParams($params)
{
$method = new \ReflectionMethod($this, 'run');
return $this->normalizeParamsByMethod($method, $params);
}
/**
* Extracts the input parameters according to the specified method signature.
* @param \ReflectionMethod $method the method reflection
* @param array $params the parameters in name-value pairs
* @return array|boolean the extracted parameters in the order as declared in the "run()" method.
* False is returned if the input parameters do not follow the method declaration.
*/
protected function normalizeParamsByMethod($method, $params)
{
$ps = array();
foreach ($method->getParameters() as $param) {
$name = $param->getName();
if (isset($params[$name])) {
if ($param->isArray()) {
$ps[] = is_array($params[$name]) ? $params[$name] : array($params[$name]);
} elseif (!is_array($params[$name])) {
$ps[] = $params[$name];
} else {
return false;
}
} elseif ($param->isDefaultValueAvailable()) {
$ps[] = $param->getDefaultValue();
} else {
return false;
}
$params = \yii\util\ReflectionHelper::bindParams($method, $params);
if ($params === false) {
$this->controller->invalidActionParams($this);
return 1;
} else {
return (int)$method->invokeArgs($this, $params);
}
return false;
}
}
......@@ -187,10 +187,10 @@ abstract class Application extends Module
throw new Exception(\Yii::t('yii', 'Unable to resolve the request.'));
}
list($controller, $action) = $result;
$oldController = $this->controller;
$priorController = $this->controller;
$this->controller = $controller;
$status = $controller->run($action, $params);
$this->controller = $oldController;
$this->controller = $priorController;
return $status;
}
......
......@@ -42,6 +42,30 @@ class Controller extends Component implements Initable
*/
public $defaultAction = 'index';
/**
* @var array mapping from action ID to action configuration.
* Array keys are action IDs, and array values are the corresponding
* action class names or action configuration arrays. For example,
*
* ~~~
* return array(
* 'action1' => '@application/components/Action1',
* 'action2' => array(
* 'class' => '@application/components/Action2',
* 'property1' => 'value1',
* 'property2' => 'value2',
* ),
* );
* ~~~
*
* [[\Yii::createObject()]] will be invoked to create the requested action
* using the configuration provided here.
*
* Note, in order to inherit actions defined in the parent class, a child class needs to
* merge the parent actions with child actions using functions like `array_merge()`.
* @see createAction
*/
public $actions = array();
/**
* @var Action the action that is currently being executed
*/
public $action;
......@@ -66,45 +90,11 @@ class Controller extends Component implements Initable
}
/**
* Returns a list of external action classes.
* Array keys are action IDs, and array values are the corresponding
* action class names or action configuration arrays. For example,
*
* ~~~
* return array(
* 'action1'=>'@application/components/Action1',
* 'action2'=>array(
* 'class'=>'@application/components/Action2',
* 'property1'=>'value1',
* 'property2'=>'value2',
* ),
* );
* ~~~
*
* [[\Yii::createObject()]] will be invoked to create the requested action
* using the configuration provided here.
*
* Derived classes may override this method to declare external actions.
*
* Note, in order to inherit actions defined in the parent class, a child class needs to
* merge the parent actions with child actions using functions like `array_merge()`.
*
* @return array list of external action classes
* @see createAction
*/
public function actions()
{
return array();
}
/**
* Runs the controller with the specified action and parameters.
* @param Action|string $action the action to be executed. This can be either an action object
* or the ID of the action.
* @param array $params the parameters to be passed to the action.
* @param array $params the parameters (name-value pairs) to be passed to the action.
* If null, the result of [[getActionParams()]] will be used as action parameters.
* Note that the parameters must be name-value pairs with the names corresponding to
* the parameter names as declared by the action.
* @return integer the exit status of the action. 0 means normal, other values mean abnormal.
* @see missingAction
* @see createAction
......@@ -122,32 +112,17 @@ class Controller extends Component implements Initable
$priorAction = $this->action;
$this->action = $action;
$exitStatus = 1;
if ($this->authorize($action)) {
$params = $action->normalizeParams($params === null ? $this->getActionParams() : $params);
if ($params !== false) {
if ($this->beforeAction($action)) {
$exitStatus = (int)call_user_func_array(array($action, 'run'), $params);
$this->afterAction($action);
}
} else {
$this->invalidActionParams($action);
}
if ($this->authorize($action) && $this->beforeAction($action)) {
$status = $action->runWithParams($params !== null ?: $this->getActionParams());
$this->afterAction($action);
} else {
$status = 1;
}
$this->action = $priorAction;
return $exitStatus;
}
/**
* Returns the request parameters that will be used for action parameter binding.
* Default implementation simply returns an empty array.
* Child classes may override this method to customize the parameters to be provided
* for action parameter binding (e.g. `$_GET`).
* @return array the request parameters (name-value pairs) to be used for action parameter binding
*/
public function getActionParams()
{
return array();
return $status;
}
/**
......@@ -163,15 +138,25 @@ class Controller extends Component implements Initable
if ($actionID === '') {
$actionID = $this->defaultAction;
}
if (method_exists($this, 'action' . $actionID) && strcasecmp($actionID, 's')) {
if (isset($this->actions[$actionID])) {
return \Yii::createObject($this->actions[$actionID], $actionID, $this);
} elseif (method_exists($this, 'action' . $actionID)) {
return new InlineAction($actionID, $this);
} else {
$actions = $this->actions();
if (isset($actions[$actionID])) {
return \Yii::createObject($actions[$actionID], $actionID, $this);
}
return null;
}
return null;
}
/**
* Returns the request parameters that will be used for action parameter binding.
* Default implementation simply returns an empty array.
* Child classes may override this method to customize the parameters to be provided
* for action parameter binding (e.g. `$_GET`).
* @return array the request parameters (name-value pairs) to be used for action parameter binding
*/
public function getActionParams()
{
return array();
}
/**
......@@ -234,7 +219,7 @@ class Controller extends Component implements Initable
if ($route[0] !== '/' && !$this->module instanceof Application) {
$route = '/' . $this->module->getUniqueId() . '/' . $route;
}
$status = \Yii::$application->dispatch($route, $params);
$status = \Yii::$application->processRequest($route, $params);
}
if ($exit) {
\Yii::$application->end($status);
......
......@@ -21,20 +21,20 @@ namespace yii\base;
class InlineAction extends Action
{
/**
* Runs the action with the supplied parameters.
* This method is invoked by the controller.
* @param array $params the input parameters in terms of name-value pairs.
* @return boolean whether the input parameters are valid
* Runs this action with the specified parameters.
* This method is mainly invoked by the controller.
* @param array $params action parameters
* @return integer the exit status (0 means normal, non-zero means abnormal).
*/
public function runWithParams($params)
{
$method = new \ReflectionMethod($this->controller, 'action' . $this->id);
$params = $this->normalizeParamsByMethod($method, $params);
if ($params !== false) {
call_user_func_array(array($this->controller, 'action' . $this->id), $params);
return true;
$params = \yii\util\ReflectionHelper::bindParams($method, $params);
if ($params === false) {
$this->controller->invalidActionParams($this);
return 1;
} else {
return false;
return (int)$method->invokeArgs($this, $params);
}
}
}
......@@ -11,9 +11,6 @@ namespace yii\console;
use yii\base\Exception;
// fcgi doesn't have STDIN defined by default
defined('STDIN') or define('STDIN', fopen('php://stdin', 'r'));
/**
* Application represents a console application.
*
......@@ -41,9 +38,6 @@ defined('STDIN') or define('STDIN', fopen('php://stdin', 'r'));
* yiic help <command-name>
* ~~~
*
* @property string $commandPath The directory that contains the command classes. Defaults to 'protected/commands'.
* @property CommandRunner $commandRunner The command runner.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
......
<?php
/**
* ReflectionHelper class file.
*
* @link http://www.yiiframework.com/
* @copyright Copyright &copy; 2008-2012 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\util;
/**
* ReflectionHelper
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class ReflectionHelper
{
/**
* Prepares parameters so that they can be bound to the specified method.
* This method mainly helps method parameter binding. It converts `$params`
* into an array which can be passed to `call_user_func_array()` when calling
* the specified method. The conversion is based on the matching of method parameter names
* and the input array keys. For example,
*
* ~~~
* class Foo {
* function bar($a, $b) { ... }
* }
*
* $method = new \ReflectionMethod('Foo', 'bar');
* $params = array('b' => 2, 'c' => 3, 'a' => 1);
* var_export(ReflectionHelper::bindMethodParams($method, $params));
* // would output: array('a' => 1, 'b' => 2)
* ~~~
*
* @param \ReflectionMethod $method the method reflection
* @param array $params the parameters in terms of name-value pairs
* @return array|boolean the parameters that can be passed to the method via `call_user_func_array()`.
* False is returned if the input parameters do not follow the method declaration.
*/
public static function bindParams($method, $params)
{
$ps = array();
foreach ($method->getParameters() as $param) {
$name = $param->getName();
if (array_key_exists($name, $params)) {
if ($param->isArray()) {
$ps[$name] = is_array($params[$name]) ? $params[$name] : array($params[$name]);
} elseif (!is_array($params[$name])) {
$ps[$name] = $params[$name];
} else {
return false;
}
} elseif ($param->isDefaultValueAvailable()) {
$ps[$name] = $param->getDefaultValue();
} else {
return false;
}
}
return $ps;
}
}
<?php
/**
* Text helper class file.
* StringHelper class file.
*
* @link http://www.yiiframework.com/
* @copyright Copyright &copy; 2008-2012 Yii Software LLC
......@@ -10,7 +10,7 @@
namespace yii\util;
/**
* Text helper
* StringHelper
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @author Alex Makarov <sam@rmcreative.ru>
......
......@@ -7,6 +7,9 @@
* @license http://www.yiiframework.com/license/
*/
// fcgi doesn't have STDIN defined by default
defined('STDIN') or define('STDIN', fopen('php://stdin', 'r'));
require(__DIR__ . '/yii.php');
$config = array(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment