wpcoding.ru wordpress WP Coding

Автоматическое удаление товаров в WooCommerce по дате последнего заказа

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

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

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

Как найти товары без заказов или с последним заказом старше X дней

Для решения задачи важно понять, как связать товары с заказами. В WooCommerce связь между товаром и заказом ведется через wp_woocommerce_order_items и wp_woocommerce_order_itemmeta. Чтобы найти дату последнего заказа для товара, необходимо:

  • Получить все заказы с товарами (статус «completed», «processing» и т.д.)
  • Определить дату последнего заказа для каждого товара
  • Выделить товары, для которых дата последнего заказа старше нужного периода или вовсе отсутствует заказ

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

1. Создаем функцию для получения ID товаров без заказов или с устаревшим заказом

function get_products_to_delete( $days = 180 ) {
    global $wpdb;

    $threshold_date = date( 'Y-m-d H:i:s', strtotime( "-{$days} days" ) );

    // Получаем ID товаров с последней датой заказа
    $query = $wpdb->prepare(
        "SELECT p.ID, MAX(o.post_date) as last_order_date
         FROM {$wpdb->posts} p
         LEFT JOIN {$wpdb->prefix}woocommerce_order_items oi ON oi.order_item_name = p.post_title
         LEFT JOIN {$wpdb->posts} o ON o.ID = oi.order_id AND o.post_type = 'shop_order' AND o.post_status IN ('wc-completed', 'wc-processing')
         WHERE p.post_type = 'product'
         GROUP BY p.ID",
        []
    );

    $results = $wpdb->get_results( $query );
    $products_to_delete = [];

    foreach ( $results as $product ) {
        if ( empty( $product->last_order_date ) || $product->last_order_date < $threshold_date ) {
            $products_to_delete[] = $product->ID;
        }
    }

    return $products_to_delete;
}

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

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

function delete_products_by_ids( $product_ids ) {
    foreach ( $product_ids as $product_id ) {
        wp_delete_post( $product_id, true ); // true — удаляет без помещения в корзину
    }
}

3. Создаем WP-Cron задачу для регулярного удаления

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

add_action( 'daily_product_cleanup_event', 'daily_product_cleanup_callback' );
function daily_product_cleanup_callback() {
    $products_to_delete = get_products_to_delete( 180 );
    if ( ! empty( $products_to_delete ) ) {
        delete_products_by_ids( $products_to_delete );
    }
}

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

Чтобы проверить, сработала ли автоматизация:

  • Вручную запустите функцию daily_product_cleanup_callback() через консоль WP-CLI: wp eval 'daily_product_cleanup_callback();'
  • Проверьте, что товары с датой последнего заказа более 180 дней отсутствуют в каталоге
  • Проверьте логи ошибок PHP и запросы к базе на предмет ошибок
  • Для отладки можно перед удалением логировать ID товаров, которые будут удалены

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

  • Ошибка: Неправильное связывание товаров и заказов — причина: в запросе используется имя товара вместо ID заказа.
    Решение: использовать WooCommerce API для получения заказов и товаров, например wc_get_orders() и wc_get_order_item_meta().
  • Ошибка: Удаляются нужные товары или товары с заказами недавно — причина: неверный порог даты или часовой пояс.
    Решение: проверяйте время сервера, используйте функции WordPress для времени current_time('mysql').
  • Ошибка: WP-Cron не срабатывает — причина: отсутствуют посещения на сайте.
    Решение: используйте системный cron для вызова wp-cron.php или запускайте вручную.

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

  • Перед массовым удалением товаров сделайте резервную копию базы и файлов.
  • Добавьте проверку ролей и прав пользователя, если планируете запускать удаление из админки.
  • Для больших магазинов разбивайте удаление на партии по 50-100 товаров, чтобы избежать тайм-аутов.
  • Логируйте удаленные товары в отдельный файл для аудита.
  • Если используется WP-Cron, рекомендуем перевести на системный cron для надежности.

Сравнение вариантов реализации автоматического удаления

МетодОписаниеПлюсыМинусы
Чистый PHP + WP-CronСобственная функция с cron задачейМаксимальный контроль, без лишних плагиновТребует навыков разработки, возможны ошибки в логике
Плагины очистки каталогаГотовые решения из репозитория WordPressПростота установки и настройкиМогут не покрывать специфичные запросы, нагрузка
WP-CLI скриптыЗапуск удаления вручную или по расписанию через командную строкуВысокая производительность, надежностьТребуется доступ к серверу, знания CLI
×

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

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

пишет статьи

готовит SEO

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

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