Code: Alles auswählen
<?php
/**
* Bento Download & Admin API - REPARIERTE VERSION (Original-Dateinamen & Bild-Fix)
* Erstellt eine SQLite-Datenbank für Extensions, verwaltet Uploads,
* Bildvorschauen, Live-Demos, Download-Zähler und Datumsstempel.
*/
header('Content-Type: application/json; charset=utf-8');
// Konfiguration
$dbFile = 'bento_downloads.sqlite';
$uploadDir = 'uploads/';
$adminPassword = 'volker04'; // 🔒 Hier dein echtes Passwort eintragen!
// Zeitzone für korrekte deutsche Uhrzeiten setzen
date_default_timezone_set('Europe/Berlin');
ini_set('display_errors', 0);
error_reporting(E_ALL);
try {
$db = new PDO("sqlite:" . $dbFile);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
$db->exec("CREATE TABLE IF NOT EXISTS bento_documents (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT NOT NULL,
filename TEXT NOT NULL,
filesize TEXT,
filetype TEXT,
preview_img TEXT,
demo_url TEXT,
downloads INTEGER DEFAULT 0,
created_at TEXT
)");
$stmt = $db->query("PRAGMA table_info(bento_documents)");
$columns = $stmt->fetchAll();
$hasCreatedAt = false;
foreach ($columns as $col) {
if ($col['name'] === 'created_at') {
$hasCreatedAt = true;
break;
}
}
if (!$hasCreatedAt) {
$db->exec("ALTER TABLE bento_documents ADD COLUMN created_at TEXT");
}
} catch (PDOException $e) {
echo json_encode(array('success' => false, 'error' => 'Datenbank-Fehler: ' . $e->getMessage()));
exit;
}
function formatBytes($bytes, $precision = 2) {
$units = array('B', 'KB', 'MB', 'GB');
$bytes = max($bytes, 0);
$pow = floor(($bytes ? log($bytes) : 0) / log(1024));
$pow = min($pow, count($units) - 1);
$bytes /= pow(1024, $pow);
return round($bytes, $precision) . ' ' . $units[$pow];
}
$inputData = json_decode(file_get_contents('php://input'), true) ?? array();
$action = $_POST['action'] ?? $inputData['action'] ?? '';
$passwordInput = $_POST['password'] ?? $inputData['password'] ?? '';
// ==========================================
// ROUTE 1: GET - Öffentliche Liste der Downloads laden
// ==========================================
if ($_SERVER['REQUEST_METHOD'] === 'GET' && !isset($_GET['adminCheck']) && !isset($_GET['file_id'])) {
try {
$stmt = $db->query("SELECT id, title, filesize, filetype, preview_img, demo_url, downloads, created_at FROM bento_documents ORDER BY id DESC");
$docs = $stmt->fetchAll();
echo json_encode(array('success' => true, 'docs' => $docs));
exit;
} catch (PDOException $e) {
echo json_encode(array('success' => false, 'error' => $e->getMessage()));
exit;
}
}
// ==========================================
// ROUTE 2: GET - Datei herunterladen & Zähler erhöhen
// ==========================================
if ($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['file_id'])) {
$fileId = intval($_GET['file_id']);
try {
$stmt = $db->prepare("SELECT * FROM bento_documents WHERE id = :id");
$stmt->execute(array(':id' => $fileId));
$doc = $stmt->fetch();
if ($doc) {
$filePath = $uploadDir . $doc['filename'];
if (file_exists($filePath)) {
$update = $db->prepare("UPDATE bento_documents SET downloads = downloads + 1 WHERE id = :id");
$update->execute(array(':id' => $fileId));
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . basename($doc['filename']) . '"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($filePath));
readfile($filePath);
exit;
} else {
echo "Datei nicht auf dem Server gefunden.";
exit;
}
}
} catch (PDOException $e) {
echo "Download-Fehler.";
exit;
}
}
// ==========================================
// ROUTE 3: GET - Admin-Liste laden (Passwortgeschützt)
// ==========================================
if ($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['adminCheck'])) {
if ($_GET['adminCheck'] !== $adminPassword) {
echo json_encode(array('success' => false, 'error' => 'Nicht autorisiert.'));
exit;
}
$stmt = $db->query("SELECT * FROM bento_documents ORDER BY id DESC");
$docs = $stmt->fetchAll();
echo json_encode(array('success' => true, 'docs' => $docs));
exit;
}
// ==========================================
// ROUTE 4: POST - Admin Aktionen verarbeiten
// ==========================================
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if ($action === 'checkLogin') {
if ($passwordInput === $adminPassword) {
echo json_encode(array('success' => true));
} else {
echo json_encode(array('success' => false, 'error' => 'Falsches Passwort'));
}
exit;
}
if ($passwordInput !== $adminPassword) {
echo json_encode(array('success' => false, 'error' => 'Ungültiges Passwort!'));
exit;
}
// Eintrag löschen
if ($action === 'deleteFile') {
$id = intval($inputData['id'] ?? 0);
$stmt = $db->prepare("SELECT filename, preview_img FROM bento_documents WHERE id = :id");
$stmt->execute(array(':id' => $id));
$doc = $stmt->fetch();
if ($doc) {
if (!empty($doc['filename']) && file_exists($uploadDir . $doc['filename'])) {
@unlink($uploadDir . $doc['filename']);
}
if (!empty($doc['preview_img']) && file_exists($uploadDir . $doc['preview_img'])) {
@unlink($uploadDir . $doc['preview_img']);
}
$del = $db->prepare("DELETE FROM bento_documents WHERE id = :id");
$del->execute(array(':id' => $id));
echo json_encode(array('success' => true, 'message' => 'Erfolgreich gelöscht!'));
} else {
echo json_encode(array('success' => false, 'error' => 'Eintrag nicht gefunden.'));
}
exit;
}
// Bearbeiten / Titel aktualisieren
if ($action === 'updateTitle') {
$id = intval($_POST['id'] ?? 0);
$newTitle = trim($_POST['title'] ?? '');
$newDemoUrl = trim($_POST['demo_url'] ?? '');
if (empty($newTitle)) {
echo json_encode(array('success' => false, 'error' => 'Titel darf nicht leer sein!'));
exit;
}
$previewFilename = null;
if (isset($_FILES['new_preview']) && $_FILES['new_preview']['error'] === UPLOAD_ERR_OK) {
$stmtImg = $db->prepare("SELECT preview_img FROM bento_documents WHERE id = :id");
$stmtImg->execute(array(':id' => $id));
$oldDoc = $stmtImg->fetch();
if ($oldDoc && !empty($oldDoc['preview_img']) && file_exists($uploadDir . $oldDoc['preview_img'])) {
@unlink($uploadDir . $oldDoc['preview_img']);
}
$pExt = strtolower(pathinfo($_FILES['new_preview']['name'], PATHINFO_EXTENSION));
// Sicherer, sauberer Vorschaubild-Name
$previewFilename = 'thumb_' . time() . '_' . bin2hex(random_bytes(4)) . '.' . $pExt;
// 🔥 FEHLER BEHOBEN: Hier stand fälschlicherweise move_uploaded_uploaded_file
move_uploaded_file($_FILES['new_preview']['tmp_name'], $uploadDir . $previewFilename);
}
if ($previewFilename !== null) {
$update = $db->prepare("UPDATE bento_documents SET title = :title, demo_url = :demo_url, preview_img = :preview_img WHERE id = :id");
$update->execute(array(':title' => $newTitle, ':demo_url' => $newDemoUrl, ':preview_img' => $previewFilename, ':id' => $id));
} else {
$update = $db->prepare("UPDATE bento_documents SET title = :title, demo_url = :demo_url WHERE id = :id");
$update->execute(array(':title' => $newTitle, ':demo_url' => $newDemoUrl, ':id' => $id));
}
echo json_encode(array('success' => true));
exit;
}
// Statistik zurücksetzen
if ($action === 'resetDownloads') {
try {
$db->exec("UPDATE bento_documents SET downloads = 0");
echo json_encode(array('success' => true, 'message' => 'Alle Zähler wurden auf 0 zurückgesetzt!'));
} catch (PDOException $e) {
echo json_encode(array('success' => false, 'error' => $e->getMessage()));
}
exit;
}
// Brandneuer Upload
if (isset($_FILES['file'])) {
$title = trim($_POST['title'] ?? 'Unbenannte Extension');
$demoUrl = trim($_POST['demo_url'] ?? '');
if ($_FILES['file']['error'] !== UPLOAD_ERR_OK) {
echo json_encode(array('success' => false, 'error' => 'Fehler beim Datei-Upload.'));
exit;
}
if (!is_dir($uploadDir)) {
mkdir($uploadDir, 0755, true);
}
// 🔥 FIX 2: Original-Dateinamen behalten & säubern
$origFilename = $_FILES['file']['name'];
$ext = strtolower(pathinfo($origFilename, PATHINFO_EXTENSION));
$pureName = pathinfo($origFilename, PATHINFO_FILENAME);
// Ungültige Zeichen aus dem Namen entfernen für saubere URLs
$cleanName = preg_replace('/[^A-Za-z0-9_\-]/', '_', $pureName);
$newFilename = $cleanName . '.' . $ext;
// Falls die Datei schon existiert, Nummer anhängen (z.B. block_1.mbrext)
$counter = 1;
while (file_exists($uploadDir . $newFilename)) {
$newFilename = $cleanName . '_' . $counter . '.' . $ext;
$counter++;
}
$sizeFormatted = formatBytes($_FILES['file']['size']);
if (!move_uploaded_file($_FILES['file']['tmp_name'], $uploadDir . $newFilename)) {
echo json_encode(array('success' => false, 'error' => 'Datei konnte nicht gespeichert werden.'));
exit;
}
// 🔥 FIX 1: Bildvorschau-Name stabilisieren
$previewFilename = '';
if (isset($_FILES['preview']) && $_FILES['preview']['error'] === UPLOAD_ERR_OK) {
$pExt = strtolower(pathinfo($_FILES['preview']['name'], PATHINFO_EXTENSION));
// Nutzt den sauberen Namen des Blocks auch für das Bild, damit der Pfad immer greift
$previewFilename = 'thumb_' . $cleanName . '_' . time() . '.' . $pExt;
move_uploaded_file($_FILES['preview']['tmp_name'], $uploadDir . $previewFilename);
}
try {
$stmt = $db->prepare("INSERT INTO bento_documents (title, filename, filesize, filetype, preview_img, demo_url, created_at) VALUES (:title, :filename, :filesize, :filetype, :preview_img, :demo_url, :created_at)");
$stmt->execute(array(
':title' => $title,
':filename' => $newFilename,
':filesize' => $sizeFormatted,
':filetype' => strtoupper($ext),
':preview_img' => $previewFilename,
':demo_url' => $demoUrl,
':created_at' => date('Y-m-d H:i:s')
));
echo json_encode(array('success' => true, 'message' => 'Extension erfolgreich hochgeladen!'));
} catch (PDOException $e) {
echo json_encode(array('success' => false, 'error' => 'Datenbank-Eintrag fehlgeschlagen: ' . $e->getMessage()));
}
exit;
}
}
echo json_encode(array('success' => false, 'error' => 'Ungültige Anfrage.'));
exit;
?>