WP_CLI::add_command() │ public static │ WP-CLI 1.0 Register a command to WP-CLI.
WP-CLI supports using any callable class, function, or closure as a command. WP_CLI::add_command() is used for both internal and third-party command registration.
Command arguments are parsed from PHPDoc by default, but also can be supplied as an optional third argument during registration.
# Register a custom 'foo' command to output a supplied positional param.
#
# $ wp foo bar --append=qux
# Success: bar qux
/**
* My awesome closure command
*
* <message>
* : An awesome message to display
*
* --append=<message>
* : An awesome message to append to the original message.
*
* @when before_wp_load
*\/
$foo = function( $args, $assoc_args ) {
WP_CLI::success( $args[0] . ' ' . $assoc_args['append'] );
};
WP_CLI::add_command( 'foo', $foo );
Method of the class: WP_CLI{}
No Hooks.
Return
true|false
. True on success, false if deferred, hard error if registration failed.
Usage
$result = WP_CLI::add_command( $name, $callable, $args );
$name(string) (required)
Name for the command (e.g. "post list" or "site empty").
$callable(callable) (required)
Command implementation as a class, function or closure.
$args(array)
An associative array with additional registration parameters.
Default: []
before_invoke (callable)
Callback to execute before invoking the command.
after_invoke (callable)
Callback to execute after invoking the command.
shortdesc (string)
Short description (80 char or less) for the command.
longdesc (string)
Description of arbitrary length for examples, etc.
synopsis (string)
The synopsis for the command (string or array).
when (string)
Execute callback on a named WP-CLI hook (e.g. before_wp_load).
is_deferred (true|false)
Whether the command addition had already been deferred.
WP_CLI::add_command() WP CLI::add command code
WP-CLI 2.8.0-alpha
public static function add_command( $name, $callable, $args = [] ) {
// Bail immediately if the WP-CLI executable has not been run.
if ( ! defined( 'WP_CLI' ) ) {
return false;
}
$valid = false;
if ( is_callable( $callable ) ) {
$valid = true;
} elseif ( is_string( $callable ) && class_exists( (string) $callable ) ) {
$valid = true;
} elseif ( is_object( $callable ) ) {
$valid = true;
} elseif ( Utils\is_valid_class_and_method_pair( $callable ) ) {
$valid = true;
}
if ( ! $valid ) {
if ( is_array( $callable ) ) {
$callable[0] = is_object( $callable[0] ) ? get_class( $callable[0] ) : $callable[0];
$callable = [ $callable[0], $callable[1] ];
}
self::error( sprintf( 'Callable %s does not exist, and cannot be registered as `wp %s`.', json_encode( $callable ), $name ) );
}
$addition = new CommandAddition();
self::do_hook( "before_add_command:{$name}", $addition );
if ( $addition->was_aborted() ) {
self::warning( "Aborting the addition of the command '{$name}' with reason: {$addition->get_reason()}." );
return false;
}
foreach ( [ 'before_invoke', 'after_invoke' ] as $when ) {
if ( isset( $args[ $when ] ) ) {
self::add_hook( "{$when}:{$name}", $args[ $when ] );
}
}
$path = preg_split( '/\s+/', $name );
$leaf_name = array_pop( $path );
$command = self::get_root_command();
while ( ! empty( $path ) ) {
$subcommand_name = $path[0];
$parent = implode( ' ', $path );
$subcommand = $command->find_subcommand( $path );
// Parent not found. Defer addition or create an empty container as
// needed.
if ( ! $subcommand ) {
if ( isset( $args['is_deferred'] ) && $args['is_deferred'] ) {
$subcommand = new CompositeCommand(
$command,
$subcommand_name,
new DocParser( '' )
);
self::debug(
"Adding empty container for deferred command: {$name}",
'commands'
);
$command->add_subcommand( $subcommand_name, $subcommand );
} else {
self::debug( "Deferring command: {$name}", 'commands' );
self::defer_command_addition(
$name,
$parent,
$callable,
$args
);
return false;
}
}
$command = $subcommand;
}
$leaf_command = CommandFactory::create( $leaf_name, $callable, $command );
// Only add a command namespace if the command itself does not exist yet.
if ( $leaf_command instanceof CommandNamespace
&& array_key_exists( $leaf_name, $command->get_subcommands() ) ) {
return false;
}
// Reattach commands attached to namespace to real command.
$subcommand_name = (array) $leaf_name;
$existing_command = $command->find_subcommand( $subcommand_name );
if ( $existing_command instanceof CompositeCommand && $existing_command->can_have_subcommands() ) {
if ( $leaf_command instanceof CommandNamespace || ! $leaf_command->can_have_subcommands() ) {
$command_to_keep = $existing_command;
} else {
$command_to_keep = $leaf_command;
}
self::merge_sub_commands( $command_to_keep, $existing_command, $leaf_command );
}
/** @var Dispatcher\Subcommand|Dispatcher\CompositeCommand|Dispatcher\CommandNamespace $leaf_command */
if ( ! $command->can_have_subcommands() ) {
throw new Exception(
sprintf(
"'%s' can't have subcommands.",
implode( ' ', Dispatcher\get_path( $command ) )
)
);
}
if ( isset( $args['shortdesc'] ) ) {
$leaf_command->set_shortdesc( $args['shortdesc'] );
}
if ( isset( $args['longdesc'] ) ) {
$leaf_command->set_longdesc( $args['longdesc'] );
}
if ( isset( $args['synopsis'] ) ) {
if ( is_string( $args['synopsis'] ) ) {
$leaf_command->set_synopsis( $args['synopsis'] );
} elseif ( is_array( $args['synopsis'] ) ) {
$synopsis = SynopsisParser::render( $args['synopsis'] );
$leaf_command->set_synopsis( $synopsis );
$long_desc = '';
$bits = explode( ' ', $synopsis );
foreach ( $args['synopsis'] as $key => $arg ) {
$long_desc .= $bits[ $key ] . "\n";
if ( ! empty( $arg['description'] ) ) {
$long_desc .= ': ' . $arg['description'] . "\n";
}
$yamlify = [];
foreach ( [ 'default', 'options' ] as $key ) {
if ( isset( $arg[ $key ] ) ) {
$yamlify[ $key ] = $arg[ $key ];
}
}
if ( ! empty( $yamlify ) ) {
$long_desc .= Spyc::YAMLDump( $yamlify );
$long_desc .= '---' . "\n";
}
$long_desc .= "\n";
}
if ( ! empty( $long_desc ) ) {
$long_desc = rtrim( $long_desc, "\r\n" );
$long_desc = '## OPTIONS' . "\n\n" . $long_desc;
if ( ! empty( $args['longdesc'] ) ) {
$long_desc .= "\n\n" . ltrim( $args['longdesc'], "\r\n" );
}
$leaf_command->set_longdesc( $long_desc );
}
}
}
if ( isset( $args['when'] ) ) {
self::get_runner()->register_early_invoke( $args['when'], $leaf_command );
}
if ( ! empty( $parent ) ) {
$sub_command = trim( str_replace( $parent, '', $name ) );
self::debug( "Adding command: {$sub_command} in {$parent} Namespace", 'commands' );
} else {
self::debug( "Adding command: {$name}", 'commands' );
}
$command->add_subcommand( $leaf_name, $leaf_command );
self::do_hook( "after_add_command:{$name}" );
return true;
}