Need some help with your project? Contact me

3 ways to prompt for user input in Drush

Drush is awesome. It makes Drupal development much easier. Not only that it comes already packed with a bunch of useful commands, but you can declare your own with great ease. So if you need to call some of your module's functionality from Drush, all you have to do is declare a simple command that integrates with it.

In this tutorial I am going to show you how to get user feeback for such a command. I do not refer to arguments or options in this case. But how you can ask for confirmation on whether or not the command should proceed as requested and how you can ask for a choice. Additionally we'll quickly look at how to get free text back from the user.

So let's dive in with an example command callback function called drush_module_name_example_command():

/**
 * Callback function for the example command
 */
function drush_module_name_example_command() {
  // Command code we will look at
  drush_print('Hello world!');
}

Confirmation

The first thing we'll look at is how to get the user to confirm the action. So in our case, we'll ask the user if they really want this string to be printed to the screen. Drush provides a great API for this:

if (drush_confirm('Are you sure you want \'Hello world\' printed to the screen?')) {
  drush_print('Hello world!');
}
else {
  drush_user_abort();
}

You'll notice 2 new functions. The drush_confirm() function prints a question to the screen with the intent of getting one of two answers back form the user: y or n. If the response is y, the function returns true which means our print statement proceeds. If the answer is n, the drush_user_abort() function gets called instead. This is the recommended way to stop executing a Drush command.

Select option

Now let's see how you can make the user choose an option from a list you provide. For our super Hello world use case, we will give the user the choice to select from a list who Drush should say hello to. It can be implemented like this:

$options = array(
 'world' => 'World',
 'univers' => 'Univers',
 'planet' => 'Planet',
);

$choice = drush_choice($options, dt('Who do you want to say hello to?'));

if ($choice) {
  drush_print(dt('Hello @choice!', array('@choice' => $options[$choice])));
}

So what happens above? First, we create an array to store the choices called $options. The array keys are the machine name and the values are the human friendly versions. Then, we call the drush_choice() function to which we pass 2 arguments: the $options array and the question we ask from the user.

When the command is run, this function is called and returns the machine name of the option the users chooses. Then we check if this value exists and print to the screen the concatenated string. We do use the human readable value by extracting it from the $options array using the key returned.

Free text values

A third type of user input is in the form of free text that you can ask the user to input. Of course the validation of this kind of input must be much stricter so as to not break your application somehow. But let's ask our user exactly who they want to say hello to.

$value = drush_prompt(dt('Who do you want to say hello to?'));
drush_print(dt('Hello @value!', array('@value' =>  $value)));

This one is very simple. When the command is run, the drush_prompt() function is called to which we pass a string of text to be displayed in the terminal. The return value is given by the user and we use that for concatenation. But do remember that this is example code only so if you do use this function, make sure you validate the user input properly.

Conclusion

So there you have it. Three different ways to get user input in the terminal using Drush. The first two are the most common ones I believe but it's good to know there is also the last one available in case we need it.

Drush safely!

Comments

In

drush_print(dt('Hello ' . $value . '!'));

Do you think is ok to concatenate a variable inside the dt() function?
Isn't that going to create a new translatable string for every inserted value?

It's probably not a good idea :) It works for demonstration purposes. I will adapt however because you make a point.

Thanks!

D

Hi there, I'd translated this post to Chinese and posted it on my site.
Feel free to drop me a mail if you don't like it.

Add new comment

You can post comments in Markdown and basic HTML tags.
For code blocks, wrap your code within '~~~'. For example:
~~~
$var = 'my variable';
~~~