function ImportMetaData($xml_root_id, $IBLOCK_TYPE, $IBLOCK_LID, $bUpdateIBlock = true)
{
global $APPLICATION;
$rs = $this->_xml_file->GetList(
array("ID" => "asc"),
array("ID" => $xml_root_id),
array("ID", "NAME", "ATTRIBUTES")
);
$ar = $rs->Fetch();
if ($ar)
{
foreach(array(LANGUAGE_ID, "en", "ru") as $lang)
{
$mess = MainLocalizationLoc::loadLanguageFile(__FILE__, $lang);
if($ar["NAME"] === $mess["IBLOCK_XML2_COMMERCE_INFO"])
{
$this->mess = $mess;
$this->next_step["lang"] = $lang;
}
}
$xml_root_id = $ar["ID"];
}
if($ar && ($ar["ATTRIBUTES"] <> ''))
{
$info = unserialize($ar["ATTRIBUTES"], ['allowed_classes' => false]);
if(is_array($info) && array_key_exists($this->mess["IBLOCK_XML2_SUM_FORMAT"], $info))
{
if(preg_match("#".$this->mess["IBLOCK_XML2_SUM_FORMAT_DELIM"]."=(.);{0,1}#", $info[$this->mess["IBLOCK_XML2_SUM_FORMAT"]], $match))
{
$this->next_step["sdp"] = $match[1];
}
}
}
$meta_data_xml_id = false;
$XML_ELEMENTS_PARENT = false;
$XML_SECTIONS_PARENT = false;
$XML_PROPERTIES_PARENT = false;
$XML_SECTIONS_PROPERTIES_PARENT = false;
$XML_PRICES_PARENT = false;
$XML_STORES_PARENT = false;
$XML_BASE_UNITS_PARENT = false;
$XML_SECTION_PROPERTIES = false;
$arIBlock = array();
$this->next_step["bOffer"] = false;
$rs = $this->_xml_file->GetList(
array(),
array("PARENT_ID" => $xml_root_id, "NAME" => $this->mess["IBLOCK_XML2_CATALOG"]),
array("ID", "ATTRIBUTES")
);
$ar = $rs->Fetch();
if(!$ar)
{
$rs = $this->_xml_file->GetList(
array(),
array("PARENT_ID" => $xml_root_id, "NAME" => $this->mess["IBLOCK_XML2_OFFER_LIST"]),
array("ID", "ATTRIBUTES")
);
$ar = $rs->Fetch();
$this->next_step["bOffer"] = true;
}
if(!$ar)
{
$rs = $this->_xml_file->GetList(
array(),
array("PARENT_ID" => $xml_root_id, "NAME" => $this->mess["IBLOCK_XML2_OFFERS_CHANGE"]),
array("ID", "ATTRIBUTES")
);
$ar = $rs->Fetch();
$this->next_step["bOffer"] = true;
$this->next_step["bUpdateOnly"] = true;
$bUpdateIBlock = false;
}
if ($this->next_step["bOffer"] && !$this->bCatalog)
return GetMessage('IBLOCK_XML2_MODULE_CATALOG_IS_ABSENT');
if($ar)
{
if($ar["ATTRIBUTES"] <> '')
{
$attrs = unserialize($ar["ATTRIBUTES"], ['allowed_classes' => false]);
if (is_array($attrs))
{
if (isset($attrs[$this->mess["IBLOCK_XML2_UPDATE_ONLY"]]))
{
$this->next_step["bUpdateOnly"] = $attrs[$this->mess["IBLOCK_XML2_UPDATE_ONLY"]] === "true"
|| (int)$attrs[$this->mess["IBLOCK_XML2_UPDATE_ONLY"]] > 0
;
}
}
}
$rs = $this->_xml_file->GetList(
array("ID" => "asc"),
array("PARENT_ID" => $ar["ID"])
);
while($ar = $rs->Fetch())
{
if(isset($ar["VALUE_CLOB"]))
$ar["VALUE"] = $ar["VALUE_CLOB"];
$trueValue = $ar['VALUE'] === 'true' || (int)$ar['VALUE'] > 0;
if($ar["NAME"] == $this->mess["IBLOCK_XML2_ID"])
$arIBlock["XML_ID"] = ($this->use_iblock_type_id? $IBLOCK_TYPE."-": "").$ar["VALUE"];
elseif($ar["NAME"] == $this->mess["IBLOCK_XML2_CATALOG_ID"])
$arIBlock["CATALOG_XML_ID"] = ($this->use_iblock_type_id? $IBLOCK_TYPE."-": "").$ar["VALUE"];
elseif($ar["NAME"] == $this->mess["IBLOCK_XML2_NAME"])
$arIBlock["NAME"] = $ar["VALUE"];
elseif($ar["NAME"] == $this->mess["IBLOCK_XML2_DESCRIPTION"])
{
$arIBlock["DESCRIPTION"] = $ar["VALUE"];
$arIBlock["DESCRIPTION_TYPE"] = "html";
}
elseif($ar["NAME"] == $this->mess["IBLOCK_XML2_POSITIONS"] || $ar["NAME"] == $this->mess["IBLOCK_XML2_OFFERS"])
$XML_ELEMENTS_PARENT = $ar["ID"];
elseif($ar["NAME"] == $this->mess["IBLOCK_XML2_PRICE_TYPES"])
$XML_PRICES_PARENT = $ar["ID"];
elseif($ar["NAME"] == $this->mess["IBLOCK_XML2_STORES"])
$XML_STORES_PARENT = $ar["ID"];
elseif($ar["NAME"] == $this->mess["IBLOCK_XML2_BASE_UNITS"])
$XML_BASE_UNITS_PARENT = $ar["ID"];
elseif($ar["NAME"] == $this->mess["IBLOCK_XML2_METADATA_ID"])
$meta_data_xml_id = $ar["VALUE"];
elseif($ar["NAME"] == $this->mess["IBLOCK_XML2_UPDATE_ONLY"])
$this->next_step["bUpdateOnly"] = $trueValue;
elseif($ar["NAME"] == $this->mess["IBLOCK_XML2_BX_CODE"])
$arIBlock["CODE"] = $ar["VALUE"];
elseif($ar["NAME"] == $this->mess["IBLOCK_XML2_BX_API_CODE"])
$arIBlock["API_CODE"] = $ar["VALUE"];
elseif($ar["NAME"] == $this->mess["IBLOCK_XML2_BX_SORT"])
$arIBlock["SORT"] = $ar["VALUE"];
elseif($ar["NAME"] == $this->mess["IBLOCK_XML2_BX_LIST_URL"])
$arIBlock["LIST_PAGE_URL"] = $ar["VALUE"];
elseif($ar["NAME"] == $this->mess["IBLOCK_XML2_BX_DETAIL_URL"])
$arIBlock["DETAIL_PAGE_URL"] = $ar["VALUE"];
elseif($ar["NAME"] == $this->mess["IBLOCK_XML2_BX_SECTION_URL"])
$arIBlock["SECTION_PAGE_URL"] = $ar["VALUE"];
elseif($ar["NAME"] == $this->mess["IBLOCK_XML2_BX_CANONICAL_URL"])
$arIBlock["CANONICAL_PAGE_URL"] = $ar["VALUE"];
elseif($ar["NAME"] == $this->mess["IBLOCK_XML2_BX_INDEX_ELEMENTS"])
$arIBlock["INDEX_ELEMENT"] = $trueValue ? "Y": "N";
elseif($ar["NAME"] == $this->mess["IBLOCK_XML2_BX_INDEX_SECTIONS"])
$arIBlock["INDEX_SECTION"] = $trueValue ? "Y": "N";
elseif($ar["NAME"] == $this->mess["IBLOCK_XML2_BX_SECTIONS_NAME"])
$arIBlock["SECTIONS_NAME"] = $ar["VALUE"];
elseif($ar["NAME"] == $this->mess["IBLOCK_XML2_BX_SECTION_NAME"])
$arIBlock["SECTION_NAME"] = $ar["VALUE"];
elseif($ar["NAME"] == $this->mess["IBLOCK_XML2_BX_ELEMENTS_NAME"])
$arIBlock["ELEMENTS_NAME"] = $ar["VALUE"];
elseif($ar["NAME"] == $this->mess["IBLOCK_XML2_BX_ELEMENT_NAME"])
$arIBlock["ELEMENT_NAME"] = $ar["VALUE"];
elseif($ar["NAME"] == $this->mess["IBLOCK_XML2_BX_PICTURE"])
{
if($ar["VALUE"] <> '')
$arIBlock["PICTURE"] = $this->MakeFileArray($ar["VALUE"]);
else
$arIBlock["PICTURE"] = $this->MakeFileArray($this->_xml_file->GetAllChildrenArray($ar["ID"]));
}
elseif($ar["NAME"] == $this->mess["IBLOCK_XML2_BX_WORKFLOW"])
$arIBlock["WORKFLOW"] = ($ar["VALUE"]=="true") || intval($ar["VALUE"])? "Y": "N";
elseif($ar["NAME"] == $this->mess["IBLOCK_XML2_INHERITED_TEMPLATES"])
{
$arIBlock["IPROPERTY_TEMPLATES"] = array();
$arTemplates = $this->_xml_file->GetAllChildrenArray($ar["ID"]);
foreach($arTemplates as $TEMPLATE)
{
$id = $TEMPLATE[$this->mess["IBLOCK_XML2_ID"]];
$template = $TEMPLATE[$this->mess["IBLOCK_XML2_VALUE"]];
if($id <> '' && $template <> '')
$arIBlock["IPROPERTY_TEMPLATES"][$id] = $template;
}
}
elseif($ar["NAME"] == $this->mess["IBLOCK_XML2_LABELS"])
{
$arLabels = $this->_xml_file->GetAllChildrenArray($ar["ID"]);
foreach($arLabels as $arLabel)
{
$id = $arLabel[$this->mess["IBLOCK_XML2_ID"]];
$label = $arLabel[$this->mess["IBLOCK_XML2_VALUE"]];
if($id <> '' && $label <> '')
$arIBlock[$id] = $label;
}
}
}
if($this->next_step["bOffer"] && !$this->use_offers)
{
if (isset($arIBlock["CATALOG_XML_ID"]) && $arIBlock["CATALOG_XML_ID"] !== '')
{
$arIBlock["XML_ID"] = $arIBlock["CATALOG_XML_ID"];
$this->next_step["bUpdateOnly"] = true;
}
}
$obIBlock = new CIBlock;
$rsIBlocks = $obIBlock->GetList(array(), array("XML_ID"=>$arIBlock["XML_ID"]));
$ar = $rsIBlocks->Fetch();
//Also check for non bitrix xml file
if(!$ar && !array_key_exists("CODE", $arIBlock))
{
if($this->next_step["bOffer"] && $this->use_offers)
$rsIBlocks = $obIBlock->GetList(array(), array("XML_ID"=>"FUTURE-1C-OFFERS"));
else
$rsIBlocks = $obIBlock->GetList(array(), array("XML_ID"=>"FUTURE-1C-CATALOG"));
$ar = $rsIBlocks->Fetch();
}
if($ar)
{
if($bUpdateIBlock && (!$this->next_step["bOffer"] || $this->use_offers))
{
if($obIBlock->Update($ar["ID"], $arIBlock))
$arIBlock["ID"] = $ar["ID"];
else
return $obIBlock->LAST_ERROR;
}
else
{
$arIBlock["ID"] = $ar["ID"];
}
}
else
{
$arIBlock["IBLOCK_TYPE_ID"] = $this->CheckIBlockType($IBLOCK_TYPE);
if(!$arIBlock["IBLOCK_TYPE_ID"])
return GetMessage("IBLOCK_XML2_TYPE_ADD_ERROR");
$arIBlock["GROUP_ID"] = array(2=>"R");
$arIBlock["LID"] = $this->CheckSites($IBLOCK_LID);
$arIBlock["ACTIVE"] = "Y";
$arIBlock["WORKFLOW"] = "N";
if (
$this->translit_on_add
&& !array_key_exists("CODE", $arIBlock)
)
{
$arIBlock["FIELDS"] = array(
"CODE" => array( "DEFAULT_VALUE" => array(
"TRANSLITERATION" => "Y",
"TRANS_LEN" => $this->translit_on_add["max_len"],
"TRANS_CASE" => $this->translit_on_add["change_case"],
"TRANS_SPACE" => $this->translit_on_add["replace_space"],
"TRANS_OTHER" => $this->translit_on_add["replace_other"],
"TRANS_EAT" => $this->translit_on_add["delete_repeat_replace"]? "Y": "N",
)),
"SECTION_CODE" => array( "DEFAULT_VALUE" => array(
"TRANSLITERATION" => "Y",
"TRANS_LEN" => $this->translit_on_add["max_len"],
"TRANS_CASE" => $this->translit_on_add["change_case"],
"TRANS_SPACE" => $this->translit_on_add["replace_space"],
"TRANS_OTHER" => $this->translit_on_add["replace_other"],
"TRANS_EAT" => $this->translit_on_add["delete_repeat_replace"]? "Y": "N",
)),
);
}
$arIBlock["ID"] = $obIBlock->Add($arIBlock);
if(!$arIBlock["ID"])
return $obIBlock->LAST_ERROR;
}
//Make this catalog
if($this->bCatalog && $this->next_step["bOffer"])
{
$obCatalog = new CCatalog();
$intParentID = $this->GetIBlockByXML_ID($arIBlock["CATALOG_XML_ID"] ?? '');
if (0 < intval($intParentID) && $this->use_offers)
{
$mxSKUProp = $obCatalog->LinkSKUIBlock($intParentID,$arIBlock["ID"]);
if (!$mxSKUProp)
{
if ($ex = $APPLICATION->GetException())
{
$result = $ex->GetString();
return $result;
}
}
else
{
$rs = CCatalog::GetList(array(),array("IBLOCK_ID"=>$arIBlock["ID"]));
if($arOffer = $rs->Fetch())
{
$boolFlag = $obCatalog->Update($arIBlock["ID"],array('PRODUCT_IBLOCK_ID' => $intParentID,'SKU_PROPERTY_ID' => $mxSKUProp));
}
else
{
$boolFlag = $obCatalog->Add(array("IBLOCK_ID"=>$arIBlock["ID"], "YANDEX_EXPORT"=>"N", "SUBSCRIPTION"=>"N",'PRODUCT_IBLOCK_ID' => $intParentID,'SKU_PROPERTY_ID' => $mxSKUProp));
}
if (!$boolFlag)
{
if ($ex = $APPLICATION->GetException())
{
$result = $ex->GetString();
return $result;
}
}
}
}
else
{
$rs = CCatalog::GetList(array(),array("IBLOCK_ID"=>$arIBlock["ID"]));
if(!($rs->Fetch()))
{
$boolFlag = $obCatalog->Add(array("IBLOCK_ID"=>$arIBlock["ID"], "YANDEX_EXPORT"=>"N", "SUBSCRIPTION"=>"N"));
if (!$boolFlag)
{
if ($ex = $APPLICATION->GetException())
{
$result = $ex->GetString();
return $result;
}
}
}
}
}
//For non bitrix xml file
//Check for mandatory properties and add them as necessary
if(!array_key_exists("CODE", $arIBlock))
{
$arProperties = [];
$arProperties['CML2_BAR_CODE'] = GetMessage('IBLOCK_XML2_BAR_CODE');
$arProperties['CML2_ARTICLE'] = GetMessage('IBLOCK_XML2_ARTICLE');
$arProperties['CML2_ATTRIBUTES'] = [
'NAME' => GetMessage('IBLOCK_XML2_ATTRIBUTES'),
'MULTIPLE' => 'Y',
'WITH_DESCRIPTION' => 'Y',
'MULTIPLE_CNT' => 1,
];
$arProperties['CML2_TRAITS'] = [
'NAME' => GetMessage('IBLOCK_XML2_TRAITS'),
'MULTIPLE' => 'Y',
'WITH_DESCRIPTION' => 'Y',
'MULTIPLE_CNT' => 1,
];
$arProperties['CML2_BASE_UNIT'] = [
'NAME' => GetMessage('IBLOCK_XML2_BASE_UNIT_NAME'),
'WITH_DESCRIPTION' => 'Y',
];
$arProperties['CML2_TAXES'] = [
'NAME' => GetMessage('IBLOCK_XML2_TAXES'),
'MULTIPLE' => 'Y',
'WITH_DESCRIPTION' => 'Y',
'MULTIPLE_CNT' => 1,
];
$arProperties[CIBlockPropertyTools::XML_MORE_PHOTO] = CIBlockPropertyTools::getPropertyDescription(
CIBlockPropertyTools::CODE_MORE_PHOTO,
['IBLOCK_ID' => $arIBlock['ID']]
);
$arProperties['CML2_FILES'] = [
'NAME' => GetMessage('IBLOCK_XML2_FILES'),
'MULTIPLE' => 'Y',
'WITH_DESCRIPTION' => 'Y',
'MULTIPLE_CNT' => 1,
'PROPERTY_TYPE' => IblockPropertyTable::TYPE_FILE,
'CODE' => 'FILES',
];
$arProperties['CML2_MANUFACTURER'] = [
'NAME' => GetMessage('IBLOCK_XML2_PROP_MANUFACTURER'),
'MULTIPLE' => 'N',
'WITH_DESCRIPTION' => 'N',
'MULTIPLE_CNT' => 1,
'PROPERTY_TYPE' => IblockPropertyTable::TYPE_LIST,
];
foreach($arProperties as $k=>$v)
{
$result = $this->CheckProperty($arIBlock["ID"], $k, $v);
if($result!==true)
return $result;
}
//For offers make special property: link to catalog
if (isset($arIBlock['CATALOG_XML_ID']) && $this->use_offers)
{
$this->CheckProperty(
$arIBlock['ID'],
CIBlockPropertyTools::XML_SKU_LINK,
CIBlockPropertyTools::getPropertyDescription(
CIBlockPropertyTools::CODE_SKU_LINK,
[
'IBLOCK_ID' => $arIBlock['ID'],
'LINK_IBLOCK_ID' => $this->GetIBlockByXML_ID($arIBlock['CATALOG_XML_ID']),
]
)
);
}
}
$this->next_step["IBLOCK_ID"] = $arIBlock["ID"];
$this->next_step["XML_ELEMENTS_PARENT"] = $XML_ELEMENTS_PARENT;
}
if($meta_data_xml_id)
{
$rs = $this->_xml_file->GetList(
array(),
array("PARENT_ID" => $xml_root_id, "NAME" => $this->mess["IBLOCK_XML2_METADATA"]),
array("ID")
);
while($arMetadata = $rs->Fetch())
{
//Find referenced metadata
$bMetaFound = false;
$meta_roots = array();
$rsMetaRoots = $this->_xml_file->GetList(
array("ID" => "asc"),
array("PARENT_ID" => $arMetadata["ID"])
);
while($arMeta = $rsMetaRoots->Fetch())
{
if(isset($arMeta["VALUE_CLOB"]))
$arMeta["VALUE"] = $arMeta["VALUE_CLOB"];
if($arMeta["NAME"] == $this->mess["IBLOCK_XML2_ID"] && $arMeta["VALUE"] == $meta_data_xml_id)
$bMetaFound = true;
$meta_roots[] = $arMeta;
}
//Get xml parents of the properties and sections
if($bMetaFound)
{
foreach($meta_roots as $arMeta)
{
if($arMeta["NAME"] == $this->mess["IBLOCK_XML2_GROUPS"])
$XML_SECTIONS_PARENT = $arMeta["ID"];
elseif($arMeta["NAME"] == $this->mess["IBLOCK_XML2_PROPERTIES"])
$XML_PROPERTIES_PARENT = $arMeta["ID"];
elseif($arMeta["NAME"] == $this->mess["IBLOCK_XML2_GROUPS_PROPERTIES"])
$XML_SECTIONS_PROPERTIES_PARENT = $arMeta["ID"];
elseif($arMeta["NAME"] == $this->mess["IBLOCK_XML2_SECTION_PROPERTIES"])
$XML_SECTION_PROPERTIES = $arMeta["ID"];
elseif($arMeta["NAME"] == $this->mess["IBLOCK_XML2_PRICE_TYPES"])
$XML_PRICES_PARENT = $arMeta["ID"];
elseif($arMeta["NAME"] == $this->mess["IBLOCK_XML2_STORES"])
$XML_STORES_PARENT = $arMeta["ID"];
elseif($arMeta["NAME"] == $this->mess["IBLOCK_XML2_BASE_UNITS"])
$XML_BASE_UNITS_PARENT = $arMeta["ID"];
}
break;
}
}
}
$iblockFields = CIBlock::GetFields($arIBlock["ID"]);
$iblockFields["XML_IMPORT_START_TIME"] = array(
"NAME" => "XML_IMPORT_START_TIME",
"IS_REQUIRED" => "N",
"DEFAULT_VALUE" => date("Y-m-d H:i:s"),
);
CIBlock::SetFields($arIBlock["ID"], $iblockFields);
if($XML_PROPERTIES_PARENT)
{
$result = $this->ImportProperties($XML_PROPERTIES_PARENT, $arIBlock["ID"]);
if($result!==true)
return $result;
}
if($XML_SECTION_PROPERTIES)
{
$result = $this->ImportSectionProperties($XML_SECTION_PROPERTIES, $arIBlock["ID"]);
if($result!==true)
return $result;
}
if($XML_SECTIONS_PROPERTIES_PARENT)
{
$result = $this->ImportSectionsProperties($XML_SECTIONS_PROPERTIES_PARENT, $arIBlock["ID"]);
if($result!==true)
return $result;
}
if($XML_PRICES_PARENT)
{
if($this->bCatalog)
{
$result = $this->ImportPrices($XML_PRICES_PARENT, $arIBlock["ID"], $IBLOCK_LID);
if($result!==true)
return $result;
}
}
if($XML_STORES_PARENT)
{
if($this->bCatalog)
{
$result = $this->ImportStores($XML_STORES_PARENT);
if($result!==true)
return $result;
}
}
if($XML_BASE_UNITS_PARENT)
{
if($this->bCatalog)
{
$result = $this->ImportBaseUnits($XML_BASE_UNITS_PARENT);
if($result!==true)
return $result;
}
}
$this->next_step["section_sort"] = 100;
$this->next_step["XML_SECTIONS_PARENT"] = $XML_SECTIONS_PARENT;
$rs = $this->_xml_file->GetList(
array(),
array("PARENT_ID" => $xml_root_id, "NAME" => $this->mess["IBLOCK_XML2_PRODUCTS_SETS"]),
array("ID", "ATTRIBUTES")
);
$ar = $rs->Fetch();
if ($ar)
{
$this->next_step["SETS"] = (int)$ar["ID"];
}
return true;
}