wpcoding.ru wordpress WP Coding

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

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

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

Проверить наличие таких товаров можно через SQL-запрос или WP_Query, например:

$args = [
    'post_type' => 'product',
    'posts_per_page' => -1,
    'meta_query' => [
        [
            'key' => '_order_count',
            'value' => 0,
            'compare' => '=',
            'type' => 'NUMERIC'
        ]
    ]
];
$products = get_posts($args);
echo 'Товаров без заказов: ' . count($products);

Здесь _order_count — пользовательское метаполе, которое нужно создать для подсчёта заказов по товару. WooCommerce не хранит это напрямую, поэтому нужно сформировать логику подсчёта.

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

1. Подсчёт заказов для каждого товара

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

function get_products_without_orders() {
    global $wpdb;
    $query = "
        SELECT p.ID FROM {$wpdb->posts} p
        LEFT JOIN (
            SELECT order_item_id, order_item_name, order_id
            FROM {$wpdb->prefix}woocommerce_order_items
        ) oi ON oi.order_item_name = p.post_title
        LEFT JOIN {$wpdb->prefix}woocommerce_order_itemmeta oim ON oim.order_item_id = oi.order_item_id AND oim.meta_key = '_product_id'
        LEFT JOIN {$wpdb->posts} o ON o.ID = oi.order_id AND o.post_status IN ('wc-completed', 'wc-processing')
        WHERE p.post_type = 'product'
        GROUP BY p.ID
        HAVING COUNT(o.ID) = 0
    ";
    return $wpdb->get_col($query);
}

Этот запрос возвращает ID товаров, у которых нет заказов в статусах "выполнен" и "обрабатывается".

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

function delete_products_by_ids(array $product_ids) {
    foreach ($product_ids as $id) {
        wp_delete_post($id, true); // true — безвозвратное удаление
    }
}

3. Автоматизация через WP-Cron

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

add_action('wp', 'setup_weekly_delete_products_event');
function setup_weekly_delete_products_event() {
    if (!wp_next_scheduled('weekly_delete_products_hook')) {
        wp_schedule_event(time(), 'weekly', 'weekly_delete_products_hook');
    }
}

add_action('weekly_delete_products_hook', 'auto_delete_inactive_products');
function auto_delete_inactive_products() {
    $product_ids = get_products_without_orders();
    if (!empty($product_ids)) {
        delete_products_by_ids($product_ids);
    }
}

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

  • В админке WooCommerce в разделе "Товары" должно уменьшиться количество товаров без активных заказов.
  • Запустите вручную функцию auto_delete_inactive_products() через WP-CLI или временно добавьте вызов в код для отладки.
  • Проверьте, что удалённые товары исчезли из базы данных и что пользовательские страницы товаров не доступны (404).

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

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

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

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

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

МетодОписаниеПлюсыМинусы
SQL-запрос + wp_delete_post Прямое получение ID товаров через SQL, удаление через WP-функцию Точный контроль, использует штатные WP функции Сложный запрос, нагрузка на базу при большом объёме
Плагины очистки (например, Clearfy Pro) Готовые инструменты для чистки и оптимизации сайта Простота настройки, поддержка и обновления Может быть избыточным, не всегда гибко
Ручная проверка и удаление через админку Просмотр и удаление товаров по фильтрам Никакого кода, безопасно Трудоёмко, не подходит для больших сайтов
×
Сделай свой сайт крутым!

Скидка -20% на премиум плагины WordPress

Выбрать плагин сейчас ⋙