Builds the DDL SQL to add a foreign key.

@param  ForeignKey $fk
@return string
359895
public function getAddForeignKeyDDL(ForeignKey $fk)
    {
        if ($fk->isSkipSql() || $fk->isPolymorphic()) {
            return;
        }
        $pattern = "
ALTER TABLE %s ADD %s;
";

        return sprintf($pattern,
            $this->quoteIdentifier($fk->getTable()->getName()),
            $this->getForeignKeyDDL($fk)
        );
    }
862498
protected function addJoinRefFk(&$script, ForeignKey $fk)
    {
        $queryClass = $this->getQueryClassName();
        $fkTable = $this->getTable()->getDatabase()->getTable($fk->getTableName());
        $relationName = $this->getRefFKPhpNameAffix($fk);
        $joinType = $this->getJoinType($fk);
        $this->addJoinRelated($script, $fkTable, $queryClass, $relationName, $joinType);
    }
1270684
protected function addForeignKeys(Table $table)
    {
        $database = $table->getDatabase();

        $dataFetcher = $this->dbh->query(sprintf('SHOW CREATE TABLE %s', $this->getPlatform()->doQuoting($table->getName())));
        $row = $dataFetcher->fetch();

        $foreignKeys = []; // local store to avoid duplicates

        // Get the information on all the foreign keys
        $pattern = '/CONSTRAINT `([^`]+)` FOREIGN KEY \((.+)\) REFERENCES `([^\s]+)` \((.+)\)(.*)/';
        if (preg_match_all($pattern, $row[1], $matches)) {
            $tmpArray = array_keys($matches[0]);
            foreach ($tmpArray as $curKey) {
                $name    = $matches[1][$curKey];
                $rawlcol = $matches[2][$curKey];
                $ftbl    = str_replace('`', '', $matches[3][$curKey]);
                $rawfcol = $matches[4][$curKey];
                $fkey    = $matches[5][$curKey];

                $lcols = [];
                foreach (preg_split('/`, `/', $rawlcol) as $piece) {
                    $lcols[] = trim($piece, '` ');
                }

                $fcols = [];
                foreach (preg_split('/`, `/', $rawfcol) as $piece) {
                    $fcols[] = trim($piece, '` ');
                }

                // typical for mysql is RESTRICT
                $fkactions = [
                    'ON DELETE' => ForeignKey::RESTRICT,
                    'ON UPDATE' => ForeignKey::RESTRICT,
                ];

                if ($fkey) {
                    // split foreign key information -> search for ON DELETE and afterwords for ON UPDATE action
                    foreach (array_keys($fkactions) as $fkaction) {
                        $result = null;
                        preg_match('/' . $fkaction . ' (' . ForeignKey::CASCADE . '|' . ForeignKey::SETNULL . ')/', $fkey, $result);
                        if ($result && is_array($result) && isset($result[1])) {
                            $fkactions[$fkaction] = $result[1];
                        }
                    }
                }

                // restrict is the default
                foreach ($fkactions as $key => $action) {
                    if (ForeignKey::RESTRICT === $action) {
                        $fkactions[$key] = null;
                    }
                }

                $localColumns = [];
                $foreignColumns = [];
                if ($table->guessSchemaName() != $database->getSchema() && false == strpos($ftbl, $database->getPlatform()->getSchemaDelimiter())) {
                    $ftbl = $table->guessSchemaName() . $database->getPlatform()->getSchemaDelimiter() . $ftbl;
                }

                $foreignTable = $database->getTable($ftbl, true);

                if (!$foreignTable) {
                    continue;
                }

                foreach ($fcols as $fcol) {
                    $foreignColumns[] = $foreignTable->getColumn($fcol);
                }
                foreach ($lcols as $lcol) {
                    $localColumns[] = $table->getColumn($lcol);
                }

                if (!isset($foreignKeys[$name])) {
                    $fk = new ForeignKey($name);
                    $fk->setForeignTableCommonName($foreignTable->getCommonName());
                    if ($table->guessSchemaName() != $foreignTable->guessSchemaName()) {
                        $fk->setForeignSchemaName($foreignTable->guessSchemaName());
                    }
                    $fk->setOnDelete($fkactions['ON DELETE']);
                    $fk->setOnUpdate($fkactions['ON UPDATE']);
                    $table->addForeignKey($fk);
                    $foreignKeys[$name] = $fk;
                }

                $max = count($localColumns);
                for ($i = 0; $i < $max; $i++) {
                    $foreignKeys[$name]->addReference($localColumns[$i], $foreignColumns[$i]);
                }
            }
        }
    }
1215004
protected function getForeignKey($foreign)
    {
        $on = $this->wrapTable($foreign->on);

        // We need to columnize the columns that the foreign key is being defined for
        // so that it is a properly formatted list. Once we have done this, we can
        // return the foreign key SQL declaration to the calling method for use.
        $columns = $this->columnize($foreign->columns);

        $onColumns = $this->columnize((array) $foreign->references);

        return ", foreign key($columns) references $on($onColumns)";
    }
1134501
public function getForeignKey()
    {
        if (is_null($this->foreignKey)) {
            $name = $this->getParentEntityDescriptor()->getTableName();
            $this->foreignKey = "{$this->normalizeFieldName($name)}_id";
        }
        return $this->foreignKey;
    }
505747
public function getForeignKey()
    {
        if (is_null($this->foreignKey)) {
            $name = $this->getEntityDescriptor()->getTableName();
            $this->foreignKey = "{$this->normalizeFieldName($name)}_id";
        }
        return $this->foreignKey;
    }
1288878
protected function getItem($foreignKey)
    {
        $value = $foreignKey['field'];
        if (! empty($foreignKey['name'])) {
            $value .= "', '". $foreignKey['name'];
        }
        $output = sprintf(
            "\$table->foreign('%s')->references('%s')->on('%s')",
            $value,
            $foreignKey['references'],
            $foreignKey['on']
        );
        if ($foreignKey['onUpdate']) {
            $output .= sprintf("->onUpdate('%s')", $foreignKey['onUpdate']);
        }
        if ($foreignKey['onDelete']) {
            $output .= sprintf("->onDelete('%s')", $foreignKey['onDelete']);
        }
        if (isset($foreignKey['decorators'])) {
            $output .= $this->addDecorators($foreignKey['decorators']);
        }
        return $output . ';';
    }
1226458
public function getForeignKeyBaseDeclarationSQL(ForeignKeyConstraint $foreignKey)
    {
        $sql = '';
        if (strlen($foreignKey->getName())) {
            $sql .= 'CONSTRAINT ' . $foreignKey->getQuotedName($this) . ' ';
        }
        $sql .= 'FOREIGN KEY (';

        if (count($foreignKey->getLocalColumns()) === 0) {
            throw new InvalidArgumentException("Incomplete definition. 'local' required.");
        }
        if (count($foreignKey->getForeignColumns()) === 0) {
            throw new InvalidArgumentException("Incomplete definition. 'foreign' required.");
        }
        if (strlen($foreignKey->getForeignTableName()) === 0) {
            throw new InvalidArgumentException("Incomplete definition. 'foreignTable' required.");
        }

        return $sql . implode(', ', $foreignKey->getQuotedLocalColumns($this))
            . ') REFERENCES '
            . $foreignKey->getQuotedForeignTableName($this) . ' ('
            . implode(', ', $foreignKey->getQuotedForeignColumns($this)) . ')';
    }
1313981
protected function injectManyToMany(ForeignKey $fk1, ForeignKey $fk2)
    {
        $fk1->getReferencedTable()->setManyToManyRelation(array('reference' => $fk1, 'refTable' => $fk2->getReferencedTable()));

        return $this;
    }
312848
protected function getForeignKeySQLDeclaration(ForeignKey $foreignKey)
    {
        if (!$this->supportForeignKeys()) {
            throw PlatformException::methodNotSupported(__METHOD__);
        }

        return 'CONSTRAINT '.$foreignKey->getName().
               ' FOREIGN KEY'.
               ' ('.implode(', ', $foreignKey->getLocalColumnNames()).')'.
               ' REFERENCES '.$foreignKey->getForeignTableName().
               ' ('.implode(', ', $foreignKey->getForeignColumnNames()).')'.
               ' ON DELETE '.$foreignKey->getOnDelete().
               ' ON UPDATE '.$foreignKey->getOnUpdate();
    }
298424
public function belongsTo(string $related, ?string $foreign_key = null, ?string $local_key = null)
    {
        $relatedModel = app()->make($related);
        $local_key = $local_key ?? $this->getKey();
        // Make the table name singular and append ID to it
        // FIXME: Use a more reliable approach
        $foreign_key = $foreign_key ?? rtrim($relatedModel->getTable(), 's').'_id';
        return new BelongsTo($relatedModel, $this, $foreign_key, $local_key);
    }
869766
public function add($fk, $column = null, $keyName = null, $onDelete = null, $onUpdate = null)
    {
        $baseFk = $this->baseFk($fk);

        $column = $column ?: $baseFk->defaultColumn();

        static::$foreignKeys[] = [
            'column'          => $column ?: $this->column,
            'key_name'        => $keyName ?: $this->keyName,
            'table'           => $this->table->getTable(),
            'reference_table' => $baseFk->referenceTable(),
            'primary_key'     => $baseFk->primaryKey,
            'on_delete'       => $onDelete ?: $this->onDelete ?: $baseFk->onDelete,
            'on_update'       => $onUpdate ?: $this->onUpdate ?: $baseFk->onUpdate,
        ];

        return $baseFk->createFkColumn($column);
    }
864367
public function foreignKeySuffix($foreignKeySuffix = null)
    {
        if ($foreignKeySuffix === null)
        {
            return $this->_foreignKeySuffix;
        }
        $this->_foreignKeySuffix = $foreignKeySuffix;

        return $this;
    }
743349
public function getForeignKey(): ForeignKey
    {
        if ($this->foreignKey === null) {
            $pk = $this->getPrimaryKey();
            $prefix = $this->getEntityName();
            $this->foreignKey = new class($pk, $prefix) extends ForeignKey
            {
                /**
                 *  constructor.
                 * @param PrimaryKey $primaryKey
                 * @param string $prefix
                 */
                public function __construct(PrimaryKey $primaryKey, string $prefix)
                {
                    $columns = [];
                    foreach ($primaryKey->columns() as $column) {
                        $columns[$column] = $prefix . '_' . $column;
                    }
                    parent::__construct($columns);
                }
            };
        }

        return $this->foreignKey;
    }
421676
protected function checkForeignKeyOwnerTableName($foreign, $tablename)
    {
        return $this->checkReferenceTableName($foreign ? $foreign->getReferencedTable() : null, $tablename);
    }
688358
public function acceptForeignKey(Table $localTable, ForeignKeyConstraint $fkConstraint)
    {
        $this->output->createForeignKey($fkConstraint, $localTable);
    }
182674
protected function getForeignKey()
	{
		if($this->foreignKey === null)
		{
			$this->foreignKey = $this->parent->getForeignKey();
		}

		return $this->foreignKey;
	}