Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
element.php
1<?
3
13
19Loc::loadMessages(__FILE__);
20
21abstract class Element extends Base
22{
23 public function onPrepareComponentParams($params)
24 {
25 if (!is_array($params))
26 {
27 $params = [];
28 }
29 $params['ADD_SECTIONS_CHAIN'] = (isset($params['ADD_SECTIONS_CHAIN']) && $params['ADD_SECTIONS_CHAIN'] === 'N' ? 'N' : 'Y');
30 $params['PRODUCT_DISPLAY_MODE'] = 'Y';
31 $params = parent::onPrepareComponentParams($params);
32 $params['IBLOCK_TYPE'] = trim((string)($params['IBLOCK_TYPE'] ?? ''));
33
34 if ((int)$params['ELEMENT_ID'] > 0 && (int)$params['ELEMENT_ID'] != $params['ELEMENT_ID'] && Loader::includeModule('iblock'))
35 {
36 $this->errorCollection->setError(new Error(Loc::getMessage('CATALOG_ELEMENT_NOT_FOUND'), self::ERROR_404));
37
38 return $params;
39 }
40
41 $params['ELEMENT_ID'] = (int)$params['ELEMENT_ID'];
42 $params['ELEMENT_CODE'] = trim((string)($params['ELEMENT_CODE'] ?? ''));
43
44 $params['CHECK_SECTION_ID_VARIABLE'] = isset($params['CHECK_SECTION_ID_VARIABLE']) && $params['CHECK_SECTION_ID_VARIABLE'] === 'Y' ? 'Y' : 'N';
45 $params['SECTION_ID_VARIABLE'] = trim((string)($params['SECTION_ID_VARIABLE'] ?? ''));
46 if (
47 $params['SECTION_ID_VARIABLE'] === ''
48 || !preg_match(self::PARAM_TITLE_MASK, $params['SECTION_ID_VARIABLE'])
49 )
50 {
51 $params['SECTION_ID_VARIABLE'] = 'SECTION_ID';
52 }
53
54 $params['FROM_SECTION'] = '';
55 if ($params['CHECK_SECTION_ID_VARIABLE'] === 'Y')
56 {
57 $params['FROM_SECTION'] = trim($this->request->get($params['SECTION_ID_VARIABLE']));
58 }
59
60 $params['SECTIONS_CHAIN_START_FROM'] = (int)($params['SECTIONS_CHAIN_START_FROM'] ?? 0);
61 $params['META_KEYWORDS'] = trim((string)($params['META_KEYWORDS'] ?? ''));
62 $params['META_DESCRIPTION'] = trim((string)($params['META_DESCRIPTION'] ?? ''));
63 $params['BROWSER_TITLE'] = trim((string)($params['BROWSER_TITLE'] ?? ''));
64
65 $params['BACKGROUND_IMAGE'] = trim((string)($params['BACKGROUND_IMAGE'] ?? ''));
66 if ($params['BACKGROUND_IMAGE'] === '-')
67 {
68 $params['BACKGROUND_IMAGE'] = '';
69 }
70
71 $params['USE_MAIN_ELEMENT_SECTION'] = isset($params['USE_MAIN_ELEMENT_SECTION']) && $params['USE_MAIN_ELEMENT_SECTION'] === 'Y';
72 $params['ADD_ELEMENT_CHAIN'] = isset($params['ADD_ELEMENT_CHAIN']) && $params['ADD_ELEMENT_CHAIN'] === 'Y';
73 $params['LINK_IBLOCK_TYPE'] = trim((string)($params['LINK_IBLOCK_TYPE'] ?? ''));
74 $params['LINK_IBLOCK_ID'] = (int)($params['LINK_IBLOCK_ID'] ?? 0);
75 $params['LINK_PROPERTY_SID'] = trim((string)($params['LINK_PROPERTY_SID'] ?? ''));
76 $params['LINK_ELEMENTS_URL'] = trim((string)($params['LINK_ELEMENTS_URL'] ?? ''));
77 if ($params['LINK_ELEMENTS_URL'] === '')
78 {
79 $params['LINK_ELEMENTS_URL'] = 'link.php?PARENT_ELEMENT_ID=#ELEMENT_ID#';
80 }
81
82 $params['SHOW_WORKFLOW'] = $this->request->get('show_workflow') === 'Y';
83 if ($params['SHOW_WORKFLOW'])
84 {
85 $params['CACHE_TIME'] = 0;
86 }
87
88 $params['PRICE_VAT_SHOW_VALUE'] = isset($params['PRICE_VAT_SHOW_VALUE']) && $params['PRICE_VAT_SHOW_VALUE'] === 'Y';
89
90 // compatibility to old HIDE_NOT_AVAILABLE parameter
91 if (!isset($params['HIDE_NOT_AVAILABLE_OFFERS']) && isset($params['HIDE_NOT_AVAILABLE']))
92 {
93 $params['HIDE_NOT_AVAILABLE_OFFERS'] = $params['HIDE_NOT_AVAILABLE'];
94 }
95
96 if (
97 !isset($params['HIDE_NOT_AVAILABLE_OFFERS'])
98 || ($params['HIDE_NOT_AVAILABLE_OFFERS'] !== 'Y' && $params['HIDE_NOT_AVAILABLE_OFFERS'] !== 'L')
99 )
100 {
101 $params['HIDE_NOT_AVAILABLE_OFFERS'] = 'N';
102 }
103
104 $params['HIDE_NOT_AVAILABLE'] = 'N';
105 $params['USE_ELEMENT_COUNTER'] = isset($params['USE_ELEMENT_COUNTER']) && $params['USE_ELEMENT_COUNTER'] === 'N' ? 'N' : 'Y';
106 $params['SHOW_DEACTIVATED'] = isset($params['SHOW_DEACTIVATED']) && $params['SHOW_DEACTIVATED'] === 'Y' ? 'Y' : 'N';
107
108 // default gifts
109 if (empty($params['USE_GIFTS_DETAIL']))
110 {
111 $params['USE_GIFTS_DETAIL'] = 'Y';
112 }
113
114 if (empty($params['USE_GIFTS_MAIN_PR_SECTION_LIST']))
115 {
116 $params['USE_GIFTS_MAIN_PR_SECTION_LIST'] = 'Y';
117 }
118
119 if (empty($params['GIFTS_DETAIL_PAGE_ELEMENT_COUNT']))
120 {
121 $params['GIFTS_DETAIL_PAGE_ELEMENT_COUNT'] = 4;
122 }
123
124 if (empty($params['GIFTS_MAIN_PRODUCT_DETAIL_PAGE_ELEMENT_COUNT']))
125 {
126 $params['GIFTS_MAIN_PRODUCT_DETAIL_PAGE_ELEMENT_COUNT'] = 4;
127 }
128
129 $this->storage['IBLOCK_PARAMS'] = $this->getIblockParams($params);
130
131 return $params;
132 }
133
134 protected function getIblockParams(&$params)
135 {
136 $usePropertyFeatures = Iblock\Model\PropertyFeature::isEnabledFeatures();
137
138 if (!isset($params['PROPERTY_CODE']) || !is_array($params['PROPERTY_CODE']))
139 {
140 $params['PROPERTY_CODE'] = array();
141 }
142
143 foreach ($params['PROPERTY_CODE'] as $k => $v)
144 {
145 if ($v == '')
146 {
147 unset($params['PROPERTY_CODE'][$k]);
148 }
149 }
150
151 if (!isset($params['OFFERS_FIELD_CODE']))
152 {
153 $params['OFFERS_FIELD_CODE'] = array();
154 }
155 elseif (!is_array($params['OFFERS_FIELD_CODE']))
156 {
157 $params['OFFERS_FIELD_CODE'] = array($params['OFFERS_FIELD_CODE']);
158 }
159
160 foreach ($params['OFFERS_FIELD_CODE'] as $key => $value)
161 {
162 if ($value == '')
163 {
164 unset($params['OFFERS_FIELD_CODE'][$key]);
165 }
166 }
167
168 if (!isset($params['OFFERS_PROPERTY_CODE']))
169 {
170 $params['OFFERS_PROPERTY_CODE'] = array();
171 }
172 elseif (!is_array($params['OFFERS_PROPERTY_CODE']))
173 {
174 $params['OFFERS_PROPERTY_CODE'] = array($params['OFFERS_PROPERTY_CODE']);
175 }
176
177 foreach ($params['OFFERS_PROPERTY_CODE'] as $key => $value)
178 {
179 if ($value == '')
180 {
181 unset($params['OFFERS_PROPERTY_CODE'][$key]);
182 }
183 }
184
185 if (!in_array('PREVIEW_PICTURE', $params['OFFERS_PROPERTY_CODE']))
186 {
187 $params['OFFERS_PROPERTY_CODE'][] = 'PREVIEW_PICTURE';
188 }
189
190 if (!in_array('DETAIL_PICTURE', $params['OFFERS_PROPERTY_CODE']))
191 {
192 $params['OFFERS_PROPERTY_CODE'][] = 'DETAIL_PICTURE';
193 }
194
195 $cartProperties = [];
196 $offersCartProperties = [];
197 $offerTreeProperties = [];
198 if (!$usePropertyFeatures)
199 {
200 if (!isset($params['PRODUCT_PROPERTIES']) || !is_array($params['PRODUCT_PROPERTIES']))
201 {
202 $params['PRODUCT_PROPERTIES'] = array();
203 }
204
205 foreach ($params['PRODUCT_PROPERTIES'] as $k => $v)
206 {
207 if ($v == '')
208 {
209 unset($params['PRODUCT_PROPERTIES'][$k]);
210 }
211 }
212 $cartProperties = $params['PRODUCT_PROPERTIES'];
213
214 if (!isset($params['OFFERS_CART_PROPERTIES']) || !is_array($params['OFFERS_CART_PROPERTIES']))
215 {
216 $params['OFFERS_CART_PROPERTIES'] = array();
217 }
218
219 foreach ($params['OFFERS_CART_PROPERTIES'] as $i => $pid)
220 {
221 if ($pid == '')
222 {
223 unset($params['OFFERS_CART_PROPERTIES'][$i]);
224 }
225 }
226 $offersCartProperties = $params['OFFERS_CART_PROPERTIES'];
227
228 if (!isset($params['OFFER_TREE_PROPS']))
229 {
230 $params['OFFER_TREE_PROPS'] = array();
231 }
232 elseif (!is_array($params['OFFER_TREE_PROPS']))
233 {
234 $params['OFFER_TREE_PROPS'] = array($params['OFFER_TREE_PROPS']);
235 }
236
237 foreach ($params['OFFER_TREE_PROPS'] as $key => $value)
238 {
239 $value = (string)$value;
240 if ($value == '' || $value === '-')
241 {
242 unset($params['OFFER_TREE_PROPS'][$key]);
243 }
244 }
245
246 if (empty($params['OFFER_TREE_PROPS']) && !empty($params['OFFERS_CART_PROPERTIES']))
247 {
248 $params['OFFER_TREE_PROPS'] = $params['OFFERS_CART_PROPERTIES'];
249 foreach ($params['OFFER_TREE_PROPS'] as $key => $value)
250 {
251 if ($value === '-')
252 {
253 unset($params['OFFER_TREE_PROPS'][$key]);
254 }
255 }
256 }
257 $offerTreeProperties = $params['OFFER_TREE_PROPS'];
258 }
259
260 return array(
261 $params['IBLOCK_ID'] => array(
262 'PROPERTY_CODE' => $params['PROPERTY_CODE'],
263 'CART_PROPERTIES' => $cartProperties,
264 'OFFERS_FIELD_CODE' => $params['OFFERS_FIELD_CODE'],
265 'OFFERS_PROPERTY_CODE' => $params['OFFERS_PROPERTY_CODE'],
266 'OFFERS_CART_PROPERTIES' => $offersCartProperties,
267 'OFFERS_TREE_PROPS' => $offerTreeProperties
268 )
269 );
270 }
271
272 protected function checkModules()
273 {
274 if ($success = parent::checkModules())
275 {
276 $this->storage['MODULES']['workflow'] = false;
277 }
278
279 return $success;
280 }
281
282 protected function initialLoadAction()
283 {
284 parent::initialLoadAction();
285
286 if (!$this->hasErrors() && isset($this->arResult['ID']))
287 {
288 $this->initAdminIconsPanel();
289 $this->sendCounters();
290 $this->saveViewedProduct();
291 $this->initMetaData();
292 }
293 }
294
295 protected function processResultData()
296 {
297 if ($this->checkElementId())
298 {
299 parent::processResultData();
300 $this->arResult['IS_FACEBOOK_CONVERSION_CUSTOMIZE_PRODUCT_EVENT_ENABLED'] = false;
301 if (Loader::includeModule('sale'))
302 {
303 $this->arResult['IS_FACEBOOK_CONVERSION_CUSTOMIZE_PRODUCT_EVENT_ENABLED'] = FacebookConversion::isEventEnabled(
304 'CustomizeProduct'
305 );
306 }
307
308 }
309 else
310 {
311 $this->abortResultCache();
312 $this->errorCollection->setError(new Error(Loc::getMessage('CATALOG_ELEMENT_NOT_FOUND'), self::ERROR_404));
313 }
314 }
315
321 protected function checkElementId()
322 {
323 if ($this->arParams['ELEMENT_ID'] <= 0)
324 {
325 $findFilter = array(
326 'IBLOCK_ID' => $this->arParams['IBLOCK_ID'],
327 'IBLOCK_LID' => $this->getSiteId(),
328 'ACTIVE_DATE' => 'Y',
329 'CHECK_PERMISSIONS' => 'Y',
330 'MIN_PERMISSION' => 'R',
331 );
332
333 if ($this->arParams['SHOW_DEACTIVATED'] !== 'Y')
334 {
335 $findFilter['ACTIVE'] = 'Y';
336 }
337
338 $this->arParams['ELEMENT_ID'] = \CIBlockFindTools::GetElementID(
339 $this->arParams['ELEMENT_ID'],
340 $this->arParams['~ELEMENT_CODE'],
341 $this->arParams['STRICT_SECTION_CHECK']? $this->arParams['SECTION_ID']: 0,
342 $this->arParams['STRICT_SECTION_CHECK']? $this->arParams['~SECTION_CODE']: '',
343 $findFilter
344 );
345 }
346
347 return $this->arParams['ELEMENT_ID'] > 0;
348 }
349
350 protected function initCatalogInfo()
351 {
352 parent::initCatalogInfo();
353 $useCatalogButtons = array();
354
355 if (
356 !empty($this->storage['CATALOGS'][$this->arParams['IBLOCK_ID']])
357 && is_array($this->storage['CATALOGS'][$this->arParams['IBLOCK_ID']])
358 )
359 {
360 $catalogType = $this->storage['CATALOGS'][$this->arParams['IBLOCK_ID']]['CATALOG_TYPE'];
361 if ($catalogType == \CCatalogSku::TYPE_CATALOG || $catalogType == \CCatalogSku::TYPE_FULL)
362 {
363 $useCatalogButtons['add_product'] = true;
364 }
365
366 if ($catalogType == \CCatalogSku::TYPE_PRODUCT || $catalogType == \CCatalogSku::TYPE_FULL)
367 {
368 $useCatalogButtons['add_sku'] = true;
369 }
370 unset($catalogType);
371 }
372
373 $this->arResult['USE_CATALOG_BUTTONS'] = $useCatalogButtons;
374 }
375
379 protected function initIblockPropertyFeatures()
380 {
381 if (!Iblock\Model\PropertyFeature::isEnabledFeatures())
382 return;
383
384 $this->loadDisplayPropertyCodes($this->arParams['IBLOCK_ID']);
385 $this->loadBasketPropertyCodes($this->arParams['IBLOCK_ID']);
386 $this->loadOfferTreePropertyCodes($this->arParams['IBLOCK_ID']);
387 }
388
389 protected function checkProductIblock(array $product): bool
390 {
391 return ($product['PRODUCT_IBLOCK_ID'] == $this->arParams['IBLOCK_ID']);
392 }
393
398 protected function loadDisplayPropertyCodes($iblockId)
399 {
400 $list = Iblock\Model\PropertyFeature::getDetailPageShowProperties(
401 $iblockId,
402 ['CODE' => 'Y']
403 );
404 if ($list === null)
405 $list = [];
406 $this->storage['IBLOCK_PARAMS'][$iblockId]['PROPERTY_CODE'] = $list;
407 if ($this->useCatalog)
408 {
409 $list = Iblock\Model\PropertyFeature::getDetailPageShowProperties(
410 $this->getOffersIblockId($iblockId),
411 ['CODE' => 'Y']
412 );
413 if ($list === null)
414 $list = [];
415 $this->storage['IBLOCK_PARAMS'][$iblockId]['OFFERS_PROPERTY_CODE'] = $list;
416 }
417 unset($list);
418 }
419
420 protected function getSelect()
421 {
422 $selectFields = parent::getSelect();
423 $selectFields[] = 'LIST_PAGE_URL';
424 $selectFields[] = 'PROPERTY_*';
425
426 if ($this->arParams['SET_CANONICAL_URL'] === 'Y')
427 {
428 $selectFields[] = 'CANONICAL_PAGE_URL';
429 }
430
431 return $selectFields;
432 }
433
434 protected function getFilter()
435 {
436 $filterFields = parent::getFilter();
437 $filterFields['SHOW_HISTORY'] = $this->showWorkflowHistory();
438
439 if ($this->arParams['SHOW_DEACTIVATED'] !== 'Y')
440 {
441 $filterFields['ACTIVE'] = 'Y';
442 }
443
444 return $filterFields;
445 }
446
447 protected function showWorkflowHistory()
448 {
449 $wfShowHistory = 'N';
450
451 if ($this->arParams['SHOW_WORKFLOW'] && Loader::includeModule('workflow'))
452 {
453 $this->storage['modules']['workflow'] = true;
454
455 $wfElementId = \CIBlockElement::WF_GetLast($this->arParams['ELEMENT_ID']);
456 $wfStatusId = \CIBlockElement::WF_GetCurrentStatus($wfElementId, $wfStatusTitle);
457 $wfStatusPermission = \CIBlockElement::WF_GetStatusPermission($wfStatusId);
458
459 if ($wfStatusId == 1 || $wfStatusPermission < 1)
460 {
461 $wfElementId = $this->arParams['ELEMENT_ID'];
462 }
463 else
464 {
465 $wfShowHistory = 'Y';
466 }
467
468 $this->arParams['ELEMENT_ID'] = $wfElementId;
469 }
470
471 return $wfShowHistory;
472 }
473
474 protected function getElementList($iblockId, $products)
475 {
476 $section = $this->getSection();
477
478 if ($this->arParams['STRICT_SECTION_CHECK'])
479 {
480 $sectionId = !empty($section) ? $section['ID'] : 0;
481
482 if ($this->arParams['USE_MAIN_ELEMENT_SECTION'])
483 {
484 $this->filterFields['IBLOCK_SECTION_ID'] = $sectionId;
485 }
486 else
487 {
488 $this->filterFields['SECTION_ID'] = $sectionId;
489 $this->filterFields['INCLUDE_SUBSECTIONS'] = 'N';
490 }
491 }
492
493 $elementIterator = parent::getElementList($iblockId, $products);
494
495 if (!empty($elementIterator) && !$this->arParams['USE_MAIN_ELEMENT_SECTION'])
496 {
497 $elementIterator->SetSectionContext($section);
498 }
499
500 $this->storage['SECTION'] = $section;
501
502 return $elementIterator;
503 }
504
505 protected function getSection()
506 {
507 $section = false;
508 $sectionFilter = array(
509 'IBLOCK_ID' => $this->arParams['IBLOCK_ID'],
510 'ACTIVE' => 'Y',
511 );
512
513 if ($this->arParams['SECTION_ID'] > 0 || $this->arParams['SECTION_CODE'] !== '')
514 {
515 if ($this->arParams['SECTION_ID'] > 0)
516 {
517 $sectionFilter['ID'] = $this->arParams['SECTION_ID'];
518 }
519 else
520 {
521 $sectionFilter['HAS_ELEMENT'] = $this->arParams['ELEMENT_ID'];
522 $sectionFilter['=CODE'] = $this->arParams['SECTION_CODE'];
523 }
524
525 $sectionIterator = \CIBlockSection::GetList(array(), $sectionFilter);
526 $sectionIterator->SetUrlTemplates('', $this->arParams['SECTION_URL']);
527 $section = $sectionIterator->GetNext();
528 }
529 elseif ($this->arParams['CHECK_SECTION_ID_VARIABLE'] === 'Y' && $this->arParams['FROM_SECTION'] !== '')
530 {
531 if ((int)$this->arParams['FROM_SECTION'].'|' == $this->arParams['FROM_SECTION'].'|')
532 {
533 $sectionFilter['ID'] = $this->arParams['FROM_SECTION'];
534 }
535 else
536 {
537 $sectionFilter['HAS_ELEMENT'] = $this->arParams['ELEMENT_ID'];
538 $sectionFilter['=CODE'] = $this->arParams['FROM_SECTION'];
539 }
540
541 $sectionIterator = \CIBlockSection::GetList(array(), $sectionFilter);
542 $sectionIterator->SetUrlTemplates('', $this->arParams['SECTION_URL']);
543 $section = $sectionIterator->GetNext();
544 }
545
546 return $section;
547 }
548
549 protected function getIblockElements($elementIterator)
550 {
551 $iblockElements = array();
552
554 if (!empty($elementIterator) && ($elementObject = $elementIterator->GetNextElement()))
555 {
556 $element = $elementObject->GetFields();
557 $this->processElement($element);
558 $iblockElements[$element['ID']] = $element;
559 }
560 else
561 {
562 $this->abortResultCache();
563 $this->errorCollection->setError(new Error(Loc::getMessage('CATALOG_ELEMENT_NOT_FOUND'), self::ERROR_404));
564 }
565
566 return $iblockElements;
567 }
568
569 protected function modifyDisplayProperties($iblock, &$iblockElements)
570 {
571 if (!empty($iblockElements))
572 {
573 reset($iblockElements);
574 $elementKey = key($iblockElements);
575 $element =& $iblockElements[$elementKey];
576
577 $iblockParams = $this->storage['IBLOCK_PARAMS'][$iblock];
578 $propFilter = array(
579 'ID' => array_keys($iblockElements),
580 'IBLOCK_ID' => $iblock
581 );
582 \CIBlockElement::GetPropertyValuesArray($iblockElements, $iblock, $propFilter);
583
584 if (!empty($iblockParams['PROPERTY_CODE']))
585 {
586 $propertyList = $this->getPropertyList($iblock, $iblockParams['PROPERTY_CODE']);
587 }
588
589 if ($this->useCatalog && $this->useDiscountCache)
590 {
591 if ($this->storage['USE_SALE_DISCOUNTS'])
592 Catalog\Discount\DiscountManager::setProductPropertiesCache($element['ID'], $element["PROPERTIES"]);
593 else
594 \CCatalogDiscount::SetProductPropertiesCache($element['ID'], $element['PROPERTIES']);
595 }
596
597 if (!empty($propertyList))
598 {
599 foreach ($propertyList as $pid)
600 {
601 if (!isset($element['PROPERTIES'][$pid]))
602 continue;
603
604 $prop =& $element['PROPERTIES'][$pid];
605 $isArr = is_array($prop['VALUE']);
606 if (
607 ($isArr && !empty($prop['VALUE']))
608 || (!$isArr && (string)$prop['VALUE'] !== '')
610 )
611 {
612 $element['DISPLAY_PROPERTIES'][$pid] = \CIBlockFormatProperties::GetDisplayValue($element, $prop);
613 }
614 unset($prop);
615 }
616 unset($pid);
617
618 \CIBlockFormatProperties::clearCache();
620 }
621
622 if ($this->arParams['ADD_PROPERTIES_TO_BASKET'] === 'Y' && !empty($iblockParams['CART_PROPERTIES']))
623 {
624 $element['PRODUCT_PROPERTIES'] = \CIBlockPriceTools::GetProductProperties(
625 $iblock,
626 $element['ID'],
627 $iblockParams['CART_PROPERTIES'],
628 $element['PROPERTIES']
629 );
630
631 if (!empty($element['PRODUCT_PROPERTIES']))
632 {
633 $element['PRODUCT_PROPERTIES_FILL'] = \CIBlockPriceTools::getFillProductProperties($element['PRODUCT_PROPERTIES']);
634 }
635 }
636
637 $element['BACKGROUND_IMAGE'] = false;
638
639 if ($this->arParams['BACKGROUND_IMAGE'] != '' && isset($element['PROPERTIES'][$this->arParams['BACKGROUND_IMAGE']]))
640 {
641 if (!empty($element['PROPERTIES'][$this->arParams['BACKGROUND_IMAGE']]['VALUE']))
642 {
643 $element['BACKGROUND_IMAGE'] = \CFile::GetFileArray($element['PROPERTIES'][$this->arParams['BACKGROUND_IMAGE']]['VALUE']);
644 }
645 }
646
647 $element['MORE_PHOTO'] = array();
648
649 if (!empty($element['PROPERTIES']['MORE_PHOTO']['VALUE']) && is_array($element['PROPERTIES']['MORE_PHOTO']['VALUE']))
650 {
651 foreach ($element['PROPERTIES']['MORE_PHOTO']['VALUE'] as $file)
652 {
653 $file = \CFile::GetFileArray($file);
654 if (is_array($file))
655 {
656 $element['MORE_PHOTO'][] = $file;
657 }
658 }
659 }
660
661 $element['LINKED_ELEMENTS'] = array();
662
663 if (
664 $this->arParams['LINK_PROPERTY_SID'] <> ''
665 && $this->arParams['LINK_IBLOCK_TYPE'] <> ''
666 && $this->arParams['LINK_IBLOCK_ID'] > 0
667 )
668 {
669 $linkElementIterator = \CIBlockElement::GetList(
670 array('SORT' => 'ASC'),
671 array(
672 'IBLOCK_ID' => $this->arParams['LINK_IBLOCK_ID'],
673 'IBLOCK_ACTIVE' => 'Y',
674 'ACTIVE_DATE' => 'Y',
675 'ACTIVE' => 'Y',
676 'CHECK_PERMISSIONS' => 'Y',
677 'IBLOCK_TYPE' => $this->arParams['LINK_IBLOCK_TYPE'],
678 'PROPERTY_'.$this->arParams['LINK_PROPERTY_SID'] => $element['ID'],
679 ),
680 false,
681 false,
682 array('ID', 'IBLOCK_ID', 'NAME', 'DETAIL_PAGE_URL', 'IBLOCK_NAME')
683 );
684 while ($linkElement = $linkElementIterator->GetNext())
685 {
686 $element['LINKED_ELEMENTS'][] = $linkElement;
687 }
688 }
689
690 if (!$this->storage['SECTION'] && $element['IBLOCK_SECTION_ID'] > 0)
691 {
692 $sectionFilter = array(
693 'ID' => $element['IBLOCK_SECTION_ID'],
694 'IBLOCK_ID' => $element['IBLOCK_ID'],
695 'ACTIVE' => 'Y',
696 );
697 $rsSection = \CIBlockSection::GetList(array(), $sectionFilter);
698 $rsSection->SetUrlTemplates('', $this->arParams['SECTION_URL']);
699 $this->storage['SECTION'] = $rsSection->GetNext();
700 }
701
702 if (!empty($this->storage['SECTION']))
703 {
704 $blackList = array(
705 'SEARCHABLE_CONTENT', '~SEARCHABLE_CONTENT',
706 'TIMESTAMP_X', '~TIMESTAMP_X',
707 'DATE_CREATE', '~DATE_CREATE',
708 );
709 foreach ($blackList as $fieldName)
710 {
711 if (array_key_exists($fieldName, $this->storage['SECTION']))
712 {
713 unset($this->storage['SECTION'][$fieldName]);
714 }
715 }
716 unset($fieldName, $blackList);
717
718 $this->storage['SECTION']['PATH'] = array();
719 $rsPath = \CIBlockSection::GetNavChain(
720 $element['IBLOCK_ID'],
721 $this->storage['SECTION']['ID'],
722 array(
723 'ID', 'CODE', 'XML_ID', 'EXTERNAL_ID', 'IBLOCK_ID',
724 'IBLOCK_SECTION_ID', 'SORT', 'NAME', 'ACTIVE',
725 'DEPTH_LEVEL', 'SECTION_PAGE_URL'
726 )
727 );
728 $rsPath->SetUrlTemplates('', $this->arParams['SECTION_URL']);
729 while ($path = $rsPath->GetNext())
730 {
731 if ($this->arParams["ADD_SECTIONS_CHAIN"])
732 {
733 $ipropValues = new Iblock\InheritedProperty\SectionValues($element['IBLOCK_ID'], $path['ID']);
734 $path['IPROPERTY_VALUES'] = $ipropValues->getValues();
735 }
736
737 $this->storage['SECTION']['PATH'][] = $path;
738 }
739
740 if ($this->arParams['SECTIONS_CHAIN_START_FROM'] > 0)
741 {
742 $this->storage['SECTION']['PATH'] = array_slice($this->storage['SECTION']['PATH'], $this->arParams['SECTIONS_CHAIN_START_FROM']);
743 }
744
745 $element['SECTION'] = $this->storage['SECTION'];
746 }
747
748 unset($element);
749 }
750 }
751
752 protected function chooseOffer($offers, $iblockId)
753 {
754 $uniqueSortHash = array();
755
756 foreach ($offers as $offer)
757 {
758 $elementId = $offer['LINK_ELEMENT_ID'];
759
760 if (!isset($this->elementLinks[$elementId]))
761 continue;
762
763 if (!isset($uniqueSortHash[$elementId]))
764 {
765 $uniqueSortHash[$elementId] = array();
766 }
767
768 $uniqueSortHash[$elementId][$offer['SORT_HASH']] = true;
769
770 if ($this->elementLinks[$elementId]['OFFER_ID_SELECTED'] == 0 && $offer['CAN_BUY'])
771 {
772 $this->elementLinks[$elementId]['OFFER_ID_SELECTED'] = $offer['ID'];
773 }
774 }
775 unset($elementId, $offer);
776
777 foreach ($this->elementLinks as &$element)
778 {
779 if ($element['OFFER_ID_SELECTED'] == 0)
780 continue;
781
782 if (count($uniqueSortHash[$element['ID']]) < 2)
783 {
784 $element['OFFER_ID_SELECTED'] = 0;
785 }
786 }
787 }
788
789 protected function getCacheKeys()
790 {
791 $resultCacheKeys = array(
792 'IBLOCK_ID',
793 'ID',
794 'IBLOCK_SECTION_ID',
795 'NAME',
796 'LIST_PAGE_URL',
797 'CANONICAL_PAGE_URL',
798 'SECTION',
799 'IPROPERTY_VALUES',
800 'TIMESTAMP_X',
801 'BACKGROUND_IMAGE',
802 'USE_CATALOG_BUTTONS'
803 );
804
805 $this->initAdditionalCacheKeys($resultCacheKeys);
806
807 if (
808 $this->arParams['SET_TITLE']
809 || $this->arParams['ADD_ELEMENT_CHAIN']
810 || $this->arParams['SET_BROWSER_TITLE'] === 'Y'
811 || $this->arParams['SET_META_KEYWORDS'] === 'Y'
812 || $this->arParams['SET_META_DESCRIPTION'] === 'Y'
813 )
814 {
815 $this->arResult['META_TAGS'] = array();
816 $resultCacheKeys[] = 'META_TAGS';
817
818 $elementTitle = $this->arResult['NAME'];
819 if (
820 isset($this->arResult['IPROPERTY_VALUES']['ELEMENT_PAGE_TITLE'])
821 && $this->arResult['IPROPERTY_VALUES']['ELEMENT_PAGE_TITLE'] !== ''
822 )
823 {
824 $elementTitle = $this->arResult['IPROPERTY_VALUES']['ELEMENT_PAGE_TITLE'];
825 }
826 if ($this->arParams['SET_TITLE'])
827 {
828 $this->arResult['META_TAGS']['TITLE'] = $elementTitle;
829 }
830
831 if ($this->arParams['ADD_ELEMENT_CHAIN'])
832 {
833 $this->arResult['META_TAGS']['ELEMENT_CHAIN'] = $elementTitle;
834 }
835
836 if ($this->arParams['SET_BROWSER_TITLE'] === 'Y')
837 {
838 $browserTitle = Collection::firstNotEmpty(
839 $this->arResult['PROPERTIES'], array($this->arParams['BROWSER_TITLE'], 'VALUE'),
840 $this->arResult, $this->arParams['BROWSER_TITLE'],
841 $this->arResult['IPROPERTY_VALUES'], 'ELEMENT_META_TITLE'
842 );
843 $this->arResult['META_TAGS']['BROWSER_TITLE'] = is_array($browserTitle)
844 ? implode(' ', $browserTitle)
845 : $browserTitle;
846 unset($browserTitle);
847 }
848
849 if ($this->arParams['SET_META_KEYWORDS'] === 'Y')
850 {
851 $metaKeywords = Collection::firstNotEmpty(
852 $this->arResult['PROPERTIES'], array($this->arParams['META_KEYWORDS'], 'VALUE'),
853 $this->arResult['IPROPERTY_VALUES'], 'ELEMENT_META_KEYWORDS'
854 );
855 $this->arResult['META_TAGS']['KEYWORDS'] = is_array($metaKeywords)
856 ? implode(' ', $metaKeywords)
857 : $metaKeywords;
858 unset($metaKeywords);
859 }
860
861 if ($this->arParams['SET_META_DESCRIPTION'] === 'Y')
862 {
863 $metaDescription = Collection::firstNotEmpty(
864 $this->arResult['PROPERTIES'], array($this->arParams['META_DESCRIPTION'], 'VALUE'),
865 $this->arResult['IPROPERTY_VALUES'], 'ELEMENT_META_DESCRIPTION'
866 );
867 $this->arResult['META_TAGS']['DESCRIPTION'] = is_array($metaDescription)
868 ? implode(' ', $metaDescription)
869 : $metaDescription;
870 unset($metaDescription);
871 }
872 }
873
874 return $resultCacheKeys;
875 }
876
883 protected function initAdditionalCacheKeys(&$resultCacheKeys)
884 {
885 }
886
887 protected function initAdminIconsPanel()
888 {
889 global $APPLICATION, $USER;
890
891 if (!$USER->IsAuthorized())
892 return;
893
894 $arResult =& $this->arResult;
895
896 if (
897 $APPLICATION->GetShowIncludeAreas()
898 || $this->arParams['SET_TITLE']
899 || isset($arResult[$this->arParams['BROWSER_TITLE']])
900 )
901 {
902 if (Loader::includeModule('iblock'))
903 {
904 $returnUrl = array(
905 'add_element' => \CIBlock::GetArrayByID($this->arParams['IBLOCK_ID'], 'DETAIL_PAGE_URL'),
906 'delete_element' =>
907 isset($arResult['SECTION'])
908 ? $arResult['SECTION']['SECTION_PAGE_URL']
909 : $arResult['LIST_PAGE_URL'],
910 );
911 $buttonParams = array(
912 'RETURN_URL' => $returnUrl,
913 'CATALOG' => true
914 );
915
916 if (isset($arResult['USE_CATALOG_BUTTONS']))
917 {
918 $buttonParams['USE_CATALOG_BUTTONS'] = $arResult['USE_CATALOG_BUTTONS'];
919 if (!empty($buttonParams['USE_CATALOG_BUTTONS']))
920 {
921 $buttonParams['SHOW_CATALOG_BUTTONS'] = true;
922 }
923 }
924
925 $buttons = \CIBlock::GetPanelButtons(
926 $arResult['IBLOCK_ID'],
927 $arResult['ID'],
928 $arResult['IBLOCK_SECTION_ID'],
929 $buttonParams
930 );
931 unset($buttonParams);
932
933 if ($APPLICATION->GetShowIncludeAreas())
934 {
935 $this->addIncludeAreaIcons(\CIBlock::GetComponentMenu($APPLICATION->GetPublicShowMode(), $buttons));
936 }
937
938 if ($this->arParams['SET_TITLE'] || isset($arResult[$this->arParams['BROWSER_TITLE']]))
939 {
940 $this->storage['TITLE_OPTIONS'] = null;
941 if (isset($buttons['submenu']['edit_element']))
942 {
943 $this->storage['TITLE_OPTIONS'] = [
944 'ADMIN_EDIT_LINK' => $buttons['submenu']['edit_element']['ACTION'],
945 'PUBLIC_EDIT_LINK' => $buttons['edit']['edit_element']['ACTION'],
946 'COMPONENT_NAME' => $this->getName(),
947 ];
948 }
949 }
950 }
951 }
952 }
953
954 protected function sendCounters()
955 {
956 if ($this->arParams['USE_ELEMENT_COUNTER'] !== 'N' && Loader::includeModule('iblock'))
957 {
958 \CIBlockElement::CounterInc($this->arResult['ID']);
959 }
960 }
961
962 protected function saveViewedProduct()
963 {
964 }
965
966 protected function initMetaData()
967 {
968 global $APPLICATION;
969 $arResult =& $this->arResult;
970
971 if ($this->arParams['SET_CANONICAL_URL'] === 'Y' && $arResult["CANONICAL_PAGE_URL"])
972 $APPLICATION->SetPageProperty('canonical', $arResult["CANONICAL_PAGE_URL"]);
973
974 if ($this->arParams['SET_TITLE'])
975 {
976 $APPLICATION->SetTitle($arResult["META_TAGS"]["TITLE"], $this->storage['TITLE_OPTIONS']);
977 }
978
979 if ($this->arParams['SET_BROWSER_TITLE'] === 'Y')
980 {
981 if ($arResult["META_TAGS"]["BROWSER_TITLE"] !== '')
982 {
983 $APPLICATION->SetPageProperty("title", $arResult["META_TAGS"]["BROWSER_TITLE"], $this->storage['TITLE_OPTIONS']);
984 }
985 }
986
987 if ($this->arParams['SET_META_KEYWORDS'] === 'Y')
988 {
989 if ($arResult["META_TAGS"]["KEYWORDS"] !== '')
990 {
991 $APPLICATION->SetPageProperty("keywords", $arResult["META_TAGS"]["KEYWORDS"], $this->storage['TITLE_OPTIONS']);
992 }
993 }
994
995 if ($this->arParams['SET_META_DESCRIPTION'] === 'Y')
996 {
997 if ($arResult["META_TAGS"]["DESCRIPTION"] !== '')
998 {
999 $APPLICATION->SetPageProperty("description", $arResult["META_TAGS"]["DESCRIPTION"], $this->storage['TITLE_OPTIONS']);
1000 }
1001 }
1002
1003 if (!empty($arResult['BACKGROUND_IMAGE']) && is_array($arResult['BACKGROUND_IMAGE']))
1004 {
1005 $APPLICATION->SetPageProperty(
1006 'backgroundImage',
1007 'style="background-image: url(\''.\CHTTP::urnEncode($arResult['BACKGROUND_IMAGE']['SRC'], 'UTF-8').'\')"'
1008 );
1009 }
1010
1011 if ($this->arParams['ADD_SECTIONS_CHAIN'] && !empty($arResult['SECTION']['PATH']) && is_array($arResult['SECTION']['PATH']))
1012 {
1013 foreach ($arResult['SECTION']['PATH'] as $path)
1014 {
1015 if (isset($path['IPROPERTY_VALUES']['SECTION_PAGE_TITLE']) && $path['IPROPERTY_VALUES']['SECTION_PAGE_TITLE'] !== '')
1016 {
1017 $APPLICATION->AddChainItem($path['IPROPERTY_VALUES']['SECTION_PAGE_TITLE'], $path['~SECTION_PAGE_URL']);
1018 }
1019 else
1020 {
1021 $APPLICATION->AddChainItem($path['NAME'], $path['~SECTION_PAGE_URL']);
1022 }
1023 }
1024 }
1025
1026 if ($this->arParams['ADD_ELEMENT_CHAIN'])
1027 {
1028 $APPLICATION->AddChainItem($arResult["META_TAGS"]["ELEMENT_CHAIN"]);
1029 }
1030
1031 if ($this->arParams['SET_LAST_MODIFIED'] && $arResult['TIMESTAMP_X'])
1032 {
1033 Main\Context::getCurrent()->getResponse()->setLastModified(DateTime::createFromUserTime($arResult["TIMESTAMP_X"]));
1034 }
1035 }
1036
1037 protected function getAdditionalCacheId()
1038 {
1039 return array(
1040 $this->productIdMap,
1041 $this->arParams['CACHE_GROUPS'] === 'N' ? false : $this->getUserGroupsCacheId()
1042 );
1043 }
1044
1045 protected function getComponentCachePath()
1046 {
1047 return false;
1048 }
1049
1050 protected function makeOutputResult()
1051 {
1052 parent::makeOutputResult();
1053 $this->arResult['CAT_PRICES'] = $this->storage['PRICES'];
1054 $this->arResult = array_merge($this->arResult, $this->elements[0]);
1055 }
1056
1057 protected function prepareTemplateParams()
1058 {
1059 parent::prepareTemplateParams();
1060 $params =& $this->arParams;
1061
1062 $params['DISPLAY_NAME'] = $params['DISPLAY_NAME'] === 'N' ? 'N' : 'Y';
1063 $params['USE_RATIO_IN_RANGES'] = $params['USE_RATIO_IN_RANGES'] === 'N' ? 'N' : 'Y';
1064
1065 if (!isset($params['IMAGE_RESOLUTION']))
1066 {
1067 $params['IMAGE_RESOLUTION'] = '16by9';
1068 }
1069
1070 if (!is_array($params['DETAIL_PICTURE_MODE']))
1071 {
1072 $params['DETAIL_PICTURE_MODE'] = array($params['DETAIL_PICTURE_MODE']);
1073 }
1074
1075 $params['ADD_DETAIL_TO_SLIDER'] = $params['ADD_DETAIL_TO_SLIDER'] === 'Y' ? 'Y' : 'N';
1076 $displayPreviewTextMode = array('H' => true, 'E' => true, 'S' => true);
1077 if (!isset($displayPreviewTextMode[$params['DISPLAY_PREVIEW_TEXT_MODE']]))
1078 {
1079 $params['DISPLAY_PREVIEW_TEXT_MODE'] = 'E';
1080 }
1081
1082 if (!is_array($params['ADD_TO_BASKET_ACTION']))
1083 {
1084 $params['ADD_TO_BASKET_ACTION'] = array($params['ADD_TO_BASKET_ACTION']);
1085 }
1086
1087 $params['ADD_TO_BASKET_ACTION'] = array_filter($params['ADD_TO_BASKET_ACTION'], 'CIBlockParameters::checkParamValues');
1088 if (empty($params['ADD_TO_BASKET_ACTION']) || (!in_array('ADD', $params['ADD_TO_BASKET_ACTION']) && !in_array('BUY', $params['ADD_TO_BASKET_ACTION'])))
1089 {
1090 $params['ADD_TO_BASKET_ACTION'] = array('BUY');
1091 }
1092
1093 if (!isset($params['ADD_TO_BASKET_ACTION_PRIMARY']) || !is_array($params['ADD_TO_BASKET_ACTION_PRIMARY']))
1094 {
1095 $params['ADD_TO_BASKET_ACTION_PRIMARY'] = array('BUY', 'ADD');
1096 }
1097
1098 $params['USE_VOTE_RATING'] = $params['USE_VOTE_RATING'] === 'Y' ? 'Y' : 'N';
1099
1100 if ($params['VOTE_DISPLAY_AS_RATING'] != 'vote_avg')
1101 {
1102 $params['VOTE_DISPLAY_AS_RATING'] = 'rating';
1103 }
1104
1105 $params['USE_COMMENTS'] = $params['USE_COMMENTS'] === 'Y' ? 'Y' : 'N';
1106 $params['BLOG_USE'] = $params['BLOG_USE'] === 'Y' ? 'Y' : 'N';
1107 $params['VK_USE'] = $params['VK_USE'] === 'Y' && !empty($params['VK_API_ID']) ? 'Y' : 'N';
1108 $params['FB_USE'] = $params['FB_USE'] === 'Y' && !empty($params['FB_APP_ID']) ? 'Y' : 'N';
1109
1110 if ($params['USE_COMMENTS'] === 'Y')
1111 {
1112 if ($params['BLOG_USE'] === 'N' && $params['VK_USE'] === 'N' && $params['FB_USE'] === 'N')
1113 {
1114 $params['USE_COMMENTS'] = 'N';
1115 }
1116 }
1117
1118 $params['BRAND_USE'] = $params['BRAND_USE'] === 'Y' ? 'Y' : 'N';
1119
1120 if ($params['BRAND_PROP_CODE'] == '')
1121 {
1122 $params['BRAND_PROP_CODE'] = array();
1123 }
1124
1125 if (!is_array($params['BRAND_PROP_CODE']))
1126 {
1127 $params['BRAND_PROP_CODE'] = array($params['BRAND_PROP_CODE']);
1128 }
1129
1130 if (empty($params['PRODUCT_INFO_BLOCK_ORDER']))
1131 {
1132 $params['PRODUCT_INFO_BLOCK_ORDER'] = 'sku,props,priceRanges';
1133 }
1134
1135 if (is_string($params['PRODUCT_INFO_BLOCK_ORDER']))
1136 {
1137 $params['PRODUCT_INFO_BLOCK_ORDER'] = explode(',', $params['PRODUCT_INFO_BLOCK_ORDER']);
1138 }
1139
1140 if (empty($params['PRODUCT_PAY_BLOCK_ORDER']))
1141 {
1142 $params['PRODUCT_PAY_BLOCK_ORDER'] = 'rating,price,quantityLimit,quantity,buttons';
1143 }
1144
1145 if (is_string($params['PRODUCT_PAY_BLOCK_ORDER']))
1146 {
1147 $params['PRODUCT_PAY_BLOCK_ORDER'] = explode(',', $params['PRODUCT_PAY_BLOCK_ORDER']);
1148 }
1149
1150 $this->getTemplateIblockParams($params);
1151 }
1152
1153 protected function getTemplateIblockParams(&$params)
1154 {
1155 $params['ADD_PICT_PROP'] = isset($params['ADD_PICT_PROP']) ? trim($params['ADD_PICT_PROP']) : '';
1156 if ($params['ADD_PICT_PROP'] === '-')
1157 {
1158 $params['ADD_PICT_PROP'] = '';
1159 }
1160
1161 if (!isset($params['LABEL_PROP']) || !is_array($params['LABEL_PROP']))
1162 {
1163 $params['LABEL_PROP'] = array();
1164 }
1165
1166 if (!isset($params['LABEL_PROP_MOBILE']) || !is_array($params['LABEL_PROP_MOBILE']))
1167 {
1168 $params['LABEL_PROP_MOBILE'] = array();
1169 }
1170
1171 if (!empty($params['LABEL_PROP_MOBILE']))
1172 {
1173 $params['LABEL_PROP_MOBILE'] = array_flip($params['LABEL_PROP_MOBILE']);
1174 }
1175 $params['ENLARGE_PROP'] = isset($params['ENLARGE_PROP']) ? trim($params['ENLARGE_PROP']) : '';
1176 if ($params['ENLARGE_PROP'] === '-')
1177 {
1178 $params['ENLARGE_PROP'] = '';
1179 }
1180
1181 $params['OFFER_ADD_PICT_PROP'] = isset($params['OFFER_ADD_PICT_PROP']) ? trim($params['OFFER_ADD_PICT_PROP']) : '';
1182 if ($params['OFFER_ADD_PICT_PROP'] === '-')
1183 {
1184 $params['OFFER_ADD_PICT_PROP'] = '';
1185 }
1186
1187 if (!isset($params['MAIN_BLOCK_PROPERTY_CODE']) || !is_array($params['MAIN_BLOCK_PROPERTY_CODE']))
1188 {
1189 $params['MAIN_BLOCK_PROPERTY_CODE'] = array();
1190 }
1191
1192 if (!empty($params['MAIN_BLOCK_PROPERTY_CODE']))
1193 {
1194 $params['MAIN_BLOCK_PROPERTY_CODE'] = array_flip($params['MAIN_BLOCK_PROPERTY_CODE']);
1195 }
1196
1197 if (!isset($params['MAIN_BLOCK_OFFERS_PROPERTY_CODE']) || !is_array($params['MAIN_BLOCK_OFFERS_PROPERTY_CODE']))
1198 {
1199 $params['MAIN_BLOCK_OFFERS_PROPERTY_CODE'] = array();
1200 }
1201
1202 if (!empty($params['MAIN_BLOCK_OFFERS_PROPERTY_CODE']))
1203 {
1204 $params['MAIN_BLOCK_OFFERS_PROPERTY_CODE'] = array_flip($params['MAIN_BLOCK_OFFERS_PROPERTY_CODE']);
1205 }
1206
1207 if (!isset($this->storage['IBLOCK_PARAMS'][$params['IBLOCK_ID']]) || !is_array($this->storage['IBLOCK_PARAMS'][$params['IBLOCK_ID']]))
1208 {
1209 $this->storage['IBLOCK_PARAMS'][$params['IBLOCK_ID']] = array();
1210 }
1211
1212 $this->storage['IBLOCK_PARAMS'][$params['IBLOCK_ID']]['ADD_PICT_PROP'] = $params['ADD_PICT_PROP'];
1213 $this->storage['IBLOCK_PARAMS'][$params['IBLOCK_ID']]['LABEL_PROP'] = $params['LABEL_PROP'];
1214 $this->storage['IBLOCK_PARAMS'][$params['IBLOCK_ID']]['LABEL_PROP_MOBILE'] = $params['LABEL_PROP_MOBILE'];
1215 $this->storage['IBLOCK_PARAMS'][$params['IBLOCK_ID']]['ENLARGE_PROP'] = $params['ENLARGE_PROP'];
1216 $this->storage['IBLOCK_PARAMS'][$params['IBLOCK_ID']]['OFFERS_ADD_PICT_PROP'] = $params['OFFER_ADD_PICT_PROP'];
1217 $this->storage['IBLOCK_PARAMS'][$params['IBLOCK_ID']]['MAIN_BLOCK_PROPERTY_CODE'] = $params['MAIN_BLOCK_PROPERTY_CODE'];
1218 $this->storage['IBLOCK_PARAMS'][$params['IBLOCK_ID']]['MAIN_BLOCK_OFFERS_PROPERTY_CODE'] = $params['MAIN_BLOCK_OFFERS_PROPERTY_CODE'];
1219
1220 unset($skuTreeProperties);
1221 }
1222
1223 protected function getTemplateDefaultParams()
1224 {
1225 $defaultParams = parent::getTemplateDefaultParams();
1226 $defaultParams['DISPLAY_NAME'] = 'Y';
1227 $defaultParams['USE_RATIO_IN_RANGES'] = 'Y';
1228 $defaultParams['IMAGE_RESOLUTION'] = '16by9';
1229 $defaultParams['DETAIL_PICTURE_MODE'] = array('POPUP', 'MAGNIFIER');
1230 $defaultParams['ADD_DETAIL_TO_SLIDER'] = 'N';
1231 $defaultParams['DISPLAY_PREVIEW_TEXT_MODE'] = 'E';
1232 $defaultParams['ADD_TO_BASKET_ACTION'] = array('BUY');
1233 $defaultParams['ADD_TO_BASKET_ACTION_PRIMARY'] = array('BUY', 'ADD');
1234 $defaultParams['USE_VOTE_RATING'] = 'N';
1235 $defaultParams['VOTE_DISPLAY_AS_RATING'] = 'rating';
1236 $defaultParams['USE_COMMENTS'] = 'N';
1237 $defaultParams['BLOG_USE'] = 'N';
1238 $defaultParams['BLOG_URL'] = 'catalog_comments';
1239 $defaultParams['BLOG_EMAIL_NOTIFY'] = 'N';
1240 $defaultParams['VK_USE'] = 'N';
1241 $defaultParams['VK_API_ID'] = '';
1242 $defaultParams['FB_USE'] = 'N';
1243 $defaultParams['FB_APP_ID'] = '';
1244 $defaultParams['BRAND_USE'] = 'N';
1245 $defaultParams['BRAND_PROP_CODE'] = '';
1246
1247 return $defaultParams;
1248 }
1249
1250 protected function editTemplateData()
1251 {
1252 $this->arResult['DEFAULT_PICTURE'] = $this->getTemplateEmptyPreview();
1253 $this->arResult['SKU_PROPS'] = $this->getTemplateSkuPropList();
1254 $this->arResult['CURRENCIES'] = $this->getTemplateCurrencies();
1255 $this->editTemplateItems($this->arResult);
1256 }
1257
1258 protected function editTemplateOfferProps(&$item)
1259 {
1260 $matrix = array();
1261 $newOffers = array();
1262 $double = array();
1263 $item['OFFER_GROUP'] = false;
1264 $item['OFFERS_PROP'] = false;
1265
1266 $iblockParams = $this->storage['IBLOCK_PARAMS'][$item['IBLOCK_ID']];
1267
1268 $boolSkuDisplayProps = false;
1269 $skuPropList = $this->arResult['SKU_PROPS'];
1270 $skuPropIds = array_keys($skuPropList);
1271 $matrixFields = array_fill_keys($skuPropIds, false);
1272
1273 foreach ($item['OFFERS'] as $keyOffer => $offer)
1274 {
1275 $offer['ID'] = (int)$offer['ID'];
1276
1277 if (isset($double[$offer['ID']]))
1278 continue;
1279
1280 $offer['OFFER_GROUP'] = false;
1281
1282 $row = array();
1283 foreach ($skuPropIds as $code)
1284 {
1285 $row[$code] = $this->getTemplatePropCell($code, $offer, $matrixFields, $skuPropList);
1286 }
1287
1288 $matrix[$keyOffer] = $row;
1289
1290 \CIBlockPriceTools::setRatioMinPrice($offer, false);
1291 $this->editTemplateOfferSlider($offer, $item['IBLOCK_ID'], 0, $this->arParams['ADD_DETAIL_TO_SLIDER'] === 'Y', $item['MORE_PHOTO']);
1292
1293 if (\CIBlockPriceTools::clearProperties($offer['DISPLAY_PROPERTIES'], $iblockParams['OFFERS_TREE_PROPS']))
1294 {
1295 $boolSkuDisplayProps = true;
1296 }
1297 $offer['TREE'] = [];
1298
1299 $double[$offer['ID']] = true;
1300 $newOffers[$keyOffer] = $offer;
1301 }
1302
1303 $item['OFFERS'] = $newOffers;
1304 $item['SHOW_OFFERS_PROPS'] = $boolSkuDisplayProps;
1305
1306 $usedFields = array();
1307 $sortFields = array();
1308
1309 foreach ($skuPropIds as $propCode)
1310 {
1311 $boolExist = $matrixFields[$propCode];
1312 foreach ($matrix as $keyOffer => $row)
1313 {
1314 if ($boolExist)
1315 {
1316 $item['OFFERS'][$keyOffer]['TREE']['PROP_'.$skuPropList[$propCode]['ID']] = $matrix[$keyOffer][$propCode]['VALUE'];
1317 $item['OFFERS'][$keyOffer]['SKU_SORT_'.$propCode] = $matrix[$keyOffer][$propCode]['SORT'];
1318 $usedFields[$propCode] = true;
1319 $sortFields['SKU_SORT_'.$propCode] = SORT_NUMERIC;
1320 }
1321 else
1322 {
1323 unset($matrix[$keyOffer][$propCode]);
1324 }
1325 }
1326 }
1327
1328 $item['OFFERS_PROP'] = $usedFields;
1329 $item['OFFERS_PROP_CODES'] = (!empty($usedFields) ? base64_encode(serialize(array_keys($usedFields))) : '');
1330
1331 Collection::sortByColumn($item['OFFERS'], $sortFields);
1332 }
1333
1334 protected function editTemplateProductSets(&$item)
1335 {
1336 $result = array();
1337 if (!Catalog\Config\Feature::isProductSetsEnabled())
1338 return $result;
1339 if (!isset($item['PRODUCT']['TYPE']))
1340 return $result;
1341
1342 $parentBundle = ($item['PRODUCT']['BUNDLE'] == 'Y');
1343 if ($parentBundle)
1344 $result[$item['ID']] = true;
1345 if ($item['PRODUCT']['TYPE'] == Catalog\ProductTable::TYPE_SKU)
1346 {
1347 foreach ($item['OFFERS'] as $offer)
1348 {
1349 if (
1350 $parentBundle
1351 || ($offer['PRODUCT']['BUNDLE'] == 'Y')
1352 )
1353 {
1354 $result[$offer['ID']] = true;
1355 }
1356 }
1357 unset($offer);
1358 }
1359 unset($parentBundle);
1360
1361 $item['OFFER_GROUP'] = !empty($result);
1362 if (!empty($result))
1363 $item['OFFER_GROUP_VALUES'] = array_keys($result);
1364
1365 return $result;
1366 }
1367
1368 protected function editTemplateJsOffers(&$item, $offerSet)
1369 {
1370 $matrix = [];
1371 $intSelected = -1;
1372
1373 $offerText = $this->arParams['SHOW_SKU_DESCRIPTION'] === 'Y';
1374
1375 foreach ($item['OFFERS'] as $keyOffer => $offer)
1376 {
1377 if ($item['OFFER_ID_SELECTED'] > 0)
1378 {
1379 $foundOffer = ($item['OFFER_ID_SELECTED'] == $offer['ID']);
1380 }
1381 else
1382 {
1383 $foundOffer = $offer['CAN_BUY'];
1384 }
1385
1386 if ($foundOffer && $intSelected == -1)
1387 {
1388 $intSelected = $keyOffer;
1389 }
1390 unset($foundOffer);
1391
1392 $skuProps = false;
1393 if (!empty($offer['DISPLAY_PROPERTIES']))
1394 {
1395 $skuProps = [];
1396 foreach ($offer['DISPLAY_PROPERTIES'] as $oneProp)
1397 {
1398 if ($oneProp['PROPERTY_TYPE'] === Iblock\PropertyTable::TYPE_FILE)
1399 {
1400 continue;
1401 }
1402
1403 $skuProps[] = [
1404 'CODE' => $oneProp['CODE'],
1405 'NAME' => $oneProp['NAME'],
1406 'VALUE' => $oneProp['DISPLAY_VALUE'],
1407 ];
1408 }
1409 unset($oneProp);
1410 }
1411
1412 if (isset($offerSet[$offer['ID']]))
1413 {
1414 $offer['OFFER_GROUP'] = true;
1415 $item['OFFERS'][$keyOffer]['OFFER_GROUP'] = true;
1416 }
1417
1418 $ratioSelectedIndex = $offer['ITEM_MEASURE_RATIO_SELECTED'];
1419 $firstPhoto = reset($offer['MORE_PHOTO']);
1420 $oneRow = [
1421 'ID' => $offer['ID'],
1422 'CODE' => $offer['CODE'],
1423 'NAME' => $offer['~NAME'] ?? $item['~NAME'],
1424 'TREE' => $offer['TREE'],
1425 'DISPLAY_PROPERTIES' => $skuProps,
1426 'PREVIEW_TEXT' => $offerText ? $offer['PREVIEW_TEXT'] : '',
1427 'PREVIEW_TEXT_TYPE' => $offerText ? $offer['PREVIEW_TEXT_TYPE'] : '',
1428 'DETAIL_TEXT' => $offerText ? $offer['DETAIL_TEXT'] : '',
1429 'DETAIL_TEXT_TYPE' => $offerText ? $offer['DETAIL_TEXT_TYPE'] : '',
1430 'ITEM_PRICE_MODE' => $offer['ITEM_PRICE_MODE'],
1431 'ITEM_PRICES' => $offer['ITEM_PRICES'],
1432 'ITEM_PRICE_SELECTED' => $offer['ITEM_PRICE_SELECTED'],
1433 'ITEM_QUANTITY_RANGES' => $offer['ITEM_QUANTITY_RANGES'],
1434 'ITEM_QUANTITY_RANGE_SELECTED' => $offer['ITEM_QUANTITY_RANGE_SELECTED'],
1435 'ITEM_MEASURE_RATIOS' => $offer['ITEM_MEASURE_RATIOS'],
1436 'ITEM_MEASURE_RATIO_SELECTED' => $ratioSelectedIndex,
1437 'PREVIEW_PICTURE' => $firstPhoto,
1438 'DETAIL_PICTURE' => $firstPhoto,
1439 'CHECK_QUANTITY' => $offer['CHECK_QUANTITY'],
1440 'MAX_QUANTITY' => $offer['PRODUCT']['QUANTITY'],
1441 'STEP_QUANTITY' => $offer['ITEM_MEASURE_RATIOS'][$ratioSelectedIndex]['RATIO'], // deprecated
1442 'QUANTITY_FLOAT' => is_float($offer['ITEM_MEASURE_RATIOS'][$ratioSelectedIndex]['RATIO']), // deprecated
1443 'MEASURE' => $offer['ITEM_MEASURE']['TITLE'],
1444 'OFFER_GROUP' => (isset($offerSet[$offer['ID']]) && $offerSet[$offer['ID']]),
1445 'CAN_BUY' => $offer['CAN_BUY'],
1446 'CATALOG_SUBSCRIBE' => $offer['PRODUCT']['SUBSCRIBE'],
1447 'SLIDER' => $offer['MORE_PHOTO'],
1448 'SLIDER_COUNT' => $offer['MORE_PHOTO_COUNT'],
1449 ];
1450 unset($ratioSelectedIndex);
1451
1452 $matrix[$keyOffer] = $oneRow;
1453 }
1454
1455 if ($intSelected == -1)
1456 {
1457 $intSelected = 0;
1458 }
1459
1460 $item['JS_OFFERS'] = $matrix;
1461 $item['OFFERS_SELECTED'] = $intSelected;
1462
1463 if ($matrix[$intSelected]['SLIDER_COUNT'] > 0)
1464 {
1465 $item['MORE_PHOTO'] = $matrix[$intSelected]['SLIDER'];
1466 $item['MORE_PHOTO_COUNT'] = $matrix[$intSelected]['SLIDER_COUNT'];
1467 }
1468
1469 $item['OFFERS_IBLOCK'] = $this->storage['SKU_IBLOCK_INFO']['IBLOCK_ID'];
1470 }
1471
1472 public function getTemplateSkuPropList()
1473 {
1474 $skuPropList = array();
1475
1476 if ($this->arResult['MODULES']['catalog'] && !empty($this->arParams['IBLOCK_ID']))
1477 {
1478 $sku = \CCatalogSku::GetInfoByProductIBlock($this->arParams['IBLOCK_ID']);
1479 $iblockParams = $this->storage['IBLOCK_PARAMS'][$this->arParams['IBLOCK_ID']];
1480 $boolSku = !empty($sku) && is_array($sku);
1481 if ($boolSku && !empty($iblockParams['OFFERS_TREE_PROPS']) && $this->arParams['PRODUCT_DISPLAY_MODE'] === 'Y')
1482 {
1483 $this->storage['SKU_IBLOCK_INFO'] = $sku;
1484
1485 $skuPropList = \CIBlockPriceTools::getTreeProperties(
1486 $sku,
1487 $iblockParams['OFFERS_TREE_PROPS'],
1488 array(
1489 'PICT' => $this->arResult['DEFAULT_PICTURE'],
1490 'NAME' => '-'
1491 )
1492 );
1493
1494 if (empty($skuPropList))
1495 {
1496 $this->arParams['PRODUCT_DISPLAY_MODE'] = 'N';
1497 }
1498 }
1499 }
1500
1501 return $skuPropList;
1502 }
1503
1504 protected function editTemplateItems(&$item)
1505 {
1506 $skuPropList =& $this->arResult['SKU_PROPS'];
1507
1508 if (!isset($item['CATALOG_QUANTITY']))
1509 {
1510 $item['CATALOG_QUANTITY'] = 0;
1511 }
1512
1513 $item['CATALOG_QUANTITY'] = $item['CATALOG_QUANTITY'] > 0 && is_float($item['ITEM_MEASURE_RATIOS'][$item['ITEM_MEASURE_RATIO_SELECTED']]['RATIO'])
1514 ? (float)$item['CATALOG_QUANTITY']
1515 : (int)$item['CATALOG_QUANTITY'];
1516
1517 $item['CATALOG'] = false;
1518 $item['CATALOG_SUBSCRIPTION'] = isset($item['CATALOG_SUBSCRIPTION']) && $item['CATALOG_SUBSCRIPTION'] === 'Y' ? 'Y' : 'N';
1519
1520 \CIBlockPriceTools::getLabel($item, $this->arParams['LABEL_PROP']);
1521 $this->editTemplateProductSlider($item, $item['IBLOCK_ID'], 0, $this->arParams['ADD_DETAIL_TO_SLIDER'] === 'Y', array($this->arResult['DEFAULT_PICTURE']));
1522 $this->editTemplateCatalogInfo($item);
1523
1524 $item['SHOW_OFFERS_PROPS'] = false;
1525 if ($item['CATALOG'] && !empty($item['OFFERS']))
1526 {
1527 $needValues = array();
1528
1529 foreach ($item['OFFERS'] as &$offer)
1530 {
1531 foreach (array_keys($skuPropList) as $strOneCode)
1532 {
1533 if (isset($offer['DISPLAY_PROPERTIES'][$strOneCode]))
1534 {
1535 if (!isset($needValues[$skuPropList[$strOneCode]['ID']]))
1536 {
1537 $needValues[$skuPropList[$strOneCode]['ID']] = array();
1538 }
1539
1540 $valueId = $skuPropList[$strOneCode]['PROPERTY_TYPE'] == Iblock\PropertyTable::TYPE_LIST
1541 ? $offer['DISPLAY_PROPERTIES'][$strOneCode]['VALUE_ENUM_ID']
1542 : $offer['DISPLAY_PROPERTIES'][$strOneCode]['VALUE'];
1543
1544 $needValues[$skuPropList[$strOneCode]['ID']][$valueId] = $valueId;
1545 unset($valueId);
1546 }
1547 }
1548 unset($strOneCode);
1549 }
1550 unset($offer);
1551
1552 if (!empty($needValues))
1553 \CIBlockPriceTools::getTreePropertyValues($skuPropList, $needValues);
1554 unset($needValues);
1555 $this->editTemplateOfferProps($item);
1556 $offerSet = $this->editTemplateProductSets($item);
1557 $this->editTemplateJsOffers($item, $offerSet);
1558 }
1559
1560 if ($item['MODULES']['catalog'] && $item['CATALOG'])
1561 {
1562 if (
1563 $item['CATALOG_TYPE'] == Catalog\ProductTable::TYPE_PRODUCT
1564 || $item['CATALOG_TYPE'] == Catalog\ProductTable::TYPE_SET
1565 )
1566 {
1567 if (isset($item['MIN_PRICE']))
1568 {
1569 \CIBlockPriceTools::setRatioMinPrice($item, false);
1570 $item['MIN_BASIS_PRICE'] = $item['MIN_PRICE'];
1571 }
1572 }
1573
1574 if (
1575 Catalog\Config\Feature::isProductSetsEnabled()
1576 && (
1577 $item['CATALOG_TYPE'] == Catalog\ProductTable::TYPE_PRODUCT
1578 || $item['CATALOG_TYPE'] == Catalog\ProductTable::TYPE_SET
1579 )
1580 )
1581 {
1582 $item['OFFER_GROUP'] = (isset($item['PRODUCT']['BUNDLE']) && $item['PRODUCT']['BUNDLE'] === 'Y');
1583 }
1584 }
1585
1586 if (!empty($item['DISPLAY_PROPERTIES']))
1587 {
1588 foreach ($item['DISPLAY_PROPERTIES'] as $propKey => $displayProperty)
1589 {
1590 if ($displayProperty['PROPERTY_TYPE'] === 'F')
1591 {
1592 unset($item['DISPLAY_PROPERTIES'][$propKey]);
1593 }
1594 }
1595 }
1596 }
1597}
getElementList($iblockId, $products)
Definition element.php:474
checkProductIblock(array $product)
Definition element.php:389
chooseOffer($offers, $iblockId)
Definition element.php:752
initAdditionalCacheKeys(&$resultCacheKeys)
Definition element.php:883
modifyDisplayProperties($iblock, &$iblockElements)
Definition element.php:569
static isCheckboxProperty(array $property)
Definition tools.php:207
static loadMessages($file)
Definition loc.php:64
static getMessage($code, $replace=null, $language=null)
Definition loc.php:29