Почему важно отключать неактивные товары в WooCommerce
Если в вашем магазине WooCommerce много товаров, которые не продаются длительное время, они могут мешать аналитике, замедлять загрузку страниц и ухудшать пользовательский опыт. Автоматическое отключение таких товаров помогает поддерживать актуальность каталога и оптимизировать работу сайта.
Диагностика проблемы: как определить неактивные товары по дате покупки
Для начала нужно понять, какие товары не продаются определённое время. WooCommerce хранит данные о заказах и связанных с ними товарах в нескольких таблицах базы данных:
wp_posts— товары имеют тип записиproductилиproduct_variation;wp_woocommerce_order_itemsиwp_woocommerce_order_itemmeta— содержат данные о заказанных товарах;wp_postsс типомshop_order— сами заказы, где полеpost_date— дата заказа.
Поэтому задача сводится к поиску товаров, для которых не было заказов за последние N дней.
Пошаговое решение: код для автоматического отключения товаров без продаж
Добавьте следующий код в файл functions.php вашей темы или в кастомный плагин. Он будет запускаться по расписанию (cron) и менять статус товаров, не продававшихся за указанный период.
function disable_inactive_products_by_last_order() {
global $wpdb;
$days_inactive = 90; // Период неактивности в днях
$date_threshold = date('Y-m-d H:i:s', strtotime("-" . $days_inactive . " days"));
// Получаем ID товаров, у которых были продажи за последние $days_inactive дней
$active_product_ids = $wpdb->get_col($wpdb->prepare(
"SELECT DISTINCT order_items.order_item_id FROM {$wpdb->prefix}woocommerce_order_items AS order_items
INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS itemmeta ON order_items.order_item_id = itemmeta.order_item_id
INNER JOIN {$wpdb->prefix}posts AS orders ON orders.ID = order_items.order_id
WHERE orders.post_type = 'shop_order'
AND orders.post_status IN ('wc-completed', 'wc-processing')
AND orders.post_date >= %s
AND itemmeta.meta_key = '_product_id'",
$date_threshold
));
// Получаем все опубликованные товары
$all_products = get_posts(array(
'post_type' => array('product', 'product_variation'),
'post_status' => 'publish',
'numberposts' => -1,
'fields' => 'ids',
));
// Определяем неактивные товары
$inactive_products = array_diff($all_products, $active_product_ids);
// Меняем статус неактивных товаров на черновик
foreach ($inactive_products as $product_id) {
wp_update_post(array(
'ID' => $product_id,
'post_status' => 'draft'
));
}
}
// Регистрируем ежедневное событие cron
if (!wp_next_scheduled('disable_inactive_products_event')) {
wp_schedule_event(time(), 'daily', 'disable_inactive_products_event');
}
add_action('disable_inactive_products_event', 'disable_inactive_products_by_last_order');Объяснение кода
- Функция ищет ID товаров, которые были в заказах со статусом
wc-completedилиwc-processingза последние 90 дней. - Определяет все опубликованные товары и сравнивает с активными.
- Товары, которые не продавались, переводит в статус
draft, тем самым отключая их из публичного каталога. - Запускается ежедневно через wp-cron.
Проверка результата после внедрения
Чтобы убедиться, что код работает корректно:
- Подождите или вручную запустите событие
disable_inactive_products_eventчерез плагин WP Crontrol. - Перейдите в админку WooCommerce → Товары и отфильтруйте по статусу
Черновик. Там должны появиться товары без заказов за последние 90 дней. - Проверьте, что ранее продаваемые товары остались опубликованными.
Частые ошибки и их исправление
- Ошибка: Товары не отключаются.
Причина: Некорректно работает запрос к базе, например, отличаются префиксы таблиц или заказы имеют другой статус.
Решение: Проверьте префикс таблиц$wpdb->prefix, убедитесь, что статусы заказов совпадают с фактическими, например, добавьтеwc-on-holdесли нужно. - Ошибка: Скрипт отключает товары с недавними покупками.
Причина: Неверно определён период или дата заказа.
Решение: Проверьте формат даты и используйте отладку черезerror_log()для вывода значений переменных. - Ошибка: Скрипт не запускается автоматически.
Решение: Убедитесь, что wp-cron работает (например, заходите на сайт), или настройте системный cron на вызов wp-cron.php.
Практические советы по безопасности и производительности
- Перед внедрением на живом сайте сделайте полную резервную копию базы данных и файлов.
- Используйте транзакции или делайте обработку пакетами, если товаров очень много, чтобы избежать превышения времени выполнения скрипта.
- Не меняйте статус товаров на
trash, чтобы случайно не потерять данные. - Для больших магазинов используйте WP CLI для запуска подобных задач с ограничением по времени и памяти.
Таблица сравнения вариантов решения задачи
| Метод | Плюсы | Минусы | Рекомендуется для |
|---|---|---|---|
| Кастомный код (cron) | Полный контроль, нет зависимостей | Требует знаний PHP и SQL, возможны ошибки без тестирования | Средние и крупные магазины с разработчиками |
| Плагины-менеджеры товаров | Удобный интерфейс, дополнительные функции | Могут замедлять сайт, ограниченная гибкость | Небольшие магазины без разработчиков |
| Ручное отключение | Простое, без кода | Трудоёмко, не масштабируется | Малые магазины с небольшим ассортиментом |