53 $intOfferID = (int)$intOfferID;
57 if (!isset(self::$parentCache[$intOfferID]))
59 self::$parentCache[$intOfferID] =
false;
62 $intIBlockID = (int)CIBlockElement::GetIBlockByID($intOfferID);
65 return self::$parentCache[$intOfferID];
72 if (empty($skuInfo) || empty($skuInfo[
'SKU_PROPERTY_ID']))
73 return self::$parentCache[$intOfferID];
76 $helper = $conn->getSqlHelper();
78 if ($skuInfo[
'VERSION'] == 2)
80 $productField = $helper->quote(
'PROPERTY_'.$skuInfo[
'SKU_PROPERTY_ID']);
81 $sqlQuery =
'select '.$productField.
' as ID from '.$helper->quote(
'b_iblock_element_prop_s'.$skuInfo[
'IBLOCK_ID']).
82 ' where '.$helper->quote(
'IBLOCK_ELEMENT_ID').
' = '.$intOfferID;
86 $productField = $helper->quote(
'VALUE_NUM');
87 $sqlQuery =
'select '.$productField.
' as ID from '.$helper->quote(
'b_iblock_element_property').
88 ' where '.$helper->quote(
'IBLOCK_PROPERTY_ID').
' = '.$skuInfo[
'SKU_PROPERTY_ID'].
89 ' and '.$helper->quote(
'IBLOCK_ELEMENT_ID').
' = '.$intOfferID;
92 $parentIterator = $conn->query($sqlQuery);
93 if ($parent = $parentIterator->fetch())
95 $parent[
'ID'] = (int)$parent[
'ID'];
96 if ($parent[
'ID'] > 0)
98 self::$parentCache[$intOfferID] =
array(
99 'ID' => $parent[
'ID'],
100 'IBLOCK_ID' => $skuInfo[
'PRODUCT_IBLOCK_ID'],
102 'SKU_PROPERTY_ID' => $skuInfo[
'SKU_PROPERTY_ID']
106 unset($parent, $parentIterator, $sqlQuery, $helper, $conn, $skuInfo);
108 return self::$parentCache[$intOfferID];
286 $iblockID = (int)$iblockID;
287 if (!is_array($productID))
288 $productID =
array($productID);
290 if (empty($productID))
292 $result = array_fill_keys($productID,
false);
293 $iblockProduct =
array();
294 $iblockSku =
array();
299 'select' =>
array(
'ID',
'IBLOCK_ID'),
300 'filter' =>
array(
'@ID' => $productID)
302 while ($element = $elementIterator->fetch())
304 $element[
'ID'] = (int)$element[
'ID'];
305 $element[
'IBLOCK_ID'] = (int)$element[
'IBLOCK_ID'];
308 $iblockList[$element[
'IBLOCK_ID']][] = $element[
'ID'];
310 unset($element, $elementIterator);
314 foreach ($iblockListIds as &$oneIblock)
316 if (!empty(self::$arOfferCache[$oneIblock]))
321 if (isset(self::$arProductCache[$oneIblock]))
323 if (!empty(self::$arProductCache[$oneIblock]))
325 $iblockSku[$oneIblock] = self::$arProductCache[$oneIblock];
326 $iblockProduct[$oneIblock] =
$iblockList[$oneIblock];
331 unset($oneIblock, $iblockListIds);
335 'select' =>
array(
'IBLOCK_ID',
'PRODUCT_IBLOCK_ID',
'SKU_PROPERTY_ID',
'VERSION' =>
'IBLOCK.VERSION'),
338 while (
$iblock = $iblockIterator->fetch())
346 self::$arProductCache[
$iblock[
'IBLOCK_ID']] =
false;
348 self::$arOfferCache[
$iblock[
'PRODUCT_IBLOCK_ID']] =
false;
352 unset(
$iblock, $iblockIterator);
359 if (empty(self::$arOfferCache[$iblockID]))
361 if (isset(self::$arProductCache[$iblockID]))
363 if (!empty(self::$arProductCache[$iblockID]))
365 $iblockSku[$iblockID] = self::$arProductCache[$iblockID];
366 $iblockProduct[$iblockID] = $productID;
372 'select' =>
array(
'IBLOCK_ID',
'PRODUCT_IBLOCK_ID',
'SKU_PROPERTY_ID',
'VERSION' =>
'IBLOCK.VERSION'),
373 'filter' =>
array(
'=PRODUCT_IBLOCK_ID' => $iblockID)
375 if (
$iblock = $iblockIterator->fetch())
383 self::$arProductCache[
$iblock[
'IBLOCK_ID']] =
false;
385 self::$arOfferCache[
$iblock[
'PRODUCT_IBLOCK_ID']] =
false;
387 $iblockProduct[$iblockID] = $productID;
389 unset(
$iblock, $iblockIterator);
393 if (empty($iblockProduct))
397 $helper = $conn->getSqlHelper();
398 $propertyIdField = $helper->quote(
'IBLOCK_PROPERTY_ID');
400 foreach ($iblockProduct as $iblockID => $iblockProductID)
402 $sku = $iblockSku[$iblockID];
403 if ($sku[
'VERSION'] == 2)
405 $productField = $helper->quote(
'PROPERTY_'.$sku[
'SKU_PROPERTY_ID']);
406 $sqlQuery =
'select '.$productField.
' as PRODUCT_ID, COUNT(*) as CNT from '.$helper->quote(
'b_iblock_element_prop_s'.$sku[
'IBLOCK_ID']).
407 ' where '.$productField.
' IN ('.implode(
',', $iblockProductID).
')'.
408 ' group by '.$productField;
412 $productField = $helper->quote(
'VALUE_NUM');
413 $sqlQuery =
'select '.$productField.
' as PRODUCT_ID, COUNT(*) as CNT from '.$helper->quote(
'b_iblock_element_property').
414 ' where '.$propertyIdField.
' = '.$sku[
'SKU_PROPERTY_ID'].
415 ' and '.$productField.
' IN ('.implode(
',', $iblockProductID).
')'.
416 ' group by '.$productField;
418 unset($productField);
419 $productIterator = $conn->query($sqlQuery);
420 while ($product = $productIterator->fetch())
422 $product[
'CNT'] = (int)$product[
'CNT'];
423 if ($product[
'CNT'] <= 0)
426 $product[
'PRODUCT_ID'] = (int)$product[
'PRODUCT_ID'];
427 $result[$product[
'PRODUCT_ID']] =
true;
429 unset($product, $productIterator);
431 unset($sku, $iblockProductID, $iblockID, $iblockProduct);
432 unset($propertyIdField, $helper, $conn);
450 $skuFilter =
array(),
452 $propertyFilter =
array(),
457 static $propertyCache =
array();
459 $iblockID = (int)$iblockID;
460 if (!is_array($productID))
461 $productID =
array($productID);
463 if (empty($productID))
465 if (!is_array($skuFilter))
466 $skuFilter =
array();
470 if (!is_array($propertyFilter))
471 $propertyFilter =
array();
473 $iblockProduct =
array();
474 $iblockSku =
array();
475 $offersIblock =
array();
480 $list = CIBlockElement::GetIBlockByIDList($productID);
481 foreach ($list as $elementId => $elementIblock)
487 unset($elementId, $elementIblock, $list);
492 foreach ($iblockListIds as &$oneIblock)
494 if (isset(self::$arProductCache[$oneIblock]))
496 if (!empty(self::$arProductCache[$oneIblock]))
498 $iblockSku[$oneIblock] = self::$arProductCache[$oneIblock];
499 $offersIblock[] = self::$arProductCache[$oneIblock][
'IBLOCK_ID'];
500 $iblockProduct[$oneIblock] =
$iblockList[$oneIblock];
505 unset($oneIblock, $iblockListIds);
509 'select' =>
array(
'IBLOCK_ID',
'PRODUCT_IBLOCK_ID',
'SKU_PROPERTY_ID',
'VERSION' =>
'IBLOCK.VERSION'),
512 while (
$iblock = $iblockIterator->fetch())
520 self::$arProductCache[
$iblock[
'IBLOCK_ID']] =
false;
522 self::$arOfferCache[
$iblock[
'PRODUCT_IBLOCK_ID']] =
false;
524 $offersIblock[] =
$iblock[
'IBLOCK_ID'];
527 unset(
$iblock, $iblockIterator);
534 if (empty(self::$arOfferCache[$iblockID]))
536 if (isset(self::$arProductCache[$iblockID]))
538 if (!empty(self::$arProductCache[$iblockID]))
540 $iblockSku[$iblockID] = self::$arProductCache[$iblockID];
541 $offersIblock[] = self::$arProductCache[$iblockID][
'IBLOCK_ID'];
542 $iblockProduct[$iblockID] = $productID;
548 'select' =>
array(
'IBLOCK_ID',
'PRODUCT_IBLOCK_ID',
'SKU_PROPERTY_ID',
'VERSION' =>
'IBLOCK.VERSION'),
549 'filter' =>
array(
'=PRODUCT_IBLOCK_ID' => $iblockID)
551 if (
$iblock = $iblockIterator->fetch())
559 self::$arProductCache[
$iblock[
'IBLOCK_ID']] =
false;
561 self::$arOfferCache[
$iblock[
'PRODUCT_IBLOCK_ID']] =
false;
563 $offersIblock[] =
$iblock[
'IBLOCK_ID'];
564 $iblockProduct[$iblockID] = $productID;
566 unset(
$iblock, $iblockIterator);
570 if (empty($iblockProduct))
573 $propertyFilter = array_filter($propertyFilter);
574 if (isset($propertyFilter[
'ID']))
576 $propertyFilter[
'ID'] = array_filter($propertyFilter[
'ID']);
577 if (empty($propertyFilter[
'ID']))
578 unset($propertyFilter[
'ID']);
580 if (isset($propertyFilter[
'CODE']))
582 $propertyFilter[
'CODE'] = array_filter($propertyFilter[
'CODE']);
583 if (empty($propertyFilter[
'CODE']))
584 unset($propertyFilter[
'CODE']);
587 $iblockProperties =
array();
588 if (!empty($propertyFilter[
'ID']) || !empty($propertyFilter[
'CODE']))
591 $propertyIblock =
array(
'@IBLOCK_ID' => $offersIblock);
592 if (!empty($propertyFilter[
'ID']))
594 sort($propertyFilter[
'ID']);
595 $propertyIblock[
'@ID'] = $propertyFilter[
'ID'];
599 sort($propertyFilter[
'CODE']);
600 $propertyIblock[
'@CODE'] = $propertyFilter[
'CODE'];
602 $propertyKey = md5(serialize($propertyIblock));
603 if (!isset($propertyCache[$propertyKey]))
605 $propertyCache[$propertyKey] = array_fill_keys($offersIblock,
array());
607 'select' =>
array(
'ID',
'IBLOCK_ID'),
608 'filter' => $propertyIblock
610 while ($property = $propertyIterator->fetch())
612 $property[
'IBLOCK_ID'] = (int)$property[
'IBLOCK_ID'];
613 $propertyCache[$propertyKey][$property[
'IBLOCK_ID']][] = (int)$property[
'ID'];
615 unset($property, $propertyIterator, $propertyIblock);
617 $iblockProperties = $propertyCache[$propertyKey];
619 unset($offersIblock);
625 $orderFields = array_keys(
$order);
629 foreach ($iblockProduct as $iblockID => $productList)
631 $skuProperty =
'PROPERTY_'.$iblockSku[$iblockID][
'SKU_PROPERTY_ID'];
632 $iblockFilter = $skuFilter;
633 $iblockFilter[
'IBLOCK_ID'] = $iblockSku[$iblockID][
'IBLOCK_ID'];
634 $iblockFilter[
'='.$skuProperty] = $productList;
636 $iblockFields[] = $skuProperty;
637 $iblockFields = array_merge($iblockFields, $orderFields);
638 $skuProperty .=
'_VALUE';
639 $skuPropertyId = $skuProperty.
'_ID';
640 $offersLinks =
array();
641 $needProperties = !empty($iblockProperties[$iblockSku[$iblockID][
'IBLOCK_ID']]);
643 $offersIterator = CIBlockElement::GetList(
650 while ($offer = $offersIterator->Fetch())
652 $offerProduct = (int)$offer[$skuProperty];
653 unset($offer[$skuProperty]);
654 if (isset($offer[$skuPropertyId]))
655 unset($offer[$skuPropertyId]);
656 if (!isset(
$result[$offerProduct]))
658 $offer[
'ID'] = (int)$offer[
'ID'];
659 $offer[
'IBLOCK_ID'] = (int)$offer[
'IBLOCK_ID'];
660 $offer[
'PARENT_ID'] = $offerProduct;
662 $offer[
'PROPERTIES'] =
array();
663 $result[$offerProduct][$offer[
'ID']] = $offer;
664 $offersLinks[$offer[
'ID']] = &
$result[$offerProduct][$offer[
'ID']];
666 unset($offerProduct, $offer, $offersIterator, $skuProperty);
669 $offerIds = array_keys($offersLinks);
670 foreach (array_chunk($offerIds, 500) as $pageIds)
672 $pageOffersFilter =
array(
674 'IBLOCK_ID' => $iblockSku[$iblockID][
'IBLOCK_ID']
676 CIBlockElement::GetPropertyValuesArray(
678 $iblockSku[$iblockID][
'IBLOCK_ID'],
680 array(
'ID' => $iblockProperties[$iblockSku[$iblockID][
'IBLOCK_ID']]),
683 unset($pageOffersFilter);
685 unset($pageIds, $offerIds);
689 unset($productList, $iblockID, $iblockProduct);
696 $iblockID = (int)$iblockID;
697 if (!is_array($offerID))
698 $offerID =
array($offerID);
703 $iblockSku =
array();
704 $iblockOffers =
array();
709 'select' =>
array(
'ID',
'IBLOCK_ID'),
710 'filter' =>
array(
'@ID' => $offerID)
712 while ($element = $elementIterator->fetch())
714 $element[
'ID'] = (int)$element[
'ID'];
715 $element[
'IBLOCK_ID'] = (int)$element[
'IBLOCK_ID'];
718 $iblockList[$element[
'IBLOCK_ID']][] = $element[
'ID'];
720 unset($element, $elementIterator);
724 foreach ($iblockListIds as &$oneIblock)
726 if (!empty(self::$arProductCache[$oneIblock]))
731 if (isset(self::$arOfferCache[$oneIblock]))
733 if (!empty(self::$arOfferCache[$oneIblock]))
735 $iblockSku[$oneIblock] = self::$arOfferCache[$oneIblock];
736 $iblockOffers[$oneIblock] =
$iblockList[$oneIblock];
741 unset($oneIblock, $iblockListIds);
745 'select' =>
array(
'IBLOCK_ID',
'PRODUCT_IBLOCK_ID',
'SKU_PROPERTY_ID',
'VERSION' =>
'IBLOCK.VERSION'),
746 'filter' =>
array(
'@IBLOCK_ID' => array_keys(
$iblockList),
'!=PRODUCT_IBLOCK_ID' => 0)
748 while (
$iblock = $iblockIterator->fetch())
756 self::$arProductCache[
$iblock[
'IBLOCK_ID']] =
false;
758 self::$arOfferCache[
$iblock[
'PRODUCT_IBLOCK_ID']] =
false;
762 unset(
$iblock, $iblockIterator);
769 if (empty(self::$arProductCache[$iblockID]))
771 if (isset(self::$arOfferCache[$iblockID]))
773 if (!empty(self::$arOfferCache[$iblockID]))
775 $iblockSku[$iblockID] = self::$arOfferCache[$iblockID];
776 $iblockOffers[$iblockID] = $offerID;
782 'select' =>
array(
'IBLOCK_ID',
'PRODUCT_IBLOCK_ID',
'SKU_PROPERTY_ID',
'VERSION' =>
'IBLOCK.VERSION'),
783 'filter' =>
array(
'=IBLOCK_ID' => $iblockID,
'!=PRODUCT_IBLOCK_ID' => 0)
785 if (
$iblock = $iblockIterator->fetch())
793 self::$arProductCache[
$iblock[
'IBLOCK_ID']] =
false;
795 self::$arOfferCache[
$iblock[
'PRODUCT_IBLOCK_ID']] =
false;
797 $iblockOffers[$iblockID] = $offerID;
799 unset(
$iblock, $iblockIterator);
803 if (empty($iblockOffers))
809 $helper = $conn->getSqlHelper();
810 $offerField = $helper->quote(
'IBLOCK_ELEMENT_ID');
811 $propertyIdField = $helper->quote(
'IBLOCK_PROPERTY_ID');
813 foreach ($iblockOffers as $iblockID =>
$offerList)
815 $sku = $iblockSku[$iblockID];
817 foreach (array_chunk(
$offerList, 500) as $pageIds)
819 if ($sku[
'VERSION'] == 2)
821 $productField = $helper->quote(
'PROPERTY_'.$sku[
'SKU_PROPERTY_ID']);
822 $sqlQuery =
'select '.$productField.
' as PRODUCT_ID, '.$offerField.
' as ID from '.$helper->quote(
'b_iblock_element_prop_s'.$sku[
'IBLOCK_ID']).
823 ' where '.$offerField.
' IN ('.implode(
',', $pageIds).
')';
827 $productField = $helper->quote(
'VALUE_NUM');
828 $sqlQuery =
'select '.$productField.
' as PRODUCT_ID, '.$offerField.
' as ID from '.$helper->quote(
'b_iblock_element_property').
829 ' where '.$propertyIdField.
' = '.$sku[
'SKU_PROPERTY_ID'].
830 ' and '.$offerField.
' IN ('.implode(
',', $pageIds).
')';
832 unset($productField);
833 $offersIterator = $conn->query($sqlQuery);
834 while ($offer = $offersIterator->fetch())
836 $currentOffer = (int)$offer[
'ID'];
837 $productID = (int)$offer[
'PRODUCT_ID'];
838 if (!isset(
$result[$currentOffer]) || $productID <= 0)
843 'IBLOCK_ID' => $sku[
'PRODUCT_IBLOCK_ID'],
844 'OFFER_IBLOCK_ID' => $iblockID,
845 'SKU_PROPERTY_ID' => $sku[
'SKU_PROPERTY_ID']
851 unset($iblockID, $iblockOffers);
852 unset($helper, $conn);