Files
webprogrammierung/php/controller/updateArticle-controller.php
T
2026-07-19 13:15:23 +02:00

188 lines
7.5 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
require_once '../model/LocalArticleManager.php';
require_once '../model/ArticleManager.php';
require_once '../model/Article.php';
require_once '../validator/article-validator.php';
require_once '../../includes/article-block-helper.php';
if (!isset($_SESSION["user_email"])) {
header("Location: index.php?pfad=login");
exit();
}
if ($_SERVER["REQUEST_METHOD"] === "POST") {
if (isset($_GET["id"]) && !empty($_GET["id"])) {
$id = $_GET["id"];
} else {
$_SESSION["message"] = "missing_id";
header("location: ../../index.php?pfad=updateArticle");
exit();
}
try {
$articleManager = ArticleManager::getInstance();
$article = $articleManager->getArticle($id);
if ($article->getAuthor() != $_SESSION["user_email"]) {
$_SESSION["message"] = "unauthorized_access";
header("location: ../../index.php");
exit();
}
} catch (Exception $e) {
$_SESSION["message"] = $e->getMessage();
header("location: ../../index.php?pfad=updateArticle&id=$id");
exit();
}
$uploadDir = __DIR__ . '/../../uploads/';
if (!file_exists($uploadDir)) {
mkdir($uploadDir, 0755, true);
}
// Formularzustand (Titel/Tags/Kategorie/Blöcke) immer sichern, damit er nach einem
// Redirect (PRG-Pattern oder Validierungsfehler) wieder angezeigt werden kann.
$_SESSION["old_title"] = $_POST["title"] ?? '';
$_SESSION["old_tags"] = $_POST["tags"] ?? '';
$_SESSION["old_category"] = $_POST["category"] ?? '';
$blocks = rebuildBlocksFromPost($_POST['blocks'] ?? [], $_FILES['blocks'] ?? [], $uploadDir);
$_SESSION["old_content"] = json_encode($blocks, JSON_UNESCAPED_UNICODE);
// ---------------------------------------------------------------------
// Zwischen-Schritt: Block hinzufügen oder entfernen (kein echtes Speichern).
// Wird bei aktivem JavaScript per preventDefault() abgefangen und lokal im
// DOM erledigt (js/editor.js) ohne JS läuft dieser Server-Roundtrip.
// ---------------------------------------------------------------------
if (isset($_POST['editor_action']) && $_POST['editor_action'] !== '') {
$action = $_POST['editor_action'];
if ($action === 'add_text') {
$blocks[] = ['type' => 'text', 'value' => ''];
} elseif ($action === 'add_image') {
$blocks[] = ['type' => 'image', 'value' => ''];
} elseif (str_starts_with($action, 'delete_block:')) {
$deleteIndex = (int) substr($action, strlen('delete_block:'));
unset($blocks[$deleteIndex]);
$blocks = array_values($blocks);
}
$_SESSION["old_content"] = json_encode($blocks, JSON_UNESCAPED_UNICODE);
header("location: ../../content/updateArticle.php?id=$id");
exit();
}
// ---------------------------------------------------------------------
// Echtes Speichern
// ---------------------------------------------------------------------
if (!isset($_POST["title"]) || !isset($_POST["category"])) {
$_SESSION["message"] = "missing_parameters";
header("location: ../../index.php?pfad=updateArticle&id=$id");
exit();
} else {
$title = $_POST["title"];
$content = json_encode($blocks, JSON_UNESCAPED_UNICODE);
$author = $_SESSION["user_email"];
$category = $_POST["category"];
$tags = $_POST['tags'] ?? '';
// -------------------------------- Validierung der Daten: -------------------------
if (!articleTitleValidator($title)) {
$_SESSION["message"] = "invalid_title";
header("location: ../../index.php?pfad=updateArticle&id=$id");
exit();
}
if (!articleContentValidator($content)) {
$_SESSION["message"] = "invalid_content";
header("location: ../../index.php?pfad=updateArticle&id=$id");
exit();
}
if (!articleCategoryValidator($category)) {
$_SESSION["message"] = "invalid_category";
header("location: ../../index.php?pfad=updateArticle&id=$id");
exit();
}
if (!articleTagValidator($tags)) {
$_SESSION["message"] = "invalid_tags";
header("location: ../../index.php?pfad=updateArticle&id=$id");
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);
}
// ----------------- Verwaiste Bilder aufräumen -----------------
// Bilder, die im alten (gespeicherten) Content vorkamen, im neuen aber nicht
// mehr referenziert werden, wurden vom Nutzer entfernt oder ersetzt -> löschen.
// Hinweis/TODO: Bilder, die innerhalb derselben Bearbeitungs-Sitzung neu
// hochgeladen und noch vor dem finalen Speichern wieder entfernt wurden,
// werden hierüber nicht erfasst (sie tauchten nie im alten Content auf) und
// bleiben als Datei liegen. Für eine vollständige Bereinigung würde sich ein
// regelmäßiger Cleanup-Job anbieten, der verwaiste Dateien im uploads/-Ordner
// mit den in der Datenbank referenzierten Pfaden abgleicht.
$oldBlocks = json_decode($article->getContent(), true);
$oldImagePaths = [];
if (is_array($oldBlocks)) {
foreach ($oldBlocks as $oldBlock) {
if (($oldBlock['type'] ?? '') === 'image'
&& !empty($oldBlock['value'])
&& is_string($oldBlock['value'])
&& str_starts_with($oldBlock['value'], 'uploads/')) {
$oldImagePaths[] = $oldBlock['value'];
}
}
}
$newImagePaths = [];
foreach ($blocks as $block) {
if (($block['type'] ?? '') === 'image' && !empty($block['value'])) {
$newImagePaths[] = $block['value'];
}
}
$orphanedImages = array_diff($oldImagePaths, $newImagePaths);
foreach ($orphanedImages as $orphanedImage) {
$absolutePath = __DIR__ . '/../../' . $orphanedImage;
if (is_file($absolutePath)) {
@unlink($absolutePath);
}
}
// ----------------- Ü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);
unset($_SESSION["old_title"], $_SESSION["old_content"], $_SESSION["old_category"], $_SESSION["old_tags"]);
} catch (\Throwable $e) {
$_SESSION["message"] = $e->getMessage();
header("location: ../../index.php?pfad=updateArticle&id=$id");
exit();
}
$_SESSION["message"] = "article_updated";
// Weiterleitung zur Homepage
header("location: ../../index.php?pfad=showArticle&id=$id");
}
}
?>