From eb56b8d6a0710291cf55a8b031916ee2a0acb67d Mon Sep 17 00:00:00 2001
From: Caroline Schulte
Date: Mon, 15 Jun 2026 21:45:17 +0200
Subject: [PATCH 01/20] Implementierung
---
.idea/dataSources.local.xml | 2 +-
content/showArticle.php | 83 +++++++++++--
php/model/Comment.php | 92 ++++++++++++++
php/model/CommentManager.php | 25 ++++
php/model/CommentManagerDAO.php | 40 +++++++
php/model/DatabaseCommentManager.php | 173 +++++++++++++++++++++++++++
6 files changed, 401 insertions(+), 14 deletions(-)
create mode 100644 php/model/Comment.php
create mode 100644 php/model/CommentManager.php
create mode 100644 php/model/CommentManagerDAO.php
create mode 100644 php/model/DatabaseCommentManager.php
diff --git a/.idea/dataSources.local.xml b/.idea/dataSources.local.xml
index cdc31de..707e2b3 100644
--- a/.idea/dataSources.local.xml
+++ b/.idea/dataSources.local.xml
@@ -1,6 +1,6 @@
-
+
"
diff --git a/content/showArticle.php b/content/showArticle.php
index 4457dcc..fff5b00 100644
--- a/content/showArticle.php
+++ b/content/showArticle.php
@@ -1,18 +1,31 @@
getCommentsByArticle($_GET["id"]);
+ } catch (Exception $e) {
+ $_SESSION["message"] = "internal_error";
+ }
+}
?>
+
-
Es ist ein interner Fehler aufgetreten. Bitte versuche es erneut.
+
Es ist ein Fehler aufgetreten. Die ID konnte nicht ausgelesen werden. Bitte versuche es erneut.
@@ -24,54 +37,59 @@ include_once 'php/controller/showArticle-controller.php';
Jeder Beitrag muss einen Titel, Kategorie und Inhalt besitzen.
+
Dein Beitrag wurde erfolgreich bearbeitet!
-
-
+
+
-
-
Tags:
+
-
+
+
+
-
+
+ Kommentare
+
+
+
+
+
+ Du musst angemeldet sein, um einen Kommentar zu schreiben.
+
+
+
+
\ No newline at end of file
diff --git a/php/model/Comment.php b/php/model/Comment.php
new file mode 100644
index 0000000..42405a1
--- /dev/null
+++ b/php/model/Comment.php
@@ -0,0 +1,92 @@
+id = $id;
+ $this->articleId = $articleId;
+ $this->author = $author;
+ $this->content = $content;
+ $this->created = $created;
+ }
+
+ /**
+ * Gibt die ID des Kommentars zurück.
+ *
+ * @return int Kommentar-ID
+ */
+ public function getId(): int
+ {
+ return $this->id;
+ }
+
+ /**
+ * Gibt die ID des zugehörigen Beitrags zurück.
+ *
+ * @return int Beitrags-ID
+ */
+ public function getArticleId(): int
+ {
+ return $this->articleId;
+ }
+
+ /**
+ * Gibt den Autor des Kommentars zurück.
+ *
+ * @return string Autor
+ */
+ public function getAuthor(): string
+ {
+ return $this->author;
+ }
+
+ /**
+ * Gibt den Inhalt des Kommentars zurück.
+ *
+ * @return string Kommentarinhalt
+ */
+ public function getContent(): string
+ {
+ return $this->content;
+ }
+
+ /**
+ * Gibt das Erstellungsdatum des Kommentars zurück.
+ *
+ * @return string Erstellungsdatum
+ */
+ public function getCreated(): string
+ {
+ return $this->created;
+ }
+}
diff --git a/php/model/CommentManager.php b/php/model/CommentManager.php
new file mode 100644
index 0000000..6ca6cb4
--- /dev/null
+++ b/php/model/CommentManager.php
@@ -0,0 +1,25 @@
+getConnection();
+
+ $db->exec("
+ CREATE TABLE IF NOT EXISTS comments (
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ article_id INTEGER NOT NULL,
+ author TEXT NOT NULL,
+ content TEXT NOT NULL,
+ created TIMESTAMP DEFAULT CURRENT_TIMESTAMP
+ );
+ ");
+
+ unset($db);
+
+ } catch (PDOException $e) {
+ throw new RuntimeException(
+ "Kommentardatenbank konnte nicht erstellt werden."
+ );
+ }
+ }
+
+ /**
+ * Baut die Verbindung zur SQLite-Datenbank auf.
+ *
+ * @return PDO Datenbankverbindung
+ */
+ private function getConnection()
+ {
+ try {
+ $dsn = 'sqlite:' . __DIR__ . '/../../db/comments.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 Kommentardatenbank fehlgeschlagen."
+ );
+ }
+ }
+
+ /**
+ * Gibt die Singleton-Instanz zurück.
+ *
+ * @return DatabaseCommentManager
+ */
+ public static function getInstance()
+ {
+ if (self::$instance === null) {
+ self::$instance = new DatabaseCommentManager();
+ }
+
+ return self::$instance;
+ }
+
+ /**
+ * Speichert einen neuen Kommentar
+ * zu einem Beitrag.
+ *
+ * @param int $articleId ID des Beitrags
+ * @param string $author Autor des Kommentars
+ * @param string $content Inhalt des Kommentars
+ *
+ * @return void
+ */
+ public function addComment(
+ $articleId,
+ $author,
+ $content
+ ) {
+ try {
+ $db = $this->getConnection();
+
+ $sql = "
+ INSERT INTO comments (
+ article_id,
+ author,
+ content
+ )
+ VALUES (
+ :articleId,
+ :author,
+ :content
+ )
+ ";
+
+ $command = $db->prepare($sql);
+
+ $command->execute([
+ ":articleId" => $articleId,
+ ":author" => $author,
+ ":content" => $content
+ ]);
+
+ } catch (PDOException $e) {
+ throw new RuntimeException(
+ "Kommentar konnte nicht gespeichert werden."
+ );
+ }
+ }
+
+ /**
+ * Lädt alle Kommentare eines Beitrags.
+ *
+ * @param int $articleId ID des Beitrags
+ *
+ * @return Comment[]
+ */
+ public function getCommentsByArticle(
+ $articleId
+ ) {
+ try {
+ $db = $this->getConnection();
+
+ $sql = "
+ SELECT *
+ FROM comments
+ WHERE article_id = :articleId
+ ORDER BY created DESC
+ ";
+
+ $command = $db->prepare($sql);
+
+ $command->execute([
+ ":articleId" => $articleId
+ ]);
+
+ $comments = [];
+
+ while ($row = $command->fetch(PDO::FETCH_ASSOC)) {
+
+ $comments[] = new Comment(
+ $row["id"],
+ $row["article_id"],
+ $row["author"],
+ $row["content"],
+ $row["created"]
+ );
+ }
+
+ return $comments;
+
+ } catch (PDOException $e) {
+ throw new RuntimeException(
+ "Kommentare konnten nicht geladen werden."
+ );
+ }
+ }
+}
--
2.47.3
From e1ee70b46f60e97ad5733f02844d9ed2472c1c8b Mon Sep 17 00:00:00 2001
From: Caroline Schulte
Date: Mon, 15 Jun 2026 21:54:06 +0200
Subject: [PATCH 02/20] ajax implementiert
---
content/showArticle.php | 4 ++-
index.php | 71 +++++++++++++---------------------------
js/comments.js | 55 +++++++++++++++++++++++++++++++
php/ajax/add-comment.php | 48 +++++++++++++++++++++++++++
4 files changed, 129 insertions(+), 49 deletions(-)
create mode 100644 js/comments.js
create mode 100644 php/ajax/add-comment.php
diff --git a/content/showArticle.php b/content/showArticle.php
index fff5b00..3feb0bf 100644
--- a/content/showArticle.php
+++ b/content/showArticle.php
@@ -114,7 +114,9 @@ if (isset($_GET["id"])) {
-
Noch keine Kommentare vorhanden.
+
diff --git a/index.php b/index.php
index 1006322..5b5a7cb 100644
--- a/index.php
+++ b/index.php
@@ -29,55 +29,30 @@ if ($pfad === "deleteAccount") {
}
?>
-
-
-
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
- EduForge
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+ EduForge
+
\ No newline at end of file
diff --git a/js/comments.js b/js/comments.js
new file mode 100644
index 0000000..7ee43f7
--- /dev/null
+++ b/js/comments.js
@@ -0,0 +1,55 @@
+document.addEventListener("DOMContentLoaded", function () {
+ const form = document.getElementById("comment-form");
+ const commentsList = document.getElementById("comments-list");
+ const commentContent = document.getElementById("comment-content");
+
+ if (!form || !commentsList || !commentContent) {
+ return;
+ }
+
+ form.addEventListener("submit", function (event) {
+ event.preventDefault();
+
+ const formData = new FormData(form);
+
+ fetch("php/ajax/add-comment.php", {
+ method: "POST",
+ body: formData
+ })
+ .then(response => response.json())
+ .then(data => {
+ if (!data.success) {
+ alert(data.message);
+ return;
+ }
+
+ const emptyMessage = commentsList.querySelector(".no-comments-message");
+ if (emptyMessage) {
+ emptyMessage.remove();
+ }
+
+ const commentElement = document.createElement("div");
+ commentElement.classList.add("comment-item");
+
+ commentElement.innerHTML = `
+
+ ${escapeHtml(data.author)}
+ ${escapeHtml(data.created)}
+
+ ${escapeHtml(data.content).replace(/\n/g, " ")}
+ `;
+
+ commentsList.prepend(commentElement);
+ commentContent.value = "";
+ })
+ .catch(() => {
+ alert("Kommentar konnte nicht gesendet werden.");
+ });
+ });
+
+ function escapeHtml(text) {
+ const div = document.createElement("div");
+ div.textContent = text;
+ return div.innerHTML;
+ }
+});
\ No newline at end of file
diff --git a/php/ajax/add-comment.php b/php/ajax/add-comment.php
new file mode 100644
index 0000000..0895de3
--- /dev/null
+++ b/php/ajax/add-comment.php
@@ -0,0 +1,48 @@
+ false,
+ "message" => "Du musst angemeldet sein."
+ ]);
+ exit();
+}
+
+$articleId = $_POST["article_id"] ?? null;
+$content = trim($_POST["content"] ?? "");
+
+if (empty($articleId) || empty($content)) {
+ echo json_encode([
+ "success" => false,
+ "message" => "Kommentar darf nicht leer sein."
+ ]);
+ exit();
+}
+
+try {
+ $commentManager = CommentManager::getInstance();
+
+ $commentManager->addComment(
+ $articleId,
+ $_SESSION["user_email"],
+ $content
+ );
+
+ echo json_encode([
+ "success" => true,
+ "author" => $_SESSION["user_email"],
+ "content" => $content,
+ "created" => date("Y-m-d H:i:s")
+ ]);
+
+} catch (Exception $e) {
+ echo json_encode([
+ "success" => false,
+ "message" => "Kommentar konnte nicht gespeichert werden."
+ ]);
+}
--
2.47.3
From 21c5471d73f7362982852015a0cd378e71f3f9c9 Mon Sep 17 00:00:00 2001
From: Caroline Schulte
Date: Mon, 15 Jun 2026 22:08:46 +0200
Subject: [PATCH 03/20] fehlerkorrektur
---
index.php | 71 +++++++++++++++++++++++++++++++++++++------------------
1 file changed, 48 insertions(+), 23 deletions(-)
diff --git a/index.php b/index.php
index 5b5a7cb..3cd00fb 100644
--- a/index.php
+++ b/index.php
@@ -29,30 +29,55 @@ if ($pfad === "deleteAccount") {
}
?>
-
-
-
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
- EduForge
-
\ No newline at end of file
+ EduForge
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
--
2.47.3
From 59012cacfbbb86b62587f2c7ba0d59a280421561 Mon Sep 17 00:00:00 2001
From: Caroline Schulte
Date: Mon, 15 Jun 2026 22:14:51 +0200
Subject: [PATCH 04/20] css design
---
css/showArticle.css | 62 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 62 insertions(+)
diff --git a/css/showArticle.css b/css/showArticle.css
index ca3b40a..cfe0aed 100644
--- a/css/showArticle.css
+++ b/css/showArticle.css
@@ -115,4 +115,66 @@
.article-view-title {
font-size: 1.85rem;
}
+
+ /* --- KOMMENTARE --- */
+
+ .article-comments-section {
+ margin-top: 3rem;
+ padding-top: 2rem;
+ border-top: 1px solid #e2e8f0;
+ }
+
+ .article-comments-section h2 {
+ font-size: 2rem;
+ margin-bottom: 1.5rem;
+ color: #1a202c;
+ }
+
+ .comment-item {
+ background-color: #f8fafc;
+ border: 1px solid #e2e8f0;
+ border-radius: 10px;
+ padding: 1rem 1.25rem;
+ margin-bottom: 1rem;
+ }
+
+ .comment-item strong {
+ color: #1a202c;
+ }
+
+ .comment-item span {
+ color: #64748b;
+ font-size: 0.9rem;
+ margin-left: 0.5rem;
+ }
+
+ .comment-item p {
+ margin: 0.5rem 0;
+ }
+
+ #comment-form {
+ margin-top: 2rem;
+ }
+
+ #comment-content {
+ width: 100%;
+ min-height: 120px;
+ padding: 1rem;
+ border: 1px solid #cbd5e1;
+ border-radius: 8px;
+ font-size: 1rem;
+ font-family: inherit;
+ resize: vertical;
+ margin-bottom: 1rem;
+ }
+
+ #comment-content:focus {
+ outline: none;
+ border-color: #2563eb;
+ }
+
+ .no-comments-message {
+ color: #64748b;
+ font-style: italic;
+ }
}
--
2.47.3
From f13a2c6f1e4d12cd5dc0cb8da5e1db82f01955ba Mon Sep 17 00:00:00 2001
From: Caroline Schulte
Date: Mon, 15 Jun 2026 22:17:44 +0200
Subject: [PATCH 05/20] css design
---
css/showArticle.css | 40 +++++++++++++---------------------------
1 file changed, 13 insertions(+), 27 deletions(-)
diff --git a/css/showArticle.css b/css/showArticle.css
index cfe0aed..1539f90 100644
--- a/css/showArticle.css
+++ b/css/showArticle.css
@@ -115,6 +115,7 @@
.article-view-title {
font-size: 1.85rem;
}
+}
/* --- KOMMENTARE --- */
@@ -127,7 +128,10 @@
.article-comments-section h2 {
font-size: 2rem;
margin-bottom: 1.5rem;
- color: #1a202c;
+ }
+
+ #comments-list {
+ margin-bottom: 2rem;
}
.comment-item {
@@ -138,43 +142,25 @@
margin-bottom: 1rem;
}
- .comment-item strong {
- color: #1a202c;
- }
-
- .comment-item span {
- color: #64748b;
- font-size: 0.9rem;
- margin-left: 0.5rem;
- }
-
- .comment-item p {
- margin: 0.5rem 0;
- }
-
#comment-form {
- margin-top: 2rem;
+ width: 100%;
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
}
#comment-content {
- width: 100%;
- min-height: 120px;
+ width: 100% !important;
+ min-height: 130px !important;
padding: 1rem;
border: 1px solid #cbd5e1;
border-radius: 8px;
font-size: 1rem;
font-family: inherit;
resize: vertical;
- margin-bottom: 1rem;
}
- #comment-content:focus {
- outline: none;
- border-color: #2563eb;
+ #comment-form .button {
+ width: 100%;
}
- .no-comments-message {
- color: #64748b;
- font-style: italic;
- }
-}
--
2.47.3
From 6f6e53a483bbee4aa8358333108844f5a45791c5 Mon Sep 17 00:00:00 2001
From: Caroline Schulte
Date: Mon, 15 Jun 2026 22:32:00 +0200
Subject: [PATCH 06/20] =?UTF-8?q?Antwortm=C3=B6glichkeit?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
content/showArticle.php | 44 +++++++++--
js/comments.js | 106 +++++++++++++++++++++++++--
php/ajax/add-comment.php | 13 +++-
php/model/Comment.php | 31 +++++++-
php/model/CommentManagerDAO.php | 9 ++-
php/model/DatabaseCommentManager.php | 39 ++++++++--
6 files changed, 213 insertions(+), 29 deletions(-)
diff --git a/content/showArticle.php b/content/showArticle.php
index 3feb0bf..dbd4082 100644
--- a/content/showArticle.php
+++ b/content/showArticle.php
@@ -104,14 +104,38 @@ if (isset($_GET["id"])) {
diff --git a/php/controller/profile-controller.php b/php/controller/profile-controller.php
index e183b20..9990fbc 100644
--- a/php/controller/profile-controller.php
+++ b/php/controller/profile-controller.php
@@ -3,6 +3,7 @@
require_once "php/model/UserManager.php";
require_once "php/model/Article.php";
require_once "php/model/ArticleManager.php";
+require_once "php/model/CommentManager.php";
require_once "php/validator/user-validator.php";
$error = null;
@@ -76,6 +77,9 @@ try {
$articleManager = ArticleManager::getInstance();
$userArticles = $articleManager->getArticlesByAuthor($_SESSION["user_email"]);
+ $commentManager = CommentManager::getInstance();
+ $userComments = $commentManager->getCommentsByAuthor($_SESSION["user_email"]);
+
if (!isset($userArticles)) {
$_SESSION["message"] = "user_has_no_articles";
}
diff --git a/php/model/CommentManagerDAO.php b/php/model/CommentManagerDAO.php
index 63aaf83..348126e 100644
--- a/php/model/CommentManagerDAO.php
+++ b/php/model/CommentManagerDAO.php
@@ -42,4 +42,13 @@ interface CommentManagerDAO
public function getCommentsByArticle(
$articleId
);
+
+ /**
+ * Gibt alle Kommentare eines Autors zurück.
+ *
+ * @param string $author E-Mail-Adresse des Autors
+ *
+ * @return Comment[] Liste der Kommentare
+ */
+ public function getCommentsByAuthor($author);
}
\ No newline at end of file
diff --git a/php/model/DatabaseCommentManager.php b/php/model/DatabaseCommentManager.php
index 5f61e13..29f2699 100644
--- a/php/model/DatabaseCommentManager.php
+++ b/php/model/DatabaseCommentManager.php
@@ -1,222 +1,68 @@
-getConnection();
- /**
- * Erstellt die Kommentartabelle,
- * falls diese noch nicht existiert.
- *
- * Zusätzlich wird geprüft, ob die Spalte parent_comment_id existiert.
- */
- public function __construct()
- {
- try {
- $db = $this->getConnection();
+$sql = "
+SELECT
+id,
+article_id,
+CASE
+WHEN parent_comment_id IS NULL THEN NULL
+WHEN parent_comment_id = '' THEN NULL
+WHEN parent_comment_id = 0 THEN NULL
+ELSE parent_comment_id
+END AS parent_comment_id,
+author,
+content,
+created
+FROM comments
+WHERE author = :author
+ORDER BY created DESC
+";
- $db->exec("
- CREATE TABLE IF NOT EXISTS comments (
- id INTEGER PRIMARY KEY AUTOINCREMENT,
- article_id INTEGER NOT NULL,
- parent_comment_id INTEGER NULL,
- author TEXT NOT NULL,
- content TEXT NOT NULL,
- created TIMESTAMP DEFAULT CURRENT_TIMESTAMP
- );
- ");
+$command = $db->prepare($sql);
- $columns = $db->query("PRAGMA table_info(comments);")->fetchAll(PDO::FETCH_ASSOC);
- $hasParentColumn = false;
+$command->execute([
+":author" => $author
+]);
- foreach ($columns as $column) {
- if ($column["name"] === "parent_comment_id") {
- $hasParentColumn = true;
- break;
- }
- }
+$comments = [];
- if (!$hasParentColumn) {
- $db->exec("ALTER TABLE comments ADD COLUMN parent_comment_id INTEGER NULL;");
- }
+while ($row = $command->fetch(PDO::FETCH_ASSOC)) {
+$parentCommentId = null;
- unset($db);
+if (
+isset($row["parent_comment_id"])
+&& $row["parent_comment_id"] !== null
+&& $row["parent_comment_id"] !== ""
+&& intval($row["parent_comment_id"]) !== 0
+) {
+$parentCommentId = intval($row["parent_comment_id"]);
+}
- } catch (PDOException $e) {
- throw new RuntimeException(
- "Kommentardatenbank konnte nicht erstellt werden."
- );
- }
- }
+$comments[] = new Comment(
+intval($row["id"]),
+intval($row["article_id"]),
+$parentCommentId,
+$row["author"],
+$row["content"],
+$row["created"]
+);
+}
- /**
- * Baut die Verbindung zur SQLite-Datenbank auf.
- *
- * @return PDO Datenbankverbindung
- */
- private function getConnection()
- {
- try {
- $dsn = 'sqlite:' . __DIR__ . '/../../db/comments.db';
+return $comments;
- $db = new PDO($dsn, null, null);
- $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
-
- return $db;
-
- } catch (PDOException $e) {
- throw new RuntimeException(
- "Verbindung zur Kommentardatenbank fehlgeschlagen."
- );
- }
- }
-
- /**
- * Gibt die Singleton-Instanz zurück.
- *
- * @return DatabaseCommentManager
- */
- public static function getInstance()
- {
- if (self::$instance === null) {
- self::$instance = new DatabaseCommentManager();
- }
-
- return self::$instance;
- }
-
- /**
- * Speichert einen neuen Kommentar oder eine Antwort.
- *
- * @param int $articleId ID des Beitrags
- * @param string $author Autor des Kommentars
- * @param string $content Inhalt des Kommentars
- * @param int|null $parentCommentId ID des Eltern-Kommentars oder null
- *
- * @return int ID des neu gespeicherten Kommentars
- */
- public function addComment(
- $articleId,
- $author,
- $content,
- $parentCommentId = null
- ) {
- try {
- $db = $this->getConnection();
-
- if ($parentCommentId === "" || $parentCommentId === 0 || $parentCommentId === "0") {
- $parentCommentId = null;
- }
-
- $sql = "
- INSERT INTO comments (
- article_id,
- parent_comment_id,
- author,
- content
- )
- VALUES (
- :articleId,
- :parentCommentId,
- :author,
- :content
- )
- ";
-
- $command = $db->prepare($sql);
-
- $command->execute([
- ":articleId" => $articleId,
- ":parentCommentId" => $parentCommentId,
- ":author" => $author,
- ":content" => $content
- ]);
-
- return intval($db->lastInsertId());
-
- } catch (PDOException $e) {
- throw new RuntimeException(
- "Kommentar konnte nicht gespeichert werden."
- );
- }
- }
-
- /**
- * Lädt alle Kommentare eines Beitrags.
- *
- * @param int $articleId ID des Beitrags
- *
- * @return Comment[]
- */
- public function getCommentsByArticle(
- $articleId
- ) {
- try {
- $db = $this->getConnection();
-
- $sql = "
- SELECT
- id,
- article_id,
- CASE
- WHEN parent_comment_id IS NULL THEN NULL
- WHEN parent_comment_id = '' THEN NULL
- WHEN parent_comment_id = 0 THEN NULL
- ELSE parent_comment_id
- END AS parent_comment_id,
- author,
- content,
- created
- FROM comments
- WHERE article_id = :articleId
- ORDER BY created ASC
- ";
-
- $command = $db->prepare($sql);
-
- $command->execute([
- ":articleId" => $articleId
- ]);
-
- $comments = [];
-
- while ($row = $command->fetch(PDO::FETCH_ASSOC)) {
- $parentCommentId = null;
-
- if (
- isset($row["parent_comment_id"])
- && $row["parent_comment_id"] !== null
- && $row["parent_comment_id"] !== ""
- && intval($row["parent_comment_id"]) !== 0
- ) {
- $parentCommentId = intval($row["parent_comment_id"]);
- }
-
- $comments[] = new Comment(
- intval($row["id"]),
- intval($row["article_id"]),
- $parentCommentId,
- $row["author"],
- $row["content"],
- $row["created"]
- );
- }
-
- return $comments;
-
- } catch (PDOException $e) {
- throw new RuntimeException(
- "Kommentare konnten nicht geladen werden."
- );
- }
- }
+} catch (PDOException $e) {
+throw new RuntimeException(
+"Kommentare konnten nicht geladen werden."
+);
+}
}
\ No newline at end of file
--
2.47.3
From 47239016c5ac8715123bd36f2f2b335471e2afe0 Mon Sep 17 00:00:00 2001
From: Caroline Schulte
Date: Tue, 16 Jun 2026 00:02:06 +0200
Subject: [PATCH 18/20] Fehlerbehebung
---
php/model/DatabaseCommentManager.php | 301 ++++++++++++++++++++++-----
1 file changed, 245 insertions(+), 56 deletions(-)
diff --git a/php/model/DatabaseCommentManager.php b/php/model/DatabaseCommentManager.php
index 29f2699..0a603e3 100644
--- a/php/model/DatabaseCommentManager.php
+++ b/php/model/DatabaseCommentManager.php
@@ -1,68 +1,257 @@
+getConnection();
+ private static $instance = null;
-$sql = "
-SELECT
-id,
-article_id,
-CASE
-WHEN parent_comment_id IS NULL THEN NULL
-WHEN parent_comment_id = '' THEN NULL
-WHEN parent_comment_id = 0 THEN NULL
-ELSE parent_comment_id
-END AS parent_comment_id,
-author,
-content,
-created
-FROM comments
-WHERE author = :author
-ORDER BY created DESC
-";
+ /**
+ * Erstellt die Kommentartabelle, falls diese noch nicht existiert.
+ */
+ public function __construct()
+ {
+ try {
+ $db = $this->getConnection();
-$command = $db->prepare($sql);
+ $db->exec("
+ CREATE TABLE IF NOT EXISTS comments (
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ article_id INTEGER NOT NULL,
+ parent_comment_id INTEGER NULL,
+ author TEXT NOT NULL,
+ content TEXT NOT NULL,
+ created TIMESTAMP DEFAULT CURRENT_TIMESTAMP
+ );
+ ");
-$command->execute([
-":author" => $author
-]);
+ $columns = $db->query("PRAGMA table_info(comments);")->fetchAll(PDO::FETCH_ASSOC);
+ $hasParentColumn = false;
-$comments = [];
+ foreach ($columns as $column) {
+ if ($column["name"] === "parent_comment_id") {
+ $hasParentColumn = true;
+ break;
+ }
+ }
-while ($row = $command->fetch(PDO::FETCH_ASSOC)) {
-$parentCommentId = null;
+ if (!$hasParentColumn) {
+ $db->exec("ALTER TABLE comments ADD COLUMN parent_comment_id INTEGER NULL;");
+ }
-if (
-isset($row["parent_comment_id"])
-&& $row["parent_comment_id"] !== null
-&& $row["parent_comment_id"] !== ""
-&& intval($row["parent_comment_id"]) !== 0
-) {
-$parentCommentId = intval($row["parent_comment_id"]);
-}
+ } catch (PDOException $e) {
+ throw new RuntimeException("Kommentardatenbank konnte nicht erstellt werden.");
+ }
+ }
-$comments[] = new Comment(
-intval($row["id"]),
-intval($row["article_id"]),
-$parentCommentId,
-$row["author"],
-$row["content"],
-$row["created"]
-);
-}
+ /**
+ * Baut die Verbindung zur SQLite-Datenbank auf.
+ *
+ * @return PDO Datenbankverbindung
+ */
+ private function getConnection()
+ {
+ try {
+ $dsn = 'sqlite:' . __DIR__ . '/../../db/comments.db';
-return $comments;
+ $db = new PDO($dsn, null, null);
+ $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
-} catch (PDOException $e) {
-throw new RuntimeException(
-"Kommentare konnten nicht geladen werden."
-);
-}
+ return $db;
+
+ } catch (PDOException $e) {
+ throw new RuntimeException("Verbindung zur Kommentardatenbank fehlgeschlagen.");
+ }
+ }
+
+ /**
+ * Gibt die Singleton-Instanz zurück.
+ *
+ * @return DatabaseCommentManager
+ */
+ public static function getInstance()
+ {
+ if (self::$instance === null) {
+ self::$instance = new DatabaseCommentManager();
+ }
+
+ return self::$instance;
+ }
+
+ /**
+ * Speichert einen neuen Kommentar oder eine Antwort.
+ *
+ * @param int $articleId ID des Beitrags
+ * @param string $author Autor des Kommentars
+ * @param string $content Inhalt des Kommentars
+ * @param int|null $parentCommentId ID des Eltern-Kommentars oder null
+ *
+ * @return int ID des neu gespeicherten Kommentars
+ */
+ public function addComment(
+ $articleId,
+ $author,
+ $content,
+ $parentCommentId = null
+ ) {
+ try {
+ $db = $this->getConnection();
+
+ if ($parentCommentId === "" || $parentCommentId === 0 || $parentCommentId === "0") {
+ $parentCommentId = null;
+ }
+
+ $sql = "
+ INSERT INTO comments (
+ article_id,
+ parent_comment_id,
+ author,
+ content
+ )
+ VALUES (
+ :articleId,
+ :parentCommentId,
+ :author,
+ :content
+ )
+ ";
+
+ $command = $db->prepare($sql);
+
+ $command->execute([
+ ":articleId" => $articleId,
+ ":parentCommentId" => $parentCommentId,
+ ":author" => $author,
+ ":content" => $content
+ ]);
+
+ return intval($db->lastInsertId());
+
+ } catch (PDOException $e) {
+ throw new RuntimeException("Kommentar konnte nicht gespeichert werden.");
+ }
+ }
+
+ /**
+ * Lädt alle Kommentare eines Beitrags.
+ *
+ * @param int $articleId ID des Beitrags
+ *
+ * @return Comment[]
+ */
+ public function getCommentsByArticle($articleId)
+ {
+ try {
+ $db = $this->getConnection();
+
+ $sql = "
+ SELECT
+ id,
+ article_id,
+ CASE
+ WHEN parent_comment_id IS NULL THEN NULL
+ WHEN parent_comment_id = '' THEN NULL
+ WHEN parent_comment_id = 0 THEN NULL
+ ELSE parent_comment_id
+ END AS parent_comment_id,
+ author,
+ content,
+ created
+ FROM comments
+ WHERE article_id = :articleId
+ ORDER BY created ASC
+ ";
+
+ $command = $db->prepare($sql);
+ $command->execute([":articleId" => $articleId]);
+
+ return $this->mapRowsToComments($command);
+
+ } catch (PDOException $e) {
+ throw new RuntimeException("Kommentare konnten nicht geladen werden.");
+ }
+ }
+
+ /**
+ * Lädt alle Kommentare eines Autors.
+ *
+ * @param string $author E-Mail-Adresse des Autors
+ *
+ * @return Comment[]
+ */
+ public function getCommentsByAuthor($author)
+ {
+ try {
+ $db = $this->getConnection();
+
+ $sql = "
+ SELECT
+ id,
+ article_id,
+ CASE
+ WHEN parent_comment_id IS NULL THEN NULL
+ WHEN parent_comment_id = '' THEN NULL
+ WHEN parent_comment_id = 0 THEN NULL
+ ELSE parent_comment_id
+ END AS parent_comment_id,
+ author,
+ content,
+ created
+ FROM comments
+ WHERE author = :author
+ ORDER BY created DESC
+ ";
+
+ $command = $db->prepare($sql);
+ $command->execute([":author" => $author]);
+
+ return $this->mapRowsToComments($command);
+
+ } catch (PDOException $e) {
+ throw new RuntimeException("Kommentare konnten nicht geladen werden.");
+ }
+ }
+
+ /**
+ * Wandelt Datenbankzeilen in Comment-Objekte um.
+ *
+ * @param PDOStatement $command Ausgeführtes Statement
+ *
+ * @return Comment[]
+ */
+ private function mapRowsToComments($command)
+ {
+ $comments = [];
+
+ while ($row = $command->fetch(PDO::FETCH_ASSOC)) {
+ $parentCommentId = null;
+
+ if (
+ isset($row["parent_comment_id"])
+ && $row["parent_comment_id"] !== null
+ && $row["parent_comment_id"] !== ""
+ && intval($row["parent_comment_id"]) !== 0
+ ) {
+ $parentCommentId = intval($row["parent_comment_id"]);
+ }
+
+ $comments[] = new Comment(
+ intval($row["id"]),
+ intval($row["article_id"]),
+ $parentCommentId,
+ $row["author"],
+ $row["content"],
+ $row["created"]
+ );
+ }
+
+ return $comments;
+ }
}
\ No newline at end of file
--
2.47.3
From 23ccbe2d02d7b074078963dff3c6a0f39fa090b8 Mon Sep 17 00:00:00 2001
From: Caroline Schulte
Date: Tue, 16 Jun 2026 22:09:17 +0200
Subject: [PATCH 19/20] =?UTF-8?q?Review=C3=A4nderungen?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
content/showArticle.php | 33 ++++++++++++++++++++++++++++
css/showArticle.css | 4 ++--
index.php | 1 +
php/ajax/add-comment.php | 4 +++-
php/model/DatabaseCommentManager.php | 10 ++++-----
5 files changed, 44 insertions(+), 8 deletions(-)
diff --git a/content/showArticle.php b/content/showArticle.php
index 5c9e5dc..fc8502e 100644
--- a/content/showArticle.php
+++ b/content/showArticle.php
@@ -24,6 +24,11 @@ if (isset($_GET["id"])) {
}
}
?>
+
+
@@ -32,8 +37,30 @@ if (isset($_GET["id"])) {
+
+
+ Es ist ein Fehler aufgetreten. Die ID konnte nicht ausgelesen werden. Bitte versuche es erneut.
+
+
+
+
+
+ Jeder Beitrag muss einen Titel, Kategorie und Inhalt besitzen.
+
+
+
+
+ Dein Beitrag wurde erfolgreich bearbeitet!
+
+
+
+
+
+
@@ -52,13 +79,18 @@ if (isset($_GET["id"])) {
+
+
+
+
@@ -66,6 +98,7 @@ if (isset($_GET["id"])) {
+
EduForge
diff --git a/php/ajax/add-comment.php b/php/ajax/add-comment.php
index 95a59e7..b2c14b9 100644
--- a/php/ajax/add-comment.php
+++ b/php/ajax/add-comment.php
@@ -1,5 +1,7 @@
lastInsertId());
} catch (PDOException $e) {
- throw new RuntimeException("Kommentar konnte nicht gespeichert werden.");
+ throw new RuntimeException("internal_error");
}
}
@@ -175,7 +175,7 @@ class DatabaseCommentManager implements CommentManagerDAO
return $this->mapRowsToComments($command);
} catch (PDOException $e) {
- throw new RuntimeException("Kommentare konnten nicht geladen werden.");
+ throw new RuntimeException("internal_error");
}
}
@@ -215,7 +215,7 @@ class DatabaseCommentManager implements CommentManagerDAO
return $this->mapRowsToComments($command);
} catch (PDOException $e) {
- throw new RuntimeException("Kommentare konnten nicht geladen werden.");
+ throw new RuntimeException("internal_error");
}
}
--
2.47.3
From a8d321609ddb4e7580ff7eb2287e3a55ac036a67 Mon Sep 17 00:00:00 2001
From: Caroline Schulte
Date: Tue, 16 Jun 2026 22:31:49 +0200
Subject: [PATCH 20/20] =?UTF-8?q?Review=C3=A4nderungen?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
content/profile.php | 61 ++++++++++++++++++++++++++++-----------------
1 file changed, 38 insertions(+), 23 deletions(-)
diff --git a/content/profile.php b/content/profile.php
index 4ac69fc..65ce6c9 100644
--- a/content/profile.php
+++ b/content/profile.php
@@ -185,38 +185,53 @@ $isEditMode = (isset($_GET["edit"]) && $_GET["edit"] === "1") || !empty($error);
- Meine Kommentare
+
+
-
\ No newline at end of file
--
2.47.3
Kommentare
++ getAuthor()); ?> + getCreated()); ?> +
+ +getContent())); ?>
+Noch keine Kommentare vorhanden.
+ +Du musst angemeldet sein, um einen Kommentar zu schreiben.
+ +