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

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

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

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

Товар считается «без активных заказов», если для него нет заказов со статусами, указывающими на незавершённую покупку (например, «processing», «on-hold», «completed» – в зависимости от логики магазина). Нужно проверить наличие связанных с товаром заказов с нужными статусами.

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

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

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

function wpc_delete_products_without_active_orders() {
    // Получаем все товары
    $args = [
        'post_type' => 'product',
        'posts_per_page' => -1,
        'post_status' => 'publish',
        'fields' => 'ids',
    ];
    $product_ids = get_posts($args);

    foreach ($product_ids as $product_id) {
        $has_active_orders = false;

        // Получаем заказы, где есть этот товар
        $orders = wc_get_orders([
            'limit' => -1,
            'status' => ['processing', 'on-hold', 'completed'], // активные статусы
            'return' => 'ids',
        ]);

        foreach ($orders as $order_id) {
            $order = wc_get_order($order_id);
            foreach ($order->get_items() as $item) {
                if ($item->get_product_id() == $product_id) {
                    $has_active_orders = true;
                    break 2; // если найден заказ с этим товаром, выходим
                }
            }
        }

        if (!$has_active_orders) {
            wp_delete_post($product_id, true); // принудительное удаление
        }
    }
}

2. Настройка WP-Cron для регулярного запуска

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

add_action('wpc_delete_products_cron_hook', 'wpc_delete_products_without_active_orders');

3. Запуск функции вручную (для теста)

Чтобы проверить работу без ожидания cron, вызовите функцию вручную из файла functions.php или через hook admin_init:

add_action('admin_init', function() {
    if (current_user_can('manage_options') && isset($_GET['run_delete_products'])) {
        wpc_delete_products_without_active_orders();
        echo 'Удаление выполнено';
        exit;
    }
});

Далее откройте в браузере https://ваш-сайт.ru/wp-admin/?run_delete_products=1 чтобы запустить удаление вручную.

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

  • В админке WooCommerce проверьте список товаров до и после запуска скрипта.
  • Для убедительности можно добавить логирование удалённых товаров (например, в файл), чтобы видеть, какие ID были удалены.
  • Проверьте, что товары с активными заказами не удаляются.
  • Убедитесь, что cron-задача запускается (проверка через плагин WP Crontrol или аналогичные).

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

  • Удаляются товары с активными заказами: Проверьте правильность статусов, по которым ищутся заказы. Возможно, нужно расширить список статусов.
  • Скрипт не запускается по расписанию: Проверьте, что WP-Cron работает (можно использовать плагин WP Crontrol), и что нет конфликтов с серверными настройками.
  • Проблемы с производительностью при большом количестве товаров и заказов: Вынесите логику проверки заказов в отдельные запросы с пагинацией или используйте прямые SQL-запросы для оптимизации.
  • Удаление происходит слишком часто или неожиданно: Добавьте дополнительные проверки, например, минимальный возраст товара, чтобы он удалялся только после определённого времени без заказов.

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

  • Не используйте wp_delete_post без необходимости, если хотите иметь возможность восстановить товары — рассмотрите переход в статус 'trash' вместо полного удаления.
  • Добавьте проверку прав пользователя при ручном запуске удаления.
  • Для ускорения поиска связанных заказов можно использовать SQL-запросы напрямую, обращаясь к таблицам wp_woocommerce_order_items и wp_woocommerce_order_itemmeta, если в проекте много заказов.
  • Рассмотрите возможность отправки отчётов об удалённых товарах на email администратора для контроля.

Сравнение способов реализации

МетодПлюсыМинусы
WP-Cron + PHP код (как в статье)Гибкость, интеграция с WooCommerce, не требует сторонних плагиновЗависит от работы WP-Cron, возможны проблемы с производительностью на больших сайтах
Плагины для очистки каталогаПростота настройки, UI для контроляМогут иметь ограниченную функциональность, лишний плагин в системе
Ручная очистка через админкуПростой контроль, нет автоматизацииТрудозатратно, риск забыть удалить
×

Увеличьте продажи!

Скидка на
My Popup!

-15%
плагин для WordPress

Успей купить ⋙