Merge branch 'Beitrag-bearbeiten' into dev

This commit is contained in:
2026-06-01 23:14:14 +02:00
17 changed files with 812 additions and 88 deletions
+59 -5
View File
@@ -2,30 +2,84 @@
session_start();
require_once '../model/LocalArticleManager.php';
require_once '../model/ArticleManager.php';
require_once '../validator/article-validator.php';
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$_SESSION["old_title"] = $_POST["title"] ?? '';
$_SESSION["old_content"] = $_POST["content"] ?? '';
$_SESSION["old_category"] = $_POST["category"] ?? '';
$_SESSION["old_tags"] = $_POST["tags"] ?? '';
if(!isset($_POST["title"]) ||!isset($_POST["content"]) || !isset($_POST["category"])){
$_SESSION["message"] = "missing_parameters";
header("location: ../../index.php?pfad=createArticle");
exit();
} else {
$title = $_POST["title"];
$content = $_POST["content"];
$category = $_POST["category"];
$author = "max.mustermann"; // TODO: später aus Session den angemeldeten Nutzer beziehen.
$tags = $_POST["tags"];
$category = $_POST["category"];
$tags = $_POST['tags'] ?? '';
// -------------------------------- Validierung der Daten: -------------------------
if (!articleAuthorValidator($author)) {
$_SESSION["message"] = "author_not_valid";
header("location: ../../index.php?pfad=createArticle");
exit();
}
if (!articleTitleValidator($title)) {
$_SESSION["message"] = "invalid_title";
header("location: ../../index.php?pfad=createArticle");
exit();
}
if (!articleContentValidator($content)) {
$_SESSION["message"] = "invalid_content";
header("location: ../../index.php?pfad=createArticle");
exit();
}
if (!articleCategoryValidator($category)) {
$_SESSION["message"] = "invalid_category";
header("location: ../../index.php?pfad=createArticle");
exit();
}
if (!articleTagValidator($tags)) {
$_SESSION["message"] = "invalid_tags";
header("location: ../../index.php?pfad=createArticle");
exit();
} else {
$cleanedTags = [];
$rawTags = explode(',', $tags);
foreach ($rawTags as $rawTag) {
// Leerzeichen am Anfang/Ende des einzelnen Tags entfernen:
$tag = trim($rawTag);
$cleanedTags[] = $tag;
}
// Duplikate entfernen:
$cleanedTags = array_unique($cleanedTags);
$cleanedTags = implode(',', $cleanedTags);
}
// ----------------- Übertragung der validierten Daten in ArticleManager: ---------------------------
try {
$articleManager = ArticleManager::getInstance();
$articleManager->addArticle($title, $content, $author, $category, $tags);
$articleManager->addArticle($title, $content, $author, $category, $cleanedTags);
// Formulardaten nach erfolgreichem Erstellen aus der Session löschen
unset($_SESSION["old_title"], $_SESSION["old_content"], $_SESSION["old_category"], $_SESSION["old_tags"]);
} catch (Exception $e){
$_SESSION["message"] = "internal_error";
header("location: ../../index.php?pfad=createArticle");
exit();
}
$_SESSION["message"] = "new_article";
// Weiterleitung zur Homepage
header("location: ../../index.php");
exit();
}
}
@@ -0,0 +1,21 @@
<?php
/*
* Controller für die Liste der eigenen Beiträge eines Nutzers auf der eigenen Profilseite
*/
session_start();
require_once 'php/model/Article.php';
require_once 'php/model/ArticleManager.php';
try {
$author = "max.mustermann"; // TODO: später Nutzer aus der Session beziehen.
$articleManager = ArticleManager::getInstance();
$userArticles = $articleManager->getArticlesByAuthor($author);
if(!isset($userArticles)) {
$_SESSION["message"] = "user_has_no_articles";
}
} catch (Exception $e) {
$_SESSION["message"] = "internal_error";
}
?>
+8 -7
View File
@@ -3,10 +3,11 @@ session_start();
require_once 'php/model/Article.php';
require_once 'php/model/ArticleManager.php';
if (isset($_GET["id"])){
if (isset($_GET["id"]) && !empty($_GET["id"])){
try {
$id = $_GET["id"];
$articleManager = ArticleManager::getInstance();
$article = $articleManager->getArticle($_GET["id"]);
$article = $articleManager->getArticle($id);
if($article != null){
$title = $article->getTitle();
$content = $article->getContent();
@@ -14,15 +15,15 @@ if (isset($_GET["id"])){
$author = $article->getAuthor();
$tags = $article->getTags();
}else{
$_SESSION["message"] = "article_not_found";
echo "article_not_found";
//header("location: index.php?pfad=404");
include_once "content/404.php";
exit();
}
} catch (Exception $e){
$_SESSION["message"] = "internal_error";
echo "Fehler aufgetreten: " . $e->getMessage();
exit();
}
}else{
$_SESSION["message"] = "article_not_found";
echo "article_not_found";
$_SESSION["message"] = "missing_id";
}
?>
@@ -0,0 +1,95 @@
<?php
session_start();
require_once '../model/LocalArticleManager.php';
require_once '../model/ArticleManager.php';
require_once '../model/Article.php';
require_once '../validator/article-validator.php';
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$_SESSION["old_title"] = $_POST["title"] ?? '';
$_SESSION["old_content"] = $_POST["content"] ?? '';
$_SESSION["old_category"] = $_POST["category"] ?? '';
$_SESSION["old_tags"] = $_POST["tags"] ?? '';
if (isset($_GET["id"]) && !empty($_GET["id"])) {
$id = $_GET["id"];
} else {
$_SESSION["message"] = "missing_id";
header("location: ../../index.php?pfad=updateArticle");
exit();
}
if (!isset($_POST["title"]) ||!isset($_POST["content"]) || !isset($_POST["category"])){
$_SESSION["message"] = "missing_parameters";
header("location: ../../index.php?pfad=updateArticle");
exit();
}else{
$title = $_POST["title"];
$content = $_POST["content"];
$author = "max.mustermann"; // TODO: später aus Session den angemeldeten Nutzer beziehen.
$category = $_POST["category"];
$tags = $_POST['tags'] ?? '';
// -------------------------------- Validierung der Daten: -------------------------
if (!articleAuthorValidator($author)) {
$_SESSION["message"] = "author_not_valid";
header("location: ../../index.php?pfad=updateArticle");
exit();
}
if (!articleTitleValidator($title)) {
$_SESSION["message"] = "invalid_title";
header("location: ../../index.php?pfad=updateArticle");
exit();
}
if (!articleContentValidator($content)) {
$_SESSION["message"] = "invalid_content";
header("location: ../../index.php?pfad=updateArticle");
exit();
}
if (!articleCategoryValidator($category)) {
$_SESSION["message"] = "invalid_category";
header("location: ../../index.php?pfad=updateArticle");
exit();
}
if (!articleTagValidator($tags)) {
$_SESSION["message"] = "invalid_tags";
header("location: ../../index.php?pfad=updateArticle");
exit();
} else {
$cleanedTags = [];
$rawTags = explode(',', $tags);
foreach ($rawTags as $rawTag) {
// Leerzeichen am Anfang/Ende des einzelnen Tags entfernen:
$tag = trim($rawTag);
$cleanedTags[] = $tag;
}
// Duplikate entfernen:
$cleanedTags = array_unique($cleanedTags);
$cleanedTags = implode(',', $cleanedTags);
}
// ----------------- Übertragung der validierten Daten in ArticleManager: ---------------------------
try {
$articleManager = ArticleManager::getInstance();
$article = $articleManager->getArticle($id);
$article->setTitle($title);
$article->setContent($content);
$article->setCategory($category);
$article->setTags($cleanedTags);
$articleManager->updateArticle($id ,$article, $author);
} catch (Exception $e){
$_SESSION["message"] = "internal_error";
header("location: ../../index.php?pfad=updateArticle");
exit();
}
$_SESSION["message"] = "article_updated";
// Weiterleitung zur Homepage
header("location: ../../index.php?pfad=showArticle&id=$id");
}
}
?>
+21 -11
View File
@@ -1,7 +1,7 @@
<?php
/**
* Klasse: Artikel
* Diese Klasse stellt alle Daten eines Artikels (Beitrag) bereit
* Diese Klasse stellt alle Daten eines Beitrags (Beitrag) bereit
*
* @author Niklas Ortmann
*/
@@ -38,7 +38,7 @@ class Article
}
/**
* Gibt die ID eines Artikels zurück.
* Gibt die ID eines Beitrags zurück.
* @return int
*/
public function getId(): int
@@ -47,7 +47,7 @@ class Article
}
/**
* Gibt den Titel eines Artikels zurück.
* Gibt den Titel eines Beitrags zurück.
* @return string
*/
public function getTitle(): string
@@ -56,7 +56,7 @@ class Article
}
/**
* Setzt den Titel eines Artikels
* Setzt den Titel eines Beitrags
* @param $title
* @return void
*/
@@ -66,7 +66,7 @@ class Article
}
/**
* Gibt den Content eines Artikels zurück.
* Gibt den Content eines Beitrags zurück.
* TODO: Content muss noch definiert werden.
* @return string
*/
@@ -76,7 +76,7 @@ class Article
}
/**
* Setzt den Content eines Artikels.
* Setzt den Content eines Beitrags.
* TODO: Content muss noch definiert werden.
* @param $content
* @return void
@@ -87,7 +87,7 @@ class Article
}
/**
* Gibt den Autor eines Artikels zurück.
* Gibt den Autor eines Beitrags zurück.
* @return string
*/
public function getAuthor(): string
@@ -96,7 +96,7 @@ class Article
}
/**
* Gibt das Veröffentlichungsdatum des Artikels zurück.
* Gibt das Veröffentlichungsdatum des Beitrags zurück.
* @return string
*/
public function getCreationDate(): string
@@ -105,7 +105,7 @@ class Article
}
/**
* Gibt die Kategorie eines Artikels zurück.
* Gibt die Kategorie eines Beitrags zurück.
* @return string
*/
public function getCategory(): string
@@ -114,7 +114,17 @@ class Article
}
/**
* Gibt die Schlagworte eines Artikels zurück.
* Setzt die Kategorie eines Beitrags.
* @param string $category
* @return void
*/
public function setCategory(string $category)
{
$this->category = $category;
}
/**
* Gibt die Schlagworte eines Beitrags zurück.
* @return string
*/
public function getTags(): string
@@ -123,7 +133,7 @@ class Article
}
/**
* Setzt die Schlagworte eines Artikels.
* Setzt die Schlagworte eines Beitrags.
* @param string $tags
*/
public function setTags(string $tags)
+20 -16
View File
@@ -21,26 +21,24 @@ interface ArticleManagerDAO
public function addArticle($title, $content, $author, $category, $tags);
/**
* Ein angemeldeter Nutzer bearbeitet einen Beitrag.
* $id ID des Beitrags
* $title Titel des Beitrags
* $content Der Inhalt des Beitrags
* $author dem Author des des Beitrags (NID oder email)
* Ändert den gespeicherten Beitrag eines übergebenen Beitrags und eines Autors.
* Es wird geprüft, ob der zu änderne Beitrag existiert und ob der übergebene Autor der Autor des originalen
* Beitrages ist.
* @param $id
* @param $article
* @param $author
* @return void
*
* Mögliche Exceptions:
* TODO Fehlerbeschreibung hinzufügen
* TODO: Fehlerbeschreibung hinzufügen
*/
public function updateArticle($id, $title, $content, $author);
public function updateArticle($id, $article, $author);
/*
* Ein angemeldeter Nutzer löscht einen seiner Beiträge.
* $id ID des Beitrags
* $title Titel des Beitrags
* $content Der Inhalt des Beitrags
* $author dem Author des des Beitrags (NID oder email)
/**
* Löscht einen Beitrag aus übergebener ID.
* @param $id
* @return void
*
* Mögliche Exceptions:
* TODO Fehlerbeschreibung hinzufügen
* TODO: Fehlerbeschreibung hinzufügen
*/
public function deleteArticle($id);
@@ -62,6 +60,12 @@ interface ArticleManagerDAO
*/
public function getAllArticles();
/**
* Gibt alle Beiträge eines Nutzer mit einer gegebenen ID aus.
* @param $author
* @return Article[]
*/
public function getArticlesByAuthor($author);
}
?>
+74 -3
View File
@@ -62,14 +62,65 @@ class LocalArticleManager implements ArticleManagerDAO {
$this->saveArticle($articles);
}
public function updateArticle($id, $title, $content, $author)
public function updateArticle($id, $article, $author)
{
// TODO: Implement updateArticle() method.
if (empty($article)) {
// TODO: Implement Exception.
return;
}
// Berechtigungsprüfung:
if ($article->getAuthor() !== $author) {
// TODO: Implement Exception.
return;
}
// Beitrag aktualisieren:
$articles = $this->getAllArticles();
$updated = false;
foreach ($articles as $index => $storedArticle) {
if (isset($storedArticle['id']) && $storedArticle['id'] == $id) {
$articles[$index] = [
"id" => $id,
"title" => $article->getTitle(),
"content" => $article->getContent(),
"author" => $author,
"category" => $article->getCategory(),
"tags" => $article->getTags(),
"creationDate" => $article->getCreationDate()
];
$updated = true;
break;
}else{
// TODO: Implement Exception.
return;
}
}
// Nur speichern, wenn Beitrag geändert wurde:
if ($updated) {
$this->saveArticle($articles);
}
}
public function deleteArticle($id)
{
// TODO: Implement deleteArticle() method.
$articles = $this->getAllArticles();
$articleFound = false;
foreach ($articles as $index => $article) {
if (isset($article['id']) && $article['id'] == $id) {
unset($articles[$index]);
$articleFound = true;
break; // Schleife abbrechen, da die ID eindeutig ist
}
}
if ($articleFound) {
// array_values stellt sicher, dass die Array-Keys wieder fortlaufend bei 0 beginnen
$this->saveArticle(array_values($articles));
}
}
public function getArticle($id)
@@ -97,5 +148,25 @@ class LocalArticleManager implements ArticleManagerDAO {
return is_array($articles) ? $articles : [];
}
public function getArticlesByAuthor($author)
{
$articles = $this->getAllArticles();
$filteredArticles = [];
foreach ($articles as $article) {
if (isset($article['author']) && $article['author'] == $author) {
$filteredArticles[] = new Article(
intval($article['id']),
$article['title'],
$article['content'],
$article['author'],
$article['category'],
$article['tags'],
$article['creationDate']
);
}
}
return $filteredArticles;
}
}
?>
+107
View File
@@ -0,0 +1,107 @@
<?php
/**
* Prüft, ob der Autor auch der Eigentümer des Beitrags ist.
* @param $author
* @return true
* TODO: Implement this.
*/
function articleAuthorValidator($author)
{
return true;
}
/**
* Prüft, ob der Titel die folgenden Bedingungen erfüllt:
* Buchstaben von a-z; A-Z
* Zahlen von 0-9
* Umlaute äöüÄÖÜß
* Satzeichen .,!?:;()"„“«»_+-
* 5-120 Zeichen
* @param $title
* @return bool
*/
function articleTitleValidator($title)
{
$title = trim($title);
$titlePattern = '/^[a-zA-Z0-9äöüÄÖÜß\s.,!?:;()\'"„“«»_+-]{5,120}$/u';
if (preg_match($titlePattern, $title)) {
return true;
} else {
return false;
}
}
/**
* Prüft, ob der Contenttext 10-7000 Zeichen enthält.
* @param $content
* @return bool
*/
function articleContentValidator($content)
{
$content = trim($content);
$zeichenAnzahl = mb_strlen($content);
if ($zeichenAnzahl <= 7000 && $zeichenAnzahl >= 10) {
return true;
}else{
return false;
}
}
/**
* Prüft, ob die Kategorie eine erlaubt Kategorie ist.
* @param $category
* @return bool
*/
function articleCategoryValidator($category)
{
$allowedCategories = [
'deutsch', 'englisch', 'franzoesisch', 'latein', 'literatur',
'mathe', 'biologie', 'chemie', 'physik', 'informatik', 'astronomie',
'geschichte', 'erdkunde', 'sozialkunde', 'wirtschaft', 'religion',
'ethik', 'philosophie', 'psychologie', 'kunst', 'musik', 'theater',
'technik', 'werken', 'hauswirtschaft', 'sport'
];
if (in_array($category, $allowedCategories, true)) {
return true;
} else {
return false;
}
}
/**
* Prüft, ob die Tags die folgenden Bedingungen erfüllen:
* Buchstaben von a-z; A-Z
* Zahlen von 0-9
* Umlaute äöüÄÖÜß
* Satzeichen -
* 2-50 Zeichen
* @param $tags
* @return bool
*/
function articleTagValidator($tags)
{
if (!isset($tags)) {
$tags = '';
}
$rawTags = explode(',', $tags);
foreach ($rawTags as $rawTag) {
// Leerzeichen am Anfang/Ende des einzelnen Tags entfernen:
$tag = trim($rawTag);
// leere Elemente überspringen:
if ($tag === '') {
continue;
}
// Tag mit Regex prüfen:
$tagPattern = '/^[a-zA-Z0-9äöüÄÖÜß\s-]{2,50}$/u';
if (!preg_match($tagPattern, $tag)) {
return false;
}
}
return true;
}
?>