'DataCore Demo S.r.l.', 996002 => 'NIS2 Sandbox Formazione S.r.l.', ]; private const USERCOLS = ['owner_user_id','responsible_user_id','assigned_to','reported_by','created_by','uploaded_by','relevance_assessed_by','assessed_by','approved_by','reviewed_by','closed_by','user_id']; /** parent → child (FK figlio) da remappare al nuovo parent */ private const PC = [ ['assessments','assessment_responses','assessment_id'], ['risks','risk_treatments','risk_id'], ['incidents','incident_timeline','incident_id'], ['training_courses','training_assignments','course_id'], ['policies','policy_versions','policy_id'], ]; private const SIMPLE = ['compliance_controls','suppliers','assets']; /** * Esegue il seed/reset. $targets: mappa orgId=>nome (default: entrambe). * @return array esito per org ("ok uid=N" | "errore: ...") */ public static function seed(?array $targets = null): array { $targets = $targets ?: self::TARGETS; $pdo = Database::getInstance(); $out = []; $pdo->exec('SET FOREIGN_KEY_CHECKS=0'); foreach ($targets as $T => $NAME) { $T = (int) $T; $pdo->beginTransaction(); try { self::purge($pdo, $T); $org = Database::fetchOne('SELECT * FROM organizations WHERE id = ?', [self::SRC_ORG]); self::copyRow($pdo, 'organizations', $org, ['id' => $T, 'name' => $NAME], 0); $uid = (int) Database::insert('users', [ 'email' => "demo-$T@nis2-demo.local", 'full_name' => "Demo NIS2 $T", 'role' => 'org_admin', 'password_hash' => password_hash(bin2hex(random_bytes(12)), PASSWORD_DEFAULT), 'is_active' => 1, 'must_change_password' => 0, 'password_version' => 1, ]); $pdo->prepare('INSERT INTO user_organizations (user_id,organization_id,role) VALUES (?,?,?)')->execute([$uid, $T, 'org_admin']); foreach (self::PC as [$par, $chi, $fk]) { if (!self::tableExists($pdo, $par)) continue; foreach (Database::fetchAll("SELECT * FROM `$par` WHERE organization_id = ? ORDER BY id", [self::SRC_ORG]) as $r) { $newPar = self::copyRow($pdo, $par, $r, ['organization_id' => $T], $uid); if (self::tableExists($pdo, $chi)) { foreach (Database::fetchAll("SELECT * FROM `$chi` WHERE `$fk` = ? ORDER BY id", [$r['id']]) as $cr) { $ov = [$fk => $newPar]; if (in_array('organization_id', self::cols($pdo, $chi), true)) $ov['organization_id'] = $T; self::copyRow($pdo, $chi, $cr, $ov, $uid); } } } } foreach (self::SIMPLE as $t) { if (!self::tableExists($pdo, $t)) continue; foreach (Database::fetchAll("SELECT * FROM `$t` WHERE organization_id = ? ORDER BY id", [self::SRC_ORG]) as $r) { self::copyRow($pdo, $t, $r, ['organization_id' => $T], $uid); } } $pdo->commit(); $out[$T] = "ok (uid=$uid)"; } catch (Throwable $ex) { $pdo->rollBack(); $out[$T] = 'errore: ' . $ex->getMessage(); } } $pdo->exec('SET FOREIGN_KEY_CHECKS=1'); return $out; } private static function purge(PDO $pdo, int $T): void { foreach (self::PC as [$par, $chi, $fk]) { if (self::tableExists($pdo, $chi)) $pdo->exec("DELETE FROM `$chi` WHERE `$fk` IN (SELECT id FROM `$par` WHERE organization_id = $T)"); } foreach (array_merge(array_column(self::PC, 0), self::SIMPLE) as $t) { if (self::tableExists($pdo, $t)) $pdo->exec("DELETE FROM `$t` WHERE organization_id = $T"); } $pdo->exec("DELETE FROM user_organizations WHERE organization_id = $T"); $pdo->exec("DELETE FROM users WHERE email = 'demo-$T@nis2-demo.local'"); $pdo->exec("DELETE FROM organizations WHERE id = $T"); } private static function cols(PDO $pdo, string $t): array { static $cache = []; if (!isset($cache[$t])) { $cache[$t] = $pdo->query("SELECT COLUMN_NAME FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='$t' ORDER BY ORDINAL_POSITION")->fetchAll(PDO::FETCH_COLUMN); } return $cache[$t]; } private static function tableExists(PDO $pdo, string $t): bool { return (int) $pdo->query("SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='$t'")->fetchColumn() > 0; } /** Copia una riga in $table applicando $overrides e rimappando le colonne utente a $uid. */ private static function copyRow(PDO $pdo, string $table, array $row, array $overrides, int $uid): int { $data = []; foreach (self::cols($pdo, $table) as $c) { if ($c === 'id') { if (array_key_exists('id', $overrides)) $data['id'] = $overrides['id']; continue; } if (array_key_exists($c, $overrides)) { $data[$c] = $overrides[$c]; continue; } $v = $row[$c] ?? null; if (in_array($c, self::USERCOLS, true) && $v !== null) $v = $uid; $data[$c] = $v; } $cl = implode(',', array_map(fn($x) => "`$x`", array_keys($data))); $ph = implode(',', array_fill(0, count($data), '?')); $pdo->prepare("INSERT INTO `$table` ($cl) VALUES ($ph)")->execute(array_values($data)); return (int) $pdo->lastInsertId(); } }