Дата последнего изменения: 10.11.2023
Допустим, что у нас имеются связанные инфоблоки и поставлена следующая задача: необходимо в специальном поле элемента инфоблока получить сумму значений полей связанных элементов.
Решение возможно как с использованием модуля Интернет-магазин, так и без него. При использовании интернет-магазина все инфоблоки должны иметь свойства торгового каталога с указанием цены в соответствующих полях. Если используется редакция без интернет-магазина, то все поля исходных инфоблоков должны иметь тип число и (в рамках данного решения) иметь код PRICE.
Пусть поле результирующего инфоблока называется COST. Его тип должен быть - число. В поле "Значение по умолчанию" параметра COST должно быть внесено выражение типа:
Код ниже приведен для вывода результата в компоненте catalog.section. Для вывода результатов в другом компоненте требуется модификация кода. Приведенный код вносится в файл result_modifer.php указанного компонента:
<? //Эту строчку можно раскомментировать и посмотреть содержимое arResult //того компонента под который будет адаптирован этот модификатор //echo "<pre>",htmlspecialchars(print_r($arResult, 1)),"</pre>"; //Символьный код свойства значение по умолчанию которого содержит выражения //результат вычисления будет показан шаблоном компонента //Само выражение представляет собой исполняемый eval'ом PHP код //в котором по шаблонам вида {<СИМВОЛЬНЫЙ КОД СВОЙСТВА>} будут подставлены конкретные значения //Эти свойства должны быть выбраны в настройках компонента и доступны через arResult //в противном случае надо воспользоваться функцией CIBlockElement::GetProperty для доступа к БД //Эти свойства должны быть НЕ множественными //Пример выражения: "({PROP_1_PRICE} + {PROP_2_PRICE}) * {PROP_COUNTER}" //Обратите внимание на _PRICE - это указание на необходимость выборки цены привязанного элемента! //Само свойство должно иметь символьный код PROP_1 и PROP_2 соответственно $CALCULATOR_CODE="COST"; //ИД цены которая будет браться для вычислений $PRICE_ID = 1; //Идентификатор инфоблока (для разных компонент надо брать разные поля arResult) $IBLOCK_ID = $arResult["IBLOCK_ID"]; //Получаем метаданные свойства "Калькулятора" $arProperty = CIBlockProperty::GetPropertyArray($CALCULATOR_CODE, $IBLOCK_ID); //Если такое свойство есть и у него задано выражение для вычислений: if($arProperty && strlen($arProperty["DEFAULT_VALUE"]) > 0) { //Цикл по всем элементам каталога foreach($arResult["ITEMS"] as $i => $arElement) { //Берем выражение "Калькулятора" $EQUATION = $arProperty["DEFAULT_VALUE"]; //Проверим надо ли выполнять подстановку шаблонов if(preg_match_all("/(\\{.*?\\})/", $EQUATION, $arMatch)) { //Цикл по всем использованным в выражении свойствам $arPropCodes = array(); foreach($arMatch[0] as $equation_code) { //Это "цена" и она потребует больших усилий $bPrice = substr($equation_code, -7)=="_PRICE}"; //Символьный код свойства значение которого будет подставлено в выражение $property_code = ($bPrice? substr($equation_code, 1, -7): substr($equation_code, 1, -1)); if($bPrice) { //Находим связанный элемент $rsLinkedElement = CIBlockElement::GetList( array(), array( "=ID" => $arElement["PROPERTIES"][$property_code]["~VALUE"], "IBLOCK_ID" => $arElement["PROPERTIES"][$property_code]["~LINK_IBLOCK_ID"] ), false, false, array( "ID", "IBLOCK_ID", "CATALOG_GROUP_".$PRICE_ID, "PROPERTY_PRICE" ) ); $arLinkedElement = $rsLinkedElement->Fetch(); //Забираем его цену if($arLinkedElement["CATALOG_PRICE_".$PRICE_ID]) $value = doubleval($arLinkedElement["CATALOG_PRICE_".$PRICE_ID]); else $value = doubleval($arLinkedElement["PROPERTY_PRICE_VALUE"]); } else { //Если вам потребуются не только числа, но и строки //избавьтесь от doubleval и добавьте экранирование строковых символов $value = doubleval($arElement["PROPERTIES"][$property_code]["~VALUE"]); } //Подстановка значения $EQUATION = str_replace($equation_code, $value, $EQUATION); } } //Собственно вычисление $VALUE = @eval("return ".$EQUATION.";"); //и сохрание его результата для показа в шаблоне $arResult["ITEMS"][$i]["DISPLAY_PROPERTIES"][$CALCULATOR_CODE] = $arResult["ITEMS"][$i]["PROPERTIES"][$CALCULATOR_CODE]; $arResult["ITEMS"][$i]["DISPLAY_PROPERTIES"][$CALCULATOR_CODE]["DISPLAY_VALUE"] = htmlspecialchars($VALUE); } } ?>