WooCommerce: как автоматически удалять товары без заказов за 30 дней

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

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

Чтобы убедиться, что у вас есть такие товары, выполните SQL-запрос к базе данных:

SELECT p.ID, p.post_title, MAX(oim.meta_value) as last_order_date
FROM wp_posts p
LEFT JOIN wp_woocommerce_order_items oi ON oi.order_item_name = p.post_title
LEFT JOIN wp_woocommerce_order_itemmeta oim ON oi.order_item_id = oim.order_item_id AND oim.meta_key = '_product_id'
WHERE p.post_type = 'product'
GROUP BY p.ID
ORDER BY last_order_date ASC;

Если товары не имеют записей заказов за последние 30 дней, их можно удалять автоматически.

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

1. Создаем функцию для проверки даты последнего заказа товара

function get_last_order_date_for_product($product_id) {
    global $wpdb;
    $query = $wpdb->prepare(
        "SELECT MAX(p.post_date) FROM {$wpdb->prefix}posts p
         INNER JOIN {$wpdb->prefix}woocommerce_order_items oi ON p.ID = oi.order_id
         INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta oim ON oi.order_item_id = oim.order_item_id
         WHERE p.post_type = 'shop_order'
         AND p.post_status IN ('wc-completed', 'wc-processing')
         AND oim.meta_key = '_product_id'
         AND oim.meta_value = %d",
        $product_id
    );
    return $wpdb->get_var($query);
}

2. Функция для удаления товаров без заказов за последние 30 дней

function delete_products_without_orders_30_days() {
    $args = array(
        'post_type' => 'product',
        'posts_per_page' => -1,
        'post_status' => 'publish',
    );
    $products = get_posts($args);
    $now = current_time('timestamp');
    $deleted_count = 0;
    foreach ($products as $product) {
        $last_order_date = get_last_order_date_for_product($product->ID);
        if (!$last_order_date) {
            // Нет заказов вообще
            wp_delete_post($product->ID, true);
            $deleted_count++;
            continue;
        }
        $last_order_timestamp = strtotime($last_order_date);
        if (($now - $last_order_timestamp) > 30 * DAY_IN_SECONDS) {
            wp_delete_post($product->ID, true);
            $deleted_count++;
        }
    }
    error_log("Автоматическое удаление товаров: удалено {$deleted_count} товаров без заказов за 30 дней");
}

3. Запускаем функцию по расписанию через WP-Cron

Добавьте в functions.php регистрацию события и его обработчик:

if (!wp_next_scheduled('delete_products_without_orders_event')) {
    wp_schedule_event(time(), 'daily', 'delete_products_without_orders_event');
}
add_action('delete_products_without_orders_event', 'delete_products_without_orders_30_days');

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

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

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

  • Неправильные статусы заказов в запросе: учитывайте только 'wc-completed' и 'wc-processing', иначе товары с отмененными или черновыми заказами будут ошибочно учитываться.
  • Отсутствие прав на удаление товаров: убедитесь, что код выполняется с достаточными правами (админ).
  • Пустой результат из-за кеширования: очищайте кеш WooCommerce и объекта, чтобы получить актуальные данные.
  • Нагрузка на базу при большом количестве товаров: разбейте обработку на порции, используйте transients для хранения прогресса.

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

  • Перед удалением товаров делайте бэкап базы данных.
  • Добавьте логирование удалений для аудита.
  • Используйте WP-CLI для ручного запуска и отладки.
  • Для очень больших магазинов запускать удаление ночью, чтобы снизить нагрузку.
  • Можно добавить в админку кнопку для запуска очистки с подтверждением.

Сравнение вариантов реализации автоматического удаления

МетодПлюсыМинусы
Код через WP-Cron (как в статье)Полный контроль, гибкость, интеграция с WooCommerceНагрузка при большом количестве товаров, требует навыков PHP
Плагины очистки WooCommerceПростота установки, интерфейсМогут не покрывать все требования, ограниченная кастомизация
Ручное удаление через SQL-запросыПрямое управление, быстроРиск ошибок, потеря данных, сложность поддержки
WooCommerce: решение проблемы не отображения атрибутов вариативных товаров
05.06.2026
WooCommerce: отладка и решение проблем с неотображением вариативных атрибутов
19.05.2026
WooCommerce: решение проблемы не работающих вариативных атрибутов в описании товара
19.04.2026
Как отключить autoload для оптимизации WordPress
01.02.2026
WooCommerce: автоматическое удаление товаров без заказов за заданный период
17.07.2026