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

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

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

Как определить товары без заказов за период

Для начала необходимо получить список товаров, которые не были куплены за заданное количество дней. В WooCommerce заказы и товары связаны через таблицы wp_woocommerce_order_items и wp_woocommerce_order_itemmeta. Однако для упрощения задачи можно использовать WP_Query с мета-запросами и дополнительную логику на PHP.

Пример запроса для получения ID товаров без заказов за 30 дней

function get_products_without_orders( $days = 30 ) {
    global $wpdb;
    $date_threshold = date( 'Y-m-d H:i:s', strtotime( "-{$days} days" ) );

    // Получаем ID товаров, которые были в заказах за последние $days дней
    $ordered_product_ids = $wpdb->get_col( $wpdb->prepare(
        "SELECT DISTINCT order_item_meta.meta_value FROM {$wpdb->prefix}woocommerce_order_items AS order_items
        
        INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS order_item_meta ON order_items.order_item_id = order_item_meta.order_item_id
        
        INNER JOIN {$wpdb->prefix}posts AS orders ON orders.ID = order_items.order_id
        
        WHERE order_item_meta.meta_key = '_product_id'
        AND orders.post_type = 'shop_order'
        AND orders.post_status IN ('wc-completed', 'wc-processing')
        AND orders.post_date >= %s",
        $date_threshold
    ));

    if ( empty( $ordered_product_ids ) ) {
        // Если заказов не было, возвращаем все товары
        $all_products = get_posts( [
            'post_type' => 'product',
            'numberposts' => -1,
            'fields' => 'ids',
        ] );
        return $all_products;
    }

    // Получаем все товары
    $all_products = get_posts( [
        'post_type' => 'product',
        'numberposts' => -1,
        'fields' => 'ids',
    ] );

    // Вычитаем товары с заказами
    return array_diff( $all_products, $ordered_product_ids );
}

Пошаговое решение: автоматизация удаления товаров

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

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

function delete_products_without_orders_cron() {
    $days = 30; // Период без заказов
    $products_to_delete = get_products_without_orders( $days );

    if ( empty( $products_to_delete ) ) {
        return;
    }

    foreach ( $products_to_delete as $product_id ) {
        wp_delete_post( $product_id, true ); // Полное удаление
    }
}

2. Регистрация WP-Cron задачи

add_action( 'wpengine_daily_delete_products', 'delete_products_without_orders_cron' );

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

3. Как вручную запустить задачу (для тестирования)

// Временно вызовем функцию для проверки
add_action( 'admin_init', function() {
    if ( isset( $_GET['run_delete_products'] ) && current_user_can( 'manage_options' ) ) {
        delete_products_without_orders_cron();
        wp_die( 'Удаление товаров выполнено' );
    }
});

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

  • Перейдите в раздел Товары в админке и проверьте, что товары без заказов за последний месяц удалены.
  • Запустите вручную удаление по ссылке https://example.com/wp-admin/?run_delete_products=1 под своей учетной записью с правами администратора.
  • Проверьте логи сервера и отладочные логи WordPress на предмет ошибок.
  • Убедитесь, что WP-Cron событие wpengine_daily_delete_products запланировано (например через плагин WP Crontrol).

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

  • WP-Cron не запускается: По умолчанию WP-Cron активируется при посещении сайта. Если трафика мало, cron может не срабатывать. Решение: настроить системный cron на сервере для вызова wp-cron.php или использовать плагины для управления задачами.
  • Удаление не происходит: Проверьте, что функция get_products_without_orders() корректно возвращает ID товаров. Ошибка в SQL-запросе или права доступа к базе могут блокировать получение данных.
  • Удаляются нужные товары: Убедитесь, что фильтрация по датам и статусам заказов настроена правильно. Перед удалением полезно выводить список товаров для проверки.
  • Высокая нагрузка при выполнении: Если товаров слишком много, удаление всех за один раз может вызвать таймаут. Разбейте удаление на партии по 50-100 товаров.

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

  • Перед автоматическим удалением товаров делайте резервную копию базы данных.
  • Добавьте логирование действий удаления в отдельный файл или в системный лог для аудита.
  • Для больших магазинов используйте пакетную обработку (batch processing) с transients или options для сохранения прогресса.
  • Используйте проверки nonce и права пользователя, если делаете ручной запуск через URL.
  • Если не хотите полностью удалять товары, можно сначала переводить их в черновики с помощью wp_update_post(['ID' => $product_id, 'post_status' => 'draft']).

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

МетодПреимуществаНедостатки
WP-Cron с кастомной функциейГибкость, полный контроль, не требует сторонних плагиновЗависит от трафика, требует отладки SQL и PHP-кода
Плагины для автоматизации очистки каталогаПростота настройки, готовые интерфейсыМогут быть тяжелыми, не всегда гибкие под задачи
Ручное удаление через админкуБезопасность, контрольТрудоемко, неэффективно для больших магазинов
Как создать динамический метабокс в WordPress с помощью хуков
02.04.2026
Как защитить WordPress от Brute Force атак
30.03.2026
Оптимизация WordPress для быстрой загрузки сайта: практические методы и примеры
05.11.2025
WooCommerce: автоматическое удаление закрытых заказов для оптимизации базы данных
03.07.2026
Как отключить autoload для оптимизации WordPress
01.02.2026