public function getBundleItems(array $products)
{
$result = new SaleResult();
$resultList = array();
$productIdList = array();
static $proxyCatalogProductSet = array();
static $proxyCatalogSkuData = array();
$bundleItemList = array();
$bundleIndex = array();
foreach ($products as $productId => $productData)
{
$proxyCatalogProductSetKey = $productId."|".static::BUNDLE_TYPE;
if (!empty($proxyCatalogProductSet[$proxyCatalogProductSetKey]) && is_array($proxyCatalogProductSet[$proxyCatalogProductSetKey]))
{
$childItemList = $proxyCatalogProductSet[$proxyCatalogProductSetKey];
}
else
{
$childItemList = CCatalogProductSet::getAllSetsByProduct($productId, static::BUNDLE_TYPE);
if (!empty($childItemList) && is_array($childItemList))
{
$proxyCatalogProductSet[$proxyCatalogProductSetKey] = $childItemList;
}
}
if (!empty($childItemList))
{
$bundleItemList = $childItemList + $bundleItemList;
$bundleItemListIds = array_keys($childItemList);
$bundleItemId = reset($bundleItemListIds);
unset($bundleItemListIds);
$bundleIndex[$bundleItemId] = $productId;
}
}
$childIdList = array();
if (empty($bundleItemList))
return $result;
$bundleChildList = array();
$childProducts = array();
$productIndexList = array();
foreach ($bundleItemList as $parentItemid => $bundleItemData)
{
$productId = $bundleIndex[$parentItemid];
foreach ($bundleItemData["ITEMS"] as $childItemid => $item)
{
if (!isset($childIdList[$item['ITEM_ID']]))
$childIdList[$item['ITEM_ID']] = true;
$bundleChildList[$item['ITEM_ID']] = $item;
$childProducts[$item['ITEM_ID']] = array(
'ITEM_CODE' => $item['ITEM_ID'],
'PRODUCT_ID' => $item['ITEM_ID'],
Base::FLAT_QUANTITY_LIST => [$item['ITEM_ID'] => $item['QUANTITY']],
'BUNDLE_CHILD' => true,
);
$productIndexList[$item['ITEM_ID']] = array(
'PRODUCT_ID' => $productId,
'PARENT_ID' => $parentItemid,
'CHILD_ID' => $childItemid
);
}
}
$r = $this->getProductData($childProducts);
if ($r->isSuccess())
{
$resultData = $r->getData();
if (
!empty($resultData[Base::SUMMMARY_PRODUCT_LIST])
&& is_array($resultData[Base::SUMMMARY_PRODUCT_LIST])
)
{
$resultDataList = $resultData[Base::SUMMMARY_PRODUCT_LIST];
foreach ($resultDataList as $itemCode => $itemData)
{
$item = $bundleChildList[$itemCode];
if (array_key_exists('QUANTITY_TRACE', $itemData))
unset($itemData['QUANTITY_TRACE']);
$itemData["PRODUCT_ID"] = $item["ITEM_ID"];
$itemData["MODULE"] = 'catalog';
$itemData["PRODUCT_PROVIDER_CLASS"] = Basket::getDefaultProviderName();
$productIdList[] = $item["ITEM_ID"];
$itemData["PROPS"] = array();
if (!empty($proxyCatalogSkuData[$item["ITEM_ID"]]) && is_array($proxyCatalogSkuData[$item["ITEM_ID"]]))
{
$parentSkuData = $proxyCatalogSkuData[$item["ITEM_ID"]];
}
else
{
$parentSkuData = CCatalogSku::GetProductInfo($item["ITEM_ID"]);
if ($parentSkuData)
{
$proxyCatalogSkuData[$item["ITEM_ID"]] = $parentSkuData;
}
}
if (!empty($parentSkuData))
{
$childDataList = array();
$childIdGetList = array();
$iblockPropertyDataList = array();
$iblockPropertyIdList = array();
$propsSku = array();
foreach ($childIdList as $childId => $parentValue)
{
$productData = static::getHitCache(self::CACHE_ELEMENT_SHORT_DATA, $item["ITEM_ID"]);
if (!empty($productData))
{
$childDataList[$childId] = $productData;
if (!isset($iblockPropertyIdList[$productData['IBLOCK_ID']]))
{
$iblockPropertyIdList[$productData['IBLOCK_ID']] = true;
}
}
else
{
$childIdGetList[] = $childId;
}
}
if (!empty($childIdGetList))
{
$iterator = IblockElementTable::getList([
'select' => [
'ID',
'IBLOCK_ID',
'NAME',
'IBLOCK_SECTION_ID',
],
'filter' => CIBlockElement::getPublicElementsOrmFilter(['@ID' => $childIdGetList]),
]);
while ($productData = $iterator->fetch())
{
static::setHitCache(self::CACHE_ELEMENT_SHORT_DATA, $productData["ID"], $productData);
$childDataList[$productData["ID"]] = $productData;
if (!isset($iblockPropertyIdList[$productData['IBLOCK_ID']]))
{
$iblockPropertyIdList[$productData['IBLOCK_ID']] = true;
}
}
}
foreach ($iblockPropertyIdList as $iblockPropertyId => $iblockPropertyValue)
{
if ($propsSku = static::getHitCache('IBLOCK_PROPERTY', $iblockPropertyId))
{
$iblockPropertyDataList[$iblockPropertyId] = $propsSku;
}
else
{
$dbOfferProperties = CIBlock::GetProperties($iblockPropertyId, array(), array("!XML_ID" => "CML2_LINK"));
while($offerProperties = $dbOfferProperties->Fetch())
{
$propsSku[] = $offerProperties["CODE"];
}
static::setHitCache('IBLOCK_PROPERTY', $iblockPropertyId, $propsSku);
}
}
$propSkuHash = (!empty($propsSku)) ? md5(join('|', $propsSku)): md5($item["ITEM_ID"]);
$proxyProductPropertyKey = $item["ITEM_ID"]."_".$parentSkuData["IBLOCK_ID"]."_".$propSkuHash;
$productProperties = static::getHitCache('PRODUCT_PROPERTY', $proxyProductPropertyKey);
if (empty($productProperties))
{
$productProperties = CIBlockPriceTools::GetOfferProperties(
$item["ITEM_ID"],
$parentSkuData["IBLOCK_ID"],
$propsSku
);
static::setHitCache('PRODUCT_PROPERTY', $proxyProductPropertyKey, $productProperties);
}
if (!empty($productProperties))
{
foreach ($productProperties as $propData)
{
$itemData["PROPS"][] = array(
"NAME" => $propData["NAME"],
"CODE" => $propData["CODE"],
"VALUE" => $propData["VALUE"],
"SORT" => $propData["SORT"]
);
}
}
}
$parentProductIndexData = $productIndexList[$itemCode];
$priceData = array();
if (!empty($itemData['PRICE_LIST']))
{
$priceData = reset($itemData['PRICE_LIST']);
unset($itemData['PRICE_LIST']);
}
if (array_key_exists('PRODUCT', $itemData))
{
unset($itemData['PRODUCT']);
}
$bundleItemList[$parentProductIndexData['PARENT_ID']]["ITEMS"][$parentProductIndexData['CHILD_ID']] = array_merge($item, $itemData, $priceData);
}
}
}
$elementList = static::getHitCache('IBLOCK_ELEMENT_LIST', $productId);
if (empty($elementList))
{
$productRes = CIBlockElement::GetList(
array(),
array('ID' => $productIdList),
false,
false,
array("ID", "IBLOCK_ID", "IBLOCK_SECTION_ID", "PREVIEW_PICTURE", "DETAIL_PICTURE", "IBLOCK_TYPE_ID", "XML_ID")
);
while ($productData = $productRes->GetNext())
{
$elementList[$productData['ID']] = $productData;
}
if (!empty($elementList) && is_array($elementList))
{
static::setHitCache('IBLOCK_ELEMENT_LIST', $productId, $elementList);
}
}
if (!empty($elementList) && is_array($elementList))
{
foreach ($bundleItemList as $bundleParentId => $bundleItemData)
{
foreach ($bundleItemData["ITEMS"] as $bundleChildId => $item)
{
if (!$elementList[$item["ITEM_ID"]])
continue;
$elementData = $elementList[$item["ITEM_ID"]];
$properties = array();
$strIBlockXmlID = (string)CIBlock::GetArrayByID($elementData['IBLOCK_ID'], 'XML_ID');
if ($strIBlockXmlID != "")
{
$properties[] = array(
"NAME" => "Catalog XML_ID",
"CODE" => "CATALOG.XML_ID",
"VALUE" => $strIBlockXmlID
);
$elementData['CATALOG_XML_ID'] = $strIBlockXmlID;
}
if (!empty($proxyCatalogSkuData[$item["ITEM_ID"]]) && strpos($elementData["XML_ID"], '#') === false)
{
$parentSkuData = $proxyCatalogSkuData[$item["ITEM_ID"]];
if (!empty($proxyParentData[$parentSkuData['ID']]) && is_array($proxyParentData[$parentSkuData['ID']]))
{
$parentData = $proxyParentData[$parentSkuData['ID']];
}
else
{
$parentIterator = IblockElementTable::getList(
array(
'select' => array('ID', 'XML_ID'),
'filter' => array('ID' => $parentSkuData['ID'])
)
);
$parentData = $parentIterator->fetch();
if (!empty($parentData))
{
$proxyParentData[$parentSkuData['ID']] = $parentData;
}
unset($parentIterator);
}
$elementData["XML_ID"] = $parentData['XML_ID'].'#'.$elementData["XML_ID"];
unset($parentData);
}
$properties[] = array(
"NAME" => "Product XML_ID",
"CODE" => "PRODUCT.XML_ID",
"VALUE" => $elementData["XML_ID"]
);
$bundleItemData = $bundleItemList[$bundleParentId]["ITEMS"][$bundleChildId];
$bundleItemProps = array();
if (is_array($elementData["PROPS"]) && !empty($elementData["PROPS"]))
{
$bundleItemProps = $elementData["PROPS"];
}
if (!empty($properties))
{
$bundleItemProps = $bundleItemProps + $properties;
}
$bundleItemList[$bundleParentId]["ITEMS"][$bundleChildId] = $bundleItemData + array(
'IBLOCK_ID' => $elementData["IBLOCK_ID"],
'IBLOCK_SECTION_ID' => $elementData["IBLOCK_SECTION_ID"],
'PREVIEW_PICTURE' => $elementData["PREVIEW_PICTURE"],
'DETAIL_PICTURE' => $elementData["DETAIL_PICTURE"],
'CATALOG_XML_ID' => $elementData["CATALOG_XML_ID"],
'PRODUCT_XML_ID' => $elementData["XML_ID"],
);
$bundleItemList[$bundleParentId]["ITEMS"][$bundleChildId]['PROPS'] = $bundleItemProps;
}
}
}
foreach(GetModuleEvents("sale", "OnGetSetItems", true) as $eventData)
{
ExecuteModuleEventEx($eventData, array(&$bundleItemList));
}
if (!empty($bundleItemList))
{
foreach ($bundleItemList as $bundleParentId => $bundleData)
{
if (empty($bundleIndex[$bundleParentId]))
continue;
$productId = $bundleIndex[$bundleParentId];
$resultList[$productId] = $bundleData;
}
$result->setData(
array(
'BUNDLE_LIST' => $resultList
)
);
}
return $result;
}