Удаление изображений вместе с товаром в 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 гигов, тариф стал очень дорогой, в то время как сам сайт небольшой и товаров не много. Наняли специалиста для проверки, а причина то была совсем простая, много неиспользуемых изображений, так как часто удаляли, заливали товары.

Карина М.

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

Марина

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