Make WP-CLI Work For You

Extending WP-CLI With Custom Commands

Chris Wiegman / @chris

WordPress Business Success

by: Karen and Steve Dimmick

WordPress Business Success

Have You Said Hi Roy Today?

Have you said Hi Roy today?

About me

  • Senior Web Engineer - 10up
  • HigherEd Developer
    • Southern Illinois University
    • St. Edward's University
  • Teacher
  • Educator
About Chris Wiegman

We're Hiring

What is WP-CLI?

WP-CLI is a PHP script that interacts with WordPress from the command line (Unix).

WP-CLI is not, itself, a plugin.

WP-CLI works on your server (or local dev environment). It is not necessarily part of WordPress itself.

WP-CLI lets you work with nearly all parts of WordPress, content, users, settings, plugins, etc.

WP-CLI has a simple API which makes it easily and infinitely extensible.

Why Extend WP-CLI?

By default WP-CLI only works with WordPress' core functionality. Extending WP-CLI lets you work with:

  • Plugins
  • Themes
  • Other (non WordPress) Software

What Can a command do?

  • Write to a log
  • Enable/Disable options
  • Write to other software
  • Interact with an API
  • Manage cache
  • Handle security functions

Some Examples:

  • Perform an index of the site with Elasticsearch/ElasticPress
  • Create Munin and Monit plugins
  • Clear iThemes Security logs and lockouts
  • Compare a screenshot of a staging site to production
  • Disable/handicap a user via Fail2ban
  • Offload heavy tasks

Writing a new command

Each Command Must be Registered

				WP_CLI::add_command( 'hello', 'Hello_World_Command' );

A command is a simple class

				class Hello_World_Command extends WP_CLI_Command {

				public function __invoke() {

				WP_CLI::success( 'Hello World' );


$ wp hello

But... What about options?

				class Hello_World_Command extends WP_CLI_Command {

				* An improved Hello World
				* @synopsis [<NAME>] [--name=<NAME>]
				public function __invoke( $args, $assoc_args) {

				$name = 'World';

				if ( isset( $args[0] ) || isset( $assoc_args['name'] ) ) {
				$name = isset( $args[0] ) ? $args[0] : $assoc_args['name'];

				WP_CLI::success( 'Hello ' . sanitize_text_field( $name );


$ wp hello Chris


$ wp hello --name=Chris

A subcommand can expand it

				class Hello_World_Command extends WP_CLI_Command {

				public function world() {

				WP_CLI::success( 'Hello World' );


				* An improved Hello World
				* @synopsis <NAME>
				public function name( $args, $assoc_args) {

				WP_CLI::success( 'Hello ' . sanitize_text_field( $args[0] );



$ wp hello world


$ wp hello name Chris

Custom Command Tips

Don't Automatically Register Commands

				if ( defined( 'WP_CLI' ) && WP_CLI ) {
				WP_CLI::add_command( 'hello', 'Hello_World_Command' );

Success and Failure are Not Treated Equal

WP_CLI::success( 'You Did Good' );
WP_CLI::error( "You Failed. I'm done" );

WP_CLI::error will, if called like success, terminate the script. Success will just go on

You can set the 2nd param, exit, to false on WP_CLI::error to continue execution

WP_CLI::error( "You Failed, but I'll keep going anyway.", false );

Use the Formatter

You can automattically output data in various formats:

  • JSON
  • Table
  • csv
  • IDs
  • count
WP_CLI\Utils\format_items( 'json', get_users(), array( 'ID', 'user_login' ) );
WP_CLI\Utils\format_items( 'table', get_users(), array( 'ID', 'user_login' )

It can do a Progress Bar too!

$notify = \WP_CLI\Utils\make_progress_bar( 'Generating posts', $current_post_count

Use The Force Utils

Various [not well documented] utility function in php/utils.php

  • locate_wp_config()
  • write_csv( $fd, $rows, $headers = array() )
  • launch_editor_for_input( $input, $title = 'WP-CLI' )
  • parse_url( $url )
  • is_windows()

We don't need no stinkin plugin

The path variable lets you execute a command from anywhere

Target file only needs the command registration and location of command class (require statement)

One command repo on the server/environment/etc can execute commands for all sites


Thank You

Chris Wiegman / @chris