• Модуль: lists
  • Путь к файлу: ~/bitrix/modules/lists/classes/general/lists.php
  • Класс: CLists
  • Вызов: CLists::checkChangedFields
static function checkChangedFields($iblockId, $elementId, array $select, array $elementFields, array $elementProperty)
{
	$changedFields = array();
	/* We get the new data element. */
	$elementNewData = array();
	$elementQuery = CIBlockElement::getList(
		array(), array('IBLOCK_ID' => $iblockId, '=ID' => $elementId), false, false, $select);
	$elementObject = $elementQuery->getNextElement();

	if(is_object($elementObject))
		$elementNewData = $elementObject->getFields();

	$elementOldData = $elementFields;
	unset($elementNewData["TIMESTAMP_X"]);
	unset($elementOldData["TIMESTAMP_X"]);

	$elementNewData["PROPERTY_VALUES"] = array();
	if(is_object($elementObject))
	{
		$propertyQuery = CIBlockElement::getProperty(
			$iblockId,
			$elementId,
			array("sort"=>"asc", "id"=>"asc", "enum_sort"=>"asc", "value_id"=>"asc"),
			array("ACTIVE"=>"Y", "EMPTY"=>"N")
		);
		while($property = $propertyQuery->fetch())
		{
			$propertyId = $property["ID"];
			if(!array_key_exists($propertyId, $elementNewData["PROPERTY_VALUES"]))
			{
				$elementNewData["PROPERTY_VALUES"][$propertyId] = $property;
				unset($elementNewData["PROPERTY_VALUES"][$propertyId]["DESCRIPTION"]);
				unset($elementNewData["PROPERTY_VALUES"][$propertyId]["VALUE_ENUM_ID"]);
				unset($elementNewData["PROPERTY_VALUES"][$propertyId]["VALUE_ENUM"]);
				unset($elementNewData["PROPERTY_VALUES"][$propertyId]["VALUE_XML_ID"]);
				$elementNewData["PROPERTY_VALUES"][$propertyId]["FULL_VALUES"] = array();
				$elementNewData["PROPERTY_VALUES"][$propertyId]["VALUES_LIST"] = array();
			}

			$elementNewData["PROPERTY_VALUES"][$propertyId]["FULL_VALUES"][$property["PROPERTY_VALUE_ID"]] = array(
				"VALUE" => $property["VALUE"],
				"DESCRIPTION" => $property["DESCRIPTION"],
			);
			$elementNewData["PROPERTY_VALUES"][$propertyId]["VALUES_LIST"][$property["PROPERTY_VALUE_ID"]] = $property["VALUE"];
		}
	}

	$elementOldData["PROPERTY_VALUES"] = $elementProperty;

	/* Check added or deleted fields. */
	$listNewFieldIdToDelete = array();
	$listOldFieldIdToDelete = array();
	$differences = array_diff_key($elementNewData, $elementOldData);
	foreach(array_keys($differences) as $fieldId)
	{
		if($fieldId[0] === '~')
			continue;
		$changedFields[] = $fieldId;
		$listNewFieldIdToDelete["FIELD"][] = $fieldId;
	}
	$differences = array_diff_key($elementOldData, $elementNewData);
	foreach(array_keys($differences) as $fieldId)
	{
		if($fieldId[0] === '~')
			continue;
		$changedFields[] = $fieldId;
		$listOldFieldIdToDelete["FIELD"][] = $fieldId;
	}

	$differences = array_diff_key(
		$elementNewData["PROPERTY_VALUES"],
		$elementOldData["PROPERTY_VALUES"]
	);
	foreach(array_keys($differences) as $fieldId)
	{
		$listNewFieldIdToDelete["PROPERTY"][] = $fieldId;

		if(!empty($elementNewData["PROPERTY_VALUES"][$fieldId]["CODE"]))
			$fieldId = "PROPERTY_".$elementNewData["PROPERTY_VALUES"][$fieldId]["CODE"];
		else
			$fieldId = "PROPERTY_".$fieldId;
		$changedFields[] = $fieldId;
	}
	$differences = array_diff_key(
		$elementOldData["PROPERTY_VALUES"],
		$elementNewData["PROPERTY_VALUES"]
	);
	foreach(array_keys($differences) as $fieldId)
	{
		$listOldFieldIdToDelete["PROPERTY"][] = $fieldId;

		if(!empty($elementOldData["PROPERTY_VALUES"][$fieldId]["CODE"]))
			$fieldId = "PROPERTY_".$elementOldData["PROPERTY_VALUES"][$fieldId]["CODE"];
		else
			$fieldId = "PROPERTY_".$fieldId;
		$changedFields[] = $fieldId;
	}

	foreach($listNewFieldIdToDelete as $typeField => $listField)
	{
		if($typeField == "FIELD")
			foreach($listField as $fieldId)
				unset($elementNewData[$fieldId]);
		elseif($typeField == "PROPERTY")
			foreach($listField as $fieldId)
				unset($elementNewData["PROPERTY_VALUES"][$fieldId]);
	}
	foreach($listOldFieldIdToDelete as $typeField => $listField)
	{
		if($typeField == "FIELD")
			foreach($listField as $fieldId)
				unset($elementOldData[$fieldId]);
		elseif($typeField == "PROPERTY")
			foreach($listField as $fieldId)
				unset($elementOldData["PROPERTY_VALUES"][$fieldId]);
	}

	/* Preparing arrays to compare */
	$listObject = new CList($iblockId);
	foreach($elementNewData as $fieldId => $fieldValue)
	{
		if(!$listObject->is_field($fieldId) && $fieldId != "PROPERTY_VALUES")
		{
			unset($elementNewData[$fieldId]);
		}
		elseif($fieldId == "PROPERTY_VALUES")
		{
			foreach($fieldValue as $propertyId => $propertyData)
			{
				if(!empty($propertyData["CODE"]))
					$elementNewData["PROPERTY_".$propertyData["CODE"]] = $propertyData["VALUES_LIST"];
				else
					$elementNewData["PROPERTY_".$propertyData["ID"]] = $propertyData["VALUES_LIST"];

				unset($elementNewData["PROPERTY_VALUES"][$propertyId]);
			}
			unset($elementNewData["PROPERTY_VALUES"]);
		}
	}
	foreach($elementOldData as $fieldId => $fieldValue)
	{
		if(!$listObject->is_field($fieldId) && $fieldId != "PROPERTY_VALUES")
		{
			unset($elementOldData[$fieldId]);
		}
		elseif($fieldId == "PROPERTY_VALUES")
		{
			foreach($fieldValue as $propertyId => $propertyData)
			{
				if(!empty($propertyData["CODE"]))
					$elementOldData["PROPERTY_".$propertyData["CODE"]] = $propertyData["VALUES_LIST"];
				else
					$elementOldData["PROPERTY_".$propertyData["ID"]] = $propertyData["VALUES_LIST"];

				unset($elementOldData["PROPERTY_VALUES"][$propertyId]);
			}
			unset($elementOldData["PROPERTY_VALUES"]);
		}
	}

	/* Compares the value */
	foreach($elementNewData as $fieldName => $fieldValue)
	{
		if(is_array($fieldValue))
		{
			if(is_array(current($fieldValue)))
			{
				$firstValues = array();
				$secondValues = array();
				foreach ($fieldValue as $values)
				{
					$firstValues = is_array($values) ? $values : [$values];
				}
				foreach ($elementOldData[$fieldName] as $values)
				{
					$secondValues = is_array($values) ? $values : [$values];
				}

				if(array_key_exists("TEXT", $firstValues))
				{
					$differences = array_diff($firstValues, $secondValues);
					if(!empty($differences))
						$changedFields[] = $fieldName;
				}
				else
				{
					if(count($firstValues) != count($secondValues))
						$changedFields[] = $fieldName;
				}
			}
			else
			{
				$differences = array_diff($fieldValue, $elementOldData[$fieldName]);
				if(!empty($differences))
					$changedFields[] = $fieldName;
			}
		}
		else
		{
			if(strcmp((string)$fieldValue, (string)$elementOldData[$fieldName]) !== 0)
				$changedFields[] = $fieldName;
		}
	}

	return $changedFields;
}