Drupal 8 brings us Drupal Console as a new CLI tool. Its functionality partly overlaps with Drush, but it makes perfect sense to use both tools in the same Drupal setup. In this post I will explain how to make your own commands for Drupal Console.
Drupal Console (DC) is a new tool for Drupal 8. In line with the decision to use several Symfony 2 components in the Drupal 8 core, DC is based on the Symfony console component (https://symfony.com/doc/current/components/console.html).
Drupal Console started out as a code generation tool. During the long years that Drupal 8 has been in development however, the concept of DC broadened. From code generation it has become a modular CLI tool that can be used by module developers or site admins to write commands to speed up the development process. As a result, Drupal Console has become a little bit like Drush, a well known CLI tool from earlier versions of the Drupal CMS.
Drupal Console should not be seen as a replacement for Drush, but as an extra tool in the box. The maintainers of DC seem to agree. They have decided to facilitate the use of Drush and have included a drush command in Console.
The Drupal Console documentation does not contain much information on how to create your own custom commands. In this post I’ll use some basic examples to show you how to do that.
a simple hello world example
I’m going to use the excellent Drush command starter article by Daniel Sipos (https://www.sitepoint.com/Drupal-create-drush-command/) as a base to create our first Drupal Console commands. For Drush you have to add a module_name.drush.inc file where you create hooks to register the command and the command callback that contains the actual code.
Drupal 8 uses a lot less hooks than earlier versions of the CMS. Drupal Console only requires you to create a Command subdirectory in the src directory of your module. This is in line with a Symfony console convention.
Daniel’s article demonstrates how to create code for Drush that returns ‘hello world’ when you call it. Now let’s do the same for Drupal Console:
The ContainerAwareCommand class implements an interface that requires you to add two methods to every command. This is the only link with the Drupal Console code in the command. Instead of the hooks in Drush, the commands in DC are classes with methods. The two methods to be added are:
- configure: this is where you set the definition of the command that can be called by Drupal Console
- execute: this is the place where you add the actual code of the command
To execute the PrintCommand you use Drupal mce:print or php console.phar mce:print, depending on how you’ve installed Drupal Console.
You did probably notice the “trans” method with an array structured string as argument. This is the translator helper from the Drupal Console. It allows you to create translation yaml files that can be called by their keys. As a result, changing the text does not require you to make code changes.
This is how the yaml file of the PrintCommand looks like:
mce is the name of the module, one level below are the names of the commands.
the print_event command
First I’ll explain how to deal with command line arguments. If you look at the yaml translation file, you can see that I defined a second command called print_event. This command takes 2 parameters as input and prints out some text.
Symfony console commands have 2 types of parameters that can be passed to a command: arguments and options. The main difference between them is that arguments are mandatory and options are not. More information can be found on http://symfony.com/doc/current/components/console.html#using-command-arguments and http://symfony.com/doc/current/components/console/introduction.html#using-command-options.
Note that the documentation also illustrates the differences in how arguments and options are passed on to the console
Now we’ll look at the actual code of the print_event command. The command returns a text with the event that I’ve added as the argument. The text is by default printed only once. You can call this command using Drupal mce:print_event error.
You can repeat the message as often as you want by setting the number in the option: Drupal mce:print_event success –-repeat=”5”
In Drupal 8 beta 12 a Symfony console application that creates a script with a dump of the database was added in the core code. The script is different from a sql dump because it has to be executed in a Drupal environment to import the data. You can call it with the command php core/scripts/dump-database-d8-mysql.php > ~/dump.php
Now let’s make this a Drupal Console command:
- Go to core\lib\Drupal\Core\Command and copy the DbDumpCommand.php file to one of your own modules. I created a database_dumper module for it.
- On line 13 change use Symfony\Component\Console\Command\Command; in use Drupal\AppConsole\Command\ContainerAwareCommand;
- On line 33 change Command to ContainerAwareCommand
- replace the __construct method with the code below
In order to make the command a Drupal Console command, the connection and the moduleHandler should be set in the constructor. We can do this because Drupal Console takes care of the Drupal bootstrap. This is different from the Symfony console application in the Drupal 8 core, which passes the connection and the moduleHandler as arguments.
5. replace the configure method with the code below:
In this method our command is given a nice name and the option to define the output file is added.
6. replace the execute method with the code below:
The only change here is that there is a check to verify if the file option is added or not and based on that check the script is added to the file or displayed on the screen.
7. Finally create a translation file in your module
You can call the command using Drupal db:dump --file=”~/dump.php”.
8. Congratulations, you have successfully transformed the command into a Drupal Console command. That’s how simple it is to create command line scripts to help you with Drupal 8 development.
In this post I did not write about the code generation abilities of Drupal Console, but wanted to show you that DC is a great tool for creating custom commands for your modules.
Both Drush and DC can be used to create custom commands for Drupal 8 modules. My preference for these custom commands is to use DC, since it results in cleaner code than Drush.
Drush however is still very valuable for custom site installations. Nevertheless, Drupal Console is a fine addition to the Drupal developer’s toolbox. In a large Drupal 8 project, we are using both Drush and Drupal Console, each for its specific merits.
This blog post is a part of our series ‘Embarking on a Drupal 8 adventure’. More here: https://www.foreach.be/blog/embarking-Drupal-8-adventure