Автоматическое удаление непроданных товаров WooCommerce по времени

Почему нужно автоматизировать удаление непроданных товаров в WooCommerce

В интернет-магазинах WooCommerce часто возникает задача очистки каталога от товаров, которые не были проданы за определенный период. Это помогает поддерживать актуальность ассортимента, улучшить производительность сайта и упростить управление товарами.

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

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

Перед автоматическим удалением нужно четко определить критерии:

  • Товар не имеет ни одного заказа (не продан).
  • Дата создания товара старше X дней (например, 90).
  • Товар не находится в статусе "черновик" или "ожидание".

Для проверки можно выполнить SQL-запрос, чтобы найти количество таких товаров:

SELECT p.ID, p.post_date FROM wp_posts p
LEFT JOIN wp_woocommerce_order_items oi ON oi.order_item_name = p.post_title
WHERE p.post_type = 'product' AND p.post_status = 'publish'
GROUP BY p.ID
HAVING COUNT(oi.order_item_id) = 0 AND p.post_date < NOW() - INTERVAL 90 DAY;

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

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

1. Регистрация cron-задания

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

2. Обработчик cron задачи

add_action('wc_auto_delete_old_unsold_products', function() {
    global $wpdb;
    // Период в днях для удаления
    $days = 90;
    
    // Получаем ID товаров, которые не проданы и старше $days дней
    $query = $wpdb->prepare(
        "SELECT p.ID FROM {$wpdb->posts} p
        LEFT JOIN (
            SELECT DISTINCT order_item_meta.post_id
            FROM {$wpdb->prefix}woocommerce_order_items oi
            INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta order_item_meta ON oi.order_item_id = order_item_meta.order_item_id
            WHERE order_item_meta.meta_key = '_product_id'
        ) sold ON sold.post_id = p.ID
        WHERE p.post_type = 'product' 
        AND p.post_status = 'publish'
        AND sold.post_id IS NULL
        AND p.post_date < NOW() - INTERVAL %d DAY",
        $days
    );

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

    if (empty($product_ids)) {
        return; // Нет товаров для удаления
    }

    foreach ($product_ids as $product_id) {
        wp_delete_post($product_id, true); // Безопасное удаление с обходом корзины
    }
});

3. Очистка cron при деактивации темы или плагина

register_deactivation_hook(__FILE__, function() {
    $timestamp = wp_next_scheduled('wc_auto_delete_old_unsold_products');
    if ($timestamp) {
        wp_unschedule_event($timestamp, 'wc_auto_delete_old_unsold_products');
    }
});

Как проверить, что автоматическое удаление работает

  • Включите WP_DEBUG в wp-config.php и добавьте логирование в обработчик для проверки ID удаляемых товаров.
  • Запустите вручную cron-задачу через плагин WP Crontrol или вызовите обработчик через do_action('wc_auto_delete_old_unsold_products');.
  • Проверьте в админке WooCommerce, что товары, удовлетворяющие условию, исчезли.
  • Убедитесь, что в отчетах заказов отсутствуют удалённые товары.

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

  • Неверный выборка товаров: учитывайте использование кастомных полей и вариаций. Наш запрос основывается на метаполях заказов и может не учитывать вариации, если мета ключ другой.
  • Удаление активных товаров: проверьте, что статус товаров — publish, чтобы не удалять черновики или архивные товары.
  • WP-Cron не запускается: стандартный WP-Cron зависит от посещений сайта. Для стабильности настройте системный cron на вызов wp-cron.php.
  • Ошибка при удалении товаров: убедитесь, что у пользователя, под которым выполняется код, есть права на удаление постов.

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

  • Запускайте удаление не чаще раза в сутки, чтобы не нагружать сервер.
  • Проверяйте наличие резервных копий перед автоматическим удалением.
  • При большом количестве товаров делайте удаление пакетами (порциями по 50-100), чтобы избежать таймаутов.
  • Логируйте операции в отдельный файл или таблицу для аудита.
  • Для ускорения используйте прямые SQL-запросы выборки, но удаление делайте через wp_delete_post(), чтобы корректно очистить все связанные данные.

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

МетодПлюсыМинусы
Плагин очистки (например, WP Sweep)Удобство, опции настроек, UIМожет не поддерживать конкретные задачи под WooCommerce
Кастомный код с WP-Cron (как в статье)Точный контроль, адаптация под задачиТребует навыков, возможны ошибки в коде
Ручное удаление через админкуПростота для новичковРучной труд, риск пропуска
Автоматическое изменение метаданных SEO в WordPress
22.03.2026
Как удалить или заблокировать регистрацию пользователей в WordPress
09.01.2026
Как автоматизировать удаление старых неиспользуемых медиафайлов в WordPress
07.03.2026
WooCommerce: как исключить товары из поиска и каталога по атрибутам
13.05.2026
Как изменить структуру URL в WordPress без плагинов
24.01.2026