Frage

Gibt es eine korrekte und offiziell unterstützte Möglichkeit, Ihre CLI-Befehle zu einem Magento 2-Modul hinzuzufügen?Soweit ich weiß, stehen Ihnen folgende Optionen zur Verfügung

  1. Fügen Sie Ihre Befehlsklasse zum hinzu commands Argument von Magento\Framework\Console\CommandList über ein di.xml Datei

  2. Registrieren Sie Ihren Befehl über \Magento\Framework\Console\CommandLocator::register in einem registration.php Datei oder eine cli_commands.php Datei

Keine dieser Optionen ist mit einem gesegnet @api.Als Erweiterungsentwickler ist es nicht klar, wie wir Befehlszeilenskripts hinzufügen sollen, damit sie von Version zu Version erhalten bleiben.

Weiß jemand, ob es eine offizielle Magento-Richtlinie für die Vorgehensweise von The Right™ gibt?

War es hilfreich?

Lösung

cli_commands.php sollte verwendet werden, falls der Befehl in einem nicht modularen Paket hinzugefügt wird.Wenn sich der Befehl also im Modul befindet und es in Ordnung (erwartet) ist, dass er nur verfügbar ist, wenn das Modul aktiviert ist, di.xml sollte benutzt werden.Wenn Sie kein Modul hinzufügen möchten und nur ein beliebiges Composer-Paket haben möchten, können Sie es verwenden cli_commands.php um dort den Befehl zu registrieren.Natürlich sollte es dann wirklich unabhängig von Magento sein.Oder dieser Ansatz kann vorerst verwendet werden, um Befehle zu registrieren, die auch dann erforderlich sind, wenn ein Modul deaktiviert ist (stellen Sie sicher, dass es nicht auf der Logik eines Moduls basiert, das nur funktioniert, wenn es aktiviert ist).

Andere Tipps

Der richtige Weg ist:

Erstellen Sie Ihr Modul wie jedes andere Modul auch

Erstellen Sie einfach Ihr registration.php Datei

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

Und erschaffe dich module.xml Datei:

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

Fügen Sie einen Eintrag hinzu 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>

Erstellen Sie Ihre Befehlsklasse:

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

Um Ihre Aufgabe auszuführen, geben Sie einfach Folgendes ein:

php bin/magento my:command

Zur Kompatibilität:

@api wird für Befehle nicht benötigt, sondern für verwendet Dienstleistungsverträge SO VIEL ICH WEISS.

Wenn Sie sie kompatibel machen möchten, verwenden Sie einfach eine Schnittstellen-API in Ihr Skript integrieren, anstatt die Logik darin zu platzieren.

Zum Beispiel:

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

Wenn ich es richtig verstanden habe, sind in der CommandList über DI definierte Befehle nur in einer installierten Magento-Instanz und auch nur für Magento-Module verfügbar (da sie in der di.xml definiert werden müssen): https://github.com/magento/magento2/blob/6352f8fbca2cbf21de88db0cf7f4555bfc60451c/lib/internal/Magento/Framework/Console/Cli.php#L124

Magento\Framework\App\DeploymentConfig::isAvailable() in der obigen Methode sucht nach einem Installationsdatum in der Konfiguration, um nach einem installierten Magento2 zu suchen: https://github.com/magento/magento2/blob/6352f8fbca2cbf21de88db0cf7f4555bfc60451c/lib/internal/Magento/Framework/App/DeploymentConfig.php#L83).

Die im Magento\Framework\Console\CommandLocator definierten Befehle sind hingegen immer verfügbar und können sogar von Nicht-Magento-Modulen über die statische CommandLocator::register-Methode in einer vom Composer automatisch geladenen Datei definiert werden (z. B. 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

Daher denke ich, dass beide Methoden notwendig sind und ihre Daseinsberechtigung haben

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit magento.stackexchange
scroll top