Compare commits

..

17 Commits

Author SHA1 Message Date
caroschulte02-alt d440b98774 First Implementation 2026-05-13 01:32:52 +02:00
caroschulte02-alt f1feb4677e First Implementation 2026-05-13 01:31:50 +02:00
caroschulte02-alt e7bc5a5709 First Implementation 2026-05-13 01:30:41 +02:00
caroschulte02-alt dfb5076032 First Implementation 2026-05-13 01:29:17 +02:00
caroschulte02-alt 68b6ecdfc3 First Implementation 2026-05-13 01:27:55 +02:00
caroschulte02-alt a3fe501282 First Implementation 2026-05-13 01:26:09 +02:00
caroschulte02-alt 1a80d3576f First Implementation 2026-05-13 01:19:20 +02:00
caroschulte02-alt 60b6449ecd First Implementation 2026-05-13 01:16:05 +02:00
caroschulte02-alt 45924e6cfb First Implementation 2026-05-13 01:12:25 +02:00
caroschulte02-alt cd1512eadf First Implementation 2026-05-13 01:09:44 +02:00
caroschulte02-alt 71fc4c8184 First Implementation 2026-05-13 01:07:02 +02:00
caroschulte02-alt a32b59825e First Implementation 2026-05-13 01:03:48 +02:00
caroschulte02-alt 590ff7d916 First Implementation 2026-05-13 01:01:53 +02:00
caroschulte02-alt 51093d4995 First Implementation 2026-05-13 00:59:45 +02:00
caroschulte02-alt c6e7cdf95c First Implementation 2026-05-13 00:56:04 +02:00
caroschulte02-alt d2a4c14c88 First Implementation 2026-05-13 00:54:22 +02:00
caroschulte02-alt 9d5a76973b First Implementation 2026-05-12 21:56:26 +02:00
76 changed files with 1112 additions and 6143 deletions
View File
-18
View File
@@ -1,18 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="dataSourceStorageLocal" created-in="IU-261.24374.151">
<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>&quot;</identifier-quote-string>
</database-info>
<case-sensitivity plain-identifiers="mixed" quoted-identifiers="mixed" />
<secret-storage>master_key</secret-storage>
<auth-provider>no-auth</auth-provider>
<schema-mapping>
<introspection-scope>
<node kind="schema" qname="@" />
</introspection-scope>
</schema-mapping>
</data-source>
</component>
</project>
-12
View File
@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DataSourceManagerImpl" format="xml" multifile-model="true">
<data-source source="LOCAL" name="articles" uuid="315cb5c9-2b0f-435b-b602-59823b160908">
<driver-ref>sqlite.xerial</driver-ref>
<synchronize>true</synchronize>
<jdbc-driver>org.sqlite.JDBC</jdbc-driver>
<jdbc-url>jdbc:sqlite:$PROJECT_DIR$/db/articles</jdbc-url>
<working-dir>$ProjectFileDir$</working-dir>
</data-source>
</component>
</project>
File diff suppressed because it is too large Load Diff
@@ -1,2 +0,0 @@
#n:main
!<md> [0, 0, null, null, -2147483648, -2147483648]
-42
View File
@@ -1,42 +0,0 @@
<DataSourcesHistory>
<DataSourceFromHistory isRemovedFromProject="true">
<data-source source="LOCAL" name="articles" uuid="a0abcd0a-1d6f-40e4-88be-f442bcb431ba">
<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>&quot;</identifier-quote-string>
</database-info>
<case-sensitivity plain-identifiers="mixed" quoted-identifiers="mixed" />
<driver-ref>sqlite.xerial</driver-ref>
<synchronize>true</synchronize>
<jdbc-driver>org.sqlite.JDBC</jdbc-driver>
<jdbc-url>jdbc:sqlite:$PROJECT_DIR$/db/articles</jdbc-url>
<secret-storage>master_key</secret-storage>
<auth-provider>no-auth</auth-provider>
<schema-mapping>
<introspection-scope>
<node kind="schema" qname="@" />
</introspection-scope>
</schema-mapping>
<working-dir>$ProjectFileDir$</working-dir>
</data-source>
</DataSourceFromHistory>
<DataSourceFromHistory isRemovedFromProject="true">
<data-source source="LOCAL" 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>&quot;</identifier-quote-string>
</database-info>
<case-sensitivity plain-identifiers="mixed" quoted-identifiers="mixed" />
<driver-ref>sqlite.xerial</driver-ref>
<synchronize>true</synchronize>
<jdbc-driver>org.sqlite.JDBC</jdbc-driver>
<jdbc-url>jdbc:sqlite:$PROJECT_DIR$/db/articles</jdbc-url>
<secret-storage>master_key</secret-storage>
<auth-provider>no-auth</auth-provider>
<schema-mapping>
<introspection-scope>
<node kind="schema" qname="@" />
</introspection-scope>
</schema-mapping>
<working-dir>$ProjectFileDir$</working-dir>
</data-source>
</DataSourceFromHistory>
</DataSourcesHistory>
Generated
-1
View File
@@ -10,7 +10,6 @@
<option name="highlightLevel" value="WARNING" />
<option name="transferred" value="true" />
</component>
<component name="PhpProjectSharedConfiguration" php_language_level="8.5" />
<component name="PhpStanOptionsConfiguration">
<option name="transferred" value="true" />
</component>
+9 -34
View File
@@ -1,35 +1,10 @@
# Webprogrammierung: Gruppe DI-14-C
Team Tag-Buchstabe: DI-14-C-Schulte-Eilers-Ortmann
Namen der Studierenden:
- Name 1 Caroline Schulte
- Name 2 Jacques Eilers
- Name 3 Niklas Ortmann
Abgabe zu Aufgabenblatt 1
## Beteiligte
- Caroline Schulte
- Jacques Eilers
- Niklas Ortmann
## Login-Informationen für Dummy-User
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.
- Die Suchseite und Kategorieseite packen momentan alle passenden Beiträge untereinander. Später sollen zunächst 10
Ergebnisse auf einer Seite angezeigt werden.
## Besonderheiten des Projektes
- 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
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).
Hinweise:
index.html wurde zu einer index.php umbenannt.
webhook.php bitte ignorieren. Diese dient nur als zukünftige Automatisierung des Repo-Pulls (s. https://docs.gitea.com/usage/webhooks)
+76
View File
@@ -0,0 +1,76 @@
<!--
Artikel: Datenschutz vs Datensicherheit
Funktion: Inhalt zum Fach Informatik
-->
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="description" content="EduForge">
<meta name="author" content="Niklas Ortmann">
<link rel="stylesheet" href="../../css/main.css" />
<title>EduForge</title>
</head>
<body>
<nav style="background:#808080; height: 60px;">
<div style="float:left; text-align: center;">
<a href="../index.php">
<img src="../images/logo.png" alt="" style="height: 44px;">
</a>
|
<a href = "../content/informatik.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Informatik</b></a>
|
<a href = "../content/mathe.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Mathe</b></a>
|
<a href = "../content/physik.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Physik</b></a>
|
<a href = "../content/profile.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Dein Profil</b></a>
|
</div>
<div style="float:right; text-align: center;">
<?php
include_once '../includes/search.php';
?>
|
<a href = "../auth/login.php" style = "background-color: #f44336; color: white; padding: 4px 20px; text-align: center; text-decoration: none; display: inline-block;"> Anmelden </a>
<a href = "../auth/register.php" style = "background-color: #f44336; color: white; padding: 4px 20px; text-align: center; text-decoration: none; display: inline-block;"> Registrieren </a>
</div>
</nav>
<main>
<h1>Datenschutz vs Datensicherheit</h1>
<p>
Datenschutz ist in unserer digital vernetzten Welt allgegenwärtig ob in sozialen Netzwerken, beim
Online-Shopping oder dem Einsatz von Bonuskarten, bei der Auswertung von Konsumverhalten und selbstverständlich
auch im schulischen Kontext.
</p>
<h2>
Was ist Datenschutz?
</h2>
<p>
Datenschutz bedeutet, dass persönliche Daten nur gesammelt, gespeichert und verwendet werden dürfen, wenn
es wirklich nötig ist und nur für klar festgelegte Zwecke. Es geht darum, die Privatsphäre von Menschen
zu schützen.
</p>
<h2>
Was ist Datenschutz?
</h2>
<p>
Datensicherheit umfasst alle technischen und organisatorischen Maßnahmen, die verhindern sollen, dass Daten
verloren gehen, beschädigt oder unbemerkt verändert werden. Sie schützt Informationen vor Missbrauch.
</p>
</main>
<footer style="position:fixed;bottom:0;width:100%;background:#fff;text-align:center;">
<a href="../../legal/impressum.php">Impressum</a>
<a href="../../legal/datenschutz.php">Datenschutz</a>
<a href="../../legal/nutzungsbedingungen.php">Nutzungsbedingungen</a>
</footer>
</body>
</html>
+72
View File
@@ -0,0 +1,72 @@
<!--
Artikel: Satz des Pythagoras
Funktion: Inhalt zum Fach Mathe
-->
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="description" content="EduForge">
<meta name="author" content="Niklas Ortmann">
<link rel="stylesheet" href="../../css/main.css" />
<title>EduForge</title>
</head>
<body>
<nav style="background:#808080; height: 60px;">
<div style="float:left; text-align: center;">
<a href="../index.php">
<img src="../images/logo.png" alt="" style="height: 44px;">
</a>
|
<a href = "../content/informatik.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Informatik</b></a>
|
<a href = "../content/mathe.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Mathe</b></a>
|
<a href = "../content/physik.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Physik</b></a>
|
<a href = "../content/profile.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Dein Profil</b></a>
|
</div>
<div style="float:right; text-align: center;">
<?php
include_once '../includes/search.php';
?>
|
<a href = "../auth/login.php" style = "background-color: #f44336; color: white; padding: 4px 20px; text-align: center; text-decoration: none; display: inline-block;"> Anmelden </a>
<a href = "../auth/register.php" style = "background-color: #f44336; color: white; padding: 4px 20px; text-align: center; text-decoration: none; display: inline-block;"> Registrieren </a>
</div>
</nav>
<main>
<h1>Satz des Pythagoras</h1>
<p>
Der Satz des Pythagoras wurde von dem griechischen Philosophen Pythagoras von Samos formuliert und im
dritten Jahrhundert vor Christus veröffentlicht.
</p>
<figure>
<img src="https://cdn8.picryl.com/photo/2016/05/14/pythagoras-e9560b-1024.jpg" alt="Trulli" style="width:10%">
<figcaption><a href="https://cdn8.picryl.com/photo/2016/05/14/pythagoras-e9560b-1024.jpg">Quelle</a></figcaption>
</figure>
<p>
In der beigefügten Abbildung sehen wir ein rechtwinkliges Dreieck, dessen drei Seiten die Längen a, b und c
besitzen. Auf jeder Seite ist ein Quadrat konstruiert. Das Quadrat auf der Seite a hat die Fläche a2, das
Quadrat auf der Seite b hat die Fläche b2 und das Quadrat auf der Seite c hat die Fläche c2. Der Satz des
Pythagoras besagt, dass die Summe der Flächen der beiden kleineren Quadrate gleich der Fläche des größten
Quadrats ist. Das bedeutet, dass a^2+b^2=c^2 (Satz des Pythagoras).
</p>
<a href="../docs/Uebungsaufgaben_Pythagoras.pdf">Lernzettel-Download</a>
</main>
<footer style="position:fixed;bottom:0;width:100%;background:#fff;text-align:center;">
<a href="../../legal/impressum.php">Impressum</a>
<a href="../../legal/datenschutz.php">Datenschutz</a>
<a href="../../legal/nutzungsbedingungen.php">Nutzungsbedingungen</a>
</footer>
</body>
</html>
+66
View File
@@ -0,0 +1,66 @@
<!--
Artikel: Tunneleffekt
Funktion: Inhalt zum Fach Physik
-->
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="description" content="EduForge">
<meta name="author" content="Niklas Ortmann">
<link rel="stylesheet" href="../../css/main.css" />
<title>EduForge</title>
</head>
<body>
<nav style="background:#808080; height: 60px;">
<div style="float:left; text-align: center;">
<a href="../index.php">
<img src="../images/logo.png" alt="" style="height: 44px;">
</a>
|
<a href = "../content/informatik.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Informatik</b></a>
|
<a href = "../content/mathe.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Mathe</b></a>
|
<a href = "../content/physik.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Physik</b></a>
|
<a href = "../content/profile.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Dein Profil</b></a>
|
</div>
<div style="float:right; text-align: center;">
<?php
include_once '../includes/search.php';
?>
|
<a href = "../auth/login.php" style = "background-color: #f44336; color: white; padding: 4px 20px; text-align: center; text-decoration: none; display: inline-block;"> Anmelden </a>
<a href = "../auth/register.php" style = "background-color: #f44336; color: white; padding: 4px 20px; text-align: center; text-decoration: none; display: inline-block;"> Registrieren </a>
</div>
</nav>
<main>
<h1>Tunneleffekt</h1>
<p>
Der Tunneleffekt ist ein quantenmechanisches Phänomen, bei dem Teilchen vor allem Elektronen eine
Energiebarriere überwinden können, obwohl sie nach den Regeln der klassischen Physik nicht genügend Energie
dafür besitzen. In der klassischen Vorstellung müsste ein Elektron entweder genügend Energie haben, um über
eine Barriere zu „springen“, oder es würde vollständig zurückgeworfen. In der Quantenphysik wird ein Elektron
jedoch nicht als punktförmiges Teilchen beschrieben, sondern als Wellenfunktion, die sich räumlich ausdehnt.
Dadurch besteht eine endliche Wahrscheinlichkeit, dass sich das Elektron auf der anderen Seite einer Barriere
befindet (Griffiths & Schroeter, 2018).
</p>
</main>
<footer style="position:fixed;bottom:0;width:100%;background:#fff;text-align:center;">
<a href="../../legal/impressum.php">Impressum</a>
<a href="../../legal/datenschutz.php">Datenschutz</a>
<a href="../../legal/nutzungsbedingungen.php">Nutzungsbedingungen</a>
</footer>
</body>
</html>
+75
View File
@@ -0,0 +1,75 @@
<!--
Form: Login-Bereich
Funktion: Benutzerauthentifizierung und Zugang zum eigenen Profil, Erstellen von Beiträgen, etc.
-->
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="description" content="EduForge">
<meta name="author" content="Niklas Ortmann">
<link rel="stylesheet" href="../css/main.css" />
<title>EduForge</title>
</head>
<body>
<nav style="background:#808080; height: 60px;">
<div style="float:left; text-align: center;">
<a href="../index.php">
<img src="../images/logo.png" alt="" style="height: 44px;">
</a>
|
<a href = "../content/informatik.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Informatik</b></a>
|
<a href = "../content/mathe.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Mathe</b></a>
|
<a href = "../content/physik.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Physik</b></a>
|
<a href = "../content/profile.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Dein Profil</b></a>
|
</div>
<div style="float:right; text-align: center;">
<?php
include_once '../includes/search.php';
?>
|
<a href = "login.php" style = "background-color: #f44336; color: white; padding: 4px 20px; text-align: center; text-decoration: none; display: inline-block;"> Anmelden </a>
<a href = "register.php" style = "background-color: #f44336; color: white; padding: 4px 20px; text-align: center; text-decoration: none; display: inline-block;"> Registrieren </a>
</div>
</nav>
<main>
<div style="width: 50%">
<div style="width: 130px;">
<img src="../images/logo.png" alt="" width="120" height="72">
</div>
<h1 style="width: 60%; text-align: center">Bitte anmelden</h1><br>
<label id="inputEmail" >E-Mail-Adresse / </label>
<p style="width: 80%;">Benutzername/E-Mail-Adresse:</p>
<input type="email" name="email" style="width: 80%;" placeholder="E-Mail-Adresse" required autofocus>
<p style="width: 80%;">Passwort:</p>
<input type="password" name="password" style="width: 80%;" placeholder="Passwort" required>
<div style="width: 80%;">
<label>
<input type="checkbox" name="remember-me" value="1"> angemeldet bleiben
</label>
</div>
<button type="submit" value="anmelden" name="loginSubmit" style="width: 80%;">anmelden</button><br>
<div style="width: 70%; text-align: center">
<a href="register.php" style="text-align: center;"> Noch keinen Account? Jetzt hier registrieren! </a>
</div>
</div>
</main>
<footer style="position:fixed;bottom:0;width:100%;background:#fff;text-align:center;">
<a href="../legal/impressum.php">Impressum</a>
<a href="../legal/datenschutz.php">Datenschutz</a>
<a href="../legal/nutzungsbedingungen.php">Nutzungsbedingungen</a>
</footer>
</body>
</html>
+76
View File
@@ -0,0 +1,76 @@
<!--
Form: Registrierung
Funktion: Erstellung neuer Benutzerkonten
-->
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="description" content="EduForge">
<meta name="author" content="Niklas Ortmann">
<link rel="stylesheet" href="../css/main.css" />
<title>EduForge</title>
</head>
<body>
<nav style="background:#808080; height: 60px;">
<div style="float:left; text-align: center;">
<a href="../index.php">
<img src="../images/logo.png" alt="" style="height: 44px;">
</a>
|
<a href = "../content/informatik.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Informatik</b></a>
|
<a href = "../content/mathe.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Mathe</b></a>
|
<a href = "../content/physik.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Physik</b></a>
|
<a href = "../content/profile.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Dein Profil</b></a>
|
</div>
<div style="float:right; text-align: center;">
<?php
include_once '../includes/search.php';
?>
|
<a href = "login.php" style = "background-color: #f44336; color: white; padding: 4px 20px; text-align: center; text-decoration: none; display: inline-block;"> Anmelden </a>
<a href = "register.php" style = "background-color: #f44336; color: white; padding: 4px 20px; text-align: center; text-decoration: none; display: inline-block;"> Registrieren </a>
</div>
</nav>
<main>
<div style="width: 50%">
<div style="width: 130px;">
<img src="../images/logo.png" alt="" width="120" height="72">
</div>
<h1 style="width: 50%; text-align: center">Jetzt Registrieren!</h1><br>
<p style="width: 80%;"> Email:</p>
<input type="email" name="email" style="width: 80%;" placeholder="mustermann@web.de" required>
<p style="width: 80%;"> Vorname:</p>
<input type="text" name="vorname" style="width: 80%;" placeholder="Max" required>
<p style="width: 80%;"> Nachname:</p>
<input type="text" name="nachname" style="width: 80%;" placeholder="Mustermann" required>
<p style="width: 80%;"> Passwort:</p>
<input type="password" name="password" style="width: 80%;" placeholder="Passwort" required>
<div style="width: 80%;">
<label>
<input type="checkbox" value="remember-me"> angemeldet bleiben
</label>
</div>
<button type="submit" value="anmelden" name="loginSubmit" style="width: 80%;">kostenlos registrieren</button>
</div>
</main>
<footer style="position:fixed;bottom:0;width:100%;background:#fff;text-align:center;">
<a href="../legal/impressum.php">Impressum</a>
<a href="../legal/datenschutz.php">Datenschutz</a>
<a href="../legal/nutzungsbedingungen.php">Nutzungsbedingungen</a>
</footer>
</body>
</html>
-20
View File
@@ -1,20 +0,0 @@
<!--
Seite: 404 Seite nicht gefunden
Funktion: Wenn eine Seite nicht gefunden wurde oder noch fehlt, dann wird hierauf verwiesen.
-->
<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.
Alle Content-Links der Navbar führen zunächst hier her. Exemplarisch wurden für die Fächer Informatik, Physik, Mathematik der Content als Seite erstellt und kann über die Navbar ausgekundschaftet werden.
</p>
</main>
-122
View File
@@ -1,122 +0,0 @@
<?php
$user = $user ?? null;
if (!isset($_SESSION["user"])) {
header("Location: index.php?pfad=login");
exit();
}
?>
<!--
Seite: Beitrag erstellen
Inhalt: Formular für die Erstellung eines neuen Beitrags
-->
<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"]);
?>
<input type="text" id="title" name="title"
value="<?php echo htmlspecialchars($_SESSION['old_title'] ?? ''); unset($_SESSION['old_title']); ?>"
placeholder="Titel hier eingeben" required>
<textarea id="content" name="content" placeholder="Schreibe deinen Beitrag...">
<?php echo htmlspecialchars($_SESSION['old_content'] ?? ''); unset($_SESSION['old_content']); ?>
</textarea>
</main>
<!-- Seitenleiste -->
<aside class="editor-sidebar">
<div class="sidebar-block">
<button type="submit" id="editor-button" class="button">Veröffentlichen</button>
</div>
<div class="sidebar-block">
<label for="category">Kategorie <span class="required">*</span></label>
<select id="category" name="category" required>
<option value="" disabled selected>Kategorie wählen...</option>
<optgroup label="Sprachen">
<option value="deutsch">Deutsch</option>
<option value="englisch">Englisch</option>
<option value="franzoesisch">Französisch</option>
<option value="latein">Latein</option>
<option value="literatur">Literatur</option>
</optgroup>
<optgroup label="MINT">
<option value="mathe">Mathematik</option>
<option value="biologie">Biologie</option>
<option value="chemie">Chemie</option>
<option value="physik">Physik</option>
<option value="informatik">Informatik</option>
<option value="astronomie">Astronomie</option>
</optgroup>
<optgroup label="Gesellschaft & Werte">
<option value="geschichte">Geschichte</option>
<option value="erdkunde">Erdkunde</option>
<option value="sozialkunde">Sozialkunde</option>
<option value="wirtschaft">Wirtschaftskunde</option>
<option value="religion">Religion</option>
<option value="ethik">Ethikunterricht</option>
<option value="philosophie">Philosophie</option>
<option value="psychologie">Psychologie</option>
<option value="kunst">Kunst</option>
<option value="musik">Musik</option>
<option value="theater">Theater</option>
</optgroup>
<optgroup label="Technik & Praxis">
<option value="technik">Technik</option>
<option value="werken">Werken</option>
<option value="hauswirtschaft">Hauswirtschaft</option>
<option value="sport">Sport</option>
</optgroup>
</select>
</div>
<div class="sidebar-block">
<label for="tags">Schlagwörter</label>
<input type="text" id="tags" name="tags"
value="<?php echo htmlspecialchars($_SESSION['old_tags'] ?? ''); unset($_SESSION['old_tags']); ?>"
placeholder="z.B. Technik, IT (mit Komma trennen)">
</div>
</aside>
</form>
-18
View File
@@ -1,18 +0,0 @@
<!--
Seite: Datenschutzerklärung
Inhalt: Informationen zur Datenverarbeitung gemäß DSGVO
-->
<main>
<h1>Datenschutz</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>
</main>
-19
View File
@@ -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();
+17 -46
View File
@@ -1,30 +1,8 @@
<?php
include_once 'php/controller/home-controller.php';
?>
<!--
Seite: Home
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"]);
?>
<h1>Home</h1>
<p>
@@ -35,29 +13,22 @@ include_once 'php/controller/home-controller.php';
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>
<!-- Flexbox -->
<div class="flexbox">
<div class="container">
<a href="index.php?pfad=showCategory&category=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>
<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>
<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>
</div>
<div>
<a href = "content/informatik.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Informatik</b></a> <br>
<div>
<a href="articles/datenschutz.php">Datenschutz vs. Datensicherheit</a>
</div>
</div>
<div>
<a href = "content/mathe.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Mathe</b></a> <br>
<div>
<a href="articles/pythagoras.php">Satz des Pythagoras</a>
</div>
</div>
<div>
<a href = "content/physik.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Physik</b></a>
<div>
<a href="articles/tunneleffekt.php">Der Tunneleffekt</a>
</div>
</div>
</main>
-19
View File
@@ -1,19 +0,0 @@
<!--
Seite: Impressum
Inhalt: wer wie was auf der Webseite
-->
<main>
<h1>Impressum</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>
</main>
+63 -15
View File
@@ -2,20 +2,68 @@
Seite: Informatik
Inhalt: Eine Übersicht über alle Beiträge zum Fach
-->
<main>
<!DOCTYPE html>
<html lang="de">
<h1>Informatik</h1>
<head>
<meta charset="utf-8">
<meta name="description" content="EduForge">
<meta name="author" content="Niklas Ortmann">
<link rel="stylesheet" href="../css/main.css" />
<title>EduForge</title>
</head>
<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>
<body>
<nav style="background:#808080; height: 60px;">
<div style="float:left; text-align: center;">
<a href="../index.php">
<img src="../images/logo.png" alt="" style="height: 44px;">
</a>
|
<a href = "informatik.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Informatik</b></a>
|
<a href = "mathe.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Mathe</b></a>
|
<a href = "physik.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Physik</b></a>
|
<a href = "profile.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Dein Profil</b></a>
|
</div>
<div style="float:right; text-align: center;">
<?php
include_once '../includes/search.php';
?>
|
<a href = "../auth/login.php" style = "background-color: #f44336; color: white; padding: 4px 20px; text-align: center; text-decoration: none; display: inline-block;"> Anmelden </a>
<a href = "../auth/register.php" style = "background-color: #f44336; color: white; padding: 4px 20px; text-align: center; text-decoration: none; display: inline-block;"> Registrieren </a>
</div>
</nav>
<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="../articles/datenschutz.php">Datenschutz vs. Datensicherheit</a>
</div>
</main>
<footer style="position:fixed;bottom:0;width:100%;background:#fff;text-align:center;">
<a href="../legal/impressum.php">Impressum</a>
<a href="../legal/datenschutz.php">Datenschutz</a>
<a href="../legal/nutzungsbedingungen.php">Nutzungsbedingungen</a>
</footer>
</body>
</html>
-53
View File
@@ -1,53 +0,0 @@
<?php
$error = $error ?? null;
?>
<!--
Form: Login-Bereich
Funktion: Benutzerauthentifizierung und Zugang zum eigenen Profil, Erstellen von Beiträgen, etc.
-->
<main class="login-page">
<div class="login-container">
<h1>Bitte anmelden</h1>
<?php if ($error): ?>
<p style="color:red;">
<?php echo htmlspecialchars($error); ?>
</p>
<?php endif; ?>
<form method="post" action="index.php?pfad=login">
<p class="input-label">Benutzername/E-Mail-Adresse:</p>
<input type="email"
name="email"
class="login-input"
placeholder="E-Mail-Adresse"
required
autofocus>
<p class="input-label">Passwort:</p>
<input type="password"
name="password"
class="login-input"
placeholder="Passwort"
required>
<button type="submit"
value="anmelden"
name="loginSubmit"
class="button">
anmelden
</button>
<div class="register-link">
<a href="index.php?pfad=register">
Noch keinen Account? Jetzt hier registrieren!
</a>
</div>
</form>
</div>
</main>
-6
View File
@@ -1,6 +0,0 @@
<?php
$_SESSION = [];
session_destroy();
header("Location: index.php");
exit();
+63 -15
View File
@@ -2,21 +2,69 @@
Seite: Mathe
Inhalt: Eine Übersicht über alle Beiträge zum Fach
-->
<main>
<!DOCTYPE html>
<html lang="de">
<h1>Mathe</h1>
<head>
<meta charset="utf-8">
<meta name="description" content="EduForge">
<meta name="author" content="Niklas Ortmann">
<link rel="stylesheet" href="../css/main.css" />
<title>EduForge</title>
</head>
<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>
<body>
<h2>Artikel:</h2>
<div>
<a href="pythagoras.php">Satz des Pythagoras</a>
</div>
</main>
<nav style="background:#808080; height: 60px;">
<div style="float:left; text-align: center;">
<a href="../index.php">
<img src="../images/logo.png" alt="" style="height: 44px;">
</a>
|
<a href = "informatik.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Informatik</b></a>
|
<a href = "mathe.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Mathe</b></a>
|
<a href = "physik.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Physik</b></a>
|
<a href = "profile.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Dein Profil</b></a>
|
</div>
<div style="float:right; text-align: center;">
<?php
include_once '../includes/search.php';
?>
|
<a href = "../auth/login.php" style = "background-color: #f44336; color: white; padding: 4px 20px; text-align: center; text-decoration: none; display: inline-block;"> Anmelden </a>
<a href = "../auth/register.php" style = "background-color: #f44336; color: white; padding: 4px 20px; text-align: center; text-decoration: none; display: inline-block;"> Registrieren </a>
</div>
</nav>
<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="../articles/pythagoras.php">Satz des Pythagoras</a>
</div>
</main>
<footer style="position:fixed;bottom:0;width:100%;background:#fff;text-align:center;">
<a href="../legal/impressum.php">Impressum</a>
<a href="../legal/datenschutz.php">Datenschutz</a>
<a href="../legal/nutzungsbedingungen.php">Nutzungsbedingungen</a>
</footer>
</body>
</html>
-46
View File
@@ -1,46 +0,0 @@
<!--
Seite: Nutzungsbedingungen
Inhalt: Regelungen für die Nutzung der Plattform (AGBs und so...)
-->
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="description" content="EduForge">
<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">
<title>EduForge</title>
</head>
<body>
<?php
include_once 'includes/navbar.php';
?>
<main>
<h1>Nutzungsbedingungen</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>
</main>
<?php
include_once 'includes/footer.php';
?>
</body>
</html>
+63 -15
View File
@@ -2,22 +2,70 @@
Seite: Physik
Inhalt: Eine Übersicht über alle Beiträge zum Fach
-->
<main>
<!DOCTYPE html>
<html lang="de">
<h1>Physik</h1>
<head>
<meta charset="utf-8">
<meta name="description" content="EduForge">
<meta name="author" content="Niklas Ortmann">
<link rel="stylesheet" href="../css/main.css" />
<title>EduForge</title>
</head>
<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>
<body>
<h2>Artikel:</h2>
<div>
<a href="tunneleffekt.php">Der Tunneleffekt</a>
</div>
<nav style="background:#808080; height: 60px;">
<div style="float:left; text-align: center;">
<a href="../index.php">
<img src="../images/logo.png" alt="" style="height: 44px;">
</a>
|
<a href = "informatik.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Informatik</b></a>
|
<a href = "mathe.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Mathe</b></a>
|
<a href = "physik.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Physik</b></a>
|
<a href = "profile.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Dein Profil</b></a>
|
</div>
<div style="float:right; text-align: center;">
<?php
include_once '../includes/search.php';
?>
|
<a href = "../auth/login.php" style = "background-color: #f44336; color: white; padding: 4px 20px; text-align: center; text-decoration: none; display: inline-block;"> Anmelden </a>
</main>
<a href = "../auth/register.php" style = "background-color: #f44336; color: white; padding: 4px 20px; text-align: center; text-decoration: none; display: inline-block;"> Registrieren </a>
</div>
</nav>
<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="../articles/tunneleffekt.php">Der Tunneleffekt</a>
</div>
</main>
<footer style="position:fixed;bottom:0;width:100%;background:#fff;text-align:center;">
<a href="../legal/impressum.php">Impressum</a>
<a href="../legal/datenschutz.php">Datenschutz</a>
<a href="../legal/nutzungsbedingungen.php">Nutzungsbedingungen</a>
</footer>
</body>
</html>
+74 -164
View File
@@ -1,174 +1,84 @@
<?php
include_once 'php/controller/profile-controller.php';
<!--
Seite: Profil
Inhalt: Das eigene Profil, wenn man angemeldet ist. Dort hat man die Möglichkeit seine Angaben zu ändern.
-->
<!DOCTYPE html>
<html lang="de">
$user = $user ?? null;
$isEditMode = (isset($_GET["edit"]) && $_GET["edit"] === "1") || !empty($error);
?>
<head>
<meta charset="utf-8">
<meta name="description" content="EduForge">
<meta name="author" content="Niklas Ortmann">
<link rel="stylesheet" href="../css/main.css" />
<title>EduForge</title>
</head>
<main class="form-page">
<div class="flexbox">
<body>
<div class="container">
<nav style="background:#808080; height: 60px;">
<div style="float:left; text-align: center;">
<a href="../index.php">
<img src="../images/logo.png" alt="" style="height: 44px;">
</a>
|
<a href = "../content/informatik.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Informatik</b></a>
|
<a href = "../content/mathe.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Mathe</b></a>
|
<a href = "../content/physik.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Physik</b></a>
|
<a href = "../content/profile.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Dein Profil</b></a>
|
</div>
<div style="float:right; text-align: center;">
<?php
include_once '../includes/search.php';
?>
|
<a href = "../auth/login.php" style = "background-color: #f44336; color: white; padding: 4px 20px; text-align: center; text-decoration: none; display: inline-block;"> Anmelden </a>
<?php if (!empty($error)): ?>
<p class="alert-message is-error">
<?php echo htmlspecialchars($error); ?>
</p>
<?php endif; ?>
<form method="post" action="index.php?pfad=profile">
<label class="input-label">Vorname</label>
<input type="text"
name="vorname"
class="login-input"
value="<?php echo htmlspecialchars($_POST["vorname"] ?? $user["vorname"] ?? ""); ?>"
<?php echo $isEditMode ? "" : "readonly"; ?>
required>
<label class="input-label">Nachname</label>
<input type="text"
name="nachname"
class="login-input"
value="<?php echo htmlspecialchars($_POST["nachname"] ?? $user["nachname"] ?? ""); ?>"
<?php echo $isEditMode ? "" : "readonly"; ?>
required>
<label class="input-label">Email-Adresse</label>
<input type="email"
name="email"
class="login-input"
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="Leer lassen, wenn es gleich bleiben soll">
<?php else: ?>
<input type="password"
name="password"
class="login-input"
value="********"
readonly>
<?php endif; ?>
<br><br>
<?php if ($isEditMode): ?>
<button type="submit"
name="saveProfile"
class="button">
Speichern
</button>
<a href="index.php?pfad=profile" class="button">
Abbrechen
</a>
<?php else: ?>
<a href="index.php?pfad=profile&edit=1" class="button">
Bearbeiten
</a>
<?php endif; ?>
</form>
<br>
<a href="index.php?pfad=deleteAccount" class="button">
Account löschen
</a>
<br><br>
<a href="index.php?pfad=logout" class="button">
Abmelden
</a>
<a href = "../auth/register.php" style = "background-color: #f44336; color: white; padding: 4px 20px; text-align: center; text-decoration: none; display: inline-block;"> Registrieren </a>
</div>
</nav>
<div class="container">
<h2 class="section-title">Meine Beiträge</h2>
<main>
<div class="articles-list">
<?php if (isset($_SESSION["message"]) && $_SESSION["message"] == "internal_error"): ?>
<p class="alert-message is-error">
Es ist ein interner Fehler aufgetreten. Bitte versuche es erneut.
</p>
<?php elseif (isset($userArticles) && count($userArticles) > 0): ?>
<?php foreach ($userArticles as $userArticle): ?>
<div class="article-item">
<div class="article-meta">
<span class="article-date">
<?php echo htmlspecialchars($userArticle->getCreationDate()); ?>
</span>
<span class="article-category">
<?php echo htmlspecialchars($userArticle->getCategory()); ?>
</span>
</div>
<h3 class="article-title">
<?php echo htmlspecialchars($userArticle->getTitle()); ?>
</h3>
<?php
$tags = $userArticle->getTags();
if (isset($tags) && !empty($tags)):
?>
<div class="article-view-bottom-section">
<div class="article-view-tags-label">Tags:</div>
<div class="article-view-tags-list">
<?php
$tagArray = is_array($tags) ? $tags : explode(',', $tags);
foreach ($tagArray as $tag):
$trimmedTag = trim($tag);
if (!empty($trimmedTag)):
?>
<span class="article-view-tag-item">
<?php echo htmlspecialchars($trimmedTag); ?>
</span>
<?php
endif;
endforeach;
?>
</div>
</div>
<?php endif; ?>
<a href="index.php?pfad=updateArticle&id=<?php echo $userArticle->getID(); ?>"
class="edit-link-button">
Bearbeiten
</a>
</div>
<?php endforeach; ?>
<?php else: ?>
<p>Du hast noch keine Beiträge erstellt.</p>
<button type="button"
class="button"
onclick="window.location.href='index.php?pfad=createArticle';">
Beitrag erstellen!
</button>
<?php endif; ?>
<?php unset($_SESSION["message"]); ?>
<hr>
<div>
<div>
<h1>Benutzerdaten ändern</h1>
<a href="/users"><img src="../images/logo.png" alt="" width="120" height="72"></a>
</div>
<div>
<div>
<label id="Vorname">Vorname</label>
<input type="text" name="Vorname" required placeholder="Vorname" value="<?php //DB-Daten ?>">
</div>
<div>
<label id="Nachname">Nachname</label>
<input type="text" name="Nachname" required placeholder="Nachname" value="<?php //DB-Daten ?>">
</div>
<div>
<label id="Email">Email-Adresse</label>
<input type="email" name="Email" required placeholder="mustermann@web.de" value="<?php //DB-Daten ?>">
</div>
<div>
<label id="Passwort">Passwort</label>
<input type="password" name="Passwort" required placeholder="Passwort">
</div>
<div>
<br>
<button type="submit" name="submit"><i></i> Speichern</button>
</div>
</div>
</div>
</main>
</div>
</main>
<footer style="position:fixed;bottom:0;width:100%;background:#fff;text-align:center;">
<a href="../legal/impressum.php">Impressum</a>
<a href="../legal/datenschutz.php">Datenschutz</a>
<a href="../legal/nutzungsbedingungen.php">Nutzungsbedingungen</a>
</footer>
</body>
</html>
-63
View File
@@ -1,63 +0,0 @@
<?php
$error = $error ?? null;
?>
<!--
Form: Registrierung
Funktion: Erstellung neuer Benutzerkonten
-->
<main class="login-page">
<div class="login-container">
<h1>Jetzt Registrieren!</h1>
<?php if (!empty($error)): ?>
<p class="alert-message is-error" style="color:red;">
<?php echo htmlspecialchars($error); ?>
</p>
<?php endif; ?>
<form method="post" action="index.php?pfad=register">
<p class="input-label">Email:</p>
<input type="email"
name="email"
class="login-input"
placeholder="mustermann@web.de"
value="<?php echo htmlspecialchars($_POST["email"] ?? ""); ?>"
required>
<p class="input-label">Vorname:</p>
<input type="text"
name="vorname"
class="login-input"
placeholder="Max"
value="<?php echo htmlspecialchars($_POST["vorname"] ?? ""); ?>"
required>
<p class="input-label">Nachname:</p>
<input type="text"
name="nachname"
class="login-input"
placeholder="Mustermann"
value="<?php echo htmlspecialchars($_POST["nachname"] ?? ""); ?>"
required>
<p class="input-label">Passwort:</p>
<input type="password"
name="password"
class="login-input"
placeholder="Passwort"
required>
<button type="submit"
value="register"
name="registerSubmit"
class="button">
kostenlos registrieren
</button>
</form>
</div>
</main>
-116
View File
@@ -1,116 +0,0 @@
<?php
session_start();
$results = $_SESSION["search_results"] ?? [];
$query = $_SESSION["search_query"] ?? "";
$resultCount = count($results);
?>
<!--
Seite: Suchergebnisse
Inhalt: Zeigt die Ergebnisse einer Suche an
-->
<div class="s-res-layout-grid">
<!-- 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">
<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>
<button type="submit" class="nav__search-button">Suchen</button>
</div>
<div class="s-res-sidebar-box">
<h3 class="s-res-sidebar-title">Sortierung</h3>
<?php $currentSort = $_SESSION['search_sort'] ?? 'alphabet'; ?>
<div class="s-res-filter-group">
<label class="s-res-filter-option">
<input type="radio" name="sort" value="alphabet" <?php echo $currentSort === 'alphabet' ? 'checked' : ''; ?> onchange="this.form.submit()">
<span>Alphabetisch</span>
</label>
<!-- Noch disabled, da likes noch nicht implementiert-->
<label class="s-res-filter-option">
<input type="radio" name="sort" value="likes" <?php echo $currentSort === 'likes' ? 'checked' : ''; ?> disabled>
<span style="color: #94a3b8;">Beliebtheit (Likes)</span>
</label>
<label class="s-res-filter-option">
<input type="radio" name="sort" value="newest" <?php echo $currentSort === 'newest' ? 'checked' : ''; ?> onchange="this.form.submit()">
<span>Neueste Beiträge</span>
</label>
<label class="s-res-filter-option">
<input type="radio" name="sort" value="oldest" <?php echo $currentSort === 'oldest' ? 'checked' : ''; ?> onchange="this.form.submit()">
<span>Älteste Beiträge</span>
</label>
</div>
</div>
</form>
</aside>
<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>
</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>
<?php endif; ?>
<?php
unset($_SESSION["message"]);
?>
</div>
<div class="s-res-pagination-footer">
<!-- 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>
</div>
<div class="s-res-page-navigation">
<button type="button" class="s-res-page-btn" disabled>&laquo;</button>
<button type="button" class="s-res-page-btn s-res-page-btn-active">1</button>
<button type="button" class="s-res-page-btn">&raquo;</button>
</div>
</div>
</main>
</div>
-84
View File
@@ -1,84 +0,0 @@
<?php
include_once 'php/controller/showArticle-controller.php';
?>
<!--
Seite: Anzeige für Beiträge
Funktion: Stellt einen übergebenen Beitrag dar.
-->
<!-- Hauptcontainer für die Beitragsansicht (Ausschließlich der Content-Bereich) -->
<main class="article-view-container">
<?php if (isset($_SESSION["message"]) && $_SESSION["message"] == "internal_error"): ?>
<p class="alert-message is-error">
Es ist ein interner Fehler 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"] == "article_updated"): ?>
<p class="alert-message is-success">
Dein Beitrag wurde erfolgreich bearbeitet!
</p>
<?php endif; ?>
<?php
unset($_SESSION["message"]);
?>
<!-- Metadaten & Titel -->
<div class="article-view-top-section">
<?php if (isset($category) && !empty($category)): ?>
<span class="article-view-category"><?php echo htmlspecialchars($category); ?></span>
<?php endif; ?>
<h1 class="article-view-title">
<?php if (isset($title)) { echo htmlspecialchars($title); } ?>
</h1>
<div class="article-view-meta">
<?php if (isset($author) && !empty($author)): ?>
<span class="article-view-author">Von: <strong><?php echo htmlspecialchars($author); ?></strong></span>
<?php endif; ?>
</div>
</div>
<!-- Beitrags-Inhalt -->
<div class="article-view-content">
<?php if (isset($content)): ?>
<!-- nl2br für Zeilenumbrüche -->
<div class="article-view-body"><?php echo nl2br(htmlspecialchars($content)); ?></div>
<?php endif; ?>
</div>
<!-- Beitrags-Endbereich (Tags) -->
<?php if (isset($tags) && !empty($tags)): ?>
<div class="article-view-bottom-section">
<div class="article-view-tags-label">Tags:</div>
<div class="article-view-tags-list">
<?php
// Falls $tags ein String ist (z.B. "Web, CSS"), in ein Array umwandeln
$tagArray = is_array($tags) ? $tags : explode(',', $tags);
foreach ($tagArray as $tag):
$trimmedTag = trim($tag);
if (!empty($trimmedTag)):
?>
<span class="article-view-tag-item"><?php echo htmlspecialchars($trimmedTag); ?></span>
<?php
endif;
endforeach;
?>
</div>
</div>
<?php endif; ?>
</main>
-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>
-157
View File
@@ -1,157 +0,0 @@
<?php
$user = $user ?? null;
if (!isset($_SESSION["user"])) {
header("Location: index.php?pfad=login");
exit();
}
include_once 'php/controller/showArticle-controller.php';
?>
<!--
Seite: Beitrag erstellen
Inhalt: Formular für die Erstellung eines neuen Beitrags
-->
<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"]);
?>
<input type="text" id="title" name="title"
value="<?php
if (isset($title) && !empty($title)){echo htmlspecialchars($title);
}elseif (isset($_SESSION['old_title']) && !empty($_SESSION['old_title'])){
echo htmlspecialchars($_SESSION['old_title']);
unset($_SESSION['old_title']);
}
?>"
placeholder="Titel hier eingeben" required>
<textarea id="content" name="content" placeholder="Schreibe deinen Beitrag...">
<?php
if (isset($content) && !empty($content)){echo htmlspecialchars($content);
}elseif (isset($_SESSION['old_content']) && !empty($_SESSION['old_content'])){
echo htmlspecialchars($_SESSION['old_content']);
unset($_SESSION['old_content']);
}
?>
</textarea>
</main>
<!-- Seitenleiste -->
<aside class="editor-sidebar">
<div class="sidebar-block">
<button type="submit" id="editor-button" class="button">Änderungen speichern</button>
</div>
<div class="sidebar-block">
<label for="category">Kategorie <span class="required">*</span></label>
<select id="category" name="category" required>
<option disabled selected>Kategorie wählen...</option>
<optgroup label="Sprachen">
<option value="deutsch">Deutsch</option>
<option value="englisch">Englisch</option>
<option value="franzoesisch">Französisch</option>
<option value="latein">Latein</option>
<option value="literatur">Literatur</option>
</optgroup>
<optgroup label="MINT">
<option value="mathe">Mathematik</option>
<option value="biologie">Biologie</option>
<option value="chemie">Chemie</option>
<option value="physik">Physik</option>
<option value="informatik">Informatik</option>
<option value="astronomie">Astronomie</option>
</optgroup>
<optgroup label="Gesellschaft & Werte">
<option value="geschichte">Geschichte</option>
<option value="erdkunde">Erdkunde</option>
<option value="sozialkunde">Sozialkunde</option>
<option value="wirtschaft">Wirtschaftskunde</option>
<option value="religion">Religion</option>
<option value="ethik">Ethikunterricht</option>
<option value="philosophie">Philosophie</option>
<option value="psychologie">Psychologie</option>
<option value="kunst">Kunst</option>
<option value="musik">Musik</option>
<option value="theater">Theater</option>
</optgroup>
<optgroup label="Technik & Praxis">
<option value="technik">Technik</option>
<option value="werken">Werken</option>
<option value="hauswirtschaft">Hauswirtschaft</option>
<option value="sport">Sport</option>
</optgroup>
</select>
</div>
<div class="sidebar-block">
<label for="tags">Schlagwörter</label>
<input type="text" id="tags" name="tags"
value="<?php
if (isset($tags) && !empty($tags)){echo htmlspecialchars($tags);
} elseif (isset($_SESSION['old_tags']) && !empty($_SESSION['old_tags'])){
echo htmlspecialchars($_SESSION['old_tags']);
unset($_SESSION['old_tags']);
}
?>"
placeholder="z.B. Technik, IT (mit Komma trennen)">
</div>
</aside>
</form>
-116
View File
@@ -1,116 +0,0 @@
/* editor in Flexbox */
.article-editor-scope.editor-container {
display: flex;
min-height: 100vh;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
color: #1e1e1e;
background-color: #f0f2f5;
box-sizing: border-box;
max-width: 1200px;
margin: 0 auto; /* Zentriert den gesamten Container horizontal */
width: 100%;
}
.article-editor-scope * {
box-sizing: border-box;
margin: 0;
padding: 0;
}
/* Hauptbereich */
.article-editor-scope .editor-main {
flex: 1;
padding: 40px;
display: flex;
flex-direction: column;
gap: 20px;
background: #ffffff;
}
.article-editor-scope #title {
font-size: 2.5rem;
font-weight: 700;
border: none;
outline: none;
width: 100%;
background: transparent;
}
.article-editor-scope #content {
flex: 1;
font-size: 1.1rem;
line-height: 1.6;
border: none;
outline: none;
resize: none;
width: 100%;
background: transparent;
}
/* Seitenleiste */
.article-editor-scope .editor-sidebar {
width: 300px;
background-color: #ffffff;
border-left: 1px solid #e0e0e0;
padding: 20px;
display: flex;
flex-direction: column;
gap: 24px;
}
.article-editor-scope .sidebar-block {
display: flex;
flex-direction: column;
gap: 8px;
}
.article-editor-scope .sidebar-block label {
font-weight: 600;
font-size: 0.9rem;
}
.article-editor-scope .required {
color: #d94f4f;
}
/* Formularelemente innerhalb der Editor-Sidebar */
.article-editor-scope .editor-sidebar select,
.article-editor-scope .editor-sidebar input[type="text"] {
width: 100%;
padding: 8px;
border: 1px solid #ccc;
border-radius: 4px;
font-size: 0.9rem;
background: #ffffff;
}
/* Button-Zeugs */
.button#editor-button {
padding: 18px 12px;
}
/* Responsive Anpassungen unter 760px (für z.B. Smartphones) */
@media (max-width: 760px) {
.article-editor-scope.editor-container {
/* Sidebar nach unten */
flex-direction: column;
}
.article-editor-scope .editor-main {
/* weniger Innenabstand */
padding: 20px;
}
.article-editor-scope #content {
/* Verhindert, dass das Textfeld auf kleinen Displays kollabiert */
min-height: 300px;
}
.article-editor-scope .editor-sidebar {
width: 100%;
/* Entfernt den linken Rand und setzt ihn nach oben als Trenner */
border-left: none;
border-top: 1px solid #e0e0e0;
}
}
-19
View File
@@ -1,19 +0,0 @@
/* FooterGrundlayout */
footer {
width: 100%;
background: #333d43;
text-align: center;
padding: 10px 0;
}
footer a {
color: white;
text-decoration: none;
margin: 0 12px;
transition: color 0.2s ease; /* Farbwechsel */
}
footer a:hover,
footer a:focus {
color: #0066cc;
}
+153 -202
View File
@@ -1,228 +1,179 @@
main {
max-width:1200px;
margin: 0 auto;
padding: 20px;
width: 100%;
box-sizing: border-box;
* {
box-sizing: border-box;
}
body {
background-color: #eef2f7;
color: #1f2937;
margin: 0;
/* =========================
Farben
========================= */
min-height: 100vh;
display: grid;
grid-template-rows: auto 1fr auto; /* Header(auto), Inhalt (bekommt Rest), Footer(auto) */
}
:root {
--bg: #eef2f7;
--white: #ffffff;
a, button, input, select, textarea, label, main{
font-family: Arial, Helvetica, sans-serif;
}
--nav: #1e293b;
--nav-hover: #334155;
h1 {
text-transform: uppercase;
}
--primary: #2563eb;
--primary-hover: #1d4ed8;
.flexbox {
display: flex;
flex-direction: row;
flex-wrap: wrap;
gap: 20px;
margin-top: 30px;
}
--text: #1e293b;
--text-light: #64748b;
.container {
--border: #dbe4ee;
}
/* =========================
Body
========================= */
body {
font-family: "Segoe UI", Arial, sans-serif;
background-color: var(--bg);
color: var(--text);
}
/* =========================
Header
========================= */
header {
background-color: var(--nav);
}
/* =========================
Logo / Bild
========================= */
header img {
object-fit: cover;
background-color: white;
border-radius: 8px;
padding: 15px;
border: 1px solid #dbe3ec;
box-shadow: 0 4px 12px rgba(0,0,0,0.08);
transition: transform 0.2s, box-shadow 0.2s;
flex: 1 1 300px;
}
border-radius: 14px;
}
.container:hover {
transform: translateY(-3px);
box-shadow: 0 6px 18px rgba(0,0,0,0.12);
}
/* =========================
Navigation
========================= */
.category-link {
display: block;
text-align: left;
nav {
background-color: var(--nav);
}
nav a {
text-decoration: none;
font-weight: bold;
padding: 12px;
background-color: #2563eb;
color: white;
border-radius: 8px;
margin-bottom: 10px;
transition: background-color 0.2s, transform 0.2s, box-shadow 0.2s;
}
.category-link:hover {
background-color: #1d4ed8;
transform: translateY(-2px);
box-shadow: 0 4px 10px rgba(0,0,0,0.15);
}
.article-link a {
color: #1f2937;
text-decoration: none;
font-weight: bold;
transition: color 0.2s;
}
.article-link a:hover {
color: #2563eb;
text-decoration: underline;
}
@media (min-width: 1024px) {
.container {
padding: 25px;
}
}
/* Seite wird horizontal und vertikal zentriert */
.login-page {
display: flex;
justify-content: center;
align-items: center;
min-height: 80vh;
}
.login-container {
width: 90%;
max-width: 450px;
padding: 30px;
border: 1px solid #dbe3ec;
color: #f1f5f9;
font-weight: 600;
border-radius: 10px;
transition: 0.3s ease;
}
nav a:hover {
background-color: var(--nav-hover);
color: white;
}
/* =========================
Suchfeld
========================= */
input[type="text"],
input[type="search"] {
border: 1px solid var(--border);
background-color: white;
box-shadow: 0 6px 20px rgba(0,0,0,0.1);
}
.logo-wrapper {
text-align: center;
margin-bottom: 20px;
}
.login-logo {
width: 120px;
height: auto;
}
.login-container h1 {
text-align: center;
margin-bottom: 25px;
font-size: 1.7rem;
color: #1e293b;
}
.input-label {
margin-bottom: 5px;
font-weight: bold;
width: 100%;
color: #1f2937;
}
.input-label {
margin-bottom: 5px;
font-weight: bold;
width: 100%;
color: #1f2937;
}
.login-input {
width: 100%;
padding: 12px;
margin-bottom: 20px;
border: 1px solid #d1d5db;
border-radius: 6px;
box-sizing: border-box;
font-size: 1rem;
background-color: white;
}
border-radius: 12px;
}
.login-input:focus {
outline: none;
border-color: #2563eb;
box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.15);
}
input:focus {
border-color: var(--primary);
}
.checkbox-wrapper {
margin-bottom: 20px;
color: #1f2937;
}
/* =========================
Buttons
========================= */
.button {
width: 100%;
padding: 12px;
background-color: #2563eb;
button {
background-color: var(--primary);
color: white;
border: none;
border-radius: 8px;
font-size: 1rem;
font-weight: bold;
font-weight: 600;
cursor: pointer;
transition: background-color 0.2s, transform 0.2s, box-shadow 0.2s;
}
.button:hover {
background-color: #1d4ed8;
border-radius: 12px;
transition: 0.25s ease;
}
/* Hover Bewegung */
button:hover {
background-color: var(--primary-hover);
transform: translateY(-2px);
box-shadow: 0 4px 10px rgba(0,0,0,0.15);
}
}
.register-link {
margin-top: 20px;
text-align: center;
font-size: 0.9rem;
color: #1f2937;
}
.register-link a {
color: #2563eb;
/* Klick-Effekt */
button:active {
transform: translateY(0px);
}
/* =========================
Hauptinhalt
========================= */
main {
background-color: var(--white);
border-radius: 24px;
}
/* =========================
Überschriften
========================= */
h1 {
color: var(--primary);
font-size: 3.5rem;
}
h2 {
color: var(--primary);
}
/* =========================
Texte
========================= */
p {
color: var(--text-light);
line-height: 1.8;
font-size: 1.08rem;
}
/* =========================
Links
========================= */
a {
color: var(--primary);
transition: 0.3s ease;
}
a:hover {
color: var(--primary-hover);
}
/* =========================
Footer
========================= */
footer {
background-color: var(--white);
}
footer a {
text-decoration: none;
font-weight: bold;
transition: color 0.2s;
}
color: var(--text-light);
font-weight: 500;
}
.register-link a:hover {
color: #1d4ed8;
text-decoration: underline;
}
/* Versteckt das doppelte Label fuer Screenreader/Accessibility */
.screenreader-only {
display: none;
}
/* Allgemeine Formularseiten */
.form-page {
display: flex;
justify-content: center;
padding: 40px 20px;
}
.form-container {
width: 90%;
max-width: 600px;
padding: 30px;
background-color: white;
border: 1px solid #dbe3ec;
border-radius: 10px;
box-shadow: 0 6px 20px rgba(0,0,0,0.1);
}
.form-container {
flex: 1 1 450px;
padding: 30px;
background-color: white;
border: 1px solid #dbe3ec;
border-radius: 10px;
box-shadow: 0 6px 20px rgba(0,0,0,0.1);
box-sizing: border-box;
}
footer a:hover {
color: var(--primary);
}
-29
View File
@@ -1,29 +0,0 @@
.alert-message {
padding: 12px 16px;
margin: 12px 0;
border-radius: 6px;
border: 1px solid transparent;
font-family: sans-serif;
font-size: 14px;
font-weight: 500;
line-height: 1.5;
display: flex;
align-items: center;
gap: 10px;
}
/* Rote Fehlermeldung */
.alert-message.is-error {
color: #ba1a1a;
background-color: #ffeede;
border-color: #ffb4ab;
}
/* Grüne Erfolgsmeldung */
.alert-message.is-success {
color: #006e2c;
background-color: #e8f5e9;
border-color: #b2dfdb;
}
-289
View File
@@ -1,289 +0,0 @@
/*
CSS für die navbar
*/
.nav {
display: flex;
justify-content: space-between;
align-items: center;
background-color: #333d43;
padding: 0 1rem;
}
.nav__left,
.nav__right {
display: flex;
align-items: center;
}
.nav__logo img {
height: 3rem;
}
.nav__center {
display: flex;
align-items: center;
}
.nav__item {
position: relative;
margin: 0 0.5rem;
}
.nav__dropdown-toggle {
background: none;
border: none;
cursor: pointer;
font-weight: 600;
padding: 0.5rem 1rem;
color: #fff;
text-decoration: none;
}
.nav__dropdown-menu {
display: none;
position: absolute;
top: 100%;
left: 0;
background: #f9f9f9;
min-width: 12rem;
box-shadow: 0 2px 5px rgba(0,0,0,.15);
padding: 0.5rem 0;
}
.nav__dropdown-menu a {
padding: 0.5rem 1rem; /* Abstand um den Text */
color: #333;
text-decoration: none;
font-weight: 600;
}
.nav__link {
display: inline-block;
font-weight: 600;
background: none;
border: none;
cursor: pointer;
padding: 0.5rem 1rem;
color: #fff;
text-decoration: none;
}
.nav__button {
display: inline-block;
background: #fff;
border: none;
border-radius: 4px;
padding: 0.5rem 1rem;
cursor: pointer;
color: #333;
text-decoration: none;
font-weight: 600;
margin-left: 0.5rem;
white-space: nowrap;
}
.nav__search {
display: flex;
align-items: center;
border-radius: 4px; /* Abgerundete Ecken */
background: #fff;
margin: 0 0.5rem;
}
.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__dropdown:hover .nav__dropdown-menu {
display: block;
}
.nav__checkbox {
display: none;
}
.nav__mobile-submenu {
display: block;
}
/* Responsive Anpassung unter 1210px */
@media (max-width: 1210px) {
.nav {
flex-wrap: wrap; /* zweite Nav-Zeile*/
padding: 0.5rem 1rem;
}
.nav__left {
order: 1;
flex: 1; /* nimmt den Platz ganz links ein */
}
.nav__right {
order: 2;
flex: 1;
justify-content: flex-end; /* schiebt Buttons nach ganz rechts */
}
.nav__center {
order: 3;
flex-basis: 100%; /* Erzwingt, dass dieses Element eine eigene Zeile einnimmt */
justify-content: center; /*zentriert die Links in der zweiten Zeile */
padding: 0.5rem 0;
border-top: 1px solid rgba(255,255,255,0.1); /* Optionale Trennlinie */
margin-top: 0.5rem;
}
.nav__item {
margin: 0.25rem;
}
}
#mobile-nav {
display: none;
}
/* Responsive Anpassungen unter 760px (für z.B. Smartphones) */
@media (max-width: 800px) {
.nav {
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
padding: 0 1rem;
}
.nav__logo img {
height: 50px;
}
.nav__left {
order: 2;
flex: 1;
justify-content: flex-start;
}
.nav__right {
order: 3;
width: 100%;
display: flex;
margin-top: 0.5em;
}
#mobile-nav {
display: block;
order: 1;
background: #333d43;
border: none;
color: #fff;
font-size: 1.5rem;
padding: 0.5rem 0.1rem;
border-radius: 0.2rem;
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;
}
/* restliche desktop-navbar aus */
.nav__center,
.nav__right .nav__button,
.nav__right .nav__link {
display: none;
}
/* off canvas menu */
.nav__mobile-menu {
display: flex;
flex-direction: column;
position: fixed;
top: 0;
left: -100%; /* kommt von links */
width: 280px;
height: 100vh;
background: #333d43;
z-index: 1000;
transition: left 0.3s ease;
padding: 2rem 1rem;
box-shadow: 2px 0 10px rgba(0,0,0,0.5);
overflow-y: auto;
/* Genug Abstand oben rechts, damit Links nicht hinter dem X liegen */
padding: 4rem 1.5rem 2rem 1.5rem;
}
.nav__checkbox:checked ~ .nav__mobile-menu {
left: 0;
}
.nav_mobile-menu.is-active {
left: 0;
}
.nav__close-btn {
position: absolute;
top: 1rem;
right: 1.5rem;
font-size: 2rem;
color: #fff;
cursor: pointer;
line-height: 1;
user-select: none;
transition: color 0.2s ease, transform 0.2s ease;
}
.nav__mobile-menu a {
color: #fff;
text-decoration: none;
font-size: 1.2rem;
font-weight: 600;
display: block;
padding: 0.5rem 1rem;
border-bottom: 1px solid #333d43;
}
.nav__mobile-submenu {
display: block;
list-style: none;
padding: 0;
background: rgba(0, 0, 0, 0.15);
}
.nav__mobile-label {
display: flex;
justify-content: space-between;
align-items: center;
color: #fff;
font-size: 1.2rem;
font-weight: 600;
padding: 0.8rem 1rem;
cursor: pointer;
}
}
-89
View File
@@ -1,89 +0,0 @@
/*
CSS für die Profilseite
*/
/* Roter Button für Account löschen */
.delete-account-button {
background-color: #dc2626;
margin-bottom: 0;
}
.delete-account-button:hover {
background-color: #b91c1c;
}
/* Beitragsliste Styling */
.section-title {
margin-top: 0;
margin-bottom: 25px;
font-size: 1.5rem;
color: #1f2937;
border-bottom: 2px solid #eef2f7;
padding-bottom: 10px;
}
.articles-list {
display: flex;
flex-direction: column;
gap: 20px;
}
.article-item {
padding: 15px;
border: 1px solid #e5e7eb;
border-radius: 8px;
background-color: #f9fafb;
position: relative;
}
.article-meta {
display: flex;
justify-content: space-between;
font-size: 0.85rem;
color: #6b7280;
margin-bottom: 8px;
}
.article-category {
font-weight: bold;
color: #2563eb;
}
.article-title {
margin: 0 0 10px 0;
font-size: 1.2rem;
color: #1f2937;
}
.article-tags {
display: flex;
flex-wrap: wrap;
gap: 6px;
margin-bottom: 15px;
}
.tag {
font-size: 0.75rem;
background-color: #e5e7eb;
color: #374151;
padding: 3px 8px;
border-radius: 4px;
}
/* Bearbeiten-Button als Link deklariert */
.edit-link-button {
display: inline-block;
text-decoration: none;
font-size: 0.9rem;
font-weight: bold;
color: #2563eb;
border: 1px solid #2563eb;
padding: 6px 12px;
border-radius: 6px;
transition: background-color 0.2s, color 0.2s;
}
.edit-link-button:hover {
background-color: #2563eb;
color: white;
}
-263
View File
@@ -1,263 +0,0 @@
/*
CSS für die Suchergebnis-Seite
*/
/* Container und Layout-Schutz vor globalen Styles */
.s-res-layout-grid {
box-sizing: border-box;
max-width: 95%; /* Nutzt jetzt 95% der Bildschirmbreite statt starrer Pixel */
width: 95%; /* Erhöht das Limit für extrem große Monitore von 1200px auf 1600px */
margin: 2rem auto;
padding: 0 1rem;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
color: #212529;
line-height: 1.5;
/* Grid für die Zweispaltigkeit */
display: grid;
grid-template-columns: 320px 1fr; /* Seitenleiste leicht verbreitert, Inhalt nimmt den gesamten Rest ein */
gap: 2.5rem; /* Etwas mehr Abstand zwischen Seitenleiste und Inhalt für das breitere Layout */
}
.s-res-layout-grid * {
box-sizing: border-box;
}
/* --- SEITENLEISTE (FILTER & SUCHE) --- */
.s-res-sidebar {
display: flex;
flex-direction: column;
gap: 1.5rem;
}
.s-res-sidebar-box {
background-color: #ffffff;
border: 1px solid #e2e8f0;
border-radius: 8px;
padding: 1.25rem;
}
.s-res-sidebar-title {
font-size: 1rem;
font-weight: 700;
color: #1a202c;
margin: 0 0 1rem 0;
text-transform: uppercase;
letter-spacing: 0.05em;
}
/* Formular & deine Suchleisten-Klassen */
.s-res-search-form {
display: flex;
align-items: center;
}
/* Filter Radio-Buttons */
.s-res-filter-group {
display: flex;
flex-direction: column;
gap: 0.75rem;
}
.s-res-filter-option {
display: flex;
align-items: center;
gap: 0.5rem;
cursor: pointer;
font-size: 0.95rem;
color: #4a5568;
}
.s-res-filter-option input[type="radio"] {
margin: 0;
accent-color: #3182ce;
}
/* --- HAUPTINHALT (ERGEBNISSE) --- */
.s-res-main-content {
min-width: 0;
}
.s-res-header {
margin-bottom: 2rem;
border-bottom: 2px solid #dee2e6;
padding-bottom: 1rem;
}
.s-res-main-title {
font-size: 2rem;
color: #1a202c;
margin: 0 0 0.5rem 0;
font-weight: 700;
}
.s-res-meta {
color: #6c757d;
font-size: 0.95rem;
margin: 0;
}
.s-res-list {
display: flex;
flex-direction: column;
gap: 1rem;
}
/* Einzelner Beitrag */
.s-res-item {
background-color: #ffffff;
border: 1px solid #e2e8f0;
border-radius: 8px;
padding: 1.25rem;
display: flex;
justify-content: space-between;
align-items: center;
transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
}
.s-res-item:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
border-color: #cbd5e1;
}
.s-res-content {
flex: 1;
}
.s-res-item-title {
font-size: 1.25rem;
margin: 0 0 0.25rem 0;
font-weight: 600;
}
.s-res-link {
color: #3182ce;
text-decoration: none;
transition: color 0.2s ease;
}
.s-res-link:hover {
text-decoration: underline;
color: #2b6cb0;
}
.s-res-author {
font-size: 0.875rem;
color: #4a5568;
margin: 0;
}
.s-res-author-name {
font-weight: 600;
color: #2d3748;
}
.s-res-arrow {
font-size: 1.5rem;
color: #a0aec0;
padding-left: 1rem;
transition: color 0.2s ease, transform 0.2s ease;
}
.s-res-item:hover .s-res-arrow {
color: #3182ce;
transform: translateX(3px);
}
/* ERGEBNISSE PRO SEITE & PAGINIERUNG */
.s-res-pagination-footer {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 2rem;
padding-top: 1.5rem;
border-top: 1px solid #e2e8f0;
}
/* Dropdown-Auswahl */
.s-res-limit-selector {
display: flex;
align-items: center;
gap: 0.5rem;
}
.s-res-limit-label {
font-size: 0.9rem;
color: #4a5568;
}
.s-res-limit-select {
padding: 0.35rem 1.5rem 0.35rem 0.5rem;
font-size: 0.9rem;
color: #2d3748;
background-color: #ffffff;
border: 1px solid #cbd5e1;
border-radius: 4px;
cursor: pointer;
outline: none;
transition: border-color 0.2s;
/* Diskreter nativer Pfeil-Style */
appearance: none;
background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://w3.org' viewBox='0 0 24 24' fill='none' stroke='%234a5568' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: right 0.4rem center;
background-size: 1em;
}
.s-res-limit-select:focus {
border-color: #3182ce;
}
/* Seitennummern Navigation */
.s-res-page-navigation {
display: flex;
gap: 0.25rem;
}
.s-res-page-btn {
background-color: #ffffff;
border: 1px solid #cbd5e1;
color: #4a5568;
padding: 0.35rem 0.75rem;
font-size: 0.9rem;
font-weight: 500;
border-radius: 4px;
cursor: pointer;
transition: all 0.2s ease;
}
.s-res-page-btn:hover:not(:disabled) {
background-color: #f8f9fa;
border-color: #cbd5e1;
color: #2d3748;
}
.s-res-page-btn-active {
background-color: #3182ce;
border-color: #3182ce;
color: #ffffff;
cursor: default;
}
.s-res-page-btn:disabled {
background-color: #f1f5f9;
border-color: #e2e8f0;
color: #94a3b8;
cursor: not-allowed;
}
/* Responsive Anpassungen unter 760px (für z.B. Smartphones) */
@media (max-width: 768px) {
.s-res-layout-grid {
grid-template-columns: 1fr; /* Stapelt Seitenleiste und Inhalt untereinander */
gap: 1.5rem;
margin: 1rem auto;
}
.s-res-pagination-footer {
flex-direction: column;
gap: 1rem;
align-items: flex-start;
}
}
-118
View File
@@ -1,118 +0,0 @@
/* Container für den gesamten articleikel */
.article-view-container {
box-sizing: border-box;
max-width: 900px; /* Angenehme Lesebreite für längere Texte */
margin: 3rem auto;
padding: 0 2rem;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
color: #212529;
line-height: 1.6;
}
.article-view-container * {
box-sizing: border-box;
}
/* --- KOPFDATEN-BEREICH --- */
.article-view-top-section {
margin-bottom: 2.5rem;
border-bottom: 1px solid #e2e8f0;
padding-bottom: 1.5rem;
}
/* Kategorie-Badge */
.article-view-category {
display: inline-block;
background-color: #ebf8ff;
color: #2b6cb0;
font-size: 0.8rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.05em;
padding: 0.25rem 0.75rem;
border-radius: 4px;
margin-bottom: 0.75rem;
}
/* Hauptüberschrift */
.article-view-title {
font-size: 2.5rem;
color: #1a202c;
line-height: 1.2;
margin: 0 0 0.75rem 0;
font-weight: 800;
}
/* Autoren-Zeile */
.article-view-meta {
font-size: 0.95rem;
color: #4a5568;
}
.article-view-author strong {
color: #2d3748;
}
/* --- INHALT --- */
.article-view-content {
margin-bottom: 3rem;
}
.article-view-body {
font-size: 1.125rem;
color: #2d3748;
white-space: pre-line;
}
/* --- TAG-BEREICH --- */
.article-view-bottom-section {
border-top: 1px solid #e2e8f0;
padding-top: 1.5rem;
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.article-view-tags-label {
font-size: 0.9rem;
font-weight: 600;
color: #718096;
text-transform: uppercase;
letter-spacing: 0.05em;
}
.article-view-tags-list {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
}
/* Einzelner Tag */
.article-view-tag-item {
background-color: #f1f5f9;
color: #475569;
font-size: 0.85rem;
font-weight: 500;
padding: 0.35rem 0.75rem;
border-radius: 6px;
border: 1px solid #e2e8f0;
transition: background-color 0.2s, color 0.2s;
}
.article-view-tag-item:hover {
background-color: #e2e8f0;
color: #1e293b;
cursor: default;
}
/* Responsive Anpassungen unter 760px (für z.B. Smarticlephones) */
@media (max-width: 760px) {
.article-view-container {
margin: 1.5rem auto;
padding: 0 1rem;
}
.article-view-title {
font-size: 1.85rem;
}
}
View File
-1
View File
@@ -1 +0,0 @@
[]
-3
View File
@@ -1,3 +0,0 @@
<FilesMatch "\.db">
deny from all
</FilesMatch>
Binary file not shown.

After

Width:  |  Height:  |  Size: 169 KiB

Before

Width:  |  Height:  |  Size: 199 KiB

After

Width:  |  Height:  |  Size: 199 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 157 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

-5
View File
@@ -1,5 +0,0 @@
<footer>
<a href="index.php?pfad=impressum">Impressum</a>
<a href="index.php?pfad=datenschutz">Datenschutz</a>
<a href="index.php?pfad=nutzungsbedingungen">Nutzungsbedingungen</a>
</footer>
+22 -174
View File
@@ -1,180 +1,28 @@
<?php
session_start();
?>
<!--
Globales Menü, wird via PHP später in alle Seiten eingebunden
-->
<nav class="nav">
<div class="nav__left">
<a href="index.php" class="nav__logo">
<img src="images/logos/logo_full.png" alt="Logo">
</a>
</div>
<!-- Mobile navbar mit Burger-Symbol -->
<input type="checkbox" id="nav-toggle" class="nav__checkbox">
<label for="nav-toggle" id="mobile-nav">
<span>☰</span>
</label>
<ul id="mobile-nav" class="nav__mobile-menu">
<li>
<label for="nav-toggle" class="nav__close-btn">&times;</label>
</li>
<?php if (isset($_SESSION['user'])): ?>
<li><a href="index.php?pfad=profile">Profil</a></li>
<li><a href="index.php?pfad=logout">Abmelden</a></li>
<li><a href="index.php?pfad=createArticle">Beitrag erstellen</a></li>
<?php else: ?>
<li><a href="index.php?pfad=login">Anmelden</a></li>
<li><a href="index.php?pfad=register">Registrieren</a></li>
<?php endif; ?>
<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>
</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>
</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>
</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>
</ul>
</li>
</ul>
<!-- normale Navbar (Desktop) -->
<div class="nav__center">
<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>
</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>
</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>
</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>
</div>
</div>
</div>
<div class="nav__right">
<?php if (isset($_SESSION['user'])): ?>
<a href="index.php?pfad=profile" class="nav__item nav__link">
Profil
</a>
<div class="nav__search">
<?php include_once 'search.php'; ?>
</div>
<a href="index.php?pfad=createArticle" class="nav__item nav__button">
Beitrag erstellen
</a>
<a href="index.php?pfad=logout" class="nav__item nav__button">
Abmelden
</a>
<?php else: ?>
<div class="nav__search">
<?php include_once 'search.php'; ?>
</div>
<a href="index.php?pfad=login" class="nav__item nav__button">
Anmelden
</a>
<a href="index.php?pfad=register" class="nav__item nav__button">
Registrieren
</a>
<?php endif; ?>
<nav style="background:#808080; height: 60px;">
<div style="float:left; text-align: center;">
<a href="index.php">
<img src="images/logo.png" alt="" style="height: 44px;">
</a>
|
<a href = "content/informatik.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Informatik</b></a>
|
<a href = "content/mathe.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Mathe</b></a>
|
<a href = "content/physik.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Physik</b></a>
|
<a href = "content/profile.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Dein Profil</b></a>
|
</div>
<div style="float:right; text-align: center;">
<?php
include_once 'search.php';
?>
|
<a href = "auth/login.php" style = "background-color: #f44336; color: white; padding: 4px 20px; text-align: center; text-decoration: none; display: inline-block;"> Anmelden </a>
<a href = "auth/register.php" style = "background-color: #f44336; color: white; padding: 4px 20px; text-align: center; text-decoration: none; display: inline-block;"> Registrieren </a>
</div>
</nav>
+2 -8
View File
@@ -1,11 +1,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>
<button type="submit" class="nav__search-button">Suchen</button>
</form>
<input type="search" id="site-search" name="q" placeholder="Suchen...">
<button type="submit">Suchen</button>
+25 -70
View File
@@ -1,77 +1,32 @@
<?php
session_start();
ob_start();
<!--
Seite: Hompage der Lernplattform
Funktion: Webseitengerüst, Anzeigen von Beiträgen, Suchfunktion etc.
-->
<!DOCTYPE html>
<html lang="de">
$pfad = $_GET["pfad"] ?? "home";
<head>
<meta charset="utf-8">
<meta name="description" content="EduForge">
<meta name="author" content="Niklas Ortmann">
<link rel="stylesheet" href="css/main.css" />
<title>EduForge</title>
</head>
/*
Controller für Aktionen werden vor der HTML-Ausgabe geladen,
damit Weiterleitungen mit header() funktionieren.
*/
if ($pfad === "login") {
include_once "php/controller/login-controller.php";
}
if ($pfad === "register") {
include_once "php/controller/register-controller.php";
}
if ($pfad === "logout") {
include_once "content/logout.php";
exit();
}
if ($pfad === "deleteAccount") {
include_once "content/deleteAccount.php";
exit();
}
?>
<!--
Seite: Index der Lernplattform
Funktion: Webseitengerüst, Anzeigen von Content
-->
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="description" content="EduForge">
<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">
<link rel="stylesheet" href="css/search-results.css">
<link rel="stylesheet" href="css/createArticle.css">
<link rel="stylesheet" href="css/profile.css">
<link rel="stylesheet" href="css/showArticle.css">
<link rel="stylesheet" href="css/message.css">
<title>EduForge</title>
</head>
<body>
<body>
<?php
include_once 'includes/navbar.php';
include_once 'includes/navbar.php';
//Dynamischer Inhalt (später mit php...):
include_once 'content/home.php';
?>
/*
Dynamischer Inhalt:
Je nach pfad-Parameter wird die passende Datei aus content geladen.
*/
if (file_exists('content/' . $pfad . '.php')) {
include_once 'content/' . $pfad . '.php';
} else {
include_once 'content/404.php';
}
<footer style="position:fixed;bottom:0;width:100%;background:#fff;text-align:center;">
<a href="legal/impressum.php">Impressum</a>
<a href="legal/datenschutz.php">Datenschutz</a>
<a href="legal/nutzungsbedingungen.php">Nutzungsbedingungen</a>
</footer>
</body>
include_once 'includes/footer.php';
?>
</body>
</html>
<?php
ob_end_flush();
?>
</html>
+67
View File
@@ -0,0 +1,67 @@
<!--
Seite: Datenschutzerklärung
Inhalt: Informationen zur Datenverarbeitung gemäß DSGVO
-->
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="description" content="EduForge">
<meta name="author" content="Niklas Ortmann">
<link rel="stylesheet" href="../css/main.css" />
<title>EduForge</title>
</head>
<body>
<nav style="background:#808080; height: 60px;">
<div style="float:left; text-align: center;">
<a href="../index.php">
<img src="../images/logo.png" alt="" style="height: 44px;">
</a>
|
<a href = "../content/informatik.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Informatik</b></a>
|
<a href = "../content/mathe.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Mathe</b></a>
|
<a href = "../content/physik.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Physik</b></a>
|
<a href = "../content/profile.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Dein Profil</b></a>
|
</div>
<div style="float:right; text-align: center;">
<?php
include_once '../includes/search.php';
?>
|
<a href = "../auth/login.php" style = "background-color: #f44336; color: white; padding: 4px 20px; text-align: center; text-decoration: none; display: inline-block;"> Anmelden </a>
<a href = "../auth/register.php" style = "background-color: #f44336; color: white; padding: 4px 20px; text-align: center; text-decoration: none; display: inline-block;"> Registrieren </a>
</div>
</nav>
<main>
<h1>Datenschutz</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>
</main>
<footer style="position:fixed;bottom:0;width:100%;background:#fff;text-align:center;">
<a href="impressum.php">Impressum</a>
<a href="datenschutz.php">Datenschutz</a>
<a href="nutzungsbedingungen.php">Nutzungsbedingungen</a>
</footer>
</body>
</html>
+67
View File
@@ -0,0 +1,67 @@
<!--
Seite: Impressum
Inhalt: wer wie was auf der Webseite
-->
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="description" content="EduForge">
<meta name="author" content="Niklas Ortmann">
<link rel="stylesheet" href="../css/main.css" />
<title>EduForge</title>
</head>
<body>
<nav style="background:#808080; height: 60px;">
<div style="float:left; text-align: center;">
<a href="../index.php">
<img src="../images/logo.png" alt="" style="height: 44px;">
</a>
|
<a href = "../content/informatik.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Informatik</b></a>
|
<a href = "../content/mathe.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Mathe</b></a>
|
<a href = "../content/physik.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Physik</b></a>
|
<a href = "../content/profile.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Dein Profil</b></a>
|
</div>
<div style="float:right; text-align: center;">
<?php
include_once '../includes/search.php';
?>
|
<a href = "../auth/login.php" style = "background-color: #f44336; color: white; padding: 4px 20px; text-align: center; text-decoration: none; display: inline-block;"> Anmelden </a>
<a href = "../auth/register.php" style = "background-color: #f44336; color: white; padding: 4px 20px; text-align: center; text-decoration: none; display: inline-block;"> Registrieren </a>
</div>
</nav>
<main>
<h1>Impressum</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>
</main>
<footer style="position:fixed;bottom:0;width:100%;background:#fff;text-align:center;">
<a href="impressum.php">Impressum</a>
<a href="datenschutz.php">Datenschutz</a>
<a href="nutzungsbedingungen.php">Nutzungsbedingungen</a>
</footer>
</body>
</html>
+66
View File
@@ -0,0 +1,66 @@
<!--
Seite: Nutzungsbedingungen
Inhalt: Regelungen für die Nutzung der Plattform (AGBs und so...)
-->
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="description" content="EduForge">
<meta name="author" content="Niklas Ortmann">
<link rel="stylesheet" href="../css/main.css" />
<title>EduForge</title>
</head>
<body>
<nav style="background:#808080; height: 60px;">
<div style="float:left; text-align: center;">
<a href="../index.php">
<img src="../images/logo.png" alt="" style="height: 44px;">
</a>
|
<a href = "../content/informatik.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Informatik</b></a>
|
<a href = "../content/mathe.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Mathe</b></a>
|
<a href = "../content/physik.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Physik</b></a>
|
<a href = "../content/profile.php" style = "padding: 5px; text-align: center; text-decoration: none; display: inline-block;"><b>Dein Profil</b></a>
|
</div>
<div style="float:right; text-align: center;">
<?php
include_once '../includes/search.php';
?>
|
<a href = "../auth/login.php" style = "background-color: #f44336; color: white; padding: 4px 20px; text-align: center; text-decoration: none; display: inline-block;"> Anmelden </a>
<a href = "../auth/register.php" style = "background-color: #f44336; color: white; padding: 4px 20px; text-align: center; text-decoration: none; display: inline-block;"> Registrieren </a>
</div>
</nav>
<main>
<h1>Nutzungsbedingungen</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>
</main>
<footer style="position:fixed;bottom:0;width:100%;background:#fff;text-align:center;">
<a href="impressum.php">Impressum</a>
<a href="datenschutz.php">Datenschutz</a>
<a href="nutzungsbedingungen.php">Nutzungsbedingungen</a>
</footer>
</body>
</html>
@@ -1,89 +0,0 @@
<?php
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"] ?? '';
$_SESSION["old_content"] = $_POST["content"] ?? '';
$_SESSION["old_category"] = $_POST["category"] ?? '';
$_SESSION["old_tags"] = $_POST["tags"] ?? '';
if(!isset($_POST["title"]) ||!isset($_POST["content"]) || !isset($_POST["category"])){
$_SESSION["message"] = "missing_parameters";
header("location: ../../index.php?pfad=createArticle");
exit();
} else {
$title = $_POST["title"];
$content = $_POST["content"];
$author = $_SESSION["user_email"];
$category = $_POST["category"];
$tags = $_POST['tags'] ?? '';
// -------------------------------- Validierung der Daten: -------------------------
if (!articleAuthorValidator($author)) {
$_SESSION["message"] = "author_not_valid";
header("location: ../../index.php?pfad=createArticle");
exit();
}
if (!articleTitleValidator($title)) {
$_SESSION["message"] = "invalid_title";
header("location: ../../index.php?pfad=createArticle");
exit();
}
if (!articleContentValidator($content)) {
$_SESSION["message"] = "invalid_content";
header("location: ../../index.php?pfad=createArticle");
exit();
}
if (!articleCategoryValidator($category)) {
$_SESSION["message"] = "invalid_category";
header("location: ../../index.php?pfad=createArticle");
exit();
}
if (!articleTagValidator($tags)) {
$_SESSION["message"] = "invalid_tags";
header("location: ../../index.php?pfad=createArticle");
exit();
} else {
$cleanedTags = [];
$rawTags = explode(',', $tags);
foreach ($rawTags as $rawTag) {
// Leerzeichen am Anfang/Ende des einzelnen Tags entfernen:
$tag = trim($rawTag);
$cleanedTags[] = $tag;
}
// Duplikate entfernen:
$cleanedTags = array_unique($cleanedTags);
$cleanedTags = implode(',', $cleanedTags);
}
// ----------------- Übertragung der validierten Daten in ArticleManager: ---------------------------
try {
$articleManager = ArticleManager::getInstance();
$articleManager->addArticle($title, $content, $author, $category, $cleanedTags);
// Formulardaten nach erfolgreichem Erstellen aus der Session löschen
unset($_SESSION["old_title"], $_SESSION["old_content"], $_SESSION["old_category"], $_SESSION["old_tags"]);
} catch (Exception $e){
$_SESSION["message"] = "internal_error";
header("location: ../../index.php?pfad=createArticle");
exit();
}
$_SESSION["message"] = "new_article";
// Weiterleitung zur Homepage
header("location: ../../index.php");
exit();
}
}
?>
-17
View File
@@ -1,17 +0,0 @@
<?php
session_start();
require_once 'php/model/Article.php';
require_once 'php/model/ArticleManager.php';
require_once 'php/model/LocalArticleManager.php';
try {
$articleManager = ArticleManager::getInstance();
// Beziehen der Dummy-Beiträge aus dem ArticleManager:
$dummy1 = $articleManager->getArticle(1);
$dummy2 = $articleManager->getArticle(2);
$dummy3 = $articleManager->getArticle(3);
} catch (Exception $e){
$_SESSION["message"] = "internal_error";
echo "Fehler aufgetreten: " . $e->getMessage();
}
?>
-3
View File
@@ -1,3 +0,0 @@
<?php
?>
-35
View File
@@ -1,35 +0,0 @@
<?php
require_once "php/model/LocalUserManager.php";
$dao = new LocalUserManager();
$error = null;
/*
Verarbeitung des Login-Formulars
Funktion: Prüft Benutzerdaten und erstellt Session für eingeloggten Nutzer
*/
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$email = $_POST["email"] ?? "";
$password = $_POST["password"] ?? "";
$user = $dao->findUser($email);
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");
exit();
} else {
$error = "Login fehlgeschlagen. Bitte überprüfe deine Eingaben.";
}
}
-91
View File
@@ -1,91 +0,0 @@
<?php
require_once "php/model/LocalUserManager.php";
require_once "php/model/Article.php";
require_once "php/model/ArticleManager.php";
require_once "php/validator/user-validator.php";
$error = null;
if (!isset($_SESSION["user"])) {
header("Location: index.php?pfad=login");
exit();
}
try {
$dao = new LocalUserManager();
$user = $dao->findUser($_SESSION["user_email"] ?? "");
if (!$user) {
$_SESSION = [];
session_destroy();
header("Location: index.php?pfad=login");
exit();
}
if ($_SERVER["REQUEST_METHOD"] === "POST" && isset($_POST["saveProfile"])) {
$oldEmail = $_SESSION["user_email"];
$newEmail = trim($_POST["email"] ?? "");
$vorname = trim($_POST["vorname"] ?? "");
$nachname = trim($_POST["nachname"] ?? "");
$password = $_POST["password"] ?? "";
if (!userEmailValidator($newEmail)) {
$error = "Bitte gib eine gültige E-Mail-Adresse ein.";
$_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";
} else {
$updated = $dao->updateUser(
$oldEmail,
$newEmail,
$vorname,
$nachname,
$password
);
if ($updated) {
$_SESSION["user"] = $vorname . " " . $nachname;
$_SESSION["user_email"] = $newEmail;
header("Location: index.php?pfad=profile");
exit();
} else {
$error = "Die Daten konnten nicht gespeichert werden.";
$_GET["edit"] = "1";
}
}
}
$user = $dao->findUser($_SESSION["user_email"] ?? "");
$articleManager = ArticleManager::getInstance();
$userArticles = $articleManager->getArticlesByAuthor($_SESSION["user_email"]);
if (!isset($userArticles)) {
$_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";
}
@@ -1,24 +0,0 @@
<?php
/*
* Controller für die Liste der eigenen Beiträge eines Nutzers auf der eigenen Profilseite
*/
require_once 'php/model/Article.php';
require_once 'php/model/ArticleManager.php';
require_once "../model/LocalUserManager.php";
try {
$dao = new LocalUserManager();
$user = $dao->findUser($_SESSION["user_email"] ?? "");
$author = $user["email"];
$articleManager = ArticleManager::getInstance();
$userArticles = $articleManager->getArticlesByAuthor($author);
if(!isset($userArticles)) {
$_SESSION["message"] = "user_has_no_articles";
}
} catch (Exception $e) {
$_SESSION["message"] = "internal_error";
}
?>
-43
View File
@@ -1,43 +0,0 @@
<?php
require_once "php/model/LocalUserManager.php";
require_once "php/validator/user-validator.php";
$error = null;
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$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 LocalUserManager();
$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.";
}
}
}
@@ -1,68 +0,0 @@
<?php
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"] = "";
$_SESSION["message"] = "missing_parameters";
} else {
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";
} catch (Exception $e){
$_SESSION["message"] = "internal_error";
}
}
header("Location: ../../index.php?pfad=search-results");
exit();
}
?>
-29
View File
@@ -1,29 +0,0 @@
<?php
session_start();
require_once 'php/model/Article.php';
require_once 'php/model/ArticleManager.php';
if (isset($_GET["id"]) && !empty($_GET["id"])){
try {
$id = $_GET["id"];
$articleManager = ArticleManager::getInstance();
$article = $articleManager->getArticle($id);
if($article != null){
$title = $article->getTitle();
$content = $article->getContent();
$category = $article->getCategory();
$author = $article->getAuthor();
$tags = $article->getTags();
}else{
//header("location: index.php?pfad=404");
include_once "content/404.php";
exit();
}
} catch (Exception $e){
$_SESSION["message"] = "internal_error";
exit();
}
}else{
$_SESSION["message"] = "missing_id";
}
?>
@@ -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();
}
?>
@@ -1,95 +0,0 @@
<?php
SESSION_START();
require_once '../model/LocalArticleManager.php';
require_once '../model/ArticleManager.php';
require_once '../model/Article.php';
require_once '../validator/article-validator.php';
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$_SESSION["old_title"] = $_POST["title"] ?? '';
$_SESSION["old_content"] = $_POST["content"] ?? '';
$_SESSION["old_category"] = $_POST["category"] ?? ''; // TODO: die Kategorie im Dropdown setzen, wenn der Editor erneut geöffnet wird.
$_SESSION["old_tags"] = $_POST["tags"] ?? '';
if (isset($_GET["id"]) && !empty($_GET["id"])) {
$id = $_GET["id"];
} else {
$_SESSION["message"] = "missing_id";
header("location: ../../index.php?pfad=updateArticle");
exit();
}
if (!isset($_POST["title"]) ||!isset($_POST["content"]) || !isset($_POST["category"])){
$_SESSION["message"] = "missing_parameters";
header("location: ../../index.php?pfad=updateArticle");
exit();
}else{
$title = $_POST["title"];
$content = $_POST["content"];
$author = $_SESSION["user_email"];
$category = $_POST["category"];
$tags = $_POST['tags'] ?? '';
// -------------------------------- Validierung der Daten: -------------------------
if (!articleAuthorValidator($author)) {
$_SESSION["message"] = "author_not_valid";
header("location: ../../index.php?pfad=updateArticle");
exit();
}
if (!articleTitleValidator($title)) {
$_SESSION["message"] = "invalid_title";
header("location: ../../index.php?pfad=updateArticle");
exit();
}
if (!articleContentValidator($content)) {
$_SESSION["message"] = "invalid_content";
header("location: ../../index.php?pfad=updateArticle");
exit();
}
if (!articleCategoryValidator($category)) {
$_SESSION["message"] = "invalid_category";
header("location: ../../index.php?pfad=updateArticle");
exit();
}
if (!articleTagValidator($tags)) {
$_SESSION["message"] = "invalid_tags";
header("location: ../../index.php?pfad=updateArticle");
exit();
} else {
$cleanedTags = [];
$rawTags = explode(',', $tags);
foreach ($rawTags as $rawTag) {
// Leerzeichen am Anfang/Ende des einzelnen Tags entfernen:
$tag = trim($rawTag);
$cleanedTags[] = $tag;
}
// Duplikate entfernen:
$cleanedTags = array_unique($cleanedTags);
$cleanedTags = implode(',', $cleanedTags);
}
// ----------------- Übertragung der validierten Daten in ArticleManager: ---------------------------
try {
$articleManager = ArticleManager::getInstance();
$article = $articleManager->getArticle($id);
$article->setTitle($title);
$article->setContent($content);
$article->setCategory($category);
$article->setTags($cleanedTags);
$articleManager->updateArticle($id ,$article, $author);
} catch (Exception $e){
$_SESSION["message"] = $e->getMessage();
header("location: ../../index.php?pfad=updateArticle");
exit();
}
$_SESSION["message"] = "article_updated";
// Weiterleitung zur Homepage
header("location: ../../index.php?pfad=showArticle&id=$id");
}
}
?>
-147
View File
@@ -1,147 +0,0 @@
<?php
/**
* Klasse: Artikel
* Diese Klasse stellt alle Daten eines Beitrags (Beitrag) bereit
*
* @author Niklas Ortmann
*/
class Article
{
public $id;
public $title;
public $content;
public $author;
public $creationDate;
public $category;
public $tags;
/**
* Konstruktor
*
* @param $id integer ID des Beitrages
* @param $title string Titel des Beitrags
* @param $content string Inhalt des Beitrags
* @param $author string der Autor des des Beitrages NID
* @param $category string Kategorie des Beitrages
* @param $tags string optionale Schlagworte für eine bessere Suche
* @param $creationDate string Datum der Beitragserstellung
*/
public function __construct(int $id, string $title, string $content, string $author, string $category, string $tags, string $creationDate)
{
$this->id = $id;
$this->title = $title;
$this->content = $content;
$this->author = $author;
$this->creationDate = $creationDate;
$this->category = $category;
$this->tags = $tags;
}
/**
* Gibt die ID eines Beitrags zurück.
* @return int
*/
public function getId(): int
{
return $this->id;
}
/**
* Gibt den Titel eines Beitrags zurück.
* @return string
*/
public function getTitle(): string
{
return $this->title;
}
/**
* Setzt den Titel eines Beitrags
* @param $title
* @return void
*/
public function setTitle($title)
{
$this->title = $title;
}
/**
* Gibt den Content eines Beitrags zurück.
* TODO: Content muss noch definiert werden.
* @return string
*/
public function getContent(): string
{
return $this->content;
}
/**
* Setzt den Content eines Beitrags.
* TODO: Content muss noch definiert werden.
* @param $content
* @return void
*/
public function setContent($content)
{
$this->content = $content;
}
/**
* Gibt den Autor eines Beitrags zurück.
* @return string
*/
public function getAuthor(): string
{
return $this->author;
}
/**
* Gibt das Veröffentlichungsdatum des Beitrags zurück.
* @return string
*/
public function getCreationDate(): string
{
return $this->creationDate;
}
/**
* Gibt die Kategorie eines Beitrags zurück.
* @return string
*/
public function getCategory(): string
{
return $this->category;
}
/**
* Setzt die Kategorie eines Beitrags.
* @param string $category
* @return void
*/
public function setCategory(string $category)
{
$this->category = $category;
}
/**
* Gibt die Schlagworte eines Beitrags zurück.
* @return string
*/
public function getTags(): string
{
return $this->tags;
}
/**
* Setzt die Schlagworte eines Beitrags.
* @param string $tags
*/
public function setTags(string $tags)
{
$this->tags = $tags;
}
}
?>
-49
View File
@@ -1,49 +0,0 @@
<?php
require_once 'LocalArticleManager.php';
require_once 'DatabaseArticleManager.php';
require_once 'Article.php';
/**
* Die Klasse beinhaltet alle Methoden für die Operation mit den Artikel-Daten.
*
* @author Niklas Ortmann
*/
class ArticleManager
{
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 ){
$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"
);
}
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;
}
}
-96
View File
@@ -1,96 +0,0 @@
<?php
require_once "Article.php";
class NotFoundException extends Exception {}
class UnauthorizedAccessException extends Exception {}
class InternalServerErrorException extends Exception {}
/**
* Die Klasse beinhaltet alle Methoden für die Operation mit den Artikel-Daten.
*
* @author Niklas Ortmann
*/
interface ArticleManagerDAO
{
/**
* Ein angemeldeter Nutzer erstellt einen neuen Beitrag.
* @param $title string Titel des Beitrags
* @param $content string Inhalt des Beitrags
* @param $author string der Autor des des Beitrages NID
* @param $category string Kategorie des Beitrages
* @param $tags string optionale Schlagworte für eine bessere Suche
*
* @throws InternalServerErrorException
*/
public function addArticle($title, $content, $author, $category, $tags);
/**
* Ändert den gespeicherten Beitrag eines übergebenen Beitrags und eines Autors.
* Es wird geprüft, ob der zu änderne Beitrag existiert und ob der übergebene Autor der Autor des originalen
* Beitrages ist.
* @param $id
* @param $article
* @param $author
* @return void
*
* @throws InternalServerErrorException
* @throws NotFoundException
* @throws UnauthorizedAccessException
*/
public function updateArticle($id, $article, $author);
/**
* Löscht einen Beitrag aus übergebener ID und dem Nutzer, der die Löschung ausführt.
* @param $id
* @param $author
* @return void
* @throws InternalServerErrorException
* @throws NotFoundException
* @throws UnauthorizedAccessException
*/
public function deleteArticle($id, $author);
/**
* Beitrag aufrufen.
* $id ID des Beitrags
*
* @return Article
* @throws InternalServerErrorException
*/
public function getArticle($id);
/**
* Alle Beiträge aufrufen.
*
* @throws InternalServerErrorException
*/
public function getAllArticles();
/**
* Gibt alle Beiträge eines Nutzer mit einer gegebenen ID aus.
* @param $author
* @return Article[]
* @throws InternalServerErrorException
*/
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
* @throws InternalServerErrorException
*/
public function getArticlesByCategory($category);
}
?>
-313
View File
@@ -1,313 +0,0 @@
<?php
require_once 'ArticleManagerDAO.php';
require_once 'Article.php';
/**
* Klasse: Eine SQLLite3 Lösung des ArticleManagerDAO.
*
* @author Niklas Ortmann
*/
class DatabaseArticleManager implements ArticleManagerDAO {
private static $instance = null;
/**
* Konstruktor
*
* Erstellt die Datenbankverbindung und die Tabelle articles.
* @throws InternalServerErrorException
*/
public function __construct()
{
if (!file_exists(__DIR__ . '/../../db/articles.db')) {
try {
$db = $this->getConnection();
$db->exec("
CREATE TABLE articles (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT,
content TEXT,
author TEXT,
category TEXT,
tags TEXT,
created TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);");
unset($db);
} catch (PDOException $e) {
throw new InternalServerErrorException($e->getMessage());
}
}
}
/**
* Baut die Verbindung zur Datenbank auf.
* @throws InternalServerErrorException
*/
private function getConnection()
{
try {
$user = 'root';
$pw = null;
$dsn = 'sqlite:' . __DIR__ . '/../../db/articles.db';
return new PDO($dsn, $user, $pw);
} catch (PDOException $e) {
throw new InternalServerErrorException($e->getMessage());
}
}
/**
* Gibt die DatabaseArticleManager-Instanz zurück.
* @return DatabaseArticleManager
*/
public static function getInstance()
{
if (self::$instance == null) {
self::$instance = new DatabaseArticleManager();
}
return self::$instance;
}
public function addArticle($title, $content, $author, $category, $tags)
{
try {
$db = $this->getConnection();
$sql = "INSERT INTO articles (title, content, author, category, tags)
VALUES (:title, :content, :author, :category, :tags);";
$command = $db->prepare($sql);
if (!$command) {
throw new InternalServerErrorException("internal_error");
}
// Verknüpft die übergebenen Parameter exakt mit den SQL-Platzhaltern
$success = $command->execute([
":title" => $title,
":content" => $content,
":author" => $author,
":category" => $category,
":tags" => $tags
]);
if (!$success) {
throw new InternalServerErrorException("internal_error");
}
return intval($db->lastInsertId());
} catch (PDOException $e) {
throw new InternalServerErrorException($e->getMessage());
}
}
public function updateArticle($id, $article, $author)
{
if (empty($article)) {
throw new InternalServerErrorException("internal_error");
}
// Berechtigungsprüfung analog zur lokalen Implementierung:
if ($article->getAuthor() !== $author) {
throw new UnauthorizedAccessException("unauthorized_access");
}
try {
$db = $this->getConnection();
$sql = "UPDATE articles
SET title = :title, content = :content, author = :author, category = :category, tags = :tags
WHERE id = :id;";
$command = $db->prepare($sql);
if (!$command) {
throw new InternalServerErrorException("internal_error");
}
$success = $command->execute([
":id" => $id,
":title" => $article->getTitle(),
":content" => $article->getContent(),
":author" => $author,
":category" => $article->getCategory(),
":tags" => $article->getTags()
]);
// rowCount() prüft, ob eine Zeile mit dieser ID existierte und geändert werden konnte
if (!$success || $command->rowCount() === 0) {
// Falls die ID nicht existiert, prüfen wir, ob sie überhaupt da ist
if (!$this->getArticle($id)) {
throw new NotFoundException("missing_id");
}
}
} catch (PDOException $e) {
throw new InternalServerErrorException("internal_error");
}
}
public function deleteArticle($id, $author)
{
$article = getArticle($id);
if (empty($article)) {
throw new NotFoundException("not_found_article");
}
// Berechtigungsprüfung:
if ($article->getAuthor() !== $author) {
throw new UnauthorizedAccessException("unauthorized_access");
}
try {
$db = $this->getConnection();
$sql = "DELETE FROM articles WHERE id = :id;";
$command = $db->prepare($sql);
if (!$command) {
throw new InternalServerErrorException("internal_error");
}
if (!$command->execute([":id" => $id])) {
throw new InternalServerErrorException("internal_error");
}
} catch (PDOException $exc) {
throw new InternalServerErrorException("internal_error");
}
}
public function getArticle($id)
{
try {
$db = $this->getConnection();
$sql = "SELECT * FROM articles WHERE id = :id;";
$command = $db->prepare($sql);
if (!$command) {
throw new InternalServerErrorException("internal_error");
}
$command->execute([":id" => $id]);
$row = $command->fetch(PDO::FETCH_ASSOC);
if ($row) {
return new Article(
intval($row['id']),
$row['title'],
$row['content'],
$row['author'],
$row['category'],
$row['tags'],
$row['created']
);
}
return null;
} catch (PDOException $e) {
throw new InternalServerErrorException("internal_error");
}
}
public function getAllArticles()
{
try {
$db = $this->getConnection();
$sql = "SELECT * FROM articles;";
$command = $db->query($sql);
if (!$command) {
throw new InternalServerErrorException("internal_error");
}
$rows = $command->fetchAll(PDO::FETCH_ASSOC);
$articles = [];
foreach ($rows as $row) {
$articles[] = new Article(
intval($row['id']),
$row['title'],
$row['content'],
$row['author'],
$row['category'],
$row['tags'],
$row['created']
);
}
return $articles;
} catch (PDOException $e) {
throw new InternalServerErrorException("internal_error");
}
}
public function getArticlesByAuthor($author)
{
try {
$db = $this->getConnection();
$sql = "SELECT * FROM articles WHERE author = :author;";
$command = $db->prepare($sql);
if (!$command) {
throw new InternalServerErrorException("internal_error");
}
$command->execute([":author" => $author]);
$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']
);
}
return $filteredArticles;
} catch (PDOException $e) {
throw new InternalServerErrorException("internal_error");
}
}
public function getArticlesByCategory($category)
{
try {
$db = $this->getConnection();
$sql = "SELECT * FROM articles WHERE category = :category;";
$command = $db->prepare($sql);
if (!$command) {
throw new InternalServerErrorException("internal_error");
}
$command->execute([":category" => $category]);
$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']
);
}
return $filteredArticles;
} catch (PDOException $exc) {
throw new InternalServerErrorException("internal_error");
}
}
public function search(string $keyword): array
{
// TODO: implement search()
return [];
}
}
-26
View File
@@ -1,26 +0,0 @@
<?php
require_once "UserManagerDAO.php";
class DatabaseUserManager implements UserManagerDAO {
public function findUser($email)
{
// TODO: Implement findUser() method.
}
public function addUser($email, $vorname, $nachname, $password)
{
// TODO: Implement addUser() method.
}
public function updateUser($oldEmail, $newEmail, $vorname, $nachname, $password = null)
{
// TODO: Implement updateUser() method.
}
public function deleteUser($email)
{
// TODO: Implement deleteUser() method.
}
}
-236
View File
@@ -1,236 +0,0 @@
<?php
require_once 'ArticleManagerDAO.php';
require_once 'Article.php';
/**
* Klasse: Eine lokale Lösung des ArticleManagerDAO.
* Schreibt zunächst Daten lokal in das Verzeichnis und kann diese wieder auslesen.
*
* @author Niklas Ortmann
*/
class LocalArticleManager implements ArticleManagerDAO {
private $file;
private static $instance = null;
/**
* Konstruktor
*/
public function __construct()
{
$this->file = __DIR__ . '/../../data/articles.json';
}
/**
* Gibt die LocalArticleManager-Instanz zurück.
* @return LocalArticleManager
*/
public static function getInstance()
{
if (self::$instance == null) {
self::$instance = new LocalArticleManager();
}
return self::$instance;
}
/**
* Speichert alle Artikel/Beiträge in der Datei.
* @param $articles
* @return void
* TODO: Exceptions implementieren.
*/
public function saveArticle($articles)
{
file_put_contents(
$this->file,
json_encode($articles, JSON_PRETTY_PRINT)
);
}
public function addArticle($title, $content, $author, $category, $tags)
{
$articles = $this->getAllArticles();
$articles[] = [
"id" => count($articles)+1,
"title" => $title,
"content" => $content,
"author" => $author,
"category" => $category,
"tags" => $tags,
"creationDate" => date("Y-m-d H:i:s")
];
$this->saveArticle($articles);
}
public function updateArticle($id, $article, $author)
{
if (empty($article)) {
throw new NotFoundException("not_found_article");
}
// Berechtigungsprüfung:
if ($article->getAuthor() !== $author) {
throw new UnauthorizedAccessException("unauthorized_access");
}
// Beitrag aktualisieren:
$articles = $this->getAllArticles();
$updated = false;
foreach ($articles as $index => $storedArticle) {
if (isset($storedArticle['id']) && $storedArticle['id'] == $id) {
$articles[$index] = [
"id" => $id,
"title" => $article->getTitle(),
"content" => $article->getContent(),
"author" => $author,
"category" => $article->getCategory(),
"tags" => $article->getTags(),
"creationDate" => $article->getCreationDate()
];
$updated = true;
break;
}
}
// Nur speichern, wenn Beitrag geändert wurde:
if ($updated) {
$this->saveArticle($articles);
} else {
throw new NotFoundException("missing_id");
}
}
public function deleteArticle($id, $author)
{
$article = getArticle($id);
if (empty($article)) {
throw new NotFoundException("not_found_article");
}
// Berechtigungsprüfung:
if ($article->getAuthor() !== $author) {
throw new UnauthorizedAccessException("unauthorized_access");
}
$articles = $this->getAllArticles();
$articleFound = false;
foreach ($articles as $index => $article) {
if (isset($article['id']) && $article['id'] == $id) {
unset($articles[$index]);
$articleFound = true;
break; // Schleife abbrechen, da die ID eindeutig ist
}
}
if ($articleFound) {
// array_values stellt sicher, dass die Array-Keys wieder fortlaufend bei 0 beginnen
$this->saveArticle(array_values($articles));
}
}
public function getArticle($id)
{
$articles = $this->getAllArticles();
foreach ($articles as $article) {
if (isset($article['id']) && $article['id'] == $id) {
return new Article(intval($article['id']), $article['title'], $article['content'], $article['author'], $article['category'], $article['tags'], $article['creationDate']);
}
}
return null;
}
public function getAllArticles(): array
{
if (!file_exists($this->file)) {
return [];
}
$json = file_get_contents($this->file);
$articles = json_decode($json, true);
return is_array($articles) ? $articles : [];
}
public function getArticlesByAuthor($author)
{
$articles = $this->getAllArticles();
$filteredArticles = [];
foreach ($articles as $article) {
if (isset($article['author']) && $article['author'] == $author) {
$filteredArticles[] = new Article(
intval($article['id']),
$article['title'],
$article['content'],
$article['author'],
$article['category'],
$article['tags'],
$article['creationDate']
);
}
}
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;
}
}
?>
-185
View File
@@ -1,185 +0,0 @@
<?php
require_once "UserManagerDAO.php";
class LocalUserManager implements UserManagerDAO {
private string $file = "data/users.json";
public static function getInstance(){
// TODO: implement the getIsntance method.
}
/**
* 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 [];
}
$json = file_get_contents($this->file);
if ($json === false) {
throw new RuntimeException("Benutzerdaten konnten nicht gelesen werden.");
}
$users = json_decode($json, true);
if ($users === null && json_last_error() !== JSON_ERROR_NONE) {
throw new RuntimeException("Benutzerdaten sind fehlerhaft.");
}
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) {
$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.");
}
}
/**
* 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) {
$users = $this->loadUsers();
foreach ($users as $user) {
if (isset($user["email"]) && $user["email"] === $email) {
if (!isset($user["vorname"]) && isset($user["username"])) {
$nameParts = explode(" ", $user["username"], 2);
$user["vorname"] = $nameParts[0] ?? "";
$user["nachname"] = $nameParts[1] ?? "";
}
return $user;
}
}
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) {
$users = $this->loadUsers();
foreach ($users as $user) {
if (isset($user["email"]) && $user["email"] === $email) {
throw new InvalidArgumentException("Diese E-Mail-Adresse wird bereits verwendet.");
}
}
$users[] = [
"email" => $email,
"vorname" => $vorname,
"nachname" => $nachname,
"password" => $password
];
$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) {
$users = $this->loadUsers();
foreach ($users as $user) {
if (
isset($user["email"])
&& $user["email"] === $newEmail
&& $newEmail !== $oldEmail
) {
throw new InvalidArgumentException("Diese E-Mail-Adresse wird bereits verwendet.");
}
}
foreach ($users as $i => $user) {
if (isset($user["email"]) && $user["email"] === $oldEmail) {
$users[$i]["email"] = $newEmail;
$users[$i]["vorname"] = $vorname;
$users[$i]["nachname"] = $nachname;
unset($users[$i]["username"]);
if (!empty($password)) {
$users[$i]["password"] = password_hash($password, PASSWORD_DEFAULT);
}
$this->saveUsers($users);
return true;
}
}
return false;
}
/**
* Löscht einen Benutzer anhand seiner E-Mail-Adresse.
*
* TODO: wenn ein Benutzer gelöscht wird, sollten dann auch seine Beiträge gelöscht werden?
*
* @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) {
$users = $this->loadUsers();
foreach ($users as $i => $user) {
if (isset($user["email"]) && $user["email"] === $email) {
unset($users[$i]);
$users = array_values($users);
$this->saveUsers($users);
return true;
}
}
return false;
}
}
-10
View File
@@ -1,10 +0,0 @@
<?php
require_once "UserManagerDAO.php";
class UserManager extends LocalUserManager{
public static function getInstance(){
// TODO: implement this.
// TODO: dummy-user anlegen: - `max.mustermann, test123, mustermann@web.de` (analog zu ArticleManager)
}
}
-89
View File
@@ -1,89 +0,0 @@
<?php
/**
* Interface für den Zugriff auf Benutzerdaten.
*
* Definiert die Methoden, die jede UserDAO-Implementierung
* bereitstellen muss.
*/
interface UserManagerDAO {
/**
* Sucht einen Benutzer anhand seiner E-Mail-Adresse.
*
* Funktion:
* Liefert die gespeicherten Benutzerdaten zu einer E-Mail-Adresse.
*
* Eingabe:
* @param string $email E-Mail-Adresse des gesuchten Benutzers
*
* Ausgabe:
* @return array|null Benutzerdaten als Array oder null
*
* Mögliche Fehler:
* @throws RuntimeException wenn die Benutzerdaten nicht gelesen werden können
*/
public function findUser($email);
/**
* Fügt einen neuen Benutzer hinzu.
*
* Funktion:
* Erstellt einen neuen Benutzereintrag und speichert ihn
* in der jeweiligen Datenquelle.
*
* Eingabe:
* @param string $email E-Mail-Adresse des Benutzers
* @param string $vorname Vorname des Benutzers
* @param string $nachname Nachname des Benutzers
* @param string $password Passwort des Benutzers
*
* Ausgabe:
* @return void
*
* Mögliche Fehler:
* @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);
/**
* Aktualisiert einen bestehenden Benutzer.
*
* Funktion:
* Ändert die E-Mail-Adresse, den Vornamen, den Nachnamen
* und optional das Passwort eines bestehenden Benutzers.
*
* Eingabe:
* @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
*
* Ausgabe:
* @return bool true, wenn der Benutzer aktualisiert wurde, sonst false
*
* Mögliche Fehler:
* @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);
/**
* Löscht einen Benutzer anhand seiner E-Mail-Adresse.
*
* Funktion:
* Entfernt einen vorhandenen Benutzer aus der Datenquelle.
*
* Eingabe:
* @param string $email E-Mail-Adresse des zu löschenden Benutzers
*
* Ausgabe:
* @return bool true, wenn der Benutzer gelöscht wurde, sonst false
*
* Mögliche Fehler:
* @throws RuntimeException wenn die Benutzerdaten nicht gelesen oder gespeichert werden können
*/
public function deleteUser($email);
}
-107
View File
@@ -1,107 +0,0 @@
<?php
/**
* Prüft, ob der Autor auch der Eigentümer des Beitrags ist.
* @param $author
* @return true
* TODO: Implement this.
*/
function articleAuthorValidator($author)
{
return true;
}
/**
* Prüft, ob der Titel die folgenden Bedingungen erfüllt:
* Buchstaben von a-z; A-Z
* Zahlen von 0-9
* Umlaute äöüÄÖÜß
* Satzeichen .,!?:;()"„“«»_+-
* 5-120 Zeichen
* @param $title
* @return bool
*/
function articleTitleValidator($title)
{
$title = trim($title);
$titlePattern = '/^[a-zA-Z0-9äöüÄÖÜß\s.,!?:;()\'"„“«»_+-]{5,120}$/u';
if (preg_match($titlePattern, $title)) {
return true;
} else {
return false;
}
}
/**
* Prüft, ob der Contenttext 10-7000 Zeichen enthält.
* @param $content
* @return bool
*/
function articleContentValidator($content)
{
$content = trim($content);
$zeichenAnzahl = mb_strlen($content);
if ($zeichenAnzahl <= 7000 && $zeichenAnzahl >= 10) {
return true;
}else{
return false;
}
}
/**
* Prüft, ob die Kategorie eine erlaubt Kategorie ist.
* @param $category
* @return bool
*/
function articleCategoryValidator($category)
{
$allowedCategories = [
'deutsch', 'englisch', 'franzoesisch', 'latein', 'literatur',
'mathe', 'biologie', 'chemie', 'physik', 'informatik', 'astronomie',
'geschichte', 'erdkunde', 'sozialkunde', 'wirtschaft', 'religion',
'ethik', 'philosophie', 'psychologie', 'kunst', 'musik', 'theater',
'technik', 'werken', 'hauswirtschaft', 'sport'
];
if (in_array($category, $allowedCategories, true)) {
return true;
} else {
return false;
}
}
/**
* Prüft, ob die Tags die folgenden Bedingungen erfüllen:
* Buchstaben von a-z; A-Z
* Zahlen von 0-9
* Umlaute äöüÄÖÜß
* Satzeichen -
* 2-50 Zeichen
* @param $tags
* @return bool
*/
function articleTagValidator($tags)
{
if (!isset($tags)) {
$tags = '';
}
$rawTags = explode(',', $tags);
foreach ($rawTags as $rawTag) {
// Leerzeichen am Anfang/Ende des einzelnen Tags entfernen:
$tag = trim($rawTag);
// leere Elemente überspringen:
if ($tag === '') {
continue;
}
// Tag mit Regex prüfen:
$tagPattern = '/^[a-zA-Z0-9äöüÄÖÜß\s-]{2,50}$/u';
if (!preg_match($tagPattern, $tag)) {
return false;
}
}
return true;
}
?>
-33
View File
@@ -1,33 +0,0 @@
<?php
function userNameValidator($name)
{
$name = trim($name);
$namePattern = '/^[a-zA-ZäöüÄÖÜß\s-]{2,50}$/u';
return preg_match($namePattern, $name) === 1;
}
function userEmailValidator($email)
{
$email = trim($email);
return filter_var($email, FILTER_VALIDATE_EMAIL) !== false
&& mb_strlen($email) <= 100;
}
function userPasswordValidator($password)
{
$zeichenAnzahl = mb_strlen($password);
return $zeichenAnzahl >= 8 && $zeichenAnzahl <= 72;
}
function userOptionalPasswordValidator($password)
{
if (!isset($password) || $password === '') {
return true;
}
return userPasswordValidator($password);
}
+56
View File
@@ -0,0 +1,56 @@
<?php
// Webhook: erfasst einen push auf dem dev (und aktualisiert das Webverzeichnis des Servers)
// Quelle: https://docs.gitea.com/usage/webhooks
ini_set('error_log', __DIR__ . '/tmp.log');
$secret_key = '763489347';
// check for POST request
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
error_log('FAILED - not POST - '. $_SERVER['REQUEST_METHOD']);
exit();
}
// get content type
$content_type = isset($_SERVER['CONTENT_TYPE']) ? strtolower(trim($_SERVER['CONTENT_TYPE'])) : '';
if ($content_type != 'application/json') {
error_log('FAILED - not application/json - '. $content_type);
exit();
}
// get payload
$payload = trim(file_get_contents("php://input"));
if (empty($payload)) {
error_log('FAILED - no payload');
exit();
}
// get header signature
$header_signature = isset($_SERVER['HTTP_X_GITEA_SIGNATURE']) ? $_SERVER['HTTP_X_GITEA_SIGNATURE'] : '';
if (empty($header_signature)) {
error_log('FAILED - header signature missing');
exit();
}
// calculate payload signature
$payload_signature = hash_hmac('sha256', $payload, $secret_key, false);
// check payload signature against header signature
if ($header_signature !== $payload_signature) {
error_log('FAILED - payload signature');
exit();
}
// convert json to array
$decoded = json_decode($payload, true);
// check for json decode errors
if (json_last_error() !== JSON_ERROR_NONE) {
error_log('FAILED - json decode - '. json_last_error());
exit();
}
// success, do something
error_log('SUCCESS - Webhook hat funktioniert');