Диагностика проблемы удаления старых товаров и вариантов в WooCommerce
В интернет-магазинах на WooCommerce часто возникает необходимость автоматически удалять товары, которые устарели или больше не продаются, а также варианты товаров, которые недоступны. Ручное выполнение этой задачи неудобно и подвержено ошибкам, особенно при большом каталоге.
Типичные признаки проблемы:
- В каталоге остаются товары, которых давно нет в наличии и которые не следует показывать.
- Варианты товаров (вариации) с нулевым остатком и без перспективы пополнения остаются активными.
- Заказчики видят неактуальные позиции, что ухудшает UX и ведет к ошибкам при оформлении.
Пошаговое решение: автоматизация удаления товаров и вариаций
1. Определение критериев удаления
Рекомендуется использовать следующие критерии для удаления товаров и вариаций:
- Дата последнего обновления товара или вариации больше N месяцев назад.
- Отсутствие остатков на складе (stock_quantity = 0) и статус «нет в наличии» (outofstock).
- Статус публикации «черновик» не удалять, т.к. они могут быть временно сняты с продажи.
2. Создание пользовательской WP-Cron задачи для регулярной проверки
Добавьте следующий код в файл functions.php дочерней темы или в отдельный плагин, чтобы запускать очистку еженедельно:
<?php
// Планируем задачу при активации темы или плагина
function wc_schedule_cleanup_event() {
if ( ! wp_next_scheduled( 'wc_cleanup_old_products_hook' ) ) {
wp_schedule_event( time(), 'weekly', 'wc_cleanup_old_products_hook' );
}
}
add_action( 'wp', 'wc_schedule_cleanup_event' );
// Очистка товаров и вариаций
add_action( 'wc_cleanup_old_products_hook', 'wc_cleanup_old_products' );
function wc_cleanup_old_products() {
$args = [
'post_type' => ['product', 'product_variation'],
'post_status' => 'publish',
'date_query' => [
'before' => date( 'Y-m-d', strtotime( '-6 months' ) ), // старше 6 месяцев
],
'meta_query' => [
[
'key' => '_stock_status',
'value' => 'outofstock',
],
],
'posts_per_page' => -1,
'fields' => 'ids',
];
$old_products = get_posts( $args );
foreach ( $old_products as $product_id ) {
wp_trash_post( $product_id );
}
}
// Отменяем задачу при деактивации
function wc_unschedule_cleanup_event() {
wp_clear_scheduled_hook( 'wc_cleanup_old_products_hook' );
}
register_deactivation_hook( __FILE__, 'wc_unschedule_cleanup_event' );
?>3. Проверка остатков при вариантах товаров
Для вариаций дополнительно можно проверить мета '_stock' (количество) и удалить только те, у которых 0:
function wc_cleanup_old_products() {
$args = [
'post_type' => ['product', 'product_variation'],
'post_status' => 'publish',
'date_query' => [
'before' => date( 'Y-m-d', strtotime( '-6 months' ) ),
],
'posts_per_page' => -1,
'fields' => 'ids',
];
$old_products = get_posts( $args );
foreach ( $old_products as $product_id ) {
$stock_status = get_post_meta( $product_id, '_stock_status', true );
$stock_qty = (int) get_post_meta( $product_id, '_stock', true );
if ( $stock_status === 'outofstock' || $stock_qty === 0 ) {
wp_trash_post( $product_id );
}
}
}Как проверить, что очистка сработала
- В админке WooCommerce перейдите в раздел «Товары» и примените фильтр по дате публикации — убедитесь, что старые товары с нулевыми остатками отсутствуют.
- Логируйте ID удалённых товаров, добавив
error_log('Deleted product ID: '.$product_id);внутри цикла — проверьте логи сервера. - Проверьте корзину WordPress (Trash) — удалённые товары должны там появляться.
Частые ошибки и как их исправить
- Неправильный формат даты в date_query: Используйте формат
Y-m-d, иначе запрос не сработает. - Удаление черновиков: В запросе стоит фильтровать только
publish, иначе можно потерять товары на доработке. - Отсутствие WP-Cron на сайте: Если на сайте отключен WP-Cron, задача не запустится. Настройте системный cron или запустите задачу вручную.
- Удаление товаров с наличием: Проверьте логику проверки остатка, чтобы не удалить товар с положительным запасом.
Практические советы по безопасности и производительности
- Всегда создавайте резервные копии базы перед автоматическим удалением.
- Для больших магазинов реализуйте удаление пакетами (
posts_per_pageс пагинацией), чтобы избежать перегрузки памяти. - Логируйте операции удаления и добавьте возможность отложенного восстановления (через корзину WordPress).
- Для повышения безопасности ограничьте запуск WP-Cron только с администратора или через системный cron.
Сравнение вариантов реализации удаления старых товаров
| Метод | Описание | Преимущества | Недостатки |
|---|---|---|---|
| WP-Cron с пользовательским кодом | Автоматическая очистка с контролем логики | Гибкость, точность, без сторонних плагинов | Зависит от WP-Cron и ресурсов сервера |
| Плагин очистки каталога | Готовое решение с UI и настройками | Простота настройки, визуальный контроль | Зависимость от стороннего кода, нагрузка |
| Ручное удаление через админку | Удаление вручную | Просто, без кода | Нерационально для больших магазинов, риск ошибок |