Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
ProductProvider.php
1<?php
2
4
8use Bitrix\Catalog\Product\PropertyCatalogFeature;
19
21{
22 protected const PRODUCT_LIMIT = 20;
23 protected const ENTITY_ID = 'product';
24
25 public function __construct(array $options = [])
26 {
27 parent::__construct();
28
29 $this->options['iblockId'] = (int)($options['iblockId'] ?? 0);
30 $this->options['basePriceId'] = (int)($options['basePriceId'] ?? 0);
31 $this->options['currency'] = $options['currency'] ?? '';
32 if (isset($options['restrictedProductTypes']) && is_array($options['restrictedProductTypes']))
33 {
34 $this->options['restrictedProductTypes'] = $options['restrictedProductTypes'];
35 }
36 else
37 {
38 $this->options['restrictedProductTypes'] = null;
39 }
40
41 $this->options['showPriceInCaption'] = (bool)($options['showPriceInCaption'] ?? true);
42 }
43
44 public function isAvailable(): bool
45 {
46 global $USER;
47
48 if (
49 !$USER->isAuthorized()
50 || !AccessController::getCurrent()->check(ActionDictionary::ACTION_CATALOG_READ)
51 )
52 {
53 return false;
54 }
55
56 if ($this->getIblockId() <= 0 || !$this->getIblockInfo())
57 {
58 return false;
59 }
60
61 return true;
62 }
63
64 public function getItems(array $ids): array
65 {
66 $items = [];
67
68 foreach ($this->getProductsByIds($ids) as $product)
69 {
70 $items[] = $this->makeItem($product);
71 }
72
73 return $items;
74 }
75
76 public function getSelectedItems(array $ids): array
77 {
78 return $this->getItems($ids);
79 }
80
81 public function fillDialog(Dialog $dialog): void
82 {
83 $dialog->loadPreselectedItems();
84
85 if ($dialog->getItemCollection()->count() > 0)
86 {
87 foreach ($dialog->getItemCollection() as $item)
88 {
89 $dialog->addRecentItem($item);
90 }
91 }
92
93 $recentItems = $dialog->getRecentItems()->getEntityItems(static::ENTITY_ID);
94 $recentItemsCount = count($recentItems);
95 if (
96 $this->options['restrictedProductTypes']
97 && is_array($this->options['restrictedProductTypes'])
98 && $recentItemsCount > 0
99 )
100 {
101 $ids = [];
102 foreach ($recentItems as $recentItem)
103 {
104 $ids[] = $recentItem->getId();
105 }
106
107 $products = $this->getProductsByIds($ids);
108
109 $restrictedTypes = array_flip($this->options['restrictedProductTypes']);
110 $selectedIds = [];
111 foreach ($products as $sku)
112 {
113 if (!isset($restrictedTypes[$sku['TYPE']]))
114 {
115 $selectedIds[] = $sku['ID'];
116 }
117 }
118
119 if ($selectedIds)
120 {
121 $selectedIds = array_flip($selectedIds);
122 }
123
125 foreach ($recentItems as $recentItem)
126 {
127 if (!isset($selectedIds[$recentItem->getId()]))
128 {
129 $recentItem->setAvailable(false);
130 $recentItemsCount--;
131 }
132 }
133 }
134
135 if ($recentItemsCount < self::PRODUCT_LIMIT)
136 {
137 foreach ($this->getProducts() as $product)
138 {
139 $dialog->addRecentItem($this->makeItem($product));
140 }
141 }
142 }
143
144 public function doSearch(SearchQuery $searchQuery, Dialog $dialog): void
145 {
146 $searchQuery->setCacheable(false);
147 $products = $this->getProductsBySearchString($searchQuery->getQuery());
148
149 if (!empty($products))
150 {
151 foreach ($products as $product)
152 {
153 $dialog->addItem(
154 $this->makeItem($product)
155 );
156 }
157
158 if ($this->shouldDisableCache($products))
159 {
160 $searchQuery->setCacheable(false);
161 }
162 }
163 }
164
165 protected function makeItem(array $product): Item
166 {
167 $customData = array_filter(array_intersect_key($product, [
168 'SKU_PROPERTIES' => true,
169 'SEARCH_PROPERTIES' => true,
170 'PREVIEW_TEXT' => true,
171 'DETAIL_TEXT' => true,
172 'PARENT_NAME' => true,
173 'PARENT_SEARCH_PROPERTIES' => true,
174 'PARENT_PREVIEW_TEXT' => true,
175 'PARENT_DETAIL_TEXT' => true,
176 'BARCODE' => true,
177 ]));
178
179 return new Item([
180 'id' => $product['ID'],
181 'entityId' => static::ENTITY_ID,
182 'title' => $product['NAME'],
183 'supertitle' => $product['SKU_PROPERTIES'],
184 'subtitle' => $this->getSubtitle($product),
185 'caption' => $this->getCaption($product),
186 'avatar' => $product['IMAGE'],
187 'customData' => $customData,
188 ]);
189 }
190
191 protected function getSubtitle(array $product): string
192 {
193 return $product['BARCODE'] ?? '';
194 }
195
196 protected function getCaption(array $product): array
197 {
198 if (!$this->shouldDisplayPriceInCaption())
199 {
200 return [];
201 }
202
203 return [
204 'text' => $product['PRICE'],
205 'type' => 'html',
206 ];
207 }
208
209 protected function getIblockId()
210 {
211 return $this->getOptions()['iblockId'];
212 }
213
214 private function getBasePriceId()
215 {
216 return $this->getOptions()['basePriceId'];
217 }
218
219 private function getCurrency()
220 {
221 return $this->getOptions()['currency'];
222 }
223
224 private function shouldDisplayPriceInCaption()
225 {
226 return $this->getOptions()['showPriceInCaption'];
227 }
228
229 protected function getIblockInfo(): ?IblockInfo
230 {
231 static $iblockInfo = null;
232
233 if ($iblockInfo === null)
234 {
235 $iblockInfo = ServiceContainer::getIblockInfo($this->getIblockId());
236 }
237
238 return $iblockInfo;
239 }
240
241 private function getImageSource(int $id): ?string
242 {
243 if ($id <= 0)
244 {
245 return null;
246 }
247
248 $file = \CFile::GetFileArray($id);
249 if (!$file)
250 {
251 return null;
252 }
253
254 return Tools::getImageSrc($file, false) ?: null;
255 }
256
257 protected function getProductsByIds(array $ids): array
258 {
259 [$productIds, $offerIds] = $this->separateOffersFromProducts($ids);
260
261 $products = $this->getProducts([
262 'filter' => ['=ID' => $productIds],
263 'offer_filter' => ['=ID' => $offerIds],
264 'sort' => [],
265 ]);
266
267 // sort $products by $productIds
268 return $this->sortProductsByIds($products, $productIds);
269 }
270
271 private function separateOffersFromProducts(array $ids): array
272 {
273 $iblockInfo = $this->getIblockInfo();
274 if (!$iblockInfo)
275 {
276 return [[], []];
277 }
278
279 $productIds = $ids;
280 $offerIds = [];
281
282 if ($iblockInfo->canHaveSku())
283 {
284 $productList = \CCatalogSku::getProductList($ids, $iblockInfo->getSkuIblockId());
285 if (!empty($productList))
286 {
287 $productIds = [];
288 $counter = 0;
289
290 foreach ($ids as $id)
291 {
292 if ($counter >= self::PRODUCT_LIMIT)
293 {
294 break;
295 }
296
297 if (isset($productList[$id]))
298 {
299 $productId = $productList[$id]['ID'];
300
301 if (isset($productIds[$productId]))
302 {
303 continue;
304 }
305
306 $offerIds[] = $id;
307 $productIds[$productId] = $productId;
308 }
309 else
310 {
311 $productIds[$id] = $id;
312 }
313
314 $counter++;
315 }
316
317 $productIds = array_values($productIds);
318 }
319 }
320
321 return [$productIds, $offerIds];
322 }
323
324 private function sortProductsByIds(array $products, array $ids): array
325 {
326 $sorted = [];
327
328 foreach ($ids as $id)
329 {
330 if (isset($products[$id]))
331 {
332 $sorted[$id] = $products[$id];
333 }
334 }
335
336 return $sorted;
337 }
338
339 protected function getProductsBySearchString(string $searchString = ''): array
340 {
341 $iblockInfo = $this->getIblockInfo();
342 if (!$iblockInfo)
343 {
344 return [];
345 }
346
347 $productFilter = [];
348 $offerFilter = [];
349
350 if ($searchString !== '')
351 {
352 $simpleProductFilter = [
353 '*SEARCHABLE_CONTENT' => $searchString,
354 ];
355
356 if ($iblockInfo->canHaveSku())
357 {
358 $productFilter[] = [
359 'LOGIC' => 'OR',
360 '*SEARCHABLE_CONTENT' => $searchString,
361 '=ID' => \CIBlockElement::SubQuery('PROPERTY_' . $iblockInfo->getSkuPropertyId(), [
362 'CHECK_PERMISSIONS' => 'Y',
363 'MIN_PERMISSION' => 'R',
364 'ACTIVE' => 'Y',
365 'ACTIVE_DATE' => 'Y',
366 'IBLOCK_ID' => $iblockInfo->getSkuIblockId(),
367 '*SEARCHABLE_CONTENT' => $searchString,
368 ]),
369 ];
370
371 $offerFilter = $simpleProductFilter;
372 }
373 else
374 {
375 $productFilter = $simpleProductFilter;
376 }
377 }
378
379 return $this->getProducts([
380 'filter' => $productFilter,
381 'offer_filter' => $offerFilter,
382 'searchString' => $searchString,
383 ]);
384 }
385
386 protected function getProducts(array $parameters = []): array
387 {
388 $iblockInfo = $this->getIblockInfo();
389 if (!$iblockInfo)
390 {
391 return [];
392 }
393
394 $productFilter = (array)($parameters['filter'] ?? []);
395 $offerFilter = (array)($parameters['offer_filter'] ?? []);
396 $shouldLoadOffers = (bool)($parameters['load_offers'] ?? true);
397
398 $additionalProductFilter = ['IBLOCK_ID' => $iblockInfo->getProductIblockId()];
399 $filteredTypes = [];
400 if ($this->options['restrictedProductTypes'] !== null)
401 {
402 $filteredTypes = array_intersect(
403 $this->options['restrictedProductTypes'],
405 );
406 }
407 $filteredTypes[] = ProductTable::TYPE_EMPTY_SKU;
408 $additionalProductFilter['!=TYPE'] = array_values(array_unique($filteredTypes));
409
410 $products = $this->loadElements([
411 'filter' => array_merge($productFilter, $additionalProductFilter),
412 'limit' => self::PRODUCT_LIMIT,
413 ]);
414 if (empty($products))
415 {
416 return [];
417 }
418
419 $products = $this->loadProperties($products, $iblockInfo->getProductIblockId(), $iblockInfo);
420
421 if ($shouldLoadOffers && $iblockInfo->canHaveSku())
422 {
423 $products = $this->loadOffers($products, $iblockInfo, $offerFilter);
424 }
425
426 $products = $this->loadPrices($products);
427
428 if (!empty($parameters['searchString']))
429 {
430 $products = $this->loadBarcodes($products, $parameters['searchString']);
431 }
432
433 return $products;
434 }
435
436 protected function loadElements(array $parameters = []): array
437 {
438 $elements = [];
439
440 $additionalFilter = (array)($parameters['filter'] ?? []);
441 $limit = (int)($parameters['limit'] ?? 0);
442
443 $filter = [
444 'CHECK_PERMISSIONS' => 'Y',
445 'MIN_PERMISSION' => 'R',
446 'ACTIVE' => 'Y',
447 'ACTIVE_DATE' => 'Y',
448 ];
449
450 $shortSelect = [
451 'ID',
452 'IBLOCK_ID',
453 ];
454
455 $selectFields = array_filter(array_unique(array_merge(
456 [
457 'ID',
458 'NAME',
459 'IBLOCK_ID',
460 'TYPE',
461 'PREVIEW_PICTURE',
462 'DETAIL_PICTURE',
463 'PREVIEW_TEXT',
464 'PREVIEW_TEXT_TYPE',
465 'DETAIL_TEXT',
466 'DETAIL_TEXT_TYPE',
467 ],
468 array_keys($additionalFilter)
469 )));
470 $navParams = false;
471 if ($limit > 0)
472 {
473 $navParams = [
474 'nTopCount' => $limit,
475 ];
476 }
477
478 $elementIterator = \CIBlockElement::GetList(
479 ['ID' => 'DESC'],
480 array_merge($filter, $additionalFilter),
481 false,
482 $navParams,
483 $shortSelect
484 );
485 while ($row = $elementIterator->Fetch())
486 {
487 $row['ID'] = (int)$row['ID'];
488 $row['IBLOCK_ID'] = (int)$row['IBLOCK_ID'];
489
490 $elements[$row['ID']] = $row;
491 }
492 unset($row, $elementIterator);
493
494 if (!empty($elements))
495 {
496 $elementIterator = \CIBlockElement::GetList(
497 [],
498 [
499 'ID' => array_keys($elements)
500 ],
501 false,
502 false,
503 $selectFields
504 );
505 while ($row = $elementIterator->Fetch())
506 {
507 $id = (int)$row['ID'];
508 unset($row['ID'], $row['IBLOCK_ID']);
509
510 $row['TYPE'] = (int)$row['TYPE'];
511 $row['IMAGE'] = null;
512 $row['PRICE'] = null;
513 $row['SKU_PROPERTIES'] = null;
514
515 if (!empty($row['PREVIEW_PICTURE']))
516 {
517 $row['IMAGE'] = $this->getImageSource((int)$row['PREVIEW_PICTURE']);
518 }
519
520 if (empty($row['IMAGE']) && !empty($row['DETAIL_PICTURE']))
521 {
522 $row['IMAGE'] = $this->getImageSource((int)$row['DETAIL_PICTURE']);
523 }
524
525 if (!empty($row['PREVIEW_TEXT']) && $row['PREVIEW_TEXT_TYPE'] === 'html')
526 {
527 $row['PREVIEW_TEXT'] = HTMLToTxt($row['PREVIEW_TEXT']);
528 }
529
530 if (!empty($row['DETAIL_TEXT']) && $row['DETAIL_TEXT_TYPE'] === 'html')
531 {
532 $row['DETAIL_TEXT'] = HTMLToTxt($row['DETAIL_TEXT']);
533 }
534
535 $elements[$id] += $row;
536 }
537 unset($row, $elementIterator);
538 }
539
540 return $elements;
541 }
542
543 private function loadOffers(array $products, IblockInfo $iblockInfo, array $additionalFilter = []): array
544 {
545 $productsWithOffers = $this->filterProductsWithOffers($products);
546 if (empty($productsWithOffers))
547 {
548 return $products;
549 }
550
551 $skuPropertyId = 'PROPERTY_' . $iblockInfo->getSkuPropertyId();
552 $offerFilter = [
553 'IBLOCK_ID' => $iblockInfo->getSkuIblockId(),
554 $skuPropertyId => array_keys($productsWithOffers),
555 ];
556 if (!empty($additionalFilter))
557 {
558 $offerFilter = array_merge($offerFilter, $additionalFilter);
559 }
560
561 // first - load offers with coincidence in searchable content or by offer ids
562 $offers = $this->loadElements(['filter' => $offerFilter]);
563 $offers = array_column($offers, null, $skuPropertyId . '_VALUE');
564
565 $productsStillWithoutOffers = array_diff_key($productsWithOffers, $offers);
566 if (!empty($productsStillWithoutOffers))
567 {
568 // second - load any offer for product if you have no coincidences in searchable content
569 $additionalOffers = $this->loadElements([
570 'filter' => [
571 'IBLOCK_ID' => $iblockInfo->getSkuIblockId(),
572 $skuPropertyId => array_keys($productsStillWithoutOffers),
573 ],
574 ]);
575 $additionalOffers = array_column($additionalOffers, null, $skuPropertyId . '_VALUE');
576 $offers = array_merge($offers, $additionalOffers);
577 }
578
579 if (!empty($offers))
580 {
581 $offers = array_column($offers, null, 'ID');
582 $offers = $this->loadProperties($offers, $iblockInfo->getSkuIblockId(), $iblockInfo);
583 $products = $this->matchProductOffers($products, $offers, $skuPropertyId . '_VALUE');
584 }
585
586 return $products;
587 }
588
589 protected function loadPrices(array $elements): array
590 {
591 if (empty($elements))
592 {
593 return [];
594 }
595
596 $variationToProductMap = [];
597 foreach ($elements as $id => $element)
598 {
599 $variationToProductMap[$element['ID']] = $id;
600 }
601
602 $priceTableResult = PriceTable::getList([
603 'select' => ['PRICE', 'CURRENCY', 'PRODUCT_ID'],
604 'filter' => [
605 'PRODUCT_ID' => array_keys($variationToProductMap),
606 '=CATALOG_GROUP_ID' => $this->getBasePriceId(),
607 [
608 'LOGIC' => 'OR',
609 '<=QUANTITY_FROM' => 1,
610 '=QUANTITY_FROM' => null,
611 ],
612 [
613 'LOGIC' => 'OR',
614 '>=QUANTITY_TO' => 1,
615 '=QUANTITY_TO' => null,
616 ],
617 ],
618 ]);
619
620 while ($price = $priceTableResult->fetch())
621 {
622 $productId = $variationToProductMap[$price['PRODUCT_ID']];
623
624 $priceValue = $price['PRICE'];
625 $currency = $price['CURRENCY'];
626 if (!empty($this->getCurrency()) && $this->getCurrency() !== $currency)
627 {
628 $priceValue = \CCurrencyRates::ConvertCurrency($priceValue, $currency, $this->getCurrency());
629 $currency = $this->getCurrency();
630 }
631
632 $formattedPrice = \CCurrencyLang::CurrencyFormat($priceValue, $currency, true);
633 $elements[$productId]['PRICE'] = $formattedPrice;
634 }
635
636 return $elements;
637 }
638
639 protected function loadBarcodes(array $elements, string $searchString): array
640 {
641 if (empty($elements))
642 {
643 return [];
644 }
645
646 $variationToProductMap = [];
647 foreach ($elements as $id => $element)
648 {
649 $element['BARCODE'] = null;
650 $variationToProductMap[$element['ID']] = $id;
651 }
652
653 $variationIds = array_keys($variationToProductMap);
654
655 if (empty($variationIds))
656 {
657 return $elements;
658 }
659
660 $barcodeRaw = \Bitrix\Catalog\StoreBarcodeTable::getList([
661 'filter' => [
662 '=PRODUCT_ID' => $variationIds,
663 'BARCODE' => $searchString . '%'
664 ],
665 'select' => ['BARCODE', 'PRODUCT_ID']
666 ]);
667
668 while ($barcode = $barcodeRaw->fetch())
669 {
670 $variationId = $barcode['PRODUCT_ID'];
671 $productId = $variationToProductMap[$variationId];
672
673 if (!isset($productId))
674 {
675 continue;
676 }
677
678 $elements[$productId]['BARCODE'] = $barcode['BARCODE'];
679 }
680
681 return $elements;
682 }
683
684 private function matchProductOffers(array $products, array $offers, string $productLinkProperty): array
685 {
686 foreach ($offers as $offer)
687 {
688 $productId = $offer[$productLinkProperty] ?? null;
689
690 if ($productId && isset($products[$productId]))
691 {
692 $fieldsToSafelyMerge = [
693 'ID',
694 'NAME',
695 'PREVIEW_PICTURE',
696 'DETAIL_PICTURE',
697 'PREVIEW_TEXT',
698 'DETAIL_TEXT',
699 'SEARCH_PROPERTIES',
700 ];
701 foreach ($fieldsToSafelyMerge as $field)
702 {
703 $products[$productId]['PARENT_' . $field] = $products[$productId][$field] ?? null;
704 $products[$productId][$field] = $offer[$field] ?? null;
705 }
706
707 if (!empty($offer['IMAGE']))
708 {
709 $products[$productId]['IMAGE'] = $offer['IMAGE'];
710 }
711
712 if (!empty($offer['SKU_PROPERTIES']))
713 {
714 $products[$productId]['SKU_PROPERTIES'] = $offer['SKU_PROPERTIES'];
715 }
716 }
717 }
718
719 return $products;
720 }
721
722 private function filterProductsWithOffers(array $products): array
723 {
724 return array_filter(
725 $products,
726 static function ($item)
727 {
728 return $item['TYPE'] === ProductTable::TYPE_SKU;
729 }
730 );
731 }
732
733 protected function loadProperties(array $elements, int $iblockId, IblockInfo $iblockInfo): array
734 {
735 if (empty($elements))
736 {
737 return [];
738 }
739
740 $propertyIds = [];
741
742 $skuTreeProperties = null;
743 if ($iblockInfo->getSkuIblockId() === $iblockId)
744 {
745 $skuTreeProperties = array_map(
746 'intval',
747 PropertyCatalogFeature::getOfferTreePropertyCodes($iblockId) ?? []
748 );
749 if (!empty($skuTreeProperties))
750 {
751 $propertyIds = array_merge($propertyIds, $skuTreeProperties);
752 }
753 }
754
755 $morePhotoId = $this->getMorePhotoPropertyId($iblockId);
756 if ($morePhotoId)
757 {
758 $propertyIds[] = $morePhotoId;
759 }
760
761 $searchProperties = $this->getSearchPropertyIds($iblockId);
762 if (!empty($searchProperties))
763 {
764 $propertyIds = array_merge($propertyIds, $searchProperties);
765 }
766
767 if (empty($propertyIds))
768 {
769 return $elements;
770 }
771
772 $elementPropertyValues = array_fill_keys(array_keys($elements), []);
773 $offersFilter = [
774 'IBLOCK_ID' => $iblockId,
775 'ID' => array_column($elements, 'ID'),
776 ];
777 $propertyFilter = [
778 'ID' => array_unique($propertyIds),
779 ];
780 \CIBlockElement::GetPropertyValuesArray($elementPropertyValues, $iblockId, $offersFilter, $propertyFilter);
781
782 foreach ($elementPropertyValues as $elementId => $elementProperties)
783 {
784 if (empty($elementProperties))
785 {
786 continue;
787 }
788
789 $currentElement =& $elements[$elementId];
790
791 foreach ($elementProperties as $property)
792 {
793 $propertyId = (int)$property['ID'];
794
795 if ($propertyId === $morePhotoId)
796 {
797 if (empty($currentElement['IMAGE']))
798 {
799 $propertyValue = is_array($property['VALUE']) ? reset($property['VALUE']) : $property['VALUE'];
800 if ((int)$propertyValue > 0)
801 {
802 $currentElement['IMAGE'] = $this->getImageSource((int)$propertyValue);
803 }
804 }
805 }
806 else
807 {
808 $isArray = is_array($property['~VALUE']);
809 if (
810 ($isArray && !empty($property['~VALUE']))
811 || (!$isArray && (string)$property['~VALUE'] !== '')
812 )
813 {
814 $propertyValue = $this->getPropertyDisplayValue($property);
815 if ($propertyValue !== '')
816 {
817 if ($skuTreeProperties !== null && in_array($propertyId, $skuTreeProperties, true))
818 {
819 $currentElement['SKU_PROPERTIES'][$propertyId] = $propertyValue;
820 }
821 else
822 {
823 $currentElement['SEARCH_PROPERTIES'][$propertyId] = $propertyValue;
824 }
825 }
826 }
827 }
828 }
829
830 $currentElement['SKU_PROPERTIES'] = !empty($currentElement['SKU_PROPERTIES'])
831 ? implode(', ', $currentElement['SKU_PROPERTIES'])
832 : null;
833
834 $currentElement['SEARCH_PROPERTIES'] = !empty($currentElement['SEARCH_PROPERTIES'])
835 ? implode(', ', $currentElement['SEARCH_PROPERTIES'])
836 : null;
837 }
838
839 unset($currentElement);
840
841 return $elements;
842 }
843
844 private function getPropertyDisplayValue(array $property): string
845 {
846 if (!empty($property['USER_TYPE']))
847 {
848 $userType = \CIBlockProperty::GetUserType($property['USER_TYPE']);
849 $searchMethod = $userType['GetSearchContent'] ?? null;
850
851 if ($searchMethod && is_callable($searchMethod))
852 {
853 $value = $searchMethod($property, ['VALUE' => $property['~VALUE']], []);
854 }
855 else
856 {
857 $value = '';
858 }
859 }
860 else
861 {
862 $value = $property['~VALUE'] ?? '';
863 }
864
865 if (is_array($value))
866 {
867 $value = implode(', ', $value);
868 }
869
870 return trim((string)$value);
871 }
872
873 private function getMorePhotoPropertyId(int $iblockId): ?int
874 {
875 $iterator = PropertyTable::getList([
876 'select' => ['ID'],
877 'filter' => [
878 '=IBLOCK_ID' => $iblockId,
879 '=CODE' => \CIBlockPropertyTools::CODE_MORE_PHOTO,
880 '=ACTIVE' => 'Y',
881 ],
882 ]);
883 if ($row = $iterator->fetch())
884 {
885 return (int)$row['ID'];
886 }
887
888 return null;
889 }
890
891 private function getSearchPropertyIds(int $iblockId): array
892 {
893 $properties = PropertyTable::getList([
894 'select' => ['ID'],
895 'filter' => [
896 '=IBLOCK_ID' => $iblockId,
897 '=ACTIVE' => 'Y',
898 '=SEARCHABLE' => 'Y',
899 '@PROPERTY_TYPE' => [
900 PropertyTable::TYPE_STRING,
901 PropertyTable::TYPE_NUMBER,
902 PropertyTable::TYPE_LIST,
903 ],
904 ],
905 'order' => ['SORT' => 'ASC', 'ID' => 'ASC'],
906 ])->fetchAll()
907 ;
908
909 return array_map('intval', array_column($properties, 'ID'));
910 }
911
912 protected function shouldDisableCache(array $products): bool
913 {
914 if (count($products) >= self::PRODUCT_LIMIT)
915 {
916 return true;
917 }
918
919 foreach ($products as $product)
920 {
921 if (!empty($product['PARENT_ID']))
922 {
923 return true;
924 }
925 }
926
927 return false;
928 }
929}
static getProductTypes($descr=false)
Definition product.php:824
loadProperties(array $elements, int $iblockId, IblockInfo $iblockInfo)
static getList(array $parameters=array())
loadPreselectedItems($preselectedMode=true)
Definition dialog.php:389