Диагностика проблемы: зачем и когда отключать неактивные товары
В интернет-магазинах на WooCommerce часто возникает ситуация, когда товары перестают быть актуальными — например, устаревшие коллекции, сезонные позиции или товары, которых давно нет в наличии. Чтобы не показывать такие товары покупателям и не загромождать каталог, их нужно отключать или скрывать.
Ручное отключение большого количества товаров — трудоемкий и ошибкоопасный процесс. Автоматизация этого процесса с помощью WP-Cron и хуков WooCommerce позволяет облегчить администрирование и поддерживать каталог в актуальном состоянии.
Как автоматически отключать товары, неактивные по времени
Определяем критерии неактивности товара
Самый распространенный способ — отключать товары, которые не обновлялись и не продавались в течение заданного периода. Например, если товар не продавался и не обновлялся 180 дней — отключаем.
Можно использовать даты последнего изменения товара (post_modified) и дату последней продажи (мета-данные заказа).
Пошаговое решение через WP-Cron и кастомный PHP-код
1. Создаем функцию для поиска и отключения неактивных товаров.
function disable_inactive_products() {
$days_inactive = 180; // количество дней неактивности
$date_threshold = date('Y-m-d H:i:s', strtotime('-' . $days_inactive . ' days'));
// Получаем товары, которые не обновлялись с даты порога и имеют статус publish
$args = [
'post_type' => 'product',
'post_status' => 'publish',
'date_query' => [
[
'column' => 'post_modified',
'before' => $date_threshold,
],
],
'posts_per_page' => -1,
'fields' => 'ids',
];
$query = new WP_Query($args);
if (!$query->have_posts()) {
return; // Нет товаров для отключения
}
foreach ($query->posts as $product_id) {
// Проверяем дату последней продажи
$last_order_date = get_post_meta($product_id, '_last_order_date', true);
if ($last_order_date && strtotime($last_order_date) > strtotime($date_threshold)) {
continue; // Товар недавно продавался
}
// Меняем статус на 'draft' (черновик)
wp_update_post([
'ID' => $product_id,
'post_status' => 'draft',
]);
}
}2. Создаем WP-Cron задачу для регулярного запуска функции:
function schedule_disable_inactive_products() {
if (!wp_next_scheduled('disable_inactive_products_cron')) {
wp_schedule_event(time(), 'daily', 'disable_inactive_products_cron');
}
}
add_action('wp', 'schedule_disable_inactive_products');
add_action('disable_inactive_products_cron', 'disable_inactive_products');3. Добавляем обновление мета-поля _last_order_date при каждой продаже товара:
function update_last_order_date($order_id) {
$order = wc_get_order($order_id);
if (!$order) return;
foreach ($order->get_items() as $item) {
$product_id = $item->get_product_id();
update_post_meta($product_id, '_last_order_date', current_time('mysql'));
}
}
add_action('woocommerce_thankyou', 'update_last_order_date');Как проверить, что решение работает
- Проверьте, что WP-Cron запланирован: в админке WP или с помощью плагина WP Crontrol должен быть событие
disable_inactive_products_cron. - Создайте тестовый товар и установите дату последнего обновления в прошлое (через базу данных или программно).
- Убедитесь, что у товара нет мета
_last_order_dateили он старше 180 дней. - Запустите вручную функцию
disable_inactive_products()(например, через admin-ajax или WP-CLI) и проверьте, что статус товара изменился наdraft. - Проверьте логи сервера на ошибки и корректность выполнения WP-Cron.
Частые ошибки и их исправление
- WP-Cron не запускается: причина — низкий трафик сайта или отключенный WP-Cron в
wp-config.php. Решение — использовать системный cron на сервере для запускаwp-cron.phpили плагин для управления cron. - Метаданные даты продажи не обновляются: проверьте, подключен ли хук
woocommerce_thankyouи нет ли конфликтов с другими плагинами, блокирующими обновление мета. - Товары не переходят в статус
draft: убедитесь, что у пользователя, от имени которого выполняется скрипт, есть права на редактирование постов, и что нет фильтров, которые блокируют смену статуса. - Функция выбирает слишком много товаров и нагрузка растет: добавьте пагинацию и ограничьте количество товаров на итерацию, чтобы не создавать нагрузку.
Практические советы по оптимизации и безопасности
- Обрабатывайте товары пачками по 50-100 штук, чтобы избежать таймаутов и нагрузок.
- Используйте транзиенты или кеширование для хранения результатов, если логика усложняется.
- Проверяйте права пользователя при необходимости — если планируете запускать отключение вручную через админку.
- Резервное копирование базы данных перед внедрением автоматических изменений — обязательное условие.
Сравнение вариантов реализации
| Вариант | Преимущества | Недостатки |
|---|---|---|
| Плагин с автоматическим отключением | Быстрая настройка, интерфейс, поддержка | Может быть избыточным, нагрузка, ограниченная кастомизация |
| Кастомный код с WP-Cron (как в статье) | Полный контроль, точная логика, минимальная нагрузка | Требует навыков, отладка, ответственность за обновления |
| Ручное отключение | Минимум кода, быстро | Трудоемко, риск пропустить товары, ошибки |