heute mal was ohne KI
Ein simples aber geniales uploadscript das nur mit einer PIN klappt.
So kann man z.B. Kunden oder Usern die Möglichkeit geben Daten auf seinen Server zu laden wenn Mailversand nicht geht weil zu groß.
Wenn jemand was hoch geladen hat, bekommt der Admin eine Mail ( auch bei IONOS ) Ist eine Weiche drin die muss nur angemacht werden mit define('USE_SMTP', false); da auf true stellen
Die PIN wird auch im Script eingegeben und kann beliebig lang sein und alle Zeichen enthalten
Das ganze gibt es nur hier exklusiv in diesen Forum
Und hier ist es:
Code: Alles auswählen
<?php
// --- 1. SITZUNG STARTEN (Für das Admin-Login) ---
session_start();
// --- 2. KONFIGURATION ---
// HIER DEIN ADMIN-PASSWORT IM KLARTEXT EINTRAGEN (wird beim ersten Aufruf verschlüsselt hinterlegt)
define('ADMIN_PASSWORD_PLAIN', 'deinpasswort');
define('DB_FILE', __DIR__ . '/uploads_secure_db.sqlite'); // Pfad zur Mini-Datenbank
define('UPLOAD_DIR', __DIR__ . '/uploads/'); // Zielordner für Uploads mit htaccess sichern !!!
define('ADMIN_EMAIL', 'deine@mail.de'); // Wohin die Info-Mail gehen soll
// --- WEICHE: PHP MAIL ODER SMTP ---
define('USE_SMTP', false); // true = SMTP | false = php mail()
define('SMTP_HOST', 'smtp.ionos.de');
define('SMTP_PORT', 465);
define('SMTP_USER', 'deine-adresse@deine-domain.de');
define('SMTP_PASS', 'dein_ionos_passwort');
// Erlaubte Dateiendungen können hier angepasst werden
$allowedExtensions = ['jpg', 'jpeg', 'png', 'gif', 'pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'zip', 'rar', 'txt'];
$message = '';
$status = '';
$login_error = '';
// --- 3. DATENBANK INITIALISIEREN ---
try {
$db = new PDO("sqlite:" . DB_FILE);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// Tabelle für PINs (ohne Ablaufdatum, da dauerhaft gewollt)
$db->exec("CREATE TABLE IF NOT EXISTS customer_pins (
id INTEGER PRIMARY KEY AUTOINCREMENT,
customer_name TEXT NOT NULL,
pin TEXT NOT NULL UNIQUE,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
)");
} catch (Exception $e) {
die("Datenbank-Fehler: " . $e->getMessage());
}
// --- 4. ADMIN-LOGIK (LOGIN, LOGOUT, GENERIEREN, LÖSCHEN) ---
$isAdminView = (isset($_GET['view']) && $_GET['view'] === 'admin');
$isLoggedIn = (isset($_SESSION['admin_logged_in']) && $_SESSION['admin_logged_in'] === true);
// Passwort-Hash für den Vergleich generieren
$admin_password_hash = password_hash(ADMIN_PASSWORD_PLAIN, PASSWORD_DEFAULT);
// Login verarbeiten
if (isset($_POST['action_login'])) {
$entered_password = isset($_POST['admin_password']) ? $_POST['admin_password'] : '';
// Sicherer Hash-Vergleich
if (password_verify($entered_password, $admin_password_hash)) {
$_SESSION['admin_logged_in'] = true;
$isLoggedIn = true;
} else {
$login_error = 'Falsches Passwort!';
}
}
// Logout verarbeiten
if (isset($_GET['action']) && $_GET['action'] === 'logout') {
$_SESSION['admin_logged_in'] = false;
session_destroy();
header("Location: upload.php?view=admin");
exit;
}
// PIN generieren (Eingeloggt)
if ($isLoggedIn && $_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action_generate'])) {
$newCustomer = trim($_POST['target_customer']);
if (!empty($newCustomer)) {
$newPin = random_int(100000, 999999);
try {
$stmt = $db->prepare("INSERT INTO customer_pins (customer_name, pin) VALUES (:name, :pin)");
$stmt->execute([':name' => $newCustomer, ':pin' => $newPin]);
header("Location: upload.php?view=admin&success=1");
exit;
} catch (Exception $e) {
$message = "Fehler beim Speichern der PIN: " . $e->getMessage();
$status = "danger";
}
}
}
// PIN löschen (Eingeloggt)
if ($isLoggedIn && isset($_GET['action']) && $_GET['action'] === 'delete' && isset($_GET['id'])) {
$deleteId = (int)$_GET['id'];
$stmt = $db->prepare("DELETE FROM customer_pins WHERE id = :id");
$stmt->execute([':id' => $deleteId]);
header("Location: upload.php?view=admin");
exit;
}
// --- 5. KUNDEN-LOGIK: UPLOAD VERARBEITEN ---
if ($_SERVER['REQUEST_METHOD'] === 'POST' && !isset($_POST['action_generate']) && !isset($_POST['action_login'])) {
$kundeName = isset($_POST['name']) ? trim($_POST['name']) : '';
$kundeEmail = isset($_POST['email']) ? trim($_POST['email']) : '';
$userPin = isset($_POST['pin']) ? trim($_POST['pin']) : '';
// DB-Abfrage: Existiert die PIN (Dauerhaft gültig)?
$stmt = $db->prepare("SELECT customer_name FROM customer_pins WHERE pin = :pin LIMIT 1");
$stmt->execute([':pin' => $userPin]);
$pinRow = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$pinRow) {
$status = 'danger';
$message = 'Fehler: Die eingegebene PIN ist ungültig!';
}
elseif (empty($kundeName) || empty($kundeEmail) || !isset($_FILES['userfiles'])) {
$status = 'danger';
$message = 'Fehler: Bitte fülle alle Felder aus.';
}
else {
$files = $_FILES['userfiles'];
$fileCount = count($files['name']);
$uploadedFilesList = [];
$errors = [];
if (!is_dir(UPLOAD_DIR)) {
mkdir(UPLOAD_DIR, 0755, true);
}
for ($i = 0; $i < $fileCount; $i++) {
if ($files['error'][$i] === UPLOAD_ERR_NO_FILE) continue;
if ($files['error'][$i] !== UPLOAD_ERR_OK) {
$errors[] = "Fehler bei Datei '" . htmlspecialchars($files['name'][$i]) . "' (Code: " . $files['error'][$i] . ")";
continue;
}
$originalFilename = $files['name'][$i];
$ext = strtolower(pathinfo($originalFilename, PATHINFO_EXTENSION));
if (!in_array($ext, $allowedExtensions)) {
$errors[] = "Datei '" . htmlspecialchars($originalFilename) . "' hat einen unzulässigen Dateityp.";
continue;
}
$cleanName = preg_replace('/[^a-zA-Z0-9_-]/', '_', $kundeName);
$serverFilename = time() . '_' . $i . '_' . $cleanName . '.' . $ext;
$destination = UPLOAD_DIR . $serverFilename;
if (move_uploaded_file($files['tmp_name'][$i], $destination)) {
$uploadedFilesList[] = "- " . $originalFilename . " (gespeichert als: " . $serverFilename . ")";
} else {
$errors[] = "Datei '" . htmlspecialchars($originalFilename) . "' konnte nicht gespeichert werden.";
}
}
if (count($uploadedFilesList) > 0) {
$status = 'success';
$message = "<strong>Erfolgreich hochgeladen!</strong> " . count($uploadedFilesList) . " Datei(en) wurden sicher gespeichert.";
if (count($errors) > 0) {
$message .= "<br>Fehler bei einigen Dateien:<br>" . implode("<br>", $errors);
}
// E-MAIL AN ADMIN
$subject = "Neuer Kunden-Upload (" . count($uploadedFilesList) . " Dateien): " . $kundeName;
$mailBody = "Hallo Admin,\n\ein Kunde (validiert via PIN) hat Dateien hochgeladen.\n\nFormular-Name: $kundeName\nHinterlegt auf PIN von: " . $pinRow['customer_name'] . "\nE-Mail: $kundeEmail\nDatum: " . date('d.m.Y H:i:s') . "\n\n";
$mailBody .= "--- Dateien ---\n" . implode("\n", $uploadedFilesList) . "\n\n";
if (USE_SMTP) {
send_hybrid_smtp($subject, $mailBody, $kundeEmail);
} else {
$headers = ['From' => 'upload@' . $_SERVER['SERVER_NAME'], 'Reply-To' => $kundeEmail, 'Content-Type' => 'text/plain; charset=UTF-8'];
@mail(ADMIN_EMAIL, $subject, $mailBody, $headers);
}
} else {
$status = 'danger';
$message = "Es wurden keine Dateien hochgeladen.<br>" . implode("<br>", $errors);
}
}
}
// --- 6. NATIVE SMTP-FUNKTION ---
function send_hybrid_smtp($subject, $body, $replyTo) {
$context = (SMTP_PORT == 465) ? 'ssl://' : '';
$socket = @fsockopen($context . SMTP_HOST, SMTP_PORT, $errno, $errstr, 15);
if (!$socket) return false;
fgets($socket, 515); fwrite($socket, "EHLO " . $_SERVER['SERVER_NAME'] . "\r\n"); fgets($socket, 515);
fwrite($socket, "AUTH LOGIN\r\n"); fgets($socket, 515);
fwrite($socket, base64_encode(SMTP_USER) . "\r\n"); fgets($socket, 515);
fwrite($socket, base64_encode(SMTP_PASS) . "\r\n"); fgets($socket, 515);
fwrite($socket, "MAIL FROM:<" . SMTP_USER . ">\r\n"); fgets($socket, 515);
fwrite($socket, "RCPT TO:<" . ADMIN_EMAIL . ">\r\n"); fgets($socket, 515);
fwrite($socket, "DATA\r\n"); fgets($socket, 515);
$headers = "From: <" . SMTP_USER . ">\r\nTo: <" . ADMIN_EMAIL . ">\r\nReply-To: <" . $replyTo . ">\r\nSubject: =?UTF-8?B?" . base64_encode($subject) . "?=\r\nMIME-Version: 1.0\r\nContent-Type: text/plain; charset=UTF-8\r\n\r\n";
fwrite($socket, $headers . $body . "\r\n.\r\n"); fgets($socket, 515);
fwrite($socket, "QUIT\r\n"); fclose($socket); return true;
}
?>
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?= $isAdminView ? 'Admin-Panel' : 'Sicherer Datei-Upload'; ?></title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
body { background-color: #f8f9fa; }
.upload-card, .admin-card { max-width: 700px; margin: 40px auto; border: none; box-shadow: 0 4px 12px rgba(0,0,0,0.1); }
</style>
</head>
<body>
<div class="container">
<?php if ($isAdminView): ?>
<?php if (!$isLoggedIn): ?>
<div class="card admin-card mt-5" style="max-width: 450px;">
<div class="card-header bg-dark text-white text-center py-3">
<h5 class="mb-0">🔒 Admin-Anmeldung</h5>
</div>
<div class="card-body p-4">
<?php if (!empty($login_error)): ?>
<div class="alert alert-danger"><?= $login_error; ?></div>
<?php endif; ?>
<form action="upload.php?view=admin" method="POST">
<input type="hidden" name="action_login" value="1">
<div class="mb-3">
<label for="admin_password" class="form-label">Admin-Passwort</label>
<input type="password" class="form-control" id="admin_password" name="admin_password" required autofocus>
</div>
<div class="d-grid">
<button type="submit" class="btn btn-dark">Einloggen</button>
</div>
</form>
</div>
</div>
<?php else: ?>
<div class="d-flex justify-content-between align-items-center mt-4 mb-3" style="max-width:700px; margin:auto;">
<h4>⚙️ Admin-Verwaltungspanel</h4>
<a href="upload.php?view=admin&action=logout" class="btn btn-sm btn-outline-danger">Abmelden</a>
</div>
<div class="card admin-card mt-2">
<div class="card-header bg-danger text-white">
<h5 class="mb-0">🔑 Neue Kunden-PIN generieren</h5>
</div>
<div class="card-body">
<?php if (isset($_GET['success'])): ?>
<div class="alert alert-success">PIN erfolgreich generiert und dauerhaft gespeichert!</div>
<?php endif; ?>
<form action="upload.php?view=admin" method="POST">
<input type="hidden" name="action_generate" value="1">
<div class="input-group mb-3">
<input type="text" class="form-control" name="target_customer" required placeholder="Kunde / Firma (z.B. Autohaus Schmidt)" aria-label="Kundenname">
<button class="btn btn-danger" type="submit">Generieren</button>
</div>
</form>
</div>
</div>
<div class="card admin-card mt-4">
<div class="card-header bg-secondary text-white">
<h5 class="mb-0">📋 Aktive Kunden-PINs (Dauerhaft)</h5>
</div>
<div class="table-responsive p-3">
<table class="table table-striped align-middle mb-0">
<thead>
<tr>
<th>Kunde / Zuordnung</th>
<th>PIN (Geheimzahl)</th>
<th>Erstellt am</th>
<th class="text-end">Aktion</th>
</tr>
</thead>
<tbody>
<?php
$stmt = $db->query("SELECT * FROM customer_pins ORDER BY id DESC");
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
if (count($rows) === 0):
?>
<tr><td colspan="4" class="text-center text-muted">Noch keine PINs generiert.</td></tr>
<?php else: foreach ($rows as $row): ?>
<tr>
<td><strong><?= htmlspecialchars($row['customer_name']); ?></strong></td>
<td><span class="badge bg-dark fs-6 font-monospace"><?= htmlspecialchars($row['pin']); ?></span></td>
<td class="small text-muted"><?= date('d.m.Y H:i', strtotime($row['created_at'])); ?></td>
<td class="text-end">
<a href="upload.php?view=admin&action=delete&id=<?= $row['id']; ?>" class="btn btn-sm btn-danger" onclick="return confirm('Möchtest du diese PIN wirklich unwiderruflich löschen? Der Kunde verliert sofort den Zugriff.');">Löschen</a>
</td>
</tr>
<?php endforeach; endif; ?>
</tbody>
</table>
</div>
</div>
<div class="text-center mt-3">
<a href="upload.php" class="text-muted small">Zur Standard-Upload-Seite wechseln</a>
</div>
<?php endif; ?>
<?php else: ?>
<div class="card upload-card">
<div class="card-header bg-primary text-white text-center py-3">
<h4 class="mb-0">Kunden-Upload-Bereich</h4>
</div>
<div class="card-body p-4">
<?php if (!empty($message)): ?>
<div class="alert alert-<?= $status; ?> alert-dismissible fade show" role="alert">
<?= $message; ?>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
<?php endif; ?>
<form action="upload.php" method="POST" enctype="multipart/form-data">
<div class="mb-3">
<label for="name" class="form-label">Dein Name / Firma *</label>
<input type="text" class="form-control" id="name" name="name" required placeholder="Max Mustermann">
</div>
<div class="mb-3">
<label for="email" class="form-label">Deine E-Mail-Adresse *</label>
<input type="email" class="form-control" id="email" name="email" required placeholder="max@beispiel.de">
</div>
<div class="mb-3">
<label for="pin" class="form-label">Upload-PIN *</label>
<input type="text" class="form-control font-monospace" id="pin" name="pin" required placeholder="6-stellige Nummer eingeben">
<div class="form-text">Bitte gib die PIN ein, die du von uns erhalten hast.</div>
</div>
<div class="mb-4">
<label for="userfile" class="form-label">Dateien auswählen * (Mehrfach-Auswahl möglich)</label>
<input class="form-control" type="file" id="userfile" name="userfiles[]" required multiple>
</div>
<div class="d-grid">
<button type="submit" class="btn btn-primary btn-lg">Alle Dateien jetzt hochladen</button>
</div>
</form>
</div>
</div>
<?php endif; ?>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
