Implementierung
This commit is contained in:
Generated
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<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">
|
<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">
|
<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>
|
<identifier-quote-string>"</identifier-quote-string>
|
||||||
|
|||||||
+70
-13
@@ -1,18 +1,31 @@
|
|||||||
<?php
|
<?php
|
||||||
include_once 'php/controller/showArticle-controller.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
|
Seite: Anzeige für Beiträge
|
||||||
Funktion: Stellt einen übergebenen Beitrag dar.
|
Funktion: Stellt einen übergebenen Beitrag dar.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<!-- Hauptcontainer für die Beitragsansicht (Ausschließlich der Content-Bereich) -->
|
|
||||||
<main class="article-view-container">
|
<main class="article-view-container">
|
||||||
<?php if (isset($_SESSION["message"]) && $_SESSION["message"] == "internal_error"): ?>
|
<?php if (isset($_SESSION["message"]) && $_SESSION["message"] == "internal_error"): ?>
|
||||||
<p class="alert-message is-error">
|
<p class="alert-message is-error">
|
||||||
Es ist ein interner Fehler aufgetreten. Bitte versuche es erneut.
|
Es ist ein interner Fehler aufgetreten. Bitte versuche es erneut.
|
||||||
</p>
|
</p>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
<?php if (isset($_SESSION["message"]) && $_SESSION["message"] == "missing_id"): ?>
|
<?php if (isset($_SESSION["message"]) && $_SESSION["message"] == "missing_id"): ?>
|
||||||
<p class="alert-message is-error">
|
<p class="alert-message is-error">
|
||||||
Es ist ein Fehler aufgetreten. Die ID konnte nicht ausgelesen werden. 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.
|
Jeder Beitrag muss einen Titel, Kategorie und Inhalt besitzen.
|
||||||
</p>
|
</p>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
<?php if (isset($_SESSION["message"]) && $_SESSION["message"] == "article_updated"): ?>
|
<?php if (isset($_SESSION["message"]) && $_SESSION["message"] == "article_updated"): ?>
|
||||||
<p class="alert-message is-success">
|
<p class="alert-message is-success">
|
||||||
Dein Beitrag wurde erfolgreich bearbeitet!
|
Dein Beitrag wurde erfolgreich bearbeitet!
|
||||||
</p>
|
</p>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
<?php
|
|
||||||
unset($_SESSION["message"]);
|
|
||||||
?>
|
|
||||||
|
|
||||||
<!-- Metadaten & Titel -->
|
<?php unset($_SESSION["message"]); ?>
|
||||||
|
|
||||||
<div class="article-view-top-section">
|
<div class="article-view-top-section">
|
||||||
|
|
||||||
<?php if (isset($category) && !empty($category)): ?>
|
<?php if (isset($category) && !empty($category)): ?>
|
||||||
<span class="article-view-category"><?php echo htmlspecialchars($category); ?></span>
|
<span class="article-view-category"><?php echo htmlspecialchars($category); ?></span>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
<h1 class="article-view-title">
|
<h1 class="article-view-title">
|
||||||
<?php if (isset($title)) { echo htmlspecialchars($title); } ?>
|
<?php if (isset($title)) { echo htmlspecialchars($title); } ?>
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<div class="article-view-meta">
|
<div class="article-view-meta">
|
||||||
<?php if (isset($author) && !empty($author)): ?>
|
<?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; ?>
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Beitrags-Inhalt -->
|
|
||||||
<div class="article-view-content">
|
<div class="article-view-content">
|
||||||
<?php if (isset($content)): ?>
|
<?php if (isset($content)): ?>
|
||||||
<!-- nl2br für Zeilenumbrüche -->
|
<div class="article-view-body">
|
||||||
<div class="article-view-body"><?php echo nl2br(htmlspecialchars($content)); ?></div>
|
<?php echo nl2br(htmlspecialchars($content)); ?>
|
||||||
|
</div>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Beitrags-Endbereich (Tags) -->
|
|
||||||
<?php if (isset($tags) && !empty($tags)): ?>
|
<?php if (isset($tags) && !empty($tags)): ?>
|
||||||
<div class="article-view-bottom-section">
|
<div class="article-view-bottom-section">
|
||||||
<div class="article-view-tags-label">Tags:</div>
|
<div class="article-view-tags-label">Tags:</div>
|
||||||
|
|
||||||
<div class="article-view-tags-list">
|
<div class="article-view-tags-list">
|
||||||
<?php
|
<?php
|
||||||
// Falls $tags ein String ist (z.B. "Web, CSS"), in ein Array umwandeln
|
|
||||||
$tagArray = is_array($tags) ? $tags : explode(',', $tags);
|
$tagArray = is_array($tags) ? $tags : explode(',', $tags);
|
||||||
|
|
||||||
foreach ($tagArray as $tag):
|
foreach ($tagArray as $tag):
|
||||||
$trimmedTag = trim($tag);
|
$trimmedTag = trim($tag);
|
||||||
|
|
||||||
if (!empty($trimmedTag)):
|
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
|
<?php
|
||||||
endif;
|
endif;
|
||||||
endforeach;
|
endforeach;
|
||||||
@@ -80,5 +98,44 @@ include_once 'php/controller/showArticle-controller.php';
|
|||||||
</div>
|
</div>
|
||||||
<?php endif; ?>
|
<?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