188 lines
7.5 KiB
PHP
188 lines
7.5 KiB
PHP
<?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"])) {
|
||
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: ../../index.php?pfad=updateArticle&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");
|
||
}
|
||
}
|
||
|
||
?>
|