Автоматическое удаление неактивных товаров в WooCommerce по дате последнего обновления

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

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

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

«Неактивные» в данном случае — товары, которые не обновлялись более определенного периода, например, 180 дней, и не имеют заказов за это время.

  • Дата последнего обновления товара — поле post_modified в таблице wp_posts.
  • Проверка наличия заказов с этим товаром.

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

Пошаговое решение: автоудаление неактивных товаров через WP-Cron

1. Создаем функцию для выборки и удаления неактивных товаров

function wpt_delete_inactive_products() {
    $days_inactive = 180; // Порог неактивности в днях
    $date_threshold = date('Y-m-d H:i:s', strtotime('-' . $days_inactive . ' days'));

    // Получаем ID товаров, обновленных раньше порога
    $args = [
        'post_type'      => 'product',
        'post_status'    => 'publish',
        'date_query'     => [
            [
                'column' => 'post_modified',
                'before' => $date_threshold,
            ],
        ],
        'fields'         => 'ids',
        'posts_per_page' => -1,
    ];
    $query = new WP_Query($args);
    $product_ids = $query->posts;

    foreach ($product_ids as $product_id) {
        // Проверяем заказы с этим товаром
        global $wpdb;
        $order_count = $wpdb->get_var($wpdb->prepare(
            "SELECT COUNT(*) 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->posts} p ON p.ID = oi.order_id
             WHERE oim.meta_key = '_product_id' AND oim.meta_value = %d AND p.post_status IN ('wc-completed','wc-processing')",
            $product_id
        ));

        if (intval($order_count) === 0) {
            wp_delete_post($product_id, true); // Полное удаление без корзины
        }
    }
}

2. Регистрируем WP-Cron задачу

add_action('wpt_daily_inactive_products_delete', 'wpt_delete_inactive_products');

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

3. Добавляем удаление задачи при деактивации темы или плагина

function wpt_deactivate_cleanup() {
    wp_clear_scheduled_hook('wpt_daily_inactive_products_delete');
}
register_deactivation_hook(__FILE__, 'wpt_deactivate_cleanup');

Проверка результата

Для проверки, что функция сработала:

  • Просмотрите список товаров в админке, убедитесь, что товары с датой обновления старше 180 дней без заказов удалены.
  • Логи сервера или плагина для логов (например, Query Monitor) помогут увидеть вызов WP-Cron.
  • Для отладки временно добавьте error_log внутри функции, чтобы фиксировать удаляемые ID.

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

  • Товары не удаляются: проверьте, запущен ли WP-Cron (можно вручную вызвать событие через wp cron event run --due-now в WP-CLI).
  • Удаляются нужные товары: проверьте правильность условий выборки, возможно, дата или проверка заказов настроены неверно.
  • Проблемы с производительностью при большом количестве товаров: разбейте удаление на партии, используя параметр 'posts_per_page' и пагинацию.

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

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

Сравнение вариантов удаления неактивных товаров

МетодПлюсыМинусыПрименимость
Ручное удаление из админкиПростота, контрольЗатратно по времени, риск пропускаМагазины с малым числом товаров
Плагин очистки товаров (например, Bulk Delete)Интерфейс, фильтрыДополнительные зависимости, нагрузкаСредние магазины
Автоматизация через WP-Cron и кастомный код (как в статье)Полный контроль, гибкость, без лишних плагиновТребует начальных знаний, поддержка кодаКрупные магазины, разработчики
Как создать динамический шаблон для WooCommerce с кастомным выводом товаров
17.02.2026
Создание кастомных типов записей и таксономий в WordPress с примерами кода
12.12.2025
Как создать автоматические шаблоны для постов в WordPress с кастомным выводом
08.04.2026
Как изменить вывод публикаций в WordPress без изменения шаблона
04.03.2026
Создаем свой шаблон для WordPress с нуля
04.11.2025