1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
comp_pricetools.php
См. документацию.
1<?
10
11Loc::loadMessages(__FILE__);
12
14{
15 protected static $catalogIncluded = null;
16 protected static $highLoadInclude = null;
17 protected static $saleIncluded = null;
18 protected static $needDiscountCache = null;
19 protected static $calculationDiscounts = 0;
20
27 public static function GetCatalogPrices($IBLOCK_ID, $arPriceCode)
28 {
29 global $USER;
30 $arCatalogPrices = array();
31 if (self::$catalogIncluded === null)
32 self::$catalogIncluded = Loader::includeModule('catalog');
33 if (self::$catalogIncluded)
34 {
35 $arCatalogGroupCodesFilter = array();
36 foreach($arPriceCode as $value)
37 {
38 $t_value = trim($value);
39 if ('' != $t_value)
40 $arCatalogGroupCodesFilter[$value] = true;
41 }
42 $arCatalogGroupsFilter = array();
43 $arCatalogGroups = CCatalogGroup::GetListArray();
44 foreach ($arCatalogGroups as $key => $value)
45 {
46 if (isset($arCatalogGroupCodesFilter[$value['NAME']]))
47 {
48 $arCatalogGroupsFilter[] = $key;
49 $arCatalogPrices[$value["NAME"]] = array(
50 "ID" => (int)$value["ID"],
51 "CODE" => $value["NAME"],
52 "SORT" => (int)$value["SORT"],
53 "BASE" => $value["BASE"],
54 "XML_ID" => $value["XML_ID"],
55 "TITLE" => htmlspecialcharsbx($value["NAME_LANG"]),
56 "~TITLE" => $value["NAME_LANG"],
57 "SELECT" => "CATALOG_GROUP_".$value["ID"],
58 "SELECT_EXTENDED" => array("PRICE_".$value["ID"], "CURRENCY_".$value["ID"], "SCALED_PRICE_".$value["ID"])
59 );
60 }
61 }
62 $userGroups = array(2);
63 if (isset($USER) && $USER instanceof CUser)
64 $userGroups = $USER->GetUserGroupArray();
65 $arPriceGroups = CCatalogGroup::GetGroupsPerms($userGroups, $arCatalogGroupsFilter);
66 foreach($arCatalogPrices as $name=>$value)
67 {
68 $arCatalogPrices[$name]["CAN_VIEW"] = in_array($value["ID"], $arPriceGroups["view"]);
69 $arCatalogPrices[$name]["CAN_BUY"] = in_array($value["ID"], $arPriceGroups["buy"]);
70 }
71 }
72 else
73 {
74 $rsProperties = CIBlockProperty::GetList(array(), array(
75 "IBLOCK_ID" => $IBLOCK_ID,
76 "CHECK_PERMISSIONS" => "N",
77 "PROPERTY_TYPE" => "N",
78 "MULTIPLE" => "N"
79 ));
80 while ($arProperty = $rsProperties->Fetch())
81 {
82 if (in_array($arProperty["CODE"], $arPriceCode))
83 {
84 $arCatalogPrices[$arProperty["CODE"]] = array(
85 "ID" => (int)$arProperty["ID"],
86 "CODE" => $arProperty["CODE"],
87 "SORT" => (int)$arProperty["SORT"],
88 "BASE" => "N",
89 "XML_ID" => $arProperty["XML_ID"],
90 "TITLE" => htmlspecialcharsbx($arProperty["NAME"]),
91 "~TITLE" => $arProperty["NAME"],
92 "SELECT" => "PROPERTY_".$arProperty["ID"],
93 "SELECT_EXTENDED" => array("PROPERTY_".$arProperty["ID"]),
94 "CAN_VIEW"=>true,
95 "CAN_BUY"=>false,
96 );
97 }
98 }
99 }
100 return $arCatalogPrices;
101 }
102
107 public static function GetAllowCatalogPrices($arPriceTypes)
108 {
109 $arResult = array();
110 if (empty($arPriceTypes) || !is_array($arPriceTypes))
111 return $arResult;
112
113 foreach ($arPriceTypes as $arOnePriceType)
114 {
115 if ($arOnePriceType['CAN_VIEW'] || $arOnePriceType['CAN_BUY'])
116 $arResult[] = (int)$arOnePriceType['ID'];
117 }
118 unset($arOnePriceType);
119 if (!empty($arResult))
121 return $arResult;
122 }
123
124 public static function SetCatalogDiscountCache($arCatalogGroups, $arUserGroups, $siteId = false)
125 {
126 $result = false;
127
128 if (!is_array($arUserGroups))
129 return $result;
131 if (empty($arUserGroups))
132 return $result;
133
134 if ($siteId === false)
136
137 if(\Bitrix\Main\Config\Option::get('sale', 'use_sale_discount_only') === 'Y')
138 {
139 self::$needDiscountCache = false;
140 if (self::$saleIncluded === null)
141 self::$saleIncluded = Loader::includeModule('sale');
142 if (self::$saleIncluded)
143 {
145 $ids = $cache->getDiscountIds($arUserGroups);
146 if (!empty($ids))
147 {
148 $discountList = $cache->getDiscounts(
149 $ids,
150 ['all', 'catalog'],
151 $siteId,
152 []
153 );
154 if (!empty($discountList))
155 {
156 $result = true;
157 }
158 }
159 }
160 return $result;
161 }
162
163 if (self::$catalogIncluded === null)
164 self::$catalogIncluded = Loader::includeModule('catalog');
165 if (self::$catalogIncluded)
166 {
167 if (!is_array($arCatalogGroups))
168 return $result;
170 if (empty($arUserGroups))
171 return $result;
172
173 $arRestFilter = array(
174 'PRICE_TYPES' => $arCatalogGroups,
175 'USER_GROUPS' => $arUserGroups,
176 );
177 $arRest = CCatalogDiscount::GetRestrictions($arRestFilter, false, false);
178 $arDiscountFilter = array();
179 $arDiscountResult = array();
180 if (empty($arRest) || (array_key_exists('DISCOUNTS', $arRest) && empty($arRest['DISCOUNTS'])))
181 {
182 foreach ($arCatalogGroups as $intOneGroupID)
183 {
184 $strCacheKey = CCatalogDiscount::GetDiscountFilterCacheKey(array($intOneGroupID), $arUserGroups, false);
185 $arDiscountFilter[$strCacheKey] = array();
186 }
187 unset($intOneGroupID);
188 }
189 else
190 {
191 $arResultDiscountList = array();
192
193 $select = array(
194 'ID', 'TYPE', 'SITE_ID', 'ACTIVE', 'ACTIVE_FROM', 'ACTIVE_TO',
195 'RENEWAL', 'NAME', 'SORT', 'MAX_DISCOUNT', 'VALUE_TYPE', 'VALUE', 'CURRENCY',
196 'PRIORITY', 'LAST_DISCOUNT',
197 'USE_COUPONS', 'UNPACK', 'CONDITIONS'
198 );
199 $currentDatetime = new Main\Type\DateTime();
200 $discountRows = array_chunk($arRest['DISCOUNTS'], 500);
201 foreach ($discountRows as $pageIds)
202 {
203 $discountFilter = array(
204 '@ID' => $pageIds,
205 '=SITE_ID' => $siteId,
207 array(
208 'LOGIC' => 'OR',
209 'ACTIVE_FROM' => '',
210 '<=ACTIVE_FROM' => $currentDatetime
211 ),
212 array(
213 'LOGIC' => 'OR',
214 'ACTIVE_TO' => '',
215 '>=ACTIVE_TO' => $currentDatetime
216 ),
217 '=USE_COUPONS' => 'N',
218 '=RENEWAL' => 'N',
219 );
220 CTimeZone::Disable();
221 $iterator = Catalog\DiscountTable::getList(array(
222 'select' => $select,
223 'filter' => $discountFilter
224 ));
225 while ($row = $iterator->fetch())
226 {
227 $row['ID'] = (int)$row['ID'];
228 $row['HANDLERS'] = array();
229 $row['MODULE_ID'] = 'catalog';
230 $row['TYPE'] = (int)$row['TYPE'];
231 if ($row['ACTIVE_FROM'] instanceof Main\Type\DateTime)
232 $row['ACTIVE_FROM'] = $row['ACTIVE_FROM']->toString();
233 if ($row['ACTIVE_TO'] instanceof Main\Type\DateTime)
234 $row['ACTIVE_TO'] = $row['ACTIVE_TO']->toString();
235 $row['COUPON_ACTIVE'] = '';
236 $row['COUPON'] = '';
237 $row['COUPON_ONE_TIME'] = null;
238 $arResultDiscountList[$row['ID']] = $row;
239 }
240 unset($row, $iterator);
241 CTimeZone::Enable();
242 }
243 unset($pageIds, $discountRows);
244
245 foreach ($arCatalogGroups as $intOneGroupID)
246 {
247 $strCacheKey = CCatalogDiscount::GetDiscountFilterCacheKey(array($intOneGroupID), $arUserGroups, false);
248 $arDiscountDetailList = array();
249 $arDiscountList = array();
250 foreach ($arRest['RESTRICTIONS'] as $intDiscountID => $arDiscountRest)
251 {
252 if (empty($arDiscountRest['PRICE_TYPE']) || array_key_exists($intOneGroupID, $arDiscountRest['PRICE_TYPE']))
253 {
254 $arDiscountList[] = $intDiscountID;
255 if (isset($arResultDiscountList[$intDiscountID]))
256 $arDiscountDetailList[] = $arResultDiscountList[$intDiscountID];
257 }
258 }
259 sort($arDiscountList);
260 $arDiscountFilter[$strCacheKey] = $arDiscountList;
261 $strResultCacheKey = CCatalogDiscount::GetDiscountResultCacheKey($arDiscountList, $siteId, 'N');
262 $arDiscountResult[$strResultCacheKey] = $arDiscountDetailList;
263 }
264 unset($intOneGroupID);
265 }
266 $boolFlag = CCatalogDiscount::SetAllDiscountFilterCache($arDiscountFilter, false);
267 $boolFlagExt = CCatalogDiscount::SetAllDiscountResultCache($arDiscountResult);
268 $result = $boolFlag && $boolFlagExt;
269 self::$needDiscountCache = $result;
270 }
271 return $result;
272 }
273
274 public static function GetItemPrices($IBLOCK_ID,
276 $arCatalogPrices,
277 $arItem, $bVATInclude = true,
278 $arCurrencyParams = array(),
279 $USER_ID = 0,
280 $LID = SITE_ID
281 )
282 {
283 $arPrices = array();
284
285 if (empty($arCatalogPrices) || !is_array($arCatalogPrices))
286 return $arPrices;
287
288 global $USER;
289 static $arCurUserGroups = array();
290 static $strBaseCurrency = '';
291
292 if (self::$catalogIncluded === null)
293 self::$catalogIncluded = Loader::includeModule('catalog');
294 if (self::$catalogIncluded)
295 {
296 $existUser = (isset($USER) && $USER instanceof CUser);
297 $USER_ID = (int)$USER_ID;
298 $intUserID = ($USER_ID > 0 ? $USER_ID : 0);
299 if ($intUserID == 0 && $existUser)
300 $intUserID = (int)$USER->GetID();
301 if (!isset($arCurUserGroups[$intUserID]))
302 {
303 $arUserGroups = array(2);
304 if ($intUserID > 0)
305 $arUserGroups = CUser::GetUserGroup($intUserID);
306 elseif ($existUser)
307 $arUserGroups = $USER->GetUserGroupArray();
309 $arCurUserGroups[$intUserID] = $arUserGroups;
310 unset($arUserGroups);
311 }
312 $arUserGroups = $arCurUserGroups[$intUserID];
313
314 $boolConvert = false;
315 $resultCurrency = '';
316 if (isset($arCurrencyParams['CURRENCY_ID']) && !empty($arCurrencyParams['CURRENCY_ID']))
317 {
318 $boolConvert = true;
319 $resultCurrency = $arCurrencyParams['CURRENCY_ID'];
320 }
321 if (!$boolConvert && '' == $strBaseCurrency)
322 $strBaseCurrency = Currency\CurrencyManager::getBaseCurrency();
323
324 $percentVat = $arItem['CATALOG_VAT'] * 0.01;
325 $percentPriceWithVat = 1 + $arItem['CATALOG_VAT'] * 0.01;
326
327 $strMinCode = '';
328 $boolStartMin = true;
329 $dblMinPrice = 0;
330 $strMinCurrency = ($boolConvert ? $resultCurrency : $strBaseCurrency);
332 foreach ($arCatalogPrices as $key => $value)
333 {
334 $catalogPriceValue = 'CATALOG_PRICE_'.$value['ID'];
335 $catalogCurrencyValue = 'CATALOG_CURRENCY_'.$value['ID'];
336 if (
337 !$value['CAN_VIEW']
338 || !isset($arItem[$catalogPriceValue])
339 || $arItem[$catalogPriceValue] == ''
340 )
341 continue;
342
343 $arItem[$catalogPriceValue] = (float)$arItem[$catalogPriceValue];
344 // get final price with VAT included.
345 if ($arItem['CATALOG_VAT_INCLUDED'] != 'Y')
346 $arItem[$catalogPriceValue] *= $percentPriceWithVat;
347
348 $originalCurrency = $arItem[$catalogCurrencyValue];
349 $calculateCurrency = $arItem[$catalogCurrencyValue];
350 $calculatePrice = $arItem[$catalogPriceValue];
351 $cnangeCurrency = ($boolConvert && $resultCurrency != $calculateCurrency);
352 if ($cnangeCurrency)
353 {
354 $calculateCurrency = $resultCurrency;
355 $calculatePrice = CCurrencyRates::ConvertCurrency($calculatePrice, $originalCurrency, $resultCurrency);
356 }
357
358 // so discounts will include VAT
359 $discounts = array();
360 if (self::isEnabledCalculationDiscounts())
361 {
362 $discounts = CCatalogDiscount::GetDiscount(
363 $arItem['ID'],
364 $arItem['IBLOCK_ID'],
365 array($value['ID']),
366 $arUserGroups,
367 'N',
368 $LID,
369 array()
370 );
371 }
373 $calculatePrice,
374 $calculateCurrency,
375 $discounts
376 );
377 unset($discounts);
378 if ($discountPrice === false)
379 continue;
380
381 $originalPriceWithVat = $arItem[$catalogPriceValue];
382 $priceWithVat = $calculatePrice;
383 $discountPriceWithVat = $discountPrice;
384
385 if ($cnangeCurrency)
386 $originalDiscountPrice = CCurrencyRates::ConvertCurrency($discountPrice, $calculateCurrency, $arItem[$catalogCurrencyValue]);
387 else
388 $originalDiscountPrice = $discountPrice;
389 $originalDiscountPriceWithVat = $originalDiscountPrice;
390
391 $arItem[$catalogPriceValue] /= $percentPriceWithVat;
392 $calculatePrice /= $percentPriceWithVat;
393 $originalDiscountPrice /= $percentPriceWithVat;
394 $discountPrice /= $percentPriceWithVat;
395
396 $originalVatValue = $originalPriceWithVat - $arItem[$catalogPriceValue];
397 $vatValue = $priceWithVat - $calculatePrice;
398 $originalDiscountVatValue = $originalDiscountPriceWithVat - $originalDiscountPrice;
399 $discountVatValue = $discountPriceWithVat - $discountPrice;
400
401 $roundPriceWithVat = Catalog\Product\Price::roundPrice($value['ID'], $discountPriceWithVat, $calculateCurrency);
402 $roundPrice = Catalog\Product\Price::roundPrice($value['ID'], $discountPrice, $calculateCurrency);
403
404 $priceResult = array(
405 'VALUE_NOVAT' => $calculatePrice,
406 'PRINT_VALUE_NOVAT' => CCurrencyLang::CurrencyFormat($calculatePrice, $calculateCurrency, true),
407
408 'VALUE_VAT' => $priceWithVat,
409 'PRINT_VALUE_VAT' => CCurrencyLang::CurrencyFormat($priceWithVat, $calculateCurrency, true),
410
411 'VATRATE_VALUE' => $vatValue,
412 'PRINT_VATRATE_VALUE' => CCurrencyLang::CurrencyFormat($vatValue, $calculateCurrency, true),
413
414 'DISCOUNT_VALUE_NOVAT' => $discountPrice,
415 'PRINT_DISCOUNT_VALUE_NOVAT' => CCurrencyLang::CurrencyFormat($discountPrice, $calculateCurrency, true),
416
417 'DISCOUNT_VALUE_VAT' => $discountPriceWithVat,
418 'PRINT_DISCOUNT_VALUE_VAT' => CCurrencyLang::CurrencyFormat($discountPriceWithVat, $calculateCurrency, true),
419
420 'DISCOUNT_VATRATE_VALUE' => $discountVatValue,
421 'PRINT_DISCOUNT_VATRATE_VALUE' => CCurrencyLang::CurrencyFormat($discountVatValue, $calculateCurrency, true),
422
423 'CURRENCY' => $calculateCurrency,
424
425 'ROUND_VALUE_VAT' => $roundPriceWithVat,
426 'ROUND_VALUE_NOVAT' => $roundPrice,
427 'ROUND_VATRATE_VALUE' => $roundPriceWithVat - $roundPrice,
428 );
429
430 if ($cnangeCurrency)
431 {
432 $priceResult['ORIG_VALUE_NOVAT'] = $arItem[$catalogPriceValue];
433 $priceResult['ORIG_VALUE_VAT'] = $originalPriceWithVat;
434 $priceResult['ORIG_VATRATE_VALUE'] = $originalVatValue;
435 $priceResult['ORIG_DISCOUNT_VALUE_NOVAT'] = $originalDiscountPrice;
436 $priceResult['ORIG_DISCOUNT_VALUE_VAT'] = $originalDiscountPriceWithVat;
437 $priceResult['ORIG_DISCOUNT_VATRATE_VALUE'] = $originalDiscountVatValue;
438 $priceResult['ORIG_CURRENCY'] = $originalCurrency;
439 }
440
441 $priceResult['PRICE_ID'] = $value['ID'];
442 $priceResult['ID'] = $arItem['CATALOG_PRICE_ID_'.$value['ID']];
443 $priceResult['CAN_ACCESS'] = $arItem['CATALOG_CAN_ACCESS_'.$value['ID']];
444 $priceResult['CAN_BUY'] = $arItem['CATALOG_CAN_BUY_'.$value['ID']];
445 $priceResult['MIN_PRICE'] = 'N';
446
447 if ($bVATInclude)
448 {
449 $priceResult['VALUE'] = $priceWithVat;
450 $priceResult['PRINT_VALUE'] = $priceResult['PRINT_VALUE_VAT'];
451 $priceResult['UNROUND_DISCOUNT_VALUE'] = $discountPriceWithVat;
452 $priceResult['DISCOUNT_VALUE'] = $roundPriceWithVat;
453 $priceResult['PRINT_DISCOUNT_VALUE'] = CCurrencyLang::CurrencyFormat(
454 $roundPriceWithVat,
455 $calculateCurrency,
456 true
457 );
458 }
459 else
460 {
461 $priceResult['VALUE'] = $calculatePrice;
462 $priceResult['PRINT_VALUE'] = $priceResult['PRINT_VALUE_NOVAT'];
463 $priceResult['UNROUND_DISCOUNT_VALUE'] = $discountPrice;
464 $priceResult['DISCOUNT_VALUE'] = $roundPrice;
465 $priceResult['PRINT_DISCOUNT_VALUE'] = CCurrencyLang::CurrencyFormat(
466 $roundPrice,
467 $calculateCurrency,
468 true
469 );;
470 }
471
472 if ((roundEx($priceResult['VALUE'], 2) - roundEx($priceResult['UNROUND_DISCOUNT_VALUE'], 2)) < 0.01)
473 {
474 $priceResult['VALUE'] = $priceResult['DISCOUNT_VALUE'];
475 $priceResult['PRINT_VALUE'] = $priceResult['PRINT_DISCOUNT_VALUE'];
476 $priceResult['DISCOUNT_DIFF'] = 0;
477 $priceResult['DISCOUNT_DIFF_PERCENT'] = 0;
478 }
479 else
480 {
481 $priceResult['DISCOUNT_DIFF'] = $priceResult['VALUE'] - $priceResult['DISCOUNT_VALUE'];
482 $priceResult['DISCOUNT_DIFF_PERCENT'] = roundEx(100*$priceResult['DISCOUNT_DIFF']/$priceResult['VALUE'], 0);
483 }
484 $priceResult['PRINT_DISCOUNT_DIFF'] = CCurrencyLang::CurrencyFormat(
485 $priceResult['DISCOUNT_DIFF'],
486 $calculateCurrency,
487 true
488 );
489
490 if ($boolStartMin)
491 {
492 $dblMinPrice = ($boolConvert || ($calculateCurrency == $strMinCurrency)
493 ? $priceResult['DISCOUNT_VALUE']
494 : CCurrencyRates::ConvertCurrency($priceResult['DISCOUNT_VALUE'], $calculateCurrency, $strMinCurrency)
495 );
496 $strMinCode = $key;
497 $boolStartMin = false;
498 }
499 else
500 {
501 $dblComparePrice = ($boolConvert || ($calculateCurrency == $strMinCurrency)
502 ? $priceResult['DISCOUNT_VALUE']
503 : CCurrencyRates::ConvertCurrency($priceResult['DISCOUNT_VALUE'], $calculateCurrency, $strMinCurrency)
504 );
505 if ($dblMinPrice > $dblComparePrice)
506 {
507 $dblMinPrice = $dblComparePrice;
508 $strMinCode = $key;
509 }
510 }
511 unset($calculateCurrency);
512 unset($originalCurrency);
513
514 $arPrices[$key] = $priceResult;
515 unset($priceResult);
516 }
517 if ($strMinCode != '')
518 $arPrices[$strMinCode]['MIN_PRICE'] = 'Y';
520
521 unset($percentPriceWithVat);
522 unset($percentVat);
523 }
524 else
525 {
526 $strMinCode = '';
527 $boolStartMin = true;
528 $dblMinPrice = 0;
529 foreach($arCatalogPrices as $key => $value)
530 {
531 if (!$value['CAN_VIEW'])
532 continue;
533
534 $dblValue = round(doubleval($arItem["PROPERTY_".$value["ID"]."_VALUE"]), 2);
535 if ($boolStartMin)
536 {
537 $dblMinPrice = $dblValue;
538 $strMinCode = $key;
539 $boolStartMin = false;
540 }
541 else
542 {
543 if ($dblMinPrice > $dblValue)
544 {
545 $dblMinPrice = $dblValue;
546 $strMinCode = $key;
547 }
548 }
549 $arPrices[$key] = array(
550 "ID" => $arItem["PROPERTY_".$value["ID"]."_VALUE_ID"],
551 "VALUE" => $dblValue,
552 "PRINT_VALUE" => $dblValue." ".$arItem["PROPERTY_".$value["ID"]."_DESCRIPTION"],
553 "DISCOUNT_VALUE" => $dblValue,
554 "PRINT_DISCOUNT_VALUE" => $dblValue." ".$arItem["PROPERTY_".$value["ID"]."_DESCRIPTION"],
555 "CURRENCY" => $arItem["PROPERTY_".$value["ID"]."_DESCRIPTION"],
556 "CAN_ACCESS" => true,
557 "CAN_BUY" => false,
558 'DISCOUNT_DIFF_PERCENT' => 0,
559 'DISCOUNT_DIFF' => 0,
560 'PRINT_DISCOUNT_DIFF' => '0 '.$arItem["PROPERTY_".$value["ID"]."_DESCRIPTION"],
561 "MIN_PRICE" => "N",
562 'PRICE_ID' => $value['ID']
563 );
564 }
565 if ($strMinCode != '')
566 $arPrices[$strMinCode]['MIN_PRICE'] = 'Y';
567 }
568 return $arPrices;
569 }
570
577 public static function CanBuy($IBLOCK_ID,
579 $arCatalogPrices,
580 $arItem
581 )
582 {
583 if (isset($arItem['ACTIVE']) && $arItem['ACTIVE'] === 'N')
584 return false;
585
586 if (isset($arItem['CATALOG_AVAILABLE']) && $arItem['CATALOG_AVAILABLE'] === 'N')
587 return false;
588 if (isset($arItem['AVAILABLE']) && $arItem['AVAILABLE'] === 'N')
589 return false;
590
591 if (!empty($arItem["PRICE_MATRIX"]) && is_array($arItem["PRICE_MATRIX"]))
592 {
593 return $arItem["PRICE_MATRIX"]["AVAILABLE"] == "Y";
594 }
595 else
596 {
597 if (empty($arCatalogPrices) || !is_array($arCatalogPrices))
598 return false;
599
600 foreach ($arCatalogPrices as $arPrice)
601 {
602 //if ($arPrice["CAN_BUY"] && isset($arItem["CATALOG_PRICE_".$arPrice["ID"]]) && $arItem["CATALOG_PRICE_".$arPrice["ID"]] !== null)
603 if ($arPrice["CAN_BUY"] && isset($arItem["CATALOG_PRICE_".$arPrice["ID"]]))
604 return true;
605 }
606 }
607 return false;
608 }
609
610 public static function GetProductProperties(
611 $IBLOCK_ID,$ELEMENT_ID,
613 $arPropertiesList,
614 $arPropertiesValues
615 )
616 {
617 static $cache = array();
618 static $userTypeList = array();
619 $propertyTypeSupport = array(
620 'Y' => array(
621 'N' => true,
622 'S' => true,
623 'L' => true,
624 'G' => true,
625 'E' => true
626 ),
627 'N' => array(
628 'L' => true,
629 'E' => true
630 )
631 );
632
633 $result = array();
634 foreach ($arPropertiesList as $pid)
635 {
636 if (preg_match("/[^A-Za-z0-9_]/", $pid) || !isset($arPropertiesValues[$pid]))
637 continue;
638 $prop = $arPropertiesValues[$pid];
639 $prop['ID'] = (int)$prop['ID'];
640 if (!isset($propertyTypeSupport[$prop['MULTIPLE']][$prop['PROPERTY_TYPE']]))
641 {
642 continue;
643 }
644 $emptyValues = true;
645 $productProp = array('VALUES' => array(), 'SELECTED' => false, 'SET' => false);
646
647 $userTypeProp = false;
648 $userType = null;
649 if (isset($prop['USER_TYPE']) && !empty($prop['USER_TYPE']))
650 {
651 if (!isset($userTypeList[$prop['USER_TYPE']]))
652 {
653 $userTypeDescr = CIBlockProperty::GetUserType($prop['USER_TYPE']);
654 if (isset($userTypeDescr['GetPublicViewHTML']))
655 {
656 $userTypeList[$prop['USER_TYPE']] = $userTypeDescr['GetPublicViewHTML'];
657 }
658 }
659 if (isset($userTypeList[$prop['USER_TYPE']]))
660 {
661 $userTypeProp = true;
662 $userType = $userTypeList[$prop['USER_TYPE']];
663 }
664 }
665
666 if ($prop["MULTIPLE"] == "Y" && !empty($prop["VALUE"]) && is_array($prop["VALUE"]))
667 {
668 if ($userTypeProp)
669 {
670 $countValues = 0;
671 foreach($prop["VALUE"] as $value)
672 {
673 if (!is_scalar($value))
674 continue;
675 $value = (string)$value;
676 $displayValue = (string)call_user_func_array($userType,
677 array(
678 $prop,
679 array('VALUE' => $value),
680 array(array('MODE' => 'SIMPLE_TEXT'))
681 ));
682 if ('' !== $displayValue)
683 {
684 if ($productProp["SELECTED"] === false)
685 $productProp["SELECTED"] = $value;
686 $productProp["VALUES"][$value] = htmlspecialcharsbx($displayValue);
687 $emptyValues = false;
688 $countValues++;
689 }
690 }
691 $productProp['SET'] = ($countValues === 1);
692 }
693 else
694 {
695 switch($prop["PROPERTY_TYPE"])
696 {
697 case "S":
698 case "N":
699 $countValues = 0;
700 foreach($prop["VALUE"] as $value)
701 {
702 if (!is_scalar($value))
703 continue;
704 $value = (string)$value;
705 if($value !== '')
706 {
707 if($productProp["SELECTED"] === false)
708 $productProp["SELECTED"] = $value;
709 $productProp["VALUES"][$value] = $value;
710 $emptyValues = false;
711 $countValues++;
712 }
713 $productProp['SET'] = ($countValues === 1);
714 }
715 break;
716 case "G":
717 $ar = array();
718 foreach($prop["VALUE"] as $value)
719 {
720 $value = (int)$value;
721 if($value > 0)
722 $ar[] = $value;
723 }
724 if (!empty($ar))
725 {
726 $countValues = 0;
727 $rsSections = CIBlockSection::GetList(
728 array("LEFT_MARGIN"=>"ASC"),
729 array("=ID" => $ar),
730 false,
731 array('ID', 'NAME')
732 );
733 while ($arSection = $rsSections->GetNext())
734 {
735 $arSection["ID"] = (int)$arSection["ID"];
736 if ($productProp["SELECTED"] === false)
737 $productProp["SELECTED"] = $arSection["ID"];
738 $productProp["VALUES"][$arSection["ID"]] = $arSection["NAME"];
739 $emptyValues = false;
740 $countValues++;
741 }
742 $productProp['SET'] = ($countValues === 1);
743 }
744 break;
745 case "E":
746 $ar = array();
747 foreach($prop["VALUE"] as $value)
748 {
749 $value = (int)$value;
750 if($value > 0)
751 $ar[] = $value;
752 }
753 if (!empty($ar))
754 {
755 $countValues = 0;
756 $rsElements = CIBlockElement::GetList(
757 array("ID" => "ASC"),
758 array("=ID" => $ar),
759 false,
760 false,
761 array("ID", "NAME")
762 );
763 while($arElement = $rsElements->GetNext())
764 {
765 $arElement['ID'] = (int)$arElement['ID'];
766 if($productProp["SELECTED"] === false)
767 $productProp["SELECTED"] = $arElement["ID"];
768 $productProp["VALUES"][$arElement["ID"]] = $arElement["NAME"];
769 $emptyValues = false;
770 $countValues++;
771 }
772 $productProp['SET'] = ($countValues === 1);
773 }
774 break;
775 case "L":
776 $countValues = 0;
777 foreach($prop["VALUE"] as $i => $value)
778 {
779 $prop["VALUE_ENUM_ID"][$i] = (int)$prop["VALUE_ENUM_ID"][$i];
780 if($productProp["SELECTED"] === false)
781 $productProp["SELECTED"] = $prop["VALUE_ENUM_ID"][$i];
782 $productProp["VALUES"][$prop["VALUE_ENUM_ID"][$i]] = $value;
783 $emptyValues = false;
784 $countValues++;
785 }
786 $productProp['SET'] = ($countValues === 1);
787 break;
788 }
789 }
790 }
791 elseif($prop["MULTIPLE"] == "N")
792 {
793 switch($prop["PROPERTY_TYPE"])
794 {
795 case "L":
796 if (0 == (int)$prop["VALUE_ENUM_ID"])
797 {
798 if (isset($cache[$prop['ID']]))
799 {
800 $productProp = $cache[$prop['ID']];
801 $emptyValues = false;
802 }
803 else
804 {
806 array("SORT"=>"ASC", "VALUE"=>"ASC"),
807 array("IBLOCK_ID"=>$IBLOCK_ID, "PROPERTY_ID" => $prop['ID'])
808 );
809 while ($arEnum = $rsEnum->GetNext())
810 {
811 $arEnum["ID"] = (int)$arEnum["ID"];
812 $productProp["VALUES"][$arEnum["ID"]] = $arEnum["VALUE"];
813 if ($arEnum["DEF"] == "Y")
814 $productProp["SELECTED"] = $arEnum["ID"];
815 $emptyValues = false;
816 }
817 if (!$emptyValues)
818 {
819 $cache[$prop['ID']] = $productProp;
820 }
821 }
822 }
823 else
824 {
825 $prop['VALUE_ENUM_ID'] = (int)$prop['VALUE_ENUM_ID'];
826 $productProp['VALUES'][$prop['VALUE_ENUM_ID']] = $prop['VALUE'];
827 $productProp['SELECTED'] = $prop['VALUE_ENUM_ID'];
828 $productProp['SET'] = true;
829 $emptyValues = false;
830 }
831 break;
832 case "E":
833 if (0 == (int)$prop['VALUE'])
834 {
835 if (isset($cache[$prop['ID']]))
836 {
837 $productProp = $cache[$prop['ID']];
838 $emptyValues = false;
839 }
840 else
841 {
842 if($prop["LINK_IBLOCK_ID"] > 0)
843 {
844 $rsElements = CIBlockElement::GetList(
845 array("NAME"=>"ASC", "SORT"=>"ASC"),
846 array("IBLOCK_ID"=>$prop["LINK_IBLOCK_ID"], "ACTIVE"=>"Y"),
847 false, false,
848 array("ID", "NAME")
849 );
850 while ($arElement = $rsElements->GetNext())
851 {
852 $arElement['ID'] = (int)$arElement['ID'];
853 if($productProp["SELECTED"] === false)
854 $productProp["SELECTED"] = $arElement["ID"];
855 $productProp["VALUES"][$arElement["ID"]] = $arElement["NAME"];
856 $emptyValues = false;
857 }
858 if (!$emptyValues)
859 {
860 $cache[$prop['ID']] = $productProp;
861 }
862 }
863 }
864 }
865 else
866 {
867 $rsElements = CIBlockElement::GetList(
868 array(),
869 array('ID' => $prop["VALUE"], 'ACTIVE' => 'Y'),
870 false,
871 false,
872 array('ID', 'NAME')
873 );
874 if ($arElement = $rsElements->GetNext())
875 {
876 $arElement['ID'] = (int)$arElement['ID'];
877 $productProp['VALUES'][$arElement['ID']] = $arElement['NAME'];
878 $productProp['SELECTED'] = $arElement['ID'];
879 $productProp['SET'] = true;
880 $emptyValues = false;
881 }
882 }
883 break;
884 }
885 }
886
887 if (!$emptyValues)
888 {
889 $result[$pid] = $productProp;
890 }
891 }
892
893 return $result;
894 }
895
896 public static function getFillProductProperties($productProps)
897 {
898 $result = array();
899 if (!empty($productProps) && is_array($productProps))
900 {
901 foreach ($productProps as $propID => $propInfo)
902 {
903 if (isset($propInfo['SET']) && $propInfo['SET'])
904 {
905 $result[$propID] = array(
906 'ID' => $propInfo['SELECTED'],
907 'VALUE' => $propInfo['VALUES'][$propInfo['SELECTED']]
908 );
909 }
910 }
911 }
912 return $result;
913 }
914
915 /*
916 Checks arPropertiesValues against DB values
917 returns array on success
918 or number on fail (may be used for debug)
919 */
920 public static function CheckProductProperties($iblockID, $elementID, $propertiesList, $propertiesValues, $enablePartialList = false)
921 {
922 $propertyTypeSupport = array(
923 'Y' => array(
924 'N' => true,
925 'S' => true,
926 'L' => true,
927 'G' => true,
928 'E' => true
929 ),
930 'N' => array(
931 'L' => true,
932 'E' => true
933 )
934 );
935 $iblockID = (int)$iblockID;
936 $elementID = (int)$elementID;
937 if (0 >= $iblockID || 0 >= $elementID)
938 return 6;
939 $enablePartialList = (true === $enablePartialList);
940 $sortIndex = 1;
941 $result = array();
942 if (!is_array($propertiesList))
943 $propertiesList = array();
944 if (empty($propertiesList))
945 return $result;
946 $checkProps = array_fill_keys($propertiesList, true);
947 $propCodes = $checkProps;
948 $existProps = array();
949 $rsProps = CIBlockElement::GetProperty($iblockID, $elementID, 'sort', 'asc', array());
950 while ($oneProp = $rsProps->Fetch())
951 {
952 if (!isset($propCodes[$oneProp['CODE']]) && !isset($propCodes[$oneProp['ID']]))
953 continue;
954 $propID = (isset($propCodes[$oneProp['CODE']]) ? $oneProp['CODE'] : $oneProp['ID']);
955 if (!isset($checkProps[$propID]))
956 continue;
957
958 if (!isset($propertyTypeSupport[$oneProp['MULTIPLE']][$oneProp['PROPERTY_TYPE']]))
959 {
960 return ($oneProp['MULTIPLE'] == 'Y' ? 2 : 3);
961 }
962
963 if (null !== $oneProp['VALUE'])
964 {
965 $existProps[$propID] = true;
966 }
967
968 if (!isset($propertiesValues[$propID]))
969 {
970 if ($enablePartialList)
971 {
972 continue;
973 }
974 return 1;
975 }
976
977 if (!is_scalar($propertiesValues[$propID]))
978 return 5;
979
980 $propertiesValues[$propID] = (string)$propertiesValues[$propID];
981 $existValue = ('' != $propertiesValues[$propID]);
982 if (!$existValue)
983 return 1;
984
985 $userTypeProp = false;
986 $userType = null;
987 if (isset($oneProp['USER_TYPE']) && !empty($oneProp['USER_TYPE']))
988 {
989 $userTypeDescr = CIBlockProperty::GetUserType($oneProp['USER_TYPE']);
990 if (isset($userTypeDescr['GetPublicViewHTML']))
991 {
992 $userTypeProp = true;
993 $userType = $userTypeDescr['GetPublicViewHTML'];
994 }
995 }
996
997 if ($oneProp["MULTIPLE"] == "Y")
998 {
999 if ($userTypeProp)
1000 {
1001 if ($oneProp["VALUE"] == $propertiesValues[$propID])
1002 {
1003 $displayValue = (string)call_user_func_array($userType,
1004 array(
1005 $oneProp,
1006 array('VALUE' => $oneProp['VALUE']),
1007 array('MODE' => 'SIMPLE_TEXT')
1008 ));
1009 $result[] = array(
1010 "NAME" => $oneProp["NAME"],
1011 "CODE" => $propID,
1012 "VALUE" => $displayValue,
1013 "SORT" => $sortIndex++,
1014 );
1015 unset($checkProps[$propID]);//mark as found
1016 }
1017 }
1018 else
1019 {
1020 switch($oneProp["PROPERTY_TYPE"])
1021 {
1022 case "S":
1023 case "N":
1024 if ($oneProp["VALUE"] == $propertiesValues[$propID])
1025 {
1026 $result[] = array(
1027 "NAME" => $oneProp["NAME"],
1028 "CODE" => $propID,
1029 "VALUE" => $oneProp["VALUE"],
1030 "SORT" => $sortIndex++,
1031 );
1032 unset($checkProps[$propID]);//mark as found
1033 }
1034 break;
1035 case "G":
1036 if ($oneProp["VALUE"] == $propertiesValues[$propID])
1037 {
1038 $rsSection = CIBlockSection::GetList(
1039 array(),
1040 array("=ID" => $oneProp["VALUE"]),
1041 false,
1042 array('ID', 'NAME')
1043 );
1044 if($arSection = $rsSection->Fetch())
1045 {
1046 $result[] = array(
1047 "NAME" => $oneProp["NAME"],
1048 "CODE" => $propID,
1049 "VALUE" => $arSection["NAME"],
1050 "SORT" => $sortIndex++,
1051 );
1052 unset($checkProps[$propID]);//mark as found
1053 }
1054 }
1055 break;
1056 case "E":
1057 if ($oneProp["VALUE"] == $propertiesValues[$propID])
1058 {
1059 $rsElement = CIBlockElement::GetList(
1060 array(),
1061 array("=ID" => $oneProp["VALUE"]),
1062 false,
1063 false,
1064 array("ID", "NAME")
1065 );
1066 if ($arElement = $rsElement->Fetch())
1067 {
1068 $result[] = array(
1069 "NAME" => $oneProp["NAME"],
1070 "CODE" => $propID,
1071 "VALUE" => $arElement["NAME"],
1072 "SORT" => $sortIndex++,
1073 );
1074 unset($checkProps[$propID]);//mark as found
1075 }
1076 }
1077 break;
1078 case "L":
1079 if ($oneProp["VALUE"] == $propertiesValues[$propID])
1080 {
1082 array(),
1083 array( "ID" => $propertiesValues[$propID], "IBLOCK_ID" => $iblockID, "PROPERTY_ID" => $oneProp['ID'])
1084 );
1085 if ($arEnum = $rsEnum->Fetch())
1086 {
1087 $result[] = array(
1088 "NAME" => $oneProp["NAME"],
1089 "CODE" => $propID,
1090 "VALUE" => $arEnum["VALUE"],
1091 "SORT" => $sortIndex++,
1092 );
1093 unset($checkProps[$propID]);//mark as found
1094 }
1095 }
1096 break;
1097 }
1098 }
1099 }
1100 else
1101 {
1102 switch ($oneProp["PROPERTY_TYPE"])
1103 {
1104 case "L":
1105 if (0 < (int)$propertiesValues[$propID])
1106 {
1108 array(),
1109 array("ID" => $propertiesValues[$propID], "IBLOCK_ID" => $iblockID, "PROPERTY_ID" => $oneProp['ID'])
1110 );
1111 if ($arEnum = $rsEnum->Fetch())
1112 {
1113 $result[] = array(
1114 "NAME" => $oneProp["NAME"],
1115 "CODE" => $propID,
1116 "VALUE" => $arEnum["VALUE"],
1117 "SORT" => $sortIndex++,
1118 );
1119 unset($checkProps[$propID]);//mark as found
1120 }
1121 }
1122 break;
1123 case "E":
1124 if (0 < (int)$propertiesValues[$propID])
1125 {
1126 $rsElement = CIBlockElement::GetList(
1127 array(),
1128 array("=ID" => $propertiesValues[$propID]),
1129 false,
1130 false,
1131 array("ID", "NAME")
1132 );
1133 if ($arElement = $rsElement->Fetch())
1134 {
1135 $result[] = array(
1136 "NAME" => $oneProp["NAME"],
1137 "CODE" => $propID,
1138 "VALUE" => $arElement["NAME"],
1139 "SORT" => $sortIndex++,
1140 );
1141 unset($checkProps[$propID]);//mark as found
1142 }
1143 }
1144 break;
1145 }
1146 }
1147 }
1148
1149 if ($enablePartialList && !empty($checkProps))
1150 {
1151 $nonExistProps = array_keys($checkProps);
1152 foreach ($nonExistProps as &$oneCode)
1153 {
1154 if (!isset($existProps[$oneCode]))
1155 unset($checkProps[$oneCode]);
1156 }
1157 unset($oneCode);
1158 }
1159
1160 if(!empty($checkProps))
1161 return 4;
1162
1163 return $result;
1164 }
1165
1166 public static function GetOffersIBlock($IBLOCK_ID)
1167 {
1168 $arResult = false;
1169 $IBLOCK_ID = (int)$IBLOCK_ID;
1170 if (0 < $IBLOCK_ID)
1171 {
1172 if (self::$catalogIncluded === null)
1173 self::$catalogIncluded = Loader::includeModule('catalog');
1174 if (self::$catalogIncluded)
1175 {
1176 $arCatalog = CCatalogSku::GetInfoByProductIBlock($IBLOCK_ID);
1177 if (!empty($arCatalog) && is_array($arCatalog))
1178 {
1179 $arResult = array(
1180 'OFFERS_IBLOCK_ID' => $arCatalog['IBLOCK_ID'],
1181 'OFFERS_PROPERTY_ID' => $arCatalog['SKU_PROPERTY_ID'],
1182 );
1183 }
1184 }
1185 }
1186 return $arResult;
1187 }
1188
1189 public static function GetOfferProperties($offerID, $iblockID, $propertiesList, $skuTreeProps = '')
1190 {
1191 $iblockInfo = false;
1192 $result = array();
1193
1194 $iblockID = (int)$iblockID;
1195 $offerID = (int)$offerID;
1196 if (0 >= $iblockID || 0 >= $offerID)
1197 return $result;
1198
1199 $skuPropsList = array();
1200 if (!empty($skuTreeProps))
1201 {
1202 if (is_array($skuTreeProps))
1203 {
1204 $skuPropsList = $skuTreeProps;
1205 }
1206 else
1207 {
1208 $skuTreeProps = base64_decode((string)$skuTreeProps);
1209 if (false !== $skuTreeProps && CheckSerializedData($skuTreeProps))
1210 {
1211 $skuPropsList = unserialize($skuTreeProps, ['allowed_classes' => false]);
1212 if (!is_array($skuPropsList))
1213 {
1214 $skuPropsList = array();
1215 }
1216 }
1217 }
1218 }
1219
1220 if (!is_array($propertiesList))
1221 {
1222 $propertiesList = array();
1223 }
1224 if (!empty($skuPropsList))
1225 {
1226 $propertiesList = array_unique(array_merge($propertiesList, $skuPropsList));
1227 }
1228 if (empty($propertiesList))
1229 return $result;
1230 $propCodes = array_fill_keys($propertiesList, true);
1231
1232 if (self::$catalogIncluded === null)
1233 self::$catalogIncluded = Loader::includeModule('catalog');
1234 if (self::$catalogIncluded)
1235 {
1236 $iblockInfo = CCatalogSku::GetInfoByProductIBlock($iblockID);
1237 if (empty($iblockInfo))
1238 {
1239 $iblockInfo = CCatalogSku::GetInfoByOfferIBlock($iblockID);
1240 }
1241 }
1242 if (empty($iblockInfo))
1243 return $result;
1244
1245 $sortIndex = 1;
1246 $rsProps = CIBlockElement::GetProperty(
1247 $iblockInfo['IBLOCK_ID'],
1248 $offerID,
1249 array("sort"=>"asc", "enum_sort" => "asc", "value_id"=>"asc"),
1250 array("EMPTY"=>"N")
1251 );
1252
1253 while ($oneProp = $rsProps->Fetch())
1254 {
1255 if (!isset($propCodes[$oneProp['CODE']]) && !isset($propCodes[$oneProp['ID']]))
1256 continue;
1257 $propID = (isset($propCodes[$oneProp['CODE']]) ? $oneProp['CODE'] : $oneProp['ID']);
1258
1259 $userTypeProp = false;
1260 $userType = null;
1261 if (isset($oneProp['USER_TYPE']) && !empty($oneProp['USER_TYPE']))
1262 {
1263 $userTypeDescr = CIBlockProperty::GetUserType($oneProp['USER_TYPE']);
1264 if (isset($userTypeDescr['GetPublicViewHTML']))
1265 {
1266 $userTypeProp = true;
1267 $userType = $userTypeDescr['GetPublicViewHTML'];
1268 }
1269 }
1270
1271 if ($userTypeProp)
1272 {
1273 $displayValue = (string)call_user_func_array($userType,
1274 array(
1275 $oneProp,
1276 array('VALUE' => $oneProp['VALUE']),
1277 array('MODE' => 'SIMPLE_TEXT')
1278 ));
1279 $result[] = array(
1280 "NAME" => $oneProp["NAME"],
1281 "CODE" => $propID,
1282 "VALUE" => $displayValue,
1283 "SORT" => $sortIndex++,
1284 );
1285 }
1286 else
1287 {
1288 switch ($oneProp["PROPERTY_TYPE"])
1289 {
1290 case "S":
1291 case "N":
1292 $result[] = array(
1293 "NAME" => $oneProp["NAME"],
1294 "CODE" => $propID,
1295 "VALUE" => $oneProp["VALUE"],
1296 "SORT" => $sortIndex++,
1297 );
1298 break;
1299 case "G":
1300 $rsSection = CIBlockSection::GetList(
1301 array(),
1302 array("=ID"=>$oneProp["VALUE"]),
1303 false,
1304 array('ID', 'NAME')
1305 );
1306 if ($arSection = $rsSection->Fetch())
1307 {
1308 $result[] = array(
1309 "NAME" => $oneProp["NAME"],
1310 "CODE" => $propID,
1311 "VALUE" => $arSection["NAME"],
1312 "SORT" => $sortIndex++,
1313 );
1314 }
1315 break;
1316 case "E":
1317 $rsElement = CIBlockElement::GetList(
1318 array(),
1319 array("=ID"=>$oneProp["VALUE"]),
1320 false,
1321 false,
1322 array("ID", "NAME")
1323 );
1324 if ($arElement = $rsElement->Fetch())
1325 {
1326 $result[] = array(
1327 "NAME" => $oneProp["NAME"],
1328 "CODE" => $propID,
1329 "VALUE" => $arElement["NAME"],
1330 "SORT" => $sortIndex++,
1331 );
1332 }
1333 break;
1334 case "L":
1335 $result[] = array(
1336 "NAME" => $oneProp["NAME"],
1337 "CODE" => $propID,
1338 "VALUE" => $oneProp["VALUE_ENUM"],
1339 "SORT" => $sortIndex++,
1340 );
1341 break;
1342 }
1343 }
1344 }
1345 return $result;
1346 }
1347
1348 public static function GetOffersArray($arFilter, $arElementID, $arOrder, $arSelectFields, $arSelectProperties, $limit, $arPrices, $vat_include, $arCurrencyParams = array(), $USER_ID = 0, $LID = SITE_ID)
1349 {
1350 global $USER;
1351
1352 $arResult = array();
1353
1354 $boolCheckPermissions = false;
1355 $boolHideNotAvailable = false;
1356 $showPriceCount = false;
1357 $customFilter = false;
1358 $IBLOCK_ID = 0;
1359
1360 if (!empty($arFilter) && is_array($arFilter))
1361 {
1362 if (isset($arFilter['IBLOCK_ID']))
1363 $IBLOCK_ID = $arFilter['IBLOCK_ID'];
1364 if (isset($arFilter['HIDE_NOT_AVAILABLE']))
1365 $boolHideNotAvailable = ($arFilter['HIDE_NOT_AVAILABLE'] === 'Y');
1366 if (isset($arFilter['CHECK_PERMISSIONS']))
1367 $boolCheckPermissions = ($arFilter['CHECK_PERMISSIONS'] === 'Y');
1368 if (isset($arFilter['SHOW_PRICE_COUNT']))
1369 {
1370 $showPriceCount = (int)$arFilter['SHOW_PRICE_COUNT'];
1371 if ($showPriceCount <= 0)
1372 $showPriceCount = false;
1373 }
1374
1375 if (isset($arFilter['CUSTOM_FILTER']))
1376 {
1377 $customFilter = $arFilter['CUSTOM_FILTER'];
1378 }
1379 }
1380 else
1381 {
1383 }
1384
1385 if (self::$needDiscountCache === null)
1386 {
1387 if(\Bitrix\Main\Config\Option::get('sale', 'use_sale_discount_only') === 'Y')
1388 {
1389 self::$needDiscountCache = false;
1390 }
1391 else
1392 {
1393 $pricesAllow = CIBlockPriceTools::GetAllowCatalogPrices($arPrices);
1394 if (empty($pricesAllow))
1395 {
1396 self::$needDiscountCache = false;
1397 }
1398 else
1399 {
1400 $USER_ID = (int)$USER_ID;
1401 $userGroups = array(2);
1402 if ($USER_ID > 0)
1403 $userGroups = CUser::GetUserGroup($USER_ID);
1404 elseif (isset($USER) && $USER instanceof CUser)
1405 $userGroups = $USER->GetUserGroupArray();
1406 self::$needDiscountCache = CIBlockPriceTools::SetCatalogDiscountCache($pricesAllow, $userGroups);
1407 unset($userGroups);
1408 }
1409 unset($pricesAllow);
1410 }
1411 }
1412
1414 if($arOffersIBlock)
1415 {
1416 $arDefaultMeasure = CCatalogMeasure::getDefaultMeasure(true, true);
1417
1418 $limit = (int)$limit;
1419 if (0 > $limit)
1420 $limit = 0;
1421
1422 if (!isset($arOrder["ID"]))
1423 $arOrder["ID"] = "DESC";
1424
1425 $intOfferIBlockID = $arOffersIBlock["OFFERS_IBLOCK_ID"];
1426
1427 $productProperty = 'PROPERTY_'.$arOffersIBlock['OFFERS_PROPERTY_ID'];
1428 $productPropertyValue = $productProperty.'_VALUE';
1429
1430 $propertyList = array();
1431 if (!empty($arSelectProperties))
1432 {
1433 $selectProperties = array_fill_keys($arSelectProperties, true);
1434 $propertyIterator = Iblock\PropertyTable::getList(array(
1435 'select' => array('ID', 'CODE'),
1436 'filter' => array('=IBLOCK_ID' => $intOfferIBlockID, '=ACTIVE' => 'Y'),
1437 'order' => array('SORT' => 'ASC', 'ID' => 'ASC')
1438 ));
1439 while ($property = $propertyIterator->fetch())
1440 {
1441 $code = (string)$property['CODE'];
1442 if ($code == '')
1443 $code = $property['ID'];
1444 if (!isset($selectProperties[$code]))
1445 continue;
1446 $propertyList[] = $code;
1447 unset($code);
1448 }
1449 unset($property, $propertyIterator);
1450 unset($selectProperties);
1451 }
1452
1453 $arFilter = array(
1454 "IBLOCK_ID" => $intOfferIBlockID,
1455 $productProperty => $arElementID,
1456 "ACTIVE" => "Y",
1457 "ACTIVE_DATE" => "Y",
1458 );
1459
1460 if (!empty($customFilter))
1461 {
1462 $arFilter[] = $customFilter;
1463 }
1464
1465 if ($boolHideNotAvailable)
1466 $arFilter['CATALOG_AVAILABLE'] = 'Y';
1467 if ($boolCheckPermissions)
1468 {
1469 $arFilter['CHECK_PERMISSIONS'] = "Y";
1470 $arFilter['MIN_PERMISSION'] = "R";
1471 }
1472
1473 $arSelect = array(
1474 "ID" => 1,
1475 "IBLOCK_ID" => 1,
1476 $productProperty => 1,
1477 "CATALOG_QUANTITY" => 1
1478 );
1479 //if(!$arParams["USE_PRICE_COUNT"])
1480 {
1481 foreach($arPrices as $value)
1482 {
1483 if (!$value['CAN_VIEW'] && !$value['CAN_BUY'])
1484 continue;
1485 $arSelect[$value["SELECT"]] = 1;
1486 if ($showPriceCount !== false)
1487 {
1488 $arFilter['CATALOG_SHOP_QUANTITY_'.$value['ID']] = $showPriceCount;
1489 }
1490 }
1491 }
1492
1493 if (!empty($arSelectFields))
1494 {
1495 foreach ($arSelectFields as $code)
1496 $arSelect[$code] = 1; //mark to select
1497 unset($code);
1498 }
1499 $checkFields = array();
1500 foreach (array_keys($arOrder) as $code)
1501 {
1502 $code = mb_strtoupper($code);
1503 $arSelect[$code] = 1;
1504 if ($code == 'ID' || $code == 'CATALOG_AVAILABLE')
1505 continue;
1506 $checkFields[] = $code;
1507 }
1508 unset($code);
1509
1510 if (!isset($arSelect['PREVIEW_PICTURE']))
1511 $arSelect['PREVIEW_PICTURE'] = 1;
1512 if (!isset($arSelect['DETAIL_PICTURE']))
1513 $arSelect['DETAIL_PICTURE'] = 1;
1514
1515 $arOfferIDs = array();
1516 $arMeasureMap = array();
1517 $intKey = 0;
1518 $arOffersPerElement = array();
1519 $arOffersLink = array();
1520 $extPrices = array();
1521 $rsOffers = CIBlockElement::GetList($arOrder, $arFilter, false, false, array_keys($arSelect));
1522 while($arOffer = $rsOffers->GetNext())
1523 {
1524 $arOffer['ID'] = (int)$arOffer['ID'];
1525 $element_id = (int)$arOffer[$productPropertyValue];
1526 //No more than limit offers per element
1527 if ($limit > 0)
1528 {
1529 $arOffersPerElement[$element_id] ??= 0;
1530 $arOffersPerElement[$element_id]++;
1531 if($arOffersPerElement[$element_id] > $limit)
1532 continue;
1533 }
1534
1535 if($element_id > 0)
1536 {
1537 $arOffer['SORT_HASH'] = 'ID';
1538 if (!empty($checkFields))
1539 {
1540 $checkValues = '';
1541 foreach ($checkFields as $code)
1542 $checkValues .= (isset($arOffer[$code]) ? $arOffer[$code] : '').'|';
1543 unset($code);
1544 if ($checkValues != '')
1545 $arOffer['SORT_HASH'] = md5($checkValues);
1546 unset($checkValues);
1547 }
1548 $arOffer["LINK_ELEMENT_ID"] = $element_id;
1549 $arOffer["PROPERTIES"] = array();
1550 $arOffer["DISPLAY_PROPERTIES"] = array();
1551
1553 $arOffer,
1554 array('PREVIEW_PICTURE', 'DETAIL_PICTURE'),
1555 Iblock\Component\Tools::IPROPERTY_ENTITY_ELEMENT,
1556 ''
1557 );
1558
1559 $arOffer['CHECK_QUANTITY'] = ('Y' == $arOffer['CATALOG_QUANTITY_TRACE'] && 'N' == $arOffer['CATALOG_CAN_BUY_ZERO']);
1560 $arOffer['CATALOG_TYPE'] = CCatalogProduct::TYPE_OFFER;
1561 $arOffer['CATALOG_MEASURE_NAME'] = $arDefaultMeasure['SYMBOL_RUS'];
1562 $arOffer['~CATALOG_MEASURE_NAME'] = $arDefaultMeasure['SYMBOL_RUS'];
1563 $arOffer["CATALOG_MEASURE_RATIO"] = 1;
1564 if (!isset($arOffer['CATALOG_MEASURE']))
1565 $arOffer['CATALOG_MEASURE'] = 0;
1566 $arOffer['CATALOG_MEASURE'] = (int)$arOffer['CATALOG_MEASURE'];
1567 if (0 > $arOffer['CATALOG_MEASURE'])
1568 $arOffer['CATALOG_MEASURE'] = 0;
1569 if (0 < $arOffer['CATALOG_MEASURE'])
1570 {
1571 if (!isset($arMeasureMap[$arOffer['CATALOG_MEASURE']]))
1572 $arMeasureMap[$arOffer['CATALOG_MEASURE']] = array();
1573 $arMeasureMap[$arOffer['CATALOG_MEASURE']][] = $intKey;
1574 }
1575
1576 $arOfferIDs[] = $arOffer['ID'];
1577 $arResult[$intKey] = $arOffer;
1578 if (!isset($arOffersLink[$arOffer['ID']]))
1579 {
1580 $arOffersLink[$arOffer['ID']] = &$arResult[$intKey];
1581 }
1582 else
1583 {
1584 if (!isset($extPrices[$arOffer['ID']]))
1585 {
1586 $extPrices[$arOffer['ID']] = array();
1587 }
1588 $extPrices[$arOffer['ID']][] = &$arResult[$intKey];
1589 }
1590 $intKey++;
1591 }
1592 }
1593 if (!empty($arOfferIDs))
1594 {
1596 array(),
1597 array('@PRODUCT_ID' => $arOfferIDs),
1598 false,
1599 false,
1600 array('PRODUCT_ID', 'RATIO')
1601 );
1602 while ($arRatio = $rsRatios->Fetch())
1603 {
1604 $arRatio['PRODUCT_ID'] = (int)$arRatio['PRODUCT_ID'];
1605 if (isset($arOffersLink[$arRatio['PRODUCT_ID']]))
1606 {
1607 $intRatio = (int)$arRatio['RATIO'];
1608 $dblRatio = (float)$arRatio['RATIO'];
1609 $mxRatio = ($dblRatio > $intRatio ? $dblRatio : $intRatio);
1610 if (CATALOG_VALUE_EPSILON > abs($mxRatio))
1611 $mxRatio = 1;
1612 elseif (0 > $mxRatio)
1613 $mxRatio = 1;
1614 $arOffersLink[$arRatio['PRODUCT_ID']]['CATALOG_MEASURE_RATIO'] = $mxRatio;
1615 }
1616 }
1617
1618 if (!empty($propertyList))
1619 {
1620 CIBlockElement::GetPropertyValuesArray($arOffersLink, $intOfferIBlockID, $arFilter);
1621 foreach ($arResult as &$arOffer)
1622 {
1623 if (self::$needDiscountCache)
1624 CCatalogDiscount::SetProductPropertiesCache($arOffer['ID'], $arOffer["PROPERTIES"]);
1625 if (\Bitrix\Main\Config\Option::get('sale', 'use_sale_discount_only') === 'Y')
1626 Catalog\Discount\DiscountManager::setProductPropertiesCache($arOffer['ID'], $arOffer["PROPERTIES"]);
1627
1628 foreach ($propertyList as $pid)
1629 {
1630 if (!isset($arOffer["PROPERTIES"][$pid]))
1631 continue;
1632 $prop = &$arOffer["PROPERTIES"][$pid];
1633 $boolArr = is_array($prop["VALUE"]);
1634 if(
1635 ($boolArr && !empty($prop["VALUE"])) ||
1636 (!$boolArr && (string)$prop["VALUE"] !== '')
1637 )
1638 {
1639 $arOffer["DISPLAY_PROPERTIES"][$pid] = CIBlockFormatProperties::GetDisplayValue($arOffer, $prop);
1640 }
1641 unset($boolArr, $prop);
1642 }
1643 unset($pid);
1644 }
1645 unset($arOffer);
1646 }
1647
1648 if (!empty($extPrices))
1649 {
1650 foreach ($extPrices as $origID => $prices)
1651 {
1652 foreach ($prices as $oneRow)
1653 {
1654 $oneRow['PROPERTIES'] = $arOffersLink[$origID]['PROPERTIES'];
1655 $oneRow['DISPLAY_PROPERTIES'] = $arOffersLink[$origID]['DISPLAY_PROPERTIES'];
1656 $oneRow['CATALOG_MEASURE_RATIO'] = $arOffersLink[$origID]['CATALOG_MEASURE_RATIO'];
1657 }
1658 }
1659 }
1660 if (self::$needDiscountCache)
1661 {
1663 CCatalogDiscount::SetDiscountProductCache($arOfferIDs, array('IBLOCK_ID' => $intOfferIBlockID, 'GET_BY_ID' => 'Y'));
1664 }
1665 if (\Bitrix\Main\Config\Option::get('sale', 'use_sale_discount_only') === 'Y')
1666 {
1667 $pricesAllow = CIBlockPriceTools::GetAllowCatalogPrices($arPrices);
1668 if (!empty($pricesAllow))
1669 {
1670 $USER_ID = (int)$USER_ID;
1671 $userGroups = array(2);
1672 if ($USER_ID > 0)
1673 $userGroups = CUser::GetUserGroup($USER_ID);
1674 elseif (isset($USER) && $USER instanceof CUser)
1675 $userGroups = $USER->GetUserGroupArray();
1676 Catalog\Discount\DiscountManager::preloadPriceData($arOfferIDs, $pricesAllow);
1678 unset($userGroups);
1679 }
1680 unset($pricesAllow);
1681 }
1682 foreach ($arResult as &$arOffer)
1683 {
1684 $arOffer['CATALOG_QUANTITY'] = (
1685 0 < $arOffer['CATALOG_QUANTITY'] && is_float($arOffer['CATALOG_MEASURE_RATIO'])
1686 ? (float)$arOffer['CATALOG_QUANTITY']
1687 : (int)$arOffer['CATALOG_QUANTITY']
1688 );
1689 $arOffer['MIN_PRICE'] = false;
1690 $arOffer["PRICES"] = CIBlockPriceTools::GetItemPrices($arOffersIBlock["OFFERS_IBLOCK_ID"], $arPrices, $arOffer, $vat_include, $arCurrencyParams, $USER_ID, $LID);
1691 if (!empty($arOffer["PRICES"]))
1692 {
1693 foreach ($arOffer['PRICES'] as &$arOnePrice)
1694 {
1695 if ($arOnePrice['MIN_PRICE'] == 'Y')
1696 {
1697 $arOffer['MIN_PRICE'] = $arOnePrice;
1698 break;
1699 }
1700 }
1701 unset($arOnePrice);
1702 }
1703 $arOffer["CAN_BUY"] = CIBlockPriceTools::CanBuy($arOffersIBlock["OFFERS_IBLOCK_ID"], $arPrices, $arOffer);
1704 }
1705 if (isset($arOffer))
1706 unset($arOffer);
1707 }
1708 if (!empty($arMeasureMap))
1709 {
1710 $rsMeasures = CCatalogMeasure::getList(
1711 array(),
1712 array('@ID' => array_keys($arMeasureMap)),
1713 false,
1714 false,
1715 array('ID', 'SYMBOL_RUS')
1716 );
1717 while ($arMeasure = $rsMeasures->GetNext())
1718 {
1719 $arMeasure['ID'] = (int)$arMeasure['ID'];
1720 if (isset($arMeasureMap[$arMeasure['ID']]) && !empty($arMeasureMap[$arMeasure['ID']]))
1721 {
1722 foreach ($arMeasureMap[$arMeasure['ID']] as $intOneKey)
1723 {
1724 $arResult[$intOneKey]['CATALOG_MEASURE_NAME'] = $arMeasure['SYMBOL_RUS'];
1725 $arResult[$intOneKey]['~CATALOG_MEASURE_NAME'] = $arMeasure['~SYMBOL_RUS'];
1726 }
1727 unset($intOneKey);
1728 }
1729 }
1730 }
1731 }
1732
1733 return $arResult;
1734 }
1735
1743 public static function GetDefaultMeasure()
1744 {
1745 if (self::$catalogIncluded === null)
1746 self::$catalogIncluded = Loader::includeModule('catalog');
1747 return (self::$catalogIncluded ? array() : CCatalogMeasure::getDefaultMeasure(true, true));
1748 }
1749
1750 public static function setRatioMinPrice(&$item, $replaceMinPrice = false)
1751 {
1752 $replaceMinPrice = ($replaceMinPrice !== false);
1753 if (isset($item['MIN_PRICE']) && !empty($item['MIN_PRICE']) && isset($item['CATALOG_MEASURE_RATIO']))
1754 {
1755 if ($item['CATALOG_MEASURE_RATIO'] === 1)
1756 {
1757 $item['RATIO_PRICE'] = array(
1758 'VALUE' => $item['MIN_PRICE']['VALUE'],
1759 'DISCOUNT_VALUE' => $item['MIN_PRICE']['DISCOUNT_VALUE'],
1760 'PRINT_VALUE' => $item['MIN_PRICE']['PRINT_VALUE'],
1761 'PRINT_DISCOUNT_VALUE' => $item['MIN_PRICE']['PRINT_DISCOUNT_VALUE'],
1762 'DISCOUNT_DIFF' => $item['MIN_PRICE']['DISCOUNT_DIFF'],
1763 'PRINT_DISCOUNT_DIFF' => $item['MIN_PRICE']['PRINT_DISCOUNT_DIFF'],
1764 'DISCOUNT_DIFF_PERCENT' => $item['MIN_PRICE']['DISCOUNT_DIFF_PERCENT'],
1765 'CURRENCY' => $item['MIN_PRICE']['CURRENCY']
1766 );
1767 }
1768 else
1769 {
1770 $item['RATIO_PRICE'] = array(
1771 'VALUE' => $item['MIN_PRICE']['VALUE']*$item['CATALOG_MEASURE_RATIO'],
1772 'DISCOUNT_VALUE' => $item['MIN_PRICE']['DISCOUNT_VALUE']*$item['CATALOG_MEASURE_RATIO'],
1773 'CURRENCY' => $item['MIN_PRICE']['CURRENCY']
1774 );
1775 $item['RATIO_PRICE']['PRINT_VALUE'] = CCurrencyLang::CurrencyFormat(
1776 $item['RATIO_PRICE']['VALUE'],
1777 $item['RATIO_PRICE']['CURRENCY'],
1778 true
1779 );
1780 $item['RATIO_PRICE']['PRINT_DISCOUNT_VALUE'] = CCurrencyLang::CurrencyFormat(
1781 $item['RATIO_PRICE']['DISCOUNT_VALUE'],
1782 $item['RATIO_PRICE']['CURRENCY'],
1783 true
1784 );
1785 if ($item['MIN_PRICE']['VALUE'] == $item['MIN_PRICE']['DISCOUNT_VALUE'])
1786 {
1787 $item['RATIO_PRICE']['DISCOUNT_DIFF'] = 0;
1788 $item['RATIO_PRICE']['DISCOUNT_DIFF_PERCENT'] = 0;
1789 $item['RATIO_PRICE']['PRINT_DISCOUNT_DIFF'] = CCurrencyLang::CurrencyFormat(0, $item['RATIO_PRICE']['CURRENCY'], true);
1790 }
1791 else
1792 {
1793 $item['RATIO_PRICE']['DISCOUNT_DIFF'] = $item['RATIO_PRICE']['VALUE'] - $item['RATIO_PRICE']['DISCOUNT_VALUE'];
1794 $item['RATIO_PRICE']['DISCOUNT_DIFF_PERCENT'] = roundEx(100*$item['RATIO_PRICE']['DISCOUNT_DIFF']/$item['RATIO_PRICE']['VALUE'], 0);
1795 $item['RATIO_PRICE']['PRINT_DISCOUNT_DIFF'] = CCurrencyLang::CurrencyFormat(
1796 $item['RATIO_PRICE']['DISCOUNT_DIFF'],
1797 $item['RATIO_PRICE']['CURRENCY'],
1798 true
1799 );
1800 }
1801 }
1802 if ($replaceMinPrice)
1803 {
1804 $item['MIN_PRICE'] = $item['RATIO_PRICE'];
1805 unset($item['RATIO_PRICE']);
1806 }
1807 }
1808 }
1809
1810 public static function checkPropDirectory(&$property, $getPropInfo = false)
1811 {
1812 if (empty($property) || !is_array($property))
1813 {
1814 return false;
1815 }
1816 if (empty($property['USER_TYPE_SETTINGS']['TABLE_NAME']))
1817 {
1818 return false;
1819 }
1820 if (self::$highLoadInclude === null)
1821 {
1822 self::$highLoadInclude = Loader::includeModule('highloadblock');
1823 }
1824 if (!self::$highLoadInclude)
1825 {
1826 return false;
1827 }
1828
1829 $highBlock = HighloadBlockTable::getRow([
1830 'filter' => [
1831 '=TABLE_NAME' => $property['USER_TYPE_SETTINGS']['TABLE_NAME'],
1832 ],
1833 ]);
1834 if ($highBlock === null)
1835 {
1836 return false;
1837 }
1838
1839 $entity = HighloadBlockTable::compileEntity($highBlock);
1840 $fieldsList = $entity->getFields();
1841 if (empty($fieldsList))
1842 {
1843 return false;
1844 }
1845
1846 $requireFields = [
1847 'ID',
1848 'UF_XML_ID',
1849 'UF_NAME',
1850 ];
1851 foreach ($requireFields as $fieldCode)
1852 {
1853 if (!isset($fieldsList[$fieldCode]))
1854 {
1855 return false;
1856 }
1857 }
1858 if ($getPropInfo)
1859 {
1860 $property['USER_TYPE_SETTINGS']['FIELDS_MAP'] = $fieldsList;
1861 $property['USER_TYPE_SETTINGS']['ENTITY'] = $entity;
1862 }
1863
1864 return true;
1865 }
1866
1867 public static function getTreeProperties($skuInfo, $propertiesCodes, $defaultFields = array())
1868 {
1869 if (isset($defaultFields['PICT']) && is_array($defaultFields['PICT']))
1870 {
1871 if (!isset($defaultFields['PICT']['ID']))
1872 $defaultFields['PICT']['ID'] = 0;
1873 }
1874
1875 $requireFields = array(
1876 'ID',
1877 'UF_XML_ID',
1878 'UF_NAME',
1879 );
1880
1881 $result = array();
1882 if (empty($skuInfo))
1883 return $result;
1884 if (!is_array($skuInfo))
1885 {
1886 $skuInfo = (int)$skuInfo;
1887 if ($skuInfo <= 0)
1888 return $result;
1889 if (self::$catalogIncluded === null)
1890 self::$catalogIncluded = Loader::includeModule('catalog');
1891 if (!self::$catalogIncluded)
1892 return $result;
1893 $skuInfo = CCatalogSku::GetInfoByProductIBlock($skuInfo);
1894 if (empty($skuInfo))
1895 return $result;
1896 }
1897 if (empty($propertiesCodes) || !is_array($propertiesCodes))
1898 return $result;
1899
1900 $showMode = '';
1901
1902 $propertyIterator = Iblock\PropertyTable::getList(array(
1903 'select' => array(
1904 'ID', 'IBLOCK_ID', 'CODE', 'NAME', 'SORT', 'LINK_IBLOCK_ID', 'PROPERTY_TYPE', 'USER_TYPE', 'USER_TYPE_SETTINGS'
1905 ),
1906 'filter' => array(
1907 '=IBLOCK_ID' => $skuInfo['IBLOCK_ID'],
1908 '=PROPERTY_TYPE' => array(
1912 ),
1913 '=ACTIVE' => 'Y', '=MULTIPLE' => 'N'
1914 ),
1915 'order' => array(
1916 'SORT' => 'ASC', 'ID' => 'ASC'
1917 )
1918 ));
1919 while ($propInfo = $propertyIterator->fetch())
1920 {
1921 $propInfo['ID'] = (int)$propInfo['ID'];
1922 if ($propInfo['ID'] == $skuInfo['SKU_PROPERTY_ID'])
1923 continue;
1924 $propInfo['CODE'] = (string)$propInfo['CODE'];
1925 if ($propInfo['CODE'] === '')
1926 $propInfo['CODE'] = $propInfo['ID'];
1927 if (!in_array($propInfo['CODE'], $propertiesCodes))
1928 continue;
1929 $propInfo['SORT'] = (int)$propInfo['SORT'];
1930 $propInfo['USER_TYPE'] = (string)$propInfo['USER_TYPE'];
1931 if ($propInfo['PROPERTY_TYPE'] == Iblock\PropertyTable::TYPE_STRING)
1932 {
1933 if ('directory' != $propInfo['USER_TYPE'])
1934 continue;
1935 $propInfo['USER_TYPE_SETTINGS'] = (string)$propInfo['USER_TYPE_SETTINGS'];
1936 if ($propInfo['USER_TYPE_SETTINGS'] == '')
1937 continue;
1938 $propInfo['USER_TYPE_SETTINGS'] = unserialize($propInfo['USER_TYPE_SETTINGS'], ['allowed_classes' => false]);
1939 if (!isset($propInfo['USER_TYPE_SETTINGS']['TABLE_NAME']) || empty($propInfo['USER_TYPE_SETTINGS']['TABLE_NAME']))
1940 continue;
1941 if (self::$highLoadInclude === null)
1942 self::$highLoadInclude = Loader::includeModule('highloadblock');
1943 if (!self::$highLoadInclude)
1944 continue;
1945
1946 $highBlock = HighloadBlockTable::getList(array(
1947 'filter' => array('=TABLE_NAME' => $propInfo['USER_TYPE_SETTINGS']['TABLE_NAME'])
1948 ))->fetch();
1949 if (!isset($highBlock['ID']))
1950 continue;
1951
1952 $entity = HighloadBlockTable::compileEntity($highBlock);
1953 $fieldsList = $entity->getFields();
1954 if (empty($fieldsList))
1955 continue;
1956
1957 $flag = true;
1958 foreach ($requireFields as $fieldCode)
1959 {
1960 if (!isset($fieldsList[$fieldCode]) || empty($fieldsList[$fieldCode]))
1961 {
1962 $flag = false;
1963 break;
1964 }
1965 }
1966 unset($fieldCode);
1967 if (!$flag)
1968 continue;
1969 $propInfo['USER_TYPE_SETTINGS']['FIELDS_MAP'] = $fieldsList;
1970 $propInfo['USER_TYPE_SETTINGS']['ENTITY'] = $entity;
1971 }
1972 switch ($propInfo['PROPERTY_TYPE'])
1973 {
1975 $showMode = 'PICT';
1976 break;
1978 $showMode = 'TEXT';
1979 break;
1981 $showMode = (isset($fieldsList['UF_FILE']) ? 'PICT' : 'TEXT');
1982 break;
1983 }
1984 $treeProp = array(
1985 'ID' => $propInfo['ID'],
1986 'CODE' => $propInfo['CODE'],
1987 'NAME' => $propInfo['NAME'],
1988 'SORT' => $propInfo['SORT'],
1989 'PROPERTY_TYPE' => $propInfo['PROPERTY_TYPE'],
1990 'USER_TYPE' => $propInfo['USER_TYPE'],
1991 'LINK_IBLOCK_ID' => $propInfo['LINK_IBLOCK_ID'],
1992 'USER_TYPE_SETTINGS' => $propInfo['USER_TYPE_SETTINGS'],
1993 'VALUES' => array(),
1994 'SHOW_MODE' => $showMode,
1995 'DEFAULT_VALUES' => array(
1996 'PICT' => false,
1997 'NAME' => '-'
1998 )
1999 );
2000 if ($showMode == 'PICT')
2001 {
2002 if (isset($defaultFields['PICT']))
2003 $treeProp['DEFAULT_VALUES']['PICT'] = $defaultFields['PICT'];
2004 }
2005 if (isset($defaultFields['NAME']))
2006 {
2007 $treeProp['DEFAULT_VALUES']['NAME'] = $defaultFields['NAME'];
2008 }
2009 $result[$treeProp['CODE']] = $treeProp;
2010 }
2011 return $result;
2012 }
2013
2014 public static function getTreePropertyValues(&$propList, &$propNeedValues)
2015 {
2016 $result = array();
2017 if (!empty($propList) && is_array($propList))
2018 {
2019 $useFilterValues = !empty($propNeedValues) && is_array($propNeedValues);
2020 foreach ($propList as $oneProperty)
2021 {
2022 if (isset($oneProperty['DEFAULT_VALUES']['PICT']) && is_array($oneProperty['DEFAULT_VALUES']['PICT']))
2023 {
2024 if (!isset($oneProperty['DEFAULT_VALUES']['PICT']['ID']))
2025 $oneProperty['DEFAULT_VALUES']['PICT']['ID'] = 0;
2026 }
2027 $values = array();
2028 $valuesExist = false;
2029 $pictMode = ('PICT' == $oneProperty['SHOW_MODE']);
2030 $needValuesExist = !empty($propNeedValues[$oneProperty['ID']]) && is_array($propNeedValues[$oneProperty['ID']]);
2031 if ($useFilterValues && !$needValuesExist)
2032 continue;
2033 switch($oneProperty['PROPERTY_TYPE'])
2034 {
2035 case Iblock\PropertyTable::TYPE_LIST:
2036 if ($needValuesExist)
2037 {
2038 foreach (array_chunk($propNeedValues[$oneProperty['ID']], 500) as $pageIds)
2039 {
2040 $iterator = Iblock\PropertyEnumerationTable::getList(array(
2041 'select' => array('ID', 'VALUE', 'SORT'),
2042 'filter' => array('=PROPERTY_ID' => $oneProperty['ID'], '@ID' => $pageIds),
2043 'order' => array('SORT' => 'ASC', 'VALUE' => 'ASC')
2044 ));
2045 while ($row = $iterator->fetch())
2046 {
2047 $row['ID'] = (int)$row['ID'];
2048 $values[$row['ID']] = array(
2049 'ID' => $row['ID'],
2050 'NAME' => $row['VALUE'],
2051 'SORT' => (int)$row['SORT'],
2052 'PICT' => false
2053 );
2054 $valuesExist = true;
2055 }
2056 unset($row, $iterator);
2057 }
2058 unset($pageIds);
2059 }
2060 else
2061 {
2062 $iterator = Iblock\PropertyEnumerationTable::getList(array(
2063 'select' => array('ID', 'VALUE', 'SORT'),
2064 'filter' => array('=PROPERTY_ID' => $oneProperty['ID']),
2065 'order' => array('SORT' => 'ASC', 'VALUE' => 'ASC')
2066 ));
2067 while ($row = $iterator->fetch())
2068 {
2069 $row['ID'] = (int)$row['ID'];
2070 $values[$row['ID']] = array(
2071 'ID' => $row['ID'],
2072 'NAME' => $row['VALUE'],
2073 'SORT' => (int)$row['SORT'],
2074 'PICT' => false
2075 );
2076 $valuesExist = true;
2077 }
2078 unset($row, $iterator);
2079 }
2080 $values[0] = array(
2081 'ID' => 0,
2082 'SORT' => PHP_INT_MAX,
2083 'NA' => true,
2084 'NAME' => $oneProperty['DEFAULT_VALUES']['NAME'],
2085 'PICT' => $oneProperty['DEFAULT_VALUES']['PICT']
2086 );
2087 break;
2088 case Iblock\PropertyTable::TYPE_ELEMENT:
2089 $selectFields = array('ID', 'NAME');
2090 if ($pictMode)
2091 $selectFields[] = 'PREVIEW_PICTURE';
2092
2093 if ($needValuesExist)
2094 {
2095 foreach (array_chunk($propNeedValues[$oneProperty['ID']], 500) as $pageIds)
2096 {
2098 array('SORT' => 'ASC', 'NAME' => 'ASC'),
2099 array('ID' => $pageIds, 'IBLOCK_ID' => $oneProperty['LINK_IBLOCK_ID'], 'ACTIVE' => 'Y'),
2100 false,
2101 false,
2103 );
2104 while ($row = $iterator->Fetch())
2105 {
2106 if ($pictMode)
2107 {
2108 $row['PICT'] = false;
2109 if (!empty($row['PREVIEW_PICTURE']))
2110 {
2111 $previewPict = CFile::GetFileArray($row['PREVIEW_PICTURE']);
2112 if (!empty($previewPict))
2113 {
2114 $row['PICT'] = array(
2115 'ID' => (int)$previewPict['ID'],
2116 'SRC' => $previewPict['SRC'],
2117 'WIDTH' => (int)$previewPict['WIDTH'],
2118 'HEIGHT' => (int)$previewPict['HEIGHT']
2119 );
2120 }
2121 }
2122 if (empty($row['PICT']))
2123 $row['PICT'] = $oneProperty['DEFAULT_VALUES']['PICT'];
2124 }
2125 $row['ID'] = (int)$row['ID'];
2126 $values[$row['ID']] = array(
2127 'ID' => $row['ID'],
2128 'NAME' => $row['NAME'],
2129 'SORT' => (int)$row['SORT'],
2130 'PICT' => ($pictMode ? $row['PICT'] : false)
2131 );
2132 $valuesExist = true;
2133 }
2134 unset($row, $iterator);
2135 }
2136 unset($pageIds);
2137 }
2138 else
2139 {
2141 array('SORT' => 'ASC', 'NAME' => 'ASC'),
2142 array('IBLOCK_ID' => $oneProperty['LINK_IBLOCK_ID'], 'ACTIVE' => 'Y'),
2143 false,
2144 false,
2146 );
2147 while ($row = $iterator->Fetch())
2148 {
2149 if ($pictMode)
2150 {
2151 $row['PICT'] = false;
2152 if (!empty($row['PREVIEW_PICTURE']))
2153 {
2154 $previewPict = CFile::GetFileArray($row['PREVIEW_PICTURE']);
2155 if (!empty($previewPict))
2156 {
2157 $row['PICT'] = array(
2158 'ID' => (int)$previewPict['ID'],
2159 'SRC' => $previewPict['SRC'],
2160 'WIDTH' => (int)$previewPict['WIDTH'],
2161 'HEIGHT' => (int)$previewPict['HEIGHT']
2162 );
2163 }
2164 }
2165 if (empty($row['PICT']))
2166 $row['PICT'] = $oneProperty['DEFAULT_VALUES']['PICT'];
2167 }
2168 $row['ID'] = (int)$row['ID'];
2169 $values[$row['ID']] = array(
2170 'ID' => $row['ID'],
2171 'NAME' => $row['NAME'],
2172 'SORT' => (int)$row['SORT'],
2173 'PICT' => ($pictMode ? $row['PICT'] : false)
2174 );
2175 $valuesExist = true;
2176 }
2177 unset($row, $iterator);
2178 }
2179 $values[0] = array(
2180 'ID' => 0,
2181 'SORT' => PHP_INT_MAX,
2182 'NA' => true,
2183 'NAME' => $oneProperty['DEFAULT_VALUES']['NAME'],
2184 'PICT' => ($pictMode ? $oneProperty['DEFAULT_VALUES']['PICT'] : false)
2185 );
2186 break;
2187 case Iblock\PropertyTable::TYPE_STRING:
2188 if (self::$highLoadInclude === null)
2189 self::$highLoadInclude = Loader::includeModule('highloadblock');
2190 if (!self::$highLoadInclude)
2191 continue 2;
2192 $xmlMap = array();
2193 $sortExist = isset($oneProperty['USER_TYPE_SETTINGS']['FIELDS_MAP']['UF_SORT']);
2194
2195 $directorySelect = array('ID', 'UF_NAME', 'UF_XML_ID');
2196 $directoryOrder = array();
2197 if ($pictMode)
2198 $directorySelect[] = 'UF_FILE';
2199 if ($sortExist)
2200 {
2201 $directorySelect[] = 'UF_SORT';
2202 $directoryOrder['UF_SORT'] = 'ASC';
2203 }
2204 $directoryOrder['UF_NAME'] = 'ASC';
2205 $sortValue = 100;
2206
2208 $entity = $oneProperty['USER_TYPE_SETTINGS']['ENTITY'];
2209 if (!($entity instanceof Main\Entity\Base))
2210 continue 2;
2211 $entityDataClass = $entity->getDataClass();
2212 $entityGetList = array(
2213 'select' => $directorySelect,
2214 'order' => $directoryOrder
2215 );
2216
2217 if ($needValuesExist)
2218 {
2219 foreach (array_chunk($propNeedValues[$oneProperty['ID']], 500) as $pageIds)
2220 {
2221 $entityGetList['filter'] = array('=UF_XML_ID' => $pageIds);
2222 $iterator = $entityDataClass::getList($entityGetList);
2223 while ($row = $iterator->fetch())
2224 {
2225 $row['ID'] = (int)$row['ID'];
2226 $row['UF_SORT'] = ($sortExist ? (int)$row['UF_SORT'] : $sortValue);
2227 $sortValue += 100;
2228
2229 if ($pictMode)
2230 {
2231 if (!empty($row['UF_FILE']))
2232 {
2233 $arFile = CFile::GetFileArray($row['UF_FILE']);
2234 if (!empty($arFile))
2235 {
2236 $row['PICT'] = array(
2237 'ID' => (int)$arFile['ID'],
2238 'SRC' => $arFile['SRC'],
2239 'WIDTH' => (int)$arFile['WIDTH'],
2240 'HEIGHT' => (int)$arFile['HEIGHT']
2241 );
2242 }
2243 }
2244 if (empty($row['PICT']))
2245 $row['PICT'] = $oneProperty['DEFAULT_VALUES']['PICT'];
2246 }
2247 $values[$row['ID']] = array(
2248 'ID' => $row['ID'],
2249 'NAME' => $row['UF_NAME'],
2250 'SORT' => (int)$row['UF_SORT'],
2251 'XML_ID' => $row['UF_XML_ID'],
2252 'PICT' => ($pictMode ? $row['PICT'] : false)
2253 );
2254 $valuesExist = true;
2255 $xmlMap[$row['UF_XML_ID']] = $row['ID'];
2256 }
2257 unset($row, $iterator);
2258 }
2259 unset($pageIds);
2260 }
2261 else
2262 {
2263 $iterator = $entityDataClass::getList($entityGetList);
2264 while ($row = $iterator->fetch())
2265 {
2266 $row['ID'] = (int)$row['ID'];
2267 $row['UF_SORT'] = ($sortExist ? (int)$row['UF_SORT'] : $sortValue);
2268 $sortValue += 100;
2269
2270 if ($pictMode)
2271 {
2272 if (!empty($row['UF_FILE']))
2273 {
2274 $arFile = CFile::GetFileArray($row['UF_FILE']);
2275 if (!empty($arFile))
2276 {
2277 $row['PICT'] = array(
2278 'ID' => (int)$arFile['ID'],
2279 'SRC' => $arFile['SRC'],
2280 'WIDTH' => (int)$arFile['WIDTH'],
2281 'HEIGHT' => (int)$arFile['HEIGHT']
2282 );
2283 }
2284 }
2285 if (empty($row['PICT']))
2286 $row['PICT'] = $oneProperty['DEFAULT_VALUES']['PICT'];
2287 }
2288 $values[$row['ID']] = array(
2289 'ID' => $row['ID'],
2290 'NAME' => $row['UF_NAME'],
2291 'SORT' => (int)$row['UF_SORT'],
2292 'XML_ID' => $row['UF_XML_ID'],
2293 'PICT' => ($pictMode ? $row['PICT'] : false)
2294 );
2295 $valuesExist = true;
2296 $xmlMap[$row['UF_XML_ID']] = $row['ID'];
2297 }
2298 unset($row, $iterator);
2299 }
2300 $values[0] = array(
2301 'ID' => 0,
2302 'SORT' => PHP_INT_MAX,
2303 'NA' => true,
2304 'NAME' => $oneProperty['DEFAULT_VALUES']['NAME'],
2305 'XML_ID' => '',
2306 'PICT' => ($pictMode ? $oneProperty['DEFAULT_VALUES']['PICT'] : false)
2307 );
2308 if ($valuesExist)
2309 $oneProperty['XML_MAP'] = $xmlMap;
2310 break;
2311 }
2312 if (!$valuesExist)
2313 continue;
2314 $oneProperty['VALUES'] = $values;
2315 $oneProperty['VALUES_COUNT'] = count($values);
2316
2317 $result[$oneProperty['CODE']] = $oneProperty;
2318 }
2319 }
2320 $propList = $result;
2321 unset($arFilterProp);
2322 }
2323
2324 public static function getMinPriceFromOffers(&$offers, $currency, $replaceMinPrice = true)
2325 {
2326 $replaceMinPrice = ($replaceMinPrice === true);
2327 $result = false;
2328 $minPrice = 0;
2329 if (!empty($offers) && is_array($offers))
2330 {
2331 $doubles = array();
2332 foreach ($offers as $oneOffer)
2333 {
2334 $oneOffer['ID'] = (int)$oneOffer['ID'];
2335 if (isset($doubles[$oneOffer['ID']]))
2336 continue;
2337 if (!$oneOffer['CAN_BUY'])
2338 continue;
2339
2340 CIBlockPriceTools::setRatioMinPrice($oneOffer, $replaceMinPrice);
2341
2342 $oneOffer['MIN_PRICE']['CATALOG_MEASURE_RATIO'] = $oneOffer['CATALOG_MEASURE_RATIO'];
2343 $oneOffer['MIN_PRICE']['CATALOG_MEASURE'] = $oneOffer['CATALOG_MEASURE'];
2344 $oneOffer['MIN_PRICE']['CATALOG_MEASURE_NAME'] = $oneOffer['CATALOG_MEASURE_NAME'];
2345 $oneOffer['MIN_PRICE']['~CATALOG_MEASURE_NAME'] = $oneOffer['~CATALOG_MEASURE_NAME'];
2346
2347 if (empty($result))
2348 {
2349 $minPrice = ($oneOffer['MIN_PRICE']['CURRENCY'] == $currency
2350 ? $oneOffer['MIN_PRICE']['DISCOUNT_VALUE']
2351 : CCurrencyRates::ConvertCurrency($oneOffer['MIN_PRICE']['DISCOUNT_VALUE'], $oneOffer['MIN_PRICE']['CURRENCY'], $currency)
2352 );
2353 $result = $oneOffer['MIN_PRICE'];
2354 }
2355 else
2356 {
2357 $comparePrice = ($oneOffer['MIN_PRICE']['CURRENCY'] == $currency
2358 ? $oneOffer['MIN_PRICE']['DISCOUNT_VALUE']
2359 : CCurrencyRates::ConvertCurrency($oneOffer['MIN_PRICE']['DISCOUNT_VALUE'], $oneOffer['MIN_PRICE']['CURRENCY'], $currency)
2360 );
2361 if ($minPrice > $comparePrice)
2362 {
2363 $minPrice = $comparePrice;
2364 $result = $oneOffer['MIN_PRICE'];
2365 }
2366 }
2367 $doubles[$oneOffer['ID']] = true;
2368 }
2369 }
2370 return $result;
2371 }
2372
2373 public static function getDoublePicturesForItem(&$item, $propertyCode, $encode = true)
2374 {
2375 $encode = ($encode === true);
2376 $result = array(
2377 'PICT' => false,
2378 'SECOND_PICT' => false
2379 );
2380
2381 if (!empty($item) && is_array($item))
2382 {
2383 if (!empty($item['PREVIEW_PICTURE']))
2384 {
2385 if (!is_array($item['PREVIEW_PICTURE']))
2386 $item['PREVIEW_PICTURE'] = CFile::GetFileArray($item['PREVIEW_PICTURE']);
2387 if (isset($item['PREVIEW_PICTURE']['ID']))
2388 {
2389 $result['PICT'] = array(
2390 'ID' => (int)$item['PREVIEW_PICTURE']['ID'],
2391 'SRC' => Iblock\Component\Tools::getImageSrc($item['PREVIEW_PICTURE'], $encode),
2392 'WIDTH' => (int)$item['PREVIEW_PICTURE']['WIDTH'],
2393 'HEIGHT' => (int)$item['PREVIEW_PICTURE']['HEIGHT']
2394 );
2395 }
2396 }
2397 if (!empty($item['DETAIL_PICTURE']))
2398 {
2399 $keyPict = (empty($result['PICT']) ? 'PICT' : 'SECOND_PICT');
2400 if (!is_array($item['DETAIL_PICTURE']))
2401 $item['DETAIL_PICTURE'] = CFile::GetFileArray($item['DETAIL_PICTURE']);
2402 if (isset($item['DETAIL_PICTURE']['ID']))
2403 {
2404 $result[$keyPict] = array(
2405 'ID' => (int)$item['DETAIL_PICTURE']['ID'],
2406 'SRC' => Iblock\Component\Tools::getImageSrc($item['DETAIL_PICTURE'], $encode),
2407 'WIDTH' => (int)$item['DETAIL_PICTURE']['WIDTH'],
2408 'HEIGHT' => (int)$item['DETAIL_PICTURE']['HEIGHT']
2409 );
2410 }
2411 }
2412 if (empty($result['SECOND_PICT']))
2413 {
2414 if (
2415 '' != $propertyCode &&
2416 isset($item['PROPERTIES'][$propertyCode]) &&
2417 'F' == $item['PROPERTIES'][$propertyCode]['PROPERTY_TYPE']
2418 )
2419 {
2420 if (
2421 isset($item['DISPLAY_PROPERTIES'][$propertyCode]['FILE_VALUE']) &&
2422 !empty($item['DISPLAY_PROPERTIES'][$propertyCode]['FILE_VALUE'])
2423 )
2424 {
2425 $fileValues = (
2426 isset($item['DISPLAY_PROPERTIES'][$propertyCode]['FILE_VALUE']['ID']) ?
2427 array(0 => $item['DISPLAY_PROPERTIES'][$propertyCode]['FILE_VALUE']) :
2428 $item['DISPLAY_PROPERTIES'][$propertyCode]['FILE_VALUE']
2429 );
2430 foreach ($fileValues as $oneFileValue)
2431 {
2432 $keyPict = (empty($result['PICT']) ? 'PICT' : 'SECOND_PICT');
2433 $result[$keyPict] = array(
2434 'ID' => (int)$oneFileValue['ID'],
2435 'SRC' => Iblock\Component\Tools::getImageSrc($oneFileValue, $encode),
2436 'WIDTH' => (int)$oneFileValue['WIDTH'],
2437 'HEIGHT' => (int)$oneFileValue['HEIGHT']
2438 );
2439 if ('SECOND_PICT' == $keyPict)
2440 break;
2441 }
2442 if (isset($oneFileValue))
2443 unset($oneFileValue);
2444 }
2445 else
2446 {
2447 $propValues = $item['PROPERTIES'][$propertyCode]['VALUE'];
2448 if (!is_array($propValues))
2449 $propValues = array($propValues);
2450 foreach ($propValues as $oneValue)
2451 {
2452 $oneFileValue = CFile::GetFileArray($oneValue);
2453 if (isset($oneFileValue['ID']))
2454 {
2455 $keyPict = (empty($result['PICT']) ? 'PICT' : 'SECOND_PICT');
2456 $result[$keyPict] = array(
2457 'ID' => (int)$oneFileValue['ID'],
2458 'SRC' => Iblock\Component\Tools::getImageSrc($oneFileValue, $encode),
2459 'WIDTH' => (int)$oneFileValue['WIDTH'],
2460 'HEIGHT' => (int)$oneFileValue['HEIGHT']
2461 );
2462 if ('SECOND_PICT' == $keyPict)
2463 break;
2464 }
2465 }
2466 if (isset($oneValue))
2467 unset($oneValue);
2468 }
2469 }
2470 }
2471 }
2472 return $result;
2473 }
2474
2475 public static function getSliderForItem(&$item, $propertyCode, $addDetailToSlider, $encode = true)
2476 {
2477 $encode = ($encode === true);
2478 $result = array();
2479
2480 if (!empty($item) && is_array($item))
2481 {
2482 if (
2483 '' != $propertyCode &&
2484 isset($item['PROPERTIES'][$propertyCode]) &&
2485 'F' == $item['PROPERTIES'][$propertyCode]['PROPERTY_TYPE']
2486 )
2487 {
2488 if ('MORE_PHOTO' == $propertyCode && isset($item['MORE_PHOTO']) && !empty($item['MORE_PHOTO']))
2489 {
2490 foreach ($item['MORE_PHOTO'] as $onePhoto)
2491 {
2492 $result[] = array(
2493 'ID' => (int)$onePhoto['ID'],
2494 'SRC' => Iblock\Component\Tools::getImageSrc($onePhoto, $encode),
2495 'WIDTH' => (int)$onePhoto['WIDTH'],
2496 'HEIGHT' => (int)$onePhoto['HEIGHT']
2497 );
2498 }
2499 unset($onePhoto);
2500 }
2501 else
2502 {
2503 if (
2504 isset($item['DISPLAY_PROPERTIES'][$propertyCode]['FILE_VALUE']) &&
2505 !empty($item['DISPLAY_PROPERTIES'][$propertyCode]['FILE_VALUE'])
2506 )
2507 {
2508 $fileValues = (
2509 isset($item['DISPLAY_PROPERTIES'][$propertyCode]['FILE_VALUE']['ID']) ?
2510 array(0 => $item['DISPLAY_PROPERTIES'][$propertyCode]['FILE_VALUE']) :
2511 $item['DISPLAY_PROPERTIES'][$propertyCode]['FILE_VALUE']
2512 );
2513 foreach ($fileValues as $oneFileValue)
2514 {
2515 $result[] = array(
2516 'ID' => (int)$oneFileValue['ID'],
2517 'SRC' => Iblock\Component\Tools::getImageSrc($oneFileValue, $encode),
2518 'WIDTH' => (int)$oneFileValue['WIDTH'],
2519 'HEIGHT' => (int)$oneFileValue['HEIGHT']
2520 );
2521 }
2522 if (isset($oneFileValue))
2523 unset($oneFileValue);
2524 }
2525 else
2526 {
2527 $propValues = $item['PROPERTIES'][$propertyCode]['VALUE'];
2528 if (!is_array($propValues))
2529 $propValues = array($propValues);
2530
2531 foreach ($propValues as $oneValue)
2532 {
2533 $oneFileValue = CFile::GetFileArray($oneValue);
2534 if (isset($oneFileValue['ID']))
2535 {
2536 $result[] = array(
2537 'ID' => (int)$oneFileValue['ID'],
2538 'SRC' => Iblock\Component\Tools::getImageSrc($oneFileValue, $encode),
2539 'WIDTH' => (int)$oneFileValue['WIDTH'],
2540 'HEIGHT' => (int)$oneFileValue['HEIGHT']
2541 );
2542 }
2543 }
2544 if (isset($oneValue))
2545 unset($oneValue);
2546 }
2547 }
2548 }
2549 if ($addDetailToSlider || empty($result))
2550 {
2551 if (!empty($item['DETAIL_PICTURE']))
2552 {
2553 if (!is_array($item['DETAIL_PICTURE']))
2554 $item['DETAIL_PICTURE'] = CFile::GetFileArray($item['DETAIL_PICTURE']);
2555 if (isset($item['DETAIL_PICTURE']['ID']))
2556 {
2557 array_unshift(
2558 $result,
2559 array(
2560 'ID' => (int)$item['DETAIL_PICTURE']['ID'],
2561 'SRC' => Iblock\Component\Tools::getImageSrc($item['DETAIL_PICTURE'], $encode),
2562 'WIDTH' => (int)$item['DETAIL_PICTURE']['WIDTH'],
2563 'HEIGHT' => (int)$item['DETAIL_PICTURE']['HEIGHT']
2564 )
2565 );
2566 }
2567 }
2568 }
2569 }
2570 return $result;
2571 }
2572
2573 public static function getLabel(&$item, $propertyCode)
2574 {
2575 static $propertyEnum = array();
2576
2577 if (!empty($item) && is_array($item))
2578 {
2579 $item['LABEL'] = false;
2580 $item['LABEL_VALUE'] = '';
2581 $item['LABEL_ARRAY_VALUE'] = array();
2582
2583 if (!is_array($propertyCode))
2584 {
2585 $propertyCode = array($propertyCode);
2586 }
2587
2588 if (!empty($propertyCode))
2589 {
2590 foreach ($propertyCode as $index => $code)
2591 {
2592 $code = (string)$code;
2593
2594 if ($code !== '' && isset($item['PROPERTIES'][$code]))
2595 {
2596 $prop = $item['PROPERTIES'][$code];
2597
2598 if (!empty($prop['VALUE']))
2599 {
2600 $useName = false;
2601
2602 if ($prop['PROPERTY_TYPE'] == 'L' && $prop['MULTIPLE'] == 'N')
2603 {
2604 if (!isset($propertyEnum[$prop['ID']]))
2605 {
2606 $count = 0;
2607 $enumList = CIBlockPropertyEnum::GetList(
2608 array(),
2609 array('PROPERTY_ID' => $prop['ID'])
2610 );
2611 while ($enum = $enumList->Fetch())
2612 {
2613 $count++;
2614 }
2615
2616 $propertyEnum[$prop['ID']] = $count;
2617 unset($enum, $enumList, $count);
2618 }
2619
2620 $useName = ($propertyEnum[$prop['ID']] == 1);
2621 }
2622
2623 if ($useName)
2624 {
2625 $item['LABEL_ARRAY_VALUE'][$code] = $prop['NAME'];
2626 }
2627 else
2628 {
2629 $item['LABEL_ARRAY_VALUE'][$code] = (is_array($prop['VALUE'])
2630 ? implode(' / ', $prop['VALUE'])
2631 : $prop['VALUE']
2632 );
2633 }
2634
2635 unset($useName);
2636 $item['LABEL'] = true;
2637
2638 if ($item['LABEL_VALUE'] === '')
2639 {
2640 $item['LABEL_VALUE'] = $item['LABEL_ARRAY_VALUE'][$code];
2641 }
2642
2643 if (isset($item['DISPLAY_PROPERTIES'][$code]))
2644 {
2645 unset($item['DISPLAY_PROPERTIES'][$code]);
2646 }
2647 }
2648 unset($prop);
2649 }
2650 }
2651 }
2652 }
2653 }
2654
2655 public static function clearProperties(&$properties, $clearCodes)
2656 {
2657 if (!empty($properties) && is_array($properties) && !empty($clearCodes))
2658 {
2659 if (!is_array($clearCodes))
2660 $clearCodes = array($clearCodes);
2661
2662 foreach ($clearCodes as $oneCode)
2663 {
2664 if (isset($properties[$oneCode]))
2665 unset($properties[$oneCode]);
2666 }
2667 unset($oneCode);
2668 }
2669 return !empty($properties);
2670 }
2671
2672 public static function getMinPriceFromList($priceList)
2673 {
2674 if (empty($priceList) || !is_array($priceList))
2675 return false;
2676 $result = false;
2677 foreach ($priceList as $price)
2678 {
2679 if (isset($price['MIN_PRICE']) && $price['MIN_PRICE'] == 'Y')
2680 {
2681 $result = $price;
2682 break;
2683 }
2684 }
2685 unset($price);
2686 return $result;
2687 }
2688
2689 public static function isEnabledCalculationDiscounts()
2690 {
2691 return (self::$calculationDiscounts >= 0);
2692 }
2693
2694 public static function enableCalculationDiscounts()
2695 {
2696 self::$calculationDiscounts++;
2697 }
2698
2699 public static function disableCalculationDiscounts()
2700 {
2701 self::$calculationDiscounts--;
2702 }
2703}
$count
Определения admin_tab.php:4
const CATALOG_VALUE_EPSILON
Определения include.php:108
$arResult
Определения generate_coupon.php:16
$boolFlag
Определения generate_coupon.php:21
static preloadPriceData(array $productIds, array $catalogGroups)
Определения discountmanager.php:562
static preloadProductDataToExtendOrder(array $productIds, array $userGroups)
Определения discountmanager.php:626
static setProductPropertiesCache($productId, $props)
Определения discountmanager.php:517
const TYPE_DISCOUNT
Определения discount.php:70
static getFieldImageData(array &$item, array $keys, $entity, $ipropertyKey='IPROPERTY_VALUES')
Определения tools.php:102
const TYPE_ELEMENT
Определения propertytable.php:68
const TYPE_STRING
Определения propertytable.php:65
const TYPE_LIST
Определения propertytable.php:70
static get($moduleId, $name, $default="", $siteId=false)
Определения option.php:30
Определения loader.php:13
static includeModule($moduleName)
Определения loader.php:67
static getList(array $parameters=array())
Определения datamanager.php:431
static normalizeArrayValuesByInt(&$map, $sorted=true)
Определения collection.php:150
static SetDiscountProductCache($arItem, $arParams=array())
Определения discount.php:3986
static SetAllDiscountFilterCache($arDiscountCache, $boolNeedClear=true)
Определения discount.php:3849
static GetDiscountFilterCacheKey($arCatalogGroups, $arUserGroups, $boolNeedClear=true)
Определения discount.php:3917
static SetProductSectionsCache($arItemIDs)
Определения discount.php:4147
static SetProductPropertiesCache($intProductID, $arProps)
Определения discount.php:4185
static GetDiscountResultCacheKey($arDiscountIDs, $strSiteID, $strRenewal, $boolNeedClear=true)
Определения discount.php:3968
static SetAllDiscountResultCache($arDiscountResultCache)
Определения discount.php:3956
static GetRestrictions($arParams, $boolKeys=true, $boolRevert=true)
Определения discount.php:2128
static Disable()
Определения discount_save.php:38
static Enable()
Определения discount_save.php:33
static GetListArray()
Определения cataloggroup.php:291
static GetGroupsPerms($arUserGroups=array(), $arCatalogGroupsFilter=array())
Определения cataloggroup.php:167
const TYPE_OFFER
Определения product.php:26
static CountPriceWithDiscount($price, $currency, $discounts)
Определения product.php:1863
static ConvertCurrency($valSum, $curFrom, $curTo, $valDate="")
Определения currency_rate.php:393
static getList($arOrder=array(), $arFilter=array(), $arGroupBy=false, $arNavStartParams=false, $arSelectFields=array())
Определения measure_ratio.php:15
static GetFileArray($fileId, $uploadDir=false)
Определения file.php:1207
static GetList($arOrder=array("SORT"=>"ASC"), $arFilter=array(), $arGroupBy=false, $arNavStartParams=false, $arSelectFields=array())
Определения iblockelement.php:658
static GetCatalogPrices($IBLOCK_ID, $arPriceCode)
Определения comp_pricetools.php:27
static GetProductProperties( $IBLOCK_ID, $ELEMENT_ID, $arPropertiesList, $arPropertiesValues)
Определения comp_pricetools.php:610
static getMinPriceFromList($priceList)
Определения comp_pricetools.php:2672
static $needDiscountCache
Определения comp_pricetools.php:18
static setRatioMinPrice(&$item, $replaceMinPrice=false)
Определения comp_pricetools.php:1750
static SetCatalogDiscountCache($arCatalogGroups, $arUserGroups, $siteId=false)
Определения comp_pricetools.php:124
static GetOffersIBlock($IBLOCK_ID)
Определения comp_pricetools.php:1166
static CheckProductProperties($iblockID, $elementID, $propertiesList, $propertiesValues, $enablePartialList=false)
Определения comp_pricetools.php:920
static getDoublePicturesForItem(&$item, $propertyCode, $encode=true)
Определения comp_pricetools.php:2373
static getSliderForItem(&$item, $propertyCode, $addDetailToSlider, $encode=true)
Определения comp_pricetools.php:2475
static $saleIncluded
Определения comp_pricetools.php:17
static enableCalculationDiscounts()
Определения comp_pricetools.php:2694
static getLabel(&$item, $propertyCode)
Определения comp_pricetools.php:2573
static $highLoadInclude
Определения comp_pricetools.php:16
static $catalogIncluded
Определения comp_pricetools.php:15
static getMinPriceFromOffers(&$offers, $currency, $replaceMinPrice=true)
Определения comp_pricetools.php:2324
static CanBuy( $IBLOCK_ID, $arCatalogPrices, $arItem)
Определения comp_pricetools.php:577
static GetOfferProperties($offerID, $iblockID, $propertiesList, $skuTreeProps='')
Определения comp_pricetools.php:1189
static GetItemPrices( $IBLOCK_ID, $arCatalogPrices, $arItem, $bVATInclude=true, $arCurrencyParams=array(), $USER_ID=0, $LID=SITE_ID)
Определения comp_pricetools.php:274
static $calculationDiscounts
Определения comp_pricetools.php:19
static getTreeProperties($skuInfo, $propertiesCodes, $defaultFields=array())
Определения comp_pricetools.php:1867
static isEnabledCalculationDiscounts()
Определения comp_pricetools.php:2689
static GetOffersArray($arFilter, $arElementID, $arOrder, $arSelectFields, $arSelectProperties, $limit, $arPrices, $vat_include, $arCurrencyParams=array(), $USER_ID=0, $LID=SITE_ID)
Определения comp_pricetools.php:1348
static getFillProductProperties($productProps)
Определения comp_pricetools.php:896
static checkPropDirectory(&$property, $getPropInfo=false)
Определения comp_pricetools.php:1810
static clearProperties(&$properties, $clearCodes)
Определения comp_pricetools.php:2655
static disableCalculationDiscounts()
Определения comp_pricetools.php:2699
static GetAllowCatalogPrices($arPriceTypes)
Определения comp_pricetools.php:107
static GetDefaultMeasure()
Определения comp_pricetools.php:1743
static GetList($arOrder=array("SORT"=>"ASC", "VALUE"=>"ASC"), $arFilter=array())
Определения iblockpropertyenum.php:18
Определения user.php:6037
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
$result
Определения get_property_values.php:14
$entity
$elementID
Определения group_wiki_post_comment.php:17
$select
Определения iblock_catalog_list.php:194
$selectFields
Определения iblock_catalog_list.php:160
$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
$siteId
Определения ajax.php:8
CheckSerializedData($str, $max_depth=200)
Определения tools.php:4949
roundEx($value, $prec=0)
Определения tools.php:4635
htmlspecialcharsbx($string, $flags=ENT_COMPAT, $doubleEncode=true)
Определения tools.php:2701
$name
Определения menu_edit.php:35
Определения collection.php:2
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
Определения prolog_main_admin.php:393
$ar
Определения options.php:199
if(empty($signedUserToken)) $key
Определения quickway.php:257
$i
Определения factura.php:643
</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
const SITE_ID
Определения sonet_set_content_view.php:12
$arFilter
Определения user_search.php:106
$intOfferIBlockID
Определения yandex_detail.php:77
$rsProps
Определения yandex_run.php:584
$iterator
Определения yandex_run.php:610
$arCatalog
Определения yandex_run.php:674