Удаление изображений вместе с товаром в WooCommerce

Удаление изображений вместе с товаром в WooCommerce

В WooCommerce многие разработчики замечают: удаляешь товар, а изображения остаются в медиабиблиотеке. Это не баг, а осознанная архитектура WordPress. В этой статье разберём:

  • как связаны товары и изображения
  • почему изображения не удаляются автоматически
  • какие есть хуки для удаления
  • готовые PHP-решения
  • плагины для автоматической очистки медиатеки

Как WooCommerce хранит изображения товаров

Чтобы понять проблему, нужно разобраться в архитектуре WordPress.

1. Изображения — это отдельные записи (attachment)

В WordPress каждое изображение — это не “файл внутри товара”, а отдельный объект в базе данных:

  • тип записи: attachment
  • хранится в таблице wp_posts
  • файл лежит в /wp-content/uploads/

Товар (product) — это тоже запись в wp_posts, но с типом product.

Связь между ними — только через мета-поля:

  • _thumbnail_id — главное изображение товара
  • _product_image_gallery — галерея (ID через запятую)

2. Важно: изображение может использоваться в разных местах

Одно изображение может быть:

  • в товаре
  • в записи блога
  • в галерее
  • в ACF-полях
  • в Elementor

Поэтому WordPress НЕ удаляет его автоматически — иначе можно сломать сайт.

Почему изображения не удаляются при удалении товара

Это ключевой момент.

Причина 1: безопасность данных

Если удалить товар → удалить изображения → а они используются в другом месте → сайт ломается.

Поэтому WordPress выбирает безопасную стратегию: удаляем товар, но медиа оставляем

Причина 2: изображения не “принадлежат” товару

У товара нет “владения” файлами. Есть только ссылки (ID).

Причина 3: производительность

Автоматическая проверка “где используется файл”:

  • дорогая операция
  • замедляет удаление постов
  • требует обхода всей базы

Причина 4: корзина (Trash)

Если товар в корзине — его можно восстановить.
Если бы изображения удалились сразу — восстановление было бы невозможным.

Как правильно удалять изображения товара

Есть несколько уровней решения.

1. Хук WooCommerce при удалении товара

Самый правильный способ — использовать хук:

add_action('before_delete_post', 'delete_woocommerce_product_images');

function delete_woocommerce_product_images($post_id) {
    if (get_post_type($post_id) !== 'product') {
        return;
    }

    $product = wc_get_product($post_id);

    if (!$product) return;

    // Главное изображение
    $thumbnail_id = $product->get_image_id();

    // Галерея
    $gallery_ids = $product->get_gallery_image_ids();

    $image_ids = array_merge([$thumbnail_id], $gallery_ids);

    foreach ($image_ids as $image_id) {
        if ($image_id) {
            wp_delete_attachment($image_id, true);
        }
    }
}

Что делает код:

  • ловит удаление товара
  • получает ID изображений
  • удаляет файлы + записи attachment

2. Альтернатива: хук WooCommerce

Можно использовать более “WooCommerce-специфичный” вариант:

add_action('woocommerce_delete_product', 'wc_delete_product_images');

function wc_delete_product_images($product_id) {
    $product = wc_get_product($product_id);
    if (!$product) return;

    $images = array_merge(
        [$product->get_image_id()],
        $product->get_gallery_image_ids()
    );

    foreach ($images as $image_id) {
        wp_delete_attachment($image_id, true);
    }
}

3. Удаление только “неиспользуемых” изображений (умный вариант)

Если важно не сломать сайт:

function safe_delete_attachment($attachment_id) {
    global $wpdb;

    $used = $wpdb->get_var($wpdb->prepare("
        SELECT post_id FROM $wpdb->postmeta
        WHERE meta_value = %d
        LIMIT 1
    ", $attachment_id));

    if (!$used) {
        wp_delete_attachment($attachment_id, true);
    }
}

Удаляет только если изображение нигде не используется.

Плагины для автоматического удаления изображений

Если не хочется писать код:

1. Media Cleaner

  • ищет “осиротевшие” изображения
  • удаляет неиспользуемые файлы
  • безопасный режим (dry run)

2. WP Bulk Delete

  • массовое удаление товаров
  • очистка привязанных данных
  • поддержка WooCommerce

3. Advanced Database Cleaner

  • чистит мета-данные
  • удаляет мусорные attachment
  • оптимизирует базу

Частые ошибки разработчиков

❌ Ошибка 1: удаление файла напрямую

unlink($file);

Плохо, потому что:

  • остаётся запись attachment
  • ломаются ссылки в базе

❌ Ошибка 2: удаление только главного изображения

Многие забывают про gallery:

$product->get_gallery_image_ids();

❌ Ошибка 3: удаление без проверки использования

Можно случайно удалить изображение, которое используется в блоге.

Как это делают крупные проекты

В больших WooCommerce-магазинах обычно:

  • изображения НЕ удаляют сразу
  • используют cron-очистку
  • проверяют usage по всей базе
  • делают “мягкое удаление” (soft delete)

Лучший практический подход

Рекомендуемая схема:

  1. При удалении товара — помечать изображения как “candidate for deletion”
  2. Через cron проверять использование
  3. Удалять только если нет связей

Вывод

WooCommerce не удаляет изображения автоматически по одной простой причине: изображения — это независимые сущности, которые могут использоваться в разных частях сайта.

Поэтому правильное решение зависит от проекта:

  • маленький сайт → можно удалять через hook
  • магазин → лучше проверка + cron
  • крупный проект → система очистки медиатеки
Подписаться
Уведомить о
guest

5 комментариев
Популярные
Новые Старые
Межтекстовые Отзывы
Посмотреть все комментарии
Ильяс

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

Карина М.

А куда писать этот код, хук?

Марина

А вручную можно удалить?