Диагностика проблемы: почему нужно отключать неактивные товары
В большом WooCommerce-магазине товары, на которые давно не было продаж, могут занимать место в каталоге, ухудшать пользовательский опыт и влиять на SEO. Автоматическое отключение таких товаров помогает поддерживать актуальность ассортимента без ручного контроля.
Критерии определения неактивных товаров
Задача — найти товары, у которых не было заказов за определённый период, например, за последние 90 дней, и автоматически изменить их статус на «черновик» или «скрыть».
Выбирайте подходящий статус в зависимости от задачи:
- Черновик (<code>draft</code>) — товар не отображается в каталоге и не доступен для покупки.
- В ожидании (<code>pending</code>) — можно использовать для временного скрытия с последующей проверкой.
- Приватный (<code>private</code>) — виден только администраторам.
Пошаговое решение: автоматизация отключения
1. Создание WP-Cron задачи
Добавим еженедельное задание для проверки активности товаров:
function wpmanager_schedule_inactive_products_cron() {
if ( ! wp_next_scheduled( 'wpmanager_check_inactive_products' ) ) {
wp_schedule_event( time(), 'weekly', 'wpmanager_check_inactive_products' );
}
}
add_action( 'wp', 'wpmanager_schedule_inactive_products_cron' );2. Функция поиска и отключения неактивных товаров
Основной код для проверки продаж и отключения:
function wpmanager_deactivate_inactive_products() {
global $wpdb;
$days = 90; // период без продаж
$date_limit = date( 'Y-m-d H:i:s', strtotime( "-{$days} days" ) );
// Получаем ID товаров, у которых были продажи за последние 90 дней
$sold_products = $wpdb->get_col( $wpdb->prepare(
"SELECT DISTINCT order_item_meta.meta_value 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->prefix}posts as posts ON posts.ID = order_items.order_id
WHERE order_item_meta.meta_key = '_product_id'
AND posts.post_type = 'shop_order'
AND posts.post_status IN ('wc-completed', 'wc-processing', 'wc-on-hold')
AND posts.post_date >= %s
", $date_limit
));
// Получаем все опубликованные товары
$args = array(
'post_type' => 'product',
'post_status' => 'publish',
'numberposts' => -1,
'fields' => 'ids',
);
$all_products = get_posts( $args );
// Определяем товары без продаж
$inactive_products = array_diff( $all_products, $sold_products );
// Отключаем неактивные
foreach ( $inactive_products as $product_id ) {
// Меняем статус на черновик
wp_update_post( array(
'ID' => $product_id,
'post_status' => 'draft',
) );
}
}
add_action( 'wpmanager_check_inactive_products', 'wpmanager_deactivate_inactive_products' );3. Очистка задачи при деактивации темы или плагина
function wpmanager_clear_inactive_products_cron() {
$timestamp = wp_next_scheduled( 'wpmanager_check_inactive_products' );
if ( $timestamp ) {
wp_unschedule_event( $timestamp, 'wpmanager_check_inactive_products' );
}
}
register_deactivation_hook( __FILE__, 'wpmanager_clear_inactive_products_cron' );Проверка результата после внедрения
- Запустите событие вручную для проверки:
do_action('wpmanager_check_inactive_products'); - Проверьте список товаров в админке WooCommerce – неактивные должны стать «черновиками».
- Проверьте, что товары больше не отображаются на витрине и в поиске.
- Убедитесь, что товары с недавними продажами остались опубликованными.
Частые ошибки и как исправить
- Ошибка: Товары с продажами тоже отключаются.
Причина: Неверный запрос или неучтённые статусы заказов.
Решение: Проверьте SQL-запрос, убедитесь, что учитываются только нужные статусы заказов:wc-completed,wc-processing,wc-on-hold. - Ошибка: Cron-задача не запускается.
Причина: WP-Cron отключён или нет посетителей сайта.
Решение: Настройте системный cron на сервере для вызоваwp-cron.phpили запускайте задачу вручную. - Ошибка: Медленная работа при большом количестве товаров.
Решение: Разбейте обработку на партии с помощью пагинации и запускайте cron чаще с меньшим объёмом.
Практические советы по безопасности и производительности
- Используйте
wp_schedule_eventс интервалами, подходящими по нагрузке (например, weekly или daily). - Добавьте логирование отключённых товаров для аудита.
- Кэшируйте результаты запросов, если запускаете функции вручную.
- Всегда создавайте резервную копию базы перед массовыми изменениями.
Сравнение вариантов реализации автоматического отключения товаров
| Метод | Описание | Плюсы | Минусы |
|---|---|---|---|
| Плагин (например, «WooCommerce Smart Manager») | Использование готового решения с настройками | Удобство, поддержка, GUI | Может быть тяжелее, платные функции |
| Код с WP-Cron (как в статье) | Кастомный код для точного контроля | Лёгкий, точечный, бесплатный | Требует навыков, возможна нагрузка |
| Ручное отключение | Админка WooCommerce, фильтры по продажам | Простота, без кода | Затратно по времени, ошибки |