Создание команд Artisan для управления Laravel

Laravel – это открытый PHP-фреймворк, в котором вы найдете набор инструментов и ресурсов для создания современных PHP-приложений. Эта серия руководств поможет вам создать простое приложение на платформе Laravel, используя среду разработки PHP, контейнеризованную при помощи Docker Compose. В итоге вы получите одностраничный веб-сайт, которым можно управлять с помощью команд Artisan. На этом сайте вы сможете делиться с аудиторией актуальными ссылками.

Примечание: Другие части этой серии можно найти по этой ссылке.

Если вы выполнили предыдущие руководства этой серии, у вас уже есть готовые таблицы БД. Теперь же нам необходимо разработать способ, позволяющий пользователям вставлять новые записи в таблицу links.

Чтобы наше тестовое приложение было полнофункциональным, мы напишем команды Artisan для создания и удаления ссылок в БД. Artisan – это инструмент командной строки, который поставляется с Laravel и предлагает ряд утилит для ускорения процесса разработки (включая утилиты для генерации шаблонного кода, удаления и восстановления базы данных приложения).

Использование командной строки для управления приложением может стать хорошей альтернативой веб-формам и защищенным областям, поскольку для работы с командной строкой пользователь должен быть зарегистрирован на сервере, а не пройти аутентификацию в браузере. Если позже вы решите использовать защищенную область, вы сможете создать веб-формы, которые позволят зарегистрированным пользователям отправлять новые ссылки в базы данных.

Команды Artisan часто используются для того, чтобы вручную или автоматически (через механизм планирования типа Crontab) запускать задачи приложения, которые должны выполняться в фоновом режиме. Их также можно использовать для быстрого создания прототипов новых функций приложения, которые необходимо динамически настраивать в зависимости от ввода авторизованного пользователя.

Для начала создадим новую команду Artisan; для этого есть вспомогательная команда make:command:

docker-compose exec app php artisan make:command LinkNew
Console command created successfully.

Она создаст файл LinkNew.php в каталоге app/Console/Commands. Внутри этого класса (который является расширением родительского класса Illuminate\Console\Command) нам нужно будет реализовать метод handle, который будет выполняться при вызове этой команды. Чтобы определить подпись команды, установите значение link:new для защищенного свойства $signature.

Откройте новый файл в текстовом редакторе или редакторе кода:

nano app/Console/Commands/LinkNew.php

Чтобы вы могли сохранить новую ссылку в базу данных, в метод handle должны произойти несколько вещей. Во-первых, нужно запросить у пользователей входные данные, чтобы получить URL-адрес.

$url = $this->ask('Link URL:');

Затем на понадобится функция filter_var, которая подтвердит, что ввод, полученный от пользователя, является допустимым URL-адресом. Если ссылка недействительна, пользователь увидит сообщение об ошибке и выйдет из приложения с кодом состояния 1 (который значит, что приложение завершило работу из-за ошибки).

if (!filter_var($url, FILTER_VALIDATE_URL)) {
$this->error("Invalid URL. Exiting...");
return 1;
}

Если ссылка действительна, приложение продолжит работу и запросит описание ссылки (тем же способом, что и раньше).

$description = $this->ask('Link Description:');

Затем приложение запросит окончательное подтверждение того, что все данные верны, для этого существует вспомогательная команда confirm. Если пользователь подтверждает данные, ссылка будет вставлена в БД. Для взаимодействия с базой данных мы используем модель Eloquent по имени Link, созданную в предыдущей части этой серии.

$this->info("New Link:");
$this->info($url . ' - ' . $description);
if ($this->confirm('Is this information correct?')) {
$link = new Link();
$link->url = $url;
$link->description = $description;
$link->save();
$this->info("Saved.");
}

Приложение завершит работу с кодом 0 – это успешный статус (то есть 0 ошибок).

return 0;

Следующий код включает все эти изменения. Замените текущий код в вашем классе app/Console/Commands/LinkNew.php на такой:

<?php
namespace App\Console\Commands;
use App\Models\Link;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
class LinkNew extends Command
{
/**
* имя и подпись консольной команды.
*
* @var string
*/
protected $signature = 'link:new';
/**
* описание команды.
*
* @var string
*/
protected $description = 'Create a New Link';
/**
* создание нового экземпляра команды.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* выполнение команды.
*
* @return int
*/
public function handle()
{
$url = $this->ask('Link URL:');
if (!filter_var($url, FILTER_VALIDATE_URL)) {
$this->error("Invalid URL. Exiting...");
return 1;
}
$description = $this->ask('Link Description:');
$this->info("New Link:");
$this->info($url . ' - ' . $description);
if ($this->confirm('Is this information correct?')) {
$link = new Link();
$link->url = $url;
$link->description = $description;
$link->save();
$this->info("Saved.");
}
return 0;
}
}

Сохраните и закройте файл, когда закончите работу.

Чтобы выполнить команду и вставить новую ссылку в базу данных, запустите:

docker-compose exec app php artisan link:new

Вы получите такой вывод:

Link URL::
> https://www.8host.com/blog/
Link Description::
> Community
New Link:
https://www.8host.com/blog/ - Community
Is this information correct? (yes/no) [no]:
> yes
Saved.

Если хотите, можете добавить еще несколько ссылок.

Список ссылок

А теперь нужно создать новую команду Artisan для отображения списка всех ссылок. Назовем эту команду link:list.

Создайте новую команду с помощью:

docker-compose exec app php artisan make:command LinkList

Откройте класс handle, используя любой текстовый редактор или редактор кода:

nano app/Console/Commands/LinkList.php

В методе handle этой команды мы запросим все строки таблицы links. Вы можете использовать модель Link для доступа к базовым методам запросов к базе данных, которые предоставляет Eloquent. Чтобы красиво отобразить результаты в командной строке, мы обратимся к вспомогательной команде вывода table:

$headers = [ 'id', 'url', 'description' ];
$links = Link::all(['id', 'url', 'description'])->toArray();
$this->table($headers, $links);
return 0;

Ниже вы найдете полную реализацию команды link:list. Замените содержимое файла app/Console/Commands/LinkList.php следующим:

<?php
namespace App\Console\Commands;
use App\Models\Link;
use Illuminate\Console\Command;
class LinkList extends Command
{
/**
* имя и подпись консольной команды.
*
* @var string
*/
protected $signature = 'link:list';
/**
* описание команды.
*
* @var string
*/
protected $description = 'List links saved in the database';
/**
* создание нового экземпляра команды.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Выполнение команды.
*
* @return int
*/
public function handle()
{
$headers = [ 'id', 'url', 'description' ];
$links = Link::all(['id', 'url', 'description'])->toArray();
$this->table($headers, $links);
return 0;
}
}

Сохраните и закройте файл, когда закончите.

Чтобы запустить эту команду и показать список всех ссылок, уже вставленных в таблицу links, выполните:

docker-compose exec app php artisan link:list

Вы получите такой вывод:

+—-+————————————+————–+
| id | url                                | description  |
+—-+————————————+————–+
| 1  | https://www.8host.com/blog/ | Community |
| 2  | https://laravel.com                | Laravel      |
+—-+————————————+————–+

А сейчас мы создадим команду для удаления ссылок:

docker-compose exec app php artisan make:command LinkDelete

Вывод:

Console command created successfully.

Откройте новый файл с помощью выбранного текстового редактора или редактора кода:

nano app/Console/Commands/LinkDelete.php

Назовем эту команду link:delete. Чтобы узнать, какую ссылку необходимо удалить, приложение должно потребовать, чтобы пользователи указали дополнительный аргумент при вызове команды: идентификатор ссылки. Это также устанавливается в переменной $signature, которая определяет, как вызывается команда и какие аргументы (обязательные или опциональные) должны быть в ней:

protected $signature = 'link:delete {link_id}';

Метод handle этой команды реализует несколько разных инструкций. Сначала приложение получит идентификатор ссылки, который должен быть указан в вызове команды.

$link_id = $this->argument('link_id');

Затем указанная ссылка извлекается из базы данных с помощью метода поиска Eloquent, который доступен в вашей модели Link.

$link = Link::find($link_id);

Если метод find не находит в базе данных запись с таким идентификатором, он вернет null. Затем приложение проверит, является ли это текущим значением, содержащимся в переменной $link, и в этом случае вернет ошибку. Программа завершит работу с ошибкой (код 1).

if ($link === null) {
$this->error("Invalid or non-existent link ID.");
return 1;
}

Если значение $link не равно нулю, команда продолжает выполнение. Затем мы используем вспомогательную команду confirm, чтобы запросить подтверждение пользователя.

if ($this->confirm(‘Are you sure you want to delete this link? ‘ . $link->url)) {
// удаляет ссылку
}

Когда пользователь подтверждает действие, набрав yes и нажав Enter, приложение вызывает метод delete из модели Link, чтобы удалить указанную ссылку из базы данных.

$link->delete();
$this->info("Link deleted.");

Ниже вы найдете полный код команды list:delete. Замените содержимое файла LinkDelete.php этим кодом:

<?php
namespace App\Console\Commands;
use App\Models\Link;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
class LinkDelete extends Command
{
/**
* имя и подпись консольной команды.
*
* @var string
*/
protected $signature = 'link:delete {link_id}';
/**
* описание команды.
*
* @var string
*/
protected $description = 'Deletes a link from the database.';
/**
* Создание нового экземпляра команды.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Выполнение команды.
*
* @return int
*/
public function handle()
{
$link_id = $this->argument('link_id');
$link = Link::find($link_id);
if ($link === null) {
$this->error("Invalid or non-existent link ID.");
return 1;
}
if ($this->confirm('Are you sure you want to delete this link? ' . $link->url)) {
$link->delete();
$this->info("Link deleted.");
}
return 0;
}
}

Сохраните и закройте файл, когда закончите.

Если теперь вы захотите удалить ссылку из таблицы links, вам сначала нужно будет получить идентификатор ссылки с помощью команды artisan link:list, как было показано ранее. Как только вы узнаете идентификатор, вы сможете запустить команду artisan link:delete с помощью:

docker-compose exec app php artisan link:delete LINK_ID

Вы получите такой вывод:

Are you sure you want to delete this link? https://laravel.com (yes/no) [no]:
> yes
Link deleted.

Теперь вы можете вставлять ссылки в БД приложения, а также запрашивать их список и удалять их с помощью команд Artisan, выполняемых из командной строки. В следующей части этой серии мы сосредоточимся на внешнем интерфейсе приложения и разработаем его с помощью шаблонов Blade и CSS-фреймворка Bulma.

Tags: ,

Добавить комментарий