I like WP_CLI and how it can improve your development and management of sites. I sometimes even use it to create a new WordPress site locally. But what if you work on your own custom WP_CLI commands and want them more interactive?

At the time of writing, I was not able to find an interactive command in WP_CLI other than WP_CLI::confirm. This command is interactive but it has one downside, if the answer is not y, it will stop executing code.

WP_CLI::Confirm command

Let’s try it out. I’ll add a file command.php (you can name it however you want) and place it under wp-content/mu-plugins/ (if you don’t have that folder, you can create it). It will always load files inside of that folder.

<?php

/**
 * Implements example command.
 */
class Example_Command {
	
	/**
	 * Confirm example
	 *
	 * ## OPTIONS
	 *
	 * <name>
	 * : The name of the person to greet.
	 *
	 * ## EXAMPLES
	 *
	 *     wp example confirm Newman
	 *
	 * @when after_wp_load
	 */
	public function confirm( $args ) {
		list( $name ) = $args;
		WP_CLI::confirm( "Are you {$name}?" );

		WP_CLI::line( 'Welcome. Let\'s Proceed with other tasks.' );
	}

}

WP_CLI::add_command( 'example', 'Example_Command' );

So now, if you go to the site through your terminal (command prompt), you should be able to try it out. I’ll run wp example confirm Igor.

I’ll get a question “Are you Igor?” and if I type n, the code will stop without any other notice. Which is fine as you know what is happening.

But, what if I want an interactive method here so I can control the flow of the code in a WP_CLI command? For example, I am importing a bunch of data and some data has an error. I can present the error and ask if we still want to proceed with that row of data.

If not, I can ignore it and continue importing other sets of data. With the WP_CLI confirm method, this won’t be possible. Because if I don’t answer positively, it will stop executing the next iteration.

Creating an Interactive WP_CLI command method

So, let’s create now an interactive method that we can use multiple times and also accept completely different answers.

I’ll call this method ask. Let’s define it in our command that we already created. You can put this method at the bottom of the Example_Command class.

<?php

class Example_Command {
  // ... previous code

    /**
	 * We are asking a question and returning an answer as a string.
	 *
	 * @param $question
	 *
	 * @return string
	 */
	protected function ask( $question ) {
		// Adding space to question and showing it.
		fwrite( STDOUT, $question . ' ' );

		return strtolower( trim( fgets( STDIN ) ) );
	}
}

Now, if we use $this->ask() in our code, we can get answers to a bunch of questions. Let’s now see how this works. I’ll create a new method inside of that class and name it prompt.

<?php

class Example_Command {
  // ... previous code

    /**
	 * Prompt example
	 *
	 * ## OPTIONS
	 *
	 * <name>
	 * : The name of the person to greet.
	 *
	 * ## EXAMPLES
	 *
	 *     wp example confirm Newman
	 *
	 * @when after_wp_load
	 */
	public function prompt( $args ) {
		list( $name ) = $args;

		$answer = $this->ask( "Are you {$name}? " );

		if ( 'y' !== $answer ) {
			WP_CLI::error( "Sorry, only {$name} can go through" );
			exit;
		}

		WP_CLI::success( 'Welcome. Let\'s Proceed with other tasks.' );

		$year = $this->ask( 'Birth year?');

		if ( absint( $year ) > absint(date('Y'))) {
			WP_CLI::error( "Ha! Good one. You're yet to be born!" );
			exit;
		}

		$old = absint(date('Y')) - absint($year);
		$job = $this->ask( 'What do you do for a living?');


		WP_CLI::success( "So, you're ~{$old} years old and you're working as a {$job}. Cool");
	}
}

Now, when I ask the user if the name is correct and I get a negative answer, I will also display a message there saying that only that name can continue.

But, if I answer with a positive answer (y) then, I will be asked a few more questions. The first one will be my year of birth. In the code, I get the year and I test if the provided year is in the future. If it is, I’ll give an error message and exit the code.

But if I enter a year that is in the past, I’ll get another question about my job. Once I enter them both, I’ll get a success message telling me how old I am and what I do for a living (the ~ before the year is because we don’t check the full date).

Do mind that this is just for tutorial purposes to show how the method can be used. No data validation is done here actually.

Code

I have also zipped the whole code here so you can unzip it, change it and use it as you would want. I can also recommend moving the ask method to a utility class as a static method so you could use it in other WP_CLI commands you create.

This part is available only to the members. If you want to become a member and support my work go to this link and subscribe: Become a Member

Conclusion

If you’re developing a plugin or a framework that offers WP_CLI commands, you might need a more interactive approach to some of the methods.

With the interactive example we did, you could make your commands even accept arguments if some of the arguments are required to perform some actions (but not required by command definition).

Have you created custom WP_CLI commands? If so, let others know what you did!

Become a Sponsor

Posted by Igor Benic

Web Developer who mainly uses WordPress for projects. Working on various project through Codeable & Toptal. Author of several ebooks at https://leanpub.com/u/igorbenic.

Leave a reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.