public function __construct($name, Schema $schema) { $this->_name = $name; $this->_schema = $schema; $fields = $this->_describeFields(); $array = array(); foreach ($fields as $field) { $tableColumn = new Column($field, $this); $array[] = $tableColumn; $this->_columnByNameRegistry[$tableColumn->getName()] = $tableColumn; } parent::__construct($array); }
/** * Отобразить в качестве массива * * @return array */ public function toArray() { $result = array('name' => $this->getName(), 'type' => $this->getLinkType(), 'local_table' => $this->getLocalTable()->getName(), 'local_column' => $this->getLocalColumn()->getName(), 'foreign_table' => $this->getForeignTable()->getName(), 'foreign_column' => $this->getForeignColumn()->getName(), 'rule_update' => $this->getRuleUpdate(), 'rule_delete' => $this->getRuleDelete()); if ($this->_linkTableLocalColumn && $this->_linkTableForeignColumn) { $result['link_table'] = $this->_linkTable->getName(); $result['link_table_local_column'] = $this->_linkTableLocalColumn->getName(); $result['link_table_foreign_column'] = $this->_linkTableForeignColumn->getName(); } return $result; }
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; }