0 follower

CConsoleCommand

Package system.console
Inheritance abstract class CConsoleCommand » CComponent
Subclasses CHelpCommand
Since 1.0
Source Code framework/console/CConsoleCommand.php
CConsoleCommand represents an executable console command.

It works like CController 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:
yiic CommandName ActionName --Option1=Value1 --Option2=Value2 ...


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 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 yiic sitemap --type=News:
class SitemapCommand extends CConsoleCommand {
    public function actionIndex($type) {
        ....
    }
}


Since version 1.1.11 the return value of action methods will be used as application exit code if it is an integer value.

Public Properties

Hide inherited properties

PropertyTypeDescriptionDefined By
commandRunner CConsoleCommandRunner the command runner instance CConsoleCommand
defaultAction string the name of the default action. CConsoleCommand
help string Provides the command description. CConsoleCommand
name string the command name. CConsoleCommand
optionHelp array Provides the command option help information. CConsoleCommand

Public Methods

Hide inherited methods

MethodDescriptionDefined By
__call() Calls the named method which is not a class method. CComponent
__construct() Constructor. CConsoleCommand
__get() Returns a property value, an event handler list or a behavior based on its name. CComponent
__isset() Checks if a property value is null. CComponent
__set() Sets value of a component property. CComponent
__unset() Sets a component property to be null. CComponent
asa() Returns the named behavior object. CComponent
attachBehavior() Attaches a behavior to this component. CComponent
attachBehaviors() Attaches a list of behaviors to the component. CComponent
attachEventHandler() Attaches an event handler to an event. CComponent
behaviors() Returns a list of behaviors that this command should behave as. CConsoleCommand
buildFileList() Builds the file list of a directory. CConsoleCommand
canGetProperty() Determines whether a property can be read. CComponent
canSetProperty() Determines whether a property can be set. CComponent
confirm() Asks user to confirm by typing y or n. CConsoleCommand
copyFiles() Copies a list of files from one place to another. CConsoleCommand
detachBehavior() Detaches a behavior from the component. CComponent
detachBehaviors() Detaches all behaviors from the component. CComponent
detachEventHandler() Detaches an existing event handler. CComponent
disableBehavior() Disables an attached behavior. CComponent
disableBehaviors() Disables all behaviors attached to this component. CComponent
enableBehavior() Enables an attached behavior. CComponent
enableBehaviors() Enables all behaviors attached to this component. CComponent
ensureDirectory() Creates all parent directories if they do not exist. CConsoleCommand
evaluateExpression() Evaluates a PHP expression or callback under the context of this component. CComponent
getCommandRunner() Returns the command runner instance CConsoleCommand
getEventHandlers() Returns the list of attached event handlers for an event. CComponent
getHelp() Provides the command description. CConsoleCommand
getName() Returns the command name. CConsoleCommand
getOptionHelp() Provides the command option help information. CConsoleCommand
hasEvent() Determines whether an event is defined. CComponent
hasEventHandler() Checks whether the named event has attached handlers. CComponent
hasProperty() Determines whether a property is defined. CComponent
init() Initializes the command object. CConsoleCommand
onAfterAction() This event is raised after an action finishes execution. CConsoleCommand
onBeforeAction() This event is raised before an action is to be executed. CConsoleCommand
pluralize() Converts a word to its plural form. CConsoleCommand
prompt() Reads input via the readline PHP extension if that's available, or fgets() if readline is not installed. CConsoleCommand
raiseEvent() Raises an event. CComponent
renderFile() Renders a view file. CConsoleCommand
run() Executes the command. CConsoleCommand
usageError() Displays a usage error. CConsoleCommand

Protected Methods

Hide inherited methods

MethodDescriptionDefined By
afterAction() This method is invoked right after an action finishes execution. CConsoleCommand
beforeAction() This method is invoked right before an action is to be executed. CConsoleCommand
resolveRequest() Parses the command line arguments and determines which action to perform. CConsoleCommand

Events

Hide inherited events

EventDescriptionDefined By
onBeforeAction This event is raised before an action is to be executed. CConsoleCommand
onAfterAction This event is raised after an action finishes execution. CConsoleCommand

Property Details

commandRunner property read-only

the command runner instance

defaultAction property (available since v1.1.5)
public string $defaultAction;

the name of the default action. Defaults to 'index'.

help property read-only
public string getHelp()

Provides the command description. This method may be overridden to return the actual command description.

name property read-only
public string getName()

the command name.

optionHelp property read-only (available since v1.1.5)
public array getOptionHelp()

Provides the command option help information. The default implementation will return all available actions together with their corresponding option information.

Method Details

__construct() method
public void __construct(string $name, CConsoleCommandRunner $runner)
$name string name of the command
$runner CConsoleCommandRunner the command runner
Source Code: framework/console/CConsoleCommand.php#65 (show)
public function __construct($name,$runner)
{
    
$this->_name=$name;
    
$this->_runner=$runner;
    
$this->attachBehaviors($this->behaviors());
}

Constructor.

afterAction() method
protected integer afterAction(string $action, array $params, integer $exitCode=0)
$action string the action name
$params array the parameters to be passed to the action method.
$exitCode integer the application exit code returned by the action method.
{return} integer application exit code (return value is available since version 1.1.11)
Source Code: framework/console/CConsoleCommand.php#213 (show)
protected function afterAction($action,$params,$exitCode=0)
{
    
$event=new CConsoleCommandEvent($this,$params,$action,$exitCode);
    if(
$this->hasEventHandler('onAfterAction'))
        
$this->onAfterAction($event);
    return 
$event->exitCode;
}

This method is invoked right after an action finishes execution. You may override this method to do some postprocessing for the action.

beforeAction() method
protected boolean beforeAction(string $action, array $params)
$action string the action name
$params array the parameters to be passed to the action method.
{return} boolean whether the action should be executed.
Source Code: framework/console/CConsoleCommand.php#191 (show)
protected function beforeAction($action,$params)
{
    if(
$this->hasEventHandler('onBeforeAction'))
    {
        
$event = new CConsoleCommandEvent($this,$params,$action);
        
$this->onBeforeAction($event);
        return !
$event->stopCommand;
    }
    else
    {
        return 
true;
    }
}

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.

behaviors() method (available since v1.1.11)
public array behaviors()
{return} array the behavior configurations (behavior name=>behavior configuration)
Source Code: framework/console/CConsoleCommand.php#103 (show)
public function behaviors()
{
    return array();
}

Returns a list of behaviors that this command should behave as. The return value should be an array of behavior configurations indexed by behavior names. Each behavior configuration can be either a string specifying the behavior class or an array of the following structure:

'behaviorName'=>array(
    'class'=>'path.to.BehaviorClass',
    'property1'=>'value1',
    'property2'=>'value2',
)


Note, the behavior classes must implement IBehavior or extend from CBehavior. Behaviors declared in this method will be attached to the controller when it is instantiated.

For more details about behaviors, see CComponent.
buildFileList() method
public array buildFileList(string $sourceDir, string $targetDir, string $baseDir='', array $ignoreFiles=array ( ), array $renameMap=array ( ))
$sourceDir string the source directory
$targetDir string the target directory
$baseDir string base directory
$ignoreFiles array list of the names of files that should be ignored in list building process. Argument available since 1.1.11.
$renameMap array hash array of file names that should be renamed. Example value: array('1.old.txt'=>'2.new.txt'). Argument available since 1.1.11.
{return} array the file list (see copyFiles)
Source Code: framework/console/CConsoleCommand.php#440 (show)
public function buildFileList($sourceDir$targetDir$baseDir=''$ignoreFiles=array(), $renameMap=array())
{
    
$list=array();
    
$handle=opendir($sourceDir);
    while((
$file=readdir($handle))!==false)
    {
        if(
in_array($file,array('.','..','.svn','.gitignore')) || in_array($file,$ignoreFiles))
            continue;
        
$sourcePath=$sourceDir.DIRECTORY_SEPARATOR.$file;
        
$targetPath=$targetDir.DIRECTORY_SEPARATOR.strtr($file,$renameMap);
        
$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,$ignoreFiles,$renameMap));
    }
    
closedir($handle);
    return 
$list;
}

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 copyFiles.

confirm() method (available since v1.1.9)
public boolean confirm(string $message, boolean $default=false)
$message string to echo out before waiting for user input
$default boolean this value is returned if no selection is made. This parameter has been available since version 1.1.11.
{return} boolean whether user confirmed
Source Code: framework/console/CConsoleCommand.php#578 (show)
public function confirm($message,$default=false)
{
    echo 
$message.' (yes|no) [' . ($default 'yes' 'no') . ']:';

    
$input trim(fgets(STDIN));
    return empty(
$input) ? $default : !strncasecmp($input,'y',1);
}

Asks user to confirm by typing y or n.

copyFiles() method
public void copyFiles(array $fileList, boolean $overwriteAll=false)
$fileList array 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:
  • source: required, the full path of the file/directory to be copied from
  • target: required, the full path of the file/directory to be copied to
  • callback: optional, the callback to be invoked when copying a file. The callback function should be declared as follows:
      function foo($source,$params)
      
    where $source parameter is the source file path, and the content returned by the function will be saved into the target file.
  • params: optional, the parameters to be passed to the callback
$overwriteAll boolean whether to overwrite all files.
Source Code: framework/console/CConsoleCommand.php#367 (show)
public function copyFiles($fileList,$overwriteAll=false)
{
    foreach(
$fileList as $name=>$file)
    {
        
$source=strtr($file['source'],'/\\',DIRECTORY_SEPARATOR.DIRECTORY_SEPARATOR);
        
$target=strtr($file['target'],'/\\',DIRECTORY_SEPARATOR.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;
                elseif(!
strncasecmp($answer,'y',1))
                    echo 
"  overwrite $name\n";
                elseif(!
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);
    }
}

Copies a list of files from one place to another.

See Also

ensureDirectory() method
public void ensureDirectory(string $directory)
$directory string the directory to be checked
Source Code: framework/console/CConsoleCommand.php#463 (show)
public function ensureDirectory($directory)
{
    if(!
is_dir($directory))
    {
        
$this->ensureDirectory(dirname($directory));
        echo 
"      mkdir ".strtr($directory,'\\','/')."\n";
        
mkdir($directory);
    }
}

Creates all parent directories if they do not exist.

getCommandRunner() method
public CConsoleCommandRunner getCommandRunner()
{return} CConsoleCommandRunner the command runner instance
Source Code: framework/console/CConsoleCommand.php#268 (show)
public function getCommandRunner()
{
    return 
$this->_runner;
}

getHelp() method
public string getHelp()
{return} string the command description. Defaults to 'Usage: php entry-script.php command-name'.
Source Code: framework/console/CConsoleCommand.php#278 (show)
public function getHelp()
{
    
$help='Usage: '.$this->getCommandRunner()->getScriptName().' '.$this->getName();
    
$options=$this->getOptionHelp();
    if(empty(
$options))
        return 
$help."\n";
    if(
count($options)===1)
        return 
$help.' '.$options[0]."\n";
    
$help.=" <action>\nActions:\n";
    foreach(
$options as $option)
        
$help.='    '.$option."\n";
    return 
$help;
}

Provides the command description. This method may be overridden to return the actual command description.

getName() method
public string getName()
{return} string the command name.
Source Code: framework/console/CConsoleCommand.php#260 (show)
public function getName()
{
    return 
$this->_name;
}

getOptionHelp() method (available since v1.1.5)
public array getOptionHelp()
{return} array the command option help information. Each array element describes the help information for a single action.
Source Code: framework/console/CConsoleCommand.php#300 (show)
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;
                if(
is_array($defaultValue)) {
                    
$defaultValue str_replace(array("\r\n""\n""\r"), ""print_r($defaultValuetrue));
                }
                
$name=$param->getName();

                if(
$name==='args')
                    continue;

                if(
$optional)
                    
$help.=" [--$name=$defaultValue]";
                else
                    
$help.=" --$name=value";
            }
            
$options[]=$help;
        }
    }
    return 
$options;
}

Provides the command option help information. The default implementation will return all available actions together with their corresponding option information.

init() method (available since v1.1.6)
public void init()
Source Code: framework/console/CConsoleCommand.php#78 (show)
public function init()
{
}

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.

onAfterAction() method (available since v1.1.11)
public void onAfterAction(CConsoleCommandEvent $event)
$event CConsoleCommandEvent the event parameter
Source Code: framework/console/CConsoleCommand.php#601 (show)
public function onAfterAction($event)
{
    
$this->raiseEvent('onAfterAction',$event);
}

This event is raised after an action finishes execution.

onBeforeAction() method (available since v1.1.11)
public void onBeforeAction(CConsoleCommandEvent $event)
$event CConsoleCommandEvent the event parameter
Source Code: framework/console/CConsoleCommand.php#591 (show)
public function onBeforeAction($event)
{
    
$this->raiseEvent('onBeforeAction',$event);
}

This event is raised before an action is to be executed.

pluralize() method
public string pluralize(string $name)
$name string the word to be pluralized
{return} string the pluralized word
Source Code: framework/console/CConsoleCommand.php#502 (show)
public function pluralize($name)
{
    
$rules=array(
        
'/(m)ove$/i' => '\1oves',
        
'/(f)oot$/i' => '\1eet',
        
'/(c)hild$/i' => '\1hildren',
        
'/(h)uman$/i' => '\1umans',
        
'/(m)an$/i' => '\1en',
        
'/(s)taff$/i' => '\1taff',
        
'/(t)ooth$/i' => '\1eeth',
        
'/(p)erson$/i' => '\1eople',
        
'/([m|l])ouse$/i' => '\1ice',
        
'/(x|ch|ss|sh|us|as|is|os)$/i' => '\1es',
        
'/([^aeiouy]|qu)y$/i' => '\1ies',
        
'/(?:([^f])fe|([lr])f)$/i' => '\1\2ves',
        
'/(shea|lea|loa|thie)f$/i' => '\1ves',
        
'/([ti])um$/i' => '\1a',
        
'/(tomat|potat|ech|her|vet)o$/i' => '\1oes',
        
'/(bu)s$/i' => '\1ses',
        
'/(ax|test)is$/i' => '\1es',
        
'/s$/' => 's',
    );
    foreach(
$rules as $rule=>$replacement)
    {
        if(
preg_match($rule,$name))
            return 
preg_replace($rule,$replacement,$name);
    }
    return 
$name.'s';
}

Converts a word to its plural form.

prompt() method (available since v1.1.9)
public mixed prompt(string $message, string $default=NULL)
$message string to echo out before waiting for user input
$default string the default string to be returned when user does not write anything. Defaults to null, means that default string is disabled. This parameter is available since version 1.1.11.
{return} mixed line read as a string, or false if input has been closed
Source Code: framework/console/CConsoleCommand.php#542 (show)
public function prompt($message,$default=null)
{
    if(
$default!==null)
        
$message.=" [$default] ";
    else
        
$message.=' ';

    if(
extension_loaded('readline'))
    {
        
$input=readline($message);
        if(
$input!==false)
            
readline_add_history($input);
    }
    else
    {
        echo 
$message;
        
$input=fgets(STDIN);
    }

    if(
$input===false)
        return 
false;
    else{
        
$input=trim($input);
        return (
$input==='' && $default!==null) ? $default $input;
    }
}

Reads input via the readline PHP extension if that's available, or fgets() if readline is not installed.

renderFile() method
public mixed renderFile(string $_viewFile_, array $_data_=NULL, boolean $_return_=false)
$_viewFile_ string view file path
$_data_ array optional data to be extracted as local view variables
$_return_ boolean whether to return the rendering result instead of displaying it
{return} mixed the rendering result if required. Null otherwise.
Source Code: framework/console/CConsoleCommand.php#480 (show)
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_);
}

Renders a view file.

resolveRequest() method (available since v1.1.5)
protected array resolveRequest(array $args)
$args array command line arguments
{return} array the action name, named options (name=>value), and unnamed options
Source Code: framework/console/CConsoleCommand.php#227 (show)
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;
        }
        elseif(isset(
$action))
            
$params[]=$arg;
        else
            
$action=$arg;
    }
    if(!isset(
$action))
        
$action=$this->defaultAction;

    return array(
$action,$options,$params);
}

Parses the command line arguments and determines which action to perform.

run() method
public integer run(array $args)
$args array command line parameters for this command.
{return} integer application exit code, which is returned by the invoked action. 0 if the action did not return anything. (return value is available since version 1.1.11)
Source Code: framework/console/CConsoleCommand.php#117 (show)
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 $i=>$param)
    {
        
$name=$param->getName();
        if(isset(
$options[$name]))
        {
            if(
version_compare(PHP_VERSION,'8.0','>=')) {
                
$isArray=$param->getType() && $param->getType()->getName()==='array';
            } else {
                
$isArray $param->isArray();
            }

            if(
$isArray)
                
$params[]=is_array($options[$name]) ? $options[$name] : array($options[$name]);
            elseif(!
is_array($options[$name]))
                
$params[]=$options[$name];
            else
                
$this->usageError("Option --$name requires a scalar. Array is given.");
        }
        elseif(
$name==='args')
            
$params[]=$args;
        elseif(
$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)));

    
$exitCode=0;
    if(
$this->beforeAction($action,$params))
    {
        
$exitCode=$method->invokeArgs($this,$params);
        
$exitCode=$this->afterAction($action,$params,is_int($exitCode)?$exitCode:0);
    }
    return 
$exitCode;
}

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

usageError() method
public void usageError(string $message)
$message string the error message
Source Code: framework/console/CConsoleCommand.php#341 (show)
public function usageError($message)
{
    echo 
"Error: $message\n\n".$this->getHelp()."\n";
    exit(
1);
}

Displays a usage error. This method will then terminate the execution of the current application.