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

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

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

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

1. Определение товаров без заказов за нужный период

Для начала нам нужно получить список товаров, у которых не было заказов за последний, например, год. Это делается запросом к базе данных, используя WC_Order_Item_Product и WP_Query.

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

    // Получаем ID продуктов, у которых были заказы за период
    $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 posts ON order_items.order_id = posts.ID
        WHERE order_item_meta.meta_key = '_product_id'
        AND posts.post_type = 'shop_order'
        AND posts.post_status IN ('wc-completed', 'wc-processing')
        AND posts.post_date >= %s",
        $date_limit
    ) );

    // Получаем все опубликованные товары
    $args = [
        'post_type' => 'product',
        'post_status' => 'publish',
        'posts_per_page' => -1,
        'fields' => 'ids',
        'post__not_in' => $ordered_product_ids
    ];
    $query = new WP_Query( $args );
    return $query->posts;
}

2. Удаление товаров без заказов

Функция удаления должна запускаться по расписанию (WP-Cron) или вручную. Важно использовать wp_delete_post() с параметром true для полного удаления без перемещения в корзину.

function delete_products_without_orders() {
    $products_to_delete = get_products_without_orders( 365 ); // за последний год
    foreach ( $products_to_delete as $product_id ) {
        wp_delete_post( $product_id, true );
    }
}

// Добавим WP-Cron задачу
if ( ! wp_next_scheduled( 'daily_delete_products_without_orders' ) ) {
    wp_schedule_event( time(), 'daily', 'daily_delete_products_without_orders' );
}
add_action( 'daily_delete_products_without_orders', 'delete_products_without_orders' );

3. Ручной запуск для проверки

Для теста можно запускать функцию вручную из консоли или через админку:

delete_products_without_orders(); // Вызвать в functions.php или через WP-CLI

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

  • После запуска функции проверьте, что товары без заказов удалены через админку WooCommerce.
  • Выполните SQL-запрос SELECT COUNT(*) FROM wp_posts WHERE post_type = 'product' AND ID IN (...) для проверки наличия удалённых товаров.
  • Проверьте логи WP-Cron, чтобы убедиться, что задача срабатывает ежедневно.

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

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

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

  • Перед удалением делайте резервное копирование базы данных.
  • Используйте транзакции или разбивайте удаление на небольшие части (например, по 50 товаров за раз).
  • Чтобы не нагружать базу, добавляйте в запросы индексирование по дате и ID.
  • Запускайте удаление в ночное время или периоды низкой нагрузки.

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

МетодПреимуществаНедостатки
Код в functions.php + WP-CronПолный контроль, без лишних плагинов, гибкие настройкиТребует знаний PHP, WP-Cron зависит от посещаемости сайта
Плагины очистки каталога (например, Bulk Delete)Простота использования, графический интерфейсИзбыточный функционал, возможна нагрузка, ограниченная кастомизация
Внешние скрипты через WP-CLIБыстрая обработка больших объёмов, не зависит от WP-CronТребует доступа к серверу и навыков командной строки
Как создать свой плагин для WordPress с нуля
12.11.2025
WooCommerce: как автоматически удалять товары без заказов за 30 дней
24.06.2026
WooCommerce: решение проблемы не работающих вариативных атрибутов в описании товара
16.05.2026
WooCommerce: решение проблем с автоматическим обновлением остатков и цен товаров
24.07.2026
Как автоматизировать управление ролями в WordPress с помощью кода
14.02.2026