From fd1bc5812a58c47b98fb932a097d16fec19a76d3 Mon Sep 17 00:00:00 2001 From: Matthias Grief Date: Tue, 10 Dec 2024 21:16:41 +0100 Subject: [PATCH] Speichern und Laden von Inhalten verbessert --- webseite/classes/SubjectData.php | 7 +-- webseite/classes/TopicData.php | 90 +++++++++++++++++++++++--------- webseite/classes/Util.php | 18 +++++++ 3 files changed, 84 insertions(+), 31 deletions(-) diff --git a/webseite/classes/SubjectData.php b/webseite/classes/SubjectData.php index d957308..b5e2641 100644 --- a/webseite/classes/SubjectData.php +++ b/webseite/classes/SubjectData.php @@ -41,7 +41,7 @@ class SubjectData public array $topics; /** - * Erstellt ein neues Fach + * Erstellt ein neues Fach. Es wird noch nichts gespeichert! * @param string $id Ein eindeutiger Bezeichner für das Fach, darf nur A-Z, a-Z, 0-9 sowie _ und - enthalten * @param string $displayName Der für User angezeigte Name des Faches, nur reiner Text * @param string $description Eine kurze Beschreibung des Faches, z.B. für den Text auf der Startseite, kann HTML enthalten @@ -72,17 +72,12 @@ class SubjectData $result->topics = $topics; - if(!$result->save()) { - return false; - } - return $result; } /** * Prüft, ob das Thema zu den angegebenen IDs existiert * @param string $subjectId ID des Faches - * @param string $topicId ID des Themas * @return bool true, wenn es existiert, sonst false */ public static function exists(string $subjectId): bool diff --git a/webseite/classes/TopicData.php b/webseite/classes/TopicData.php index 06cad94..5ef3e87 100644 --- a/webseite/classes/TopicData.php +++ b/webseite/classes/TopicData.php @@ -49,33 +49,32 @@ class TopicData public string $article; /** - * Erstellt ein neues Thema + * Erstellt ein neues Thema. Es wird noch nichts gespeichert! * @param string $id Innerhalb des zugehörigen Faches eindeutige ID, darf nur A-Z, a-z, 0-9 sowie - und _ enthalten * @param string $subjectId Die eindeutige ID des zugehörigen Faches, das Fach muss schon existieren * @param string $displayName Der für User angezeigt Name des Themas, darf nur reinen Text enthalten * @param string $icon Das Icon des Themas als Font-Awesome CSS-Klasse * @param string $description Eine kurze Beschreibung des Themas, z.B. für die Fachübersichtsseite, darf HTML enthalten * @param array $relatedTopics Die IDs aller verwandten Themen als String - * @param array $files Die Dateinamen (Datei.pdf) aller downloadbarer Dateien zu diesem Thema als String. Die eigentlichen Dateien müssen seperat hinzugefügt werden * @param string $article Der gesamte Erklärungstext zum Thema, enthält fertiges HTML und LATEX Formelsyntax für MathJax https://docs.mathjax.org/en/latest/basic/mathematics.html * @return TopicData|false Neues Thema oder false, wenn ein Fehler auftritt */ - public static function createNew(string $id, string $subjectId, string $displayName, string $icon, string $description, array $relatedTopics, array $files, string $article): TopicData|false + public static function createNew(string $id, string $subjectId, string $displayName, string $icon, string $description, array $relatedTopics, string $article): TopicData|false { $result = new TopicData(); - if(Util::containsIllegalCharacters($subjectId)) { + if (Util::containsIllegalCharacters($subjectId)) { return false; } - if(!SubjectData::exists($subjectId)) { + if (!SubjectData::exists($subjectId)) { return false; } $result->subjectId = $subjectId; - if(Util::containsIllegalCharacters($id)) { + if (Util::containsIllegalCharacters($id)) { return false; } - if(self::exists($subjectId, $id)) { + if (self::exists($subjectId, $id)) { return false; } $result->id = $id; @@ -88,14 +87,10 @@ class TopicData $result->relatedTopics = $relatedTopics; - $result->files = $files; + $result->files = array(); $result->article = $article; - if(!$result->save()) { - return false; - } - return $result; } @@ -107,7 +102,7 @@ class TopicData */ public static function exists(string $subjectId, string $topicId): bool { - if(!is_dir(Config::getTopicDirectory($subjectId, $topicId))) { + if (!is_dir(Config::getTopicDirectory($subjectId, $topicId))) { return false; } @@ -189,18 +184,7 @@ class TopicData } $result->relatedTopics = $relatedTopics; - $files = array(); - $downloadDirectory = Config::getTopicDirectory($subjectId, $topicId) . "downloads/"; - if (is_dir($downloadDirectory)) { - $fileNames = scandir($downloadDirectory); - foreach ($fileNames as $fileName) { - if ($fileName == "." || $fileName == "..") { - continue; - } - - $files[] = $fileName; - } - } + $files = Util::getFilesFromDirectory(Config::getTopicDirectory($subjectId, $topicId) . "downloads/"); $result->files = $files; $article = Util::readFileContent(Config::getTopicDirectory($subjectId, $topicId) . "article.html"); @@ -209,6 +193,9 @@ class TopicData } $result->article = str_replace('$TOPICPATH', Config::getTopicDirectory($subjectId, $topicId) . "images", $article); + $result->cleanupRelatedTopics(); + $result->cleanupFiles(); + return $result; } @@ -218,6 +205,9 @@ class TopicData */ public function save(): bool { + $this->cleanupRelatedTopics(); + $this->cleanupFiles(); + $data = array(); $data["displayName"] = $this->displayName; $data["icon"] = $this->icon; @@ -316,6 +306,56 @@ class TopicData return true; } + /** + * Prüft für alle verwandten Themen, ob diese auch existieren. Wenn nicht, wird es aus der Liste entfernt + * @return bool true, wenn Elemente entfernt wurden, sonst false + */ + private function cleanupRelatedTopics(): bool + { + $changed = false; + $nonexistentEntries = array(); + + foreach ($this->relatedTopics as $topic) { + if (!self::exists($this->subjectId, $topic)) { + $nonexistentEntries[] = $topic; + $changed = true; + } + } + + $this->relatedTopics = array_diff($this->relatedTopics, $nonexistentEntries); + + return $changed; + } + + /** + * Prüft für alle Downloads, ob die zugehörige Datei existiert und ob zu jeder Datei ein Eintrag existiert. + * Wenn eine Datei nicht existiert, wird auch der zugehörige Eintrag entfernt. + * Wenn ein Eintrag nicht existiert, wird auch die Datei gelöscht. + * @return bool true, wenn etwas verändert wurde + */ + private function cleanupFiles(): bool + { + $changed = false; + + $nonexistentEntries = array(); + foreach ($this->files as $file) { + if(!file_exists(Config::getTopicDirectory($this->subjectId, $this->id) . "downloads/$file")) { + $nonexistentEntries[] = $file; + $changed = true; + } + } + $this->files = array_diff($this->files, $nonexistentEntries); + + foreach (Util::getFilesFromDirectory(Config::getTopicDirectory($this->subjectId, $this->id) . "downloads/") as $file) { + if(!array_search($file, $this->files) === false) { + Util::delete(Config::getTopicDirectory($this->subjectId, $this->id) . "downloads/$file"); + $changed = true; + } + } + + return $changed; + } + /** * Löscht ein Bild des Themas * @param string $name Dateiname diff --git a/webseite/classes/Util.php b/webseite/classes/Util.php index a8cabb8..2802e8a 100644 --- a/webseite/classes/Util.php +++ b/webseite/classes/Util.php @@ -29,6 +29,24 @@ class Util return false; } + static function getFilesFromDirectory(string $directory): array + { + $files = array(); + + if (is_dir($directory)) { + $fileNames = scandir($directory); + foreach ($fileNames as $fileName) { + if ($fileName == "." || $fileName == "..") { + continue; + } + + $files[] = $fileName; + } + } + + return $files; + } + /** * Liest den gesamten Text aus einer Datei aus * @param string $filename Dateipfad