Views: 9444
Last Modified: 19.01.2024

Let us assume that we have related infoblocks and we face the following task: to obtain a sum of field values of related elements in a specific field of an infoblock element.

Solution is possible both with using the module e-Store or without it. If the e-Store module is used, all of the infoblocks must have properties of a trade catalog with an indication of the price in the appropriate fields. If the version without the e-Store module is used, all of the fields of the source infoblocks must have the number type and (as a part of this solution) have the PRICE code.

Let us assume that the resulting infoblock is called COST. It must have the number type. The following expression must be entered in the field “Default values” of the COST parameter:

  • {PROP_1_PRICE}+{PROP_2_PRICE}+... - for versions without e-Store.
  • {PROP_1} + {PROP_2}+... - for versions with e-Store.

The code below is provided to obtain results in the component catalog.section. Code modification is required in order to display results in another component. The code provided shall be entered in the file result_modifer.php of the indicated component:

<?
//This string can be uncommented and see the contents arResult
//of the component for which this modifier is to be adapted

//echo "<pre>",htmlspecialchars(print_r($arResult, 1)),"</pre>";


//The symbol code of a property with a default value containing expressions
//the calculation result will be displayed by the component template
//The expression itself represents a PHP code executable by eval
//in which specific values will be substituted to the templates of the type {}
//These properties must be selected in the component settings and available through arResult
//otherwise, the function CIBlockElement::GetProperty must be used to access the database
//These properties must NOT be multiple
//Example of the expression: "({PROP_1_PRICE} + {PROP_2_PRICE}) * {PROP_COUNTER}"
//Please pay attention to the _PRICE – it is an indication that the price of a related element must be selected! 
//The property itself must have a symbol code PROP_1 and PROP_2, accordingly


$CALCULATOR_CODE="COST";
//ID of the price that will be retrieved for calculations
$PRICE_ID = 1;
//Infoblock identifier (for different components different fields of arResult must be chosen)
$IBLOCK_ID = $arResult["IBLOCK_ID"];
//We obtain metadata of the “Calculator” property (COST)
$arProperty = CIBlockProperty::GetPropertyArray($CALCULATOR_CODE, $IBLOCK_ID);
//If there is such property and the expression for calculation is set:
if($arProperty && strlen($arProperty["DEFAULT_VALUE"]) > 0)
{
   //The cycle for all the elements of the catalog
   foreach($arResult["ITEMS"] as $i => $arElement)
   {
      //We take the “Calculator”’s expression
      $EQUATION = $arProperty["DEFAULT_VALUE"];
      //Check if template substitution is necessary
      if(preg_match_all("/(\\{.*?\\})/", $EQUATION, $arMatch))
      {
         //Cycle for all of the properties used in the expression
         $arPropCodes = array();
         foreach($arMatch[0] as $equation_code)
         {
            //This is the "price"
            $bPrice = substr($equation_code, -7)=="_PRICE}";
            //Symbol code of the property which value will be substituted in the expression
            $property_code = ($bPrice? substr($equation_code, 1, -7): substr($equation_code, 1, -1));

            if($bPrice)
            {
               //Let us find a related element
               $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();
               //We borrow its price
               if($arLinkedElement["CATALOG_PRICE_".$PRICE_ID])
                  $value = doubleval($arLinkedElement["CATALOG_PRICE_".$PRICE_ID]);
               else
                  $value = doubleval($arLinkedElement["PROPERTY_PRICE_VALUE"]);
            }
            else
            {
               //If we require not only numbers but also strings
               //get rid of doubleval and add screening of string symbols
               $value = doubleval($arElement["PROPERTIES"][$property_code]["~VALUE"]);
            }
            //Value substitution
            $EQUATION = str_replace($equation_code, $value, $EQUATION);
         }

      }
      //Calculation proper
      $VALUE = @eval("return ".$EQUATION.";");
      //and saving its result to be displayed in the template
      $arResult["ITEMS"][$i]["DISPLAY_PROPERTIES"][$CALCULATOR_CODE] = $arResult["ITEMS"][$i]["PROPERTIES"][$CALCULATOR_CODE];
      $arResult["ITEMS"][$i]["DISPLAY_PROPERTIES"][$CALCULATOR_CODE]["DISPLAY_VALUE"] = htmlspecialchars($VALUE);
   }
}
?>




Courses developed by Bitrix24