42 private const ENTITY_ID_PREFIX =
'HLBLOCK_';
44 private const ENTITY_ID_MASK =
'/^HLBLOCK_(\d+)$/';
46 private const NAME_COLLECTION =
'collection';
53 return 'b_hlblock_entity';
58 return HighloadBlock::class;
65 $sqlHelper = Application::getConnection()->getSqlHelper();
69 'data_type' =>
'integer',
71 'autocomplete' =>
true,
74 'data_type' =>
'string',
76 'validation' => [__CLASS__,
'validateName'],
79 'data_type' =>
'string',
81 'validation' => [__CLASS__,
'validateTableName'],
84 'data_type' =>
'integer',
86 '(SELECT COUNT(ID) FROM b_user_field WHERE b_user_field.ENTITY_ID = '.
87 $sqlHelper->getConcatFunction(
"'".self::ENTITY_ID_PREFIX.
"'", $sqlHelper->castToChar(
'%s')).
')',
91 'LANG' =>
new Entity\ReferenceField(
93 'Bitrix\Highloadblock\HighloadBlockLangTable',
121 ->configureNullable(
false)
122 ->configurePrimary(
true)
123 ->configureAutocomplete(
true)
138 $rowId = (int)
$result->getId();
139 $connection->queryExecute(
'delete from ' . $sqlHelper->quote(self::getTableName()) .
' where ID = ' . $rowId);
142 'HIGHLOADBLOCK_HIGHLOAD_BLOCK_ENTITY_TABLE_CREATE_ERROR',
144 '#ERROR#' => $e->getMessage(),
164 $oldData = static::getByPrimary($primary)->fetch();
175 if (isset(
$data[
'TABLE_NAME']) &&
$data[
'TABLE_NAME'] !== $oldData[
'TABLE_NAME'])
185 "EXEC sp_rename %s, %s, 'OBJECT'",
186 $sqlHelper->quote($oldData[
'TABLE_NAME'].
'_ibpk_1'),
187 $sqlHelper->quote(
$data[
'TABLE_NAME'].
'_ibpk_1')
193 foreach (
$USER_FIELD_MANAGER->getUserFields(static::compileEntityId($oldData[
'ID'])) as $field)
195 if ($field[
'MULTIPLE'] ==
'Y')
197 $oldUtmTableName = static::getMultipleValueTableName($oldData, $field);
198 $newUtmTableName = static::getMultipleValueTableName(
$data, $field);
200 $connection->renameTable($oldUtmTableName, $newUtmTableName);
213 public static function delete($primary)
218 $hlblock = static::getByPrimary($primary)->fetch();
221 $result = parent::delete($primary);
229 $fileFieldList =
array();
235 if ($field[
'USER_TYPE'][
'BASE_TYPE'] ===
'file')
237 $fileFieldList[] =
$name;
242 if (!empty($fileFieldList))
244 $oldEntity = static::compileEntity($hlblock);
246 $query =
new Entity\Query($oldEntity);
249 $query->setSelect($fileFieldList);
254 foreach ($fileFieldList as $fileField)
256 $filter[
'!'.$fileField] =
false;
266 foreach ($fileFieldList as $fileField)
268 if (!empty($row[$fileField]))
270 if (is_array($row[$fileField]))
272 foreach ($row[$fileField] as $value)
274 \CFile::delete($value);
279 \CFile::delete($row[$fileField]);
292 if ($field[
'USER_TYPE'][
'BASE_TYPE'] ===
'enum')
294 $enumField = new \CUserFieldEnum;
295 $enumField->DeleteFieldEnum($field[
'ID']);
298 $connection->query(
"DELETE FROM b_user_field_lang WHERE USER_FIELD_ID = ".$field[
'ID']);
299 $connection->query(
"DELETE FROM b_user_field WHERE ID = ".$field[
'ID']);
302 if ($field[
'MULTIPLE'] ==
'Y')
304 $utmTableName = static::getMultipleValueTableName($hlblock, $field);
310 $managedCache = Application::getInstance()->getManagedCache();
311 if(CACHED_b_user_field !==
false)
313 $managedCache->cleanDir(
"b_user_field");
317 $res = HighloadBlockLangTable::getList(
array(
318 'filter' =>
array(
'ID' => $primary)
320 while ($row =
$res->fetch())
322 HighloadBlockLangTable::delete([
324 'LID' => $row[
'LID'],
329 $res = HighloadBlockRightsTable::getList(
array(
330 'filter' =>
array(
'HL_ID' => $primary)
332 while ($row =
$res->fetch())
334 HighloadBlockRightsTable::delete($row[
'ID']);
349 if (!is_array($hlblock))
351 if (is_int($hlblock) || is_numeric(mb_substr($hlblock, 0, 1)))
354 $hlblock = HighloadBlockTable::getByPrimary(
363 elseif (is_string($hlblock) && $hlblock !==
'')
366 $hlblock = HighloadBlockTable::query()
369 ->where(
'NAME', $hlblock)
382 if (!isset($hlblock[
'ID']))
384 if (!isset($hlblock[
'NAME']) || !preg_match(
'/^[a-z0-9_]+$/i', $hlblock[
'NAME']))
386 if (empty($hlblock[
'TABLE_NAME']))
399 public static function compileEntity($hlblock,
bool $force =
false)
403 $rawBlock = $hlblock;
404 $hlblock = static::resolveHighloadblock($hlblock);
408 "Invalid highloadblock description '%s'.",
mydump($rawBlock)
413 if (class_exists($hlblock[
'NAME'] .
'Table') && !$force)
419 $fieldsMap =
array();
422 $fieldsMap[
'ID'] =
array(
423 'data_type' =>
'integer',
425 'autocomplete' =>
true
429 $entityName = $hlblock[
'NAME'];
430 $entityDataClass = $hlblock[
'NAME'].
'Table';
432 if (class_exists($entityDataClass))
435 Main\ORM\Entity::destroy($entityDataClass);
439 $entityTableName = $hlblock[
'TABLE_NAME'];
443 class '.$entityDataClass.
' extends '.__NAMESPACE__.
'\DataManager
445 public static function getTableName()
447 return '.var_export($entityTableName,
true).
';
450 public static function getMap()
452 return '.var_export($fieldsMap,
true).
';
455 public static function getHighloadBlock()
457 return '.var_export($hlblock,
true).
';
467 $entity = $entityDataClass::getEntity();
472 foreach ($uFields as $uField)
474 if ($uField[
'MULTIPLE'] ==
'N')
478 'required' => $uField[
'MANDATORY'] ==
'Y'
490 static::compileUtmEntity(
$entity, $uField);
494 return Main\ORM\Entity::getInstance($entityName);
503 return self::ENTITY_ID_PREFIX.$id;
508 if (preg_match(self::ENTITY_ID_MASK, $field[
'ENTITY_ID'],
$matches))
510 if (mb_substr($field[
'FIELD_NAME'], -4) ==
'_REF')
519 Main\
Localization\Loc::getMessage(
'HIGHLOADBLOCK_HIGHLOAD_BLOCK_ENTITY_FIELD_NAME_REF_RESERVED')
526 return array(
'PROVIDE_STORAGE' =>
false);
537 if (preg_match(self::ENTITY_ID_MASK, $field[
'ENTITY_ID'],
$matches))
543 $hlblock = HighloadBlockTable::getById($hlblockId)->fetch();
548 'Entity "'.static::compileEntityId(
'%s').
'" wasn\'t found.', $hlblockId
562 'ALTER TABLE %s ADD %s %s',
563 $sqlHelper->quote($hlblock[
'TABLE_NAME']), $sqlHelper->quote($field[
'FIELD_NAME']), $sqlColumnType
566 if ($field[
'MULTIPLE'] ==
'Y')
569 $hlentity = static::compileEntity($hlblock,
true);
572 $utmEntity->createDbTable();
576 'CREATE INDEX %s ON %s (%s)',
577 $sqlHelper->quote(
'IX_UTM_HL'.$hlblock[
'ID'].
'_'.$field[
'ID'].
'_ID'),
578 $sqlHelper->quote($utmEntity->getDBTableName()),
579 $sqlHelper->quote(
'ID')
583 'CREATE INDEX %s ON %s (%s)',
584 $sqlHelper->quote(
'IX_UTM_HL'.$hlblock[
'ID'].
'_'.$field[
'ID'].
'_VALUE'),
585 $sqlHelper->quote($utmEntity->getDBTableName()),
586 $sqlHelper->quote(
'VALUE')
590 return array(
'PROVIDE_STORAGE' =>
false);
596 public static function OnBeforeUserTypeDelete($field)
600 if (preg_match(self::ENTITY_ID_MASK, $field[
'ENTITY_ID'],
$matches))
604 $hlblock = HighloadBlockTable::getById($hlblockId)->fetch();
609 return array(
'PROVIDE_STORAGE' =>
false);
615 if ($fieldType[
'BASE_TYPE'] ==
'file')
618 $entity = static::compileEntity($hlblock);
621 $dataClass =
$entity->getDataClass();
623 $rows = $dataClass::getList(
array(
'select' =>
array($field[
'FIELD_NAME'])));
625 while ($oldData =
$rows->fetch())
627 if (empty($oldData[$field[
'FIELD_NAME']]))
632 if(is_array($oldData[$field[
'FIELD_NAME']]))
634 foreach($oldData[$field[
'FIELD_NAME']] as $value)
636 \CFile::delete($value);
641 \CFile::delete($oldData[$field[
'FIELD_NAME']]);
648 $connection->dropColumn($hlblock[
'TABLE_NAME'], $field[
'FIELD_NAME']);
651 if ($field[
'MULTIPLE'] ==
'Y')
653 $utmTableName = static::getMultipleValueTableName($hlblock, $field);
657 return array(
'PROVIDE_STORAGE' =>
false);
663 protected static function compileUtmEntity(Entity\Base $hlentity, $userfield)
669 $hlDataClass = $hlentity->getDataClass();
670 $hlblock = $hlDataClass::getHighloadBlock();
672 $utmClassName = static::getUtmEntityClassName($hlentity, $userfield);
673 $utmTableName = static::getMultipleValueTableName($hlblock, $userfield);
675 if (class_exists($utmClassName.
'Table'))
678 Entity\Base::destroy($utmClassName.
'Table');
679 $utmEntity = Entity\Base::getInstance($utmClassName);
684 $utmEntity = Entity\Base::compileEntity($utmClassName,
array(),
array(
685 'table_name' => $utmTableName,
686 'namespace' => $hlentity->getNamespace()
693 $utmEntityFields =
array(
694 new Entity\IntegerField(
'ID'),
701 foreach ($references as $reference)
703 $utmEntityFields[] = $reference;
706 foreach ($utmEntityFields as $field)
708 $utmEntity->addField($field);
712 $referenceField =
new Entity\ReferenceField(
715 array(
'=this.ID' =>
'ref.ID')
718 $utmEntity->addField($referenceField);
721 $aliasField =
new Entity\ExpressionField(
722 $userfield[
'FIELD_NAME'].
'_SINGLE',
724 $utmEntity->getFullName().
':'.
'OBJECT.VALUE',
726 'data_type' => get_class($utmEntity->getField(
'VALUE')),
727 'required' => $userfield[
'MANDATORY'] ==
'Y'
731 $hlentity->addField($aliasField);
741 $cacheField =
new Main\ORM\Fields\ArrayField($userfield[
'FIELD_NAME'],
array(
742 'required' => $userfield[
'MANDATORY'] ==
'Y'
745 Main\UserFieldTable::setMultipleFieldSerialization($cacheField, $userfield);
747 $hlentity->addField($cacheField);
759 return $hlblock[
'TABLE_NAME'].
'_'.mb_strtolower($userfield[
'FIELD_NAME']);
765 new Entity\Validator\Unique,
766 new Entity\Validator\Length(
769 array(
'MAX' =>
GetMessage(
'HIGHLOADBLOCK_HIGHLOAD_BLOCK_ENTITY_NAME_FIELD_LENGTH_INVALID'))
771 new Entity\Validator\RegExp(
772 '/^[A-Z][A-Za-z0-9]*$/',
773 GetMessage(
'HIGHLOADBLOCK_HIGHLOAD_BLOCK_ENTITY_NAME_FIELD_REGEXP_INVALID')
775 new Entity\Validator\RegExp(
777 GetMessage(
'HIGHLOADBLOCK_HIGHLOAD_BLOCK_ENTITY_NAME_FIELD_TABLE_POSTFIX_INVALID')
785 new Entity\Validator\Unique,
786 new Entity\Validator\Length(
789 array(
'MAX' =>
GetMessage(
'HIGHLOADBLOCK_HIGHLOAD_BLOCK_ENTITY_TABLE_NAME_FIELD_LENGTH_INVALID'))
791 new Entity\Validator\RegExp(
793 GetMessage(
'HIGHLOADBLOCK_HIGHLOAD_BLOCK_ENTITY_TABLE_NAME_FIELD_REGEXP_INVALID')
795 array(__CLASS__,
'validateTableExisting')
811 $oldData = static::getByPrimary($primary)->fetch();
813 if ($value != $oldData[
'TABLE_NAME'])
820 if (!empty($checkName))
822 if (Application::getConnection()->isTableExists($checkName))
824 return GetMessage(
'HIGHLOADBLOCK_HIGHLOAD_BLOCK_ENTITY_TABLE_NAME_ALREADY_EXISTS',
825 array(
'#TABLE_NAME#' => $value)
841 parent::cleanCache();
842 \CIBlockPropertyDirectory::cleanCache();
847 return self::checkNameFieldValueToReserved(
$event);
852 return self::checkNameFieldValueToReserved(
$event);
861 if (is_string(
$name) && mb_strtolower(
$name) === self::NAME_COLLECTION)
865 'HIGHLOADBLOCK_HIGHLOAD_BLOCK_ENTITY_NAME_FIELD_VALUE_IS_COLLECTION',
static loadLanguageFile($file, $language=null, $normalize=true)
static getInstance($entityName)
static snake2camel($str, bool $lowCaseFirst=false)
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)