Compare commits

..

8 Commits

Author SHA1 Message Date
caroline.slt 1314362df9 Buttonfix 2026-06-03 21:32:14 +02:00
caroline.slt 5a1c032f1b Reviewnacharbeitung 2026-06-03 21:27:08 +02:00
caroline.slt fae4bc86ad Reviewnacharbeitung 2026-06-03 21:16:31 +02:00
caroline.slt 664092d52f Reviewnacharbeitung 2026-06-03 21:14:01 +02:00
caroline.slt 22b1dd827d Reviewnacharbeitung 2026-06-03 21:09:34 +02:00
caroline.slt 50df844e23 Reviewnacharbeitung 2026-06-03 21:05:32 +02:00
caroline.slt 45b6b41d60 Reviewnacharbeitung 2026-06-03 21:01:28 +02:00
caroline.slt a0a79e0191 Reviewnacharbeitung 2026-06-03 20:58:26 +02:00
16 changed files with 286 additions and 331 deletions
-6
View File
@@ -10,15 +10,12 @@ Jeweils im Format `Anmeldename, Passwort, Mailadresse`:
- `max.mustermann, test123, mustermann@web.de` - `max.mustermann, test123, mustermann@web.de`
## Weitere Voraussetzungen zur Nutzung ## Weitere Voraussetzungen zur Nutzung
- Per Klick auf das Logo gelangt man auf die Home-Seite.
## Ausgelassene Teilaufgaben ## Ausgelassene Teilaufgaben
## Bekannte Fehler und Mängel ## Bekannte Fehler und Mängel
- Der Beitragseditor fügt beim Laden von Inhalten leere Zeichen ein. - Der Beitragseditor fügt beim Laden von Inhalten leere Zeichen ein.
- Bitte auf die gesetzten TODO's achten. Wenn Inhalte fehlen, sind sie i.d.R. als TODO kommentiert. - Bitte auf die gesetzten TODO's achten. Wenn Inhalte fehlen, sind sie i.d.R. als TODO kommentiert.
- Die Navbar hat noch keine onHover-Effekte und erschwert etwas die Bedienung.
- Suchleiste in der Nav ist in der mobilen Ansicht etwas schmal. Ggf. ein alternatives (kleineres) Logo implementieren.
## Besonderheiten des Projektes ## Besonderheiten des Projektes
- Es wurde ein einfacher Beitrags-Editor erstellt. Mit diesem können Beiträge erstellt oder bearbeitet werden. - Es wurde ein einfacher Beitrags-Editor erstellt. Mit diesem können Beiträge erstellt oder bearbeitet werden.
@@ -26,6 +23,3 @@ Jeweils im Format `Anmeldename, Passwort, Mailadresse`:
- Es sind drei Dummy-Beiträge für den Nutzer max.mustermann hinterlegt. - Es sind drei Dummy-Beiträge für den Nutzer max.mustermann hinterlegt.
- Beim Verwenden der Navbar-Links bitte Folgendes beachten: nur die Kategorien Physik, Mathe, Informatik führen exemplarisch auf eine Beispiel-Seite. - Beim Verwenden der Navbar-Links bitte Folgendes beachten: nur die Kategorien Physik, Mathe, Informatik führen exemplarisch auf eine Beispiel-Seite.
Die anderen Links sind erstmal Platzhalter und führen auf eine 404-Seite. Die anderen Links sind erstmal Platzhalter und führen auf eine 404-Seite.
- Die Such-Seite umfasst eine Suchfunktion (aber noch nicht nach Tags) und Sortierfunktion. Jedoch fehlt noch eine Filterfunktion (z.B. nur Mathe anzeigen).
Wenn die Filterfunktion implementiert ist, dann können die statischen Seiten "Informatik", "Mathe", "Physik" entfernt und dynamisch auf der Suchseite
nach gefiltertem Fach angezeigt werden. (Vorläufige showCategory.php implementiert)
+16 -8
View File
@@ -2,7 +2,7 @@
include_once 'php/controller/profile-controller.php'; include_once 'php/controller/profile-controller.php';
$user = $user ?? null; $user = $user ?? null;
$isEditMode = isset($_GET["edit"]) && $_GET["edit"] === "1"; $isEditMode = (isset($_GET["edit"]) && $_GET["edit"] === "1") || !empty($error);
?> ?>
<main class="form-page"> <main class="form-page">
@@ -10,8 +10,8 @@ $isEditMode = isset($_GET["edit"]) && $_GET["edit"] === "1";
<div class="container"> <div class="container">
<?php if (isset($error) && $error): ?> <?php if (!empty($error)): ?>
<p style="color:red;"> <p class="alert-message is-error">
<?php echo htmlspecialchars($error); ?> <?php echo htmlspecialchars($error); ?>
</p> </p>
<?php endif; ?> <?php endif; ?>
@@ -22,7 +22,7 @@ $isEditMode = isset($_GET["edit"]) && $_GET["edit"] === "1";
<input type="text" <input type="text"
name="vorname" name="vorname"
class="login-input" class="login-input"
value="<?php echo htmlspecialchars($user["vorname"] ?? ""); ?>" value="<?php echo htmlspecialchars($_POST["vorname"] ?? $user["vorname"] ?? ""); ?>"
<?php echo $isEditMode ? "" : "readonly"; ?> <?php echo $isEditMode ? "" : "readonly"; ?>
required> required>
@@ -30,7 +30,7 @@ $isEditMode = isset($_GET["edit"]) && $_GET["edit"] === "1";
<input type="text" <input type="text"
name="nachname" name="nachname"
class="login-input" class="login-input"
value="<?php echo htmlspecialchars($user["nachname"] ?? ""); ?>" value="<?php echo htmlspecialchars($_POST["nachname"] ?? $user["nachname"] ?? ""); ?>"
<?php echo $isEditMode ? "" : "readonly"; ?> <?php echo $isEditMode ? "" : "readonly"; ?>
required> required>
@@ -38,18 +38,26 @@ $isEditMode = isset($_GET["edit"]) && $_GET["edit"] === "1";
<input type="email" <input type="email"
name="email" name="email"
class="login-input" class="login-input"
value="<?php echo htmlspecialchars($user["email"] ?? ""); ?>" value="<?php echo htmlspecialchars($_POST["email"] ?? $user["email"] ?? ""); ?>"
<?php echo $isEditMode ? "" : "readonly"; ?> <?php echo $isEditMode ? "" : "readonly"; ?>
required> required>
<label class="input-label"> <label class="input-label">
<?php echo $isEditMode ? "Neues Passwort" : "Passwort"; ?> <?php echo $isEditMode ? "Neues Passwort" : "Passwort"; ?>
</label> </label>
<?php if ($isEditMode): ?>
<input type="password" <input type="password"
name="password" name="password"
class="login-input" class="login-input"
placeholder="<?php echo $isEditMode ? "Leer lassen, wenn es gleich bleiben soll" : "********"; ?>" placeholder="Leer lassen, wenn es gleich bleiben soll">
<?php echo $isEditMode ? "" : "readonly"; ?>> <?php else: ?>
<input type="password"
name="password"
class="login-input"
value="********"
readonly>
<?php endif; ?>
<br><br> <br><br>
+9 -4
View File
@@ -1,16 +1,18 @@
<?php <?php
include_once 'php/controller/register-controller.php';
$error = $error ?? null; $error = $error ?? null;
?> ?>
<!--
Form: Registrierung
Funktion: Erstellung neuer Benutzerkonten
-->
<main class="login-page"> <main class="login-page">
<div class="login-container"> <div class="login-container">
<h1>Jetzt Registrieren!</h1> <h1>Jetzt Registrieren!</h1>
<?php if ($error): ?> <?php if (!empty($error)): ?>
<p style="color:red;"> <p class="alert-message is-error" style="color:red;">
<?php echo htmlspecialchars($error); ?> <?php echo htmlspecialchars($error); ?>
</p> </p>
<?php endif; ?> <?php endif; ?>
@@ -22,6 +24,7 @@ $error = $error ?? null;
name="email" name="email"
class="login-input" class="login-input"
placeholder="mustermann@web.de" placeholder="mustermann@web.de"
value="<?php echo htmlspecialchars($_POST["email"] ?? ""); ?>"
required> required>
<p class="input-label">Vorname:</p> <p class="input-label">Vorname:</p>
@@ -29,6 +32,7 @@ $error = $error ?? null;
name="vorname" name="vorname"
class="login-input" class="login-input"
placeholder="Max" placeholder="Max"
value="<?php echo htmlspecialchars($_POST["vorname"] ?? ""); ?>"
required> required>
<p class="input-label">Nachname:</p> <p class="input-label">Nachname:</p>
@@ -36,6 +40,7 @@ $error = $error ?? null;
name="nachname" name="nachname"
class="login-input" class="login-input"
placeholder="Mustermann" placeholder="Mustermann"
value="<?php echo htmlspecialchars($_POST["nachname"] ?? ""); ?>"
required> required>
<p class="input-label">Passwort:</p> <p class="input-label">Passwort:</p>
+50 -41
View File
@@ -1,10 +1,5 @@
<?php <?php
session_start(); session_start();
$results = $_SESSION["search_results"] ?? [];
$query = $_SESSION["search_query"] ?? "";
$resultCount = count($results);
?> ?>
<!-- <!--
Seite: Suchergebnisse Seite: Suchergebnisse
@@ -15,81 +10,95 @@ $resultCount = count($results);
<!-- Links: Seitenleiste für Filter und Suche --> <!-- Links: Seitenleiste für Filter und Suche -->
<aside class="s-res-sidebar"> <aside class="s-res-sidebar">
<!-- Sortierfuntion Box und Such Box--> <!-- Suchleiste Box -->
<form action="php/controller/search-results-controller.php" method="GET" class="s-res-sidebar-form">
<div class="s-res-sidebar-box"> <div class="s-res-sidebar-box">
<h3 class="s-res-sidebar-title">Suche anpassen</h3> <h3 class="s-res-sidebar-title">Suche anpassen</h3>
<input type="search" id="site-search" name="q" placeholder="Suchen..." class="nav__search" value="<?php echo htmlspecialchars($query); ?>" maxlength="50" required> <form action="#" method="GET" class="s-res-search-form">
<input type="search" id="site-search" name="q" placeholder="Suchen..." class="nav__search">
<button type="submit" class="nav__search-button">Suchen</button> <button type="submit" class="nav__search-button">Suchen</button>
</form>
</div> </div>
<!-- Sortierfuntion Box -->
<div class="s-res-sidebar-box"> <div class="s-res-sidebar-box">
<h3 class="s-res-sidebar-title">Sortierung</h3> <h3 class="s-res-sidebar-title">Sortierung</h3>
<?php $currentSort = $_SESSION['search_sort'] ?? 'alphabet'; ?>
<div class="s-res-filter-group"> <div class="s-res-filter-group">
<label class="s-res-filter-option"> <label class="s-res-filter-option">
<input type="radio" name="sort" value="alphabet" <?php echo $currentSort === 'alphabet' ? 'checked' : ''; ?> onchange="this.form.submit()"> <input type="radio" name="sort" value="alphabet" checked>
<span>Alphabetisch</span> <span>Alphabetisch</span>
</label> </label>
<!-- Noch disabled, da likes noch nicht implementiert-->
<label class="s-res-filter-option"> <label class="s-res-filter-option">
<input type="radio" name="sort" value="likes" <?php echo $currentSort === 'likes' ? 'checked' : ''; ?> disabled> <input type="radio" name="sort" value="likes">
<span style="color: #94a3b8;">Beliebtheit (Likes)</span> <span>Beliebtheit (Likes)</span>
</label> </label>
<label class="s-res-filter-option"> <label class="s-res-filter-option">
<input type="radio" name="sort" value="newest" <?php echo $currentSort === 'newest' ? 'checked' : ''; ?> onchange="this.form.submit()"> <input type="radio" name="sort" value="newest">
<span>Neueste Beiträge</span> <span>Neueste Beiträge</span>
</label> </label>
<label class="s-res-filter-option"> <label class="s-res-filter-option">
<input type="radio" name="sort" value="oldest" <?php echo $currentSort === 'oldest' ? 'checked' : ''; ?> onchange="this.form.submit()"> <input type="radio" name="sort" value="oldest">
<span>Älteste Beiträge</span> <span>Älteste Beiträge</span>
</label> </label>
</div> </div>
</div> </div>
</form>
</aside> </aside>
<main class="s-res-main-content"> <main class="s-res-main-content">
<div class="s-res-header"> <div class="s-res-header">
<h1 class="s-res-main-title">Suchergebnisse</h1> <h1 class="s-res-main-title">Suchergebnisse</h1>
<p class="s-res-meta"><?php echo $resultCount; ?> Treffer für Ihre Suchanfrage "<?php echo htmlspecialchars($query); ?>"</p> <p class="s-res-meta">3 Treffer für Ihre Suchanfrage</p>
</div> </div>
<!-- Ergebnisliste --> <!-- Ergebnisliste -->
<div class="s-res-list"> <div class="s-res-list">
<?php
if (!empty($results)): ?>
<?php foreach ($results as $item): ?>
<div class="s-res-item">
<div class="s-res-content">
<h2 class="s-res-item-title">
<a href="index.php?pfad=showArticle&id=<?php echo $item['id']; ?>" class="s-res-link">
<?php echo htmlspecialchars($item['title']); ?>
</a>
</h2>
<p class="s-res-author">Von: <span class="s-res-author-name"><?php echo htmlspecialchars($item['author']); ?></span></p>
</div>
<div class="s-res-arrow">&rarr;</div>
</div>
<?php endforeach; ?>
<?php <?php
elseif (isset($_SESSION["search_query"]) && $_SESSION["search_query"] !== "" && $resultCount === 0): ?> if(isset($_SESSION['message']) && $_SESSION['message'] == "new_search_results"): ?>
<p>Keine Beiträge zu diesem Suchbegriff gefunden.</p> <!-- TODO: Hier die Beiträge ausgeben. -->
<?php <?php elseif (isset($_SESSION["message"]) && $_SESSION["message"] == "missing_parameters"): ?>
elseif (isset($_SESSION["message"]) && $_SESSION["message"] == "missing_parameters"): ?> <p>
<p>Bitte überprüfe deine Sucheingabe und versuche es erneut!</p> Bitte überprüfe deine Sucheingabe und versuche es erneut!
</p>
<?php endif; ?> <?php endif; ?>
<?php <?php
unset($_SESSION["message"]); unset($_SESSION["message"]);
?> ?>
<!-- Beispielbeitrag -->
<div class="s-res-item">
<div class="s-res-content">
<h2 class="s-res-item-title">
<a href="#" class="s-res-link">Pythagoras</a>
</h2>
<p class="s-res-author">Von: <span class="s-res-author-name">Max Mustermann</span></p>
</div>
<div class="s-res-arrow">&rarr;</div>
</div>
<!-- Beispielbeitrag -->
<div class="s-res-item">
<div class="s-res-content">
<h2 class="s-res-item-title">
<a href="#" class="s-res-link">Pythagoras</a>
</h2>
<p class="s-res-author">Von: <span class="s-res-author-name">Max Mustermann</span></p>
</div>
<div class="s-res-arrow">&rarr;</div>
</div>
<!-- Beispielbeitrag -->
<div class="s-res-item">
<div class="s-res-content">
<h2 class="s-res-item-title">
<a href="#" class="s-res-link">Pythagoras</a>
</h2>
<p class="s-res-author">Von: <span class="s-res-author-name">Max Mustermann</span></p>
</div>
<div class="s-res-arrow">&rarr;</div>
</div>
</div> </div>
<div class="s-res-pagination-footer"> <div class="s-res-pagination-footer">
+2 -7
View File
@@ -2,10 +2,5 @@
Suchleiste. Wird via PHP später in alle Seiten eingebunden Suchleiste. Wird via PHP später in alle Seiten eingebunden
--> -->
<!--<label for="site-search">Suche</label>--> <!--<label for="site-search">Suche</label>-->
<form action="php/controller/search-results-controller.php" method="GET" class="search-form" style="display: flex; align-items: center; gap: 5px;"> <input type="search" id="site-search" name="q" placeholder="Suchen..." class="nav__search">
<button type="submit" class="nav__search-button">Suchen</button>
<input type="hidden" name="pfad" value="search-results">
<input type="search" id="site-search" name="q" placeholder="Suchen..." class="nav__search" maxlength="50" required>
<button type="submit" class="nav__search-button">Suchen</button>
</form>
+3 -9
View File
@@ -1,4 +1,3 @@
<?php <?php
session_start(); session_start();
ob_start(); ob_start();
@@ -52,8 +51,8 @@ if ($pfad === "deleteAccount") {
<title>EduForge</title> <title>EduForge</title>
</head> </head>
<body>
<body>
<?php <?php
include_once 'includes/navbar.php'; include_once 'includes/navbar.php';
@@ -61,20 +60,15 @@ if ($pfad === "deleteAccount") {
Dynamischer Inhalt: Dynamischer Inhalt:
Je nach pfad-Parameter wird die passende Datei aus content geladen. Je nach pfad-Parameter wird die passende Datei aus content geladen.
*/ */
if (isset($_GET["pfad"])) { if (file_exists('content/' . $pfad . '.php')) {
if (file_exists('content/' . $_GET["pfad"] . '.php')) { include_once 'content/' . $pfad . '.php';
include_once 'content/' . $_GET["pfad"] . '.php';
} else { } else {
include_once 'content/404.php'; include_once 'content/404.php';
} }
} else {
include_once 'content/home.php';
}
include_once 'includes/footer.php'; include_once 'includes/footer.php';
?> ?>
</body> </body>
</html> </html>
+24 -42
View File
@@ -1,8 +1,9 @@
<?php <?php
require_once "php/model/LocalUserDAO.php"; require_once "php/model/LocalUserDAO.php";
require_once 'php/model/Article.php'; require_once "php/model/Article.php";
require_once 'php/model/ArticleManager.php'; require_once "php/model/ArticleManager.php";
require_once "php/validator/user-validator.php";
$error = null; $error = null;
@@ -11,34 +12,6 @@ if (!isset($_SESSION["user"])) {
exit(); exit();
} }
/*
* Prüft Vor- und Nachnamen.
* Erlaubt sind Buchstaben, Umlaute, Leerzeichen und Bindestriche.
*/
function isValidName($name): bool {
return preg_match("/^[a-zA-ZäöüÄÖÜß -]{2,50}$/", $name);
}
/*
* Prüft, ob die E-Mail-Adresse ein gültiges Format hat.
*/
function isValidEmailAddress($email): bool {
return filter_var($email, FILTER_VALIDATE_EMAIL) !== false
&& strlen($email) <= 100;
}
/*
* Prüft das neue Passwort.
* Leeres Passwort ist erlaubt, wenn der Nutzer es nicht ändern möchte.
*/
function isValidProfilePassword($password): bool {
if ($password === "") {
return true;
}
return strlen($password) >= 8 && strlen($password) <= 72;
}
try { try {
$dao = new LocalUserDAO(); $dao = new LocalUserDAO();
@@ -60,19 +33,22 @@ try {
$nachname = trim($_POST["nachname"] ?? ""); $nachname = trim($_POST["nachname"] ?? "");
$password = $_POST["password"] ?? ""; $password = $_POST["password"] ?? "";
if (!isValidName($vorname)) { if (!userEmailValidator($newEmail)) {
$error = "Der Vorname darf nur Buchstaben, Leerzeichen und Bindestriche enthalten und muss 2 bis 50 Zeichen lang sein.";
} elseif (!isValidName($nachname)) {
$error = "Der Nachname darf nur Buchstaben, Leerzeichen und Bindestriche enthalten und muss 2 bis 50 Zeichen lang sein.";
} elseif (!isValidEmailAddress($newEmail)) {
$error = "Bitte gib eine gültige E-Mail-Adresse ein."; $error = "Bitte gib eine gültige E-Mail-Adresse ein.";
} elseif (!isValidProfilePassword($password)) { $_GET["edit"] = "1";
$error = "Das Passwort muss mindestens 8 Zeichen lang sein.";
} else { } elseif (!userNameValidator($vorname)) {
$existingUser = $dao->findUser($newEmail); $error = "Der Vorname muss 2 bis 50 Zeichen lang sein und darf nur Buchstaben, Leerzeichen und Bindestriche enthalten.";
$_GET["edit"] = "1";
} elseif (!userNameValidator($nachname)) {
$error = "Der Nachname muss 2 bis 50 Zeichen lang sein und darf nur Buchstaben, Leerzeichen und Bindestriche enthalten.";
$_GET["edit"] = "1";
} elseif (!userOptionalPasswordValidator($password)) {
$error = "Das Passwort muss 8 bis 72 Zeichen lang sein.";
$_GET["edit"] = "1";
if ($existingUser && $newEmail !== $oldEmail) {
$error = "Diese E-Mail-Adresse wird bereits verwendet.";
} else { } else {
$updated = $dao->updateUser( $updated = $dao->updateUser(
$oldEmail, $oldEmail,
@@ -90,7 +66,7 @@ try {
exit(); exit();
} else { } else {
$error = "Die Daten konnten nicht gespeichert werden."; $error = "Die Daten konnten nicht gespeichert werden.";
} $_GET["edit"] = "1";
} }
} }
} }
@@ -104,6 +80,12 @@ try {
$_SESSION["message"] = "user_has_no_articles"; $_SESSION["message"] = "user_has_no_articles";
} }
} catch (InvalidArgumentException $e) {
$error = $e->getMessage();
$_GET["edit"] = "1";
} catch (Exception $e) { } catch (Exception $e) {
$error = "Es ist ein interner Fehler aufgetreten. Bitte versuche es erneut.";
$_SESSION["message"] = "internal_error"; $_SESSION["message"] = "internal_error";
$_GET["edit"] = "1";
} }
+24 -18
View File
@@ -1,37 +1,43 @@
<?php <?php
require_once "php/model/LocalUserDAO.php"; require_once "php/model/LocalUserDAO.php";
require_once "php/validator/user-validator.php";
$dao = new LocalUserDAO();
$error = null; $error = null;
if ($_SERVER["REQUEST_METHOD"] === "POST") { if ($_SERVER["REQUEST_METHOD"] === "POST") {
$email = $_POST["email"] ?? ""; $email = trim($_POST["email"] ?? "");
$vorname = $_POST["vorname"] ?? ""; $vorname = trim($_POST["vorname"] ?? "");
$nachname = $_POST["nachname"] ?? ""; $nachname = trim($_POST["nachname"] ?? "");
$password = password_hash( $plainPassword = $_POST["password"] ?? "";
$_POST["password"] ?? "",
PASSWORD_DEFAULT
);
if ($dao->findUser($email)) {
$error = "Diese E-Mail-Adresse ist bereits registriert.";
if (!userEmailValidator($email)) {
$error = "Bitte gib eine gültige E-Mail-Adresse ein.";
} elseif (!userNameValidator($vorname)) {
$error = "Der Vorname muss 2 bis 50 Zeichen lang sein und darf nur Buchstaben, Umlaute, Leerzeichen und Bindestriche enthalten.";
} elseif (!userNameValidator($nachname)) {
$error = "Der Nachname muss 2 bis 50 Zeichen lang sein und darf nur Buchstaben, Umlaute, Leerzeichen und Bindestriche enthalten.";
} elseif (!userPasswordValidator($plainPassword)) {
$error = "Das Passwort muss 8 bis 72 Zeichen lang sein.";
} else { } else {
try {
$dao = new LocalUserDAO();
$dao->addUser( $password = password_hash($plainPassword, PASSWORD_DEFAULT);
$email,
$vorname, $dao->addUser($email, $vorname, $nachname, $password);
$nachname,
$password
);
$_SESSION["user"] = $vorname . " " . $nachname; $_SESSION["user"] = $vorname . " " . $nachname;
$_SESSION["user_email"] = $email; $_SESSION["user_email"] = $email;
header("Location: index.php"); header("Location: index.php");
exit(); exit();
} catch (InvalidArgumentException $e) {
$error = $e->getMessage();
} catch (Exception $e) {
$error = "Die Registrierung konnte nicht gespeichert werden.";
}
} }
} }
+12 -51
View File
@@ -2,67 +2,28 @@
session_start(); session_start();
require_once '../model/LocalArticleManager.php'; require_once '../model/LocalArticleManager.php';
require_once '../model/ArticleManager.php'; require_once '../model/ArticleManager.php';
require_once '../model/Article.php';
if ($_SERVER["REQUEST_METHOD"] === "GET" && isset($_GET["q"])) { if ($_SERVER["REQUEST_METHOD"] === "POST") {
if(!isset($_POST["search"])){
$search = trim($_GET["q"]);
if (empty($search)) {
$_SESSION["search_results"] = [];
$_SESSION["search_query"] = "";
$_SESSION["message"] = "missing_parameters"; $_SESSION["message"] = "missing_parameters";
header("location: ../../index.php?pfad=search-results");
} else { } else {
$search = $_POST["search"];
try { try {
$articleManager = ArticleManager::getInstance(); $articleManager = ArticleManager::getInstance();
$articleManager->search($search); // TODO: Methode implementieren.
$results = $articleManager->search($search);
$sortStyle = $_GET['sort'] ?? 'alphabet';
$_SESSION['search_sort'] = $sortStyle;
if ($sortStyle === 'alphabet') {
// Titel aufsteigend alphabetiisch sortiert
usort($results, function($a, $b) {
return strcasecmp($a->title, $b->title);
});
} elseif ($sortStyle === 'newest') {
// Datum neu zu alt sortiert
usort($results, function($a, $b) {
return strcmp($b->creationDate, $a->creationDate);
});
} elseif ($sortStyle === 'oldest') {
// Datum alt zu neu sortiert
usort($results, function($a, $b) {
return strcmp($a->creationDate, $b->creationDate);
});
}
// Ergebnisse werden in ein flaches array umgewandelt, da sont incomplete-PHP error im Ergebnis
$safeArrayResults = [];
foreach ($results as $obj) {
$safeArrayResults[] = [
"id" => $obj->id,
"title" => $obj->title,
"content" => $obj->content,
"author" => $obj->author,
"category" => $obj->category,
"tags" => $obj->tags,
"creationDate" => $obj->creationDate
];
}
$_SESSION["search_results"] = $safeArrayResults;
$_SESSION["search_query"] = $search;
$_SESSION["message"] = "new_search_results";
} catch (Exception $e){ } catch (Exception $e){
$_SESSION["message"] = "internal_error"; $_SESSION["message"] = "internal_error";
} }
} $_SESSION["message"] = "new_search_results";
header("Location: ../../index.php?pfad=search-results"); // TODO: Liste mit Artikeln in der Suchreihenfolge übertragen.
// Weiterleitung zur Suchergebnisanzeige
header("location: ../../index.php?pfad=search-results");
exit(); exit();
}
} }
?> ?>
+7 -7
View File
@@ -7,13 +7,13 @@
*/ */
class Article class Article
{ {
public $id; private $id;
public $title; private $title;
public $content; private $content;
public $author; private $author;
public $creationDate; private $creationDate;
public $category; private $category;
public $tags; private $tags;
/** /**
* Konstruktor * Konstruktor
-1
View File
@@ -44,5 +44,4 @@ class ArticleManager extends LocalArticleManager
return $articleManager; return $articleManager;
} }
} }
-10
View File
@@ -76,15 +76,5 @@ interface ArticleManagerDAO
*/ */
public function getArticlesByAuthor($author); public function getArticlesByAuthor($author);
/**
* Durchsucht die vorhandenen Beiträge nach einem bestimmten Suchbegriff.
* Die Suche prüft, ob das übergebene Keyword im Titel oder im Inhalt eines Beitrags vorkommt.
* (Unabhängig von Groß-und Kleinschreibung)
* @param string $keyword Der eingegebene Suchbegriff.
* @return array Ein Array von Artikeln ,die dem Suchkriterium entsprechen. Wenn nichts gefunden wird, ein leeres Array.
*/
public function search(string $keyword): array;
} }
?> ?>
-35
View File
@@ -166,40 +166,5 @@ class LocalArticleManager implements ArticleManagerDAO {
} }
return $filteredArticles; return $filteredArticles;
} }
public function search(string $keyword): array
{
$articles = $this->getAllArticles();
$filteredArticles = [];
if (!is_array($articles)) {
return [];
}
$cleanKeyword = strtolower(trim($keyword));
foreach ($articles as $article) {
$title = isset($article['title']) ? strtolower((string)$article['title']) : '';
$content = isset($article['content']) ? strtolower((string)$article['content']) : '';
if (($cleanKeyword !== '' && strpos($title, $cleanKeyword) !== false) ||
($cleanKeyword !== '' && strpos($content, $cleanKeyword) !== false)) {
$filteredArticles[] = new Article(
intval($article['id'] ?? 0),
$article['title'] ?? '',
$article['content'] ?? '',
$article['author'] ?? '',
$article['category'] ?? '',
$article['tags'] ?? '',
$article['creationDate'] ?? ''
);
}
}
return $filteredArticles;
}
} }
?> ?>
+58 -38
View File
@@ -6,6 +6,13 @@ class LocalUserDAO implements UserDAOInterface {
private string $file = "data/users.json"; private string $file = "data/users.json";
/**
* Lädt alle Benutzer aus der JSON-Datei.
*
* @return array Liste aller Benutzer
* @throws RuntimeException wenn die Datei nicht gelesen werden kann
* oder fehlerhafte JSON-Daten enthält
*/
private function loadUsers() { private function loadUsers() {
if (!file_exists($this->file)) { if (!file_exists($this->file)) {
return []; return [];
@@ -26,40 +33,35 @@ class LocalUserDAO implements UserDAOInterface {
return is_array($users) ? $users : []; return is_array($users) ? $users : [];
} }
/**
* Speichert alle Benutzer in die JSON-Datei.
*
* @param array $users Liste aller Benutzer
* @return void
* @throws RuntimeException wenn die Daten nicht gespeichert werden können
*/
private function saveUsers($users) { private function saveUsers($users) {
$result = file_put_contents( $json = json_encode($users, JSON_PRETTY_PRINT);
$this->file,
json_encode($users, JSON_PRETTY_PRINT) if ($json === false) {
); throw new RuntimeException("Benutzerdaten konnten nicht umgewandelt werden.");
}
$result = file_put_contents($this->file, $json);
if ($result === false) { if ($result === false) {
throw new RuntimeException("Benutzerdaten konnten nicht gespeichert werden."); throw new RuntimeException("Benutzerdaten konnten nicht gespeichert werden.");
} }
} }
private function validateEmail($email) { /**
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { * Sucht einen Benutzer anhand seiner E-Mail-Adresse.
throw new InvalidArgumentException("Ungültige E-Mail-Adresse."); *
} * @param string $email E-Mail-Adresse des gesuchten Benutzers
} * @return array|null Benutzerdaten oder null, wenn kein Benutzer gefunden wurde
* @throws RuntimeException wenn die Benutzerdaten nicht gelesen werden können
private function validateName($name, $fieldName) { */
if (!preg_match("/^[a-zA-ZäöüÄÖÜß -]{2,50}$/", $name)) {
throw new InvalidArgumentException(
$fieldName . " darf nur Buchstaben, Leerzeichen und Bindestriche enthalten."
);
}
}
private function validatePassword($password) {
if (empty($password)) {
throw new InvalidArgumentException("Passwort darf nicht leer sein.");
}
}
public function findUser($email) { public function findUser($email) {
$this->validateEmail($email);
$users = $this->loadUsers(); $users = $this->loadUsers();
foreach ($users as $user) { foreach ($users as $user) {
@@ -78,12 +80,18 @@ class LocalUserDAO implements UserDAOInterface {
return null; return null;
} }
/**
* Fügt einen neuen Benutzer hinzu.
*
* @param string $email E-Mail-Adresse
* @param string $vorname Vorname
* @param string $nachname Nachname
* @param string $password Passwort-Hash
* @return void
* @throws InvalidArgumentException wenn die E-Mail-Adresse bereits verwendet wird
* @throws RuntimeException wenn die Benutzerdaten nicht gelesen oder gespeichert werden können
*/
public function addUser($email, $vorname, $nachname, $password) { public function addUser($email, $vorname, $nachname, $password) {
$this->validateEmail($email);
$this->validateName($vorname, "Vorname");
$this->validateName($nachname, "Nachname");
$this->validatePassword($password);
$users = $this->loadUsers(); $users = $this->loadUsers();
foreach ($users as $user) { foreach ($users as $user) {
@@ -102,12 +110,19 @@ class LocalUserDAO implements UserDAOInterface {
$this->saveUsers($users); $this->saveUsers($users);
} }
/**
* Aktualisiert einen bestehenden Benutzer.
*
* @param string $oldEmail Alte E-Mail-Adresse
* @param string $newEmail Neue E-Mail-Adresse
* @param string $vorname Neuer Vorname
* @param string $nachname Neuer Nachname
* @param string|null $password Neues Passwort oder null
* @return bool true, wenn der Benutzer aktualisiert wurde, sonst false
* @throws InvalidArgumentException wenn die neue E-Mail-Adresse bereits verwendet wird
* @throws RuntimeException wenn die Benutzerdaten nicht gelesen oder gespeichert werden können
*/
public function updateUser($oldEmail, $newEmail, $vorname, $nachname, $password = null) { public function updateUser($oldEmail, $newEmail, $vorname, $nachname, $password = null) {
$this->validateEmail($oldEmail);
$this->validateEmail($newEmail);
$this->validateName($vorname, "Vorname");
$this->validateName($nachname, "Nachname");
$users = $this->loadUsers(); $users = $this->loadUsers();
foreach ($users as $user) { foreach ($users as $user) {
@@ -140,9 +155,14 @@ class LocalUserDAO implements UserDAOInterface {
return false; return false;
} }
/**
* Löscht einen Benutzer anhand seiner E-Mail-Adresse.
*
* @param string $email E-Mail-Adresse des zu löschenden Benutzers
* @return bool true, wenn der Benutzer gelöscht wurde, sonst false
* @throws RuntimeException wenn die Benutzerdaten nicht gelesen oder gespeichert werden können
*/
public function deleteUser($email) { public function deleteUser($email) {
$this->validateEmail($email);
$users = $this->loadUsers(); $users = $this->loadUsers();
foreach ($users as $i => $user) { foreach ($users as $i => $user) {
+5 -11
View File
@@ -21,7 +21,6 @@ interface UserDAOInterface {
* @return array|null Benutzerdaten als Array oder null * @return array|null Benutzerdaten als Array oder null
* *
* Mögliche Fehler: * Mögliche Fehler:
* @throws InvalidArgumentException wenn die E-Mail-Adresse ungültig ist
* @throws RuntimeException wenn die Benutzerdaten nicht gelesen werden können * @throws RuntimeException wenn die Benutzerdaten nicht gelesen werden können
*/ */
public function findUser($email); public function findUser($email);
@@ -43,9 +42,8 @@ interface UserDAOInterface {
* @return void * @return void
* *
* Mögliche Fehler: * Mögliche Fehler:
* @throws InvalidArgumentException wenn Eingabedaten ungültig sind * @throws InvalidArgumentException wenn die E-Mail-Adresse bereits verwendet wird
* oder die E-Mail-Adresse bereits verwendet wird * @throws RuntimeException wenn die Benutzerdaten nicht gelesen oder gespeichert werden können
* @throws RuntimeException wenn die Benutzerdaten nicht gespeichert werden können
*/ */
public function addUser($email, $vorname, $nachname, $password); public function addUser($email, $vorname, $nachname, $password);
@@ -67,10 +65,8 @@ interface UserDAOInterface {
* @return bool true, wenn der Benutzer aktualisiert wurde, sonst false * @return bool true, wenn der Benutzer aktualisiert wurde, sonst false
* *
* Mögliche Fehler: * Mögliche Fehler:
* @throws InvalidArgumentException wenn Eingabedaten ungültig sind * @throws InvalidArgumentException wenn die neue E-Mail-Adresse bereits verwendet wird
* oder die neue E-Mail-Adresse bereits verwendet wird * @throws RuntimeException wenn die Benutzerdaten nicht gelesen oder gespeichert werden können
* @throws RuntimeException wenn die Benutzerdaten nicht gelesen
* oder gespeichert werden können
*/ */
public function updateUser($oldEmail, $newEmail, $vorname, $nachname, $password = null); public function updateUser($oldEmail, $newEmail, $vorname, $nachname, $password = null);
@@ -87,9 +83,7 @@ interface UserDAOInterface {
* @return bool true, wenn der Benutzer gelöscht wurde, sonst false * @return bool true, wenn der Benutzer gelöscht wurde, sonst false
* *
* Mögliche Fehler: * Mögliche Fehler:
* @throws InvalidArgumentException wenn die E-Mail-Adresse ungültig ist * @throws RuntimeException wenn die Benutzerdaten nicht gelesen oder gespeichert werden können
* @throws RuntimeException wenn die Benutzerdaten nicht gelesen
* oder gespeichert werden können
*/ */
public function deleteUser($email); public function deleteUser($email);
} }
+33
View File
@@ -0,0 +1,33 @@
<?php
function userNameValidator($name)
{
$name = trim($name);
$namePattern = '/^[a-zA-ZäöüÄÖÜß\s-]{2,50}$/u';
return preg_match($namePattern, $name) === 1;
}
function userEmailValidator($email)
{
$email = trim($email);
return filter_var($email, FILTER_VALIDATE_EMAIL) !== false
&& mb_strlen($email) <= 100;
}
function userPasswordValidator($password)
{
$zeichenAnzahl = mb_strlen($password);
return $zeichenAnzahl >= 8 && $zeichenAnzahl <= 72;
}
function userOptionalPasswordValidator($password)
{
if (!isset($password) || $password === '') {
return true;
}
return userPasswordValidator($password);
}