wpdownload.ru wordpress WPDownload.ru

WooCommerce: автоматическое удаление товаров без остатков и заказов

Диагностика проблемы: зачем автоматизировать удаление товаров без остатков и заказов

В крупных магазинах на WooCommerce накапливаются товары, которые уже не продаются: остатков нет, а заказов по ним не было. Такие товары занимают место в базе, замедляют админку и усложняют управление каталогом. Ручное удаление занимает много времени и часто приводит к ошибкам.

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

  • Остаток товара равен нулю или меньше.
  • Отсутствуют завершённые заказы с этим товаром.
  • Товар не является вариацией с активными запасами.

Правильно определить товары для удаления — ключ к корректной очистке каталога без потери данных.

Пошаговое решение: автоматическое удаление товаров без остатков и заказов

Реализуем WP-Cron задачу, которая будет запускаться раз в день и удалять товары с нулевым остатком и без заказов.

1. Создание функции для выборки товаров

function wpdownload_get_products_to_delete() {
    global $wpdb;

    // Получаем ID товаров с нулевым или отрицательным запасом
    $products = $wpdb->get_col(
        "SELECT p.ID FROM {$wpdb->prefix}posts p
        LEFT JOIN {$wpdb->prefix}wc_product_meta_lookup pm ON p.ID = pm.product_id
        WHERE p.post_type = 'product'
        AND p.post_status = 'publish'
        AND (pm.stock_quantity IS NULL OR pm.stock_quantity <= 0)"
    );

    if (empty($products)) {
        return [];
    }

    // Исключаем товары, которые встречаются в заказах
    $placeholders = implode(',', array_fill(0, count($products), '%d'));
    $query = $wpdb->prepare(
        "SELECT DISTINCT order_item_meta.meta_value as product_id
        FROM {$wpdb->prefix}woocommerce_order_items order_items
        JOIN {$wpdb->prefix}woocommerce_order_itemmeta order_item_meta ON order_items.order_item_id = order_item_meta.order_item_id
        JOIN {$wpdb->prefix}posts orders ON orders.ID = order_items.order_id
        WHERE order_item_meta.meta_key IN ('_product_id', '_variation_id')
        AND orders.post_status IN ('wc-completed', 'wc-processing')
        AND order_item_meta.meta_value IN ($placeholders)",
        ...$products
    );

    $products_in_orders = $wpdb->get_col($query);

    // Возвращаем товары, которых нет в заказах
    return array_diff($products, $products_in_orders ?: []);
}

2. Функция удаления товаров

function wpdownload_delete_products(array $product_ids) {
    foreach ($product_ids as $product_id) {
        wp_delete_post($product_id, true); // true — удаление без возможности восстановления
    }
}

3. Создание WP-Cron задачи

function wpdownload_schedule_product_cleanup() {
    if (!wp_next_scheduled('wpdownload_daily_product_cleanup')) {
        wp_schedule_event(time(), 'daily', 'wpdownload_daily_product_cleanup');
    }
}
add_action('wp', 'wpdownload_schedule_product_cleanup');

add_action('wpdownload_daily_product_cleanup', function() {
    $products_to_delete = wpdownload_get_products_to_delete();
    if ($products_to_delete) {
        wpdownload_delete_products($products_to_delete);
    }
});

Проверка результата после внедрения

Чтобы убедиться, что автоматическое удаление работает:

  • В админке WooCommerce зайдите в список товаров и проверьте, что товары с нулевым остатком и без заказов исчезают после запуска задачи.
  • Запустите задачу вручную, вызвав функцию из консоли или добавив временный вызов wpdownload_delete_products(wpdownload_get_products_to_delete()); в файл functions.php (не забудьте потом удалить).
  • Проверьте логи сервера или плагина для отладки, если используется, чтобы убедиться, что ошибок нет.

Частые ошибки и как исправить

  • Удаляются товары с активными заказами: Проверьте корректность запроса, особенно фильтр по статусам заказов (wc-completed, wc-processing).
  • Не удаляются товары с нулевым остатком: Убедитесь, что индекс wc_product_meta_lookup.stock_quantity актуален и данные синхронизированы (запустите wp wc product meta lookup sync или аналог).
  • Задача WP-Cron не запускается: Проверьте, что на сайте есть трафик для запуска WP-Cron или настройте системный cron для wp-cron.php.
  • Удаление не учитывает вариации: Исправьте запрос, добавив проверку вариаций и их запасов отдельно.

Практические советы по безопасности и производительности

  • Удаление с wp_delete_post($id, true) — без восстановления. Для безопасных операций сначала можно использовать wp_trash_post($id), чтобы проверить результаты.
  • Если товаров очень много, разбейте удаление на партии по 50-100 штук, чтобы не перегружать сервер.
  • Добавьте логирование удалённых товаров в отдельный файл для аудита.
  • Используйте транзакции базы данных, если позволяет версия MySQL, чтобы избежать частичного удаления.

Сравнение вариантов реализации удаления товаров

МетодПлюсыМинусы
Ручное удаление через админку Простота, контроль Долго, риск пропустить товары
Плагин для очистки каталога Автоматизация, интерфейс Доп. нагрузка, возможны конфликты
Код с WP-Cron и запросами SQL (как в статье) Точный контроль, производительность Требует навыков, опасность ошибок без тестов
×

AI-плагин

WPGPT
Сам создает статьи для вашего сайта WordPress

SEO и мета-теги

Парсинг конкурентов

Изображения

Комментарии

Подробнее