Диагностика задачи: зачем ограничивать доступ к разделам товаров по ролям
В WooCommerce нередко возникает необходимость скрыть определённые категории или товары от конкретных групп пользователей. Задача может быть связана с оптовыми покупателями, внутренними сотрудниками или гостями. Например, администраторы хотят, чтобы обычные пользователи не видели товары для оптовиков или внутренний каталог.
Стандартных настроек WooCommerce для этого нет, поэтому приходится использовать программные решения. Важно понять, что необходимо ограничить не только визуальный показ, но и прямой доступ по URL, а также исключить товары из поиска и виджетов.
Пошаговое решение: скрываем категории и товары по ролям
1. Определение ролей и категорий для ограничения
Для начала уточним, какие роли пользователей мы хотим ограничить и какие категории скрыть. Например, мы хотим скрыть категорию с ярлыком wholesale для всех пользователей, у которых нет роли wholesale_customer.
2. Фильтрация запросов WooCommerce
Добавим фильтр, который исключит товары из категории wholesale для неподходящих пользователей. Код вставляем в файл functions.php дочерней темы или в собственный плагин:
add_action('pre_get_posts', function($query) {
if (is_admin() || !$query->is_main_query()) {
return;
}
if (is_shop() || is_product_category() || is_product_tag()) {
$user = wp_get_current_user();
// Проверяем роль пользователя
if (!in_array('wholesale_customer', (array) $user->roles)) {
// Получаем ID категории wholesale
$term = get_term_by('slug', 'wholesale', 'product_cat');
if ($term) {
$tax_query = (array) $query->get('tax_query');
$tax_query[] = array(
'taxonomy' => 'product_cat',
'field' => 'term_id',
'terms' => array($term->term_id),
'operator' => 'NOT IN',
);
$query->set('tax_query', $tax_query);
}
}
}
});3. Блокировка прямого доступа к товарам из скрытой категории
Чтобы пользователь не мог перейти по прямой ссылке на товар из категории wholesale, добавим проверку на загрузке страницы одиночного товара:
add_action('template_redirect', function() {
if (is_singular('product')) {
$user = wp_get_current_user();
if (!in_array('wholesale_customer', (array) $user->roles)) {
global $post;
$terms = get_the_terms($post->ID, 'product_cat');
if ($terms) {
foreach ($terms as $term) {
if ($term->slug === 'wholesale') {
wp_redirect(home_url());
exit;
}
}
}
}
}
});Проверка результата после внедрения
- Создайте тестового пользователя с ролью, отличной от
wholesale_customer. - Зайдите под этим пользователем на страницу магазина и убедитесь, что товары из категории
wholesaleне отображаются. - Попробуйте перейти по прямой ссылке на товар из категории
wholesale— должен произойти редирект на главную или страницу по вашему выбору. - Авторизуйтесь под пользователем с ролью
wholesale_customerи проверьте, что товары видны.
Частые ошибки и способы их устранения
- Не работает фильтрация в админке. Фильтр
pre_get_postsприменён с условиемis_admin()— убедитесь, что вы не исключаете запросы в админке, если там хотите видеть все товары. - Редирект на странице товара не срабатывает. Проверьте, что хук
template_redirectне конфликтует с другими плагинами или темой, и что проверка категорий выполнена корректно. - Товары отображаются в виджетах поиска или рекомендованных товаров. Для полного скрытия нужно дополнительно фильтровать запросы виджетов и поиск, например, через
woocommerce_product_query.
Практические советы по безопасности и производительности
- Обрабатывайте роли пользователей с помощью
wp_get_current_user(), не полагаясь на глобальные переменные. - Проверяйте наличие категорий через
get_term_byи кешируйте результат, если возможно. - Используйте минимально необходимые хуки и не загружайте лишние проверки на страницах, где они не нужны.
- Если сайт большой, подумайте об использовании transient-кеша для результатов проверки ролей и категорий.
Сравнение способов ограничения доступа к товарам
| Метод | Плюсы | Минусы | Компромисс |
|---|---|---|---|
| Плагин для ограничения контента | Удобство настройки, готовые функции | Нагрузка, лишний функционал, зависимость от стороннего кода | Использовать легковесные плагины, проверенные сообществом |
| Кодовые фильтры в functions.php | Лёгкий, контролируемый, без сторонних зависимостей | Нужно уметь программировать, требуется поддержка | Писать аккуратный, хорошо документированный код |
| Комбинированный подход | Гибкость, можно быстро внедрить и доработать | Риск конфликтов, требует тестирования | Тестировать на тестовом окружении перед продакшеном |