Compare commits

..

57 Commits

Author SHA1 Message Date
niklas.ortmann 1343496a12 Merge pull request 'Vor und Nachname separat speichern sowie Profilbearbeitung' (#18) from Profilbearbeitung into dev
Reviewed-on: #18
2026-06-03 20:13:03 +02:00
niklas.ortmann 1735dd28a2 Update README.md 2026-06-03 20:12:14 +02:00
niklas.ortmann 9c3ebc9877 Merge pull request 'WIP Suche implementiert, sowie Sortieren der Ergebnisse' (#19) from ImplementedSearch into dev
Reviewed-on: #19
2026-06-03 16:07:41 +02:00
rirat-0 3d13c3b8c8 Design Anpassung der search in navbar 2026-06-03 07:59:39 +02:00
rirat-0 6c3e788f13 Limitation der eingabefelder auf 50 zeichen 2026-06-03 03:03:37 +02:00
rirat-0 aceac0bf8b aufraeumen 7 2026-06-03 02:52:22 +02:00
rirat-0 78d04f1715 aufraeumen 6 2026-06-03 02:48:11 +02:00
rirat-0 1d773ea4e6 Funktionalitaet der sortierung 2026-06-03 02:44:59 +02:00
rirat-0 a595567db1 funktionale suche der sidebox 2026-06-03 02:39:03 +02:00
rirat-0 945d3e1c1f aufraeumen 5 2026-06-03 02:28:45 +02:00
rirat-0 d58ea953af aufraeumen 4 2026-06-03 02:02:54 +02:00
rirat-0 b9475a045f aufraeumen 3 2026-06-03 01:58:02 +02:00
rirat-0 32c2a1a3d8 aufraeumen 2 2026-06-03 01:56:57 +02:00
rirat-0 fc93f2b3f0 aufraeumen 2026-06-03 01:55:33 +02:00
rirat-0 f33778f97a fehlersuche 12 2026-06-03 01:51:26 +02:00
rirat-0 1c72a03f26 fehlersuche 11 2026-06-03 01:48:00 +02:00
rirat-0 3dcbdbf23c fehlersuche 10 2026-06-03 01:45:04 +02:00
rirat-0 8143d501fa fehlersuche 9 2026-06-03 01:42:09 +02:00
rirat-0 3471eedf4a fehlersuche 8 2026-06-03 01:17:38 +02:00
rirat-0 b6a3dad2ab fehlersuche 7 2026-06-03 01:08:14 +02:00
rirat-0 375e6d9625 fehlersuche 6 2026-06-03 00:45:57 +02:00
rirat-0 4d144ec704 fehlersuche 5 2026-06-03 00:44:57 +02:00
rirat-0 370c047c16 fehlersuche 4 2026-06-02 18:06:45 +02:00
rirat-0 a562a67923 fehlersuche 3 2026-06-02 18:02:40 +02:00
rirat-0 078dbd8901 fehlersuche 2 2026-06-02 18:01:14 +02:00
rirat-0 64d624a6df fehlersuche 1 2026-06-02 18:00:01 +02:00
rirat-0 90ab57e4cb Mehrere anpassungen, damit ergebnisse angezeigt werden 2026-06-02 17:53:04 +02:00
rirat-0 a00ddf18e6 update der pfade 2026-06-02 17:19:03 +02:00
rirat-0 5048dc2466 weitere anpassungen der such funktion 2026-06-02 17:16:57 +02:00
rirat-0 7209fe3e20 article.php wird nun genutzt im search results controller 2026-06-02 17:14:45 +02:00
rirat-0 4e35e67ef1 anpassung von der search function 2026-06-02 17:06:41 +02:00
rirat-0 830b57d245 anpassung der such funktion 2026-06-02 17:03:06 +02:00
rirat-0 06930644a6 Implementierung von neuem such algorithmus und entsprechenden anpassungen in anderen dateien 2026-06-02 16:58:12 +02:00
niklas.ortmann 8e3642c668 Merge branch 'dev' into ImplementedSearch 2026-06-02 14:48:37 +02:00
rirat-0 87d78b749b Finale Aktualisierung 2026-06-02 14:09:06 +02:00
rirat-0 604dbeca93 Aktualisierung 2026-06-02 14:07:33 +02:00
rirat-0 8e9e7d65d0 noch mehr debugging 2026-06-02 13:59:21 +02:00
rirat-0 e2c317e507 mehr debugging 2026-06-02 13:57:30 +02:00
rirat-0 5a7fa35465 test mit absoluten pfaden 2026-06-02 13:55:58 +02:00
rirat-0 2601a1c1ca naechster debugging versuch 2026-06-02 13:54:04 +02:00
rirat-0 0e26679f24 anpassung beider article manager 2026-06-02 13:48:51 +02:00
rirat-0 d5ab659217 anpassung von article managerdao 2026-06-02 13:44:37 +02:00
rirat-0 2d5919d572 alte aenderung reverted 2026-06-02 13:41:51 +02:00
rirat-0 f56a074a3c search results controller wird ueber die results seite geladen 2026-06-02 13:38:19 +02:00
rirat-0 24dc432f01 entfernung mancher aenderungen 2026-06-02 13:26:11 +02:00
rirat-0 016193de07 weitere anpassung von index.php 2026-06-02 13:24:17 +02:00
rirat-0 f04d8fecd3 Anpassung der index.php damit der richtige controller geladen wird 2026-06-02 13:20:54 +02:00
rirat-0 36276c7c88 debug versuch nr.5 2026-06-02 13:16:53 +02:00
rirat-0 4a2cf0b55b 4. versuch 2026-06-02 13:14:04 +02:00
rirat-0 400436a73f 3. versuch die homepage zu reparieren 2026-06-02 13:13:02 +02:00
rirat-0 4c378dfba6 2. versuch das problem der homepage zu loesen 2026-06-02 13:08:17 +02:00
rirat-0 c3a9de71f4 1. versuch, das problem der homepage zu beheben 2026-06-02 13:06:29 +02:00
rirat-0 ecf2e9ef57 Update von ArticleManagerDAO, damit die search Methode auch genutzt werden kann 2026-06-02 13:00:21 +02:00
rirat-0 45ac70eba2 Weitere Anpassung der search.php 2026-06-02 12:54:15 +02:00
rirat-0 3b66c6aa3a aenderung des such formulars um korrekte action zu nutzen 2026-06-02 12:49:24 +02:00
rirat-0 e37b882481 anpassung von controllern und results
search function implementiert, search controller entsprechend angepasst und die results seite angepasst
2026-06-02 12:43:59 +02:00
rirat-0 b328c2613c search.php form erstellt 2026-06-01 21:04:37 +02:00
16 changed files with 332 additions and 287 deletions
+6
View File
@@ -10,12 +10,15 @@ 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.
@@ -23,3 +26,6 @@ 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)
+11 -19
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") || !empty($error); $isEditMode = isset($_GET["edit"]) && $_GET["edit"] === "1";
?> ?>
<main class="form-page"> <main class="form-page">
@@ -10,8 +10,8 @@ $isEditMode = (isset($_GET["edit"]) && $_GET["edit"] === "1") || !empty($error);
<div class="container"> <div class="container">
<?php if (!empty($error)): ?> <?php if (isset($error) && $error): ?>
<p class="alert-message is-error"> <p style="color:red;">
<?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") || !empty($error);
<input type="text" <input type="text"
name="vorname" name="vorname"
class="login-input" class="login-input"
value="<?php echo htmlspecialchars($_POST["vorname"] ?? $user["vorname"] ?? ""); ?>" value="<?php echo htmlspecialchars($user["vorname"] ?? ""); ?>"
<?php echo $isEditMode ? "" : "readonly"; ?> <?php echo $isEditMode ? "" : "readonly"; ?>
required> required>
@@ -30,7 +30,7 @@ $isEditMode = (isset($_GET["edit"]) && $_GET["edit"] === "1") || !empty($error);
<input type="text" <input type="text"
name="nachname" name="nachname"
class="login-input" class="login-input"
value="<?php echo htmlspecialchars($_POST["nachname"] ?? $user["nachname"] ?? ""); ?>" value="<?php echo htmlspecialchars($user["nachname"] ?? ""); ?>"
<?php echo $isEditMode ? "" : "readonly"; ?> <?php echo $isEditMode ? "" : "readonly"; ?>
required> required>
@@ -38,26 +38,18 @@ $isEditMode = (isset($_GET["edit"]) && $_GET["edit"] === "1") || !empty($error);
<input type="email" <input type="email"
name="email" name="email"
class="login-input" class="login-input"
value="<?php echo htmlspecialchars($_POST["email"] ?? $user["email"] ?? ""); ?>" value="<?php echo htmlspecialchars($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>
<input type="password"
<?php if ($isEditMode): ?> name="password"
<input type="password" class="login-input"
name="password" placeholder="<?php echo $isEditMode ? "Leer lassen, wenn es gleich bleiben soll" : "********"; ?>"
class="login-input" <?php echo $isEditMode ? "" : "readonly"; ?>>
placeholder="Leer lassen, wenn es gleich bleiben soll">
<?php else: ?>
<input type="password"
name="password"
class="login-input"
value="********"
readonly>
<?php endif; ?>
<br><br> <br><br>
+4 -9
View File
@@ -1,18 +1,16 @@
<?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 (!empty($error)): ?> <?php if ($error): ?>
<p class="alert-message is-error" style="color:red;"> <p style="color:red;">
<?php echo htmlspecialchars($error); ?> <?php echo htmlspecialchars($error); ?>
</p> </p>
<?php endif; ?> <?php endif; ?>
@@ -24,7 +22,6 @@ $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>
@@ -32,7 +29,6 @@ $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>
@@ -40,7 +36,6 @@ $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>
+61 -70
View File
@@ -1,5 +1,10 @@
<?php <?php
session_start(); session_start();
$results = $_SESSION["search_results"] ?? [];
$query = $_SESSION["search_query"] ?? "";
$resultCount = count($results);
?> ?>
<!-- <!--
Seite: Suchergebnisse Seite: Suchergebnisse
@@ -10,37 +15,40 @@ session_start();
<!-- Links: Seitenleiste für Filter und Suche --> <!-- Links: Seitenleiste für Filter und Suche -->
<aside class="s-res-sidebar"> <aside class="s-res-sidebar">
<!-- Suchleiste Box --> <!-- Sortierfuntion Box und Such Box-->
<div class="s-res-sidebar-box"> <form action="php/controller/search-results-controller.php" method="GET" class="s-res-sidebar-form">
<h3 class="s-res-sidebar-title">Suche anpassen</h3>
<form action="#" method="GET" class="s-res-search-form"> <div class="s-res-sidebar-box">
<input type="search" id="site-search" name="q" placeholder="Suchen..." class="nav__search"> <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>
<button type="submit" class="nav__search-button">Suchen</button> <button type="submit" class="nav__search-button">Suchen</button>
</form>
</div>
<!-- Sortierfuntion Box -->
<div class="s-res-sidebar-box">
<h3 class="s-res-sidebar-title">Sortierung</h3>
<div class="s-res-filter-group">
<label class="s-res-filter-option">
<input type="radio" name="sort" value="alphabet" checked>
<span>Alphabetisch</span>
</label>
<label class="s-res-filter-option">
<input type="radio" name="sort" value="likes">
<span>Beliebtheit (Likes)</span>
</label>
<label class="s-res-filter-option">
<input type="radio" name="sort" value="newest">
<span>Neueste Beiträge</span>
</label>
<label class="s-res-filter-option">
<input type="radio" name="sort" value="oldest">
<span>Älteste Beiträge</span>
</label>
</div> </div>
</div>
<div class="s-res-sidebar-box">
<h3 class="s-res-sidebar-title">Sortierung</h3>
<?php $currentSort = $_SESSION['search_sort'] ?? 'alphabet'; ?>
<div class="s-res-filter-group">
<label class="s-res-filter-option">
<input type="radio" name="sort" value="alphabet" <?php echo $currentSort === 'alphabet' ? 'checked' : ''; ?> onchange="this.form.submit()">
<span>Alphabetisch</span>
</label>
<!-- Noch disabled, da likes noch nicht implementiert-->
<label class="s-res-filter-option">
<input type="radio" name="sort" value="likes" <?php echo $currentSort === 'likes' ? 'checked' : ''; ?> disabled>
<span style="color: #94a3b8;">Beliebtheit (Likes)</span>
</label>
<label class="s-res-filter-option">
<input type="radio" name="sort" value="newest" <?php echo $currentSort === 'newest' ? 'checked' : ''; ?> onchange="this.form.submit()">
<span>Neueste Beiträge</span>
</label>
<label class="s-res-filter-option">
<input type="radio" name="sort" value="oldest" <?php echo $currentSort === 'oldest' ? 'checked' : ''; ?> onchange="this.form.submit()">
<span>Älteste Beiträge</span>
</label>
</div>
</div>
</form>
</aside> </aside>
@@ -48,57 +56,40 @@ session_start();
<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">3 Treffer für Ihre Suchanfrage</p> <p class="s-res-meta"><?php echo $resultCount; ?> Treffer für Ihre Suchanfrage "<?php echo htmlspecialchars($query); ?>"</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
if(isset($_SESSION['message']) && $_SESSION['message'] == "new_search_results"): ?> elseif (isset($_SESSION["search_query"]) && $_SESSION["search_query"] !== "" && $resultCount === 0): ?>
<!-- TODO: Hier die Beiträge ausgeben. --> <p>Keine Beiträge zu diesem Suchbegriff gefunden.</p>
<?php elseif (isset($_SESSION["message"]) && $_SESSION["message"] == "missing_parameters"): ?> <?php
<p> elseif (isset($_SESSION["message"]) && $_SESSION["message"] == "missing_parameters"): ?>
Bitte überprüfe deine Sucheingabe und versuche es erneut! <p>Bitte überprüfe deine Sucheingabe und versuche es erneut!</p>
</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">
+7 -2
View File
@@ -2,5 +2,10 @@
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>-->
<input type="search" id="site-search" name="q" placeholder="Suchen..." class="nav__search"> <form action="php/controller/search-results-controller.php" method="GET" class="search-form" style="display: flex; align-items: center; gap: 5px;">
<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>
+10 -4
View File
@@ -1,3 +1,4 @@
<?php <?php
session_start(); session_start();
ob_start(); ob_start();
@@ -51,8 +52,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';
@@ -60,15 +61,20 @@ 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 (file_exists('content/' . $pfad . '.php')) { if (isset($_GET["pfad"])) {
include_once 'content/' . $pfad . '.php'; if (file_exists('content/' . $_GET["pfad"] . '.php')) {
include_once 'content/' . $_GET["pfad"] . '.php';
} else {
include_once 'content/404.php';
}
} else { } else {
include_once 'content/404.php'; include_once 'content/home.php';
} }
include_once 'includes/footer.php'; include_once 'includes/footer.php';
?> ?>
</body> </body>
</html> </html>
+57 -39
View File
@@ -1,9 +1,8 @@
<?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;
@@ -12,6 +11,34 @@ 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();
@@ -33,40 +60,37 @@ try {
$nachname = trim($_POST["nachname"] ?? ""); $nachname = trim($_POST["nachname"] ?? "");
$password = $_POST["password"] ?? ""; $password = $_POST["password"] ?? "";
if (!userEmailValidator($newEmail)) { if (!isValidName($vorname)) {
$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.";
$_GET["edit"] = "1"; } elseif (!isValidProfilePassword($password)) {
$error = "Das Passwort muss mindestens 8 Zeichen lang sein.";
} elseif (!userNameValidator($vorname)) {
$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";
} else { } else {
$updated = $dao->updateUser( $existingUser = $dao->findUser($newEmail);
$oldEmail,
$newEmail,
$vorname,
$nachname,
$password
);
if ($updated) { if ($existingUser && $newEmail !== $oldEmail) {
$_SESSION["user"] = $vorname . " " . $nachname; $error = "Diese E-Mail-Adresse wird bereits verwendet.";
$_SESSION["user_email"] = $newEmail;
header("Location: index.php?pfad=profile");
exit();
} else { } else {
$error = "Die Daten konnten nicht gespeichert werden."; $updated = $dao->updateUser(
$_GET["edit"] = "1"; $oldEmail,
$newEmail,
$vorname,
$nachname,
$password
);
if ($updated) {
$_SESSION["user"] = $vorname . " " . $nachname;
$_SESSION["user_email"] = $newEmail;
header("Location: index.php?pfad=profile");
exit();
} else {
$error = "Die Daten konnten nicht gespeichert werden.";
}
} }
} }
} }
@@ -80,12 +104,6 @@ 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";
} }
+22 -28
View File
@@ -1,43 +1,37 @@
<?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 = trim($_POST["email"] ?? ""); $email = $_POST["email"] ?? "";
$vorname = trim($_POST["vorname"] ?? ""); $vorname = $_POST["vorname"] ?? "";
$nachname = trim($_POST["nachname"] ?? ""); $nachname = $_POST["nachname"] ?? "";
$plainPassword = $_POST["password"] ?? ""; $password = password_hash(
$_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();
$password = password_hash($plainPassword, PASSWORD_DEFAULT); $dao->addUser(
$email,
$vorname,
$nachname,
$password
);
$dao->addUser($email, $vorname, $nachname, $password); $_SESSION["user"] = $vorname . " " . $nachname;
$_SESSION["user_email"] = $email;
$_SESSION["user"] = $vorname . " " . $nachname; header("Location: index.php");
$_SESSION["user_email"] = $email; exit();
header("Location: index.php");
exit();
} catch (InvalidArgumentException $e) {
$error = $e->getMessage();
} catch (Exception $e) {
$error = "Die Registrierung konnte nicht gespeichert werden.";
}
} }
} }
+52 -13
View File
@@ -2,28 +2,67 @@
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"] === "POST") { if ($_SERVER["REQUEST_METHOD"] === "GET" && isset($_GET["q"])) {
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";
// TODO: Liste mit Artikeln in der Suchreihenfolge übertragen.
// Weiterleitung zur Suchergebnisanzeige
header("location: ../../index.php?pfad=search-results");
exit();
} }
header("Location: ../../index.php?pfad=search-results");
exit();
} }
?> ?>
+7 -7
View File
@@ -7,13 +7,13 @@
*/ */
class Article class Article
{ {
private $id; public $id;
private $title; public $title;
private $content; public $content;
private $author; public $author;
private $creationDate; public $creationDate;
private $category; public $category;
private $tags; public $tags;
/** /**
* Konstruktor * Konstruktor
+1
View File
@@ -44,4 +44,5 @@ class ArticleManager extends LocalArticleManager
return $articleManager; return $articleManager;
} }
} }
+10
View File
@@ -76,5 +76,15 @@ 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,5 +166,40 @@ 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;
}
} }
?> ?>
+38 -58
View File
@@ -6,13 +6,6 @@ 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 [];
@@ -33,35 +26,40 @@ 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) {
$json = json_encode($users, JSON_PRETTY_PRINT); $result = file_put_contents(
$this->file,
if ($json === false) { json_encode($users, JSON_PRETTY_PRINT)
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) {
* Sucht einen Benutzer anhand seiner E-Mail-Adresse. if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
* 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) {
@@ -80,18 +78,12 @@ 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) {
@@ -110,19 +102,12 @@ 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) {
@@ -155,14 +140,9 @@ 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) {
+11 -5
View File
@@ -21,6 +21,7 @@ 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);
@@ -42,8 +43,9 @@ interface UserDAOInterface {
* @return void * @return void
* *
* Mögliche Fehler: * Mögliche Fehler:
* @throws InvalidArgumentException wenn die E-Mail-Adresse bereits verwendet wird * @throws InvalidArgumentException wenn Eingabedaten ungültig sind
* @throws RuntimeException wenn die Benutzerdaten nicht gelesen oder gespeichert werden können * oder die E-Mail-Adresse bereits verwendet wird
* @throws RuntimeException wenn die Benutzerdaten nicht gespeichert werden können
*/ */
public function addUser($email, $vorname, $nachname, $password); public function addUser($email, $vorname, $nachname, $password);
@@ -65,8 +67,10 @@ 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 die neue E-Mail-Adresse bereits verwendet wird * @throws InvalidArgumentException wenn Eingabedaten ungültig sind
* @throws RuntimeException wenn die Benutzerdaten nicht gelesen oder gespeichert werden können * oder 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);
@@ -83,7 +87,9 @@ 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 RuntimeException wenn die Benutzerdaten nicht gelesen oder gespeichert werden können * @throws InvalidArgumentException wenn die E-Mail-Adresse ungültig ist
* @throws RuntimeException wenn die Benutzerdaten nicht gelesen
* oder gespeichert werden können
*/ */
public function deleteUser($email); public function deleteUser($email);
} }
-33
View File
@@ -1,33 +0,0 @@
<?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);
}