Implementierung
This commit is contained in:
Generated
+1
-1
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="dataSourceStorageLocal" created-in="IU-261.24374.151">
|
||||
<component name="dataSourceStorageLocal" created-in="IU-253.32098.101">
|
||||
<data-source name="articles" uuid="315cb5c9-2b0f-435b-b602-59823b160908">
|
||||
<database-info product="SQLite" version="3.51.1" jdbc-version="4.2" driver-name="SQLite JDBC" driver-version="3.51.1.0" dbms="SQLITE" exact-version="3.51.1" exact-driver-version="3.51">
|
||||
<identifier-quote-string>"</identifier-quote-string>
|
||||
|
||||
+70
-13
@@ -1,18 +1,31 @@
|
||||
<?php
|
||||
include_once 'php/controller/showArticle-controller.php';
|
||||
require_once 'php/model/CommentManager.php';
|
||||
|
||||
$comments = [];
|
||||
|
||||
if (isset($_GET["id"])) {
|
||||
try {
|
||||
$commentManager = CommentManager::getInstance();
|
||||
$comments = $commentManager->getCommentsByArticle($_GET["id"]);
|
||||
} catch (Exception $e) {
|
||||
$_SESSION["message"] = "internal_error";
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
<!--
|
||||
Seite: Anzeige für Beiträge
|
||||
Funktion: Stellt einen übergebenen Beitrag dar.
|
||||
-->
|
||||
|
||||
<!-- Hauptcontainer für die Beitragsansicht (Ausschließlich der Content-Bereich) -->
|
||||
<main class="article-view-container">
|
||||
<?php if (isset($_SESSION["message"]) && $_SESSION["message"] == "internal_error"): ?>
|
||||
<p class="alert-message is-error">
|
||||
Es ist ein interner Fehler aufgetreten. Bitte versuche es erneut.
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (isset($_SESSION["message"]) && $_SESSION["message"] == "missing_id"): ?>
|
||||
<p class="alert-message is-error">
|
||||
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.
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (isset($_SESSION["message"]) && $_SESSION["message"] == "article_updated"): ?>
|
||||
<p class="alert-message is-success">
|
||||
Dein Beitrag wurde erfolgreich bearbeitet!
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
<?php
|
||||
unset($_SESSION["message"]);
|
||||
?>
|
||||
|
||||
<!-- Metadaten & Titel -->
|
||||
<?php unset($_SESSION["message"]); ?>
|
||||
|
||||
<div class="article-view-top-section">
|
||||
|
||||
<?php if (isset($category) && !empty($category)): ?>
|
||||
<span class="article-view-category"><?php echo htmlspecialchars($category); ?></span>
|
||||
<?php endif; ?>
|
||||
|
||||
<h1 class="article-view-title">
|
||||
<?php if (isset($title)) { echo htmlspecialchars($title); } ?>
|
||||
</h1>
|
||||
|
||||
<div class="article-view-meta">
|
||||
<?php if (isset($author) && !empty($author)): ?>
|
||||
<span class="article-view-author">Von: <strong><?php echo htmlspecialchars($author); ?></strong></span>
|
||||
<span class="article-view-author">
|
||||
Von: <strong><?php echo htmlspecialchars($author); ?></strong>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Beitrags-Inhalt -->
|
||||
<div class="article-view-content">
|
||||
<?php if (isset($content)): ?>
|
||||
<!-- nl2br für Zeilenumbrüche -->
|
||||
<div class="article-view-body"><?php echo nl2br(htmlspecialchars($content)); ?></div>
|
||||
<div class="article-view-body">
|
||||
<?php echo nl2br(htmlspecialchars($content)); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<!-- Beitrags-Endbereich (Tags) -->
|
||||
<?php if (isset($tags) && !empty($tags)): ?>
|
||||
<div class="article-view-bottom-section">
|
||||
<div class="article-view-tags-label">Tags:</div>
|
||||
|
||||
<div class="article-view-tags-list">
|
||||
<?php
|
||||
// Falls $tags ein String ist (z.B. "Web, CSS"), in ein Array umwandeln
|
||||
$tagArray = is_array($tags) ? $tags : explode(',', $tags);
|
||||
|
||||
foreach ($tagArray as $tag):
|
||||
$trimmedTag = trim($tag);
|
||||
|
||||
if (!empty($trimmedTag)):
|
||||
?>
|
||||
<span class="article-view-tag-item"><?php echo htmlspecialchars($trimmedTag); ?></span>
|
||||
<span class="article-view-tag-item">
|
||||
<?php echo htmlspecialchars($trimmedTag); ?>
|
||||
</span>
|
||||
<?php
|
||||
endif;
|
||||
endforeach;
|
||||
@@ -80,5 +98,44 @@ include_once 'php/controller/showArticle-controller.php';
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
</main>
|
||||
<section class="article-comments-section">
|
||||
<h2>Kommentare</h2>
|
||||
|
||||
<div id="comments-list">
|
||||
<?php if (!empty($comments)): ?>
|
||||
<?php foreach ($comments as $comment): ?>
|
||||
<div class="comment-item">
|
||||
<p>
|
||||
<strong><?php echo htmlspecialchars($comment->getAuthor()); ?></strong>
|
||||
<span><?php echo htmlspecialchars($comment->getCreated()); ?></span>
|
||||
</p>
|
||||
|
||||
<p><?php echo nl2br(htmlspecialchars($comment->getContent())); ?></p>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
<?php else: ?>
|
||||
<p>Noch keine Kommentare vorhanden.</p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<?php if (isset($_SESSION["user_email"])): ?>
|
||||
<form id="comment-form">
|
||||
<input type="hidden"
|
||||
name="article_id"
|
||||
value="<?php echo htmlspecialchars($_GET["id"] ?? ""); ?>">
|
||||
|
||||
<textarea name="content"
|
||||
id="comment-content"
|
||||
placeholder="Schreibe einen Kommentar..."
|
||||
required></textarea>
|
||||
|
||||
<button type="submit" class="button">
|
||||
Kommentar senden
|
||||
</button>
|
||||
</form>
|
||||
<?php else: ?>
|
||||
<p>Du musst angemeldet sein, um einen Kommentar zu schreiben.</p>
|
||||
<?php endif; ?>
|
||||
</section>
|
||||
|
||||
</main>
|
||||
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Repräsentiert einen Kommentar unter einem Beitrag.
|
||||
*
|
||||
* Ein Kommentar besteht aus einer eindeutigen ID,
|
||||
* der ID des zugehörigen Beitrags, dem Autor,
|
||||
* dem Inhalt sowie dem Erstellungsdatum.
|
||||
*
|
||||
* @author Caroline Schulte
|
||||
*/
|
||||
class Comment
|
||||
{
|
||||
private int $id;
|
||||
private int $articleId;
|
||||
private string $author;
|
||||
private string $content;
|
||||
private string $created;
|
||||
|
||||
/**
|
||||
* Erstellt einen neuen Kommentar.
|
||||
*
|
||||
* @param int $id Eindeutige ID des Kommentars
|
||||
* @param int $articleId ID des zugehörigen Beitrags
|
||||
* @param string $author Autor des Kommentars
|
||||
* @param string $content Inhalt des Kommentars
|
||||
* @param string $created Erstellungsdatum des Kommentars
|
||||
*/
|
||||
public function __construct(
|
||||
int $id,
|
||||
int $articleId,
|
||||
string $author,
|
||||
string $content,
|
||||
string $created
|
||||
) {
|
||||
$this->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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
require_once "DatabaseCommentManager.php";
|
||||
|
||||
/**
|
||||
* Zentrale Zugriffsschicht für Kommentare.
|
||||
*
|
||||
* Die Anwendung arbeitet ausschließlich
|
||||
* mit dem CommentManager und kennt die
|
||||
* konkrete Speicherimplementierung nicht.
|
||||
*
|
||||
* @author Caroline Schulte
|
||||
*/
|
||||
class CommentManager
|
||||
{
|
||||
/**
|
||||
* Gibt die aktive Kommentarverwaltung zurück.
|
||||
*
|
||||
* @return CommentManagerDAO
|
||||
*/
|
||||
public static function getInstance()
|
||||
{
|
||||
return DatabaseCommentManager::getInstance();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
require_once "Comment.php";
|
||||
|
||||
/**
|
||||
* Schnittstelle für die Verwaltung von Kommentaren.
|
||||
*
|
||||
* Definiert die grundlegenden Methoden zum
|
||||
* Speichern und Laden von Kommentaren.
|
||||
*
|
||||
* @author Caroline Schulte
|
||||
*/
|
||||
interface CommentManagerDAO
|
||||
{
|
||||
/**
|
||||
* 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
|
||||
);
|
||||
|
||||
/**
|
||||
* Gibt alle Kommentare eines Beitrags zurück.
|
||||
*
|
||||
* @param int $articleId ID des Beitrags
|
||||
*
|
||||
* @return Comment[] Liste der Kommentare
|
||||
*/
|
||||
public function getCommentsByArticle(
|
||||
$articleId
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
<?php
|
||||
|
||||
require_once "CommentManagerDAO.php";
|
||||
require_once "Comment.php";
|
||||
|
||||
/**
|
||||
* Verwaltet die Speicherung und das Laden von Kommentaren
|
||||
* über eine SQLite-Datenbank.
|
||||
*
|
||||
* @author Caroline Schulte
|
||||
*/
|
||||
class DatabaseCommentManager implements CommentManagerDAO
|
||||
{
|
||||
private static $instance = null;
|
||||
|
||||
/**
|
||||
* Erstellt die Kommentartabelle,
|
||||
* falls diese noch nicht existiert.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
try {
|
||||
$db = $this->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."
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user