Почему важно автоматически отключать неактивные товары в WooCommerce
Если в вашем магазине на WooCommerce есть товары, которые давно не продаются, их наличие может создавать проблемы: загромождать каталог, ухудшать пользователский опыт и снижать конверсию. Автоматическое отключение таких товаров по дате последней покупки помогает поддерживать актуальность ассортимента и облегчает управление магазином.
Диагностика: как определить неактивные товары
Для автоматического отключения сначала нужно выявить товары, которые не покупались определённое время (например, 6 месяцев). В WooCommerce дата последней покупки не хранится в метаполях товара напрямую, поэтому нужно анализировать заказы и искать последние даты покупок для каждого товара.
Проверка товаров с помощью 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' AND o.post_status IN ('wc-completed', 'wc-processing')
WHERE p.post_type = 'product'
GROUP BY p.ID
ORDER BY last_order_date ASC;Этот запрос показывает дату последнего заказа для каждого товара. Если дата отсутствует или слишком старая, товар можно считать неактивным.
Пошаговое решение: автоматическое отключение товаров
1. Создаём функцию для получения ID неактивных товаров
function get_inactive_products( $months = 6 ) {
global $wpdb;
$date_limit = date( 'Y-m-d H:i:s', strtotime( "-{$months} months" ) );
$query = $wpdb->prepare(
"SELECT p.ID 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 oi.order_id = o.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
HAVING MAX(o.post_date) IS NULL OR MAX(o.post_date) < %s",
$date_limit
);
return $wpdb->get_col( $query );
}2. Создаём функцию для массового отключения товаров
function disable_inactive_products( $months = 6 ) {
$inactive_products = get_inactive_products( $months );
if ( empty( $inactive_products ) ) {
return 0;
}
foreach ( $inactive_products as $product_id ) {
wp_update_post([
'ID' => $product_id,
'post_status' => 'draft' // или 'private' для скрытия от посетителей
]);
}
return count( $inactive_products );
}3. Настраиваем запуск автоматического отключения через WP-Cron
if ( ! wp_next_scheduled( 'disable_inactive_products_daily' ) ) {
wp_schedule_event( time(), 'daily', 'disable_inactive_products_daily' );
}
add_action( 'disable_inactive_products_daily', function() {
$count = disable_inactive_products( 6 );
error_log( "Disabled {$count} inactive WooCommerce products." );
});Проверка результата после внедрения
- Запустите функцию
disable_inactive_products(6)вручную в среде разработки и проверьте, что товары со сроком последней покупки более 6 месяцев получают статусdraft. - Проверьте в админке WooCommerce, что такие товары действительно скрыты с публичной части сайта.
- Убедитесь, что по расписанию (например, через сутки) в логах появляется запись о количестве отключённых товаров.
Частые ошибки и как их исправить
- Неправильный статус заказа учтён: учитывайте только статусы
wc-completedиwc-processing, иначе товары могут остаться активными из-за отменённых или возвратных заказов. - Некорректный SQL-запрос из-за изменений префикса таблиц: всегда используйте
$wpdb->prefixи$wpdb->postsдля портируемости. - Отсутствие расписания WP-Cron: убедитесь, что WP-Cron работает и не отключён на сервере, иначе автоматическое отключение не сработает.
Практические советы по безопасности и производительности
- Для больших магазинов с тысячами товаров и заказов оптимизируйте SQL-запрос, добавляя индексы или разбивая выборку на части.
- Перед массовым изменением статусов делайте резервные копии базы данных или используйте тестовую среду.
- Для повышения безопасности не давайте доступ к этой функции неавторизованным пользователям и не запускайте её из публичного интерфейса.
Сравнение способов реализации автоматического отключения
| Метод | Плюсы | Минусы |
|---|---|---|
| SQL-запрос + WP-Cron (как в статье) | Контроль, гибкость, отсутствие сторонних плагинов | Требует навыков SQL, риск ошибок при неправильном запросе |
| Плагины для управления товарами | Простота использования, интерфейс | Может замедлять сайт, ограниченная кастомизация |
| Ручное отключение через админку | Минимум технических знаний | Неэффективно для большого каталога, трудозатратно |