wp-lessons.ru wordpress WP-Lessons

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

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

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

Если вы замечаете, что в админке WooCommerce много вариаций, которые не продаются и не используются, это сигнал к тому, чтобы автоматизировать их удаление.

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

1. Определяем критерии неактивности вариаций

Чаще всего неактивные вариации — это те, у которых:

  • статус «черновик» или «отменён»;
  • отсутствует запас на складе;
  • нет заказов за определённый период (например, 6 месяцев);
  • отключены для продажи (приватный статус или meta поле «_stock_status» = «outofstock»).

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

2. Создаем WP-Cron задачу для регулярного удаления вариаций

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

if (!wp_next_scheduled('wc_delete_inactive_variations')) {
    wp_schedule_event(time(), 'daily', 'wc_delete_inactive_variations');
}

add_action('wc_delete_inactive_variations', 'wc_delete_old_inactive_variations');

function wc_delete_old_inactive_variations() {
    global $wpdb;

    // Получаем ID вариаций с нулевым запасом и статусом 'private' или 'draft'
    $query = "
        SELECT p.ID FROM {$wpdb->posts} p
        LEFT JOIN {$wpdb->postmeta} pm_stock ON (p.ID = pm_stock.post_id AND pm_stock.meta_key = '_stock_status')
        WHERE p.post_type = 'product_variation'
        AND (p.post_status = 'draft' OR p.post_status = 'private')
        AND (pm_stock.meta_value = 'outofstock' OR pm_stock.meta_value IS NULL)
    ";

    $variations = $wpdb->get_col($query);

    if (!empty($variations)) {
        foreach ($variations as $variation_id) {
            wp_delete_post($variation_id, true); // жесткое удаление
        }
    }
}

Код запускает ежедневную задачу, которая удаляет вариации с черновым или приватным статусом и отсутствием запаса на складе.

3. Расширение фильтра: удаление вариаций без заказов за 6 месяцев

Чтобы добавить проверку на отсутствие заказов за последние 6 месяцев, используйте такой подход:

function wc_delete_inactive_variations() {
    global $wpdb;

    $six_months_ago = date('Y-m-d H:i:s', strtotime('-6 months'));

    $query = "
        SELECT p.ID FROM {$wpdb->posts} p
        LEFT JOIN {$wpdb->postmeta} pm_stock ON (p.ID = pm_stock.post_id AND pm_stock.meta_key = '_stock_status')
        LEFT JOIN (
            SELECT order_item_meta.meta_value AS variation_id, MAX(posts.post_date) AS last_order_date
            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->posts} AS posts ON order_items.order_id = posts.ID
            WHERE order_item_meta.meta_key = '_variation_id'
            AND posts.post_type = 'shop_order'
            AND posts.post_status IN ('wc-completed', 'wc-processing')
            GROUP BY order_item_meta.meta_value
        ) AS orders ON p.ID = orders.variation_id
        WHERE p.post_type = 'product_variation'
        AND (p.post_status = 'draft' OR p.post_status = 'private')
        AND (pm_stock.meta_value = 'outofstock' OR pm_stock.meta_value IS NULL)
        AND (orders.last_order_date IS NULL OR orders.last_order_date < %s)
    ";

    $prepared_query = $wpdb->prepare($query, $six_months_ago);
    $variations = $wpdb->get_col($prepared_query);

    if (!empty($variations)) {
        foreach ($variations as $variation_id) {
            wp_delete_post($variation_id, true);
        }
    }
}

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

  • Выполните вручную запуск задачи из админки WP-CLI: wp cron event run wc_delete_inactive_variations. Если WP-CLI нет, временно вызовите функцию вручную.
  • Проверьте таблицу wp_posts — вариации с указанными критериями должны исчезнуть.
  • В админке WooCommerce откройте список вариаций и убедитесь, что неактивные вариации удалены.
  • Отслеживайте логи ошибок и базу данных на предмет удаления нужных записей.

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

  • Ошибка в SQL-запросе: Неверный join или опечатки в названиях таблиц приводят к пустым результатам. Проверьте префикс таблиц $wpdb->prefix и соответствие полей.
  • Неправильный статус вариаций: Некоторые вариации могут иметь статус publish, но быть неактивными. Добавьте дополнительные проверки по мета-данным.
  • Отсутствие прав на удаление: Функция wp_delete_post требует прав администратора. Убедитесь, что задача запускается от имени пользователя с нужными правами.
  • Конфликт с кэшированием: После удаления вариаций очистите кэш сайта и браузера, чтобы изменения отобразились.

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

  • Резервное копирование базы данных: Перед внедрением автоматического удаления сделайте полную резервную копию базы данных.
  • Запуск WP-Cron: По умолчанию WP-Cron запускается при посещении сайта, что может привести к задержкам. Лучше настроить системный cron на сервере для запуска wp cron event run --due-now каждые 5-10 минут.
  • Логирование: Добавьте логирование удалённых вариаций в файл для аудита и отката при ошибках.
  • Оптимизация запросов: При большом каталоге товаров разбивайте удаление на партии, чтобы избежать превышения лимита памяти или таймаута.

Сравнение вариантов решения

МетодПлюсыМинусыПример кода/плагина
Код с WP-CronПолный контроль, отсутствие зависимостей, можно настроить под свои критерииТребует навыков программирования, возможны ошибки в SQLПриведён в статье
Плагины для очистки WooCommerceПростота использования, готовые интерфейсыЗависимость от сторонних решений, не всегда гибкоWP-Optimize, Advanced Database Cleaner
Ручное удаление через админкуПростота, без риска автоматических ошибокЗатратно по времени, неэффективно при большом количестве вариацийСтандартный интерфейс WooCommerce
×

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

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

пишет статьи

готовит SEO

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

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