Commit fd3c29aa by Qiang Xue

Added console Request class.

Refactored console Application code.
parent ec59da15
...@@ -16,135 +16,47 @@ namespace yii\base; ...@@ -16,135 +16,47 @@ namespace yii\base;
class Request extends ApplicationComponent class Request extends ApplicationComponent
{ {
private $_scriptFile; private $_scriptFile;
private $_isConsoleRequest;
/** /**
* Initializes the application component. * Returns a value indicating whether the current request is made via command line
* This method overrides the parent implementation by preprocessing * @return boolean the value indicating whether the current request is made via console
* the user request data.
*/ */
public function init() public function getIsConsoleRequest()
{ {
return isset($this->_isConsoleRequest) ? $this->_isConsoleRequest : PHP_SAPI === 'cli';
} }
/** /**
* Returns the relative URL of the entry script. * Sets the value indicating whether the current request is made via command line
* The implementation of this method referenced Zend_Controller_Request_Http in Zend Framework. * @param boolean $value the value indicating whether the current request is made via command line
* @return string the relative URL of the entry script.
*/ */
public function getScriptUrl() public function setIsConsoleRequest($value)
{ {
if($this->_scriptUrl===null) $this->_isConsoleRequest = $value;
{
$scriptName=basename($_SERVER['SCRIPT_FILENAME']);
if(basename($_SERVER['SCRIPT_NAME'])===$scriptName)
$this->_scriptUrl=$_SERVER['SCRIPT_NAME'];
else if(basename($_SERVER['PHP_SELF'])===$scriptName)
$this->_scriptUrl=$_SERVER['PHP_SELF'];
else if(isset($_SERVER['ORIG_SCRIPT_NAME']) && basename($_SERVER['ORIG_SCRIPT_NAME'])===$scriptName)
$this->_scriptUrl=$_SERVER['ORIG_SCRIPT_NAME'];
else if(($pos=strpos($_SERVER['PHP_SELF'],'/'.$scriptName))!==false)
$this->_scriptUrl=substr($_SERVER['SCRIPT_NAME'],0,$pos).'/'.$scriptName;
else if(isset($_SERVER['DOCUMENT_ROOT']) && strpos($_SERVER['SCRIPT_FILENAME'],$_SERVER['DOCUMENT_ROOT'])===0)
$this->_scriptUrl=str_replace('\\','/',str_replace($_SERVER['DOCUMENT_ROOT'],'',$_SERVER['SCRIPT_FILENAME']));
else
throw new Exception(Yii::t('yii','CHttpRequest is unable to determine the entry script URL.'));
}
return $this->_scriptUrl;
}
/**
* Sets the relative URL for the application entry script.
* This setter is provided in case the entry script URL cannot be determined
* on certain Web servers.
* @param string $value the relative URL for the application entry script.
*/
public function setScriptUrl($value)
{
$this->_scriptUrl='/'.trim($value,'/');
} }
/** /**
* Returns whether this is an AJAX (XMLHttpRequest) request. * Returns entry script file path.
* @return boolean whether this is an AJAX (XMLHttpRequest) request. * @return string entry script file path (processed w/ realpath())
*/
public function getIsAjaxRequest()
{
return isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH']==='XMLHttpRequest';
}
/**
* Returns whether this is an Adobe Flash or Adobe Flex request.
* @return boolean whether this is an Adobe Flash or Adobe Flex request.
* @since 1.1.11
*/
public function getIsFlashRequest()
{
return isset($_SERVER['HTTP_USER_AGENT']) && (stripos($_SERVER['HTTP_USER_AGENT'],'Shockwave')!==false || stripos($_SERVER['HTTP_USER_AGENT'],'Flash')!==false);
}
/**
* Returns the server name.
* @return string server name
*/
public function getServerName()
{
return $_SERVER['SERVER_NAME'];
}
/**
* Returns the server port number.
* @return integer server port number
*/
public function getServerPort()
{
return $_SERVER['SERVER_PORT'];
}
/**
* Returns the URL referrer, null if not present
* @return string URL referrer, null if not present
*/
public function getUrlReferrer()
{
return isset($_SERVER['HTTP_REFERER'])?$_SERVER['HTTP_REFERER']:null;
}
/**
* Returns the user agent, null if not present.
* @return string user agent, null if not present
*/
public function getUserAgent()
{
return isset($_SERVER['HTTP_USER_AGENT'])?$_SERVER['HTTP_USER_AGENT']:null;
}
/**
* Returns the user IP address.
* @return string user IP address
*/ */
public function getUserHostAddress() public function getScriptFile()
{ {
return isset($_SERVER['REMOTE_ADDR'])?$_SERVER['REMOTE_ADDR']:'127.0.0.1'; if ($this->_scriptFile === null) {
$this->_scriptFile = realpath($_SERVER['SCRIPT_FILENAME']);
} }
return $this->_scriptFile;
/**
* Returns the user host name, null if it cannot be determined.
* @return string user host name, null if cannot be determined
*/
public function getUserHost()
{
return isset($_SERVER['REMOTE_HOST'])?$_SERVER['REMOTE_HOST']:null;
} }
/** /**
* Returns entry script file path. * Sets the entry script file path.
* @return string entry script file path (processed w/ realpath()) * This can be an absolute or relative file path, or a path alias.
* Note that you normally do not have to set the script file path
* as [[getScriptFile()]] can determine it based on `$_SERVER['SCRIPT_FILENAME']`.
* @param string $value the entry script file
*/ */
public function getScriptFile() public function setScriptFile($value)
{ {
if($this->_scriptFile!==null) $this->_scriptFile = realpath(\Yii::getAlias($value));
return $this->_scriptFile;
else
return $this->_scriptFile=realpath($_SERVER['SCRIPT_FILENAME']);
} }
} }
...@@ -25,21 +25,21 @@ use yii\util\ReflectionHelper; ...@@ -25,21 +25,21 @@ use yii\util\ReflectionHelper;
* - The command processes the user request with the specified parameters. * - The command processes the user request with the specified parameters.
* *
* The command classes reside in the directory specified by [[controllerPath]]. * The command classes reside in the directory specified by [[controllerPath]].
* Their naming should follow the same naming as controllers. For example, the `help` command * Their naming should follow the same naming convention as controllers. For example, the `help` command
* is implemented using the `HelpController` class. * is implemented using the `HelpController` class.
* *
* To run the console application, enter the following on the command line: * To run the console application, enter the following on the command line:
* *
* ~~~ * ~~~
* yiic <route> [...options...] * yiic <route> [--param1=value1 --param2 ...]
* ~~~ * ~~~
* *
* where `<route>` refers to a controller route in the form of `ModuleID/ControllerID/ActionID` * where `<route>` refers to a controller route in the form of `ModuleID/ControllerID/ActionID`
* (e.g. `sitemap/create`), and `options` refers to a set of named parameters that will be used * (e.g. `sitemap/create`), and `param1`, `param2` refers to a set of named parameters that
* to initialize the command controller instance and the corresponding action (e.g. `--since=0` * will be used to initialize the controller action (e.g. `--since=0` specifies a `since` parameter
* specifies a `since` parameter whose value is 0). * whose value is 0 and a corresponding `$since` parameter is passed to the action method).
* *
* A `help` command is provided by default, which may list available commands and show their usage. * A `help` command is provided by default, which lists available commands and shows their usage.
* To use this command, simply type: * To use this command, simply type:
* *
* ~~~ * ~~~
...@@ -89,11 +89,13 @@ class Application extends \yii\base\Application ...@@ -89,11 +89,13 @@ class Application extends \yii\base\Application
*/ */
public function processRequest() public function processRequest()
{ {
if (!isset($_SERVER['argv'])) { /** @var $request Request */
$request = $this->getRequest();
if ($request->getIsConsoleRequest()) {
return $this->runController($request->route, $request->params);
} else {
die('This script must be run from the command line.'); die('This script must be run from the command line.');
} }
list($route, $params) = $this->resolveRequest($_SERVER['argv']);
return $this->runController($route, $params);
} }
/** /**
...@@ -120,35 +122,6 @@ class Application extends \yii\base\Application ...@@ -120,35 +122,6 @@ class Application extends \yii\base\Application
} }
/** /**
* Resolves the request.
* @param array $args the arguments passed via the command line
* @return array the controller route and the parameters for the controller action
*/
protected function resolveRequest($args)
{
array_shift($args); // the 1st argument is the yiic script name
if (isset($args[0])) {
$route = $args[0];
array_shift($args);
} else {
$route = '';
}
$params = array();
foreach ($args as $arg) {
if (preg_match('/^--(\w+)(=(.*))?$/', $arg, $matches)) {
$name = $matches[1];
$params[$name] = isset($matches[3]) ? $matches[3] : true;
} else {
$params['args'][] = $arg;
}
}
return array($route, $params);
}
/**
* Returns the configuration of the built-in commands. * Returns the configuration of the built-in commands.
* @return array the configuration of the built-in commands. * @return array the configuration of the built-in commands.
*/ */
......
...@@ -20,7 +20,7 @@ use yii\base\Exception; ...@@ -20,7 +20,7 @@ use yii\base\Exception;
* The `yiic` program is used when calling a console command, like the following: * The `yiic` program is used when calling a console command, like the following:
* *
* ~~~ * ~~~
* yiic <route> [...options...] * yiic <route> [--param1=value1 --param2 ...]
* ~~~ * ~~~
* *
* @author Qiang Xue <qiang.xue@gmail.com> * @author Qiang Xue <qiang.xue@gmail.com>
...@@ -36,13 +36,14 @@ class Controller extends \yii\base\Controller ...@@ -36,13 +36,14 @@ class Controller extends \yii\base\Controller
*/ */
public function invalidActionParams($action, $exception) public function invalidActionParams($action, $exception)
{ {
echo "Error: " . $exception->getMessage() . "\n"; echo \Yii::t('yii', 'Error: {message}', array(
'{message}' => $exception->getMessage(),
));
\Yii::$application->end(1); \Yii::$application->end(1);
} }
/** /**
* This method is invoked when extra parameters are provided to an action when it is executed. * This method is invoked when extra parameters are provided to an action while it is executed.
* The default implementation does nothing.
* @param Action $action the action being executed * @param Action $action the action being executed
* @param array $expected the expected action parameters (name => value) * @param array $expected the expected action parameters (name => value)
* @param array $actual the actual action parameters (name => value) * @param array $actual the actual action parameters (name => value)
...@@ -53,7 +54,7 @@ class Controller extends \yii\base\Controller ...@@ -53,7 +54,7 @@ class Controller extends \yii\base\Controller
$keys = array_diff(array_keys($actual), array_keys($expected)); $keys = array_diff(array_keys($actual), array_keys($expected));
if (!empty($keys)) { if (!empty($keys)) {
echo "Error: " . \Yii::t('yii', 'Unknown parameters: {params}', array( echo \Yii::t('yii', 'Error: Unknown parameter(s): {params}', array(
'{params}' => implode(', ', $keys), '{params}' => implode(', ', $keys),
)) . "\n"; )) . "\n";
\Yii::$application->end(1); \Yii::$application->end(1);
......
<?php
/**
* Request class file.
*
* @link http://www.yiiframework.com/
* @copyright Copyright &copy; 2008-2012 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\console;
/**
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
class Request extends \yii\base\ApplicationComponent
{
/**
* @var string the controller route specified by this request. If this is an empty string,
* it means the [[Application::defaultRoute|default route]] will be used.
* Note that the value of this property may not be a correct route. The console application
* will determine it is valid or not when it attempts to execute with this route.
*/
public $route;
/**
* @var array
*/
public $params;
public function init()
{
parent::init();
$this->resolveRequest();
}
public function getRawParams()
{
return isset($_SERVER['argv']) ? $_SERVER['argv'] : array();
}
protected function resolveRequest()
{
$rawParams = $this->getRawParams();
array_shift($rawParams); // the 1st argument is the yiic script name
if (isset($rawParams[0])) {
$this->route = $rawParams[0];
array_shift($rawParams);
} else {
$this->route = '';
}
$this->params = array();
foreach ($rawParams as $param) {
if (preg_match('/^--(\w+)(=(.*))?$/', $param, $matches)) {
$name = $matches[1];
$this->params[$name] = isset($matches[3]) ? $matches[3] : true;
} else {
$this->params['--args'][] = $param;
}
}
}
}
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