Purging a plugin looks for and removes its tables
parent
10460baad8
commit
b88b2ce8a5
|
|
@ -275,7 +275,7 @@ class PluginManager
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Purge plugin by dropping its tables and removing settings.
|
* Purge plugin by dropping its migration-defined tables and removing settings.
|
||||||
*/
|
*/
|
||||||
public static function purge(string $plugin): bool
|
public static function purge(string $plugin): bool
|
||||||
{
|
{
|
||||||
|
|
@ -290,6 +290,8 @@ class PluginManager
|
||||||
}
|
}
|
||||||
$pdo = ($db instanceof \PDO) ? $db : $db->getConnection();
|
$pdo = ($db instanceof \PDO) ? $db : $db->getConnection();
|
||||||
|
|
||||||
|
$foreignKeyChecksDisabled = false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// First disable the plugin
|
// First disable the plugin
|
||||||
self::setEnabled($plugin, false);
|
self::setEnabled($plugin, false);
|
||||||
|
|
@ -298,34 +300,55 @@ class PluginManager
|
||||||
$stmt = $pdo->prepare('DELETE FROM settings WHERE `key` LIKE :pattern');
|
$stmt = $pdo->prepare('DELETE FROM settings WHERE `key` LIKE :pattern');
|
||||||
$stmt->execute([':pattern' => 'plugin_enabled_' . $plugin]);
|
$stmt->execute([':pattern' => 'plugin_enabled_' . $plugin]);
|
||||||
|
|
||||||
// Drop plugin-specific tables (user_pro_* tables for this plugin)
|
$migrationDir = self::$catalog[$plugin]['path'] . '/migrations';
|
||||||
$stmt = $pdo->prepare('SHOW TABLES LIKE "user_pro_%"');
|
$migrationFiles = glob($migrationDir . '/*.sql') ?: [];
|
||||||
$stmt->execute();
|
$tables = [];
|
||||||
$tables = $stmt->fetchAll(\PDO::FETCH_COLUMN, 0);
|
|
||||||
|
|
||||||
// Disable foreign key checks temporarily to allow table drops
|
foreach ($migrationFiles as $migrationFile) {
|
||||||
$pdo->exec('SET FOREIGN_KEY_CHECKS=0');
|
if (!is_string($migrationFile) || !file_exists($migrationFile)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($tables as $table) {
|
$migrationContent = file_get_contents($migrationFile);
|
||||||
// Check if this table belongs to the plugin by checking its migration file
|
if (!is_string($migrationContent) || $migrationContent === '') {
|
||||||
$migrationFile = self::$catalog[$plugin]['path'] . '/migrations/create_' . $plugin . '_tables.sql';
|
continue;
|
||||||
if (file_exists($migrationFile)) {
|
}
|
||||||
$migrationContent = file_get_contents($migrationFile);
|
|
||||||
if (strpos($migrationContent, $table) !== false) {
|
// Derive table ownership from CREATE TABLE statements in plugin migrations.
|
||||||
$pdo->exec("DROP TABLE IF EXISTS `$table`");
|
preg_match_all('/CREATE\s+TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?`?([a-zA-Z0-9_]+)`?/i', $migrationContent, $matches);
|
||||||
app_log('info', 'PluginManager::purge: Dropped table ' . $table . ' for plugin ' . $plugin, ['scope' => 'plugin']);
|
$discoveredTables = $matches[1] ?? [];
|
||||||
|
foreach ($discoveredTables as $tableName) {
|
||||||
|
if (!is_string($tableName) || $tableName === '') {
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
$tables[] = $tableName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Re-enable foreign key checks
|
$tables = array_values(array_unique($tables));
|
||||||
$pdo->exec('SET FOREIGN_KEY_CHECKS=1');
|
|
||||||
|
// Disable foreign key checks temporarily to allow table drops
|
||||||
|
$pdo->exec('SET FOREIGN_KEY_CHECKS=0');
|
||||||
|
$foreignKeyChecksDisabled = true;
|
||||||
|
|
||||||
|
foreach ($tables as $table) {
|
||||||
|
$pdo->exec("DROP TABLE IF EXISTS `$table`");
|
||||||
|
app_log('info', 'PluginManager::purge: Dropped table ' . $table . ' for plugin ' . $plugin, ['scope' => 'plugin']);
|
||||||
|
}
|
||||||
|
|
||||||
app_log('info', 'PluginManager::purge: Successfully purged plugin ' . $plugin, ['scope' => 'plugin']);
|
app_log('info', 'PluginManager::purge: Successfully purged plugin ' . $plugin, ['scope' => 'plugin']);
|
||||||
return true;
|
return true;
|
||||||
} catch (Throwable $e) {
|
} catch (Throwable $e) {
|
||||||
app_log('error', 'PluginManager::purge failed for ' . $plugin . ': ' . $e->getMessage(), ['scope' => 'plugin']);
|
app_log('error', 'PluginManager::purge failed for ' . $plugin . ': ' . $e->getMessage(), ['scope' => 'plugin']);
|
||||||
return false;
|
return false;
|
||||||
|
} finally {
|
||||||
|
if ($foreignKeyChecksDisabled) {
|
||||||
|
try {
|
||||||
|
$pdo->exec('SET FOREIGN_KEY_CHECKS=1');
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
app_log('error', 'PluginManager::purge: Failed to restore FOREIGN_KEY_CHECKS for ' . $plugin . ': ' . $e->getMessage(), ['scope' => 'plugin']);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue