13 private const PROPERTY_PREFIX =
'PROPERTY_';
14 private const PROPERTY_MASK =
'/^' . self::PROPERTY_PREFIX .
'([0-9]+)$/';
16 private int $iblockId;
17 private bool $isShowXmlId;
18 private bool $isShowSections;
19 private array $propertyList = [];
20 private array $userTypeList;
22 public function __construct(
int $iblockId,
bool $isShowXmlId,
bool $isShowSections)
24 $this->iblockId = $iblockId;
25 $this->isShowXmlId = $isShowXmlId;
26 $this->isShowSections = $isShowSections;
51 if ($this->isShowSections)
53 $fields[
'SECTION_ID'] = [
58 $fields[
'INCLUDE_SUBSECTIONS'] = [
69 if ($this->isShowXmlId)
80 $fields[
'TIMESTAMP_X'] = [
84 $fields[
'MODIFIED_BY'] = [
85 'type' =>
'entity_selector',
88 $fields[
'DATE_CREATE'] = [
92 $fields[
'CREATED_BY'] = [
93 'type' =>
'entity_selector',
96 $fields[
'ACTIVE_FROM'] = [
100 $fields[
'ACTIVE_TO'] = [
132 'USER_TYPE_SETTINGS_LIST',
135 '=IBLOCK_ID' => $this->iblockId,
147 while ($row = $iterator->fetch())
149 $row = $this->validateProperty($row);
156 empty($row[
'USER_TYPE'])
157 ? $row[
'PROPERTY_TYPE']
158 : $row[
'PROPERTY_TYPE'] .
':' . $row[
'USER_TYPE']
161 $fieldType = $typesMap[$fullType] ??
null;
167 $id = $this->getPropertyId($row[
'ID']);
169 'type' => $fieldType,
170 'name' => $row[
'NAME'],
175 $field[
'partial'] =
true;
178 $row[
'USER_TYPE'] !==
''
181 $userType = $this->userTypeList[$row[
'USER_TYPE']];
182 if (isset($userType[
'GetUIFilterProperty']) && is_callable($userType[
'GetUIFilterProperty']))
184 call_user_func_array(
185 $userType[
'GetUIFilterProperty'],
192 if (empty($field) || !is_array($field))
196 $field[
'partial'] =
true;
200 $properties[$id] = $field;
202 $this->propertyList[$id] = $row;
204 unset($row, $iterator);
212 foreach ($rawFilterValue as $fieldId => $values)
214 $field = \CIBlock::MkOperationFilter($fieldId);
215 $id = $field[
'FIELD'];
218 $result[$fieldId] = $values;
220 elseif (isset($this->propertyList[$id]))
222 $prepareResult = $this->preparePropertyValues($id, $values);
225 $result[$fieldId] = $prepareResult;
227 unset($prepareResult);
234 private function preparePropertyValues(
string $propertyId, $values): mixed
237 $row = $this->propertyList[$propertyId];
238 if ($row[
'USER_TYPE'] ===
'')
244 $userType = $this->userTypeList[$row[
'USER_TYPE']] ??
null;
247 if (isset($userType[
'ConvertToDB']) && is_callable($userType[
'ConvertToDB']))
249 if (is_array($values))
252 foreach ($values as $item)
254 $prepareItem = $this->convertPropertyValueToDb(
255 $userType[
'ConvertToDB'],
261 $prepareValues[] = $prepareItem;
265 if (!empty($prepareValues))
267 $result = $prepareValues;
269 unset($prepareValues);
273 $prepareValue = $this->convertPropertyValueToDb(
274 $userType[
'ConvertToDB'],
280 $result = $prepareValue;
282 unset($prepareValue);
297 private function convertPropertyValueToDb(callable $function, array $property, $value): mixed
299 $result = call_user_func_array(
310 is_array($result) && isset($result[
'VALUE']) && (
string)$result[
'VALUE'] !==
''
313 return $result[
'VALUE'];
324 $result[0] =
Loc::getMessage(
'IBLOCK_FILTER_DATAPROVIDER_ELEMENT_FIELDS_SECTION_TOP_LEVEL');
326 $iterator = CIBlockSection::GetList(
328 'LEFT_MARGIN' =>
'ASC',
331 'IBLOCK_ID' => $this->iblockId,
332 'CHECK_PERMISSIONS' =>
'Y',
333 'MIN_PERMISSION' =>
'R',
344 while ($row = $iterator->Fetch())
346 $margin = max((
int)$row[
'DEPTH_LEVEL'], 1) - 1;
347 $result[$row[
'ID']] = str_repeat(
'.', $margin) . $row[
'NAME'];
349 unset($row, $iterator);
360 if (!isset($this->propertyList[$fieldId]))
364 $row = $this->propertyList[$fieldId];
368 && $row[
'USER_TYPE'] ===
''
377 $propertyId = $this->propertyList[$fieldId][
'ID'] ??
null;
380 return $this->getPropertyEnumValueListItems($propertyId);
386 private function getPropertyEnumValueListItems(
int $propertyId): array
389 $iterator = PropertyEnumerationTable::getList([
396 '=PROPERTY_ID' => $propertyId,
407 while ($row = $iterator->fetch())
409 $result[$row[
'ID']] = $row[
'VALUE'];
411 unset($row, $iterator);
416 private function getPropertyId(
string|
int $id): string
418 return self::PROPERTY_PREFIX . $id;
423 return (preg_match(self::PROPERTY_MASK, $id) === 1);
428 if (!isset($this->propertyList[$id]))
433 $row = $this->propertyList[$id];
436 if ($row[
'USER_TYPE'] ===
'')
438 switch ($row[
'PROPERTY_TYPE'])
442 'items' => $this->getPropertyEnumValueListItems($row[
'ID']),
444 if (count($description[
'items']) > 1)
446 $description[
'params'] = [
455 $userType = $this->userTypeList[$row[
'USER_TYPE']];
456 if (isset($userType[
'GetUIFilterProperty']) && is_callable($userType[
'GetUIFilterProperty']))
459 call_user_func_array(
460 $userType[
'GetUIFilterProperty'],
467 if (empty($description) || !is_array($description))
477 private function validateProperty(array $row): ?array
479 $row[
'ID'] = (int)$row[
'ID'];
480 $row[
'USER_TYPE'] = (string)$row[
'USER_TYPE'];
481 $row[
'USER_TYPE_SETTINGS'] = $row[
'USER_TYPE_SETTINGS_LIST'];
482 unset($row[
'USER_TYPE_SETTINGS_LIST']);
483 $row[
'FULL_PROPERTY_TYPE'] = $this->getFullPropertyType($row);
484 if ($row[
'USER_TYPE'] ===
'')
489 if (!isset($this->userTypeList))
491 $this->userTypeList = \CIBlockProperty::GetUserType();
493 $userTypeId = $row[
'USER_TYPE'];
494 if (!isset($this->userTypeList[$userTypeId]))
502 private function getFullPropertyType(array $row): string
505 $row[
'USER_TYPE'] ===
''
506 ? $row[
'PROPERTY_TYPE']
507 : $row[
'PROPERTY_TYPE'] .
':' . $row[
'USER_TYPE']
static getMessage($code, $replace=null, $language=null)
static getList(array $parameters=array())