Рассмотрим получение элемента на примере класса, который проверяет права на просмотр файлов для отдельных групп пользователей.
Право на просмотр файла в проекте хранится в булевом свойстве FOR_VALID_GROUPS_ONLY
$documentHelper = new \Helper\DocumentHelper(
$this::IBLOCK_ID_DOCUMENTS, // iblockId
'FOR_VALID_GROUPS_ONLY', // propCode
'N' // propValidValue
);
// Получаем массив Id файлов, которые нужно удалить из выборки
$checkPermissionResult = $documentHelper->checkPermissionsByProp($documentsIds);
// Ниже вся остальная логика проекта...
<?php
namespace Helper;
use Bitrix\Iblock\ElementPropertyTable;
use Bitrix\Iblock\Iblock;
use Bitrix\Main\SystemException;
class DocumentHelper
{
private int $iblockId;
private string $propCode;
// Проверяемое значение свойства.
// Например, мы не хотим показывать элементы со свойством "Доступно Только для дистрибьюторов" (Y/N),
// если пользователь НЕ состоит в группе "Дистрибьюторы" (или любая другая логика), значит нам в конструктор класса
// нужно передать 'N'.
private string $propValidValue;
public function __construct(int $iblockId, string $propCode, string $propValidValue)
{
$this->iblockId = $iblockId;
$this->propCode = $propCode;
$this->propValidValue = $propValidValue;
}
public function checkPermissionsByProp(array $fileIds): array
{
if (empty($fileIds)) {
return [];
}
return $this->validate($fileIds);
}
public function validate(array $fileIds): array
{
try {
// Шаг 1: Получаем привязки файлов к элементам (сразу из нескольких таблиц).
$fileToElementsMap = $this->getFileToElementsMap($fileIds);
if (empty($fileToElementsMap)) {
return $this->getNotFoundFiles($fileIds);
}
// Шаг 2: Получаем значения свойства для элементов.
$elementIds = array_keys($fileToElementsMap);
$elementPropValues = $this->getElementPropertyValues($elementIds);
// Шаг 3: Фильтруем недоступные файлы.
return $this->filterInvalidFiles($fileIds, $fileToElementsMap, $elementPropValues);
} catch (\Exception $e) {
// Логирование ошибки, если нужно.
\Bitrix\Main\Diag\Debug::writeToFile(
$e->getMessage(),
date('d.m.Y H:i:s').' Ошибка validate():',
'docHelper.log');
return [];
}
}
private function getFileToElementsMap(array $fileIds): array
{
$res = ElementPropertyTable::getList([
'filter' => [
'VALUE' => $fileIds,
'IBLOCK_ELEMENT.IBLOCK_ID' => $this->iblockId
],
'select' => ['VALUE', 'IBLOCK_ELEMENT_ID'],
'runtime' => [
'IBLOCK_ELEMENT' => [
'data_type' => '\Bitrix\Iblock\ElementTable',
'reference' => [
'=this.IBLOCK_ELEMENT_ID' => 'ref.ID'
]
]
]
]);
$map = [];
while ($row = $res->fetch()) {
$fileId = (int)$row['VALUE'];
$elementId = (int)$row['IBLOCK_ELEMENT_ID'];
$map[$elementId][] = $fileId;
}
return $map;
}
private function getElementPropertyValues(array $elementIds): array
{
$iblock = Iblock::wakeUp($this->iblockId);
$entity = $iblock->getEntityDataClass();
$res = $entity::getList([
'select' => ['ID', $alias = $this->propCode . '_' => $this->propCode],
'filter' => ['ID' => $elementIds],
'cache' => ['ttl' => 3600]
]);
$values = [];
while ($row = $res->fetch()) {
$values[(int)$row['ID']] = $row[$alias.'VALUE'];
}
return $values;
}
private function filterInvalidFiles(array $fileIds, array $fileToElementsMap, array $elementPropValues): array
{
$invalidFiles = [];
// Создаем карту доступности файлов.
$accessMap = array_fill_keys($fileIds, false);
// Помечаем файлы с доступом.
foreach ($fileToElementsMap as $elementId => $files) {
if (isset($elementPropValues[$elementId]) &&
$elementPropValues[$elementId] === $this->propValidValue) {
foreach ($files as $file) {
if (isset($accessMap[$file])) {
$accessMap[$file] = true;
}
}
}
}
// Собираем недоступные файлы.
foreach ($accessMap as $file => $hasAccess) {
if (!$hasAccess) {
$invalidFiles[] = $file;
}
}
return $invalidFiles;
}
private function getNotFoundFiles(array $fileIds): array
{
// Все файлы не найдены.
return $fileIds;
}
}