wpdownload.ru wordpress WPDownload.ru

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

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

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

Как определить товары для удаления

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

  • Отсутствуют остатки на складе (stock_quantity = 0 или manage_stock = yes и stock_status = 'outofstock').
  • Отсутствуют заказы с этими товарами в статусах, которые считаются завершёнными или активными (например, completed, processing).

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

Добавьте следующий код в файл functions.php вашей темы или создайте отдельный плагин для удобства и безопасности:

function wc_delete_products_without_orders_and_stock() {
    // Получаем ID товаров с остатком 0 или без управления запасом
    $args = array(
        'post_type' => 'product',
        'posts_per_page' => -1,
        'meta_query' => array(
            'relation' => 'OR',
            array(
                'key' => '_stock_status',
                'value' => 'outofstock',
            ),
            array(
                'key' => '_manage_stock',
                'value' => 'yes',
            ),
        ),
        'fields' => 'ids',
    );

    $products = get_posts($args);
    if (empty($products)) {
        return;
    }

    foreach ($products as $product_id) {
        // Проверяем, есть ли заказы с этим товаром
        global $wpdb;
        $order_items = $wpdb->get_var($wpdb->prepare(
            "SELECT COUNT(oi.order_item_id) FROM {$wpdb->prefix}woocommerce_order_items oi
             
             JOIN {$wpdb->prefix}woocommerce_order_itemmeta oim ON oi.order_item_id = oim.order_item_id
             
             JOIN {$wpdb->prefix}posts p ON oi.order_id = p.ID
             
             WHERE oi.order_item_type = 'line_item'
             
             AND oim.meta_key = '_product_id' AND oim.meta_value = %d
             
             AND p.post_status IN ('wc-completed', 'wc-processing', 'wc-on-hold')",
            $product_id
        ));

        if (empty($order_items)) {
            // Дополнительно проверяем остаток
            $stock_qty = get_post_meta($product_id, '_stock', true);
            $manage_stock = get_post_meta($product_id, '_manage_stock', true);
            $stock_status = get_post_meta($product_id, '_stock_status', true);

            $no_stock = false;
            if ($manage_stock === 'yes' && ($stock_qty === '' || intval($stock_qty) <= 0)) {
                $no_stock = true;
            } elseif ($stock_status === 'outofstock') {
                $no_stock = true;
            }

            if ($no_stock) {
                // Удаляем товар окончательно
                wp_delete_post($product_id, true);
            }
        }
    }
}

// Для безопасности запускаем функцию вручную по хуку
// Например, крон или через admin_init (только для теста, убрать после)
add_action('admin_init', function() {
    if (current_user_can('manage_woocommerce') && isset($_GET['run_wc_cleanup'])) {
        wc_delete_products_without_orders_and_stock();
        wp_redirect(admin_url('edit.php?post_type=product&wc_cleanup=done'));
        exit;
    }
});

Для запуска перейдите в админку по адресу https://ваш-сайт/wp-admin/edit.php?post_type=product&run_wc_cleanup=1. После выполнения произойдёт удаление товаров, отвечающих условиям.

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

  • Проверьте список товаров в админке WooCommerce. Товары без заказов и остатков должны исчезнуть.
  • Для проверки можно использовать SQL-запрос в базе, чтобы убедиться, что удалённые товары отсутствуют в таблице wp_posts с типом product.
  • Проверьте, что заказы с этими товарами остаются без изменений.

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

  • Ошибка: Товары не удаляются.
    Причина: Неправильные статусы заказов в условии или кэширование.
    Исправление: Проверьте, что статусы заказов в запросе соответствуют вашим настройкам WooCommerce. Очистите кэш сайта и базы данных.
  • Ошибка: Удаляются товары с остатками.
    Причина: Некорректно проверяется количество на складе.
    Исправление: Проверьте мета-поля _stock, _manage_stock, _stock_status. Возможно, нужно адаптировать логику под вашу схему учёта запасов.
  • Ошибка: Функция запускается слишком часто и грузит сервер.
    Исправление: Запускайте функцию вручную или через WP Cron с долгими интервалами. Не привязывайте к хукам с частым срабатыванием.

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

  • Всегда делайте резервную копию базы данных перед массовым удалением товаров.
  • Для больших магазинов разбивайте удаление на партии по 50-100 товаров, чтобы избежать таймаутов.
  • Используйте пользовательские роли и проверки доступа (как в примере, current_user_can('manage_woocommerce')), чтобы запускать удаление только авторизованные администраторы.
  • Если хотите автоматизировать процесс, настройте WP Cron с запуском раз в неделю или месяц.
  • Для удобства добавьте логирование удалённых товаров в файл или таблицу базы, чтобы можно было восстановить по необходимости.

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

ВариантОписаниеПлюсыМинусы
Через SQL-запросы напрямую Удаление продуктов через запросы к базе данных Очень быстро для больших объёмов Риск нарушить целостность данных, обойти хуки WooCommerce
Через WP-функции wp_delete_post Удаление через API WordPress с учётом всех хуков Безопасно, с очищением мета и связанных данных Медленнее, нагрузка на сервер при большом количестве товаров
Использование плагинов для очистки Готовые решения для удаления неактивных товаров Удобно, интерфейс, поддержка Могут быть избыточными или содержать ненужные функции
×

AI-плагин от WPShop.ru

анализирует конкурентов

пишет статьи

готовит SEO

генерирует изображения

и еще кое-что...
WPGPT
Плагин, который наполняет ваш сайт WordPress
Узнать больше