Всех приветствую! Все чаще встречаю вопрос о том как удалять изображения или файлы при использовании полей Image/File в MoonShine. На момент написания этой статьи в Мун нет такой возможности на уровне интерфейса полей, но не стоит упираться в возможности админ. панели, ведь она использует возможности Laravel по-максимому и в этом и таится ответ на вопрос как удалять!
Давайте рассмотрим детально как выполнить задачу по удалению файлов, а заодно получим интересный опыт взаимодействия с событиями модели. Мы с Вами знаем что стандартный ресурс в Мун это всего лишь обвертка над моделью. И при редактировании, удалении или добавлении - дергаются события, давайте ими воспользуемся:
// ...
Image::make('Thumbnail')->dir('articles')->removable(),
// ...
У нас есть ресурс со статьями, у которых есть миниатюра (thumbnail) и мы даем возможность удалять изображение.
В модели Article нам необходимо объявить событие на редактирование
protected static function boot(): void
{
parent::boot();
static::updated(static function (Article $item) {
});
}
Давайте добавим логику и обратите внимание, на сколько она простая
protected static function boot(): void
{
parent::boot();
static::updated(static function (Article $item) {
if ($item->wasChanged('thumbnail') && $item->getOriginal('thumbnail')) {
Storage::disk('public')->delete($item->getOriginal('thumbnail'));
}
});
}
С помощью метода wasChanged мы проверяем, изменилось ли у нас поле с изображением, а также проверяем есть ли у нас предыдущее значение с помощью метода getOriginal (необходимо так как изображения могло не быть и мы его только добавили, но удалять пока нечего).
Ну а далее мы удаляем предыдущее значение, которое больше к статье не привязано.
То же самое можно сделать и на уровне MoonShine в ресурсе, ведь там также есть события. Такой путь может потребоваться если вы не хотите мешать логику проекта с админ. панелью
protected function afterUpdated(Model $item)
{
if ($item->wasChanged('thumbnail') && $item->getOriginal('thumbnail')) {
Storage::disk('public')->delete($item->getOriginal('thumbnail'));
}
}
Тут уже выбирать Вам как лучше, но цель этой статьи расширить ваше мышление разработчика, смотрите на код иначе, думайте за пределами интерфейса который вам предоставлен! Все-таки мы не пользователи, а разработчики и это прекрасно!
P.s. У кого то из вас может возникнуть вопрос - "Ок, как удалять одно изображение понятно, но как удалять если там коллекция?!". Это не сложно, буквально на пару строчек кода будет больше. И я расскажу вам как это можно сделать, если будет интересно. Поэтому дайте мне знать, нужен ли такой совет в комментариях к этому посту! Всем спасибо за внимание. Пользуйтесь MoonShine!