344 lines
8.9 KiB
PHP
344 lines
8.9 KiB
PHP
<?php
|
|
require_once("Config.php");
|
|
require_once("Util.php");
|
|
|
|
class TopicData
|
|
{
|
|
/**
|
|
* @var string Innerhalb des zugehörigen Faches eindeutige ID, darf nur A-Z, a-z, 0-9 sowie - und _ enthalten
|
|
*/
|
|
public string $id;
|
|
|
|
/**
|
|
* @var string Die eindeutige ID des zugehörigen Faches
|
|
*/
|
|
public string $subjectId;
|
|
|
|
/**
|
|
* @var string Der für User angezeigt Name des Themas, darf nur reinen Text enthalten
|
|
*/
|
|
public string $displayName;
|
|
|
|
/**
|
|
* @var string Das Icon des Themas als Font-Awesome CSS-Klasse
|
|
*/
|
|
public string $icon;
|
|
|
|
/**
|
|
* @var string Eine kurze Beschreibung des Themas, z.B. für die Fachübersichtsseite, darf HTML enthalten
|
|
*/
|
|
public string $description;
|
|
|
|
/**
|
|
* @var array Die IDs aller verwandten Themen als String
|
|
*/
|
|
public array $relatedTopics;
|
|
|
|
/**
|
|
* @var array Die Dateinamen (Datei.pdf) aller downloadbarer Dateien zu diesem Thema als String
|
|
*/
|
|
public array $files;
|
|
|
|
/**
|
|
* @var string 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
|
|
*/
|
|
public string $article;
|
|
|
|
/**
|
|
* Gibt alle Themen zu einem gegebenen Fach zurück
|
|
* @param $subjectId string Die ID des Faches
|
|
* @return array Alle zugehörigen Themen als TopicData Objekte
|
|
*/
|
|
public static function getAll(string $subjectId): array
|
|
{
|
|
$result = array();
|
|
|
|
$topicNames = scandir(Config::getTopicsDirectory($subjectId));
|
|
|
|
usort($topicNames, function ($a, $b) {
|
|
return strcmp($a, $b);
|
|
});
|
|
|
|
foreach ($topicNames as $topicName) {
|
|
if ($topicName == "." || $topicName == "..") {
|
|
continue;
|
|
}
|
|
$topicData = TopicData::fromName($subjectId, $topicName);
|
|
if (!isset($topicData)) {
|
|
continue;
|
|
}
|
|
|
|
$result[$topicData->id] = $topicData;
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* Gibt Themendaten zu einem bestimmten Thema eines Faches zurück
|
|
* @param $subjectId string Die ID des Faches
|
|
* @param $topicId string Die ID des Themas
|
|
* @return TopicData|null Die Themendaten oder null, wenn das Thema nicht existiert
|
|
*/
|
|
public static function fromName(string $subjectId, string $topicId): TopicData|null
|
|
{
|
|
$result = new TopicData();
|
|
|
|
$subjectId = Util::removeIllegalCharacters($subjectId);
|
|
$topicId = Util::removeIllegalCharacters($topicId);
|
|
|
|
$data = Util::parseJsonFromFile(Config::getTopicDirectory($subjectId, $topicId) . "properties.json");
|
|
if (!isset($data)) {
|
|
return null;
|
|
}
|
|
|
|
$result->id = $topicId;
|
|
$result->subjectId = $subjectId;
|
|
|
|
if (isset($data->displayName)) {
|
|
$result->displayName = $data->displayName;
|
|
} else {
|
|
return null;
|
|
}
|
|
|
|
if (isset($data->icon)) {
|
|
$result->icon = $data->icon;
|
|
} else {
|
|
return null;
|
|
}
|
|
|
|
if (isset($data->description)) {
|
|
$result->description = $data->description;
|
|
} else {
|
|
return null;
|
|
}
|
|
|
|
if (isset($data->relatedTopics)) {
|
|
$result->relatedTopics = $data->relatedTopics;
|
|
} else {
|
|
$result->relatedTopics = array();
|
|
}
|
|
|
|
$result->files = array();
|
|
$downloadDirectory = Config::getTopicDirectory($subjectId, $topicId) . "downloads/";
|
|
if(is_dir($downloadDirectory)) {
|
|
$fileNames = scandir($downloadDirectory);
|
|
foreach ($fileNames as $fileName) {
|
|
if ($fileName == "." || $fileName == "..") {
|
|
continue;
|
|
}
|
|
|
|
$result->files[] = $fileName;
|
|
}
|
|
}
|
|
|
|
$article = Util::readFileContent(Config::getTopicDirectory($subjectId, $topicId) . "article.html");
|
|
if (!isset($article)) {
|
|
$article = "Kein Erklärtext vorhanden";
|
|
}
|
|
$article = str_replace('$TOPICPATH', Config::getTopicDirectory($subjectId, $topicId), $article);
|
|
|
|
$result->article = $article;
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* Schreibt alle Daten in Dateien
|
|
* @return bool true, wenn erfolgreich, sonst false
|
|
*/
|
|
public function save(): bool
|
|
{
|
|
$data = array();
|
|
$data["displayName"] = $this->displayName;
|
|
$data["icon"] = $this->icon;
|
|
$data["description"] = $this->description;
|
|
$data["relatedTopics"] = $this->relatedTopics;
|
|
$data["files"] = $this->files;
|
|
|
|
$json = json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
|
if (!$json) {
|
|
return false;
|
|
}
|
|
|
|
if (!is_dir(Config::getSubjectDirectory($this->getSubjectId()))) {
|
|
return false;
|
|
}
|
|
|
|
$topicDirectory = Config::getTopicDirectory($this->getSubjectId(), $this->getId());
|
|
if (!is_dir($topicDirectory)) {
|
|
mkdir($topicDirectory, 0777, true);
|
|
}
|
|
|
|
if (!(Util::writeFileContent($topicDirectory . "properties.json", $json)
|
|
&& Util::writeFileContent($topicDirectory . "article.html", $json))
|
|
) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Lädt eine Datei als Download zum Thema hoch
|
|
* @param string $name Dateiname von User
|
|
* @param string $tmp_name Temporärer Pfad zur hochgeladenen Datei
|
|
* @return bool true, wenn erfolgreich, sonst false
|
|
*/
|
|
private function addDownload(string $name, string $tmp_name): bool
|
|
{
|
|
$downloadDirectory = Config::getTopicDirectory($this->getSubjectId() , $this->getId()) . "downloads/";
|
|
|
|
if(!is_dir($downloadDirectory)) {
|
|
if(!mkdir($downloadDirectory)) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if(!move_uploaded_file($tmp_name, $downloadDirectory . $name)) {
|
|
return false;
|
|
}
|
|
|
|
$this->files[] = $name;
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Lädt eine oder mehrere Dateien als Downloads zu diesem Thema hoch
|
|
* @param array $files Das array mit den Dateidaten, normalerweise z.B. $_FILES['html-input-name']
|
|
* @return bool true, wenn erfolgreich, sonst false
|
|
*/
|
|
public function addDownloads(array $files): bool
|
|
{
|
|
if(count($files) == 0) {
|
|
return false;
|
|
}
|
|
|
|
if(!isset($files["name"]) || !isset($files["tmp_name"])) {
|
|
return false;
|
|
}
|
|
|
|
if(!is_array($files["name"])) {
|
|
return $this->addDownload($files["name"], $files["tmp_name"]);
|
|
}
|
|
|
|
foreach ($files["name"] as $key => $name) {
|
|
if(!$this->addDownload($name, $files["tmp_name"][$key])) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public function deleteDownload(string $name): bool
|
|
{
|
|
if(!isset($this->files[$name])) {
|
|
return false;
|
|
}
|
|
|
|
if(!unlink(Config::getTopicDirectory($this->getSubjectId() , $this->getId()) . "downloads/$name")) {
|
|
return false;
|
|
}
|
|
|
|
$this->files = array_diff($this->files, [$name]);
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Löscht das Thema inklusive aller zugehörigen Dateien
|
|
* @return bool true, wenn erfolgreich gelöscht, sonst false
|
|
*/
|
|
public function delete(): bool
|
|
{
|
|
if(!Util::delete(Config::getTopicDirectory($this->getSubjectId(), $this->getId()))) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public function getId(): string
|
|
{
|
|
return $this->id;
|
|
}
|
|
|
|
public function setId(string $id): void
|
|
{
|
|
$this->id = $id;
|
|
}
|
|
|
|
public function getSubjectId(): string
|
|
{
|
|
return $this->subjectId;
|
|
}
|
|
|
|
public function setSubjectId(string $subjectId): void
|
|
{
|
|
$this->subjectId = $subjectId;
|
|
}
|
|
|
|
public function getDisplayName(): string
|
|
{
|
|
return $this->displayName;
|
|
}
|
|
|
|
public function setDisplayName(string $displayName): void
|
|
{
|
|
$this->displayName = $displayName;
|
|
}
|
|
|
|
public function getIcon(): string
|
|
{
|
|
return $this->icon;
|
|
}
|
|
|
|
public function setIcon(string $icon): void
|
|
{
|
|
$this->icon = $icon;
|
|
}
|
|
|
|
public function getDescription(): string
|
|
{
|
|
return $this->description;
|
|
}
|
|
|
|
public function setDescription(string $description): void
|
|
{
|
|
$this->description = $description;
|
|
}
|
|
|
|
public function getRelatedTopics(): array
|
|
{
|
|
return $this->relatedTopics;
|
|
}
|
|
|
|
public function setRelatedTopics(array $relatedTopics): void
|
|
{
|
|
$this->relatedTopics = $relatedTopics;
|
|
}
|
|
|
|
public function getFiles(): array
|
|
{
|
|
return $this->files;
|
|
}
|
|
|
|
public function setFiles(array $files): void
|
|
{
|
|
$this->files = $files;
|
|
}
|
|
|
|
public function getArticle(): string
|
|
{
|
|
return $this->article;
|
|
}
|
|
|
|
public function setArticle(string $article): void
|
|
{
|
|
$this->article = $article;
|
|
}
|
|
|
|
|
|
} |