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

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

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

  • Неправильный выбор статуса заказа для проверки (например, учитываются только completed, а заказы в статусе processing игнорируются).
  • Отсутствие правильной фильтрации по дате — учитываются все заказы, или дата заказа не проверяется.
  • Ошибки в SQL-запросах, которые не возвращают корректный список товаров.
  • Кэширование, из-за которого скрипт не видит актуальные данные.
  • Проблемы с правами пользователя, под которым запускается скрипт удаления.

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

1. Определение периода и статусов заказов

Для начала определите, за какой период товаров без заказов нужно удалять, и какие статусы заказов считать:

$period_days = 90; // Товары без заказов за последние 90 дней будут удалены
$order_statuses = array('wc-completed', 'wc-processing'); // Учесть только эти статусы

2. Получение ID товаров с заказами

Используйте WP_Query с meta-запросом по заказам и статусам, чтобы получить ID товаров, которые были в заказах за период:

$date_threshold = date('Y-m-d H:i:s', strtotime('-' . $period_days . ' days'));

$args = array(
    'post_type'      => 'shop_order',
    'post_status'    => $order_statuses,
    'date_query'     => array(
        array(
            'after' => $date_threshold,
            'inclusive' => true,
        ),
    ),
    'posts_per_page' => -1,
    'fields'         => 'ids',
);

$order_query = new WP_Query($args);

$orders_ids = $order_query->posts;

3. Получение ID товаров из заказов

Извлеките товары из заказов и составьте список ID:

$products_in_orders = array();

foreach ($orders_ids as $order_id) {
    $order = wc_get_order($order_id);
    if (!$order) continue;

    foreach ($order->get_items() as $item) {
        $product_id = $item->get_product_id();
        $products_in_orders[$product_id] = true;
    }
}

$products_with_orders = array_keys($products_in_orders);

4. Получение всех ID товаров и фильтрация на удаление

Получите все товары и исключите те, что были в заказах:

$all_products = get_posts(array(
    'post_type'      => 'product',
    'posts_per_page' => -1,
    'fields'         => 'ids',
));

$products_to_delete = array_diff($all_products, $products_with_orders);

5. Удаление товаров

Удалите товары программно, используя wp_delete_post() с параметром true для безвозвратного удаления:

foreach ($products_to_delete as $product_id) {
    wp_delete_post($product_id, true);
}

6. Автоматизация через WP-Cron

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

if (!wp_next_scheduled('auto_delete_unused_products')) {
    wp_schedule_event(time(), 'daily', 'auto_delete_unused_products');
}

add_action('auto_delete_unused_products', function() use ($period_days, $order_statuses) {
    // Весь код удаления из предыдущих шагов здесь
});

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

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

  • Проверьте, что на сайте исчезли товары без заказов за указанный период.
  • Включите журнал ошибок WP и проверьте, нет ли ошибок при выполнении задачи.
  • Выполните скрипт вручную (через вызов функции или WP-CLI), чтобы убедиться, что товары удаляются корректно.
  • Проверьте, что товары, по которым были заказы, остались в каталоге.

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

  • Неправильные статусы заказов: Если учитывать только wc-completed, можно пропустить товары с заказами в статусе processing. Добавьте все релевантные статусы.
  • Не учитывается дата заказа: Без фильтра по дате удаляются товары, которые могли быть заказаны недавно.
  • Отсутствие проверки на существование заказа: Используйте wc_get_order() и проверяйте, что объект заказа не null.
  • Удаление без подтверждения: При разработке используйте флаг wp_delete_post($id, false) для перемещения в корзину, чтобы избежать потери данных.
  • Проблемы с правами: Запуск кода должен быть от имени администратора или пользователя с правами на удаление товаров.

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

  • Перед массовым удалением товаров сделайте резервную копию базы данных.
  • Учитывайте нагрузку на сервер при запуске cron-задачи: делайте её в ночное время или разбивайте удаление на части.
  • Используйте транзиенты или кеширование для хранения списка товаров с заказами, чтобы не делать тяжелые запросы каждый раз.
  • Проверяйте, не зависят ли другие плагины или кастомный функционал от удаляемых товаров.
  • Рассмотрите использование плагина Clearfy Pro для оптимизации базы и удаления дубликатов и неиспользуемых данных (https://wpshop.ru/plugins/clearfy?utm_source=wpengine.ru&utm_medium=article&utm_campaign=woocommerce-reshenie-problem-s-avtomaticheskim-udaleniem-tovarov-bez-zakazov).

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

МетодОписаниеПлюсыМинусы
Ручное удаление через админкуУдаление товаров вручную в WooCommerceПростой способ, без кодаНеэффективно для большого каталога
Плагин для удаления неактивных товаровИспользование готовых плагиновАвтоматизация, удобный интерфейсМожет быть ресурсозатратным, ограниченная гибкость
Кастомный код с WP-CronСобственная реализация автоматического удаленияПолный контроль, настройка под задачиТребует навыков разработки, риск ошибок
Как отключить XML-RPC в WordPress для повышения безопасности
05.03.2026
Автоматизация обновлений WordPress с WPengine: настройка и примеры
14.12.2025
Как отключить Gutenberg в WordPress: лучшие способы и практические примеры
03.12.2025
WooCommerce: автоматическое удаление товаров без заказов
12.05.2026
Автоматическое создание купонов в WooCommerce по условиям заказов
04.06.2026