How to Write a Magento 2 Console Command
Tags: magento, php, webdev
Published: 2019-06-09 20:54:32

---
title: How to Write a Magento 2 Console Command
published: true
description: A short tutorial about writing Magento 2 console commands
tags: magento, php, webdev
canonical_url: https://andrewdavis.me/post/writing-a-magento-2-console-command/
---
In Magento 2, the platform introduced a new command line interface called `bin/magento` that is included in every installation. Most Magento developers are familiar with it because it makes it very easy to peform common tasks on the install like clear cache and install a database. What you might not know is that you can add custom commands to the Magento CLI to allow you to run your own code. I have used this feature to create custom cron jobs that can be executed by the OS cron instead of Magento's cron system. Magento's CLI is based on the [Symfony Console](https://symfony.com/doc/current/components/console.html) package which is commonly used in the PHP ecosystem. Laravel bases their `artisan` command on Symfony Console, for example. In Magento 2, you can create custom Symfony Console commands and include them in Magento's CLI. To help other developers get started with console commands, I want to provide this quick tutorial.

*I am assuming you have a Magento 2 installation ready to use for development. To learn how to set up Magento, check out [Magento's devdocs post](https://devdocs.magento.com/guides/v2.3/install-gde/bk-install-guide.html) for installation instructions. I used Magento Community 2.3.1 for this tutorial.*

### 1. Make a Module
We need to create our own custom module in `app/code`. I am calling my module `Restoreddev_Console`. For every module we need a `registration.php` and `module.xml` file.

`app/code/Restoreddev/Console/registration.php`
```php
<?php

use \Magento\Framework\Component\ComponentRegistrar;

ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Restoreddev_Console', __DIR__);
```

`app/code/Restoreddev/Console/etc/module.xml`
```xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Restoreddev_Console" />
</config>
```

Now you can run `php bin/magento setup:upgrade` to install your custom module into Magento's database.

### 2. Create Console Command Class
Next, we can create a class that implements Symfony Command that will be run when our command is executed. I want to create a custom command that clears the `generated` directory, similar to how `cache:flush` works. Add this class to your module:

`app/code/Restoreddev/Console/Console/Command/GeneratedFlushCommand.php`
```php
<?php

namespace Restoreddev\Console\Console\Command;

use Symfony\Component\Console\Command\Command;
use Magento\Framework\Filesystem\DirectoryList;
use Magento\Framework\Filesystem\Io\File as FileIo;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class GeneratedFlushCommand extends Command
{
    protected $fileIo;
    protected $directoryList;

    public function __construct(
        FileIo $fileIo,
        DirectoryList $directoryList
    ) {
        parent::__construct();

        $this->fileIo = $fileIo;
        $this->directoryList = $directoryList;
    }

    protected function configure()
    {
        $this->setName('generated:flush');
        $this->setDescription('Deletes code in generated folder');

        parent::configure();
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $path = $this->directoryList->getPath('generated');
        $dirs = glob("$path/*", GLOB_ONLYDIR);
        foreach ($dirs as $dir) {
            $this->fileIo->rmdir($dir, $recursive = true);
        }

        $output->writeln('Generated folder successfully flushed');
    }
}
```

There is a lot happening in this class, so we need to analyze it in sections.

1. You will see that the class extends `Symfony\Component\Console\Command\Command`. The Symfony parent class provides the interface for our class to be included in the command list.
2. In the `__construct` method, we can inject Magento dependencies like other Magento classes. However, you do have to run `parent::__construct();` for the class to be implemented properly.
3. The `configure` method allows you to define the command name and description that appears in the CLI menu.
4. The `execute` method contains the code that will run when the CLI command is executed. The method receives two objects: `$input` (contains any console arguments) and `$output` (allows you to send text to the terminal). I am using Magento's classes to get the `generated` directory and to delete any directories inside of it. At the end, I am using `$output->writeln()` to send a success message to the user.

### 3. Register Command in Magento
Finally, we need to register the command in Magento's dependency injection system. Create the following `di.xml` file in your module.

`app/code/Restoreddev/Console/etc/di.xml`
```xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Framework\Console\CommandListInterface">
        <arguments>
            <argument name="commands" xsi:type="array">
                <item name="generatedFlushCommand" xsi:type="object">Restoreddev\Console\Console\Command\GeneratedFlushCommand</item>
            </argument>
        </arguments>
    </type>
</config>
```

In the `di.xml`, we are targeting the `CommandListInterface` and adding an additional command to its arguments. Now you can flush Magento's cache (`php bin/magento cache:flush`) and run `php bin/magento`. You will see a new command called `generated:flush`. If you execute it `php bin/magento generated:flush`, then you will see all subdirectories in the `generated` folder have been deleted.

I hope this quick tutorial has helped you learn about a neat new feature in Magento 2. If you would like to see another specific Magento tutorial, let me know in the comments!