CommandRunner.php 3.73 KB
Newer Older
Alexander Makarov committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
<?php
/**
 * CConsoleCommandRunner class file.
 *
 * @author Qiang Xue <qiang.xue@gmail.com>
 * @link http://www.yiiframework.com/
 * @copyright Copyright &copy; 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>
 * @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);
Qiang Xue committed
58
		} else
Alexander Makarov committed
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
			$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]);
Qiang Xue committed
128
				} else // an alias
Alexander Makarov committed
129 130
					$className=\Yii::import($this->commands[$name]);
				return new $className($name,$this);
Qiang Xue committed
131
			} else // an array configuration
Alexander Makarov committed
132
				return \Yii::create($this->commands[$name],$name,$this);
Qiang Xue committed
133
		} else if($name==='help')
Alexander Makarov committed
134 135 136 137 138
			return new HelpCommand('help',$this);
		else
			return null;
	}
}