La forma correcta es:
Cree su módulo como lo hace para cualquier tipo de módulo
Solo crea tu registration.php
archivo
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'My_Module',
__DIR__
);
Y crea tu module.xml
archivo:
<?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>
Agregar una entrada en 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>
Crea tu clase 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 ejecutar su tarea simplemente escriba:
php bin/magento my:command
Sobre compatibilidad:
@api no es necesario para los comandos, se usa para contratos de servicio AFAIK.
Si necesita dejarlos compatibles, simplemente use una API de interfaz dentro de su script en lugar de poner la lógica dentro de él.
Por ejemplo:
<?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.');
}
}
Magento\Framework\Console\CommandList
si lo entendí bien, los comandos definidos en la Lista de comandos sobre DI solo están disponibles en una Instancia Magento instalada y también solo para los Módulos Magento (ya que deben definirse en el di.xml): https://github.com/magento /magento2/blob/6352f8fbca2cbf21de88db0cf7f4555bfc60451c/lib/internal/Magento/Framework/Console/Cli.php#L124
Magento \ Framework \ App \ DeploymentConfig :: isAvailable () en el método anterior busca una fecha de instalación en la configuración para verificar si hay un Magento2 instalado: https://github.com/magento/magento2/blob/6352f8fbca2cbf21de88db0cf7f4555bfc60451c/lib/ interno / Magento / Framework / App / DeploymentConfig.php # L83 ).
Los comandos definidos en Magento \ Framework \ Console \ CommandLocator, por otro lado, siempre están disponibles e incluso pueden ser definidos por módulos que no son de Magento a través del método estático CommandLocator :: register en un archivo cargado automáticamente por el compositor (por ejemplo 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
Entonces, creo que ambos métodos son necesarios y tienen derecho a existir
fuente