Свои команды Drush
Своя команда Drush запускает код модуля из терминала: импорт данных, рассылку, очистку. Это удобнее страницы в панели, когда работа долгая или должна выполняться по расписанию. Команда — метод класса с атрибутом.
Где лежит команда
Drush ищет команды модуля в папке src/Drush/Commands. Создайте папки и файл вручную или командой drush generate drush:command-file.
Первая команда
// web/modules/custom/blog/src/Drush/Commands/BlogCommands.php
namespace Drupal\blog\Drush\Commands;
use Drush\Attributes as CLI;
use Drush\Commands\DrushCommands;
final class BlogCommands extends DrushCommands
{
#[CLI\Command(name: 'blog:subscribers')]
public function subscribers(): void
{
$count = \Drupal::database()
->select('blog_subscribers')
->countQuery()
->execute()
->fetchField();
$this->io()->writeln("Подписчиков: $count");
}
}Атрибут CLI\Command задаёт имя команды. Его принято начинать с имени модуля и двоеточия. Имя файла должно заканчиваться на Commands.php.
vendor/bin/drush cr
vendor/bin/drush blog:subscribersКоманда напечатает число строк в таблице подписчиков, например «Подписчиков: 3».
Аргументы
Аргумент — обязательное значение после имени команды. Он попадает в параметр метода:
// web/modules/custom/blog/src/Drush/Commands/BlogCommands.php
#[CLI\Command(name: 'blog:unsubscribe')]
#[CLI\Argument(name: 'email', description: 'Адрес подписчика')]
public function unsubscribe(string $email): void
{
$deleted = \Drupal::database()
->delete('blog_subscribers')
->condition('email', $email)
->execute();
$this->io()->success("Удалено записей: $deleted");
}vendor/bin/drush blog:unsubscribe anna@example.comКоманда удалит подписку и напечатает зелёное сообщение. Без адреса Drush сообщит, что аргумента не хватает.
Опции
Опция — необязательный ключ с двумя дефисами. Опции приходят в последний параметр метода, массив $options, где заданы значения по умолчанию:
// web/modules/custom/blog/src/Drush/Commands/BlogCommands.php
#[CLI\Command(name: 'blog:list')]
#[CLI\Option(name: 'limit', description: 'Сколько адресов показать')]
public function list(array $options = ['limit' => 10]): void
{
$emails = \Drupal::database()
->select('blog_subscribers', 's')
->fields('s', ['email'])
->range(0, (int) $options['limit'])
->execute()
->fetchCol();
foreach ($emails as $email) {
$this->io()->writeln($email);
}
}vendor/bin/drush blog:list --limit=3Без опции команда покажет десять адресов, с опцией — три.
Вывод
| Метод | Что печатает |
|---|---|
$this->io()->writeln('…') | Строку текста |
$this->io()->success('…') | Сообщение об успехе |
$this->io()->error('…') | Сообщение об ошибке |
$this->io()->table($headers, $rows) | Таблицу |
$this->io()->confirm('…') | Вопрос «да или нет», возвращает true или false |
$this->logger()->notice('…') | Запись уровня «уведомление» |
Справка
Описание из атрибутов попадает в справку:
vendor/bin/drush help blog:unsubscribe
vendor/bin/drush list --filter=blogПервая команда покажет аргументы и опции, вторая — все команды модуля.
Частая ошибка
Drush сообщает, что команда не определена. Проверьте путь и пространство имён: файл лежит в src/Drush/Commands, namespace — Drupal\blog\Drush\Commands, имя файла заканчивается на Commands.php, а модуль включён. В старых руководствах команды кладут в src/Commands и регистрируют в файле drush.services.yml — в современных версиях Drush это не нужно. После добавления файла выполните drush cr.