1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
cml2.php
См. документацию.
1<?php
2
9
10IncludeModuleLangFile(__FILE__);
11
13{
14 public const IBLOCK_CACHE_FREEZE = 'D';
15 public const IBLOCK_CACHE_FINAL = 'F';
16 public const IBLOCK_CACHE_HIT = 'H';
17 public const IBLOCK_CACHE_NORMAL = 'N';
18
19 var $LAST_ERROR = "";
21 var $next_step = false;
22 var $files_dir = false;
23 var $use_offers = true;
24 var $force_offers = false;
26 var $use_crc = true;
27
28 var $preview = false;
29 var $detail = false;
30 var $iblock_resize = false;
31
33 var $_xml_file = null;
34
35 var $bCatalog = false;
36 var $isCatalogIblock = false;
46 var $mess = array();
47
52 var $arLinkedProps = false;
53
54 var $translit_on_add = false;
57 var $skip_root_section = false;
59
60 protected $activeStores = array();
61
62 protected $iblockCacheMode = self::IBLOCK_CACHE_NORMAL;
63
64 private $bitrix24mode = null;
65
66 protected $currentUserId = null;
67
68 protected $currencyIncluded = null;
69
70 protected array $productSizes = [
71 'WIDTH',
72 'LENGTH',
73 'HEIGHT',
74 ];
75
77 {
78 $defaultParams = array(
79 "files_dir" => false,
80 "use_crc" => true,
81 "preview" => false,
82 "detail" => false,
83 "use_offers" => false,
84 "force_offers" => false,
85 "use_iblock_type_id" => false,
86 "table_name" => "b_xml_tree",
87 "translit_on_add" => false,
88 "translit_on_update" => false,
89 "translit_params" => array(
90 "max_len" => 255,
91 "change_case" => 'L', // 'L' - toLower, 'U' - toUpper, false - do not change
92 "replace_space" => '-',
93 "replace_other" => '-',
94 "delete_repeat_replace" => true,
95 ),
96 "skip_root_section" => false,
97 "disable_change_price_name" => false,
98 "iblock_cache_mode" => self::IBLOCK_CACHE_NORMAL
99 );
100 foreach($defaultParams as $key => $value)
101 if(!array_key_exists($key, $params))
102 $params[$key] = $value;
103
104 $this->Init($next_step,
105 $params["files_dir"],
106 $params["use_crc"],
107 $params["preview"],
108 $params["detail"],
109 $params["use_offers"],
110 $params["use_iblock_type_id"],
111 $params["table_name"]
112 );
113
114 if($params["translit_on_add"])
115 $this->translit_on_add = $params["translit_params"];
116 if($params["translit_on_update"])
117 $this->translit_on_update = $params["translit_params"];
118 if ($params["disable_change_price_name"])
119 $this->disable_change_price_name = $params["disable_change_price_name"];
120
121 $this->skip_root_section = ($params["skip_root_section"] === true);
122 $this->force_offers = ($params["force_offers"] === true);
123
124 if (
125 $params['iblock_cache_mode'] == self::IBLOCK_CACHE_FREEZE
126 || $params['iblock_cache_mode'] == self::IBLOCK_CACHE_FINAL
127 || $params['iblock_cache_mode'] == self::IBLOCK_CACHE_HIT
128 || $params['iblock_cache_mode'] == self::IBLOCK_CACHE_NORMAL
129 )
130 {
131 $this->iblockCacheMode = $params['iblock_cache_mode'];
132 }
133 }
134
135 function Init(&$next_step, $files_dir = false, $use_crc = true, $preview = false, $detail = false, $use_offers = false, $use_iblock_type_id = false, $table_name = "b_xml_tree")
136 {
137 global $USER;
138 $this->currentUserId = (isset($USER) && $USER instanceof CUser ? (int)$USER->GetID() : 0);
139
140 $this->next_step = &$next_step;
141 $this->files_dir = $files_dir;
142 $this->use_offers = $use_offers;
143 $this->use_iblock_type_id = $use_iblock_type_id;
144 $this->use_crc = $use_crc;
145
146 $this->_xml_file = new CIBlockXMLFile($table_name);
147
148 if(!is_array($preview) && $preview)
149 $this->iblock_resize = true;
150
151 if(is_array($preview) && count($preview)==2)
152 $this->preview = $preview;
153 else
154 $this->preview = false;
155
156 if(is_array($detail) && count($detail)==2)
157 $this->detail = $detail;
158 else
159 $this->detail = false;
160
161 $this->bCatalog = Loader::includeModule('catalog');
162 $this->currencyIncluded = Loader::includeModule('currency');
163 $this->bitrix24mode = ModuleManager::isModuleInstalled('bitrix24');
164 $this->arProperties = array();
165 $this->PROPERTY_MAP = array();
166 if (isset($this->next_step["IBLOCK_ID"]) && $this->next_step["IBLOCK_ID"] > 0)
167 {
168 $obProperty = new CIBlockProperty;
169 $rsProperties = $obProperty->GetList(array(), array("IBLOCK_ID"=>$this->next_step["IBLOCK_ID"], "ACTIVE"=>"Y"));
170 while($arProperty = $rsProperties->Fetch())
171 {
172 $this->PROPERTY_MAP[$arProperty["XML_ID"]] = $arProperty["ID"];
173 $this->arProperties[$arProperty["ID"]] = $arProperty;
174 }
175
176 if ($this->bCatalog)
177 {
179 'select' => array('IBLOCK_ID'),
180 'filter' => array('=IBLOCK_ID' => $this->next_step["IBLOCK_ID"])
181 ));
182 if ($catalogData = $catalogsIterator->fetch())
183 $this->isCatalogIblock = true;
184 unset($catalogData, $catalogsIterator);
185 }
186 }
187
188 if (isset($this->next_step['lang']) && $this->next_step['lang'])
189 {
190 $this->mess = Main\Localization\Loc::loadLanguageFile(__FILE__, $this->next_step['lang']);
191 }
192
193 $this->arTempFiles = array();
194 $this->arLinkedProps = false;
195 }
196
197 public static function CheckIfFileIsCML($file_name)
198 {
199 if(file_exists($file_name) && is_file($file_name))
200 {
201 $fp = fopen($file_name, "rb");
202 if(is_resource($fp))
203 {
204 $header = fread($fp, 1024);
205 fclose($fp);
206
207 if(preg_match("/<"."\\?XML[^>]{1,}encoding=[\"']([^>\"']{1,})[\"'][^>]{0,}\\?".">/i", $header, $matches))
208 {
209 if(strtoupper($matches[1]) !== strtoupper(LANG_CHARSET))
211 }
212
213 foreach(array(LANGUAGE_ID, "en", "ru") as $lang)
214 {
216 if(strpos($header, "<".$mess["IBLOCK_XML2_COMMERCE_INFO"]) !== false)
217 return $lang;
218 }
219 }
220 }
221 return false;
222 }
223
224 public function isTemporaryTablesExist(): bool
225 {
226 return $this->_xml_file->IsExistTemporaryTable();
227 }
228
229 public function isTemporaryTablesStructureCorrect(): bool
230 {
231 return $this->_xml_file->isTableStructureCorrect();
232 }
233
234 public function truncateTemporaryTables(): bool
235 {
236 return $this->_xml_file->truncateTemporaryTables();
237 }
238
240 {
241 return $this->_xml_file->DropTemporaryTables();
242 }
243
245 {
246 return $this->_xml_file->CreateTemporaryTables();
247 }
248
250 {
251 return $this->_xml_file->initializeTemporaryTables();
252 }
253
255 {
256 return $this->_xml_file->IndexTemporaryTables();
257 }
258
259 function ReadXMLToDatabase($fp, &$NS, $time_limit=0, $read_size = 1024)
260 {
261 return $this->_xml_file->ReadXMLToDatabase($fp, $NS, $time_limit, $read_size);
262 }
263
264 public function GetRoot()
265 {
266 return $this->_xml_file->GetRoot();
267 }
268
269 function StartSession($sess_id)
270 {
271 return $this->_xml_file->StartSession($sess_id);
272 }
273
274 function GetSessionRoot()
275 {
276 return $this->_xml_file->GetSessionRoot();
277 }
278
279 function EndSession()
280 {
281 return $this->_xml_file->EndSession();
282 }
283
284 public function GetFilePosition()
285 {
286 return $this->_xml_file->GetFilePosition();
287 }
288
289 function CleanTempFiles()
290 {
291 foreach($this->arTempFiles as $file)
292 {
293 if (file_exists($file))
294 unlink($file);
295 }
296 $this->arTempFiles = array();
297 }
298
299 public function MakeFileArray($file, $fields = [])
300 {
301 if (is_array($file))
302 {
303 $url = (string)($file[$this->mess['IBLOCK_XML2_BX_URL']] ?? '');
304 if ($url !== '')
305 {
306 if (Loader::includeModule('clouds'))
307 {
309 if (is_object($bucket) && $bucket->READ_ONLY === 'Y')
310 {
311 return [
312 'name' => $file[$this->mess['IBLOCK_XML2_BX_ORIGINAL_NAME']],
313 'description' => $file[$this->mess['IBLOCK_XML2_DESCRIPTION']],
314 'tmp_name' => $url,
315 'file_size' => $file[$this->mess['IBLOCK_XML2_BX_FILE_SIZE']],
316 'width' => $file[$this->mess['IBLOCK_XML2_BX_FILE_WIDTH']],
317 'height' => $file[$this->mess['IBLOCK_XML2_BX_FILE_HEIGHT']],
318 'type' => $file[$this->mess['IBLOCK_XML2_BX_FILE_CONTENT_TYPE']],
319 'content' => '', //Fake field in order to avoid warning
320 'bucket' => $bucket,
321 ];
322 }
323 }
324
325 return CFile::MakeFileArray($this->URLEncode($url)); //Download from the cloud
326 }
327 }
328 else
329 {
330 $file = (string)$file;
331 if ($file !== '')
332 {
333 try
334 {
335 $filePath = Main\IO\Path::normalize($file);
336 }
338 {
339 $filePath = '';
340 }
341 if ($filePath === '/')
342 {
343 $filePath = '';
344 }
345 if ($filePath !== '')
346 {
347 $externalId = md5($filePath);
348 $fullPath = Main\IO\Path::combine($this->files_dir, $filePath);
349 if (is_file($fullPath))
350 {
351 return CFile::MakeFileArray($fullPath, false, false, $externalId);
352 }
353 $fileId = (int)$this->CheckFileByName($externalId, $fields);
354 if ($fileId > 0)
355 {
356 return CFile::MakeFileArray($fileId);
357 }
358 }
359 }
360 }
361
362 return [
363 'tmp_name' => '',
364 'del' => 'Y',
365 ];
366 }
367
368 function URLEncode($str)
369 {
370 $strEncodedURL = '';
371 $arUrlComponents = preg_split("#(://|/|\\?|=|&)#", $str, -1, PREG_SPLIT_DELIM_CAPTURE);
372 foreach($arUrlComponents as $i => $part_of_url)
373 {
374 if($i % 2)
375 $strEncodedURL .= $part_of_url;
376 else
377 $strEncodedURL .= urlencode($part_of_url);
378 }
379 return $strEncodedURL;
380 }
381
382 function CheckFileByName($file, $fields = null)
383 {
384 $external_id = $file;
385 $fileName = bx_basename($file);
386 if (!empty($fields) && $fileName != "")
387 {
388 if (empty($this->arElementFiles))
389 {
390 $this->arElementFiles = array();
391 $ID = array();
392 foreach ($this->arElementFilesId as $fileId)
393 {
394 foreach($fileId as $value)
395 $ID[$value] = $value;
396 }
397 $rsFile = CFile::GetList(array(), array(
398 "@ID" => implode(",", $ID),
399 ));
400 while ($arFile = $rsFile->Fetch())
401 {
402 $arFile["~ORIGINAL_NAME"] = preg_replace("/(\\.resize[0-9]+\\.)/", ".", $arFile["ORIGINAL_NAME"]);
403 $this->arElementFiles[$arFile["ID"]] = $arFile;
404 }
405 }
406
407 foreach ($fields as $fieldId)
408 {
409 if (isset($this->arElementFilesId[$fieldId]))
410 {
411 foreach ($this->arElementFilesId[$fieldId] as $fileId)
412 {
413 if (isset($this->arElementFiles[$fileId]))
414 {
415 if ($this->arElementFiles[$fileId]["EXTERNAL_ID"] === $external_id)
416 return $fileId;
417 if ($this->arElementFiles[$fileId]["~ORIGINAL_NAME"] === $fileName)
418 return $fileId;
419 }
420 }
421 }
422 }
423 }
424 return false;
425 }
426
427 function ResizePicture($file, $resize, $primaryField, $secondaryField = "")
428 {
429 static $errorFile = array("tmp_name"=>"", "del"=>"Y");
430 $external_id = md5($file);
431 if($file == '')
432 {
433 return $errorFile;
434 }
435
436 if(file_exists($this->files_dir.$file) && is_file($this->files_dir.$file))
437 {
438 $file = $this->files_dir.$file;
439 }
440 elseif(file_exists($file) && is_file($file))
441 {
442 }
443 elseif(($fileId = $this->CheckFileByName($external_id, array($primaryField))) > 0)
444 {
445 return CFile::MakeFileArray($fileId);
446 }
447 elseif($secondaryField && ($fileId = $this->CheckFileByName($external_id, array($secondaryField))) > 0)
448 {
449 $storedFile = CFile::MakeFileArray($fileId);
450 if (isset($storedFile['tmp_name']))
451 {
452 $tempFile = CTempFile::GetFileName(bx_basename($storedFile["tmp_name"]));
453 CheckDirPath($tempFile);
454 if (copy($storedFile["tmp_name"], $tempFile))
455 {
456 $storedFile["tmp_name"] = $tempFile;
457 return $storedFile;
458 }
459 else
460 {
461 return $errorFile;
462 }
463 }
464 else
465 {
466 return $errorFile;
467 }
468 }
469 else
470 {
471 return $errorFile;
472 }
473
474 if(!is_array($resize) || !preg_match("#(\\.)([^./\\\\]+?)$#", $file))
475 {
476 $arFile = CFile::MakeFileArray($file, false, false, $external_id);
477 if($arFile && $this->iblock_resize)
478 $arFile["COPY_FILE"] = "Y";
479 return $arFile;
480 }
481
482 $i = 1;
483 while(file_exists(preg_replace("#(\\.)([^./\\\\]+?)$#", ".resize".$i.".\\2", $file)))
484 $i++;
485 $new_file = preg_replace("#(\\.)([^./\\\\]+?)$#", ".resize".$i.".\\2", $file);
486
487 if (!CFile::ResizeImageFile($file, $new_file, array("width"=>$resize[0], "height"=>$resize[1])))
488 return CFile::MakeFileArray($file, false, false, $external_id);
489
490 $this->arTempFiles[] = $new_file;
491
492 return CFile::MakeFileArray($new_file, false, false, $external_id);
493 }
494
495 function GetIBlockByXML_ID($XML_ID)
496 {
497 if($XML_ID <> '')
498 {
499 $obIBlock = new CIBlock;
500 $rsIBlock = $obIBlock->GetList(array(), array("XML_ID"=>$XML_ID, "CHECK_PERMISSIONS" => "N"));
501 if($arIBlock = $rsIBlock->Fetch())
502 return $arIBlock["ID"];
503 else
504 return false;
505 }
506 return false;
507 }
508
510 {
511 if (!isset($this->arSectionCache[$IBLOCK_ID]))
512 $this->arSectionCache[$IBLOCK_ID] = array();
513 if (!isset($this->arSectionCache[$IBLOCK_ID][$XML_ID]))
514 {
515 $rsSection = CIBlockSection::GetList(array(), array("IBLOCK_ID"=>$IBLOCK_ID, "EXTERNAL_ID"=>$XML_ID), false, array('ID'));
516 if($arSection = $rsSection->Fetch())
517 $this->arSectionCache[$IBLOCK_ID][$XML_ID] = $arSection["ID"];
518 else
519 $this->arSectionCache[$IBLOCK_ID][$XML_ID] = false;
520 unset($rsSection);
521 unset($arSection);
522 }
523 return $this->arSectionCache[$IBLOCK_ID][$XML_ID];
524 }
525
527 {
528 if($XML_ID == '')
529 return false;
530 if (!isset($this->arElementCache[$IBLOCK_ID]))
531 $this->arElementCache[$IBLOCK_ID] = array();
532 if (!isset($this->arElementCache[$IBLOCK_ID][$XML_ID]))
533 {
534 $obElement = new CIBlockElement;
535 $rsElement = $obElement->GetList(
536 array('ID' => 'ASC'),
537 array("=XML_ID" => $XML_ID, "IBLOCK_ID" => $IBLOCK_ID),
538 false, false,
539 array("ID", "XML_ID")
540 );
541 if($arElement = $rsElement->Fetch())
542 $this->arElementCache[$IBLOCK_ID][$XML_ID] = $arElement["ID"];
543 else
544 $this->arElementCache[$IBLOCK_ID][$XML_ID] = false;
545 }
546
547 return $this->arElementCache[$IBLOCK_ID][$XML_ID];
548 }
549
550 function GetEnumByXML_ID($PROP_ID, $XML_ID)
551 {
552 if($XML_ID == '')
553 return "";
554
555 if(!isset($this->arEnumCache[$PROP_ID]))
556 $this->arEnumCache[$PROP_ID] = array();
557
558 if(!isset($this->arEnumCache[$PROP_ID][$XML_ID]))
559 {
561 array(),
562 array("EXTERNAL_ID" => $XML_ID, "PROPERTY_ID" => $PROP_ID)
563 );
564 if($arEnum = $rsEnum->Fetch())
565 $this->arEnumCache[$PROP_ID][$XML_ID] = $arEnum["ID"];
566 else
567 $this->arEnumCache[$PROP_ID][$XML_ID] = false;
568 }
569
570 return $this->arEnumCache[$PROP_ID][$XML_ID];
571 }
572
573 function GetSectionEnumByXML_ID($FIELD_ID, $XML_ID)
574 {
575 if($XML_ID == '')
576 return "";
577
578 $cacheId = "E".$FIELD_ID;
579 if(!isset($this->arEnumCache[$cacheId]))
580 $this->arEnumCache[$cacheId] = array();
581
582 if(!isset($this->arEnumCache[$cacheId][$XML_ID]))
583 {
584 $obEnum = new CUserFieldEnum;
585 $rsEnum = $obEnum->GetList(array(), array(
586 "USER_FIELD_ID" => $FIELD_ID,
587 "XML_ID" => $XML_ID,
588 ));
589 if($arEnum = $rsEnum->Fetch())
590 $this->arEnumCache[$cacheId][$XML_ID] = $arEnum["ID"];
591 else
592 $this->arEnumCache[$cacheId][$XML_ID] = false;
593 }
594
595 if ($this->arEnumCache[$cacheId][$XML_ID])
596 return $this->arEnumCache[$cacheId][$XML_ID];
597 else
598 return $XML_ID;
599 }
600
602 {
603 $obProperty = new CIBlockProperty;
604 $rsProperty = $obProperty->GetList(array(), array("IBLOCK_ID"=>$IBLOCK_ID, "XML_ID"=>$XML_ID));
605 if($arProperty = $rsProperty->Fetch())
606 return $arProperty["ID"];
607 else
608 return false;
609 }
610
611 function CheckProperty($IBLOCK_ID, $code, $xml_name)
612 {
613 $obProperty = new CIBlockProperty;
614 $rsProperty = $obProperty->GetList(array(), array("IBLOCK_ID"=>$IBLOCK_ID, "XML_ID"=>$code));
615 $dbProperty = $rsProperty->Fetch();
616 if(!$dbProperty)
617 {
618 $arProperty = array(
619 "IBLOCK_ID" => $IBLOCK_ID,
620 "NAME" => is_array($xml_name)? $xml_name["NAME"]: $xml_name,
621 "CODE" => $code,
622 "XML_ID" => $code,
623 "MULTIPLE" => "N",
624 "PROPERTY_TYPE" => "S",
625 "ACTIVE" => "Y",
626 );
627 if(is_array($xml_name))
628 {
629 foreach($xml_name as $name => $value)
630 $arProperty[$name] = $value;
631 }
632 $ID = $obProperty->Add($arProperty);
633 if(!$ID)
634 return $obProperty->LAST_ERROR;
635 }
636 elseif (is_array($xml_name))
637 {
638 $update = array();
639 foreach($xml_name as $name => $value)
640 {
641 if (($name != "NAME") && ($dbProperty[$name] != $value))
642 {
643 $update[$name] = $value;
644 }
645 }
646 if ($update)
647 {
648 $obProperty->Update($dbProperty["ID"], $update);
649 }
650 }
651 return true;
652 }
653
654 function CheckTax($title, $rate)
655 {
656 if ($rate === null)
657 {
658 $taxName = GetMessage('IBLOCK_NO_VAT_TITLE');
659 }
660 else
661 {
662 $taxName = $title . " " . $rate . "%";
663 }
664
665 if (isset($this->arTaxCache[$taxName]))
666 {
667 return $this->arTaxCache[$taxName];
668 }
669
670 $vatParams = [
671 'select' => ['ID'],
672 ];
673
674 if ($rate === null)
675 {
676 $vatParams['filter'] = [
677 '=EXCLUDE_VAT' => 'Y',
678 ];
679 }
680 else
681 {
682 $vatParams['filter'] = [
683 '=NAME' => $taxName,
684 '=EXCLUDE_VAT' => 'N',
685 '=RATE' => $rate,
686 ];
687 }
688
689 $getResult = \Bitrix\Catalog\Model\Vat::getList($vatParams)->fetch();
690 if (isset($getResult['ID']))
691 {
692 $vatId = $getResult['ID'];
693 $this->arTaxCache[$taxName] = $vatId;
694 return $vatId;
695 }
696
697 $addParams = [
698 'ACTIVE' => 'Y',
699 'NAME' => $taxName,
700 ];
701
702 if ($rate === null)
703 {
704 $addParams['EXCLUDE_VAT'] = 'Y';
705 }
706 else
707 {
708 $addParams['RATE'] = $rate;
709 }
710
711 $this->arTaxCache[$taxName] = \Bitrix\Catalog\Model\Vat::add($addParams)->getId();
712
713 return $this->arTaxCache[$taxName];
714 }
715
717 {
718 global $CML2_CURRENCY;
719
720 if($currency==$this->mess["IBLOCK_XML2_RUB"])
721 {
722 $currency="RUB";
723 }
724 elseif(!preg_match("/^[a-zA-Z]+$/", $currency))
725 {
726 if(
727 is_array($CML2_CURRENCY)
728 && isset($CML2_CURRENCY[$currency])
729 && is_string($CML2_CURRENCY[$currency])
730 && preg_match("/^[a-zA-Z0-9]+$/", $CML2_CURRENCY[$currency])
731 )
732 {
733 $currency = $CML2_CURRENCY[$currency];
734 }
735 else
736 {
737 $currency="RUB";
738 $this->LAST_ERROR = GetMessage("IBLOCK_XML2_CURRENCY_ERROR");
739 }
740 }
741
742 if(!isset($this->arCurrencyCache[$currency]))
743 {
744 if($this->bCatalog && $this->currencyIncluded)
745 {
747 "CURRENCY" => $currency,
748 ));
749 }
750 $this->arCurrencyCache[$currency] = true;
751 }
752
753 return $currency;
754 }
755
757 {
758 $obType = new CIBlockType;
759 $rsType = $obType->GetByID($ID);
760 if($arType = $rsType->Fetch())
761 {
762 return $arType["ID"];
763 }
764 else
765 {
766 $rsType = $obType->GetByID("1c_catalog");
767 if($arType = $rsType->Fetch())
768 {
769 return $arType["ID"];
770 }
771 else
772 {
773 $result = $obType->Add(array(
774 "ID" => "1c_catalog",
775 "SECTIONS" => "Y",
776 "LANG" => array(
777 "ru" => array(
778 "NAME" => GetMessage("IBLOCK_XML2_CATALOG_NAME"),
779 "SECTION_NAME" => GetMessage("IBLOCK_XML2_CATALOG_SECTION_NAME"),
780 "ELEMENT_NAME" => GetMessage("IBLOCK_XML2_CATALOG_ELEMENT_NAME"),
781 ),
782 ),
783 ));
784 if($result)
785 return $result;
786 else
787 return false;
788 }
789 }
790 }
791
792 function CheckSites($arSite)
793 {
794 $arResult = array();
795 if(!is_array($arSite))
796 $arSite = array($arSite);
797 foreach($arSite as $site_id)
798 {
799 if($site_id <> '')
800 {
801 $rsSite = CSite::GetByID($site_id);
802 if($rsSite->Fetch())
804 }
805 }
806 if(!defined("ADMIN_SECTION"))
807 {
808 $rsSite = CSite::GetByID(SITE_ID);
809 if($rsSite->Fetch())
810 $arResult[] = SITE_ID;
811 }
812 if(count($arResult)<1)
813 $arResult[] = CSite::GetDefSite();
814 return $arResult;
815 }
816
817 function ImportMetaData($xml_root_id, $IBLOCK_TYPE, $IBLOCK_LID, $bUpdateIBlock = true)
818 {
819 global $APPLICATION;
820
821 $rs = $this->_xml_file->GetList(
822 array("ID" => "asc"),
823 array("ID" => $xml_root_id),
824 array("ID", "NAME", "ATTRIBUTES")
825 );
826 $ar = $rs->Fetch();
827
828 if ($ar)
829 {
830 foreach(array(LANGUAGE_ID, "en", "ru") as $lang)
831 {
833 if($ar["NAME"] === $mess["IBLOCK_XML2_COMMERCE_INFO"])
834 {
835 $this->mess = $mess;
836 $this->next_step["lang"] = $lang;
837 }
838 }
839 $xml_root_id = $ar["ID"];
840 }
841
842 if($ar && ($ar["ATTRIBUTES"] <> ''))
843 {
844 $info = unserialize($ar["ATTRIBUTES"], ['allowed_classes' => false]);
845 if(is_array($info) && array_key_exists($this->mess["IBLOCK_XML2_SUM_FORMAT"], $info))
846 {
847 if(preg_match("#".$this->mess["IBLOCK_XML2_SUM_FORMAT_DELIM"]."=(.);{0,1}#", $info[$this->mess["IBLOCK_XML2_SUM_FORMAT"]], $match))
848 {
849 $this->next_step["sdp"] = $match[1];
850 }
851 }
852 }
853
854 $meta_data_xml_id = false;
855 $XML_ELEMENTS_PARENT = false;
856 $XML_SECTIONS_PARENT = false;
857 $XML_PROPERTIES_PARENT = false;
858 $XML_SECTIONS_PROPERTIES_PARENT = false;
859 $XML_PRICES_PARENT = false;
860 $XML_STORES_PARENT = false;
861 $XML_BASE_UNITS_PARENT = false;
862 $XML_SECTION_PROPERTIES = false;
863 $arIBlock = array();
864
865 $this->next_step["bOffer"] = false;
866 $rs = $this->_xml_file->GetList(
867 array(),
868 array("PARENT_ID" => $xml_root_id, "NAME" => $this->mess["IBLOCK_XML2_CATALOG"]),
869 array("ID", "ATTRIBUTES")
870 );
871 $ar = $rs->Fetch();
872 if(!$ar)
873 {
874 $rs = $this->_xml_file->GetList(
875 array(),
876 array("PARENT_ID" => $xml_root_id, "NAME" => $this->mess["IBLOCK_XML2_OFFER_LIST"]),
877 array("ID", "ATTRIBUTES")
878 );
879 $ar = $rs->Fetch();
880 $this->next_step["bOffer"] = true;
881 }
882 if(!$ar)
883 {
884 $rs = $this->_xml_file->GetList(
885 array(),
886 array("PARENT_ID" => $xml_root_id, "NAME" => $this->mess["IBLOCK_XML2_OFFERS_CHANGE"]),
887 array("ID", "ATTRIBUTES")
888 );
889 $ar = $rs->Fetch();
890 $this->next_step["bOffer"] = true;
891 $this->next_step["bUpdateOnly"] = true;
892 $bUpdateIBlock = false;
893 }
894
895 if ($this->next_step["bOffer"] && !$this->bCatalog)
896 return GetMessage('IBLOCK_XML2_MODULE_CATALOG_IS_ABSENT');
897
898 if($ar)
899 {
900 if($ar["ATTRIBUTES"] <> '')
901 {
902 $attrs = unserialize($ar["ATTRIBUTES"], ['allowed_classes' => false]);
903 if (is_array($attrs))
904 {
905 if (isset($attrs[$this->mess["IBLOCK_XML2_UPDATE_ONLY"]]))
906 {
907 $this->next_step["bUpdateOnly"] = $attrs[$this->mess["IBLOCK_XML2_UPDATE_ONLY"]] === "true"
908 || (int)$attrs[$this->mess["IBLOCK_XML2_UPDATE_ONLY"]] > 0
909 ;
910 }
911 }
912 }
913
914 $rs = $this->_xml_file->GetList(
915 array("ID" => "asc"),
916 array("PARENT_ID" => $ar["ID"])
917 );
918 while($ar = $rs->Fetch())
919 {
920 if(isset($ar["VALUE_CLOB"]))
921 $ar["VALUE"] = $ar["VALUE_CLOB"];
922
923 $trueValue = $ar['VALUE'] === 'true' || (int)$ar['VALUE'] > 0;
924
925 if($ar["NAME"] == $this->mess["IBLOCK_XML2_ID"])
926 $arIBlock["XML_ID"] = ($this->use_iblock_type_id? $IBLOCK_TYPE."-": "").$ar["VALUE"];
927 elseif($ar["NAME"] == $this->mess["IBLOCK_XML2_CATALOG_ID"])
928 $arIBlock["CATALOG_XML_ID"] = ($this->use_iblock_type_id? $IBLOCK_TYPE."-": "").$ar["VALUE"];
929 elseif($ar["NAME"] == $this->mess["IBLOCK_XML2_NAME"])
930 $arIBlock["NAME"] = $ar["VALUE"];
931 elseif($ar["NAME"] == $this->mess["IBLOCK_XML2_DESCRIPTION"])
932 {
933 $arIBlock["DESCRIPTION"] = $ar["VALUE"];
934 $arIBlock["DESCRIPTION_TYPE"] = "html";
935 }
936 elseif($ar["NAME"] == $this->mess["IBLOCK_XML2_POSITIONS"] || $ar["NAME"] == $this->mess["IBLOCK_XML2_OFFERS"])
937 $XML_ELEMENTS_PARENT = $ar["ID"];
938 elseif($ar["NAME"] == $this->mess["IBLOCK_XML2_PRICE_TYPES"])
939 $XML_PRICES_PARENT = $ar["ID"];
940 elseif($ar["NAME"] == $this->mess["IBLOCK_XML2_STORES"])
941 $XML_STORES_PARENT = $ar["ID"];
942 elseif($ar["NAME"] == $this->mess["IBLOCK_XML2_BASE_UNITS"])
943 $XML_BASE_UNITS_PARENT = $ar["ID"];
944 elseif($ar["NAME"] == $this->mess["IBLOCK_XML2_METADATA_ID"])
945 $meta_data_xml_id = $ar["VALUE"];
946 elseif($ar["NAME"] == $this->mess["IBLOCK_XML2_UPDATE_ONLY"])
947 $this->next_step["bUpdateOnly"] = $trueValue;
948 elseif($ar["NAME"] == $this->mess["IBLOCK_XML2_BX_CODE"])
949 $arIBlock["CODE"] = $ar["VALUE"];
950 elseif($ar["NAME"] == $this->mess["IBLOCK_XML2_BX_API_CODE"])
951 $arIBlock["API_CODE"] = $ar["VALUE"];
952 elseif($ar["NAME"] == $this->mess["IBLOCK_XML2_BX_SORT"])
953 $arIBlock["SORT"] = $ar["VALUE"];
954 elseif($ar["NAME"] == $this->mess["IBLOCK_XML2_BX_LIST_URL"])
955 $arIBlock["LIST_PAGE_URL"] = $ar["VALUE"];
956 elseif($ar["NAME"] == $this->mess["IBLOCK_XML2_BX_DETAIL_URL"])
957 $arIBlock["DETAIL_PAGE_URL"] = $ar["VALUE"];
958 elseif($ar["NAME"] == $this->mess["IBLOCK_XML2_BX_SECTION_URL"])
959 $arIBlock["SECTION_PAGE_URL"] = $ar["VALUE"];
960 elseif($ar["NAME"] == $this->mess["IBLOCK_XML2_BX_CANONICAL_URL"])
961 $arIBlock["CANONICAL_PAGE_URL"] = $ar["VALUE"];
962 elseif($ar["NAME"] == $this->mess["IBLOCK_XML2_BX_INDEX_ELEMENTS"])
963 $arIBlock["INDEX_ELEMENT"] = $trueValue ? "Y": "N";
964 elseif($ar["NAME"] == $this->mess["IBLOCK_XML2_BX_INDEX_SECTIONS"])
965 $arIBlock["INDEX_SECTION"] = $trueValue ? "Y": "N";
966 elseif($ar["NAME"] == $this->mess["IBLOCK_XML2_BX_SECTIONS_NAME"])
967 $arIBlock["SECTIONS_NAME"] = $ar["VALUE"];
968 elseif($ar["NAME"] == $this->mess["IBLOCK_XML2_BX_SECTION_NAME"])
969 $arIBlock["SECTION_NAME"] = $ar["VALUE"];
970 elseif($ar["NAME"] == $this->mess["IBLOCK_XML2_BX_ELEMENTS_NAME"])
971 $arIBlock["ELEMENTS_NAME"] = $ar["VALUE"];
972 elseif($ar["NAME"] == $this->mess["IBLOCK_XML2_BX_ELEMENT_NAME"])
973 $arIBlock["ELEMENT_NAME"] = $ar["VALUE"];
974 elseif($ar["NAME"] == $this->mess["IBLOCK_XML2_BX_PICTURE"])
975 {
976 if($ar["VALUE"] <> '')
977 $arIBlock["PICTURE"] = $this->MakeFileArray($ar["VALUE"]);
978 else
979 $arIBlock["PICTURE"] = $this->MakeFileArray($this->_xml_file->GetAllChildrenArray($ar["ID"]));
980 }
981 elseif($ar["NAME"] == $this->mess["IBLOCK_XML2_BX_WORKFLOW"])
982 $arIBlock["WORKFLOW"] = ($ar["VALUE"]=="true") || intval($ar["VALUE"])? "Y": "N";
983 elseif($ar["NAME"] == $this->mess["IBLOCK_XML2_INHERITED_TEMPLATES"])
984 {
985 $arIBlock["IPROPERTY_TEMPLATES"] = array();
986 $arTemplates = $this->_xml_file->GetAllChildrenArray($ar["ID"]);
987 foreach($arTemplates as $TEMPLATE)
988 {
989 $id = $TEMPLATE[$this->mess["IBLOCK_XML2_ID"]];
990 $template = $TEMPLATE[$this->mess["IBLOCK_XML2_VALUE"]];
991 if($id <> '' && $template <> '')
992 $arIBlock["IPROPERTY_TEMPLATES"][$id] = $template;
993 }
994 }
995 elseif($ar["NAME"] == $this->mess["IBLOCK_XML2_LABELS"])
996 {
997 $arLabels = $this->_xml_file->GetAllChildrenArray($ar["ID"]);
998 foreach($arLabels as $arLabel)
999 {
1000 $id = $arLabel[$this->mess["IBLOCK_XML2_ID"]];
1001 $label = $arLabel[$this->mess["IBLOCK_XML2_VALUE"]];
1002 if($id <> '' && $label <> '')
1003 $arIBlock[$id] = $label;
1004 }
1005 }
1006 }
1007 if($this->next_step["bOffer"] && !$this->use_offers)
1008 {
1009 if (isset($arIBlock["CATALOG_XML_ID"]) && $arIBlock["CATALOG_XML_ID"] !== '')
1010 {
1011 $arIBlock["XML_ID"] = $arIBlock["CATALOG_XML_ID"];
1012 $this->next_step["bUpdateOnly"] = true;
1013 }
1014 }
1015
1016 $obIBlock = new CIBlock;
1017 $rsIBlocks = $obIBlock->GetList(array(), array("XML_ID"=>$arIBlock["XML_ID"]));
1018 $ar = $rsIBlocks->Fetch();
1019
1020 //Also check for non bitrix xml file
1021 if(!$ar && !array_key_exists("CODE", $arIBlock))
1022 {
1023 if($this->next_step["bOffer"] && $this->use_offers)
1024 $rsIBlocks = $obIBlock->GetList(array(), array("XML_ID"=>"FUTURE-1C-OFFERS"));
1025 else
1026 $rsIBlocks = $obIBlock->GetList(array(), array("XML_ID"=>"FUTURE-1C-CATALOG"));
1027 $ar = $rsIBlocks->Fetch();
1028 }
1029 if($ar)
1030 {
1031 if($bUpdateIBlock && (!$this->next_step["bOffer"] || $this->use_offers))
1032 {
1033 if($obIBlock->Update($ar["ID"], $arIBlock))
1034 $arIBlock["ID"] = $ar["ID"];
1035 else
1036 return $obIBlock->LAST_ERROR;
1037 }
1038 else
1039 {
1040 $arIBlock["ID"] = $ar["ID"];
1041 }
1042 }
1043 else
1044 {
1045 $arIBlock["IBLOCK_TYPE_ID"] = $this->CheckIBlockType($IBLOCK_TYPE);
1046 if(!$arIBlock["IBLOCK_TYPE_ID"])
1047 return GetMessage("IBLOCK_XML2_TYPE_ADD_ERROR");
1048 $arIBlock["GROUP_ID"] = array(2=>"R");
1049 $arIBlock["LID"] = $this->CheckSites($IBLOCK_LID);
1050 $arIBlock["ACTIVE"] = "Y";
1051 $arIBlock["WORKFLOW"] = "N";
1052 if (
1053 $this->translit_on_add
1054 && !array_key_exists("CODE", $arIBlock)
1055 )
1056 {
1057 $arIBlock["FIELDS"] = array(
1058 "CODE" => array( "DEFAULT_VALUE" => array(
1059 "TRANSLITERATION" => "Y",
1060 "TRANS_LEN" => $this->translit_on_add["max_len"],
1061 "TRANS_CASE" => $this->translit_on_add["change_case"],
1062 "TRANS_SPACE" => $this->translit_on_add["replace_space"],
1063 "TRANS_OTHER" => $this->translit_on_add["replace_other"],
1064 "TRANS_EAT" => $this->translit_on_add["delete_repeat_replace"]? "Y": "N",
1065 )),
1066 "SECTION_CODE" => array( "DEFAULT_VALUE" => array(
1067 "TRANSLITERATION" => "Y",
1068 "TRANS_LEN" => $this->translit_on_add["max_len"],
1069 "TRANS_CASE" => $this->translit_on_add["change_case"],
1070 "TRANS_SPACE" => $this->translit_on_add["replace_space"],
1071 "TRANS_OTHER" => $this->translit_on_add["replace_other"],
1072 "TRANS_EAT" => $this->translit_on_add["delete_repeat_replace"]? "Y": "N",
1073 )),
1074 );
1075 }
1076 $arIBlock["ID"] = $obIBlock->Add($arIBlock);
1077 if(!$arIBlock["ID"])
1078 return $obIBlock->LAST_ERROR;
1079 }
1080
1081 //Make this catalog
1082 if($this->bCatalog && $this->next_step["bOffer"])
1083 {
1084 $obCatalog = new CCatalog();
1085 $intParentID = $this->GetIBlockByXML_ID($arIBlock["CATALOG_XML_ID"] ?? '');
1086 if (0 < intval($intParentID) && $this->use_offers)
1087 {
1088 $mxSKUProp = $obCatalog->LinkSKUIBlock($intParentID,$arIBlock["ID"]);
1089 if (!$mxSKUProp)
1090 {
1091 if ($ex = $APPLICATION->GetException())
1092 {
1093 $result = $ex->GetString();
1094 return $result;
1095 }
1096 }
1097 else
1098 {
1099 $rs = CCatalog::GetList(array(),array("IBLOCK_ID"=>$arIBlock["ID"]));
1100 if($arOffer = $rs->Fetch())
1101 {
1102 $boolFlag = $obCatalog->Update($arIBlock["ID"],array('PRODUCT_IBLOCK_ID' => $intParentID,'SKU_PROPERTY_ID' => $mxSKUProp));
1103 }
1104 else
1105 {
1106 $boolFlag = $obCatalog->Add(array("IBLOCK_ID"=>$arIBlock["ID"], "YANDEX_EXPORT"=>"N", "SUBSCRIPTION"=>"N",'PRODUCT_IBLOCK_ID' => $intParentID,'SKU_PROPERTY_ID' => $mxSKUProp));
1107 }
1108 if (!$boolFlag)
1109 {
1110 if ($ex = $APPLICATION->GetException())
1111 {
1112 $result = $ex->GetString();
1113 return $result;
1114 }
1115 }
1116 }
1117 }
1118 else
1119 {
1120 $rs = CCatalog::GetList(array(),array("IBLOCK_ID"=>$arIBlock["ID"]));
1121 if(!($rs->Fetch()))
1122 {
1123 $boolFlag = $obCatalog->Add(array("IBLOCK_ID"=>$arIBlock["ID"], "YANDEX_EXPORT"=>"N", "SUBSCRIPTION"=>"N"));
1124 if (!$boolFlag)
1125 {
1126 if ($ex = $APPLICATION->GetException())
1127 {
1128 $result = $ex->GetString();
1129 return $result;
1130 }
1131 }
1132 }
1133 }
1134 }
1135
1136 //For non bitrix xml file
1137 //Check for mandatory properties and add them as necessary
1138 if(!array_key_exists("CODE", $arIBlock))
1139 {
1140 $arProperties = [];
1141 $arProperties['CML2_BAR_CODE'] = GetMessage('IBLOCK_XML2_BAR_CODE');
1142 $arProperties['CML2_ARTICLE'] = GetMessage('IBLOCK_XML2_ARTICLE');
1143 $arProperties['CML2_ATTRIBUTES'] = [
1144 'NAME' => GetMessage('IBLOCK_XML2_ATTRIBUTES'),
1145 'MULTIPLE' => 'Y',
1146 'WITH_DESCRIPTION' => 'Y',
1147 'MULTIPLE_CNT' => 1,
1148 ];
1149 $arProperties['CML2_TRAITS'] = [
1150 'NAME' => GetMessage('IBLOCK_XML2_TRAITS'),
1151 'MULTIPLE' => 'Y',
1152 'WITH_DESCRIPTION' => 'Y',
1153 'MULTIPLE_CNT' => 1,
1154 ];
1155 $arProperties['CML2_BASE_UNIT'] = [
1156 'NAME' => GetMessage('IBLOCK_XML2_BASE_UNIT_NAME'),
1157 'WITH_DESCRIPTION' => 'Y',
1158 ];
1159 $arProperties['CML2_TAXES'] = [
1160 'NAME' => GetMessage('IBLOCK_XML2_TAXES'),
1161 'MULTIPLE' => 'Y',
1162 'WITH_DESCRIPTION' => 'Y',
1163 'MULTIPLE_CNT' => 1,
1164 ];
1167 ['IBLOCK_ID' => $arIBlock['ID']]
1168 );
1169 $arProperties['CML2_FILES'] = [
1170 'NAME' => GetMessage('IBLOCK_XML2_FILES'),
1171 'MULTIPLE' => 'Y',
1172 'WITH_DESCRIPTION' => 'Y',
1173 'MULTIPLE_CNT' => 1,
1174 'PROPERTY_TYPE' => Iblock\PropertyTable::TYPE_FILE,
1175 'CODE' => 'FILES',
1176 ];
1177 $arProperties['CML2_MANUFACTURER'] = [
1178 'NAME' => GetMessage('IBLOCK_XML2_PROP_MANUFACTURER'),
1179 'MULTIPLE' => 'N',
1180 'WITH_DESCRIPTION' => 'N',
1181 'MULTIPLE_CNT' => 1,
1182 'PROPERTY_TYPE' => Iblock\PropertyTable::TYPE_LIST,
1183 ];
1184
1185 foreach($arProperties as $k=>$v)
1186 {
1187 $result = $this->CheckProperty($arIBlock["ID"], $k, $v);
1188 if($result!==true)
1189 return $result;
1190 }
1191 //For offers make special property: link to catalog
1192 if (isset($arIBlock['CATALOG_XML_ID']) && $this->use_offers)
1193 {
1194 $this->CheckProperty(
1195 $arIBlock['ID'],
1199 [
1200 'IBLOCK_ID' => $arIBlock['ID'],
1201 'LINK_IBLOCK_ID' => $this->GetIBlockByXML_ID($arIBlock['CATALOG_XML_ID']),
1202 ]
1203 )
1204 );
1205 }
1206 }
1207
1208 $this->next_step["IBLOCK_ID"] = $arIBlock["ID"];
1209 $this->next_step["XML_ELEMENTS_PARENT"] = $XML_ELEMENTS_PARENT;
1210 }
1211
1212 if($meta_data_xml_id)
1213 {
1214 $rs = $this->_xml_file->GetList(
1215 array(),
1216 array("PARENT_ID" => $xml_root_id, "NAME" => $this->mess["IBLOCK_XML2_METADATA"]),
1217 array("ID")
1218 );
1219 while($arMetadata = $rs->Fetch())
1220 {
1221 //Find referenced metadata
1222 $bMetaFound = false;
1223 $meta_roots = array();
1224 $rsMetaRoots = $this->_xml_file->GetList(
1225 array("ID" => "asc"),
1226 array("PARENT_ID" => $arMetadata["ID"])
1227 );
1228 while($arMeta = $rsMetaRoots->Fetch())
1229 {
1230 if(isset($arMeta["VALUE_CLOB"]))
1231 $arMeta["VALUE"] = $arMeta["VALUE_CLOB"];
1232
1233 if($arMeta["NAME"] == $this->mess["IBLOCK_XML2_ID"] && $arMeta["VALUE"] == $meta_data_xml_id)
1234 $bMetaFound = true;
1235
1236 $meta_roots[] = $arMeta;
1237 }
1238
1239 //Get xml parents of the properties and sections
1240 if($bMetaFound)
1241 {
1242 foreach($meta_roots as $arMeta)
1243 {
1244 if($arMeta["NAME"] == $this->mess["IBLOCK_XML2_GROUPS"])
1245 $XML_SECTIONS_PARENT = $arMeta["ID"];
1246 elseif($arMeta["NAME"] == $this->mess["IBLOCK_XML2_PROPERTIES"])
1247 $XML_PROPERTIES_PARENT = $arMeta["ID"];
1248 elseif($arMeta["NAME"] == $this->mess["IBLOCK_XML2_GROUPS_PROPERTIES"])
1249 $XML_SECTIONS_PROPERTIES_PARENT = $arMeta["ID"];
1250 elseif($arMeta["NAME"] == $this->mess["IBLOCK_XML2_SECTION_PROPERTIES"])
1251 $XML_SECTION_PROPERTIES = $arMeta["ID"];
1252 elseif($arMeta["NAME"] == $this->mess["IBLOCK_XML2_PRICE_TYPES"])
1253 $XML_PRICES_PARENT = $arMeta["ID"];
1254 elseif($arMeta["NAME"] == $this->mess["IBLOCK_XML2_STORES"])
1255 $XML_STORES_PARENT = $arMeta["ID"];
1256 elseif($arMeta["NAME"] == $this->mess["IBLOCK_XML2_BASE_UNITS"])
1257 $XML_BASE_UNITS_PARENT = $arMeta["ID"];
1258 }
1259 break;
1260 }
1261 }
1262 }
1263
1264 $iblockFields = CIBlock::GetFields($arIBlock["ID"]);
1265 $iblockFields["XML_IMPORT_START_TIME"] = array(
1266 "NAME" => "XML_IMPORT_START_TIME",
1267 "IS_REQUIRED" => "N",
1268 "DEFAULT_VALUE" => date("Y-m-d H:i:s"),
1269 );
1270 CIBlock::SetFields($arIBlock["ID"], $iblockFields);
1271
1272 if($XML_PROPERTIES_PARENT)
1273 {
1274 $result = $this->ImportProperties($XML_PROPERTIES_PARENT, $arIBlock["ID"]);
1275 if($result!==true)
1276 return $result;
1277 }
1278
1279 if($XML_SECTION_PROPERTIES)
1280 {
1281 $result = $this->ImportSectionProperties($XML_SECTION_PROPERTIES, $arIBlock["ID"]);
1282 if($result!==true)
1283 return $result;
1284 }
1285
1286 if($XML_SECTIONS_PROPERTIES_PARENT)
1287 {
1288 $result = $this->ImportSectionsProperties($XML_SECTIONS_PROPERTIES_PARENT, $arIBlock["ID"]);
1289 if($result!==true)
1290 return $result;
1291 }
1292
1293 if($XML_PRICES_PARENT)
1294 {
1295 if($this->bCatalog)
1296 {
1297 $result = $this->ImportPrices($XML_PRICES_PARENT, $arIBlock["ID"], $IBLOCK_LID);
1298 if($result!==true)
1299 return $result;
1300 }
1301 }
1302
1303 if($XML_STORES_PARENT)
1304 {
1305 if($this->bCatalog)
1306 {
1307 $result = $this->ImportStores($XML_STORES_PARENT);
1308 if($result!==true)
1309 return $result;
1310 }
1311 }
1312
1313 if($XML_BASE_UNITS_PARENT)
1314 {
1315 if($this->bCatalog)
1316 {
1317 $result = $this->ImportBaseUnits($XML_BASE_UNITS_PARENT);
1318 if($result!==true)
1319 return $result;
1320 }
1321 }
1322
1323 $this->next_step["section_sort"] = 100;
1324 $this->next_step["XML_SECTIONS_PARENT"] = $XML_SECTIONS_PARENT;
1325
1326 $rs = $this->_xml_file->GetList(
1327 array(),
1328 array("PARENT_ID" => $xml_root_id, "NAME" => $this->mess["IBLOCK_XML2_PRODUCTS_SETS"]),
1329 array("ID", "ATTRIBUTES")
1330 );
1331 $ar = $rs->Fetch();
1332 if ($ar)
1333 {
1334 $this->next_step["SETS"] = (int)$ar["ID"];
1335 }
1336
1337 return true;
1338 }
1339
1341 {
1342 if($this->next_step["XML_SECTIONS_PARENT"])
1343 {
1344 $rs = $this->_xml_file->GetList(
1345 array("ID" => "asc"),
1346 array("PARENT_ID" => $this->next_step["XML_SECTIONS_PARENT"]),
1347 array("ID", "NAME", "VALUE")
1348 );
1349 $arID = array();
1350 while($ar = $rs->Fetch())
1351 $arID[] = $ar["ID"];
1352
1353 if($this->skip_root_section && (count($arID) == 1))
1354 {
1355 $rs = $this->_xml_file->GetList(
1356 array("ID" => "asc"),
1357 array("PARENT_ID" => $arID[0]),
1358 array("ID", "NAME", "VALUE")
1359 );
1360
1361 $XML_SECTIONS_PARENT = false;
1362 while($ar = $rs->Fetch())
1363 if($ar["NAME"] == $this->mess["IBLOCK_XML2_GROUPS"])
1364 $XML_SECTIONS_PARENT = $ar["ID"];
1365
1366 $arID = array();
1367 if($XML_SECTIONS_PARENT > 0)
1368 {
1369 $rs = $this->_xml_file->GetList(
1370 array("ID" => "asc"),
1371 array("PARENT_ID" => $XML_SECTIONS_PARENT),
1372 array("ID", "NAME", "VALUE")
1373 );
1374 while($ar = $rs->Fetch())
1375 $arID[] = $ar["ID"];
1376 }
1377 }
1378
1379 foreach($arID as $id)
1380 {
1381 $result = $this->ImportSection($id, $this->next_step["IBLOCK_ID"], false);
1382 if($result !== true)
1383 return $result;
1384 }
1385 }
1386
1387 return true;
1388 }
1389
1391 {
1392 if(array_key_exists("bUpdateOnly", $this->next_step) && $this->next_step["bUpdateOnly"])
1393 return;
1394 if(!$this->next_step["XML_SECTIONS_PARENT"])
1395 return;
1396
1397 if($action!="D" && $action!="A")
1398 return;
1399
1400 $bDelete = $action=="D";
1401
1402 //This will protect us from deactivating when next_step is lost
1403 $IBLOCK_ID = intval($this->next_step["IBLOCK_ID"]);
1404 if($IBLOCK_ID < 1)
1405 return;
1406
1407 $arFilter = array(
1408 "IBLOCK_ID" => $IBLOCK_ID,
1409 );
1410 if(!$bDelete)
1411 $arFilter["ACTIVE"] = "Y";
1412
1413 $obSection = new CIBlockSection;
1414 $rsSection = $obSection->GetList(array("ID"=>"asc"), $arFilter, false, ['ID', 'IBLOCK_ID']);
1415
1416 while($arSection = $rsSection->Fetch())
1417 {
1418 $rs = $this->_xml_file->GetList(
1419 array(),
1420 array("PARENT_ID+0" => 0, "LEFT_MARGIN" => $arSection["ID"]),
1421 array("ID")
1422 );
1423 $ar = $rs->Fetch();
1424 if(!$ar)
1425 {
1426 if($bDelete)
1427 {
1428 $obSection->Delete($arSection["ID"]);
1429 }
1430 else
1431 {
1432 $obSection->Update($arSection["ID"], array("ACTIVE"=>"N"));
1433 }
1434 }
1435 else
1436 {
1437 $this->_xml_file->Delete($ar["ID"]);
1438 }
1439 }
1440 return;
1441 }
1442
1444 {
1445 CIBlockSection::ReSort($this->next_step["IBLOCK_ID"]);
1446 }
1447
1448 function ImportPrices($XML_PRICES_PARENT, $IBLOCK_ID, $IBLOCK_LID)
1449 {
1450 $price_sort = 0;
1451 $this->next_step["XML_PRICES_PARENT"] = $XML_PRICES_PARENT;
1452
1453 $arLang = array();
1454 foreach($IBLOCK_LID as $site_id)
1455 {
1456 $rsSite = CSite::GetList("sort", "asc", array("ID" => $site_id));
1457 while ($site = $rsSite->Fetch())
1458 $arLang[$site["LANGUAGE_ID"]] = $site["LANGUAGE_ID"];
1459 }
1460
1461 $arPrices = CCatalogGroup::GetListArray();
1462
1463 if (!Catalog\Config\Feature::isMultiPriceTypesEnabled())
1464 {
1465 $prices_limit = 1 - count($arPrices);
1466 }
1467 else
1468 {
1469 $prices_limit = null;
1470 }
1471
1472 $arXMLPrices = $this->_xml_file->GetAllChildrenArray($XML_PRICES_PARENT);
1473 $uniqPriceById = array();
1474 foreach($arXMLPrices as $arXMLPrice)
1475 {
1476 $PRICE_ID = $arXMLPrice[$this->mess["IBLOCK_XML2_ID"]];
1477 $PRICE_NAME = $arXMLPrice[$this->mess["IBLOCK_XML2_NAME"]];
1478 if (array_key_exists($PRICE_ID, $uniqPriceById))
1479 return GetMessage("IBLOCK_XML2_PRICE_DUP_ERROR");
1480 else
1481 $uniqPriceById[$PRICE_ID] = true;
1482
1483 $found_id = 0;
1484 //Check for price by XML_ID
1485 if (isset($PRICE_ID) && $PRICE_ID != "")
1486 {
1487 foreach($arPrices as $i => $arPrice)
1488 {
1489 if ($PRICE_ID === $arPrice["XML_ID"])
1490 {
1491 $found_id = $arPrice["ID"];
1492 $arPrices[$i]["found"] = true;
1493 break;
1494 }
1495 }
1496 }
1497 //When lookup by it's name
1498 if (!$found_id)
1499 {
1500 foreach($arPrices as $arPrice)
1501 {
1502 if ($PRICE_NAME === $arPrice["NAME"] && !isset($arPrice["found"]))
1503 {
1504 $found_id = $arPrice["ID"];
1505 break;
1506 }
1507 }
1508 }
1509 //Add new price type
1510 if(!$found_id)
1511 {
1512 $price_sort += 100;
1513 $arPrice = array(
1514 "NAME" => $PRICE_NAME,
1515 "XML_ID" => $PRICE_ID,
1516 "SORT" => $price_sort,
1517 "USER_LANG" => array(),
1518 "USER_GROUP" => array(2),
1519 "USER_GROUP_BUY" => array(2),
1520 );
1521 foreach($arLang as $lang)
1522 {
1523 $arPrice["USER_LANG"][$lang] = $arXMLPrice[$this->mess["IBLOCK_XML2_NAME"]];
1524 }
1525
1526 if(!isset($prices_limit) || $prices_limit > 0)
1527 {
1528 CCatalogGroup::Add($arPrice);
1529 }
1530 elseif (isset($prices_limit))
1531 {
1532 if ($this->bitrix24mode)
1533 {
1534 return GetMessage("IBLOCK_XML2_PRICE_SB_ADD_ERROR_B24");
1535 }
1536 else
1537 {
1538 return GetMessage("IBLOCK_XML2_PRICE_SB_ADD_ERROR");
1539 }
1540 }
1541 }
1542 //We can update XML_ID of the price
1543 elseif ($arPrices[$found_id]["XML_ID"] == '' && $PRICE_ID <> '')
1544 {
1545 CCatalogGroup::Update($found_id, array(
1546 "XML_ID" => $PRICE_ID,
1547 ));
1548 }
1549 //We should update NAME of the price
1550 elseif ($arPrices[$found_id]["NAME"] !== $PRICE_NAME && !$this->disable_change_price_name)
1551 {
1552 CCatalogGroup::Update($found_id, array(
1553 "NAME" => $PRICE_NAME,
1554 ));
1555 }
1556
1557 if (isset($prices_limit))
1558 $prices_limit--;
1559 }
1560 return true;
1561 }
1562
1563 function ImportBaseUnits($XML_BASE_UNITS_PARENT)
1564 {
1565 $arXMLBaseUnits = $this->_xml_file->GetAllChildrenArray($XML_BASE_UNITS_PARENT);
1566 foreach ($arXMLBaseUnits as $arXMLBaseUnit)
1567 {
1568 $arUnit = array(
1569 "CODE" => $arXMLBaseUnit[$this->mess["IBLOCK_XML2_CODE"]],
1570 "MEASURE_TITLE" => $arXMLBaseUnit[$this->mess["IBLOCK_XML2_FULL_NAME"]],
1571 "SYMBOL_RUS" => $arXMLBaseUnit[$this->mess["IBLOCK_XML2_SHORT_NAME"]],
1572 //"SYMBOL_INTL" => $arXMLBaseUnit[$this->mess["IBLOCK_XML2_SHORT_NAME"]],
1573 "SYMBOL_LETTER_INTL" => $arXMLBaseUnit[$this->mess["IBLOCK_XML2_INTL_SHORT_NAME"]],
1574 );
1575
1576 $rsBaseUnit = CCatalogMeasure::GetList(array(), array("CODE" => $arUnit["CODE"]));
1577 $arIDUnit = $rsBaseUnit->Fetch();
1578 if (!$arIDUnit)
1579 {
1580 $ID = CCatalogMeasure::Add($arUnit);
1581 if (!$ID)
1582 {
1583 return GetMessage("IBLOCK_XML2_BASE_UNIT_ADD_ERROR", array("#CODE#" => $arUnit["CODE"]));
1584 }
1585 }
1586 }
1587 return true;
1588 }
1589
1590 function ImportStores($XML_STORES_PARENT)
1591 {
1592 $error = '';
1593 $ID = 0;
1594 $arDBStores = $this->getStoreList();
1595
1596 $arXMLStores = $this->_xml_file->GetAllChildrenArray($XML_STORES_PARENT);
1597 foreach($arXMLStores as $arXMLStore)
1598 {
1599 $arStore = array(
1600 "TITLE" => $arXMLStore[$this->mess["IBLOCK_XML2_NAME"]],
1601 "XML_ID" => $arXMLStore[$this->mess["IBLOCK_XML2_ID"]],
1602 );
1603 if(isset($arXMLStore[$this->mess["IBLOCK_XML2_STORE_ADDRESS"]]))
1604 $arStore["ADDRESS"] = $arXMLStore[$this->mess["IBLOCK_XML2_STORE_ADDRESS"]][$this->mess["IBLOCK_XML2_VIEW"]];
1605 if(isset($arXMLStore[$this->mess["IBLOCK_XML2_STORE_DESCRIPTION"]]))
1606 $arStore["DESCRIPTION"] = $arXMLStore[$this->mess["IBLOCK_XML2_STORE_DESCRIPTION"]];
1607
1608 if(
1609 isset($arXMLStore[$this->mess["IBLOCK_XML2_STORE_CONTACTS"]])
1610 && is_array($arXMLStore[$this->mess["IBLOCK_XML2_STORE_CONTACTS"]])
1611 )
1612 {
1613 $storeContact = array();
1614 foreach($arXMLStore[$this->mess["IBLOCK_XML2_STORE_CONTACTS"]] as $arContact)
1615 {
1616 if (
1617 is_array($arContact)
1618 && (
1619 !isset($arContact[$this->mess["IBLOCK_XML2_TYPE"]])
1620 || mb_substr($arContact[$this->mess["IBLOCK_XML2_TYPE"]], 0, mb_strlen($this->mess["IBLOCK_XML2_STORE_PHONE"])) === $this->mess["IBLOCK_XML2_STORE_PHONE"]
1621 )
1622 )
1623 {
1624 $storeContact[] = $arContact[$this->mess["IBLOCK_XML2_VALUE"]];
1625 }
1626 }
1627
1628 if($storeContact)
1629 $arStore["PHONE"] = implode(", ", $storeContact);
1630 }
1631
1632 if (!isset($arDBStores[$arStore["XML_ID"]]))
1633 {
1634 if ((count($arDBStores) < 1) || Catalog\Config\Feature::isMultiStoresEnabled())
1635 $arDBStores[$arStore["XML_ID"]] = $ID = CCatalogStore::Add($arStore);
1636 else
1637 $error = GetMessage("IBLOCK_XML2_MULTI_STORE_IMPORT_ERROR");
1638 }
1639 else
1640 {
1641 if ((count($arDBStores) <= 1) || Catalog\Config\Feature::isMultiStoresEnabled())
1642 $ID = CCatalogStore::Update($arDBStores[$arStore["XML_ID"]], $arStore);
1643 else
1644 $error = GetMessage("IBLOCK_XML2_MULTI_STORE_IMPORT_ERROR");
1645 }
1646 }
1647
1648 if($error)
1649 return $error;
1650 if(!$ID)
1651 return false;
1652 return true;
1653 }
1654
1656 {
1657 $arFields = array();
1658 $arFields['PRODUCT_ID'] = $elementID;
1659 static $arStoreResult = false;
1660 if ($arStoreResult === false)
1661 {
1662 $arStoreResult = $this->getStoreList();
1663 }
1664
1665 foreach($arElement as $xmlID => $amount)
1666 {
1667 if (isset($arStoreResult[$xmlID]))
1668 {
1669 $arFields['STORE_ID'] = $arStoreResult[$xmlID];
1670 $arFields['AMOUNT'] = $amount;
1671 $res = CCatalogStoreProduct::UpdateFromForm($arFields);
1672 if(!$res)
1673 $counter["ERR"]++;
1674 }
1675 }
1676 return true;
1677 }
1678
1679 function ImportSectionsProperties($XML_PARENT, $IBLOCK_ID)
1680 {
1682 global $APPLICATION;
1683 $obTypeManager = new CUserTypeEntity;
1684 $sort = 100;
1685
1686 $rs = $this->_xml_file->GetList(
1687 array("ID" => "asc"),
1688 array("PARENT_ID" => $XML_PARENT),
1689 array("ID")
1690 );
1691 while($ar = $rs->Fetch())
1692 {
1693 $XML_ENUM_PARENT = array();
1694 $arField = array(
1695 );
1696 $rsP = $this->_xml_file->GetList(
1697 array("ID" => "asc"),
1698 array("PARENT_ID" => $ar["ID"])
1699 );
1700 while($arP = $rsP->Fetch())
1701 {
1702 if(isset($arP["VALUE_CLOB"]))
1703 $arP["VALUE"] = $arP["VALUE_CLOB"];
1704
1705 if($arP["NAME"] == $this->mess["IBLOCK_XML2_ID"])
1706 $arField["XML_ID"] = $arP["VALUE"];
1707 elseif($arP["NAME"] == $this->mess["IBLOCK_XML2_NAME"])
1708 $arField["FIELD_NAME"] = $arP["VALUE"];
1709 elseif($arP["NAME"] == $this->mess["IBLOCK_XML2_SORT"])
1710 $arField["SORT"] = $arP["VALUE"];
1711 elseif($arP["NAME"] == $this->mess["IBLOCK_XML2_MULTIPLE"])
1712 $arField["MULTIPLE"] = ($arP["VALUE"]=="true") || intval($arP["VALUE"])? "Y": "N";
1713 elseif($arP["NAME"] == $this->mess["IBLOCK_XML2_BX_PROPERTY_TYPE"])
1714 $arField["USER_TYPE_ID"] = $arP["VALUE"];
1715 elseif($arP["NAME"] == $this->mess["IBLOCK_XML2_BX_IS_REQUIRED"])
1716 $arField["MANDATORY"] = ($arP["VALUE"]=="true") || intval($arP["VALUE"])? "Y": "N";
1717 elseif($arP["NAME"] == $this->mess["IBLOCK_XML2_BX_FILTER"])
1718 $arField["SHOW_FILTER"] = ($arP["VALUE"]=="true") || intval($arP["VALUE"])? "Y": "N";
1719 elseif($arP["NAME"] == $this->mess["IBLOCK_XML2_BX_SHOW_IN_LIST"])
1720 $arField["SHOW_IN_LIST"] = ($arP["VALUE"]=="true") || intval($arP["VALUE"])? "Y": "N";
1721 elseif($arP["NAME"] == $this->mess["IBLOCK_XML2_BX_EDIT_IN_LIST"])
1722 $arField["EDIT_IN_LIST"] = ($arP["VALUE"]=="true") || intval($arP["VALUE"])? "Y": "N";
1723 elseif($arP["NAME"] == $this->mess["IBLOCK_XML2_BX_SEARCH"])
1724 $arField["IS_SEARCHABLE"] = ($arP["VALUE"]=="true") || intval($arP["VALUE"])? "Y": "N";
1725 elseif($arP["NAME"] == $this->mess["IBLOCK_XML2_BX_SETTINGS"])
1726 $arField["SETTINGS"] = unserialize($arP["VALUE"], ['allowed_classes' => false]);
1727 elseif($arP["NAME"]==$this->mess["IBLOCK_XML2_CHOICE_VALUES"])
1728 $XML_ENUM_PARENT = $arP["ID"];
1729 }
1730
1731 $rsUserFields = $obTypeManager->GetList(array(), array("ENTITY_ID"=> "IBLOCK_".$IBLOCK_ID."_SECTION", "XML_ID"=>$arField["XML_ID"]));
1732 $arDBField = $rsUserFields->Fetch();
1733 if(!$arDBField)
1734 {
1735 $rsUserFields = $obTypeManager->GetList(array(), array("ENTITY_ID"=> "IBLOCK_".$IBLOCK_ID."_SECTION", "FIELD_NAME"=>$arField["FIELD_NAME"]));
1736 $arDBField = $rsUserFields->Fetch();
1737 }
1738
1739 if($arDBField)
1740 {
1741 $bChanged = false;
1742 foreach($arField as $key=>$value)
1743 {
1744 if($arDBField[$key] !== $value)
1745 {
1746 $bChanged = true;
1747 break;
1748 }
1749 }
1750 if(!$bChanged)
1751 $arField["ID"] = $arDBField["ID"];
1752 elseif($obTypeManager->Update($arDBField["ID"], $arField))
1753 $arField["ID"] = $arDBField["ID"];
1754 else
1755 {
1756 if($e = $APPLICATION->GetException())
1757 return GetMessage("IBLOCK_XML2_UF_ERROR", array(
1758 "#XML_ID#" => $arField["XML_ID"],
1759 "#ERROR_TEXT#" => $e->GetString(),
1760 ));
1761 else
1762 return false;
1763 }
1764 }
1765 else
1766 {
1767 $arField["ENTITY_ID"] = "IBLOCK_".$IBLOCK_ID."_SECTION";
1768 if(!array_key_exists("SORT", $arField))
1769 $arField["SORT"] = $sort;
1770 $arField["ID"] = $obTypeManager->Add($arField);
1771 if(!$arField["ID"])
1772 {
1773 if($e = $APPLICATION->GetException())
1774 return GetMessage("IBLOCK_XML2_UF_ERROR", array(
1775 "#XML_ID#" => $arField["XML_ID"],
1776 "#ERROR_TEXT#" => $e->GetString(),
1777 ));
1778 else
1779 return false;
1780 }
1781 }
1782
1783 if ($XML_ENUM_PARENT)
1784 {
1785 $arEnumXmlNodes = array();
1786 $rsE = $this->_xml_file->GetList(
1787 array("ID" => "asc"),
1788 array("PARENT_ID" => $XML_ENUM_PARENT)
1789 );
1790 while($arE = $rsE->Fetch())
1791 {
1792 if(isset($arE["VALUE_CLOB"]))
1793 $arE["VALUE"] = $arE["VALUE_CLOB"];
1794 $arEnumXmlNodes[] = $arE;
1795 }
1796
1797 if (!empty($arEnumXmlNodes))
1798 {
1799 $this->ImportSectionPropertyEnum($arField["ID"], $arEnumXmlNodes);
1800 }
1801 }
1802
1803 $sort += 100;
1804 }
1805
1806 return true;
1807 }
1808
1809 function ImportProperties($XML_PROPERTIES_PARENT, $IBLOCK_ID)
1810 {
1811 $obProperty = new CIBlockProperty;
1812 $sort = 100;
1813
1814 $arElementFields = array(
1815 "CML2_ACTIVE" => $this->mess["IBLOCK_XML2_BX_ACTIVE"],
1816 "CML2_CODE" => $this->mess["IBLOCK_XML2_SYMBOL_CODE"],
1817 "CML2_SORT" => $this->mess["IBLOCK_XML2_SORT"],
1818 "CML2_ACTIVE_FROM" => $this->mess["IBLOCK_XML2_START_TIME"],
1819 "CML2_ACTIVE_TO" => $this->mess["IBLOCK_XML2_END_TIME"],
1820 "CML2_PREVIEW_TEXT" => $this->mess["IBLOCK_XML2_ANONS"],
1821 "CML2_DETAIL_TEXT" => $this->mess["IBLOCK_XML2_DETAIL"],
1822 "CML2_PREVIEW_PICTURE" => $this->mess["IBLOCK_XML2_PREVIEW_PICTURE"],
1823 );
1824
1825 $rs = $this->_xml_file->GetList(
1826 array("ID" => "asc"),
1827 array("PARENT_ID" => $XML_PROPERTIES_PARENT),
1828 array("ID")
1829 );
1830 while($ar = $rs->Fetch())
1831 {
1832 $XML_ENUM_PARENT = false;
1833 $isExternal = false;
1834 $arProperty = array(
1835 );
1836 $rsP = $this->_xml_file->GetList(
1837 array("ID" => "asc"),
1838 array("PARENT_ID" => $ar["ID"])
1839 );
1840 while($arP = $rsP->Fetch())
1841 {
1842 if(isset($arP["VALUE_CLOB"]))
1843 $arP["VALUE"] = $arP["VALUE_CLOB"];
1844
1845 if($arP["NAME"]==$this->mess["IBLOCK_XML2_ID"])
1846 {
1847 $arProperty["XML_ID"] = $arP["VALUE"];
1848 if(array_key_exists($arProperty["XML_ID"], $arElementFields))
1849 break;
1850 }
1851 elseif($arP["NAME"]==$this->mess["IBLOCK_XML2_NAME"])
1852 $arProperty["NAME"] = $arP["VALUE"];
1853 elseif($arP["NAME"]==$this->mess["IBLOCK_XML2_MULTIPLE"])
1854 $arProperty["MULTIPLE"] = ($arP["VALUE"]=="true") || intval($arP["VALUE"])? "Y": "N";
1855 elseif($arP["NAME"]==$this->mess["IBLOCK_XML2_BX_SORT"])
1856 $arProperty["SORT"] = $arP["VALUE"];
1857 elseif($arP["NAME"]==$this->mess["IBLOCK_XML2_BX_CODE"])
1858 $arProperty["CODE"] = $arP["VALUE"];
1859 elseif($arP["NAME"]==$this->mess["IBLOCK_XML2_BX_DEFAULT_VALUE"])
1860 $arProperty["DEFAULT_VALUE"] = $arP["VALUE"];
1861 elseif($arP["NAME"]==$this->mess["IBLOCK_XML2_SERIALIZED"])
1862 $arProperty["SERIALIZED"] = ($arP["VALUE"]=="true") || intval($arP["VALUE"])? "Y": "N";
1863 elseif($arP["NAME"]==$this->mess["IBLOCK_XML2_BX_PROPERTY_TYPE"])
1864 {
1865 $arProperty["PROPERTY_TYPE"] = $arP["VALUE"];
1866 $arProperty["USER_TYPE"] = "";
1867 }
1868 elseif($arP["NAME"]==$this->mess["IBLOCK_XML2_BX_ROWS"])
1869 $arProperty["ROW_COUNT"] = $arP["VALUE"];
1870 elseif($arP["NAME"]==$this->mess["IBLOCK_XML2_BX_COLUMNS"])
1871 $arProperty["COL_COUNT"] = $arP["VALUE"];
1872 elseif($arP["NAME"]==$this->mess["IBLOCK_XML2_BX_LIST_TYPE"])
1873 $arProperty["LIST_TYPE"] = $arP["VALUE"];
1874 elseif($arP["NAME"]==$this->mess["IBLOCK_XML2_BX_FILE_EXT"])
1875 $arProperty["FILE_TYPE"] = $arP["VALUE"];
1876 elseif($arP["NAME"]==$this->mess["IBLOCK_XML2_BX_FIELDS_COUNT"])
1877 $arProperty["MULTIPLE_CNT"] = $arP["VALUE"];
1878 elseif($arP["NAME"]==$this->mess["IBLOCK_XML2_BX_USER_TYPE"])
1879 $arProperty["USER_TYPE"] = $arP["VALUE"];
1880 elseif($arP["NAME"]==$this->mess["IBLOCK_XML2_BX_WITH_DESCRIPTION"])
1881 $arProperty["WITH_DESCRIPTION"] = ($arP["VALUE"]=="true") || intval($arP["VALUE"])? "Y": "N";
1882 elseif($arP["NAME"]==$this->mess["IBLOCK_XML2_BX_SEARCH"])
1883 $arProperty["SEARCHABLE"] = ($arP["VALUE"]=="true") || intval($arP["VALUE"])? "Y": "N";
1884 elseif($arP["NAME"]==$this->mess["IBLOCK_XML2_BX_FILTER"])
1885 $arProperty["FILTRABLE"] = ($arP["VALUE"]=="true") || intval($arP["VALUE"])? "Y": "N";
1886 elseif($arP["NAME"]==$this->mess["IBLOCK_XML2_BX_LINKED_IBLOCK"])
1887 $arProperty["LINK_IBLOCK_ID"] = $this->GetIBlockByXML_ID($arP["VALUE"]);
1888 elseif($arP["NAME"]==$this->mess["IBLOCK_XML2_CHOICE_VALUES"])
1889 $XML_ENUM_PARENT = $arP["ID"];
1890 elseif($arP["NAME"]==$this->mess["IBLOCK_XML2_BX_IS_REQUIRED"])
1891 $arProperty["IS_REQUIRED"] = ($arP["VALUE"]=="true") || intval($arP["VALUE"])? "Y": "N";
1892 elseif($arP["NAME"]==$this->mess["IBLOCK_XML2_VALUES_TYPE"])
1893 {
1894 if(
1895 $arP["VALUE"] == $this->mess["IBLOCK_XML2_TYPE_LIST"]
1896 && !$isExternal
1897 )
1898 {
1899 $arProperty["PROPERTY_TYPE"] = "L";
1900 $arProperty["USER_TYPE"] = "";
1901 }
1902 elseif($arP["VALUE"] == $this->mess["IBLOCK_XML2_TYPE_NUMBER"])
1903 {
1904 $arProperty["PROPERTY_TYPE"] = "N";
1905 $arProperty["USER_TYPE"] = "";
1906 }
1907 elseif($arP["VALUE"] == $this->mess["IBLOCK_XML2_TYPE_STRING"])
1908 {
1909 $arProperty["PROPERTY_TYPE"] = "S";
1910 $arProperty["USER_TYPE"] = "";
1911 }
1912 elseif($arP["VALUE"] == $this->mess["IBLOCK_XML2_USER_TYPE_DATE"])
1913 {
1914 $arProperty["PROPERTY_TYPE"] = "S";
1915 $arProperty["USER_TYPE"] = "Date";
1916 }
1917 elseif($arP["VALUE"] == $this->mess["IBLOCK_XML2_USER_TYPE_DATETIME"])
1918 {
1919 $arProperty["PROPERTY_TYPE"] = "S";
1920 $arProperty["USER_TYPE"] = "DateTime";
1921 }
1922 }
1923 elseif($arP["NAME"]==$this->mess["IBLOCK_XML2_VALUES_TYPES"])
1924 {
1925 //This property metadata contains information about it's type
1926 $rsTypes = $this->_xml_file->GetList(
1927 array("ID" => "asc"),
1928 array("PARENT_ID" => $arP["ID"]),
1929 array("ID", "LEFT_MARGIN", "RIGHT_MARGIN", "NAME")
1930 );
1931 $arType = $rsTypes->Fetch();
1932 //We'll process only properties with NOT composing types
1933 //composed types will be supported only as simple string properties
1934 if($arType && !$rsTypes->Fetch())
1935 {
1936 $rsType = $this->_xml_file->GetList(
1937 array("ID" => "asc"),
1938 array("PARENT_ID" => $arType["ID"]),
1939 array("ID", "LEFT_MARGIN", "RIGHT_MARGIN", "NAME", "VALUE")
1940 );
1941 while($arType = $rsType->Fetch())
1942 {
1943 if($arType["NAME"] == $this->mess["IBLOCK_XML2_TYPE"])
1944 {
1945 if($arType["VALUE"] == $this->mess["IBLOCK_XML2_TYPE_LIST"])
1946 $arProperty["PROPERTY_TYPE"] = "L";
1947 elseif($arType["VALUE"] == $this->mess["IBLOCK_XML2_TYPE_NUMBER"])
1948 $arProperty["PROPERTY_TYPE"] = "N";
1949 }
1950 elseif($arType["NAME"] == $this->mess["IBLOCK_XML2_CHOICE_VALUES"])
1951 {
1952 $XML_ENUM_PARENT = $arType["ID"];
1953 }
1954 }
1955 }
1956 }
1957 elseif($arP["NAME"]==$this->mess["IBLOCK_XML2_BX_USER_TYPE_SETTINGS"])
1958 {
1959 $arProperty["USER_TYPE_SETTINGS"] = unserialize($arP["VALUE"], ['allowed_classes' => false]);
1960 }
1961 elseif($arP["NAME"]==$this->mess["IBLOCK_XML2_EXTERNAL"])
1962 {
1963 $isExternal = ($arP["VALUE"]=="true") || intval($arP["VALUE"])? true: false;
1964 if ($isExternal)
1965 {
1966 $arProperty["PROPERTY_TYPE"] = "S";
1967 $arProperty["USER_TYPE"] = "directory";
1968 }
1969 }
1970 elseif($arP["NAME"]==$this->mess["IBLOCK_XML2_BX_PROPERTY_FEATURE_LIST"])
1971 {
1972 $arProperty["FEATURES"] = unserialize($arP["VALUE"], ['allowed_classes' => false]);
1973 }
1974 }
1975
1976 if(array_key_exists($arProperty["XML_ID"], $arElementFields))
1977 continue;
1978
1979 // Skip properties with no choice values
1980 // http://jabber.bx/view.php?id=30476
1981 $arEnumXmlNodes = array();
1982 if($XML_ENUM_PARENT)
1983 {
1984 $rsE = $this->_xml_file->GetList(
1985 array("ID" => "asc"),
1986 array("PARENT_ID" => $XML_ENUM_PARENT)
1987 );
1988 while($arE = $rsE->Fetch())
1989 {
1990 if(isset($arE["VALUE_CLOB"]))
1991 $arE["VALUE"] = $arE["VALUE_CLOB"];
1992 $arEnumXmlNodes[] = $arE;
1993 }
1994
1995 if (empty($arEnumXmlNodes))
1996 continue;
1997 }
1998
1999 if (isset($arProperty['SERIALIZED']))
2000 {
2001 if ($arProperty['SERIALIZED'] === 'Y')
2002 {
2003 $arProperty['DEFAULT_VALUE'] = unserialize($arProperty['DEFAULT_VALUE'], ['allowed_classes' => false]);
2004 }
2005 unset($arProperty['SERIALIZED']);
2006 }
2007
2008 $rsProperty = $obProperty->GetList(
2009 array(),
2010 array(
2011 "IBLOCK_ID"=>$IBLOCK_ID,
2012 "XML_ID"=>$arProperty["XML_ID"],
2013 )
2014 );
2015 $arDBProperty = $rsProperty->Fetch();
2016 unset($rsProperty);
2017 if ($arDBProperty)
2018 {
2019 $arDBProperty['FEATURES'] = [];
2020 $featuresIterator = Iblock\PropertyFeatureTable::getList([
2021 'select' => [
2022 'ID',
2023 'MODULE_ID',
2024 'FEATURE_ID',
2025 'IS_ENABLED',
2026 ],
2027 'filter' => [
2028 '=PROPERTY_ID' => (int)$arDBProperty['ID'],
2029 ],
2030 'order' => [
2031 'ID' => 'ASC',
2032 ],
2033 ]);
2034 while ($featureRow = $featuresIterator->fetch())
2035 {
2036 unset($featureRow['ID']);
2037 $arDBProperty['FEATURES'][] = $featureRow;
2038 }
2039 unset($featureRow, $featuresIterator);
2040
2041 $bChanged = false;
2042 foreach($arProperty as $key=>$value)
2043 {
2044 if($arDBProperty[$key] !== $value)
2045 {
2046 $bChanged = true;
2047 break;
2048 }
2049 }
2050 if(!$bChanged)
2051 $arProperty["ID"] = $arDBProperty["ID"];
2052 elseif($obProperty->Update($arDBProperty["ID"], $arProperty))
2053 $arProperty["ID"] = $arDBProperty["ID"];
2054 else
2055 return $obProperty->LAST_ERROR;
2056 }
2057 else
2058 {
2059 $arProperty["IBLOCK_ID"] = $IBLOCK_ID;
2060 $arProperty["ACTIVE"] = "Y";
2061 if(!array_key_exists("PROPERTY_TYPE", $arProperty))
2062 $arProperty["PROPERTY_TYPE"] = "S";
2063 if(!array_key_exists("SORT", $arProperty))
2064 $arProperty["SORT"] = $sort;
2065 if(!array_key_exists("CODE", $arProperty))
2066 {
2067 $arProperty["CODE"] = $this->safeTranslit($arProperty["NAME"]);
2068 if(preg_match('/^[0-9]/', $arProperty["CODE"]))
2069 $arProperty["CODE"] = '_'.$arProperty["CODE"];
2070
2071 $rsProperty = $obProperty->GetList(array(), array("IBLOCK_ID"=>$IBLOCK_ID, "CODE"=>$arProperty["CODE"]));
2072 if($arDBProperty = $rsProperty->Fetch())
2073 {
2074 $suffix = 0;
2075 do {
2076 $suffix++;
2077 $rsProperty = $obProperty->GetList(array(), array("IBLOCK_ID"=>$IBLOCK_ID, "CODE"=>$arProperty["CODE"]."_".$suffix));
2078 } while ($rsProperty->Fetch());
2079 $arProperty["CODE"] .= '_'.$suffix;
2080 }
2081 }
2082 $arProperty["ID"] = $obProperty->Add($arProperty);
2083 if(!$arProperty["ID"])
2084 return $obProperty->LAST_ERROR;
2085 }
2086
2087 if($XML_ENUM_PARENT)
2088 {
2089 if ($isExternal)
2090 $result = $this->ImportPropertyDirectory($arProperty, $arEnumXmlNodes);
2091 else
2092 $result = $this->ImportPropertyEnum($arProperty, $arEnumXmlNodes);
2093
2094 if ($result !== true)
2095 return $result;
2096 }
2097 $sort += 100;
2098 }
2099 return true;
2100 }
2101
2102 function ImportPropertyEnum($arProperty, $arEnumXmlNodes)
2103 {
2104 $arEnumMap = array();
2105 $arProperty["VALUES"] = array();
2106 $rsEnum = CIBlockProperty::GetPropertyEnum($arProperty["ID"]);
2107 while($arEnum = $rsEnum->Fetch())
2108 {
2109 $arProperty["VALUES"][$arEnum["ID"]] = $arEnum;
2110 $arEnumMap[$arEnum["XML_ID"]] = &$arProperty["VALUES"][$arEnum["ID"]];
2111 }
2112
2113 $i = 0;
2114 foreach($arEnumXmlNodes as $arE)
2115 {
2116 if(
2117 $arE["NAME"] == $this->mess["IBLOCK_XML2_CHOICE"]
2118 || $arE["NAME"] == $this->mess["IBLOCK_XML2_CHOICE_VALUE"]
2119 )
2120 {
2121 $arE = $this->_xml_file->GetAllChildrenArray($arE);
2122 if(isset($arE[$this->mess["IBLOCK_XML2_ID"]]))
2123 {
2124 $xml_id = $arE[$this->mess["IBLOCK_XML2_ID"]];
2125 if(!array_key_exists($xml_id, $arEnumMap))
2126 {
2127 $arProperty["VALUES"]["n".$i] = array();
2128 $arEnumMap[$xml_id] = &$arProperty["VALUES"]["n".$i];
2129 $i++;
2130 }
2131 $arEnumMap[$xml_id]["CML2_EXPORT_FLAG"] = true;
2132 $arEnumMap[$xml_id]["XML_ID"] = $xml_id;
2133 if(isset($arE[$this->mess["IBLOCK_XML2_VALUE"]]))
2134 $arEnumMap[$xml_id]["VALUE"] = $arE[$this->mess["IBLOCK_XML2_VALUE"]];
2135 if(isset($arE[$this->mess["IBLOCK_XML2_BY_DEFAULT"]]))
2136 $arEnumMap[$xml_id]["DEF"] = ($arE[$this->mess["IBLOCK_XML2_BY_DEFAULT"]]=="true") || intval($arE[$this->mess["IBLOCK_XML2_BY_DEFAULT"]])? "Y": "N";
2137 if(isset($arE[$this->mess["IBLOCK_XML2_SORT"]]))
2138 $arEnumMap[$xml_id]["SORT"] = intval($arE[$this->mess["IBLOCK_XML2_SORT"]]);
2139 }
2140 }
2141 elseif(
2142 $arE["NAME"] == $this->mess["IBLOCK_XML2_TYPE_LIST"]
2143 )
2144 {
2145 $arE = $this->_xml_file->GetAllChildrenArray($arE);
2146 if(isset($arE[$this->mess["IBLOCK_XML2_VALUE_ID"]]))
2147 {
2148 $xml_id = $arE[$this->mess["IBLOCK_XML2_VALUE_ID"]];
2149 if(!array_key_exists($xml_id, $arEnumMap))
2150 {
2151 $arProperty["VALUES"]["n".$i] = array();
2152 $arEnumMap[$xml_id] = &$arProperty["VALUES"]["n".$i];
2153 $i++;
2154 }
2155 $arEnumMap[$xml_id]["CML2_EXPORT_FLAG"] = true;
2156 $arEnumMap[$xml_id]["XML_ID"] = $xml_id;
2157 if(isset($arE[$this->mess["IBLOCK_XML2_VALUE"]]))
2158 $arEnumMap[$xml_id]["VALUE"] = $arE[$this->mess["IBLOCK_XML2_VALUE"]];
2159 }
2160 }
2161 }
2162
2163 $bUpdateOnly = array_key_exists("bUpdateOnly", $this->next_step) && $this->next_step["bUpdateOnly"];
2164 $sort = 100;
2165
2166 foreach($arProperty["VALUES"] as $id=>$arEnum)
2167 {
2168 if(!isset($arEnum["CML2_EXPORT_FLAG"]))
2169 {
2170 //Delete value only when full exchange happened
2171 if(!$bUpdateOnly)
2172 $arProperty["VALUES"][$id]["VALUE"] = "";
2173 }
2174 elseif(isset($arEnum["SORT"]))
2175 {
2176 if($arEnum["SORT"] > $sort)
2177 $sort = $arEnum["SORT"] + 100;
2178 }
2179 else
2180 {
2181 $arProperty["VALUES"][$id]["SORT"] = $sort;
2182 $sort += 100;
2183 }
2184 }
2185
2186 $obProperty = new CIBlockProperty;
2187 $obProperty->UpdateEnum($arProperty["ID"], $arProperty["VALUES"], false);
2188
2189 return true;
2190 }
2191
2200 function ImportPropertyDirectory($arProperty, $arEnumXmlNodes)
2201 {
2202 if (!Loader::includeModule('highloadblock'))
2203 return true;
2204
2205 $rsProperty = CIBlockProperty::GetList(array(), array("ID"=>$arProperty["ID"]));
2206 $arProperty = $rsProperty->Fetch();
2207 if (!$arProperty)
2208 return true;
2209
2210 $tableName = 'b_'.strtolower($arProperty["CODE"]);
2211 if ($arProperty["USER_TYPE_SETTINGS"]["TABLE_NAME"] == '')
2212 {
2213 $hlblock = Bitrix\Highloadblock\HighloadBlockTable::getList(array(
2214 "filter" => array(
2215 "=TABLE_NAME" => $tableName,
2216 )))->fetch();
2217 if (!$hlblock)
2218 {
2219 $highBlockName = trim($arProperty["CODE"]);
2220 $highBlockName = preg_replace('/([^A-Za-z0-9]+)/', '', $highBlockName);
2221 $highBlockName = preg_replace('/(^[0-9]+)/', '', $highBlockName);
2222 if ($highBlockName === '')
2223 {
2224 return GetMessage('IBLOCK_XML2_HBLOCK_NAME_IS_INVALID');
2225 }
2226
2227 $highBlockName = ucfirst($highBlockName);
2228 $data = [
2229 'NAME' => $highBlockName,
2230 'TABLE_NAME' => $tableName,
2231 ];
2233 if (!$result->isSuccess())
2234 {
2235 $errors = implode('. ', $result->getErrorMessages());
2236 if ($errors === '')
2237 {
2239 'IBLOCK_XML2_HBLOCK_CREATE_ERROR_UNKNOWN',
2240 [
2241 '#ID#' => $arProperty['ID'],
2242 '#NAME#' => $arProperty['NAME'],
2243 ]
2244 );
2245 }
2246 else
2247 {
2249 'IBLOCK_XML2_HBLOCK_CREATE_ERROR',
2250 [
2251 '#ID#' => $arProperty['ID'],
2252 '#NAME#' => $arProperty['NAME'],
2253 '#ERRORS#' => $errors,
2254 ]
2255 );
2256 }
2257
2258 return $errors;
2259 }
2260
2261 $highBlockID = $result->getId();
2262
2263 $arFieldsName = array(
2264 'UF_NAME' => array("Y", "string"),
2265 'UF_XML_ID' => array("Y", "string"),
2266 'UF_LINK' => array("N", "string"),
2267 'UF_DESCRIPTION' => array("N", "string"),
2268 'UF_FULL_DESCRIPTION' => array("N", "string"),
2269 'UF_SORT' => array("N", "integer"),
2270 'UF_FILE' => array("N", "file"),
2271 'UF_DEF' => array("N", "boolean"),
2272 );
2273 $obUserField = new CUserTypeEntity();
2274 $sort = 100;
2275 foreach($arFieldsName as $fieldName => $fieldValue)
2276 {
2277 $arUserField = array(
2278 "ENTITY_ID" => "HLBLOCK_".$highBlockID,
2279 "FIELD_NAME" => $fieldName,
2280 "USER_TYPE_ID" => $fieldValue[1],
2281 "XML_ID" => "",
2282 "SORT" => $sort,
2283 "MULTIPLE" => "N",
2284 "MANDATORY" => $fieldValue[0],
2285 "SHOW_FILTER" => "N",
2286 "SHOW_IN_LIST" => "Y",
2287 "EDIT_IN_LIST" => "Y",
2288 "IS_SEARCHABLE" => "N",
2289 "SETTINGS" => array(),
2290 );
2291 $obUserField->Add($arUserField);
2292 $sort += 100;
2293 }
2294 }
2295
2296 $arProperty["USER_TYPE_SETTINGS"]["TABLE_NAME"] = $tableName;
2297 $obProperty = new CIBlockProperty;
2298 $obProperty->Update($arProperty["ID"], $arProperty);
2299 }
2300
2301 $hlblock = Bitrix\Highloadblock\HighloadBlockTable::getList(array(
2302 "filter" => array(
2303 "=TABLE_NAME" => $arProperty["USER_TYPE_SETTINGS"]["TABLE_NAME"],
2304 )))->fetch();
2305
2306 if (empty($hlblock))
2307 {
2308 return GetMessage(
2309 "IBLOCK_XML2_HBLOCK_ABSENT",
2310 array(
2311 "#ID#" => $arProperty["ID"],
2312 "#NAME#" => $arProperty["NAME"]
2313 )
2314 );
2315 }
2316
2317 $entity = Bitrix\Highloadblock\HighloadBlockTable::compileEntity($hlblock);
2318 $entity_data_class = $entity->getDataClass();
2319
2320 $arEnumMap = array();
2321 $rsData = $entity_data_class::getList(array(
2322 "select" => array("ID", "UF_NAME", "UF_XML_ID", "UF_SORT"),
2323 ));
2324 while($arData = $rsData->fetch())
2325 {
2326 $arEnumMap[$arData["UF_XML_ID"]] = $arData;
2327 }
2328
2329 $i = 0;
2330 foreach($arEnumXmlNodes as $arE)
2331 {
2332 if(
2333 $arE["NAME"] == $this->mess["IBLOCK_XML2_TYPE_LIST"]
2334 )
2335 {
2336 $arE = $this->_xml_file->GetAllChildrenArray($arE);
2337 if(
2338 isset($arE[$this->mess["IBLOCK_XML2_VALUE_ID"]])
2339 && isset($arE[$this->mess["IBLOCK_XML2_VALUE"]])
2340 )
2341 {
2342 $xml_id = $arE[$this->mess["IBLOCK_XML2_VALUE_ID"]];
2343 $arFields = array(
2344 "UF_XML_ID" => $xml_id,
2345 "UF_NAME" => $arE[$this->mess["IBLOCK_XML2_VALUE"]],
2346 );
2347 if (isset($arE[$this->mess["IBLOCK_XML2_PICTURE"]]))
2348 {
2349 $arFields["UF_FILE"] = $this->MakeFileArray($arE[$this->mess["IBLOCK_XML2_PICTURE"]]);
2350 }
2351
2352 if(!array_key_exists($xml_id, $arEnumMap))
2353 {
2354 $entity_data_class::add($arFields);
2355 }
2356 elseif ($arEnumMap[$xml_id]["UF_NAME"] !== $arFields['UF_NAME'])
2357 {
2358 $entity_data_class::update($arEnumMap[$xml_id]["ID"], $arFields);
2359 }
2360 }
2361 }
2362 }
2363
2364 return true;
2365 }
2366
2367 function ImportSectionPropertyEnum($FIELD_ID, $arEnumXmlNodes)
2368 {
2369 $arEnumMap = array();
2370 $arEnumValues = array();
2371 $obEnum = new CUserFieldEnum;
2372 $rsEnum = $obEnum->GetList(array(), array(
2373 "USER_FIELD_ID" => $FIELD_ID,
2374 ));
2375 while($arEnum = $rsEnum->Fetch())
2376 {
2377 $arEnumValues[$arEnum["ID"]] = $arEnum;
2378 $arEnumMap[$arEnum["XML_ID"]] = &$arEnumValues[$arEnum["ID"]];
2379 }
2380
2381 $i = 0;
2382 foreach($arEnumXmlNodes as $arE)
2383 {
2384 if($arE["NAME"] == $this->mess["IBLOCK_XML2_CHOICE"])
2385 {
2386 $arE = $this->_xml_file->GetAllChildrenArray($arE);
2387 if(isset($arE[$this->mess["IBLOCK_XML2_ID"]]))
2388 {
2389 $xml_id = $arE[$this->mess["IBLOCK_XML2_ID"]];
2390 if(!array_key_exists($xml_id, $arEnumMap))
2391 {
2392 $arEnumValues["n".$i] = array();
2393 $arEnumMap[$xml_id] = &$arEnumValues["n".$i];
2394 $i++;
2395 }
2396 $arEnumMap[$xml_id]["CML2_EXPORT_FLAG"] = true;
2397 $arEnumMap[$xml_id]["XML_ID"] = $xml_id;
2398 if(isset($arE[$this->mess["IBLOCK_XML2_VALUE"]]))
2399 $arEnumMap[$xml_id]["VALUE"] = $arE[$this->mess["IBLOCK_XML2_VALUE"]];
2400 if(isset($arE[$this->mess["IBLOCK_XML2_BY_DEFAULT"]]))
2401 $arEnumMap[$xml_id]["DEF"] = ($arE[$this->mess["IBLOCK_XML2_BY_DEFAULT"]]=="true") || intval($arE[$this->mess["IBLOCK_XML2_BY_DEFAULT"]])? "Y": "N";
2402 if(isset($arE[$this->mess["IBLOCK_XML2_SORT"]]))
2403 $arEnumMap[$xml_id]["SORT"] = intval($arE[$this->mess["IBLOCK_XML2_SORT"]]);
2404 }
2405 }
2406 }
2407
2408 $bUpdateOnly = array_key_exists("bUpdateOnly", $this->next_step) && $this->next_step["bUpdateOnly"];
2409 $sort = 100;
2410
2411 foreach($arEnumValues as $id=>$arEnum)
2412 {
2413 if(!isset($arEnum["CML2_EXPORT_FLAG"]))
2414 {
2415 //Delete value only when full exchange happened
2416 if(!$bUpdateOnly)
2417 $arEnumValues[$id]["VALUE"] = "";
2418 }
2419 elseif(isset($arEnum["SORT"]))
2420 {
2421 if($arEnum["SORT"] > $sort)
2422 $sort = $arEnum["SORT"] + 100;
2423 }
2424 else
2425 {
2426 $arEnumValues[$id]["SORT"] = $sort;
2427 $sort += 100;
2428 }
2429 }
2430
2431 $obEnum = new CUserFieldEnum;
2432 $res = $obEnum->SetEnumValues($FIELD_ID, $arEnumValues);
2433
2434 return true;
2435 }
2436
2437 function ImportSectionProperties($XML_SECTION_PROPERTIES, $IBLOCK_ID, $SECTION_ID = 0)
2438 {
2439 if($SECTION_ID == 0)
2440 {
2441 CIBlockSectionPropertyLink::DeleteByIBlock($IBLOCK_ID);
2442 $ib = new CIBlock;
2443 $ib->Update($IBLOCK_ID, array("SECTION_PROPERTY" => "Y"));
2444 }
2445
2446 $rs = $this->_xml_file->GetList(
2447 array("ID" => "asc"),
2448 array("PARENT_ID" => $XML_SECTION_PROPERTIES),
2449 array("ID")
2450 );
2451 while($ar = $rs->Fetch())
2452 {
2453 $iblockId = 0;
2454 $sectionId = 0;
2455 $arLink = array(
2456 );
2457 $rsP = $this->_xml_file->GetList(
2458 array("ID" => "asc"),
2459 array("PARENT_ID" => $ar["ID"])
2460 );
2461 while($arP = $rsP->Fetch())
2462 {
2463 if($arP["NAME"]==$this->mess["IBLOCK_XML2_ID"])
2464 $arLink["XML_ID"] = $arP["VALUE"];
2465 elseif($arP["NAME"]==$this->mess["IBLOCK_XML2_SMART_FILTER"])
2466 $arLink["SMART_FILTER"] = ($arP["VALUE"]=="true") || intval($arP["VALUE"])? "Y": "N";
2467 elseif($arP["NAME"]==$this->mess["IBLOCK_XML2_SMART_FILTER_DISPLAY_TYPE"])
2468 $arLink["DISPLAY_TYPE"] = $arP["VALUE"];
2469 elseif($arP["NAME"]==$this->mess["IBLOCK_XML2_SMART_FILTER_DISPLAY_EXPANDED"])
2470 $arLink["DISPLAY_EXPANDED"] = ($arP["VALUE"]=="true") || intval($arP["VALUE"])? "Y": "N";
2471 elseif($arP["NAME"]==$this->mess["IBLOCK_XML2_SMART_FILTER_HINT"])
2472 $arLink["FILTER_HINT"] = $arP["VALUE"];
2473 elseif($arP["NAME"]==$this->mess["IBLOCK_XML2_BX_LINKED_IBLOCK"])
2474 $iblockId = $this->GetIBlockByXML_ID($arP["VALUE"]);
2475 elseif($arP["NAME"]==$this->mess["IBLOCK_XML2_GROUP"] && $iblockId > 0)
2476 $sectionId = $this->GetSectionByXML_ID($iblockId, $arP["VALUE"]);
2477 }
2478
2479 if ($iblockId > 0)
2480 $arLink["IBLOCK_ID"] = $iblockId;
2481
2482 $rsProperty = CIBlockProperty::GetList(array(), array(
2483 "IBLOCK_ID" => $IBLOCK_ID,
2484 "XML_ID" => $arLink["XML_ID"],
2485 "CHECK_PERMISSIONS" => "N",
2486 ));
2487 if($arDBProperty = $rsProperty->Fetch())
2488 {
2489 CIBlockSectionPropertyLink::Add($sectionId? $sectionId: $SECTION_ID, $arDBProperty["ID"], $arLink);
2490 }
2491 }
2492 return true;
2493 }
2494
2496 {
2497 if(!is_array($SECTION_MAP))
2498 {
2499 $SECTION_MAP = array();
2500 $rsSections = CIBlockSection::GetList(array(), array("IBLOCK_ID"=>$this->next_step["IBLOCK_ID"]), false);
2501 while($ar = $rsSections->Fetch())
2502 $SECTION_MAP[$ar["XML_ID"]] = $ar["ID"];
2503 unset($rsSections);
2504 }
2505 $this->SECTION_MAP = $SECTION_MAP;
2506
2507 if(!is_array($PRICES_MAP))
2508 {
2509 $arPrices = array();
2510 if($this->bCatalog)
2511 {
2512 $arPrices = CCatalogGroup::GetListArray();
2513 }
2514
2515 $PRICES_MAP = array();
2516 if(isset($this->next_step["XML_PRICES_PARENT"]))
2517 {
2518 $rs = $this->_xml_file->GetList(
2519 array("ID" => "asc"),
2520 array("PARENT_ID" => $this->next_step["XML_PRICES_PARENT"])
2521 );
2522 while($arParent = $rs->Fetch())
2523 {
2524 if(isset($arParent["VALUE_CLOB"]))
2525 $arParent["VALUE"] = $arParent["VALUE_CLOB"];
2526 $arXMLPrice = $this->_xml_file->GetAllChildrenArray($arParent);
2527 $PRICE_ID = $arXMLPrice[$this->mess["IBLOCK_XML2_ID"]];
2528 $PRICE_NAME = $arXMLPrice[$this->mess["IBLOCK_XML2_NAME"]];
2529 $arPrice = array(
2530 "NAME" => $PRICE_NAME,
2531 "XML_ID" => $PRICE_ID,
2532 "CURRENCY" => $arXMLPrice[$this->mess["IBLOCK_XML2_CURRENCY"]] ?? '',
2533 "TAX_NAME" => $arXMLPrice[$this->mess["IBLOCK_XML2_TAX"]][$this->mess["IBLOCK_XML2_NAME"]] ?? '',
2534 "TAX_IN_SUM" => $arXMLPrice[$this->mess["IBLOCK_XML2_TAX"]][$this->mess["IBLOCK_XML2_IN_SUM"]] ?? '',
2535 );
2536 if($this->bCatalog)
2537 {
2538 $found_id = 0;
2539 //Check for price by XML_ID
2540 if (isset($PRICE_ID) && $PRICE_ID != "")
2541 {
2542 foreach($arPrices as $price)
2543 {
2544 if ($PRICE_ID === $price["XML_ID"])
2545 {
2546 $found_id = $price["ID"];
2547 break;
2548 }
2549 }
2550 }
2551 //When lookup by it's name
2552 if (!$found_id)
2553 {
2554 foreach($arPrices as $price)
2555 {
2556 if ($PRICE_NAME === $price["NAME"])
2557 {
2558 $found_id = $price["ID"];
2559 break;
2560 }
2561 }
2562 }
2563
2564 if($found_id)
2565 $arPrice["ID"] = $found_id;
2566 else
2567 $arPrice["ID"] = 0;
2568 }
2569 else
2570 {
2571 $obProperty = new CIBlockProperty;
2572 $rsProperty = $obProperty->GetList(array(), array("IBLOCK_ID"=>$this->next_step["IBLOCK_ID"], "XML_ID"=>$arPrice["XML_ID"]));
2573 if($ar = $rsProperty->Fetch())
2574 $arPrice["ID"] = $ar["ID"];
2575 else
2576 $arPrice["ID"] = 0;
2577 }
2578 $PRICES_MAP[$PRICE_ID] = $arPrice;
2579 }
2580 }
2581 else
2582 {
2583 foreach($arPrices as $arPrice)
2584 {
2585 $arPrice['TAX_NAME'] = '';
2586 $arPrice['TAX_IN_SUM'] = '';
2587 $PRICES_MAP[$arPrice["XML_ID"]] = $arPrice;
2588 }
2589 }
2590 }
2591 $this->PRICES_MAP = $PRICES_MAP;
2592 }
2593
2594 function GetElementCRC($arElement)
2595 {
2596 if(!is_array($arElement))
2597 {
2598 $parent_id = $arElement;
2599 $rsElement = $this->_xml_file->GetList(
2600 array("ID" => "asc"),
2601 array("PARENT_ID" => $parent_id)
2602 );
2603 $arElement = array();
2604 while($ar = $rsElement->Fetch())
2605 $arElement[] = array(
2606 $ar["NAME"],
2607 $ar["VALUE"],
2608 $ar["VALUE_CLOB"],
2609 $ar["ATTRIBUTES"],
2610 );
2611 }
2612 $c = crc32(print_r($arElement, true));
2613 if($c > 0x7FFFFFFF)
2614 $c = -(0xFFFFFFFF - $c + 1);
2615 return $c;
2616 }
2617
2618 function CheckManufacturer($xml)
2619 {
2620 if (!$xml)
2621 {
2622 return "";
2623 }
2624
2625 if (!isset($this->PROPERTY_MAP["CML2_MANUFACTURER"]))
2626 {
2627 return '';
2628 }
2629
2630 $propertyId = $this->PROPERTY_MAP["CML2_MANUFACTURER"];
2631 $enumXmlId = $xml[$this->mess["IBLOCK_XML2_ID"]];
2632 $enumName = $xml[$this->mess["IBLOCK_XML2_NAME"]];
2633 if ($enumXmlId == '')
2634 {
2635 return "";
2636 }
2638 "PROPERTY_ID" => $propertyId,
2639 "XML_ID" => $enumXmlId,
2640 ));
2641 $enum = $enumValue->Fetch();
2642
2643 if ($enum)
2644 {
2645 if ($enum["VALUE"] !== $enumName)
2646 {
2648 "VALUE" => $enumName,
2649 ));
2650 }
2651 return $enum["ID"];
2652 }
2653 else
2654 {
2656 "VALUE" => $enumName,
2657 "PROPERTY_ID" => $propertyId,
2658 "DEF" => "N",
2659 "XML_ID" => $enumXmlId,
2660 ));
2661 }
2662 }
2663
2668 {
2669 $result = true;
2670 if (isset($this->next_step["XML_ELEMENTS_PARENT"]) && $this->next_step["XML_ELEMENTS_PARENT"] > 0)
2671 {
2672 if (!isset($this->next_step["DONE"]))
2673 $this->next_step["DONE"] = [];
2674 if (!isset($this->next_step["DONE"]["ALL"]))
2675 $this->next_step["DONE"]["ALL"] = 0;
2676 if ($this->next_step["DONE"]["ALL"] <= 0)
2677 {
2678 if ($this->_xml_file->IsExistTemporaryTable())
2679 {
2680 $this->next_step["DONE"]["ALL"] = $this->_xml_file->GetCountItemsWithParent($this->next_step["XML_ELEMENTS_PARENT"]);
2681 }
2682 else
2683 {
2684 $this->LAST_ERROR = GetMessage("IBLOCK_XML2_TEMPORARY_TABLE_EXIST_ERROR");
2685 $result = false;
2686 }
2687 }
2688 }
2689 return $result;
2690 }
2691
2697 public function ImportElements($start_time, $interval)
2698 {
2699 global $DB;
2700 $counter = array(
2701 "ADD" => 0,
2702 "UPD" => 0,
2703 "DEL" => 0,
2704 "DEA" => 0,
2705 "ERR" => 0,
2706 "CRC" => 0,
2707 );
2708 if($this->next_step["XML_ELEMENTS_PARENT"])
2709 {
2711 if ($this->bCatalog)
2713 $this->activeStores = $this->getActiveStores();
2714
2715 $obElement = new CIBlockElement();
2716 $obElement->CancelWFSetMove();
2717 $bWF = Loader::includeModule("workflow");
2718 $filter = [
2719 'PARENT_ID' => $this->next_step['XML_ELEMENTS_PARENT'],
2720 ];
2721 if (isset($this->next_step['XML_LAST_ID']))
2722 {
2723 $filter['>ID'] = $this->next_step['XML_LAST_ID'];
2724 }
2725 $rsParents = $this->_xml_file->GetList(
2726 array("ID" => "asc"),
2727 $filter,
2728 array("ID", "LEFT_MARGIN", "RIGHT_MARGIN")
2729 );
2730 while($arParent = $rsParents->Fetch())
2731 {
2732 if (!$arParent["RIGHT_MARGIN"])
2733 continue;
2734
2735 $counter["CRC"]++;
2736
2737 $arXMLElement = $this->_xml_file->GetAllChildrenArray($arParent);
2738 $hashPosition = strrpos($arXMLElement[$this->mess["IBLOCK_XML2_ID"]], "#");
2739
2740 if(!$this->next_step["bOffer"] && $this->use_offers)
2741 {
2742 if($hashPosition !== false)
2743 {
2744 $this->next_step["XML_LAST_ID"] = $arParent["ID"];
2745 continue;
2746 }
2747 }
2748 if(array_key_exists($this->mess["IBLOCK_XML2_STATUS"], $arXMLElement) && ($arXMLElement[$this->mess["IBLOCK_XML2_STATUS"]] == $this->mess["IBLOCK_XML2_DELETED"]))
2749 {
2750 $ID = $this->GetElementByXML_ID($this->next_step["IBLOCK_ID"], $arXMLElement[$this->mess["IBLOCK_XML2_ID"]]);
2751 if($ID && $obElement->Update($ID, array("ACTIVE"=>"N"), $bWF))
2752 {
2753 if($this->use_offers)
2754 $this->ChangeOffersStatus($ID, "N", $bWF);
2755 $counter["DEA"]++;
2756 }
2757 else
2758 {
2759 $counter["ERR"]++;
2760 }
2761 }
2762 elseif(array_key_exists($this->mess["IBLOCK_XML2_BX_TAGS"], $arXMLElement))
2763 {
2764 //This is our export file
2765 $ID = $this->ImportElement($arXMLElement, $counter, $bWF, $arParent);
2766 }
2767 else
2768 {
2769 $this->arFileDescriptionsMap = array();
2770 $this->arElementFilesId = array();
2771 $this->arElementFiles = array();
2772 //offers.xml
2773 if ($this->next_step["bOffer"])
2774 {
2775 if (!$this->use_offers)
2776 {
2777 //We have only one information block
2778 $ID = $this->ImportElementPrices($arXMLElement, $counter, $arParent);
2779 }
2780 elseif ($hashPosition === false && !$this->force_offers)
2781 {
2782 //We have separate offers iblock and there is element price
2783 $ID = $this->ImportElementPrices($arXMLElement, $counter, $arParent);
2784 }
2785 else
2786 {
2787 $xmlKeys = array_keys($arXMLElement);
2788 if ($xmlKeys == array($this->mess["IBLOCK_XML2_ID"], $this->mess["IBLOCK_XML2_PRICES"]))
2789 {
2790 //prices.xml
2791 $ID = $this->ImportElementPrices($arXMLElement, $counter, $arParent);
2792 }
2793 elseif ($xmlKeys == array($this->mess["IBLOCK_XML2_ID"], $this->mess["IBLOCK_XML2_RESTS"]))
2794 {
2795 //rests.xml
2796 $ID = $this->ImportElementPrices($arXMLElement, $counter, $arParent);
2797 }
2798 else
2799 {
2800 //It's an offer in offers iblock
2801 $ID = $this->ImportElement($arXMLElement, $counter, $bWF, $arParent);
2802 }
2803 }
2804 }
2805 //import.xml
2806 else
2807 {
2808 $ID = $this->ImportElement($arXMLElement, $counter, $bWF, $arParent);
2809 }
2810 }
2811
2812 if($ID)
2813 {
2814 $ipropValues = new \Bitrix\Iblock\InheritedProperty\ElementValues($this->next_step["IBLOCK_ID"], $ID);
2815 $ipropValues->clearValues();
2816
2817 $DB->Query("UPDATE b_iblock_element SET TIMESTAMP_X = ".$DB->CurrentTimeFunction()." WHERE ID=".$ID);
2818 $this->_xml_file->Add(array("PARENT_ID" => 0, "LEFT_MARGIN" => $ID));
2819 }
2820
2821 $this->next_step["XML_LAST_ID"] = $arParent["ID"];
2822
2823 if($interval > 0 && (time()-$start_time) > (2*$interval/3))
2824 break;
2825 }
2826 if ($this->bCatalog)
2827 {
2830 }
2832 Iblock\PropertyIndex\Manager::runDeferredIndexing($this->next_step["IBLOCK_ID"]);
2833 }
2834 $this->CleanTempFiles();
2835 return $counter;
2836 }
2837
2839 {
2840 if ($this->bCatalog && isset($this->next_step["SETS"]) && $this->next_step["SETS"] > 0)
2841 {
2842 $rsParents = $this->_xml_file->GetList(
2843 array("ID" => "asc"),
2844 array("PARENT_ID" => $this->next_step["SETS"]),
2845 array("ID", "LEFT_MARGIN", "RIGHT_MARGIN")
2846 );
2847 while($arParent = $rsParents->Fetch())
2848 {
2849 $arXMLElement = $this->_xml_file->GetAllChildrenArray($arParent);
2850 if(isset($arXMLElement[$this->mess["IBLOCK_XML2_ID"]]))
2851 {
2852 $rsElement = CIBlockElement::GetList(
2853 array(),
2854 array("=XML_ID" => $arXMLElement[$this->mess["IBLOCK_XML2_ID"]], "IBLOCK_ID" => $this->next_step["IBLOCK_ID"]),
2855 false, false,
2856 array("ID", "IBLOCK_ID")
2857 );
2858 if ($arDBElement = $rsElement->Fetch())
2859 {
2861 if (isset($arXMLElement[$this->mess["IBLOCK_XML2_PRODUCT_SET"]]))
2862 {
2863 $arFields = array(
2864 "ITEM_ID" => $arDBElement["ID"],
2866 "ITEMS" => array(),
2867 );
2868 foreach ($arXMLElement[$this->mess["IBLOCK_XML2_PRODUCT_SET"]] as $xmlSet)
2869 {
2870 $arFields["ITEMS"][] = array(
2871 "ITEM_ID" => $this->GetElementByXML_ID($arDBElement["IBLOCK_ID"], $xmlSet[$this->mess["IBLOCK_XML2_VALUE"]]),
2872 "SORT" => intval($xmlSet[$this->mess["IBLOCK_XML2_SORT"]]),
2873 "QUANTITY" => intval($xmlSet[$this->mess["IBLOCK_XML2_AMOUNT"]]),
2874 );
2875 }
2876 $ps = new CCatalogProductSet;
2877 $ps->add($arFields);
2878 }
2879 }
2880 }
2881 }
2882 }
2883 }
2884
2885 function ChangeOffersStatus($ELEMENT_ID, $STATUS = "Y", $bWF = true)
2886 {
2887 if($this->arLinkedProps === false)
2888 {
2889 $this->arLinkedProps = array();
2890 $obProperty = new CIBlockProperty;
2891 $rsProperty = $obProperty->GetList(array(), array("LINK_IBLOCK_ID"=>$this->next_step["IBLOCK_ID"], "XML_ID"=>"CML2_LINK"));
2892 while($arProperty = $rsProperty->Fetch())
2893 $this->arLinkedProps[] = $arProperty;
2894 }
2895 $obElement = new CIBlockElement;
2896 $obElement->CancelWFSetMove();
2897 $elementFields = array("ACTIVE"=>$STATUS);
2898 if ((string)\Bitrix\Main\Config\Option::get('iblock', 'change_user_by_group_active_modify') === 'Y')
2899 {
2900 $elementFields['MODIFIED_BY'] = $this->currentUserId;
2901 }
2902 foreach($this->arLinkedProps as $arProperty)
2903 {
2904 $rsElements = $obElement->GetList(
2905 Array("ID"=>"asc"),
2906 Array(
2907 "PROPERTY_".$arProperty["ID"] => $ELEMENT_ID,
2908 "IBLOCK_ID" => $arProperty["IBLOCK_ID"],
2909 "ACTIVE" => $STATUS=="Y"? "N": "Y",
2910 ),
2911 false, false,
2912 Array("ID", "TMP_ID")
2913 );
2914 while($arElement = $rsElements->Fetch())
2915 $obElement->Update($arElement["ID"], $elementFields, $bWF);
2916 }
2917 }
2918
2920 {
2921 $params = array(
2922 "max_len" => 50,
2923 "change_case" => 'U', // 'L' - toLower, 'U' - toUpper, false - do not change
2924 "replace_space" => '_',
2925 "replace_other" => '_',
2926 "delete_repeat_replace" => true,
2927 );
2928
2929 $result = CUtil::translit($str, LANGUAGE_ID, $params);
2930 $result = preg_replace("/[^a-zA-Z0-9_]/", $params["replace_other"], $result);
2931 if ($params["delete_repeat_replace"])
2932 $result = preg_replace("/".preg_quote($params["replace_other"], "/")."+/", $params["replace_other"], $result);
2933
2934 return $result;
2935 }
2936
2941 public function ToFloat($str)
2942 {
2943 static $search = false;
2944 static $replace = false;
2945 if(!$search)
2946 {
2947 if (isset($this->next_step["sdp"]) && $this->next_step["sdp"] !== '')
2948 {
2949 $search = array("\xc2\xa0", "\xa0", " ", $this->next_step["sdp"], ",");
2950 $replace = array("", "", "", ".", ".");
2951 }
2952 else
2953 {
2954 $search = array("\xc2\xa0", "\xa0", " ", ",");
2955 $replace = array("", "", "", ".");
2956 }
2957 }
2958
2959 return (float)str_replace($search, $replace, $str);
2960 }
2961
2966 public function ToFloatEmpty($value)
2967 {
2968 return ($value === '' ? '' : $this->ToFloat($value));
2969 }
2970
2975 public function ToInt($str)
2976 {
2977 static $search = false;
2978 static $replace = false;
2979 if(!$search)
2980 {
2981 if (isset($this->next_step["sdp"]) && $this->next_step["sdp"] !== '')
2982 {
2983 $search = array("\xa0", " ", $this->next_step["sdp"], ",");
2984 $replace = array("", "", ".", ".");
2985 }
2986 else
2987 {
2988 $search = array("\xa0", " ", ",");
2989 $replace = array("", "", ".");
2990 }
2991 }
2992
2993 return (int)str_replace($search, $replace, $str);
2994 }
2995
2996 function Unserialize($string)
2997 {
2998 $decoded_string = preg_replace_callback('/(s:\d+:")(.*?)(";)/s', array($this, "__unserialize_callback"), $string);
2999 return unserialize($decoded_string, ['allowed_classes' => false]);
3000 }
3001
3002 function __unserialize_callback($match)
3003 {
3004 return 's:'.strlen($match[2]).':"'.$match[2].'";';
3005 }
3006
3008 {
3009 static $cacheValue = array();
3010 static $cacheDescr = array();
3011 $xmlValue = (int)$xmlValue;
3012 if (!isset($cacheValue[$xmlValue]))
3013 {
3014 $cacheValue[$xmlValue] = $xmlValue;
3015 $cacheDescr[$xmlValue] = false;
3016 if ($xmlValue > 0 && Loader::includeModule('catalog'))
3017 {
3018 $rsBaseUnit = CCatalogMeasure::GetList(array(), array("CODE" => $xmlValue));
3019 $arIDUnit = $rsBaseUnit->Fetch();
3020 if ($arIDUnit)
3021 {
3022 $cacheValue[$xmlValue] = $arIDUnit["SYMBOL_RUS"];
3023 $cacheDescr[$xmlValue] = $arIDUnit["ID"];
3024 }
3025 else
3026 {
3027 $rsBaseUnit = CCatalogMeasure::GetList(array(), array("ID" => $xmlValue));
3028 $arIDUnit = $rsBaseUnit->Fetch();
3029 if ($arIDUnit)
3030 {
3031 $cacheValue[$xmlValue] = $arIDUnit["SYMBOL_RUS"];
3032 $cacheDescr[$xmlValue] = $arIDUnit["ID"];
3033 }
3034 }
3035 }
3036 }
3037
3038 return array(
3039 "VALUE" => $cacheValue[$xmlValue],
3040 "DESCRIPTION" => $cacheDescr[$xmlValue],
3041 );
3042 }
3043
3044 function CheckIfElementIsActive($arXMLElement)
3045 {
3046 $bActive = true; //by default
3047 if(isset($arXMLElement[$this->mess["IBLOCK_XML2_PROPERTIES_VALUES"]]))
3048 {
3049 foreach($arXMLElement[$this->mess["IBLOCK_XML2_PROPERTIES_VALUES"]] as $value)
3050 {
3051 if($value[$this->mess["IBLOCK_XML2_ID"]] === "CML2_ACTIVE")
3052 {
3053 if($value[$this->mess["IBLOCK_XML2_VALUE"]] === "false" || $value[$this->mess["IBLOCK_XML2_VALUE"]] === "0")
3054 {
3055 $bActive = false;
3056 break;
3057 }
3058 }
3059 }
3060 }
3061 return $bActive;
3062 }
3063
3064 function ImportElement($arXMLElement, &$counter, $bWF, $arParent)
3065 {
3066 $arElement = array(
3067 "ACTIVE" => "Y",
3068 "PROPERTY_VALUES" => array(),
3069 );
3070
3071 if(isset($arXMLElement[$this->mess["IBLOCK_XML2_VERSION"]]))
3072 $arElement["TMP_ID"] = $arXMLElement[$this->mess["IBLOCK_XML2_VERSION"]];
3073 else
3074 $arElement["TMP_ID"] = $this->GetElementCRC($arXMLElement);
3075
3076 if(isset($arXMLElement[$this->mess["IBLOCK_XML2_ID_1C_SITE"]]))
3077 $arElement["XML_ID"] = $arXMLElement[$this->mess["IBLOCK_XML2_ID_1C_SITE"]];
3078 elseif(isset($arXMLElement[$this->mess["IBLOCK_XML2_ID"]]))
3079 $arElement["XML_ID"] = $arXMLElement[$this->mess["IBLOCK_XML2_ID"]];
3080
3081 $obElement = new CIBlockElement;
3082 $obElement->CancelWFSetMove();
3083 $rsElement = $obElement->GetList(
3084 Array("ID"=>"asc"),
3085 Array("=XML_ID" => $arElement["XML_ID"], "IBLOCK_ID" => $this->next_step["IBLOCK_ID"]),
3086 false, false,
3087 Array("ID", "TMP_ID", "ACTIVE", "CODE", "PREVIEW_PICTURE", "DETAIL_PICTURE")
3088 );
3089
3090 $bMatch = false;
3091 if($arDBElement = $rsElement->Fetch())
3092 $bMatch = ($arElement["TMP_ID"] == $arDBElement["TMP_ID"]);
3093
3094 if($bMatch && $this->use_crc)
3095 {
3096 //Check Active flag in XML is not set to false
3097 if($this->CheckIfElementIsActive($arXMLElement))
3098 {
3099 //In case element is not active in database we have to activate it and its offers
3100 if($arDBElement["ACTIVE"] != "Y")
3101 {
3102 $obElement->Update($arDBElement["ID"], array("ACTIVE"=>"Y"), $bWF);
3103 $this->ChangeOffersStatus($arDBElement["ID"], "Y", $bWF);
3104 $counter["UPD"]++;
3105 }
3106 }
3107 $arElement["ID"] = $arDBElement["ID"];
3108 }
3109 elseif(isset($arXMLElement[$this->mess["IBLOCK_XML2_NAME"]]))
3110 {
3111 if($arDBElement)
3112 {
3113 if ($arDBElement["PREVIEW_PICTURE"] > 0)
3114 $this->arElementFilesId["PREVIEW_PICTURE"] = array($arDBElement["PREVIEW_PICTURE"]);
3115 if ($arDBElement["DETAIL_PICTURE"] > 0)
3116 $this->arElementFilesId["DETAIL_PICTURE"] = array($arDBElement["DETAIL_PICTURE"]);
3117
3118 $rsProperties = $obElement->GetProperty($this->next_step["IBLOCK_ID"], $arDBElement["ID"], "sort", "asc");
3119 while($arProperty = $rsProperties->Fetch())
3120 {
3121 if(!array_key_exists($arProperty["ID"], $arElement["PROPERTY_VALUES"]))
3122 $arElement["PROPERTY_VALUES"][$arProperty["ID"]] = array(
3123 "bOld" => true,
3124 );
3125
3126 $arElement["PROPERTY_VALUES"][$arProperty["ID"]][$arProperty['PROPERTY_VALUE_ID']] = array(
3127 "VALUE"=>$arProperty['VALUE'],
3128 "DESCRIPTION"=>$arProperty["DESCRIPTION"]
3129 );
3130
3131 if($arProperty["PROPERTY_TYPE"] == "F" && $arProperty["VALUE"] > 0)
3132 $this->arElementFilesId[$arProperty["ID"]][] = $arProperty["VALUE"];
3133 }
3134 }
3135
3136 if ($this->bCatalog && $this->next_step["bOffer"])
3137 {
3138 if (isset($this->PROPERTY_MAP["CML2_LINK"]))
3139 {
3140 $p = strpos($arXMLElement[$this->mess["IBLOCK_XML2_ID"]], "#");
3141 if ($p !== false)
3142 {
3143 $link_xml_id = substr($arXMLElement[$this->mess["IBLOCK_XML2_ID"]], 0, $p);
3144 }
3145 else
3146 {
3147 $link_xml_id = $arXMLElement[$this->mess["IBLOCK_XML2_ID"]];
3148 }
3149
3150 $arElement["PROPERTY_VALUES"][$this->PROPERTY_MAP["CML2_LINK"]] = [
3151 "n0" => [
3152 "VALUE" => $this->GetElementByXML_ID(
3153 $this->arProperties[$this->PROPERTY_MAP["CML2_LINK"]]["LINK_IBLOCK_ID"],
3154 $link_xml_id
3155 ),
3156 "DESCRIPTION" => false,
3157 ],
3158 ];
3159 }
3160 }
3161
3162 if(isset($arXMLElement[$this->mess["IBLOCK_XML2_NAME"]]))
3163 $arElement["NAME"] = $arXMLElement[$this->mess["IBLOCK_XML2_NAME"]];
3164
3165 if(isset($arXMLElement[$this->mess["IBLOCK_XML2_DELETE_MARK"]]))
3166 {
3167 $value = $arXMLElement[$this->mess["IBLOCK_XML2_DELETE_MARK"]];
3168 $arElement["ACTIVE"] = ($value=="true") || intval($value)? "N": "Y";
3169 }
3170
3171 if(array_key_exists($this->mess["IBLOCK_XML2_BX_TAGS"], $arXMLElement))
3172 $arElement["TAGS"] = $arXMLElement[$this->mess["IBLOCK_XML2_BX_TAGS"]];
3173
3174 if(array_key_exists($this->mess["IBLOCK_XML2_DESCRIPTION"], $arXMLElement))
3175 {
3176 if($arXMLElement[$this->mess["IBLOCK_XML2_DESCRIPTION"]] <> '')
3177 $arElement["DETAIL_TEXT"] = $arXMLElement[$this->mess["IBLOCK_XML2_DESCRIPTION"]];
3178 else
3179 $arElement["DETAIL_TEXT"] = "";
3180
3181 if(preg_match('/<[a-zA-Z0-9]+.*?>/', $arElement["DETAIL_TEXT"]))
3182 $arElement["DETAIL_TEXT_TYPE"] = "html";
3183 else
3184 $arElement["DETAIL_TEXT_TYPE"] = "text";
3185 }
3186
3187 if(array_key_exists($this->mess["IBLOCK_XML2_FULL_TITLE"], $arXMLElement))
3188 {
3189 if($arXMLElement[$this->mess["IBLOCK_XML2_FULL_TITLE"]] <> '')
3190 $arElement["PREVIEW_TEXT"] = $arXMLElement[$this->mess["IBLOCK_XML2_FULL_TITLE"]];
3191 else
3192 $arElement["PREVIEW_TEXT"] = "";
3193
3194 if(preg_match('/<[a-zA-Z0-9]+.*?>/', $arElement["PREVIEW_TEXT"]))
3195 $arElement["PREVIEW_TEXT_TYPE"] = "html";
3196 else
3197 $arElement["PREVIEW_TEXT_TYPE"] = "text";
3198 }
3199
3200 if(array_key_exists($this->mess["IBLOCK_XML2_INHERITED_TEMPLATES"], $arXMLElement))
3201 {
3202 $arElement["IPROPERTY_TEMPLATES"] = array();
3203 foreach($arXMLElement[$this->mess["IBLOCK_XML2_INHERITED_TEMPLATES"]] as $TEMPLATE)
3204 {
3205 $id = $TEMPLATE[$this->mess["IBLOCK_XML2_ID"]];
3206 $template = $TEMPLATE[$this->mess["IBLOCK_XML2_VALUE"]];
3207 if($id <> '' && $template <> '')
3208 $arElement["IPROPERTY_TEMPLATES"][$id] = $template;
3209 }
3210 }
3211 if (isset($this->PROPERTY_MAP["CML2_BAR_CODE"]))
3212 {
3213 if (array_key_exists($this->mess["IBLOCK_XML2_BAR_CODE2"], $arXMLElement))
3214 {
3215 $arElement["PROPERTY_VALUES"][$this->PROPERTY_MAP["CML2_BAR_CODE"]] = [
3216 "n0" => [
3217 "VALUE" => $arXMLElement[$this->mess["IBLOCK_XML2_BAR_CODE2"]],
3218 "DESCRIPTION" => false,
3219 ],
3220 ];
3221 }
3222 elseif (array_key_exists($this->mess["IBLOCK_XML2_BAR_CODE"], $arXMLElement))
3223 {
3224 $arElement["PROPERTY_VALUES"][$this->PROPERTY_MAP["CML2_BAR_CODE"]] = [
3225 "n0" => [
3226 "VALUE" => $arXMLElement[$this->mess["IBLOCK_XML2_BAR_CODE"]],
3227 "DESCRIPTION" => false,
3228 ],
3229 ];
3230 }
3231 }
3232
3233 if (isset($this->PROPERTY_MAP["CML2_ARTICLE"]))
3234 {
3235 if (array_key_exists($this->mess["IBLOCK_XML2_ARTICLE"], $arXMLElement))
3236 {
3237 $arElement["PROPERTY_VALUES"][$this->PROPERTY_MAP["CML2_ARTICLE"]] = [
3238 "n0" => [
3239 "VALUE" => $arXMLElement[$this->mess["IBLOCK_XML2_ARTICLE"]],
3240 "DESCRIPTION" => false,
3241 ],
3242 ];
3243 }
3244 }
3245
3246 if (
3247 array_key_exists($this->mess["IBLOCK_XML2_MANUFACTURER"], $arXMLElement)
3248 && isset($this->PROPERTY_MAP["CML2_MANUFACTURER"])
3249 && $this->PROPERTY_MAP["CML2_MANUFACTURER"] > 0
3250 )
3251 {
3252 $arElement["PROPERTY_VALUES"][$this->PROPERTY_MAP["CML2_MANUFACTURER"]] = array(
3253 "n0" => array(
3254 "VALUE" => $this->CheckManufacturer($arXMLElement[$this->mess["IBLOCK_XML2_MANUFACTURER"]]),
3255 "DESCRIPTION" => false,
3256 ),
3257 );
3258 }
3259
3260 if(array_key_exists($this->mess["IBLOCK_XML2_PICTURE"], $arXMLElement))
3261 {
3262 $rsFiles = $this->_xml_file->GetList(
3263 array("ID" => "asc"),
3264 array("PARENT_ID" => $arParent["ID"], "NAME" => $this->mess["IBLOCK_XML2_PICTURE"])
3265 );
3266 $arFile = $rsFiles->Fetch();
3267 if($arFile)
3268 {
3269 $description = "";
3270 if($arFile["ATTRIBUTES"] <> '')
3271 {
3272 $arAttributes = unserialize($arFile["ATTRIBUTES"], ['allowed_classes' => false]);
3273 if(is_array($arAttributes) && array_key_exists($this->mess["IBLOCK_XML2_DESCRIPTION"], $arAttributes))
3274 {
3275 $description = $arAttributes[$this->mess["IBLOCK_XML2_DESCRIPTION"]];
3276 }
3277 }
3278
3279 if($arFile["VALUE"] <> '')
3280 {
3281 $arElement["DETAIL_PICTURE"] = $this->ResizePicture($arFile["VALUE"], $this->detail, "DETAIL_PICTURE", $this->PROPERTY_MAP["CML2_PICTURES"] ?? '');
3282
3283 if(is_array($arElement["DETAIL_PICTURE"]))
3284 {
3285 $arElement["DETAIL_PICTURE"]["description"] = $description;
3286 $this->arFileDescriptionsMap[$arFile["VALUE"]][] = &$arElement["DETAIL_PICTURE"]["description"];
3287 }
3288
3289 if(is_array($this->preview))
3290 {
3291 $arElement["PREVIEW_PICTURE"] = $this->ResizePicture($arFile["VALUE"], $this->preview, "PREVIEW_PICTURE");
3292 if(is_array($arElement["PREVIEW_PICTURE"]))
3293 {
3294 $arElement["PREVIEW_PICTURE"]["description"] = $description;
3295 $this->arFileDescriptionsMap[$arFile["VALUE"]][] = &$arElement["PREVIEW_PICTURE"]["description"];
3296 }
3297 }
3298 }
3299 else
3300 {
3301 $arElement["DETAIL_PICTURE"] = $this->MakeFileArray($this->_xml_file->GetAllChildrenArray($arFile["ID"]));
3302
3303 if(is_array($arElement["DETAIL_PICTURE"]))
3304 {
3305 $arElement["DETAIL_PICTURE"]["description"] = $description;
3306 }
3307 }
3308
3309 $prop_id = (int)($this->PROPERTY_MAP["CML2_PICTURES"] ?? 0);
3310 if($prop_id > 0)
3311 {
3312 $i = 1;
3313 while($arFile = $rsFiles->Fetch())
3314 {
3315 $description = "";
3316 if($arFile["ATTRIBUTES"] <> '')
3317 {
3318 $arAttributes = unserialize($arFile["ATTRIBUTES"], ['allowed_classes' => false]);
3319 if(is_array($arAttributes) && array_key_exists($this->mess["IBLOCK_XML2_DESCRIPTION"], $arAttributes))
3320 {
3321 $description = $arAttributes[$this->mess["IBLOCK_XML2_DESCRIPTION"]];
3322 }
3323 }
3324
3325 if($arFile["VALUE"] <> '')
3326 $arPropFile = $this->ResizePicture($arFile["VALUE"], $this->detail, $this->PROPERTY_MAP["CML2_PICTURES"], "DETAIL_PICTURE");
3327 else
3328 $arPropFile = $this->MakeFileArray($this->_xml_file->GetAllChildrenArray($arFile["ID"]));
3329
3330 if(is_array($arPropFile))
3331 {
3332 $arPropFile = array(
3333 "VALUE" => $arPropFile,
3334 "DESCRIPTION" => $description,
3335 );
3336 }
3337 $arElement["PROPERTY_VALUES"][$prop_id]["n".$i] = $arPropFile;
3338 if ($arFile["VALUE"] <> '')
3339 $this->arFileDescriptionsMap[$arFile["VALUE"]][] = &$arElement["PROPERTY_VALUES"][$prop_id]["n".$i]["DESCRIPTION"];
3340 $i++;
3341 }
3342
3343 if(
3344 isset($arElement["PROPERTY_VALUES"][$prop_id])
3345 && is_array($arElement["PROPERTY_VALUES"][$prop_id]))
3346 {
3347 foreach($arElement["PROPERTY_VALUES"][$prop_id] as $PROPERTY_VALUE_ID => $PROPERTY_VALUE)
3348 {
3349 if(!$PROPERTY_VALUE_ID)
3350 unset($arElement["PROPERTY_VALUES"][$prop_id][$PROPERTY_VALUE_ID]);
3351 elseif(strncmp($PROPERTY_VALUE_ID, "n", 1) !== 0)
3352 $arElement["PROPERTY_VALUES"][$prop_id][$PROPERTY_VALUE_ID] = array(
3353 "tmp_name" => "",
3354 "del" => "Y",
3355 );
3356 }
3357 unset($arElement["PROPERTY_VALUES"][$prop_id]["bOld"]);
3358 }
3359 }
3360 }
3361 }
3362
3363 $cleanCml2FilesProperty = false;
3364 if(
3365 array_key_exists($this->mess["IBLOCK_XML2_FILE"], $arXMLElement)
3366 && isset($this->PROPERTY_MAP["CML2_FILES"])
3367 )
3368 {
3369 $prop_id = $this->PROPERTY_MAP["CML2_FILES"];
3370 $rsFiles = $this->_xml_file->GetList(
3371 array("ID" => "asc"),
3372 array("PARENT_ID" => $arParent["ID"], "NAME" => $this->mess["IBLOCK_XML2_FILE"])
3373 );
3374 $i = 1;
3375 while($arFile = $rsFiles->Fetch())
3376 {
3377
3378 if($arFile["VALUE"] <> '')
3379 $file = $this->MakeFileArray($arFile["VALUE"], array($prop_id));
3380 else
3381 $file = $this->MakeFileArray($this->_xml_file->GetAllChildrenArray($arFile["ID"]));
3382
3383 $arElement["PROPERTY_VALUES"][$prop_id]["n".$i] = array(
3384 "VALUE" => $file,
3385 "DESCRIPTION" => $file["description"],
3386 );
3387 if($arFile["ATTRIBUTES"] <> '')
3388 {
3389 $desc = unserialize($arFile["ATTRIBUTES"], ['allowed_classes' => false]);
3390 if(is_array($desc) && array_key_exists($this->mess["IBLOCK_XML2_DESCRIPTION"], $desc))
3391 {
3392 $arElement["PROPERTY_VALUES"][$prop_id]["n".$i]["DESCRIPTION"] = $desc[$this->mess["IBLOCK_XML2_DESCRIPTION"]];
3393 }
3394 }
3395 $i++;
3396 }
3397 $cleanCml2FilesProperty = true;
3398 }
3399
3400 if(array_key_exists($this->mess["IBLOCK_XML2_GROUPS"], $arXMLElement))
3401 {
3402 $arElement["IBLOCK_SECTION"] = array();
3403 if (
3404 !empty($arXMLElement[$this->mess["IBLOCK_XML2_GROUPS"]])
3405 && is_array($arXMLElement[$this->mess["IBLOCK_XML2_GROUPS"]])
3406 )
3407 {
3408 foreach ($arXMLElement[$this->mess["IBLOCK_XML2_GROUPS"]] as $value)
3409 {
3410 if (array_key_exists($value, $this->SECTION_MAP))
3411 $arElement["IBLOCK_SECTION"][] = $this->SECTION_MAP[$value];
3412 }
3413 }
3414 if($arElement["IBLOCK_SECTION"])
3415 $arElement["IBLOCK_SECTION_ID"] = $arElement["IBLOCK_SECTION"][0];
3416 }
3417
3418 if(array_key_exists($this->mess["IBLOCK_XML2_PRICES"], $arXMLElement))
3419 {//Collect price information for future use
3420 $arElement["PRICES"] = array();
3421 if (is_array($arXMLElement[$this->mess["IBLOCK_XML2_PRICES"]]))
3422 {
3423 foreach($arXMLElement[$this->mess["IBLOCK_XML2_PRICES"]] as $price)
3424 {
3425 if(isset($price[$this->mess["IBLOCK_XML2_PRICE_TYPE_ID"]]) && array_key_exists($price[$this->mess["IBLOCK_XML2_PRICE_TYPE_ID"]], $this->PRICES_MAP))
3426 {
3427 $price["PRICE"] = $this->PRICES_MAP[$price[$this->mess["IBLOCK_XML2_PRICE_TYPE_ID"]]];
3428 $arElement["PRICES"][] = $price;
3429 }
3430 }
3431 }
3432
3433 $arElement["DISCOUNTS"] = array();
3434 if(isset($arXMLElement[$this->mess["IBLOCK_XML2_DISCOUNTS"]]))
3435 {
3436 foreach($arXMLElement[$this->mess["IBLOCK_XML2_DISCOUNTS"]] as $discount)
3437 {
3438 if(
3439 isset($discount[$this->mess["IBLOCK_XML2_DISCOUNT_CONDITION"]])
3440 && $discount[$this->mess["IBLOCK_XML2_DISCOUNT_CONDITION"]]===$this->mess["IBLOCK_XML2_DISCOUNT_COND_VOLUME"]
3441 )
3442 {
3443 $discount_value = $this->ToInt($discount[$this->mess["IBLOCK_XML2_DISCOUNT_COND_VALUE"]]);
3444 $discount_percent = $this->ToFloat($discount[$this->mess["IBLOCK_XML2_DISCOUNT_COND_PERCENT"]]);
3445 if($discount_value > 0 && $discount_percent > 0)
3446 $arElement["DISCOUNTS"][$discount_value] = $discount_percent;
3447 }
3448 }
3449 }
3450 }
3451
3452 if($this->bCatalog && array_key_exists($this->mess["IBLOCK_XML2_AMOUNT"], $arXMLElement))
3453 {
3454 $arElement["QUANTITY_RESERVED"] = 0;
3455 if($arDBElement)
3456 {
3458 'select' => ['ID', 'QUANTITY_RESERVED'],
3459 'filter' => ['=ID' => $arDBElement['ID']]
3460 ]);
3461 $arElementTmp = $iterator->fetch();
3462 if (isset($arElementTmp["QUANTITY_RESERVED"]))
3463 $arElement["QUANTITY_RESERVED"] = (float)$arElementTmp["QUANTITY_RESERVED"];
3464 unset($arElementTmp);
3465 unset($iterator);
3466 }
3467 $arElement["QUANTITY"] = $this->ToFloat($arXMLElement[$this->mess["IBLOCK_XML2_AMOUNT"]]) - $arElement["QUANTITY_RESERVED"];
3468 }
3469
3470 if (
3471 isset($arXMLElement[$this->mess["IBLOCK_XML2_ITEM_ATTRIBUTES"]])
3472 && isset($this->PROPERTY_MAP["CML2_ATTRIBUTES"])
3473 )
3474 {
3475 $arElement["PROPERTY_VALUES"][$this->PROPERTY_MAP["CML2_ATTRIBUTES"]] = array();
3476 $i = 0;
3477 foreach($arXMLElement[$this->mess["IBLOCK_XML2_ITEM_ATTRIBUTES"]] as $value)
3478 {
3479 $arElement["PROPERTY_VALUES"][$this->PROPERTY_MAP["CML2_ATTRIBUTES"]]["n".$i] = array(
3480 "VALUE" => $value[$this->mess["IBLOCK_XML2_VALUE"]],
3481 "DESCRIPTION" => $value[$this->mess["IBLOCK_XML2_NAME"]],
3482 );
3483 $i++;
3484 }
3485 }
3486
3487 $i = 0;
3488 $weightKey = false;
3489 if (isset($arXMLElement[$this->mess["IBLOCK_XML2_TRAITS_VALUES"]]))
3490 {
3491 if (isset($this->PROPERTY_MAP["CML2_TRAITS"]))
3492 {
3493 $arElement["PROPERTY_VALUES"][$this->PROPERTY_MAP["CML2_TRAITS"]] = [];
3494 }
3495 foreach($arXMLElement[$this->mess["IBLOCK_XML2_TRAITS_VALUES"]] as $value)
3496 {
3497 if(
3498 !array_key_exists("PREVIEW_TEXT", $arElement)
3499 && $value[$this->mess["IBLOCK_XML2_NAME"]] == $this->mess["IBLOCK_XML2_FULL_TITLE2"]
3500 )
3501 {
3502 $arElement["PREVIEW_TEXT"] = $value[$this->mess["IBLOCK_XML2_VALUE"]];
3503 if(strpos($arElement["PREVIEW_TEXT"], "<") !== false)
3504 $arElement["PREVIEW_TEXT_TYPE"] = "html";
3505 else
3506 $arElement["PREVIEW_TEXT_TYPE"] = "text";
3507 }
3508 elseif(
3509 $value[$this->mess["IBLOCK_XML2_NAME"]] == $this->mess["IBLOCK_XML2_HTML_DESCRIPTION"]
3510 )
3511 {
3512 if($value[$this->mess["IBLOCK_XML2_VALUE"]] <> '')
3513 {
3514 $arElement["DETAIL_TEXT"] = $value[$this->mess["IBLOCK_XML2_VALUE"]];
3515 $arElement["DETAIL_TEXT_TYPE"] = "html";
3516 }
3517 }
3518 elseif(
3519 $value[$this->mess["IBLOCK_XML2_NAME"]] == $this->mess["IBLOCK_XML2_FILE"]
3520 )
3521 {
3522 if($value[$this->mess["IBLOCK_XML2_VALUE"]] <> '')
3523 {
3524 $prop_id = $this->PROPERTY_MAP["CML2_FILES"] ?? 0;
3525
3526 $j = 1;
3527 while (isset($arElement["PROPERTY_VALUES"][$prop_id]["n".$j]))
3528 $j++;
3529
3530 $file = $this->MakeFileArray($value[$this->mess["IBLOCK_XML2_VALUE"]], array($prop_id));
3531 if (is_array($file))
3532 {
3533 $arElement["PROPERTY_VALUES"][$prop_id]["n".$j] = array(
3534 "VALUE" => $file,
3535 "DESCRIPTION" => "",
3536 );
3537 unset($arElement["PROPERTY_VALUES"][$prop_id]["bOld"]);
3538 $this->arFileDescriptionsMap[$value[$this->mess["IBLOCK_XML2_VALUE"]]][] = &$arElement["PROPERTY_VALUES"][$prop_id]["n".$j]["DESCRIPTION"];
3539 $cleanCml2FilesProperty = true;
3540 }
3541 }
3542 }
3543 elseif(
3544 $value[$this->mess["IBLOCK_XML2_NAME"]] == $this->mess["IBLOCK_XML2_FILE_DESCRIPTION"]
3545 )
3546 {
3547 if($value[$this->mess["IBLOCK_XML2_VALUE"]] <> '')
3548 {
3549 [$fileName, $description] = explode("#", $value[$this->mess["IBLOCK_XML2_VALUE"]]);
3550 if (isset($this->arFileDescriptionsMap[$fileName]))
3551 {
3552 foreach($this->arFileDescriptionsMap[$fileName] as $k => $tmp)
3553 $this->arFileDescriptionsMap[$fileName][$k] = $description;
3554 }
3555 }
3556 }
3557 else
3558 {
3559 if($value[$this->mess["IBLOCK_XML2_NAME"]] == $this->mess["IBLOCK_XML2_WEIGHT"])
3560 {
3561 $arElement["BASE_WEIGHT"] = $this->ToFloat($value[$this->mess["IBLOCK_XML2_VALUE"]])*1000;
3562 $weightKey = "n".$i;
3563 }
3564 if (isset($this->PROPERTY_MAP["CML2_TRAITS"]))
3565 {
3566 $arElement["PROPERTY_VALUES"][$this->PROPERTY_MAP["CML2_TRAITS"]]["n" . $i] = [
3567 "VALUE" => $value[$this->mess["IBLOCK_XML2_VALUE"]],
3568 "DESCRIPTION" => $value[$this->mess["IBLOCK_XML2_NAME"]],
3569 ];
3570 }
3571 $i++;
3572 }
3573 }
3574 }
3575
3576 if (isset($arXMLElement[$this->mess["IBLOCK_XML2_WEIGHT"]]))
3577 {
3578 if (isset($this->PROPERTY_MAP["CML2_TRAITS"]))
3579 {
3580 if ($weightKey === false)
3581 {
3582 if (!isset($arElement["PROPERTY_VALUES"][$this->PROPERTY_MAP["CML2_TRAITS"]]))
3583 {
3584 $arElement["PROPERTY_VALUES"][$this->PROPERTY_MAP["CML2_TRAITS"]] = [];
3585 $weightKey = "n0";
3586 }
3587 else // $weightKey === false && isset($arElement["PROPERTY_VALUES"][$this->PROPERTY_MAP["CML2_TRAITS"]])
3588 {
3589 $weightKey = "n" . $i;
3590 }
3591 }
3592 $arElement["PROPERTY_VALUES"][$this->PROPERTY_MAP["CML2_TRAITS"]][$weightKey] = [
3593 "VALUE" => $arXMLElement[$this->mess["IBLOCK_XML2_WEIGHT"]],
3594 "DESCRIPTION" => $this->mess["IBLOCK_XML2_WEIGHT"],
3595 ];
3596 }
3597 $arElement["BASE_WEIGHT"] = $this->ToFloat($arXMLElement[$this->mess["IBLOCK_XML2_WEIGHT"]])*1000;
3598 }
3599
3600 if ($this->bCatalog)
3601 {
3602 $arElement = array_merge(
3603 $arElement,
3604 $this->getProductFieldsFromXml($arXMLElement)
3605 );
3606 }
3607
3608 if ($cleanCml2FilesProperty)
3609 {
3610 $prop_id = $this->PROPERTY_MAP["CML2_FILES"] ?? 0;
3611 if (
3612 isset($arElement["PROPERTY_VALUES"][$prop_id])
3613 && is_array($arElement["PROPERTY_VALUES"][$prop_id])
3614 )
3615 {
3616 foreach($arElement["PROPERTY_VALUES"][$prop_id] as $PROPERTY_VALUE_ID => $PROPERTY_VALUE)
3617 {
3618 if(!$PROPERTY_VALUE_ID)
3619 unset($arElement["PROPERTY_VALUES"][$prop_id][$PROPERTY_VALUE_ID]);
3620 elseif(strncmp($PROPERTY_VALUE_ID, "n", 1) !== 0)
3621 $arElement["PROPERTY_VALUES"][$prop_id][$PROPERTY_VALUE_ID] = array(
3622 "tmp_name" => "",
3623 "del" => "Y",
3624 );
3625 }
3626 unset($arElement["PROPERTY_VALUES"][$prop_id]["bOld"]);
3627 }
3628 }
3629
3630 if (isset($arXMLElement[$this->mess["IBLOCK_XML2_TAXES_VALUES"]]))
3631 {
3632 if (isset($this->PROPERTY_MAP["CML2_TAXES"]))
3633 {
3634 $arElement["PROPERTY_VALUES"][$this->PROPERTY_MAP["CML2_TAXES"]] = [];
3635 $i = 0;
3636 foreach ($arXMLElement[$this->mess["IBLOCK_XML2_TAXES_VALUES"]] as $value)
3637 {
3638 $arElement["PROPERTY_VALUES"][$this->PROPERTY_MAP["CML2_TAXES"]]["n" . $i] = [
3639 "VALUE" => $value[$this->mess["IBLOCK_XML2_TAX_VALUE"]],
3640 "DESCRIPTION" => $value[$this->mess["IBLOCK_XML2_NAME"]],
3641 ];
3642 $i++;
3643 }
3644 }
3645 }
3646
3647 $rsBaseUnit = $this->_xml_file->GetList(
3648 array("ID" => "asc"),
3649 array(
3650 "><LEFT_MARGIN" => array($arParent["LEFT_MARGIN"], $arParent["RIGHT_MARGIN"]),
3651 "NAME" => $this->mess["IBLOCK_XML2_BASE_UNIT"],
3652 ),
3653 array("ID", "ATTRIBUTES")
3654 );
3655 while ($arBaseUnit = $rsBaseUnit->Fetch())
3656 {
3657 if($arBaseUnit["ATTRIBUTES"] <> '')
3658 {
3659 $info = unserialize($arBaseUnit["ATTRIBUTES"], ['allowed_classes' => false]);
3660 if(
3661 is_array($info)
3662 && array_key_exists($this->mess["IBLOCK_XML2_CODE"], $info)
3663 )
3664 {
3665 $arXMLElement[$this->mess["IBLOCK_XML2_BASE_UNIT"]] = $info[$this->mess["IBLOCK_XML2_CODE"]];
3666 }
3667 }
3668 }
3669
3670 if(isset($arXMLElement[$this->mess["IBLOCK_XML2_BASE_UNIT"]]))
3671 {
3672 $unitData = $this->convertBaseUnitFromXmlToPropertyValue($arXMLElement[$this->mess["IBLOCK_XML2_BASE_UNIT"]]);
3673 if (isset($this->PROPERTY_MAP["CML2_BASE_UNIT"]))
3674 {
3675 $arElement["PROPERTY_VALUES"][$this->PROPERTY_MAP["CML2_BASE_UNIT"]] = [
3676 "n0" => $unitData,
3677 ];
3678 }
3679 if ($unitData["DESCRIPTION"])
3680 {
3681 $arElement['MEASURE'] = $unitData["DESCRIPTION"];
3682 }
3683 }
3684
3685 if(isset($arXMLElement[$this->mess["IBLOCK_XML2_PROPERTIES_VALUES"]]))
3686 {
3687 foreach($arXMLElement[$this->mess["IBLOCK_XML2_PROPERTIES_VALUES"]] as $value)
3688 {
3689 if (!isset($value[$this->mess['IBLOCK_XML2_ID']]))
3690 {
3691 continue;
3692 }
3693
3694 $prop_id = $value[$this->mess["IBLOCK_XML2_ID"]];
3695 unset($value[$this->mess["IBLOCK_XML2_ID"]]);
3696
3697 //Handle properties which is actually element fields
3698 if(!array_key_exists($prop_id, $this->PROPERTY_MAP))
3699 {
3700 if($prop_id == "CML2_CODE")
3701 $arElement["CODE"] = $value[$this->mess["IBLOCK_XML2_VALUE"]] ?? "";
3702 elseif($prop_id == "CML2_ACTIVE")
3703 {
3704 $value = array_pop($value);
3705 $arElement["ACTIVE"] = ($value=="true") || intval($value)? "Y": "N";
3706 }
3707 elseif($prop_id == "CML2_SORT")
3708 $arElement["SORT"] = array_pop($value);
3709 elseif($prop_id == "CML2_ACTIVE_FROM")
3710 $arElement["ACTIVE_FROM"] = CDatabase::FormatDate(array_pop($value), "YYYY-MM-DD HH:MI:SS", CLang::GetDateFormat("FULL"));
3711 elseif($prop_id == "CML2_ACTIVE_TO")
3712 $arElement["ACTIVE_TO"] = CDatabase::FormatDate(array_pop($value), "YYYY-MM-DD HH:MI:SS", CLang::GetDateFormat("FULL"));
3713 elseif($prop_id == "CML2_PREVIEW_TEXT")
3714 {
3715 if(array_key_exists($this->mess["IBLOCK_XML2_VALUE"], $value))
3716 {
3717 if(isset($value[$this->mess["IBLOCK_XML2_VALUE"]]))
3718 $arElement["PREVIEW_TEXT"] = $value[$this->mess["IBLOCK_XML2_VALUE"]];
3719 else
3720 $arElement["PREVIEW_TEXT"] = "";
3721
3722 if(isset($value[$this->mess["IBLOCK_XML2_TYPE"]]))
3723 $arElement["PREVIEW_TEXT_TYPE"] = $value[$this->mess["IBLOCK_XML2_TYPE"]];
3724 else
3725 $arElement["PREVIEW_TEXT_TYPE"] = "html";
3726 }
3727 }
3728 elseif($prop_id == "CML2_DETAIL_TEXT")
3729 {
3730 if(array_key_exists($this->mess["IBLOCK_XML2_VALUE"], $value))
3731 {
3732 if(isset($value[$this->mess["IBLOCK_XML2_VALUE"]]))
3733 $arElement["DETAIL_TEXT"] = $value[$this->mess["IBLOCK_XML2_VALUE"]];
3734 else
3735 $arElement["DETAIL_TEXT"] = "";
3736
3737 if(isset($value[$this->mess["IBLOCK_XML2_TYPE"]]))
3738 $arElement["DETAIL_TEXT_TYPE"] = $value[$this->mess["IBLOCK_XML2_TYPE"]];
3739 else
3740 $arElement["DETAIL_TEXT_TYPE"] = "html";
3741 }
3742 }
3743 elseif($prop_id == "CML2_PREVIEW_PICTURE")
3744 {
3745 if(!is_array($this->preview) || !$arElement["PREVIEW_PICTURE"])
3746 {
3747 $arElement["PREVIEW_PICTURE"] = $this->MakeFileArray($value[$this->mess["IBLOCK_XML2_VALUE"]], array("PREVIEW_PICTURE"));
3748 $arElement["PREVIEW_PICTURE"]["COPY_FILE"] = "Y";
3749 }
3750 }
3751
3752 continue;
3753 }
3754
3755 $prop_id = $this->PROPERTY_MAP[$prop_id];
3756 $prop_type = $this->arProperties[$prop_id]["PROPERTY_TYPE"];
3757
3758 if(!array_key_exists($prop_id, $arElement["PROPERTY_VALUES"]))
3759 $arElement["PROPERTY_VALUES"][$prop_id] = array();
3760
3761 //check for bitrix extended format
3762 if(array_key_exists($this->mess["IBLOCK_XML2_PROPERTY_VALUE"], $value))
3763 {
3764 $i = 1;
3765 $strPV = $this->mess["IBLOCK_XML2_PROPERTY_VALUE"];
3766 $lPV = mb_strlen($strPV);
3767 foreach($value as $k=>$prop_value)
3768 {
3769 if ($prop_value === null)
3770 {
3771 continue;
3772 }
3773 if(mb_substr($k, 0, $lPV) === $strPV)
3774 {
3775 if(array_key_exists($this->mess["IBLOCK_XML2_SERIALIZED"], $prop_value))
3776 $prop_value[$this->mess["IBLOCK_XML2_VALUE"]] = $this->Unserialize($prop_value[$this->mess["IBLOCK_XML2_VALUE"]]);
3777 if($prop_type=="F")
3778 {
3779 $prop_value[$this->mess["IBLOCK_XML2_VALUE"]] = $this->MakeFileArray($prop_value[$this->mess["IBLOCK_XML2_VALUE"]], array($prop_id));
3780 }
3781 elseif($prop_type=="G")
3782 $prop_value[$this->mess["IBLOCK_XML2_VALUE"]] = $this->GetSectionByXML_ID($this->arProperties[$prop_id]["LINK_IBLOCK_ID"], $prop_value[$this->mess["IBLOCK_XML2_VALUE"]]);
3783 elseif($prop_type=="E")
3784 $prop_value[$this->mess["IBLOCK_XML2_VALUE"]] = $this->GetElementByXML_ID($this->arProperties[$prop_id]["LINK_IBLOCK_ID"], $prop_value[$this->mess["IBLOCK_XML2_VALUE"]]);
3785 elseif($prop_type=="L")
3786 $prop_value[$this->mess["IBLOCK_XML2_VALUE"]] = $this->GetEnumByXML_ID($this->arProperties[$prop_id]["ID"], $prop_value[$this->mess["IBLOCK_XML2_VALUE"]]);
3787
3788 if(array_key_exists("bOld", $arElement["PROPERTY_VALUES"][$prop_id]))
3789 {
3790 if($prop_type=="F")
3791 {
3792 foreach($arElement["PROPERTY_VALUES"][$prop_id] as $PROPERTY_VALUE_ID => $PROPERTY_VALUE)
3793 $arElement["PROPERTY_VALUES"][$prop_id][$PROPERTY_VALUE_ID] = array(
3794 "tmp_name" => "",
3795 "del" => "Y",
3796 );
3797 unset($arElement["PROPERTY_VALUES"][$prop_id]["bOld"]);
3798 }
3799 else
3800 $arElement["PROPERTY_VALUES"][$prop_id] = array();
3801 }
3802
3803 $arElement["PROPERTY_VALUES"][$prop_id]["n".$i] = array(
3804 "VALUE" => $prop_value[$this->mess["IBLOCK_XML2_VALUE"]],
3805 "DESCRIPTION" => $prop_value[$this->mess["IBLOCK_XML2_DESCRIPTION"]] ?? null,
3806 );
3807 $i++;
3808 }
3809 }
3810 }
3811 else
3812 {
3813 if($prop_type == "L" && !array_key_exists($this->mess["IBLOCK_XML2_VALUE_ID"], $value))
3814 $l_key = $this->mess["IBLOCK_XML2_VALUE"];
3815 else
3816 $l_key = $this->mess["IBLOCK_XML2_VALUE_ID"];
3817
3818 $i = 0;
3819 foreach($value as $k=>$prop_value)
3820 {
3821 if(array_key_exists("bOld", $arElement["PROPERTY_VALUES"][$prop_id]))
3822 {
3823 if($prop_type=="F")
3824 {
3825 foreach($arElement["PROPERTY_VALUES"][$prop_id] as $PROPERTY_VALUE_ID => $PROPERTY_VALUE)
3826 $arElement["PROPERTY_VALUES"][$prop_id][$PROPERTY_VALUE_ID] = array(
3827 "tmp_name" => "",
3828 "del" => "Y",
3829 );
3830 unset($arElement["PROPERTY_VALUES"][$prop_id]["bOld"]);
3831 }
3832 else
3833 {
3834 $arElement["PROPERTY_VALUES"][$prop_id] = array();
3835 }
3836 }
3837
3838 if($prop_type == "L" && $k == $l_key)
3839 {
3840 $prop_value = $this->GetEnumByXML_ID($this->arProperties[$prop_id]["ID"], $prop_value);
3841 }
3842 elseif($prop_type == "N" && isset($this->next_step["sdp"]))
3843 {
3844 if ($prop_value <> '')
3845 $prop_value = $this->ToFloat($prop_value);
3846 }
3847
3848 $arElement["PROPERTY_VALUES"][$prop_id]["n".$i] = array(
3849 "VALUE" => $prop_value,
3850 "DESCRIPTION" => false,
3851 );
3852 $i++;
3853 }
3854 }
3855 }
3856 }
3857
3858 //If there is no BaseUnit specified check prices for it
3859 if (isset($this->PROPERTY_MAP["CML2_BASE_UNIT"]))
3860 {
3861 if (
3862 (
3863 !array_key_exists($this->PROPERTY_MAP["CML2_BASE_UNIT"], $arElement["PROPERTY_VALUES"])
3864 || (
3865 is_array($arElement["PROPERTY_VALUES"][$this->PROPERTY_MAP["CML2_BASE_UNIT"]])
3866 && array_key_exists("bOld",
3867 $arElement["PROPERTY_VALUES"][$this->PROPERTY_MAP["CML2_BASE_UNIT"]])
3868 )
3869 )
3870 && isset($arXMLElement[$this->mess["IBLOCK_XML2_PRICES"]])
3871 )
3872 {
3873 foreach ($arXMLElement[$this->mess["IBLOCK_XML2_PRICES"]] as $price)
3874 {
3875 if (
3876 isset($price[$this->mess["IBLOCK_XML2_PRICE_TYPE_ID"]])
3877 && array_key_exists($price[$this->mess["IBLOCK_XML2_PRICE_TYPE_ID"]], $this->PRICES_MAP)
3878 && array_key_exists($this->mess["IBLOCK_XML2_MEASURE"], $price)
3879 )
3880 {
3881 $arElement["PROPERTY_VALUES"][$this->PROPERTY_MAP["CML2_BASE_UNIT"]] = [
3882 "n0" => $this->convertBaseUnitFromXmlToPropertyValue($price[$this->mess["IBLOCK_XML2_MEASURE"]]),
3883 ];
3884 break;
3885 }
3886 }
3887 }
3888 }
3889
3890 if($arDBElement)
3891 {
3892 foreach($arElement["PROPERTY_VALUES"] as $prop_id=>$prop)
3893 {
3894 if(is_array($arElement["PROPERTY_VALUES"][$prop_id]) && array_key_exists("bOld", $arElement["PROPERTY_VALUES"][$prop_id]))
3895 {
3896 if($this->arProperties[$prop_id]["PROPERTY_TYPE"]=="F")
3897 unset($arElement["PROPERTY_VALUES"][$prop_id]);
3898 else
3899 unset($arElement["PROPERTY_VALUES"][$prop_id]["bOld"]);
3900 }
3901 }
3902
3903 if (!isset($arElement['MODIFIED_BY']) || (int)$arElement['MODIFIED_BY'] <= 0)
3904 {
3905 if ($this->currentUserId > 0)
3906 {
3907 $arElement['MODIFIED_BY'] = $this->currentUserId;
3908 }
3909 }
3910
3911 if(!array_key_exists("CODE", $arElement) && is_array($this->translit_on_update))
3912 {
3913 $CODE = CUtil::translit($arElement["NAME"], LANGUAGE_ID, $this->translit_on_update);
3914 $CODE = $this->CheckElementCode($this->next_step["IBLOCK_ID"], $arDBElement["ID"], $CODE);
3915 if($CODE !== false)
3916 $arElement["CODE"] = $CODE;
3917 }
3918
3919 //Check if detail picture hasn't been changed
3920 if (
3921 isset($arElement["DETAIL_PICTURE"])
3922 && !isset($arElement["PREVIEW_PICTURE"])
3923 && is_array($arElement["DETAIL_PICTURE"])
3924 && isset($arElement["DETAIL_PICTURE"]["external_id"])
3925 && $this->arElementFilesId
3926 && $this->arElementFilesId["DETAIL_PICTURE"]
3927 && isset($this->arElementFiles[$this->arElementFilesId["DETAIL_PICTURE"][0]])
3928 && $this->arElementFiles[$this->arElementFilesId["DETAIL_PICTURE"][0]]["EXTERNAL_ID"] === $arElement["DETAIL_PICTURE"]["external_id"]
3929 && $this->arElementFiles[$this->arElementFilesId["DETAIL_PICTURE"][0]]["DESCRIPTION"] === $arElement["DETAIL_PICTURE"]["description"]
3930 )
3931 {
3932 unset($arElement["DETAIL_PICTURE"]);
3933 }
3934
3935 $updateResult = $obElement->Update($arDBElement["ID"], $arElement, $bWF, true, $this->iblock_resize);
3936 //In case element was not active in database we have to activate its offers
3937 if($arDBElement["ACTIVE"] != "Y")
3938 {
3939 $this->ChangeOffersStatus($arDBElement["ID"], "Y", $bWF);
3940 }
3941 $arElement["ID"] = $arDBElement["ID"];
3942 if($updateResult)
3943 {
3944 $counter["UPD"]++;
3945 }
3946 else
3947 {
3948 $this->LAST_ERROR = $obElement->LAST_ERROR;
3949 $counter["ERR"]++;
3950 }
3951 }
3952 else
3953 {
3954 if(!array_key_exists("CODE", $arElement) && is_array($this->translit_on_add))
3955 {
3956 $CODE = CUtil::translit($arElement["NAME"], LANGUAGE_ID, $this->translit_on_add);
3957 $CODE = $this->CheckElementCode($this->next_step["IBLOCK_ID"], 0, $CODE);
3958 if($CODE !== false)
3959 $arElement["CODE"] = $CODE;
3960 }
3961
3962 $arElement["IBLOCK_ID"] = $this->next_step["IBLOCK_ID"];
3963 $this->fillDefaultPropertyValues($arElement, $this->arProperties);
3964
3965 $arElement["ID"] = $obElement->Add($arElement, $bWF, true, $this->iblock_resize);
3966 if($arElement["ID"])
3967 {
3968 $counter["ADD"]++;
3969 }
3970 else
3971 {
3972 $this->LAST_ERROR = $obElement->LAST_ERROR;
3973 $counter["ERR"]++;
3974 }
3975 }
3976 }
3977 elseif(array_key_exists($this->mess["IBLOCK_XML2_PRICES"], $arXMLElement))
3978 {
3979 //Collect price information for future use
3980 $arElement["PRICES"] = array();
3981 if (is_array($arXMLElement[$this->mess["IBLOCK_XML2_PRICES"]]))
3982 {
3983 foreach($arXMLElement[$this->mess["IBLOCK_XML2_PRICES"]] as $price)
3984 {
3985 if(isset($price[$this->mess["IBLOCK_XML2_PRICE_TYPE_ID"]]) && array_key_exists($price[$this->mess["IBLOCK_XML2_PRICE_TYPE_ID"]], $this->PRICES_MAP))
3986 {
3987 $price["PRICE"] = $this->PRICES_MAP[$price[$this->mess["IBLOCK_XML2_PRICE_TYPE_ID"]]];
3988 $arElement["PRICES"][] = $price;
3989 }
3990 }
3991 }
3992
3993 $arElement["DISCOUNTS"] = array();
3994 if(isset($arXMLElement[$this->mess["IBLOCK_XML2_DISCOUNTS"]]))
3995 {
3996 foreach($arXMLElement[$this->mess["IBLOCK_XML2_DISCOUNTS"]] as $discount)
3997 {
3998 if(
3999 isset($discount[$this->mess["IBLOCK_XML2_DISCOUNT_CONDITION"]])
4000 && $discount[$this->mess["IBLOCK_XML2_DISCOUNT_CONDITION"]]===$this->mess["IBLOCK_XML2_DISCOUNT_COND_VOLUME"]
4001 )
4002 {
4003 $discount_value = $this->ToInt($discount[$this->mess["IBLOCK_XML2_DISCOUNT_COND_VALUE"]]);
4004 $discount_percent = $this->ToFloat($discount[$this->mess["IBLOCK_XML2_DISCOUNT_COND_PERCENT"]]);
4005 if($discount_value > 0 && $discount_percent > 0)
4006 $arElement["DISCOUNTS"][$discount_value] = $discount_percent;
4007 }
4008 }
4009 }
4010
4011 if ($arDBElement)
4012 {
4013 $arElement["ID"] = $arDBElement["ID"];
4014 $counter["UPD"]++;
4015 }
4016 }
4017
4018 if(isset($arXMLElement[$this->mess["IBLOCK_XML2_STORE_AMOUNT_LIST"]]))
4019 {
4020 $arElement["STORE_AMOUNT"] = array();
4021 foreach($arXMLElement[$this->mess["IBLOCK_XML2_STORE_AMOUNT_LIST"]] as $storeAmount)
4022 {
4023 if(isset($storeAmount[$this->mess["IBLOCK_XML2_STORE_ID"]]))
4024 {
4025 $storeXMLID = $storeAmount[$this->mess["IBLOCK_XML2_STORE_ID"]];
4026 $amount = $this->ToFloat($storeAmount[$this->mess["IBLOCK_XML2_AMOUNT"]]);
4027 $arElement["STORE_AMOUNT"][$storeXMLID] = $amount;
4028 }
4029 }
4030 }
4031 elseif(
4032 array_key_exists($this->mess["IBLOCK_XML2_STORES"], $arXMLElement)
4033 || array_key_exists($this->mess["IBLOCK_XML2_STORE"], $arXMLElement)
4034 )
4035 {
4036 $arElement["STORE_AMOUNT"] = array();
4037 $rsStores = $this->_xml_file->GetList(
4038 array("ID" => "asc"),
4039 array(
4040 "><LEFT_MARGIN" => array($arParent["LEFT_MARGIN"], $arParent["RIGHT_MARGIN"]),
4041 "NAME" => $this->mess["IBLOCK_XML2_STORE"],
4042 ),
4043 array("ID", "ATTRIBUTES")
4044 );
4045 while ($arStore = $rsStores->Fetch())
4046 {
4047 if($arStore["ATTRIBUTES"] <> '')
4048 {
4049 $info = unserialize($arStore["ATTRIBUTES"], ['allowed_classes' => false]);
4050 if(
4051 is_array($info)
4052 && array_key_exists($this->mess["IBLOCK_XML2_STORE_ID"], $info)
4053 && array_key_exists($this->mess["IBLOCK_XML2_STORE_AMOUNT"], $info)
4054 )
4055 {
4056 $arElement["STORE_AMOUNT"][$info[$this->mess["IBLOCK_XML2_STORE_ID"]]] = $this->ToFloat($info[$this->mess["IBLOCK_XML2_STORE_AMOUNT"]]);
4057 }
4058 }
4059 }
4060 }
4061
4062 if($bMatch && $this->use_crc)
4063 {
4064 //nothing to do
4065 }
4066 elseif($arElement["ID"] && $this->bCatalog && $this->isCatalogIblock)
4067 {
4068 $arProduct = array(
4069 "ID" => $arElement["ID"],
4070 );
4071
4072 if(isset($arElement["QUANTITY"]))
4073 $arProduct["QUANTITY"] = (float)$arElement["QUANTITY"];
4074 elseif(isset($arElement["STORE_AMOUNT"]) && !empty($arElement["STORE_AMOUNT"]))
4075 $arProduct["QUANTITY"] = $this->countTotalQuantity($arElement["STORE_AMOUNT"]);
4076
4077 $CML_LINK = '';
4078 $CML_LINK_ELEMENT = 0;
4079 if (isset($this->PROPERTY_MAP["CML2_LINK"]))
4080 {
4081 $CML_LINK = $this->PROPERTY_MAP["CML2_LINK"];
4082 if (isset($arElement["PROPERTY_VALUES"][$CML_LINK]))
4083 {
4084 $CML_LINK_ELEMENT = $arElement["PROPERTY_VALUES"][$CML_LINK];
4085 }
4086 }
4087 if (is_array($CML_LINK_ELEMENT) && isset($CML_LINK_ELEMENT["n0"]))
4088 {
4089 $CML_LINK_ELEMENT = $CML_LINK_ELEMENT["n0"];
4090 }
4091 if (is_array($CML_LINK_ELEMENT) && isset($CML_LINK_ELEMENT["VALUE"]))
4092 {
4093 $CML_LINK_ELEMENT = $CML_LINK_ELEMENT["VALUE"];
4094 }
4095
4096 if(isset($arElement["BASE_WEIGHT"]))
4097 {
4098 $arProduct["WEIGHT"] = (float)$arElement["BASE_WEIGHT"];
4099 }
4100 elseif ($CML_LINK_ELEMENT > 0)
4101 {
4102 $rsWeight = CIBlockElement::GetProperty($this->arProperties[$CML_LINK]["LINK_IBLOCK_ID"], $CML_LINK_ELEMENT, array(), array("CODE" => "CML2_TRAITS"));
4103 while($arWeight = $rsWeight->Fetch())
4104 {
4105 if($arWeight["DESCRIPTION"] == $this->mess["IBLOCK_XML2_WEIGHT"])
4106 $arProduct["WEIGHT"] = $this->ToFloat($arWeight["VALUE"])*1000;
4107 }
4108 }
4109
4110 if ($CML_LINK_ELEMENT > 0)
4111 {
4112 $rsUnit = CIBlockElement::GetProperty($this->arProperties[$CML_LINK]["LINK_IBLOCK_ID"], $CML_LINK_ELEMENT, array(), array("CODE" => "CML2_BASE_UNIT"));
4113 while($arUnit = $rsUnit->Fetch())
4114 {
4115 if($arUnit["DESCRIPTION"] > 0)
4116 $arProduct["MEASURE"] = $arUnit["DESCRIPTION"];
4117 }
4118 }
4119
4120 if(isset($arElement["PRICES"]))
4121 {
4122 //Here start VAT handling
4123
4124 //Check if all the taxes exists in BSM catalog
4125 $arTaxMap = array();
4126 if ($CML_LINK !== '' && isset($this->arProperties[$CML_LINK]) && $CML_LINK_ELEMENT > 0)
4127 {
4128 $rsTaxProperty = CIBlockElement::GetProperty(
4129 $this->arProperties[$CML_LINK]["LINK_IBLOCK_ID"],
4130 $CML_LINK_ELEMENT,
4131 "sort",
4132 "asc",
4133 [
4134 "CODE" => "CML2_TAXES",
4135 ]
4136 );
4137 while ($arTaxProperty = $rsTaxProperty->Fetch())
4138 {
4139 if (
4140 $arTaxProperty["DESCRIPTION"] <> ''
4141 && !array_key_exists($arTaxProperty["DESCRIPTION"], $arTaxMap)
4142 )
4143 {
4144 if ($arTaxProperty["VALUE"] === '' || !is_numeric($arTaxProperty["VALUE"]))
4145 {
4146 $taxValue = null;
4147 }
4148 else
4149 {
4150 $taxValue = $this->ToFloat($arTaxProperty["VALUE"]);
4151 }
4152 $arTaxMap[$arTaxProperty["DESCRIPTION"]] = [
4153 "RATE" => $this->ToFloat($arTaxProperty["VALUE"]),
4154 "ID" => $this->CheckTax($arTaxProperty["DESCRIPTION"], $taxValue),
4155 ];
4156 }
4157 }
4158 unset($rsTaxProperty);
4159 }
4160
4161 //First find out if all the prices have TAX_IN_SUM true
4162 $TAX_IN_SUM = "Y";
4163
4164 foreach($arElement["PRICES"] as $price)
4165 {
4166 if($price["PRICE"]["TAX_IN_SUM"] !== "true")
4167 {
4168 $TAX_IN_SUM = "N";
4169 break;
4170 }
4171 }
4172 //If there was found not included tax we'll make sure
4173 //that all prices has the same flag
4174 if($TAX_IN_SUM === "N")
4175 {
4176 foreach($arElement["PRICES"] as $price)
4177 {
4178 if($price["PRICE"]["TAX_IN_SUM"] !== "false")
4179 {
4180 $TAX_IN_SUM = "Y";
4181 break;
4182 }
4183 }
4184 //Check if there is a mix of tax in sum
4185 //and correct it by recalculating all the prices
4186 if($TAX_IN_SUM === "Y")
4187 {
4188 foreach($arElement["PRICES"] as $key=>$price)
4189 {
4190 if($price["PRICE"]["TAX_IN_SUM"] !== "true")
4191 {
4192 $TAX_NAME = $price["PRICE"]["TAX_NAME"];
4193 if(array_key_exists($TAX_NAME, $arTaxMap))
4194 {
4195 $PRICE_WO_TAX = $this->ToFloat($price[$this->mess["IBLOCK_XML2_PRICE_FOR_ONE"]]);
4196 $PRICE = $PRICE_WO_TAX + ($PRICE_WO_TAX / 100.0 * $arTaxMap[$TAX_NAME]["RATE"]);
4197 $arElement["PRICES"][$key][$this->mess["IBLOCK_XML2_PRICE_FOR_ONE"]] = $PRICE;
4198 }
4199 }
4200 }
4201 }
4202 }
4203 foreach($arElement["PRICES"] as $price)
4204 {
4205 $TAX_NAME = $price["PRICE"]["TAX_NAME"];
4206 if(array_key_exists($TAX_NAME, $arTaxMap))
4207 {
4208 $arProduct["VAT_ID"] = $arTaxMap[$TAX_NAME]["ID"];
4209 break;
4210 }
4211 }
4212 $arProduct["VAT_INCLUDED"] = $TAX_IN_SUM;
4213 }
4214
4215 $arProduct = array_merge(
4216 $arProduct,
4217 $this->getPreparedProductFieldsFromArray($arElement)
4218 );
4219
4220 $productCache = Catalog\Model\Product::getCacheItem($arProduct['ID'], true);
4221 if (!empty($productCache))
4222 {
4223 $productResult = Catalog\Model\Product::update(
4224 $arProduct['ID'],
4225 array(
4226 'fields' => $arProduct,
4227 'external_fields' => array(
4228 'IBLOCK_ID' => $this->next_step["IBLOCK_ID"]
4229 )
4230 )
4231 );
4232 }
4233 else
4234 {
4235 $productResult = Catalog\Model\Product::add(
4236 array(
4237 'fields' => $arProduct,
4238 'external_fields' => array(
4239 'IBLOCK_ID' => $this->next_step["IBLOCK_ID"]
4240 )
4241 )
4242 );
4243 }
4244 if ($productResult->isSuccess())
4245 {
4246 //TODO: replace this code after upload measure ratio from 1C
4247 $iterator = \Bitrix\Catalog\MeasureRatioTable::getList(array(
4248 'select' => array('ID'),
4249 'filter' => array('=PRODUCT_ID' => $arElement['ID'])
4250 ));
4251 $ratioRow = $iterator->fetch();
4252 if (empty($ratioRow))
4253 {
4254 $ratioResult = \Bitrix\Catalog\MeasureRatioTable::add(array(
4255 'PRODUCT_ID' => $arElement['ID'],
4256 'RATIO' => 1,
4257 'IS_DEFAULT' => 'Y'
4258 ));
4259 unset($ratioResult);
4260 }
4261 unset($ratioRow, $iterator);
4262 }
4263
4264 if(isset($arElement["PRICES"]))
4265 $this->SetProductPrice($arElement["ID"], $arElement["PRICES"], $arElement["DISCOUNTS"]);
4266
4267 if(isset($arElement["STORE_AMOUNT"]))
4268 $this->ImportStoresAmount($arElement["STORE_AMOUNT"], $arElement["ID"], $counter);
4269 }
4270
4271
4272 return $arElement["ID"];
4273 }
4274
4275 protected function getProductFieldsFromXml(array $xmlElement): array
4276 {
4277 $result = [];
4278
4279 if (array_key_exists($this->mess['IBLOCK_XML2_MARKING_CODE_GROUP'], $xmlElement))
4280 {
4281 $result[Product\SystemField\MarkingCodeGroup::FIELD_ID] = $xmlElement[$this->mess['IBLOCK_XML2_MARKING_CODE_GROUP']] ?? '';
4282 }
4283 if (array_key_exists($this->mess['IBLOCK_XML2_PRODUCT_MAPPING'], $xmlElement))
4284 {
4285 $result[Product\SystemField\ProductMapping::FIELD_ID] = [];
4286 if (is_array($xmlElement[$this->mess['IBLOCK_XML2_PRODUCT_MAPPING']]))
4287 {
4288 foreach ($xmlElement[$this->mess['IBLOCK_XML2_PRODUCT_MAPPING']] as $value)
4289 {
4290 $value = (string)$value;
4291 if ($value !== '')
4292 {
4293 $result[Product\SystemField\ProductMapping::FIELD_ID][] = $value;
4294 }
4295 }
4296 }
4297 }
4298 if (isset($xmlElement[$this->mess['IBLOCK_XML2_WIDTH']]))
4299 {
4300 $result['WIDTH'] = $this->ToFloatEmpty($xmlElement[$this->mess['IBLOCK_XML2_WIDTH']]);
4301 }
4302 if (isset($xmlElement[$this->mess['IBLOCK_XML2_LENGTH']]))
4303 {
4304 $result['LENGTH'] = $this->ToFloatEmpty($xmlElement[$this->mess['IBLOCK_XML2_LENGTH']]);
4305 }
4306 if (isset($xmlElement[$this->mess['IBLOCK_XML2_HEIGHT']]))
4307 {
4308 $result['HEIGHT'] = $this->ToFloatEmpty($xmlElement[$this->mess['IBLOCK_XML2_HEIGHT']]);
4309 }
4310
4311 return $result;
4312 }
4313
4314 protected function getPreparedProductFieldsFromArray(array $element): array
4315 {
4316 $result = [];
4317
4318 $productSystemFields = Product\SystemField::getImportSelectFields();
4319 if (!empty($productSystemFields))
4320 {
4321 foreach ($productSystemFields as $index => $value)
4322 {
4323 $fieldName = is_string($index) ? $index : $value;
4324 if (isset($element[$fieldName]))
4325 {
4326 $result[$fieldName] = $element[$fieldName] === '' ? null : $element[$fieldName];
4327 }
4328 }
4329 unset($fieldName, $index, $value);
4330
4331 Product\SystemField::prepareRow($result, Product\SystemField::OPERATION_IMPORT);
4332 }
4333
4334 if (isset($element['MEASURE']))
4335 {
4336 $result['MEASURE'] = ($element['MEASURE'] === '' ? null : (int)$element['MEASURE']);
4337 }
4338
4339 foreach ($this->productSizes as $fieldName)
4340 {
4341 if (isset($element[$fieldName]))
4342 {
4343 $result[$fieldName] = $element[$fieldName] === '' ? null : $element[$fieldName];
4344 }
4345 }
4346 unset($fieldName);
4347
4348 return $result;
4349 }
4350
4351 function ImportElementPrices($arXMLElement, &$counter, $arParent = false)
4352 {
4354 global $APPLICATION;
4355 static $catalogs = array();
4356
4357 $arElement = array(
4358 "ID" => 0,
4359 "XML_ID" => $arXMLElement[$this->mess["IBLOCK_XML2_ID"]],
4360 );
4361
4362 $hashPosition = strrpos($arElement["XML_ID"], "#");
4363 if (
4364 $this->use_offers
4365 && $hashPosition === false && !$this->force_offers
4366 && isset($this->PROPERTY_MAP["CML2_LINK"])
4367 && isset($this->arProperties[$this->PROPERTY_MAP["CML2_LINK"]])
4368 )
4369 {
4370 $IBLOCK_ID = $this->arProperties[$this->PROPERTY_MAP["CML2_LINK"]]["LINK_IBLOCK_ID"];
4371 if (!isset($catalogs[$IBLOCK_ID]))
4372 {
4373 $catalogs[$IBLOCK_ID] = true;
4374
4375 $rs = CCatalog::GetList(array(),array("IBLOCK_ID" => $IBLOCK_ID));
4376 if (!$rs->Fetch())
4377 {
4378 $obCatalog = new CCatalog();
4379 $boolFlag = $obCatalog->Add(array(
4380 "IBLOCK_ID" => $IBLOCK_ID,
4381 "YANDEX_EXPORT" => "N",
4382 "SUBSCRIPTION" => "N",
4383 ));
4384 if (!$boolFlag)
4385 {
4386 if ($ex = $APPLICATION->GetException())
4387 $this->LAST_ERROR = $ex->GetString();
4388 return 0;
4389 }
4390 }
4391 }
4392 }
4393 else
4394 {
4395 $IBLOCK_ID = $this->next_step["IBLOCK_ID"];
4396 }
4397
4398 $obElement = new CIBlockElement;
4399 $rsElement = $obElement->GetList(
4400 Array("ID"=>"asc"),
4401 Array("=XML_ID" => $arElement["XML_ID"], "IBLOCK_ID" => $IBLOCK_ID),
4402 false, false,
4403 Array("ID", "TMP_ID", "ACTIVE")
4404 );
4405 $arDBElement = $rsElement->Fetch();
4406 if($arDBElement)
4407 $arElement["ID"] = $arDBElement["ID"];
4408
4409 if(isset($arXMLElement[$this->mess["IBLOCK_XML2_STORE_AMOUNT_LIST"]]))
4410 {
4411 $arElement["STORE_AMOUNT"] = array();
4412 foreach($arXMLElement[$this->mess["IBLOCK_XML2_STORE_AMOUNT_LIST"]] as $storeAmount)
4413 {
4414 if(isset($storeAmount[$this->mess["IBLOCK_XML2_STORE_ID"]]))
4415 {
4416 $storeXMLID = $storeAmount[$this->mess["IBLOCK_XML2_STORE_ID"]];
4417 $amount = $this->ToFloat($storeAmount[$this->mess["IBLOCK_XML2_AMOUNT"]]);
4418 $arElement["STORE_AMOUNT"][$storeXMLID] = $amount;
4419 }
4420 }
4421 }
4422 elseif(isset($arXMLElement[$this->mess["IBLOCK_XML2_RESTS"]]))
4423 {
4424 $arElement["STORE_AMOUNT"] = array();
4425 foreach($arXMLElement[$this->mess["IBLOCK_XML2_RESTS"]] as $xmlRest)
4426 {
4427 foreach($xmlRest as $storeAmount)
4428 {
4429 if(is_array($storeAmount))
4430 {
4431 if (isset($storeAmount[$this->mess["IBLOCK_XML2_ID"]]))
4432 {
4433 $storeXMLID = $storeAmount[$this->mess["IBLOCK_XML2_ID"]];
4434 $amount = $this->ToFloat($storeAmount[$this->mess["IBLOCK_XML2_AMOUNT"]]);
4435 $arElement["STORE_AMOUNT"][$storeXMLID] = $amount;
4436 }
4437 }
4438 else
4439 {
4440 if ($storeAmount <> '')
4441 {
4442 $amount = $this->ToFloat($storeAmount);
4443 $arElement["QUANTITY"] = $amount;
4444 }
4445 }
4446 }
4447 }
4448 }
4449 elseif(
4450 $arParent
4451 && (
4452 array_key_exists($this->mess["IBLOCK_XML2_STORES"], $arXMLElement)
4453 || array_key_exists($this->mess["IBLOCK_XML2_STORE"], $arXMLElement)
4454 )
4455 )
4456 {
4457 $arElement["STORE_AMOUNT"] = array();
4458 $rsStores = $this->_xml_file->GetList(
4459 array("ID" => "asc"),
4460 array(
4461 "><LEFT_MARGIN" => array($arParent["LEFT_MARGIN"], $arParent["RIGHT_MARGIN"]),
4462 "NAME" => $this->mess["IBLOCK_XML2_STORE"],
4463 ),
4464 array("ID", "ATTRIBUTES")
4465 );
4466 while ($arStore = $rsStores->Fetch())
4467 {
4468 if($arStore["ATTRIBUTES"] <> '')
4469 {
4470 $info = unserialize($arStore["ATTRIBUTES"], ['allowed_classes' => false]);
4471 if(
4472 is_array($info)
4473 && array_key_exists($this->mess["IBLOCK_XML2_STORE_ID"], $info)
4474 && array_key_exists($this->mess["IBLOCK_XML2_STORE_AMOUNT"], $info)
4475 )
4476 {
4477 $arElement["STORE_AMOUNT"][$info[$this->mess["IBLOCK_XML2_STORE_ID"]]] = $this->ToFloat($info[$this->mess["IBLOCK_XML2_STORE_AMOUNT"]]);
4478 }
4479 }
4480 }
4481 }
4482
4483 if(isset($arElement["STORE_AMOUNT"]))
4484 $this->ImportStoresAmount($arElement["STORE_AMOUNT"], $arElement["ID"], $counter);
4485
4486 if($arDBElement)
4487 {
4488 $arProduct = array(
4489 "ID" => $arElement["ID"],
4490 );
4491
4492 if(isset($arXMLElement[$this->mess["IBLOCK_XML2_PRICES"]]))
4493 {
4494 $arElement["PRICES"] = array();
4495 foreach($arXMLElement[$this->mess["IBLOCK_XML2_PRICES"]] as $price)
4496 {
4497 if(
4498 isset($price[$this->mess["IBLOCK_XML2_PRICE_TYPE_ID"]])
4499 && array_key_exists($price[$this->mess["IBLOCK_XML2_PRICE_TYPE_ID"]], $this->PRICES_MAP)
4500 )
4501 {
4502 $price["PRICE"] = $this->PRICES_MAP[$price[$this->mess["IBLOCK_XML2_PRICE_TYPE_ID"]]];
4503 $arElement["PRICES"][] = $price;
4504
4505 if(
4506 array_key_exists($this->mess["IBLOCK_XML2_MEASURE"], $price)
4507 && !isset($arProduct["MEASURE"])
4508 )
4509 {
4510 $tmp = $this->convertBaseUnitFromXmlToPropertyValue($price[$this->mess["IBLOCK_XML2_MEASURE"]]);
4511 if ($tmp["DESCRIPTION"] > 0)
4512 $arProduct["MEASURE"] = $tmp["DESCRIPTION"];
4513 }
4514 }
4515 }
4516
4517 $arElement["DISCOUNTS"] = array();
4518 if(isset($arXMLElement[$this->mess["IBLOCK_XML2_DISCOUNTS"]]))
4519 {
4520 foreach($arXMLElement[$this->mess["IBLOCK_XML2_DISCOUNTS"]] as $discount)
4521 {
4522 if(
4523 isset($discount[$this->mess["IBLOCK_XML2_DISCOUNT_CONDITION"]])
4524 && $discount[$this->mess["IBLOCK_XML2_DISCOUNT_CONDITION"]] === $this->mess["IBLOCK_XML2_DISCOUNT_COND_VOLUME"]
4525 )
4526 {
4527 $discount_value = $this->ToInt($discount[$this->mess["IBLOCK_XML2_DISCOUNT_COND_VALUE"]]);
4528 $discount_percent = $this->ToFloat($discount[$this->mess["IBLOCK_XML2_DISCOUNT_COND_PERCENT"]]);
4529 if($discount_value > 0 && $discount_percent > 0)
4530 $arElement["DISCOUNTS"][$discount_value] = $discount_percent;
4531 }
4532 }
4533 }
4534 }
4535
4536 if($this->bCatalog && array_key_exists($this->mess["IBLOCK_XML2_AMOUNT"], $arXMLElement))
4537 {
4538 $arElement["QUANTITY_RESERVED"] = 0;
4539 if($arElement["ID"])
4540 {
4542 'select' => ['ID', 'QUANTITY_RESERVED'],
4543 'filter' => ['=ID' => $arDBElement['ID']]
4544 ]);
4545 $arElementTmp = $iterator->fetch();
4546 if (!empty($arElementTmp) && is_array($arElementTmp) && isset($arElementTmp["QUANTITY_RESERVED"]))
4547 $arElement["QUANTITY_RESERVED"] = (float)$arElementTmp["QUANTITY_RESERVED"];
4548 unset($arElementTmp);
4549 unset($iterator);
4550 }
4551 $arElement["QUANTITY"] = $this->ToFloat($arXMLElement[$this->mess["IBLOCK_XML2_AMOUNT"]]) - $arElement["QUANTITY_RESERVED"];
4552 }
4553
4554 if(isset($arElement["PRICES"]) && $this->bCatalog)
4555 {
4556 if(isset($arElement["QUANTITY"]))
4557 $arProduct["QUANTITY"] = (float)$arElement["QUANTITY"];
4558 elseif(isset($arElement["STORE_AMOUNT"]) && !empty($arElement["STORE_AMOUNT"]))
4559 $arProduct["QUANTITY"] = $this->countTotalQuantity($arElement["STORE_AMOUNT"]);
4560
4561 $rsWeight = CIBlockElement::GetProperty($IBLOCK_ID, $arElement["ID"], array(), array("CODE" => "CML2_TRAITS"));
4562 while($arWeight = $rsWeight->Fetch())
4563 {
4564 if($arWeight["DESCRIPTION"] == $this->mess["IBLOCK_XML2_WEIGHT"])
4565 $arProduct["WEIGHT"] = $this->ToFloat($arWeight["VALUE"])*1000;
4566 }
4567
4568 $rsUnit = CIBlockElement::GetProperty($IBLOCK_ID, $arElement["ID"], array(), array("CODE" => "CML2_BASE_UNIT"));
4569 while($arUnit = $rsUnit->Fetch())
4570 {
4571 if($arUnit["DESCRIPTION"] > 0)
4572 $arProduct["MEASURE"] = $arUnit["DESCRIPTION"];
4573 }
4574
4575 //Here start VAT handling
4576
4577 //Check if all the taxes exists in BSM catalog
4578 $arTaxMap = array();
4579 $rsTaxProperty = CIBlockElement::GetProperty($IBLOCK_ID, $arElement["ID"], array("sort" => "asc"), array("CODE" => "CML2_TAXES"));
4580 while($arTaxProperty = $rsTaxProperty->Fetch())
4581 {
4582 if(
4583 $arTaxProperty["DESCRIPTION"] <> ''
4584 && !array_key_exists($arTaxProperty["DESCRIPTION"], $arTaxMap)
4585 )
4586 {
4587 if ($arTaxProperty["VALUE"] === '' || !is_numeric($arTaxProperty["VALUE"]))
4588 {
4589 $taxValue = null;
4590 }
4591 else
4592 {
4593 $taxValue = $this->ToFloat($arTaxProperty["VALUE"]);
4594 }
4595 $arTaxMap[$arTaxProperty["DESCRIPTION"]] = array(
4596 "RATE" => $this->ToFloat($arTaxProperty["VALUE"]),
4597 "ID" => $this->CheckTax($arTaxProperty["DESCRIPTION"], $taxValue),
4598 );
4599 }
4600 }
4601
4602 //Try to search in main element
4603 if (
4604 !$arTaxMap
4605 && $this->use_offers
4606 && $hashPosition !== false
4607 && isset($this->PROPERTY_MAP["CML2_LINK"])
4608 && $this->arProperties[$this->PROPERTY_MAP["CML2_LINK"]]["LINK_IBLOCK_ID"] > 0
4609 )
4610 {
4611 $rsLinkProperty = CIBlockElement::GetProperty($IBLOCK_ID, $arElement["ID"], array("sort" => "asc"), array("CODE" => "CML2_LINK"));
4612 if( ($arLinkProperty = $rsLinkProperty->Fetch()) && ($arLinkProperty["VALUE"] > 0))
4613 {
4614 $rsTaxProperty = CIBlockElement::GetProperty($this->arProperties[$this->PROPERTY_MAP["CML2_LINK"]]["LINK_IBLOCK_ID"], $arLinkProperty["VALUE"], array("sort" => "asc"), array("CODE" => "CML2_TAXES"));
4615 while($arTaxProperty = $rsTaxProperty->Fetch())
4616 {
4617 if(
4618 $arTaxProperty["DESCRIPTION"] <> ''
4619 && !array_key_exists($arTaxProperty["DESCRIPTION"], $arTaxMap)
4620 )
4621 {
4622 if ($arTaxProperty["VALUE"] === '' || !is_numeric($arTaxProperty["VALUE"]))
4623 {
4624 $taxValue = null;
4625 }
4626 else
4627 {
4628 $taxValue = $this->ToFloat($arTaxProperty["VALUE"]);
4629 }
4630 $arTaxMap[$arTaxProperty["DESCRIPTION"]] = array(
4631 "RATE" => $this->ToFloat($arTaxProperty["VALUE"]),
4632 "ID" => $this->CheckTax($arTaxProperty["DESCRIPTION"], $taxValue),
4633 );
4634 }
4635 }
4636 }
4637 }
4638
4639 //First find out if all the prices have TAX_IN_SUM true
4640 $TAX_IN_SUM = "Y";
4641 foreach($arElement["PRICES"] as $price)
4642 {
4643 if($price["PRICE"]["TAX_IN_SUM"] !== "true")
4644 {
4645 $TAX_IN_SUM = "N";
4646 break;
4647 }
4648 }
4649 //If there was found not included tax we'll make sure
4650 //that all prices has the same flag
4651 if($TAX_IN_SUM === "N")
4652 {
4653 foreach($arElement["PRICES"] as $price)
4654 {
4655 if($price["PRICE"]["TAX_IN_SUM"] !== "false")
4656 {
4657 $TAX_IN_SUM = "Y";
4658 break;
4659 }
4660 }
4661 //Check if there is a mix of tax in sum
4662 //and correct it by recalculating all the prices
4663 if($TAX_IN_SUM === "Y")
4664 {
4665 foreach($arElement["PRICES"] as $key=>$price)
4666 {
4667 if($price["PRICE"]["TAX_IN_SUM"] !== "true")
4668 {
4669 $TAX_NAME = $price["PRICE"]["TAX_NAME"];
4670 if(array_key_exists($TAX_NAME, $arTaxMap))
4671 {
4672 $PRICE_WO_TAX = $this->ToFloat($price[$this->mess["IBLOCK_XML2_PRICE_FOR_ONE"]]);
4673 $PRICE = $PRICE_WO_TAX + ($PRICE_WO_TAX / 100.0 * $arTaxMap[$TAX_NAME]["RATE"]);
4674 $arElement["PRICES"][$key][$this->mess["IBLOCK_XML2_PRICE_FOR_ONE"]] = $PRICE;
4675 }
4676 }
4677 }
4678 }
4679 }
4680
4681 if ($TAX_IN_SUM == "Y" && $arTaxMap)
4682 {
4683 $vat = current($arTaxMap);
4684 $arProduct["VAT_ID"] = $vat["ID"];
4685 }
4686 else
4687 {
4688 foreach($arElement["PRICES"] as $price)
4689 {
4690 $TAX_NAME = $price["PRICE"]["TAX_NAME"];
4691 if(array_key_exists($TAX_NAME, $arTaxMap))
4692 {
4693 $arProduct["VAT_ID"] = $arTaxMap[$TAX_NAME]["ID"];
4694 break;
4695 }
4696 }
4697 }
4698
4699 $arProduct["VAT_INCLUDED"] = $TAX_IN_SUM;
4700
4701 $productCache = Catalog\Model\Product::getCacheItem($arProduct['ID'], true);
4702 if (!empty($productCache))
4703 {
4704 $productResult = Catalog\Model\Product::update(
4705 $arProduct['ID'],
4706 array(
4707 'fields' => $arProduct,
4708 'external_fields' => array(
4709 'IBLOCK_ID' => $IBLOCK_ID
4710 )
4711 )
4712 );
4713 }
4714 else
4715 {
4716 $productResult = Catalog\Model\Product::add(
4717 array(
4718 'fields' => $arProduct,
4719 'external_fields' => array(
4720 'IBLOCK_ID' => $IBLOCK_ID
4721 )
4722 )
4723 );
4724 }
4725 if ($productResult->isSuccess())
4726 {
4727 //TODO: replace this code after upload measure ratio from 1C
4728 $iterator = \Bitrix\Catalog\MeasureRatioTable::getList(array(
4729 'select' => array('ID'),
4730 'filter' => array('=PRODUCT_ID' => $arElement['ID'])
4731 ));
4732 $ratioRow = $iterator->fetch();
4733 if (empty($ratioRow))
4734 {
4735 $ratioResult = \Bitrix\Catalog\MeasureRatioTable::add(array(
4736 'PRODUCT_ID' => $arElement['ID'],
4737 'RATIO' => 1,
4738 'IS_DEFAULT' => 'Y'
4739 ));
4740 unset($ratioResult);
4741 }
4742 unset($ratioRow, $iterator);
4743 }
4744
4745 $this->SetProductPrice($arElement["ID"], $arElement["PRICES"], $arElement["DISCOUNTS"]);
4747 }
4748 elseif(
4749 $this->bCatalog
4750 && (
4751 (isset($arElement["STORE_AMOUNT"]) && !empty($arElement["STORE_AMOUNT"]))
4752 || isset($arElement["QUANTITY"])
4753 )
4754 )
4755 {
4757 'select' => ['ID', 'QUANTITY_RESERVED'],
4758 'filter' => ['=ID' => $arElement['ID']]
4759 ]);
4760 $arElementTmp = $iterator->fetch();
4761 if (!empty($arElementTmp) && is_array($arElementTmp))
4762 {
4763 $quantityReserved = 0;
4764 if (isset($arElementTmp["QUANTITY_RESERVED"]))
4765 $quantityReserved = (float)$arElementTmp["QUANTITY_RESERVED"];
4766 $internalFields = [];
4767 if (isset($arElement["STORE_AMOUNT"]) && !empty($arElement["STORE_AMOUNT"]))
4768 {
4769 $internalFields['QUANTITY'] = $this->countTotalQuantity($arElement["STORE_AMOUNT"]);
4770 }
4771 elseif (isset($arElement["QUANTITY"]))
4772 {
4773 $internalFields['QUANTITY'] = $arElement["QUANTITY"];
4774 }
4775 if (!empty($internalFields))
4776 {
4777 $internalFields['QUANTITY'] -= $quantityReserved;
4778 $internalResult = Catalog\Model\Product::update(
4779 $arElement['ID'],
4780 array(
4781 'fields' => $internalFields,
4782 'external_fields' => array(
4783 'IBLOCK_ID' => $IBLOCK_ID
4784 )
4785 )
4786 );
4787 if (!$internalResult->isSuccess())
4788 {
4789
4790 }
4791 unset($internalResult);
4792 }
4793 unset($internalFields);
4794 unset($quantityReserved);
4795 }
4796 unset($arElementTmp);
4797 unset($iterator);
4798 }
4799 }
4800
4801 $counter["UPD"]++;
4802 return $arElement["ID"];
4803 }
4804
4805 function fillDefaultPropertyValues(&$arElement, $iblockProperties)
4806 {
4807 if (isset($arElement["PROPERTY_VALUES"]))
4808 {
4809 $elementProperties = &$arElement["PROPERTY_VALUES"];
4810 foreach ($iblockProperties as $PID => $property)
4811 {
4812 if (!array_key_exists($PID, $elementProperties))
4813 {
4814 if ($property["PROPERTY_TYPE"] == "L")
4815 {
4816 $enumDefaults = CIBlockPropertyEnum::GetList(array(), array(
4817 "PROPERTY_ID" => $PID,
4818 "DEF" => "Y",
4819 ));
4820 $i = 0;
4821 while($enum = $enumDefaults->Fetch())
4822 {
4823 $elementProperties[$PID]["n".$i] = $enum["ID"];
4824 $i++;
4825 }
4826 }
4827 elseif (is_array($property["DEFAULT_VALUE"]) || $property["DEFAULT_VALUE"] <> '')
4828 {
4829 $elementProperties[$PID]["n0"] = array(
4830 "VALUE" => $property["DEFAULT_VALUE"],
4831 "DESCRIPTION" => "",
4832 );
4833 }
4834 }
4835 }
4836 }
4837 }
4838
4839 function ConvertDiscounts($arDiscounts)
4840 {
4841 if (is_array($arDiscounts) && count($arDiscounts) > 0)
4842 {
4843 if (!array_key_exists(0, $arDiscounts))
4844 $arDiscounts[0] = 0;
4845
4846 ksort($arDiscounts);
4847 $keys = array_keys($arDiscounts);
4848 $cnt = count($keys);
4849 for ($i = 0; $i < $cnt; $i++)
4850 {
4851 $arDiscounts[$keys[$i]] = array(
4852 "QUANTITY_FROM" => $keys[$i] + 1,
4853 "QUANTITY_TO" => $i < $cnt ? $keys[$i + 1] : "",
4854 "PERCENT" => $arDiscounts[$keys[$i]],
4855 );
4856 }
4857 }
4858 else
4859 {
4860 $arDiscounts = array(
4861 array(
4862 "QUANTITY_FROM" => "",
4863 "QUANTITY_TO" => "",
4864 "PERCENT" => 0,
4865 ),
4866 );
4867 }
4868 return $arDiscounts;
4869 }
4870
4876 function SetProductPrice($PRODUCT_ID, $arPrices, $arDiscounts = false)
4877 {
4878 $arDBPrices = array();
4880 'select' => array(
4881 'ID', 'PRODUCT_ID', 'CATALOG_GROUP_ID',
4882 'QUANTITY_FROM', 'QUANTITY_TO'
4883 ),
4884 'filter' => array('=PRODUCT_ID' => $PRODUCT_ID)
4885 ));
4886 while ($row = $iterator->fetch())
4887 {
4888 $arDBPrices[$row["CATALOG_GROUP_ID"].":".$row["QUANTITY_FROM"].":".$row["QUANTITY_TO"]] = $row["ID"];
4889 }
4890
4891 $arToDelete = $arDBPrices;
4892
4893 if(!is_array($arPrices))
4894 $arPrices = array();
4895
4896 foreach($arPrices as $price)
4897 {
4898
4899 if(!isset($price[$this->mess["IBLOCK_XML2_CURRENCY"]]))
4900 $price[$this->mess["IBLOCK_XML2_CURRENCY"]] = $price["PRICE"]["CURRENCY"];
4901
4902 $arPrice = Array(
4903 "PRODUCT_ID" => $PRODUCT_ID,
4904 "CATALOG_GROUP_ID" => $price["PRICE"]["ID"],
4905 "^PRICE" => $this->ToFloat($price[$this->mess["IBLOCK_XML2_PRICE_FOR_ONE"]]),
4906 "CURRENCY" => $this->CheckCurrency($price[$this->mess["IBLOCK_XML2_CURRENCY"]]),
4907 );
4908
4909 if (
4910 (isset($price[$this->mess["IBLOCK_XML2_QUANTITY_FROM"]]) && (string)$price[$this->mess["IBLOCK_XML2_QUANTITY_FROM"]] != '')
4911 || (isset($price[$this->mess["IBLOCK_XML2_QUANTITY_TO"]]) && (string)$price[$this->mess["IBLOCK_XML2_QUANTITY_TO"]] != '')
4912 )
4913 {
4914 $arPrice["QUANTITY_FROM"] = $price[$this->mess["IBLOCK_XML2_QUANTITY_FROM"]];
4915 $arPrice["QUANTITY_TO"] = $price[$this->mess["IBLOCK_XML2_QUANTITY_TO"]];
4916 $arPrice["PRICE"] = $arPrice["^PRICE"];
4917 unset($arPrice["^PRICE"]);
4918 if ($arPrice["QUANTITY_FROM"] === ''
4919 || $arPrice["QUANTITY_FROM"] === false
4920 || $arPrice["QUANTITY_FROM"] === '0'
4921 || $arPrice["QUANTITY_FROM"] === 0
4922 )
4923 $arPrice["QUANTITY_FROM"] = null;
4924 if ($arPrice["QUANTITY_TO"] === ''
4925 || $arPrice["QUANTITY_TO"] === false
4926 || $arPrice["QUANTITY_TO"] === '0'
4927 || $arPrice["QUANTITY_TO"] === 0
4928 )
4929 $arPrice["QUANTITY_TO"] = null;
4930
4931 $id = $arPrice["CATALOG_GROUP_ID"].":".$arPrice["QUANTITY_FROM"].":".$arPrice["QUANTITY_TO"];
4932 if(isset($arDBPrices[$id]))
4933 {
4934 $priceResult = Catalog\Model\Price::update($arDBPrices[$id], $arPrice);
4935 unset($arToDelete[$id]);
4936 }
4937 else
4938 {
4939 $priceResult = Catalog\Model\Price::add($arPrice);
4940 }
4941 }
4942 else
4943 {
4944 foreach($this->ConvertDiscounts($arDiscounts) as $arDiscount)
4945 {
4946 $arPrice["QUANTITY_FROM"] = $arDiscount["QUANTITY_FROM"];
4947 $arPrice["QUANTITY_TO"] = $arDiscount["QUANTITY_TO"];
4948 if($arDiscount["PERCENT"] > 0)
4949 $arPrice["PRICE"] = $arPrice["^PRICE"] - $arPrice["^PRICE"]/100*$arDiscount["PERCENT"];
4950 else
4951 $arPrice["PRICE"] = $arPrice["^PRICE"];
4952 unset($arPrice["^PRICE"]);
4953 if ($arPrice["QUANTITY_FROM"] === ''
4954 || $arPrice["QUANTITY_FROM"] === false
4955 || $arPrice["QUANTITY_FROM"] === '0'
4956 || $arPrice["QUANTITY_FROM"] === 0
4957 )
4958 $arPrice["QUANTITY_FROM"] = null;
4959 if ($arPrice["QUANTITY_TO"] === ''
4960 || $arPrice["QUANTITY_TO"] === false
4961 || $arPrice["QUANTITY_TO"] === '0'
4962 || $arPrice["QUANTITY_TO"] === 0
4963 )
4964 $arPrice["QUANTITY_TO"] = null;
4965
4966 $id = $arPrice["CATALOG_GROUP_ID"].":".$arPrice["QUANTITY_FROM"].":".$arPrice["QUANTITY_TO"];
4967 if(isset($arDBPrices[$id]))
4968 {
4969 $priceResult = Catalog\Model\Price::update($arDBPrices[$id], $arPrice);
4970 unset($arToDelete[$id]);
4971 }
4972 else
4973 {
4974 $priceResult = Catalog\Model\Price::add($arPrice);
4975 }
4976 }
4977 }
4978 }
4979
4980 foreach($arToDelete as $id)
4981 {
4982 $priceResult = Catalog\Model\Price::delete($id);
4983 }
4984 }
4985
4986 function ImportSection($xml_tree_id, $IBLOCK_ID, $parent_section_id)
4987 {
4989 global $USER_FIELD_MANAGER;
4991 global $DB;
4992
4993 static $arUserFields;
4994 if($parent_section_id === false)
4995 {
4996 $arUserFields = array();
4997 foreach($USER_FIELD_MANAGER->GetUserFields("IBLOCK_".$IBLOCK_ID."_SECTION") as $FIELD_ID => $arField)
4998 {
4999 if($arField["XML_ID"] == '')
5000 $arUserFields[$FIELD_ID] = $arField;
5001 else
5002 $arUserFields[$arField["XML_ID"]] = $arField;
5003 }
5004 }
5005
5006 $this->next_step["section_sort"] += 10;
5007 $arSection = array(
5008 "IBLOCK_SECTION_ID" => $parent_section_id,
5009 "ACTIVE" => "Y",
5010 );
5011 $rsS = $this->_xml_file->GetList(
5012 array("ID" => "asc"),
5013 array("PARENT_ID" => $xml_tree_id)
5014 );
5015 $XML_SECTIONS_PARENT = false;
5016 $XML_PROPERTIES_PARENT = false;
5017 $XML_SECTION_PROPERTIES = false;
5018 $deletedStatus = false;
5019 while($arS = $rsS->Fetch())
5020 {
5021 if(isset($arS["VALUE_CLOB"]))
5022 $arS["VALUE"] = $arS["VALUE_CLOB"];
5023
5024 if($arS["NAME"]==$this->mess["IBLOCK_XML2_ID"])
5025 $arSection["XML_ID"] = $arS["VALUE"];
5026 elseif($arS["NAME"]==$this->mess["IBLOCK_XML2_NAME"])
5027 $arSection["NAME"] = $arS["VALUE"];
5028 elseif($arS["NAME"]==$this->mess["IBLOCK_XML2_DESCRIPTION"])
5029 {
5030 $arSection["DESCRIPTION"] = $arS["VALUE"];
5031 $arSection["DESCRIPTION_TYPE"] = "html";
5032 }
5033 elseif($arS["NAME"]==$this->mess["IBLOCK_XML2_GROUPS"])
5034 $XML_SECTIONS_PARENT = $arS["ID"];
5035 elseif($arS["NAME"]==$this->mess["IBLOCK_XML2_PROPERTIES_VALUES"])
5036 $XML_PROPERTIES_PARENT = $arS["ID"];
5037 elseif($arS["NAME"]==$this->mess["IBLOCK_XML2_BX_SORT"])
5038 $arSection["SORT"] = intval($arS["VALUE"]);
5039 elseif($arS["NAME"]==$this->mess["IBLOCK_XML2_BX_CODE"])
5040 $arSection["CODE"] = $arS["VALUE"];
5041 elseif($arS["NAME"] == $this->mess["IBLOCK_XML2_BX_PICTURE"])
5042 {
5043 if($arS["VALUE"] <> '')
5044 $arSection["PICTURE"] = $this->MakeFileArray($arS["VALUE"]);
5045 else
5046 $arSection["PICTURE"] = $this->MakeFileArray($this->_xml_file->GetAllChildrenArray($arS["ID"]));
5047 }
5048 elseif($arS["NAME"] == $this->mess["IBLOCK_XML2_BX_DETAIL_PICTURE"])
5049 {
5050 if($arS["VALUE"] <> '')
5051 $arSection["DETAIL_PICTURE"] = $this->MakeFileArray($arS["VALUE"]);
5052 else
5053 $arSection["DETAIL_PICTURE"] = $this->MakeFileArray($this->_xml_file->GetAllChildrenArray($arS["ID"]));
5054 }
5055 elseif($arS["NAME"] == $this->mess["IBLOCK_XML2_BX_ACTIVE"])
5056 $arSection["ACTIVE"] = ($arS["VALUE"]=="true") || intval($arS["VALUE"])? "Y": "N";
5057 elseif($arS["NAME"] == $this->mess["IBLOCK_XML2_SECTION_PROPERTIES"])
5058 $XML_SECTION_PROPERTIES = $arS["ID"];
5059 elseif($arS["NAME"] == $this->mess["IBLOCK_XML2_STATUS"])
5060 $deletedStatus = $arS["VALUE"] === $this->mess["IBLOCK_XML2_DELETED"];
5061 elseif($arS["NAME"] == $this->mess["IBLOCK_XML2_INHERITED_TEMPLATES"])
5062 {
5063 $arSection["IPROPERTY_TEMPLATES"] = array();
5064 $arTemplates = $this->_xml_file->GetAllChildrenArray($arS["ID"]);
5065 foreach($arTemplates as $TEMPLATE)
5066 {
5067 $id = $TEMPLATE[$this->mess["IBLOCK_XML2_ID"]];
5068 $template = $TEMPLATE[$this->mess["IBLOCK_XML2_VALUE"]];
5069 if($id <> '' && $template <> '')
5070 $arSection["IPROPERTY_TEMPLATES"][$id] = $template;
5071 }
5072 }
5073 elseif($arS["NAME"] == $this->mess["IBLOCK_XML2_DELETE_MARK"])
5074 {
5075 $arSection["ACTIVE"] = ($arS["VALUE"]=="true") || intval($arS["VALUE"])? "N": "Y";
5076 }
5077 }
5078
5079 if ($deletedStatus)
5080 {
5081 $obSection = new CIBlockSection;
5082 $rsSection = $obSection->GetList(array(), array(
5083 "IBLOCK_ID" => $IBLOCK_ID,
5084 "XML_ID" => $arSection["XML_ID"],
5085 ), false, array("ID"));
5086 if($arDBSection = $rsSection->Fetch())
5087 {
5088 $obSection->Update($arDBSection["ID"], array(
5089 "ACTIVE" => "N",
5090 ));
5091 $this->_xml_file->Add(array("PARENT_ID" => 0, "LEFT_MARGIN" => $arDBSection["ID"]));
5092 }
5093 return true;
5094 }
5095
5096 if($XML_PROPERTIES_PARENT)
5097 {
5098 $rs = $this->_xml_file->GetList(
5099 array("ID" => "asc"),
5100 array("PARENT_ID" => $XML_PROPERTIES_PARENT),
5101 array("ID")
5102 );
5103 while($ar = $rs->Fetch())
5104 {
5105 $arXMLProp = $this->_xml_file->GetAllChildrenArray($ar["ID"]);
5106 if(
5107 array_key_exists($this->mess["IBLOCK_XML2_ID"], $arXMLProp)
5108 && array_key_exists($arXMLProp[$this->mess["IBLOCK_XML2_ID"]], $arUserFields)
5109 )
5110 {
5111 $arUserField = $arUserFields[$arXMLProp[$this->mess["IBLOCK_XML2_ID"]]];
5112 unset($arXMLProp[$this->mess["IBLOCK_XML2_ID"]]);
5113
5114 $arProp = array();
5115 $i = 0;
5116 foreach($arXMLProp as $value)
5117 {
5118 if($arUserField["USER_TYPE"]["BASE_TYPE"] === "file")
5119 $arProp["n".($i++)] = $this->MakeFileArray($value);
5120 elseif($arUserField["USER_TYPE"]["BASE_TYPE"] === "enum")
5121 $arProp["n".($i++)] = $this->GetSectionEnumByXML_ID($arUserField["ID"], $value);
5122 else
5123 $arProp["n".($i++)] = $value;
5124 }
5125
5126 if($arUserField["MULTIPLE"] == "N")
5127 $arSection[$arUserField["FIELD_NAME"]] = array_pop($arProp);
5128 else
5129 $arSection[$arUserField["FIELD_NAME"]] = $arProp;
5130 }
5131 }
5132 }
5133
5134 $obSection = new CIBlockSection;
5135 $rsSection = $obSection->GetList(array(), array("IBLOCK_ID"=>$IBLOCK_ID, "XML_ID"=>$arSection["XML_ID"]), false);
5136 if($arDBSection = $rsSection->Fetch())
5137 {
5138 if(
5139 !array_key_exists("CODE", $arSection)
5140 && is_array($this->translit_on_update)
5141 )
5142 {
5143 $CODE = CUtil::translit($arSection["NAME"], LANGUAGE_ID, $this->translit_on_update);
5144 $CODE = $this->CheckSectionCode($IBLOCK_ID, $arDBSection["ID"], $CODE);
5145 if ($CODE !== false)
5146 $arSection["CODE"] = $CODE;
5147 }
5148
5149 $bChanged = false;
5150 foreach($arSection as $key=>$value)
5151 {
5152 if(is_array($arDBSection[$key]) || ($arDBSection[$key] != $value))
5153 {
5154 $bChanged = true;
5155 break;
5156 }
5157 }
5158
5159 if($bChanged)
5160 {
5161 foreach($arUserFields as $arField1)
5162 {
5163 if($arField1["USER_TYPE"]["BASE_TYPE"] == "file")
5164 {
5165 $sectionUF = $USER_FIELD_MANAGER->GetUserFields("IBLOCK_".$IBLOCK_ID."_SECTION", $arDBSection["ID"]);
5166 foreach($sectionUF as $arField2)
5167 {
5168 if(
5169 $arField2["USER_TYPE"]["BASE_TYPE"] == "file"
5170 && isset($arSection[$arField2["FIELD_NAME"]])
5171 )
5172 {
5173 if($arField2["MULTIPLE"] == "Y" && is_array($arField2["VALUE"]))
5174 {
5175 foreach($arField2["VALUE"] as $old_file_id)
5176 $arSection[$arField2["FIELD_NAME"]][] = array("del"=>true,"old_id"=>$old_file_id);
5177 }
5178 elseif($arField2["MULTIPLE"] == "N" && $arField2["VALUE"] > 0)
5179 {
5180 $arSection[$arField2["FIELD_NAME"]]["old_id"] = $arField2["VALUE"];
5181 }
5182 }
5183 }
5184 break;
5185 }
5186 }
5187
5188 if (!isset($arSection['MODIFIED_BY']) || (int)$arSection['MODIFIED_BY'] <= 0)
5189 {
5190 if ($this->currentUserId > 0)
5191 {
5192 $arSection['MODIFIED_BY'] = $this->currentUserId;
5193 }
5194 }
5195
5196 $res = $obSection->Update($arDBSection["ID"], $arSection);
5197 if(!$res)
5198 {
5199 $this->LAST_ERROR = $obSection->LAST_ERROR;
5200 return $this->LAST_ERROR;
5201 }
5202 }
5203 else
5204 {
5205 $strUpdate = "TIMESTAMP_X = ".$DB->CurrentTimeFunction();
5206 if ($this->currentUserId > 0)
5207 $strUpdate .= ", MODIFIED_BY=".$this->currentUserId;
5208 $DB->Query("UPDATE b_iblock_section SET ".$strUpdate." WHERE ID=".$arDBSection["ID"]);
5209 unset($strUpdate);
5210 }
5211
5212 $arSection["ID"] = $arDBSection["ID"];
5213 }
5214 else
5215 {
5216 if(!array_key_exists("CODE", $arSection) && is_array($this->translit_on_add))
5217 {
5218 $CODE = CUtil::translit($arSection["NAME"], LANGUAGE_ID, $this->translit_on_add);
5219 $CODE = $this->CheckSectionCode($IBLOCK_ID, 0, $CODE);
5220 if ($CODE !== false)
5221 $arSection["CODE"] = $CODE;
5222 }
5223
5224 $arSection["IBLOCK_ID"] = $IBLOCK_ID;
5225 if(!isset($arSection["SORT"]))
5226 $arSection["SORT"] = $this->next_step["section_sort"];
5227
5228 $arSection["ID"] = $obSection->Add($arSection);
5229 if(!$arSection["ID"])
5230 {
5231 $this->LAST_ERROR = $obSection->LAST_ERROR;
5232 return $this->LAST_ERROR;
5233 }
5234 }
5235
5236 if($XML_SECTION_PROPERTIES)
5237 {
5238 $this->ImportSectionProperties($XML_SECTION_PROPERTIES, $IBLOCK_ID, $arSection["ID"]);
5239 }
5240
5241 //Clear seo cache
5242 if(isset($bChanged) && $bChanged)
5243 {
5244 $ipropValues = new \Bitrix\Iblock\InheritedProperty\SectionValues($this->next_step["IBLOCK_ID"], $arSection["ID"]);
5245 $ipropValues->clearValues();
5246 }
5247
5248 if($arSection["ID"])
5249 {
5250 $this->_xml_file->Add(array("PARENT_ID" => 0, "LEFT_MARGIN" => $arSection["ID"]));
5251 }
5252
5253 if($XML_SECTIONS_PARENT)
5254 {
5255 $rs = $this->_xml_file->GetList(
5256 array("ID" => "asc"),
5257 array("PARENT_ID" => $XML_SECTIONS_PARENT),
5258 array("ID")
5259 );
5260 while($ar = $rs->Fetch())
5261 {
5262 $result = $this->ImportSection($ar["ID"], $IBLOCK_ID, $arSection["ID"]);
5263 if($result !== true)
5264 return $result;
5265 }
5266 }
5267
5268 return true;
5269 }
5270
5272 {
5273 $arCodes = array();
5274 $rsCodeLike = CIBlockElement::GetList(array(), array(
5275 "IBLOCK_ID" => $IBLOCK_ID,
5276 "CODE" => $CODE."%",
5277 ), false, false, array("ID", "CODE"));
5278 while($ar = $rsCodeLike->Fetch())
5279 {
5280 if ($ID == $ar["ID"])
5281 return false;
5282 $arCodes[$ar["CODE"]] = true;
5283 }
5284
5285 if (array_key_exists($CODE, $arCodes))
5286 {
5287 $i = 1;
5288 while(array_key_exists($CODE."_".$i, $arCodes))
5289 $i++;
5290
5291 return $CODE."_".$i;
5292 }
5293 else
5294 {
5295 return $CODE;
5296 }
5297 }
5298
5300 {
5301 $arCodes = array();
5302 $rsCodeLike = CIBlockSection::GetList(array(), array(
5303 "IBLOCK_ID" => $IBLOCK_ID,
5304 "CODE" => $CODE."%",
5305 ), false, array("ID", "CODE"));
5306 while($ar = $rsCodeLike->Fetch())
5307 {
5308 if ($ID == $ar["ID"])
5309 return false;
5310 $arCodes[$ar["CODE"]] = true;
5311 }
5312
5313 if (array_key_exists($CODE, $arCodes))
5314 {
5315 $i = 1;
5316 while(array_key_exists($CODE."_".$i, $arCodes))
5317 $i++;
5318
5319 return $CODE."_".$i;
5320 }
5321 else
5322 {
5323 return $CODE;
5324 }
5325 }
5326
5328 {
5329 $counter = array(
5330 "DEL" => 0,
5331 "DEA" => 0,
5332 "NON" => 0,
5333 );
5334
5335 if(array_key_exists("bUpdateOnly", $this->next_step) && $this->next_step["bUpdateOnly"])
5336 return $counter;
5337
5338 if($action!="D" && $action!="A")
5339 return $counter;
5340
5341 $bDelete = $action=="D";
5342
5343 //This will protect us from deactivating when next_step is lost
5344 $IBLOCK_ID = intval($this->next_step["IBLOCK_ID"]);
5345 if($IBLOCK_ID < 1)
5346 return $counter;
5347
5348 $arFilter = array(
5349 ">ID" => $this->next_step["LAST_ID"] ?? 0,
5350 "IBLOCK_ID" => $IBLOCK_ID,
5351 );
5352 if(!$bDelete)
5353 $arFilter["ACTIVE"] = "Y";
5354
5355 $obElement = new CIBlockElement;
5356 $rsElement = $obElement->GetList(
5357 Array("ID"=>"asc"),
5358 $arFilter,
5359 false, false,
5360 Array("ID", "ACTIVE")
5361 );
5362
5363 while($arElement = $rsElement->Fetch())
5364 {
5365 $rs = $this->_xml_file->GetList(
5366 array(),
5367 array("PARENT_ID+0" => 0, "LEFT_MARGIN" => $arElement["ID"]),
5368 array("ID")
5369 );
5370 $ar = $rs->Fetch();
5371 if(!$ar)
5372 {
5373 if($bDelete)
5374 {
5375 $obElement->Delete($arElement["ID"]);
5376 $counter["DEL"]++;
5377 }
5378 else
5379 {
5380 $elementFields = array("ACTIVE"=>"N");
5381 if ((string)\Bitrix\Main\Config\Option::get('iblock', 'change_user_by_group_active_modify') === 'Y')
5382 {
5383 $elementFields['MODIFIED_BY'] = $this->currentUserId;
5384 }
5385 $obElement->Update($arElement["ID"], $elementFields);
5386 $counter["DEA"]++;
5387 }
5388 }
5389 else
5390 {
5391 $counter["NON"]++;
5392 }
5393
5394 $this->next_step["LAST_ID"] = $arElement["ID"];
5395
5396 if($interval > 0 && (time()-$start_time) > $interval)
5397 break;
5398
5399 }
5400 return $counter;
5401 }
5402
5407 public function updateCounters(array $counters): int
5408 {
5409 $result = 0;
5410
5411 if (!isset($this->next_step["DONE"]))
5412 $this->next_step["DONE"] = [];
5413 foreach ($counters as $index => $value)
5414 {
5415 if (!isset($this->next_step["DONE"][$index]))
5416 $this->next_step["DONE"][$index] = 0;
5417 $value = (int)$value;
5418 $this->next_step["DONE"][$index] += $value;
5419 $result += $value;
5420 }
5421 unset($index, $value);
5422
5423 return $result;
5424 }
5425
5430 public static function getIblockCacheModeList(bool $description = false): array
5431 {
5432 if ($description)
5433 {
5434 return array(
5435 self::IBLOCK_CACHE_NORMAL => GetMessage('IBLOCK_XML2_IBLOCK_CACHE_MODE_NORMAL'),
5436 self::IBLOCK_CACHE_HIT => GetMessage('IBLOCK_XML2_IBLOCK_CACHE_MODE_HIT'),
5437 self::IBLOCK_CACHE_FINAL => GetMessage('IBLOCK_XML2_IBLOCK_CACHE_MODE_FINAL'),
5438 self::IBLOCK_CACHE_FREEZE => GetMessage('IBLOCK_XML2_IBLOCK_CACHE_MODE_FREEZE')
5439 );
5440 }
5441 return array(
5442 self::IBLOCK_CACHE_NORMAL,
5443 self::IBLOCK_CACHE_HIT,
5444 self::IBLOCK_CACHE_FINAL,
5445 self::IBLOCK_CACHE_FREEZE
5446 );
5447 }
5448
5452 public function freezeIblockCache(): void
5453 {
5454 if (
5455 isset($this->next_step['IBLOCK_ID'])
5456 && $this->next_step['IBLOCK_ID'] > 0
5457 && !$this->isIblockCacheModeNormal()
5458 )
5459 {
5460 CIBlock::disableClearTagCache();
5461 }
5462 }
5463
5467 public function unFreezeIblockCache(): void
5468 {
5469 if (
5470 isset($this->next_step['IBLOCK_ID'])
5471 && $this->next_step['IBLOCK_ID'] > 0
5472 && !$this->isIblockCacheModeNormal()
5473 )
5474 {
5475 CIBlock::enableClearTagCache();
5476 }
5477 }
5478
5482 public function clearIblockCacheOnHit(): void
5483 {
5484 if (
5485 !isset($this->next_step['IBLOCK_ID'])
5486 || $this->next_step['IBLOCK_ID'] <= 0
5487 || !$this->isIblockCacheModeHit()
5488 )
5489 {
5490 return;
5491 }
5492
5493 CIBlock::clearIblockTagCache($this->next_step['IBLOCK_ID']);
5494 }
5495
5499 public function clearIblockCacheAfterFinal(): void
5500 {
5501 if (
5502 !isset($this->next_step['IBLOCK_ID'])
5503 || $this->next_step['IBLOCK_ID'] <= 0
5504 || !$this->isIblockCacheModeFinal()
5505 )
5506 {
5507 return;
5508 }
5509
5510 CIBlock::clearIblockTagCache($this->next_step['IBLOCK_ID']);
5511 }
5512
5516 public function getIblockCacheMode(): string
5517 {
5519 }
5520
5524 public function isIblockCacheModeNormal(): bool
5525 {
5526 return $this->getIblockCacheMode() === self::IBLOCK_CACHE_NORMAL;
5527 }
5528
5532 public function isIblockCacheModeHit(): bool
5533 {
5534 return $this->getIblockCacheMode() === self::IBLOCK_CACHE_HIT;
5535 }
5536
5540 public function isIblockCacheModeFinal(): bool
5541 {
5542 return $this->getIblockCacheMode() === self::IBLOCK_CACHE_FINAL;
5543 }
5544
5548 public function isIblockCacheModeFreeze(): bool
5549 {
5550 return $this->getIblockCacheMode() === self::IBLOCK_CACHE_FREEZE;
5551 }
5552
5558 protected function getStoreList(): array
5559 {
5560 $result = array();
5561 if ($this->bCatalog)
5562 {
5563 $iterator = Catalog\StoreTable::getList(array(
5564 'select' => array('ID', 'XML_ID')
5565 ));
5566 while ($row = $iterator->fetch())
5567 {
5568 $result[$row['XML_ID']] = $row['ID'];
5569 }
5570 unset($row);
5571 unset($iterator);
5572 }
5573 return $result;
5574 }
5575
5581 protected function getActiveStores(): array
5582 {
5583 $result = array();
5584 if ($this->bCatalog)
5585 {
5586 $iterator = Catalog\StoreTable::getList(array(
5587 'select' => array('ID', 'XML_ID'),
5588 'filter' => array('=ACTIVE' => 'Y')
5589 ));
5590 while ($row = $iterator->fetch())
5591 {
5592 $result[$row['XML_ID']] = $row['ID'];
5593 }
5594 unset($row);
5595 unset($iterator);
5596 }
5597 return $result;
5598 }
5599
5606 protected function countTotalQuantity(array $stores)
5607 {
5608 $totalQuantity = 0;
5609 foreach ($stores as $xmlId => $quantity)
5610 {
5611 if (isset($this->activeStores[$xmlId]))
5612 {
5613 $totalQuantity += $quantity;
5614 }
5615 }
5616 return $totalQuantity;
5617 }
5618}
5619
5621{
5622 var $fp = null;
5623 var $IBLOCK_ID = false;
5624 var $bExtended = false;
5625 var $work_dir = false;
5626 var $file_dir = false;
5628 var $next_step = false;
5630 var $arIBlock = false;
5632 var $only_price = false;
5634 var $export_as_url = false;
5636
5637 function Init($fp, $IBLOCK_ID, $next_step, $bExtended=false, $work_dir=false, $file_dir=false, $bCheckPermissions = true, $PRODUCT_IBLOCK_ID = false)
5638 {
5639 $this->fp = $fp;
5640 $this->IBLOCK_ID = intval($IBLOCK_ID);
5641 $this->bExtended = $bExtended;
5642 $this->work_dir = $work_dir;
5643 $this->file_dir = $file_dir;
5644 $this->next_step = $next_step;
5645 $this->only_price = false;
5646 $this->download_files = true;
5647 $this->PRODUCT_IBLOCK_ID = intval($PRODUCT_IBLOCK_ID);
5648
5649 $arFilter = array(
5650 "ID" => $this->IBLOCK_ID,
5651 "MIN_PERMISSION" => "W",
5652 );
5653 if(!$bCheckPermissions)
5654 $arFilter["CHECK_PERMISSIONS"] = "N";
5655
5656 $rsIBlock = CIBlock::GetList(array(), $arFilter);
5657 if(($this->arIBlock = $rsIBlock->Fetch()) && ($this->arIBlock["ID"]==$this->IBLOCK_ID))
5658 {
5659 $this->next_step["catalog"] = Loader::includeModule('catalog');
5660 if($this->next_step["catalog"])
5661 {
5662 $rs = CCatalog::GetList(array(),array("IBLOCK_ID"=>$this->arIBlock["ID"]));
5663 if($rs->Fetch())
5664 {
5665 $this->next_step["catalog"] = true;
5666 $this->prices = array();
5667 foreach (Catalog\GroupTable::getTypeList() as $arPrice)
5668 {
5669 $this->prices[$arPrice["ID"]] = $arPrice["NAME"];
5670 }
5671 }
5672 else
5673 {
5674 $this->next_step["catalog"] = false;
5675 }
5676 }
5677 return true;
5678 }
5679 else
5680 return false;
5681 }
5682
5684 {
5685 $this->download_files = false;
5686 }
5687
5688 function NotCatalog()
5689 {
5690 $this->next_step["catalog"] = false;
5691 }
5692
5694 {
5695 $this->export_as_url = true;
5696 }
5697
5698 function GetIBlockXML_ID($IBLOCK_ID, $XML_ID=false)
5699 {
5700 if($XML_ID === false)
5701 {
5702 $IBLOCK_ID = intval($IBLOCK_ID);
5703 if($IBLOCK_ID>0)
5704 {
5705 $obIBlock = new CIBlock;
5706 $rsIBlock = $obIBlock->GetList(array(), array("ID"=>$IBLOCK_ID));
5707 if($arIBlock = $rsIBlock->Fetch())
5708 $XML_ID = $arIBlock["XML_ID"];
5709 else
5710 return "";
5711 }
5712 else
5713 return "";
5714 }
5715 if($XML_ID == '')
5716 {
5717 $XML_ID = $IBLOCK_ID;
5718 $obIBlock = new CIBlock;
5719 $rsIBlock = $obIBlock->GetList(array(), array("XML_ID"=>$XML_ID));
5720 while($rsIBlock->Fetch())
5721 {
5722 $XML_ID = md5(uniqid(mt_rand(), true));
5723 $rsIBlock = $obIBlock->GetList(array(), array("XML_ID"=>$XML_ID));
5724 }
5725 $obIBlock->Update($IBLOCK_ID, array("XML_ID" => $XML_ID));
5726 }
5727 return $XML_ID;
5728 }
5729
5730 function GetSectionXML_ID($IBLOCK_ID, $SECTION_ID, $XML_ID = false)
5731 {
5732 if($XML_ID === false)
5733 {
5734 $rsSection = CIBlockSection::GetList(array(), array("IBLOCK_ID"=>$IBLOCK_ID, "ID"=>$SECTION_ID), false, array('ID', 'XML_ID'));
5735 if($arSection = $rsSection->Fetch())
5736 {
5737 $XML_ID = $arSection["XML_ID"];
5738 }
5739 unset($rsSection);
5740 }
5741 if($XML_ID == '')
5742 {
5743 $XML_ID = $SECTION_ID;
5744 $obSection = new CIBlockSection;
5745 $rsSection = $obSection->GetList(array(), array("IBLOCK_ID"=>$IBLOCK_ID, "EXTERNAL_ID"=>$XML_ID), false, array('ID'));
5746 while($rsSection->Fetch())
5747 {
5748 $XML_ID = md5(uniqid(mt_rand(), true));
5749 $rsSection = $obSection->GetList(array(), array("IBLOCK_ID"=>$IBLOCK_ID, "EXTERNAL_ID"=>$XML_ID), false, array('ID'));
5750 }
5751 $obSection->Update($SECTION_ID, array("XML_ID" => $XML_ID), false, false);
5752 }
5753 return $XML_ID;
5754 }
5755
5756 function GetElementXML_ID($IBLOCK_ID, $ELEMENT_ID, $XML_ID = false)
5757 {
5758 if($XML_ID === false)
5759 {
5760 $arFilter = array(
5761 "ID" => $ELEMENT_ID,
5762 "SHOW_HISTORY"=>"Y",
5763 );
5764 if($IBLOCK_ID > 0)
5765 $arFilter["IBLOCK_ID"] = $IBLOCK_ID;
5766 $rsElement = CIBlockElement::GetList(
5767 Array("ID"=>"asc"),
5768 $arFilter,
5769 false, false,
5770 Array("ID", "XML_ID")
5771 );
5772 if($arElement = $rsElement->Fetch())
5773 {
5774 $XML_ID = $arElement["XML_ID"];
5775 }
5776 unset($rsElement);
5777 unset($arElement);
5778 }
5779 return $XML_ID;
5780 }
5781
5782 function GetPropertyXML_ID($IBLOCK_ID, $NAME, $PROPERTY_ID, $XML_ID)
5783 {
5784 if($XML_ID == '')
5785 {
5786 $XML_ID = $PROPERTY_ID;
5787 $obProperty = new CIBlockProperty;
5788 $rsProperty = $obProperty->GetList(array(), array("IBLOCK_ID"=>$IBLOCK_ID, "XML_ID"=>$XML_ID));
5789 while($rsProperty->Fetch())
5790 {
5791 $XML_ID = md5(uniqid(mt_rand(), true));
5792 $rsProperty = $obProperty->GetList(array(), array("IBLOCK_ID"=>$IBLOCK_ID, "XML_ID"=>$XML_ID));
5793 }
5794 $obProperty->Update($PROPERTY_ID, array("NAME"=>$NAME, "XML_ID" => $XML_ID));
5795 }
5796 return $XML_ID;
5797 }
5798
5799 function StartExport()
5800 {
5801 fwrite($this->fp, "<"."?xml version=\"1.0\" encoding=\"".LANG_CHARSET."\"?".">\n");
5802 fwrite($this->fp, "<".GetMessage("IBLOCK_XML2_COMMERCE_INFO")." ".GetMessage("IBLOCK_XML2_SCHEMA_VERSION")."=\"2.021\" ".GetMessage("IBLOCK_XML2_TIMESTAMP")."=\"".date("Y-m-d")."T".date("H:i:s")."\">\n");
5803 }
5804
5805 function ExportFile($FILE_ID)
5806 {
5807 if($this->work_dir)
5808 {
5809 $arFile = CFile::GetFileArray($FILE_ID);
5810 if($arFile)
5811 {
5812 if((!$this->download_files) && ($arFile["HANDLER_ID"] > 0))
5813 {
5814 return array(
5815 GetMessage("IBLOCK_XML2_BX_ORIGINAL_NAME") => $arFile["ORIGINAL_NAME"],
5816 GetMessage("IBLOCK_XML2_DESCRIPTION") => $arFile["DESCRIPTION"],
5817 GetMessage("IBLOCK_XML2_BX_URL") => urldecode($arFile["SRC"]),
5818 GetMessage("IBLOCK_XML2_BX_FILE_SIZE") => $arFile["FILE_SIZE"],
5819 GetMessage("IBLOCK_XML2_BX_FILE_WIDTH") => $arFile["WIDTH"],
5820 GetMessage("IBLOCK_XML2_BX_FILE_HEIGHT") => $arFile["HEIGHT"],
5821 GetMessage("IBLOCK_XML2_BX_FILE_CONTENT_TYPE") => $arFile["CONTENT_TYPE"],
5822 );
5823 }
5824 else
5825 {
5826 $arTempFile = CFile::MakeFileArray($FILE_ID);
5827 if(isset($arTempFile["tmp_name"]) && $arTempFile["tmp_name"] <> "")
5828 {
5829 $strFile = $arFile["SUBDIR"]."/".$arFile["FILE_NAME"];
5830 $strNewFile = str_replace("//", "/", $this->work_dir.$this->file_dir.$strFile);
5831 CheckDirPath($strNewFile);
5832
5833 if(@copy($arTempFile["tmp_name"], $strNewFile))
5834 return $this->file_dir.$strFile;
5835 }
5836 }
5837 }
5838 }
5839 elseif($this->export_as_url)
5840 {
5841 $arFile = CFile::GetFileArray($FILE_ID);
5842 if($arFile)
5843 return CHTTP::URN2URI($arFile["SRC"]);
5844 }
5845
5846 return "";
5847 }
5848
5849 function ExportEnum($arUserField, $value)
5850 {
5851 static $cache = array();
5852 if (!isset($cache[$value]))
5853 {
5854 $obEnum = new CUserFieldEnum;
5855 $rsEnum = $obEnum->GetList(array(), array(
5856 "USER_FIELD_ID" => $arUserField["ID"],
5857 "ID" => $value,
5858 ));
5859 $cache[$value] = $rsEnum->Fetch();
5860 }
5861 return $cache[$value]["XML_ID"];
5862 }
5863
5864 function formatXMLNode($level, $tagName, $value)
5865 {
5866 if(is_array($value))
5867 {
5868 $xmlValue = "";
5869 foreach($value as $k => $v)
5870 {
5871 if($k)
5872 $xmlValue .= "\n".rtrim($this->formatXMLNode($level+1, $k, $v), "\n");
5873 }
5874 $xmlValue .= "\n".str_repeat("\t", $level);
5875 }
5876 else
5877 {
5878 $xmlValue = htmlspecialcharsbx($value);
5879 }
5880
5881 return str_repeat("\t", $level)."<".$tagName.">".$xmlValue."</".$tagName.">\n";
5882 }
5883
5885 {
5886 $xml_id = $this->GetIBlockXML_ID($this->arIBlock["ID"], $this->arIBlock["XML_ID"]);
5887 $this->arIBlock["XML_ID"] = $xml_id;
5888 fwrite($this->fp, "\t<".GetMessage("IBLOCK_XML2_METADATA").">\n");
5889 fwrite($this->fp, $this->formatXMLNode(2, GetMessage("IBLOCK_XML2_ID"), $xml_id));
5890 fwrite($this->fp, $this->formatXMLNode(2, GetMessage("IBLOCK_XML2_NAME"), $this->arIBlock["NAME"]));
5891 if($this->arIBlock["DESCRIPTION"] <> '')
5892 fwrite($this->fp, $this->formatXMLNode(2, GetMessage("IBLOCK_XML2_DESCRIPTION"), FormatText($this->arIBlock["DESCRIPTION"], $this->arIBlock["DESCRIPTION_TYPE"])));
5893 }
5894
5895 function ExportSectionsProperties($arUserFields)
5896 {
5897 if(empty($arUserFields))
5898 return;
5899
5900 fwrite($this->fp, "\t\t<".GetMessage("IBLOCK_XML2_GROUPS_PROPERTIES").">\n");
5901 foreach($arUserFields as $FIELD_ID => $arField)
5902 {
5903 fwrite($this->fp, "\t\t\t<".GetMessage("IBLOCK_XML2_PROPERTY").">\n");
5904 fwrite($this->fp, "\t\t\t\t<".GetMessage("IBLOCK_XML2_ID").">".htmlspecialcharsbx($arField["XML_ID"])."</".GetMessage("IBLOCK_XML2_ID").">\n");
5905 fwrite($this->fp, "\t\t\t\t<".GetMessage("IBLOCK_XML2_NAME").">".htmlspecialcharsbx($FIELD_ID)."</".GetMessage("IBLOCK_XML2_NAME").">\n");
5906 fwrite($this->fp, "\t\t\t\t<".GetMessage("IBLOCK_XML2_SORT").">".htmlspecialcharsbx($arField["SORT"])."</".GetMessage("IBLOCK_XML2_SORT").">\n");
5907 fwrite($this->fp, "\t\t\t\t<".GetMessage("IBLOCK_XML2_MULTIPLE").">".($arField["MULTIPLE"] == "Y"? "true": "false")."</".GetMessage("IBLOCK_XML2_MULTIPLE").">\n");
5908 fwrite($this->fp, "\t\t\t\t<".GetMessage("IBLOCK_XML2_BX_PROPERTY_TYPE").">".htmlspecialcharsbx($arField["USER_TYPE_ID"])."</".GetMessage("IBLOCK_XML2_BX_PROPERTY_TYPE").">\n");
5909 fwrite($this->fp, "\t\t\t\t<".GetMessage("IBLOCK_XML2_BX_IS_REQUIRED").">".($arField["MANDATORY"] == "Y"? "true": "false")."</".GetMessage("IBLOCK_XML2_BX_IS_REQUIRED").">\n");
5910 fwrite($this->fp, "\t\t\t\t<".GetMessage("IBLOCK_XML2_BX_FILTER").">".($arField["SHOW_FILTER"] == "Y"? "true": "false")."</".GetMessage("IBLOCK_XML2_BX_FILTER").">\n");
5911 fwrite($this->fp, "\t\t\t\t<".GetMessage("IBLOCK_XML2_BX_SHOW_IN_LIST").">".($arField["SHOW_IN_LIST"] == "Y"? "true": "false")."</".GetMessage("IBLOCK_XML2_BX_SHOW_IN_LIST").">\n");
5912 fwrite($this->fp, "\t\t\t\t<".GetMessage("IBLOCK_XML2_BX_EDIT_IN_LIST").">".($arField["EDIT_IN_LIST"] == "Y"? "true": "false")."</".GetMessage("IBLOCK_XML2_BX_EDIT_IN_LIST").">\n");
5913 fwrite($this->fp, "\t\t\t\t<".GetMessage("IBLOCK_XML2_BX_SEARCH").">".($arField["IS_SEARCHABLE"] == "Y"? "true": "false")."</".GetMessage("IBLOCK_XML2_BX_SEARCH").">\n");
5914 fwrite($this->fp, "\t\t\t\t<".GetMessage("IBLOCK_XML2_BX_SETTINGS").">".htmlspecialcharsbx(serialize($arField["SETTINGS"]))."</".GetMessage("IBLOCK_XML2_BX_SETTINGS").">\n");
5915
5916 if (is_callable(array($arField["USER_TYPE"]['CLASS_NAME'], 'getlist')))
5917 {
5918 fwrite($this->fp, "\t\t\t\t<".GetMessage("IBLOCK_XML2_CHOICE_VALUES").">\n");
5919
5920 $rsEnum = call_user_func_array(
5921 array($arField["USER_TYPE"]["CLASS_NAME"], "getlist"),
5922 array(
5923 $arField,
5924 )
5925 );
5926 if (is_object($rsEnum))
5927 {
5928 while ($arEnum = $rsEnum->GetNext())
5929 {
5930 fwrite($this->fp,
5931 "\t\t\t\t\t<".GetMessage("IBLOCK_XML2_CHOICE").">\n"
5932 .$this->formatXMLNode(6, GetMessage("IBLOCK_XML2_ID"), $arEnum["XML_ID"])
5933 .$this->formatXMLNode(6, GetMessage("IBLOCK_XML2_VALUE"), $arEnum["VALUE"])
5934 .$this->formatXMLNode(6, GetMessage("IBLOCK_XML2_BY_DEFAULT"), ($arEnum["DEF"] == "Y" ? "true" : "false"))
5935 .$this->formatXMLNode(6, GetMessage("IBLOCK_XML2_SORT"), intval($arEnum["SORT"]))
5936 ."\t\t\t\t\t</".GetMessage("IBLOCK_XML2_CHOICE").">\n"
5937 );
5938 }
5939 }
5940 unset($rsEnum);
5941
5942 fwrite($this->fp, "\t\t\t\t</".GetMessage("IBLOCK_XML2_CHOICE_VALUES").">\n");
5943 }
5944
5945 fwrite($this->fp, "\t\t\t</".GetMessage("IBLOCK_XML2_PROPERTY").">\n");
5946 }
5947 fwrite($this->fp, "\t\t</".GetMessage("IBLOCK_XML2_GROUPS_PROPERTIES").">\n");
5948 }
5949
5950 function ExportSections(&$SECTION_MAP, $start_time, $INTERVAL, $FILTER = "", $PROPERTY_MAP = array())
5951 {
5953 global $USER_FIELD_MANAGER;
5954
5955 $counter = 0;
5956 if(!array_key_exists("CURRENT_DEPTH", $this->next_step))
5957 $this->next_step["CURRENT_DEPTH"]=0;
5958 else // this makes second "step"
5959 return $counter;
5960
5961 $arUserFields = $USER_FIELD_MANAGER->GetUserFields("IBLOCK_".$this->arIBlock["ID"]."_SECTION");
5962 foreach($arUserFields as $FIELD_ID => $arField)
5963 if($arField["XML_ID"] == '')
5964 $arUserFields[$FIELD_ID]["XML_ID"] = $FIELD_ID;
5965
5966 if($this->bExtended)
5967 $this->ExportSectionsProperties($arUserFields);
5968
5969 $SECTION_MAP = array();
5970
5971 if($FILTER === "none")
5972 return 0;
5973 $arFilter = array(
5974 "IBLOCK_ID" => $this->arIBlock["ID"],
5975 "GLOBAL_ACTIVE" => "Y",
5976 "CHECK_PERMISSIONS" => "N",
5977 );
5978 if($FILTER === "all")
5979 unset($arFilter["GLOBAL_ACTIVE"]);
5980
5981 $rsSections = CIBlockSection::GetList(array("left_margin"=>"asc"), $arFilter, false, array("UF_*"));
5982 fwrite($this->fp, "\t\t<".GetMessage("IBLOCK_XML2_GROUPS").">\n");
5983 while($arSection = $rsSections->Fetch())
5984 {
5985 $white_space = str_repeat("\t\t", $arSection["DEPTH_LEVEL"]);
5986 $level = ($arSection["DEPTH_LEVEL"]+1)*2;
5987
5988 while($this->next_step["CURRENT_DEPTH"] >= $arSection["DEPTH_LEVEL"])
5989 {
5990 fwrite($this->fp, str_repeat("\t\t", $this->next_step["CURRENT_DEPTH"])."\t\t</".GetMessage("IBLOCK_XML2_GROUPS").">\n");
5991 fwrite($this->fp, str_repeat("\t\t", $this->next_step["CURRENT_DEPTH"]-1)."\t\t\t</".GetMessage("IBLOCK_XML2_GROUP").">\n");
5992 $this->next_step["CURRENT_DEPTH"]--;
5993 }
5994
5995 $xml_id = $this->GetSectionXML_ID($this->arIBlock["ID"], $arSection["ID"], $arSection["XML_ID"]);
5996 $SECTION_MAP[$arSection["ID"]] = $xml_id;
5997
5998 fwrite($this->fp,
5999 $white_space."\t<".GetMessage("IBLOCK_XML2_GROUP").">\n"
6000 .$this->formatXMLNode($level, GetMessage("IBLOCK_XML2_ID"), $xml_id)
6001 .$this->formatXMLNode($level, GetMessage("IBLOCK_XML2_NAME"), $arSection["NAME"])
6002 );
6003 if($arSection["DESCRIPTION"] <> '')
6004 fwrite($this->fp, $white_space."\t\t<".GetMessage("IBLOCK_XML2_DESCRIPTION").">".htmlspecialcharsbx(FormatText($arSection["DESCRIPTION"], $arSection["DESCRIPTION_TYPE"]))."</".GetMessage("IBLOCK_XML2_DESCRIPTION").">\n");
6005 if($this->bExtended)
6006 {
6007 fwrite($this->fp,
6008 $this->formatXMLNode($level, GetMessage("IBLOCK_XML2_BX_ACTIVE"), ($arSection["ACTIVE"]=="Y"? "true": "false"))
6009 .$this->formatXMLNode($level, GetMessage("IBLOCK_XML2_BX_SORT"), intval($arSection["SORT"]))
6010 .$this->formatXMLNode($level, GetMessage("IBLOCK_XML2_BX_CODE"), $arSection["CODE"])
6011 .$this->formatXMLNode($level, GetMessage("IBLOCK_XML2_BX_PICTURE"), $this->ExportFile($arSection["PICTURE"]))
6012 .$this->formatXMLNode($level, GetMessage("IBLOCK_XML2_BX_DETAIL_PICTURE"), $this->ExportFile($arSection["DETAIL_PICTURE"]))
6013 );
6014
6015 if(!empty($arUserFields))
6016 {
6017 fwrite($this->fp, $white_space."\t\t<".GetMessage("IBLOCK_XML2_PROPERTIES_VALUES").">\n");
6018 foreach($arUserFields as $FIELD_ID => $arField)
6019 {
6020 fwrite($this->fp, $white_space."\t\t\t<".GetMessage("IBLOCK_XML2_PROPERTY_VALUES").">\n");
6021 fwrite($this->fp, $this->formatXMLNode($level+2, GetMessage("IBLOCK_XML2_ID"), $arField["XML_ID"]));
6022
6023 $values = array();
6024 if(!is_array($arSection[$FIELD_ID]))
6025 {
6026 if($arField["USER_TYPE"]["BASE_TYPE"] === "file")
6027 $values[] = $this->ExportFile($arSection[$FIELD_ID]);
6028 elseif($arField["USER_TYPE"]["BASE_TYPE"] === "enum")
6029 $values[] = $this->ExportEnum($arField, $arSection[$FIELD_ID]);
6030 else
6031 $values[] = $arSection[$FIELD_ID];
6032 }
6033 elseif(empty($arSection[$FIELD_ID]))
6034 {
6035 $values[] = "";
6036 }
6037 else
6038 {
6039 foreach($arSection[$FIELD_ID] as $value)
6040 {
6041 if($arField["USER_TYPE"]["BASE_TYPE"] === "file")
6042 $values[] = $this->ExportFile($value);
6043 elseif($arField["USER_TYPE"]["BASE_TYPE"] === "enum")
6044 $values[] = $this->ExportEnum($arField, $value);
6045 else
6046 $values[] = $value;
6047 }
6048 }
6049
6050 foreach($values as $value)
6051 {
6052 fwrite($this->fp, $this->formatXMLNode($level+2, GetMessage("IBLOCK_XML2_VALUE"), $value));
6053 }
6054
6055 fwrite($this->fp, $white_space."\t\t\t</".GetMessage("IBLOCK_XML2_PROPERTY_VALUES").">\n");
6056 }
6057 fwrite($this->fp, $white_space."\t\t</".GetMessage("IBLOCK_XML2_PROPERTIES_VALUES").">\n");
6058 }
6059
6060 $this->ExportSmartFilter($level, $this->arIBlock["ID"], $arSection["ID"], $PROPERTY_MAP);
6061
6062 $sectionTemplates = new \Bitrix\Iblock\InheritedProperty\SectionTemplates($this->arIBlock["ID"], $arSection["ID"]);
6063 $this->exportInheritedTemplates($arSection["DEPTH_LEVEL"]*2 + 2, $sectionTemplates);
6064 }
6065
6066 fwrite($this->fp, $white_space."\t\t<".GetMessage("IBLOCK_XML2_GROUPS").">\n");
6067
6068 $this->next_step["CURRENT_DEPTH"] = $arSection["DEPTH_LEVEL"];
6069 $counter++;
6070 }
6071
6072 while($this->next_step["CURRENT_DEPTH"] > 0)
6073 {
6074 fwrite($this->fp, str_repeat("\t\t", $this->next_step["CURRENT_DEPTH"])."\t\t</".GetMessage("IBLOCK_XML2_GROUPS").">\n");
6075 fwrite($this->fp, str_repeat("\t\t", $this->next_step["CURRENT_DEPTH"]-1)."\t\t\t</".GetMessage("IBLOCK_XML2_GROUP").">\n");
6076 $this->next_step["CURRENT_DEPTH"]--;
6077 }
6078 fwrite($this->fp, "\t\t</".GetMessage("IBLOCK_XML2_GROUPS").">\n");
6079
6080 return $counter;
6081 }
6082
6083 function ExportProperties(&$PROPERTY_MAP)
6084 {
6085 $PROPERTY_MAP = array();
6086
6087 fwrite($this->fp, "\t\t<".GetMessage("IBLOCK_XML2_PROPERTIES").">\n");
6088
6089 if($this->bExtended)
6090 {
6091 $arElementFields = array(
6092 "CML2_ACTIVE" => GetMessage("IBLOCK_XML2_BX_ACTIVE"),
6093 "CML2_CODE" => GetMessage("IBLOCK_XML2_SYMBOL_CODE"),
6094 "CML2_SORT" => GetMessage("IBLOCK_XML2_SORT"),
6095 "CML2_ACTIVE_FROM" => GetMessage("IBLOCK_XML2_START_TIME"),
6096 "CML2_ACTIVE_TO" => GetMessage("IBLOCK_XML2_END_TIME"),
6097 "CML2_PREVIEW_TEXT" => GetMessage("IBLOCK_XML2_ANONS"),
6098 "CML2_DETAIL_TEXT" => GetMessage("IBLOCK_XML2_DETAIL"),
6099 "CML2_PREVIEW_PICTURE" => GetMessage("IBLOCK_XML2_PREVIEW_PICTURE"),
6100 );
6101
6102 foreach($arElementFields as $key => $value)
6103 {
6104 fwrite($this->fp, $this->formatXMLNode(3, GetMessage("IBLOCK_XML2_PROPERTY"), array(
6105 GetMessage("IBLOCK_XML2_ID") => $key,
6106 GetMessage("IBLOCK_XML2_NAME") => $value,
6107 GetMessage("IBLOCK_XML2_MULTIPLE") => "false",
6108 )));
6109 }
6110 }
6111
6112 $featureList = [];
6114 'select' => ['PROPERTY_ID', 'MODULE_ID', 'FEATURE_ID', 'IS_ENABLED'],
6115 'filter' => [
6116 '=PROPERTY.IBLOCK_ID' => $this->arIBlock['ID'],
6117 '=PROPERTY.ACTIVE' => 'Y'
6118 ],
6119 'order' => ['PROPERTY_ID' => 'ASC']
6120 ]);
6121 while ($row = $iterator->fetch())
6122 {
6123 $id = (int)$row['PROPERTY_ID'];
6124 if (!isset($featureList[$id]))
6125 $featureList[$id] = [];
6126 $featureList[$id][] = [
6127 'MODULE_ID' => $row['MODULE_ID'],
6128 'FEATURE_ID' => $row['FEATURE_ID'],
6129 'IS_ENABLED' => $row['IS_ENABLED']
6130 ];
6131 unset($id);
6132 }
6133 unset($row, $iterator);
6134
6135 $arFilter = array(
6136 "IBLOCK_ID" => $this->arIBlock["ID"],
6137 "ACTIVE" => "Y",
6138 );
6139 $arSort = array(
6140 "sort" => "asc",
6141 );
6142
6143 $obProp = new CIBlockProperty();
6144 $rsProp = $obProp->GetList($arSort, $arFilter);
6145 while($arProp = $rsProp->Fetch())
6146 {
6147 $id = (int)$arProp["ID"];
6148 fwrite($this->fp, "\t\t\t<".GetMessage("IBLOCK_XML2_PROPERTY").">\n");
6149
6150 $xml_id = $this->GetPropertyXML_ID($this->arIBlock["ID"], $arProp["NAME"], $arProp["ID"], $arProp["XML_ID"]);
6151 $PROPERTY_MAP[$arProp["ID"]] = $xml_id;
6152 $PROPERTY_MAP["~".$arProp["ID"]] = $arProp["NAME"];
6153 fwrite($this->fp, $this->formatXMLNode(4, GetMessage("IBLOCK_XML2_ID"), $xml_id));
6154
6155 fwrite($this->fp, $this->formatXMLNode(4, GetMessage("IBLOCK_XML2_NAME"), $arProp["NAME"]));
6156 fwrite($this->fp, $this->formatXMLNode(4, GetMessage("IBLOCK_XML2_MULTIPLE"), ($arProp["MULTIPLE"]=="Y"? "true": "false")));
6157 if($arProp["PROPERTY_TYPE"]=="L")
6158 {
6159 fwrite($this->fp, "\t\t\t\t<".GetMessage("IBLOCK_XML2_CHOICE_VALUES").">\n");
6160 $rsEnum = CIBlockProperty::GetPropertyEnum($arProp["ID"]);
6161 while($arEnum = $rsEnum->Fetch())
6162 {
6163 fwrite($this->fp, $this->formatXMLNode(5, GetMessage("IBLOCK_XML2_VALUE"), $arEnum["VALUE"]));
6164 if($this->bExtended)
6165 {
6166 fwrite($this->fp,
6167 "\t\t\t\t\t<".GetMessage("IBLOCK_XML2_CHOICE").">\n"
6168 .$this->formatXMLNode(6, GetMessage("IBLOCK_XML2_ID"), $arEnum["XML_ID"])
6169 .$this->formatXMLNode(6, GetMessage("IBLOCK_XML2_VALUE"), $arEnum["VALUE"])
6170 .$this->formatXMLNode(6, GetMessage("IBLOCK_XML2_BY_DEFAULT"), ($arEnum["DEF"]=="Y"? "true": "false"))
6171 .$this->formatXMLNode(6, GetMessage("IBLOCK_XML2_SORT"), intval($arEnum["SORT"]))
6172 ."\t\t\t\t\t</".GetMessage("IBLOCK_XML2_CHOICE").">\n"
6173 );
6174 }
6175 }
6176 fwrite($this->fp, "\t\t\t\t</".GetMessage("IBLOCK_XML2_CHOICE_VALUES").">\n");
6177 }
6178
6179 if($this->bExtended)
6180 {
6181 $strUserSettings = '';
6182 if ('' != $arProp["USER_TYPE"])
6183 {
6184 if (!empty($arProp['USER_TYPE_SETTINGS']) && is_array($arProp['USER_TYPE_SETTINGS']))
6185 {
6186 $strUserSettings = $this->formatXMLNode(4, GetMessage("IBLOCK_XML2_BX_USER_TYPE_SETTINGS"), serialize($arProp['USER_TYPE_SETTINGS']));
6187 }
6188 }
6189 $propertyFeatures = '';
6190 if (isset($featureList[$id]))
6191 {
6192 $propertyFeatures = $this->formatXMLNode(
6193 4,
6194 GetMessage('IBLOCK_XML2_BX_PROPERTY_FEATURE_LIST'),
6195 serialize($featureList[$id])
6196 );
6197 }
6198
6199 fwrite($this->fp,
6200 $this->formatXMLNode(4, GetMessage("IBLOCK_XML2_BX_SORT"), intval($arProp["SORT"]))
6201 .$this->formatXMLNode(4, GetMessage("IBLOCK_XML2_BX_CODE"), $arProp["CODE"])
6202 .$this->formatXMLNode(4, GetMessage("IBLOCK_XML2_BX_PROPERTY_TYPE"), $arProp["PROPERTY_TYPE"])
6203 .$this->formatXMLNode(4, GetMessage("IBLOCK_XML2_BX_ROWS"), $arProp["ROW_COUNT"])
6204 .$this->formatXMLNode(4, GetMessage("IBLOCK_XML2_BX_COLUMNS"), $arProp["COL_COUNT"])
6205 .$this->formatXMLNode(4, GetMessage("IBLOCK_XML2_BX_LIST_TYPE"), $arProp["LIST_TYPE"])
6206 .$this->formatXMLNode(4, GetMessage("IBLOCK_XML2_BX_FILE_EXT"), $arProp["FILE_TYPE"])
6207 .$this->formatXMLNode(4, GetMessage("IBLOCK_XML2_BX_FIELDS_COUNT"), $arProp["MULTIPLE_CNT"])
6208 .$this->formatXMLNode(4, GetMessage("IBLOCK_XML2_BX_LINKED_IBLOCK"), $this->GetIBlockXML_ID($arProp["LINK_IBLOCK_ID"]))
6209 .$this->formatXMLNode(4, GetMessage("IBLOCK_XML2_BX_WITH_DESCRIPTION"), ($arProp["WITH_DESCRIPTION"]=="Y"? "true": "false"))
6210 .$this->formatXMLNode(4, GetMessage("IBLOCK_XML2_BX_SEARCH"), ($arProp["SEARCHABLE"]=="Y"? "true": "false"))
6211 .$this->formatXMLNode(4, GetMessage("IBLOCK_XML2_BX_FILTER"), ($arProp["FILTRABLE"]=="Y"? "true": "false"))
6212 .$this->formatXMLNode(4, GetMessage("IBLOCK_XML2_BX_USER_TYPE"), $arProp["USER_TYPE"])
6213 .$this->formatXMLNode(4, GetMessage("IBLOCK_XML2_BX_IS_REQUIRED"), ($arProp["IS_REQUIRED"]=="Y"? "true": "false"))
6214 .$this->formatXMLNode(4, GetMessage("IBLOCK_XML2_BX_DEFAULT_VALUE"), serialize($arProp["DEFAULT_VALUE"]))
6215 .$this->formatXMLNode(4, GetMessage("IBLOCK_XML2_SERIALIZED"), 1)
6216 .$strUserSettings
6217 .$propertyFeatures
6218 );
6219 }
6220 fwrite($this->fp, "\t\t\t</".GetMessage("IBLOCK_XML2_PROPERTY").">\n");
6221 }
6222 fwrite($this->fp, "\t\t</".GetMessage("IBLOCK_XML2_PROPERTIES").">\n");
6223
6224 if($this->bExtended)
6225 {
6226 $catalog = false;
6227 if (Loader::includeModule("catalog"))
6228 {
6229 $catalog = CCatalogSKU::getInfoByOfferIBlock($this->arIBlock["ID"]);
6230 }
6231
6232 if (!empty($catalog) && is_array($catalog))
6233 {
6234 $this->ExportSmartFilter(2, $this->arIBlock["ID"], false, $PROPERTY_MAP, $catalog["PRODUCT_IBLOCK_ID"]);
6235 }
6236 else
6237 {
6238 $this->ExportSmartFilter(2, $this->arIBlock["ID"], 0, $PROPERTY_MAP);
6239 }
6240 }
6241 }
6242
6243 function ExportSmartFilter($level, $iblockId, $sectionId, $PROPERTY_MAP, $productIblockId = 0)
6244 {
6245 $propertyLinksBySection = array();
6246 if ($sectionId === false)
6247 {
6248 $propertyLinksBySection[0] = CIBlockSectionPropertyLink::GetArray($iblockId, 0);
6249 foreach($propertyLinksBySection[0] as $PID => $arLink)
6250 {
6251 if($arLink["INHERITED"] != "N" || !array_key_exists($PID, $PROPERTY_MAP))
6252 {
6253 unset($propertyLinksBySection[0][$PID]);
6254 }
6255 else
6256 {
6257 if ($productIblockId > 0)
6258 {
6259 $iblock_xml_id = $this->GetIBlockXML_ID($productIblockId, CIBlock::GetArrayByID($productIblockId, "XML_ID"));
6260 $propertyLinksBySection[0][$PID]["IBLOCK_XML_ID"] = $iblock_xml_id;
6261 }
6262 }
6263 }
6264
6265 $arFilter = array(
6267 "CHECK_PERMISSIONS" => "N",
6268 );
6269 $rsSections = CIBlockSection::GetList(array("left_margin"=>"asc"), $arFilter, false, array("ID", "XML_ID", "IBLOCK_ID"));
6270 while($arSection = $rsSections->Fetch())
6271 {
6272 $section_xml_id = $this->GetSectionXML_ID($arSection["IBLOCK_ID"], $arSection["ID"], $arSection["XML_ID"]);
6273 $iblock_xml_id = $this->GetIBlockXML_ID($arSection["IBLOCK_ID"], CIBlock::GetArrayByID($arSection["IBLOCK_ID"], "XML_ID"));
6274
6275 $propertyLinksBySection[$arSection["ID"]] = CIBlockSectionPropertyLink::GetArray($iblockId, $arSection["ID"]);
6276 foreach($propertyLinksBySection[$arSection["ID"]] as $PID => $arLink)
6277 {
6278 if($arLink["INHERITED"] != "N" || !array_key_exists($PID, $PROPERTY_MAP))
6279 {
6280 unset($propertyLinksBySection[$arSection["ID"]][$PID]);
6281 }
6282 else
6283 {
6284 $propertyLinksBySection[$arSection["ID"]][$PID]["IBLOCK_XML_ID"] = $iblock_xml_id;
6285 $propertyLinksBySection[$arSection["ID"]][$PID]["SECTION_XML_ID"] = $section_xml_id;
6286 }
6287 }
6288 }
6289 }
6290 else
6291 {
6292 $propertyLinksBySection[$sectionId] = CIBlockSectionPropertyLink::GetArray($iblockId, $sectionId);
6293 foreach($propertyLinksBySection[$sectionId] as $PID => $arLink)
6294 {
6295 if($arLink["INHERITED"] != "N" || !array_key_exists($PID, $PROPERTY_MAP))
6296 unset($propertyLinksBySection[$sectionId][$PID]);
6297 }
6298 }
6299
6300 $first = true;
6301 foreach ($propertyLinksBySection as $arPropLink)
6302 {
6303 if(!empty($arPropLink))
6304 {
6305 if ($first)
6306 {
6307 fwrite($this->fp, str_repeat("\t", $level)."<".GetMessage("IBLOCK_XML2_SECTION_PROPERTIES").">\n");
6308 $first = false;
6309 }
6310
6311 foreach($arPropLink as $PID => $arLink)
6312 {
6313 $xmlLink = array(
6314 GetMessage("IBLOCK_XML2_ID") => $PROPERTY_MAP[$PID],
6315 GetMessage("IBLOCK_XML2_SMART_FILTER") => ($arLink["SMART_FILTER"] == "Y"? "true": "false"),
6316 GetMessage("IBLOCK_XML2_SMART_FILTER_DISPLAY_TYPE") => $arLink["DISPLAY_TYPE"],
6317 GetMessage("IBLOCK_XML2_SMART_FILTER_DISPLAY_EXPANDED") => ($arLink["DISPLAY_EXPANDED"] == "Y"? "true": "false"),
6318 GetMessage("IBLOCK_XML2_SMART_FILTER_HINT") => $arLink["FILTER_HINT"],
6319 );
6320
6321 if (isset($arLink["IBLOCK_XML_ID"]))
6322 {
6323 $xmlLink[GetMessage("IBLOCK_XML2_BX_LINKED_IBLOCK")] = $arLink["IBLOCK_XML_ID"];
6324 }
6325
6326 if (isset($arLink["SECTION_XML_ID"]))
6327 {
6328 $xmlLink[GetMessage("IBLOCK_XML2_GROUP")] = $arLink["SECTION_XML_ID"];
6329 }
6330
6331 fwrite($this->fp, $this->formatXMLNode($level+1, GetMessage("IBLOCK_XML2_PROPERTY"), $xmlLink));
6332 }
6333 }
6334 }
6335 if (!$first)
6336 {
6337 fwrite($this->fp, str_repeat("\t", $level)."</".GetMessage("IBLOCK_XML2_SECTION_PROPERTIES").">\n");
6338 }
6339 }
6340
6341 function ExportPrices()
6342 {
6343 if($this->next_step["catalog"])
6344 {
6345 $priceTypes = CCatalogGroup::GetListArray();
6346 if (!empty($priceTypes))
6347 {
6348 fwrite($this->fp, "\t\t<".GetMessage("IBLOCK_XML2_PRICE_TYPES").">\n");
6349 foreach ($priceTypes as $arPrice)
6350 {
6351 fwrite($this->fp, $this->formatXMLNode(3, GetMessage("IBLOCK_XML2_PRICE_TYPE"), array(
6352 GetMessage("IBLOCK_XML2_ID") => $arPrice["NAME"],
6353 GetMessage("IBLOCK_XML2_NAME") => $arPrice["NAME"],
6354 )));
6355 }
6356 unset($arPrice);
6357 fwrite($this->fp, "\t\t</".GetMessage("IBLOCK_XML2_PRICE_TYPES").">\n");
6358 }
6359 unset($priceTypes);
6360 }
6361 }
6362
6364 {
6365 fwrite($this->fp, "\t</".GetMessage("IBLOCK_XML2_METADATA").">\n");
6366 }
6367
6368 function StartExportCatalog($with_metadata = true, $changes_only = false)
6369 {
6370 if($this->next_step["catalog"])
6371 fwrite($this->fp, "\t<".GetMessage("IBLOCK_XML2_OFFER_LIST").">\n");
6372 else
6373 fwrite($this->fp, "\t<".GetMessage("IBLOCK_XML2_CATALOG").">\n");
6374
6375 if($this->PRODUCT_IBLOCK_ID)
6376 $xml_id = $this->GetIBlockXML_ID($this->PRODUCT_IBLOCK_ID, CIBlock::GetArrayByID($this->PRODUCT_IBLOCK_ID, "XML_ID"));
6377 else
6378 $xml_id = $this->GetIBlockXML_ID($this->arIBlock["ID"], $this->arIBlock["XML_ID"]);
6379 $this->arIBlock["XML_ID"] = $xml_id;
6380
6381 fwrite($this->fp, $this->formatXMLNode(2, GetMessage("IBLOCK_XML2_ID"), $xml_id));
6382 if($with_metadata)
6383 {
6384 fwrite($this->fp, $this->formatXMLNode(2, GetMessage("IBLOCK_XML2_METADATA_ID"), $xml_id));
6385 fwrite($this->fp, $this->formatXMLNode(2, GetMessage("IBLOCK_XML2_NAME"), $this->arIBlock["NAME"]));
6386
6387 if($this->arIBlock["DESCRIPTION"] <> '')
6388 fwrite($this->fp, $this->formatXMLNode(2, GetMessage("IBLOCK_XML2_DESCRIPTION"), FormatText($this->arIBlock["DESCRIPTION"], $this->arIBlock["DESCRIPTION_TYPE"])));
6389
6390 if($this->bExtended)
6391 {
6392 fwrite($this->fp,
6393 $this->formatXMLNode(2, GetMessage("IBLOCK_XML2_BX_CODE"), $this->arIBlock["CODE"])
6394 .$this->formatXMLNode(2, GetMessage("IBLOCK_XML2_BX_API_CODE"), (string)$this->arIBlock["API_CODE"])
6395 .$this->formatXMLNode(2, GetMessage("IBLOCK_XML2_BX_SORT"), intval($this->arIBlock["SORT"]))
6396 .$this->formatXMLNode(2, GetMessage("IBLOCK_XML2_BX_LIST_URL"), $this->arIBlock["LIST_PAGE_URL"])
6397 .$this->formatXMLNode(2, GetMessage("IBLOCK_XML2_BX_DETAIL_URL"), $this->arIBlock["DETAIL_PAGE_URL"])
6398 .$this->formatXMLNode(2, GetMessage("IBLOCK_XML2_BX_SECTION_URL"), $this->arIBlock["SECTION_PAGE_URL"])
6399 .$this->formatXMLNode(2, GetMessage("IBLOCK_XML2_BX_CANONICAL_URL"), $this->arIBlock["CANONICAL_PAGE_URL"])
6400 .$this->formatXMLNode(2, GetMessage("IBLOCK_XML2_BX_PICTURE"), $this->ExportFile($this->arIBlock["PICTURE"]))
6401 .$this->formatXMLNode(2, GetMessage("IBLOCK_XML2_BX_INDEX_ELEMENTS"), ($this->arIBlock["INDEX_ELEMENT"]=="Y"? "true": "false"))
6402 .$this->formatXMLNode(2, GetMessage("IBLOCK_XML2_BX_INDEX_SECTIONS"), ($this->arIBlock["INDEX_SECTION"]=="Y"? "true": "false"))
6403 .$this->formatXMLNode(2, GetMessage("IBLOCK_XML2_BX_WORKFLOW"), ($this->arIBlock["WORKFLOW"]=="Y"? "true": "false"))
6404 );
6405
6406 fwrite($this->fp, "\t\t<".GetMessage("IBLOCK_XML2_LABELS").">\n");
6407 $arLabels = CIBlock::GetMessages($this->arIBlock["ID"]);
6408 foreach($arLabels as $id => $label)
6409 {
6410 fwrite($this->fp, $this->formatXMLNode(3, GetMessage("IBLOCK_XML2_LABEL"), array(
6411 GetMessage("IBLOCK_XML2_ID") => $id,
6412 GetMessage("IBLOCK_XML2_VALUE") => $label,
6413 )));
6414 }
6415 fwrite($this->fp, "\t\t</".GetMessage("IBLOCK_XML2_LABELS").">\n");
6416
6417 $iblockTemplates = new \Bitrix\Iblock\InheritedProperty\IblockTemplates($this->arIBlock["ID"]);
6418 $this->exportInheritedTemplates(2, $iblockTemplates);
6419 }
6420 }
6421
6422 if($with_metadata || $this->only_price)
6423 {
6424 $this->ExportPrices();
6425 }
6426
6427 if($changes_only)
6428 fwrite($this->fp, $this->formatXMLNode(2, GetMessage("IBLOCK_XML2_UPDATE_ONLY"), "true"));
6429
6430 if($this->next_step["catalog"])
6431 fwrite($this->fp, "\t\t<".GetMessage("IBLOCK_XML2_OFFERS").">\n");
6432 else
6433 fwrite($this->fp, "\t\t<".GetMessage("IBLOCK_XML2_POSITIONS").">\n");
6434 }
6435
6436 function ExportPropertyValue($xml_id, $value, $type = null)
6437 {
6438 fwrite($this->fp, $this->formatXMLNode(5, GetMessage("IBLOCK_XML2_PROPERTY_VALUES"), array(
6439 GetMessage("IBLOCK_XML2_ID") => $xml_id,
6440 GetMessage("IBLOCK_XML2_VALUE") => $value,
6441 (isset($type)? GetMessage("IBLOCK_XML2_TYPE"): "") => $type,
6442 )));
6443 }
6444
6446 {
6447 $templates = $template->get();
6448 if (!empty($templates))
6449 {
6450 $ws = str_repeat("\t", $level);
6451 fwrite($this->fp, $ws."<".GetMessage("IBLOCK_XML2_INHERITED_TEMPLATES").">\n");
6452 foreach ($templates as $CODE => $TEMPLATE)
6453 {
6454 fwrite($this->fp, $ws."\t<".GetMessage("IBLOCK_XML2_TEMPLATE").">\n");
6455 fwrite($this->fp, $ws."\t\t<".GetMessage("IBLOCK_XML2_ID").">".htmlspecialcharsbx($CODE)."</".GetMessage("IBLOCK_XML2_ID").">\n");
6456 fwrite($this->fp, $ws."\t\t<".GetMessage("IBLOCK_XML2_VALUE").">".htmlspecialcharsbx($TEMPLATE["TEMPLATE"])."</".GetMessage("IBLOCK_XML2_VALUE").">\n");
6457 fwrite($this->fp, $ws."\t</".GetMessage("IBLOCK_XML2_TEMPLATE").">\n");
6458 }
6459 fwrite($this->fp, $ws."</".GetMessage("IBLOCK_XML2_INHERITED_TEMPLATES").">\n");
6460 }
6461 }
6462
6468 function preparePropertiesValues($arElement, $arFilter=array("ACTIVE"=>"Y"))
6469 {
6470 $arPropOrder = array(
6471 "sort" => "asc",
6472 "id" => "asc",
6473 "enum_sort" => "asc",
6474 "value_id" => "asc",
6475 );
6476
6477 $rsProps = CIBlockElement::GetProperty($this->arIBlock["ID"], $arElement["ID"], $arPropOrder, $arFilter);
6478 $arProps = array();
6479 while($arProp = $rsProps->Fetch())
6480 {
6481 $pid = $arProp["ID"];
6482 if(!array_key_exists($pid, $arProps))
6483 $arProps[$pid] = array(
6484 "PROPERTY_TYPE" => $arProp["PROPERTY_TYPE"],
6485 "LINK_IBLOCK_ID" => $arProp["LINK_IBLOCK_ID"],
6486 "VALUES" => array(),
6487 );
6488
6489 if($arProp["PROPERTY_TYPE"] == "L")
6490 $arProps[$pid]["VALUES"][] = array(
6491 "VALUE" => $arProp["VALUE_ENUM"],
6492 "DESCRIPTION" => $arProp["DESCRIPTION"],
6493 "VALUE_ENUM_ID" => $arProp["VALUE"],
6494 );
6495 else
6496 $arProps[$pid]["VALUES"][] = array(
6497 "VALUE" => $arProp["VALUE"],
6498 "DESCRIPTION" => $arProp["DESCRIPTION"],
6499 "VALUE_ENUM_ID" => $arProp["VALUE_ENUM_ID"],
6500 );
6501 }
6502
6503 return $arProps;
6504 }
6505
6506 function exportElementProperties($arElement, $PROPERTY_MAP)
6507 {
6508 if($this->bExtended)
6509 {
6510 $this->ExportPropertyValue("CML2_ACTIVE", ($arElement["ACTIVE"]=="Y"? "true": "false"));
6511 $this->ExportPropertyValue("CML2_CODE", $arElement["CODE"]);
6512 $this->ExportPropertyValue("CML2_SORT", intval($arElement["SORT"]));
6513 $this->ExportPropertyValue("CML2_ACTIVE_FROM", CDatabase::FormatDate($arElement["ACTIVE_FROM"], CLang::GetDateFormat("FULL"), "YYYY-MM-DD HH:MI:SS"));
6514 $this->ExportPropertyValue("CML2_ACTIVE_TO", CDatabase::FormatDate($arElement["ACTIVE_TO"], CLang::GetDateFormat("FULL"), "YYYY-MM-DD HH:MI:SS"));
6515 $this->ExportPropertyValue("CML2_PREVIEW_TEXT", $arElement["PREVIEW_TEXT"], $arElement["PREVIEW_TEXT_TYPE"]);
6516 $this->ExportPropertyValue("CML2_DETAIL_TEXT", $arElement["DETAIL_TEXT"], $arElement["DETAIL_TEXT_TYPE"]);
6517 $this->ExportPropertyValue("CML2_PREVIEW_PICTURE", $this->ExportFile($arElement["PREVIEW_PICTURE"]));
6518 }
6519
6520 $arProps = $this->preparePropertiesValues($arElement);
6521
6522 foreach($arProps as $pid => $arProp)
6523 {
6524 $bEmpty = true;
6525
6526 if($this->next_step["catalog"] && !$this->bExtended)
6527 fwrite($this->fp, "\t\t\t\t\t<".GetMessage("IBLOCK_XML2_ITEM_ATTRIBUTE").">\n");
6528 else
6529 fwrite($this->fp, "\t\t\t\t\t<".GetMessage("IBLOCK_XML2_PROPERTY_VALUES").">\n");
6530
6531 if($this->next_step["catalog"] && !$this->bExtended)
6532 fwrite($this->fp, "\t\t\t\t\t\t<".GetMessage("IBLOCK_XML2_NAME").">".htmlspecialcharsbx($PROPERTY_MAP["~".$pid])."</".GetMessage("IBLOCK_XML2_NAME").">\n");
6533 else
6534 fwrite($this->fp, "\t\t\t\t\t\t<".GetMessage("IBLOCK_XML2_ID").">".htmlspecialcharsbx($PROPERTY_MAP[$pid])."</".GetMessage("IBLOCK_XML2_ID").">\n");
6535
6536 foreach($arProp["VALUES"] as $arValue)
6537 {
6538 $value = $arValue["VALUE"];
6539 if(is_array($value) || (string)$value != '')
6540 {
6541 $bEmpty = false;
6542 $bSerialized = false;
6543 $this->preparePropertyValue($arProp, $arValue, $value, $bSerialized);
6544 fwrite($this->fp, $this->formatXMLNode(6, GetMessage("IBLOCK_XML2_VALUE"), $value));
6545 if($this->bExtended)
6546 {
6547 fwrite($this->fp, "\t\t\t\t\t\t<".GetMessage("IBLOCK_XML2_PROPERTY_VALUE").">\n");
6548 if($bSerialized)
6549 fwrite($this->fp, "\t\t\t\t\t\t\t<".GetMessage("IBLOCK_XML2_SERIALIZED").">true</".GetMessage("IBLOCK_XML2_SERIALIZED").">\n");
6550 fwrite($this->fp, $this->formatXMLNode(7, GetMessage("IBLOCK_XML2_VALUE"), $value));
6551 fwrite($this->fp, "\t\t\t\t\t\t\t<".GetMessage("IBLOCK_XML2_DESCRIPTION").">".htmlspecialcharsbx($arValue["DESCRIPTION"])."</".GetMessage("IBLOCK_XML2_DESCRIPTION").">\n");
6552 fwrite($this->fp, "\t\t\t\t\t\t</".GetMessage("IBLOCK_XML2_PROPERTY_VALUE").">\n");
6553 }
6554 }
6555 }
6556
6557 if($bEmpty)
6558 fwrite($this->fp, "\t\t\t\t\t\t<".GetMessage("IBLOCK_XML2_VALUE")."></".GetMessage("IBLOCK_XML2_VALUE").">\n");
6559
6560 if($this->next_step["catalog"] && !$this->bExtended)
6561 fwrite($this->fp, "\t\t\t\t\t</".GetMessage("IBLOCK_XML2_ITEM_ATTRIBUTE").">\n");
6562 else
6563 fwrite($this->fp, "\t\t\t\t\t</".GetMessage("IBLOCK_XML2_PROPERTY_VALUES").">\n");
6564 }
6565 }
6566
6567 function preparePropertyValue($arProp, $arValue, &$value, &$bSerialized)
6568 {
6569 if($this->bExtended)
6570 {
6571 if($arProp["PROPERTY_TYPE"]=="L")
6572 {
6573 $value = CIBlockPropertyEnum::GetByID($arValue["VALUE_ENUM_ID"]);
6574 $value = $value["XML_ID"];
6575 }
6576 elseif($arProp["PROPERTY_TYPE"]=="F")
6577 {
6578 $value = $this->ExportFile($value);
6579 }
6580 elseif($arProp["PROPERTY_TYPE"]=="G")
6581 {
6582 $value = $this->GetSectionXML_ID($arProp["LINK_IBLOCK_ID"], $value);
6583 }
6584 elseif($arProp["PROPERTY_TYPE"]=="E")
6585 {
6586 $value = $this->GetElementXML_ID($arProp["LINK_IBLOCK_ID"], $value);
6587 }
6588
6589 if(is_array($value) && $arProp["PROPERTY_TYPE"]!=="F")
6590 {
6591 $bSerialized = true;
6592 $value = serialize($value);
6593 }
6594 }
6595 }
6596
6597 function exportElementFields($arElement, $SECTION_MAP)
6598 {
6599 fwrite($this->fp, "\t\t\t\t<".GetMessage("IBLOCK_XML2_NAME").">".htmlspecialcharsbx($arElement["NAME"])."</".GetMessage("IBLOCK_XML2_NAME").">\n");
6600 if($this->bExtended)
6601 fwrite($this->fp, "\t\t\t\t<".GetMessage("IBLOCK_XML2_BX_TAGS").">".htmlspecialcharsbx($arElement["TAGS"])."</".GetMessage("IBLOCK_XML2_BX_TAGS").">\n");
6602
6603 $arSections = array();
6604 $rsSections = CIBlockElement::GetElementGroups($arElement["ID"], true);
6605 while($arSection = $rsSections->Fetch())
6606 if(array_key_exists($arSection["ID"], $SECTION_MAP))
6607 $arSections[] = $SECTION_MAP[$arSection["ID"]];
6608
6609 fwrite($this->fp, "\t\t\t\t<".GetMessage("IBLOCK_XML2_GROUPS").">\n");
6610 foreach($arSections as $xml_id)
6611 fwrite($this->fp, "\t\t\t\t\t<".GetMessage("IBLOCK_XML2_ID").">".htmlspecialcharsbx($xml_id)."</".GetMessage("IBLOCK_XML2_ID").">\n");
6612 fwrite($this->fp, "\t\t\t\t</".GetMessage("IBLOCK_XML2_GROUPS").">\n");
6613
6614 if(!$this->bExtended)
6615 fwrite($this->fp, "\t\t\t\t<".GetMessage("IBLOCK_XML2_DESCRIPTION").">".htmlspecialcharsbx(FormatText($arElement["DETAIL_TEXT"], $arElement["DETAIL_TEXT_TYPE"]))."</".GetMessage("IBLOCK_XML2_DESCRIPTION").">\n");
6616
6617 fwrite($this->fp, $this->formatXMLNode(4, GetMessage("IBLOCK_XML2_PICTURE"), $this->ExportFile($arElement["DETAIL_PICTURE"])));
6618 }
6619
6620 function aliasXmlId($xml_id)
6621 {
6622 return '';
6623 }
6624
6625 function exportElement($arElement, $SECTION_MAP, $PROPERTY_MAP)
6626 {
6627 if($arElement["XML_ID"] <> '')
6628 $xml_id = $arElement["XML_ID"];
6629 else
6630 $xml_id = $arElement["ID"];
6631
6632 if($this->PRODUCT_IBLOCK_ID > 0)
6633 {
6634 $arPropOrder = array(
6635 "sort" => "asc",
6636 "id" => "asc",
6637 "enum_sort" => "asc",
6638 "value_id" => "asc",
6639 );
6640 $rsLink = CIBlockElement::GetProperty($this->arIBlock["ID"], $arElement["ID"], $arPropOrder, array("ACTIVE"=>"Y", "CODE" => "CML2_LINK"));
6641 $arLink = $rsLink->Fetch();
6642 if(is_array($arLink) && !is_array($arLink["VALUE"]) && $arLink["VALUE"] > 0)
6643 {
6644 $parent_xml_id = $this->GetElementXML_ID($this->PRODUCT_IBLOCK_ID, $arLink["VALUE"]);
6645 if ($parent_xml_id === $xml_id)
6646 $xml_id = $parent_xml_id;
6647 else
6648 {
6649 [$productXmlId, $offerXmlId] = explode("#", $xml_id, 2);
6650 if ($productXmlId !== $parent_xml_id)
6651 $xml_id = $parent_xml_id."#".$xml_id;
6652 }
6653 }
6654 }
6655
6656 fwrite($this->fp, "\t\t\t\t<".GetMessage("IBLOCK_XML2_ID").">".htmlspecialcharsbx($xml_id)."</".GetMessage("IBLOCK_XML2_ID").">\n");
6657
6658 if(($aliasXmlId = $this->aliasXmlId($xml_id))>0)
6659 fwrite($this->fp, $aliasXmlId);
6660
6661 if(!$this->only_price)
6662 {
6663 $this->exportElementFields($arElement, $SECTION_MAP);
6664
6665 if($this->next_step["catalog"] && !$this->bExtended)
6666 fwrite($this->fp, "\t\t\t\t<".GetMessage("IBLOCK_XML2_ITEM_ATTRIBUTES").">\n");
6667 else
6668 fwrite($this->fp, "\t\t\t\t<".GetMessage("IBLOCK_XML2_PROPERTIES_VALUES").">\n");
6669
6670 $this->exportElementProperties($arElement, $PROPERTY_MAP);
6671
6672 if($this->next_step["catalog"] && !$this->bExtended)
6673 fwrite($this->fp, "\t\t\t\t</".GetMessage("IBLOCK_XML2_ITEM_ATTRIBUTES").">\n");
6674 else
6675 fwrite($this->fp, "\t\t\t\t</".GetMessage("IBLOCK_XML2_PROPERTIES_VALUES").">\n");
6676
6677 if($this->bExtended)
6678 {
6679 $elementTemplates = new \Bitrix\Iblock\InheritedProperty\ElementTemplates($this->arIBlock["ID"], $arElement["ID"]);
6680 $this->exportInheritedTemplates(4, $elementTemplates);
6681 }
6682 }
6683
6684 if($this->next_step["catalog"])
6685 {
6686 static $measure = null;
6687 if (!isset($measure))
6688 {
6689 $measure = array();
6690 $rsBaseUnit = CCatalogMeasure::GetList(array(), array());
6691 while($arIDUnit = $rsBaseUnit->Fetch())
6692 $measure[$arIDUnit["ID"]] = $arIDUnit["CODE"];
6693 }
6694
6695 static $systemFieldTypes = null;
6696 if (!isset($systemFieldTypes))
6697 {
6698 $systemFieldTypes = [];
6699 if (Product\SystemField\MarkingCodeGroup::isAllowed())
6700 {
6701 $systemFieldTypes[Product\SystemField\MarkingCodeGroup::FIELD_ID] = array_fill_keys(
6702 Product\SystemField\MarkingCodeGroup::getAllowedProductTypeList(),
6703 true
6704 );
6705 }
6706 if (Product\SystemField\ProductMapping::isAllowed())
6707 {
6708 $systemFieldTypes[Product\SystemField\ProductMapping::FIELD_ID] = array_fill_keys(
6709 Product\SystemField\ProductMapping::getAllowedProductTypeList(),
6710 true
6711 );
6712 }
6713 }
6714
6715 //TODO: change this code after refactoring product system fields
6716 $selectFields = ['ID', 'MEASURE', 'QUANTITY', 'TYPE', 'WIDTH', 'LENGTH', 'HEIGHT'];
6717 $productSystemFields = Catalog\Product\SystemField::getExportSelectFields();
6718
6719 $selectFields = array_merge($selectFields, $productSystemFields);
6721 'select' => $selectFields,
6722 'filter' => ['=ID' => $arElement['ID']]
6723 ]);
6724 $row = $iterator->fetch();
6725 unset($iterator);
6726 if (!empty($row) && is_array($row))
6727 {
6728 Product\SystemField::prepareRow($row, Product\SystemField::OPERATION_EXPORT);
6729 $row['TYPE'] = (int)$row['TYPE'];
6730
6731 if (
6732 isset($systemFieldTypes[Product\SystemField\MarkingCodeGroup::FIELD_ID])
6733 && isset($systemFieldTypes[Product\SystemField\MarkingCodeGroup::FIELD_ID][$row['TYPE']])
6734 )
6735 {
6736 fwrite(
6737 $this->fp,
6738 "\t\t\t\t<".GetMessage("IBLOCK_XML2_MARKING_CODE_GROUP").">"
6739 .htmlspecialcharsbx((string)$row[Product\SystemField\MarkingCodeGroup::FIELD_ID])
6740 ."</".GetMessage("IBLOCK_XML2_MARKING_CODE_GROUP").">\n"
6741 );
6742 }
6743 if (
6744 isset($systemFieldTypes[Product\SystemField\ProductMapping::FIELD_ID])
6745 && isset($systemFieldTypes[Product\SystemField\ProductMapping::FIELD_ID][$row['TYPE']])
6746 )
6747 {
6748 fwrite(
6749 $this->fp,
6750 "\t\t\t\t<".GetMessage("IBLOCK_XML2_PRODUCT_MAPPING").">\n"
6751 );
6752 if (
6753 !empty($row[Product\SystemField\ProductMapping::FIELD_ID])
6754 && is_array($row[Product\SystemField\ProductMapping::FIELD_ID])
6755 )
6756 {
6757 foreach ($row[Product\SystemField\ProductMapping::FIELD_ID] as $value)
6758 {
6759 fwrite(
6760 $this->fp,
6761 "\t\t\t\t\t<".GetMessage('IBLOCK_XML2_ID').">"
6762 .htmlspecialcharsbx($value)
6763 ."</".GetMessage('IBLOCK_XML2_ID').">\n"
6764 );
6765 }
6766 }
6767 fwrite(
6768 $this->fp,
6769 "\t\t\t\t</".GetMessage("IBLOCK_XML2_PRODUCT_MAPPING").">\n"
6770 );
6771 }
6772
6773 if (
6774 $row['TYPE'] == Catalog\ProductTable::TYPE_PRODUCT
6775 || $row['TYPE'] == Catalog\ProductTable::TYPE_SET
6776 || $row['TYPE'] == Catalog\ProductTable::TYPE_OFFER
6777 || (
6778 $row['TYPE'] == Catalog\ProductTable::TYPE_SKU
6779 && Main\Config\Option::get('catalog', 'show_catalog_tab_with_offers') === 'Y'
6780 )
6781 )
6782 {
6783 $row['MEASURE'] = (int)$row['MEASURE'];
6784 $xmlMeasure = GetMessage("IBLOCK_XML2_PCS");
6785 if ($row["MEASURE"] > 0 && isset($measure[$row["MEASURE"]]))
6786 $xmlMeasure = $measure[$row["MEASURE"]];
6787
6788 $arPrices = [];
6789 $rsPrices = Catalog\PriceTable::getList([
6790 'select' => ['ID', 'CATALOG_GROUP_ID', 'PRICE', 'CURRENCY', 'QUANTITY_FROM', 'QUANTITY_TO'],
6791 'filter' => ['=PRODUCT_ID' => $arElement['ID']]
6792 ]);
6793 while($arPrice = $rsPrices->fetch())
6794 {
6795 $arPrices[] = [
6796 GetMessage("IBLOCK_XML2_PRICE_TYPE_ID") => $this->prices[$arPrice["CATALOG_GROUP_ID"]],
6797 GetMessage("IBLOCK_XML2_PRICE_FOR_ONE") => $arPrice["PRICE"],
6798 GetMessage("IBLOCK_XML2_CURRENCY") => $arPrice["CURRENCY"],
6799 GetMessage("IBLOCK_XML2_MEASURE") => $xmlMeasure,
6800 GetMessage("IBLOCK_XML2_QUANTITY_FROM") => $arPrice["QUANTITY_FROM"],
6801 GetMessage("IBLOCK_XML2_QUANTITY_TO") => $arPrice["QUANTITY_TO"],
6802 ];
6803 }
6804 unset($arPrice);
6805 unset($rsPrices);
6806 if (!empty($arPrices))
6807 {
6808 fwrite($this->fp, "\t\t\t\t<".GetMessage("IBLOCK_XML2_PRICES").">\n");
6809 foreach($arPrices as $arPrice)
6810 {
6811 fwrite($this->fp, "\t\t\t\t\t<".GetMessage("IBLOCK_XML2_PRICE").">\n");
6812 foreach($arPrice as $key=>$value)
6813 {
6814 fwrite($this->fp, "\t\t\t\t\t\t<".$key.">".htmlspecialcharsbx($value)."</".$key.">\n");
6815 }
6816 fwrite($this->fp, "\t\t\t\t\t</".GetMessage("IBLOCK_XML2_PRICE").">\n");
6817 }
6818 fwrite($this->fp, "\t\t\t\t</".GetMessage("IBLOCK_XML2_PRICES").">\n");
6819 }
6820 unset($arPrices);
6821 if ($row['TYPE'] != Catalog\ProductTable::TYPE_SET)
6822 {
6823 fwrite(
6824 $this->fp,
6825 "\t\t\t\t<".GetMessage("IBLOCK_XML2_AMOUNT").">"
6826 .htmlspecialcharsbx($row["QUANTITY"])
6827 ."</".GetMessage("IBLOCK_XML2_AMOUNT").">\n"
6828 );
6829 }
6830 fwrite(
6831 $this->fp,
6832 "\t\t\t\t<".GetMessage("IBLOCK_XML2_BASE_UNIT").">"
6833 .htmlspecialcharsbx($xmlMeasure)
6834 ."</".GetMessage("IBLOCK_XML2_BASE_UNIT").">\n"
6835 );
6836 fwrite(
6837 $this->fp,
6838 "\t\t\t\t<".GetMessage("IBLOCK_XML2_WIDTH").">"
6839 .htmlspecialcharsbx($row["WIDTH"])
6840 ."</".GetMessage("IBLOCK_XML2_WIDTH").">\n"
6841 );
6842 fwrite(
6843 $this->fp,
6844 "\t\t\t\t<".GetMessage("IBLOCK_XML2_LENGTH").">"
6845 .htmlspecialcharsbx($row["LENGTH"])
6846 ."</".GetMessage("IBLOCK_XML2_LENGTH").">\n"
6847 );
6848 fwrite(
6849 $this->fp,
6850 "\t\t\t\t<".GetMessage("IBLOCK_XML2_HEIGHT").">"
6851 .htmlspecialcharsbx($row["HEIGHT"])
6852 ."</".GetMessage("IBLOCK_XML2_HEIGHT").">\n"
6853 );
6854 }
6855 }
6856 unset($row);
6857 }
6858 }
6859
6860 function ExportElements($PROPERTY_MAP, $SECTION_MAP, $start_time, $INTERVAL, $counter_limit = 0, $arElementFilter = false)
6861 {
6862 $counter = 0;
6863 $arSelect = array(
6864 "ID",
6865 "IBLOCK_ID",
6866 "XML_ID",
6867 "ACTIVE",
6868 "CODE",
6869 "NAME",
6870 "PREVIEW_TEXT",
6871 "PREVIEW_TEXT_TYPE",
6872 "ACTIVE_FROM",
6873 "ACTIVE_TO",
6874 "SORT",
6875 "TAGS",
6876 "DETAIL_TEXT",
6877 "DETAIL_TEXT_TYPE",
6878 "PREVIEW_PICTURE",
6879 "DETAIL_PICTURE",
6880 );
6881
6882 if(is_array($arElementFilter))
6883 {
6884 $arFilter = $arElementFilter;
6885 }
6886 else
6887 {
6888 if($arElementFilter === "none")
6889 return 0;
6890 $arFilter = array (
6891 "IBLOCK_ID"=> $this->arIBlock["ID"],
6892 "ACTIVE" => "Y",
6893 ">ID" => $this->next_step["LAST_ID"] ?? 0,
6894 );
6895 if($arElementFilter === "all")
6896 unset($arFilter["ACTIVE"]);
6897 }
6898
6899 $arOrder = array(
6900 "ID" => "ASC",
6901 );
6902
6903 $rsElements = CIBlockElement::GetList($arOrder, $arFilter, false, false, $arSelect);
6904 while($arElement = $rsElements->Fetch())
6905 {
6906 if($this->next_step["catalog"])
6907 fwrite($this->fp, "\t\t\t<".GetMessage("IBLOCK_XML2_OFFER").">\n");
6908 else
6909 fwrite($this->fp, "\t\t\t<".GetMessage("IBLOCK_XML2_POSITION").">\n");
6910
6911 $this->exportElement($arElement, $SECTION_MAP, $PROPERTY_MAP);
6912
6913 if($this->next_step["catalog"])
6914 fwrite($this->fp, "\t\t\t</".GetMessage("IBLOCK_XML2_OFFER").">\n");
6915 else
6916 fwrite($this->fp, "\t\t\t</".GetMessage("IBLOCK_XML2_POSITION").">\n");
6917
6918 $this->next_step["LAST_ID"] = $arElement["ID"];
6919 $counter++;
6920 if($INTERVAL > 0 && (time()-$start_time) > $INTERVAL)
6921 break;
6922 if($counter_limit > 0 && ($counter >= $counter_limit))
6923 break;
6924 }
6925 return $counter;
6926 }
6927
6929 {
6930 if($this->next_step["catalog"])
6931 {
6932 fwrite($this->fp, "\t\t</".GetMessage("IBLOCK_XML2_OFFERS").">\n");
6933 fwrite($this->fp, "\t</".GetMessage("IBLOCK_XML2_OFFER_LIST").">\n");
6934 }
6935 else
6936 {
6937 fwrite($this->fp, "\t\t</".GetMessage("IBLOCK_XML2_POSITIONS").">\n");
6938 fwrite($this->fp, "\t</".GetMessage("IBLOCK_XML2_CATALOG").">\n");
6939 }
6940 }
6941
6942 function ExportProductSet($elementId, $elementXml)
6943 {
6945 if (is_array($arSetItems) && !empty($arSetItems))
6946 {
6947 fwrite($this->fp, "\t\t<".GetMessage("IBLOCK_XML2_PRODUCT_SETS").">\n");
6948 fwrite($this->fp, "\t\t\t<".GetMessage("IBLOCK_XML2_ID").">".htmlspecialcharsbx($elementXml)."</".GetMessage("IBLOCK_XML2_ID").">\n");
6949 foreach ($arSetItems as $arOneSet)
6950 {
6951 fwrite($this->fp, "\t\t\t<".GetMessage("IBLOCK_XML2_PRODUCT_SET").">\n");
6952 if (is_array($arOneSet["ITEMS"]) && !empty($arOneSet["ITEMS"]))
6953 {
6954 foreach ($arOneSet["ITEMS"] as $setItem)
6955 {
6956 $xmlId = $this->GetElementXML_ID($this->arIBlock["ID"], $setItem["ITEM_ID"]);
6957 if ($xmlId !== false)
6958 {
6959 fwrite($this->fp, "\t\t\t\t<".GetMessage("IBLOCK_XML2_PRODUCT_SET_ITEM").">\n");
6960 fwrite($this->fp, "\t\t\t\t\t<".GetMessage("IBLOCK_XML2_VALUE").">".htmlspecialcharsbx($xmlId)."</".GetMessage("IBLOCK_XML2_VALUE").">\n");
6961 fwrite($this->fp, "\t\t\t\t\t<".GetMessage("IBLOCK_XML2_AMOUNT").">".intval($setItem["QUANTITY"])."</".GetMessage("IBLOCK_XML2_AMOUNT").">\n");
6962 fwrite($this->fp, "\t\t\t\t\t<".GetMessage("IBLOCK_XML2_SORT").">".intval($setItem["SORT"])."</".GetMessage("IBLOCK_XML2_SORT").">\n");
6963 fwrite($this->fp, "\t\t\t\t</".GetMessage("IBLOCK_XML2_PRODUCT_SET_ITEM").">\n");
6964 }
6965 }
6966 }
6967 fwrite($this->fp, "\t\t\t</".GetMessage("IBLOCK_XML2_PRODUCT_SET").">\n");
6968 }
6969 fwrite($this->fp, "\t\t</".GetMessage("IBLOCK_XML2_PRODUCT_SETS").">\n");
6970 }
6971 }
6972
6974 {
6975 if ($this->next_step["catalog"] && $this->bExtended)
6976 {
6977 unset($this->next_step["FILTER"][">ID"]);
6978 $rsElements = CIBlockElement::GetList(array(), $this->next_step["FILTER"], false, false, array("ID", "XML_ID"));
6979
6980 fwrite($this->fp, "\t<".GetMessage("IBLOCK_XML2_PRODUCTS_SETS").">\n");
6981 while($arElement = $rsElements->Fetch())
6982 {
6984 {
6985 if($arElement["XML_ID"] <> '')
6986 $xml_id = $arElement["XML_ID"];
6987 else
6988 $xml_id = $arElement["ID"];
6989
6990 $this->ExportProductSet($arElement["ID"], $xml_id);
6991 }
6992 }
6993 fwrite($this->fp, "\t</".GetMessage("IBLOCK_XML2_PRODUCTS_SETS").">\n");
6994 }
6995
6996 }
6997
6998 function EndExport()
6999 {
7000 fwrite($this->fp, "</".GetMessage("IBLOCK_XML2_COMMERCE_INFO").">\n");
7001 }
7002}
7003/*
7004GetMessage("IBLOCK_XML2_COEFF")
7005GetMessage("IBLOCK_XML2_OWNER")
7006GetMessage("IBLOCK_XML2_TITLE")
7007GetMessage("IBLOCK_XML2_VALUES_TYPE")
7008GetMessage("IBLOCK_XML2_VIEW")
7009*/
if(isset( $_REQUEST["mode"]) &&$_REQUEST["mode"]=="ajax") if(isset($_REQUEST["mode"]) && $_REQUEST["mode"]=="save_lru" &&check_bitrix_sessid()) $first
Определения access_dialog.php:54
$type
Определения options.php:106
global $APPLICATION
Определения include.php:80
$catalogData
Определения options.php:2236
$arResult
Определения generate_coupon.php:16
$boolFlag
Определения generate_coupon.php:21
static getTypeList()
Определения group.php:273
static update($id, array $data)
Определения entity.php:229
static getList(array $parameters)
Определения entity.php:78
static add(array $data)
Определения entity.php:150
static delete($id)
Определения entity.php:317
static getCacheItem($id, bool $load=false)
Определения entity.php:396
static enableDeferredCalculation()
Определения sku.php:87
static disableDeferredCalculation()
Определения sku.php:97
static calculate()
Определения sku.php:450
const TYPE_SET
Определения product.php:71
const TYPE_SKU
Определения product.php:72
const TYPE_OFFER
Определения product.php:73
const TYPE_PRODUCT
Определения product.php:70
static add(array $data)
Определения highloadblocktable.php:105
static disableDeferredIndexing()
Определения manager.php:300
static updateElementIndex($iblockId, $elementId)
Определения manager.php:264
static runDeferredIndexing($iblockId)
Определения manager.php:321
static enableDeferredIndexing()
Определения manager.php:290
const TYPE_FILE
Определения propertytable.php:67
const TYPE_LIST
Определения propertytable.php:70
static get($moduleId, $name, $default="", $siteId=false)
Определения option.php:30
static normalize($path)
Определения path.php:22
static combine(... $args)
Определения path.php:254
Определения loader.php:13
static includeModule($moduleName)
Определения loader.php:67
static loadLanguageFile($file, $language=null, $normalize=true)
Определения loc.php:225
static isModuleInstalled($moduleName)
Определения modulemanager.php:125
static getList(array $parameters=array())
Определения datamanager.php:431
static convertEncoding($data, $charsetFrom, $charsetTo)
Определения encoding.php:17
static GetListArray()
Определения cataloggroup.php:291
static Add($arFields)
Определения currency.php:279
CancelWFSetMove()
Определения iblockelement.php:181
Update($ID, $arFields)
Определения iblock.php:1146
static Add($arFields)
Определения cataloggroup.php:9
static Update($ID, $arFields)
Определения cataloggroup.php:82
Определения catalog.php:6
static GetList($arOrder=array(), $arFilter=array(), $arGroupBy=false, $arNavStartParams=false, $arSelectFields=array())
Определения catalog.php:15
static deleteAllSetsByProduct($intProductID, $intSetType)
Определения product_set.php:169
const TYPE_GROUP
Определения product_set.php:10
static getAllSetsByProduct($intProductID, $intSetType)
Определения product_set.php:341
static isProductHaveSet($arProductID, $intSetType=0)
Определения product_set.php:313
static add($arFields)
Определения product_set.php:10
static FindBucketByFile($file_name)
Определения storage.php:1650
static URN2URI($urn, $server_name='')
Определения http.php:39
Определения cml2.php:5621
ExportPropertyValue($xml_id, $value, $type=null)
Определения cml2.php:6436
$file_dir
Определения cml2.php:5626
GetIBlockXML_ID($IBLOCK_ID, $XML_ID=false)
Определения cml2.php:5698
$bExtended
Определения cml2.php:5624
ExportFile($FILE_ID)
Определения cml2.php:5805
$export_as_url
Определения cml2.php:5634
$fp
Определения cml2.php:5622
ExportSectionsProperties($arUserFields)
Определения cml2.php:5895
$IBLOCK_ID
Определения cml2.php:5623
formatXMLNode($level, $tagName, $value)
Определения cml2.php:5864
ExportEnum($arUserField, $value)
Определения cml2.php:5849
GetSectionXML_ID($IBLOCK_ID, $SECTION_ID, $XML_ID=false)
Определения cml2.php:5730
DoNotDownloadCloudFiles()
Определения cml2.php:5683
$prices
Определения cml2.php:5631
ExportFileAsURL()
Определения cml2.php:5693
ExportProductSets()
Определения cml2.php:6973
NotCatalog()
Определения cml2.php:5688
EndExportMetadata()
Определения cml2.php:6363
$next_step
Определения cml2.php:5628
exportElementProperties($arElement, $PROPERTY_MAP)
Определения cml2.php:6506
ExportPrices()
Определения cml2.php:6341
$download_files
Определения cml2.php:5633
$PRODUCT_IBLOCK_ID
Определения cml2.php:5635
aliasXmlId($xml_id)
Определения cml2.php:6620
preparePropertiesValues($arElement, $arFilter=array("ACTIVE"=>"Y"))
Определения cml2.php:6468
preparePropertyValue($arProp, $arValue, &$value, &$bSerialized)
Определения cml2.php:6567
StartExportCatalog($with_metadata=true, $changes_only=false)
Определения cml2.php:6368
exportElement($arElement, $SECTION_MAP, $PROPERTY_MAP)
Определения cml2.php:6625
Init($fp, $IBLOCK_ID, $next_step, $bExtended=false, $work_dir=false, $file_dir=false, $bCheckPermissions=true, $PRODUCT_IBLOCK_ID=false)
Определения cml2.php:5637
GetPropertyXML_ID($IBLOCK_ID, $NAME, $PROPERTY_ID, $XML_ID)
Определения cml2.php:5782
exportElementFields($arElement, $SECTION_MAP)
Определения cml2.php:6597
$work_dir
Определения cml2.php:5625
$only_price
Определения cml2.php:5632
EndExport()
Определения cml2.php:6998
exportInheritedTemplates($level, \Bitrix\Iblock\InheritedProperty\BaseTemplate $template)
Определения cml2.php:6445
ExportElements($PROPERTY_MAP, $SECTION_MAP, $start_time, $INTERVAL, $counter_limit=0, $arElementFilter=false)
Определения cml2.php:6860
StartExport()
Определения cml2.php:5799
ExportProperties(&$PROPERTY_MAP)
Определения cml2.php:6083
ExportProductSet($elementId, $elementXml)
Определения cml2.php:6942
EndExportCatalog()
Определения cml2.php:6928
ExportSmartFilter($level, $iblockId, $sectionId, $PROPERTY_MAP, $productIblockId=0)
Определения cml2.php:6243
GetElementXML_ID($IBLOCK_ID, $ELEMENT_ID, $XML_ID=false)
Определения cml2.php:5756
StartExportMetadata()
Определения cml2.php:5884
$arIBlock
Определения cml2.php:5630
Определения cml2.php:13
GetSectionByXML_ID($IBLOCK_ID, $XML_ID)
Определения cml2.php:509
$preview
Определения cml2.php:28
$iblock_resize
Определения cml2.php:30
$use_iblock_type_id
Определения cml2.php:25
array $productSizes
Определения cml2.php:70
ReadCatalogData(&$SECTION_MAP, &$PRICES_MAP)
Определения cml2.php:2495
$arTempFiles
Определения cml2.php:48
ToFloat($str)
Определения cml2.php:2941
$arFileDescriptionsMap
Определения cml2.php:49
const IBLOCK_CACHE_FINAL
Определения cml2.php:15
$arLinkedProps
Определения cml2.php:52
$use_crc
Определения cml2.php:26
clearIblockCacheAfterFinal()
Определения cml2.php:5499
GetFilePosition()
Определения cml2.php:284
$PROPERTY_MAP
Определения cml2.php:37
ImportPropertyDirectory($arProperty, $arEnumXmlNodes)
Определения cml2.php:2200
isIblockCacheModeNormal()
Определения cml2.php:5524
GetSectionEnumByXML_ID($FIELD_ID, $XML_ID)
Определения cml2.php:573
CheckProperty($IBLOCK_ID, $code, $xml_name)
Определения cml2.php:611
ImportElements($start_time, $interval)
Определения cml2.php:2697
$translit_on_add
Определения cml2.php:54
$force_offers
Определения cml2.php:24
ImportBaseUnits($XML_BASE_UNITS_PARENT)
Определения cml2.php:1563
GetTotalCountElementsForImport()
Определения cml2.php:2667
DeactivateSections($action)
Определения cml2.php:1390
$arElementFiles
Определения cml2.php:51
CheckElementCode($IBLOCK_ID, $ID, $CODE)
Определения cml2.php:5271
ToFloatEmpty($value)
Определения cml2.php:2966
ImportStoresAmount($arElement, $elementID, &$counter)
Определения cml2.php:1655
const IBLOCK_CACHE_NORMAL
Определения cml2.php:17
ImportElementPrices($arXMLElement, &$counter, $arParent=false)
Определения cml2.php:4351
$arTaxCache
Определения cml2.php:45
CheckTax($title, $rate)
Определения cml2.php:654
ToInt($str)
Определения cml2.php:2975
freezeIblockCache()
Определения cml2.php:5452
ConvertDiscounts($arDiscounts)
Определения cml2.php:4839
$translit_on_update
Определения cml2.php:55
$currencyIncluded
Определения cml2.php:68
ImportProperties($XML_PROPERTIES_PARENT, $IBLOCK_ID)
Определения cml2.php:1809
CheckFileByName($file, $fields=null)
Определения cml2.php:382
CreateTemporaryTables()
Определения cml2.php:244
$SECTION_MAP
Определения cml2.php:38
$activeStores
Определения cml2.php:60
GetEnumByXML_ID($PROP_ID, $XML_ID)
Определения cml2.php:550
ImportProductSets()
Определения cml2.php:2838
getPreparedProductFieldsFromArray(array $element)
Определения cml2.php:4314
$currentUserId
Определения cml2.php:66
SectionsResort()
Определения cml2.php:1443
$skip_root_section
Определения cml2.php:57
URLEncode($str)
Определения cml2.php:368
__unserialize_callback($match)
Определения cml2.php:3002
$next_step
Определения cml2.php:21
$mess
Определения cml2.php:46
fillDefaultPropertyValues(&$arElement, $iblockProperties)
Определения cml2.php:4805
$PRICES_MAP
Определения cml2.php:39
$_xml_file
Определения cml2.php:33
GetRoot()
Определения cml2.php:264
getProductFieldsFromXml(array $xmlElement)
Определения cml2.php:4275
$translit_params
Определения cml2.php:56
CheckSites($arSite)
Определения cml2.php:792
$arCurrencyCache
Определения cml2.php:44
CleanTempFiles()
Определения cml2.php:289
static getIblockCacheModeList(bool $description=false)
Определения cml2.php:5430
MakeFileArray($file, $fields=[])
Определения cml2.php:299
SetProductPrice($PRODUCT_ID, $arPrices, $arDiscounts=false)
Определения cml2.php:4876
getActiveStores()
Определения cml2.php:5581
safeTranslit($str)
Определения cml2.php:2919
isIblockCacheModeHit()
Определения cml2.php:5532
$LAST_ERROR
Определения cml2.php:19
ImportSectionPropertyEnum($FIELD_ID, $arEnumXmlNodes)
Определения cml2.php:2367
convertBaseUnitFromXmlToPropertyValue($xmlValue)
Определения cml2.php:3007
DropTemporaryTables()
Определения cml2.php:239
$detail
Определения cml2.php:29
ImportSectionProperties($XML_SECTION_PROPERTIES, $IBLOCK_ID, $SECTION_ID=0)
Определения cml2.php:2437
CheckCurrency($currency)
Определения cml2.php:716
Unserialize($string)
Определения cml2.php:2996
ImportStores($XML_STORES_PARENT)
Определения cml2.php:1590
$iblockCacheMode
Определения cml2.php:62
clearIblockCacheOnHit()
Определения cml2.php:5482
InitEx(&$next_step, $params)
Определения cml2.php:76
StartSession($sess_id)
Определения cml2.php:269
ImportPropertyEnum($arProperty, $arEnumXmlNodes)
Определения cml2.php:2102
IndexTemporaryTables()
Определения cml2.php:254
EndSession()
Определения cml2.php:279
updateCounters(array $counters)
Определения cml2.php:5407
GetIBlockByXML_ID($XML_ID)
Определения cml2.php:495
CheckIBlockType($ID)
Определения cml2.php:756
$arEnumCache
Определения cml2.php:43
$arElementCache
Определения cml2.php:42
isIblockCacheModeFreeze()
Определения cml2.php:5548
CheckIfElementIsActive($arXMLElement)
Определения cml2.php:3044
ImportPrices($XML_PRICES_PARENT, $IBLOCK_ID, $IBLOCK_LID)
Определения cml2.php:1448
GetElementCRC($arElement)
Определения cml2.php:2594
unFreezeIblockCache()
Определения cml2.php:5467
getIblockCacheMode()
Определения cml2.php:5516
ChangeOffersStatus($ELEMENT_ID, $STATUS="Y", $bWF=true)
Определения cml2.php:2885
isIblockCacheModeFinal()
Определения cml2.php:5540
CheckSectionCode($IBLOCK_ID, $ID, $CODE)
Определения cml2.php:5299
$use_offers
Определения cml2.php:23
countTotalQuantity(array $stores)
Определения cml2.php:5606
$files_dir
Определения cml2.php:22
isTemporaryTablesStructureCorrect()
Определения cml2.php:229
Init(&$next_step, $files_dir=false, $use_crc=true, $preview=false, $detail=false, $use_offers=false, $use_iblock_type_id=false, $table_name="b_xml_tree")
Определения cml2.php:135
truncateTemporaryTables()
Определения cml2.php:234
DeactivateElement($action, $start_time, $interval)
Определения cml2.php:5327
$arSectionCache
Определения cml2.php:41
ReadXMLToDatabase($fp, &$NS, $time_limit=0, $read_size=1024)
Определения cml2.php:259
const IBLOCK_CACHE_FREEZE
Определения cml2.php:14
$bCatalog
Определения cml2.php:35
const IBLOCK_CACHE_HIT
Определения cml2.php:16
ImportSections()
Определения cml2.php:1340
isTemporaryTablesExist()
Определения cml2.php:224
GetElementByXML_ID($IBLOCK_ID, $XML_ID)
Определения cml2.php:526
ResizePicture($file, $resize, $primaryField, $secondaryField="")
Определения cml2.php:427
CheckManufacturer($xml)
Определения cml2.php:2618
initializeTemporaryTables()
Определения cml2.php:249
GetSessionRoot()
Определения cml2.php:274
$arElementFilesId
Определения cml2.php:50
$isCatalogIblock
Определения cml2.php:36
static CheckIfFileIsCML($file_name)
Определения cml2.php:197
$disable_change_price_name
Определения cml2.php:58
ImportMetaData($xml_root_id, $IBLOCK_TYPE, $IBLOCK_LID, $bUpdateIBlock=true)
Определения cml2.php:817
getStoreList()
Определения cml2.php:5558
ImportElement($arXMLElement, &$counter, $bWF, $arParent)
Определения cml2.php:3064
GetPropertyByXML_ID($IBLOCK_ID, $XML_ID)
Определения cml2.php:601
$arProperties
Определения cml2.php:40
Определения iblockelement.php:9
static GetList($arOrder=array("SORT"=>"ASC"), $arFilter=array(), $arGroupBy=false, $arNavStartParams=false, $arSelectFields=array())
Определения iblockelement.php:658
Определения iblock.php:9
static GetList($arOrder=Array("SORT"=>"ASC"), $arFilter=Array(), $bIncCnt=false)
Определения iblock.php:13
static Add($arFields)
Определения iblockpropertyenum.php:127
static GetByID($ID)
Определения iblockpropertyenum.php:217
static GetList($arOrder=array("SORT"=>"ASC", "VALUE"=>"ASC"), $arFilter=array())
Определения iblockpropertyenum.php:18
static Update($ID, $arFields)
Определения iblockpropertyenum.php:157
static getPropertyDescription(string $code, array $fields=[])
Определения iblockproptools.php:148
const XML_MORE_PHOTO
Определения iblockproptools.php:27
const XML_SKU_LINK
Определения iblockproptools.php:28
const CODE_MORE_PHOTO
Определения iblockproptools.php:11
const CODE_SKU_LINK
Определения iblockproptools.php:12
Определения iblocksection.php:5
static GetList($arOrder=array("SORT"=>"ASC"), $arFilter=array(), $bIncCnt=false, $arSelect=array(), $arNavStartParams=false)
Определения iblocksection.php:14
Определения iblocktype.php:20
static GetByID($ID)
Определения iblocktype.php:220
Определения cml2.php:10
Определения userfieldenum.php:6
static GetList($aSort=array(), $aFilter=array())
Определения userfieldenum.php:179
Определения user.php:6037
Определения usertype.php:985
static translit($str, $lang, $params=[])
Определения util.php:629
$start_time
Определения clock_selector.php:9
$str
Определения commerceml2.php:63
if(!is_array($prop["VALUES"])) $tmp
Определения component_props.php:203
$arFields
Определения dblapprove.php:5
$data['IS_AVAILABLE']
Определения .description.php:13
$template
Определения file_edit.php:49
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
$res
Определения filter_act.php:7
global $USER_FIELD_MANAGER
Определения attempt.php:6
$result
Определения get_property_values.php:14
if($ajaxMode) $ID
Определения get_user.php:27
$entity
$p
Определения group_list_element_edit.php:23
$elementID
Определения group_wiki_post_comment.php:17
if(Loader::includeModule( 'bitrix24')) elseif(Loader::includeModule('intranet') &&CIntranetUtils::getPortalZone() !=='ru') $description
Определения .description.php:24
$iblockId
Определения iblock_catalog_edit.php:30
$errors
Определения iblock_catalog_edit.php:74
$catalog
Определения iblock_catalog_edit.php:135
$productIblockId
Определения iblock_catalog_edit.php:242
$filter
Определения iblock_catalog_list.php:54
$selectFields
Определения iblock_catalog_list.php:160
foreach( $arCellTemplates as $key=> $value) foreach( $arCellTemplates as $key=> $value)
if(! $ar_profile) $strFile
Определения cron_frame.php:59
global $DB
Определения cron_frame.php:29
if(preg_match('/^ else[a-z0-9_]{2}$/i', $siteID)===1)
Определения cron_frame.php:23
$IBLOCK_ID
Определения csv_new_run.php:168
global $USER
Определения csv_new_run.php:40
if(!is_null($config))($config as $configItem)(! $configItem->isVisible()) $code
Определения options.php:195
if(!defined('SITE_ID')) $lang
Определения include.php:91
const LANG_CHARSET
Определения include.php:65
$arCodes
Определения options.php:154
if($NS['step']==6) if( $NS[ 'step']==7) if(COption::GetOptionInt('main', 'disk_space', 0) > 0) $info
Определения backup.php:924
if(!defined('NOT_CHECK_PERMISSIONS')) $NS
Определения backup.php:24
CheckDirPath($path)
Определения tools.php:2707
FormatText($strText, $strTextType="text")
Определения tools.php:2675
bx_basename($path, $ext="")
Определения tools.php:3269
htmlspecialcharsbx($string, $flags=ENT_COMPAT, $doubleEncode=true)
Определения tools.php:2701
IncludeModuleLangFile($filepath, $lang=false, $bReturnArray=false)
Определения tools.php:3778
GetMessage($name, $aReplace=null)
Определения tools.php:3397
$name
Определения menu_edit.php:35
Определения basket.php:2
Определения directory.php:3
if(!function_exists(__NAMESPACE__.'\\___972068685'))
Определения license.php:1
if(mb_strlen($order)< 6) $desc
Определения payment.php:44
if(!function_exists("bx_hmac")) $amount
Определения payment.php:30
$counter
Определения options.php:5
return false
Определения prolog_main_admin.php:185
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
Определения prolog_main_admin.php:393
$ar
Определения options.php:199
$fileName
Определения quickway.php:305
if(empty($signedUserToken)) $key
Определения quickway.php:257
$i
Определения factura.php:643
$discount
Определения waybill.php:788
</p ></td >< td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 2.0pt 0cm 2.0pt;height:9.0pt'>< p class=Normal align=center style='margin:0cm;margin-bottom:.0001pt;text-align:center;line-height:normal'>< a name=ТекстовоеПоле54 ></a ><?=($taxRate > count( $arTaxList) > 0) ? $taxRate."%"
Определения waybill.php:936
$currency
Определения template.php:266
$vat
Определения template.php:273
if($inWords) echo htmlspecialcharsbx(Number2Word_Rus(roundEx($totalVatSum $params['CURRENCY']
Определения template.php:799
$title
Определения pdf.php:123
$matches
Определения index.php:22
$counters
Определения options.php:100
$site_id
Определения sonet_set_content_view.php:9
const SITE_ID
Определения sonet_set_content_view.php:12
$error
Определения subscription_card_product.php:20
$rs
Определения action.php:82
$k
Определения template_pdf.php:567
$action
Определения file_dialog.php:21
if(file_exists($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/updater.log") &&is_file($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/updater.log") &&is_readable($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/updater.log")) $rsData
Определения update_log.php:102
$arFilter
Определения user_search.php:106
$url
Определения iframe.php:7
$rsIBlocks
Определения yandex_detail.php:58
$arIBlock['PROPERTY']
Определения yandex_detail.php:172
$rsProps
Определения yandex_run.php:584
$arSections
Определения yandex_run.php:805
$iterator
Определения yandex_run.php:610
$site
Определения yandex_run.php:614
$fields
Определения yandex_run.php:501