Правильный, поддерживаемый способ добавления команд командной строки в Magento 2
Существует ли правильный и официально поддерживаемый способ добавления ваших команд командной строки в модуль Magento 2? Из того, что я понял, ваши варианты
Добавьте свой класс команд в аргумент
commands
Magento\Framework\Console\CommandList
с помощью файлаdi.xml
Зарегистрируйте свою команду с помощью
\Magento\Framework\Console\CommandLocator::register
в файлеregistration.php
или файлеcli_commands.php
Ни один из этих вариантов не наделен @api
. Как разработчикам расширений, неясно, как мы должны добавлять командную строку сценарии таковы, что они будут придерживаться версии от версии к версии.
Кто-нибудь знает, существует ли официальная политика Magento в отношении правильного способа сделать это?
3 answers
cli_commands.php
следует использовать в случае, если команда добавлена в немодульный пакет.
Поэтому, если команда находится в модуле и нормально (ожидается), что она доступна только тогда, когда модуль включен, следует использовать di.xml
. Если вы не хотите добавлять модуль и хотите иметь только произвольный пакет Composer, вы можете использовать cli_commands.php
для регистрации команды там. Конечно, тогда он должен быть действительно независимым от Magento. Или, на данный момент, этот подход может быть использован для регистрации команд, необходимых, даже если модуль отключен (убедитесь, что он не полагается на логику какого-либо модуля, которая работает только тогда, когда она включена).
Правильный способ:
Создайте свой модуль так же, как вы делаете это для любого типа модулей
Просто создайте свой registration.php
файл
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'My_Module',
__DIR__
);
И создадим вам module.xml
файл:
<?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>
Добавьте запись в 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>
Создайте свой класс команд:
<?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!');
}
}
Чтобы выполнить свою задачу, просто введите:
php bin/magento my:command
О совместимости:
@api не нужен для команд, он используется для контракты на обслуживание AFAIK.
Если вам нужно, чтобы они были совместимы, просто используйте интерфейс API внутри вашего скрипта вместо того, чтобы помещать в него логику.
Например:
<?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.');
}
}
Если я правильно понял, команды, определенные в списке команд через DI, доступны только в установленном экземпляре Magento, а также только для модулей Magento (поскольку они должны быть определены в di.xml): https://github.com/magento/magento2/blob/6352f8fbca2cbf21de88db0cf7f4555bfc60451c/lib/internal/Magento/Framework/Console/Cli.php#L124
Magento\Framework\App\DeploymentConfig::isAvailable() в приведенном выше методе проверяет дату установки в конфигурации, чтобы проверить наличие установленный Magento2: https://github.com/magento/magento2/blob/6352f8fbca2cbf21de88db0cf7f4555bfc60451c/lib/internal/Magento/Framework/App/DeploymentConfig.php#L83).
Команды, определенные в Magento\Framework\Console\Commandlocator, с другой стороны, всегда доступны и даже могут быть определены модулями, отличными от Magento, с помощью статического метода CommandLocator::register в файле, загружаемом автоматически композитором (например cli_commands.php)
Поэтому я думаю, что оба метода необходимы и имеют право на существование