/** * Adds many-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 * @param string $fieldType The field type. By default the field type is manyToMany, * but you can specify another type if it is based on manyToMany. * In this case this type should be registered * in entity_extend.yml under underlying_types section */ public function addManyToManyRelation(Schema $schema, $table, $associationName, $targetTable, array $targetTitleColumnNames, array $targetDetailedColumnNames, array $targetGridColumnNames, array $options = [], $fieldType = RelationType::MANY_TO_MANY) { $this->ensureExtendFieldSet($options); $selfTableName = $this->getTableName($table); $selfTable = $this->getTable($table, $schema); $selfClassName = $this->getEntityClassByTableName($selfTableName); $selfRelationName = $this->nameGenerator->generateManyToManyRelationColumnName($selfClassName); $selfPrimaryKeyColumnName = $this->getPrimaryKeyColumnName($selfTable); $selfPrimaryKeyColumn = $selfTable->getColumn($selfPrimaryKeyColumnName); $targetTableName = $this->getTableName($targetTable); $targetTable = $this->getTable($targetTable, $schema); $targetClassName = $this->getEntityClassByTableName($targetTableName); $targetRelationName = $this->nameGenerator->generateManyToManyRelationColumnName($targetClassName); $targetPrimaryKeyColumnName = $this->getPrimaryKeyColumnName($targetTable); $targetPrimaryKeyColumn = $targetTable->getColumn($targetPrimaryKeyColumnName); $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); $this->addRelationColumn($selfTable, $selfColumnName, $targetPrimaryKeyColumn, ['notnull' => false]); $selfTable->addUniqueIndex([$selfColumnName]); $selfTable->addForeignKeyConstraint($targetTable, [$selfColumnName], [$targetPrimaryKeyColumnName], ['onDelete' => 'SET NULL']); } $relationsTableName = $this->nameGenerator->generateManyToManyJoinTableName($selfClassName, $associationName, $targetClassName); $relationsTable = $schema->createTable($relationsTableName); $this->addRelationColumn($relationsTable, $selfRelationName, $selfPrimaryKeyColumn); $relationsTable->addIndex([$selfRelationName]); $relationsTable->addForeignKeyConstraint($selfTable, [$selfRelationName], [$selfPrimaryKeyColumnName], ['onDelete' => 'CASCADE']); $this->addRelationColumn($relationsTable, $targetRelationName, $targetPrimaryKeyColumn); $relationsTable->addIndex([$targetRelationName]); $relationsTable->addForeignKeyConstraint($targetTable, [$targetRelationName], [$targetPrimaryKeyColumnName], ['onDelete' => 'CASCADE']); $relationsTable->setPrimaryKey([$selfRelationName, $targetRelationName]); $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); }