Удаление изображений/файлов

Удаление изображений/файлов

Danil Shutsky
Danil Shutsky
06.05.2023 в 09:24

Всех приветствую! Все чаще встречаю вопрос о том как удалять изображения или файлы при использовании полей 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!