diff --git a/application/Espo/Core/Utils/Database/Orm/Converter.php b/application/Espo/Core/Utils/Database/Orm/Converter.php index 6f9a63a2cb..cb8df1d4ec 100644 --- a/application/Espo/Core/Utils/Database/Orm/Converter.php +++ b/application/Espo/Core/Utils/Database/Orm/Converter.php @@ -149,6 +149,10 @@ class Converter $ormMetadata[$entityType]['skipRebuild'] = true; } + if ($entityMetadata['modifierClassName'] ?? null) { + $ormMetadata[$entityType]['modifierClassName'] = $entityMetadata['modifierClassName']; + } + /** @var array> $ormMetadata */ $ormMetadata = Util::merge( $ormMetadata, diff --git a/application/Espo/Core/Utils/Database/Schema/Builder.php b/application/Espo/Core/Utils/Database/Schema/Builder.php index 4d383955a5..bd5a483cef 100644 --- a/application/Espo/Core/Utils/Database/Schema/Builder.php +++ b/application/Espo/Core/Utils/Database/Schema/Builder.php @@ -29,6 +29,7 @@ namespace Espo\Core\Utils\Database\Schema; +use Espo\Core\InjectableFactory; use Espo\Core\Utils\Database\ConfigDataProvider; use Espo\Core\Utils\Database\MetadataProvider as MetadataProvider; use Espo\Core\Utils\File\Manager as FileManager; @@ -50,6 +51,8 @@ use Doctrine\DBAL\Schema\Schema as DbalSchema; use Doctrine\DBAL\Types\Type as DbalType; use Espo\ORM\Type\AttributeType; +use const E_USER_DEPRECATED; + /** * Schema representation builder. */ @@ -70,6 +73,7 @@ class Builder private Metadata $metadata, private FileManager $fileManager, private Log $log, + private InjectableFactory $injectableFactory, private PathProvider $pathProvider, ConfigDataProvider $configDataProvider, ColumnPreparatorFactory $columnPreparatorFactory, @@ -136,6 +140,14 @@ class Builder $entityType = $entityDefs->getName(); + $modifier = $this->getEntityDefsModifier($entityDefs); + + if ($modifier) { + $modifiedEntityDefs = $modifier->modify($entityDefs); + + $entityDefs = EntityDefs::fromRaw($modifiedEntityDefs->toAssoc(), $entityType); + } + $this->log->debug("Schema\Builder: Entity {$entityType}"); $tableName = Util::toUnderScore($entityType); @@ -196,6 +208,18 @@ class Builder $this->addIndexes($table, $entityDefs->getIndexList()); } + private function getEntityDefsModifier(EntityDefs $entityDefs): ?EntityDefsModifier + { + /** @var ?class-string $modifierClassName */ + $modifierClassName = $entityDefs->getParam('modifierClassName'); + + if (!$modifierClassName) { + return null; + } + + return $this->injectableFactory->create($modifierClassName); + } + /** * @param array $ormMeta * @param ?string[] $entityTypeList @@ -464,6 +488,13 @@ class Builder $this->loadData($this->pathProvider->getCustom() . $this->tablesPath) ); + if ($customTables !== []) { + trigger_error( + 'Definitions in Database\\Schema\\tables are deprecated and will be remove in v8.0.', + E_USER_DEPRECATED + ); + } + return $customTables; } diff --git a/application/Espo/Core/Utils/Database/Schema/tables/preferences.php b/application/Espo/Core/Utils/Database/Schema/EntityDefsModifier.php similarity index 76% rename from application/Espo/Core/Utils/Database/Schema/tables/preferences.php rename to application/Espo/Core/Utils/Database/Schema/EntityDefsModifier.php index 750a62c976..27ba9f710b 100644 --- a/application/Espo/Core/Utils/Database/Schema/tables/preferences.php +++ b/application/Espo/Core/Utils/Database/Schema/EntityDefsModifier.php @@ -27,24 +27,15 @@ * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. ************************************************************************/ -return [ - 'unset' => [ - '__APPEND__', - 'Preferences', - ], - 'unsetIgnore' => [ - '__APPEND__', - ['Preferences', 'fields', 'id'], - ['Preferences', 'fields', 'data'], - ], - 'Preferences' => [ - 'fields' => [ - 'id' => [ - 'type' => 'id', - ], - 'data' => [ - 'type' => 'text', - ] - ] - ], -]; +namespace Espo\Core\Utils\Database\Schema; + +use Espo\Core\Utils\Database\Orm\Defs\EntityDefs; +use Espo\ORM\Defs\EntityDefs as OrmEntityDefs; + +/** + * Modifies definitions before building a schema. + */ +interface EntityDefsModifier +{ + public function modify(OrmEntityDefs $entityDefs): EntityDefs; +} diff --git a/application/Espo/Core/Utils/Database/Schema/EntityDefsModifiers/JsonData.php b/application/Espo/Core/Utils/Database/Schema/EntityDefsModifiers/JsonData.php new file mode 100644 index 0000000000..e054f1a065 --- /dev/null +++ b/application/Espo/Core/Utils/Database/Schema/EntityDefsModifiers/JsonData.php @@ -0,0 +1,68 @@ +getAttribute('id'); + + $idAttribute = AttributeDefs::create('id') + ->withType(AttributeType::ID); + + $length = $sourceIdAttribute->getLength(); + $dbType = $sourceIdAttribute->getParam('dbType'); + + if ($length) { + $idAttribute = $idAttribute->withLength($length); + } + + if ($dbType) { + $idAttribute = $idAttribute->withDbType($dbType); + } + + return EntityDefs::create() + ->withAttribute($idAttribute) + ->withAttribute( + AttributeDefs::create('data') + ->withType(AttributeType::JSON_OBJECT) + ); + } +} diff --git a/application/Espo/Resources/metadata/entityDefs/Preferences.json b/application/Espo/Resources/metadata/entityDefs/Preferences.json index 983b59fa7b..b131b03511 100644 --- a/application/Espo/Resources/metadata/entityDefs/Preferences.json +++ b/application/Espo/Resources/metadata/entityDefs/Preferences.json @@ -186,5 +186,6 @@ "default": false } }, - "noDeletedAttribute": true + "noDeletedAttribute": true, + "modifierClassName": "Espo\\Core\\Utils\\Database\\Schema\\EntityDefsModifiers\\JsonData" }