Диагностика проблемы: зачем автоматически отключать товары без продаж
В интернет-магазинах на WooCommerce часто возникает ситуация, когда часть товаров не продаётся долгое время. Это может приводить к загромождению каталога, ухудшению SEO и снижению конверсии. Автоматическое отключение таких товаров позволяет поддерживать каталог в актуальном состоянии и сосредоточить внимание покупателей на актуальных предложениях.
Как определить, что товар не продаётся?
Для этого важно проверить количество заказов по каждому товару за определённый период. WooCommerce хранит информацию о заказах в таблицах wp_posts (заказы) и wp_woocommerce_order_items (позиции заказов). На практике достаточно использовать функцию wc_get_orders() с фильтрами по дате и статусу.
Пошаговое решение: код для автоматического отключения товаров без продаж
Реализуем функцию, которая запускаться по крону (WP-Cron) и отключает товары, у которых нет продаж за последние 90 дней.
function wpeasy_disable_unsold_products() {
$days = 90; // период в днях
$date_before = date('Y-m-d H:i:s', strtotime("-{$days} days"));
// Получаем все опубликованные товары
$args = [
'post_type' => 'product',
'posts_per_page' => -1,
'post_status' => 'publish',
'fields' => 'ids',
];
$products = get_posts($args);
foreach ($products as $product_id) {
// Ищем заказы с этим товаром за последние 90 дней
$orders = wc_get_orders([
'limit' => 1, // достаточно одного
'status' => ['completed', 'processing'],
'date_created' => '>=' . $date_before,
'product' => $product_id,
]);
if (empty($orders)) {
// Нет продаж за период - меняем статус товара на черновик
wp_update_post([
'ID' => $product_id,
'post_status' => 'draft',
]);
}
}
}
// Регистрируем событие в WP-Cron при активации темы или плагина
if (!wp_next_scheduled('wpeasy_disable_unsold_products_hook')) {
wp_schedule_event(time(), 'daily', 'wpeasy_disable_unsold_products_hook');
}
add_action('wpeasy_disable_unsold_products_hook', 'wpeasy_disable_unsold_products');Как запустить вручную для отладки
Чтобы проверить работу функции без ожидания крон-события, можно вызвать её напрямую:
wpeasy_disable_unsold_products();Проверка результата после внедрения
- Перейдите в админку WooCommerce - товары.
- Отфильтруйте товары по статусу «Черновик».
- Проверьте, что товары без продаж за последние 90 дней изменили статус на черновик.
- Для нескольких товаров можно вручную создать фиктивные заказы и проверить, что они не отключаются.
Частые ошибки и как их исправить
- Функция не отключает товары: Проверьте, что WP-Cron работает — используйте плагин WP Crontrol для просмотра запланированных событий.
- Большая нагрузка при большом количестве товаров: Ограничьте выборку товаров порциями с помощью параметра
posts_per_pageи реализуйте пагинацию в функции. - Некорректный подсчёт продаж: Убедитесь, что фильтрация заказов по статусам включает только завершённые или в обработке (
completed,processing), чтобы не учитывать отменённые. - Статус товара меняется, но не отражается на сайте: Проверьте кэш и плагин кэширования; очистите кэш.
Практические советы по безопасности и производительности
- Для больших магазинов с тысячами товаров используйте пакетную обработку (например, по 50 товаров за раз) и запускайте функцию с помощью WP CLI для скорости.
- Не удаляйте товары автоматически, только меняйте статус — чтобы не потерять данные.
- Добавьте логирование отключённых товаров для аудита и возможного восстановления.
- Проверьте права пользователя, под которым запускается WP-Cron, чтобы избежать проблем с доступом.
Пример пакетной обработки по 50 товаров
function wpeasy_disable_unsold_products_batch($offset = 0, $batch_size = 50) {
$days = 90;
$date_before = date('Y-m-d H:i:s', strtotime("-{$days} days"));
$args = [
'post_type' => 'product',
'posts_per_page' => $batch_size,
'post_status' => 'publish',
'fields' => 'ids',
'offset' => $offset,
];
$products = get_posts($args);
if (empty($products)) {
return false; // Конец
}
foreach ($products as $product_id) {
$orders = wc_get_orders([
'limit' => 1,
'status' => ['completed', 'processing'],
'date_created' => '>=' . $date_before,
'product' => $product_id,
]);
if (empty($orders)) {
wp_update_post([
'ID' => $product_id,
'post_status' => 'draft',
]);
}
}
return true;
}Для запуска пакетов последовательно используйте WP CLI или планировщик задач с передачей смещения.
Сравнение способов реализации автоматического отключения товаров
| Метод | Преимущества | Недостатки |
|---|---|---|
| Код на PHP с WP-Cron | Гибкость, нет лишних плагинов, можно адаптировать под бизнес-логику | Нагрузка при большом каталоге, нужно следить за WP-Cron |
| Плагин автоматизации (например, WooCommerce Scheduler) | Простота установки, готовый интерфейс | Могут быть лишние функции, нагрузка, зависимость от обновлений плагина |
| Ручная фильтрация и отключение | Максимальный контроль, нет кода | Трудозатратно, ошибка человеческого фактора |