static function getProductDataToFillBasket($productId, $quantity, $userId, $LID, $userColumns, $tmpId = "")
{
$isSetItem = $tmpId != "";
if (self::$catalogIncluded === null)
self::$catalogIncluded = MainLoader::includeModule('catalog');
if (!self::$catalogIncluded)
return array();
$arParams = array();
static $proxyIblockElement = array();
static $proxyCatalogMeasure = array();
static $proxyParent = array();
static $proxyIblockProperty = array();
static $proxyProductData = array();
static $proxyCatalogProduct = array();
static $proxyCatalogMeasureRatio = array();
$productId = (int)$productId;
if ($productId <= 0)
{
return $arParams;
}
if (!empty($proxyIblockElement[$productId]))
{
$iblockId = $proxyIblockElement[$productId];
}
else
{
$iblockId = (int)CIBlockElement::getIBlockByID($productId);
if ($iblockId > 0)
$proxyIblockElement[$productId] = $iblockId;
}
if ($iblockId <= 0)
{
return $arParams;
}
$arSku2Parent = array();
$arElementId = array();
$arElementId[] = $productId;
$proxyParentKey = $productId."|".$iblockId;
if (!empty($proxyParent[$proxyParentKey]) && is_array($proxyParent[$proxyParentKey]))
{
$arParent = $proxyParent[$proxyParentKey];
}
else
{
$arParent = CCatalogSku::getProductInfo($productId, $iblockId);
$proxyParent[$proxyParentKey] = $arParent;
}
if ($arParent)
{
$arElementId[] = $arParent["ID"];
$arSku2Parent[$productId] = $arParent["ID"];
}
$arPropertyInfo = array();
$userColumns = (string)$userColumns;
$arUserColumns = ($userColumns != '') ? explode(",", $userColumns) : array();
foreach ($arUserColumns as $key => $column)
{
$column = mb_strtoupper($column);
if (strncmp($column, 'PROPERTY_', 9) != 0)
{
unset($arUserColumns[$key]);
}
else
{
$propertyCode = mb_substr($column, 9);
if ($propertyCode == '')
{
unset($arUserColumns[$key]);
continue;
}
if (!empty($proxyIblockProperty[$propertyCode]) && is_array($proxyIblockProperty[$propertyCode]))
{
$arPropertyInfo[$column] = $proxyIblockProperty[$propertyCode];
}
else
{
$dbres = CIBlockProperty::getList(array(), array("CODE" => $propertyCode));
if ($arPropData = $dbres->getNext())
{
$arPropertyInfo[$column] = $arPropData;
$proxyIblockProperty[$propertyCode] = $arPropData;
}
}
}
}
$arSelect = array_merge(
[
"ID",
"NAME",
"IBLOCK_ID",
"IBLOCK_SECTION_ID",
"DETAIL_PICTURE",
"PREVIEW_PICTURE",
"XML_ID",
"IBLOCK_EXTERNAL_ID",
"DETAIL_PAGE_URL",
],
$arUserColumns
);
$proxyProductDataKey = md5(join('|', $arElementId)."_".join('|', $arSelect));
if (!empty($proxyProductData[$proxyProductDataKey]) && is_array($proxyProductData[$proxyProductDataKey]))
{
$arProductData = $proxyProductData[$proxyProductDataKey];
}
else
{
$arProductData = getProductProps($arElementId, $arSelect);
$proxyProductData[$proxyProductDataKey] = $arProductData;
}
$defaultMeasure = CCatalogMeasure::getDefaultMeasure(true, true);
if (!empty($arProductData))
{
$arElementInfo = array();
foreach ($arProductData as $elemId => &$arElement)
{
foreach ($arElement as $key => $value)
{
if (strncmp($key, 'PROPERTY_', 9) == 0 && mb_substr($key, -6) == "_VALUE")
{
$columnCode = str_replace("_VALUE", "", $key);
if (!isset($arPropertyInfo[$columnCode]))
continue;
$keyResult = 'PROPERTY_'.$arPropertyInfo[$columnCode]['CODE'].'_VALUE';
$arElement[$key] = getIblockPropInfo($value, $arPropertyInfo[$columnCode], array("WIDTH" => 90, "HEIGHT" => 90));
if ($keyResult != $key)
$arElement[$keyResult] = $arElement[$key];
unset($keyResult);
}
}
}
unset($arElement);
if (isset($arProductData[$productId]))
$arElementInfo = $arProductData[$productId];
if (isset( $arSku2Parent[$productId]))
$arParent = $arProductData[$arSku2Parent[$productId]];
if (!empty($arSku2Parent)) // if sku element doesn't have value of some property - we'll show parent element value instead
{
foreach ($arUserColumns as $field)
{
$fieldVal = $field."_VALUE";
$parentId = $arSku2Parent[$productId];
if ((!isset($arElementInfo[$fieldVal]) || (isset($arElementInfo[$fieldVal]) && $arElementInfo[$fieldVal] == ''))
&& (isset($arProductData[$parentId][$fieldVal]) && !empty($arProductData[$parentId][$fieldVal]))) // can be array or string
{
$arElementInfo[$fieldVal] = $arProductData[$parentId][$fieldVal];
}
}
if (mb_strpos($arElementInfo["~XML_ID"], '#') === false)
{
$arElementInfo["~XML_ID"] = $arParent['~XML_ID'].'#'.$arElementInfo["~XML_ID"];
}
}
$arElementInfo["MODULE"] = "catalog";
$arElementInfo["PRODUCT_PROVIDER_CLASS"] = "CCatalogProductProvider";
$arElementInfo["PRODUCT_ID"] = $arElementInfo["ID"];
if ($arElementInfo["IBLOCK_ID"] > 0)
{
$arElementInfo["EDIT_PAGE_URL"] = CIBlock::GetAdminElementEditLink($arElementInfo["IBLOCK_ID"], $arElementInfo["PRODUCT_ID"], array(
"find_section_section" => $arElementInfo["IBLOCK_SECTION_ID"],
'WF' => 'Y',
));
}
static $buyersGroups = array();
if(empty($buyersGroups[$userId]))
$buyersGroups[$userId] = CUser::getUserGroup($userId);
$arBuyerGroups = $buyersGroups[$userId];
// price
CatalogProductPriceCalculation::pushConfig();
CatalogProductPriceCalculation::setConfig(array(
'CURRENCY' => SaleInternalsSiteCurrencyTable::getSiteCurrency($LID),
'PRECISION' => (int)MainConfigOption::get('sale', 'value_precision'),
'USE_DISCOUNTS' => !$isSetItem,
'RESULT_WITH_VAT' => true
));
$arPrice = CCatalogProduct::getOptimalPrice($arElementInfo["ID"], 1, $arBuyerGroups, "N", array(), $LID);
CatalogProductPriceCalculation::popConfig();
$priceType = GetCatalogGroup($arPrice["PRICE"]["CATALOG_GROUP_ID"]);
$currentPrice = $arPrice['RESULT_PRICE']['DISCOUNT_PRICE'];
$arElementInfo['PRICE'] = $currentPrice;
$arElementInfo['CURRENCY'] = $arPrice['RESULT_PRICE']['CURRENCY'];
$currentTotalPrice = $arPrice['RESULT_PRICE']['BASE_PRICE'];
if (!empty($proxyCatalogProduct[$productId]) && is_array($proxyCatalogProduct[$productId]))
{
$arProduct = $proxyCatalogProduct[$productId];
}
else
{
$rsProducts = CatalogProductTable::getList([
'select' => ['ID', 'QUANTITY', 'WEIGHT', 'MEASURE', 'TYPE', 'BARCODE_MULTI', 'WIDTH', 'LENGTH', 'HEIGHT'],
'filter' => ['=ID' => $productId]
]);
if ($arProduct = $rsProducts->fetch())
{
$proxyCatalogProduct[$productId] = $arProduct;
}
unset($rsProducts);
}
if (empty($arProduct) || !is_array($arProduct))
{
return array();
}
$balance = floatval($arProduct["QUANTITY"]);
// sku props
$arSkuData = array();
static $proxySkuProperty = array();
if (!empty($proxySkuProperty[$productId]) && is_array($proxySkuProperty[$productId]))
{
$arSkuProperty = $proxySkuProperty[$productId];
}
else
{
$arSkuProperty = CSaleProduct::GetProductSkuProps($productId, '', true);
$proxySkuProperty[$productId] = $arSkuProperty;
}
if (!empty($arSkuProperty))
{
foreach ($arSkuProperty as &$val)
{
$arSkuData[] = array(
'NAME' => htmlspecialcharsback($val['NAME']),
'VALUE' => htmlspecialcharsback($val['VALUE']),
'CODE' => htmlspecialcharsback($val['CODE'])
);
}
unset($val);
}
if($arElementInfo["~IBLOCK_EXTERNAL_ID"] <> '')
{
$arSkuData[] = array(
"NAME" => "Catalog XML_ID",
"CODE" => "CATALOG.XML_ID",
"VALUE" => $arElementInfo['~IBLOCK_EXTERNAL_ID']
);
}
if($arElementInfo["~XML_ID"] <> '')
{
$arSkuData[] = array(
"NAME" => "Product XML_ID",
"CODE" => "PRODUCT.XML_ID",
"VALUE" => $arElementInfo["~XML_ID"]
);
}
$arElementInfo["WEIGHT"] = $arProduct["WEIGHT"];
$arElementInfo["WIDTH"] = $arProduct["WIDTH"];
$arElementInfo["LENGTH"] = $arProduct["LENGTH"];
$arElementInfo["HEIGHT"] = $arProduct["HEIGHT"];
// measure
$arElementInfo["MEASURE_TEXT"] = "";
$arElementInfo["MEASURE_CODE"] = 0;
if ((int)$arProduct["MEASURE"] > 0)
{
if (!empty($proxyCatalogMeasure[$arProduct["MEASURE"]]) && is_array($proxyCatalogMeasure[$arProduct["MEASURE"]]))
{
$arMeasure = $proxyCatalogMeasure[$arProduct["MEASURE"]];
}
else
{
$dbMeasure = CCatalogMeasure::GetList(array(), array("ID" => intval($arProduct["MEASURE"])), false, false, array("ID", "SYMBOL_RUS", "SYMBOL_INTL"));
if ($arMeasure = $dbMeasure->Fetch())
{
$proxyCatalogMeasure[$arProduct["MEASURE"]] = $arMeasure;
}
}
if (!empty($arMeasure) && is_array($arMeasure))
{
$arElementInfo["MEASURE_TEXT"] = ($arMeasure["SYMBOL_RUS"] != '' ? $arMeasure["SYMBOL_RUS"] : $arMeasure["SYMBOL_INTL"]);
$arElementInfo["MEASURE_CODE"] = $arMeasure["CODE"];
}
}
if ($arElementInfo["MEASURE_TEXT"] == '')
{
$arElementInfo["MEASURE_TEXT"] = ($defaultMeasure["SYMBOL_RUS"] != '' ? $defaultMeasure["SYMBOL_RUS"] : $defaultMeasure["SYMBOL_INTL"]);
}
// ratio
$arElementInfo["RATIO"] = 1;
if (!empty($proxyCatalogMeasureRatio[$productId]) && is_array($proxyCatalogMeasureRatio[$productId]))
{
$arRatio = $proxyCatalogMeasureRatio[$productId];
}
else
{
$dbratio = CatalogMeasureRatioTable::getList(array(
'select' => array('*'),
'filter' => array('=PRODUCT_ID' => $productId, '=IS_DEFAULT' => 'Y')
));
if ($arRatio = $dbratio->fetch())
{
$proxyCatalogMeasureRatio[$productId] = $arRatio;
}
}
if (!empty($arRatio) && is_array($arRatio))
$arElementInfo["RATIO"] = $arRatio["RATIO"];
// image
$imgCode = '';
$imgUrl = '';
if ($arElementInfo["PREVIEW_PICTURE"] > 0)
$imgCode = $arElementInfo["PREVIEW_PICTURE"];
elseif ($arElementInfo["DETAIL_PICTURE"] > 0)
$imgCode = $arElementInfo["DETAIL_PICTURE"];
if ($imgCode == "" && !empty($arParent) && is_array($arParent))
{
if ($arParent["PREVIEW_PICTURE"] > 0)
$imgCode = $arParent["PREVIEW_PICTURE"];
elseif ($arParent["DETAIL_PICTURE"] > 0)
$imgCode = $arParent["DETAIL_PICTURE"];
}
if ($imgCode > 0)
{
$arFile = CFile::GetFileArray($imgCode);
$arImgProduct = CFile::ResizeImageGet($arFile, array('width'=>80, 'height'=>80), BX_RESIZE_IMAGE_PROPORTIONAL, false, false);
if (is_array($arImgProduct))
$imgUrl = $arImgProduct["src"];
}
$arSetInfo = array();
$arStores = array();
/** @var $productProvider IBXSaleProductProvider */
if ($productProvider = CSaleBasket::GetProductProvider(array("MODULE" => $arElementInfo["MODULE"], "PRODUCT_PROVIDER_CLASS" => $arElementInfo["PRODUCT_PROVIDER_CLASS"])))
{
// get set items if it is set
if ($arProduct["TYPE"] == CCatalogProduct::TYPE_SET)
{
if (method_exists($productProvider, "GetSetItems"))
{
$arSets = $productProvider::GetSetItems($productId, CSaleBasket::TYPE_SET);
if ($tmpId == "")
$tmpId = randString(7);
if (!empty($arSets))
{
foreach ($arSets as $arSetData)
{
foreach ($arSetData["ITEMS"] as $setItem)
{
$arSetItemParams = self::getProductDataToFillBasket($setItem["PRODUCT_ID"], $setItem["QUANTITY"], $userId, $LID, $userColumns, $tmpId); // recursive call
// re-define some fields with set data values
$arSetItemParams["PARENT_OFFER_ID"] = $productId;
$arSetItemParams["OFFER_ID"] = $setItem["PRODUCT_ID"];
$arSetItemParams["NAME"] = $setItem["NAME"];
$arSetItemParams["MODULE"] = $setItem["MODULE"];
$arSetItemParams["PRODUCT_PROVIDER_CLASS"] = $setItem["PRODUCT_PROVIDER_CLASS"];
$arSetItemParams["QUANTITY"] = $setItem["QUANTITY"] * $quantity;
$arSetItemParams["BARCODE_MULTI"] = $setItem["BARCODE_MULTI"];
$arSetItemParams["PRODUCT_TYPE"] = $setItem["TYPE"];
$arSetItemParams["WEIGHT"] = $setItem["WEIGHT"];
$arSetItemParams["VAT_RATE"] = $setItem["VAT_RATE"];
$arSetItemParams["SET_ITEMS"] = "";
$arSetItemParams["OLD_PARENT_ID"] = $productId."_tmp".$tmpId;
$arSetItemParams["IS_SET_ITEM"] = "Y";
$arSetItemParams["IS_SET_PARENT"] = "N";
$arSetItemParams["PROVIDER_DATA"] = serialize($setItem);
$arSetInfo[] = $arSetItemParams;
}
}
}
}
}
// get stores
$storeCount = $productProvider::GetStoresCount(array("SITE_ID" => $LID)); // with exact SITE_ID or SITE_ID = NULL
if ($storeCount > 0)
{
if ($arProductStore = $productProvider::GetProductStores(array("PRODUCT_ID" => $productId, "SITE_ID" => $LID)))
$arStores = $arProductStore;
}
}
$currentTotalPrice = (float)$currentTotalPrice;
// params array
$arParams["OFFER_ID"] = $productId;
$arParams["NAME"] = $arElementInfo["~NAME"]; //'
$arParams["EDIT_PAGE_URL"] = $arElementInfo["EDIT_PAGE_URL"];
$arParams["DETAIL_PAGE_URL"] = htmlspecialcharsex($arElementInfo["~DETAIL_PAGE_URL"]);
$arParams["PICTURE_URL"] = $imgUrl;
$arParams["PRICE"] = floatval($arElementInfo["PRICE"]);
$arParams["PRICE_BASE"] = $currentTotalPrice;
$arParams["DIMENSIONS"] = serialize(array("WIDTH" => $arElementInfo["WIDTH"], "HEIGHT" => $arElementInfo["HEIGHT"], "LENGTH" => $arElementInfo["LENGTH"]));
$arParams["QUANTITY"] = $quantity;
$arParams["MODULE"] = $arElementInfo["MODULE"];
$arParams["CURRENCY"] = $arElementInfo["CURRENCY"];
$arParams["WEIGHT"] = $arElementInfo["WEIGHT"];
$arParams["VAT_RATE"] = $arPrice["PRICE"]["VAT_RATE"];
$arParams["PRICE_TYPE"] = $priceType["NAME_LANG"];
$arParams["AVAILABLE"] = $balance;
$arParams["NOTES"] = (!empty($priceType["NAME_LANG"]) ? $priceType["NAME_LANG"] : "");
$arParams["CATALOG_XML_ID"] = $arElementInfo["~IBLOCK_EXTERNAL_ID"];
$arParams["PRODUCT_XML_ID"] = $arElementInfo["~XML_ID"];
$arParams["PRODUCT_PROVIDER_CLASS"] = $arElementInfo["PRODUCT_PROVIDER_CLASS"];
$arParams["PROPS"] = $arSkuData;
$arParams["MEASURE_TEXT"] = $arElementInfo["MEASURE_TEXT"];
$arParams["MEASURE_CODE"] = $arElementInfo["MEASURE_CODE"];
$arParams["MEASURE_RATIO"] = $arElementInfo["RATIO"];
$arParams["BARCODE_MULTI"] = $arProduct["BARCODE_MULTI"];
$arParams["PRODUCT_TYPE"] = empty($arSetInfo) ? "" : CSaleBasket::TYPE_SET;
$arParams["OLD_PARENT_ID"] = empty($arSetInfo) ? "" : $productId."_tmp".$tmpId;
$arParams["SET_ITEMS"] = $arSetInfo;
$arParams["IS_SET_ITEM"] = "N";
$arParams["IS_SET_PARENT"] = empty($arSetInfo) ? "N" : "Y";
$arParams["STORES"] = empty($arSetInfo) ? $arStores : array();
$arParams["PRODUCT_PROPS_VALUES"] = $arElementInfo; // along with other information also contains values of properties with correct keys (after getProductProps)
}
return $arParams;
}