Диагностика задачи: зачем ограничивать доступ к WooCommerce по ролям
Часто в проектах на WordPress с WooCommerce необходимо скрыть магазин или его отдельные разделы от неавторизованных пользователей или пользователей с определёнными ролями. Это встречается при создании интернет-магазина для закрытого клуба, B2B-площадки, или при ограничении доступа к ценам и товарам для клиентов с разным уровнем доступа.
Основные симптомы, указывающие на необходимость ограничения доступа:
- Магазин доступен всем, а нужно, чтобы только зарегистрированные пользователи с ролью "клиент" или "оптовик" видели каталог и могли делать заказы.
- Нужно скрыть цены и кнопку "В корзину" для гостей или пользователей с ролью "подписчик".
- Требуется перенаправлять пользователей без нужной роли на страницу входа или другую страницу.
Пошаговое решение: ограничиваем доступ к WooCommerce по ролям
1. Проверяем роли пользователей и добавляем свои, если нужно
По умолчанию WooCommerce использует роли customer, shop_manager и др. Для B2B можно создать кастомную роль, например wholesale_customer:
function wpcommunity_add_wholesale_role() {
add_role('wholesale_customer', 'Оптовый клиент', [
'read' => true,
'level_0' => true,
'view_woocommerce_reports' => true
]);
}
add_action('init', 'wpcommunity_add_wholesale_role');
2. Скрываем магазин и страницы WooCommerce от пользователей без нужной роли
Добавляем код в functions.php темы или в кастомный плагин. Здесь пример, который перенаправляет всех, кто не залогинен или не имеет роли customer или wholesale_customer, со страниц магазина, товаров, корзины и оформления заказа на страницу входа.
function wpcommunity_restrict_woocommerce_access() {
if ( is_admin() ) {
return; // Не трогаем админку
}
if ( ! is_user_logged_in() ) {
if ( is_shop() || is_product() || is_cart() || is_checkout() ) {
wp_redirect( wp_login_url() );
exit;
}
} else {
$user = wp_get_current_user();
$allowed_roles = ['customer', 'wholesale_customer'];
if ( ( is_shop() || is_product() || is_cart() || is_checkout() ) && ! array_intersect($allowed_roles, $user->roles) ) {
wp_redirect( home_url() );
exit;
}
}
}
add_action( 'template_redirect', 'wpcommunity_restrict_woocommerce_access' );
3. Скрываем цены и кнопки "Добавить в корзину" для неавторизованных пользователей
Чтобы дополнительно скрыть цены и кнопку "В корзину" для пользователей без доступа, используем фильтры WooCommerce:
// Скрываем цены
add_filter( 'woocommerce_get_price_html', 'wpcommunity_hide_price_for_guests', 10, 2 );
function wpcommunity_hide_price_for_guests( $price, $product ) {
if ( ! is_user_logged_in() ) {
return '<span class="price-hidden">Цена доступна только после входа</span>';
}
return $price;
}
// Скрываем кнопку "Добавить в корзину"
add_filter( 'woocommerce_is_purchasable', 'wpcommunity_disable_add_to_cart_for_guests', 10, 2 );
function wpcommunity_disable_add_to_cart_for_guests( $purchasable, $product ) {
if ( ! is_user_logged_in() ) {
return false;
}
return $purchasable;
}
Проверка результата после внедрения
- Зайдите на сайт в режиме инкогнито — магазин, товары, корзина и оформление заказа должны перебрасывать на страницу входа.
- Залогиньтесь под пользователем с ролью
customerилиwholesale_customer, убедитесь, что магазин и функционал работают. - Залогиньтесь под пользователем с ролью без доступа (например,
subscriber) — вы должны быть перенаправлены с магазина на главную страницу. - Проверьте страницы товаров: у неавторизованных пользователей цены и кнопки "В корзину" отсутствуют и заменены на сообщение.
Частые ошибки и пути их исправления
- Проблема: После добавления кода магазин закрывается для всех, включая администраторов.
Причина: Не исключена админка и роли админов из проверки.
Решение: Добавить проверкуis_admin()и разрешить доступ администраторам через условие. - Проблема: Пользователи с нужной ролью всё равно не видят магазин.
Причина: Роль не совпадает с указанными в массиве$allowed_roles.
Решение: Проверьте названия ролей в админке или черезprint_r(wp_get_current_user()->roles). - Проблема: Кнопка "Добавить в корзину" не появляется, хотя пользователь залогинен.
Причина: Кэширование страницы мешает обновлению.
Решение: Очистите кэш сайта и браузера, проверьте отключение кэша для страниц WooCommerce.
Практические советы по безопасности и производительности
- Используйте проверку ролей на серверной стороне, чтобы не показывать запрещённый контент даже при отключённом JavaScript.
- Не храните чувствительные данные в куках или локальном хранилище без шифрования.
- Для больших сайтов с разными ролями и уровнями доступа рассмотрите использование плагинов для управления доступом, например Clearfy Pro, который позволяет оптимизировать и контролировать доступ.
- Избегайте большого количества условий в хук
template_redirect, чтобы не замедлять загрузку страниц.
Сравнение вариантов ограничения доступа к WooCommerce
| Метод | Описание | Плюсы | Минусы |
|---|---|---|---|
| Кастомный код | Использование хуков для проверки ролей и перенаправления | Полный контроль, бесплатно, гибко | Нужны знания PHP и WP API, возможны ошибки без правильной отладки |
| Плагин приватности/ограничения доступа | Готовые решения для ограничения просмотра и покупок | Простота настройки, поддержка разработчиков | Может быть платным, влияние на производительность |
| Комбинированный подход | Код + плагин для расширенных функций | Оптимальный баланс контроля и удобства | Сложнее поддерживать, возможны конфликты |