Enhance offerAdder and shopAdder with detailed PHPDoc comments for improved code documentation and maintainability

This commit is contained in:
Fabian Schieder 2026-04-06 22:49:16 +02:00
parent 77ced928b0
commit df6118a4d9
2 changed files with 204 additions and 5 deletions

View File

@ -1,11 +1,26 @@
<?php <?php
/** /**
* @file offerAdder.php * @file offerAdder.php
* @brief Angebot hinzufügen * @brief Angebot hinzufügen und verwalten.
*
* Dieses Skript stellt eine Benutzeroberfläche und die zugrundeliegende Logik bereit,
* um Angebote für Produkte in verschiedenen Shops hinzuzufügen, anzuzeigen und zu löschen.
* Der Zugriff ist streng auf Administratoren beschränkt.
*
* @author Geizkragen-Team
* @date 2026-04-06
*/ */
require_once __DIR__ . '/lib/bootstrap.php'; require_once __DIR__ . '/lib/bootstrap.php';
/**
* @brief Zugriffskontrolle für Administratoren.
*
* Überprüft, ob der aktuelle Benutzer angemeldet ist, Rollen zugewiesen hat
* und ob die Rolle 'ADMIN' in seinen Benutzerrollen enthalten ist.
* Falls nicht, wird ein HTTP 403 (Forbidden) Fehler gesendet und eine
* Fehlermeldung auf der Seite angezeigt, bevor die Ausführung beendet wird.
*/
// Only ADMIN // Only ADMIN
if (empty($_SESSION['user_id']) || empty($_SESSION['user_roles']) || !in_array('ADMIN', $_SESSION['user_roles'], true)) { if (empty($_SESSION['user_id']) || empty($_SESSION['user_roles']) || !in_array('ADMIN', $_SESSION['user_roles'], true)) {
http_response_code(403); http_response_code(403);
@ -18,11 +33,30 @@ if (empty($_SESSION['user_id']) || empty($_SESSION['user_roles']) || !in_array('
exit; exit;
} }
/**
* @brief Datenbankverbindung herstellen und Initialisierung von Statusvariablen.
*
* @var mysqli $conn Die aktive Datenbankverbindung.
* @var string $message Eine Nachricht an den Benutzer (Erfolg oder Fehler).
* @var string $messageType Der Typ der Nachricht ('success' oder 'error').
*/
$conn = db_connect(); $conn = db_connect();
$message = ''; $message = '';
$messageType = ''; $messageType = '';
/**
* @brief Verarbeitung von POST-Anfragen zur Angebotsverwaltung.
*
* Überprüft, ob das Formular abgesendet wurde und eine spezifische 'action' gesetzt ist.
* Unterstützte Aktionen sind 'add_offer' (Angebot hinzufügen) und 'delete_offer' (Angebot löschen).
*/
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) { if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
/**
* @brief Aktion: Neues Angebot hinzufügen.
*
* Liest die übermittelten Formulardaten aus, validiert diese (Produkt-ID, Shop-ID und
* gültiger Preis) und fügt sie durch ein Prepared Statement in die Tabelle `offers` ein.
*/
if ($_POST['action'] === 'add_offer') { if ($_POST['action'] === 'add_offer') {
$productID = (int)$_POST['product_id']; $productID = (int)$_POST['product_id'];
$shopID = (int)$_POST['shop_id']; $shopID = (int)$_POST['shop_id'];
@ -32,6 +66,10 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
$offerURL = trim($_POST['offer_url']); $offerURL = trim($_POST['offer_url']);
if ($productID > 0 && $shopID > 0 && $price >= 0) { if ($productID > 0 && $shopID > 0 && $price >= 0) {
/**
* @brief Einfügen in die Datenbank.
* Bereitet das SQL-Statement vor und bindet die Parameter sicher, um SQL-Injection zu verhindern.
*/
$stmt = $conn->prepare("INSERT INTO offers (productID, shopID, price, shippingCost, inStock, offerURL) VALUES (?, ?, ?, ?, ?, ?)"); $stmt = $conn->prepare("INSERT INTO offers (productID, shopID, price, shippingCost, inStock, offerURL) VALUES (?, ?, ?, ?, ?, ?)");
$stmt->bind_param("iiddis", $productID, $shopID, $price, $shippingCost, $inStock, $offerURL); $stmt->bind_param("iiddis", $productID, $shopID, $price, $shippingCost, $inStock, $offerURL);
if ($stmt->execute()) { if ($stmt->execute()) {
@ -43,10 +81,19 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
} }
$stmt->close(); $stmt->close();
} else { } else {
/**
* @brief Fehlerbehandlung bei ungültigen Eingaben.
*/
$message = 'Bitte alle Pflichtfelder korrekt ausfüllen.'; $message = 'Bitte alle Pflichtfelder korrekt ausfüllen.';
$messageType = 'error'; $messageType = 'error';
} }
} elseif ($_POST['action'] === 'delete_offer') { } elseif ($_POST['action'] === 'delete_offer') {
/**
* @brief Aktion: Existierendes Angebot löschen.
*
* Überprüft die übermittelte Angebot-ID und löscht den entsprechenden Eintrag
* sicher per Prepared Statement aus der Datenbank.
*/
$offerID = (int)$_POST['offer_id']; $offerID = (int)$_POST['offer_id'];
if ($offerID > 0) { if ($offerID > 0) {
$stmt = $conn->prepare("DELETE FROM offers WHERE offerID = ?"); $stmt = $conn->prepare("DELETE FROM offers WHERE offerID = ?");
@ -63,6 +110,14 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
} }
} }
/**
* @brief Abrufen aller Produkte für das Dropdown-Feld.
*
* Führt eine Query aus, um alle verfügbaren Produkte (IDs und Modelle)
* alphabetisch geordnet aus der Datenbank zu laden.
*
* @var array $products Enthält die geladenen Produkte.
*/
// Get all products for dropdown // Get all products for dropdown
$productsResult = $conn->query("SELECT productID, model FROM products ORDER BY model ASC"); $productsResult = $conn->query("SELECT productID, model FROM products ORDER BY model ASC");
$products = []; $products = [];
@ -72,6 +127,14 @@ if ($productsResult) {
} }
} }
/**
* @brief Abrufen aller Shops für das Dropdown-Feld.
*
* Führt eine Query aus, um alle verfügbaren Shops (IDs und Namen)
* alphabetisch geordnet aus der Datenbank zu laden.
*
* @var array $shops Enthält die geladenen Shops.
*/
// Get all shops for dropdown // Get all shops for dropdown
$shopsResult = $conn->query("SELECT shopID, name FROM shops ORDER BY name ASC"); $shopsResult = $conn->query("SELECT shopID, name FROM shops ORDER BY name ASC");
$shops = []; $shops = [];
@ -81,6 +144,15 @@ if ($shopsResult) {
} }
} }
/**
* @brief Filterlogik für die Anzeige existierender Angebote.
*
* Überprüft, ob über GET ein Filter für eine bestimmte Produkt-ID gesetzt wurde.
* Ist dies der Fall, werden nur Angebote für dieses Produkt angezeigt.
*
* @var int $filterProductID Die ID des zu filternden Produkts (0, wenn kein Filter gesetzt ist).
* @var string $offersQuery Die dynamisch generierte SQL-Abfrage für die Angebote.
*/
$filterProductID = isset($_GET['filter_product_id']) ? (int)$_GET['filter_product_id'] : 0; $filterProductID = isset($_GET['filter_product_id']) ? (int)$_GET['filter_product_id'] : 0;
$offersQuery = " $offersQuery = "
@ -91,11 +163,20 @@ $offersQuery = "
"; ";
if ($filterProductID > 0) { if ($filterProductID > 0) {
/**
* @brief Anwenden des Filters auf die SQL-Query, falls notwendig.
*/
$offersQuery .= " WHERE o.productID = " . $filterProductID; $offersQuery .= " WHERE o.productID = " . $filterProductID;
} }
$offersQuery .= " ORDER BY o.offerID DESC"; $offersQuery .= " ORDER BY o.offerID DESC";
/**
* @brief Ausführen der Angebot-Abfrage und Speichern in ein Array.
*
* @var array $existingOffers Enthält die geladenen Angebote inkl. Shop- und Produkt-Namen,
* die zur Anzeige in der Tabelle verwendet werden.
*/
// Get existing offers to manage // Get existing offers to manage
$offersResult = $conn->query($offersQuery); $offersResult = $conn->query($offersQuery);
$existingOffers = []; $existingOffers = [];
@ -105,6 +186,9 @@ if ($offersResult) {
} }
} }
/**
* @brief Einbinden des HTML-Headers, der Navigation und Stile.
*/
include 'header.php'; include 'header.php';
?> ?>
<main class="auth"> <main class="auth">
@ -217,6 +301,10 @@ include 'header.php';
<form method="POST" action="offerAdder.php<?php echo $filterProductID > 0 ? '?filter_product_id=' . $filterProductID : ''; ?>" onsubmit="return confirm('Möchtest du dieses Angebot wirklich löschen?');" style="display: inline-block; margin: 0;"> <form method="POST" action="offerAdder.php<?php echo $filterProductID > 0 ? '?filter_product_id=' . $filterProductID : ''; ?>" onsubmit="return confirm('Möchtest du dieses Angebot wirklich löschen?');" style="display: inline-block; margin: 0;">
<input type="hidden" name="action" value="delete_offer"> <input type="hidden" name="action" value="delete_offer">
<input type="hidden" name="offer_id" value="<?php echo $offer['offerID']; ?>"> <input type="hidden" name="offer_id" value="<?php echo $offer['offerID']; ?>">
<!--
@brief Button für das Löschen eines Angebotes.
Enthält ein SVG-Icon als Mülleimer. Ein Klick löst einen Bestätigungsdialog (JavaScript) aus.
-->
<button type="submit" style="background: none; border: none; color: #ef4444; cursor: pointer; display: flex; align-items: center; justify-content: flex-end; padding: 0.5rem; border-radius: 4px;" title="Angebot löschen" onmouseover="this.style.backgroundColor='#fee2e2';" onmouseout="this.style.backgroundColor='transparent';"> <button type="submit" style="background: none; border: none; color: #ef4444; cursor: pointer; display: flex; align-items: center; justify-content: flex-end; padding: 0.5rem; border-radius: 4px;" title="Angebot löschen" onmouseover="this.style.backgroundColor='#fee2e2';" onmouseout="this.style.backgroundColor='transparent';">
<svg width="20" height="20" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24"> <svg width="20" height="20" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24">
<polyline points="3 6 5 6 21 6"></polyline> <polyline points="3 6 5 6 21 6"></polyline>
@ -236,5 +324,9 @@ include 'header.php';
</div> </div>
</section> </section>
</main> </main>
<?php include 'footer.php'; ?> <?php
/**
* @brief Einbinden des HTML-Footers am Ende der Seite.
*/
include 'footer.php';
?>

View File

@ -1,11 +1,25 @@
<?php <?php
/** /**
* @file shopAdder.php * @file shopAdder.php
* @brief Shop hinzufügen * @brief Shop-Verwaltungssystem (Hinzufügen und Löschen von Shops)
*
* Dieses Skript ermöglicht Administratoren das Hinzufügen neuer Shops sowie das Löschen
* bestehender Shops, sofern diese keine verknüpften Angebote (Offers) haben.
* Es enthält Funktionen für den Upload oder die Verlinkung von Shop-Logos.
*
* @author GitHub Copilot
* @version 1.0
*/ */
require_once __DIR__ . '/lib/bootstrap.php'; require_once __DIR__ . '/lib/bootstrap.php';
/**
* @brief Überprüfung der Zugriffsberechtigungen
*
* Es wird geprüft, ob eine aktive Benutzersession existiert und ob der Benutzer
* die Rolle 'ADMIN' besitzt. Wenn nicht, wird der Zugriff verweigert (Status 403)
* und eine entsprechende Fehlermeldung ausgegeben.
*/
// Only ADMIN // Only ADMIN
if (empty($_SESSION['user_id']) || empty($_SESSION['user_roles']) || !in_array('ADMIN', $_SESSION['user_roles'], true)) { if (empty($_SESSION['user_id']) || empty($_SESSION['user_roles']) || !in_array('ADMIN', $_SESSION['user_roles'], true)) {
http_response_code(403); http_response_code(403);
@ -18,34 +32,69 @@ if (empty($_SESSION['user_id']) || empty($_SESSION['user_roles']) || !in_array('
exit; exit;
} }
/**
* @brief Datenbankverbindung herstellen
* @var mysqli $conn Die aktive Datenbankverbindung
*/
$conn = db_connect(); $conn = db_connect();
/**
* @var string $message Speichert Erfolgs- oder Fehlermeldungen für den Benutzer
* @var string $messageType Definiert den Typ der Nachricht ('success' oder 'error')
*/
$message = ''; $message = '';
$messageType = ''; $messageType = '';
/**
* @brief Verarbeitung von POST-Anfragen (Formular-Übermittlungen)
*
* Prüft, ob ein Formular abgesendet wurde und welche Aktion ('add_shop' oder 'delete_shop')
* ausgeführt werden soll.
*/
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) { if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
if ($_POST['action'] === 'add_shop') { if ($_POST['action'] === 'add_shop') {
/**
* @brief Extrahieren der Formulardaten für einen neuen Shop
*/
$name = trim($_POST['name']); $name = trim($_POST['name']);
$website = trim($_POST['website']); $website = trim($_POST['website']);
$shippingTime = trim($_POST['shipping_time']); $shippingTime = trim($_POST['shipping_time']);
$logoPath = null; $logoPath = null;
/**
* @brief Verarbeitung des Logo-Uploads
*
* Prüft zunächst, ob eine Datei hochgeladen wurde und kein Fehler aufgetreten ist.
*/
// Handle logo upload // Handle logo upload
if (isset($_FILES['logo']) && $_FILES['logo']['error'] === UPLOAD_ERR_OK) { if (isset($_FILES['logo']) && $_FILES['logo']['error'] === UPLOAD_ERR_OK) {
/**
* @brief Validierung des MIME-Types der hochgeladenen Datei
*/
$allowedTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp']; $allowedTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
$fileInfo = finfo_open(FILEINFO_MIME_TYPE); $fileInfo = finfo_open(FILEINFO_MIME_TYPE);
$mimeType = finfo_file($fileInfo, $_FILES['logo']['tmp_name']); $mimeType = finfo_file($fileInfo, $_FILES['logo']['tmp_name']);
finfo_close($fileInfo); finfo_close($fileInfo);
if (in_array($mimeType, $allowedTypes)) { if (in_array($mimeType, $allowedTypes)) {
/**
* @brief Verzeichnisstruktur für Logos sicherstellen
*/
$uploadDir = __DIR__ . '/assets/images/shopLogo/'; $uploadDir = __DIR__ . '/assets/images/shopLogo/';
if (!is_dir($uploadDir)) { if (!is_dir($uploadDir)) {
mkdir($uploadDir, 0777, true); mkdir($uploadDir, 0777, true);
} }
/**
* @brief Generierung eines eindeutigen Dateinamens
*/
$extension = pathinfo($_FILES['logo']['name'], PATHINFO_EXTENSION); $extension = pathinfo($_FILES['logo']['name'], PATHINFO_EXTENSION);
$fileName = preg_replace('/[^a-zA-Z0-9_-]/', '_', $name) . '_' . time() . '.' . $extension; $fileName = preg_replace('/[^a-zA-Z0-9_-]/', '_', $name) . '_' . time() . '.' . $extension;
$targetFile = $uploadDir . $fileName; $targetFile = $uploadDir . $fileName;
/**
* @brief Speichern der hochgeladenen Datei
*/
if (move_uploaded_file($_FILES['logo']['tmp_name'], $targetFile)) { if (move_uploaded_file($_FILES['logo']['tmp_name'], $targetFile)) {
$logoPath = 'assets/images/shopLogo/' . $fileName; $logoPath = 'assets/images/shopLogo/' . $fileName;
} else { } else {
@ -57,9 +106,18 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
$messageType = 'error'; $messageType = 'error';
} }
} elseif (isset($_POST['logo_url']) && trim($_POST['logo_url']) !== '') { } elseif (isset($_POST['logo_url']) && trim($_POST['logo_url']) !== '') {
/**
* @brief Fallback auf eine angegebene Bild-URL, falls keine Datei hochgeladen wurde
*/
$logoPath = trim($_POST['logo_url']); $logoPath = trim($_POST['logo_url']);
} }
/**
* @brief Speichern des neuen Shops in der Datenbank
*
* Wenn keine Fehler aufgetreten sind und ein Name angegeben wurde,
* wird der Shop über ein Prepared Statement in die Datenbank eingefügt.
*/
if (empty($message) && $name !== '') { if (empty($message) && $name !== '') {
$stmt = $conn->prepare("INSERT INTO shops (name, website, logoPath, shippingTime) VALUES (?, ?, ?, ?)"); $stmt = $conn->prepare("INSERT INTO shops (name, website, logoPath, shippingTime) VALUES (?, ?, ?, ?)");
$stmt->bind_param("ssss", $name, $website, $logoPath, $shippingTime); $stmt->bind_param("ssss", $name, $website, $logoPath, $shippingTime);
@ -76,8 +134,18 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
$messageType = 'error'; $messageType = 'error';
} }
} elseif ($_POST['action'] === 'delete_shop') { } elseif ($_POST['action'] === 'delete_shop') {
/**
* @brief Löschen eines bestehenden Shops
*/
$shopID = (int)$_POST['shop_id']; $shopID = (int)$_POST['shop_id'];
if ($shopID > 0) { if ($shopID > 0) {
/**
* @brief Überprüfung auf verknüpfte Angebote
*
* Bevor ein Shop gelöscht wird, muss sichergestellt werden, dass
* keine Angebote (Offers) mehr mit diesem verknüpft sind, um die
* referenzielle Integrität zu wahren.
*/
// First check if the shop has associated offers // First check if the shop has associated offers
$checkStmt = $conn->prepare("SELECT COUNT(*) AS offerCount FROM offers WHERE shopID = ?"); $checkStmt = $conn->prepare("SELECT COUNT(*) AS offerCount FROM offers WHERE shopID = ?");
$checkStmt->bind_param("i", $shopID); $checkStmt->bind_param("i", $shopID);
@ -88,9 +156,15 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
$checkStmt->close(); $checkStmt->close();
if ($offerCount > 0) { if ($offerCount > 0) {
/**
* @brief Löschen verhindern, wenn Angebote existieren
*/
$message = "Der Shop kann nicht gelöscht werden, da er noch $offerCount verknüpfte Angebote hat."; $message = "Der Shop kann nicht gelöscht werden, da er noch $offerCount verknüpfte Angebote hat.";
$messageType = 'error'; $messageType = 'error';
} else { } else {
/**
* @brief Führt das Löschen des Shops aus der Datenbank durch
*/
$stmt = $conn->prepare("DELETE FROM shops WHERE shopID = ?"); $stmt = $conn->prepare("DELETE FROM shops WHERE shopID = ?");
$stmt->bind_param("i", $shopID); $stmt->bind_param("i", $shopID);
if ($stmt->execute()) { if ($stmt->execute()) {
@ -106,6 +180,13 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
} }
} }
/**
* @brief Abrufen aller bestehenden Shops zur Verwaltung
*
* Es wird eine Liste aller Shops inklusive der Anzahl ihrer zugeordneten Angebote
* (über einen LEFT JOIN mit der Tabelle offers) abgerufen, um diese in der Tabelle
* im Frontend anzuzeigen.
*/
// Get existing shops to manage // Get existing shops to manage
$shopsResult = $conn->query(" $shopsResult = $conn->query("
SELECT s.shopID, s.name, s.website, s.logoPath, s.shippingTime, COUNT(o.offerID) AS offerCount SELECT s.shopID, s.name, s.website, s.logoPath, s.shippingTime, COUNT(o.offerID) AS offerCount
@ -114,6 +195,9 @@ $shopsResult = $conn->query("
GROUP BY s.shopID, s.name, s.website, s.logoPath, s.shippingTime GROUP BY s.shopID, s.name, s.website, s.logoPath, s.shippingTime
ORDER BY s.name ASC ORDER BY s.name ASC
"); ");
/**
* @var array $existingShops Speichert die aus der Datenbank abgerufenen Shops
*/
$existingShops = []; $existingShops = [];
if ($shopsResult) { if ($shopsResult) {
while ($row = $shopsResult->fetch_assoc()) { while ($row = $shopsResult->fetch_assoc()) {
@ -121,21 +205,31 @@ if ($shopsResult) {
} }
} }
/**
* @brief Einbinden des globalen Headers
*/
include 'header.php'; include 'header.php';
?> ?>
<!--
@brief Hauptbereich für die Shop-Verwaltung
Hier wird die GUI zum Anlegen und Löschen von Shops aufgebaut.
-->
<main class="auth"> <main class="auth">
<section class="auth__grid" style="grid-template-columns: 1fr;"> <section class="auth__grid" style="grid-template-columns: 1fr;">
<div class="auth__card"> <div class="auth__card">
<header class="auth__header"> <header class="auth__header">
<!-- @brief Überschrift für das Hinzufügen-Formular -->
<h2 class="auth__title">Shop verwalten</h2> <h2 class="auth__title">Shop verwalten</h2>
</header> </header>
<?php if ($message): ?> <?php if ($message): ?>
<!-- @brief Ausgabe von Systemnachrichten (Erfolg / Fehler) -->
<p class="<?php echo $messageType === 'success' ? 'auth__alert__sucess' : 'auth__alert__error'; ?>" style="margin-bottom: 1rem;"> <p class="<?php echo $messageType === 'success' ? 'auth__alert__sucess' : 'auth__alert__error'; ?>" style="margin-bottom: 1rem;">
<?php echo htmlspecialchars($message); ?> <?php echo htmlspecialchars($message); ?>
</p> </p>
<?php endif; ?> <?php endif; ?>
<!-- @brief Formular zum Hinzufügen eines neuen Shops -->
<form method="POST" action="shopAdder.php" class="auth__form" enctype="multipart/form-data"> <form method="POST" action="shopAdder.php" class="auth__form" enctype="multipart/form-data">
<input type="hidden" name="action" value="add_shop"> <input type="hidden" name="action" value="add_shop">
@ -155,6 +249,7 @@ include 'header.php';
</div> </div>
<div style="margin-top: 1rem;"> <div style="margin-top: 1rem;">
<!-- @brief Upload-Bereich für das Shop-Logo oder URL-Eingabe -->
<label style="display: block; margin-bottom: 0.5rem; font-weight: 500; color: var(--text-muted);">Shop Logo</label> <label style="display: block; margin-bottom: 0.5rem; font-weight: 500; color: var(--text-muted);">Shop Logo</label>
<div style="display: flex; flex-direction: column; gap: 0.8rem; background: var(--bg-alt); padding: 1rem; border-radius: 6px; border: 1px solid var(--border-light);"> <div style="display: flex; flex-direction: column; gap: 0.8rem; background: var(--bg-alt); padding: 1rem; border-radius: 6px; border: 1px solid var(--border-light);">
<div> <div>
@ -170,6 +265,7 @@ include 'header.php';
</div> </div>
<div class="auth__actions" style="margin-top: 1.5rem;"> <div class="auth__actions" style="margin-top: 1.5rem;">
<!-- @brief Absende-Button -->
<button type="submit" class="auth__submit">Shop hinzufügen</button> <button type="submit" class="auth__submit">Shop hinzufügen</button>
</div> </div>
</form> </form>
@ -177,10 +273,12 @@ include 'header.php';
<div class="auth__card" style="margin-top: 2rem;"> <div class="auth__card" style="margin-top: 2rem;">
<header class="auth__header"> <header class="auth__header">
<!-- @brief Überschrift für die Liste der bestehenden Shops -->
<h2 class="auth__title">Bestehende Shops verwalten</h2> <h2 class="auth__title">Bestehende Shops verwalten</h2>
</header> </header>
<?php if (count($existingShops) > 0): ?> <?php if (count($existingShops) > 0): ?>
<!-- @brief Tabelle mit den vorhandenen Shops -->
<div style="overflow-x: auto; margin-top: 1rem;"> <div style="overflow-x: auto; margin-top: 1rem;">
<table style="width: 100%; border-collapse: collapse; min-width: 600px;"> <table style="width: 100%; border-collapse: collapse; min-width: 600px;">
<thead> <thead>
@ -194,6 +292,7 @@ include 'header.php';
</thead> </thead>
<tbody> <tbody>
<?php foreach ($existingShops as $shop): ?> <?php foreach ($existingShops as $shop): ?>
<!-- @brief Tabellenzeile für jeden einzelnen Shop -->
<tr style="border-bottom: 1px solid var(--border-light);"> <tr style="border-bottom: 1px solid var(--border-light);">
<td style="padding: 1rem 0.5rem; vertical-align: middle;"> <td style="padding: 1rem 0.5rem; vertical-align: middle;">
<?php if ($shop['logoPath']): ?> <?php if ($shop['logoPath']): ?>
@ -215,6 +314,7 @@ include 'header.php';
</td> </td>
<td style="padding: 1rem 0.5rem; text-align: right; vertical-align: middle;"> <td style="padding: 1rem 0.5rem; text-align: right; vertical-align: middle;">
<?php if ($shop['offerCount'] > 0): ?> <?php if ($shop['offerCount'] > 0): ?>
<!-- @brief Deaktivierter Löschen-Button, falls Angebote existieren -->
<button disabled style="background: none; border: none; color: #ccc; cursor: not-allowed; display: inline-flex; align-items: center; justify-content: flex-end; padding: 0.5rem;" title="Shop kann nicht gelöscht werden, da er noch Angebote hat"> <button disabled style="background: none; border: none; color: #ccc; cursor: not-allowed; display: inline-flex; align-items: center; justify-content: flex-end; padding: 0.5rem;" title="Shop kann nicht gelöscht werden, da er noch Angebote hat">
<svg width="20" height="20" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24"> <svg width="20" height="20" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" viewBox="0 0 24 24">
<polyline points="3 6 5 6 21 6"></polyline> <polyline points="3 6 5 6 21 6"></polyline>
@ -222,6 +322,7 @@ include 'header.php';
</svg> </svg>
</button> </button>
<?php else: ?> <?php else: ?>
<!-- @brief Aktives Formular mit Lösch-Button, wenn keine Angebote verknüpft sind -->
<form method="POST" action="shopAdder.php" onsubmit="return confirm('Möchtest du diesen Shop wirklich löschen?');" style="display: inline-block; margin: 0;"> <form method="POST" action="shopAdder.php" onsubmit="return confirm('Möchtest du diesen Shop wirklich löschen?');" style="display: inline-block; margin: 0;">
<input type="hidden" name="action" value="delete_shop"> <input type="hidden" name="action" value="delete_shop">
<input type="hidden" name="shop_id" value="<?php echo $shop['shopID']; ?>"> <input type="hidden" name="shop_id" value="<?php echo $shop['shopID']; ?>">
@ -240,9 +341,15 @@ include 'header.php';
</table> </table>
</div> </div>
<?php else: ?> <?php else: ?>
<!-- @brief Hinweis, wenn noch keine Shops in der Datenbank vorhanden sind -->
<p style="margin-top: 1rem; color: var(--text-muted); text-align: center; padding: 2rem 0;">Keine Shops vorhanden.</p> <p style="margin-top: 1rem; color: var(--text-muted); text-align: center; padding: 2rem 0;">Keine Shops vorhanden.</p>
<?php endif; ?> <?php endif; ?>
</div> </div>
</section> </section>
</main> </main>
<?php include 'footer.php'; ?> <?php
/**
* @brief Einbinden des globalen Footers
*/
include 'footer.php';
?>