201 lines
6.2 KiB
PHP
201 lines
6.2 KiB
PHP
|
<?php
|
||
|
/**
|
||
|
* CConsoleApplication class file.
|
||
|
*
|
||
|
* @author Qiang Xue <qiang.xue@gmail.com>
|
||
|
* @link http://www.yiiframework.com/
|
||
|
* @copyright 2008-2013 Yii Software LLC
|
||
|
* @license http://www.yiiframework.com/license/
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* CConsoleApplication represents a console application.
|
||
|
*
|
||
|
* CConsoleApplication extends {@link CApplication} by providing functionalities
|
||
|
* specific to console requests. In particular, it deals with console requests
|
||
|
* through a command-based approach:
|
||
|
* <ul>
|
||
|
* <li>A console application consists of one or several possible user commands;</li>
|
||
|
* <li>Each user command is implemented as a class extending {@link CConsoleCommand};</li>
|
||
|
* <li>User specifies which command to run on the command line;</li>
|
||
|
* <li>The command processes the user request with the specified parameters.</li>
|
||
|
* </ul>
|
||
|
*
|
||
|
* The command classes reside in the directory {@link getCommandPath commandPath}.
|
||
|
* The name of the class follows the pattern: <command-name>Command, and its
|
||
|
* file name is the same as the class name. For example, the 'ShellCommand' class defines
|
||
|
* a 'shell' command and the class file name is 'ShellCommand.php'.
|
||
|
*
|
||
|
* To run the console application, enter the following on the command line:
|
||
|
* <pre>
|
||
|
* php path/to/entry_script.php <command name> [param 1] [param 2] ...
|
||
|
* </pre>
|
||
|
*
|
||
|
* You may use the following to see help instructions about a command:
|
||
|
* <pre>
|
||
|
* php path/to/entry_script.php help <command name>
|
||
|
* </pre>
|
||
|
*
|
||
|
* @property string $commandPath The directory that contains the command classes. Defaults to 'protected/commands'.
|
||
|
* @property CConsoleCommandRunner $commandRunner The command runner.
|
||
|
* @property CConsoleCommand $command The currently active command.
|
||
|
*
|
||
|
* @author Qiang Xue <qiang.xue@gmail.com>
|
||
|
* @package system.console
|
||
|
* @since 1.0
|
||
|
*/
|
||
|
class CConsoleApplication extends CApplication
|
||
|
{
|
||
|
/**
|
||
|
* @var array mapping from command name to command configurations.
|
||
|
* Each command configuration can be either a string or an array.
|
||
|
* If the former, the string should be the file path of the command class.
|
||
|
* If the latter, the array must contain a 'class' element which specifies
|
||
|
* the command's class name or {@link YiiBase::getPathOfAlias class path alias}.
|
||
|
* The rest name-value pairs in the array are used to initialize
|
||
|
* the corresponding command properties. For example,
|
||
|
* <pre>
|
||
|
* array(
|
||
|
* 'email'=>array(
|
||
|
* 'class'=>'path.to.Mailer',
|
||
|
* 'interval'=>3600,
|
||
|
* ),
|
||
|
* 'log'=>'path/to/LoggerCommand.php',
|
||
|
* )
|
||
|
* </pre>
|
||
|
*/
|
||
|
public $commandMap=array();
|
||
|
|
||
|
private $_commandPath;
|
||
|
private $_runner;
|
||
|
|
||
|
/**
|
||
|
* Initializes the application by creating the command runner.
|
||
|
*/
|
||
|
protected function init()
|
||
|
{
|
||
|
parent::init();
|
||
|
if(!isset($_SERVER['argv'])) // || strncasecmp(php_sapi_name(),'cli',3))
|
||
|
die('This script must be run from the command line.');
|
||
|
$this->_runner=$this->createCommandRunner();
|
||
|
$this->_runner->commands=$this->commandMap;
|
||
|
$this->_runner->addCommands($this->getCommandPath());
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Processes the user request.
|
||
|
* This method uses a console command runner to handle the particular user command.
|
||
|
* Since version 1.1.11 this method will exit application with an exit code if one is returned by the user command.
|
||
|
*/
|
||
|
public function processRequest()
|
||
|
{
|
||
|
$exitCode=$this->_runner->run($_SERVER['argv']);
|
||
|
if(is_int($exitCode))
|
||
|
$this->end($exitCode);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Creates the command runner instance.
|
||
|
* @return CConsoleCommandRunner the command runner
|
||
|
*/
|
||
|
protected function createCommandRunner()
|
||
|
{
|
||
|
return new CConsoleCommandRunner;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Displays the captured PHP error.
|
||
|
* This method displays the error in console mode when there is
|
||
|
* no active error handler.
|
||
|
* @param integer $code error code
|
||
|
* @param string $message error message
|
||
|
* @param string $file error file
|
||
|
* @param string $line error line
|
||
|
*/
|
||
|
public function displayError($code,$message,$file,$line)
|
||
|
{
|
||
|
echo "PHP Error[$code]: $message\n";
|
||
|
echo " in file $file at line $line\n";
|
||
|
$trace=debug_backtrace();
|
||
|
// skip the first 4 stacks as they do not tell the error position
|
||
|
if(count($trace)>4)
|
||
|
$trace=array_slice($trace,4);
|
||
|
foreach($trace as $i=>$t)
|
||
|
{
|
||
|
if(!isset($t['file']))
|
||
|
$t['file']='unknown';
|
||
|
if(!isset($t['line']))
|
||
|
$t['line']=0;
|
||
|
if(!isset($t['function']))
|
||
|
$t['function']='unknown';
|
||
|
echo "#$i {$t['file']}({$t['line']}): ";
|
||
|
if(isset($t['object']) && is_object($t['object']))
|
||
|
echo get_class($t['object']).'->';
|
||
|
echo "{$t['function']}()\n";
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Displays the uncaught PHP exception.
|
||
|
* This method displays the exception in console mode when there is
|
||
|
* no active error handler.
|
||
|
* @param Exception $exception the uncaught exception
|
||
|
*/
|
||
|
public function displayException($exception)
|
||
|
{
|
||
|
echo $exception;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @return string the directory that contains the command classes. Defaults to 'protected/commands'.
|
||
|
*/
|
||
|
public function getCommandPath()
|
||
|
{
|
||
|
$applicationCommandPath = $this->getBasePath().DIRECTORY_SEPARATOR.'commands';
|
||
|
if($this->_commandPath===null && file_exists($applicationCommandPath))
|
||
|
$this->setCommandPath($applicationCommandPath);
|
||
|
return $this->_commandPath;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string $value the directory that contains the command classes.
|
||
|
* @throws CException if the directory is invalid
|
||
|
*/
|
||
|
public function setCommandPath($value)
|
||
|
{
|
||
|
if(($this->_commandPath=realpath($value))===false || !is_dir($this->_commandPath))
|
||
|
throw new CException(Yii::t('yii','The command path "{path}" is not a valid directory.',
|
||
|
array('{path}'=>$value)));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the command runner.
|
||
|
* @return CConsoleCommandRunner the command runner.
|
||
|
*/
|
||
|
public function getCommandRunner()
|
||
|
{
|
||
|
return $this->_runner;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the currently running command.
|
||
|
* This is shortcut method for {@link CConsoleCommandRunner::getCommand()}.
|
||
|
* @return CConsoleCommand|null the currently active command.
|
||
|
* @since 1.1.14
|
||
|
*/
|
||
|
public function getCommand()
|
||
|
{
|
||
|
return $this->getCommandRunner()->getCommand();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* This is shortcut method for {@link CConsoleCommandRunner::setCommand()}.
|
||
|
* @param CConsoleCommand $value the currently active command.
|
||
|
* @since 1.1.14
|
||
|
*/
|
||
|
public function setCommand($value)
|
||
|
{
|
||
|
$this->getCommandRunner()->setCommand($value);
|
||
|
}
|
||
|
}
|