• Модуль: iblock
  • Путь к файлу: ~/bitrix/modules/iblock/classes/general/iblockelement.php
  • Класс: CAllIBlockElement
  • Вызов: CAllIBlockElement::GetPropertyValuesArray
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);
	}
}