static function prepareChange(EntityEvent $event, $actionType)
{
$result = new EntityEventResult();
$fields = $event->getParameter('fields');
$primary = $event->getParameter('primary');
$unsetFields = array();
$modifyFields = array();
$siteController = self::getSiteController();
$deleteMode = false;
self::$touchMode = isset($fields['TOUCH']) && $fields['TOUCH'] == 'Y';
if ($actionType == self::ACTION_TYPE_ADD)
{
//@tmp log
BitrixLandingDebug::log(
$fields['TITLE'] ?? 'Noname',
print_r([$fields, BitrixMainDiagHelper::getBackTrace(15)], true),
'LANDING_SITE_CREATE'
);
}
// clear binding cache
if (
isset($fields['CODE']) ||
isset($fields['TITLE']) ||
isset($fields['DELETED'])
)
{
if ($primary)
{
BitrixLandingBindingEntity::onSiteChange(
$primary['ID']
);
}
}
if (
isset($fields['DOMAIN_ID']) &&
$fields['DOMAIN_ID'] === ''
)
{
unset($fields['DOMAIN_ID']);
$unsetFields[] = 'DOMAIN_ID';
}
// if delete, set unpublic always
if (isset($fields['DELETED']))
{
$deleteMode = true;
$modifyFields['ACTIVE'] = 'N';
$fields['ACTIVE'] = 'N';
// user try to restore site, check the limits
if ($primary && $fields['DELETED'] == 'N')
{
$fields['TYPE'] = self::getValueByCode(
$primary['ID'],
$fields,
'TYPE'
);
$check = Manager::checkFeature(
Manager::FEATURE_CREATE_SITE,
[
'type' => $fields['TYPE'],
'filter' => ['!ID' => $primary['ID']]
]
);
if (!$check)
{
$result->setErrors([
new EntityEntityError(
RestrictionManager::getSystemErrorMessage('limit_sites_number'),
'TOTAL_SITE_REACHED'
)
]);
return $result;
}
}
else if ($primary && $fields['DELETED'] == 'Y')
{
$fields['DOMAIN_PROVIDER'] = self::getValueByCode(
$primary['ID'],
$fields,
'DOMAIN_PROVIDER'
);
if ($fields['DOMAIN_PROVIDER'] && ModuleManager::isModuleInstalled('bitrix24'))
{
$result->setErrors([
new EntityEntityError(
Loc::getMessage('LANDING_TABLE_ERROR_ACCESS_DENIED_DELETED'),
'ACCESS_DENIED_DELETED'
)
]);
return $result;
}
}
}
// check that TYPE is valid and allowed
if (!$primary && isset($fields['TYPE']))
{
$allowedTypes = (array)BitrixLandingSiteType::getFilterType();
if (!in_array($fields['TYPE'], $allowedTypes))
{
$result->setErrors(array(
new EntityEntityError(
Loc::getMessage('LANDING_TABLE_ERROR_ACCESS_DENIED_ADD'),
'ACCESS_DENIED'
)
));
return $result;
}
}
// if domain id is not specified
if (!$primary && !array_key_exists('DOMAIN_ID', $fields))
{
$fields['DOMAIN_ID'] = BitrixLandingSiteType::getDomainId();
$modifyFields['DOMAIN_ID'] = $fields['DOMAIN_ID'];
}
// check rights
if (isset($primary['ID']) && Rights::isOn())
{
$rights = Rights::getOperationsForSite(
$primary['ID']
);
$freeAccessFields = [
'CREATED_BY_ID',
'MODIFIED_BY_ID',
'DATE_CREATE',
'DATE_MODIFY',
'TOUCH'
];
if (in_array(Rights::ACCESS_TYPES['sett'], $rights))
{
$freeAccessFields = $fields;
if (isset($freeAccessFields['ACTIVE']))
{
unset($freeAccessFields['ACTIVE']);
}
if (isset($freeAccessFields['DELETED']))
{
unset($freeAccessFields['DELETED']);
}
$freeAccessFields = array_keys($freeAccessFields);
}
if (in_array(Rights::ACCESS_TYPES['public'], $rights))
{
$freeAccessFields[] = 'ACTIVE';
}
if (in_array(Rights::ACCESS_TYPES['delete'], $rights))
{
$freeAccessFields[] = 'DELETED';
$freeAccessFields[] = 'DOMAIN_PROVIDER';
// allow unpublic in delete case
if ($deleteMode)
{
$freeAccessFields[] = 'ACTIVE';
}
}
foreach ($fields as $key => $val)
{
if (!in_array($key, $freeAccessFields))
{
$errMessage = Loc::getMessage(
'LANDING_TABLE_ERROR_ACCESS_DENIED_' . $key
);
if (!$errMessage)
{
$errMessage = Loc::getMessage(
'LANDING_TABLE_ERROR_ACCESS_DENIED'
);
}
$result->setErrors(array(
new EntityEntityError(
$errMessage,
'ACCESS_DENIED'
)
));
return $result;
}
}
}
else if (Rights::isOn())
{
$hasAccess = Rights::hasAdditionalRight(
Rights::ADDITIONAL_RIGHTS['create']
);
if (!$hasAccess)
{
$result->setErrors(array(
new EntityEntityError(
Loc::getMessage('LANDING_TABLE_ERROR_ACCESS_DENIED_ADD'),
'ACCESS_DENIED'
)
));
return $result;
}
}
// additional fields save after
if (array_key_exists('ADDITIONAL_FIELDS', $fields))
{
self::$additionalFields = $fields['ADDITIONAL_FIELDS'];
$unsetFields[] = 'ADDITIONAL_FIELDS';
}
else
{
self::$additionalFields = array();
}
// check rights for site domain
if (
array_key_exists('DOMAIN_ID', $fields) &&
!Manager::isB24()
)
{
// for check rights call upper level
$res = Domain::getList(array(
'select' => array(
'ID'
),
'filter' => array(
'ID' => $fields['DOMAIN_ID']
)
));
if (!$res->fetch())
{
$result->unsetFields($unsetFields);
$result->setErrors(array(
new EntityEntityError(
Loc::getMessage('LANDING_TABLE_ERROR_DOMAIN_NOT_EXIST'),
'DOMAIN_NOT_FOUND'
)
));
return $result;
}
}
// check active first (limit count)
if (
isset($fields['ACTIVE']) &&
$fields['ACTIVE'] == 'Y'
)
{
if ($primary)
{
$fields['TYPE'] = self::getValueByCode(
$primary['ID'],
$fields,
'TYPE'
);
}
else
{
$fields['TYPE'] = null;
}
$special = self::getValueByCode(
$primary['ID'],
$fields,
'SPECIAL'
);
if ($special == 'Y')
{
$canPublicSite = true;
}
else
{
$domainProvider = self::getValueByCode(
$primary['ID'],
$fields,
'DOMAIN_PROVIDER'
);
if ($domainProvider)
{
if (!RestrictionManager::isAllowed('limit_free_domen', ['trueOnNotNull' => true]))
{
$result->unsetFields($unsetFields);
$result->setErrors(array(
new EntityEntityError(
RestrictionManager::getSystemErrorMessage('limit_free_domen'),
'FREE_DOMAIN_IS_NOT_ALLOWED'
)
));
return $result;
}
}
$canPublicSite = Manager::checkFeature(
Manager::FEATURE_PUBLICATION_SITE,
$primary
? array(
'filter' => array(
'!ID' => $primary['ID']
),
'type' => $fields['TYPE']
)
: array(
'type' => $fields['TYPE']
)
);
}
if (!$canPublicSite)
{
$errCode = Manager::licenseIsFreeSite($fields['TYPE']) && !Manager::isFreePublicAllowed()
? 'PUBLIC_SITE_REACHED_FREE'
: 'PUBLIC_SITE_REACHED';
$msgCode = Manager::licenseIsFreeSite($fields['TYPE']) && !Manager::isFreePublicAllowed()
? 'limit_sites_number_free'
: 'limit_sites_number';
$result->unsetFields($unsetFields);
$result->setErrors(array(
new EntityEntityError(
RestrictionManager::getSystemErrorMessage($msgCode),
$errCode
)
));
return $result;
}
}
// prepare CODE - base part of URL
if (array_key_exists('CODE', $fields))
{
$fields['CODE'] = trim(trim(trim($fields['CODE']), '/'));
if (mb_strpos($fields['CODE'], '/') !== false)
{
$result->unsetFields($unsetFields);
$result->setErrors(array(
new EntityEntityError(
Loc::getMessage('LANDING_TABLE_ERROR_SITE_SLASH_IS_NOT_ALLOWED'),
'SLASH_IS_NOT_ALLOWED'
)
));
return $result;
}
// generate CODE from TITLE, if CODE is empty (in create)
if (!$fields['CODE'])
{
$fields['CODE'] = CUtil::translit(
(array_key_exists('TITLE', $fields) && trim($fields['TITLE']))
? $fields['TITLE'] : 'site',
LANGUAGE_ID
);
if (!$fields['CODE'])
{
$fields['CODE'] = randString(12);
}
}
// only digits is disallowed
if (preg_match('/^[d]+$/', $fields['CODE']))
{
$fields['CODE'] = 'site' . $fields['CODE'];
}
$fields['CODE'] = mb_substr($fields['CODE'], 0, 253);
$domainId = null;
// get domain id if no exists
if (!array_key_exists('DOMAIN_ID', $fields) && $primary)
{
$domainId = self::getValueByCode(
$primary['ID'],
$fields,
'DOMAIN_ID'
);
}
else if (array_key_exists('DOMAIN_ID', $fields))
{
$domainId = $fields['DOMAIN_ID'];
}
// make CODE unique in one domain
if ($domainId !== null)
{
$checkCount = 1;
$originalCode = $fields['CODE'];
do
{
$unique = self::checkUniqueInDomain(
'/' . $fields['CODE'] . '/',
$primary ? $primary['ID'] : 0,
$domainId
);
if (!$unique)
{
$fields['CODE'] = $originalCode . (++$checkCount);
}
} while (!$unique);
}
$fields['CODE'] = '/' . $fields['CODE'] . '/';
$modifyFields['CODE'] = $fields['CODE'];
}
// create/get domain by name (reg in b24.site if Bitrix24)
if (
array_key_exists('DOMAIN_ID', $fields) &&
$fields['DOMAIN_ID'] !== 0 &&
(
preg_replace('/[d]/', '', trim($fields['DOMAIN_ID'])) != '' ||
Manager::isB24()
)
)
{
$domainId = 0;
$domainName = mb_strtolower(trim($fields['DOMAIN_ID']));
$domainNameOld = '';
// fix for full name
if ($domainName != '')
{
$puny = new CBXPunycode;
$domainName = $puny->encode($domainName);
// check correct name
if (!preg_match('/^[a-z0-9-.]+.[a-z0-9-]{2,20}$/i', $domainName))
{
$result->unsetFields($unsetFields);
$result->setErrors(array(
new EntityEntityError(
Loc::getMessage('LANDING_TABLE_ERROR_DOMAIN_IS_INCORRECT2'),
'DOMAIN_IS_INCORRECT'
)
));
return $result;
}
}
// if add - unset domain_id, else - get current domain of site
if ($actionType == self::ACTION_TYPE_ADD)
{
$modifyFields['DOMAIN_ID'] = 0;
}
else
{
if ($primary)
{
$res = self::getList(array(
'select' => array(
'DOMAIN_ID',
'DOMAIN_NAME' => 'DOMAIN.DOMAIN'
),
'filter' => array(
'ID' => $primary['ID'],
'CHECK_PERMISSIONS' => 'N'
)
));
if ($row = $res->fetch())
{
$domainNameOld = mb_strtolower($row['DOMAIN_NAME']);
$domainId = $row['DOMAIN_ID'];
}
}
$unsetFields[] = 'DOMAIN_ID';
}
// check CODE unique in site group
if ($domainId && array_key_exists('CODE', $fields))
{
$unique = self::checkUniqueInDomain(
$fields['CODE'],
$primary ? $primary['ID'] : 0,
$domainId
);
if (!$unique)
{
$result->unsetFields($unsetFields);
$result->setErrors(array(
new EntityEntityError(
Loc::getMessage('LANDING_TABLE_ERROR_SITE_CODE_IS_NOT_UNIQUE2'),
'CODE_IS_NOT_UNIQUE'
)
));
return $result;
}
}
// if domain name now changed
if (
$domainName != $domainNameOld ||
$actionType == self::ACTION_TYPE_ADD
)
{
$domainExist = false;
// check domain exist
if ($domainName != '')
{
$resDomain = Domain::getList(array(
'select' => array(
'ID'
),
'filter' => array(
'=DOMAIN' => $domainName
)
));
if ($rowDomain = $resDomain->fetch())
{
$domainExist = true;
$resSite = Site::getList(array(
'select' => array(
'ID'
),
'filter' => array(
'DOMAIN_ID' => $rowDomain['ID'],
'=DELETED' => 'Y',
'CHECK_PERMISSIONS' => 'N'
)
));
if ($resSite->fetch())
{
$result->setErrors(
array(
new EntityEntityError(
Loc::getMessage('LANDING_TABLE_ERROR_DOMAIN_EXIST_TRASH'),
'DOMAIN_EXIST_TRASH'
)
)
);
return $result;
}
}
elseif (Manager::isB24())
{
try
{
$domainExist = $siteController::isDomainExists($domainName);
}
catch (SystemException $ex)
{
$result->unsetFields($unsetFields);
$result->setErrors(array(
self::customizeControllerError($ex)
));
return $result;
}
}
}
if ($domainExist)
{
$result->unsetFields($unsetFields);
if (self::checkBitrixUse($domainName))
{
$result->setErrors(
array(
new EntityEntityError(
Loc::getMessage('LANDING_TABLE_ERROR_DOMAIN_BITRIX_DISABLE'),
'DOMAIN_DISABLE'
)
)
);
}
else
{
$result->setErrors(
array(
new EntityEntityError(
Loc::getMessage('LANDING_TABLE_ERROR_DOMAIN_EXIST'),
'DOMAIN_EXIST'
)
)
);
}
return $result;
}
// check available external service
try
{
$siteController::isDomainExists('repo.bitrix24.site');
}
catch (SystemException $ex)
{
$result->unsetFields($unsetFields);
$result->setErrors(array(
self::customizeControllerError($ex)
));
return $result;
}
// handler on add / update
$eventManager = BitrixMainEventManager::getInstance();
$eventManager->addEventHandler(
'landing',
$actionType == self::ACTION_TYPE_ADD
? '\' . __NAMESPACE__ . '\Site::onAfterAdd'
: '\' . __NAMESPACE__ . '\Site::onAfterUpdate',
function(EntityEvent $event) use ($domainId, $domainName, $domainNameOld, $result, $unsetFields, $siteController)
{
$primary = $event->getParameter('primary');
$fields = $event->getParameter('fields');
if ($primary)
{
// create domain
if (!$domainId)
{
// action in b24
if (Manager::isB24())
{
$publicUrl = Manager::getPublicationPath(
$primary['ID']
);
try
{
$row = self::getList(array(
'select' => array(
'TYPE'
),
'filter' => array(
'ID' => $primary['ID']
)
))->fetch();
if ($row['TYPE'] == 'STORE')// fix for controller
{
$row['TYPE'] = 'shop';
}
if ($domainName)
{
$siteController::addDomain(
$domainName,
$publicUrl,
'N',
$row['TYPE'],
self::prepareLangForController(Manager::getZone())
);
}
else
{
$domainName = $siteController::addRandomDomain(
$publicUrl,
$row['TYPE'],
self::prepareLangForController(Manager::getZone())
);
}
}
catch (SystemException $ex)
{
$result->unsetFields($unsetFields);
$result->setErrors(array(
self::customizeControllerError($ex)
));
return $result;
}
}
// add new domain
if ($domainName)
{
$resDomain = Domain::add(array(
'ACTIVE' => 'Y',
'DOMAIN' => $domainName
));
$domainId = $resDomain->getId();
if ($domainId)
{
SiteTable::$disableCallback = true;
SiteTable::update($primary['ID'], array(
'DOMAIN_ID' => $domainId
));
SiteTable::$disableCallback = false;
}
}
}
// update domain
else
{
$res = Domain::update($domainId, array(
'DOMAIN' => $domainName,
'FAIL_COUNT' => null,
'PROVIDER' => null
));
if ($res->isSuccess())
{
if (Manager::isB24())
{
try
{
$publicUrl = Manager::getPublicationPath(
$primary['ID']
);
$siteController::updateDomain(
$domainNameOld,
$domainName,
$publicUrl
);
}
catch (SystemException $ex)
{
$result->unsetFields($unsetFields);
$result->setErrors(array(
self::customizeControllerError($ex)
));
return $result;
}
}
}
}
}
}
);
}
}
$result->unsetFields($unsetFields);
$result->modifyFields($modifyFields);
return $result;
}