28 Commits

Author SHA1 Message Date
e68c86c93e Merge branch 'frontendBackendFinal' of https://git.bib.de/PBBFA23CSE/Bib-Arts into frontendBackendFinal 2025-07-07 14:38:36 +02:00
a9997b3c63 Registrierung und Login aufgeräumt: Felder und Fehler angepasst, Formulardaten bleiben bei Fehlern erhalten, Navigation zeigt jetzt nur noch passende Links je nach Login-Status, Passwort-Fehler verständlich auf Deutsch. Alles einheitlich und benutzerfreundlich gemacht! 2025-07-07 14:31:32 +02:00
9ce7a6cfd3 fixed infos 2025-07-07 14:26:26 +02:00
ca757d1723 Merge branch 'frontendBackendFinal' of https://git.bib.de/PBBFA23CSE/Bib-Arts into frontendBackendFinal 2025-07-07 14:22:53 +02:00
717d361dbb showNews angebindet und zum laufen gebracht. 2025-07-07 14:19:52 +02:00
404e846418 logout von form zu button mit get request geändert 2025-07-07 12:46:49 +02:00
3ce61ace17 "Zwischen-Views" erstellt für Weiterleitung nach Login/Logout. Views einheitlich im div container class="inhalt". Error message nach fehlerhaftem login. 2025-07-07 12:43:25 +02:00
3dc68dd0bc forgot pw try to fix 2025-07-07 11:24:11 +02:00
b9fc6bcdd5 fixed Registration 2025-07-07 11:20:57 +02:00
a50b48592b fixed event 2025-07-07 11:15:49 +02:00
1691370db6 Merge branch 'frontendBackendFinal' of https://git.bib.de/PBBFA23CSE/Bib-Arts into frontendBackendFinal 2025-07-07 11:04:31 +02:00
a6b672ee7e Refactor Controller and models anhand der bibarts.sql und unbrauchbare Controllers und Models entfernt. 2025-07-07 11:03:59 +02:00
97c03d817e Initiales .sql script angepasst 2025-07-07 11:03:51 +02:00
877be4e567 Login Form updated 2025-07-07 11:01:54 +02:00
ef3349c6e4 fixed login and register with right linktos 2025-07-07 10:42:58 +02:00
415d8120e5 AuthController hinzugefügt 2025-07-07 10:35:49 +02:00
a4eef4e4e3 AuthController und methoden hinzugefügt. 2025-07-07 10:34:37 +02:00
37ee931954 Merge branch 'backend' into frontendBackendFinal 2025-07-07 10:06:42 +02:00
cbd7b0f8cc Spaltennamen angepasst 2025-06-30 10:13:36 +02:00
db1b26f017 Merge remote-tracking branch 'refs/remotes/origin/frontend' into frontendbackendtest 2025-06-30 10:00:17 +02:00
d8865cbd27 Controller und Tickets vereinheitlicht (CRUD) 2025-06-23 14:46:12 +02:00
66ff531ba4 Tickets erweitert 2025-06-23 11:11:18 +02:00
1964cadd8c Standardmethoden für Standort und News.Events erweitert 2025-06-23 11:10:46 +02:00
6e3e3708b2 EventController, TicketController + Model + essenzielle Funktionen 2025-06-16 15:12:03 +02:00
5bde268b89 Merge remote-tracking branch 'origin/develop' into develop 2025-06-12 16:30:43 +02:00
5cef69ae81 added database creation sql with test data karsten kann nicht coden 2025-06-12 16:29:00 +02:00
f3699cb287 Added .gitignore 2025-06-12 16:27:03 +02:00
1f8e7dc67b Test 2025-06-12 16:24:31 +02:00
42 changed files with 1810 additions and 307 deletions

193
.gitignore vendored Normal file
View File

@@ -0,0 +1,193 @@
# Created by https://www.toptal.com/developers/gitignore/api/intellij,windows,macos,git
# Edit at https://www.toptal.com/developers/gitignore?templates=intellij,windows,macos,git
### Git ###
# Created by git for backups. To disable backups in Git:
# $ git config --global mergetool.keepBackup false
*.orig
# Created by git when using merge tools for conflicts
*.BACKUP.*
*.BASE.*
*.LOCAL.*
*.REMOTE.*
*_BACKUP_*.txt
*_BASE_*.txt
*_LOCAL_*.txt
*_REMOTE_*.txt
### Intellij ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff
.idea/**/workspace.xml
.idea/encodings.xml
.idea/php.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
# AWS User-specific
.idea/**/aws.xml
# Generated files
.idea/**/contentModel.xml
# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml
# Gradle
.idea/**/gradle.xml
.idea/**/libraries
# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/artifacts
# .idea/compiler.xml
# .idea/jarRepositories.xml
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# *.iml
# *.ipr
# CMake
cmake-build-*/
# Mongo Explorer plugin
.idea/**/mongoSettings.xml
# File-based project format
*.iws
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# SonarLint plugin
.idea/sonarlint/
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
# Editor-based Rest Client
.idea/httpRequests
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser
### Intellij Patch ###
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
# *.iml
# modules.xml
# .idea/misc.xml
# *.ipr
# Sonarlint plugin
# https://plugins.jetbrains.com/plugin/7973-sonarlint
.idea/**/sonarlint/
# SonarQube Plugin
# https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin
.idea/**/sonarIssues.xml
# Markdown Navigator plugin
# https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced
.idea/**/markdown-navigator.xml
.idea/**/markdown-navigator-enh.xml
.idea/**/markdown-navigator/
# Cache file creation bug
# See https://youtrack.jetbrains.com/issue/JBR-2257
.idea/$CACHE_FILE$
# CodeStream plugin
# https://plugins.jetbrains.com/plugin/12206-codestream
.idea/codestream.xml
# Azure Toolkit for IntelliJ plugin
# https://plugins.jetbrains.com/plugin/8053-azure-toolkit-for-intellij
.idea/**/azureSettings.xml
### macOS ###
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
### macOS Patch ###
# iCloud generated files
*.icloud
### Windows ###
# Windows thumbnail cache files
Thumbs.db
Thumbs.db:encryptable
ehthumbs.db
ehthumbs_vista.db
# Dump file
*.stackdump
# Folder config file
[Dd]esktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp
# Windows shortcuts
*.lnk
# End of https://www.toptal.com/developers/gitignore/api/intellij,windows,macos,git

6
.idea/sqldialects.xml generated
View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="SqlDialectMappings">
<file url="file://$PROJECT_DIR$/contact.sql" dialect="GenericSQL" />
</component>
</project>

View File

@@ -150,32 +150,63 @@ a {
border-radius: 10px;
}
.login-container {
position: absolute;
top: 200px;
.form-container {
background-color: #BAC8D4;
width: 900px;
height: 450px;
width: 100%;
max-width: 400px;
border-radius: 10px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
box-sizing: border-box;
padding: 32px 24px 24px 24px;
margin: 32px auto;
}
.tickets-container {
position: absolute;
top: 200px;
background-color: #BAC8D4;
width: 900px;
height: 450px;
border-radius: 10px;
.form-horizontal {
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 12px;
margin-bottom: 10px;
}
.form-horizontal label {
margin-bottom: 2px;
}
.form-horizontal input[type="text"],
.form-horizontal input[type="email"],
.form-horizontal input[type="password"] {
width: 100%;
padding: 8px 10px;
border: 1px solid #BAC8D4;
border-radius: 4px;
font-size: 1rem;
box-sizing: border-box;
background: #fff;
}
.form-horizontal button {
width: 100%;
padding: 10px 0;
border: none;
border-radius: 4px;
background: #4d4d4d;
color: #fff;
font-size: 1rem;
margin-top: 8px;
cursor: pointer;
transition: background 0.2s;
}
.form-horizontal button:hover {
background: #333;
}
.login-error, .form-error {
background: #ffe0e0;
color: #b30000;
border: 1px solid #ffb3b3;
border-radius: 6px;
padding: 10px 16px;
margin-bottom: 18px;
width: 100%;
text-align: center;
}
@media (max-width: 600px) {
@@ -297,7 +328,7 @@ a {
padding: 16px 8px;
box-sizing: border-box;
}
.tickets-container {
.event-container {
position: static;
width: 95vw;
max-width: 400px;
@@ -310,7 +341,7 @@ a {
font-size: 1.5em;
text-align: center;
}
.tickets-container h1 {
.event-container h1 {
font-size: 1.5em;
text-align: center;
}

View File

@@ -0,0 +1,150 @@
<?php
namespace Blog\Controller;
use Blog\Model\AuthModel;
class AuthController
{
private $model;
private $view;
public function __construct($view) {
$this->model = new AuthModel();
$this->view = $view;
}
public function showLoginForm() {
$this->view->setVars([
'labels' => [
"email" => "E-Mail-Adresse",
"password" => "Passwort",
"password_repeat" => "Passwort wiederholen",
"old_password" => "Altes Passwort"
],
'errors' => $_SESSION['auth_errors'] ?? [],
'validData' => $_SESSION['auth_validData'] ?? []
]);
unset($_SESSION['auth_errors'], $_SESSION['auth_validData']);
}
public function showRegistrationForm() {
$this->view->setVars([
'labels' => [
"email" => "E-Mail-Adresse",
"password" => "Passwort",
"password_repeat" => "Passwort wiederholen",
"old_password" => "Altes Passwort"
],
'errors' => $_SESSION['auth_errors'] ?? [],
'validData' => $_SESSION['auth_validData'] ?? []
]);
unset($_SESSION['auth_errors'], $_SESSION['auth_validData']);
}
public function login() {
$email = $_POST['email'];
$password = $_POST['password'];
$result = $this->model->login($email, $password);
if ($result === true) {
$_SESSION['user'] = $email;
$this->view->setDoMethodName('showLoginSuccess');
} else {
$this->view->setVars([
'errors' => ['login' => is_string($result) ? $result : "Login fehlgeschlagen."],
'validData' => ['email' => $email],
'loginSuccess' => false
]);
$this->view->setDoMethodName('showLoginForm');
}
}
public function register() {
$data = [
'first_name' => $_POST['first_name'] ?? '',
'last_name' => $_POST['last_name'] ?? '',
'street' => $_POST['street'] ?? '',
'house_number' => $_POST['house_number'] ?? '',
'postal_code' => $_POST['postal_code'] ?? '',
'city' => $_POST['city'] ?? '',
'country' => $_POST['country'] ?? '',
'phone' => $_POST['phone'] ?? '',
'email' => $_POST['email'] ?? '',
'password' => $_POST['password'] ?? '',
'password_repeat' => $_POST['password_repeat'] ?? '',
'is_admin' => $_POST['isAdmin'] ?? false,
];
$result = $this->model->register($data);
if ($result === true) {
$this->view->setDoMethodName('showRegistrationSuccess');
} else {
if (is_array($result)) {
$errors['register'] = implode('<br>', $result);
} else {
$errors['register'] = is_string($result) ? $result : "Registrierung fehlgeschlagen.";
}
$this->view->setVars(['errors' => $errors, 'validData' => $data]);
$this->view->setDoMethodName('showRegistrationForm');
}
}
public function forgotPassword() {
$email = $_POST['email'] ?? '';
if (empty($email)) {
$_SESSION['auth_errors']['email'] = "Bitte E-Mail-Adresse angeben.";
header("Location: /?controller=Auth&do=showAuthForm");
exit;
}
$this->model->pwForgot($email);
header("Location: /?controller=Auth&do=showConfirmation&msg=pwforgot");
exit;
}
public function changePassword()
{
$email = $_POST['email'] ?? '';
$oldpw = $_POST['old_password'] ?? '';
$newpw = $_POST['password'] ?? '';
$repeat = $_POST['password_repeat'] ?? '';
if (!$this->model->checkDoublePw($newpw, $repeat)) {
$_SESSION['auth_errors']['password'] = "Neue Passwörter stimmen nicht überein.";
header("Location: /?controller=Auth&do=showAuthForm");
exit;
}
$result = $this->model->updatePassword($email, $oldpw, $newpw);
if ($result === true) {
header("Location: /?controller=Auth&do=showConfirmation&msg=pwchange");
exit;
} else {
$_SESSION['auth_errors']['password'] = is_string($result) ? $result : "Fehler beim Aktualisieren des Passworts.";
header("Location: /?controller=Auth&do=showAuthForm");
exit;
}
}
public function showConfirmation() {
$messages = [
'login' => "Login erfolgreich.",
'register' => "Registrierung erfolgreich.",
'pwforgot' => "Ein temporäres Passwort wurde an Ihre E-Mail gesendet.",
'pwchange' => "Passwort erfolgreich geändert."
];
$msgKey = $_GET['msg'] ?? '';
$message = $messages[$msgKey] ?? "Aktion erfolgreich.";
$this->view->setVars(['message' => $message]);
$this->view->render('auth/confirmation');
}
public function logout() {
unset($_SESSION['user']);
session_destroy();
$this->view->setDoMethodName('showLogoutSuccess');
}
}

View File

@@ -1,56 +0,0 @@
<?php
namespace Blog\Controller;
use Blog\Model\ContactModel;
class ContactController
{
protected $view;
private $db;
private $validData = array();
private $errors = array();
private $labels = array("name" => "Name", "email" => "E-Mail-Adresse", "content" => "Nachricht");
public function __construct($view)
{
$this->db = new ContactModel();
$this->view = $view;
}
public function showContactForm()
{
$this->view->setVars([
'labels' => $this->labels,
'validData' => $this->validData,
'errors' => $this->errors
]);
}
public function showConfirmation()
{
}
public function validateForm(){
foreach ($this->labels as $index => $value) {
if (!isset($_POST[$index]) || empty($_POST[$index])) {
$this->errors[$index] = "Bitte " . $value . " angeben";
} else {
$this->validData[$index] = $_POST[$index];
}
}
if (count($this->errors) > 0) {
$this->view->setDoMethodName("showContactForm");
$this->showContactForm();
} else {
if ($this->db->writeContactData($this->validData)) {
$this->view->setDoMethodName("showConfirmation");
$this->showConfirmation();
}
}
}
}
?>

View File

@@ -0,0 +1,64 @@
<?php
namespace Blog\Controller;
use Blog\Model\EventModel;
class EventController {
private $model;
private $view;
public function __construct($view) {
$this->model = new EventModel();
$this->view = $view;
}
public function showEvents() {
$events = $this->model->getEvents();
$this->view->setVars([
'events' => $events
]);
}
public function createEvent() {
$data = [
'name' => $_POST['name'] ?? null,
'beschreibung' => $_POST['beschreibung'] ?? null,
'standortid' => $_POST['standortid'] ?? null,
'datum_von' => $_POST['datum_von'] ?? null,
'datum_bis' => $_POST['datum_bis'] ?? null,
'max_tickets' => $_POST['max_tickets'] ?? null,
'preis' => $_POST['preis'] ?? null
];
$this->model->createEvent($data);
$this->view->setVars(['event' => $data]);
exit;
}
public function editEventForm() {
$id = $_GET['ausstellungid'];
$event = $this->model->getEvent($id);
$this->view->setVars(['event' => $event]);
}
public function updateEvent($id, $data) {
$id = $_POST['ausstellungid'];
$data = [
'standortid' => $_POST['standortid'] ?? null,
'datum_von' => $_POST['datum_von'] ?? null,
'datum_bis' => $_POST['datum_bis'] ?? null,
'name' => $_POST['name'] ?? null,
'beschreibung' => $_POST['beschreibung'] ?? null,
'max_tickets' => $_POST['max_tickets'] ?? null,
'preis' => $_POST['preis'] ?? null
];
$this->model->updateEvent($id, $data);
}
public function deleteEvent($id) {
$this->model->deleteEvent($id);
$this->view->setVars(['id' => $id]);
}
}

View File

@@ -0,0 +1,57 @@
<?php
namespace Blog\Controller;
use Blog\Model\GutscheinModel;
class GutscheinController {
private $model;
private $view;
public function __construct($view) {
$this->model = new GutscheinModel();
$this->view = $view;
}
public function showGutscheine() {
$gutscheine = $this->model->getGutscheine();
$this->view->setVars(['gutscheine' => $gutscheine]);
}
public function createGutschein() {
$data = [
'code' => $_POST['code'] ?? null,
'rabatt' => $_POST['rabatt'] ?? null,
'eventid' => $_POST['eventid'] ?? null,
'gültigkeit' => $_POST['gültigkeit'] ?? null
];
$erg = $this->model->createGutschein($data);
$this->view->setVars(['gutschein' => $erg]);
exit;
}
public function editGutscheinForm() {
$id = $_GET['gutscheinid'];
if ($id) {
$gutschein = $this->model->getGutschein($id);
$this->view->setVars(['gutschein' => $gutschein]);
}
}
public function updateGutschein() {
$id = $_POST['gutscheinid'];
$data = [
'code' => $_POST['code'] ?? null,
'rabatt' => $_POST['rabatt'] ?? null,
'eventid' => $_POST['eventid'] ?? null,
'gültigkeit' => $_POST['gültigkeit'] ?? null
];
$this->model->updateGutschein($id, $data);
}
public function deleteGutschein() {
$id = $_GET['gutscheinid'] ?? null;
$this->model->deleteGutschein($id);
}
}

View File

@@ -1,12 +0,0 @@
<?php
namespace Blog\Controller;
class LoginController {
function showLoginPage(){
}
function showPasswortVergessen(){
}
}

View File

@@ -0,0 +1,53 @@
<?php
namespace Blog\Controller;
use Blog\Model\NewsModel;
class NewsController {
private $model;
private $view;
public function __construct($view) {
$this->model = new NewsModel();
$this->view = $view;
}
public function showNews() {
$news = $this->model->getNews();
$this->view->setVars(['news' => $news]);
}
public function createNews() {
$data = [
'name' => $_POST['name'],
'beschreibung' => $_POST['beschreibung'],
'datum' => $_POST['datum'],
];
$erg = $this->model->createNews($data);
$this->view->setVars(['news' => $erg]);
exit;
}
public function editNewsForm() {
$id = $_GET['newsid'];
$news = $this->model->getNewsById($id);
$this->view->setVars(['news' => $news]);
}
public function updateNews() {
$id = $_POST['newsid'] ?? null;
$data = [
'name' => $_POST['name'],
'beschreibung' => $_POST['beschreibung'],
'datum' => $_POST['datum'],
];
$this->model->updateNews($id, $data);
}
public function deleteNews() {
$id = $_GET['newsid'] ?? null;
$this->model->deleteNews($id);
}
}

View File

@@ -1,10 +0,0 @@
<?php
namespace Blog\Controller;
class RegisterController {
function showRegisterPage()
{
}
}

View File

@@ -0,0 +1,61 @@
<?php
namespace Blog\Controller;
use Blog\Model\StandortModel;
class StandortController {
private $model;
private $view;
public function __construct($view) {
$this->model = new StandortModel();
$this->view = $view;
}
public function showStandorte() {
$standorte = $this->model->getStandorte();
$this->view->setVars(['standorte' => $standorte]);
}
public function createStandort() {
$data = [
'straße' => $_POST['straße'],
'hausnr' => $_POST['hausnr'],
'postleitzahl' => $_POST['postleitzahl'],
'ort' => $_POST['ort'],
'land' => $_POST['land'],
'tel' => $_POST['tel'],
'email' => $_POST['email']
];
$erg = $this->model->createStandort($data);
$this->view->setVars(['standort' => $erg]);
}
public function editStandortForm() {
$id = $_GET['standortid'];
$standort = $this->model->getStandort($id);
$this->view->setVars(['standort' => $standort]);
}
public function updateStandort() {
$id = $_POST['standortid'];
$data = [
'straße' => $_POST['straße'],
'hausnr' => $_POST['hausnr'],
'postleitzahl' => $_POST['postleitzahl'],
'ort' => $_POST['ort'],
'land' => $_POST['land'],
'tel' => $_POST['tel'],
'email' => $_POST['email']
];
$erg = $this->model->updateStandort($id, $data);
$this->view->setVars(['standort' => $erg]);
}
public function deleteStandort() {
$id = $_GET['standortid'] ?? null;
$this->model->deleteStandort($id);
}
}

View File

@@ -0,0 +1,39 @@
<?php
namespace Blog\Controller;
use Blog\Model\TicketModel;
class TicketController {
private $ticketModel;
private $view;
public function __construct($view) {
$this->ticketModel = new TicketModel();
$this->view = $view;
}
public function showTickets() {
$tickets = $this->ticketModel->getTickets();
$this->view->setVars(['tickets' => $tickets]);
}
public function buyTicket() {
$data = [
'userid' => $_POST['userid'],
'eventid' => $_POST['eventid'],
'kaufdatum' => date('Y-m-d'),
'gültigkeitsdatum' => $_POST['gültigkeitsdatum']
];
$erg = $this->ticketModel->buyTicket($data);
$this->view->setVars(['ticket' => $erg]);
}
public function deleteTicket() {
$ticketid = $_GET['ticketid'] ?? null;
if ($ticketid) {
$this->ticketModel->deleteTicket($ticketid);
}
}
}

View File

@@ -1,18 +0,0 @@
<?php
namespace Blog\Controller;
class WelcomeController
{
function showWelcome() {
}
function showProjects() {
}
function showTutorials() {
}
}

240
Model/AuthModel.php Normal file
View File

@@ -0,0 +1,240 @@
<?php
namespace Blog\Model;
use DateTime;
use PDO;
use PDOException;
class AuthModel extends Database
{
public function login(string $email, string $password)
{
$pdo = $this->linkDB();
$sql = "SELECT email, password, valid_until FROM user WHERE email = :email";
$params = [":email" => $email];
try {
$sth = $pdo->prepare($sql);
$sth->execute($params);
$user = $sth->fetch(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
new \Blog\Library\ErrorMsg("Fehler beim Abrufen der Benutzerdaten.", $e);
return "Interner Datenbankfehler."; // Nur für Debug sichtbar machen, sonst besser allgemein halten
}
if (!$user) {
return "Benutzer mit dieser E-Mail wurde nicht gefunden.";
}
if (!password_verify($password, $user['password'])) {
return "Das eingegebene Passwort ist falsch.";
}
try {
$now = new DateTime();
$validUntil = new DateTime($user['valid_until']);
if ($now > $validUntil) {
return "Ihr Passwort ist abgelaufen. Bitte setzen Sie ein neues über \"Passwort vergessen\".";
}
} catch (\Exception $e) {
new \Blog\Library\ErrorMsg("Fehler beim Verarbeiten des Gültigkeitsdatums.", $e);
return "Fehler bei der Passwortprüfung.";
}
return true;
}
public function register($data) {
if (!filter_var($data['email'], FILTER_VALIDATE_EMAIL)) {
return "Bitte geben Sie eine gültige E-Mail ein.";
}
$requiredFields = [
'email', 'password', 'password_repeat', 'street', 'house_number', 'city', 'postal_code',
'country', 'first_name', 'last_name', 'phone'
];
foreach ($requiredFields as $field) {
if (empty($data[$field])) {
return "Bitte füllen Sie alle Felder aus.";
}
}
if ($this->userExistsByEmail($data['email'])) {
return "Ein Account mit dieser E-Mail existiert bereits.";
}
// Passwort-Validierung
if (!$this->checkDoublePw($data['password'], $data['password_repeat'])) {
return "Passwörter stimmen nicht überein.";
}
$pwCheck = $this->pwRequirementCheck($data['password']);
if ($pwCheck !== true) {
return $pwCheck; // Array mit spezifischen Fehlern zurückgeben
}
$hashedPassword = password_hash($data['password'], PASSWORD_DEFAULT);
$sql = "INSERT INTO user (email, password, street, house_number, city, postal_code, country, first_name, last_name, phone, is_admin)
VALUES (:email, :password, :street, :house_number, :city, :postal_code, :country, :first_name, :last_name, :phone, :is_admin)";
$params = [
':email' => $data['email'],
':password' => $hashedPassword,
':street' => $data['street'],
':house_number' => $data['house_number'],
':city' => $data['city'],
':postal_code'=> $data['postal_code'],
':country'=> $data['country'],
':first_name' => $data['first_name'],
':last_name'=> $data['last_name'],
':phone' => $data['phone'],
':is_admin' => $data['is_admin'] ? 1 : 0,
];
try {
$pdo = $this->linkDB();
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
return true;
} catch (PDOException $e) {
new \Blog\Library\ErrorMsg("Fehler beim Schreiben der Daten.", $e);
return false;
}
}
private function userExistsByEmail($email) {
try {
$pdo = $this->linkDB();
$sql = "SELECT user_id FROM user WHERE email = :email";
$params = [':email' => $email];
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
return (bool) $stmt->fetch();
} catch (\PDOException $e) {
new \Blog\Library\ErrorMsg("Fehler bei der E-Mail-Prüfung", $e);
return false;
}
}
public function pwForgot($email){
$randomPw = bin2hex(random_bytes(12 / 2));
$hashedPassword = password_hash($randomPw, PASSWORD_DEFAULT);
$this->forgottenPwUpdate($email, $hashedPassword);
$betreff = "Passwort zurücksetzen bei bibArts";
$nachricht = "Hallo,\n\nhier ihr temporäres Passwort:\n\n $randomPw \n\n Bitte beachten Sie, dass das Passwort nur 2 stunden Gülltig ist. \nViele Grüße,\nbibArts Team";
$header = "From: noreply@edu.bib.de\r\n";
$header .= "Content-Type: text/plain; charset=UTF-8\r\n";
$maxTries = 5;
$try = 0;
$success = false;
while ($try < $maxTries && !$success) {
$erfolg = mail($email, $betreff, $nachricht, $header);
$try++;
if (!$erfolg) {
error_log("Mailversuch $try an $email fehlgeschlagen.");
sleep(1);
}
}
}
private function forgottenPwUpdate($email, $hashedPassword) {
try{
$pdo = $this->linkDB();
$sqlCheck = "SELECT COUNT(*) FROM user WHERE email = :email";
$stmt = $pdo->prepare($sqlCheck);
$stmt->execute([':email' => $email]);
if ($stmt->fetchColumn() == 0) {
return false;
}
$validUntil = (new DateTime())->add(new DateInterval('PT2H'))->format('Y-m-d H:i:s');
$sql = "UPDATE user
SET password = :password, valid_until = :valid_until
WHERE email = :email";
$stmt = $pdo->prepare($sql);
$params = [
':email' => $email,
':password' => $hashedPassword,
':valid_until' => $validUntil
];
return $stmt->execute($params);
} catch (PDOException $e) {
new \Blog\Library\ErrorMsg("Fehler beim Aktualisieren der Daten.", $e);
die;
return false;
}
}
public function updatePassword($email, $oldpw, $newpw){
if(!$this->login($email, $oldpw)) {
return false;
}
$requiredFields = [$email, $oldpw, $newpw];
foreach ($requiredFields as $field) {
if (empty($field)) {
return "Bitte füllen Sie alle Felder aus";
}
}
$hashedPassword = password_hash($newpw, PASSWORD_DEFAULT);
$sql = "UPDATE user SET password = :password WHERE email = :email";
try{
$pdo = $this->linkDB();
$stmt = $pdo->prepare($sql);
$params = [
':email' => $email,
':password' => $hashedPassword,
];
return $stmt->execute($params);
} catch (PDOException $e) {
new \Blog\Library\ErrorMsg("Fehler beim Schreiben der Daten.", $e);
die;
}
}
public function checkDoublePw($password1, $password2){
if($password1 === $password2){
return true;
}
else
return false;
}
public function pwRequirementCheck($password){
$error = [];
if(strlen($password) < 8)
$error[] = "Passwort: mindestens 8 Zeichen";
if(!preg_match("/[A-Z]/", $password))
$error[] = "Passwort: mindestens ein Großbuchstabe";
if(!preg_match("/[a-z]/", $password))
$error[] = "Passwort: mindestens ein Kleinbuchstabe";
if(!preg_match("/[0-9]/", $password))
$error[] = "Passwort: mindestens eine Zahl";
if(!preg_match("/[^a-zA-Z0-9\s]/", $password))
$error[] = "Passwort: mindestens ein Sonderzeichen";
if(empty($error))
return true;
else
return $error;
}
}

View File

@@ -1,31 +0,0 @@
<?php
namespace Blog\Model;
use PDOException;
class ContactModel extends Database
{
public function writeContactData($values)
{
$guid = $this->createUUID();
$sql = "INSERT INTO contact (`id`, `name`, `email`, `content`) VALUES (
:guid, :name, :email, :content);";
$pdo = $this->linkDB();
try {
$sth = $pdo->prepare($sql);
$sth->execute(array(":guid" => $guid,
":name" => $values["name"],
":email" => $values["email"],
":content" => $values["content"]));
} catch (PDOException $e) {
new \Blog\Library\ErrorMsg("Fehler beim Schreiben der Daten.", $e);
die;
}
return true;
}
}

90
Model/EventModel.php Normal file
View File

@@ -0,0 +1,90 @@
<?php
namespace Blog\Model;
use PDOException;
class EventModel extends Database {
public function getEvents() {
$pdo = $this->linkDB();
$sql = "SELECT * FROM event ORDER BY start_date DESC;";
try {
$sth = $pdo->prepare($sql);
$sth->execute();
return $sth->fetchAll(\PDO::FETCH_ASSOC);
} catch (PDOException $e) {
new \Blog\Library\ErrorMsg("Fehler beim Lesen der Events.", $e);
die;
}
}
public function getEvent($id) {
$pdo = $this->linkDB();
$sql = "SELECT * FROM event WHERE event_id = :id;";
try {
$sth = $pdo->prepare($sql);
$sth->execute([":id" => $id]);
return $sth->fetch(\PDO::FETCH_ASSOC);
} catch (PDOException $e) {
new \Blog\Library\ErrorMsg("Fehler beim Lesen des Events.", $e);
die;
}
}
public function updateEvent($id, $data) {
$pdo = $this->linkDB();
$sql = "UPDATE event SET location_id = :location_id, start_date = :start_date, end_date = :end_date, name = :name, description = :description, max_tickets = :max_tickets, ticket_price = :ticket_price WHERE event_id = :id;";
$params = [
":location_id" => $data['location_id'],
":start_date" => $data['start_date'],
":end_date" => $data['end_date'],
":name" => $data['name'],
":description" => $data['description'],
":max_tickets" => $data['max_tickets'],
":ticket_price" => $data['ticket_price'],
":id" => $id
];
try {
$sth = $pdo->prepare($sql);
$sth->execute($params);
} catch (PDOException $e) {
new \Blog\Library\ErrorMsg("Fehler beim Aktualisieren des Events.", $e);
die;
}
}
public function createEvent($data) {
$pdo = $this->linkDB();
$sql = "INSERT INTO event (location_id, start_date, end_date, name, description, max_tickets, ticket_price) VALUES (:location_id, :start_date, :end_date, :name, :description, :max_tickets, :ticket_price);";
$params = [
":location_id" => $data['location_id'],
":start_date" => $data['start_date'],
":end_date" => $data['end_date'],
":name" => $data['name'],
":description" => $data['description'],
":max_tickets" => $data['max_tickets'],
":ticket_price" => $data['ticket_price']
];
try {
$sth = $pdo->prepare($sql);
$sth->execute($params);
return $sth;
} catch (PDOException $e) {
new \Blog\Library\ErrorMsg("Fehler beim Erstellen des Events.", $e);
die;
}
}
public function deleteEvent($id) {
$pdo = $this->linkDB();
$sql = "DELETE FROM event WHERE event_id = :id;";
try {
$sth = $pdo->prepare($sql);
$sth->execute([":id" => $id]);
} catch (PDOException $e) {
new \Blog\Library\ErrorMsg("Fehler beim Löschen des Events.", $e);
die;
}
}
}

86
Model/GutscheinModel.php Normal file
View File

@@ -0,0 +1,86 @@
<?php
namespace Blog\Model;
use PDOException;
class GutscheinModel extends Database {
public function getGutscheine() {
$pdo = $this->linkDB();
$sql = "SELECT * FROM voucher ORDER BY valid_until DESC;";
try {
$sth = $pdo->prepare($sql);
$sth->execute();
return $sth->fetchAll(\PDO::FETCH_ASSOC);
} catch (PDOException $e) {
new \Blog\Library\ErrorMsg("Fehler beim Lesen der Gutscheine.", $e);
die;
}
}
public function getGutschein($id) {
$pdo = $this->linkDB();
$sql = "SELECT * FROM voucher WHERE voucher_id = :id;";
$params = [":id" => $id];
try {
$sth = $pdo->prepare($sql);
$sth->execute($params);
return $sth->fetch(\PDO::FETCH_ASSOC);
} catch (PDOException $e) {
new \Blog\Library\ErrorMsg("Fehler beim Lesen des Gutscheins.", $e);
die;
}
}
public function createGutschein($data) {
$pdo = $this->linkDB();
$sql = "INSERT INTO voucher (code, discount, event_id, valid_until) VALUES (:code, :discount, :event_id, :valid_until);";
$params = [
":code" => $data['code'],
":discount" => $data['discount'],
":event_id" => $data['event_id'],
":valid_until" => $data['valid_until']
];
try {
$sth = $pdo->prepare($sql);
$sth->execute($params);
return $sth;
} catch (PDOException $e) {
new \Blog\Library\ErrorMsg("Fehler beim Erstellen des Gutscheins.", $e);
die;
}
}
public function updateGutschein($id, $data) {
$pdo = $this->linkDB();
$sql = "UPDATE voucher SET code = :code, discount = :discount, event_id = :event_id, valid_until = :valid_until WHERE voucher_id = :id;";
$params = [
":code" => $data['code'],
":discount" => $data['discount'],
":event_id" => $data['event_id'],
":valid_until" => $data['valid_until'],
":id" => $id
];
try {
$sth = $pdo->prepare($sql);
$sth->execute($params);
} catch (PDOException $e) {
new \Blog\Library\ErrorMsg("Fehler beim Aktualisieren des Gutscheins.", $e);
die;
}
}
public function deleteGutschein($id) {
$pdo = $this->linkDB();
$sql = "DELETE FROM voucher WHERE voucher_id = :id;";
$params = [":id" => $id];
try {
$sth = $pdo->prepare($sql);
$sth->execute($params);
} catch (PDOException $e) {
new \Blog\Library\ErrorMsg("Fehler beim Löschen des Gutscheins.", $e);
die;
}
}
}

85
Model/NewsModel.php Normal file
View File

@@ -0,0 +1,85 @@
<?php
namespace Blog\Model;
use PDOException;
class NewsModel extends Database {
public function getNewsById($newsId) {
$pdo = $this->linkDB();
$sql = "SELECT * FROM news WHERE news_id = :news_id;";
$params = [":news_id" => $newsId];
try {
$sth = $pdo->prepare($sql);
$sth->execute($params);
return $sth->fetch(\PDO::FETCH_ASSOC);
} catch (PDOException $e) {
new \Blog\Library\ErrorMsg("Fehler beim Lesen der News.", $e);
die;
}
}
public function updateNews($newsId, $news) {
$pdo = $this->linkDB();
$sql = "UPDATE news SET name = :name, description = :description, date = :date WHERE news_id = :news_id;";
$params = [
":name" => $news['titel'],
":description" => $news['inhalt'],
":date" => $news['datum'],
":news_id" => $newsId
];
try {
$sth = $pdo->prepare($sql);
$sth->execute($params);
return $sth;
} catch (PDOException $e) {
new \Blog\Library\ErrorMsg("Fehler beim Aktualisieren der News.", $e);
die;
}
}
public function getNews() {
$pdo = $this->linkDB();
$sql = "SELECT * FROM news ORDER BY date DESC;";
try {
$sth = $pdo->prepare($sql);
$sth->execute();
return $sth->fetchAll(\PDO::FETCH_ASSOC);
} catch (PDOException $e) {
new \Blog\Library\ErrorMsg("Fehler beim Lesen der News.", $e);
die;
}
}
public function createNews($news) {
$pdo = $this->linkDB();
$sql = "INSERT INTO news (name, description, date) VALUES (:name, :description, :date);";
$params = [
":name" => $news['titel'],
":description" => $news['inhalt'],
":date" => $news['datum']
];
try {
$sth = $pdo->prepare($sql);
$sth->execute($params);
return $sth;
} catch (PDOException $e) {
new \Blog\Library\ErrorMsg("Fehler beim Schreiben der News.", $e);
die;
}
}
public function deleteNews($newsId) {
$pdo = $this->linkDB();
$sql = "DELETE FROM news WHERE news_id = :news_id;";
$params = [":news_id" => $newsId];
try {
$sth = $pdo->prepare($sql);
$sth->execute($params);
} catch (PDOException $e) {
new \Blog\Library\ErrorMsg("Fehler beim Löschen der News.", $e);
die;
}
}
}

103
Model/StandortModel.php Normal file
View File

@@ -0,0 +1,103 @@
<?php
namespace Blog\Model;
use PDOException;
class StandortModel extends Database {
public function getStandorte() {
$pdo = $this->linkDB();
$sql = "SELECT * FROM location ORDER BY location_id ASC;";
try {
$sth = $pdo->prepare($sql);
$sth->execute();
return $sth->fetchAll(\PDO::FETCH_ASSOC);
} catch (PDOException $e) {
new \Blog\Library\ErrorMsg("Fehler beim Lesen der Standorte.", $e);
die;
}
}
public function getStandort($location_id) {
$pdo = $this->linkDB();
$sql = "SELECT * FROM location WHERE location_id = :location_id;";
$params = [":location_id" => $location_id];
try {
$sth = $pdo->prepare($sql);
$sth->execute($params);
return $sth->fetch(\PDO::FETCH_ASSOC);
} catch (PDOException $e) {
new \Blog\Library\ErrorMsg("Fehler beim Lesen des Standorts.", $e);
die;
}
}
public function createStandort($data) {
$pdo = $this->linkDB();
$sql = "INSERT INTO location (street, house_number, postal_code, city, country, phone, email)
VALUES (:street, :house_number, :postal_code, :city, :country, :phone, :email);";
$params = [
":street" => $data['street'],
":house_number" => $data['house_number'],
":postal_code" => $data['postal_code'],
":city" => $data['city'],
":country" => $data['country'],
":phone" => $data['phone'],
":email" => $data['email']
];
try {
$sth = $pdo->prepare($sql);
$sth->execute($params);
return $pdo->lastInsertId();
} catch (PDOException $e) {
new \Blog\Library\ErrorMsg("Fehler beim Anlegen des Standorts.", $e);
die;
}
}
public function updateStandort($location_id, $data) {
$pdo = $this->linkDB();
$sql = "UPDATE location SET
street = :street,
house_number = :house_number,
postal_code = :postal_code,
city = :city,
country = :country,
phone = :phone,
email = :email
WHERE location_id = :location_id;";
$params = [
":street" => $data['street'],
":house_number" => $data['house_number'],
":postal_code" => $data['postal_code'],
":city" => $data['city'],
":country" => $data['country'],
":phone" => $data['phone'],
":email" => $data['email'],
":location_id" => $location_id
];
try {
$sth = $pdo->prepare($sql);
$sth->execute($params);
return $sth->rowCount();
} catch (PDOException $e) {
new \Blog\Library\ErrorMsg("Fehler beim Aktualisieren des Standorts.", $e);
die;
}
}
public function deleteStandort($location_id) {
$pdo = $this->linkDB();
$sql = "DELETE FROM location WHERE location_id = :location_id;";
$params = [":location_id" => $location_id];
try {
$sth = $pdo->prepare($sql);
$sth->execute($params);
return $sth->rowCount();
} catch (PDOException $e) {
new \Blog\Library\ErrorMsg("Fehler beim Löschen des Standorts.", $e);
die;
}
}
}

72
Model/TicketModel.php Normal file
View File

@@ -0,0 +1,72 @@
<?php
namespace Blog\Model;
use PDOException;
class TicketModel extends Database {
public function getTickets() {
$pdo = $this->linkDB();
$sql = "SELECT * FROM ticket ORDER BY ticket_id ASC;";
try {
$sth = $pdo->prepare($sql);
$sth->execute();
return $sth->fetchAll(\PDO::FETCH_ASSOC);
} catch (PDOException $e) {
new \Blog\Library\ErrorMsg("Fehler beim Lesen der Tickets.", $e);
die;
}
}
public function buyTicket($data) {
$pdo = $this->linkDB();
$sql = "INSERT INTO ticket (user_id, event_id, purchase_date, valid_until)
VALUES (:user_id, :event_id, :purchase_date, :valid_until);";
$params = [
":user_id" => $data['user_id'],
":event_id" => $data['event_id'],
":purchase_date" => $data['purchase_date'],
":valid_until" => $data['valid_until']
];
try {
$sth = $pdo->prepare($sql);
$sth->execute($params);
return $pdo->lastInsertId();
} catch (PDOException $e) {
new \Blog\Library\ErrorMsg("Fehler beim Kauf des Tickets.", $e);
die;
}
}
public function hasTicket($user_id, $event_id) {
$pdo = $this->linkDB();
$sql = "SELECT COUNT(*) as count FROM ticket WHERE user_id = :user_id AND event_id = :event_id;";
$params = [
":user_id" => $user_id,
":event_id" => $event_id
];
try {
$sth = $pdo->prepare($sql);
$sth->execute($params);
return $sth->fetch(\PDO::FETCH_ASSOC);
} catch (PDOException $e) {
new \Blog\Library\ErrorMsg("Fehler bei der Ticketprüfung.", $e);
die;
}
}
public function deleteTicket($ticket_id) {
$pdo = $this->linkDB();
$sql = "DELETE FROM ticket WHERE ticket_id = :ticket_id;";
$params = [":ticket_id" => $ticket_id];
try {
$sth = $pdo->prepare($sql);
$sth->execute($params);
return $sth->rowCount();
} catch (PDOException $e) {
new \Blog\Library\ErrorMsg("Fehler beim Löschen des Tickets.", $e);
die;
}
}
}

View File

@@ -0,0 +1,23 @@
<div class="inhalt">
<div class="login-container">
<h1>Anmelden</h1>
<?php if (!empty($errors['login'])): ?>
<div class="login-error"><?=htmlspecialchars($errors['login'])?></div>
<?php endif; ?>
<form class="form-horizontal" action="index.php" method="post">
<input type="hidden" name="controller" value="Auth">
<input type="hidden" name="do" value="login">
<label for="email">E-Mail</label>
<input class="input-email" type="email" name="email" id="email" placeholder="E-Mail" required>
<label for="password">Passwort</label>
<input class="input-passwort" type="password" name="password" id="password" placeholder="Passwort" required>
<button class="button-loggin" type="submit">Login</button>
</form>
<div style="text-align:center; margin-top: 1.5em;">
<a class="link-passwort-vergessen" href="?controller=Auth&do=showForgotPasswordForm">Passwort vergessen?</a>
<br>
<a class="link-konto-erstellen" href="?controller=Auth&do=showRegistrationForm">Konto erstellen</a>
</div>
</div>
</div>

View File

@@ -0,0 +1,23 @@
<div class="inhalt">
<div class="form-container">
<h1>Anmelden</h1>
<?php if (!empty($errors['login'])): ?>
<div class="form-error"><?=htmlspecialchars($errors['login'])?></div>
<?php endif; ?>
<form class="form-horizontal" action="index.php" method="post">
<input type="hidden" name="controller" value="Auth">
<input type="hidden" name="do" value="login">
<label for="email">E-Mail</label>
<input class="input-email" type="email" name="email" id="email" placeholder="E-Mail" required>
<label for="password">Passwort</label>
<input class="input-passwort" type="password" name="password" id="password" placeholder="Passwort" required>
<button class="button-login" type="submit">Login</button>
</form>
<div style="text-align:center; margin-top: 1.5em;">
<a class="link-passwort-vergessen" href="?controller=Auth&do=showForgotPasswordForm">Passwort vergessen?</a>
<br>
<a class="link-konto-erstellen" href="?controller=Auth&do=showRegistrationForm">Konto erstellen</a>
</div>
</div>
</div>

View File

@@ -0,0 +1,15 @@
<div class="inhalt">
<div class="login-success">
<h2>Login erfolgreich!</h2>
<p>Sie werden in wenigen Sekunden zu den News weitergeleitet...</p>
</div>
</div>
<script>
setTimeout(function() {
window.location.href = "?controller=News&do=showNews";
}, 2000); // 2 Sekunden warten
</script>
<noscript>
<meta http-equiv="refresh" content="2;url=?controller=News&do=showNews">
</noscript>

View File

@@ -0,0 +1,14 @@
<div class="inhalt">
<div class="login-success">
<h2>Logout erfolgreich!</h2>
<p>Sie werden in wenigen Sekunden zum Login weitergeleitet...</p>
</div>
</div>
<script>
setTimeout(function() {
window.location.href = "?controller=Auth&do=showLoginForm";
}, 2000); // 2 Sekunden warten
</script>
<noscript>
<meta http-equiv="refresh" content="2;url=?controller=Auth&do=showLoginForm">
</noscript>

View File

@@ -0,0 +1,37 @@
<div class="inhalt">
<div class="form-container">
<h1>Registrieren</h1>
<?php if (!empty($errors['register'])): ?>
<div class="form-error"><?=htmlspecialchars($errors['register'])?></div>
<?php endif; ?>
<form class="form-horizontal" action="index.php" method="post">
<input type="hidden" name="controller" value="Auth">
<input type="hidden" name="do" value="register">
<label for="first_name">Vorname</label>
<input class="input-vorname" type="text" name="first_name" id="first_name" placeholder="Vorname" required value="<?=htmlspecialchars($validData['first_name'] ?? '')?>">
<label for="last_name">Nachname</label>
<input class="input-nachname" type="text" name="last_name" id="last_name" placeholder="Nachname" required value="<?=htmlspecialchars($validData['last_name'] ?? '')?>">
<label for="email">E-Mail</label>
<input class="input-email" type="email" name="email" id="email" placeholder="E-Mail" required value="<?=htmlspecialchars($validData['email'] ?? '')?>">
<label for="password">Passwort</label>
<input class="input-passwort" type="password" name="password" id="password" placeholder="Passwort" required>
<label for="password_repeat">Passwort wiederholen</label>
<input class="input-passwort-repeat" type="password" name="password_repeat" id="password_repeat" placeholder="Passwort wiederholen" required>
<label for="street">Straße</label>
<input class="input-strasse" type="text" name="street" id="street" placeholder="Straße" required value="<?=htmlspecialchars($validData['street'] ?? '')?>">
<label for="house_number">Hausnr.</label>
<input class="input-hausnr" type="text" name="house_number" id="house_number" placeholder="Hausnr." required value="<?=htmlspecialchars($validData['house_number'] ?? '')?>">
<label for="postal_code">Postleitzahl</label>
<input class="input-postleitzahl" type="text" name="postal_code" id="postal_code" placeholder="Postleitzahl" required value="<?=htmlspecialchars($validData['postal_code'] ?? '')?>">
<label for="city">Ort</label>
<input class="input-ort" type="text" name="city" id="city" placeholder="Ort" required value="<?=htmlspecialchars($validData['city'] ?? '')?>">
<label for="country">Land</label>
<input class="input-land" type="text" name="country" id="country" placeholder="Land" required value="<?=htmlspecialchars($validData['country'] ?? '')?>">
<label for="phone">Telefonnr.</label>
<input class="input-tel" type="text" name="phone" id="phone" placeholder="Telefonnr." required value="<?=htmlspecialchars($validData['phone'] ?? '')?>">
<button class="button-register" type="submit">Registrieren</button>
</form>
<a class="link-konto-erstellen" href="?controller=Auth&do=showLoginForm">Login</a>
</div>
</div>

View File

@@ -0,0 +1,14 @@
<div class="inhalt">
<div class="login-success">
<h2>Registrierung erfolgreich!</h2>
<p>Sie werden in wenigen Sekunden zum Login weitergeleitet...</p>
</div>
</div>
<script>
setTimeout(function() {
window.location.href = "?controller=Auth&do=showLoginForm";
}, 2000);
</script>
<noscript>
<meta http-equiv="refresh" content="2;url=?controller=Auth&do=showLoginForm">
</noscript>

View File

@@ -0,0 +1,12 @@
<?php
include dirname(__DIR__).'/header.phtml';
?>
<div class="inhalt">
<div class="msg">
<p>Das Event "<?php echo $name?>" wurde erfolgreich erstellt!</p>
<a href="?controller=Event&do=showEvents">Weiter</a>
</div>
</div>
<?php include dirname(__DIR__).'/footer.phtml'; ?>

View File

@@ -0,0 +1,12 @@
<?php
include dirname(__DIR__).'/header.phtml';
?>
<div class="inhalt">
<div class="msg">
<p>Das Event mit der id"<?php echo $id?>" wurde erfolgreich gelöscht!</p>
<a href="?controller=Event&do=showEvents">Weiter</a>
</div>
</div>
<?php include dirname(__DIR__).'/footer.phtml'; ?>

View File

@@ -0,0 +1,33 @@
<?php if (!empty($events)): ?>
<div class="inhalt">
<div class="event-container">
<h2>Alle Ausstellungen</h2>
<div class="event-container-inhalt">
<table>
<thead>
<tr>
<th>Name</th>
<th>Beschreibung</th>
<th>Von</th>
<th>Bis</th>
<th>Max. Tickets</th>
</tr>
</thead>
<tbody>
<?php foreach ($events as $event): ?>
<tr>
<td><?php echo htmlspecialchars($event['name']); ?></td>
<td><?php echo nl2br(htmlspecialchars($event['description'])); ?></td>
<td><?php echo date('d.m.Y', strtotime($event['start_date'])); ?></td>
<td><?php echo date('d.m.Y', strtotime($event['end_date'])); ?></td>
<td><?php echo (int) $event['max_tickets']; ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php else: ?>
<p>Derzeit sind keine Ausstellungen verfügbar.</p>
<?php endif; ?>
</div>
</div>
</div>

View File

@@ -0,0 +1,12 @@
<?php
include dirname(__DIR__).'/header.phtml';
?>
<div class="inhalt">
<div class="msg">
<p>Das Event mit der ID "<?php echo $ausstellungid?>" wurde erfolgreich bearbeitet!</p>
<a href="?controller=Event&do=showEvents">Weiter</a>
</div>
</div>
<?php include dirname(__DIR__).'/footer.phtml'; ?>

View File

@@ -0,0 +1 @@
echo "create gutschein"

View File

@@ -0,0 +1,36 @@
<?php include dirname(__DIR__) . '/header.phtml'; ?>
<div class="inhalt">
<h2>Alle Gutscheine</h2>
<a href="?controller=Gutschein&do=createGutscheinForm">Neuen Gutschein anlegen</a>
<?php if (!empty($gutscheine)): ?>
<table border="1" cellpadding="8" cellspacing="0">
<thead>
<tr>
<th>Code</th>
<th>Rabatt (%)</th>
<th>Event-ID</th>
<th>Gültig bis</th>
<th>Aktionen</th>
</tr>
</thead>
<tbody>
<?php foreach ($gutscheine as $g): ?>
<tr>
<td><?php echo htmlspecialchars($g['code']); ?></td>
<td><?php echo (int)$g['discount']; ?></td>
<td><?php echo (int)$g['event_id']; ?></td>
<td><?php echo htmlspecialchars($g['valid_until']); ?></td>
<td>
<a href="?controller=Gutschein&action=editGutscheinForm&id=<?php echo $g['gutscheinid']; ?>">Bearbeiten</a> |
<a href="?controller=Gutschein&action=deleteGutschein&id=<?php echo $g['gutscheinid']; ?>" onclick="return confirm('Wirklich löschen?');">Löschen</a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php else: ?>
<p>Keine Gutscheine vorhanden.</p>
<?php endif; ?>
</div>
<?php include dirname(__DIR__) . '/footer.phtml'; ?>

View File

@@ -1,20 +0,0 @@
<div class="inhalt">
<div class="login-container">
<h1>Anmelden</h1>
<form class="form-horizontal" action="#" method="post">
<label>
<input class="input-email" type="text" placeholder="E-Mail">
</label>
</form>
<form class="form-horizontal" action="#" method="post">
<label>
<input class="input-passwort" type="text" placeholder="Passwort">
</label>
</form>
<button class="button-loggin">Login</button>
<a class="link-passwort-vergessen" href="?controller=Login&do=showPasswortVergessen">Passwort vergessen?</a>
<a class="link-konto-erstellen" href="?controller=Register&do=showRegisterPage">Konto erstellen</a>
</div>
</div>

31
Views/News/showNews.phtml Normal file
View File

@@ -0,0 +1,31 @@
<?php if (!empty($news)): ?>
<div class="inhalt">
<div class="event-container">
<h2>Alle Infos</h2>
<div class="event-container-inhalt">
<table>
<thead>
<tr>
<th>Name</th>
<th>Beschreibung</th>
<th>Datum</th>
</tr>
</thead>
<tbody>
<?php foreach ($news as $item): ?>
<tr>
<td><?php echo htmlspecialchars($item['name']); ?></td>
<td><?php echo nl2br(htmlspecialchars($item['name'])); ?></td>
<td><?php echo nl2br(htmlspecialchars($item['description'])); ?></td>
<td><?php echo date('d.m.Y', strtotime($item['date'])); ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php else: ?>
<p>Derzeit sind keine News verfügbar.</p>
<?php endif; ?>
</div>
</div>
</div>

View File

@@ -1,64 +0,0 @@
<div class="inhalt">
<div class="login-container">
<h1>Registrieren</h1>
<form class="form-horizontal" action="#" method="post">
<label>
<input class="input-vorname" type="text" placeholder="Vorname">
</label>
</form>
<form class="form-horizontal" action="#" method="post">
<label>
<input class="input-nachname" type="text" placeholder="Nachname">
</label>
</form>
<form class="form-horizontal" action="#" method="post">
<label>
<input class="input-email" type="text" placeholder="E-Mail">
</label>
</form>
<form class="form-horizontal" action="#" method="post">
<label>
<input class="input-passwort" type="text" placeholder="Passwort">
</label>
</form>
<form class="form-horizontal" action="#" method="post">
<label>
<input class="input-passwort-repeat" type="text" placeholder="Passwort wiederholen">
</label>
</form>
<form class="form-horizontal" action="#" method="post">
<label>
<input class="input-strasse" type="text" placeholder="Straße">
</label>
</form>
<form class="form-horizontal" action="#" method="post">
<label>
<input class="input-hausnr" type="text" placeholder="Hausnr.">
</label>
</form>
<form class="form-horizontal" action="#" method="post">
<label>
<input class="input-postleitzahl" type="text" placeholder="Postleitzahl">
</label>
</form>
<form class="form-horizontal" action="#" method="post">
<label>
<input class="input-ort" type="text" placeholder="Ort">
</label>
</form>
<form class="form-horizontal" action="#" method="post">
<label>
<input class="input-land" type="text" placeholder="Land">
</label>
</form>
<form class="form-horizontal" action="#" method="post">
<label>
<input class="input-tel" type="text" placeholder="Telefonnr.">
</label>
</form>
<button class="button-register">Registrieren</button>
<a class="link-konto-erstellen" href="?controller=Login&do=showLoginPage">Login</a>
</div>
</div>

View File

@@ -0,0 +1,37 @@
<?php include dirname(__DIR__) . '/header.phtml'; ?>
<div class="inhalt">
<h2>Unsere Standorte</h2>
<?php if (!empty($standorte)): ?>
<table border="1" cellpadding="8" cellspacing="0">
<thead>
<tr>
<th>Straße</th>
<th>Hausnr.</th>
<th>PLZ</th>
<th>Ort</th>
<th>Land</th>
<th>Telefon</th>
<th>Email</th>
</tr>
</thead>
<tbody>
<?php foreach ($standorte as $standort): ?>
<tr>
<td><?php echo htmlspecialchars($standort['street']); ?></td>
<td><?php echo htmlspecialchars($standort['house_number']); ?></td>
<td><?php echo htmlspecialchars($standort['postal_code']); ?></td>
<td><?php echo htmlspecialchars($standort['city']); ?></td>
<td><?php echo htmlspecialchars($standort['country']); ?></td>
<td><?php echo htmlspecialchars($standort['phone']); ?></td>
<td><?php echo htmlspecialchars($standort['email']); ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php else: ?>
<p>Keine Standorte gefunden.</p>
<?php endif; ?>
</div>
<?php include dirname(__DIR__) . '/footer.phtml'; ?>

View File

@@ -0,0 +1,12 @@
<?php
include dirname(__DIR__).'/header.phtml';
?>
<div class="msg">
<p>Ihr Ticket für das Event "<?php echo $event['name']?>" wurde erfolgreich gekauft!</p>
<a href="?controller=Welcome&do=showWelcome">Weiter</a>
</div>
<?php include dirname(__DIR__).'/footer.phtml'; ?>

View File

@@ -12,11 +12,15 @@
<div id="logo" ><a class="link-logo" href="#"></a></div>
<button id="nav-toggle-btn" aria-label="Menü ein-/ausklappen">&#9660;</button>
<div class="nav-links">
<a id="link-tickets" class="links" href="?controller=Tickets&do=showTickets">Tickets</a>
<a id="link-infos" class="links" href="?controller=Welcome&do=showWelcome">Infos</a>
<a id="link-tickets" class="links" href="?controller=Event&do=showEvents">Event</a>
<a id="link-infos" class="links" href="?controller=News&do=showNews">Infos</a>
<a id="link-profil" class="links" href="?controller=Profile&do=showProfile">Profil</a>
<a id="link-login" class="links" href="?controller=Login&do=showLoginPage">Login</a>
<a id="link-register" class="links" href="?controller=Register&do=showRegisterPage">Register</a>
<?php if (isset($_SESSION['user'])): ?>
<a id="link-logout" class="links" href="?controller=Auth&do=logout">Logout</a>
<?php else: ?>
<a id="link-login" class="links" href="?controller=Auth&do=showLoginForm">Login</a>
<a id="link-register" class="links" href="?controller=Auth&do=showRegistrationForm">Register</a>
<?php endif; ?>
<div id="profile-picture"></div>
</div>
</div>

112
bibarts.sql Normal file
View File

@@ -0,0 +1,112 @@
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";
-- --------------------------------------------------------
CREATE TABLE user (
user_id INT AUTO_INCREMENT PRIMARY KEY,
first_name VARCHAR(50),
last_name VARCHAR(50),
street VARCHAR(100),
house_number VARCHAR(10),
postal_code VARCHAR(10),
city VARCHAR(50),
country VARCHAR(50),
phone VARCHAR(20),
email VARCHAR(100) UNIQUE,
is_admin BOOLEAN DEFAULT FALSE,
valid_until DATETIME NOT NULL DEFAULT '3025-01-01 00:00:00',
password VARCHAR(255)
);
CREATE TABLE location (
location_id INT AUTO_INCREMENT PRIMARY KEY,
street VARCHAR(100),
house_number VARCHAR(10),
postal_code VARCHAR(10),
city VARCHAR(50),
country VARCHAR(50),
phone VARCHAR(20),
email VARCHAR(100)
);
CREATE TABLE event (
event_id INT AUTO_INCREMENT PRIMARY KEY,
location_id INT,
start_date DATE,
end_date DATE,
name VARCHAR(100),
description TEXT,
max_tickets INT,
ticket_price DECIMAL(5,2),
FOREIGN KEY (location_id) REFERENCES location(location_id)
);
CREATE TABLE ticket (
ticket_id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT,
event_id INT,
purchase_date DATE,
valid_until DATE,
FOREIGN KEY (user_id) REFERENCES user(user_id),
FOREIGN KEY (event_id) REFERENCES event(event_id)
);
CREATE TABLE voucher (
voucher_id INT AUTO_INCREMENT PRIMARY KEY,
code VARCHAR(50) UNIQUE,
discount INT CHECK (discount BETWEEN 0 AND 100),
event_id INT,
valid_until DATE,
FOREIGN KEY (event_id) REFERENCES event(event_id)
);
CREATE TABLE news (
news_id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100),
description TEXT,
date DATE
);
-- User-Daten (Passwort: passwort123)
INSERT INTO user (first_name, last_name, street, house_number, postal_code, city, country, phone, email, is_admin, password)
VALUES
('Max', 'Muster', 'Musterstraße', '1', '12345', 'Musterstadt', 'Deutschland', '0123456789', 'max@muster.de', FALSE, '$2y$10$VAj.C0XHPUxV4oXS6b79aumlg5fBMPPx5FPqgkQSIQeBLh0WtYmKy'),
('Anna', 'Beispiel', 'Beispielweg', '5a', '54321', 'Beispielstadt', 'Deutschland', '0987654321', 'anna@beispiel.de', TRUE, '$2y$10$cnPBpkvLbdpDxzYvxlQg9uVp5y8ggr2SWL8NAMg9zk.3QnnEl.MGq');
-- Standort-Daten
INSERT INTO location (street, house_number, postal_code, city, country, phone, email)
VALUES
('Galeriestraße', '10', '10115', 'Berlin', 'Deutschland', '030123456', 'kontakt@galerie-berlin.de'),
('Kunstallee', '22b', '50667', 'Köln', 'Deutschland', '0221123456', 'info@kunst-koeln.de');
-- Ausstellung-Daten
INSERT INTO event (location_id, start_date, end_date, name, description, max_tickets, ticket_price)
VALUES
(1, '2025-07-01', '2025-08-31', 'Moderne Meisterwerke', 'Eine Sammlung moderner Kunstwerke aus Europa.', 200, 19.99),
(2, '2025-09-10', '2025-10-20', 'Kunst der Antike', 'Ausstellung antiker Skulpturen und Gemälde.', 150, 39.99);
-- Gutschein-Daten
INSERT INTO voucher (code, discount, event_id, valid_until)
VALUES
('SOMMER2025', 15, 1, '2025-08-31'),
('HERBST25', 25, 2, '2025-10-15');
-- Ticket-Daten
INSERT INTO ticket (user_id, event_id, purchase_date, valid_until)
VALUES
(1, 1, '2025-06-01', '2025-07-15'),
(2, 2, '2025-06-05', '2025-09-15');
-- News-Daten
INSERT INTO news (name, description, date)
VALUES
('Neuer Standort eröffnet', 'Unsere Galerie in Köln ist jetzt geöffnet!', '2025-06-01'),
('Frühbucher-Rabatt', 'Sichern Sie sich jetzt 15% Rabatt auf unsere Sommerausstellung.', '2025-05-20');

View File

@@ -1,30 +0,0 @@
-- phpMyAdmin SQL Dump
-- version 4.5.1
-- http://www.phpmyadmin.net
--
-- Host: 127.0.0.1
-- Erstellungszeit: 24. Nov 2017 um 17:01
-- Server-Version: 10.1.16-MariaDB
-- PHP-Version: 7.0.9
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";
--
-- Datenbank: `blog`
--
-- --------------------------------------------------------
CREATE TABLE `contact` (
`id` varchar(36) NOT NULL,
`topicCode` tinyint(2) NULL,
`name` varchar(200) NOT NULL,
`email` varchar(300) NOT NULL,
`phone` varchar(16) NULL,
`content` varchar(500) NOT NULL,
`created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `contact`
ADD PRIMARY KEY (`id`)

View File

@@ -2,48 +2,46 @@
session_start();
include 'Views/header.phtml';
?>
<div id="wrapper">
<?php
spl_autoload_register(function ($className) {
if (substr($className, 0, 5) !== 'Blog\\') {
// not our business
return;
}
$fileName = __DIR__.'/'.str_replace('\\', DIRECTORY_SEPARATOR, substr($className, 5)).'.php';
if (file_exists($fileName)) {
include $fileName;
}
});
$controllerName = "";
$doMethodName = "";
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$controllerName = isset($_POST['controller']) && $_POST['controller'] ? $_POST['controller'] : "Welcome";
$doMethodName = isset($_POST['do']) && $_POST['do'] ? $_POST['do'] : "showWelcome";
} else {
$controllerName = isset($_GET['controller']) && $_GET['controller'] ? $_GET['controller'] : "Welcome";
$doMethodName = isset($_GET['do']) && $_GET['do'] ? $_GET['do'] : "showWelcome";
<?php
spl_autoload_register(function ($className) {
if (substr($className, 0, 5) !== 'Blog\\') {
// not our business
return;
}
$controllerClassName = 'Blog\\Controller\\'.ucfirst($controllerName).'Controller';
$fileName = __DIR__.'/'.str_replace('\\', DIRECTORY_SEPARATOR, substr($className, 5)).'.php';
if (method_exists($controllerClassName, $doMethodName)) {
$view = new \Blog\Library\View(__DIR__.DIRECTORY_SEPARATOR.'Views'
, ucfirst($controllerName), $doMethodName);
$controller = new $controllerClassName($view);
$controller->$doMethodName();
$view->render();
} else {
new \Blog\Library\ErrorMsg('Page not found: '.$controllerClassName.'::'.$doMethodName);
if (file_exists($fileName)) {
include $fileName;
}
?>
</div>
});
$controllerName = "";
$doMethodName = "";
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$controllerName = isset($_POST['controller']) && $_POST['controller'] ? $_POST['controller'] : "Welcome";
$doMethodName = isset($_POST['do']) && $_POST['do'] ? $_POST['do'] : "showWelcome";
} else {
$controllerName = isset($_GET['controller']) && $_GET['controller'] ? $_GET['controller'] : "Welcome";
$doMethodName = isset($_GET['do']) && $_GET['do'] ? $_GET['do'] : "showWelcome";
}
$controllerClassName = 'Blog\\Controller\\'.ucfirst($controllerName).'Controller';
if (method_exists($controllerClassName, $doMethodName)) {
$view = new \Blog\Library\View(__DIR__.DIRECTORY_SEPARATOR.'Views'
, ucfirst($controllerName), $doMethodName);
$controller = new $controllerClassName($view);
$controller->$doMethodName();
$view->render();
} else {
new \Blog\Library\ErrorMsg('Page not found: '.$controllerClassName.'::'.$doMethodName);
}
?>
<?php
include 'Views/footer.phtml';
?>