'; echo '

Zugriff verweigert

'; echo '

Du hast keine Berechtigung, Produkte hinzuzufügen.

'; echo '
'; include 'footer.php'; exit; } /** * @section Kategorie-Auswahl * @brief Ermittlung der ausgewählten Kategorie-ID. * * Die Kategorie-ID wird entweder aus den GET- oder POST-Parametern bezogen. * Es wird sichergestellt, dass die ID aus Ziffern besteht (ctype_digit). */ /* ======================= 1) Kategorie aus GET ======================= */ $categoryID = 0; if (isset($_GET['categoryID']) && ctype_digit($_GET['categoryID'])) { $categoryID = (int)$_GET['categoryID']; } elseif (isset($_POST['categoryID']) && ctype_digit($_POST['categoryID'])) { $categoryID = (int)$_POST['categoryID']; } /** * @section Datenbankverbindung * @brief Initialisierung der Datenbankverbindung. * * Nutzt die globale Funktion db_connect() aus bootstrap.php / db.php, * um eine Verbindung zur MySQL-Datenbank herzustellen. */ /* ======================= 2) DB-Verbindung ======================= */ $conn = db_connect(); /** * @section Kategorien-Laden * @brief Abrufen aller verfügbaren Kategorien. * * Die Kategorien werden für das Dropdown-Menü im Formular benötigt * und alphabetisch sortiert geladen. */ /* ======================= 3) Kategorien laden ======================= */ $categories = []; $result = $conn->query(" SELECT categoryID, name FROM categories ORDER BY name "); while ($row = $result->fetch_assoc()) { $categories[] = $row; } /** * @section Marken-Laden * @brief Abrufen aller verfügbaren Marken. * * Lädt die Marken alphabetisch sortiert aus der Datenbank, * damit sie bei der Produkterstellung ausgewählt werden können. */ /* ======================= 3b) Marken laden ======================= */ $brands = []; $result = $conn->query(" SELECT brandID, name FROM brands ORDER BY name "); while ($row = $result->fetch_assoc()) { $brands[] = $row; } /** * @section Attribute-Laden * @brief Abrufen der kategoriespezifischen Attribute. * * Falls eine Kategorie ausgewählt wurde ($categoryID > 0), werden * die zugehörigen Attribute (inklusive Einheit und Datentyp) geladen. */ /* ======================= 4) Attribute zur Kategorie ======================= */ $attributes = []; if ($categoryID > 0) { $stmt = $conn->prepare(" SELECT a.attributeID, a.name, a.unit, a.dataType FROM categoryAttributes ca JOIN attributes a ON a.attributeID = ca.attributeID WHERE ca.categoryID = ? ORDER BY a.name "); $stmt->bind_param("i", $categoryID); $stmt->execute(); $res = $stmt->get_result(); while ($row = $res->fetch_assoc()) { $attributes[] = $row; } } /** * @section Produkt-Speicherung * @brief Verarbeitung des abgesendeten Formulars zum Speichern eines Produkts. * * Diese Sektion verarbeitet alle übergebenen Formulardaten (Modell, Beschreibung, * Kategorie, Marke, Bild-Upload/URL, Attribute), validiert sie und fügt das * neue Produkt in die Datenbank ein. */ /* ======================= 5) Produkt speichern ======================= */ $saveError = null; /** @var bool $debugMode Aktiviert den Debug-Modus für zusätzliche Fehlerausgaben, wenn ?debug=1 übergeben wird. */ $debugMode = isset($_GET['debug']) && $_GET['debug'] === '1'; $debugDetails = []; if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['saveProduct'])) { /** @var string $model Der Name bzw. das Modell des Produkts */ $model = trim($_POST['model']); /** @var string|null $description Optionale Produktbeschreibung */ $description = $_POST['description'] ?? null; $categoryID = (int)$_POST['categoryID']; $brandID = (int)($_POST['brandID'] ?? 0); /** @var string $imageUrl Optionale Bild-URL */ $imageUrl = trim((string)($_POST['imageUrl'] ?? '')); /** @var array|null $imageFile Das hochgeladene Dateiobjekt aus $_FILES */ $imageFile = (isset($_FILES['productImage']) && is_array($_FILES['productImage'])) ? $_FILES['productImage'] : null; /** @var bool $hasUpload Wahr, wenn eine Datei hochgeladen wurde und kein Fehler UPLOAD_ERR_NO_FILE vorliegt */ $hasUpload = $imageFile && isset($imageFile['error']) && (int)$imageFile['error'] !== UPLOAD_ERR_NO_FILE; $uploadMime = null; if ($debugMode) { $debugDetails['post_categoryID'] = $_POST['categoryID'] ?? null; $debugDetails['post_brandID'] = $_POST['brandID'] ?? null; $debugDetails['post_model'] = $model; $debugDetails['file_present'] = $imageFile !== null ? 'yes' : 'no'; $debugDetails['file_error'] = $imageFile['error'] ?? null; $debugDetails['file_name'] = $imageFile['name'] ?? null; $debugDetails['file_size'] = $imageFile['size'] ?? null; $debugDetails['file_tmp'] = isset($imageFile['tmp_name']) ? (string)$imageFile['tmp_name'] : null; $debugDetails['upload_max_filesize'] = ini_get('upload_max_filesize'); $debugDetails['post_max_size'] = ini_get('post_max_size'); } // Validierung der Pflichtfelder und hochgeladenen Dateien if ($categoryID <= 0) { $saveError = 'Bitte eine Kategorie auswählen.'; } elseif ($brandID <= 0) { $saveError = 'Bitte eine Marke auswählen.'; } elseif ($model === '') { $saveError = 'Bitte ein Modell angeben.'; } elseif ($imageUrl !== '' && !filter_var($imageUrl, FILTER_VALIDATE_URL)) { $saveError = 'Bitte eine gueltige Bild-URL eingeben.'; } elseif ($hasUpload) { $fileError = (int)$imageFile['error']; if ($fileError !== UPLOAD_ERR_OK) { $saveError = 'Bild-Upload fehlgeschlagen (Code ' . $fileError . ').'; } else { $tmp = isset($imageFile['tmp_name']) ? (string)$imageFile['tmp_name'] : ''; if ($tmp === '' || !is_uploaded_file($tmp)) { $saveError = 'Upload-Datei ungueltig.'; } else { $allowedMimeToExt = [ 'image/jpeg' => 'jpg', 'image/png' => 'png', ]; $mime = null; $imageInfo = @getimagesize($tmp); $imageType = (is_array($imageInfo) && isset($imageInfo[2])) ? (int)$imageInfo[2] : null; if ($imageType === IMAGETYPE_PNG) { $mime = 'image/png'; } elseif ($imageType === IMAGETYPE_JPEG) { $mime = 'image/jpeg'; } if (!$mime) { $finfo = new finfo(FILEINFO_MIME_TYPE); $mime = $finfo->file($tmp); } $fileExt = strtolower(pathinfo((string)($imageFile['name'] ?? ''), PATHINFO_EXTENSION)); if ($debugMode) { $debugDetails['getimagesize_mime'] = $imageInfo['mime'] ?? null; $debugDetails['getimagesize_type'] = $imageType; $debugDetails['finfo_mime'] = $mime; $debugDetails['file_ext'] = $fileExt; } if (!$mime || !isset($allowedMimeToExt[$mime])) { if (in_array($fileExt, ['jpg', 'jpeg', 'png'], true)) { $uploadMime = ($fileExt === 'png') ? 'image/png' : 'image/jpeg'; } else { $saveError = 'Nur JPG oder PNG sind erlaubt. Erkannter Typ: ' . ($mime ?: 'unbekannt'); } } else { $uploadMime = $mime; } } } } if ($saveError === null) { /** * @brief Produkt anlegen * Speichert die grundlegenden Produktdaten in der Tabelle 'products'. */ // --- Produkt anlegen --- $stmt = $conn->prepare(" INSERT INTO products (categoryID, brandID, model, description) VALUES (?, ?, ?, ?) "); if (!$stmt) { $saveError = 'Datenbankfehler beim Anlegen des Produkts.'; } else { $stmt->bind_param("iiss", $categoryID, $brandID, $model, $description); $ok = $stmt->execute(); if (!$ok) { error_log('Product insert failed: ' . $stmt->error); $saveError = 'Produkt konnte nicht gespeichert werden (DB-Fehler).'; if ($debugMode) { $debugDetails['db_error'] = $stmt->error; } } else { /** @var int $productID Die ID des neu erstellten Produkts (Last Insert ID) */ $productID = $stmt->insert_id; /** @var string|null $publicImagePath Der öffentliche Pfad zum gespeicherten Produktbild */ $publicImagePath = null; if ($hasUpload) { // Verarbeitung des hochgeladenen Bildes und Generierung des Zielpfades $relativeTargetDir = 'assets/images/products'; $dirTargetDir = rtrim(__DIR__, "\\/") . DIRECTORY_SEPARATOR . str_replace('/', DIRECTORY_SEPARATOR, $relativeTargetDir); $documentRoot = isset($_SERVER['DOCUMENT_ROOT']) ? (string)$_SERVER['DOCUMENT_ROOT'] : ''; $docRootTrim = rtrim($documentRoot, "\\/"); $docTargetDir = ($docRootTrim !== '') ? $docRootTrim . DIRECTORY_SEPARATOR . str_replace('/', DIRECTORY_SEPARATOR, $relativeTargetDir) : ''; $targetDir = $dirTargetDir; if ($docTargetDir !== '' && !is_dir($dirTargetDir) && is_dir($docTargetDir)) { $targetDir = $docTargetDir; } if (!is_dir($targetDir) && !@mkdir($targetDir, 0755, true)) { $saveError = 'Zielordner fuer Upload nicht verfuegbar.'; } elseif (!is_writable($targetDir)) { $saveError = 'Zielordner ist nicht beschreibbar.'; } else { $tmp = (string)$imageFile['tmp_name']; $mime = $uploadMime; if (!$mime) { $finfo = new finfo(FILEINFO_MIME_TYPE); $mime = $finfo->file($tmp); } $filename = $productID . '.png'; $targetPath = rtrim($targetDir, "\\/") . DIRECTORY_SEPARATOR . $filename; $savedOk = false; if ($mime === 'image/png') { $savedOk = move_uploaded_file($tmp, $targetPath); } elseif ($mime === 'image/jpeg') { $sourceImage = @imagecreatefromjpeg($tmp); if ($sourceImage !== false) { $savedOk = imagepng($sourceImage, $targetPath); imagedestroy($sourceImage); } } if ($savedOk) { $publicImagePath = $relativeTargetDir . '/' . $filename; } else { $saveError = 'Bild konnte nicht gespeichert werden.'; } } } elseif ($imageUrl !== '') { $publicImagePath = $imageUrl; } if ($saveError === null && $publicImagePath !== null) { /** * @brief Bildpfad aktualisieren * Aktualisiert den Datensatz des Produkts mit dem korrekten Bildpfad. */ $stmtImg = $conn->prepare("UPDATE products SET imagePath = ? WHERE productID = ?"); if ($stmtImg) { $stmtImg->bind_param("si", $publicImagePath, $productID); $stmtImg->execute(); } } /** * @brief Dynamische Attribute speichern * Iteriert über die übergebenen Attribute und speichert sie * typgerecht in der Tabelle 'productAttributes'. */ // --- Attribute speichern --- if (!empty($_POST['attributes'])) { $stmtAttr = $conn->prepare(" INSERT INTO productAttributes (productID, attributeID, valueString, valueNumber, valueBool) VALUES (?, ?, ?, ?, ?) "); foreach ($_POST['attributes'] as $attributeID => $value) { if ($value === '' || $value === null) { continue; } $valueString = null; $valueNumber = null; $valueBool = null; if (is_numeric($value)) { $valueNumber = $value; } elseif ($value === '0' || $value === '1') { $valueBool = (int)$value; } else { $valueString = trim($value); } $stmtAttr->bind_param( "iisdi", $productID, $attributeID, $valueString, $valueNumber, $valueBool ); $stmtAttr->execute(); } } if ($saveError === null) { // Nach erfolgreichem Speichern wird die Seite neu geladen (Post/Redirect/Get-Pattern) header("Location: productAdder.php?categoryID=" . $categoryID); exit; } } } } } // Inkludiert den Header-Bereich des HTML-Dokuments include 'header.php'; ?>

Kategorie wählen

0): ?>

Produkt hinzufügen

Erlaubt: JPG/PNG. max. 20MB.

Attribute

close(); include 'footer.php'; ?>