Ситуация типовая: магазин работает в B2B-режиме, остатки на складе видны только после входа, а гостям нужно показывать либо нейтральный статус, либо вообще не раскрывать количество. В WooCommerce это можно решить без тяжелых плагинов, но важно не ограничиться только шаблоном карточки товара: остатки часто всплывают в каталоге, на странице товара, в мини-корзине и в AJAX-обновлениях.
Ниже — рабочая схема, которая скрывает количество и статус наличия для неавторизованных пользователей, но не ломает логику покупки для вошедших клиентов.
Когда проблема проявляется и что именно нужно проверить
Перед правками откройте магазин в режиме гостя и пройдитесь по нескольким сценариям:
- страница товара с включенным управлением запасами;
- каталог и архивы товаров;
- вариативный товар, где остаток показывается у конкретной вариации;
- мини-корзина и корзина после AJAX-обновления;
- страницы, которые кэшируются плагином или сервером.
Если остаток виден только на карточке товара, а в каталоге уже скрыт, значит проблема не в WooCommerce как таковом, а в теме: она выводит данные напрямую через шаблон или собственный хук. Если же число скрыто в карточке, но появляется в вариациях, нужно отдельно фильтровать данные вариации.
Что обычно ломает ожидаемое поведение
Чаще всего мешают три вещи: кэш для гостей, кастомные шаблоны темы и сторонние плагины, которые добавляют блоки «в наличии / осталось N шт.» в карточку товара. Поэтому сначала стоит понять, где именно выводится остаток, а уже потом править код.
Сравнение подходов: плагин, код или правка шаблона
| Подход | Когда подходит | Минус |
|---|---|---|
| Плагин | Нужно быстро закрыть задачу без разработки | Может скрыть не все места вывода и добавить лишнюю нагрузку |
| Код через фильтры WooCommerce | Нужен точечный контроль и предсказуемое поведение | Нужно проверить тему и кэш |
| Правка шаблона | Тема выводит остатки нестандартно | Сложнее сопровождать после обновлений темы |
Если задача именно «скрыть наличие для гостей», обычно достаточно фильтров WooCommerce. Это безопаснее, чем переписывать шаблоны, и проще откатить.
Пошаговое решение через код
Добавьте код в functions.php дочерней темы или в собственный мини-плагин. Вариант ниже скрывает текст наличия и количество на складе для неавторизованных пользователей, но оставляет логику WooCommerce нетронутой для вошедших.
add_filter( 'woocommerce_get_availability_text', 'wp_course_hide_stock_for_guests', 10, 2 );
add_filter( 'woocommerce_get_availability', 'wp_course_hide_stock_for_guests_array', 10, 2 );
function wp_course_hide_stock_for_guests( $availability, $product ) {
if ( is_user_logged_in() ) {
return $availability;
}
return '';
}
function wp_course_hide_stock_for_guests_array( $availability, $product ) {
if ( is_user_logged_in() ) {
return $availability;
}
if ( is_array( $availability ) ) {
$availability['availability'] = '';
}
return $availability;
}Этот вариант закрывает стандартный вывод WooCommerce. Но если тема показывает остаток через собственный шаблон, одного фильтра может быть мало. Тогда дополнительно проверьте, не используется ли в теме прямой вызов методов товара вроде $product->get_stock_quantity() или $product->get_availability_text().
Если нужно скрыть не только текст, но и сам блок
Иногда в карточке товара есть отдельный контейнер с классом темы. В таком случае проще убрать его через хук, если тема использует стандартные действия WooCommerce. Например, можно снять вывод стандартного блока наличия:
add_action( 'wp', 'wp_course_remove_stock_display_for_guests' );
function wp_course_remove_stock_display_for_guests() {
if ( is_user_logged_in() ) {
return;
}
remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_meta', 40 );
}Но здесь важно не переборщить: функция woocommerce_template_single_meta выводит не только наличие, но и SKU, категории и теги. Если вам нужен только stock-статус, лучше не удалять весь блок, а работать точечно через фильтры или шаблон темы.
Как скрыть остаток у вариативных товаров
У вариативных товаров WooCommerce может отдавать данные через AJAX при выборе вариации. Если оставить только фильтр для обычного товара, гостю все равно может прилететь количество по конкретной вариации. Для этого добавьте фильтр на данные вариации:
add_filter( 'woocommerce_available_variation', 'wp_course_hide_variation_stock_for_guests' );
function wp_course_hide_variation_stock_for_guests( $data ) {
if ( is_user_logged_in() ) {
return $data;
}
if ( isset( $data['availability_html'] ) ) {
$data['availability_html'] = '';
}
if ( isset( $data['is_in_stock'] ) ) {
$data['is_in_stock'] = true;
}
return $data;
}Здесь есть важный нюанс: мы не меняем реальную логику складского учета, а только убираем публичный вывод. Не стоит подменять is_in_stock на false, если товар реально доступен: это может сломать кнопку покупки и поведение вариаций.
Проверка результата после внедрения
После добавления кода проверьте решение не только в браузере администратора, но и в гостевой сессии. Лучше открыть сайт в приватном окне и пройтись по этим точкам:
- карточка простого товара;
- карточка вариативного товара;
- каталог с плиткой товаров;
- страница товара после выбора вариации;
- мини-корзина, если тема показывает там остаток;
- мобильная версия, если у темы отдельная разметка.
Если у вас включен кэш, очистите его после правок и проверьте страницу без авторизации. Иногда старый HTML остается в кеше, и кажется, что код не работает, хотя на самом деле вы видите старую версию страницы.
Полезно также открыть исходный HTML страницы и поискать фразы вроде in stock, out of stock или русские тексты наличия. Если текст все еще есть в разметке, значит фильтр не перекрывает конкретный способ вывода в теме.
Частые ошибки и как их исправить
Код добавили в родительскую тему
После обновления темы изменения пропадают. Решение простое: переносите код в дочернюю тему или в отдельный плагин для сайта.
Скрыли только текст, но не сам блок
Так бывает, если тема выводит обертку с иконкой, цветным индикатором или дополнительной строкой. Тогда нужно искать конкретный хук темы или шаблон single-product, а не ограничиваться фильтром текста.
Не учли вариации
На простом товаре все выглядит нормально, а на вариативном остаток все равно виден после выбора размера или цвета. В этом случае нужен фильтр woocommerce_available_variation.
Кэш мешает проверить результат
Если подключен серверный кэш, Cloudflare или плагин кеширования, гостю может отдаваться старая версия страницы. После правок очищайте кэш на всех уровнях и проверяйте в приватном окне.
Сломали вывод SKU и метаданных
Это частая ошибка при попытке убрать весь блок метаинформации через remove_action. Если нужен только stock-статус, не удаляйте общий блок меты целиком.
Практические советы по безопасности и производительности
Если вы скрываете остатки по бизнес-причинам, не полагайтесь только на фронтенд. Неавторизованный пользователь не должен получать лишние данные ни в HTML, ни в AJAX-ответах, ни в JSON вариаций. Иначе информацию можно будет увидеть через инструменты разработчика.
С точки зрения производительности фильтры WooCommerce почти не нагружают сайт, если код написан без лишних запросов к базе. Не добавляйте внутри фильтров собственные запросы к postmeta или usermeta без необходимости: для каждой карточки товара это быстро превращается в лишнюю нагрузку.
Если вам нужно не только скрыть остатки, но и убрать дублирующиеся технические элементы на сайте, имеет смысл посмотреть в сторону Clearfy Pro: у него есть инструменты для чистки лишнего вывода и SEO-оптимизации, но применять его стоит только там, где задача действительно совпадает с его назначением. Ссылка: https://wpshop.ru/plugins/clearfy
Что должно быть видно после исправления
Для гостя на сайте:
- нет текста «в наличии», «нет в наличии» или количества на складе;
- вариации не раскрывают остаток после выбора параметров;
- кнопка покупки работает так же, как и раньше, если товар доступен;
- авторизованный пользователь видит данные, если это предусмотрено логикой магазина.
Если все эти пункты выполняются, значит решение внедрено корректно. Если хотя бы один сценарий остался с утечкой данных, ищите не в WooCommerce, а в теме, кастомных блоках или кеше.