Автоматическое удаление товаров без продаж в WooCommerce

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

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

Как определить товары без продаж и автоматически их удалять

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

В WooCommerce данные о продажах хранятся в мета-полях заказов и связях с товарами. Чтобы получить товары без продаж, можно сравнить ID товаров с ID товаров, которые были в заказах.

function get_unsold_products_ids() {
    global $wpdb;
    // Получаем все ID товаров
    $all_products = $wpdb->get_col("SELECT ID FROM {$wpdb->posts} WHERE post_type = 'product' AND post_status = 'publish'");
    
    // Получаем ID товаров, которые были куплены
    $sold_products = $wpdb->get_col(
        "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 
         WHERE order_items.order_item_type = 'line_item' 
         AND order_item_meta.meta_key = '_product_id'");

    // Находим товары без продаж
    $unsold = array_diff($all_products, $sold_products);
    return $unsold;
}

Автоматическое удаление товаров без продаж через Cron

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

function schedule_clear_unsold_products() {
    if ( ! wp_next_scheduled( 'clear_unsold_products_event' ) ) {
        wp_schedule_event( time(), 'monthly', 'clear_unsold_products_event' );
    }
}
add_action( 'wp', 'schedule_clear_unsold_products' );

function clear_unsold_products() {
    $unsold_ids = get_unsold_products_ids();
    foreach ( $unsold_ids as $product_id ) {
        wp_trash_post( $product_id ); // отправляем в корзину
    }
}
add_action( 'clear_unsold_products_event', 'clear_unsold_products' );

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

Для проверки работоспособности:

  • Запустите функцию clear_unsold_products() вручную из файла functions.php или через WP-CLI.
  • Проверьте, что товары без заказов переместились в корзину (раздел «Удалённые» в товарах).
  • Проверьте cron задачи через плагин WP Crontrol — должна быть запланирована задача clear_unsold_products_event.
  • Отслеживайте базу данных и количество товаров до и после удаления.

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

  • Удаляются товары с заказами. Проверьте правильность запроса. Важно, чтобы _product_id брались из заказов, а не из метаданных товаров.
  • WP Cron не работает. Убедитесь, что на сервере настроен правильный запуск cron, или используйте системный cron для вызова wp-cron.php.
  • Удаление не происходит. Проверьте права пользователя, под которым выполняется код, и правильность хука.
  • Товары не удаляются, а только переносятся в корзину. Это стандартное поведение функции wp_trash_post(). Для полного удаления используйте wp_delete_post( $product_id, true ), но будьте осторожны с полным удалением.

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

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

Оптимизированный вариант с проверкой даты публикации и уведомлением

function clear_old_unsold_products() {
    $unsold_ids = get_unsold_products_ids();
    $deleted = [];
    $date_threshold = strtotime('-3 months');

    foreach ( $unsold_ids as $product_id ) {
        $post_date = strtotime(get_post_field('post_date', $product_id));
        if ( $post_date < $date_threshold ) {
            wp_trash_post( $product_id );
            $deleted[] = $product_id;
        }
    }

    if ( !empty($deleted) ) {
        $admin_email = get_option('admin_email');
        wp_mail($admin_email, 'Удалены товары без продаж', 'Удалены товары с ID: ' . implode(', ', $deleted));
    }
}

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

МетодПреимуществаНедостатки
Удаление через Cron + кодГибкость, контроль, без сторонних плагиновТребует навыков программирования, настройка cron
Плагины для очистки каталогаПростота, интерфейс управленияМожет грузить базу, ограниченная кастомизация
Ручное удалениеПолный контроль, без рисков автоматизацииЗатратно по времени, возможны ошибки
Как создать свой плагин WordPress с нуля: подробное руководство для разработчиков
31.10.2025
Как удалить все записи (посты) из WordPress через код — практическое решение
21.12.2025
WooCommerce: как исправить проблемы с отображением вариантов товаров
08.07.2026
Как исправить проблемы с изменением slug в WooCommerce после редактирования товара
17.04.2026
Как создать своё устройство для автопостинга в WordPress
17.02.2026