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
23 changed files with 345 additions and 487 deletions
-6
View File
@@ -10,15 +10,12 @@ Jeweils im Format `Anmeldename, Passwort, Mailadresse`:
- `max.mustermann, test123, mustermann@web.de`
## Weitere Voraussetzungen zur Nutzung
- Per Klick auf das Logo gelangt man auf die Home-Seite.
## Ausgelassene Teilaufgaben
## Bekannte Fehler und Mängel
- 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.
- 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
- 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.
- 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 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)
-8
View File
@@ -4,14 +4,6 @@
-->
<main>
<?php if (isset($_SESSION["message"]) && $_SESSION["message"] == "internal_error"): ?>
<p class="alert-message is-error">
Es ist ein interner Fehler beim Speichern aufgetreten. Bitte versuche es erneut.
</p>
<?php endif; ?>
<?php
unset($_SESSION["message"]);
?>
<h1>404 - Seite nicht vorhanden</h1>
<p>
Später im Projekt sollen über index.php?pfad= ... der Inhalt der index.php dynamisch gesetzt werden.
+3 -8
View File
@@ -17,11 +17,6 @@ include_once 'php/controller/home-controller.php';
Dein Beitrag wurde erfolgreich veröffentlicht!
</p>
<?php endif; ?>
<?php if (isset($_SESSION["message"]) && $_SESSION["message"] == "invalid_category"): ?>
<p class="alert-message is-error">
Diese Kategorie ist nicht gültig.
</p>
<?php endif; ?>
<?php
unset($_SESSION["message"]);
?>
@@ -39,21 +34,21 @@ include_once 'php/controller/home-controller.php';
<!-- Flexbox -->
<div class="flexbox">
<div class="container">
<a href="index.php?pfad=showCategory&category=informatik" class="category-link">Informatik</a>
<a href="index.php?pfad=informatik" class="category-link">Informatik</a>
<div class="article-link">
<a href="index.php?pfad=showArticle&id=<?php echo $dummy3->getId()?>"><?php if(isset($dummy3)){echo $dummy3->getTitle();}else{echo "Fehler: Beitrag nicht gefunden!";} ?></a>
</div>
</div>
<div class="container">
<a href="index.php?pfad=showCategory&category=mathe" class="category-link">Mathe</a>
<a href="index.php?pfad=mathe" class="category-link">Mathe</a>
<div class="article-link">
<a href="index.php?pfad=showArticle&id=<?php echo $dummy1->getId()?>"><?php if(isset($dummy1)){echo $dummy1->getTitle();}else{echo "Fehler: Beitrag nicht gefunden!";} ?></a>
</div>
</div>
<div class="container">
<a href="index.php?pfad=showCategory&category=physik" class="category-link">Physik</a>
<a href="index.php?pfad=physik" class="category-link">Physik</a>
<div class="article-link">
<a href="index.php?pfad=showArticle&id=<?php echo $dummy2->getId()?>"><?php if(isset($dummy2)){echo $dummy2->getTitle();}else{echo "Fehler: Beitrag nicht gefunden!";} ?></a>
</div>
+16 -8
View File
@@ -2,7 +2,7 @@
include_once 'php/controller/profile-controller.php';
$user = $user ?? null;
$isEditMode = isset($_GET["edit"]) && $_GET["edit"] === "1";
$isEditMode = (isset($_GET["edit"]) && $_GET["edit"] === "1") || !empty($error);
?>
<main class="form-page">
@@ -10,8 +10,8 @@ $isEditMode = isset($_GET["edit"]) && $_GET["edit"] === "1";
<div class="container">
<?php if (isset($error) && $error): ?>
<p style="color:red;">
<?php if (!empty($error)): ?>
<p class="alert-message is-error">
<?php echo htmlspecialchars($error); ?>
</p>
<?php endif; ?>
@@ -22,7 +22,7 @@ $isEditMode = isset($_GET["edit"]) && $_GET["edit"] === "1";
<input type="text"
name="vorname"
class="login-input"
value="<?php echo htmlspecialchars($user["vorname"] ?? ""); ?>"
value="<?php echo htmlspecialchars($_POST["vorname"] ?? $user["vorname"] ?? ""); ?>"
<?php echo $isEditMode ? "" : "readonly"; ?>
required>
@@ -30,7 +30,7 @@ $isEditMode = isset($_GET["edit"]) && $_GET["edit"] === "1";
<input type="text"
name="nachname"
class="login-input"
value="<?php echo htmlspecialchars($user["nachname"] ?? ""); ?>"
value="<?php echo htmlspecialchars($_POST["nachname"] ?? $user["nachname"] ?? ""); ?>"
<?php echo $isEditMode ? "" : "readonly"; ?>
required>
@@ -38,18 +38,26 @@ $isEditMode = isset($_GET["edit"]) && $_GET["edit"] === "1";
<input type="email"
name="email"
class="login-input"
value="<?php echo htmlspecialchars($user["email"] ?? ""); ?>"
value="<?php echo htmlspecialchars($_POST["email"] ?? $user["email"] ?? ""); ?>"
<?php echo $isEditMode ? "" : "readonly"; ?>
required>
<label class="input-label">
<?php echo $isEditMode ? "Neues Passwort" : "Passwort"; ?>
</label>
<?php if ($isEditMode): ?>
<input type="password"
name="password"
class="login-input"
placeholder="<?php echo $isEditMode ? "Leer lassen, wenn es gleich bleiben soll" : "********"; ?>"
<?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>
+9 -4
View File
@@ -1,16 +1,18 @@
<?php
include_once 'php/controller/register-controller.php';
$error = $error ?? null;
?>
<!--
Form: Registrierung
Funktion: Erstellung neuer Benutzerkonten
-->
<main class="login-page">
<div class="login-container">
<h1>Jetzt Registrieren!</h1>
<?php if ($error): ?>
<p style="color:red;">
<?php if (!empty($error)): ?>
<p class="alert-message is-error" style="color:red;">
<?php echo htmlspecialchars($error); ?>
</p>
<?php endif; ?>
@@ -22,6 +24,7 @@ $error = $error ?? null;
name="email"
class="login-input"
placeholder="mustermann@web.de"
value="<?php echo htmlspecialchars($_POST["email"] ?? ""); ?>"
required>
<p class="input-label">Vorname:</p>
@@ -29,6 +32,7 @@ $error = $error ?? null;
name="vorname"
class="login-input"
placeholder="Max"
value="<?php echo htmlspecialchars($_POST["vorname"] ?? ""); ?>"
required>
<p class="input-label">Nachname:</p>
@@ -36,6 +40,7 @@ $error = $error ?? null;
name="nachname"
class="login-input"
placeholder="Mustermann"
value="<?php echo htmlspecialchars($_POST["nachname"] ?? ""); ?>"
required>
<p class="input-label">Passwort:</p>
+50 -41
View File
@@ -1,10 +1,5 @@
<?php
session_start();
$results = $_SESSION["search_results"] ?? [];
$query = $_SESSION["search_query"] ?? "";
$resultCount = count($results);
?>
<!--
Seite: Suchergebnisse
@@ -15,81 +10,95 @@ $resultCount = count($results);
<!-- Links: Seitenleiste für Filter und Suche -->
<aside class="s-res-sidebar">
<!-- Sortierfuntion Box und Such Box-->
<form action="php/controller/search-results-controller.php" method="GET" class="s-res-sidebar-form">
<!-- Suchleiste Box -->
<div class="s-res-sidebar-box">
<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>
</form>
</div>
<!-- Sortierfuntion Box -->
<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()">
<input type="radio" name="sort" value="alphabet" checked>
<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>
<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" <?php echo $currentSort === 'newest' ? 'checked' : ''; ?> onchange="this.form.submit()">
<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" <?php echo $currentSort === 'oldest' ? 'checked' : ''; ?> onchange="this.form.submit()">
<input type="radio" name="sort" value="oldest">
<span>Älteste Beiträge</span>
</label>
</div>
</div>
</form>
</aside>
<main class="s-res-main-content">
<div class="s-res-header">
<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>
<!-- Ergebnisliste -->
<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
elseif (isset($_SESSION["search_query"]) && $_SESSION["search_query"] !== "" && $resultCount === 0): ?>
<p>Keine Beiträge zu diesem Suchbegriff gefunden.</p>
<?php
elseif (isset($_SESSION["message"]) && $_SESSION["message"] == "missing_parameters"): ?>
<p>Bitte überprüfe deine Sucheingabe und versuche es erneut!</p>
if(isset($_SESSION['message']) && $_SESSION['message'] == "new_search_results"): ?>
<!-- TODO: Hier die Beiträge ausgeben. -->
<?php elseif (isset($_SESSION["message"]) && $_SESSION["message"] == "missing_parameters"): ?>
<p>
Bitte überprüfe deine Sucheingabe und versuche es erneut!
</p>
<?php endif; ?>
<?php
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 class="s-res-pagination-footer">
-31
View File
@@ -1,31 +0,0 @@
<?php
include_once "php/controller/showCategory-controller.php";
?>
<main>
<h1><?php if (isset($category) && !empty($category)){ echo htmlspecialchars($category); } ?></h1>
<div class="s-res-list">
<?php
if (!empty($articles)): ?>
<?php foreach ($articles as $article): ?>
<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 $article->getId(); ?>" class="s-res-link">
<?php echo htmlspecialchars($article->getTitle()); ?>
</a>
</h2>
<p class="s-res-author">Von: <span class="s-res-author-name"><?php echo htmlspecialchars($article->getAuthor()); ?></span></p>
</div>
<div class="s-res-arrow">&rarr;</div>
</div>
<?php endforeach; ?>
<?php
else: ?>
<p> Es sind noch keine Beiträge in dieser Kategorie enthalten.</p>
<?php endif; ?>
</div>
</main>
+1 -1
View File
@@ -86,7 +86,7 @@ include_once 'php/controller/showArticle-controller.php';
<aside class="editor-sidebar">
<div class="sidebar-block">
<button type="submit" id="editor-button" class="button">Änderungen speichern</button>
<button type="submit" class="button">Änderungen speichern</button>
</div>
<div class="sidebar-block">
-4
View File
@@ -22,10 +22,6 @@ a, button, input, select, textarea, label, main{
font-family: Arial, Helvetica, sans-serif;
}
h1 {
text-transform: uppercase;
}
.flexbox {
display: flex;
flex-direction: row;
+52 -52
View File
@@ -39,50 +39,50 @@ Globales Menü, wird via PHP später in alle Seiten eingebunden
<li>
<label class="nav__mobile-label">Sprachen</label>
<ul class="nav__mobile-submenu">
<li><a href="index.php?pfad=showCategory&category=deutsch">Deutsch</a></li>
<li><a href="index.php?pfad=showCategory&category=englisch">Englisch</a></li>
<li><a href="index.php?pfad=showCategory&category=franzoesisch">Französisch</a></li>
<li><a href="index.php?pfad=showCategory&category=latein">Latein</a></li>
<li><a href="index.php?pfad=showCategory&category=literatur">Literatur</a></li>
<li><a href="index.php?pfad=deutsch">Deutsch</a></li>
<li><a href="index.php?pfad=englisch">Englisch</a></li>
<li><a href="index.php?pfad=franzoesisch">Französisch</a></li>
<li><a href="index.php?pfad=latein">Latein</a></li>
<li><a href="index.php?pfad=literatur">Literatur</a></li>
</ul>
</li>
<li>
<label class="nav__mobile-label">MINT</label>
<ul class="nav__mobile-submenu">
<li><a href="index.php?pfad=showCategory&category=mathe">Mathematik</a></li>
<li><a href="index.php?pfad=showCategory&category=biologie">Biologie</a></li>
<li><a href="index.php?pfad=showCategory&category=chemie">Chemie</a></li>
<li><a href="index.php?pfad=showCategory&category=physik">Physik</a></li>
<li><a href="index.php?pfad=showCategory&category=informatik">Informatik</a></li>
<li><a href="index.php?pfad=showCategory&category=astronomie">Astronomie</a></li>
<li><a href="index.php?pfad=mathe">Mathematik</a></li>
<li><a href="index.php?pfad=biologie">Biologie</a></li>
<li><a href="index.php?pfad=chemie">Chemie</a></li>
<li><a href="index.php?pfad=physik">Physik</a></li>
<li><a href="index.php?pfad=informatik">Informatik</a></li>
<li><a href="index.php?pfad=astronomie">Astronomie</a></li>
</ul>
</li>
<li>
<label class="nav__mobile-label">Gesellschaft & Werte</label>
<ul class="nav__mobile-submenu">
<li><a href="index.php?pfad=showCategory&category=geschichte">Geschichte</a></li>
<li><a href="index.php?pfad=showCategory&category=erdkunde">Erdkunde</a></li>
<li><a href="index.php?pfad=showCategory&category=sozialkunde">Sozialkunde</a></li>
<li><a href="index.php?pfad=showCategory&category=wirtschaft">Wirtschaftskunde</a></li>
<li><a href="index.php?pfad=showCategory&category=religion">Religion</a></li>
<li><a href="index.php?pfad=showCategory&category=ethik">Ethikunterricht</a></li>
<li><a href="index.php?pfad=showCategory&category=philosophie">Philosophie</a></li>
<li><a href="index.php?pfad=showCategory&category=psychologie">Psychologie</a></li>
<li><a href="index.php?pfad=showCategory&category=kunst">Kunst</a></li>
<li><a href="index.php?pfad=showCategory&category=musik">Musik</a></li>
<li><a href="index.php?pfad=showCategory&category=theater">Theater</a></li>
<li><a href="index.php?pfad=geschichte">Geschichte</a></li>
<li><a href="index.php?pfad=erdkunde">Erdkunde</a></li>
<li><a href="index.php?pfad=sozialkunde">Sozialkunde</a></li>
<li><a href="index.php?pfad=wirtschaft">Wirtschaftskunde</a></li>
<li><a href="index.php?pfad=religion">Religion</a></li>
<li><a href="index.php?pfad=ethik">Ethikunterricht</a></li>
<li><a href="index.php?pfad=philosophie">Philosophie</a></li>
<li><a href="index.php?pfad=psychologie">Psychologie</a></li>
<li><a href="index.php?pfad=kunst">Kunst</a></li>
<li><a href="index.php?pfad=musik">Musik</a></li>
<li><a href="index.php?pfad=theater">Theater</a></li>
</ul>
</li>
<li>
<label class="nav__mobile-label">Technik & Praxis</label>
<ul class="nav__mobile-submenu">
<li><a href="index.php?pfad=showCategory&category=technik">Technik</a></li>
<li><a href="index.php?pfad=showCategory&category=werken">Werken</a></li>
<li><a href="index.php?pfad=showCategory&category=hauswirtschaft">Hauswirtschaft</a></li>
<li><a href="index.php?pfad=showCategory&category=sport">Sport</a></li>
<li><a href="index.php?pfad=technik">Technik</a></li>
<li><a href="index.php?pfad=werken">Werken</a></li>
<li><a href="index.php?pfad=hauswirtschaft">Hauswirtschaft</a></li>
<li><a href="index.php?pfad=sport">Sport</a></li>
</ul>
</li>
</ul>
@@ -92,50 +92,50 @@ Globales Menü, wird via PHP später in alle Seiten eingebunden
<div class="nav__item nav__dropdown">
<button class="nav__dropdown-toggle">Sprachen</button>
<div class="nav__dropdown-menu">
<a href="index.php?pfad=showCategory&category=deutsch">Deutsch</a>
<a href="index.php?pfad=showCategory&category=englisch">Englisch</a>
<a href="index.php?pfad=showCategory&category=franzoesisch">Französisch</a>
<a href="index.php?pfad=showCategory&category=latein">Latein</a>
<a href="index.php?pfad=showCategory&category=literatur">Literatur</a>
<a href="index.php?pfad=deutsch">Deutsch</a>
<a href="index.php?pfad=englisch">Englisch</a>
<a href="index.php?pfad=franzoesisch">Französisch</a>
<a href="index.php?pfad=latein">Latein</a>
<a href="index.php?pfad=literatur">Literatur</a>
</div>
</div>
<div class="nav__item nav__dropdown">
<button class="nav__dropdown-toggle">MINT</button>
<div class="nav__dropdown-menu">
<a href="index.php?pfad=showCategory&category=mathe">Mathematik</a>
<a href="index.php?pfad=showCategory&category=biologie">Biologie</a>
<a href="index.php?pfad=showCategory&category=chemie">Chemie</a>
<a href="index.php?pfad=showCategory&category=physik">Physik</a>
<a href="index.php?pfad=showCategory&category=informatik">Informatik</a>
<a href="index.php?pfad=showCategory&category=astronomie">Astronomie</a>
<a href="index.php?pfad=mathe">Mathematik</a>
<a href="index.php?pfad=biologie">Biologie</a>
<a href="index.php?pfad=chemie">Chemie</a>
<a href="index.php?pfad=physik">Physik</a>
<a href="index.php?pfad=informatik">Informatik</a>
<a href="index.php?pfad=astronomie">Astronomie</a>
</div>
</div>
<div class="nav__item nav__dropdown">
<button class="nav__dropdown-toggle">Gesellschaft & Werte</button>
<div class="nav__dropdown-menu">
<a href="index.php?pfad=showCategory&category=geschichte">Geschichte</a>
<a href="index.php?pfad=showCategory&category=erdkunde">Erdkunde</a>
<a href="index.php?pfad=showCategory&category=sozialkunde">Sozialkunde</a>
<a href="index.php?pfad=showCategory&category=wirtschaft">Wirtschaftskunde</a>
<a href="index.php?pfad=showCategory&category=religion">Religion</a>
<a href="index.php?pfad=showCategory&category=ethik">Ethikunterricht</a>
<a href="index.php?pfad=showCategory&category=philosophie">Philosophie</a>
<a href="index.php?pfad=showCategory&category=psychologie">Psychologie</a>
<a href="index.php?pfad=showCategory&category=kunst">Kunst</a>
<a href="index.php?pfad=showCategory&category=musik">Musik</a>
<a href="index.php?pfad=showCategory&category=theater">Theater</a>
<a href="index.php?pfad=geschichte">Geschichte</a>
<a href="index.php?pfad=erdkunde">Erdkunde</a>
<a href="index.php?pfad=sozialkunde">Sozialkunde</a>
<a href="index.php?pfad=wirtschaft">Wirtschaftskunde</a>
<a href="index.php?pfad=religion">Religion</a>
<a href="index.php?pfad=ethik">Ethikunterricht</a>
<a href="index.php?pfad=philosophie">Philosophie</a>
<a href="index.php?pfad=psychologie">Psychologie</a>
<a href="index.php?pfad=kunst">Kunst</a>
<a href="index.php?pfad=musik">Musik</a>
<a href="index.php?pfad=theater">Theater</a>
</div>
</div>
<div class="nav__item nav__dropdown">
<button class="nav__dropdown-toggle">Technik & Praxis</button>
<div class="nav__dropdown-menu">
<a href="index.php?pfad=showCategory&category=technik">Technik</a>
<a href="index.php?pfad=showCategory&category=werken">Werken</a>
<a href="index.php?pfad=showCategory&category=hauswirtschaft">Hauswirtschaft</a>
<a href="index.php?pfad=showCategory&category=sport">Sport</a>
<a href="index.php?pfad=technik">Technik</a>
<a href="index.php?pfad=werken">Werken</a>
<a href="index.php?pfad=hauswirtschaft">Hauswirtschaft</a>
<a href="index.php?pfad=sport">Sport</a>
</div>
</div>
</div>
+1 -6
View File
@@ -2,10 +2,5 @@
Suchleiste. Wird via PHP später in alle Seiten eingebunden
-->
<!--<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="hidden" name="pfad" value="search-results">
<input type="search" id="site-search" name="q" placeholder="Suchen..." class="nav__search" maxlength="50" required>
<input type="search" id="site-search" name="q" placeholder="Suchen..." class="nav__search">
<button type="submit" class="nav__search-button">Suchen</button>
</form>
+3 -9
View File
@@ -1,4 +1,3 @@
<?php
session_start();
ob_start();
@@ -52,8 +51,8 @@ if ($pfad === "deleteAccount") {
<title>EduForge</title>
</head>
<body>
<?php
include_once 'includes/navbar.php';
@@ -61,20 +60,15 @@ if ($pfad === "deleteAccount") {
Dynamischer Inhalt:
Je nach pfad-Parameter wird die passende Datei aus content geladen.
*/
if (isset($_GET["pfad"])) {
if (file_exists('content/' . $_GET["pfad"] . '.php')) {
include_once 'content/' . $_GET["pfad"] . '.php';
if (file_exists('content/' . $pfad . '.php')) {
include_once 'content/' . $pfad . '.php';
} else {
include_once 'content/404.php';
}
} else {
include_once 'content/home.php';
}
include_once 'includes/footer.php';
?>
</body>
</html>
+24 -42
View File
@@ -1,8 +1,9 @@
<?php
require_once "php/model/LocalUserDAO.php";
require_once 'php/model/Article.php';
require_once 'php/model/ArticleManager.php';
require_once "php/model/Article.php";
require_once "php/model/ArticleManager.php";
require_once "php/validator/user-validator.php";
$error = null;
@@ -11,34 +12,6 @@ if (!isset($_SESSION["user"])) {
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 {
$dao = new LocalUserDAO();
@@ -60,19 +33,22 @@ try {
$nachname = trim($_POST["nachname"] ?? "");
$password = $_POST["password"] ?? "";
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)) {
if (!userEmailValidator($newEmail)) {
$error = "Bitte gib eine gültige E-Mail-Adresse ein.";
} elseif (!isValidProfilePassword($password)) {
$error = "Das Passwort muss mindestens 8 Zeichen lang sein.";
} else {
$existingUser = $dao->findUser($newEmail);
$_GET["edit"] = "1";
} 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";
if ($existingUser && $newEmail !== $oldEmail) {
$error = "Diese E-Mail-Adresse wird bereits verwendet.";
} else {
$updated = $dao->updateUser(
$oldEmail,
@@ -90,7 +66,7 @@ try {
exit();
} else {
$error = "Die Daten konnten nicht gespeichert werden.";
}
$_GET["edit"] = "1";
}
}
}
@@ -104,6 +80,12 @@ try {
$_SESSION["message"] = "user_has_no_articles";
}
} catch (InvalidArgumentException $e) {
$error = $e->getMessage();
$_GET["edit"] = "1";
} catch (Exception $e) {
$error = "Es ist ein interner Fehler aufgetreten. Bitte versuche es erneut.";
$_SESSION["message"] = "internal_error";
$_GET["edit"] = "1";
}
+24 -18
View File
@@ -1,37 +1,43 @@
<?php
require_once "php/model/LocalUserDAO.php";
require_once "php/validator/user-validator.php";
$dao = new LocalUserDAO();
$error = null;
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$email = $_POST["email"] ?? "";
$vorname = $_POST["vorname"] ?? "";
$nachname = $_POST["nachname"] ?? "";
$password = password_hash(
$_POST["password"] ?? "",
PASSWORD_DEFAULT
);
if ($dao->findUser($email)) {
$error = "Diese E-Mail-Adresse ist bereits registriert.";
$email = trim($_POST["email"] ?? "");
$vorname = trim($_POST["vorname"] ?? "");
$nachname = trim($_POST["nachname"] ?? "");
$plainPassword = $_POST["password"] ?? "";
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 {
try {
$dao = new LocalUserDAO();
$dao->addUser(
$email,
$vorname,
$nachname,
$password
);
$password = password_hash($plainPassword, PASSWORD_DEFAULT);
$dao->addUser($email, $vorname, $nachname, $password);
$_SESSION["user"] = $vorname . " " . $nachname;
$_SESSION["user_email"] = $email;
header("Location: index.php");
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();
require_once '../model/LocalArticleManager.php';
require_once '../model/ArticleManager.php';
require_once '../model/Article.php';
if ($_SERVER["REQUEST_METHOD"] === "GET" && isset($_GET["q"])) {
$search = trim($_GET["q"]);
if (empty($search)) {
$_SESSION["search_results"] = [];
$_SESSION["search_query"] = "";
if ($_SERVER["REQUEST_METHOD"] === "POST") {
if(!isset($_POST["search"])){
$_SESSION["message"] = "missing_parameters";
header("location: ../../index.php?pfad=search-results");
} else {
$search = $_POST["search"];
try {
$articleManager = ArticleManager::getInstance();
$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";
$articleManager->search($search); // TODO: Methode implementieren.
} catch (Exception $e){
$_SESSION["message"] = "internal_error";
}
}
header("Location: ../../index.php?pfad=search-results");
$_SESSION["message"] = "new_search_results";
// TODO: Liste mit Artikeln in der Suchreihenfolge übertragen.
// Weiterleitung zur Suchergebnisanzeige
header("location: ../../index.php?pfad=search-results");
exit();
}
}
?>
@@ -1,21 +0,0 @@
<?php
require_once 'php/model/Article.php';
require_once 'php/model/ArticleManager.php';
require_once 'php/validator/article-validator.php';
if (isset($_GET["category"]) && !empty($_GET["category"]) && articleCategoryValidator($_GET["category"])){
$category = $_GET["category"];
try {
$articleManager = ArticleManager::getInstance();
$articles = $articleManager->getArticlesByCategory($category);
} catch (Exception $e) {
$_SESSION["message"] = "internal_error";
include_once "content/404.php";
exit();
}
}else{
$_SESSION["message"] = "invalid_category";
include_once "content/404.php";
exit();
}
?>
+7 -7
View File
@@ -7,13 +7,13 @@
*/
class Article
{
public $id;
public $title;
public $content;
public $author;
public $creationDate;
public $category;
public $tags;
private $id;
private $title;
private $content;
private $author;
private $creationDate;
private $category;
private $tags;
/**
* Konstruktor
+3 -4
View File
@@ -19,7 +19,7 @@ class ArticleManager extends LocalArticleManager
"Satz des Pythagoras",
"Der Satz des Pythagoras wurde von dem griechischen Philosophen Pythagoras von Samos formuliert und im dritten Jahrhundert vor Christus veröffentlicht. In der beigefügten Abbildung sehen wir ein rechtwinkliges Dreieck...",
"max.mustermann",
"mathe",
"Mathe",
"Dreiecke, Dreiecksseiten berechnen"
);
}
@@ -28,7 +28,7 @@ class ArticleManager extends LocalArticleManager
"Tunneleffekt",
"Der Tunneleffekt ist ein quantenmechanisches Phänomen, bei dem Teilchen...",
"max.mustermann",
"physik",
"Physik",
"Quantenphysik, Energie"
);
}
@@ -37,12 +37,11 @@ class ArticleManager extends LocalArticleManager
"Datenschutz vs Datensicherheit",
"Datenschutz ist in unserer digital vernetzten Welt allgegenwärtig...",
"max.mustermann",
"informatik",
"Informatik",
"Daten, DSGVO"
);
}
return $articleManager;
}
}
-17
View File
@@ -76,22 +76,5 @@ interface ArticleManagerDAO
*/
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;
/**
* Gibt alle Beiträge einer gegebenen Kategorie aus.
* @param $category
* @return mixed
*/
public function getArticlesByCategory($category);
}
?>
-56
View File
@@ -166,61 +166,5 @@ class LocalArticleManager implements ArticleManagerDAO {
}
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;
}
public function getArticlesByCategory($category)
{
$articles = $this->getAllArticles();
$filteredArticles = [];
foreach ($articles as $article) {
if (isset($article['category']) && $article['category'] == $category) {
$filteredArticles[] = new Article(
intval($article['id']),
$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";
/**
* 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() {
if (!file_exists($this->file)) {
return [];
@@ -26,40 +33,35 @@ class LocalUserDAO implements UserDAOInterface {
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) {
$result = file_put_contents(
$this->file,
json_encode($users, JSON_PRETTY_PRINT)
);
$json = 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) {
throw new RuntimeException("Benutzerdaten konnten nicht gespeichert werden.");
}
}
private function validateEmail($email) {
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
throw new InvalidArgumentException("Ungültige E-Mail-Adresse.");
}
}
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.");
}
}
/**
* Sucht einen Benutzer anhand seiner 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
*/
public function findUser($email) {
$this->validateEmail($email);
$users = $this->loadUsers();
foreach ($users as $user) {
@@ -78,12 +80,18 @@ class LocalUserDAO implements UserDAOInterface {
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) {
$this->validateEmail($email);
$this->validateName($vorname, "Vorname");
$this->validateName($nachname, "Nachname");
$this->validatePassword($password);
$users = $this->loadUsers();
foreach ($users as $user) {
@@ -102,12 +110,19 @@ class LocalUserDAO implements UserDAOInterface {
$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) {
$this->validateEmail($oldEmail);
$this->validateEmail($newEmail);
$this->validateName($vorname, "Vorname");
$this->validateName($nachname, "Nachname");
$users = $this->loadUsers();
foreach ($users as $user) {
@@ -140,9 +155,14 @@ class LocalUserDAO implements UserDAOInterface {
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) {
$this->validateEmail($email);
$users = $this->loadUsers();
foreach ($users as $i => $user) {
+5 -11
View File
@@ -21,7 +21,6 @@ interface UserDAOInterface {
* @return array|null Benutzerdaten als Array oder null
*
* Mögliche Fehler:
* @throws InvalidArgumentException wenn die E-Mail-Adresse ungültig ist
* @throws RuntimeException wenn die Benutzerdaten nicht gelesen werden können
*/
public function findUser($email);
@@ -43,9 +42,8 @@ interface UserDAOInterface {
* @return void
*
* Mögliche Fehler:
* @throws InvalidArgumentException wenn Eingabedaten ungültig sind
* oder die E-Mail-Adresse bereits verwendet wird
* @throws RuntimeException wenn die Benutzerdaten nicht gespeichert werden können
* @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);
@@ -67,10 +65,8 @@ interface UserDAOInterface {
* @return bool true, wenn der Benutzer aktualisiert wurde, sonst false
*
* Mögliche Fehler:
* @throws InvalidArgumentException wenn Eingabedaten ungültig sind
* oder die neue E-Mail-Adresse bereits verwendet wird
* @throws RuntimeException wenn die Benutzerdaten nicht gelesen
* oder gespeichert werden können
* @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);
@@ -87,9 +83,7 @@ interface UserDAOInterface {
* @return bool true, wenn der Benutzer gelöscht wurde, sonst false
*
* 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);
}
+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);
}