Files
cazubu/ajax_handler.php
Gemini Bot 61ede4c325
All checks were successful
Docker Build & Push / build-and-push (push) Successful in 1m36s
Initial commit: Dockerize Cazubu
2025-12-07 17:09:16 +00:00

358 lines
25 KiB
PHP

<?php
require_once 'includes/auth_check.php';
require_once 'includes/db_connect.php';
header('Content-Type: application/json');
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$action = $_POST['action'] ?? $_GET['action'] ?? '';
$user_id = $_SESSION['user_id'];
try {
switch ($action) {
case 'add_zone':
if (empty(trim($_POST['name']))) { echo json_encode(['success' => false, 'message' => 'Name darf nicht leer sein.']); exit; }
$sql = "INSERT INTO zones (user_id, name) VALUES (?, ?)";
if ($stmt = $mysqli->prepare($sql)) { $stmt->bind_param("is", $user_id, trim($_POST['name'])); $stmt->execute(); echo json_encode(['success' => true]); }
break;
case 'edit_zone':
if (empty(trim($_POST['name'])) || empty($_POST['id'])) { echo json_encode(['success' => false, 'message' => 'Unvollständige Daten.']); exit; }
$sql = "UPDATE zones SET name = ? WHERE id = ? AND user_id = ?";
if ($stmt = $mysqli->prepare($sql)) { $stmt->bind_param("sii", trim($_POST['name']), $_POST['id'], $user_id); $stmt->execute(); echo json_encode(['success' => true]); }
break;
case 'delete_zone':
if (empty($_POST['id'])) { echo json_encode(['success' => false, 'message' => 'Fehlende ID.']); exit; }
$sql = "DELETE FROM zones WHERE id = ? AND user_id = ?";
if ($stmt = $mysqli->prepare($sql)) { $stmt->bind_param("ii", $_POST['id'], $user_id); $stmt->execute(); echo json_encode(['success' => true]); }
break;
case 'add_container':
if (empty(trim($_POST['name'])) || empty($_POST['zone_id'])) { echo json_encode(['success' => false, 'message' => 'Name und Zone sind Pflichtfelder.']); exit; }
$sql = "INSERT INTO containers (user_id, name, zone_id) VALUES (?, ?, ?)";
if ($stmt = $mysqli->prepare($sql)) { $stmt->bind_param("isi", $user_id, trim($_POST['name']), $_POST['zone_id']); $stmt->execute(); echo json_encode(['success' => true]); }
break;
case 'edit_container':
if (empty(trim($_POST['name'])) || empty($_POST['zone_id']) || empty($_POST['id'])) { echo json_encode(['success' => false, 'message' => 'Alle Felder sind Pflicht.']); exit; }
$sql = "UPDATE containers SET name = ?, zone_id = ? WHERE id = ? AND user_id = ?";
if ($stmt = $mysqli->prepare($sql)) { $stmt->bind_param("siii", trim($_POST['name']), $_POST['zone_id'], $_POST['id'], $user_id); $stmt->execute(); echo json_encode(['success' => true]); }
break;
case 'delete_container':
if (empty($_POST['id'])) { echo json_encode(['success' => false, 'message' => 'Fehlende ID.']); exit; }
$sql = "DELETE FROM containers WHERE id = ? AND user_id = ?";
if ($stmt = $mysqli->prepare($sql)) { $stmt->bind_param("ii", $_POST['id'], $user_id); $stmt->execute(); echo json_encode(['success' => true]); }
break;
case 'add_seed':
if (empty(trim($_POST['strain_name']))) { echo json_encode(['success' => false, 'message' => 'Sortenname ist ein Pflichtfeld.']); exit; }
$sql = "INSERT INTO seeds (user_id, strain_name, internal_name, info_url, ratio_sativa, is_autoflower, stock_count, description) VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
if ($stmt = $mysqli->prepare($sql)) { $is_autoflower = isset($_POST['is_autoflower']) ? 1 : 0; $stmt->bind_param("isssiiis", $user_id, $_POST['strain_name'], $_POST['internal_name'], $_POST['info_url'], $_POST['ratio_sativa'], $is_autoflower, $_POST['stock_count'], $_POST['description']); $stmt->execute(); echo json_encode(['success' => true]); }
break;
case 'edit_seed':
if (empty(trim($_POST['strain_name'])) || empty($_POST['id'])) { echo json_encode(['success' => false, 'message' => 'ID und Sortenname sind Pflichtfelder.']); exit; }
$sql = "UPDATE seeds SET strain_name = ?, internal_name = ?, info_url = ?, ratio_sativa = ?, is_autoflower = ?, stock_count = ?, description = ? WHERE id = ? AND user_id = ?";
if ($stmt = $mysqli->prepare($sql)) { $is_autoflower = isset($_POST['is_autoflower']) ? 1 : 0; $stmt->bind_param("sssiiisii", $_POST['strain_name'], $_POST['internal_name'], $_POST['info_url'], $_POST['ratio_sativa'], $is_autoflower, $_POST['stock_count'], $_POST['description'], $_POST['id'], $user_id); $stmt->execute(); echo json_encode(['success' => true]); }
break;
case 'delete_seed':
if (empty($_POST['id'])) { echo json_encode(['success' => false, 'message' => 'Fehlende ID.']); exit; }
$sql = "DELETE FROM seeds WHERE id = ? AND user_id = ?";
if ($stmt = $mysqli->prepare($sql)) { $stmt->bind_param("ii", $_POST['id'], $user_id); if ($stmt->execute()) { echo json_encode(['success' => true]); } }
break;
case 'get_containers_by_zone':
if (empty($_GET['zone_id']) || !is_numeric($_GET['zone_id'])) { echo json_encode(['success' => false, 'message' => 'Keine oder ungültige Zone ID.']); exit; }
$zone_id = $_GET['zone_id'];
$containers = [];
$sql = "SELECT id, name FROM containers WHERE user_id = ? AND zone_id = ? AND id NOT IN (SELECT container_id FROM plants WHERE status = 'Eingepflanzt')";
if ($stmt = $mysqli->prepare($sql)) { $stmt->bind_param("ii", $user_id, $zone_id); $stmt->execute(); $result = $stmt->get_result(); while($row = $result->fetch_assoc()) { $containers[] = $row; } $stmt->close(); }
echo json_encode(['success' => true, 'data' => $containers]);
break;
case 'add_plant':
if (empty($_POST['zone_id']) || empty($_POST['container_id']) || empty($_POST['seed_id']) || empty($_POST['plant_date'])) { echo json_encode(['success' => false, 'message' => 'Bitte alle Felder ausfüllen.']); exit; }
$mysqli->begin_transaction();
$sql_insert = "INSERT INTO plants (user_id, zone_id, container_id, seed_id, plant_date, phase, status) VALUES (?, ?, ?, ?, ?, 'Keimend', 'Eingepflanzt')";
$stmt_insert = $mysqli->prepare($sql_insert);
$stmt_insert->bind_param("iiiis", $user_id, $_POST['zone_id'], $_POST['container_id'], $_POST['seed_id'], $_POST['plant_date']);
$stmt_insert->execute();
$new_plant_id = $stmt_insert->insert_id;
$stmt_insert->close();
if (isset($_POST['reduce_seed_stock']) && $_POST['reduce_seed_stock'] == '1') {
$sql_update = "UPDATE seeds SET stock_count = stock_count - 1 WHERE id = ? AND user_id = ? AND stock_count > 0";
$stmt_update = $mysqli->prepare($sql_update);
$stmt_update->bind_param("ii", $_POST['seed_id'], $user_id);
$stmt_update->execute();
$stmt_update->close();
}
$sql_activity = "INSERT INTO plant_activities (plant_id, activity_type, note, activity_date) VALUES (?, 'Pflanzung', 'Pflanze wurde erstellt.', ?)";
$stmt_activity = $mysqli->prepare($sql_activity);
$stmt_activity->bind_param("is", $new_plant_id, $_POST['plant_date']);
$stmt_activity->execute();
$stmt_activity->close();
$mysqli->commit();
echo json_encode(['success' => true]);
break;
case 'edit_plant':
if (empty($_POST['plant_id']) || empty($_POST['phase']) || empty($_POST['plant_date']) || empty($_POST['zone_id']) || empty($_POST['container_id'])) { echo json_encode(['success' => false, 'message' => 'Alle Felder sind Pflichtfelder.']); exit; }
$mysqli->begin_transaction();
$old_phase_stmt = $mysqli->prepare("SELECT phase FROM plants WHERE id = ? AND user_id = ?");
$old_phase_stmt->bind_param("ii", $_POST['plant_id'], $user_id);
$old_phase_stmt->execute();
$old_phase_result = $old_phase_stmt->get_result();
$old_phase = ($old_phase_result->num_rows > 0) ? $old_phase_result->fetch_assoc()['phase'] : null;
$old_phase_stmt->close();
$sql = "UPDATE plants SET phase = ?, plant_date = ?, zone_id = ?, container_id = ? WHERE id = ? AND user_id = ?";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param("ssiiii", $_POST['phase'], $_POST['plant_date'], $_POST['zone_id'], $_POST['container_id'], $_POST['plant_id'], $user_id);
$stmt->execute();
$stmt->close();
if ($old_phase !== null && $old_phase !== $_POST['phase']) {
$note = "Phase geändert von '{$old_phase}' zu '{$_POST['phase']}'.";
$sql_activity = "INSERT INTO plant_activities (plant_id, activity_type, note, activity_date) VALUES (?, 'Phasenwechsel', ?, NOW())";
$stmt_activity = $mysqli->prepare($sql_activity);
$stmt_activity->bind_param("is", $_POST['plant_id'], $note);
$stmt_activity->execute();
$stmt_activity->close();
}
$mysqli->commit();
echo json_encode(['success' => true]);
break;
case 'delete_plant':
if (empty($_POST['id']) || !is_numeric($_POST['id'])) { echo json_encode(['success' => false, 'message' => 'Ungültige Pflanzen-ID.']); exit; }
$plant_id = $_POST['id'];
$sql = "DELETE FROM plants WHERE id = ? AND user_id = ?";
if ($stmt = $mysqli->prepare($sql)) {
$stmt->bind_param("ii", $plant_id, $user_id);
if ($stmt->execute()) {
if ($stmt->affected_rows > 0) { echo json_encode(['success' => true]); }
else { echo json_encode(['success' => false, 'message' => 'Pflanze nicht gefunden oder keine Berechtigung.']); }
}
}
break;
case 'upload_plant_image':
$plant_id = $_POST['plant_id'] ?? 0;
if (empty($plant_id) || !isset($_FILES['plant_image'])) { echo json_encode(['success' => false, 'message' => 'Fehlende Daten.']); exit; }
$sql_check = "SELECT id FROM plants WHERE id = ? AND user_id = ?";
$stmt_check = $mysqli->prepare($sql_check); $stmt_check->bind_param("ii", $plant_id, $user_id); $stmt_check->execute();
if ($stmt_check->get_result()->num_rows === 0) { echo json_encode(['success' => false, 'message' => 'Keine Berechtigung.']); exit; }
$stmt_check->close();
$file = $_FILES['plant_image'];
if ($file['error'] !== UPLOAD_ERR_OK) { echo json_encode(['success' => false, 'message' => 'Fehler beim Upload: ' . $file['error']]); exit; }
$allowed_types = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
if (!in_array($file['type'], $allowed_types)) { echo json_encode(['success' => false, 'message' => 'Ungültiger Dateityp.']); exit; }
$upload_dir = 'uploads/user_' . $user_id . '/';
if (!is_dir($upload_dir)) { mkdir($upload_dir, 0755, true); }
$file_extension = pathinfo($file['name'], PATHINFO_EXTENSION);
$new_filename = uniqid('plant_' . $plant_id . '_', true) . '.' . $file_extension;
$destination = $upload_dir . $new_filename;
if (move_uploaded_file($file['tmp_name'], $destination)) {
$sql_insert = "INSERT INTO plant_images (plant_id, user_id, file_path) VALUES (?, ?, ?)";
$stmt_insert = $mysqli->prepare($sql_insert);
$stmt_insert->bind_param("iis", $plant_id, $user_id, $destination);
$stmt_insert->execute();
$stmt_insert->close();
echo json_encode(['success' => true]);
} else { echo json_encode(['success' => false, 'message' => 'Datei konnte nicht verschoben werden.']); }
break;
case 'delete_plant_image':
if (empty($_POST['id']) || !is_numeric($_POST['id'])) { echo json_encode(['success' => false, 'message' => 'Ungültige Bild-ID.']); exit; }
$image_id = $_POST['id']; $file_path = '';
$sql_select = "SELECT pi.file_path FROM plant_images pi WHERE pi.id = ? AND pi.user_id = ?";
if ($stmt_select = $mysqli->prepare($sql_select)) { $stmt_select->bind_param("ii", $image_id, $user_id); $stmt_select->execute(); $result = $stmt_select->get_result(); if ($result->num_rows === 1) { $file_path = $result->fetch_assoc()['file_path']; } $stmt_select->close(); }
if (empty($file_path)) { echo json_encode(['success' => false, 'message' => 'Bild nicht gefunden oder keine Berechtigung.']); exit; }
$sql_delete = "DELETE FROM plant_images WHERE id = ? AND user_id = ?";
if ($stmt_delete = $mysqli->prepare($sql_delete)) {
$stmt_delete->bind_param("ii", $image_id, $user_id);
$stmt_delete->execute();
if ($stmt_delete->affected_rows > 0) {
if (file_exists($file_path)) { unlink($file_path); }
echo json_encode(['success' => true]);
} else { echo json_encode(['success' => false, 'message' => 'Fehler beim Löschen des Datenbankeintrags.']); }
$stmt_delete->close();
}
break;
case 'harvest_plant':
if (empty($_POST['plant_id']) || !is_numeric($_POST['plant_id'])) { echo json_encode(['success' => false, 'message' => 'Ungültige Pflanzen-ID.']); exit; }
$plant_id = $_POST['plant_id']; $mysqli->begin_transaction();
$sql = "UPDATE plants SET status = 'Trocknend', phase = 'Ernte' WHERE id = ? AND user_id = ? AND status = 'Eingepflanzt'";
if ($stmt = $mysqli->prepare($sql)) {
$stmt->bind_param("ii", $plant_id, $user_id);
$stmt->execute();
if ($stmt->affected_rows > 0) {
$note = "Pflanze geerntet, Status auf 'Trocknend' gesetzt.";
$sql_activity = "INSERT INTO plant_activities (plant_id, activity_type, note, activity_date) VALUES (?, 'Ernte', ?, NOW())";
$stmt_activity = $mysqli->prepare($sql_activity);
$stmt_activity->bind_param("is", $plant_id, $note);
$stmt_activity->execute();
$stmt_activity->close();
$mysqli->commit();
echo json_encode(['success' => true]);
} else { $mysqli->rollback(); echo json_encode(['success' => false, 'message' => 'Aktion konnte nicht ausgeführt werden.']); }
$stmt->close();
}
break;
case 'finish_drying':
if (empty($_POST['plant_id']) || !is_numeric($_POST['plant_id'])) { echo json_encode(['success' => false, 'message' => 'Ungültige Pflanzen-ID.']); exit; }
$plant_id = $_POST['plant_id']; $mysqli->begin_transaction();
$sql = "UPDATE plants SET status = 'Geerntet', phase = 'Getrocknet' WHERE id = ? AND user_id = ? AND status = 'Trocknend'";
if ($stmt = $mysqli->prepare($sql)) {
$stmt->bind_param("ii", $plant_id, $user_id);
$stmt->execute();
if ($stmt->affected_rows > 0) {
$note = "Trocknung abgeschlossen, Status auf 'Geerntet' gesetzt.";
$sql_activity = "INSERT INTO plant_activities (plant_id, activity_type, note, activity_date) VALUES (?, 'Trocknung', ?, NOW())";
$stmt_activity = $mysqli->prepare($sql_activity);
$stmt_activity->bind_param("is", $plant_id, $note);
$stmt_activity->execute();
$stmt_activity->close();
$mysqli->commit();
echo json_encode(['success' => true]);
} else { $mysqli->rollback(); echo json_encode(['success' => false, 'message' => 'Aktion konnte nicht ausgeführt werden.']); }
$stmt->close();
}
break;
case 'add_activity':
if (empty($_POST['plant_id']) || empty($_POST['activity_type']) || empty($_POST['activity_date'])) { echo json_encode(['success' => false, 'message' => 'Unvollständige Daten.']); exit; }
$sql = "INSERT INTO plant_activities (plant_id, activity_type, note, activity_date) VALUES (?, ?, ?, ?)";
if ($stmt = $mysqli->prepare($sql)) {
$stmt->bind_param("isss", $_POST['plant_id'], $_POST['activity_type'], $_POST['note'], $_POST['activity_date']);
$stmt->execute();
echo json_encode(['success' => true]);
}
break;
case 'add_measurement':
if (empty($_POST['plant_id']) || !isset($_POST['height_cm']) || empty($_POST['measurement_date'])) { echo json_encode(['success' => false, 'message' => 'Unvollständige Daten.']); exit; }
$sql = "INSERT INTO plant_height_measurements (plant_id, height_cm, measurement_date) VALUES (?, ?, ?)";
if ($stmt = $mysqli->prepare($sql)) {
$stmt->bind_param("ids", $_POST['plant_id'], $_POST['height_cm'], $_POST['measurement_date']);
$stmt->execute();
echo json_encode(['success' => true]);
}
break;
case 'generate_api_key':
$new_key = bin2hex(random_bytes(16));
$sql = "UPDATE users SET api_key = ? WHERE id = ?";
if ($stmt = $mysqli->prepare($sql)) {
$stmt->bind_param("si", $new_key, $user_id);
if ($stmt->execute()) { echo json_encode(['success' => true, 'message' => 'Neuer API-Key wurde generiert.']); }
}
break;
case 'change_username':
if (empty(trim($_POST['username']))) { echo json_encode(['success' => false, 'message' => 'Benutzername darf nicht leer sein.']); exit; }
$new_username = trim($_POST['username']);
$sql_check = "SELECT id FROM users WHERE username = ? AND id != ?";
$stmt_check = $mysqli->prepare($sql_check);
$stmt_check->bind_param("si", $new_username, $user_id);
$stmt_check->execute();
if ($stmt_check->get_result()->num_rows > 0) { echo json_encode(['success' => false, 'message' => 'Dieser Benutzername ist bereits vergeben.']); exit; }
$stmt_check->close();
$sql_update = "UPDATE users SET username = ? WHERE id = ?";
$stmt_update = $mysqli->prepare($sql_update);
$stmt_update->bind_param("si", $new_username, $user_id);
$stmt_update->execute();
$_SESSION['username'] = $new_username;
echo json_encode(['success' => true, 'message' => 'Benutzername erfolgreich geändert.']);
break;
case 'change_password':
if (empty($_POST['current_password']) || empty($_POST['new_password']) || empty($_POST['confirm_new_password'])) { echo json_encode(['success' => false, 'message' => 'Alle Felder sind erforderlich.']); exit; }
if ($_POST['new_password'] !== $_POST['confirm_new_password']) { echo json_encode(['success' => false, 'message' => 'Die neuen Passwörter stimmen nicht überein.']); exit; }
if (strlen($_POST['new_password']) < 6) { echo json_encode(['success' => false, 'message' => 'Das neue Passwort muss mindestens 6 Zeichen lang sein.']); exit; }
$sql_pass = "SELECT password_hash FROM users WHERE id = ?";
$stmt_pass = $mysqli->prepare($sql_pass);
$stmt_pass->bind_param("i", $user_id);
$stmt_pass->execute();
$result_pass = $stmt_pass->get_result()->fetch_assoc();
$stmt_pass->close();
if (!password_verify($_POST['current_password'], $result_pass['password_hash'])) { echo json_encode(['success' => false, 'message' => 'Das aktuelle Passwort ist nicht korrekt.']); exit; }
$new_password_hash = password_hash($_POST['new_password'], PASSWORD_DEFAULT);
$sql_update_pass = "UPDATE users SET password_hash = ? WHERE id = ?";
$stmt_update_pass = $mysqli->prepare($sql_update_pass);
$stmt_update_pass->bind_param("si", $new_password_hash, $user_id);
$stmt_update_pass->execute();
echo json_encode(['success' => true, 'message' => 'Passwort erfolgreich geändert.']);
break;
case 'get_all_zones':
$zones = [];
$sql = "SELECT id, name FROM zones WHERE user_id = ? ORDER BY name ASC";
if ($stmt = $mysqli->prepare($sql)) {
$stmt->bind_param("i", $user_id);
$stmt->execute();
$result = $stmt->get_result();
while($row = $result->fetch_assoc()) { $zones[] = $row; }
$stmt->close();
}
echo json_encode(['success' => true, 'data' => $zones]);
break;
case 'get_plants_by_zone':
$zone_id = $_GET['zone_id'] ?? 'all';
$plants = [];
$sql = "SELECT p.id, COALESCE(s.strain_name, '[Sorte gelöscht]') as strain_name, COALESCE(c.name, '[Gefäß gelöscht]') as container_name FROM plants p LEFT JOIN seeds s ON p.seed_id = s.id LEFT JOIN containers c ON p.container_id = c.id WHERE p.user_id = ? AND p.status = 'Eingepflanzt'";
if (is_numeric($zone_id)) {
$sql .= " AND p.zone_id = ?";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param("ii", $user_id, $zone_id);
} else {
$stmt = $mysqli->prepare($sql);
$stmt->bind_param("i", $user_id);
}
$stmt->execute();
$result = $stmt->get_result();
while($row = $result->fetch_assoc()) {
$plants[] = $row;
}
$stmt->close();
echo json_encode(['success' => true, 'data' => $plants]);
break;
case 'add_global_activity':
if (empty($_POST['activity_type']) || empty($_POST['activity_date']) || empty($_POST['plant_ids'])) { echo json_encode(['success' => false, 'message' => 'Unvollständige Daten.']); exit; }
$plant_ids = $_POST['plant_ids'];
$mysqli->begin_transaction();
$sql = "INSERT INTO plant_activities (plant_id, activity_type, note, activity_date) VALUES (?, ?, ?, ?)";
$stmt = $mysqli->prepare($sql);
foreach($plant_ids as $plant_id) {
$stmt->bind_param("isss", $plant_id, $_POST['activity_type'], $_POST['note'], $_POST['activity_date']);
$stmt->execute();
}
$stmt->close();
$mysqli->commit();
echo json_encode(['success' => true]);
break;
case 'get_sensor_data':
if (empty($_GET['plant_id']) || !is_numeric($_GET['plant_id'])) { echo json_encode(['success' => false, 'message' => 'Ungültige Pflanzen-ID.']); exit; }
$plant_id = $_GET['plant_id'];
$sql_check = "SELECT id FROM plants WHERE id = ? AND user_id = ?";
$stmt_check = $mysqli->prepare($sql_check);
$stmt_check->bind_param("ii", $plant_id, $user_id);
$stmt_check->execute();
if ($stmt_check->get_result()->num_rows === 0) { echo json_encode(['success' => false, 'message' => 'Keine Berechtigung.']); exit; }
$stmt_check->close();
$sql = "SELECT sensor_type, value, timestamp FROM sensor_data WHERE plant_id = ? ORDER BY timestamp ASC";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param("i", $plant_id);
$stmt->execute();
$result = $stmt->get_result();
$raw_data = [];
while ($row = $result->fetch_assoc()) { $raw_data[] = $row; }
$stmt->close();
$data_by_timestamp = [];
foreach ($raw_data as $row) {
$timestamp = $row['timestamp'];
if (!isset($data_by_timestamp[$timestamp])) { $data_by_timestamp[$timestamp] = ['temperatur' => null, 'feuchtigkeit' => null]; }
if ($row['sensor_type'] == 'Temperatur') { $data_by_timestamp[$timestamp]['temperatur'] = (float)$row['value']; }
elseif ($row['sensor_type'] == 'Feuchtigkeit') { $data_by_timestamp[$timestamp]['feuchtigkeit'] = (float)$row['value']; }
}
ksort($data_by_timestamp);
$chart_data = ['labels' => [], 'temperature' => [], 'humidity' => []];
foreach ($data_by_timestamp as $timestamp => $values) {
$chart_data['labels'][] = date('d.m H:i', strtotime($timestamp));
$chart_data['temperature'][] = $values['temperatur'];
$chart_data['humidity'][] = $values['feuchtigkeit'];
}
echo json_encode(['success' => true, 'data' => $chart_data]);
break;
default:
echo json_encode(['success' => false, 'message' => 'Unbekannte Aktion: ' . $action]);
break;
}
} catch (mysqli_sql_exception $exception) {
if ($mysqli->ping()) { $mysqli->rollback(); }
error_log("[Cazubu Error] Datenbankfehler: " . $exception->getMessage());
echo json_encode(['success' => false, 'message' => 'Datenbankfehler: ' . $exception->getMessage()]);
}
$mysqli->close();
?>