Files
Schnappix-Web/feedback_backend.php
T

209 lines
7.0 KiB
PHP

<?php
error_reporting(0);
header('Content-Type: application/json');
$dataDir = __DIR__ . '/data/';
$dataFile = $dataDir . 'feedback.json';
function getAdminPassword() {
$envVar = getenv('ADMIN_PASSWORD');
if ($envVar !== false && $envVar !== '') {
return $envVar;
}
$envFile = __DIR__ . '/.env';
if (file_exists($envFile)) {
$lines = file($envFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach ($lines as $line) {
if (strpos(trim($line), '#') === 0) continue;
$parts = explode('=', $line, 2);
if (count($parts) === 2) {
if (trim($parts[0]) === 'ADMIN_PASSWORD') {
return trim($parts[1]);
}
}
}
}
return '1234';
}
$adminPassword = getAdminPassword();
// Create data directory if not exists
if (!is_dir($dataDir)) {
@mkdir($dataDir, 0755, true);
}
// Default Seed Data
$defaultFeedback = [
[
'id' => 'fb-1',
'author' => 'Markus T.',
'type' => 'feature',
'title' => 'QR-Code Download für Gäste',
'text' => 'Es wäre super cool, wenn nach der Aufnahme ein QR-Code angezeigt wird, über den sich die Gäste das Foto direkt auf das Handy laden können.',
'upvotes' => 42,
'answer' => null
],
[
'id' => 'fb-2',
'author' => 'Sabrina',
'type' => 'love',
'title' => 'Sticker-Editor ist genial!',
'text' => 'Unsere Hochzeitsgäste haben stundenlang Emojis und Eventtexte verschoben. Die Bedienung ist wirklich super intuitiv und einfach.',
'upvotes' => 28,
'answer' => 'Vielen Dank für das tolle Feedback! Freut uns, dass es euch gefallen hat.'
],
[
'id' => 'fb-3',
'author' => 'EventTech GmbH',
'type' => 'bug',
'title' => 'Drucker-Timeout bei schlechtem WLAN',
'text' => 'Manchmal meldet die App einen Fehler, wenn der Drucker im lokalen Netzwerk kurz die Verbindung verliert. Ein automatischer Retry wäre hilfreich.',
'upvotes' => 15,
'answer' => null
]
];
// Initialize JSON file if it doesn't exist
if (!file_exists($dataFile)) {
file_put_contents($dataFile, json_encode($defaultFeedback, JSON_PRETTY_PRINT));
}
// Read data
$feedbackData = json_decode(file_get_contents($dataFile), true);
if (!$feedbackData) {
$feedbackData = [];
}
$action = isset($_GET['action']) ? $_GET['action'] : '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// For POST requests, we might get the action from the body or query param
$inputJSON = file_get_contents('php://input');
$input = json_decode($inputJSON, true);
$action = isset($input['action']) ? $input['action'] : $action;
}
switch ($_SERVER['REQUEST_METHOD']) {
case 'GET':
// Return all feedback
echo json_encode(['success' => true, 'data' => $feedbackData]);
break;
case 'POST':
if (!$input) {
http_response_code(400);
echo json_encode(['error' => 'Invalid JSON']);
exit;
}
if ($action === 'add') {
$newFb = [
'id' => 'fb-' . time() . rand(100, 999),
'author' => htmlspecialchars($input['author'] ?? 'Anonym'),
'type' => htmlspecialchars($input['type'] ?? 'feature'),
'title' => htmlspecialchars($input['title'] ?? 'Kein Titel'),
'text' => htmlspecialchars($input['text'] ?? ''),
'upvotes' => 1,
'answer' => null
];
array_push($feedbackData, $newFb);
file_put_contents($dataFile, json_encode($feedbackData, JSON_PRETTY_PRINT));
echo json_encode(['success' => true, 'data' => $newFb]);
}
elseif ($action === 'upvote') {
$id = $input['id'] ?? '';
$undo = isset($input['undo']) && $input['undo'] === true;
$found = false;
foreach ($feedbackData as &$item) {
if ($item['id'] === $id) {
if ($undo) {
$item['upvotes'] = max(0, $item['upvotes'] - 1);
} else {
$item['upvotes']++;
}
$found = true;
break;
}
}
if ($found) {
file_put_contents($dataFile, json_encode($feedbackData, JSON_PRETTY_PRINT));
echo json_encode(['success' => true]);
} else {
http_response_code(404);
echo json_encode(['error' => 'Feedback not found']);
}
}
elseif ($action === 'verify_password') {
$secret = $input['secret'] ?? '';
if ($secret === $adminPassword) {
echo json_encode(['success' => true]);
} else {
http_response_code(401);
echo json_encode(['error' => 'Unauthorized']);
}
exit;
}
elseif ($action === 'delete') {
$id = $input['id'] ?? '';
$secret = $input['secret'] ?? '';
if ($secret !== $adminPassword) {
http_response_code(401);
echo json_encode(['error' => 'Unauthorized']);
exit;
}
$filteredData = array_filter($feedbackData, function($item) use ($id) {
return $item['id'] !== $id;
});
// Re-index array
$feedbackData = array_values($filteredData);
file_put_contents($dataFile, json_encode($feedbackData, JSON_PRETTY_PRINT));
echo json_encode(['success' => true]);
}
elseif ($action === 'answer') {
$id = $input['id'] ?? '';
$answer = $input['answer'] ?? '';
$secret = $input['secret'] ?? '';
if ($secret !== $adminPassword) {
http_response_code(401);
echo json_encode(['error' => 'Unauthorized']);
exit;
}
$found = false;
foreach ($feedbackData as &$item) {
if ($item['id'] === $id) {
// Save htmlspecialchars to avoid XSS but allow simple answers
$item['answer'] = $answer === '' ? null : htmlspecialchars($answer);
$found = true;
break;
}
}
if ($found) {
file_put_contents($dataFile, json_encode($feedbackData, JSON_PRETTY_PRINT));
echo json_encode(['success' => true]);
} else {
http_response_code(404);
echo json_encode(['error' => 'Feedback not found']);
}
}
else {
http_response_code(400);
echo json_encode(['error' => 'Unknown action']);
}
break;
default:
http_response_code(405);
echo json_encode(['error' => 'Method not allowed']);
break;
}