Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
basket.php
1<?php
3
10
11Loc::loadMessages(__FILE__);
12
17class Basket
18{
19 private static $statisticIncluded = null;
20 private static $saleIncluded = null;
21
34 public static function addProduct(array $product, array $basketFields = [], array $options = [])
35 {
36 $result = new Main\Result();
37
38 if (empty($product['PRODUCT_ID']))
39 {
40 $result->addError(new Main\Error(Loc::getMessage('BX_CATALOG_PRODUCT_BASKET_ERR_NO_PRODUCT')));
41 return $result;
42 }
43 $productId = (int)$product['PRODUCT_ID'];
44 if ($productId <= 0)
45 {
46 $result->addError(new Main\Error(Main\Localization\Loc::getMessage('BX_CATALOG_PRODUCT_BASKET_ERR_NO_PRODUCT')));
47 return $result;
48 }
49
50 $product['MODULE'] = 'catalog';
51 $product['PRODUCT_PROVIDER_CLASS'] = self::getDefaultProviderName();
52
53 if (!empty($basketFields))
54 $product = array_merge($product, $basketFields);
55
56 if (self::$saleIncluded === null)
57 self::$saleIncluded = Loader::includeModule('sale');
58
59 if (!self::$saleIncluded)
60 {
61 $result->addError(new Main\Error(Loc::getMessage('BX_CATALOG_PRODUCT_BASKET_ERR_NO_SALE')));
62 return $result;
63 }
64
65 $siteId = SITE_ID;
66 if (!empty($basketFields['LID']))
67 $siteId = $basketFields['LID'];
68
69 $context = array(
70 'SITE_ID' => $siteId,
71 );
72
73 $registry = Sale\Registry::getInstance(Sale\Registry::REGISTRY_TYPE_ORDER);
74
76 $basketClass = $registry->getBasketClassName();
77
78 $basket = $basketClass::loadItemsForFUser(Sale\Fuser::getId(), $siteId);
79
80 $options['CHECK_PERMISSIONS'] = 'Y';
81 $options['USE_MERGE'] = (isset($options['USE_MERGE']) && $options['USE_MERGE'] == 'N' ? 'N' : 'Y');
82 $options['CHECK_CRAWLERS'] = 'Y';
83
84 $result = static::add($basket, $product, $context, $options);
85
86 if ($result->isSuccess())
87 {
88 $saveResult = $basket->save();
89 if ($saveResult->isSuccess())
90 {
91 $resultData = $result->getData();
92 if (!empty($resultData['BASKET_ITEM']))
93 {
94 $item = $resultData['BASKET_ITEM'];
95 if ($item instanceof Sale\BasketItemBase)
96 {
97 if (self::$statisticIncluded === null)
98 self::$statisticIncluded = Main\Loader::includeModule('statistic');
99
100 if (self::$statisticIncluded)
101 {
102 \CStatistic::Set_Event(
103 'sale2basket', 'catalog', $item->getField('DETAIL_PAGE_URL')
104 );
105 }
106 $result->setData(array(
107 'ID' => $item->getId()
108 ));
109 }
110 else
111 {
112 $result->addError(new Main\Error(Loc::getMessage('BX_CATALOG_PRODUCT_BASKET_ERR_UNKNOWN')));
113 }
114 unset($item);
115 }
116 else
117 {
118 $result->addError(new Main\Error(Loc::getMessage('BX_CATALOG_PRODUCT_BASKET_ERR_UNKNOWN')));
119 }
120 unset($resultData);
121 }
122 else
123 {
124 $result->addErrors($saveResult->getErrors());
125 }
126 unset($saveResult);
127 }
128 unset($basket, $context, $siteId);
129
130 return $result;
131 }
132
146 public static function addProductToBasket(Sale\BasketBase $basket, array $fields, array $context, array $options = [])
147 {
148 $options['CHECK_CRAWLERS'] = 'N';
149 return static::add($basket, $fields, $context, $options);
150 }
151
165 public static function addProductToBasketWithPermissions(Sale\BasketBase $basket, array $fields, array $context, $options = true)
166 {
167 if (!is_array($options))
168 $options = ['USE_MERGE' => ($options ? 'Y' : 'N')];
169 $options['CHECK_PERMISSIONS'] = 'Y';
170 $options['CHECK_CRAWLERS'] = 'Y';
171 return static::add($basket, $fields, $context, $options);
172 }
173
188 private static function add(Sale\BasketBase $basket, array $fields, array $context, array $options = [])
189 {
190 $result = new Main\Result();
191
192 if (!isset($options['CHECK_CRAWLERS']) || $options['CHECK_CRAWLERS'] == 'Y')
193 {
194 $validBuyer = static::checkCurrentUser();
195 if (!$validBuyer->isSuccess())
196 {
197 $result->addErrors($validBuyer->getErrors());
198 return $result;
199 }
200 unset($validBuyer);
201 }
202
203 if (empty($fields['PRODUCT_ID']))
204 {
205 $result->addError(new Main\Error(Loc::getMessage('BX_CATALOG_PRODUCT_BASKET_ERR_NO_PRODUCT')));
206 return $result;
207 }
208 $productId = (int)$fields['PRODUCT_ID'];
209 if ($productId <= 0)
210 {
211 $result->addError(new Main\Error(Main\Localization\Loc::getMessage('BX_CATALOG_PRODUCT_BASKET_ERR_NO_PRODUCT')));
212 return $result;
213 }
214 unset($fields['PRODUCT_ID']);
215
216 if (empty($fields['QUANTITY']))
217 {
218 $result->addError(new Main\Error(Loc::getMessage('BX_CATALOG_PRODUCT_BASKET_ERR_EMPTY_QUANTITY')));
219 return $result;
220 }
221 $quantity = (float)$fields['QUANTITY'];
222 if ($quantity <= 0)
223 {
224 $result->addError(new Main\Error(Loc::getMessage('BX_CATALOG_PRODUCT_BASKET_ERR_EMPTY_QUANTITY')));
225 return $result;
226 }
227
228 if (self::$saleIncluded === null)
229 self::$saleIncluded = Loader::includeModule('sale');
230
231 if (!self::$saleIncluded)
232 {
233 $result->addError(new Main\Error(Loc::getMessage('BX_CATALOG_PRODUCT_BASKET_ERR_NO_SALE')));
234 return $result;
235 }
236
237 $module = 'catalog';
238
239 $presets = ['PRODUCT_ID' => $productId];
240
241 if (array_key_exists('MODULE', $fields))
242 {
243 $module = $fields['MODULE'];
244 unset($fields['MODULE']);
245 }
246
247 if (
248 $module === 'catalog'
249 && !isset($fields['PRODUCT_PROVIDER_CLASS'])
250 )
251 {
252 $fields['PRODUCT_PROVIDER_CLASS'] = self::getDefaultProviderName();
253 }
254
255 $transferFields = [
256 'PRODUCT_PROVIDER_CLASS' => true,
257 'CALLBACK_FUNC' => true,
258 'PAY_CALLBACK_FUNC' => true,
259 'SUBSCRIBE' => true
260 ];
261 $presets = array_merge($presets, array_intersect_key($fields, $transferFields));
262 $fields = array_diff_key($fields, $transferFields);
263 unset($transferFields);
264
265 $propertyList = (!empty($fields['PROPS']) && is_array($fields['PROPS']) ? $fields['PROPS'] : []);
266 if (array_key_exists('PROPS', $fields))
267 unset($fields['PROPS']);
268
269 if ($module == 'catalog')
270 {
271 $elementFilter = array(
272 'ID' => $productId,
273 'ACTIVE' => 'Y',
274 'ACTIVE_DATE' => 'Y',
275 'CHECK_PERMISSIONS' => 'N'
276 );
277
278 if (!empty($options['CHECK_PERMISSIONS']) && $options['CHECK_PERMISSIONS'] == "Y")
279 {
280 $elementFilter['CHECK_PERMISSIONS'] = 'Y';
281 $elementFilter['MIN_PERMISSION'] = 'R';
282 if (isset($context['USER_ID']))
283 $elementFilter['PERMISSIONS_BY'] = $context['USER_ID'];
284 }
285
286 $iterator = \CIBlockElement::GetList(
287 array(),
288 $elementFilter,
289 false,
290 false,
291 array(
292 "ID",
293 "IBLOCK_ID",
294 "XML_ID",
295 "NAME",
296 "DETAIL_PAGE_URL",
297 )
298 );
299 if (!($elementFields = $iterator->GetNext()))
300 {
301 $result->addError(new Main\Error(Loc::getMessage('BX_CATALOG_PRODUCT_BASKET_ERR_NO_IBLOCK_ELEMENT')));
302 return $result;
303 }
304
305 $iterator = Catalog\ProductTable::getList(array(
306 'select' => array(
307 'ID', 'TYPE', 'AVAILABLE', 'CAN_BUY_ZERO', 'QUANTITY_TRACE', 'QUANTITY',
308 'WEIGHT', 'WIDTH', 'HEIGHT', 'LENGTH',
309 'MEASURE', 'BARCODE_MULTI'
310 ),
311 'filter' => array('=ID' => $productId)
312 ));
313 $productFields = $iterator->fetch();
314 unset($iterator);
315 if (empty($productFields))
316 {
317 $result->addError(new Main\Error(Loc::getMessage('BX_CATALOG_PRODUCT_BASKET_ERR_NO_PRODUCT')));
318 return $result;
319 }
320
321 if (
322 ($productFields['TYPE'] == Catalog\ProductTable::TYPE_SKU || $productFields['TYPE'] == Catalog\ProductTable::TYPE_EMPTY_SKU)
323 && (string)Main\Config\Option::get('catalog', 'show_catalog_tab_with_offers') != 'Y'
324 )
325 {
326 $result->addError(new Main\Error(Loc::getMessage('BX_CATALOG_PRODUCT_BASKET_ERR_CANNOT_ADD_SKU')));
327 return $result;
328 }
329 if ($productFields['AVAILABLE'] != Catalog\ProductTable::STATUS_YES)
330 {
331 $result->addError(new Main\Error(Loc::getMessage('BX_CATALOG_PRODUCT_BASKET_ERR_PRODUCT_RUN_OUT')));
332 return $result;
333 }
334 if ($productFields['TYPE'] == Catalog\ProductTable::TYPE_OFFER)
335 {
336 $skuInfo = \CCatalogSku::GetProductInfo($productId, $elementFields['IBLOCK_ID']);
337 if (empty($skuInfo))
338 {
339 $result->addError(new Main\Error(Loc::getMessage('BX_CATALOG_PRODUCT_BASKET_ERR_PRODUCT_BAD_TYPE')));
340 return $result;
341 }
342 else
343 {
344 $parentIterator = \CIBlockElement::GetList(
345 array(),
346 array(
347 'ID' => $skuInfo['ID'],
348 'IBLOCK_ID' => $skuInfo['IBLOCK_ID'],
349 'ACTIVE' => 'Y',
350 'ACTIVE_DATE' => 'Y',
351 'CHECK_PERMISSIONS' => 'N'
352 ),
353 false,
354 false,
355 array('ID', 'IBLOCK_ID', 'XML_ID')
356 );
357 $parent = $parentIterator->Fetch();
358 if (empty($parent))
359 {
360 $result->addError(new Main\Error(Loc::getMessage('BX_CATALOG_PRODUCT_BASKET_ERR_NO_PRODUCT')));
361 return $result;
362 }
363 elseif (mb_strpos($elementFields["~XML_ID"], '#') === false)
364 {
365 $elementFields["~XML_ID"] = $parent['XML_ID'].'#'.$elementFields["~XML_ID"];
366 }
367 unset($parent, $parentIterator);
368 }
369 }
370
371 if ($productFields['TYPE'] == Catalog\ProductTable::TYPE_SET)
372 {
373 $allSets = \CCatalogProductSet::getAllSetsByProduct($productId, \CCatalogProductSet::TYPE_SET);
374 if (empty($allSets))
375 {
376 $result->addError(new Main\Error(Loc::getMessage('BX_CATALOG_PRODUCT_BASKET_ERR_NO_PRODUCT_SET')));
377 return $result;
378 }
379 $set = current($allSets);
380 unset($allSets);
381 $itemIds = array();
382 foreach ($set['ITEMS'] as $item)
383 {
384 if ($item['ITEM_ID'] != $item['OWNER_ID'])
385 $itemIds[$item['ITEM_ID']] = $item['ITEM_ID'];
386 }
387 if (empty($itemIds))
388 {
389 $result->addError(new Main\Error(Loc::getMessage('BX_CATALOG_PRODUCT_BASKET_ERR_NO_PRODUCT_SET')));
390 return $result;
391 }
392
393 $setFilter = array(
394 'ID' => $itemIds,
395 'ACTIVE' => 'Y',
396 'ACTIVE_DATE' => 'Y',
397 'CHECK_PERMISSIONS' => 'N'
398 );
399 if (!empty($options['CHECK_PERMISSIONS']) && $options['CHECK_PERMISSIONS'] == "Y")
400 {
401 $setFilter['CHECK_PERMISSIONS'] = 'Y';
402 $setFilter['MIN_PERMISSION'] = 'R';
403 if (isset($context['USER_ID']))
404 $setFilter['PERMISSIONS_BY'] = $context['USER_ID'];
405 }
406
407 $iterator = \CIBlockElement::GetList(
408 array(),
409 $setFilter,
410 false,
411 false,
412 array('ID', 'IBLOCK_ID')
413 );
414 while ($row = $iterator->Fetch())
415 {
416 if (isset($itemIds[$row['ID']]))
417 unset($itemIds[$row['ID']]);
418 }
419 unset($row, $iterator);
420 if (!empty($itemIds))
421 {
422 $result->addError(new Main\Error(Loc::getMessage('BX_CATALOG_PRODUCT_BASKET_ERR_NO_PRODUCT_SET_ITEMS')));
423 return $result;
424 }
425 }
426
427 $propertyIndex = self::getPropertyIndex('CATALOG.XML_ID', $propertyList);
428 if (!isset($fields['CATALOG_XML_ID']) || $propertyIndex === null)
429 {
430 $iBlockXmlID = (string)\CIBlock::GetArrayByID($elementFields['IBLOCK_ID'], 'XML_ID');
431 if ($iBlockXmlID !== '')
432 {
433 $fields['CATALOG_XML_ID'] = $iBlockXmlID;
434 $propertyData = array(
435 'NAME' => 'Catalog XML_ID',
436 'CODE' => 'CATALOG.XML_ID',
437 'VALUE' => $iBlockXmlID
438 );
439 if ($propertyIndex !== null)
440 $propertyList[$propertyIndex] = $propertyData;
441 else
442 $propertyList[] = $propertyData;
443 unset($propertyData);
444 }
445 unset($iBlockXmlID);
446 }
447
448 $propertyIndex = self::getPropertyIndex('PRODUCT.XML_ID', $propertyList);
449 if (!isset($fields['PRODUCT_XML_ID']) || $propertyIndex === null)
450 {
451 $fields['PRODUCT_XML_ID'] = $elementFields['~XML_ID'];
452 $propertyData = array(
453 'NAME' => 'Product XML_ID',
454 'CODE' => 'PRODUCT.XML_ID',
455 'VALUE' => $elementFields['~XML_ID']
456 );
457 if ($propertyIndex !== null)
458 $propertyList[$propertyIndex] = $propertyData;
459 else
460 $propertyList[] = $propertyData;
461 unset($propertyData);
462 }
463 unset($propertyIndex);
464
465 //TODO: change to d7 measure class
466 $productFields['MEASURE'] = (int)$productFields['MEASURE'];
467 $productFields['MEASURE_NAME'] = '';
468 $productFields['MEASURE_CODE'] = 0;
469 if ($productFields['MEASURE'] <= 0)
470 {
471 $measure = \CCatalogMeasure::getDefaultMeasure(true, true);
472 $productFields['MEASURE_NAME'] = $measure['~SYMBOL_RUS'];
473 $productFields['MEASURE_CODE'] = $measure['CODE'];
474 unset($measure);
475 }
476 else
477 {
478 $measureIterator = \CCatalogMeasure::getList(
479 [],
480 ['ID' => $productFields['MEASURE']],
481 false,
482 false,
483 ['ID', 'SYMBOL_RUS', 'CODE']
484 );
485 $measure = $measureIterator->Fetch();
486 unset($measureIterator);
487 if (!empty($measure))
488 {
489 $productFields['MEASURE_NAME'] = $measure['SYMBOL_RUS'];
490 $productFields['MEASURE_CODE'] = $measure['CODE'];
491 }
492 unset($measure);
493 }
494
495 if (isset($options['FILL_PRODUCT_PROPERTIES']) && $options['FILL_PRODUCT_PROPERTIES'] === 'Y')
496 {
497 if ($productFields['TYPE'] == Catalog\ProductTable::TYPE_OFFER)
498 {
499 self::fillOfferProperties($propertyList, $productId, $elementFields['IBLOCK_ID']);
500 }
501 }
502
503 $fields['TYPE'] = Sale\Internals\Catalog\ProductTypeMapper::getType((int)$productFields['TYPE']);
504
505 $fields += [
506 'DETAIL_PAGE_URL' => $elementFields['~DETAIL_PAGE_URL'],
507 'BARCODE_MULTI' => $productFields['BARCODE_MULTI'],
508 'WEIGHT' => (float)$productFields['WEIGHT'],
509 'DIMENSIONS' => [
510 'WIDTH' => $productFields['WIDTH'],
511 'HEIGHT' => $productFields['HEIGHT'],
512 'LENGTH' => $productFields['LENGTH']
513 ],
514 'MEASURE_ID' => $productFields['MEASURE'],
515 'MEASURE_NAME' => $productFields['MEASURE_NAME'],
516 'MEASURE_CODE' => $productFields['MEASURE_CODE']
517 ];
518
519 unset($productFields);
520 }
521
522 if (static::isCompatibilityEventAvailable())
523 {
524 $eventFields = array_merge($presets, $fields);
525 $eventFields['MODULE'] = $module;
526 $eventFields['PROPS'] = $propertyList;
527
528 $eventResult = static::runCompatibilityEvent($eventFields);
529 if ($eventResult === false)
530 {
531 return $result;
532 }
533
534 foreach ($eventResult as $key => $value)
535 {
536 if (isset($presets[$key]))
537 {
538 if ($presets[$key] !== $value)
539 {
540 $presets[$key] = $value;
541 }
542 }
543 elseif (!isset($fields[$key]) || $fields[$key] !== $value)
544 {
545 $fields[$key] = $value;
546 }
547 }
548 unset($key, $value);
549
550 $propertyList = $eventResult['PROPS'];
551 unset($eventResult);
552 }
553
554 $basketItem = null;
555 // using merge by default
556 if (!isset($options['USE_MERGE']) || $options['USE_MERGE'] === 'Y')
557 {
558 $basketItem = $basket->getExistsItem($module, $productId, $propertyList);
559 }
560
561 if ($basketItem)
562 {
563 $fields['QUANTITY'] = $basketItem->isDelay() ? $quantity : $basketItem->getQuantity() + $quantity;
564 }
565 else
566 {
567 $fields['QUANTITY'] = $quantity;
568 $fields['DELAY'] ??= 'N';
569 $basketCode = !empty($fields['BASKET_CODE']) ? $fields['BASKET_CODE'] : null;
570 $basketItem = $basket->createItem($module, $productId, $basketCode);
571 }
572
573 if (!$basketItem)
574 {
575 throw new Main\ObjectNotFoundException('BasketItem');
576 }
577
579 $propertyCollection = $basketItem->getPropertyCollection();
580 if ($propertyCollection)
581 {
582 $propertyCollection->redefine($propertyList);
583 }
584
585 $r = $basketItem->setFields($presets);
586 if (!$r->isSuccess())
587 {
588 $result->addErrors($r->getErrors());
589 return $result;
590 }
591
592 //If error happend while setting quantity field we will know the name of product.
593 if(!empty($elementFields['~NAME']))
594 {
595 $basketItem->setField('NAME', $elementFields['~NAME']);
596 }
597
598 $r = $basketItem->setField('QUANTITY', $fields['QUANTITY']);
599 if (!$r->isSuccess())
600 {
601 $result->addErrors($r->getErrors());
602 return $result;
603 }
604 unset($fields['QUANTITY']);
605
606 $settableFields = array_fill_keys($basketItem::getSettableFields(), true);
607 $basketFields = array_intersect_key($fields, $settableFields);
608
609 if (!empty($basketFields))
610 {
611 $r = $basketItem->setFields($basketFields);
612 if (!$r->isSuccess())
613 {
614 $result->addErrors($r->getErrors());
615 return $result;
616 }
617 }
618
619 $result->setData(['BASKET_ITEM' => $basketItem]);
620
621 return $result;
622 }
623
627 private static function isCompatibilityEventAvailable()
628 {
629 return Main\Config\Option::get('sale', 'expiration_processing_events', 'N') === 'Y';
630 }
631
636 private static function runCompatibilityEvent(array $fields)
637 {
638 foreach (GetModuleEvents("sale", "OnBeforeBasketAdd", true) as $event)
639 {
640 if (ExecuteModuleEventEx($event, array(&$fields)) === false)
641 return false;
642 }
643
644 return $fields;
645 }
646
653 private static function fillOfferProperties(array &$propertyList, $id, $iblockId)
654 {
655 static $properties = [];
656
657 $skuInfo = \CCatalogSku::GetInfoByOfferIBlock($iblockId);
658 if (empty($skuInfo))
659 return;
660 $skuPropertyId = $skuInfo['SKU_PROPERTY_ID'];
661 $parentIblockId = $skuInfo['PRODUCT_IBLOCK_ID'];
662 unset($skuInfo);
663
664 if (!isset($properties[$iblockId]))
665 {
666 $properties[$iblockId] = [];
667 $iterator = Iblock\PropertyTable::getList([
668 'select' => [
669 'ID',
670 'CODE',
671 ],
672 'filter' => [
673 '=IBLOCK_ID' => $iblockId,
674 '=ACTIVE' => 'Y',
675 '@PROPERTY_TYPE' => [
676 Iblock\PropertyTable::TYPE_ELEMENT,
677 Iblock\PropertyTable::TYPE_LIST,
678 Iblock\PropertyTable::TYPE_STRING,
679 ],
680 '=MULTIPLE' => 'N',
681 ],
682 'order' => [
683 'ID' => 'ASC',
684 ]
685 ]);
686 while ($row = $iterator->fetch())
687 {
688 $row['ID'] = (int)$row['ID'];
689 if ($row['ID'] == $skuPropertyId)
690 continue;
691 $properties[$iblockId][] = $row['CODE'] ?? $row['ID'];
692 }
693 unset($row, $iterator);
694 }
695 if (empty($properties[$iblockId]))
696 return;
697
698 $offerProperties = \CIBlockPriceTools::GetOfferProperties(
699 $id,
700 $parentIblockId,
701 $properties[$iblockId]
702 );
703 unset($parentIblockId, $skuPropertyId);
704
705 if (empty($offerProperties))
706 return;
707
708 $codeMap = [];
709 if (!empty($propertyList))
710 {
711 foreach ($propertyList as $row)
712 {
713 if (!isset($row['CODE']))
714 continue;
715 $index = (string)$row['CODE'];
716 if ($index === '')
717 continue;
718 $codeMap[$index] = true;
719 }
720 unset($index, $row);
721 }
722 foreach ($offerProperties as $row)
723 {
724 $index = (string)$row['CODE'];
725 if (isset($codeMap[$index]))
726 continue;
727 $codeMap[$index] = true;
728 $propertyList[] = $row;
729 }
730 unset($index, $row, $codeMap, $offerProperties);
731 }
732
740 private static function getPropertyIndex($code, array $propertyList = array())
741 {
742 $propertyIndex = null;
743 if (empty($propertyList))
744 return $propertyIndex;
745
746 foreach ($propertyList as $index => $propertyData)
747 {
748 if (!empty($propertyData['CODE']) && $code == $propertyData['CODE'])
749 {
750 $propertyIndex = $index;
751 break;
752 }
753 }
754 unset($index, $propertyData);
755
756 return $propertyIndex;
757 }
758
762 public static function getDefaultProviderName()
763 {
764 return "\Bitrix\Catalog\Product\CatalogProvider";
765 }
766
772 public static function isNotCrawler()
773 {
774 $result = static::checkCurrentUser();
775 return $result->isSuccess();
776
777 }
778
784 private static function checkCurrentUser()
785 {
786 $result = new Main\Result();
787
788 if (self::$statisticIncluded === null)
789 self::$statisticIncluded = Main\Loader::includeModule('statistic');
790
791 if (!self::$statisticIncluded)
792 return $result;
793
794 if (isset($_SESSION['SESS_SEARCHER_ID']) && (int)$_SESSION['SESS_SEARCHER_ID'] > 0)
795 $result->addError(new Main\Error(Loc::getMessage('BX_CATALOG_PRODUCT_BASKET_ERR_SEARCHER')));
796
797 return $result;
798 }
799}
static addProductToBasket(Sale\BasketBase $basket, array $fields, array $context, array $options=[])
Definition basket.php:146
static addProductToBasketWithPermissions(Sale\BasketBase $basket, array $fields, array $context, $options=true)
Definition basket.php:165
static loadMessages($file)
Definition loc.php:64
static getMessage($code, $replace=null, $language=null)
Definition loc.php:29
static getId($skipCreate=false)
Definition fuser.php:33