getConnection(); $db->exec(" CREATE TABLE IF NOT EXISTS users ( email TEXT PRIMARY KEY, vorname TEXT NOT NULL, nachname TEXT NOT NULL, password TEXT NOT NULL ); "); unset($db); } catch (PDOException $e) { throw new RuntimeException("Benutzerdatenbank konnte nicht erstellt werden."); } } /** * Baut eine Verbindung zur SQLite-Datenbank auf. * * @return PDO Datenbankverbindung * * @throws RuntimeException wenn keine Verbindung hergestellt werden kann */ private function getConnection() { try { $dsn = 'sqlite:' . __DIR__ . '/../../db/users.db'; $db = new PDO($dsn, null, null); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); return $db; } catch (PDOException $e) { throw new RuntimeException("Verbindung zur Benutzerdatenbank fehlgeschlagen."); } } /** * Gibt die Singleton-Instanz des DatabaseUserManagers zurück. * * @return DatabaseUserManager Instanz des DatabaseUserManagers */ public static function getInstance() { if (self::$instance == null) { self::$instance = new DatabaseUserManager(); } return self::$instance; } /** * Sucht einen Benutzer anhand seiner E-Mail-Adresse. * * @param string $email E-Mail-Adresse des Benutzers * * @return array|null Benutzerdaten als Array oder null, * wenn kein Benutzer gefunden wurde * * @throws RuntimeException wenn der Benutzer nicht geladen werden kann */ public function findUser($email) { try { $db = $this->getConnection(); $sql = "SELECT * FROM users WHERE email = :email"; $command = $db->prepare($sql); $command->execute([ ":email" => $email ]); $user = $command->fetch(PDO::FETCH_ASSOC); return $user ?: null; } catch (PDOException $e) { throw new RuntimeException("Benutzer konnte nicht geladen werden."); } } /** * Fügt einen neuen Benutzer in die Datenbank ein. * * Die Speicherung erfolgt innerhalb einer Transaktion. * Doppelte E-Mail-Adressen werden durch den Primary Key verhindert. * * @param string $email E-Mail-Adresse des Benutzers * @param string $vorname Vorname des Benutzers * @param string $nachname Nachname des Benutzers * @param string $password Passwort-Hash des Benutzers * * @return void * * @throws InvalidArgumentException wenn die E-Mail-Adresse bereits verwendet wird * @throws RuntimeException wenn der Benutzer nicht gespeichert werden kann */ public function addUser($email, $vorname, $nachname, $password) { try { $db = $this->getConnection(); $db->beginTransaction(); $sql = " INSERT INTO users (email, vorname, nachname, password) VALUES (:email, :vorname, :nachname, :password) "; $command = $db->prepare($sql); $command->execute([ ":email" => $email, ":vorname" => $vorname, ":nachname" => $nachname, ":password" => $password ]); $db->commit(); } catch (PDOException $e) { if (isset($db) && $db->inTransaction()) { $db->rollBack(); } if ($e->getCode() === "23000") { throw new InvalidArgumentException("Diese E-Mail-Adresse wird bereits verwendet."); } throw new RuntimeException("Benutzer konnte nicht gespeichert werden."); } } /** * Aktualisiert die Daten eines bestehenden Benutzers. * * Optional kann zusätzlich das Passwort geändert werden. * Wenn kein neues Passwort übergeben wird, bleibt das alte Passwort erhalten. * * @param string $oldEmail Aktuelle E-Mail-Adresse des Benutzers * @param string $newEmail Neue E-Mail-Adresse des Benutzers * @param string $vorname Neuer Vorname des Benutzers * @param string $nachname Neuer Nachname des Benutzers * @param string|null $password Neues Passwort oder null * * @return bool true, wenn der Benutzer aktualisiert wurde, * sonst false * * @throws InvalidArgumentException wenn die neue E-Mail-Adresse bereits verwendet wird * @throws RuntimeException wenn der Benutzer nicht aktualisiert werden kann */ public function updateUser($oldEmail, $newEmail, $vorname, $nachname, $password = null) { try { $db = $this->getConnection(); if (!empty($password)) { $sql = " UPDATE users SET email = :newEmail, vorname = :vorname, nachname = :nachname, password = :password WHERE email = :oldEmail "; $params = [ ":newEmail" => $newEmail, ":vorname" => $vorname, ":nachname" => $nachname, ":password" => password_hash($password, PASSWORD_DEFAULT), ":oldEmail" => $oldEmail ]; } else { $sql = " UPDATE users SET email = :newEmail, vorname = :vorname, nachname = :nachname WHERE email = :oldEmail "; $params = [ ":newEmail" => $newEmail, ":vorname" => $vorname, ":nachname" => $nachname, ":oldEmail" => $oldEmail ]; } $command = $db->prepare($sql); $command->execute($params); return $command->rowCount() > 0; } catch (PDOException $e) { if ($e->getCode() === "23000") { throw new InvalidArgumentException("Diese E-Mail-Adresse wird bereits verwendet."); } throw new RuntimeException("Benutzer konnte nicht aktualisiert werden."); } } /** * Löscht einen Benutzer anhand seiner E-Mail-Adresse. * * @param string $email E-Mail-Adresse des zu löschenden Benutzers * * @return bool true, wenn der Benutzer gelöscht wurde, * sonst false * * @throws RuntimeException wenn der Benutzer nicht gelöscht werden kann */ public function deleteUser($email) { try { $db = $this->getConnection(); $sql = "DELETE FROM users WHERE email = :email"; $command = $db->prepare($sql); $command->execute([ ":email" => $email ]); return $command->rowCount() > 0; } catch (PDOException $e) { throw new RuntimeException("Benutzer konnte nicht gelöscht werden."); } } }