WooCommerce: как автоматически удалять товары по устаревшим заказам

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

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

Проверьте, есть ли в вашем магазине товары, которые не продаются долгое время или связаны с заказами со статусом, например, "отменён" или "возврат". Для этого можно воспользоваться SQL-запросом:

SELECT p.ID, p.post_title, MAX(o.post_date) 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_posts o ON oi.order_id = o.ID AND o.post_type = 'shop_order'
WHERE p.post_type = 'product'
GROUP BY p.ID
HAVING last_order_date < DATE_SUB(NOW(), INTERVAL 6 MONTH) OR last_order_date IS NULL;

Этот запрос покажет товары, для которых последнее связанное с ними заказы были сделаны более 6 месяцев назад или отсутствуют вовсе.

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

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

Добавьте следующий код в файл functions.php вашей темы или в отдельный плагин:

function get_products_by_old_orders( $months = 6 ) {
    global $wpdb;

    $query = $wpdb->prepare(
        "SELECT p.ID FROM {$wpdb->posts} p
        LEFT JOIN {$wpdb->prefix}woocommerce_order_items oi ON oi.order_item_name = p.post_title
        LEFT JOIN {$wpdb->posts} o ON oi.order_id = o.ID AND o.post_type = 'shop_order'
        WHERE p.post_type = 'product'
        GROUP BY p.ID
        HAVING MAX(o.post_date) < DATE_SUB(NOW(), INTERVAL %d MONTH) OR MAX(o.post_date) IS NULL",
        $months
    );

    return $wpdb->get_col( $query );
}

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

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

3. Настройка WP-Cron для регулярного удаления

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

if ( ! wp_next_scheduled( 'auto_delete_old_products_hook' ) ) {
    wp_schedule_event( time(), 'monthly', 'auto_delete_old_products_hook' );
}

add_action( 'auto_delete_old_products_hook', function() {
    $old_products = get_products_by_old_orders( 6 ); // товары без заказов 6 месяцев
    if ( ! empty( $old_products ) ) {
        delete_products_by_ids( $old_products );
    }
});

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

Для проверки выполните следующие шаги:

  • Вручную вызовите функцию и выведите список ID товаров, которые будут удалены:
    $products = get_products_by_old_orders(6); print_r($products);
  • Проверьте панель управления WooCommerce — соответствующие товары должны исчезнуть.
  • Для теста запустите вручную событие WP-Cron с помощью плагина WP Crontrol или вызовите функцию напрямую.

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

  • Ошибка: Пустой результат выборки товаров.
    Причина: Неправильно настроена дата или отсутствуют корректные связи между заказами и товарами.
    Решение: Проверьте структуру таблиц woocommerce_order_items и убедитесь, что order_item_name совпадает с post_title товара. Лучше заменить JOIN на order_item_id с мета-данными.
  • Ошибка: Товары не удаляются.
    Причина: Отсутствие прав на удаление или отключена функция wp_delete_post.
    Решение: Проверьте, что код выполняется с правами администратора и что нет плагинов, блокирующих удаление.
  • Ошибка: Удаляются нужные товары.
    Причина: Слишком широкие условия выборки.
    Решение: Уточните критерии, добавьте проверки по статусу заказа (например, исключить "завершённые")

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

  • Перед массовым удалением сделайте резервную копию базы данных.
  • Добавьте логирование удалённых товаров для аудита.
  • Оптимизируйте SQL-запрос, используя мета-данные woocommerce_order_itemmeta для точной связи товаров и заказов.
  • Используйте транзакции или периодическую обработку пакетами, чтобы избежать таймаутов.

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

МетодОписаниеПлюсыМинусы
SQL + WP-Cron Прямой запрос к базе с регулярным запуском Быстро, не требует плагинов Сложность корректной настройки, риск ошибок в запросах
Плагин очистки Использование готового решения, например WP Sweep Простота, безопасность Могут быть избыточными, не всегда гибкие
Ручное удаление Через админку или экспорт Полный контроль Трудоёмко, не автоматизировано
Как создать виджет очистки кеша Redis в WordPress
29.01.2026
WooCommerce: как автоматически удалять заказы по статусу и дате
17.06.2026
WooCommerce: автоматическое изменение цены и наличия товара по расписанию
21.07.2026
WooCommerce: как автоматически удалять товары по устаревшим заказам
28.06.2026
Как создать настройку автоматической отправки email из WPForms в WordPress
25.01.2026