/ Bitrix: Отслеживание изменения свойств элемента инфоблока при помощи обработчика событий

Bitrix: Отслеживание изменения свойств элемента инфоблока при помощи обработчика событий

21 Июл 2020
Дмитрий М.
840

Допустим элемент инфоблока является товаров, у этого элемента инфоблока есть свойство PRICE, в котором хранится значение цены товара. Соответственно при обновлении этого свойства PRICE необходимо автоматически обновлять цену товара (цену которая находится на вкладке Торговый каталог).

При изменении элементов инфоблока вызываются события:

  • OnBeforeIBlockElementUpdate - событие, которое вызывается перед изменением элемента.
  • OnStartIBlockElementUpdate - событие, которое вызывается в момент начала изменения элемента.
  • OnBeforeIBlockElementUpdate - событие, которое вызывается после изменения элемента.

В нашем случаи воспользуемся событием OnBeforeIBlockElementUpdate. Цену будем обновлять при помощи способа указанно в статье об обновлении цен при помощи метода CPrice::Update;

Полученный обработчик событий необходимо прописать в файле init.php

Файл init.php храниться в папке /bitrix/php_interface/ или /local/php_interface/ если его там нет, нужно создать
AddEventHandler("iblock", "OnBeforeIBlockElementUpdate", "UpdateProductPrice");

function UpdateProductPrice($arFields){
	$IBLOCK_ID = 1; // Указываем ID инфоблока для элементов которого нужно выполнять действия
	if ($arFields['IBLOCK_ID'] == $IBLOCK_ID && !empty($arFields['PROPERTY_VALUE']['PRICE']['VALUE']) && is_numeric($arFields['PROPERTY_VALUE']['PRICE']['VALUE'])){
		$price = $arFields['PROPERTY_VALUE']['PRICE']['VALUE'];
		$id = $arFields['ID'];
		$rsFields = Array(
			"PRODUCT_ID" => $id,
			"CATALOG_GROUP_ID" => 1, // Указываем ID цены, можно посмотреть в админке: Магазин - Настройки - Типы цен
			"PRICE" => (int)$price,
			"CURRENCY" => "RUB",
			"QUANTITY_FROM" => false,
			"QUANTITY_TO" => false
		);
		// Добавляем для элемента параметры товара
		CCatalogProduct::Add(
			array(
				"ID" => $id,
				"QUANTITY" => 9999
			)
		);
		//Получаем цены товара ( в том случаи если уже есть цена у товара ), если нет, тогда добавляем сразу цену.
		$res = CPrice::GetList(
			array(),
			array(
				"PRODUCT_ID" => $id,
				"CATALOG_GROUP_ID" => 1
			)
		);
		if ($arr = $res->Fetch())
		{
			CPrice::Update($arr["ID"], $rsFields);
		}
		else
		{
			CPrice::Add($rsFields);
		}
	}
}

Однако если обновление свойства PRICE осуществляется не при помощи метода CIBlockElement::Update(), а при помощи методов: CIBlockElement::SetPropertyValues, CIBlockElement::SetPropertyValueCode, CIBlockElement::SetPropertyValuesEx - указанные выше обработчики использовать не получится, так как для этих методов работаю свои обработчики событий:

Метод Обработчик события
CIBlockElement::SetPropertyValues
  • OnIBlockElementSetPropertyValues
  • OnAfterIBlockElementSetPropertyValues
CIBlockElement::SetPropertyValuesEx
  • OnIBlockElementSetPropertyValuesEx
  • OnAfterIBlockElementSetPropertyValuesEx

В таком случаи необходимо переписать обработчик события на актуальные события в зависимости от метода изменения свойств элемента.

Допустим свойство изменяется при помощи метода CIBlockElement::SetPropertyValues, тогда код будет выглядеть следующим образом:

AddEventHandler("iblock", "OnAfterIBlockElementSetPropertyValues", "UpdateProductPrice");

function UpdateProductPrice($ELEMENT_ID, $IBLOCK_ID, $PROPERTY_VALUES, $PROPERTY_CODE){
	$iblockID = 1; // Указываем ID инфоблока для элементов которого нужно выполнять действия
	if ($IBLOCK_ID == $iblockID && $PROPERTY_CODE == 'PRICE' && !empty($PROPERTY_VALUE) && is_numeric($PROPERTY_VALUE)){
		$price = $PROPERTY_VALUE;
		$id = $ELEMENT_ID;
		$rsFields = Array(
			"PRODUCT_ID" => $id,
			"CATALOG_GROUP_ID" => 1, // Указываем ID цены, можно посмотреть в админке: Магазин - Настройки - Типы цен
			"PRICE" => (int)$price,
			"CURRENCY" => "RUB",
			"QUANTITY_FROM" => false,
			"QUANTITY_TO" => false
		);
		// Добавляем для элемента параметры товара
		CCatalogProduct::Add(
			array(
				"ID" => $id,
				"QUANTITY" => 9999
			)
		);
		//Получаем цены товара ( в том случаи если уже есть цена у товара ), если нет, тогда добавляем сразу цену.
		$res = CPrice::GetList(
			array(),
			array(
				"PRODUCT_ID" => $id,
				"CATALOG_GROUP_ID" => 1
			)
		);
		if ($arr = $res->Fetch())
		{
			CPrice::Update($arr["ID"], $rsFields);
		}
		else
		{
			CPrice::Add($rsFields);
		}
	}
}

Статья была полезна? Поблагодарите автора.

Самые читаемые
#1С Битрикс, #Bitrix CMS, #.htaccess, #настройка редиректов
4 Авг 2019
#Хлебные крошки, #1С Битрикс, #Bitrix CMS, #bitrix:breadcrumbs, #component_epilog, #кэширование
1 Окт 2018
#bitrix, #bitrix:catalog.section, #скидки, #товары со скидкой, #страница скидок, #страница со скидками
4 Окт 2018
#bitrix, #robots.txt, #sitemap.xml, #поддомены, #мультисайтовость
16 Окт 2018
#ресайз изображений, #1С Битрикс, #Bitrix CMS
3 Мар 2019
#bitrix, #пользовательские свойства, #тип свойств, #привязка к элементам
27 Ноя 2019
#Bitrix CMS, #breadcrumb, #bitrix:breadcrumbs, #хлебные крошки, #настройка
13 Фев 2019
#bitrix, #свойства элементов, #обработчик событий, #OnBeforeIBlockElementUpdate, #OnIBlockElementSetPropertyValues
21 Июл 2020