JezK
Edit File: AbstractTable.php
<?php namespace GeminiLabs\SiteReviews\Database\Tables; use GeminiLabs\SiteReviews\Database; use GeminiLabs\SiteReviews\Database\Query; use GeminiLabs\SiteReviews\Database\Tables; use GeminiLabs\SiteReviews\Helpers\Str; abstract class AbstractTable { public string $database; public \wpdb $db; public string $name = ''; public string $prefix; public string $tablename; public function __construct() { require_once \ABSPATH.'wp-admin/includes/upgrade.php'; // used for dbDelta() global $wpdb; $this->database = $wpdb->dbname ?: \DB_NAME; $this->db = $wpdb; $this->prefix = $wpdb->get_blog_prefix(); $this->tablename = $wpdb->get_blog_prefix().glsr()->prefix.$this->name; } public function addForeignConstraint(string $column, string $foreignTable, string $foreignColumn): bool { if (!glsr(Tables::class)->tableExists($foreignTable)) { glsr_log()->warning("The {$foreignTable} table does not exist, the [{$column}] foreign key was not added to {$this->tablename}."); return false; } if (!glsr(Tables::class)->isInnodb($foreignTable)) { return false; } $constraint = $this->foreignConstraint($column); if ($this->foreignConstraintExists($constraint, $foreignTable)) { return false; } $this->removeInvalidRows(); return (bool) glsr(Database::class)->dbQuery(glsr(Query::class)->sql(" ALTER TABLE {$this->tablename} ADD CONSTRAINT {$constraint} FOREIGN KEY ({$column}) REFERENCES {$foreignTable} ({$foreignColumn}) ON DELETE CASCADE ")); } abstract public function addForeignConstraints(): void; public function create(): bool { if ($this->exists()) { return false; } dbDelta($this->structure()); glsr(Database::class)->logErrors(); return true; } public function drop(): bool { if ($this->exists()) { $this->dropForeignConstraints(); return (bool) glsr(Database::class)->dbQuery("DROP TABLE IF EXISTS {$this->tablename}"); } return false; } public function dropForeignConstraint(string $column, string $foreignTable): bool { $constraint = $this->foreignConstraint($column); if (!$this->foreignConstraintExists($constraint, $foreignTable)) { return false; } return (bool) glsr(Database::class)->dbQuery(" ALTER TABLE {$this->tablename} DROP FOREIGN KEY {$constraint}; "); } abstract public function dropForeignConstraints(): void; public function empty(): bool { if ($this->exists()) { return (bool) glsr(Database::class)->dbQuery("TRUNCATE TABLE {$this->tablename}"); } return false; } public function exists(): bool { return glsr(Tables::class)->tableExists($this->tablename); } public function foreignConstraint(string $column): string { $constraint = Str::prefix($column, glsr()->prefix.$this->name.'_'); $constraint = Str::suffix($constraint, '_foreign'); if (is_multisite() && $this->db->blogid > 1) { return Str::suffix($constraint, "_{$this->db->blogid}"); } return $constraint; } public function foreignConstraintExists(string $constraint, string $foreignTable = ''): bool { if (!glsr(Tables::class)->tableExists($foreignTable)) { return false; } if (!glsr(Tables::class)->isInnodb($foreignTable)) { return false; } $constraints = $this->db->get_col(" SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS WHERE CONSTRAINT_SCHEMA = '{$this->database}' AND TABLE_NAME = '{$this->tablename}' "); return in_array($constraint, $constraints); } public function name(bool $prefixName = false): string { if (!$prefixName) { return $this->name; } return Str::prefix($this->name, glsr()->prefix); } abstract public function removeInvalidRows(): void; /** * WordPress codex says there must be two spaces between PRIMARY KEY and the key definition. * * @see https://codex.wordpress.org/Creating_Tables_with_Plugins */ abstract public function structure(): string; public function table(string $name = ''): string { return glsr(Tables::class)->table($name ?: $this->name); } }