Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
exportoffer.php
1<?php
2namespace Bitrix\Catalog\Ebay;
3
7
8class ExportOffer implements \Iterator
9{
10 /*Constructor input vars*/
11 protected $iBlockId;
12 protected $xmlData;
13
14 /*Counted by constructor vars*/
15 protected $bAllSections;
16 protected $arSections = array();
17 protected $arIblock;
18 protected $startPosition = null;
19 protected $includeSubsections = true;
20 protected $intMaxSectionID = 0;
21 protected $arSectionIDs = array();
22
23 /*Iterator vars*/
24 protected $currentKey = 0;
25 protected $currentRecord = array();
26
27 /*other vars*/
28 protected $cnt = 0;
30 protected $dbItems = NULL;
31 protected $catalogType;
32 protected $onlyAvailableElements = false; // export with flag "available"
33
34 public function __construct($catalogType, $params)
35 {
36 if(!isset($params["IBLOCK_ID"]) || intval($params["IBLOCK_ID"]) <= 0)
37 throw new SystemException("Incorrect iBlock ID (".__CLASS__."::".__METHOD__.")");
38
39 $this->catalogType = $catalogType;
40
41 $this->iBlockId = $params["IBLOCK_ID"];
42 $this->xmlData = $params["XML_DATA"];
43
44 $this->arIblock = $this->getIblockProps($params["SETUP_SERVER_NAME"]);
45 $this->arSections = $this->getSections($params["PRODUCT_GROUPS"]);
46 if(isset($params["START_POSITION"]) && $params["START_POSITION"])
47 $this->startPosition = $params["START_POSITION"];
48 if(isset($params["INCLUDE_SUBSECTION"]))
49 $this->includeSubsections = $params["INCLUDE_SUBSECTION"];
50
51 $this->bAllSections = in_array(0, $this->arSections) ? true : false;
52 $availGroups = $this->getAvailGroups();
53 $this->intMaxSectionID = $this->getMaxSectionId($availGroups);
54 $this->arSectionIDs = $this->getSectionIDs($availGroups);
55 }
56
57 /*Iterator methods*/
58
64 #[\ReturnTypeWillChange]
65 public function current()
66 {
68 }
69
75 #[\ReturnTypeWillChange]
76 public function key()
77 {
78 return $this->currentKey;
79 }
80
86 #[\ReturnTypeWillChange]
87 public function next()
88 {
89 $this->currentKey++;
90 $this->currentRecord = $this->nextItem();
91 $this->checkDiscountCache();
92 }
93
99 #[\ReturnTypeWillChange]
100 public function rewind()
101 {
102 $this->currentKey = 0;
103 $this->dbItems = $this->createDbResObject();
104 $this->currentRecord = $this->nextItem();
105 $this->cnt = 100;
106 $this->checkDiscountCache();
107 }
108
114 #[\ReturnTypeWillChange]
115 public function valid ()
116 {
117 return is_array($this->currentRecord);
118 }
119
120 protected function createDbResObject()
121 {
122// order need for limiting by ID
123 $order = array("ID" => "ASC");
124 $arSelect = array("ID", "LID", "IBLOCK_ID", "IBLOCK_SECTION_ID", "NAME", "PREVIEW_PICTURE", "PREVIEW_TEXT",
125 "PREVIEW_TEXT_TYPE", "DETAIL_PICTURE", "LANG_DIR", "DETAIL_PAGE_URL", "DETAIL_TEXT");
126
127 $filter = array("IBLOCK_ID" => $this->iBlockId);
128
129// if set start position - limit result by ID
130 if($this->startPosition)
131 $filter[">=ID"] = $this->startPosition;
132
133 if (!$this->bAllSections && !empty($this->arSections))
134 {
135 $filter["INCLUDE_SUBSECTIONS"] = $this->includeSubsections ? "Y" : "N";
136 $filter["SECTION_ID"] = $this->arSections;
137 }
138
139 if($this->onlyAvailableElements)
140 $filter["CATALOG_AVAILABLE"] = "Y";
141 $filter["ACTIVE"] = "Y";
142 $filter["SECTION_GLOBAL_ACTIVE"] = "Y";
143 $filter["ACTIVE_DATE"] = "Y";
144
145 return \CIBlockElement::GetList($order, $filter, false, false, $arSelect);
146 }
147
148 protected function getMaxSectionId(array $arAvailGroups)
149 {
150 $result = 0;
151
152 foreach($arAvailGroups as $group)
153 if ($result < $group["ID"])
154 $result = $group["ID"];
155
156 $result += 100000000;
157
158 return $result;
159 }
160
161 protected function getAvailGroups()
162 {
163 $arAvailGroups = [];
164
165 if (!$this->bAllSections)
166 {
167 $intSectionsCount = count($this->arSections);
168 for ($i = 0; $i < $intSectionsCount; $i++)
169 {
170 $list = \CIBlockSection::GetNavChain(
171 $this->iBlockId,
172 $this->arSections[$i],
173 [
174 'ID',
175 'IBLOCK_ID',
176 'IBLOCK_SECTION_ID',
177 'NAME',
178 'LEFT_MARGIN',
179 'RIGHT_MARGIN',
180 ],
181 true
182 );
183 $curLEFT_MARGIN = 0;
184 $curRIGHT_MARGIN = 0;
185 foreach ($list as $ar_res)
186 {
187 $curLEFT_MARGIN = (int)$ar_res['LEFT_MARGIN'];
188 $curRIGHT_MARGIN = (int)$ar_res['RIGHT_MARGIN'];
189 $arAvailGroups[$ar_res['ID']] = [
190 'ID' => (int)$ar_res['ID'],
191 'IBLOCK_SECTION_ID' => (int)$ar_res['IBLOCK_SECTION_ID'],
192 'NAME' => $ar_res['NAME'],
193 ];
194 }
195 unset($ar_res, $list);
196
197 $filter = [
198 'IBLOCK_ID' => $this->iBlockId,
199 '>LEFT_MARGIN' => $curLEFT_MARGIN,
200 '<RIGHT_MARGIN' => $curRIGHT_MARGIN,
201 'ACTIVE' => 'Y',
202 'IBLOCK_ACTIVE' => 'Y',
203 'GLOBAL_ACTIVE' => 'Y',
204 ];
205 $db_res = \CIBlockSection::GetList(
206 ['LEFT_MARGIN '=> 'ASC'],
207 $filter,
208 false,
209 [
210 'ID',
211 'IBLOCK_ID',
212 'IBLOCK_SECTION_ID',
213 'NAME',
214 'LEFT_MARGIN',
215 ]
216 );
217 while ($ar_res = $db_res->Fetch())
218 {
219 $arAvailGroups[$ar_res['ID']] = [
220 'ID' => (int)$ar_res['ID'],
221 'IBLOCK_SECTION_ID' => (int)$ar_res['IBLOCK_SECTION_ID'],
222 'NAME' => $ar_res['NAME'],
223 ];
224 }
225 unset($ar_res, $db_res);
226 }
227 }
228 else
229 {
230 $filter = [
231 'IBLOCK_ID' => $this->iBlockId,
232 'ACTIVE' => 'Y',
233 'IBLOCK_ACTIVE' => 'Y',
234 'GLOBAL_ACTIVE' => 'Y',
235 ];
236 $db_res = \CIBlockSection::GetList(
237 ['LEFT_MARGIN' => 'ASC'],
238 $filter,
239 false,
240 [
241 'ID',
242 'IBLOCK_ID',
243 'IBLOCK_SECTION_ID',
244 'NAME',
245 'LEFT_MARGIN',
246 ]
247 );
248 while ($ar_res = $db_res->Fetch())
249 {
250 $arAvailGroups[$ar_res['ID']] = [
251 'ID' => (int)$ar_res['ID'],
252 'IBLOCK_SECTION_ID' => (int)$ar_res['IBLOCK_SECTION_ID'],
253 'NAME' => $ar_res['NAME'],
254 ];
255 }
256 unset($ar_res, $db_res);
257 }
258
259 return $arAvailGroups;
260 }
261
262 protected function getSections($selectedGroups)
263 {
264 $arSections = array();
265
266 if (is_array($selectedGroups))
267 {
268 foreach ($selectedGroups as $value)
269 {
270 $arSections[] = (int)$value;
271
272 if ($value == 0)
273 break;
274 }
275 }
276
277 return $arSections;
278 }
279
280 protected function getIblockProps($serverName)
281 {
282 $dbIblock = \CIBlock::GetByID($this->iBlockId);
283 $arIblock = $dbIblock->Fetch();
284
285 if($arIblock)
286 {
287 if ($serverName == '')
288 {
289 if ($arIblock['SERVER_NAME'] == '')
290 {
291 $rsSite = \CSite::GetList('', '', array("LID" => $arIblock["LID"]));
292 if($arSite = $rsSite->Fetch())
293 $arIblock["SERVER_NAME"] = $arSite["SERVER_NAME"];
294 if($arIblock["SERVER_NAME"] == '' && defined("SITE_SERVER_NAME"))
295 $arIblock["SERVER_NAME"] = SITE_SERVER_NAME;
296 if($arIblock["SERVER_NAME"] == '')
297 $arIblock["SERVER_NAME"] = \COption::GetOptionString("main", "server_name", "");
298 }
299 }
300 else
301 {
302 $arIblock['SERVER_NAME'] = $serverName;
303 }
304
305 $arIblock['PROPERTY'] = array();
306
307 $rsProps = \CIBlockProperty::GetList(
308 array('SORT' => 'ASC', 'NAME' => 'ASC'),
309 array('IBLOCK_ID' => $this->iBlockId, 'ACTIVE' => 'Y', 'CHECK_PERMISSIONS' => 'N')
310 );
311 while ($arProp = $rsProps->Fetch())
312 {
313 $arProp['ID'] = (int)$arProp['ID'];
314 $arProp['USER_TYPE'] = (string)$arProp['USER_TYPE'];
315 $arProp['CODE'] = (string)$arProp['CODE'];
316 $arIblock['PROPERTY'][$arProp['ID']] = $arProp;
317 }
318 }
319
320 return $arIblock;
321 }
322
323 protected function getQuantity($productId)
324 {
325 $result = 0;
326
327 $rsProducts = \CCatalogProduct::GetList(
328 array(),
329 array('ID' => $productId),
330 false,
331 false,
332 array('ID', 'QUANTITY', 'QUANTITY_TRACE', 'CAN_BUY_ZERO')
333 );
334
335 if ($arProduct = $rsProducts->Fetch())
336 {
337 $arProduct['QUANTITY'] = doubleval($arProduct['QUANTITY']);
338
339 if (0 >= $arProduct['QUANTITY'] && ('Y' != $arProduct['QUANTITY_TRACE'] || 'N' != $arProduct['CAN_BUY_ZERO']))
340 $result = 1;
341 else
342 $result = $arProduct['QUANTITY'];
343 }
344
345 return $result;
346 }
347
353 public static function getRub()
354 {
355 $currencyList = Currency\CurrencyManager::getCurrencyList();
356
357 return (isset($currencyList['RUR']) ? 'RUR' : 'RUB');
358 }
359
365 public function setOnlyAvailableFlag($flag)
366 {
367 if($flag)
368 $this->onlyAvailableElements = true;
369 else
370 $this->onlyAvailableElements = false;
371 }
372
373 protected function getPrices($productId, $siteId)
374 {
375 $minPrice = 0;
376 $minPriceRUR = 0;
377 $minPriceGroup = 0;
378 $minPriceCurrency = "";
379
380 $baseCurrency = Currency\CurrencyManager::getBaseCurrency();
381 $RUR = $this->getRub();
382
383 if ($this->xmlData['PRICE'] > 0)
384 {
385 $rsPrices = \CPrice::GetListEx(array(),array(
386 'PRODUCT_ID' => $productId,
387 'CATALOG_GROUP_ID' => $this->xmlData['PRICE'],
388 'CAN_BUY' => 'Y',
389 'GROUP_GROUP_ID' => array(2),
390 '+<=QUANTITY_FROM' => 1,
391 '+>=QUANTITY_TO' => 1,
392 )
393 );
394
395 if ($arPrice = $rsPrices->Fetch())
396 {
397 if ($arOptimalPrice = \CCatalogProduct::GetOptimalPrice(
398 $productId,
399 1,
400 array(2), // anonymous
401 'N',
402 array($arPrice),
403 $siteId
404 ))
405 {
406 $minPrice = $arOptimalPrice['RESULT_PRICE']['DISCOUNT_PRICE'];
407 $minPriceCurrency = $baseCurrency;
408 $minPriceRUR = \CCurrencyRates::ConvertCurrency($minPrice, $baseCurrency, $RUR);
409 $minPriceGroup = $arOptimalPrice['PRICE']['CATALOG_GROUP_ID'];
410 }
411 }
412 }
413 else
414 {
415 if ($arPrice = \CCatalogProduct::GetOptimalPrice(
416 $productId,
417 1,
418 array(2), // anonymous
419 'N',
420 array(),
421 $siteId
422 ))
423 {
424 $minPrice = $arPrice['RESULT_PRICE']['DISCOUNT_PRICE'];
425 $minPriceCurrency = $baseCurrency;
426 $minPriceRUR = \CCurrencyRates::ConvertCurrency($minPrice, $baseCurrency, $RUR);
427 $minPriceGroup = $arPrice['PRICE']['CATALOG_GROUP_ID'];
428 }
429 }
430
431 $result = array(
432 "MIN" => $minPrice,
433 "MIN_RUB" => $minPriceRUR,
434 "MIN_GROUP" => $minPriceGroup,
435 "MIN_CURRENCY" => $minPriceCurrency
436 );
437
438 return $result;
439 }
440
441 protected function getDetailPageUrl($detailPageUrl)
442 {
443 if ($detailPageUrl == '')
444 $detailPageUrl = '/';
445 else
446 $detailPageUrl = str_replace(' ', '%20', $detailPageUrl);
447
448 $result = "http://".$this->arIblock['SERVER_NAME'].Main\Text\HtmlFilter::encode($detailPageUrl);
449
450 return $result;
451 }
452
453 protected function getPictureUrl($pictNo)
454 {
455 $strFile = "";
456
457 if ($file = \CFile::GetFileArray($pictNo))
458 {
459 if(mb_substr($file["SRC"], 0, 1) == "/")
460 $strFile = "http://".$this->arIblock['SERVER_NAME'].implode("/", array_map("rawurlencode", explode("/", $file["SRC"])));
461 elseif(preg_match("/^(http|https):\\/\\/(.*?)\\/(.*)\$/", $file["SRC"], $match))
462 $strFile = "http://".$match[2].'/'.implode("/", array_map("rawurlencode", explode("/", $match[3])));
463 else
464 $strFile = $file["SRC"];
465 }
466
467 return $strFile;
468 }
469
470 protected function getParams($product, $arIblock)
471 {
472 if (isset($arIblock['PROPERTY']))
473 $arProperties = $arIblock['PROPERTY'];
474 else
475 $arProperties = array();
476
477 $arUserTypeFormat = array();
478
479 foreach($arProperties as $key => $arProperty)
480 {
481 $arUserTypeFormat[$arProperty["ID"]] = false;
482 if($arProperty["USER_TYPE"] <> '')
483 {
484 $arUserType = \CIBlockProperty::GetUserType($arProperty["USER_TYPE"]);
485 if(array_key_exists("GetPublicViewHTML", $arUserType))
486 {
487 $arUserTypeFormat[$arProperty["ID"]] = $arUserType["GetPublicViewHTML"];
488 $arProperties[$key]['PROPERTY_TYPE'] = 'USER_TYPE';
489 }
490 }
491 }
492
493 $result = array();
494
495
496 if (is_array($this->xmlData) && is_array($this->xmlData['XML_DATA']) && is_array($this->xmlData['XML_DATA']['PARAMS']))
497 {
498 foreach ($this->xmlData['XML_DATA']['PARAMS'] as $key => $propId)
499 {
500 if ($propId)
501 $result[] = $this->getValue($product, 'PARAM_'.$key, $propId, $arProperties, $arUserTypeFormat);
502 }
503 }
504
505 return $result;
506 }
507
508 protected function getValue($arOffer, $param, $PROPERTY, $arProperties, $arUserTypeFormat)
509 {
510 $result = array();
511
512 $bParam = (strncmp($param, 'PARAM_', 6) == 0);
513
514 if (isset($arProperties[$PROPERTY]) && !empty($arProperties[$PROPERTY]))
515 {
516 $PROPERTY_CODE = $arProperties[$PROPERTY]['CODE'];
517 $arProperty = (
518 isset($arOffer['PROPERTIES'][$PROPERTY_CODE])
519 ? $arOffer['PROPERTIES'][$PROPERTY_CODE]
520 : $arOffer['PROPERTIES'][$PROPERTY]
521 );
522
523 $value = array();
524
525 if(!is_array($arProperty["VALUE"]))
526 $arProperty["VALUE"] = array($arProperty["VALUE"]);
527
528 switch ($arProperties[$PROPERTY]['PROPERTY_TYPE'])
529 {
530 case 'USER_TYPE':
531 foreach($arProperty["VALUE"] as $oneValue)
532 {
533 $value[] = call_user_func_array($arUserTypeFormat[$PROPERTY],
534 array(
535 $arProperty,
536 array("VALUE" => $oneValue),
537 array('MODE' => 'SIMPLE_TEXT'),
538 ));
539 }
540 break;
541
542 case 'E':
543 $arCheckValue = array();
544
545 foreach ($arProperty['VALUE'] as &$intValue)
546 {
547 $intValue = (int)$intValue;
548 if (0 < $intValue)
549 $arCheckValue[] = $intValue;
550 }
551
552 if (isset($intValue))
553 unset($intValue);
554
555 if (!empty($arCheckValue))
556 {
557 $dbRes = \CIBlockElement::GetList(array(), array('IBLOCK_ID' => $arProperties[$PROPERTY]['LINK_IBLOCK_ID'], 'ID' => $arCheckValue), false, false, array('NAME'));
558 while ($arRes = $dbRes->Fetch())
559 {
560 $value[] = $arRes['NAME'];
561 }
562 }
563 break;
564
565 case 'G':
566 $arCheckValue = array();
567
568 foreach ($arProperty['VALUE'] as &$intValue)
569 {
570 $intValue = (int)$intValue;
571 if (0 < $intValue)
572 $arCheckValue[] = $intValue;
573 }
574
575 if (isset($intValue))
576 unset($intValue);
577
578 if (!empty($arCheckValue))
579 {
580 $dbRes = \CIBlockSection::GetList(array(), array('IBLOCK_ID' => $arProperty['LINK_IBLOCK_ID'], 'ID' => $arCheckValue), false, array('NAME'));
581 while ($arRes = $dbRes->Fetch())
582 {
583 $value[] = $arRes['NAME'];
584 }
585 }
586 break;
587
588 case 'L':
589 $value .= $arProperty['VALUE'];
590 break;
591
592 case 'F':
593 foreach ($arProperty['VALUE'] as &$intValue)
594 {
595 $intValue = (int)$intValue;
596 if ($intValue > 0)
597 {
598 if ($ar_file = \CFile::GetFileArray($intValue))
599 {
600 if(mb_substr($ar_file["SRC"], 0, 1) == "/")
601 $strFile = "http://".$this->arIblock["SERVER_NAME"].implode("/", array_map("rawurlencode", explode("/", $ar_file["SRC"])));
602 elseif(preg_match("/^(http|https):\\/\\/(.*?)\\/(.*)\$/", $ar_file["SRC"], $match))
603 $strFile = "http://".$match[2].'/'.implode("/", array_map("rawurlencode", explode("/", $match[3])));
604 else
605 $strFile = $ar_file["SRC"];
606 $value[] = $strFile;
607 }
608 }
609 }
610
611 if (isset($intValue))
612 unset($intValue);
613 break;
614
615 default:
616 $value = $arProperty['VALUE'];
617 }
618
619 if(is_array($value) && count($value) == 1)
620 $value = implode("", $value);
621
622 if ($bParam)
623 {
624 $result[$param] = array(
625 "NAME" => $arProperties[$PROPERTY]['NAME'],
626 "VALUES" => $value,
627 );
628 }
629 else
630 {
631 $result[$param] = $value;
632 }
633 }
634
635 return $result;
636 }
637
638 protected function getCategories($productId)
639 {
640 $boolCurrentSections = false;
641 $result = array();
642
643 $dbElementGroups = \CIBlockElement::GetElementGroups($productId, false, array('ID', 'ADDITIONAL_PROPERTY_ID'));
644
645 while ($arElementGroup = $dbElementGroups->Fetch())
646 {
647 if (0 < (int)$arElementGroup['ADDITIONAL_PROPERTY_ID'])
648 continue;
649
650 $boolCurrentSections = true;
651
652 if (in_array((int)$arElementGroup["ID"], $this->arSectionIDs))
653 $result[] = $arElementGroup["ID"];
654 }
655
656 if (!$boolCurrentSections)
657 $result[] = $this->intMaxSectionID;
658
659 return $result;
660 }
661
662 protected function getSectionIDs(array $availGroups)
663 {
664 if (!empty($availGroups))
665 $arSectionIDs = array_keys($availGroups);
666 else
667 $arSectionIDs = array();
668
669 return $arSectionIDs;
670 }
671
672 protected function checkDiscountCache()
673 {
674 $this->cnt++;
675
676 if (100 <= $this->cnt)
677 {
678 $this->cnt = 0;
679 \CCatalogDiscount::ClearDiscountCache(array(
680 'PRODUCT' => true,
681 'SECTIONS' => true,
682 'PROPERTIES' => true,
683 ));
684 }
685 }
686
687 protected function nextItem()
688 {
689 if(!$obElement = $this->dbItems->GetNextElement())
690 return false;
691
692 $arItem = $obElement->GetFields();
693 $arItem['PROPERTIES'] = $obElement->GetProperties();
694 $arItem["QUANTITY"] = $this->getQuantity($arItem["ID"]);
695 $arItem["PRICES"] = $this->getPrices($arItem["ID"], $this->arIblock['LID']);
696 $arItem["CATEGORIES"] = $this->getCategories($arItem["ID"]);
697 $arItem["DETAIL_PICTURE_URL"] = $this->getPictureUrl((int)$arItem["DETAIL_PICTURE"]);
698 $arItem["PREVIEW_PICTURE_URL"] = $this->getPictureUrl((int)$arItem["PREVIEW_PICTURE"]);
699 $arItem["PARAMS"] = $this->getParams($arItem, $this->arIblock);
700 $arItem["DETAIL_PAGE_URL"] = $this->getDetailPageUrl($arItem["~DETAIL_PAGE_URL"]);
701
702 return $arItem;
703 }
704}
getValue($arOffer, $param, $PROPERTY, $arProperties, $arUserTypeFormat)
getParams($product, $arIblock)
getMaxSectionId(array $arAvailGroups)
getSectionIDs(array $availGroups)
getPrices($productId, $siteId)
__construct($catalogType, $params)