Зачем автоматизировать удаление проданных товаров в WooCommerce
В интернет-магазинах на WooCommerce часто накапливаются товары, которые были проданы и больше не актуальны. Это влияет на удобство управления каталогом, увеличивает нагрузку на базу данных и может замедлять работу сайта. Автоматическое удаление таких товаров по дате продажи позволяет поддерживать базу в актуальном состоянии без ручной работы.
Диагностика проблемы: как понять, что нужно удалять проданные товары
Если в вашем магазине WooCommerce есть товарные позиции, которые были проданы более месяца назад и больше не нужны, стоит задуматься об их очистке. Основные признаки:
- В каталоге отображаются товары со статусом "Продано", но с нулевым остатком.
- В базе данных накапливается большое количество постов с типом
product, которые уже не продаются. - Отчеты по товарным остаткам показывают много устаревших позиций.
Для проверки можно выполнить SQL-запрос к базе данных, чтобы найти товары без остатков и с датой последней продажи старше нужного периода:
SELECT p.ID, p.post_title, MAX(o.post_date) as last_order_date
FROM wp_posts p
LEFT JOIN wp_woocommerce_order_items oi ON oi.order_item_name = p.post_title
LEFT JOIN wp_posts o ON oi.order_id = o.ID AND o.post_type = 'shop_order'
WHERE p.post_type = 'product'
GROUP BY p.ID
HAVING last_order_date < DATE_SUB(NOW(), INTERVAL 30 DAY) OR last_order_date IS NULL;Пошаговое решение: скрипт для автоматического удаления проданных товаров по дате
Реализуем функцию, которая:
- Получит товары, проданные более 30 дней назад.
- Проверит остаток товара (stock_quantity).
- Удалит товар, если остаток равен нулю.
Для запуска кода используйте WP-Cron, чтобы задача выполнялась автоматически раз в сутки.
Код для автоматического удаления товаров
function wpreset_delete_old_sold_products() {
$args = array(
'post_type' => 'product',
'posts_per_page' => -1,
'meta_query' => array(
array(
'key' => '_stock_status',
'value' => 'outofstock',
),
),
);
$products = get_posts( $args );
foreach ( $products as $product_post ) {
$product = wc_get_product( $product_post->ID );
$last_order_date = wpreset_get_last_order_date( $product->get_id() );
if ( ! $last_order_date ) {
continue;
}
$date_threshold = strtotime( '-30 days' );
$last_order_timestamp = strtotime( $last_order_date );
if ( $last_order_timestamp <= $date_threshold ) {
wp_delete_post( $product->get_id(), true );
}
}
}
function wpreset_get_last_order_date( $product_id ) {
global $wpdb;
$query = $wpdb->prepare(
"SELECT MAX(p.post_date) FROM {$wpdb->prefix}posts p
INNER JOIN {$wpdb->prefix}woocommerce_order_items oi ON p.ID = oi.order_id
INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta oim ON oi.order_item_id = oim.order_item_id
WHERE p.post_type = 'shop_order'
AND p.post_status IN ('wc-completed', 'wc-processing')
AND oim.meta_key = '_product_id'
AND oim.meta_value = %d",
$product_id
);
return $wpdb->get_var( $query );
}
// Регистрируем задачу в WP-Cron
if ( ! wp_next_scheduled( 'wpreset_daily_delete_old_sold_products' ) ) {
wp_schedule_event( time(), 'daily', 'wpreset_daily_delete_old_sold_products' );
}
add_action( 'wpreset_daily_delete_old_sold_products', 'wpreset_delete_old_sold_products' );Проверка результата после внедрения
Чтобы убедиться, что удаление отработало корректно, выполните следующие шаги:
- Проверьте список товаров в админке WooCommerce на предмет исчезновения проданных товаров с нулевым остатком, проданных более 30 дней назад.
- Просмотрите логи WP-Cron или добавьте логирование в функцию
wpreset_delete_old_sold_productsдля контроля удаляемых товаров. - Выполните SQL-запрос из раздела диагностики до и после запуска скрипта — количество подходящих товаров должно уменьшиться.
Частые ошибки и их исправление
- Удаление не тех товаров: Ошибка в логике выбора товаров. Проверьте корректность выборки в
get_postsи функцию получения даты последнего заказа. - Функция не запускается автоматически: Проверьте регистрацию WP-Cron задачи и её наличие через
wp_next_scheduled. Убедитесь, что на сайте посещения активируют WP-Cron. - Проблемы с производительностью при большом каталоге: Разбейте обработку товаров на партии с помощью параметров
posts_per_pageи пагинации.
Практические советы по безопасности и производительности
- Перед массовым удалением создавайте резервные копии базы данных, чтобы избежать потери важных данных.
- Логируйте удаляемые ID товаров в отдельный файл или в системный лог для аудита.
- Используйте транзакции при удалении, если в базе данных есть зависимости.
- Настраивайте WP-Cron на выполнение в часы с низкой нагрузкой.
- Если на сайте много товаров, используйте WP-CLI для запуска задач удаления с контролем прогресса.
Таблица сравнения способов удаления проданных товаров
| Метод | Плюсы | Минусы | Пример кода |
|---|---|---|---|
| Ручное удаление через админку | Простота, контроль | Трудоемко, риск ошибок | — |
| Автоматизация через WP-Cron и PHP | Полная автоматизация, гибкость | Требует навыков, нагрузка на сайт | В статье выше |
| Плагины для очистки каталога | Удобство, готовое решение | Зависимость от сторонних разработчиков, возможные конфликты | WPReset, Clearfy Pro |