*/ protected array $validActions = [ self::CASCADE, self::RESTRICT, self::SET_NULL, self::NO_ACTION, self::SET_DEFAULT, ]; /** * The action to take when the referenced row is deleted. */ protected ?string $delete = null; /** * The action to take when the referenced row is updated. */ protected ?string $update = null; /** * @var string|null */ protected ?string $deferrable = null; /** * Constructor * * @param string $name The name of the index. * @param array $columns The columns to index. * @param ?string $referencedTable The columns to index. * @param array $referencedColumns The columns in $referencedTable that this key references. * @param ?string $delete The action to take when the referenced row is deleted. * @param ?string $update The action to take when the referenced row is updated. */ public function __construct( protected string $name, protected array $columns, protected ?string $referencedTable = null, protected array $referencedColumns = [], ?string $delete = null, ?string $update = null, ?string $deferrable = null, ) { $this->type = self::FOREIGN; $this->delete = $this->normalizeAction($delete ?? self::NO_ACTION); $this->update = $this->normalizeAction($update ?? self::NO_ACTION); if ($deferrable) { $this->deferrable = $this->normalizeDeferrable($deferrable); } } /** * Sets the foreign key referenced table. * * @param string $table The table this KEY is pointing to * @return $this */ public function setReferencedTable(string $table) { $this->referencedTable = $table; return $this; } /** * Gets the foreign key referenced table. * * @return ?string */ public function getReferencedTable(): ?string { return $this->referencedTable; } /** * Sets the foreign key referenced columns. * * @param array|string $referencedColumns Referenced columns * @return $this */ public function setReferencedColumns(array|string $referencedColumns) { $referencedColumns = is_string($referencedColumns) ? [$referencedColumns] : $referencedColumns; $this->referencedColumns = $referencedColumns; return $this; } /** * Gets the foreign key referenced columns. * * @return array */ public function getReferencedColumns(): array { return $this->referencedColumns; } /** * Converts the foreign key to an array that is compatible * with the constructor. * * @return array */ public function toArray(): array { return [ 'name' => $this->name, 'type' => $this->type, 'columns' => $this->columns, 'referencedTable' => $this->referencedTable, 'referencedColumns' => $this->referencedColumns, 'delete' => $this->delete, 'update' => $this->update, 'deferrable' => $this->deferrable, ]; } /** * Sets ON DELETE action for the foreign key. * * @param string $delete On Delete * @return $this */ public function setDelete(string $delete) { $this->delete = $this->normalizeAction($delete); return $this; } /** * Gets ON DELETE action for the foreign key. * * @return string|null */ public function getDelete(): ?string { return $this->delete; } /** * Gets ON UPDATE action for the foreign key. * * @return string|null */ public function getUpdate(): ?string { return $this->update; } /** * Sets ON UPDATE action for the foreign key. * * @param string $update On Update * @return $this */ public function setUpdate(string $update) { $this->update = $this->normalizeAction($update); return $this; } /** * From passed value checks if it's correct and fixes if needed * * @param string $action Action * @throws \InvalidArgumentException * @return string */ protected function normalizeAction(string $action): string { if (in_array($action, $this->validActions, true)) { return $action; } throw new InvalidArgumentException('Unknown action passed: ' . $action); } /** * Sets deferrable mode for the foreign key. * * @param string $deferrable Constraint * @return $this */ public function setDeferrable(string $deferrable) { $this->deferrable = $this->normalizeDeferrable($deferrable); return $this; } /** * Gets deferrable mode for the foreign key. */ public function getDeferrable(): ?string { return $this->deferrable; } /** * From passed value checks if it's correct and fixes if needed * * @param string $deferrable Deferrable * @throws \InvalidArgumentException * @return string */ protected function normalizeDeferrable(string $deferrable): string { $mapping = [ 'DEFERRED' => ForeignKey::DEFERRED, 'IMMEDIATE' => ForeignKey::IMMEDIATE, 'NOT DEFERRED' => ForeignKey::NOT_DEFERRED, ForeignKey::DEFERRED => ForeignKey::DEFERRED, ForeignKey::IMMEDIATE => ForeignKey::IMMEDIATE, ForeignKey::NOT_DEFERRED => ForeignKey::NOT_DEFERRED, ]; $normalized = strtoupper(str_replace('_', ' ', $deferrable)); if (array_key_exists($normalized, $mapping)) { return $mapping[$normalized]; } throw new InvalidArgumentException('Unknown deferrable passed: ' . $deferrable); } }