static function GetPropertyValuesArray(&$result, $iblockID, $filter, $propertyFilter = array(), $options = array())
{
$iblockExtVersion = (CIBlockElement::GetIBVersion($iblockID) == 2);
$propertiesList = array();
$shortProperties = array();
$userTypesList = array();
$selectListMultiply = array('SORT' => SORT_ASC, 'VALUE' => SORT_STRING);
$selectAllMultiply = array('PROPERTY_VALUE_ID' => SORT_ASC);
$selectFields = array(
'ID', 'IBLOCK_ID', 'NAME', 'ACTIVE', 'SORT', 'CODE', 'DEFAULT_VALUE', 'PROPERTY_TYPE', 'ROW_COUNT', 'COL_COUNT', 'LIST_TYPE',
'MULTIPLE', 'XML_ID', 'FILE_TYPE', 'MULTIPLE_CNT', 'LINK_IBLOCK_ID', 'WITH_DESCRIPTION', 'SEARCHABLE', 'FILTRABLE',
'IS_REQUIRED', 'VERSION', 'USER_TYPE', 'USER_TYPE_SETTINGS', 'HINT'
);
if (!is_array($options))
$options = array();
$usePropertyId = (isset($options['USE_PROPERTY_ID']) && $options['USE_PROPERTY_ID'] == 'Y');
$getRawData = (isset($options['GET_RAW_DATA']) && $options['GET_RAW_DATA'] == 'Y');
$propertyFieldList = array();
if (!empty($options['PROPERTY_FIELDS']) && is_array($options['PROPERTY_FIELDS']))
$propertyFieldList = array_intersect($options['PROPERTY_FIELDS'], $selectFields);
if (!empty($propertyFieldList))
{
if (!in_array('ID', $propertyFieldList))
$propertyFieldList[] = 'ID';
if (!$getRawData)
{
if (in_array('NAME', $propertyFieldList))
$propertyFieldList[] = '~NAME';
if (in_array('DEFAULT_VALUE', $propertyFieldList))
$propertyFieldList[] = '~DEFAULT_VALUE';
}
$propertyFieldList = array_fill_keys($propertyFieldList, true);
}
$propertyListFilter = array(
'IBLOCK_ID' => $iblockID
);
$propertyID = array();
if (isset($propertyFilter['ID']))
{
$propertyID = (is_array($propertyFilter['ID']) ? $propertyFilter['ID'] : array($propertyFilter['ID']));
MainTypeCollection::normalizeArrayValuesByInt($propertyID, true);
}
if (!empty($propertyID))
{
$propertyListFilter['@ID'] = $propertyID;
}
elseif (isset($propertyFilter['CODE']))
{
if (!is_array($propertyFilter['CODE']))
$propertyFilter['CODE'] = array($propertyFilter['CODE']);
$propertyCodes = array();
if (!empty($propertyFilter['CODE']))
{
foreach ($propertyFilter['CODE'] as &$code)
{
$code = (string)$code;
if ($code !== '')
$propertyCodes[] = $code;
}
unset($code);
}
if (!empty($propertyCodes))
$propertyListFilter['@CODE'] = $propertyCodes;
unset($propertyCodes);
}
$propertyListFilter['=ACTIVE'] = (
isset($propertyFilter['ACTIVE']) && ($propertyFilter['ACTIVE'] == 'Y' || $propertyFilter['ACTIVE'] == 'N')
? $propertyFilter['ACTIVE']
: 'Y'
);
$propertyID = array();
$propertyIterator = IblockPropertyTable::getList(array(
'select' => $selectFields,
'filter' => $propertyListFilter,
'order' => array('SORT'=>'ASC', 'ID'=>'ASC'),
'cache' => array(
'ttl' => 86400,
),
));
while ($property = $propertyIterator->fetch())
{
$propertyID[] = (int)$property['ID'];
$property['CODE'] = trim((string)$property['CODE']);
if ($property['CODE'] === '')
$property['CODE'] = $property['ID'];
$code = ($usePropertyId ? $property['ID'] : $property['CODE']);
if (!$getRawData)
{
$property['~NAME'] = $property['NAME'];
if (preg_match("/[;&<>"]/", $property['NAME']))
$property['NAME'] = htmlspecialcharsEx($property['NAME']);
}
if ($property['USER_TYPE'])
{
$userType = CIBlockProperty::GetUserType($property['USER_TYPE']);
if (isset($userType['ConvertFromDB']))
{
$userTypesList[$property['ID']] = $userType;
if (array_key_exists('DEFAULT_VALUE', $property))
{
$value = [
'VALUE' => $property['DEFAULT_VALUE'],
'DESCRIPTION' => '',
];
$value = call_user_func_array(
$userType['ConvertFromDB'],
[$property, $value]
);
$property['DEFAULT_VALUE'] = $value['VALUE'] ?? '';
}
}
}
if (!empty($property['USER_TYPE_SETTINGS']))
{
$property['USER_TYPE_SETTINGS'] = unserialize($property['USER_TYPE_SETTINGS'], ['allowed_classes' => false]);
}
if (!$getRawData)
{
$property['~DEFAULT_VALUE'] = $property['DEFAULT_VALUE'] ?? null;
if (
isset($property['DEFAULT_VALUE'])
&& (
is_array($property['DEFAULT_VALUE'])
|| preg_match("/[;&<>"]/", $property['DEFAULT_VALUE'])
)
)
{
$property['DEFAULT_VALUE'] = htmlspecialcharsEx($property['DEFAULT_VALUE']);
}
}
$propertiesList[$code] = $property;
$shortProperties[$code] = (!empty($propertyFieldList)
? array_intersect_key($property, $propertyFieldList)
: $property
);
}
unset($property, $propertyIterator);
if (empty($propertiesList))
return;
$enumList = array();
$emptyResult = empty($result);
$valuesRes = (
!empty($propertyID)
? CIBlockElement::GetPropertyValues($iblockID, $filter, true, array('ID' => $propertyID))
: CIBlockElement::GetPropertyValues($iblockID, $filter, true)
);
while ($value = $valuesRes->Fetch())
{
$elementID = (int)$value['IBLOCK_ELEMENT_ID'];
if (!isset($result[$elementID]))
{
if ($emptyResult)
{
$result[$elementID] = [];
}
else
{
continue;
}
}
$elementValues = array();
$existDescription = isset($value['DESCRIPTION']);
foreach ($propertiesList as $code => $property)
{
$existElementDescription = isset($value['DESCRIPTION']) && array_key_exists($property['ID'], $value['DESCRIPTION']);
$existElementPropertyID = isset($value['PROPERTY_VALUE_ID']) && array_key_exists($property['ID'], $value['PROPERTY_VALUE_ID']);
$elementValues[$code] = $shortProperties[$code];
$elementValues[$code]['VALUE_ENUM'] = null;
$elementValues[$code]['VALUE_XML_ID'] = null;
$elementValues[$code]['VALUE_SORT'] = null;
$elementValues[$code]['VALUE'] = null;
if ('Y' === $property['MULTIPLE'])
{
$elementValues[$code]['PROPERTY_VALUE_ID'] = false;
if (!isset($value[$property['ID']]) || empty($value[$property['ID']]))
{
$elementValues[$code]['DESCRIPTION'] = false;
$elementValues[$code]['VALUE'] = false;
if (!$getRawData)
{
$elementValues[$code]['~DESCRIPTION'] = false;
$elementValues[$code]['~VALUE'] = false;
}
if ($property['PROPERTY_TYPE'] == IblockPropertyTable::TYPE_LIST)
{
$elementValues[$code]['VALUE_ENUM_ID'] = false;
$elementValues[$code]['VALUE_ENUM'] = false;
$elementValues[$code]['VALUE_XML_ID'] = false;
$elementValues[$code]['VALUE_SORT'] = false;
}
}
else
{
if ($existElementPropertyID)
{
$elementValues[$code]['PROPERTY_VALUE_ID'] = $value['PROPERTY_VALUE_ID'][$property['ID']];
}
if (isset($userTypesList[$property['ID']]))
{
foreach ($value[$property['ID']] as $valueKey => $oneValue)
{
$raw = call_user_func_array(
$userTypesList[$property['ID']]['ConvertFromDB'],
array(
$property,
array(
'VALUE' => $oneValue,
'DESCRIPTION' => ($existElementDescription ? $value['DESCRIPTION'][$property['ID']][$valueKey] : null),
)
)
);
$value[$property['ID']][$valueKey] = $raw['VALUE'] ?? null;
if (!$existDescription)
{
$value['DESCRIPTION'] = array();
$existDescription = true;
}
if (!$existElementDescription)
{
$value['DESCRIPTION'][$property['ID']] = array();
$existElementDescription = true;
}
$value['DESCRIPTION'][$property['ID']][$valueKey] = (string)$raw['DESCRIPTION'];
}
if (isset($oneValue))
unset($oneValue);
}
if ($property['PROPERTY_TYPE'] == IblockPropertyTable::TYPE_LIST)
{
if (empty($value[$property['ID']]))
{
$elementValues[$code]['VALUE_ENUM_ID'] = $value[$property['ID']];
$elementValues[$code]['DESCRIPTION'] = ($existElementDescription ? $value['DESCRIPTION'][$property['ID']] : array());
}
else
{
$selectedValues = array();
foreach ($value[$property['ID']] as $listKey => $listValue)
{
if (!isset($enumList[$property['ID']][$listValue]))
{
if (!isset($enumList[$property['ID']]))
$enumList[$property['ID']] = [];
$enumList[$property['ID']][$listValue] = false;
$enumIterator = IblockPropertyEnumerationTable::getList(array(
'select' => array('ID', 'VALUE', 'SORT', 'XML_ID'),
'filter' => array('=ID' => $listValue, '=PROPERTY_ID' => $property['ID'])
));
$row = $enumIterator->fetch();
unset($enumIterator);
if (!empty($row))
{
$enumList[$property['ID']][$listValue] = array(
'ID' => $row['ID'],
'VALUE' => $row['VALUE'],
'SORT' => $row['SORT'],
'XML_ID' => $row['XML_ID']
);
}
unset($row);
}
if (!empty($enumList[$property['ID']][$listValue]))
{
$selectedValues[$listKey] = $enumList[$property['ID']][$listValue];
$selectedValues[$listKey]['DESCRIPTION'] = (
$existElementDescription && array_key_exists($listKey, $value['DESCRIPTION'][$property['ID']])
? $value['DESCRIPTION'][$property['ID']][$listKey]
: null
);
$selectedValues[$listKey]['PROPERTY_VALUE_ID'] = (
$existElementPropertyID && array_key_exists($listKey, $value['PROPERTY_VALUE_ID'][$property['ID']])
? $value['PROPERTY_VALUE_ID'][$property['ID']][$listKey]
: null
);
}
}
if (empty($selectedValues))
{
$elementValues[$code]['VALUE_ENUM_ID'] = $value[$property['ID']];
$elementValues[$code]['DESCRIPTION'] = ($existElementDescription ? $value['DESCRIPTION'][$property['ID']] : array());
}
else
{
MainTypeCollection::sortByColumn($selectedValues, $selectListMultiply);
$elementValues[$code]['VALUE_SORT'] = array();
$elementValues[$code]['VALUE_ENUM_ID'] = array();
$elementValues[$code]['VALUE'] = array();
$elementValues[$code]['VALUE_ENUM'] = array();
$elementValues[$code]['VALUE_XML_ID'] = array();
$elementValues[$code]['DESCRIPTION'] = array();
$elementValues[$code]['PROPERTY_VALUE_ID'] = array();
foreach ($selectedValues as $listValue)
{
$elementValues[$code]['VALUE_SORT'][] = $listValue['SORT'];
$elementValues[$code]['VALUE_ENUM_ID'][] = $listValue['ID'];
$elementValues[$code]['VALUE'][] = $listValue['VALUE'];
$elementValues[$code]['VALUE_ENUM'][] = $listValue['VALUE'];
$elementValues[$code]['VALUE_XML_ID'][] = $listValue['XML_ID'];
$elementValues[$code]['PROPERTY_VALUE_ID'][] = $listValue['PROPERTY_VALUE_ID'];
$elementValues[$code]['DESCRIPTION'][] = $listValue['DESCRIPTION'];
}
unset($selectedValues);
}
}
}
else
{
if (empty($value[$property['ID']]) || !$existElementPropertyID || isset($userTypesList[$property['ID']]))
{
$elementValues[$code]['VALUE'] = $value[$property['ID']];
$elementValues[$code]['DESCRIPTION'] = ($existElementDescription ? $value['DESCRIPTION'][$property['ID']] : array());
}
else
{
$selectedValues = array();
foreach ($value['PROPERTY_VALUE_ID'][$property['ID']] as $propKey => $propValueID)
{
$selectedValues[$propKey] = array(
'PROPERTY_VALUE_ID' => $propValueID,
'VALUE' => $value[$property['ID']][$propKey],
);
if ($existElementDescription)
{
$selectedValues[$propKey]['DESCRIPTION'] = $value['DESCRIPTION'][$property['ID']][$propKey];
}
}
unset($propValueID, $propKey);
MainTypeCollection::sortByColumn($selectedValues, $selectAllMultiply);
$elementValues[$code]['PROPERTY_VALUE_ID'] = array();
$elementValues[$code]['VALUE'] = array();
$elementValues[$code]['DESCRIPTION'] = array();
foreach ($selectedValues as &$propValue)
{
$elementValues[$code]['PROPERTY_VALUE_ID'][] = $propValue['PROPERTY_VALUE_ID'];
$elementValues[$code]['VALUE'][] = $propValue['VALUE'];
if ($existElementDescription)
{
$elementValues[$code]['DESCRIPTION'][] = $propValue['DESCRIPTION'];
}
}
unset($propValue, $selectedValues);
}
}
}
if (!$getRawData)
{
$elementValues[$code]['~VALUE'] = $elementValues[$code]['VALUE'];
if (is_array($elementValues[$code]['VALUE']))
{
foreach ($elementValues[$code]['VALUE'] as &$oneValue)
{
$isArr = is_array($oneValue);
if ($isArr || ('' !== $oneValue && null !== $oneValue))
{
if ($isArr || preg_match("/[;&<>"]/", $oneValue))
{
$oneValue = htmlspecialcharsEx($oneValue);
}
}
}
if (isset($oneValue))
unset($oneValue);
}
else
{
if ('' !== $elementValues[$code]['VALUE'] && null !== $elementValues[$code]['VALUE'])
{
if (preg_match("/[;&<>"]/", $elementValues[$code]['VALUE']))
{
$elementValues[$code]['VALUE'] = htmlspecialcharsEx($elementValues[$code]['VALUE']);
}
}
}
$elementValues[$code]['~DESCRIPTION'] = $elementValues[$code]['DESCRIPTION'];
if (is_array($elementValues[$code]['DESCRIPTION']))
{
foreach ($elementValues[$code]['DESCRIPTION'] as &$oneDescr)
{
$isArr = is_array($oneDescr);
if ($isArr || (!$isArr && '' !== $oneDescr && null !== $oneDescr))
{
if ($isArr || preg_match("/[;&<>"]/", $oneDescr))
{
$oneDescr = htmlspecialcharsEx($oneDescr);
}
}
}
if (isset($oneDescr))
unset($oneDescr);
}
else
{
if ('' !== $elementValues[$code]['DESCRIPTION'] && null !== $elementValues[$code]['DESCRIPTION'])
{
if (preg_match("/[;&<>"]/", $elementValues[$code]['DESCRIPTION']))
{
$elementValues[$code]['DESCRIPTION'] = htmlspecialcharsEx($elementValues[$code]['DESCRIPTION']);
}
}
}
}
}
else
{
$elementValues[$code]['VALUE_ENUM'] = ($iblockExtVersion ? '' : null);
$elementValues[$code]['PROPERTY_VALUE_ID'] = ($iblockExtVersion ? $elementID.':'.$property['ID'] : null);
if (!isset($value[$property['ID']]) || false === $value[$property['ID']])
{
$elementValues[$code]['DESCRIPTION'] = '';
$elementValues[$code]['VALUE'] = '';
if (!$getRawData)
{
$elementValues[$code]['~DESCRIPTION'] = '';
$elementValues[$code]['~VALUE'] = '';
}
if ($property['PROPERTY_TYPE'] == IblockPropertyTable::TYPE_LIST)
{
$elementValues[$code]['VALUE_ENUM_ID'] = null;
}
}
else
{
if ($existElementPropertyID)
{
$elementValues[$code]['PROPERTY_VALUE_ID'] = $value['PROPERTY_VALUE_ID'][$property['ID']];
}
if (isset($userTypesList[$property['ID']]))
{
$raw = call_user_func_array(
$userTypesList[$property['ID']]['ConvertFromDB'],
array(
$property,
array(
'VALUE' => $value[$property['ID']],
'DESCRIPTION' => ($existElementDescription ? $value['DESCRIPTION'][$property['ID']] : null)
)
)
);
$value[$property['ID']] = $raw['VALUE'] ?? null;
if (!$existDescription)
{
$value['DESCRIPTION'] = array();
$existDescription = true;
}
$value['DESCRIPTION'][$property['ID']] = (string)($raw['DESCRIPTION'] ?? null);
$existElementDescription = true;
}
if ($property['PROPERTY_TYPE'] == IblockPropertyTable::TYPE_LIST)
{
$elementValues[$code]['VALUE_ENUM_ID'] = $value[$property['ID']];
if (!isset($enumList[$property['ID']][$value[$property['ID']]]))
{
if (!isset($enumList[$property['ID']]))
$enumList[$property['ID']] = [];
$enumList[$property['ID']][$value[$property['ID']]] = false;
$enumIterator = IblockPropertyEnumerationTable::getList(array(
'select' => array('ID', 'VALUE', 'SORT', 'XML_ID'),
'filter' => array('=ID' => $value[$property['ID']], '=PROPERTY_ID' => $property['ID'])
));
$row = $enumIterator->fetch();
unset($enumIterator);
if (!empty($row))
{
$enumList[$property['ID']][$value[$property['ID']]] = array(
'ID' => $row['ID'],
'VALUE' => $row['VALUE'],
'SORT' => $row['SORT'],
'XML_ID' => $row['XML_ID']
);
}
unset($row);
}
if (!empty($enumList[$property['ID']][$value[$property['ID']]]))
{
$elementValues[$code]['VALUE'] = $enumList[$property['ID']][$value[$property['ID']]]['VALUE'];
$elementValues[$code]['VALUE_ENUM'] = $elementValues[$code]['VALUE'];
$elementValues[$code]['VALUE_XML_ID'] = $enumList[$property['ID']][$value[$property['ID']]]['XML_ID'];
$elementValues[$code]['VALUE_SORT'] = $enumList[$property['ID']][$value[$property['ID']]]['SORT'];
}
$elementValues[$code]['DESCRIPTION'] = ($existElementDescription ? $value['DESCRIPTION'][$property['ID']] : null);
}
else
{
$elementValues[$code]['VALUE'] = $value[$property['ID']];
$elementValues[$code]['DESCRIPTION'] = ($existElementDescription ? $value['DESCRIPTION'][$property['ID']] : null);
}
}
if (!$getRawData)
{
$elementValues[$code]['~VALUE'] = $elementValues[$code]['VALUE'];
$isArr = is_array($elementValues[$code]['VALUE']);
if ($isArr || ('' !== $elementValues[$code]['VALUE'] && null !== $elementValues[$code]['VALUE']))
{
if ($isArr || preg_match("/[;&<>"]/", $elementValues[$code]['VALUE']))
{
$elementValues[$code]['VALUE'] = htmlspecialcharsEx($elementValues[$code]['VALUE']);
}
}
$elementValues[$code]['~DESCRIPTION'] = $elementValues[$code]['DESCRIPTION'];
$isArr = is_array($elementValues[$code]['DESCRIPTION']);
if ($isArr || ('' !== $elementValues[$code]['DESCRIPTION'] && null !== $elementValues[$code]['DESCRIPTION']))
{
if ($isArr || preg_match("/[;&<>"]/", $elementValues[$code]['DESCRIPTION']))
$elementValues[$code]['DESCRIPTION'] = htmlspecialcharsEx($elementValues[$code]['DESCRIPTION']);
}
}
}
}
if (isset($result[$elementID]['PROPERTIES']))
{
$result[$elementID]['PROPERTIES'] = $elementValues;
}
else
{
$result[$elementID] = $elementValues;
}
unset($elementValues);
}
}