Compare commits
70 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 95251d23ad | |||
| c16bf574ce | |||
| 0e44d92baa | |||
| 286e2b6237 | |||
| fb78794261 | |||
| 371a65d361 | |||
| 7bd3c8dfd1 | |||
| e5aa6ea25d | |||
| de9afd3275 | |||
| 79e9f17f70 | |||
| 12cc3c5d5b | |||
| 404cea74ff | |||
| 16e94947f2 | |||
| aff0b0560f | |||
| de19a6fc65 | |||
| 1f669aadfc | |||
| 33f428559c | |||
| 0c3b9eb250 | |||
| c654fab94a | |||
| a5131e33dc | |||
| a19d1db990 | |||
| b6e7da6808 | |||
| f21fab937f | |||
| 30fccfe69b | |||
| b692d76f7d | |||
| 56533d4a16 | |||
| 8a22b475f9 | |||
| ae3a1be5e1 | |||
| 8199afc88f | |||
| 2d7ef8fc1d | |||
| d75d78ccb3 | |||
| 42489f50b6 | |||
| 52fde19380 | |||
| b1fb3e5baa | |||
| 5f3dae64c1 | |||
| b31ce66ef9 | |||
| 93bd561ff9 | |||
| d0d93be96b | |||
| 327a05cf63 | |||
| 1394467abe | |||
| ace73f15ef | |||
| a5e1fb4c38 | |||
| ac2451fe64 | |||
| 5f9789a884 | |||
| e0fbd220f0 | |||
| a0932fed04 | |||
| 42aa908f1c | |||
| da9dc0e8fb | |||
| 36f6396148 | |||
| 12facddcd5 | |||
| 429ecb4e0e | |||
| 8019d9c99a | |||
| 9f9c92385d | |||
| 9ecfc3b6f8 | |||
| d00f2d9d53 | |||
| 37a032aa9f | |||
| fd8e13eaa9 | |||
| b5d1e08d22 | |||
| a5650f2720 | |||
| 4758366063 | |||
| e7a5c2b352 | |||
| 36ec2a539c | |||
| 339e51cca7 | |||
| 0726ba214c | |||
| 0e032ae029 | |||
| b9dead1c8b | |||
| 9010b68a39 | |||
| 252c14a377 | |||
| 4abfe801ec | |||
| c23a10eb6e |
Generated
+1
-1
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="dataSourceStorageLocal" created-in="IU-261.24374.151">
|
||||
<component name="dataSourceStorageLocal" created-in="IU-261.25134.95">
|
||||
<data-source name="articles" uuid="315cb5c9-2b0f-435b-b602-59823b160908">
|
||||
<database-info product="SQLite" version="3.51.1" jdbc-version="4.2" driver-name="SQLite JDBC" driver-version="3.51.1.0" dbms="SQLITE" exact-version="3.51.1" exact-driver-version="3.51">
|
||||
<identifier-quote-string>"</identifier-quote-string>
|
||||
|
||||
-1833
File diff suppressed because it is too large
Load Diff
Generated
-2
@@ -1,2 +0,0 @@
|
||||
#n:main
|
||||
!<md> [0, 0, null, null, -2147483648, -2147483648]
|
||||
@@ -6,8 +6,8 @@
|
||||
- Niklas Ortmann
|
||||
|
||||
## Login-Informationen für Dummy-User
|
||||
Jeweils im Format `Anmeldename, Passwort, Mailadresse`:
|
||||
- `max.mustermann, test123, mustermann@web.de`
|
||||
`Anmeldename, Passwort, Mailadresse`:
|
||||
- `max.mustermann, test12345, mustermann@web.de`
|
||||
|
||||
## Weitere Voraussetzungen zur Nutzung
|
||||
- Per Klick auf das Logo gelangt man auf die Home-Seite.
|
||||
@@ -15,10 +15,7 @@ Jeweils im Format `Anmeldename, Passwort, Mailadresse`:
|
||||
## 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.
|
||||
- Die Suchseite und Kategorieseite packen momentan alle passenden Beiträge untereinander. Später sollen zunächst 10
|
||||
Ergebnisse auf einer Seite angezeigt werden.
|
||||
|
||||
@@ -26,10 +23,8 @@ Jeweils im Format `Anmeldename, Passwort, Mailadresse`:
|
||||
- Es wurde ein einfacher Beitrags-Editor erstellt. Mit diesem können Beiträge erstellt oder bearbeitet werden.
|
||||
Es handelt es sich um eine einfache Version. Später sollen z.B. Bilder und die Positionierung der Elemente folgen.
|
||||
- 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
|
||||
- Die Such-Seite umfasst eine Such- 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).
|
||||
|
||||
## Sonstiges
|
||||
- Das Datenschema befindet sich unter /planung/Datenschema.pdf
|
||||
@@ -12,44 +12,8 @@ if (!isset($_SESSION["user"])) {
|
||||
<form method="post" action="php/controller/createArticle-controller.php" id="editor-form" class="article-editor-scope.editor-container article-editor-scope editor-container">
|
||||
|
||||
<main class="editor-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 if (isset($_SESSION["message"]) && $_SESSION["message"] == "missing_parameters"): ?>
|
||||
<p class="alert-message is-error">
|
||||
Jeder Beitrag muss einen Titel, Kategorie und Inhalt besitzen.
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($_SESSION["message"]) && $_SESSION["message"] == "invalid_title"): ?>
|
||||
<p class="alert-message is-error">
|
||||
Der Titel enthält ungültige Zeichen oder erfüllt die Länge von 5-120 Zeichen nicht.
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($_SESSION["message"]) && $_SESSION["message"] == "invalid_content"): ?>
|
||||
<p class="alert-message is-error">
|
||||
Der Text erlaubt eine Länge von 10 bis maximal 7.000 Zeichen (ca. 1.000 Wörter).
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($_SESSION["message"]) && $_SESSION["message"] == "invalid_category"): ?>
|
||||
<p class="alert-message is-error">
|
||||
Die ausgewählte Kategorie ist ungültig.
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($_SESSION["message"]) && $_SESSION["message"] == "invalid_tags"): ?>
|
||||
<p class="alert-message is-error">
|
||||
Ungültige Schlagworte gefunden. Erlaubt sind nur Buchstaben, Zahlen, Leerzeichen und Bindestriche (2-50 Zeichen).
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($_SESSION["message"]) && $_SESSION["message"] == "validation_missing"): ?>
|
||||
<p class="alert-message is-error">
|
||||
Bei der Validierung deiner Daten ist ein Fehler aufgetreten. Bitte versuche es erneut.
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
<?php
|
||||
unset($_SESSION["message"]);
|
||||
?>
|
||||
<?php include_once "includes/alertMessages.php"?>
|
||||
|
||||
<input type="text" id="title" name="title"
|
||||
value="<?php echo htmlspecialchars($_SESSION['old_title'] ?? ''); unset($_SESSION['old_title']); ?>"
|
||||
placeholder="Titel hier eingeben" required>
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
<?php
|
||||
require_once "php/model/LocalUserManager.php";
|
||||
|
||||
$dao = new LocalUserManager();
|
||||
|
||||
/*
|
||||
Deregistrierung
|
||||
Funktion: Entfernt User aus Dummy-Daten und beendet Session
|
||||
*/
|
||||
|
||||
if (isset($_SESSION["user_email"])) {
|
||||
$dao->deleteUser($_SESSION["user_email"]);
|
||||
}
|
||||
|
||||
$_SESSION = [];
|
||||
session_destroy();
|
||||
|
||||
header("Location: index.php");
|
||||
exit();
|
||||
+1
-18
@@ -7,24 +7,7 @@ include_once 'php/controller/home-controller.php';
|
||||
Inhalt: Beinhaltet den Inhalt der Startseite
|
||||
-->
|
||||
<main>
|
||||
<?php if (isset($_SESSION["message"]) && $_SESSION["message"] == "internal_error"): ?>
|
||||
<p class="alert-message is-error">
|
||||
Es ist ein Fehler beim Speichern aufgetreten. Bitte versuche es erneut.
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($_SESSION["message"]) && $_SESSION["message"] == "new_article"): ?>
|
||||
<p class="alert-message is-success">
|
||||
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"]);
|
||||
?>
|
||||
<?php include_once "includes/alertMessages.php"?>
|
||||
|
||||
<h1>Home</h1>
|
||||
<p>
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
<!--
|
||||
Seite: Informatik
|
||||
Inhalt: Eine Übersicht über alle Beiträge zum Fach
|
||||
-->
|
||||
<main>
|
||||
|
||||
<h1>Informatik</h1>
|
||||
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et
|
||||
dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet
|
||||
clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet,
|
||||
consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat,
|
||||
sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no
|
||||
sea takimata sanctus est Lorem ipsum dolor sit amet.
|
||||
</p>
|
||||
<h2>Artikel:</h2>
|
||||
<div>
|
||||
<a href="datenschutzVSdatensicherheit.php">Datenschutz vs. Datensicherheit</a>
|
||||
</div>
|
||||
</main>
|
||||
@@ -1,22 +0,0 @@
|
||||
<!--
|
||||
Seite: Mathe
|
||||
Inhalt: Eine Übersicht über alle Beiträge zum Fach
|
||||
-->
|
||||
<main>
|
||||
|
||||
<h1>Mathe</h1>
|
||||
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et
|
||||
dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet
|
||||
clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet,
|
||||
consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat,
|
||||
sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no
|
||||
sea takimata sanctus est Lorem ipsum dolor sit amet.
|
||||
</p>
|
||||
|
||||
<h2>Artikel:</h2>
|
||||
<div>
|
||||
<a href="pythagoras.php">Satz des Pythagoras</a>
|
||||
</div>
|
||||
</main>
|
||||
@@ -1,23 +0,0 @@
|
||||
<!--
|
||||
Seite: Physik
|
||||
Inhalt: Eine Übersicht über alle Beiträge zum Fach
|
||||
-->
|
||||
<main>
|
||||
|
||||
<h1>Physik</h1>
|
||||
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et
|
||||
dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet
|
||||
clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet,
|
||||
consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat,
|
||||
sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no
|
||||
sea takimata sanctus est Lorem ipsum dolor sit amet.
|
||||
</p>
|
||||
|
||||
<h2>Artikel:</h2>
|
||||
<div>
|
||||
<a href="tunneleffekt.php">Der Tunneleffekt</a>
|
||||
</div>
|
||||
|
||||
</main>
|
||||
+22
-7
@@ -81,18 +81,20 @@ $isEditMode = (isset($_GET["edit"]) && $_GET["edit"] === "1") || !empty($error);
|
||||
|
||||
<br>
|
||||
|
||||
<a href="index.php?pfad=deleteAccount" class="button">
|
||||
<form action="php/controller/deleteAccount-controller.php" method="POST">
|
||||
<button type="submit"
|
||||
class="button"
|
||||
onclick="return confirm('Möchtest du deinen Account wirklich unwiderruflich löschen?');">
|
||||
Account löschen
|
||||
</a>
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<br><br>
|
||||
|
||||
<a href="index.php?pfad=logout" class="button">
|
||||
Abmelden
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
|
||||
<?php include_once "includes/alertMessages.php"?>
|
||||
|
||||
<h2 class="section-title">Meine Beiträge</h2>
|
||||
|
||||
<div class="articles-list">
|
||||
@@ -117,7 +119,9 @@ $isEditMode = (isset($_GET["edit"]) && $_GET["edit"] === "1") || !empty($error);
|
||||
</div>
|
||||
|
||||
<h3 class="article-title">
|
||||
<a href="index.php?pfad=showArticle&id=<?php echo $userArticle->getID(); ?>">
|
||||
<?php echo htmlspecialchars($userArticle->getTitle()); ?>
|
||||
</a>
|
||||
</h3>
|
||||
|
||||
<?php
|
||||
@@ -151,6 +155,17 @@ $isEditMode = (isset($_GET["edit"]) && $_GET["edit"] === "1") || !empty($error);
|
||||
class="edit-link-button">
|
||||
Bearbeiten
|
||||
</a>
|
||||
|
||||
<form action="php/controller/deleteArticle-controller.php" method="POST">
|
||||
<input type="hidden" name="id" value="<?php echo htmlspecialchars($userArticle->getID()); ?>">
|
||||
|
||||
<button type="submit"
|
||||
class="button"
|
||||
onclick="return confirm('Möchtest du diesen Artikel wirklich löschen?');">
|
||||
Löschen
|
||||
</button>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
|
||||
|
||||
+54
-12
@@ -1,22 +1,53 @@
|
||||
<?php
|
||||
session_start();
|
||||
if (session_status() === PHP_SESSION_NONE) {
|
||||
session_start();
|
||||
}
|
||||
|
||||
$results = $_SESSION["search_results"] ?? [];
|
||||
$all_results = $_SESSION["search_results"] ?? [];
|
||||
$query = $_SESSION["search_query"] ?? "";
|
||||
$totalResultsCount = count($all_results);
|
||||
|
||||
$limit = isset($_GET['limit']) ? (int)$_GET['limit'] : 10;
|
||||
if (!in_array($limit, [10, 20, 50, 100])) {
|
||||
$limit = 10;
|
||||
}
|
||||
|
||||
// Gesamtseitenzahl
|
||||
$totalPages = max(1, ceil($totalResultsCount / $limit));
|
||||
|
||||
// Aktuelle Seite auslesen und validieren
|
||||
$currentPage = isset($_GET['page']) ? (int)$_GET['page'] : 1;
|
||||
if ($currentPage < 1) {
|
||||
$currentPage = 1;
|
||||
} elseif ($currentPage > $totalPages) {
|
||||
$currentPage = $totalPages;
|
||||
}
|
||||
|
||||
// Startpunkt im Array berechnen (Offset)
|
||||
$offset = ($currentPage - 1) * $limit;
|
||||
|
||||
// Nur die Ergebnisse für die aktuelle Seite ausschneiden
|
||||
$results = array_slice($all_results, $offset, $limit);
|
||||
$resultCount = count($results);
|
||||
|
||||
?>
|
||||
<noscript>
|
||||
Bitte JavaScript aktivieren!
|
||||
</noscript>
|
||||
<!--
|
||||
Seite: Suchergebnisse
|
||||
Inhalt: Zeigt die Ergebnisse einer Suche an
|
||||
-->
|
||||
<div class="s-res-layout-grid">
|
||||
<?php include_once "includes/alertMessages.php"?>
|
||||
|
||||
<!-- 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">
|
||||
<form id="search-form-id" action="php/controller/search-results-controller.php" method="GET" class="s-res-sidebar-form">
|
||||
<!-- Dieses Feld hält die aktuelle Seitenzahl für den Submit bereit -->
|
||||
<input type="hidden" name="page" id="s-res-page-input" value="<?php echo $currentPage; ?>">
|
||||
|
||||
<div class="s-res-sidebar-box">
|
||||
<h3 class="s-res-sidebar-title">Suche anpassen</h3>
|
||||
@@ -56,7 +87,7 @@ $resultCount = count($results);
|
||||
|
||||
<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"><?php echo $totalResultsCount; ?> Treffer für Ihre Suchanfrage "<?php echo htmlspecialchars($query); ?>"</p>
|
||||
</div>
|
||||
|
||||
<!-- Ergebnisliste -->
|
||||
@@ -96,18 +127,29 @@ $resultCount = count($results);
|
||||
<!-- Auswahl der Ergebnisse pro Seite -->
|
||||
<div class="s-res-limit-selector">
|
||||
<label for="s-res-per-page" class="s-res-limit-label">Ergebnisse pro Seite:</label>
|
||||
<select id="s-res-per-page" name="limit" class="s-res-limit-select">
|
||||
<option value="10" selected>10</option>
|
||||
<option value="20">20</option>
|
||||
<option value="50">50</option>
|
||||
<option value="100">100</option>
|
||||
<select id="s-res-per-page" name="limit" class="s-res-limit-select" form="search-form-id" onchange="this.form.submit()">
|
||||
<option value="10" <?php echo $limit === 10 ? 'selected' : ''; ?>>10</option>
|
||||
<option value="20" <?php echo $limit === 20 ? 'selected' : ''; ?>>20</option>
|
||||
<option value="50" <?php echo $limit === 50 ? 'selected' : ''; ?>>50</option>
|
||||
<option value="100" <?php echo $limit === 100 ? 'selected' : ''; ?>>100</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="s-res-page-navigation">
|
||||
<button type="button" class="s-res-page-btn" disabled>«</button>
|
||||
<button type="button" class="s-res-page-btn s-res-page-btn-active">1</button>
|
||||
<button type="button" class="s-res-page-btn">»</button>
|
||||
<button type="button" class="s-res-page-btn" data-page="<?php echo $currentPage - 1; ?>" <?php echo $currentPage <= 1 ? 'disabled' : ''; ?>>
|
||||
«
|
||||
</button>
|
||||
<!-- Dynamische Seitenzahlen -->
|
||||
<?php for ($i = 1; $i <= $totalPages; $i++): ?>
|
||||
<button type="button"
|
||||
class="s-res-page-btn <?php echo $i === $currentPage ? 's-res-page-btn-active' : ''; ?>"
|
||||
data-page="<?php echo $i; ?>">
|
||||
<?php echo $i; ?>
|
||||
</button>
|
||||
<?php endfor; ?>
|
||||
<button type="button" class="s-res-page-btn" data-page="<?php echo $currentPage + 1; ?>" <?php echo $currentPage >= $totalPages ? 'disabled' : ''; ?>>
|
||||
»
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -3,6 +3,7 @@ include_once "php/controller/showCategory-controller.php";
|
||||
?>
|
||||
|
||||
<main>
|
||||
<?php include_once "includes/alertMessages.php"?>
|
||||
|
||||
<h1><?php if (isset($category) && !empty($category)){ echo htmlspecialchars($category); } ?></h1>
|
||||
|
||||
|
||||
@@ -13,59 +13,8 @@ include_once 'php/controller/showArticle-controller.php';
|
||||
<form method="post" action="php/controller/updateArticle-controller.php?id=<?php if(isset($id) && !empty($id)){echo htmlspecialchars($id);}else{$_SESSION["message"] = "missing_id";} ?>" id="editor-form" class="article-editor-scope.editor-container article-editor-scope editor-container">
|
||||
|
||||
<main class="editor-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 if (isset($_SESSION["message"]) && $_SESSION["message"] == "missing_id"): ?>
|
||||
<p class="alert-message is-error">
|
||||
Es ist ein Fehler aufgetreten. Die ID konnte nicht ausgelesen werden. Bitte versuche es erneut.
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($_SESSION["message"]) && $_SESSION["message"] == "missing_parameters"): ?>
|
||||
<p class="alert-message is-error">
|
||||
Jeder Beitrag muss einen Titel, Kategorie und Inhalt besitzen.
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($_SESSION["message"]) && $_SESSION["message"] == "invalid_title"): ?>
|
||||
<p class="alert-message is-error">
|
||||
Der Titel enthält ungültige Zeichen oder erfüllt die Länge von 5-120 Zeichen nicht.
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($_SESSION["message"]) && $_SESSION["message"] == "invalid_content"): ?>
|
||||
<p class="alert-message is-error">
|
||||
Der Text erlaubt eine Länge von 10 bis maximal 7.000 Zeichen (ca. 1.000 Wörter).
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($_SESSION["message"]) && $_SESSION["message"] == "invalid_category"): ?>
|
||||
<p class="alert-message is-error">
|
||||
Die ausgewählte Kategorie ist ungültig.
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($_SESSION["message"]) && $_SESSION["message"] == "invalid_tags"): ?>
|
||||
<p class="alert-message is-error">
|
||||
Ungültige Schlagworte gefunden. Erlaubt sind nur Buchstaben, Zahlen, Leerzeichen und Bindestriche (2-20 Zeichen).
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($_SESSION["message"]) && $_SESSION["message"] == "validation_missing"): ?>
|
||||
<p class="alert-message is-error">
|
||||
Bei der Validierung deiner Daten ist ein Fehler aufgetreten. Bitte versuche es erneut.
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($_SESSION["message"]) && $_SESSION["message"] == "unauthorized_access"): ?>
|
||||
<p class="alert-message is-error">
|
||||
Sie sind nicht berechtigt, diesen Beitrag zu bearbeiten.
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($_SESSION["message"]) && $_SESSION["message"] == "not_found_article"): ?>
|
||||
<p class="alert-message is-error">
|
||||
Der zu bearbeitende Artikel wurde nicht gefunden. Bitte versuche es erneut.
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
<?php
|
||||
unset($_SESSION["message"]);
|
||||
?>
|
||||
<?php include_once "includes/alertMessages.php"?>
|
||||
|
||||
<input type="text" id="title" name="title"
|
||||
value="<?php
|
||||
if (isset($_SESSION['old_title']) && !empty($_SESSION['old_title'])){
|
||||
|
||||
+39
-22
@@ -57,6 +57,10 @@ CSS für die navbar
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.nav__dropdown-menu a:hover {
|
||||
color: #1d4ed8;
|
||||
}
|
||||
|
||||
.nav__link {
|
||||
display: inline-block;
|
||||
font-weight: 600;
|
||||
@@ -89,6 +93,12 @@ CSS für die navbar
|
||||
border-radius: 4px; /* Abgerundete Ecken */
|
||||
background: #fff;
|
||||
margin: 0 0.5rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.nav__search input {
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.nav__search-button {
|
||||
@@ -115,8 +125,33 @@ CSS für die navbar
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* Responsive Anpassung unter 1210px */
|
||||
@media (max-width: 1210px) {
|
||||
.nav__search-form {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.nav__search {
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.nav__search-button {
|
||||
display: inline-block;
|
||||
background: #fff;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
padding: 0.4rem 0.6rem;
|
||||
font-size: 0.8rem;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
margin-left: 4px;
|
||||
flex-shrink: 0;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* Responsive Anpassung unter 1240px */
|
||||
@media (max-width: 1240px) {
|
||||
.nav {
|
||||
flex-wrap: wrap; /* zweite Nav-Zeile*/
|
||||
padding: 0.5rem 1rem;
|
||||
@@ -151,8 +186,8 @@ CSS für die navbar
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Responsive Anpassungen unter 760px (für z.B. Smartphones) */
|
||||
@media (max-width: 800px) {
|
||||
/* Responsive Anpassungen unter 900px (für z.B. Smartphones) */
|
||||
@media (max-width: 900px) {
|
||||
.nav {
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
@@ -189,24 +224,6 @@ CSS für die navbar
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.nav__search {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.nav__search-button {
|
||||
display: inline-block;
|
||||
background: #fff;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
padding: 0.4rem 0.6rem;
|
||||
font-size: 0.8rem;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
.nav__search-button:hover {
|
||||
background-color: #f8f9fa;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
<?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 if (isset($_SESSION["message"]) && $_SESSION["message"] == "missing_parameters"): ?>
|
||||
<p class="alert-message is-error">
|
||||
Jeder Beitrag muss einen Titel, Kategorie und Inhalt besitzen.
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($_SESSION["message"]) && $_SESSION["message"] == "invalid_title"): ?>
|
||||
<p class="alert-message is-error">
|
||||
Der Titel enthält ungültige Zeichen oder erfüllt die Länge von 5-120 Zeichen nicht.
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($_SESSION["message"]) && $_SESSION["message"] == "invalid_content"): ?>
|
||||
<p class="alert-message is-error">
|
||||
Der Text erlaubt eine Länge von 10 bis maximal 7.000 Zeichen (ca. 1.000 Wörter).
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($_SESSION["message"]) && $_SESSION["message"] == "invalid_category"): ?>
|
||||
<p class="alert-message is-error">
|
||||
Die ausgewählte Kategorie ist ungültig.
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($_SESSION["message"]) && $_SESSION["message"] == "invalid_tags"): ?>
|
||||
<p class="alert-message is-error">
|
||||
Ungültige Schlagworte gefunden. Erlaubt sind nur Buchstaben, Zahlen, Leerzeichen und Bindestriche (2-50 Zeichen).
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($_SESSION["message"]) && $_SESSION["message"] == "validation_missing"): ?>
|
||||
<p class="alert-message is-error">
|
||||
Bei der Validierung deiner Daten ist ein Fehler aufgetreten. Bitte versuche es erneut.
|
||||
</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 if (isset($_SESSION["message"]) && $_SESSION["message"] == "missing_id"): ?>
|
||||
<p class="alert-message is-error">
|
||||
Die Artikel-ID fehlt oder ist ungültig.
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($_SESSION["message"]) && $_SESSION["message"] == "not_found_article"): ?>
|
||||
<p class="alert-message is-error">
|
||||
Der angeforderte Beitrag konnte nicht gefunden werden.
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($_SESSION["message"]) && $_SESSION["message"] == "unauthorized_access"): ?>
|
||||
<p class="alert-message is-error">
|
||||
Du hast keine Berechtigung, diesen Beitrag zu bearbeiten oder zu löschen.
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($_SESSION["message"]) && $_SESSION["message"] == "article_deleted"): ?>
|
||||
<p class="alert-message is-success">
|
||||
Der Beitrag wurde erfolgreich gelöscht.
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($_SESSION["message"]) && $_SESSION["message"] == "new_article"): ?>
|
||||
<p class="alert-message is-success">
|
||||
Dein Beitrag wurde erfolgreich veröffentlicht!
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
<?php
|
||||
unset($_SESSION["message"]);
|
||||
?>
|
||||
+3
-1
@@ -1,5 +1,7 @@
|
||||
<?php
|
||||
session_start();
|
||||
if (session_status() === PHP_SESSION_NONE) {
|
||||
session_start();
|
||||
}
|
||||
?>
|
||||
|
||||
<!--
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
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;">
|
||||
<form action="php/controller/search-results-controller.php" method="GET" class="nav__search-form">
|
||||
|
||||
<input type="hidden" name="pfad" value="search-results">
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<?php
|
||||
session_start();
|
||||
if (session_status() === PHP_SESSION_NONE) {
|
||||
session_start();
|
||||
}
|
||||
ob_start();
|
||||
|
||||
$pfad = $_GET["pfad"] ?? "home";
|
||||
@@ -17,12 +19,12 @@ if ($pfad === "register") {
|
||||
}
|
||||
|
||||
if ($pfad === "logout") {
|
||||
include_once "content/logout.php";
|
||||
include_once "php/controller/logout-controller.php";
|
||||
exit();
|
||||
}
|
||||
|
||||
if ($pfad === "deleteAccount") {
|
||||
include_once "content/deleteAccount.php";
|
||||
include_once "php/controller/deleteAccount-controller.php";
|
||||
exit();
|
||||
}
|
||||
?>
|
||||
@@ -40,6 +42,7 @@ if ($pfad === "deleteAccount") {
|
||||
<meta name="author" content="Niklas Ortmann">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="icon" type="image/x-icon" href="images/logos/logo_icon.ico">
|
||||
|
||||
<link rel="stylesheet" href="css/main.css">
|
||||
<link rel="stylesheet" href="css/navbar.css">
|
||||
<link rel="stylesheet" href="css/footer.css">
|
||||
@@ -48,6 +51,9 @@ if ($pfad === "deleteAccount") {
|
||||
<link rel="stylesheet" href="css/profile.css">
|
||||
<link rel="stylesheet" href="css/showArticle.css">
|
||||
<link rel="stylesheet" href="css/message.css">
|
||||
|
||||
<script src="js/paginator.js" async></script>
|
||||
|
||||
<title>EduForge</title>
|
||||
</head>
|
||||
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
function initPaginator() {
|
||||
const form = document.getElementById('search-form-id');
|
||||
const pageInput = document.getElementById('s-res-page-input');
|
||||
const pageButtons = document.querySelectorAll('.s-res-page-navigation .s-res-page-btn');
|
||||
|
||||
pageButtons.forEach(button => {
|
||||
button.addEventListener('click', function() {
|
||||
if (this.disabled) return;
|
||||
|
||||
const targetPage = this.getAttribute('data-page');
|
||||
|
||||
if (targetPage && form && pageInput) {
|
||||
pageInput.value = targetPage;
|
||||
form.submit();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// ist das DOM bereits vollständig aufgebaut?
|
||||
if (document.readyState === 'loading') {
|
||||
// Falls noch geladen wird, auf das Event warten
|
||||
document.addEventListener('DOMContentLoaded', initPaginator);
|
||||
} else {
|
||||
// Falls das HTML bereits komplett da ist, sofort ausführen
|
||||
initPaginator();
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
<?php
|
||||
SESSION_START();
|
||||
if (session_status() === PHP_SESSION_NONE) {
|
||||
session_start();
|
||||
}
|
||||
require_once '../model/LocalArticleManager.php';
|
||||
require_once '../model/ArticleManager.php';
|
||||
require_once '../validator/article-validator.php';
|
||||
require_once "../model/LocalUserManager.php";
|
||||
|
||||
if ($_SERVER["REQUEST_METHOD"] === "POST") {
|
||||
$_SESSION["old_title"] = $_POST["title"] ?? '';
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
if (session_status() === PHP_SESSION_NONE) {
|
||||
session_start();
|
||||
}
|
||||
|
||||
require_once __DIR__ . "/../model/UserManager.php";
|
||||
require_once __DIR__ . "/../model/ArticleManager.php";
|
||||
|
||||
/*
|
||||
Deregistrierung
|
||||
Funktion: Entfernt User aus der Datenbank und beendet die Session
|
||||
*/
|
||||
|
||||
try {
|
||||
|
||||
$dao = UserManager::getInstance();
|
||||
$articleManager = ArticleManager::getInstance();
|
||||
|
||||
if (isset($_SESSION["user_email"])) {
|
||||
$dao->deleteUser($_SESSION["user_email"]);
|
||||
|
||||
$articles = $articleManager->getArticlesByAuthor($_SESSION["user_email"]);
|
||||
foreach ($articles as $article) {
|
||||
$articleManager->deleteArticle($article->getId(), $_SESSION["user_email"]);
|
||||
}
|
||||
|
||||
} else {
|
||||
throw new NotFoundException("missing_user_email");
|
||||
}
|
||||
|
||||
$_SESSION = [];
|
||||
session_destroy();
|
||||
|
||||
header("Location: ../../index.php");
|
||||
exit();
|
||||
|
||||
} catch (Exception $e) {
|
||||
|
||||
$_SESSION["message"] = "internal_error";
|
||||
|
||||
header("Location: ../../index.php?pfad=profile");
|
||||
exit();
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
if (session_status() === PHP_SESSION_NONE) {
|
||||
session_start();
|
||||
}
|
||||
|
||||
require_once __DIR__ . "/../model/ArticleManager.php";
|
||||
|
||||
if ($_SERVER["REQUEST_METHOD"] === "POST") {
|
||||
|
||||
if (isset($_SESSION["user_email"])) {
|
||||
$user = $_SESSION["user_email"];
|
||||
} else {
|
||||
$_SESSION = [];
|
||||
session_destroy();
|
||||
|
||||
header("Location: ../../index.php");
|
||||
exit();
|
||||
}
|
||||
|
||||
if (isset($_POST["id"]) && !empty($_POST["id"])) {
|
||||
$id = $_POST["id"];
|
||||
} else {
|
||||
$_SESSION["message"] = "missing_id";
|
||||
header("location: ../../index.php?pfad=profile");
|
||||
exit();
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
$articleManager = ArticleManager::getInstance();
|
||||
$articleManager->deleteArticle($id, $user);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
$_SESSION["message"] = $e->getMessage();
|
||||
header("location: ../../index.php?pfad=profile");
|
||||
exit();
|
||||
}
|
||||
|
||||
$_SESSION["message"] = "article_deleted";
|
||||
header("location: ../../index.php?pfad=profile");
|
||||
exit();
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
<?php
|
||||
session_start();
|
||||
if (session_status() === PHP_SESSION_NONE) {
|
||||
session_start();
|
||||
}
|
||||
require_once 'php/model/Article.php';
|
||||
require_once 'php/model/ArticleManager.php';
|
||||
require_once 'php/model/LocalArticleManager.php';
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
<?php
|
||||
|
||||
require_once "php/model/LocalUserManager.php";
|
||||
require_once "php/model/UserManager.php";
|
||||
|
||||
$dao = new LocalUserManager();
|
||||
$error = null;
|
||||
|
||||
/*
|
||||
@@ -11,6 +10,10 @@ $error = null;
|
||||
*/
|
||||
if ($_SERVER["REQUEST_METHOD"] === "POST") {
|
||||
|
||||
try {
|
||||
|
||||
$dao = UserManager::getInstance();
|
||||
|
||||
$email = $_POST["email"] ?? "";
|
||||
$password = $_POST["password"] ?? "";
|
||||
|
||||
@@ -18,12 +21,7 @@ if ($_SERVER["REQUEST_METHOD"] === "POST") {
|
||||
|
||||
if ($user && password_verify($password, $user["password"])) {
|
||||
|
||||
if (isset($user["vorname"]) && isset($user["nachname"])) {
|
||||
$_SESSION["user"] = $user["vorname"] . " " . $user["nachname"];
|
||||
} else {
|
||||
$_SESSION["user"] = $user["username"] ?? "";
|
||||
}
|
||||
|
||||
$_SESSION["user_email"] = $user["email"];
|
||||
|
||||
header("Location: index.php");
|
||||
@@ -32,4 +30,8 @@ if ($_SERVER["REQUEST_METHOD"] === "POST") {
|
||||
} else {
|
||||
$error = "Login fehlgeschlagen. Bitte überprüfe deine Eingaben.";
|
||||
}
|
||||
|
||||
} catch (Exception $e) {
|
||||
$error = "Es ist ein interner Fehler aufgetreten. Bitte versuche es erneut.";
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
require_once "php/model/LocalUserManager.php";
|
||||
require_once "php/model/UserManager.php";
|
||||
require_once "php/model/Article.php";
|
||||
require_once "php/model/ArticleManager.php";
|
||||
require_once "php/validator/user-validator.php";
|
||||
@@ -13,7 +13,7 @@ if (!isset($_SESSION["user"])) {
|
||||
}
|
||||
|
||||
try {
|
||||
$dao = new LocalUserManager();
|
||||
$dao = UserManager::getInstance();
|
||||
|
||||
$user = $dao->findUser($_SESSION["user_email"] ?? "");
|
||||
|
||||
@@ -38,15 +38,15 @@ try {
|
||||
$_GET["edit"] = "1";
|
||||
|
||||
} elseif (!userNameValidator($vorname)) {
|
||||
$error = "Der Vorname muss 2 bis 50 Zeichen lang sein und darf nur Buchstaben, Leerzeichen und Bindestriche enthalten.";
|
||||
$error = "Der Vorname muss 2 bis 20 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.";
|
||||
$error = "Der Nachname muss 2 bis 20 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.";
|
||||
$error = "Das Passwort muss 5 bis 12 Zeichen lang sein.";
|
||||
$_GET["edit"] = "1";
|
||||
|
||||
} else {
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
|
||||
require_once 'php/model/Article.php';
|
||||
require_once 'php/model/ArticleManager.php';
|
||||
require_once "../model/LocalUserManager.php";
|
||||
require_once "php/model/UserManager.php";
|
||||
|
||||
try {
|
||||
$dao = new LocalUserManager();
|
||||
$dao = UserManager::getInstance();
|
||||
$user = $dao->findUser($_SESSION["user_email"] ?? "");
|
||||
|
||||
$author = $user["email"];
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
require_once "php/model/LocalUserManager.php";
|
||||
require_once "php/model/UserManager.php";
|
||||
require_once "php/validator/user-validator.php";
|
||||
|
||||
$error = null;
|
||||
@@ -15,14 +15,14 @@ if ($_SERVER["REQUEST_METHOD"] === "POST") {
|
||||
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.";
|
||||
$error = "Der Vorname muss 2 bis 20 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.";
|
||||
$error = "Der Nachname muss 2 bis 20 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.";
|
||||
$error = "Das Passwort muss 5 bis 12 Zeichen lang sein.";
|
||||
} else {
|
||||
try {
|
||||
$dao = new LocalUserManager();
|
||||
$dao = UserManager::getInstance();
|
||||
|
||||
$password = password_hash($plainPassword, PASSWORD_DEFAULT);
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<?php
|
||||
session_start();
|
||||
if (session_status() === PHP_SESSION_NONE) {
|
||||
session_start();
|
||||
}
|
||||
require_once '../model/LocalArticleManager.php';
|
||||
require_once '../model/ArticleManager.php';
|
||||
require_once '../model/Article.php';
|
||||
@@ -60,7 +62,11 @@ if ($_SERVER["REQUEST_METHOD"] === "GET" && isset($_GET["q"])) {
|
||||
$_SESSION["message"] = "internal_error";
|
||||
}
|
||||
}
|
||||
header("Location: ../../index.php?pfad=search-results");
|
||||
|
||||
$sort = $_GET['sort'] ?? 'alphabet';
|
||||
$limit = isset($_GET['limit']) ? (int)$_GET['limit'] : 10;
|
||||
$page = isset($_GET['page']) ? (int)$_GET['page'] : 1;
|
||||
header("Location: ../../index.php?pfad=search-results&q=" . urlencode($search) . "&sort=" . urlencode($sort) . "&limit=" . $limit . "&page=" . $page);
|
||||
exit();
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
<?php
|
||||
session_start();
|
||||
if (session_status() === PHP_SESSION_NONE) {
|
||||
session_start();
|
||||
}
|
||||
|
||||
require_once 'php/model/Article.php';
|
||||
require_once 'php/model/ArticleManager.php';
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
<?php
|
||||
SESSION_START();
|
||||
if (session_status() === PHP_SESSION_NONE) {
|
||||
session_start();
|
||||
}
|
||||
|
||||
require_once '../model/LocalArticleManager.php';
|
||||
require_once '../model/ArticleManager.php';
|
||||
require_once '../model/Article.php';
|
||||
|
||||
+137
-25
@@ -4,43 +4,155 @@ require_once 'DatabaseArticleManager.php';
|
||||
require_once 'Article.php';
|
||||
|
||||
/**
|
||||
* Die Klasse beinhaltet alle Methoden für die Operation mit den Artikel-Daten.
|
||||
* Die Klasse beinhaltet alle Methoden für die Operation mit den Beitrags-Daten.
|
||||
*
|
||||
* @author Niklas Ortmann
|
||||
*/
|
||||
class ArticleManager
|
||||
{
|
||||
/**
|
||||
* Diese Methode erstellt, falls noch keine existiert, eine Instanz einer ArticleManager-Implementierung und
|
||||
* erstellt Dummy-Beiträge.
|
||||
*
|
||||
* @throws InternalServerErrorException
|
||||
*/
|
||||
public static function getInstance()
|
||||
{
|
||||
$articleManager = DatabaseArticleManager::getInstance(); // Hier kann zwischen dem lokalen und datenbankbasiertem ArticleManager gewechselt werden.
|
||||
|
||||
// Erstellen von Dummy-Beiträgen:
|
||||
if($articleManager->getArticle(1) == null ){
|
||||
// 100 fiktionale Fachbeiträge:
|
||||
$dummyArticles = [
|
||||
// --- INFORMATIK & MATHE (1-20) ---
|
||||
1 => ["Satz des Pythagoras", "Der Satz des Pythagoras beschreibt das Verhältnis der Seitenlängen in einem rechtwinkligen Dreieck.", "mathe", "Dreiecke, Geometrie"],
|
||||
2 => ["Tunneleffekt", "Der Tunneleffekt beschreibt das quantenmechanische Phänomen, dass Teilchen Barrieren überwinden können.", "physik", "Quantenphysik, Energie"],
|
||||
3 => ["Datenschutz vs Datensicherheit", "Datenschutz schützt Personen, während Datensicherheit Systeme vor unbefugten Zugriffen schützt.", "informatik", "Daten, DSGVO"],
|
||||
4 => ["Einführung in Algorithmen", "Ein Algorithmus ist eine präzise Handlungsanweisung zur Lösung eines vordefinierten Problems.", "informatik", "Code, Logik"],
|
||||
5 => ["Primzahlen im Detail", "Primzahlen sind natürliche Zahlen, die nur durch eins und sich selbst ohne Rest teilbar sind.", "mathe", "Zahlentheorie"],
|
||||
6 => ["Lineare Algebra", "Vektoren und Matrizen bilden das Fundament für moderne Computergrafik und 3D-Engines.", "mathe", "Matrizen, Vektoren"],
|
||||
7 => ["Objektorientierte Programmierung", "Die OOP nutzt Klassen und Objekte, um reale Strukturen im Quellcode abzubilden.", "informatik", "OOP, Klassen"],
|
||||
8 => ["Grundlagen von HTML und CSS", "HTML strukturiert den Inhalt einer Webseite, während CSS für das optische Design zuständig ist.", "informatik", "Web, Frontend"],
|
||||
9 => ["Die Relativitätstheorie", "Einsteins Theorie revolutionierte unser Verständnis von Raum, Zeit und Gravitation massiv.", "physik", "Einstein, Gravitation"],
|
||||
10 => ["Datenbanken und SQL", "Strukturierte Abfragesprachen erlauben das effiziente Speichern und Abrufen großer Datenmengen.", "informatik", "SQL, Datenbank"],
|
||||
11 => ["Wahrscheinlichkeitsrechnung", "Die Stochastik befasst sich mit der mathematischen Analyse von Zufallsexperimenten.", "mathe", "Zufall, Stochastik"],
|
||||
12 => ["Quantencomputing", "Künftige Quantencomputer nutzen Qubits, um komplexe Berechnungen in Rekordzeit zu lösen.", "informatik", "Hardware, Zukunft"],
|
||||
13 => ["Die Fibonacci-Folge", "Diese Zahlenreihe beschreibt mathematische Wachstumsmuster, die oft in der Natur vorkommen.", "mathe", "Zahlen, Natur"],
|
||||
14 => ["Thermodynamik", "Die Hauptsätze der Thermodynamik regeln den Energieaustausch und die Entropie in Systemen.", "physik", "Energie, Wärme"],
|
||||
15 => ["Cybersecurity Grundlagen", "Die Absicherung von Netzwerken erfordert Firewalls, Verschlüsselung und regelmäßige Audits.", "informatik", "Sicherheit, Hacker"],
|
||||
16 => ["Kryptographie", "Asymmetrische Verschlüsselungsverfahren sichern heutzutage den gesamten Datenverkehr im Web.", "informatik", "Krypto, Security"],
|
||||
17 => ["Analysis und Ableitungen", "Die Differentialrechnung untersucht die lokalen Änderungsraten von mathematischen Funktionen.", "mathe", "Analysis, Funktionen"],
|
||||
18 => ["Schwarze Löcher", "Diese Regionen im Raum besitzen eine so starke Gravitation, dass selbst Licht nicht entkommt.", "physik", "Astronomie, Kosmos"],
|
||||
19 => ["Git Versionsverwaltung", "Git erlaubt Entwicklern das parallele Arbeiten an Code-Projekten ohne Datenverlust.", "informatik", "Git, DevOps"],
|
||||
20 => ["Künstliche Intelligenz", "Neuronale Netze versuchen das menschliche Gehirn für maschinelles Lernen nachzubilden.", "informatik", "KI, Software"],
|
||||
|
||||
// --- CHEMIE & BIOLOGIE (21-40) ---
|
||||
21 => ["Das Periodensystem", "Die Elemente sind nach ihrer Ordnungszahl und chemischen Eigenschaften geordnet.", "chemie", "Elemente, Moleküle"],
|
||||
22 => ["Photosynthese", "Pflanzen wandeln mithilfe von Sonnenlicht Kohlendioxid und Wasser in Glukose und Sauerstoff um.", "biologie", "Pflanzen, Energie"],
|
||||
23 => ["Aufbau einer Zelle", "Die Zelle ist die kleinste lebende Einheit aller Organismen mit spezialisierten Organellen.", "biologie", "Zellen, Biologie"],
|
||||
24 => ["Säuren und Basen", "Der pH-Wert misst die Konzentration von Wasserstoff-Ionen in einer wässrigen Lösung.", "chemie", "Labor, pH-Wert"],
|
||||
25 => ["Die DNA-Struktur", "Die Doppelhelix enthält den genetischen Bauplan für die Entwicklung aller Lebewesen.", "biologie", "Genetik, Erbgut"],
|
||||
26 => ["Chemische Bindungen", "Kovalente Bindungen entstehen durch das Teilen von Elektronenpaaren zwischen Atomen.", "chemie", "Atome, Bindung"],
|
||||
27 => ["Das Immunsystem", "Weiße Blutkörperchen und Antikörper schützen den menschlichen Körper vor Krankheitserregern.", "biologie", "Gesundheit, Abwehr"],
|
||||
28 => ["Katalysatoren", "Katalysatoren beschleunigen chemische Reaktionen, ohne dabei selbst verbraucht zu werden.", "chemie", "Reaktion, Chemie"],
|
||||
29 => ["Ökosystem Wald", "Das Zusammenspiel von Flora, Fauna und Klima bildet ein hochsensibles ökologisches System.", "biologie", "Natur, Wald"],
|
||||
30 => ["Die Mendelschen Regeln", "Diese Grundgesetze der Vererbung beschreiben, wie Merkmale an Nachkommen weitergegeben werden.", "biologie", "Genetik, Erbung"],
|
||||
31 => ["Zustandsformen der Materie", "Fest, flüssig und gasförmig sind die klassischen Aggregatzustände von Stoffen.", "chemie", "Physik, Materie"],
|
||||
32 => ["Evolutionstheorie", "Charles Darwin begründete die Theorie der natürlichen Auslese und Anpassung von Arten.", "biologie", "Darwin, Evolution"],
|
||||
33 => ["Organische Chemie", "Die Chemie der Kohlenstoffverbindungen bildet die Basis für alles bekannte Leben.", "chemie", "Kohlenstoff, Chemie"],
|
||||
34 => ["Das menschliche Gehirn", "Milliarden von Neuronen kommunizieren über Synapsen, um Reize und Gedanken zu verarbeiten.", "biologie", "Neurologie, Nerven"],
|
||||
35 => ["Der Wasserkreislauf", "Verdunstung, Kondensation und Niederschlag halten das Wasser auf der Erde in Bewegung.", "geographie", "Wasser, Klima"],
|
||||
36 => ["Aggregatzustände von Wasser", "Wasser zeigt ungewöhnliche Eigenschaften wie die Dichteanomalie beim Gefrieren.", "chemie", "Wasser, Eis"],
|
||||
37 => ["Blutkreislauf des Menschen", "Das Herz pumpt sauerstoffreiches Blut durch Arterien in alle Organe des Körpers.", "biologie", "Herz, Medizin"],
|
||||
38 => ["Das Ohmsche Gesetz", "Es beschreibt den direkten Zusammenhang zwischen Spannung, Stromstärke und Widerstand.", "physik", "Strom, Elektronik"],
|
||||
39 => ["Plattentektonik", "Die Bewegung der Kontinentalplatten führt zu Erdbeben, Vulkanismus und Gebirgsbildung.", "geographie", "Erde, Geologie"],
|
||||
40 => ["Proteine und Enzyme", "Enzyme wirken als Biokatalysatoren und steuern fast alle Stoffwechselprozesse.", "biologie", "Biochemie, Enzyme"],
|
||||
|
||||
// --- GESCHICHTE & WIRTSCHAFT (41-60) ---
|
||||
41 => ["Das Römische Reich", "Vom Stadtstaat zum Weltreich prägte Rom die Rechts- und Kulturgeschichte Europas.", "geschichte", "Antike, Rom"],
|
||||
42 => ["Die Französische Revolution", "Freiheit, Gleichheit, Brüderlichkeit beendeten 1789 die absolute Monarchie in Frankreich.", "geschichte", "Europa, Politik"],
|
||||
43 => ["Inflation erklärt", "Inflation bezeichnet die kontinuierliche Geldentwertung und den Kaufkraftverlust.", "wirtschaft", "Geld, Finanzen"],
|
||||
44 => ["Die Industrielle Revolution", "Die Erfindung der Dampfmaschine veränderte die Produktion und die Gesellschaft tiefgreifend.", "geschichte", "Industrie, Arbeit"],
|
||||
45 => ["Angebot und Nachfrage", "Dieses fundamentale Marktgesetz bestimmt den Preis von Gütern in einer freien Wirtschaft.", "wirtschaft", "Markt, Preise"],
|
||||
46 => ["Der Buchdruck", "Johannes Gutenbergs Erfindung revolutionierte die Verbreitung von Wissen im Mittelalter.", "geschichte", "Medien, Wissen"],
|
||||
47 => ["Die Entdeckung Amerikas", "Kolumbus' Seereise im Jahr 1492 leitete das Zeitalter der Kolonialisierung ein.", "geschichte", "Entdeckung, Seefahrt"],
|
||||
48 => ["Kryptowährungen", "Bitcoin nutzt Blockchain-Technologie, um dezentralen digitalen Werttransfer zu erlauben.", "wirtschaft", "Blockchain, Finanzen"],
|
||||
49 => ["Das antike Griechenland", "Die Wiege der Demokratie und Philosophie brachte Denker wie Sokrates und Platon hervor.", "geschichte", "Antike, Philosophie"],
|
||||
50 => ["Globalisierung", "Die weltweite Verflechtung in Wirtschaft, Kultur und Politik bringt Chancen und Risiken.", "wirtschaft", "Weltwirtschaft, Handel"],
|
||||
51 => ["Der Dreißigjährige Krieg", "Ein religiöser und politischer Konflikt verwüstete zwischen 1618 und 1648 Mitteleuropa.", "geschichte", "Krieg, Europa"],
|
||||
52 => ["Die Weimarer Republik", "Die erste deutsche Demokratie scheiterte an wirtschaftlichen und politischen Krisen.", "geschichte", "Deutschland, Weimar"],
|
||||
53 => ["Aktien und Börse", "Unternehmen beschaffen sich Kapital durch die Ausgabe von Anteilen an Investoren.", "wirtschaft", "Aktien, Investieren"],
|
||||
54 => ["Das alte Ägypten", "Pharaonen, Pyramiden und Hieroglyphen zeugen von einer hochentwickelten Hochkultur am Nil.", "geschichte", "Ägypten, Antike"],
|
||||
55 => ["Der Kalte Krieg", "Das Wettrüsten zwischen USA und UdSSR prägte die globale Politik der Nachkriegszeit.", "geschichte", "Ost-West, Politik"],
|
||||
56 => ["Zentralbanken und Leitzins", "Durch Zinsänderungen steuern Notenbanken die Geldmenge und bekämpfen Inflation.", "wirtschaft", "Zinsen, Geldpolitik"],
|
||||
57 => ["Die Seidenstraße", "Das historische Netzwerk von Handelsrouten verband über Jahrhunderte Asien und Europa.", "geschichte", "Handel, Asien"],
|
||||
58 => ["Das Mittelalter", "Ritter, Burgen und das Feudalsystem prägten diese tausendjährige Epoche Europas.", "geschichte", "Mittelalter, Feudalismus"],
|
||||
59 => ["Planwirtschaft vs Marktwirtschaft", "Zentrale staatliche Steuerung steht dem freien Spiel der Marktkräfte gegenüber.", "wirtschaft", "Systeme, Wirtschaft"],
|
||||
60 => ["Die Berliner Mauer", "Ihr Bau 1961 zementierte die Teilung Deutschlands, ihr Fall 1989 beendete sie.", "geschichte", "DDR, Wiedervereinigung"],
|
||||
|
||||
// --- ANWENDUNGEN & WEITERE THEMEN (61-100) ---
|
||||
61 => ["Cloud Computing", "Das Auslagern von Rechenleistung in das Internet spart lokale IT-Infrastruktur ein.", "informatik", "Cloud, Web"],
|
||||
62 => ["Responsive Webdesign", "Moderne Webseiten passen ihr Layout dynamisch an Smartphones und Desktops an.", "informatik", "Design, CSS"],
|
||||
63 => ["Der Treibhauseffekt", "Gase in der Atmosphäre verhindern das Entweichen von Wärme ins Weltall.", "physik", "Klima, Umwelt"],
|
||||
64 => ["Mechanik und Kräfte", "Die Newtonschen Axiome beschreiben, wie Kräfte auf Körper wirken und sie bewegen.", "physik", "Newton, Kraft"],
|
||||
65 => ["Die Mendelschen Gesetze", "Die Vererbung von Genen folgt klaren statistischen Wahrscheinlichkeiten.", "biologie", "Genetik, Erbsen"],
|
||||
66 => ["Lichtgeschwindigkeit", "Im Vakuum bewegt sich Licht mit knapp 300.000 Kilometern pro Sekunde.", "physik", "Licht, Relativität"],
|
||||
67 => ["Die Funktion von APIs", "Programmierschnittstellen erlauben den Datenaustausch zwischen verschiedenen Systemen.", "informatik", "API, Schnittstelle"],
|
||||
68 => ["Der Goldstandard", "Ein historischen Währungssystem, bei dem Geld durch echtes Gold gedeckt war.", "wirtschaft", "Gold, Währung"],
|
||||
69 => ["Der Wiener Kongress", "1815 ordneten die europäischen Mächte die Landkarte nach den Napoleonischen Kriegen neu.", "geschichte", "Europa, Diplomatie"],
|
||||
70 => ["Integrierte Schaltkreise", "Mikrochips enthalten Millionen Transistoren auf kleinstem Raum für Logikschaltungen.", "informatik", "Hardware, Chips"],
|
||||
71 => ["Die Magellan-Expedition", "Die erste erfolgreiche Weltumsegelung bewies praktisch die Kugelgestalt der Erde.", "geschichte", "Seefahrt, Erde"],
|
||||
72 => ["Das Internet der Dinge", "Alltagsgegenstände werden vernetzt, um smarte Automatisierungen zu ermöglichen.", "informatik", "IoT, SmartHome"],
|
||||
73 => ["Halbwertszeit", "Die Zeitspanne, in der sich die Hälfte der instabilen Atome radioaktiv abbaut.", "physik", "Atomphysik, Strahlung"],
|
||||
74 => ["Elektromagnetismus", "Die Verknüpfung von elektrischen Strömen und magnetischen Feldern treibt Motoren an.", "physik", "Strom, Magnet"],
|
||||
75 => ["Das Ökosystem Meer", "Ozeane regulieren das Weltklima und bieten Lebensraum für unzählige Arten.", "biologie", "Meer, Ökologie"],
|
||||
76 => ["Einführung in Docker", "Containerisierung isoliert Anwendungen samt Abhängigkeiten für stabilen Betrieb.", "informatik", "Docker, DevOps"],
|
||||
77 => ["Das Römische Recht", "Viele moderne europäische Gesetzbücher basieren auf antiken römischen Rechtsprinzipien.", "geschichte", "Recht, Gesetz"],
|
||||
78 => ["Verhaltensbiologie", "Untersuchung von angeborenen und erlernten Verhaltensweisen bei Mensch und Tier.", "biologie", "Verhalten, Tiere"],
|
||||
79 => ["Verschlüsselung im Alltag", "HTTPS schützt Passwörter und Zahlungsdaten beim Surfen vor dem Mitlesen.", "informatik", "Web, HTTPS"],
|
||||
80 => ["Die Magna Carta", "1215 schränkte dieses Dokument die absolute Macht des englischen Königs ein.", "geschichte", "England, Verfassung"],
|
||||
81 => ["Marktversagen", "Wenn der freie Markt Ressourcen unvollständig verteilt, muss der Staat eingreifen.", "wirtschaft", "Markt, Staat"],
|
||||
82 => ["Optische Linsen", "Konvexe und konkave Linsen brechen Licht für Brillen, Mikroskope und Kameras.", "physik", "Optik, Licht"],
|
||||
83 => ["Die Entstehung der Erde", "Vor rund 4,5 Milliarden Jahren ballte sich kosmischer Staub zu unserem Planeten.", "geographie", "Erde, Kosmos"],
|
||||
84 => ["Grundlagen von JavaScript", "Diese Skriptsprache macht statische Webseiten interaktiv und dynamisch nutzbar.", "informatik", "JS, Webentwicklung"],
|
||||
85 => ["Die industrielle Landwirtschaft", "Moderne Techniken sichern Welternährung, belasten jedoch oft die Umwelt.", "biologie", "Landwirtschaft, Umwelt"],
|
||||
86 => ["Das Schwarze Jahr 1929", "Der New Yorker Börsencrash löste die verheerende Weltwirtschaftskrise aus.", "geschichte", "Krise, Finanzen"],
|
||||
87 => ["Die Evolution des Menschen", "Der Stammbaum des Homo Sapiens entwickelte sich über Millionen Jahre in Afrika.", "biologie", "Mensch, Evolution"],
|
||||
88 => ["Einführung in Linux", "Das Open-Source-Betriebssystem bildet das Rückgrat moderner Server-Infrastrukturen.", "informatik", "Linux, OS"],
|
||||
89 => ["Der Urknall", "Die Urknalltheorie beschreibt den Beginn des Universums aus einer Singularität.", "physik", "Astronomie, Urknall"],
|
||||
90 => ["Das Periodensystem der Elemente", "Dmitri Mendelejew ordnete Elemente logisch nach ihren Atommassen.", "chemie", "Periodensystem, Chemie"],
|
||||
91 => ["Die Hanse", "Ein mächtiger mittelalterlicher Bund von Kaufleuten dominierte den Nordseehandel.", "geschichte", "Handel, Mittelalter"],
|
||||
92 => ["Wirtschaftswachstum", "Die Steigerung des Bruttoinlandsprodukts gilt oft als Indikator für Wohlstand.", "wirtschaft", "BIP, Finanzen"],
|
||||
93 => ["Neuronale Netze", "Diese Strukturen lernen durch mathematische Gewichtung aus riesigen Datenmengen.", "informatik", "KI, Mathematik"],
|
||||
94 => ["Der Erste Weltkrieg", "Der globale Konflikt von 1914 bis 1918 zerstörte das alte europäische Machtgefüge.", "geschichte", "Europa, Krieg"],
|
||||
95 => ["Das Gehirn und Hormone", "Botenstoffe steuern Gefühle, Schlafzyklen und Reaktionen des Körpers.", "biologie", "Medizin, Hormone"],
|
||||
96 => ["SQL Joins erklärt", "Joins verknüpfen Daten aus mehreren Tabellen über gemeinsame Schlüssel.", "informatik", "SQL, Datenbanken"],
|
||||
97 => ["Wellen-Teilchen-Dualismus", "Quantenobjekte zeigen je nach Messaufbau Eigenschaften von Wellen oder Teilchen.", "physik", "Quanten, Licht"],
|
||||
98 => ["Der Absolutismus", "Der Sonnenkönig Ludwig XIV. verkörperte die unbeschränkte Herrschaft des Monarchen.", "geschichte", "Frankreich, Monarchie"],
|
||||
99 => ["Die Funktion von Routern", "Netzwerkgeräte leiten Datenpakete über IP-Adressen an den richtigen Empfänger.", "informatik", "Netzwerk, Internet"],
|
||||
100 => ["Die Entstehung des Geldes", "Vom Tauschhandel über Naturalgeld bis hin zu modernen digitalen Fiat-Währungen.", "wirtschaft", "Geld, Geschichte"]
|
||||
];
|
||||
|
||||
// 10 Dummy-User:
|
||||
$authors = [
|
||||
'max.mustermann@web.de', 'erika.mustermann@web.de', 'john.doe@gmail.com',
|
||||
'jane.doe@gmail.com', 'anna.schmidt@gmx.de', 'thomas.mueller@gmx.de',
|
||||
'sabine.fischer@outlook.com', 'michael.weber@outlook.com', 'julia.wagner@t-online.de',
|
||||
'stefan.becker@t-online.de'
|
||||
];
|
||||
|
||||
foreach ($dummyArticles as $id => $data) {
|
||||
// Falls der Artikel mit der ID noch nicht existiert, lege ihn an
|
||||
if ($articleManager->getArticle($id) == null) {
|
||||
// Verteilt die 10 Autoren gleichmäßig (ID 1 -> Autor 1, ID 10 -> Autor 10, ID 11 -> Autor 1)
|
||||
$authorEmail = $authors[($id - 1) % 10];
|
||||
|
||||
$articleManager->addArticle(
|
||||
"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",
|
||||
"Dreiecke, Dreiecksseiten berechnen"
|
||||
$data[0], // Titel
|
||||
$data[1], // Inhalt
|
||||
$authorEmail, // Rotierende Autoren-E-Mail
|
||||
$data[2], // Kategorie
|
||||
$data[3] // Tags
|
||||
);
|
||||
}
|
||||
if($articleManager->getArticle(2) == null ){
|
||||
$articleManager->addArticle(
|
||||
"Tunneleffekt",
|
||||
"Der Tunneleffekt ist ein quantenmechanisches Phänomen, bei dem Teilchen...",
|
||||
"max.mustermann",
|
||||
"physik",
|
||||
"Quantenphysik, Energie"
|
||||
);
|
||||
}
|
||||
if($articleManager->getArticle(3) == null ){
|
||||
$articleManager->addArticle(
|
||||
"Datenschutz vs Datensicherheit",
|
||||
"Datenschutz ist in unserer digital vernetzten Welt allgegenwärtig...",
|
||||
"max.mustermann",
|
||||
"informatik",
|
||||
"Daten, DSGVO"
|
||||
);
|
||||
}
|
||||
|
||||
return $articleManager;
|
||||
|
||||
@@ -80,6 +80,7 @@ interface ArticleManagerDAO
|
||||
* (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.
|
||||
* @throws InternalServerErrorException
|
||||
*/
|
||||
public function search(string $keyword): array;
|
||||
|
||||
|
||||
@@ -147,7 +147,7 @@ class DatabaseArticleManager implements ArticleManagerDAO {
|
||||
|
||||
public function deleteArticle($id, $author)
|
||||
{
|
||||
$article = getArticle($id);
|
||||
$article = $this->getArticle($id);
|
||||
if (empty($article)) {
|
||||
throw new NotFoundException("not_found_article");
|
||||
}
|
||||
@@ -306,8 +306,57 @@ class DatabaseArticleManager implements ArticleManagerDAO {
|
||||
|
||||
public function search(string $keyword): array
|
||||
{
|
||||
// TODO: implement search()
|
||||
$cleankeyword = trim($keyword);
|
||||
|
||||
// Leeren Suchbegriff sofort abfangen
|
||||
if ($cleankeyword === '') {
|
||||
return [];
|
||||
}
|
||||
|
||||
try {
|
||||
$db = $this->getConnection();
|
||||
|
||||
$sql = "SELECT id, title, content, author, category, tags, created
|
||||
FROM articles
|
||||
WHERE title LIKE :keyword
|
||||
OR content LIKE :keyword;";
|
||||
|
||||
$command = $db->prepare($sql);
|
||||
if (!$command) {
|
||||
throw new InternalServerErrorException("internal_error");
|
||||
}
|
||||
|
||||
// Wildcards für die Suche hinzufügen
|
||||
$searchParam = '%' . $cleankeyword . '%';
|
||||
|
||||
$success = $command->execute([
|
||||
":keyword" => $searchParam
|
||||
]);
|
||||
|
||||
if (!$success) {
|
||||
throw new InternalServerErrorException("internal_error");
|
||||
}
|
||||
|
||||
$rows = $command->fetchAll(PDO::FETCH_ASSOC);
|
||||
$filteredArticles = [];
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$filteredArticles[] = new Article(
|
||||
intval($row['id']),
|
||||
$row['title'] ?? '',
|
||||
$row['content'] ?? '',
|
||||
$row['author'] ?? '',
|
||||
$row['category'] ?? '',
|
||||
$row['tags'] ?? '',
|
||||
$row['created'] ?? '' // Nutzt 'created' aus deiner DB-Struktur
|
||||
);
|
||||
}
|
||||
|
||||
return $filteredArticles;
|
||||
|
||||
} catch (PDOException $e) {
|
||||
throw new InternalServerErrorException("internal_error");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,26 +1,261 @@
|
||||
<?php
|
||||
|
||||
require_once "UserManagerDAO.php";
|
||||
|
||||
/**
|
||||
* Klasse für den Zugriff auf Benutzerdaten über eine SQLite-Datenbank.
|
||||
*
|
||||
* Diese Klasse verwendet PDO, Prepared Statements und speichert
|
||||
* Benutzerdaten in der Datei db/users.db.
|
||||
*/
|
||||
class DatabaseUserManager implements UserManagerDAO {
|
||||
|
||||
private static $instance = null;
|
||||
|
||||
/**
|
||||
* Konstruktor.
|
||||
*
|
||||
* Erstellt die Benutzerdatenbank und die Tabelle users,
|
||||
* falls diese noch nicht existieren.
|
||||
*
|
||||
* @throws RuntimeException wenn die Datenbank nicht erstellt werden kann
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
try {
|
||||
$db = $this->getConnection();
|
||||
|
||||
$db->exec("
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
email TEXT PRIMARY KEY,
|
||||
vorname TEXT NOT NULL,
|
||||
nachname TEXT NOT NULL,
|
||||
password TEXT NOT NULL
|
||||
);
|
||||
");
|
||||
|
||||
unset($db);
|
||||
|
||||
} catch (PDOException $e) {
|
||||
throw new RuntimeException("Benutzerdatenbank konnte nicht erstellt werden.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Baut eine Verbindung zur SQLite-Datenbank auf.
|
||||
*
|
||||
* @return PDO Datenbankverbindung
|
||||
*
|
||||
* @throws RuntimeException wenn keine Verbindung hergestellt werden kann
|
||||
*/
|
||||
private function getConnection()
|
||||
{
|
||||
try {
|
||||
$dsn = 'sqlite:' . __DIR__ . '/../../db/users.db';
|
||||
|
||||
$db = new PDO($dsn, null, null);
|
||||
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
|
||||
return $db;
|
||||
|
||||
} catch (PDOException $e) {
|
||||
throw new RuntimeException("Verbindung zur Benutzerdatenbank fehlgeschlagen.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gibt die Singleton-Instanz des DatabaseUserManagers zurück.
|
||||
*
|
||||
* @return DatabaseUserManager Instanz des DatabaseUserManagers
|
||||
*/
|
||||
public static function getInstance()
|
||||
{
|
||||
if (self::$instance == null) {
|
||||
self::$instance = new DatabaseUserManager();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sucht einen Benutzer anhand seiner E-Mail-Adresse.
|
||||
*
|
||||
* @param string $email E-Mail-Adresse des Benutzers
|
||||
*
|
||||
* @return array|null Benutzerdaten als Array oder null,
|
||||
* wenn kein Benutzer gefunden wurde
|
||||
*
|
||||
* @throws RuntimeException wenn der Benutzer nicht geladen werden kann
|
||||
*/
|
||||
public function findUser($email)
|
||||
{
|
||||
// TODO: Implement findUser() method.
|
||||
try {
|
||||
$db = $this->getConnection();
|
||||
|
||||
$sql = "SELECT * FROM users WHERE email = :email";
|
||||
$command = $db->prepare($sql);
|
||||
|
||||
$command->execute([
|
||||
":email" => $email
|
||||
]);
|
||||
|
||||
$user = $command->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
return $user ?: null;
|
||||
|
||||
} catch (PDOException $e) {
|
||||
throw new RuntimeException("Benutzer konnte nicht geladen werden.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fügt einen neuen Benutzer in die Datenbank ein.
|
||||
*
|
||||
* Die Speicherung erfolgt innerhalb einer Transaktion.
|
||||
* Doppelte E-Mail-Adressen werden durch den Primary Key verhindert.
|
||||
*
|
||||
* @param string $email E-Mail-Adresse des Benutzers
|
||||
* @param string $vorname Vorname des Benutzers
|
||||
* @param string $nachname Nachname des Benutzers
|
||||
* @param string $password Passwort-Hash des Benutzers
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws InvalidArgumentException wenn die E-Mail-Adresse bereits verwendet wird
|
||||
* @throws RuntimeException wenn der Benutzer nicht gespeichert werden kann
|
||||
*/
|
||||
public function addUser($email, $vorname, $nachname, $password)
|
||||
{
|
||||
// TODO: Implement addUser() method.
|
||||
try {
|
||||
$db = $this->getConnection();
|
||||
$db->beginTransaction();
|
||||
|
||||
$sql = "
|
||||
INSERT INTO users (email, vorname, nachname, password)
|
||||
VALUES (:email, :vorname, :nachname, :password)
|
||||
";
|
||||
|
||||
$command = $db->prepare($sql);
|
||||
|
||||
$command->execute([
|
||||
":email" => $email,
|
||||
":vorname" => $vorname,
|
||||
":nachname" => $nachname,
|
||||
":password" => $password
|
||||
]);
|
||||
|
||||
$db->commit();
|
||||
|
||||
} catch (PDOException $e) {
|
||||
if (isset($db) && $db->inTransaction()) {
|
||||
$db->rollBack();
|
||||
}
|
||||
|
||||
if ($e->getCode() === "23000") {
|
||||
throw new InvalidArgumentException("Diese E-Mail-Adresse wird bereits verwendet.");
|
||||
}
|
||||
|
||||
throw new RuntimeException("Benutzer konnte nicht gespeichert werden.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Aktualisiert die Daten eines bestehenden Benutzers.
|
||||
*
|
||||
* Optional kann zusätzlich das Passwort geändert werden.
|
||||
* Wenn kein neues Passwort übergeben wird, bleibt das alte Passwort erhalten.
|
||||
*
|
||||
* @param string $oldEmail Aktuelle E-Mail-Adresse des Benutzers
|
||||
* @param string $newEmail Neue E-Mail-Adresse des Benutzers
|
||||
* @param string $vorname Neuer Vorname des Benutzers
|
||||
* @param string $nachname Neuer Nachname des Benutzers
|
||||
* @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 der Benutzer nicht aktualisiert werden kann
|
||||
*/
|
||||
public function updateUser($oldEmail, $newEmail, $vorname, $nachname, $password = null)
|
||||
{
|
||||
// TODO: Implement updateUser() method.
|
||||
try {
|
||||
$db = $this->getConnection();
|
||||
|
||||
if (!empty($password)) {
|
||||
$sql = "
|
||||
UPDATE users
|
||||
SET email = :newEmail,
|
||||
vorname = :vorname,
|
||||
nachname = :nachname,
|
||||
password = :password
|
||||
WHERE email = :oldEmail
|
||||
";
|
||||
|
||||
$params = [
|
||||
":newEmail" => $newEmail,
|
||||
":vorname" => $vorname,
|
||||
":nachname" => $nachname,
|
||||
":password" => password_hash($password, PASSWORD_DEFAULT),
|
||||
":oldEmail" => $oldEmail
|
||||
];
|
||||
} else {
|
||||
$sql = "
|
||||
UPDATE users
|
||||
SET email = :newEmail,
|
||||
vorname = :vorname,
|
||||
nachname = :nachname
|
||||
WHERE email = :oldEmail
|
||||
";
|
||||
|
||||
$params = [
|
||||
":newEmail" => $newEmail,
|
||||
":vorname" => $vorname,
|
||||
":nachname" => $nachname,
|
||||
":oldEmail" => $oldEmail
|
||||
];
|
||||
}
|
||||
|
||||
$command = $db->prepare($sql);
|
||||
$command->execute($params);
|
||||
|
||||
return $command->rowCount() > 0;
|
||||
|
||||
} catch (PDOException $e) {
|
||||
if ($e->getCode() === "23000") {
|
||||
throw new InvalidArgumentException("Diese E-Mail-Adresse wird bereits verwendet.");
|
||||
}
|
||||
|
||||
throw new RuntimeException("Benutzer konnte nicht aktualisiert werden.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 der Benutzer nicht gelöscht werden kann
|
||||
*/
|
||||
public function deleteUser($email)
|
||||
{
|
||||
// TODO: Implement deleteUser() method.
|
||||
}
|
||||
try {
|
||||
$db = $this->getConnection();
|
||||
|
||||
$sql = "DELETE FROM users WHERE email = :email";
|
||||
$command = $db->prepare($sql);
|
||||
|
||||
$command->execute([
|
||||
":email" => $email
|
||||
]);
|
||||
|
||||
return $command->rowCount() > 0;
|
||||
|
||||
} catch (PDOException $e) {
|
||||
throw new RuntimeException("Benutzer konnte nicht gelöscht werden.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -36,14 +36,19 @@ class LocalArticleManager implements ArticleManagerDAO {
|
||||
* Speichert alle Artikel/Beiträge in der Datei.
|
||||
* @param $articles
|
||||
* @return void
|
||||
* TODO: Exceptions implementieren.
|
||||
* @throws InternalServerErrorException
|
||||
*/
|
||||
public function saveArticle($articles)
|
||||
private function saveArticle($articles)
|
||||
{
|
||||
try{
|
||||
file_put_contents(
|
||||
$this->file,
|
||||
json_encode($articles, JSON_PRETTY_PRINT)
|
||||
);
|
||||
}catch (Exception $e){
|
||||
throw new InternalServerErrorException($e->getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function addArticle($title, $content, $author, $category, $tags)
|
||||
|
||||
@@ -1,10 +1,49 @@
|
||||
<?php
|
||||
require_once "UserManagerDAO.php";
|
||||
|
||||
class UserManager extends LocalUserManager{
|
||||
require_once "LocalUserManager.php";
|
||||
require_once "DatabaseUserManager.php";
|
||||
|
||||
public static function getInstance(){
|
||||
// TODO: implement this.
|
||||
// TODO: dummy-user anlegen: - `max.mustermann, test123, mustermann@web.de` (analog zu ArticleManager)
|
||||
/**
|
||||
* Zentrale Klasse für den Zugriff auf Benutzerdaten.
|
||||
*
|
||||
* Hier kann zwischen lokaler Speicherung und Datenbankspeicherung
|
||||
* gewechselt werden.
|
||||
*/
|
||||
class UserManager {
|
||||
|
||||
public static function getInstance() {
|
||||
$userManager = DatabaseUserManager::getInstance();
|
||||
|
||||
/*
|
||||
* Dummy-User anlegen, falls sie noch nicht existieren.
|
||||
* Passwort für alle User: test12345
|
||||
*/
|
||||
$dummyUsers = [
|
||||
['email' => 'max.mustermann@web.de', 'vorname' => 'Max', 'nachname' => 'Mustermann'],
|
||||
['email' => 'erika.mustermann@web.de', 'vorname' => 'Erika', 'nachname' => 'Mustermann'],
|
||||
['email' => 'john.doe@gmail.com', 'vorname' => 'John', 'nachname' => 'Doe'],
|
||||
['email' => 'jane.doe@gmail.com', 'vorname' => 'Jane', 'nachname' => 'Doe'],
|
||||
['email' => 'anna.schmidt@gmx.de', 'vorname' => 'Anna', 'nachname' => 'Schmidt'],
|
||||
['email' => 'thomas.mueller@gmx.de', 'vorname' => 'Thomas', 'nachname' => 'Müller'],
|
||||
['email' => 'sabine.fischer@outlook.com', 'vorname' => 'Sabine', 'nachname' => 'Fischer'],
|
||||
['email' => 'michael.weber@outlook.com', 'vorname' => 'Michael', 'nachname' => 'Weber'],
|
||||
['email' => 'julia.wagner@t-online.de', 'vorname' => 'Julia', 'nachname' => 'Wagner'],
|
||||
['email' => 'stefan.becker@t-online.de', 'vorname' => 'Stefan', 'nachname' => 'Becker']
|
||||
];
|
||||
|
||||
$passwordHash = password_hash("test12345", PASSWORD_DEFAULT);
|
||||
|
||||
foreach ($dummyUsers as $user) {
|
||||
if ($userManager->findUser($user['email']) == null) {
|
||||
$userManager->addUser(
|
||||
$user['email'],
|
||||
$user['vorname'],
|
||||
$user['nachname'],
|
||||
$passwordHash
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $userManager;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Prüft, ob der Autor auch der Eigentümer des Beitrags ist.
|
||||
* @param $author
|
||||
|
||||
@@ -1,13 +1,33 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Prüft, ob ein Vor- oder Nachname gültig ist.
|
||||
*
|
||||
* Erlaubt werden Buchstaben, Umlaute, Leerzeichen und Bindestriche.
|
||||
* Die Länge muss zwischen 2 und 20 Zeichen liegen.
|
||||
*
|
||||
* @param string $name Zu prüfender Name
|
||||
*
|
||||
* @return bool true wenn der Name gültig ist, sonst false
|
||||
*/
|
||||
function userNameValidator($name)
|
||||
{
|
||||
$name = trim($name);
|
||||
$namePattern = '/^[a-zA-ZäöüÄÖÜß\s-]{2,50}$/u';
|
||||
$namePattern = '/^[a-zA-ZäöüÄÖÜß\s-]{2,20}$/u';
|
||||
|
||||
return preg_match($namePattern, $name) === 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prüft, ob eine E-Mail-Adresse gültig ist.
|
||||
*
|
||||
* Die E-Mail-Adresse muss dem Standardformat entsprechen
|
||||
* und darf höchstens 100 Zeichen lang sein.
|
||||
*
|
||||
* @param string $email Zu prüfende E-Mail-Adresse
|
||||
*
|
||||
* @return bool true wenn die E-Mail-Adresse gültig ist, sonst false
|
||||
*/
|
||||
function userEmailValidator($email)
|
||||
{
|
||||
$email = trim($email);
|
||||
@@ -16,13 +36,35 @@ function userEmailValidator($email)
|
||||
&& mb_strlen($email) <= 100;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prüft, ob ein Passwort die Längenanforderungen erfüllt.
|
||||
*
|
||||
* Das Passwort muss zwischen 5 und 12 Zeichen lang sein.
|
||||
*
|
||||
* @param string $password Zu prüfendes Passwort
|
||||
*
|
||||
* @return bool true wenn das Passwort gültig ist, sonst false
|
||||
*/
|
||||
function userPasswordValidator($password)
|
||||
{
|
||||
$zeichenAnzahl = mb_strlen($password);
|
||||
|
||||
return $zeichenAnzahl >= 8 && $zeichenAnzahl <= 72;
|
||||
return $zeichenAnzahl >= 5 && $zeichenAnzahl <= 12;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prüft ein optionales Passwort.
|
||||
*
|
||||
* Ein leeres Passwort ist erlaubt und bedeutet,
|
||||
* dass das bestehende Passwort unverändert bleibt.
|
||||
* Falls ein Passwort angegeben wurde, wird es
|
||||
* mit den normalen Passwortregeln geprüft.
|
||||
*
|
||||
* @param string|null $password Zu prüfendes Passwort
|
||||
*
|
||||
* @return bool true wenn das Passwort gültig oder leer ist,
|
||||
* sonst false
|
||||
*/
|
||||
function userOptionalPasswordValidator($password)
|
||||
{
|
||||
if (!isset($password) || $password === '') {
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user