Question

Existe-t-il un moyen correct et officiellement pris en charge d'ajouter vos commandes CLI à un module Magento 2 ?D'après ce que j'ai rassemblé, vos options sont

  1. Ajoutez votre classe de commande au commands argument de Magento\Framework\Console\CommandList par l'intermédiaire d'un di.xml déposer

  2. Enregistrez votre commande via \Magento\Framework\Console\CommandLocator::register dans un registration.php fichier ou un cli_commands.php déposer

Aucune de ces options n'est dotée d'un @api.Il n'est pas clair, en tant que développeurs d'extensions, comment nous devrions ajouter des scripts de ligne de commande de manière à ce qu'ils restent d'une version à l'autre.

Est-ce que quelqu'un sait s'il existe une politique officielle de Magento sur la manière de procéder de The Right™ ?

Était-ce utile?

La solution

cli_commands.php doit être utilisé dans le cas où la commande est ajoutée dans un package non modulaire.Donc, si la commande est dans le module et que c'est OK (attendu) qu'elle soit disponible uniquement lorsque le module est activé, di.xml Devrait être utilisé.Si vous ne souhaitez pas ajouter de module et souhaitez simplement avoir un package Composer arbitraire, vous pouvez utiliser cli_commands.php pour y enregistrer la commande.Bien entendu, il doit alors être réellement indépendant de Magento.Ou, pour l'instant, cette approche peut être utilisée pour enregistrer les commandes nécessaires même si un module est désactivé (assurez-vous qu'il ne repose sur la logique d'aucun module qui ne fonctionne que lorsqu'il est activé).

Autres conseils

La bonne manière est la suivante :

Créez votre module comme vous le faites pour tout type de module

Créez simplement votre registration.php déposer

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

Et te créer module.xml déposer:

<?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>

Ajouter 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 contrats de services AUTANT QUE JE SACHE.

Si vous devez les rendre compatibles, utilisez simplement un API d'interface à l'intérieur de votre script au lieu d'y mettre la logique.

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.');
    }
}

si j'ai bien compris, les commandes définies dans CommandList sur DI ne sont disponibles que dans une instance Magento installée et également 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

le 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/lib/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 composer (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 le droit d'exister

Licencié sous: CC-BY-SA avec attribution
Non affilié à magento.stackexchange
scroll top