Modo corretto e supportato per aggiungere comandi CLI a Magento 2


9

Esiste un modo corretto e ufficialmente supportato per aggiungere i tuoi comandi CLI a un modulo Magento 2? Da quello che ho raccolto sono le tue opzioni

  1. Aggiungi la tua classe di comando commandsall'argomento Magento\Framework\Console\CommandListtramite un di.xmlfile

  2. Registra il tuo comando tramite \Magento\Framework\Console\CommandLocator::registerin un registration.phpfile o un cli_commands.phpfile

Nessuna di queste opzioni è benedetta con un @api. Non è chiaro, come sviluppatori di estensioni, come dovremmo aggiungere script da riga di comando in modo tale che si attacchino alla versione.

Qualcuno sa se esiste una politica ufficiale di Magento su The Right ™ per farlo?

Risposte:


6

cli_commands.phpdovrebbe essere usato nel caso in cui il comando venga aggiunto in un pacchetto non modulare. Quindi, se il comando è nel modulo ed è OK (previsto) che è disponibile solo quando il modulo è abilitato, di.xmldovrebbe essere usato. Se non vuoi aggiungere un modulo e vuoi avere solo un pacchetto Composer arbitrario, puoi usare cli_commands.phpper registrare il comando lì. Certo, dovrebbe essere davvero indipendente da Magento. Oppure, per ora, questo approccio può essere utilizzato per registrare i comandi necessari anche se un modulo è disabilitato (assicurarsi che non si basi su alcuna logica di Modulo che funzioni solo quando è abilitato).


11

Il modo corretto è:

Crea il tuo modulo come fai per qualsiasi tipo di modulo

Basta creare il tuo registration.phpfile

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

E crea il tuo module.xmlfile:

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

Aggiungi una voce in 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 la tua classe di 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!');
    }
}

Per eseguire l'attività basta digitare:

php bin/magento my:command

Informazioni sulla compatibilità:

@api non è necessario per i comandi, viene utilizzato per i contratti di servizio AFAIK.

Se devi renderli compatibili, usa semplicemente un'API di interfaccia all'interno dello script anziché inserire la logica al suo interno.

Per esempio:

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

1
Informazioni utili, +1, ma ne sei sicuro? I moduli di dati di esempio di Magento usano il metodo cli_commands.php, e questo sembra più pulito e meno probabile che si rompa se Magento modifica l'implementazione diMagento\Framework\Console\CommandList
Alan Storm

Non sono sicuro al 100%, solo Magento ne può rispondere, ma ci ho giocato un po 'e se rimuovi "cli_commands.php" vedrai comunque il tuo comando disponibile nel tuo bin / magento. Li hanno anche dichiarati su di.xml, quindi penso che sia ancora qualcosa dalla versione beta. Come è stato per costruttori e fabbriche. Se vedi, cli_command.php viene usato solo nei dati di esempio.
Phoenix128_RiccardoT

Cosa ti fa dire che @api diventerà obsoleto?
Kristof a Fooman il

@Kristof, mi dispiace di non aver compreso correttamente una delle diapositive della soluzione del partner qualificato, quindi ignora quella frase. Ho modificato il mio post rimuovendolo.
Phoenix128_RiccardoT

3

se ho capito bene, i comandi definiti nella CommandList su DI sono disponibili solo in un'istanza Magento installata e anche solo per i moduli Magento (poiché devono essere definiti nel di.xml): https://github.com/magento /magento2/blob/6352f8fbca2cbf21de88db0cf7f4555bfc60451c/lib/internal/Magento/Framework/Console/Cli.php#L124

Magento \ Framework \ App \ DeploymentConfig :: isAvailable () nel metodo sopra verifica una data di installazione in Config per verificare la presenza di un Magento2 installato: https://github.com/magento/magento2/blob/6352f8fbca2cbf21de88db0cf7f4555bfc60451c/lib/ internal / Magento / Framework / App / DeploymentConfig.php # L83 ).

I comandi definiti in Magento \ Framework \ Console \ CommandLocator invece sono sempre disponibili e possono anche essere definiti da moduli non Magento tramite il metodo statico CommandLocator :: register in un file caricato automaticamente dal compositore (ad esempio 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

Quindi penso che entrambi i metodi siano necessari e abbiano il diritto di esistere


Questa è una buona osservazione +1, ma perché dovresti aver bisogno di uno script Magento mentre il modulo relativo non è installato?
Phoenix128_RiccardoT

1
si tratta dell'istanza di Magento non essendo installata. Ci sono diversi comandi disponibili prima di installare magento2. Ad esempio il comando sampledata: deploy, che ha senso se si desidera installare direttamente i dati di esempio con l'installazione di magento2.
David Verholen,

Penso che tu abbia ragione. Quindi il modo "corretto" per un modulo Magento è usare di.xml (come nella mia risposta) e usare "cli_command.php" quando è necessario eseguire alcune attività prima che il modulo sia installato. Ha senso.
Phoenix128_RiccardoT

voi penso che dovrebbe essere così. +1 perché penso che tu abbia la risposta giusta (e molto ben spiegata), ma questo non rientrava in un commento;)
David Verholen,

Grazie @ David Verholen, il mio +1 significava che ti ho dato +1, non che ti meritassi solo un +1;)
Phoenix128_RiccardoT
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.