Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Консольные команды

Модуль может добавить в bin/magento собственные команды. Ими удобно запускать то, что не привязано к странице: импорт, пересчёт, проверку данных. Команда — обычный класс на основе компонента Symfony Console, который используется и в других фреймворках.

Где лежит команда

Классы команд кладут в папку Console/Command модуля, а регистрируют в etc/di.xml. Генератора нет — файл создают вручную.

app/code/Acme/Hello/
├── Console/
│   └── Command/
│       └── CountReviews.php    новый файл
└── etc/
    └── di.xml                  изменён

Класс команды

// app/code/Acme/Hello/Console/Command/CountReviews.php
namespace Acme\Hello\Console\Command;
 
use Acme\Hello\Model\ResourceModel\Review\CollectionFactory;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
 
class CountReviews extends Command
{
    public function __construct(private CollectionFactory $collectionFactory)
    {
        parent::__construct();
    }
 
    protected function configure(): void
    {
        $this->setName('hello:reviews:count')
            ->setDescription('Показывает число отзывов');
    }
 
    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $count = $this->collectionFactory->create()->getSize();
 
        $output->writeln("<info>Отзывов: $count</info>");
 
        return Command::SUCCESS;
    }
}

Метод configure() задаёт имя и описание, метод execute() выполняет работу и возвращает код завершения: Command::SUCCESS или Command::FAILURE. Имя принято начинать с названия модуля. В конструкторе обязательно вызывают parent::__construct().

Регистрация

Команду добавляют в список команд через аргумент-массив в di.xml:

<!-- app/code/Acme/Hello/etc/di.xml -->
<type name="Magento\Framework\Console\CommandListInterface">
    <arguments>
        <argument name="commands" xsi:type="array">
            <item name="hello_reviews_count" xsi:type="object">Acme\Hello\Console\Command\CountReviews</item>
        </argument>
    </arguments>
</type>

Это тот самый приём из урока об аргументах: модуль дописывает свой элемент в массив класса ядра.

Запуск

bin/magento cache:clean
bin/magento hello:reviews:count

Команда напечатает Отзывов: 2. Она же появится в списке bin/magento list в группе hello.

Аргументы и параметры

Аргумент — значение после имени команды, параметр — именованный ключ с двумя дефисами. Их объявляют в configure():

// app/code/Acme/Hello/Console/Command/CountReviews.php
use Symfony\Component\Console\Input\InputOption;
 
protected function configure(): void
{
    $this->setName('hello:reviews:count')
        ->setDescription('Показывает число отзывов')
        ->addOption('min-rating', null, InputOption::VALUE_REQUIRED, 'Минимальная оценка', 1);
}
 
protected function execute(InputInterface $input, OutputInterface $output): int
{
    $minRating = (int) $input->getOption('min-rating');
 
    $collection = $this->collectionFactory->create();
    $collection->addFieldToFilter('rating', ['gteq' => $minRating]);
 
    $output->writeln('<info>Отзывов: ' . $collection->getSize() . '</info>');
 
    return Command::SUCCESS;
}
bin/magento hello:reviews:count --min-rating=5

Команда посчитает только отзывы с оценкой пять. Обязательное значение без имени объявляют методом addArgument('file', InputArgument::REQUIRED, 'Описание') и читают через $input->getArgument('file').

Оформление вывода

ТегКак выглядит
infoЗелёный текст
commentЖёлтый текст
errorБелый текст на красном фоне

Теги пишут прямо в строке, как в примере выше.

Частая ошибка

Magento создаёт объекты всех команд при каждом запуске bin/magento, даже если вызвана чужая команда. Тяжёлая зависимость в конструкторе — сессия, репозиторий товаров — замедляет все команды, а иногда ломает setup:install, когда база ещё пуста. Такие зависимости подставляйте через прокси в di.xml, как показано в уроке об аргументах: объект создастся только при первом обращении.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.