La bonne façon est:
Créez votre module comme vous le faites pour tout type de module
Créez simplement votre registration.php
fichier
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'My_Module',
__DIR__
);
Et créez votre module.xml
fichier:
<?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>
Ajoutez une entrée dans 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>
Créez votre classe de commande:
<?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!');
}
}
Pour exécuter votre tâche, tapez simplement:
php bin/magento my:command
À propos de la compatibilité:
@api n'est pas nécessaire pour les commandes, il est utilisé pour les contrats de service AFAIK.
Si vous devez les laisser compatibles, utilisez simplement une API d'interface dans votre script au lieu de mettre la logique à l'intérieur.
Par exemple:
<?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 je comprends bien, les commandes définies dans la CommandList sur DI ne sont disponibles que dans une instance Magento installée et uniquement pour les modules Magento (car elles doivent être définies dans le di.xml): https://github.com/magento /magento2/blob/6352f8fbca2cbf21de88db0cf7f4555bfc60451c/lib/internal/Magento/Framework/Console/Cli.php#L124
Magento \ Framework \ App \ DeploymentConfig :: isAvailable () dans la méthode ci-dessus vérifie une date d'installation dans la configuration pour rechercher un Magento2 installé: https://github.com/magento/magento2/blob/6352f8fbca2cbf21de88db0cf7f4555bfc60451c/l internal / Magento / Framework / App / DeploymentConfig.php # L83 ).
Les commandes définies dans Magento \ Framework \ Console \ CommandLocator par contre sont toujours disponibles et peuvent même être définies par des modules non Magento via la méthode statique CommandLocator :: register dans un fichier chargé automatiquement par le compositeur (par exemple 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
Je pense donc que les deux méthodes sont nécessaires et ont leur droit d'exister
la source