Диагностика проблемы с неиспользуемыми вариантами товаров в WooCommerce
В больших интернет-магазинах на WooCommerce часто возникают ситуации, когда вариации товаров больше неактуальны, например, отсутствуют на складе или не продаются длительное время. Это приводит к путанице у покупателей и усложняет управление каталогом. Задача — автоматически отключать такие варианты, чтобы они не отображались в магазине и не создавали лишних проблем.
Как определить неиспользуемые варианты?
- Вариации с нулевым запасом и отсутствием возможности предзаказа;
- Вариации, которые не покупались длительное время (например, 6 месяцев);
- Вариации с выключенным статусом или помеченные по метке.
Простая диагностика — проверить наличие и статус вариаций в админке WooCommerce в разделе «Товары» → «Вариации».
Пошаговое решение: автоматическое отключение неиспользуемых вариантов
1. Создаем пользовательскую функцию для проверки и отключения вариаций
Для автоматизации добавим PHP-код в functions.php дочерней темы или в пользовательский плагин.
function wc_auto_disable_unused_variations() {
$args = array(
'post_type' => 'product_variation',
'posts_per_page' => -1,
'post_status' => array('publish', 'private'),
);
$variations = get_posts($args);
$date_threshold = strtotime('-6 months'); // граница времени без покупок
foreach ($variations as $variation) {
$variation_id = $variation->ID;
// Получаем объект вариации
$product_variation = wc_get_product($variation_id);
if (!$product_variation) continue;
// Проверяем наличие на складе
$stock_quantity = $product_variation->get_stock_quantity();
$is_in_stock = $product_variation->is_in_stock();
// Получаем дату последней покупки вариации
$last_order_date = get_post_meta($variation_id, '_last_order_date', true);
// Если нет даты, считаем, что вариация не покупалась
$last_order_timestamp = $last_order_date ? strtotime($last_order_date) : 0;
// Условие отключения: нет на складе и не покупалась более 6 месяцев
if ((empty($stock_quantity) || !$is_in_stock) && $last_order_timestamp < $date_threshold) {
// Меняем статус вариации на 'private' (скрыть)
wp_update_post(array(
'ID' => $variation_id,
'post_status' => 'private',
));
}
}
}
// Хук для запуска задачи по крону, например раз в день
add_action('wp_loaded', function() {
if (!wp_next_scheduled('wc_auto_disable_variations_hook')) {
wp_schedule_event(time(), 'daily', 'wc_auto_disable_variations_hook');
}
});
add_action('wc_auto_disable_variations_hook', 'wc_auto_disable_unused_variations');2. Отслеживание даты последней покупки вариации
Для работы условия по дате покупки нужно обновлять мета-данные _last_order_date при оформлении заказа. Добавим код для записи этой даты:
add_action('woocommerce_order_status_completed', 'update_variation_last_order_date');
function update_variation_last_order_date($order_id) {
$order = wc_get_order($order_id);
if (!$order) return;
foreach ($order->get_items() as $item) {
$variation_id = $item->get_variation_id();
if ($variation_id) {
update_post_meta($variation_id, '_last_order_date', current_time('mysql'));
}
}
}Проверка результата после внедрения решения
- Через несколько дней после запуска скрипта проверьте в базе или админке, что вариации с нулевым запасом и без покупок стали иметь статус
privateи не отображаются в каталоге. - Создайте тестовый заказ с вариацией и убедитесь, что мета
_last_order_dateобновляется (например, через phpMyAdmin или плагины для просмотра метаданных). - Проверьте расписание cron задач через плагин WP Crontrol или аналогичный, чтобы убедиться, что событие
wc_auto_disable_variations_hookзапущено.
Частые ошибки и способы их устранения
- Не обновляется статус вариаций. Проверьте права пользователя, от имени которого запускается скрипт, и наличие cron задач. Для проверки вручную вызовите функцию
wc_auto_disable_unused_variations(). - Дата последней покупки не записывается. Убедитесь, что хук
woocommerce_order_status_completedсрабатывает. Возможно, заказ не переходит в статус completed. Проверьте статус заказа или добавьте аналогичные хуки для других статусов. - Скрытые вариации все еще видны в каталоге. Статус
privateне всегда полностью исключает отображение. В этом случае можно дополнительно фильтровать запросы на фронтенде.
Практические советы по безопасности и производительности
- Для больших магазинов с тысячами вариаций используйте WP CLI для запуска задачи, чтобы не нагружать фронтенд.
- Добавьте логирование изменений в отдельный файл для аудита (используйте
error_logили Monolog). - Не храните дату последней покупки в мета-данных вариаций без контроля — регулярно очищайте устаревшие данные.
- Добавьте возможность отключать автоматическое отключение через настройку в админке или фильтр для гибкости.
Сравнение способов автоматического отключения вариантов товаров
| Метод | Плюсы | Минусы | Компромисс |
|---|---|---|---|
| Плагин автопоиска и отключения | Простота установки, готовый интерфейс | Может быть тяжелым, лишние функции | Подходит для магазинов без разработчиков |
| Кастомный PHP-код с cron | Легкий, точный контроль, гибкость | Требует навыков, нужно тестировать | Оптимально для опытных разработчиков |
| Ручное управление через админку | Простота и прозрачность | Трудоемко при большом каталоге | Подходит для небольших магазинов |