Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
state.php
1<?php
2
4
12use Bitrix\Crm;
13
20final class State
21{
23 private static $landingSections;
25 private static $iblockSections;
27 private static $fullIblockSections;
29 private static $elementCount;
31 private static $iblockList = [];
33 private static $crmIncluded;
34
40 public static function isUsedInventoryManagement(): bool
41 {
43 {
44 return false;
45 }
46
48 }
49
55 public final static function isEnabledInventoryManagement(): bool
56 {
57 return (Main\Config\Option::get('catalog', 'default_use_store_control') === 'Y');
58 }
59
65 public static function isShowedStoreReserve(): bool
66 {
67 if (!self::isUsedInventoryManagement())
68 {
69 return false;
70 }
71 if (
72 Main\Config\Option::get('catalog', 'enable_reservation') === 'Y'
73 && Main\Config\Option::get('catalog', 'show_store_reserve') === 'Y'
74 )
75 {
76 return true;
77 }
78 if (self::isCrmIncluded())
79 {
80 return (Main\Config\Option::get('crm', 'enable_order_deal_create') === 'Y');
81 }
82
83 return false;
84 }
85
91 public static function isExceededPriceTypeLimit(): bool
92 {
94 {
95 return false;
96 }
97
98 return Catalog\GroupTable::getCount([], ['ttl' => 86400]) > 1;
99 }
100
106 public static function isAllowedNewPriceType(): bool
107 {
109 {
110 return true;
111 }
112
113 return Catalog\GroupTable::getCount([], ['ttl' => 86400]) === 0;
114 }
115
121 public static function isExceededStoreLimit(): bool
122 {
124 {
125 return false;
126 }
127
128 return Catalog\StoreTable::getCount([], ['ttl' => 86400]) > 1;
129 }
130
136 public static function isAllowedNewStore(): bool
137 {
139 {
140 return true;
141 }
142
143 return Catalog\StoreTable::getCount([], ['ttl' => 86400]) === 0;
144 }
145
153 public static function getExceedingProductLimit(int $iblockId, ?int $sectionId = null): ?array
154 {
155 if ($iblockId <= 0)
156 {
157 return null;
158 }
159
160 if (!ModuleManager::isModuleInstalled('bitrix24'))
161 {
162 return null;
163 }
164
165 if ($iblockId !== self::getCrmCatalogId())
166 {
167 return null;
168 }
169
170 $result = self::checkIblockLimit($iblockId);
171 if ($result !== null && $sectionId !== null)
172 {
173 self::loadIblockSections($iblockId);
174 if (!isset(self::$fullIblockSections[$sectionId]))
175 {
176 $result = null;
177 }
178 }
179 if ($result === null)
180 {
181 $result = self::getCrmCatalogLimit($iblockId);
182 }
183
184 return $result;
185 }
186
192 public static function getCrmExceedingProductLimit(): ?array
193 {
194 $crmCatalogId = self::getCrmCatalogId();
195 if ($crmCatalogId > 0)
196 {
197 return self::getExceedingProductLimit($crmCatalogId);
198 }
199
200 return null;
201 }
202
203 public static function getProductLimitState(int $iblockId): ?array
204 {
205 if ($iblockId <= 0)
206 {
207 return null;
208 }
209
210 if (!ModuleManager::isModuleInstalled('bitrix24'))
211 {
212 return null;
213 }
214
215 if ($iblockId !== self::getCrmCatalogId())
216 {
217 return null;
218 }
219
220 $result = [];
222 $result[$variable] = [
223 'LIMIT_NAME' => $variable,
224 'LIMIT_VALUE' => Feature::getLandingProductLimit(),
225 'CURRENT_VALUE' => self::getElementCount($iblockId),
226 ];
227
228 $crmLimit = self::getCrmCatalogLimitState($iblockId);
229 if ($crmLimit !== null)
230 {
231 $result[$crmLimit['LIMIT_NAME']] = $crmLimit;
232 }
233
234 return $result;
235 }
236
243 public static function handlerBeforeIblockElementAdd(array &$fields): bool
244 {
245 if (!self::checkIblockId($fields))
246 {
247 return true;
248 }
249
250 $limit = self::checkIblockLimit((int)$fields['IBLOCK_ID']);
251 if (empty($limit))
252 {
253 return true;
254 }
255
256 if (!isset($fields['IBLOCK_SECTION']) || !is_array($fields['IBLOCK_SECTION']))
257 {
258 return true;
259 }
260 $sections = $fields['IBLOCK_SECTION'];
261 Main\Type\Collection::normalizeArrayValuesByInt($sections, true);
262 if (empty($sections))
263 {
264 return true;
265 }
266 self::loadIblockSections((int)$fields['IBLOCK_ID']);
267 $sections = array_intersect($sections, self::$fullIblockSections);
268 if (empty($sections))
269 {
270 return true;
271 }
272 unset($sections);
273
274 self::setProductLimitError($limit['MESSAGE']);
275 unset($limit);
276
277 return false;
278 }
279
286 public static function handlerAfterIblockElementAdd(array &$fields): void
287 {
288 if ($fields['RESULT'] === false)
289 return;
290
291 if (!self::checkIblockId($fields))
292 return;
293
294 $sections = $fields['IBLOCK_SECTION'] ?? null;
295 Main\Type\Collection::normalizeArrayValuesByInt($sections, true);
296 if (empty($sections))
297 return;
298 self::loadIblockSections((int)$fields['IBLOCK_ID']);
299 $sections = array_intersect($sections, self::$fullIblockSections);
300 if (empty($sections))
301 return;
302
303 self::$elementCount = null;
304 }
305
312 public static function handlerBeforeIblockElementUpdate(array &$fields): bool
313 {
314 if (!self::checkIblockId($fields))
315 {
316 return true;
317 }
318
319 $limit = self::checkIblockLimit((int)$fields['IBLOCK_ID']);
320 if (empty($limit))
321 {
322 return true;
323 }
324
325 if (!isset($fields['IBLOCK_SECTION']) || !is_array($fields['IBLOCK_SECTION']))
326 {
327 return true;
328 }
329 $sections = $fields['IBLOCK_SECTION'];
330 Main\Type\Collection::normalizeArrayValuesByInt($sections, true);
331 if (empty($sections))
332 {
333 return true;
334 }
335 self::loadIblockSections((int)$fields['IBLOCK_ID']);
336 $sections = array_intersect($sections, self::$fullIblockSections);
337 if (empty($sections))
338 {
339 return true;
340 }
341 unset($sections);
342
343 $notMove = false;
344 $iterator = Iblock\SectionElementTable::getList([
345 'select' => ['IBLOCK_SECTION_ID'],
346 'filter' => [
347 '=IBLOCK_ELEMENT_ID' => $fields['ID'],
348 '=ADDITIONAL_PROPERTY_ID' => null,
349 ],
350 ]);
351 while ($row = $iterator->fetch())
352 {
353 $row['ID'] = (int)$row['ID'];
354 if (isset(self::$fullIblockSections[$row['ID']]))
355 {
356 $notMove = true;
357 break;
358 }
359 }
360 unset($row, $iterator);
361 if ($notMove)
362 {
363 return true;
364 }
365
366 self::setProductLimitError($limit['MESSAGE']);
367 unset($limit);
368
369 return false;
370 }
371
378 public static function handlerAfterIblockElementUpdate(array &$fields): void
379 {
380 if ($fields['RESULT'] === false)
381 {
382 return;
383 }
384 if (!self::checkIblockId($fields))
385 {
386 return;
387 }
388 if (!array_key_exists('IBLOCK_SECTION', $fields))
389 {
390 return;
391 }
392
393 self::$elementCount = null;
394 }
395
402 public static function handlerAfterIblockElementDelete(array $fields): void
403 {
404 if (!self::checkIblockId($fields))
405 return;
406
407 self::$elementCount = null;
408 }
409
416 public static function handlerAfterIblockSectionAdd(array &$fields): void
417 {
418 if ($fields['RESULT'] === false)
419 return;
420 if (!self::checkIblockId($fields))
421 return;
422
423 self::$iblockSections = null;
424 self::$fullIblockSections = null;
425 }
426
433 public static function handlerBeforeIblockSectionUpdate(array &$fields): bool
434 {
435 if (!self::checkIblockId($fields))
436 {
437 return true;
438 }
439
440 $limit = self::getIblockLimit((int)$fields['IBLOCK_ID']);
441 if ($limit['LIMIT'] === 0)
442 {
443 return true;
444 }
445 if (!array_key_exists('IBLOCK_SECTION_ID', $fields))
446 {
447 return true;
448 }
449 $parentId = (int)$fields['IBLOCK_SECTION_ID'];
450 self::loadIblockSections((int)$fields['IBLOCK_ID']);
451 if (!isset(self::$fullIblockSections[$parentId]))
452 {
453 return true;
454 }
455 $iterator = Iblock\SectionTable::getList([
456 'select' => ['IBLOCK_SECTION_ID'],
457 'filter' => [
458 '=ID' => $fields['ID'],
459 '=IBLOCK_ID' => $fields['IBLOCK_ID'],
460 ],
461 ]);
462 $row = $iterator->fetch();
463 unset($iterator);
464 if (empty($row))
465 {
466 return true;
467 }
468 $oldParentId = (int)$row['IBLOCK_SECTION_ID'];
469 if (isset(self::$fullIblockSections[$oldParentId]))
470 {
471 return true;
472 }
473
474 $count = (int)\CIBlockElement::GetList(
475 [],
476 [
477 'IBLOCK_ID' => $fields['IBLOCK_ID'],
478 'SECTION_ID' => $fields['ID'],
479 'INCLUDE_SUBSECTIONS' => 'Y',
480 'CHECK_PERMISSIONS' => 'N',
481 ],
482 [],
483 false,
484 ['ID']
485 );
486 if ($count === 0)
487 {
488 return true;
489 }
490 $limit['COUNT'] += $count;
491 if ($limit['COUNT'] <= $limit['LIMIT'])
492 {
493 return true;
494 }
495
496 $limit['MESSAGE_ID'] = 'CATALOG_STATE_ERR_PRODUCT_IN_SECTION_LIMIT';
497
498 self::setProductLimitError(self::getProductLimitError($limit));
499 unset($limit);
500
501 return false;
502 }
503
510 public static function handlerAfterIblockSectionUpdate(array &$fields): void
511 {
512 if ($fields['RESULT'] === false)
513 {
514 return;
515 }
516 if (!self::checkIblockId($fields))
517 {
518 return;
519 }
520 if (!array_key_exists('IBLOCK_SECTION_ID', $fields))
521 {
522 return;
523 }
524
525 self::$iblockSections = null;
526 self::$fullIblockSections = null;
527 self::$elementCount = null;
528 }
529
536 public static function handlerAfterIblockSectionDelete(array $fields)
537 {
538 if (!self::checkIblockId($fields))
539 return;
540
541 self::$iblockSections = null;
542 self::$fullIblockSections = null;
543 self::$elementCount = null;
544 }
545
550 private static function getElementCount(int $iblockId): int
551 {
552 if (self::$elementCount === null)
553 {
554 self::$elementCount = 0;
555
556 $iblockSectionIds = self::getIblockSections($iblockId);
557 if (!empty($iblockSectionIds))
558 {
559 $filter = [
560 'IBLOCK_ID' => $iblockId,
561 'SECTION_ID' => $iblockSectionIds,
562 'INCLUDE_SUBSECTIONS' => 'Y',
563 'CHECK_PERMISSIONS' => 'N',
564 ];
565 $filter = Catalog\Product\SystemField\ProductMapping::getExtendedFilterByArea(
566 $filter,
567 Catalog\Product\SystemField\ProductMapping::MAP_LANDING
568 );
569 self::$elementCount = (int)\CIBlockElement::GetList(
570 [],
571 $filter,
572 [],
573 false,
574 ['ID']
575 );
576 }
577 unset($iblockSectionIds);
578 }
579 return self::$elementCount;
580 }
581
586 private static function getIblockSections(int $iblockId): array
587 {
588 if (self::$iblockSections === null)
589 {
590 self::loadIblockSections($iblockId);
591 }
592 return self::$iblockSections;
593 }
594
599 private static function loadIblockSections(int $iblockId): void
600 {
601 if (self::$iblockSections === null)
602 {
603 self::$iblockSections = [];
604 self::$fullIblockSections = [];
605 $sections = self::getLandingSections();
606 if (!empty($sections))
607 {
608 $iterator = Iblock\SectionTable::getList([
609 'select' => [
610 'ID',
611 'LEFT_MARGIN',
612 'RIGHT_MARGIN',
613 ],
614 'filter' => [
615 '=IBLOCK_ID' => $iblockId,
616 '@ID' => $sections,
617 ]
618 ]);
619 while ($row = $iterator->fetch())
620 {
621 $row['ID'] = (int)$row['ID'];
622 self::$iblockSections[] = $row['ID'];
623 self::$fullIblockSections[$row['ID']] = $row['ID'];
624 $sublist = Iblock\SectionTable::getList([
625 'select' => ['ID'],
626 'filter' => [
627 '=IBLOCK_ID' => $iblockId,
628 '>LEFT_MARGIN' => $row['LEFT_MARGIN'],
629 '<RIGHT_MARGIN' => $row['RIGHT_MARGIN'],
630 ]
631 ]);
632 while ($sub = $sublist->fetch())
633 {
634 $sub['ID'] = (int)$sub['ID'];
635 self::$fullIblockSections[$sub['ID']] = $sub['ID'];
636 }
637 }
638 unset($sub, $sublist, $row, $iterator);
639 }
640 unset($sections);
641 }
642 }
643
649 private static function getLandingSections(): array
650 {
651 if (self::$landingSections === null)
652 {
653 self::$landingSections = [];
654
655 if (!Loader::includeModule('landing'))
656 {
657 return self::$landingSections;
658 }
659
660 $iterator = Landing\Internals\HookDataTable::getList([
661 'runtime' => [
662 new Main\ORM\Fields\Relations\Reference(
663 'TMP_LANDING_SITE',
664 'Bitrix\Landing\Internals\SiteTable',
665 ['=this.ENTITY_ID' => 'ref.ID']
666 )
667 ],
668 'select' => ['VALUE'],
669 'filter' => [
670 '=ENTITY_TYPE' => Landing\Hook::ENTITY_TYPE_SITE,
671 '=HOOK' => 'SETTINGS',
672 '=CODE' => 'SECTION_ID',
673 '=TMP_LANDING_SITE.DELETED' => 'N',
674 ],
675 'cache' => ['ttl' => 86400],
676 ]);
677 while ($row = $iterator->fetch())
678 {
679 $id = (int)$row['VALUE'];
680 if ($id <= 0)
681 {
682 continue;
683 }
684 self::$landingSections[$id] = $id;
685 }
686 unset($id, $row, $iterator);
687
688 if (!empty(self::$landingSections))
689 {
690 self::$landingSections = array_values(self::$landingSections);
691 }
692 }
693
694 return self::$landingSections;
695 }
696
702 private static function getCrmCatalogId(): ?int
703 {
704 $result = null;
705 if (self::isCrmIncluded())
706 {
707 $result = Crm\Product\Catalog::getDefaultId();
708 }
709
710 return $result;
711 }
712
717 private static function getCrmCatalogLimit(int $iblockId): ?array
718 {
719 if (!self::isCrmIncluded())
720 {
721 return null;
722 }
723
724 return Crm\Config\State::getExceedingProductLimit($iblockId);
725 }
726
727 private static function getCrmCatalogLimitState(int $iblockId): ?array
728 {
729 if (!self::isCrmIncluded())
730 {
731 return null;
732 }
733
734 if (!method_exists('\Bitrix\Crm\Config\State', 'getProductLimitState'))
735 {
736 return null;
737 }
738
739 return Crm\Config\State::getProductLimitState($iblockId);
740 }
741
747 private static function isCrmIncluded(): bool
748 {
749 if (self::$crmIncluded === null)
750 {
751 self::$crmIncluded = Loader::includeModule('crm');
752 }
753
754 return self::$crmIncluded;
755 }
756
763 private static function checkIblockId(array $fields): bool
764 {
765 if (!isset($fields['IBLOCK_ID']))
766 {
767 return false;
768 }
769 $iblockId = (int)$fields['IBLOCK_ID'];
770 if ($iblockId <= 0)
771 {
772 return false;
773 }
774 if (!isset(self::$iblockList[$iblockId]))
775 {
776 $result = true;
777 if (!ModuleManager::isModuleInstalled('bitrix24'))
778 {
779 $result = false;
780 }
781 if ($iblockId !== self::getCrmCatalogId())
782 {
783 $result = false;
784 }
785 self::$iblockList[$iblockId] = $result;
786 }
787
788 return self::$iblockList[$iblockId];
789 }
790
804 private static function checkIblockLimit(int $iblockId): ?array
805 {
806 $result = self::getIblockLimit($iblockId);
807 if (
808 $result['LIMIT'] === 0
809 || $result['COUNT'] < $result['LIMIT']
810 )
811 {
812 return null;
813 }
814 $result['MESSAGE'] = self::getProductLimitError($result);
815 unset($result['MESSAGE_ID']);
816 $result['HELP_MESSAGE'] = Feature::getProductLimitHelpLink();
817
818 return $result;
819 }
820
833 private static function getIblockLimit(int $iblockId): array
834 {
835 $result = [
836 'COUNT' => 0,
838 'MESSAGE_ID' => 'CATALOG_STATE_ERR_PRODUCT_LIMIT_1'
839 ];
840 if ($result['LIMIT'] === 0)
841 {
842 return $result;
843 }
844 $result['COUNT'] = self::getElementCount($iblockId);
845
846 return $result;
847 }
848
855 private static function getProductLimitError(array $limit): ?string
856 {
857 if (!isset($limit['COUNT']) || !isset($limit['LIMIT']) || !isset($limit['MESSAGE_ID']))
858 {
859 return null;
860 }
861
862 return Loc::getMessage(
863 $limit['MESSAGE_ID'],
864 [
865 '#COUNT#' => $limit['COUNT'],
866 '#LIMIT#' => $limit['LIMIT']
867 ]
868 );
869 }
870
877 private static function setProductLimitError(string $errorMessage): void
878 {
879 global $APPLICATION;
880
881 $error = new \CAdminException([
882 [
883 'text' => $errorMessage,
884 ]
885 ]);
886 $APPLICATION->ThrowException($error);
887 }
888
894 public static function isProductCardSliderEnabled(): bool
895 {
897 {
898 return false;
899 }
900
901 return Main\Config\Option::get('catalog', 'product_card_slider_enabled') === 'Y';
902 }
903
909 public static function isProductBatchMethodSelected(): bool
910 {
912 {
913 return false;
914 }
915
916 return \Bitrix\Catalog\Product\Store\CostPriceCalculator::getMethod() !== '';
917 }
918}
static isCommonProductProcessingEnabled()
Definition feature.php:155
static handlerBeforeIblockSectionUpdate(array &$fields)
Definition state.php:433
static getProductLimitState(int $iblockId)
Definition state.php:203
static handlerAfterIblockElementUpdate(array &$fields)
Definition state.php:378
static handlerAfterIblockSectionDelete(array $fields)
Definition state.php:536
static isProductCardSliderEnabled()
Definition state.php:894
static isUsedInventoryManagement()
Definition state.php:40
static getCrmExceedingProductLimit()
Definition state.php:192
static handlerAfterIblockSectionUpdate(array &$fields)
Definition state.php:510
static isShowedStoreReserve()
Definition state.php:65
static handlerAfterIblockElementAdd(array &$fields)
Definition state.php:286
static handlerAfterIblockElementDelete(array $fields)
Definition state.php:402
static getExceedingProductLimit(int $iblockId, ?int $sectionId=null)
Definition state.php:153
static handlerBeforeIblockElementAdd(array &$fields)
Definition state.php:243
static isProductBatchMethodSelected()
Definition state.php:909
static isExceededPriceTypeLimit()
Definition state.php:91
static isEnabledInventoryManagement()
Definition state.php:55
static handlerBeforeIblockElementUpdate(array &$fields)
Definition state.php:312
static handlerAfterIblockSectionAdd(array &$fields)
Definition state.php:416
const ENTITY_TYPE_SITE
Definition hook.php:20
static getMessage($code, $replace=null, $language=null)
Definition loc.php:29