1. это логируем событие OnSuccessCatalogImport1C, что бы понять, на сколько много файликов к нам прилетело
1 2 3 4 5 6 |
AddEventHandler('catalog', 'OnSuccessCatalogImport1C', 'customCatalogImportStep'); function customCatalogImportStep($arParams, $arFields) { file_put_contents($_SERVER["DOCUMENT_ROOT"]."/1c_log.log", date("d-m-Y")."; SESSION=".print_r($_SESSION,1)."; request ".print_r($_REQUEST,1)." pararm".print_r($arParams,1)." arFields ".print_r($arFields,1).";\n", FILE_APPEND); } |
2. Добавлем в bitrix/php_interface/dbconn.php — константу, что бы файлики, которые из выгрузки пришли, сохранились в папке Upload. После тестовой выгрузки отключаем сразу . т.к нам не нужно захламлять сервер лишними xml.
1 |
//define("BX_CATALOG_IMPORT_1C_PRESERVE", true); |
3. Создаем тестовый файлик и в нем запускаем обработчик выгрузки. В него подсовываем путь к файлу на сервере.
Используемые свойства у меня ANALOGI_TEMP , ANALOGI, ANALOGI_FLAG
ANALOGI_FLAG- Это флаг, что товар пришел с 1с и его надо потом обновить в событии успеха выгрузки.
1 |
Provider::loadXml1c('путь к файлу с товаром/import___5edefae3-b2ec-4f6e-a524-b03fb56f9166 (1).xml'); |
Этим вы сможете обойтись без постоянного гоняния 1с. т.к обрабатываемый файлик лежит на сервере.
4. Пишем внутрянку для OnCompleteCatalogImport1C. Т.к у нас бывают в взаимосвязи между товарами- то мы обрабатываем их в последнюю очередь.
5. Тестируем в 1 с на полной выгрузке.
Ниже приведен полный код взаимодействия. С получением данных из xml.
Этот код вылавливает вот такую структуру их xml от 1с.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<Аналоги> <Аналог> <Ид>d5cae0f9-c568-11e0-aab1-90fba63445ee</Ид> <НомерВерсии>AAAAAAA6Kdg=50539</НомерВерсии> </Аналог> <Аналог> <Ид>1d9e4c8d-ebbe-11df-b3fd-90fba63445ee</Ид> <НомерВерсии>AAAAAABWOrY=50539</НомерВерсии> </Аналог> <Аналог> <Ид>177a58e2-40c1-11e1-9cef-90fba63445ee</Ид> <НомерВерсии>AAAAAAA5/UI=50539</НомерВерсии> </Аналог> </Аналоги> |
и такую
1 2 3 4 5 6 |
<Аналоги> <Аналог> <Ид>3ed109d7-277a-11e0-a597-90fba63445ec</Ид> <НомерВерсии>AAAAAAA6GxU=50539</НомерВерсии> </Аналог> </Аналоги> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
class Provider1c { const IBLOCK_ID = 27; /** * @param $url * @return mixed */ public static function getXml($url) { return json_decode(json_encode(simplexml_load_file($url)), true); } public static function getIdAnalogByXML_ID($XML_ID) { $ID=false; $arSelect = Array("ID", "NAME","ACTIVE","XML_ID"); $arFilter = Array("IBLOCK_ID"=>self::IBLOCK_ID, "XML_ID"=>$XML_ID, "ACTIVE"=>"Y"); $res = CIBlockElement::GetList(Array(), $arFilter, false, false, $arSelect); if($ob = $res->GetNextElement()) { $arFields = $ob->GetFields(); $ID=$arFields['ID']; } return $ID; } public static function loadXml1c($url) { $result = self::getXml($url); \CModule::IncludeModule('iblock'); if (is_array($result)) { // print_r($result); $mass_analog=array(); $mass_all_xml_id=array(); foreach ($result['Каталог']['Товары']['Товар'] as $key=>$item) { $mass_all_xml_id[]=$item['Ид']; $id_1c=$item['Ид']; if(isset($item['Аналоги']['Аналог'])) { $mass_analog_temp=array(); if( isset($item['Аналоги']['Аналог'][0])){ foreach ($item['Аналоги']['Аналог'] as $key=>$value) { // $mass_analog_temp[]= $value['НомерВерсии']; $mass_analog_temp[]= $value['Ид']; } $mass_analog[$id_1c]=$mass_analog_temp; }else{ // $mass_analog_temp[]= $item['Аналоги']['Аналог']['НомерВерсии']; $mass_analog_temp[]= $item['Аналоги']['Аналог']['Ид']; $mass_analog[$id_1c]=$mass_analog_temp; } }else{ $mass_analog[$id_1c]=false; } } $mass_analog_temp=array(); foreach ($mass_analog as $XML_ID=>$fields) { if($fields==false){ $mass_analog_temp[$XML_ID] =false; }else{ $fields_temp=array(); foreach ($fields as $XML_ID_ANALOG){ //$fields_temp[]=self::getIdAnalogByXML_ID($XML_ID_ANALOG); $fields_temp[]=$XML_ID_ANALOG; // } $mass_analog_temp[$XML_ID]=$fields_temp; } } $mass_analog=$mass_analog_temp; /* echo '<pre>'; print_r($mass_analog); echo '</pre>'; die(); */ //очистка аналогов // занесение новых foreach ($mass_analog as $XML_ID=>$fields) { $arSelect = Array("ID", "NAME","ACTIVE","XML_ID"); $arFilter = Array("IBLOCK_ID"=>self::IBLOCK_ID, "XML_ID"=>$XML_ID, "ACTIVE"=>"Y"); $res = CIBlockElement::GetList(Array(), $arFilter, false, false, $arSelect); if($ob = $res->GetNextElement()) { $arFields = $ob->GetFields(); $ID=$arFields['ID']; //echo $ID.'<br/>'; // $fields эти поля занести в свойство (временное) CIBlockElement::SetPropertyValuesEx($ID, self::IBLOCK_ID, array('ANALOGI_TEMP' => $fields)); CIBlockElement::SetPropertyValuesEx($ID, self::IBLOCK_ID, array('ANALOGI_FLAG' => 1)); } } } } static function ReloadFromTemp() { \CModule::IncludeModule('iblock'); $arFilter_old = Array( "IBLOCK_ID"=>27, // id инфоблока "PROPERTY_ANALOGI_FLAG"=>1 ); $arSelect = Array("ID", "IBLOCK_ID", "NAME", "PREVIEW_PICTURE", "DATE_ACTIVE_FROM",);//IBLOCK_ID и ID обязательно должны быть указаны, $res = CIBlockElement::GetList(Array(), $arFilter_old, false, false, $arSelect); while($ob = $res->GetNextElement()){ //получаем поля (которые указали в $arSelect) $arFields = $ob->GetFields(); $ID= $arFields['ID']; $VALUES = false; $res2 = CIBlockElement::GetProperty(self::IBLOCK_ID, $arFields['ID'], "sort", "asc", array("CODE" => "ANALOGI_TEMP")); while ($ob2 = $res2->GetNext()) { if(empty( $ob2['VALUE'])) { $VALUES[] = false; }else{ $VALUES[] = self::getIdAnalogByXML_ID($ob2['VALUE']) ; } } //убрали флаг, в аналоги занесли айдишники аналогов CIBlockElement::SetPropertyValuesEx($ID, self::IBLOCK_ID, array('ANALOGI' => $VALUES)); CIBlockElement::SetPropertyValuesEx($ID, self::IBLOCK_ID, array('ANALOGI_FLAG' => 0)); } } } //каждый шаг мы заполняем временный аналог ANALOGI_TEMP и выставляем флаг ANALOGI_FLAG AddEventHandler('catalog', 'OnSuccessCatalogImport1C', 'customCatalogImportStep'); function customCatalogImportStep($arParams, $arFields) { if (file_exists($arFields)) { Provider1c::loadXml1c($arFields); } //file_put_contents($_SERVER["DOCUMENT_ROOT"]."/1c_log.log", date("d-m-Y")."; SESSION=".print_r($_SESSION,1)."; request ".print_r($_REQUEST,1)." pararm".print_r($arParams,1)." arFields ".print_r($arFields,1).";\n", FILE_APPEND); } // AddEventHandler('catalog', 'OnCompleteCatalogImport1C', 'CompleteCatalogImport1C'); function CompleteCatalogImport1C() { Provider1c::ReloadFromTemp(); } |
В итоге, в идеале, мы можем провести всего 2 выгрузки из 1с. 1-я логируется и мы получаем все xml Для теста. 2-я проверяет. А правильно ли наши обработчики работают.