/** * Adds one-to-many relation * * @param Schema $schema * @param Table|string $table A Table object or table name * @param string $associationName A relation name * @param Table|string $targetTable A Table object or table name * @param string[] $targetTitleColumnNames Column names are used to show a title of related entity * @param string[] $targetDetailedColumnNames Column names are used to show detailed info about related entity * @param string[] $targetGridColumnNames Column names are used to show related entity in a grid * @param array $options Entity config values * format is [CONFIG_SCOPE => [CONFIG_KEY => CONFIG_VALUE]] * @param string $fieldType The field type. By default the field type is oneToMany, * but you can specify another type if it is based on oneToMany. * In this case this type should be registered * in entity_extend.yml under underlying_types section */ public function addOneToManyRelation(Schema $schema, $table, $associationName, $targetTable, array $targetTitleColumnNames, array $targetDetailedColumnNames, array $targetGridColumnNames, array $options = [], $fieldType = RelationType::ONE_TO_MANY) { $this->ensureExtendFieldSet($options); $selfTableName = $this->getTableName($table); $selfTable = $this->getTable($table, $schema); $selfClassName = $this->getEntityClassByTableName($selfTableName); $selfPrimaryKeyColumnName = $this->getPrimaryKeyColumnName($selfTable); $selfPrimaryKeyColumn = $selfTable->getColumn($selfPrimaryKeyColumnName); $targetTableName = $this->getTableName($targetTable); $targetTable = $this->getTable($targetTable, $schema); $targetColumnName = $this->nameGenerator->generateOneToManyRelationColumnName($selfClassName, $associationName); $targetPrimaryKeyColumnName = $this->getPrimaryKeyColumnName($targetTable); $this->checkColumnsExist($targetTable, $targetTitleColumnNames); $this->checkColumnsExist($targetTable, $targetDetailedColumnNames); $this->checkColumnsExist($targetTable, $targetGridColumnNames); if (!isset($options['extend']['without_default']) || !$options['extend']['without_default']) { $selfColumnName = $this->nameGenerator->generateRelationDefaultColumnName($associationName); $targetPrimaryKeyColumn = $targetTable->getColumn($targetPrimaryKeyColumnName); $this->addRelationColumn($selfTable, $selfColumnName, $targetPrimaryKeyColumn, ['notnull' => false]); $selfTable->addUniqueIndex([$selfColumnName]); $selfTable->addForeignKeyConstraint($targetTable, [$selfColumnName], [$targetPrimaryKeyColumnName], ['onDelete' => 'SET NULL']); } $this->addRelationColumn($targetTable, $targetColumnName, $selfPrimaryKeyColumn, ['notnull' => false]); $targetTable->addIndex([$targetColumnName]); $targetTable->addForeignKeyConstraint($selfTable, [$targetColumnName], [$selfPrimaryKeyColumnName], ['onDelete' => 'SET NULL']); $options[ExtendOptionsManager::TARGET_OPTION] = ['table_name' => $targetTableName, 'columns' => ['title' => $targetTitleColumnNames, 'detailed' => $targetDetailedColumnNames, 'grid' => $targetGridColumnNames]]; $options[ExtendOptionsManager::TYPE_OPTION] = $fieldType; $this->extendOptionsManager->setColumnOptions($selfTableName, $associationName, $options); }
/** * Adds the inverse side of a one-to-many relation * * @param Schema $schema * @param Table|string $table A Table object or table name * @param string $associationName The name of a relation field * @param Table|string $targetTable A Table object or table name * @param string $targetAssociationName The name of a relation field on the inverse side * @param string $targetColumnName A column name is used to show related entity * @param array $options Entity config values * format is [CONFIG_SCOPE => [CONFIG_KEY => CONFIG_VALUE]] */ public function addOneToManyInverseRelation(Schema $schema, $table, $associationName, $targetTable, $targetAssociationName, $targetColumnName, array $options = []) { $this->ensureExtendFieldSet($options); $selfTableName = $this->getTableName($table); $selfClassName = $this->getEntityClassByTableName($selfTableName); $targetTableName = $this->getTableName($targetTable); $targetTable = $this->getTable($targetTable, $schema); $targetClassName = $this->getEntityClassByTableName($targetTableName); $existingTargetColumnName = $this->nameGenerator->generateOneToManyRelationColumnName($selfClassName, $associationName); $this->checkColumnsExist($targetTable, [$targetColumnName]); $this->checkColumnsExist($targetTable, [$existingTargetColumnName]); $relationKey = ExtendHelper::buildRelationKey($selfClassName, $associationName, RelationType::ONE_TO_MANY, $targetClassName); $targetFieldId = new FieldConfigId('extend', $targetClassName, $targetAssociationName, RelationType::MANY_TO_ONE); $selfTableOptions['extend']['relation.' . $relationKey . '.target_field_id'] = $targetFieldId; $this->extendOptionsManager->setTableOptions($selfTableName, $selfTableOptions); $targetTableOptions['extend']['relation.' . $relationKey . '.field_id'] = $targetFieldId; $this->extendOptionsManager->setTableOptions($targetTableName, $targetTableOptions); $options[ExtendOptionsManager::TARGET_OPTION] = ['table_name' => $selfTableName, 'relation_key' => $relationKey, 'column' => $targetColumnName]; $options[ExtendOptionsManager::TYPE_OPTION] = RelationType::MANY_TO_ONE; $options['extend']['column_name'] = $existingTargetColumnName; $this->extendOptionsManager->setColumnOptions($targetTableName, $targetAssociationName, $options); }
protected function renameOneToManyExtendField(Schema $schema, QueryBag $queries, Table $table, $associationName, $targetEntityClassName, EntityMetadataHelper $entityMetadataHelper) { $entityClassName = $entityMetadataHelper->getEntityClassByTableName($table->getName()); $targetTableName = $entityMetadataHelper->getTableNameByEntityClass($targetEntityClassName); if ($schema->hasTable($targetTableName)) { $targetTable = $schema->getTable($targetTableName); $oldTargetColumnName = sprintf('field_%s_%s_id', strtolower(ExtendHelper::getShortClassName($entityClassName)), $associationName); if ($targetTable->hasColumn($oldTargetColumnName)) { $newTargetColumnName = $this->nameGenerator->generateOneToManyRelationColumnName($entityClassName, $associationName); $oldIndexName = $this->nameGenerator->generateIndexName($targetTableName, [$oldTargetColumnName], false, true); if ($targetTable->hasIndex($oldIndexName)) { $targetTable->dropIndex($oldIndexName); } $oldForeignKeyName = $this->nameGenerator->generateForeignKeyConstraintName($targetTableName, [$oldTargetColumnName], true); if ($targetTable->hasForeignKey($oldForeignKeyName)) { $targetTable->removeForeignKey($oldForeignKeyName); } $this->renameExtension->renameColumn($schema, $queries, $targetTable, $oldTargetColumnName, $newTargetColumnName); $this->renameExtension->addIndex($schema, $queries, $targetTable->getName(), [$newTargetColumnName]); $this->renameExtension->addForeignKeyConstraint($schema, $queries, $targetTable->getName(), $table->getName(), [$newTargetColumnName], $table->getPrimaryKeyColumns(), ['onDelete' => 'SET NULL']); } } }