Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
highloadblock.php
1<?php
3
9
10class HighloadBlock extends Base
11{
12 protected const TABLE_NAME_PREFIX = 'b_hlsys_';
13
14 protected const NAME_PREFIX = 'PRODUCT_';
15
16 protected static ?bool $highloadInclude = null;
17
18 protected static function checkRequiredModules(): void
19 {
20 parent::checkRequiredModules();
21 if (self::$highloadInclude === null)
22 {
23 self::$highloadInclude = Loader::includeModule('highloadblock');
24 if (!self::$highloadInclude)
25 {
26 self::addError(Loc::getMessage('BX_CATALOG_PRODUCT_SYSTEMFIELD_HIGHLOADBLOCK_ERR_MODULE_IS_ABSENT'));
27 }
28 }
29 }
30
31 protected static function internalCreate(array $config): Main\Result
32 {
33 $storage = static::createStorage($config['HIGHLOADBLOCK']);
34 if (!static::isSuccess())
35 {
36 return static::getErrorResult();
37 }
38
39 static::transformExistValues($storage);
40 if (!static::isSuccess())
41 {
42 return static::getErrorResult();
43 }
44
45 static::fillValues($storage);
46 if (!static::isSuccess())
47 {
48 return static::getErrorResult();
49 }
50
51 $config['HIGHLOADBLOCK'] = $storage;
52 $config = static::createLink($config);
53 if (!static::isSuccess())
54 {
55 return static::getErrorResult();
56 }
57
58 $result = new Main\Result();
59 $result->setData(['ID' => $config['FIELD']['ID']]);
60
61 return $result;
62 }
63
64 protected static function verifyConfig(array $config): array
65 {
66 return parent::verifyConfig($config);
67 }
68
73 public static function getTableName(string $code): string
74 {
75 return self::TABLE_NAME_PREFIX.mb_strtolower($code);
76 }
77
82 public static function getName(string $code): string
83 {
84 return Text\StringHelper::snake2camel(self::NAME_PREFIX.$code);
85 }
86
87 public static function getUserTypeId(): ?string
88 {
89 if (!static::isAllowed())
90 {
91 return null;
92 }
93
94 return \CUserTypeHlblock::USER_TYPE_ID;
95 }
96
97 public static function isAllowed(): bool
98 {
99 static::checkRequiredModules();
100
102 }
103
104 public static function getDefaultSettings(): ?array
105 {
106 if (!static::isAllowed())
107 {
108 return null;
109 }
110
111 return [
112 'DEFAULT_VALUE' => '',
113 'DISPLAY' => \CUserTypeHlblock::DISPLAY_LIST,
114 'LIST_HEIGHT' => 1
115 ];
116 }
117
118 public static function getDefaultRights(): ?array
119 {
120 if (!static::isAllowed())
121 {
122 return null;
123 }
124
125 $result = [
126 'G1' => 'W',
127 'G2' => 'R'
128 ];
129
130 if (static::isBitrix24())
131 {
132 if (Loader::includeModule('crm'))
133 {
134 $crmAdminGroupId = \CCrmSaleHelper::getShopGroupIdByType(\CCrmSaleHelper::GROUP_CRM_ADMIN);
135 if ($crmAdminGroupId !== null)
136 {
137 $result['G'.$crmAdminGroupId] = 'W';
138 }
139 $crmManagerGroupId = \CCrmSaleHelper::getShopGroupIdByType(\CCrmSaleHelper::GROUP_CRM_MANAGER);
140 if ($crmManagerGroupId)
141 {
142 $result['G'.$crmManagerGroupId] = 'R';
143 }
144 }
145 }
146
147 return $result;
148 }
149
154 protected static function createStorage(array $block): ?array
155 {
156 $storage = static::createStorageTable(
157 [
158 'NAME' => $block['NAME'],
159 'TABLE_NAME' => $block['TABLE_NAME'],
160 ],
161 [
162 'ALLOW_UPDATE' => true,
163 ]
164 );
165 if (empty($storage))
166 {
167 return null;
168 }
169 $block['ID'] = $storage['ID'];
170 unset($storage);
171
172 static::setStorageTitle($block);
173 if (!static::isSuccess())
174 {
175 return null;
176 }
177
178 static::setStorageRights($block);
179 if (!static::isSuccess())
180 {
181 return null;
182 }
183
184 return static::createStorageFields($block);
185 }
186
192 protected static function createStorageTable(array $block, array $options = []): ?array
193 {
194 $row = static::getStorageTable($block);
195 if (!empty($row))
196 {
197 if (isset($options['ALLOW_UPDATE']) && $options['ALLOW_UPDATE'] === true)
198 {
199 $block['ID'] = $row['ID'];
200 }
201 else
202 {
203 static::addError(Loc::getMessage(
204 'BX_CATALOG_PRODUCT_SYSTEMFIELD_HIGHLOADBLOCK_ERR_EXIST_HIGHLOADBLOCK',
205 ['#NAME#' => $block['NAME']]
206 ));
207
208 return null;
209 }
210 }
211 else
212 {
213 $internalResult = Highload\HighloadBlockTable::add([
214 'NAME' => $block['NAME'],
215 'TABLE_NAME' => $block['TABLE_NAME'],
216 ]);
217 if (!$internalResult->isSuccess())
218 {
219 static::addError(Loc::getMessage(
220 'BX_CATALOG_PRODUCT_SYSTEMFIELD_HIGHLOADBLOCK_ERR_CREATE_HIGHLOADBLOCK',
221 [
222 '#NAME#' => $block['NAME'],
223 '#ERROR#' => implode('; ', $internalResult->getErrorMessages()),
224 ]
225 ));
226
227 return null;
228 }
229 $block['ID'] = (int)$internalResult->getId();
230 }
231
232 return $block;
233 }
234
235 public static function getStorageTable(array $block): ?array
236 {
237 $iterator = Highload\HighloadBlockTable::getList([
238 'select' => [
239 'ID',
240 'NAME',
241 'TABLE_NAME',
242 ],
243 'filter' => [
244 '=NAME' => $block['NAME'],
245 '=TABLE_NAME' => $block['TABLE_NAME'],
246 ],
247 ]);
248 $row = $iterator->fetch();
249 unset($iterator);
250 if (!empty($row))
251 {
252 $row['ID'] = (int)$row['ID'];
253 return $row;
254 }
255
256 return null;
257 }
258
263 protected static function setStorageTitle(array $block): void
264 {
265 if (!isset($block['ID']))
266 {
267 static::addError(Loc::getMessage('BX_CATALOG_PRODUCT_SYSTEMFIELD_HIGHLOADBLOCK_ERR_HIGHLOADBLOCK_ID_ABSENT'));
268
269 return;
270 }
271
272 if (!empty($block['TITLES']) && is_array($block['TITLES']))
273 {
274 self::deleteStorageTitle($block);
275 foreach ($block['TITLES'] as $languageId => $title)
276 {
277 Highload\HighloadBlockLangTable::add([
278 'ID' => $block['ID'],
279 'LID' => $languageId,
280 'NAME' => $title,
281 ]);
282 }
283 }
284 }
285
286 private static function deleteStorageTitle(array $block): void
287 {
288 // because HighloadBlockLangTable primary key list was changed
289 $entity = Highload\HighloadBlockLangTable::getEntity();
290 if (in_array('LID', $entity->getPrimaryArray(), true))
291 {
292 foreach (array_keys($block['TITLES']) as $languageId)
293 {
294 Highload\HighloadBlockLangTable::delete([
295 'ID' => $block['ID'],
296 'LID' => $languageId,
297 ]);
298 }
299 }
300 else
301 {
302 Highload\HighloadBlockLangTable::delete([
303 'ID' => $block['ID'],
304 ]);
305 }
306 unset($entity);
307 }
308
313 protected static function setStorageRights(array $block): void
314 {
315 if (!isset($block['ID']))
316 {
317 static::addError(Loc::getMessage('BX_CATALOG_PRODUCT_SYSTEMFIELD_HIGHLOADBLOCK_ERR_HIGHLOADBLOCK_ID_ABSENT'));
318
319 return;
320 }
321
322 if (!empty($block['RIGHTS']) && is_array($block['RIGHTS']))
323 {
324 $tasks = static::getModuleTasks('highloadblock');
325 foreach ($block['RIGHTS'] as $accessCode => $role)
326 {
327 if (!isset($tasks[$role]))
328 {
329 continue;
330 }
331 $access = [
332 'HL_ID' => $block['ID'],
333 'ACCESS_CODE' => $accessCode,
334 'TASK_ID' => $tasks[$role],
335 ];
336 $iterator = Highload\HighloadBlockRightsTable::getList([
337 'select' => ['ID'],
338 'filter' => [
339 '=HL_ID' => $access['HL_ID'],
340 '=ACCESS_CODE' => $access['ACCESS_CODE'],
341 ],
342 ]);
343 $row = $iterator->fetch();
344 if (!empty($row))
345 {
346 Highload\HighloadBlockRightsTable::update($row['ID'], $access);
347 }
348 else
349 {
350 Highload\HighloadBlockRightsTable::add($access);
351 }
352 }
353 }
354 }
355
360 protected static function createStorageFields(array $block): ?array
361 {
362 if (!isset($block['ID']))
363 {
364 static::addError(Loc::getMessage('BX_CATALOG_PRODUCT_SYSTEMFIELD_HIGHLOADBLOCK_ERR_HIGHLOADBLOCK_ID_ABSENT'));
365
366 return null;
367 }
368
369 if (!empty($block['FIELDS']) && is_array($block['FIELDS']))
370 {
371 $entityId = Highload\HighloadBlockTable::compileEntityId($block['ID']);
372
373 foreach (array_keys($block['FIELDS']) as $index)
374 {
375 $block['FIELDS'][$index]['ENTITY_ID'] = $entityId;
376
377 $internalResult = static::createUserField($block['FIELDS'][$index]);
378 if (!$internalResult->isSuccess())
379 {
380 static::addError(Loc::getMessage(
381 'BX_CATALOG_PRODUCT_SYSTEMFIELD_HIGHLOADBLOCK_ERR_HIGHLOADBLOCK_CREATE_FIELD',
382 [
383 '#FIELD#' => $block['FIELDS'][$index]['FIELD_NAME'],
384 '#ERROR#' => implode('; ', $internalResult->getErrorMessages()),
385 ]
386 ));
387
388 return null;
389 }
390 $data = $internalResult->getData();
391 $block['FIELDS'][$index]['ID'] = (int)$data['ID'];
392 }
393 }
394
395 return $block;
396 }
397
398 protected static function transformExistValues(array $block): void
399 {
400 if (!empty($block['TRANSFORM_VALUES']) && is_array($block['TRANSFORM_VALUES']))
401 {
402 $entity = Highload\HighloadBlockTable::compileEntity($block);
403 $entityDataClass = $entity->getDataClass();
404
405 $dictionary = $block['TITLES'][LANGUAGE_ID] ?? $block['NAME'];
406
407 foreach ($block['TRANSFORM_VALUES'] as $group)
408 {
409 $iterator = $entityDataClass::getList([
410 'select' => ['ID'],
411 'filter' => ['=UF_XML_ID' => $group['OLD_XML_ID']],
412 ]);
413 $row = $iterator->fetch();
414 if (!empty($row))
415 {
416 $internalResult = $entityDataClass::update($row['ID'], ['UF_XML_ID' => $group['NEW_XML_ID']]);
417 if (!$internalResult->isSuccess())
418 {
419 static::addError(Loc::getMessage(
420 'BX_CATALOG_PRODUCT_SYSTEMFIELD_HIGHLOADBLOCK_ERR_TRANFORM_VALUE',
421 [
422 '#DICTIONARY#' => $dictionary,
423 '#ERROR#' => implode('; ', $internalResult->getErrorMessages()),
424 ]
425 ));
426 }
427 }
428 }
429 }
430 }
431
432 protected static function fillValues(array $block): void
433 {
434 if (!empty($block['VALUES']) && is_array($block['VALUES']))
435 {
436 $entity = Highload\HighloadBlockTable::compileEntity($block);
437 $entityDataClass = $entity->getDataClass();
438
439 $dictionary = $block['TITLES'][LANGUAGE_ID] ?? $block['NAME'];
440
441 foreach ($block['VALUES'] as $group)
442 {
443 $iterator = $entityDataClass::getList([
444 'select' => ['ID'],
445 'filter' => ['=UF_XML_ID' => $group['UF_XML_ID']]
446 ]);
447 $row = $iterator->fetch();
448 $found = !empty($row);
449 if (!$found)
450 {
451 $iterator = $entityDataClass::getList([
452 'select' => ['ID'],
453 'filter' => ['=UF_NAME' => $group['UF_NAME']]
454 ]);
455 $row = $iterator->fetch();
456 $found = !empty($row);
457 }
458 if ($found)
459 {
460 $internalResult = $entityDataClass::update($row['ID'], $group);
461 }
462 else
463 {
464 $internalResult = $entityDataClass::add($group);
465 }
466 if (!$internalResult->isSuccess())
467 {
468 static::addError(new Main\Error(
470 'BX_CATALOG_PRODUCT_SYSTEMFIELD_HIGHLOADBLOCK_ERR_ITEM_CREATE',
471 [
472 '#DICTIONARY#' => $dictionary,
473 '#CODE#' => '['.$group['UF_XML_ID'].'] '.$group['UF_NAME'],
474 ]
475 )
476 ));
477 }
478 }
479 }
480 }
481
482 protected static function createLink(array $config): ?array
483 {
484 $field = static::getPrepareLinkSettings($config);
485 $internalResult = static::createUserField($field);
486 if (!$internalResult->isSuccess())
487 {
488 static::addError(implode('; ', $internalResult->getErrorMessages()));
489
490 return null;
491 }
492 else
493 {
494 $data = $internalResult->getData();
495 $field['ID'] = (int)$data['ID'];
496 $config['FIELD'] = $field;
497
498 return $config;
499 }
500 }
501
502 protected static function getFieldIdbyName(array $fields, string $name): ?int
503 {
504 $result = null;
505 foreach ($fields as $item)
506 {
507 if ($item['FIELD_NAME'] === $name)
508 {
509 $result = $item['ID'];
510 }
511 }
512
513 return $result;
514 }
515
516 protected static function getPrepareLinkSettings(array $config): array
517 {
518 $field = $config['FIELD'];
519 $field['SETTINGS']['HLBLOCK_ID'] = $config['HIGHLOADBLOCK']['ID'];
520 $showedField = '';
521 if (isset($config['FIELD_CONFIG']['HLFIELD_ID']))
522 {
523 $showedField = (string)static::getFieldIdbyName(
524 $config['HIGHLOADBLOCK']['FIELDS'],
525 $config['FIELD_CONFIG']['HLFIELD_ID']
526 );
527 }
528 $field['SETTINGS']['HLFIELD_ID'] = $showedField;
529
530 if (!empty($field['SETTINGS']['DEFAULT_VALUE']))
531 {
532 $entity = Highload\HighloadBlockTable::compileEntity($config['HIGHLOADBLOCK']['ID']);
533 $entityDataClass = $entity->getDataClass();
534
535 $rawValues = $field['SETTINGS']['DEFAULT_VALUE'];
536 $map = [];
537 $iterator = $entityDataClass::getList([
538 'select' => [
539 'ID',
540 'UF_XML_ID',
541 ],
542 'filter' => ['@UF_XML_ID' => $rawValues],
543 ]);
544 while ($row = $iterator->fetch())
545 {
546 $map[$row['UF_XML_ID']] = (int)$row['ID'];
547 }
548 unset($row, $iterator);
549
550 if (is_array($rawValues))
551 {
552 $values = [];
553 foreach ($rawValues as $id)
554 {
555 if (isset($map[$id]))
556 {
557 $values[] = $map[$id];
558 }
559 }
560 $field['SETTINGS']['DEFAULT_VALUE'] = $values;
561 unset($id, $values);
562 }
563 else
564 {
565 $field['SETTINGS']['DEFAULT_VALUE'] = ($map[$rawValues] ?? 0);
566 }
567 unset($rawValues);
568 }
569
570 return $field;
571 }
572
573 protected static function internalGridAction(array $config): ?array
574 {
575 if (empty($config['USER_FIELD']) || !is_array($config['USER_FIELD']))
576 {
577 return null;
578 }
579 $userField = $config['USER_FIELD'];
580
581 $itemsConfig = [
582 'RESULT' => [
583 'NAME_WITH_ID' => 'Y',
584 ],
585 ];
586 if (
587 !empty($config['ADDITIONAL_VALUES'])
588 && is_array($config['ADDITIONAL_VALUES'])
589 )
590 {
591 $itemsConfig['ADDITIONAL_VALUES'] = $config['ADDITIONAL_VALUES'];
592 }
593
594 $list = static::getItems($userField, $itemsConfig);
595 if ($list === null)
596 {
597 return null;
598 }
599
600 $emptyText =
601 $userField['MULTIPLE'] === 'Y'
602 ? Loc::getMessage('BX_CATALOG_PRODUCT_SYSTEMFIELD_HIGHLOADBLOCK_MESS_EMPTY_VALUE')
603 : ''
604 ;
605
606 $action = [];
607 $action[] = [
608 'ACTION' => Main\Grid\Panel\Actions::RESET_CONTROLS
609 ];
610 $action[] = [
611 'ACTION' => Main\Grid\Panel\Actions::CREATE,
612 'DATA' => [
613 [
614 'TYPE' => Main\Grid\Panel\Types::DROPDOWN,
615 'ID' => $config['VISUAL']['LIST']['ID'],
616 'NAME' => $config['VISUAL']['LIST']['NAME'],
617 'ITEMS' => $list,
618 'MULTIPLE' => $userField['MULTIPLE'],
619 'EMPTY_TEXT' => $emptyText,
620 ],
621 ],
622 ];
623
624 $result = [
625 'NAME' => $userField['EDIT_FORM_LABEL'] ?? $userField['FIELD_NAME'],
626 'VALUE' => $userField['FIELD_NAME'],
627 'ONCHANGE' => $action
628 ];
629 unset($action, $list);
630
631 return $result;
632 }
633
634 public static function getIdByXmlId(int $hlblockId, array $xmlIds): array
635 {
636 $result = [];
637 $xmlIds = array_filter($xmlIds); // '0' - not valid code
638 if (empty($xmlIds))
639 {
640 return $result;
641 }
642 $hlblock = Highload\HighloadBlockTable::resolveHighloadblock($hlblockId);
643 if ($hlblock === null)
644 {
645 return $result;
646 }
647 $entity = Highload\HighloadBlockTable::compileEntity($hlblock);
648 $fieldsList = $entity->getFields();
649 if (isset($fieldsList['ID']) && isset($fieldsList['UF_XML_ID']))
650 {
651 $entityDataClass = $entity->getDataClass();
652 $iterator = $entityDataClass::getList([
653 'select' => [
654 'ID',
655 'UF_XML_ID',
656 ],
657 'filter' => [
658 '@UF_XML_ID' => $xmlIds,
659 ],
660 ]);
661 while ($value = $iterator->fetch())
662 {
663 $result[$value['UF_XML_ID']] = (int)$value['ID'];
664 }
665 unset($value, $iterator);
666 unset($entityDataClass);
667 }
668 unset($fieldsList, $entity);
669
670 return $result;
671 }
672
673 public static function getXmlIdById(int $hlblockId, array $ids): array
674 {
675 $result = [];
676 Main\Type\Collection::normalizeArrayValuesByInt($ids);
677 if (empty($ids))
678 {
679 return $result;
680 }
681 $hlblock = Highload\HighloadBlockTable::resolveHighloadblock($hlblockId);
682 if ($hlblock === null)
683 {
684 return $result;
685 }
686 $entity = Highload\HighloadBlockTable::compileEntity($hlblock);
687 $fieldsList = $entity->getFields();
688 if (isset($fieldsList['ID']) && isset($fieldsList['UF_XML_ID']))
689 {
690 $entityDataClass = $entity->getDataClass();
691 $iterator = $entityDataClass::getList([
692 'select' => [
693 'ID',
694 'UF_XML_ID',
695 ],
696 'filter' => [
697 '@ID' => $ids,
698 ],
699 ]);
700 while ($value = $iterator->fetch())
701 {
702 $result[$value['ID']] = $value['UF_XML_ID'];
703 }
704 unset($value, $iterator);
705 unset($entityDataClass);
706 }
707 unset($fieldsList, $entity);
708
709 return $result;
710 }
711
712 public static function getItems(array $userField, array $config = []): ?array
713 {
714 if (empty($userField['SETTINGS']) || !is_array($userField['SETTINGS']))
715 {
716 return null;
717 }
718 if (!isset($userField['SETTINGS']['HLBLOCK_ID']))
719 {
720 return null;
721 }
722
723 $hlblock = Highload\HighloadBlockTable::resolveHighloadblock($userField['SETTINGS']['HLBLOCK_ID']);
724 if ($hlblock === null)
725 {
726 return null;
727 }
728 $entity = Highload\HighloadBlockTable::compileEntity($hlblock);
729 $fieldsList = $entity->getFields();
730 if (!isset($fieldsList['ID']) || !isset($fieldsList['UF_NAME']))
731 {
732 return null;
733 }
734
735 $useIdKey = false;
736 $nameWithId = false;
737 if (!empty($config['RESULT']) && is_array($config['RESULT']))
738 {
739 $useIdKey = isset($config['RESULT']['RETURN_FIELD_ID']) && $config['RESULT']['RETURN_FIELD_ID'] === 'Y';
740 $nameWithId = isset($config['RESULT']['NAME_WITH_ID']) && $config['RESULT']['NAME_WITH_ID'] === 'Y';
741 }
742
743 $items = [];
744 if (
745 $userField['MANDATORY'] === 'N'
746 && $userField['MULTIPLE'] === 'N'
747 )
748 {
749 $row = [
750 'VALUE' => '0',
751 'NAME' => Loc::getMessage('BX_CATALOG_PRODUCT_SYSTEMFIELD_HIGHLOADBLOCK_MESS_EMPTY_VALUE'),
752 ];
753 if ($useIdKey)
754 {
755 $row['ID'] = '0';
756 }
757 $items[] = $row;
758 }
759
760 if (
761 !empty($config['ADDITIONAL_ITEMS']['LIST'])
762 && is_array($config['ADDITIONAL_ITEMS']['LIST'])
763 )
764 {
765 $items = array_merge(
766 $items,
767 $config['ADDITIONAL_ITEMS']['LIST']
768 );
769 }
770
771 $entityDataClass = $entity->getDataClass();
772 $iterator = $entityDataClass::getList([
773 'select' => [
774 'ID',
775 'UF_NAME',
776 ],
777 'order' => [
778 'UF_NAME' => 'ASC',
779 ],
780 ]);
781 while ($value = $iterator->fetch())
782 {
783 $row = [
784 'ID' => $value['ID'],
785 'VALUE' => $value['ID'],
786 'NAME' => ($nameWithId
787 ? $value['UF_NAME'] . ' [' .$value['ID'] . ']'
788 : $value['UF_NAME']
789 ),
790 ];
791 if ($useIdKey)
792 {
793 $row['ID'] = $value['ID'];
794 }
795 $items[] = $row;
796 }
797 unset($value, $iterator);
798 unset($entityDataClass, $entity);
799
800 return $items;
801 }
802}
static getIdByXmlId(int $hlblockId, array $xmlIds)
static getItems(array $userField, array $config=[])
static createStorageTable(array $block, array $options=[])
static getFieldIdbyName(array $fields, string $name)
static getXmlIdById(int $hlblockId, array $ids)
static getMessage($code, $replace=null, $language=null)
Definition loc.php:29