Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
site.php
1<?php
3
4use \Bitrix\Main\Localization\Loc;
5use \Bitrix\Main\Entity;
6use \Bitrix\Main\ModuleManager;
7use \Bitrix\Main\SystemException;
8use \Bitrix\Landing\Manager;
9use \Bitrix\Landing\Site;
10use \Bitrix\Landing\Domain;
11use \Bitrix\Landing\Rights;
12use \Bitrix\Landing\Role;
13use \Bitrix\Landing\Restriction;
14
15Loc::loadMessages(__FILE__);
16
33class SiteTable extends Entity\DataManager
34{
38 const ACTION_TYPE_ADD = 'add';
39
43 const ACTION_TYPE_UPDATE = 'update';
44
49 protected static $additionalFields = array();
50
55 protected static $disableCallback = false;
56
61 protected static $touchMode = false;
62
67 public static function getTableName()
68 {
69 return 'b_landing_site';
70 }
71
76 public static function getMap()
77 {
78 $types = \Bitrix\Landing\Site::getTypes();
79 $typesKeys = array_keys($types);
80
81 return array(
82 'ID' => new Entity\IntegerField('ID', array(
83 'primary' => true,
84 'autocomplete' => true,
85 'title' => 'ID'
86 )),
87 'CODE' => new Entity\StringField('CODE', array(
88 'title' => Loc::getMessage('LANDING_TABLE_FIELD_SITE_CODE'),
89 'required' => true
90 )),
91 'ACTIVE' => new Entity\StringField('ACTIVE', array(
92 'title' => Loc::getMessage('LANDING_TABLE_FIELD_SITE_ACTIVE'),
93 'default_value' => 'Y'
94 )),
95 'DELETED' => new Entity\StringField('DELETED', array(
96 'title' => Loc::getMessage('LANDING_TABLE_FIELD_LANDING_DELETED'),
97 'default_value' => 'N'
98 )),
99 'TITLE' => new Entity\StringField('TITLE', array(
100 'title' => Loc::getMessage('LANDING_TABLE_FIELD_SITE_TITLE'),
101 'required' => true
102 )),
103 'XML_ID' => new Entity\StringField('XML_ID', array(
104 'title' => Loc::getMessage('LANDING_TABLE_FIELD_XML_ID')
105 )),
106 'DESCRIPTION' => new Entity\StringField('DESCRIPTION', array(
107 'title' => Loc::getMessage('LANDING_TABLE_FIELD_DESCRIPTION')
108 )),
109 'TYPE' => new Entity\EnumField('TYPE', array(
110 'title' => Loc::getMessage('LANDING_TABLE_FIELD_TYPE'),
111 'values' => $typesKeys,
112 'default_value' => array_shift($typesKeys)
113 )),
114 'TPL_ID' => new Entity\IntegerField('TPL_ID', array(
115 'title' => Loc::getMessage('LANDING_TABLE_FIELD_TPL_ID'),
116 'default_value' => 0
117 )),
118 'TPL_CODE' => new Entity\StringField('TPL_CODE', array(
119 'title' => Loc::getMessage('LANDING_TABLE_FIELD_TPL_CODE')
120 )),
121 'DOMAIN_ID' => new Entity\IntegerField('DOMAIN_ID', array(
122 'title' => Loc::getMessage('LANDING_TABLE_FIELD_DOMAIN_ID'),
123 //'required' => true
124 )),
125 'DOMAIN' => new Entity\ReferenceField(
126 'DOMAIN',
127 'Bitrix\Landing\Internals\DomainTable',
128 array('=this.DOMAIN_ID' => 'ref.ID')
129 ),
130 'SMN_SITE_ID' => new Entity\StringField('SMN_SITE_ID', array(
131 'title' => Loc::getMessage('LANDING_TABLE_FIELD_SMN_SITE_ID')
132 )),
133 'LANDING_ID_INDEX' => new Entity\IntegerField('LANDING_ID_INDEX', array(
134 'title' => Loc::getMessage('LANDING_TABLE_FIELD_LANDING_ID_INDEX')
135 )),
136 'LANDING_ID_404' => new Entity\IntegerField('LANDING_ID_404', array(
137 'title' => Loc::getMessage('LANDING_TABLE_FIELD_LANDING_ID_404')
138 )),
139 'LANDING_ID_503' => new Entity\IntegerField('LANDING_ID_503', array(
140 'title' => Loc::getMessage('LANDING_TABLE_FIELD_LANDING_ID_503')
141 )),
142 'LANG' => new Entity\IntegerField('LANG', array(
143 'title' => Loc::getMessage('LANDING_TABLE_FIELD_LANG')
144 )),
145 'SPECIAL' => new Entity\StringField('SPECIAL', array(
146 'title' => Loc::getMessage('LANDING_TABLE_FIELD_SPECIAL'),
147 'default_value' => 'N'
148 )),
149 'VERSION' => new Entity\IntegerField('VERSION', array(
150 'title' => Loc::getMessage('LANDING_TABLE_FIELD_SITE_VERSION'),
151 'default_value' => 2
152 )),
153 'CREATED_BY_ID' => new Entity\IntegerField('CREATED_BY_ID', array(
154 'title' => Loc::getMessage('LANDING_TABLE_FIELD_CREATED_BY_ID'),
155 'required' => true
156 )),
157 'CREATED_BY' => new Entity\ReferenceField(
158 'CREATED_BY',
159 'Bitrix\Main\UserTable',
160 array('=this.CREATED_BY_ID' => 'ref.ID')
161 ),
162 'MODIFIED_BY_ID' => new Entity\IntegerField('MODIFIED_BY_ID', array(
163 'title' => Loc::getMessage('LANDING_TABLE_FIELD_MODIFIED_BY_ID'),
164 'required' => true
165 )),
166 'MODIFIED_BY' => new Entity\ReferenceField(
167 'MODIFIED_BY',
168 'Bitrix\Main\UserTable',
169 array('=this.MODIFIED_BY_ID' => 'ref.ID')
170 ),
171 'DATE_CREATE' => new Entity\DatetimeField('DATE_CREATE', array(
172 'title' => Loc::getMessage('LANDING_TABLE_FIELD_DATE_CREATE'),
173 'required' => true
174 )),
175 'DATE_MODIFY' => new Entity\DatetimeField('DATE_MODIFY', array(
176 'title' => Loc::getMessage('LANDING_TABLE_FIELD_DATE_MODIFY'),
177 'required' => true
178 ))
179 );
180 }
181
186 protected static function getSiteController()
187 {
189 }
190
198 protected static function checkUniqueInDomain($code, $currentId, $domainId)
199 {
200 $res = self::getList(array(
201 'select' => array(
202 'ID'
203 ),
204 'filter' => array(
205 '!ID' => $currentId,
206 'DOMAIN_ID' => $domainId,
207 '=CODE' => $code,
208 '=DELETED' => ['Y', 'N'],
209 'CHECK_PERMISSIONS' => 'N'
210 )
211 ));
212 return $res->fetch() ? false : true;
213 }
214
220 protected static function isB24Domain($domainName)
221 {
222 return Domain::getBitrix24Subdomain($domainName) !== null;
223 }
224
230 protected static function customizeControllerError(SystemException $ex)
231 {
232 $code = str_replace(' ', '', $ex->getMessage());
233 $code = mb_strtoupper($code);
234 $message = Loc::getMessage('LANDING_CONTROLLER_ERROR_' . $code);
235 $message = $message ? $message : $ex->getMessage();
236
237 return new Entity\EntityError(
238 $message,
239 'CONTROLLER_ERROR_' . $code
240 );
241 }
242
248 protected static function prepareLangForController(string $lang): string
249 {
250 $replaces = [
251 'in' => 'en',
252 'hi' => 'en',
253 ];
254
255 return in_array($lang, array_keys($replaces)) ? $replaces[$lang] : $lang;
256 }
257
263 public static function checkBitrixUse($domainName)
264 {
265 $isB24Domain = self::isB24Domain($domainName);
266 $disableMask = '/bitrix[^\.]*\.bitrix[^\.]+\.[a-z]+$/';
267 if (
268 Manager::isB24() &&
269 (
270 $isB24Domain && preg_match_all($disableMask, $domainName)
271 ||
272 !$isB24Domain && mb_strpos($domainName, 'bitrix') !== false
273 )
274 )
275 {
276 return true;
277 }
278 return false;
279 }
280
286 public static function setAccessFilter($params)
287 {
288 if (
289 isset($params['filter']['CHECK_PERMISSIONS']) &&
290 $params['filter']['CHECK_PERMISSIONS'] == 'N'
291 )
292 {
293 return $params;
294 }
295
296 // build filter
297 $allowedSites = Rights::getAllowedSites();
298 $buildFilter = Rights::getAccessFilter(
299 $allowedSites ? ['ID' => $allowedSites] : []
300 );
301 if (empty($buildFilter))
302 {
303 return $params;
304 }
305
306 // create runtime/filter keys if no exists
307 if (
308 !isset($params['filter']) ||
309 !is_array($params['filter'])
310 )
311 {
312 $params['filter'] = [];
313 }
314 if (
315 !isset($params['runtime']) ||
316 !is_array($params['runtime'])
317 )
318 {
319 $params['runtime'] = [];
320 }
321 if (
322 !isset($params['group']) ||
323 !is_array($params['group'])
324 )
325 {
326 $params['group'] = [];
327 }
328
329 //$tasks = Rights::getAccessTasksReferences();
330 //$readCode = Rights::ACCESS_TYPES['denied'];
331 $extendedRights = Rights::isExtendedMode();
332 static $expectedRoles = null;
333 if ($expectedRoles === null)
334 {
335 $expectedRoles = Role::getExpectedRoleIds();
336 }
337
338 // create runtime fields
339 $runtimeParams = [];
340 $runtimeParams[] = [
341 'LOGIC' => 'OR',
342 '=this.ID' => 'ref.ENTITY_ID',
343 '=ref.ENTITY_ID' => [0]
344 ];
345 if ($extendedRights)
346 {
347 $runtimeParams['=ref.ROLE_ID'] = [0];
348 }
349 else
350 {
351 $runtimeParams['=ref.ENTITY_TYPE'] = ['?', Rights::ENTITY_TYPE_SITE];
352 $runtimeParams['@ref.ROLE_ID'] = [implode(',', $expectedRoles)];
353 }
354 $params['runtime'][] = new Entity\ReferenceField(
355 'RIGHTS',
356 'Bitrix\Landing\Internals\RightsTable',
357 $runtimeParams,
358 ['join_type' => 'INNER']
359 );
360
361 $params['group'][] = 'ID';
362
363 // build filter
364 $params['filter'][] = $buildFilter;
365
366 return $params;
367 }
368
376 private static function getValueByCode($id, array $fields, $code)
377 {
378 static $data = [];
379
380 if (array_key_exists($id, $data))
381 {
382 return isset($data[$id][$code]) ? $data[$id][$code] : null;
383 }
384
385 if (array_key_exists($code, $fields))
386 {
387 return $fields[$code];
388 }
389
390 $res = self::getList([
391 'select' => [
392 '*',
393 'DOMAIN_NAME' => 'DOMAIN.DOMAIN',
394 'DOMAIN_PROVIDER' => 'DOMAIN.PROVIDER'
395 ],
396 'filter' => [
397 'ID' => $id,
398 'CHECK_PERMISSIONS' => 'N',
399 '=DELETED' => ['Y', 'N']
400 ]
401 ]);
402 if ($row = $res->fetch())
403 {
404 $data[$id] = $row;
405 }
406
407 return isset($data[$id][$code]) ? $data[$id][$code] : null;
408 }
409
416 protected static function prepareChange(Entity\Event $event, $actionType)
417 {
418 $result = new Entity\EventResult();
419 $fields = $event->getParameter('fields');
420 $primary = $event->getParameter('primary');
421 $unsetFields = array();
422 $modifyFields = array();
423 $siteController = self::getSiteController();
424 $deleteMode = false;
425
426 self::$touchMode = isset($fields['TOUCH']) && $fields['TOUCH'] == 'Y';
427
428 if ($actionType == self::ACTION_TYPE_ADD)
429 {
430 //@tmp log
431 \Bitrix\Landing\Debug::log(
432 $fields['TITLE'] ?? 'Noname',
433 print_r([$fields, \Bitrix\Main\Diag\Helper::getBackTrace(15)], true),
434 'LANDING_SITE_CREATE'
435 );
436 }
437
438 // clear binding cache
439 if (
440 isset($fields['CODE']) ||
441 isset($fields['TITLE']) ||
442 isset($fields['DELETED'])
443 )
444 {
445 if ($primary)
446 {
447 \Bitrix\Landing\Binding\Entity::onSiteChange(
448 $primary['ID']
449 );
450 }
451 }
452
453 if (
454 isset($fields['DOMAIN_ID']) &&
455 $fields['DOMAIN_ID'] === ''
456 )
457 {
458 unset($fields['DOMAIN_ID']);
459 $unsetFields[] = 'DOMAIN_ID';
460 }
461
462 // if delete, set unpublic always
463 if (isset($fields['DELETED']))
464 {
465 $deleteMode = true;
466 $modifyFields['ACTIVE'] = 'N';
467 $fields['ACTIVE'] = 'N';
468 // user try to restore site, check the limits
469 if ($primary && $fields['DELETED'] == 'N')
470 {
471 $fields['TYPE'] = self::getValueByCode(
472 $primary['ID'],
473 $fields,
474 'TYPE'
475 );
476 $check = Manager::checkFeature(
478 [
479 'type' => $fields['TYPE'],
480 'filter' => ['!ID' => $primary['ID']]
481 ]
482 );
483 if (!$check)
484 {
485 $result->setErrors([
487 Restriction\Manager::getSystemErrorMessage('limit_sites_number'),
488 'TOTAL_SITE_REACHED'
489 )
490 ]);
491 return $result;
492 }
493 }
494 else if ($primary && $fields['DELETED'] == 'Y')
495 {
496 $fields['DOMAIN_PROVIDER'] = self::getValueByCode(
497 $primary['ID'],
498 $fields,
499 'DOMAIN_PROVIDER'
500 );
501 if ($fields['DOMAIN_PROVIDER'] && ModuleManager::isModuleInstalled('bitrix24'))
502 {
503 $result->setErrors([
505 Loc::getMessage('LANDING_TABLE_ERROR_ACCESS_DENIED_DELETED'),
506 'ACCESS_DENIED_DELETED'
507 )
508 ]);
509 return $result;
510 }
511 }
512 }
513
514 // check that TYPE is valid and allowed
515 if (!$primary && isset($fields['TYPE']))
516 {
517 $allowedTypes = (array)\Bitrix\Landing\Site\Type::getFilterType();
518 if (!in_array($fields['TYPE'], $allowedTypes))
519 {
520 $result->setErrors(array(
522 Loc::getMessage('LANDING_TABLE_ERROR_ACCESS_DENIED_ADD'),
523 'ACCESS_DENIED'
524 )
525 ));
526 return $result;
527 }
528 }
529
530 // if domain id is not specified
531 if (!$primary && !array_key_exists('DOMAIN_ID', $fields))
532 {
533 $fields['DOMAIN_ID'] = \Bitrix\Landing\Site\Type::getDomainId();
534 $modifyFields['DOMAIN_ID'] = $fields['DOMAIN_ID'];
535 }
536
537 // check rights
538 if (isset($primary['ID']) && Rights::isOn())
539 {
541 $primary['ID']
542 );
543 $freeAccessFields = [
544 'CREATED_BY_ID',
545 'MODIFIED_BY_ID',
546 'DATE_CREATE',
547 'DATE_MODIFY',
548 'TOUCH'
549 ];
550 if (in_array(Rights::ACCESS_TYPES['sett'], $rights))
551 {
552 $freeAccessFields = $fields;
553 if (isset($freeAccessFields['ACTIVE']))
554 {
555 unset($freeAccessFields['ACTIVE']);
556 }
557 if (isset($freeAccessFields['DELETED']))
558 {
559 unset($freeAccessFields['DELETED']);
560 }
561 $freeAccessFields = array_keys($freeAccessFields);
562 }
563 if (in_array(Rights::ACCESS_TYPES['public'], $rights))
564 {
565 $freeAccessFields[] = 'ACTIVE';
566 }
567 if (in_array(Rights::ACCESS_TYPES['delete'], $rights))
568 {
569 $freeAccessFields[] = 'DELETED';
570 $freeAccessFields[] = 'DOMAIN_PROVIDER';
571 // allow unpublic in delete case
572 if ($deleteMode)
573 {
574 $freeAccessFields[] = 'ACTIVE';
575 }
576 }
577 foreach ($fields as $key => $val)
578 {
579 if (!in_array($key, $freeAccessFields))
580 {
581 $errMessage = Loc::getMessage(
582 'LANDING_TABLE_ERROR_ACCESS_DENIED_' . $key
583 );
584 if (!$errMessage)
585 {
586 $errMessage = Loc::getMessage(
587 'LANDING_TABLE_ERROR_ACCESS_DENIED'
588 );
589 }
590 $result->setErrors(array(
592 $errMessage,
593 'ACCESS_DENIED'
594 )
595 ));
596 return $result;
597 }
598 }
599 }
600 else if (Rights::isOn())
601 {
602 $hasAccess = Rights::hasAdditionalRight(
604 );
605 if (!$hasAccess)
606 {
607 $result->setErrors(array(
609 Loc::getMessage('LANDING_TABLE_ERROR_ACCESS_DENIED_ADD'),
610 'ACCESS_DENIED'
611 )
612 ));
613 return $result;
614 }
615 }
616
617 // additional fields save after
618 if (array_key_exists('ADDITIONAL_FIELDS', $fields))
619 {
620 self::$additionalFields = $fields['ADDITIONAL_FIELDS'];
621 $unsetFields[] = 'ADDITIONAL_FIELDS';
622 }
623 else
624 {
625 self::$additionalFields = array();
626 }
627
628 // check rights for site domain
629 if (
630 array_key_exists('DOMAIN_ID', $fields) &&
632 )
633 {
634 // for check rights call upper level
635 $res = Domain::getList(array(
636 'select' => array(
637 'ID'
638 ),
639 'filter' => array(
640 'ID' => $fields['DOMAIN_ID']
641 )
642 ));
643 if (!$res->fetch())
644 {
645 $result->unsetFields($unsetFields);
646 $result->setErrors(array(
648 Loc::getMessage('LANDING_TABLE_ERROR_DOMAIN_NOT_EXIST'),
649 'DOMAIN_NOT_FOUND'
650 )
651 ));
652 return $result;
653 }
654 }
655
656 // check active first (limit count)
657 if (
658 isset($fields['ACTIVE']) &&
659 $fields['ACTIVE'] == 'Y'
660 )
661 {
662 if ($primary)
663 {
664 $fields['TYPE'] = self::getValueByCode(
665 $primary['ID'],
666 $fields,
667 'TYPE'
668 );
669 }
670 else
671 {
672 $fields['TYPE'] = null;
673 }
674 $special = self::getValueByCode(
675 $primary['ID'],
676 $fields,
677 'SPECIAL'
678 );
679 if ($special == 'Y')
680 {
681 $canPublicSite = true;
682 }
683 else
684 {
685 $domainProvider = self::getValueByCode(
686 $primary['ID'],
687 $fields,
688 'DOMAIN_PROVIDER'
689 );
690 if ($domainProvider)
691 {
692 if (!Restriction\Manager::isAllowed('limit_free_domen', ['trueOnNotNull' => true]))
693 {
694 $result->unsetFields($unsetFields);
695 $result->setErrors(array(
697 Restriction\Manager::getSystemErrorMessage('limit_free_domen'),
698 'FREE_DOMAIN_IS_NOT_ALLOWED'
699 )
700 ));
701 return $result;
702 }
703 }
704 $canPublicSite = Manager::checkFeature(
706 $primary
707 ? array(
708 'filter' => array(
709 '!ID' => $primary['ID']
710 ),
711 'type' => $fields['TYPE']
712 )
713 : array(
714 'type' => $fields['TYPE']
715 )
716 );
717 }
718 if (!$canPublicSite)
719 {
720 $errCode = Manager::licenseIsFreeSite($fields['TYPE']) && !Manager::isFreePublicAllowed()
721 ? 'PUBLIC_SITE_REACHED_FREE'
722 : 'PUBLIC_SITE_REACHED';
723 $msgCode = Manager::licenseIsFreeSite($fields['TYPE']) && !Manager::isFreePublicAllowed()
724 ? 'limit_sites_number_free'
725 : 'limit_sites_number';
726 $result->unsetFields($unsetFields);
727 $result->setErrors(array(
729 Restriction\Manager::getSystemErrorMessage($msgCode),
730 $errCode
731 )
732 ));
733 return $result;
734 }
735 }
736
737 // prepare CODE - base part of URL
738 if (array_key_exists('CODE', $fields))
739 {
740 $fields['CODE'] = trim(trim(trim($fields['CODE']), '/'));
741 if (mb_strpos($fields['CODE'], '/') !== false)
742 {
743 $result->unsetFields($unsetFields);
744 $result->setErrors(array(
746 Loc::getMessage('LANDING_TABLE_ERROR_SITE_SLASH_IS_NOT_ALLOWED'),
747 'SLASH_IS_NOT_ALLOWED'
748 )
749 ));
750 return $result;
751 }
752 // generate CODE from TITLE, if CODE is empty (in create)
753 if (!$fields['CODE'])
754 {
755 $fields['CODE'] = \CUtil::translit(
756 (array_key_exists('TITLE', $fields) && trim($fields['TITLE']))
757 ? $fields['TITLE'] : 'site',
758 LANGUAGE_ID
759 );
760 if (!$fields['CODE'])
761 {
762 $fields['CODE'] = randString(12);
763 }
764 }
765 // only digits is disallowed
766 if (preg_match('/^[\d]+$/', $fields['CODE']))
767 {
768 $fields['CODE'] = 'site' . $fields['CODE'];
769 }
770 $fields['CODE'] = mb_substr($fields['CODE'], 0, 253);
771 $domainId = null;
772 // get domain id if no exists
773 if (!array_key_exists('DOMAIN_ID', $fields) && $primary)
774 {
775 $domainId = self::getValueByCode(
776 $primary['ID'],
777 $fields,
778 'DOMAIN_ID'
779 );
780 }
781 else if (array_key_exists('DOMAIN_ID', $fields))
782 {
783 $domainId = $fields['DOMAIN_ID'];
784 }
785 // make CODE unique in one domain
786 if ($domainId !== null)
787 {
788 $checkCount = 1;
789 $originalCode = $fields['CODE'];
790 do
791 {
793 '/' . $fields['CODE'] . '/',
794 $primary ? $primary['ID'] : 0,
795 $domainId
796 );
797 if (!$unique)
798 {
799 $fields['CODE'] = $originalCode . (++$checkCount);
800 }
801 } while (!$unique);
802 }
803 $fields['CODE'] = '/' . $fields['CODE'] . '/';
804 $modifyFields['CODE'] = $fields['CODE'];
805 }
806
807 // create/get domain by name (reg in b24.site if Bitrix24)
808 if (
809 array_key_exists('DOMAIN_ID', $fields) &&
810 $fields['DOMAIN_ID'] !== 0 &&
811 (
812 preg_replace('/[\d]/', '', trim($fields['DOMAIN_ID'])) != '' ||
814 )
815 )
816 {
817 $domainId = 0;
818 $domainName = mb_strtolower(trim($fields['DOMAIN_ID']));
819 $domainNameOld = '';
820
821 // fix for full name
822 if ($domainName != '')
823 {
824 $puny = new \CBXPunycode;
825 $domainName = $puny->encode($domainName);
826 // check correct name
827 if (!preg_match('/^[a-z0-9\-\.]+\.[a-z0-9\-]{2,20}$/i', $domainName))
828 {
829 $result->unsetFields($unsetFields);
830 $result->setErrors(array(
832 Loc::getMessage('LANDING_TABLE_ERROR_DOMAIN_IS_INCORRECT2'),
833 'DOMAIN_IS_INCORRECT'
834 )
835 ));
836 return $result;
837 }
838 }
839
840 // if add - unset domain_id, else - get current domain of site
841 if ($actionType == self::ACTION_TYPE_ADD)
842 {
843 $modifyFields['DOMAIN_ID'] = 0;
844 }
845 else
846 {
847 if ($primary)
848 {
849 $res = self::getList(array(
850 'select' => array(
851 'DOMAIN_ID',
852 'DOMAIN_NAME' => 'DOMAIN.DOMAIN'
853 ),
854 'filter' => array(
855 'ID' => $primary['ID'],
856 'CHECK_PERMISSIONS' => 'N'
857 )
858 ));
859 if ($row = $res->fetch())
860 {
861 $domainNameOld = mb_strtolower($row['DOMAIN_NAME']);
862 $domainId = $row['DOMAIN_ID'];
863 }
864 }
865 $unsetFields[] = 'DOMAIN_ID';
866 }
867
868 // check CODE unique in site group
869 if ($domainId && array_key_exists('CODE', $fields))
870 {
872 $fields['CODE'],
873 $primary ? $primary['ID'] : 0,
874 $domainId
875 );
876 if (!$unique)
877 {
878 $result->unsetFields($unsetFields);
879 $result->setErrors(array(
881 Loc::getMessage('LANDING_TABLE_ERROR_SITE_CODE_IS_NOT_UNIQUE2'),
882 'CODE_IS_NOT_UNIQUE'
883 )
884 ));
885 return $result;
886 }
887 }
888
889 // if domain name now changed
890 if (
891 $domainName != $domainNameOld ||
892 $actionType == self::ACTION_TYPE_ADD
893 )
894 {
895 $domainExist = false;
896
897 // check domain exist
898 if ($domainName != '')
899 {
900 $resDomain = Domain::getList(array(
901 'select' => array(
902 'ID'
903 ),
904 'filter' => array(
905 '=DOMAIN' => $domainName
906 )
907 ));
908 if ($rowDomain = $resDomain->fetch())
909 {
910 $domainExist = true;
911 $resSite = Site::getList(array(
912 'select' => array(
913 'ID'
914 ),
915 'filter' => array(
916 'DOMAIN_ID' => $rowDomain['ID'],
917 '=DELETED' => 'Y',
918 'CHECK_PERMISSIONS' => 'N'
919 )
920 ));
921 if ($resSite->fetch())
922 {
923 $result->setErrors(
924 array(
926 Loc::getMessage('LANDING_TABLE_ERROR_DOMAIN_EXIST_TRASH'),
927 'DOMAIN_EXIST_TRASH'
928 )
929 )
930 );
931 return $result;
932 }
933 }
934 elseif (Manager::isB24())
935 {
936 try
937 {
938 //todo: revert changes after change .by domain
939 if (
940 !str_ends_with($domainName, '.b24site.online')
941 && !str_ends_with($domainName, '.b24shop.online')
942 )
943 {
944 $domainExist = $siteController::isDomainExists($domainName);
945 }
946 else
947 {
948 $byDomainName = '';
949 if (str_ends_with($domainName, '.b24site.online'))
950 {
951 $byDomainName = str_replace('.b24site.online', '.bitrix24site.by', $domainName);
952 }
953 if (str_ends_with($domainName, '.b24shop.online'))
954 {
955 $byDomainName = str_replace('.b24shop.online', '.bitrix24shop.by', $domainName);
956 }
957 if ($byDomainName !== '' && $siteController::isDomainExists($byDomainName))
958 {
959 $domainExist = true;
960 }
961 else
962 {
963 $domainExist = $siteController::isDomainExists($domainName);
964 }
965 }
966 }
967 catch (SystemException $ex)
968 {
969 $result->unsetFields($unsetFields);
970 $result->setErrors(array(
971 self::customizeControllerError($ex)
972 ));
973 return $result;
974 }
975 }
976 }
977 if ($domainExist)
978 {
979 $result->unsetFields($unsetFields);
980 if (self::checkBitrixUse($domainName))
981 {
982 $result->setErrors(
983 array(
985 Loc::getMessage('LANDING_TABLE_ERROR_DOMAIN_BITRIX_DISABLE'),
986 'DOMAIN_DISABLE'
987 )
988 )
989 );
990 }
991 else
992 {
993 $result->setErrors(
994 array(
996 Loc::getMessage('LANDING_TABLE_ERROR_DOMAIN_EXIST'),
997 'DOMAIN_EXIST'
998 )
999 )
1000 );
1001 }
1002
1003 return $result;
1004 }
1005
1006 // check available external service
1007 try
1008 {
1009 $siteController::isDomainExists('repo.bitrix24.site');
1010 }
1011 catch (SystemException $ex)
1012 {
1013 $result->unsetFields($unsetFields);
1014 $result->setErrors(array(
1015 self::customizeControllerError($ex)
1016 ));
1017 return $result;
1018 }
1019
1020 // handler on add / update
1021 $eventManager = \Bitrix\Main\EventManager::getInstance();
1022 $eventManager->addEventHandler(
1023 'landing',
1024 $actionType == self::ACTION_TYPE_ADD
1025 ? '\\' . __NAMESPACE__ . '\\Site::onAfterAdd'
1026 : '\\' . __NAMESPACE__ . '\\Site::onAfterUpdate',
1027 function(Entity\Event $event) use ($domainId, $domainName, $domainNameOld, $result, $unsetFields, $siteController)
1028 {
1029 $primary = $event->getParameter('primary');
1030 $fields = $event->getParameter('fields');
1031
1032 if ($primary)
1033 {
1034 // create domain
1035 if (!$domainId)
1036 {
1037 // action in b24
1038 if (Manager::isB24())
1039 {
1040 $publicUrl = Manager::getPublicationPath(
1041 $primary['ID']
1042 );
1043 try
1044 {
1045 $row = self::getList(array(
1046 'select' => array(
1047 'TYPE'
1048 ),
1049 'filter' => array(
1050 'ID' => $primary['ID']
1051 )
1052 ))->fetch();
1053 if ($row['TYPE'] == 'STORE')// fix for controller
1054 {
1055 $row['TYPE'] = 'shop';
1056 }
1057 if ($domainName)
1058 {
1059 $siteController::addDomain(
1060 $domainName,
1061 $publicUrl,
1062 'N',
1063 $row['TYPE'],
1064 self::prepareLangForController(Manager::getZone())
1065 );
1066 }
1067 else
1068 {
1069 $domainName = $siteController::addRandomDomain(
1070 $publicUrl,
1071 $row['TYPE'],
1072 self::prepareLangForController(Manager::getZone())
1073 );
1074 }
1075 }
1076 catch (SystemException $ex)
1077 {
1078 $result->unsetFields($unsetFields);
1079 $result->setErrors(array(
1080 self::customizeControllerError($ex)
1081 ));
1082 return $result;
1083 }
1084 }
1085 // add new domain
1086 if ($domainName)
1087 {
1088 $resDomain = Domain::add(array(
1089 'ACTIVE' => 'Y',
1090 'DOMAIN' => $domainName
1091 ));
1092 $domainId = $resDomain->getId();
1093 if ($domainId)
1094 {
1096 SiteTable::update($primary['ID'], array(
1097 'DOMAIN_ID' => $domainId
1098 ));
1100 }
1101 }
1102 }
1103 // update domain
1104 else
1105 {
1106 $res = Domain::update($domainId, array(
1107 'DOMAIN' => $domainName,
1108 'FAIL_COUNT' => null,
1109 'PROVIDER' => null
1110 ));
1111 if ($res->isSuccess())
1112 {
1113 if (Manager::isB24())
1114 {
1115 try
1116 {
1117 $publicUrl = Manager::getPublicationPath(
1118 $primary['ID']
1119 );
1120 $siteController::updateDomain(
1121 $domainNameOld,
1122 $domainName,
1123 $publicUrl
1124 );
1125 }
1126 catch (SystemException $ex)
1127 {
1128 $result->unsetFields($unsetFields);
1129 $result->setErrors(array(
1130 self::customizeControllerError($ex)
1131 ));
1132 return $result;
1133 }
1134 }
1135 }
1136 }
1137 }
1138 }
1139 );
1140 }
1141 }
1142
1143 $result->unsetFields($unsetFields);
1144 $result->modifyFields($modifyFields);
1145
1146 return $result;
1147 }
1148
1155 public static function switchDomain(int $siteId1, int $siteId2): bool
1156 {
1157 $result = false;
1158
1159 self::$disableCallback = true;
1160
1161 $domains = [];
1162 $res = self::getList([
1163 'select' => [
1164 'ID',
1165 'TYPE',
1166 'LANG',
1167 'DOMAIN_ID',
1168 'DOMAIN_NAME' => 'DOMAIN.DOMAIN'
1169 ],
1170 'filter' => [
1171 'ID' => [$siteId1, $siteId2]
1172 ]
1173 ]);
1174 while ($row = $res->fetch())
1175 {
1176 $domains[] = [
1177 'ID' => $row['ID'],
1178 'TYPE' => $row['TYPE'],
1179 'LANG' => $row['LANG'],
1180 'DOMAIN_ID' => $row['DOMAIN_ID'],
1181 'DOMAIN_NAME' => $row['DOMAIN_NAME']
1182 ];
1183 }
1184
1185 if (count($domains) == 2)
1186 {
1187 $res1 = self::update($domains[0]['ID'], [
1188 'DOMAIN_ID' => $domains[1]['DOMAIN_ID']
1189 ]);
1190 $res2 = self::update($domains[1]['ID'], [
1191 'DOMAIN_ID' => $domains[0]['DOMAIN_ID']
1192 ]);
1193 $result = $res1->isSuccess() && $res2->isSuccess();
1194 }
1195
1196 self::$disableCallback = false;
1197
1198 // switch domain for bitrix24
1199 if ($result && Manager::isB24())
1200 {
1201 $siteController = self::getSiteController();
1202 try
1203 {
1204 for ($i = 0; $i <= 1; $i++)
1205 {
1206 $siteController::deleteDomain($domains[$i]['DOMAIN_NAME']);
1207 $siteController::addDomain(
1208 $domains[$i]['DOMAIN_NAME'],
1209 Manager::getPublicationPath($domains[$i == 0 ? 1 : 0]['ID']),
1210 'Y',
1211 ($domains[$i]['TYPE'] == 'STORE') ? 'shop' : $domains[$i]['TYPE'],
1212 self::prepareLangForController($domains[$i]['LANG'] ?? Manager::getZone())
1213 );
1214 }
1215 }
1216 catch (SystemException $ex) {}
1217 }
1218
1219 return $result;
1220 }
1221
1227 public static function randomizeDomain(int $siteId): bool
1228 {
1229 $res = self::getList([
1230 'select' => [
1231 'ID',
1232 'TYPE',
1233 'DOMAIN_ID',
1234 'DOMAIN_NAME' => 'DOMAIN.DOMAIN'
1235 ],
1236 'filter' => [
1237 'ID' => $siteId
1238 ]
1239 ]);
1240 if ($row = $res->fetch())
1241 {
1242 $siteController = self::getSiteController();
1243 $publicUrl = Manager::getPublicationPath($row['ID']);
1244 try
1245 {
1246 $siteController::deleteDomain($row['DOMAIN_NAME']);
1247 $domainName = $siteController::addRandomDomain(
1248 $publicUrl,
1249 ($row['TYPE'] == 'STORE') ? 'shop' : $row['TYPE'],
1251 );
1252 if ($domainName)
1253 {
1254 $res = Domain::update($row['DOMAIN_ID'], [
1255 'DOMAIN' => $domainName,
1256 'FAIL_COUNT' => null,
1257 'PROVIDER' => null
1258 ]);
1259 return $res->isSuccess();
1260 }
1261 }
1262 catch (SystemException $ex) {}
1263 }
1264
1265 return false;
1266 }
1267
1273 public static function OnBeforeAdd(Entity\Event $event)
1274 {
1275 $result = new Entity\EventResult();
1276
1277 if (self::$disableCallback)
1278 {
1279 return $result;
1280 }
1281
1282 $fields = $event->getParameter('fields');
1283
1284 // check site limit
1285 if (
1288 array(
1289 'type' => $fields['TYPE']
1290 )
1291 )
1292 )
1293 {
1294 $result->unsetFields(array('ADDITIONAL_FIELDS'));
1295 $result->setErrors(array(
1296 new Entity\EntityError(
1297 Restriction\Manager::getSystemErrorMessage('limit_sites_number'),
1298 'SITE_LIMIT_REACHED'
1299 )
1300 ));
1301 return $result;
1302 }
1303
1304 return self::prepareChange($event, self::ACTION_TYPE_ADD);
1305 }
1306
1312 public static function OnBeforeUpdate(Entity\Event $event)
1313 {
1314 if (self::$disableCallback)
1315 {
1316 return new Entity\EventResult();
1317 }
1318
1319 return self::prepareChange($event, self::ACTION_TYPE_UPDATE);
1320 }
1321
1327 protected static function saveAdditionalFields(Entity\Event $event)
1328 {
1329 $result = new Entity\EventResult();
1330
1331 if (!empty(self::$additionalFields))
1332 {
1333 $primary = $event->getParameter('primary');
1335 $primary['ID'],
1336 self::$additionalFields
1337 );
1338 }
1339
1340 return $result;
1341 }
1342
1348 public static function getList(array $params = array())
1349 {
1350 if (
1351 !isset($params['filter']) ||
1352 !is_array($params['filter'])
1353 )
1354 {
1355 $params['filter'] = array();
1356 }
1357 if (
1358 !isset($params['filter']['DELETED']) &&
1359 !isset($params['filter']['=DELETED'])
1360 )
1361 {
1362 $params['filter']['=DELETED'] = 'N';
1363 }
1364 if (isset($params['filter']['CHECK_PERMISSIONS']))
1365 {
1366 unset($params['filter']['CHECK_PERMISSIONS']);
1367 }
1368
1369 // strict filter by type
1370 $type = null;
1371 if (isset($params['filter']['TYPE']))
1372 {
1373 $type = $params['filter']['TYPE'];
1374 unset($params['filter']['TYPE']);
1375 }
1376 if (isset($params['filter']['=TYPE']))
1377 {
1378 $type = $params['filter']['=TYPE'];
1379 unset($params['filter']['=TYPE']);
1380 }
1381 $allowedTypes = \Bitrix\Landing\Site\Type::getFilterType();
1382 $params['filter']['=TYPE'] = (!is_array($type) && in_array($type, (array)$allowedTypes))
1383 ? $type
1384 : $allowedTypes;
1385
1386 return parent::getList($params);
1387 }
1388
1394 public static function OnAfterAdd(Entity\Event $event)
1395 {
1396 if (self::$disableCallback)
1397 {
1398 return true;
1399 }
1400
1401 return self::saveAdditionalFields($event);
1402 }
1403
1409 public static function OnAfterUpdate(Entity\Event $event)
1410 {
1411 if (self::$disableCallback)
1412 {
1413 return true;
1414 }
1415
1416 // for B24 we must update domain
1417 if (Manager::isB24() && !self::$touchMode)
1418 {
1419 static $domainUpdated = [];
1420
1421 $primary = $event->getParameter('primary');
1422
1423 if (!in_array($primary['ID'], $domainUpdated))
1424 {
1425 $domainUpdated[] = $primary['ID'];
1426 $siteController = self::getSiteController();
1427 $res = self::getList([
1428 'select' => [
1429 'ACTIVE', 'DELETED',
1430 'DOMAIN_NAME' => 'DOMAIN.DOMAIN',
1431 'LANG'
1432 ],
1433 'filter' => [
1434 'ID' => $primary['ID'],
1435 '=DELETED' => ['Y', 'N'],
1436 'CHECK_PERMISSIONS' => 'N',
1437 '>DOMAIN_ID' => 0
1438 ]
1439 ]);
1440 if ($row = $res->fetch())
1441 {
1442 try
1443 {
1444 // now external domains always are active
1445 $siteController::activateDomain(
1446 $row['DOMAIN_NAME'],
1447 'Y',
1448 self::prepareLangForController($row['LANG'] ?? Manager::getZone())
1449 );
1450 }
1451 catch (\Bitrix\Main\SystemException $ex) {}
1452 }
1453 }
1454 }
1455
1456 return self::saveAdditionalFields($event);
1457 }
1458
1464 public static function OnBeforeDelete(Entity\Event $event)
1465 {
1466 if (self::$disableCallback)
1467 {
1468 return true;
1469 }
1470
1471 $result = new Entity\EventResult();
1472 $primary = $event->getParameter('primary');
1473 $siteController = self::getSiteController();
1474
1475 if ($primary)
1476 {
1477 // check delete access
1478 $hasAccess = Rights::hasAccessForSite(
1479 $primary['ID'],
1480 Rights::ACCESS_TYPES['delete'],
1481 true
1482 );
1483 if (!$hasAccess)
1484 {
1485 $result->setErrors(array(
1486 new Entity\EntityError(
1487 Loc::getMessage('LANDING_TABLE_ERROR_ACCESS_DENIED_DELETED'),
1488 'ACCESS_DENIED'
1489 )
1490 ));
1491 return $result;
1492 }
1493 // check if site is not empty
1494 $res = LandingTable::getList(array(
1495 'select' => array(
1496 'ID'
1497 ),
1498 'filter' => array(
1499 'SITE_ID' => $primary['ID'],
1500 'CHECK_PERMISSIONS' => 'N'
1501 )
1502 ));
1503 if ($res->fetch())
1504 {
1505 $result->setErrors(array(
1506 new Entity\EntityError(
1507 Loc::getMessage('LANDING_TABLE_ERROR_SITE_IS_NOT_EMPTY'),
1508 'SITE_IS_NOT_EMPTY'
1509 )
1510 ));
1511 return $result;
1512 }
1513 // check lock status
1514 if (\Bitrix\Landing\Lock::isSiteDeleteLocked($primary['ID']))
1515 {
1516 $result->setErrors(array(
1517 new Entity\EntityError(
1518 Loc::getMessage('LANDING_TABLE_ERROR_SITE_IS_LOCK'),
1519 'SITE_IS_LOCK'
1520 )
1521 ));
1522 return $result;
1523 }
1524
1525 // delete in b24.site
1526 if (Manager::isB24())
1527 {
1528 $res = self::getList(array(
1529 'select' => array(
1530 'DOMAIN_ID',
1531 'DOMAIN_NAME' => 'DOMAIN.DOMAIN',
1532 'DOMAIN_PROVIDER' => 'DOMAIN.PROVIDER'
1533 ),
1534 'filter' => array(
1535 'ID' => $primary['ID'],
1536 'DELETED' => ['Y', 'N'],
1537 'CHECK_PERMISSIONS' => 'N'
1538 )
1539 ));
1540 if ($row = $res->fetch())
1541 {
1542 if ($row['DOMAIN_PROVIDER'] && ModuleManager::isModuleInstalled('bitrix24'))
1543 {
1544 $result->setErrors([
1545 new Entity\EntityError(
1546 Loc::getMessage('LANDING_TABLE_ERROR_ACCESS_DENIED_DELETED'),
1547 'ACCESS_DENIED_DELETED'
1548 )
1549 ]);
1550 return $result;
1551 }
1552
1553 $domainId = $row['DOMAIN_ID'];
1554 $domainName = $row['DOMAIN_NAME'];
1555 $eventManager = \Bitrix\Main\EventManager::getInstance();
1556 $eventManager->addEventHandler(
1557 'landing',
1558 '\\' . __NAMESPACE__ . '\\Site::onAfterDelete',
1559 function(Entity\Event $event) use ($domainId, $domainName, $result, $siteController)
1560 {
1561 $res = self::getList(array(
1562 'select' => array(
1563 'ID'
1564 ),
1565 'filter' => array(
1566 'DOMAIN_ID' => $domainId,
1567 'DELETED' => ['Y', 'N']
1568 )
1569 ));
1570 if (!$res->fetch())
1571 {
1572 DomainTable::delete($domainId);
1573 try
1574 {
1575 $siteController::deleteDomain($domainName);
1576 }
1577 catch (SystemException $ex)
1578 {
1579 $result->setErrors(array(
1580 self::customizeControllerError($ex)
1581 ));
1582 return $result;
1583 }
1584 }
1585 }
1586 );
1587 }
1588 }
1589 }
1590
1591 return $result;
1592 }
1593
1599 public static function onAfterDelete(Entity\Event $event)
1600 {
1601 $result = new Entity\EventResult();
1602 $primary = $event->getParameter('primary');
1603
1604 if (self::$disableCallback)
1605 {
1606 return $result;
1607 }
1608
1609 // delete all inner landings
1610 if ($primary)
1611 {
1613
1614 $res = LandingTable::getList(array(
1615 'select' => array(
1616 'ID'
1617 ),
1618 'filter' => array(
1619 'SITE_ID' => $primary['ID']
1620 )
1621 ));
1622 while ($row = $res->fetch())
1623 {
1624 \Bitrix\Landing\Landing::delete($row['ID'], true);
1625 }
1626
1627 \Bitrix\Landing\Syspage::deleteForSite($primary['ID']);
1628 \Bitrix\Landing\File::deleteFromSite($primary['ID']);
1629 \Bitrix\Landing\Hook::deleteForSite($primary['ID']);
1630 \Bitrix\Landing\TemplateRef::setForSite($primary['ID'], []);
1631 \Bitrix\Landing\UrlRewrite::removeForSite($primary['ID']);
1632 \Bitrix\Landing\Rights::setOperationsForSite($primary['ID'], []);
1633 \Bitrix\Landing\Folder::deleteForSite($primary['ID']);
1634 \Bitrix\Landing\Site\Cookies::removeAgreementsForSite($primary['ID']);
1635 BindingTable::siteClear($primary['ID']);
1636
1637 if (\Bitrix\Main\Loader::includeModule('ai'))
1638 {
1639 \Bitrix\AI\Context::clearContext([
1640 "image_site_{$primary['ID']}",
1641 "text_site_{$primary['ID']}",
1642 ]);
1643 }
1644
1645 Rights::setOn();
1646 }
1647
1648 return $result;
1649 }
1650}
static getBitrix24Subdomain(string $domainName, ?string &$baseUrl=null)
Definition domain.php:61
static getList(array $params=array())
Definition landing.php:602
static customizeControllerError(SystemException $ex)
Definition site.php:230
static switchDomain(int $siteId1, int $siteId2)
Definition site.php:1155
static getList(array $params=array())
Definition site.php:1348
static prepareChange(Entity\Event $event, $actionType)
Definition site.php:416
static OnBeforeDelete(Entity\Event $event)
Definition site.php:1464
static OnAfterUpdate(Entity\Event $event)
Definition site.php:1409
static OnBeforeAdd(Entity\Event $event)
Definition site.php:1273
static isB24Domain($domainName)
Definition site.php:220
static setAccessFilter($params)
Definition site.php:286
static checkUniqueInDomain($code, $currentId, $domainId)
Definition site.php:198
static saveAdditionalFields(Entity\Event $event)
Definition site.php:1327
static OnBeforeUpdate(Entity\Event $event)
Definition site.php:1312
static OnAfterAdd(Entity\Event $event)
Definition site.php:1394
static prepareLangForController(string $lang)
Definition site.php:248
static randomizeDomain(int $siteId)
Definition site.php:1227
static onAfterDelete(Entity\Event $event)
Definition site.php:1599
static checkBitrixUse($domainName)
Definition site.php:263
static isSiteDeleteLocked(int $siteId)
Definition lock.php:86
static getPublicationPath($siteCode=null, $siteId=null, $createPubPath=false)
Definition manager.php:396
static isFreePublicAllowed()
Definition manager.php:1243
static licenseIsFreeSite(string $type)
Definition manager.php:1233
static getExternalSiteController()
Definition manager.php:1324
const FEATURE_PUBLICATION_SITE
Definition manager.php:40
static checkFeature(string $feature, array $params=array())
Definition manager.php:831
static getAccessFilter(array $additionalFilterOr=[])
Definition rights.php:724
static getOperationsForSite($siteId)
Definition rights.php:518
static isExtendedMode()
Definition rights.php:781
static getAllowedSites()
Definition rights.php:156
static hasAdditionalRight($code, $type=null, bool $checkExtraRights=false, bool $strict=false)
Definition rights.php:1025
static hasAccessForSite($siteId, $accessType, $deleted=false)
Definition rights.php:544
static getExpectedRoleIds()
Definition role.php:566
static saveAdditionalFields($id, array $data)
Definition site.php:269
static loadMessages($file)
Definition loc.php:64
static getMessage($code, $replace=null, $language=null)
Definition loc.php:29