Суть задачи
Если у текущего пользователя есть группа с ID=10 — показывать все товары.
Если пользователь не в группе 10 (включая неавторизованных) — показывать только те товары, у которых свойство FOR_MEMBERS_ONLY не равно Y.
Способ 1. Через файл result_modifier.php шаблона компонента catalog
Создайте (или отредактируйте) файл result_modifier.php в шаблоне вашего компонента catalog (/local/templates/ваш_шаблон/components/bitrix/catalog/.default/result_modifier.php).
<?php
if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED !== true) die();
/** @var CBitrixComponentTemplate $this */
/** @var array $arParams */
/** @var array $arResult */
/** @var CMain $APPLICATION */
/** @var CUser $USER */
global $USER;
// ID группы, участники которой видят ВСЕ товары
$VipGroupId = 10;
// Код свойства — метка "только для участников"
$membersOnlyPropertyCode = 'FOR_MEMBERS_ONLY';
// Получаем массив групп текущего пользователя
$userGroups = $USER->GetUserGroupArray();
// Проверяем, состоит ли пользователь в vip-группе
$isVip = in_array($VipGroupId, $userGroups);
if (!$isVip)
{
// Для не-vip пользователей добавляем фильтр:
// показываем товары, у которых свойство FOR_MEMBERS_ONLY не равно Y (или не заполнено)
if (!isset($arParams['FILTER_NAME']) || empty($arParams['FILTER_NAME']))
{
$arParams['FILTER_NAME'] = 'arrFilter';
}
$filterName = $arParams['FILTER_NAME'];
global ${$filterName};
// Если переменная фильтра ещё не инициализирована компонентом — инициализируем
if (!isset(${$filterName}) || !is_array(${$filterName}))
{
${$filterName} = [];
}
// Добавляем условие: свойство FOR_MEMBERS_ONLY = false (не "Y")
${$filterName}['!PROPERTY_' . $membersOnlyPropertyCode] = 'Y';
// Альтернатива — показать только те, у кого свойство не заполнено:
// ${$filterName}[] = [
// 'LOGIC' => 'OR',
// ['PROPERTY_' . $membersOnlyPropertyCode => false],
// ['PROPERTY_' . $membersOnlyPropertyCode => 'N'],
// ];
}
Способ 2. Через init.php (глобальный обработчик, подходит для любых компонентов)
Добавьте следующий код в файл /bitrix/php_interface/init.php (или /local/php_interface/init.php):
<?php
// Подключаемся к событию инициализации компонента
use Bitrix\Main\EventManager;
$eventManager = EventManager::getInstance();
// Обрабатываем инициализацию всех компонентов
$eventManager->addEventHandler(
'main',
'OnProlog',
function () {
// Срабатывает на каждом хите
}
);
// Более правильный способ — перехватить через глобальные переменные
// в файле result_modifier.php шаблона компонента (см. Способ 1)
Но самый надёжный вариант — это Способ 1 (через result_modifier.php).
Способ 3. Создать свой компонент-наследник (кастомный класс)
Создайте свой класс компонента, унаследованный от CBitrixComponent, и переопределите метод executeProlog().
Файл /local/components/ваш_пространство/catalog/class.php:
<?php
if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED !== true) die();
use Bitrix\Main\Loader;
use Bitrix\Main\Context;
class CustomCatalogComponent extends CBitrixComponent
{
public function executeProlog()
{
global $USER;
$VipGroupId = 10;
$membersOnlyPropertyCode = 'FOR_MEMBERS_ONLY';
$userGroups = $USER->GetUserGroupArray();
$isVip = in_array($VipGroupId, $userGroups);
if (!$isVip)
{
$filterName = $this->arParams['FILTER_NAME'] ?? 'arrFilter';
if (empty($filterName))
{
$filterName = 'arrFilter';
}
global ${$filterName};
if (!isset(${$filterName}) || !is_array(${$filterName}))
{
${$filterName} = [];
}
// Исключаем товары с меткой "только для участников"
${$filterName}['!PROPERTY_' . $membersOnlyPropertyCode] = 'Y';
$this->arParams['FILTER_NAME'] = $filterName;
}
}
}
Пояснение ключевых API-методов
$USER->GetUserGroupArray()— возвращает массив ID групп, в которых состоит текущий пользователь. Для неавторизованного пользователя возвращается группа «Все пользователи» (обычно ID=2).in_array($VipGroupId, $userGroups)— проверяет, состоит ли пользователь в группе с ID=10.'!PROPERTY_FOR_MEMBERS_ONLY' => 'Y'— в фильтреCIBlockElement::GetListвосклицательный знак означает «НЕ равно». То есть выбираются элементы, у которых свойствоFOR_MEMBERS_ONLYне равноY.$arParams['FILTER_NAME']— имя переменной, в которую компоненты каталога (catalog.section,catalog.element) помещают свой фильтр. По умолчанию этоarrFilter.
Что нужно сделать в админке
- Создайте свойство инфоблока каталога с символьным кодом
FOR_MEMBERS_ONLYи типомСтрокаилиСписок (Y/N). - У товаров, которые должны быть скрыты от обычных пользователей, установите это свойство в значение
Y. - Убедитесь, что группа с ID=10 существует (Настройки → Пользователи → Группы пользователей).
Важные замечания
- Кеширование компонента будет учитывать разные фильтры для разных пользователей автоматически, так как Битрикс кеширует результаты отдельно для каждого набора параметров (включая глобальные фильтры).
- Если используется комплексный компонент
catalog, файлresult_modifier.phpнужно размещать в папке шаблона комплексного компонента:/local/templates/ваш_шаблон/components/bitrix/catalog/.default/result_modifier.php. - Проверьте, чтобы в настройках компонента каталога в параметре «Имя переменной для фильтра» было указано
arrFilter(или то же значение, что и в коде).