Pergunta

Há uma correta, e oficialmente suportado forma, para adicionar seus comandos CLI para uma Magento 2 módulo?A partir do que eu recolhi as opções são

  1. Adicione o seu comando de classe para o commands argumento de Magento\Framework\Console\CommandList através de uma di.xml arquivo

  2. Registe o seu comando via \Magento\Framework\Console\CommandLocator::register em um registration.php arquivo ou uma cli_commands.php arquivo

Nenhuma dessas opções são abençoados com um @api.Não está claro como os desenvolvedores de extensão, como devemos adicionar scripts de linha de comando de tal forma que eles vão ficar em torno de versão para versão.

Alguém sabe se há um oficial Magento política sobre O Direito™ maneira de fazer isso?

Foi útil?

Solução

cli_commands.php deve ser usado no caso, o comando é adicionado em um não-modular de pacotes.Então, se o comando está no módulo e é OK (espera-se) que ele está disponível apenas quando o módulo for habilitado, di.xml deve ser usado.Se você não quiser adicionar um módulo e pretende ter apenas um arbitrário Compositor pacote, você pode usar cli_commands.php para registar o comando lá.Claro, ele deve então ser realmente independente do Magento.Ou, por agora, esta abordagem pode ser utilizada para registrar comando(s) necessária, mesmo se um módulo for desativado (certifique-se de que ele não dependa de qualquer Módulo de lógica que funciona apenas quando é ativado).

Outras dicas

A maneira correta é:

Crie o seu módulo como para qualquer tipo de módulo

Basta criar o seu registration.php arquivo

\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'My_Module',
    __DIR__
);

E criar você module.xml arquivo:

<?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="My_Module" setup_version="0.1.0">
    </module>
</config>

Adicionar uma entrada no 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\CommandList">
        <arguments>
            <argument name="commands" xsi:type="array">
                <item name="my_command" xsi:type="object">My\Module\Command\Mycommand</item>
            </argument>
        </arguments>
    </type>
</config>

Crie a sua classe de comando:

<?php
namespace My\Module\Command;

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

class Mycommand extends Command
{
    protected function configure()
    {
        $this->setName('my:command');
        $this->setDescription('Run some task');

        parent::configure();
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $output->writeln('Hello world!');
    }
}

Para executar sua tarefa basta digitar:

php bin/magento my:command

Sobre a compatibilidade:

@api não é necessário para o comando, ele é utilizado para contratos de serviço AFAIK.

Se você precisa deixá-los compatíveis, basta utilizar um API de interface dentro de seu script em vez de colocar a lógica em seu interior.

Por exemplo:

<?php
use My\Module\Api\TaskInterface;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class MyCommand extends Command
{
    protected $taskInterface;

    public function __construct(
        TaskInterface $taskInterface
    ) {
        $this->taskInterface= $taskInterface;
        parent::__construct();
    }

    protected function configure()
    {
        $this->setName('my:command');
        $this->setDescription('Run some task');

        parent::configure();
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $this->taskInterface->runTask();

        $output->writeln('Done.');
    }
}

se eu entendi direito, os comandos definidos no CommandList sobre DI estão disponíveis apenas em uma instalou o Magento Instância e também só para Magento Módulos (já que eles têm que ser definidos no di.xml): https://github.com/magento/magento2/blob/6352f8fbca2cbf21de88db0cf7f4555bfc60451c/lib/internal/Magento/Framework/Console/Cli.php#L124

o Magento\Framework\App\DeploymentConfig::isAvailable() no método acima verifica uma Data de instalação no Config para verificar instalada Magento2: https://github.com/magento/magento2/blob/6352f8fbca2cbf21de88db0cf7f4555bfc60451c/lib/internal/Magento/Framework/App/DeploymentConfig.php#L83).

Os comandos definidos no Magento\Framework\Console\CommandLocator por outro lado, estão sempre disponíveis, e até mesmo podem ser definidas por não Magento através de Módulos estáticos CommandLocator::método de registro em um arquivo automaticamente pelo compositor (por exemplo, cli_commands.php)

https://github.com/magento/magento2/blob/6352f8fbca2cbf21de88db0cf7f4555bfc60451c/lib/internal/Magento/Framework/Console/Cli.php#L130

https://github.com/magento/magento2/blob/6352f8fbca2cbf21de88db0cf7f4555bfc60451c/lib/internal/Magento/Framework/Console/Cli.php#L146

Então eu acho que ambos os métodos são necessários e têm o seu direito de existir

Licenciado em: CC-BY-SA com atribuição
Não afiliado a magento.stackexchange
scroll top