Диагностика проблемы с отображением товаров в WooCommerce при нулевых остатках
В стандартной установке WooCommerce товары с нулевым остатком могут оставаться активными и видимыми в каталоге, что вводит покупателей в заблуждение. Часто владельцы магазинов хотят автоматически скрывать или отключать такие товары, чтобы не принимать заказы на отсутствие. Однако при последующем пополнении запасов товар должен автоматически становиться доступным для продажи. В этой статье разберем, как реализовать эту логику программно.
Как WooCommerce работает с остатками товаров
WooCommerce хранит количество на складе в метаполе _stock и флаг управления запасами _manage_stock. При активации управления запасами WooCommerce автоматически меняет статус товара на «В наличии» или «Нет в наличии», но не всегда скрывает товар из каталога.
По умолчанию товары с нулевым запасом отображаются, если не включена опция «Скрывать товары без наличия» в настройках WooCommerce.
Пошаговое решение: автоматическое отключение и включение товаров по остаткам
1. Проверка и настройка WooCommerce
- В админке WordPress перейдите в WooCommerce > Настройки > Товары > Запасы.
- Убедитесь, что включена опция Включить управление запасами.
- Активируйте Скрывать товары без наличия, чтобы товары с нулевым остатком автоматически не отображались в каталоге.
Однако данный метод не отключает товар, а только скрывает. Для полного отключения нужно программное решение.
2. Добавление кода для автоматического изменения статуса товара
Используем хук woocommerce_product_set_stock, который срабатывает при изменении запасов товара.
add_action('woocommerce_product_set_stock', function($product) {
if (!$product->managing_stock()) {
return; // Управление запасами отключено
}
$stock_quantity = $product->get_stock_quantity();
$post_id = $product->get_id();
// Проверяем остаток
if ($stock_quantity <= 0) {
// Отключаем товар (переводим в черновик)
if (get_post_status($post_id) !== 'draft') {
wp_update_post([
'ID' => $post_id,
'post_status' => 'draft'
]);
}
} else {
// Включаем товар (делаем опубликованным)
if (get_post_status($post_id) !== 'publish') {
wp_update_post([
'ID' => $post_id,
'post_status' => 'publish'
]);
}
}
});
Этот код автоматически переводит товар в статус черновика при нулевом или отрицательном остатке и возвращает в публикацию при наличии товара на складе.
3. Обработка вариативных товаров
Для вариативных товаров нужно учитывать остатки вариаций. Если у всех вариаций запас равен 0, отключаем родительский товар.
add_action('woocommerce_variation_set_stock', function($variation) {
$parent_id = $variation->get_parent_id();
$parent = wc_get_product($parent_id);
if (!$parent) return;
$children = $parent->get_children();
$all_out_of_stock = true;
foreach ($children as $child_id) {
$child = wc_get_product($child_id);
if ($child && $child->get_stock_quantity() > 0) {
$all_out_of_stock = false;
break;
}
}
if ($all_out_of_stock) {
if (get_post_status($parent_id) !== 'draft') {
wp_update_post(['ID' => $parent_id, 'post_status' => 'draft']);
}
} else {
if (get_post_status($parent_id) !== 'publish') {
wp_update_post(['ID' => $parent_id, 'post_status' => 'publish']);
}
}
});
Проверка результата после внедрения
- Измените остаток товара через админку WooCommerce или через API.
- Проверьте, что при обнулении остатка товар становится черновиком и не отображается в каталоге.
- При увеличении остатка товар возвращается к опубликованному состоянию и виден покупателям.
- Для вариативных товаров проверьте, что статус родительского товара меняется в зависимости от остатков вариаций.
Для быстрой проверки можно использовать WP-CLI:
wp post list --post_type=product --post_status=draft,publish --fields=ID,post_title,post_status
Частые ошибки и их исправление
- Код не срабатывает при изменении остатков: Проверьте, что управление запасами включено и используемые хуки совпадают с версией WooCommerce.
- Товар не меняет статус: Возможно, другой плагин блокирует изменение статуса. Проверьте логи ошибок и конфликтующие хуки.
- Вариативные товары не обрабатываются корректно: Убедитесь, что подхватываете изменения запасов вариаций, а не только родительского товара.
- Статус товара меняется, но он все равно отображается в каталоге: Проверьте настройки видимости и кэш сайта (например, плагинов кеширования).
Практические советы по безопасности и производительности
- Добавляйте код в дочернюю тему или собственный плагин, чтобы избежать потери при обновлениях.
- Используйте функцию
wp_update_postаккуратно, чтобы не создавать рекурсию — в нашем случае хук срабатывает на изменение запаса, а мы меняем статус поста, что не вызывает повторного срабатывания. - Отключите кеширование страниц с динамическим контентом (например, страницы каталога и карточки товара) либо используйте AJAX-запросы для обновления статуса товара.
- Для больших магазинов с тысячами товаров рассмотрите отложенное обновление статусов через WP Cron или внешние скрипты, чтобы избежать нагрузки на сервер.
- Следите за логами ошибок PHP для выявления возможных проблем при обновлении статусов.
Сравнение вариантов реализации отключения товаров по складу
| Метод | Преимущества | Недостатки | Рекомендации |
|---|---|---|---|
| Опция WooCommerce «Скрывать товары без наличия» | Простота настройки, не требует кода | Товар остается опубликованным, возможна путаница с заказами | Подходит для небольших магазинов |
| Код с изменением статуса поста | Полное отключение товара, гибкость | Требует технических знаний, возможны конфликты с плагинами | Лучше для средних и больших проектов |
| Плагины для управления видимостью товаров | Дополнительные функции, GUI | Зависимость от стороннего кода, цена | Если нужен расширенный контроль без программирования |