Magento2 How to create a custom command

Magento2 How to create a custom command

To get started with the custom command, first create a type with name Magento\Framework\Console\CommandListInterface to define the command options.

Vendor/Module/etc/di.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="vendor_custom_cmd" xsi:type="object">Vendor\Module\Console\Command\VendorCustomCommand</item>
            </argument>
        </arguments>
    </type>

</config>

Next create a command class defined under di.xml

Vendor/Module/Console/Command/VendorCustomCommand.php

<?php
namespace Vendor\Module\Console\Command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class VendorCustomCommand extends Command
{
    protected function configure()
    {
        $this->setName('vendor:custom:command');
        $this->setDescription('This is my custom console command.');
        parent::configure();
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $exitCode = 0;
        $output->writeln('<info>This is my custom console command.</info>');
        $output->writeln('<comment>Some comment.</comment>');
        return $exitCode;
    }
}

Flush the cache and run following command from cli to see the output:

php bin/magento vendor:custom:command

It will return following output:

This is my custom console command.
Some comment.

Now add an input option and make it required. It will take user input and then we can deal it as an input parameter in our code.

Add code below under configure() method and before parent call:

<?php
...

        $this->addOption(
            'Name',
            null,
            \Symfony\Component\Console\Input\InputOption::VALUE_REQUIRED,
            'Name description'
        );

...

Next we use the provided option value inside execute(…) method.

<?php
...

        if ($name = $input->getOption('name')) {
            $output->writeln('<info>My name is `' . $name . '`</info>');
        }

...

If we run same command the result will be similar as the previous output. To make a difference ask the user to enter input option by returning an error output.

Use try catch block to achieve that:

<?php
...

        try {
            if (!$name = $input->getOption(self::NAME)) {
                throw new \Magento\Framework\Exception\LocalizedException(__("Name is required."));
            }

            $output->writeln('<info>My name is `' . $name . '`</info>');
        } catch (\Magento\Framework\Exception\LocalizedException $e) {
            $output->writeln(sprintf(
                '<error>%s</error>',
                $e->getMessage()
            ));
            $exitCode = 1;
        }

...

Now if option is missing the error message will return in output. keeping all pieces in one place, our final version will look like this:

<?php
namespace Vendor\Module\Console\Command;

use Magento\Framework\Exception\LocalizedException;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

class VendorCustomCommand extends Command
{
    private const NAME = "name";

    protected function configure()
    {
        $this->setName('vendor:custom:command');
        $this->setDescription('This is my custom console command.');
        $this->addOption(
            self::NAME,
            null,
            InputOption::VALUE_REQUIRED,
            'Name'
        );
        parent::configure();
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $exitCode = 0;
        try {
            if (!$name = $input->getOption(self::NAME)) {
                throw new LocalizedException(__("Name is required."));
            }

            $output->writeln('<info>This is my custom console command.</info>');
            $output->writeln('<info>My name is `' . $name . '`</info>');
            $output->writeln('<comment>Some comment.</comment>');
        } catch (LocalizedException $e) {
            $output->writeln(sprintf(
                '<error>%s</error>',
                $e->getMessage()
            ));
            $exitCode = 1;
        }

        return $exitCode;
    }
}

Try running the command without option:

php bin/magento vendor:custom:command

The output will be:

Name is required.

Now try running command with parameter “name”:

php bin/magento vendor:custom:command --name="Arsalan"

output:

This is my custom console command.
My name is `Arsalan`
Some comment.

Leave a Reply

Your email address will not be published.