Como criar um comando personalizado no Magento 2

Lucas Teixeira dos Santos Santana - Mar 10 '22 - - Dev Community

Contextualizando

O que é um CLI?

A CLI (Command Line Interface, ou Interface de Linha de Comando) é um ambiente onde é possível interagir através do terminal para a execução de tarefas específicas pelas linhas de comando digitados pelo usuário, e após a execução da tarefa, exibirá o retorno do processo no próprio terminal.
Cada linha de comando do terminal é responsável pela execução de uma funcionalidade específica, podendo definir o valor de alguma configuração ou a realização de uma tarefa.


Código para criar um comando

Saiba mais sobre definir valores no construtor de com o type no post "Como definir valores específicos dos argumentos do construtor no Magento 2 utilizando type".

di.xml

Configurações Type descrevem o tipo de uma dependência do construtor de uma determinada classe e qual valor instanciar. Para declarar um comando é necessário injetar na classe \Magento\Framework\Console\CommandListInterface via configuração type, dentro do arquivo di.xml, seguindo a estruturas de pastas \{Vendor}\{Module}\etc\{area}\di.xml.

A configuração que será injetada deve ser do tipo object, referenciando o caminho da classe onde terá as definições do comando.

<?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\CommandList">
        <arguments>
            <argument name="commands" xsi:type="array">
                <item name="{comandName}" xsi:type="object">{Vendor}\{Module}\Console\{Directory}\{ConsoleClass}</item>
            </argument>
        </arguments>
    </type>
</config>
Enter fullscreen mode Exit fullscreen mode

Console

A classe de Console deverá seguir a estrutura de pastas \{Vendor}\{Module}\Console\{Directory}\{ConsoleClass} e estender a classe \Symfony\Component\Console\Command\Command. Esta classe deverá possuir o método protegido configure(), que será utilizado para definir o nome, a descrição, os argumentos e outras caracterísiticas que o comando possuirá. A classe também possuirá o método protegido execute(), que será o utilizado para executar as tarefas quando o comando for chamado através do terminal.

É possível, mas não obrigatório, implementar o método interact(\Symfony\Component\Console\Input\InputInterface $input, \Symfony\Component\Console\Output\OutputInterface $output), este método é executado antes da validação, ou seja, é o único lugar onde o comando pode interativamente perguntar por valores dos argumentos que não foram passados no comando do terminal.

<?php

namespace {Vendor}\{Module}\Console\{Directory};

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

class {ConsoleClass} extends Command
{
    protected function configure(): void
    {
        // Set the name of the comand that will be used in the prompt
        $this->setName('{section}:{command}');

        // Set the description for the comand
        $this->setDescription('{Console description}');

        // Sets an array of argument and option instances
        $this->setDefinition({[]});

        // Add an arguments to command
        $this->addArgument('{argumentName}');

        // Add an option to command
        $this->addOption('{optionName}');

        // Sets the process title of the command. This feature should be used only when creating a long process command
        $this->setProcessTitle('{titleProcess}');

        // Sets whether or not the command should be hidden from the list of commands
        $this->setHidden({true/false});

        // Sets the help for the command
        $this->setHelp('{Text to help}');

        // Sets the aliases for the command
        $this->setAliases({['{aliasName}']});

        // Add a command usage example
        $this->addUsage('{The usage}');

        parent::configure();
    }

    protected function execute(
        InputInterface $input,
        OutputInterface $output
    ): void {
        // Code to execute when running the command
    }

    protected function interact(
        InputInterface $input,
        OutputInterface $output
    ): void {
        // Code to execute before input
    }
}
Enter fullscreen mode Exit fullscreen mode

Ao definir o nome do comando e a tarefa que será executada ao chamar o comando pelo terminal, basta testar o comando no terminal, após habilitar as alterações (conforme abaixo).

bin/magento {section}:{command}
Enter fullscreen mode Exit fullscreen mode

Finalização

Valores entre chaves ({test}) devem ser alterados na implementação do código.

Habilitando as alterações

Apague os arquivos que são gerados na compilação do Magento e execute o comando PHP para gerar a configuração das injeções de dependência e todas as classes ausentes que precisam ser geradas (proxys, interceptors, etc) e para limpar todos os caches de armazenamento em cache do processos.

rm -rf var/generation/
rm -rf generated/
php bin/magento setup:di:compile
php bin/magento cache:clean
php bin/magento flush
Enter fullscreen mode Exit fullscreen mode

Diretórios e Arquivos

Segue a a lista de diretórios e arquivos que devem ser criados.

- app/
  - code/
    - {Vendor}/
      - {Module}/
        - etc/
          - module.xml
          - di.xml
        - Console/
          - {Directory}/
            - {ConsoleClass}.php
        - registration.php
        - composer.json
Enter fullscreen mode Exit fullscreen mode
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .