public function __construct($name, Column $localColumn, Column $foreignColumn, $ruleDelete = AbstractLink::RULE_NO_ACTION, $ruleUpdate = AbstractLink::RULE_CASCADE, Column $linkTableLocalColumn = null, Column $linkTableForeignColumn = null) { $this->_name = (string) $name; $this->_ruleUpdate = $ruleUpdate; $this->_ruleDelete = $ruleDelete; $this->_localColumn = $localColumn; $this->_foreignColumn = $foreignColumn; $this->_localTable = $localColumn->getTable(); $this->_foreignTable = $foreignColumn->getTable(); if ($linkTableLocalColumn && $linkTableForeignColumn) { $this->_linkTableLocalColumn = $linkTableLocalColumn; $this->_linkTableForeignColumn = $linkTableForeignColumn; $this->_linkTable = $linkTableLocalColumn->getTable(); } $this->setupLinkType(); }
protected function getLinkByColumns(Column $localColumn, Column $foreignColumn, $ruleUpdate = null, $ruleDelete = null) { $localTable = $localColumn->getTable(); $foreignTable = $foreignColumn->getTable(); $link = null; // Если локальный связь прямая и локальный с внешним полем уникальты - то OneToOne if ($localColumn->isUnique() && $foreignColumn->isUnique() && !$foreignTable->isLinkTable() && !$localTable->isLinkTable()) { if ($localColumn->getName() == 'id') { $name = $foreignColumn->getEntityNameAsCamelCase() . '___' . $foreignTable->getNameAsCamelCase(); } else { $name = $localColumn->getEntityNameAsCamelCase() . '___' . $localTable->getNameAsCamelCase(); } $link = new OneToOne('OneToOne___' . $name, $localColumn, $foreignColumn, $ruleDelete, $ruleUpdate); } elseif ($localColumn->isUnique() && !$foreignColumn->isUnique() && !$foreignTable->isLinkTable() && !$localTable->isLinkTable()) { // OneToMany Direct $link = new OneToMany('OneToMany___' . $foreignColumn->getEntityNameAsCamelCase() . '___' . $foreignTable->getNameAsCamelCase(), $localColumn, $foreignColumn, $ruleDelete, $ruleUpdate); } elseif (!$localColumn->isUnique() && $foreignColumn->isUnique() && !$foreignTable->isLinkTable() && !$localTable->isLinkTable()) { // ManyToOne Direct $link = new ManyToOne('ManyToOne___' . $localTable->getNameAsCamelCase() . '___' . $localColumn->getEntityNameAsCamelCase(), $localColumn, $foreignColumn, $ruleDelete, $ruleUpdate); } elseif ($localTable->isLinkTable() || $foreignTable->isLinkTable()) { $linkTable = $localTable->isLinkTable() ? $localTable : $foreignTable; if ($localTable->isLinkTable()) { $localTable = $foreignTable; $localColumn = $foreignColumn; } /** * Тут мы выясняем сколько внешних ключей у таблицы связки * Если их больше двух или меньше двух, то значит это хреновая связь * * Потом мы выясняем внешнюю таблицку и создаем связь */ $linkTableForeignKeys = $this->getForeignKeyArray($linkTable); $linkTableColumnList = $linkTable->getColumn(); $linkTableLocalColumn = null; $linkTableForeignColumn = null; $foreignColumn = null; foreach ($linkTableColumnList as $linkTableColumn) { // НЕ ID поле if (substr($linkTableColumn->getName(), -3) != '_id') { continue; } $tableName = substr($linkTableColumn->getName(), 0, -3); $matchedTable = $this->getTable($tableName); if ($matchedTable) { if ($matchedTable->getName() == $localTable->getName()) { $linkTableLocalColumn = $linkTableColumn; } else { $foreignColumn = $matchedTable->getColumn('id'); $linkTableForeignColumn = $linkTableColumn; } } } if (!empty($linkTableForeignKeys)) { foreach ($linkTableForeignKeys as $linkTableForeignKey) { if ($linkTableForeignKey['table_name'] == $localTable->getName() || $linkTableForeignKey['referenced_table_name'] == $localTable->getName()) { $linkTableLocalColumnName = $linkTableForeignKey['table_name'] == $localTable->getName() ? $linkTableForeignKey['referenced_column_name'] : $linkTableForeignKey['column_name']; $linkTableLocalColumn = $this->getTable($linkTable->getName())->getColumn($linkTableLocalColumnName); continue; } else { // Пытаемся найти внешнее поле foreignColumn if ($linkTableForeignKey['table_name'] == $linkTable->getName()) { $foreignTableName = $linkTableForeignKey['referenced_table_name']; $foreignColumnName = $linkTableForeignKey['referenced_column_name']; $linkTableForeignColumnName = $linkTableForeignKey['column_name']; } else { $foreignTableName = $linkTableForeignKey['table_name']; $foreignColumnName = $linkTableForeignKey['column_name']; $linkTableForeignColumnName = $linkTableForeignKey['referenced_column_name']; } $linkTableForeignColumn = $this->getTable($linkTable->getName())->getColumn($linkTableForeignColumnName); $foreignColumn = $this->getTable($foreignTableName)->getColumn($foreignColumnName); } } } if ($foreignColumn && $linkTableLocalColumn && $linkTableForeignColumn) { $linkTableLocalColumnNameAsCamelCase = implode(array_map('ucfirst', explode('_', preg_replace('#_id$#', '', $linkTableLocalColumn->getName())))); $linkTableForeignColumnNameAsCamelCase = implode(array_map('ucfirst', explode('_', preg_replace('#_id$#', '', $linkTableForeignColumn->getName())))); $link = new ManyToMany('ManyToMany___' . $linkTableLocalColumnNameAsCamelCase . '___' . $linkTableForeignColumnNameAsCamelCase, $localColumn, $foreignColumn, $ruleDelete, $ruleUpdate, $linkTableLocalColumn, $linkTableForeignColumn); } } return $link; }