Alexander Makarov
13 years ago
10 changed files with 1033 additions and 0 deletions
@ -0,0 +1,181 @@
|
||||
<?php |
||||
/** |
||||
* Console Application class file. |
||||
* |
||||
* @author Qiang Xue <qiang.xue@gmail.com> |
||||
* @link http://www.yiiframework.com/ |
||||
* @copyright Copyright © 2008-2012 Yii Software LLC |
||||
* @license http://www.yiiframework.com/license/ |
||||
*/ |
||||
|
||||
namespace yii\console; |
||||
|
||||
/** |
||||
* \yii\console\Application represents a console application. |
||||
* |
||||
* \yii\console\Application extends {@link \yii\base\Application} 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 \yii\console\Command};</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 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 CommandRunner $commandRunner The command runner. |
||||
* |
||||
* @author Qiang Xue <qiang.xue@gmail.com> |
||||
* @since 2.0 |
||||
*/ |
||||
class Application extends \yii\base\Application |
||||
{ |
||||
/** |
||||
* @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; |
||||
|
||||
/** |
||||
* @var \yii\console\CommandRunner |
||||
*/ |
||||
private $_runner; |
||||
|
||||
/** |
||||
* Initializes the application by creating the command runner. |
||||
*/ |
||||
public function init() |
||||
{ |
||||
if(!isset($_SERVER['argv'])) |
||||
{ |
||||
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 creates a console command runner to handle the particular user command. |
||||
*/ |
||||
public function processRequest() |
||||
{ |
||||
$this->_runner->run($_SERVER['argv']); |
||||
} |
||||
|
||||
/** |
||||
* Creates the command runner instance. |
||||
* @return CommandRunner the command runner |
||||
*/ |
||||
protected function createCommandRunner() |
||||
{ |
||||
return new CommandRunner(); |
||||
} |
||||
|
||||
/** |
||||
* 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 \yii\base\Exception(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; |
||||
} |
||||
} |
@ -0,0 +1,339 @@
|
||||
<?php |
||||
/** |
||||
* Command class file. |
||||
* |
||||
* @author Qiang Xue <qiang.xue@gmail.com> |
||||
* @link http://www.yiiframework.com/ |
||||
* @copyright Copyright © 2008-2011 Yii Software LLC |
||||
* @license http://www.yiiframework.com/license/ |
||||
*/ |
||||
|
||||
namespace yii\console; |
||||
|
||||
/** |
||||
* Command represents an executable console command. |
||||
* |
||||
* It works like {@link \yii\web\Controller} by parsing command line options and dispatching |
||||
* the request to a specific action with appropriate option values. |
||||
* |
||||
* Users call a console command via the following command format: |
||||
* <pre> |
||||
* yiic CommandName ActionName --Option1=Value1 --Option2=Value2 ... |
||||
* </pre> |
||||
* |
||||
* Child classes mainly needs to implement various action methods whose name must be |
||||
* prefixed with "action". The parameters to an action method are considered as options |
||||
* for that specific action. The action specified as {@link defaultAction} will be invoked |
||||
* when a user does not specify the action name in his command. |
||||
* |
||||
* Options are bound to action parameters via parameter names. For example, the following |
||||
* action method will allow us to run a command with <code>yiic sitemap --type=News</code>: |
||||
* <pre> |
||||
* class SitemapCommand { |
||||
* public function actionIndex($type) { |
||||
* .... |
||||
* } |
||||
* } |
||||
* </pre> |
||||
* |
||||
* @property string $name The command name. |
||||
* @property CommandRunner $commandRunner The command runner instance. |
||||
* @property string $help The command description. Defaults to 'Usage: php entry-script.php command-name'. |
||||
* @property array $optionHelp The command option help information. Each array element describes |
||||
* the help information for a single action. |
||||
* |
||||
* @author Qiang Xue <qiang.xue@gmail.com> |
||||
* @since 2.0 |
||||
*/ |
||||
abstract class Command extends \yii\base\Component |
||||
{ |
||||
/** |
||||
* @var string the name of the default action. Defaults to 'index'. |
||||
*/ |
||||
public $defaultAction='index'; |
||||
|
||||
private $_name; |
||||
private $_runner; |
||||
|
||||
/** |
||||
* Constructor. |
||||
* @param string $name name of the command |
||||
* @param CConsoleCommandRunner $runner the command runner |
||||
*/ |
||||
public function __construct($name,$runner) |
||||
{ |
||||
$this->_name=$name; |
||||
$this->_runner=$runner; |
||||
} |
||||
|
||||
/** |
||||
* Initializes the command object. |
||||
* This method is invoked after a command object is created and initialized with configurations. |
||||
* You may override this method to further customize the command before it executes. |
||||
*/ |
||||
public function init() |
||||
{ |
||||
} |
||||
|
||||
/** |
||||
* Executes the command. |
||||
* The default implementation will parse the input parameters and |
||||
* dispatch the command request to an appropriate action with the corresponding |
||||
* option values |
||||
* @param array $args command line parameters for this command. |
||||
*/ |
||||
public function run($args) |
||||
{ |
||||
list($action, $options, $args)=$this->resolveRequest($args); |
||||
$methodName='action'.$action; |
||||
if(!preg_match('/^\w+$/',$action) || !method_exists($this,$methodName)) |
||||
$this->usageError("Unknown action: ".$action); |
||||
|
||||
$method=new \ReflectionMethod($this,$methodName); |
||||
$params=array(); |
||||
// named and unnamed options |
||||
foreach($method->getParameters() as $param) |
||||
{ |
||||
$name=$param->getName(); |
||||
if(isset($options[$name])) |
||||
{ |
||||
if($param->isArray()) |
||||
$params[]=is_array($options[$name]) ? $options[$name] : array($options[$name]); |
||||
else if(!is_array($options[$name])) |
||||
$params[]=$options[$name]; |
||||
else |
||||
$this->usageError("Option --$name requires a scalar. Array is given."); |
||||
} |
||||
else if($name==='args') |
||||
$params[]=$args; |
||||
else if($param->isDefaultValueAvailable()) |
||||
$params[]=$param->getDefaultValue(); |
||||
else |
||||
$this->usageError("Missing required option --$name."); |
||||
unset($options[$name]); |
||||
} |
||||
|
||||
// try global options |
||||
if(!empty($options)) |
||||
{ |
||||
$class=new \ReflectionClass(get_class($this)); |
||||
foreach($options as $name=>$value) |
||||
{ |
||||
if($class->hasProperty($name)) |
||||
{ |
||||
$property=$class->getProperty($name); |
||||
if($property->isPublic() && !$property->isStatic()) |
||||
{ |
||||
$this->$name=$value; |
||||
unset($options[$name]); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
if(!empty($options)) |
||||
$this->usageError("Unknown options: ".implode(', ',array_keys($options))); |
||||
|
||||
if($this->beforeAction($action,$params)) |
||||
{ |
||||
$method->invokeArgs($this,$params); |
||||
$this->afterAction($action,$params); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* This method is invoked right before an action is to be executed. |
||||
* You may override this method to do last-minute preparation for the action. |
||||
* @param string $action the action name |
||||
* @param array $params the parameters to be passed to the action method. |
||||
* @return boolean whether the action should be executed. |
||||
*/ |
||||
protected function beforeAction($action,$params) |
||||
{ |
||||
return true; |
||||
} |
||||
|
||||
/** |
||||
* This method is invoked right after an action finishes execution. |
||||
* You may override this method to do some postprocessing for the action. |
||||
* @param string $action the action name |
||||
* @param array $params the parameters to be passed to the action method. |
||||
*/ |
||||
protected function afterAction($action,$params) |
||||
{ |
||||
} |
||||
|
||||
/** |
||||
* Parses the command line arguments and determines which action to perform. |
||||
* @param array $args command line arguments |
||||
* @return array the action name, named options (name=>value), and unnamed options |
||||
*/ |
||||
protected function resolveRequest($args) |
||||
{ |
||||
$options=array(); // named parameters |
||||
$params=array(); // unnamed parameters |
||||
foreach($args as $arg) |
||||
{ |
||||
if(preg_match('/^--(\w+)(=(.*))?$/',$arg,$matches)) // an option |
||||
{ |
||||
$name=$matches[1]; |
||||
$value=isset($matches[3]) ? $matches[3] : true; |
||||
if(isset($options[$name])) |
||||
{ |
||||
if(!is_array($options[$name])) |
||||
$options[$name]=array($options[$name]); |
||||
$options[$name][]=$value; |
||||
} |
||||
else |
||||
$options[$name]=$value; |
||||
} |
||||
else if(isset($action)) |
||||
$params[]=$arg; |
||||
else |
||||
$action=$arg; |
||||
} |
||||
if(!isset($action)) |
||||
$action=$this->defaultAction; |
||||
|
||||
return array($action,$options,$params); |
||||
} |
||||
|
||||
/** |
||||
* @return string the command name. |
||||
*/ |
||||
public function getName() |
||||
{ |
||||
return $this->_name; |
||||
} |
||||
|
||||
/** |
||||
* @return \yii\console\CommandRunner the command runner instance |
||||
*/ |
||||
public function getCommandRunner() |
||||
{ |
||||
return $this->_runner; |
||||
} |
||||
|
||||
/** |
||||
* Provides the command description. |
||||
* This method may be overridden to return the actual command description. |
||||
* @return string the command description. Defaults to 'Usage: php entry-script.php command-name'. |
||||
*/ |
||||
public function getHelp() |
||||
{ |
||||
$help='Usage: '.$this->getCommandRunner()->getScriptName().' '.$this->getName(); |
||||
$options=$this->getOptionHelp(); |
||||
if(empty($options)) |
||||
return $help; |
||||
if(count($options)===1) |
||||
return $help.' '.$options[0]; |
||||
$help.=" <action>\nActions:\n"; |
||||
foreach($options as $option) |
||||
$help.=' '.$option."\n"; |
||||
return $help; |
||||
} |
||||
|
||||
/** |
||||
* Provides the command option help information. |
||||
* The default implementation will return all available actions together with their |
||||
* corresponding option information. |
||||
* @return array the command option help information. Each array element describes |
||||
* the help information for a single action. |
||||
*/ |
||||
public function getOptionHelp() |
||||
{ |
||||
$options=array(); |
||||
$class=new \ReflectionClass(get_class($this)); |
||||
foreach($class->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) |
||||
{ |
||||
$name=$method->getName(); |
||||
if(!strncasecmp($name,'action',6) && strlen($name)>6) |
||||
{ |
||||
$name=substr($name,6); |
||||
$name[0]=strtolower($name[0]); |
||||
$help=$name; |
||||
|
||||
foreach($method->getParameters() as $param) |
||||
{ |
||||
$optional=$param->isDefaultValueAvailable(); |
||||
$defaultValue=$optional ? $param->getDefaultValue() : null; |
||||
$name=$param->getName(); |
||||
if($optional) |
||||
$help.=" [--$name=$defaultValue]"; |
||||
else |
||||
$help.=" --$name=value"; |
||||
} |
||||
$options[]=$help; |
||||
} |
||||
} |
||||
return $options; |
||||
} |
||||
|
||||
/** |
||||
* Displays a usage error. |
||||
* This method will then terminate the execution of the current application. |
||||
* @param string $message the error message |
||||
*/ |
||||
public function usageError($message) |
||||
{ |
||||
echo "Error: $message\n\n".$this->getHelp()."\n"; |
||||
exit(1); |
||||
} |
||||
|
||||
/** |
||||
* Renders a view file. |
||||
* @param string $_viewFile_ view file path |
||||
* @param array $_data_ optional data to be extracted as local view variables |
||||
* @param boolean $_return_ whether to return the rendering result instead of displaying it |
||||
* @return mixed the rendering result if required. Null otherwise. |
||||
*/ |
||||
public function renderFile($_viewFile_,$_data_=null,$_return_=false) |
||||
{ |
||||
if(is_array($_data_)) |
||||
extract($_data_,EXTR_PREFIX_SAME,'data'); |
||||
else |
||||
$data=$_data_; |
||||
if($_return_) |
||||
{ |
||||
ob_start(); |
||||
ob_implicit_flush(false); |
||||
require($_viewFile_); |
||||
return ob_get_clean(); |
||||
} |
||||
else |
||||
require($_viewFile_); |
||||
} |
||||
|
||||
/** |
||||
* Reads input via the readline PHP extension if that's available, or fgets() if readline is not installed. |
||||
* |
||||
* @param string $message to echo out before waiting for user input |
||||
* @return mixed line read as a string, or false if input has been closed |
||||
*/ |
||||
public function prompt($message) |
||||
{ |
||||
if(extension_loaded('readline')) |
||||
{ |
||||
$input = readline($message.' '); |
||||
readline_add_history($input); |
||||
return $input; |
||||
} |
||||
else |
||||
{ |
||||
echo $message.' '; |
||||
return trim(fgets(STDIN)); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Asks user to confirm by typing y or n. |
||||
* |
||||
* @param string $message to echo out before waiting for user input |
||||
* @return bool if user confirmed |
||||
*/ |
||||
public function confirm($message) |
||||
{ |
||||
echo $message.' [yes|no] '; |
||||
return !strncasecmp(trim(fgets(STDIN)),'y',1); |
||||
} |
||||
} |
@ -0,0 +1,144 @@
|
||||
<?php |
||||
/** |
||||
* CConsoleCommandRunner class file. |
||||
* |
||||
* @author Qiang Xue <qiang.xue@gmail.com> |
||||
* @link http://www.yiiframework.com/ |
||||
* @copyright Copyright © 2008-2011 Yii Software LLC |
||||
* @license http://www.yiiframework.com/license/ |
||||
*/ |
||||
|
||||
namespace yii\console; |
||||
|
||||
/** |
||||
* CConsoleCommandRunner manages commands and executes the requested command. |
||||
* |
||||
* @property string $scriptName The entry script name. |
||||
* |
||||
* @author Qiang Xue <qiang.xue@gmail.com> |
||||
* @version $Id: CConsoleCommandRunner.php 3426 2011-10-25 00:01:09Z alexander.makarow $ |
||||
* @package system.console |
||||
* @since 2.0 |
||||
*/ |
||||
class CommandRunner extends \yii\base\Component |
||||
{ |
||||
/** |
||||
* @var array list of all available commands (command name=>command configuration). |
||||
* Each command configuration can be either a string or an array. |
||||
* If the former, the string should be the class name or |
||||
* {@link YiiBase::getPathOfAlias class path alias} of the command. |
||||
* 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', |
||||
* ) |
||||
* </pre> |
||||
*/ |
||||
public $commands=array(); |
||||
|
||||
private $_scriptName; |
||||
|
||||
/** |
||||
* Executes the requested command. |
||||
* @param array $args list of user supplied parameters (including the entry script name and the command name). |
||||
*/ |
||||
public function run($args) |
||||
{ |
||||
$this->_scriptName=$args[0]; |
||||
array_shift($args); |
||||
if(isset($args[0])) |
||||
{ |
||||
$name=$args[0]; |
||||
array_shift($args); |
||||
} |
||||
else |
||||
$name='help'; |
||||
|
||||
if(($command=$this->createCommand($name))===null) |
||||
$command=$this->createCommand('help'); |
||||
$command->init(); |
||||
$command->run($args); |
||||
} |
||||
|
||||
/** |
||||
* @return string the entry script name |
||||
*/ |
||||
public function getScriptName() |
||||
{ |
||||
return $this->_scriptName; |
||||
} |
||||
|
||||
/** |
||||
* Searches for commands under the specified directory. |
||||
* @param string $path the directory containing the command class files. |
||||
* @return array list of commands (command name=>command class file) |
||||
*/ |
||||
public function findCommands($path) |
||||
{ |
||||
if(($dir=@opendir($path))===false) |
||||
return array(); |
||||
$commands=array(); |
||||
while(($name=readdir($dir))!==false) |
||||
{ |
||||
$file=$path.DIRECTORY_SEPARATOR.$name; |
||||
if(!strcasecmp(substr($name,-11),'Command.php') && is_file($file)) |
||||
$commands[strtolower(substr($name,0,-11))]=$file; |
||||
} |
||||
closedir($dir); |
||||
return $commands; |
||||
} |
||||
|
||||
/** |
||||
* Adds commands from the specified command path. |
||||
* If a command already exists, the new one will be ignored. |
||||
* @param string $path the alias of the directory containing the command class files. |
||||
*/ |
||||
public function addCommands($path) |
||||
{ |
||||
if(($commands=$this->findCommands($path))!==array()) |
||||
{ |
||||
foreach($commands as $name=>$file) |
||||
{ |
||||
if(!isset($this->commands[$name])) |
||||
$this->commands[$name]=$file; |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* @param string $name command name (case-insensitive) |
||||
* @return \yii\console\Command the command object. Null if the name is invalid. |
||||
*/ |
||||
public function createCommand($name) |
||||
{ |
||||
$name=strtolower($name); |
||||
if(isset($this->commands[$name])) |
||||
{ |
||||
if(is_string($this->commands[$name])) // class file path or alias |
||||
{ |
||||
if(strpos($this->commands[$name],'/')!==false || strpos($this->commands[$name],'\\')!==false) |
||||
{ |
||||
$className=substr(basename($this->commands[$name]),0,-4); |
||||
if(!class_exists($className,false)) |
||||
require_once($this->commands[$name]); |
||||
} |
||||
else // an alias |
||||
$className=\Yii::import($this->commands[$name]); |
||||
return new $className($name,$this); |
||||
} |
||||
else // an array configuration |
||||
return \Yii::create($this->commands[$name],$name,$this); |
||||
} |
||||
else if($name==='help') |
||||
return new HelpCommand('help',$this); |
||||
else |
||||
return null; |
||||
} |
||||
} |
@ -0,0 +1,79 @@
|
||||
<?php |
||||
/** |
||||
* CHelpCommand class file. |
||||
* |
||||
* @author Qiang Xue <qiang.xue@gmail.com> |
||||
* @link http://www.yiiframework.com/ |
||||
* @copyright Copyright © 2008-2011 Yii Software LLC |
||||
* @license http://www.yiiframework.com/license/ |
||||
*/ |
||||
|
||||
namespace yii\console; |
||||
|
||||
/** |
||||
* CHelpCommand represents a console help command. |
||||
* |
||||
* CHelpCommand displays the available command list or the help instructions |
||||
* about a specific command. |
||||
* |
||||
* To use this command, enter the following on the command line: |
||||
* <pre> |
||||
* php path/to/entry_script.php help [command name] |
||||
* </pre> |
||||
* In the above, if the command name is not provided, it will display all |
||||
* available commands. |
||||
* |
||||
* @property string $help The command description. |
||||
* |
||||
* @author Qiang Xue <qiang.xue@gmail.com> |
||||
* @version $Id: CHelpCommand.php 3426 2011-10-25 00:01:09Z alexander.makarow $ |
||||
* @package system.console |
||||
* @since 2.0 |
||||
*/ |
||||
class HelpCommand extends Command |
||||
{ |
||||
/** |
||||
* Execute the action. |
||||
* @param array $args command line parameters specific for this command |
||||
*/ |
||||
public function run($args) |
||||
{ |
||||
$runner=$this->getCommandRunner(); |
||||
$commands=$runner->commands; |
||||
if(isset($args[0])) |
||||
{ |
||||
$name=strtolower($args[0]); |
||||
} |
||||
if(!isset($args[0]) || !isset($commands[$name])) |
||||
{ |
||||
if(!empty($commands)) |
||||
{ |
||||
echo "Yii command runner (based on Yii v".\Yii::getVersion().")\n"; |
||||
echo "Usage: ".$runner->getScriptName()." <command-name> [parameters...]\n"; |
||||
echo "\nThe following commands are available:\n"; |
||||
$commandNames=array_keys($commands); |
||||
sort($commandNames); |
||||
echo ' - '.implode("\n - ",$commandNames); |
||||
echo "\n\nTo see individual command help, use the following:\n"; |
||||
echo " ".$runner->getScriptName()." help <command-name>\n"; |
||||
} |
||||
else |
||||
{ |
||||
echo "No available commands.\n"; |
||||
echo "Please define them under the following directory:\n"; |
||||
echo "\t".\Yii::$app->getCommandPath()."\n"; |
||||
} |
||||
} |
||||
else |
||||
echo $runner->createCommand($name)->getHelp(); |
||||
} |
||||
|
||||
/** |
||||
* Provides the command description. |
||||
* @return string the command description. |
||||
*/ |
||||
public function getHelp() |
||||
{ |
||||
return parent::getHelp().' [command-name]'; |
||||
} |
||||
} |
@ -0,0 +1,141 @@
|
||||
<?php |
||||
/** |
||||
* Filesystem helper class file. |
||||
* |
||||
* @author Qiang Xue <qiang.xue@gmail.com> |
||||
* @author Alex Makarov <sam@rmcreative.ru> |
||||
* @link http://www.yiiframework.com/ |
||||
* @copyright Copyright © 2008-2012 Yii Software LLC |
||||
* @license http://www.yiiframework.com/license/ |
||||
*/ |
||||
|
||||
namespace yii\util; |
||||
|
||||
/** |
||||
* Filesystem helper |
||||
* |
||||
* @since 2.0 |
||||
*/ |
||||
class File |
||||
{ |
||||
/** |
||||
* Copies a list of files from one place to another. |
||||
* @param array $fileList the list of files to be copied (name=>spec). |
||||
* The array keys are names displayed during the copy process, and array values are specifications |
||||
* for files to be copied. Each array value must be an array of the following structure: |
||||
* <ul> |
||||
* <li>source: required, the full path of the file/directory to be copied from</li> |
||||
* <li>target: required, the full path of the file/directory to be copied to</li> |
||||
* <li>callback: optional, the callback to be invoked when copying a file. The callback function |
||||
* should be declared as follows: |
||||
* <pre> |
||||
* function foo($source,$params) |
||||
* </pre> |
||||
* where $source parameter is the source file path, and the content returned |
||||
* by the function will be saved into the target file.</li> |
||||
* <li>params: optional, the parameters to be passed to the callback</li> |
||||
* </ul> |
||||
* @see buildFileList |
||||
*/ |
||||
public function copyFiles($fileList) |
||||
{ |
||||
$overwriteAll=false; |
||||
foreach($fileList as $name=>$file) |
||||
{ |
||||
$source=strtr($file['source'],'/\\',DIRECTORY_SEPARATOR); |
||||
$target=strtr($file['target'],'/\\',DIRECTORY_SEPARATOR); |
||||
$callback=isset($file['callback']) ? $file['callback'] : null; |
||||
$params=isset($file['params']) ? $file['params'] : null; |
||||
|
||||
if(is_dir($source)) |
||||
{ |
||||
$this->ensureDirectory($target); |
||||
continue; |
||||
} |
||||
|
||||
if($callback!==null) |
||||
$content=call_user_func($callback,$source,$params); |
||||
else |
||||
$content=file_get_contents($source); |
||||
if(is_file($target)) |
||||
{ |
||||
if($content===file_get_contents($target)) |
||||
{ |
||||
echo " unchanged $name\n"; |
||||
continue; |
||||
} |
||||
if($overwriteAll) |
||||
echo " overwrite $name\n"; |
||||
else |
||||
{ |
||||
echo " exist $name\n"; |
||||
echo " ...overwrite? [Yes|No|All|Quit] "; |
||||
$answer=trim(fgets(STDIN)); |
||||
if(!strncasecmp($answer,'q',1)) |
||||
return; |
||||
else if(!strncasecmp($answer,'y',1)) |
||||
echo " overwrite $name\n"; |
||||
else if(!strncasecmp($answer,'a',1)) |
||||
{ |
||||
echo " overwrite $name\n"; |
||||
$overwriteAll=true; |
||||
} |
||||
else |
||||
{ |
||||
echo " skip $name\n"; |
||||
continue; |
||||
} |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
$this->ensureDirectory(dirname($target)); |
||||
echo " generate $name\n"; |
||||
} |
||||
file_put_contents($target,$content); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Builds the file list of a directory. |
||||
* This method traverses through the specified directory and builds |
||||
* a list of files and subdirectories that the directory contains. |
||||
* The result of this function can be passed to {@link copyFiles}. |
||||
* @param string $sourceDir the source directory |
||||
* @param string $targetDir the target directory |
||||
* @param string $baseDir base directory |
||||
* @return array the file list (see {@link copyFiles}) |
||||
*/ |
||||
public function buildFileList($sourceDir, $targetDir, $baseDir='') |
||||
{ |
||||
$list=array(); |
||||
$handle=opendir($sourceDir); |
||||
while(($file=readdir($handle))!==false) |
||||
{ |
||||
if($file==='.' || $file==='..' || $file==='.svn' ||$file==='.yii') |
||||
continue; |
||||
$sourcePath=$sourceDir.DIRECTORY_SEPARATOR.$file; |
||||
$targetPath=$targetDir.DIRECTORY_SEPARATOR.$file; |
||||
$name=$baseDir===''?$file : $baseDir.'/'.$file; |
||||
$list[$name]=array('source'=>$sourcePath, 'target'=>$targetPath); |
||||
if(is_dir($sourcePath)) |
||||
$list=array_merge($list,$this->buildFileList($sourcePath,$targetPath,$name)); |
||||
} |
||||
closedir($handle); |
||||
return $list; |
||||
} |
||||
|
||||
/** |
||||
* Creates all parent directories if they do not exist. |
||||
* @param string $directory the directory to be checked |
||||
*/ |
||||
public function ensureDirectory($directory) |
||||
{ |
||||
if(!is_dir($directory)) |
||||
{ |
||||
$this->ensureDirectory(dirname($directory)); |
||||
echo " mkdir ".strtr($directory,'\\','/')."\n"; |
||||
mkdir($directory); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,43 @@
|
||||
<?php |
||||
/** |
||||
* Text helper class file. |
||||
* |
||||
* @author Qiang Xue <qiang.xue@gmail.com> |
||||
* @author Alex Makarov <sam@rmcreative.ru> |
||||
* @link http://www.yiiframework.com/ |
||||
* @copyright Copyright © 2008-2012 Yii Software LLC |
||||
* @license http://www.yiiframework.com/license/ |
||||
*/ |
||||
|
||||
namespace yii\util; |
||||
|
||||
/** |
||||
* Text helper |
||||
* |
||||
* @since 2.0 |
||||
*/ |
||||
class Text |
||||
{ |
||||
/** |
||||
* Converts a word to its plural form. |
||||
* @param string $name the word to be pluralized |
||||
* @return string the pluralized word |
||||
*/ |
||||
public function pluralize($name) |
||||
{ |
||||
$rules=array( |
||||
'/(x|ch|ss|sh|us|as|is|os)$/i' => '\1es', |
||||
'/(?:([^f])fe|([lr])f)$/i' => '\1\2ves', |
||||
'/(m)an$/i' => '\1en', |
||||
'/(child)$/i' => '\1ren', |
||||
'/(r)y$/i' => '\1ies', |
||||
'/s$/' => 's', |
||||
); |
||||
foreach($rules as $rule=>$replacement) |
||||
{ |
||||
if(preg_match($rule,$name)) |
||||
return preg_replace($rule,$replacement,$name); |
||||
} |
||||
return $name.'s'; |
||||
} |
||||
} |
@ -0,0 +1,40 @@
|
||||
<?php |
||||
/** |
||||
* HttpException class file. |
||||
* |
||||
* @author Qiang Xue <qiang.xue@gmail.com> |
||||
* @link http://www.yiiframework.com/ |
||||
* @copyright Copyright © 2008-2012 Yii Software LLC |
||||
* @license http://www.yiiframework.com/license/ |
||||
*/ |
||||
|
||||
namespace yii\web; |
||||
|
||||
/** |
||||
* CHttpException represents an exception caused by invalid operations of end-users. |
||||
* |
||||
* The HTTP error code can be obtained via {@link statusCode}. |
||||
* Error handlers may use this status code to decide how to format the error page. |
||||
* |
||||
* @author Qiang Xue <qiang.xue@gmail.com> |
||||
* @since 2.0 |
||||
*/ |
||||
class HttpException extends \yii\base\Exception |
||||
{ |
||||
/** |
||||
* @var integer HTTP status code, such as 403, 404, 500, etc. |
||||
*/ |
||||
public $statusCode; |
||||
|
||||
/** |
||||
* Constructor. |
||||
* @param integer $status HTTP status code, such as 404, 500, etc. |
||||
* @param string $message error message |
||||
* @param integer $code error code |
||||
*/ |
||||
public function __construct($status,$message=null,$code=0) |
||||
{ |
||||
$this->statusCode=$status; |
||||
parent::__construct($message,$code); |
||||
} |
||||
} |
@ -0,0 +1,14 @@
|
||||
#!/usr/bin/env php |
||||
<?php |
||||
/** |
||||
* Yii command line script for Unix/Linux. |
||||
* |
||||
* This is the bootstrap script for running yiic on Unix/Linux. |
||||
* |
||||
* @author Qiang Xue <qiang.xue@gmail.com> |
||||
* @link http://www.yiiframework.com/ |
||||
* @copyright Copyright © 2012 Yii Software LLC |
||||
* @license http://www.yiiframework.com/license/ |
||||
*/ |
||||
|
||||
require_once(__DIR__.'/yiic.php'); |
@ -0,0 +1,22 @@
|
||||
@echo off |
||||
|
||||
rem ------------------------------------------------------------- |
||||
rem Yii command line script for Windows. |
||||
rem |
||||
rem This is the bootstrap script for running yiic on Windows. |
||||
rem |
||||
rem @author Qiang Xue <qiang.xue@gmail.com> |
||||
rem @link http://www.yiiframework.com/ |
||||
rem @copyright Copyright © 2012 Yii Software LLC |
||||
rem @license http://www.yiiframework.com/license/ |
||||
rem ------------------------------------------------------------- |
||||
|
||||
@setlocal |
||||
|
||||
set YII_PATH=%~dp0 |
||||
|
||||
if "%PHP_COMMAND%" == "" set PHP_COMMAND=php.exe |
||||
|
||||
"%PHP_COMMAND%" "%YII_PATH%yiic" %* |
||||
|
||||
@endlocal |
@ -0,0 +1,30 @@
|
||||
<?php |
||||
/** |
||||
* Yii console bootstrap file. |
||||
* |
||||
* @link http://www.yiiframework.com/ |
||||
* @copyright Copyright © 2008-2012 Yii Software LLC |
||||
* @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'); |
||||
|
||||
if(isset($config)) |
||||
{ |
||||
$app=new \yii\console\Application($config); |
||||
$app->commandRunner->addCommands(YII_PATH.'/cli/commands'); |
||||
$env=@getenv('YII_CONSOLE_COMMANDS'); |
||||
if(!empty($env)) |
||||
$app->commandRunner->addCommands($env); |
||||
} |
||||
else |
||||
{ |
||||
$app=new \yii\console\Application(array( |
||||
'basePath'=>__DIR__.'/cli', |
||||
)); |
||||
} |
||||
|
||||
$app->run(); |
Loading…
Reference in new issue