158 lines
4.4 KiB
PHP
158 lines
4.4 KiB
PHP
<?php
|
|
header('Content-Type: application/json; charset=utf-8');
|
|
|
|
require_once __DIR__ . '/../config/database.php';
|
|
require_once __DIR__ . '/get_table_name.php';
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
|
http_response_code(405);
|
|
echo json_encode([
|
|
'status' => 'error',
|
|
'message' => 'Method not allowed'
|
|
], JSON_UNESCAPED_UNICODE);
|
|
exit;
|
|
}
|
|
|
|
$rawBody = file_get_contents('php://input');
|
|
$data = json_decode($rawBody, true);
|
|
if (!is_array($data)) {
|
|
http_response_code(400);
|
|
echo json_encode([
|
|
'status' => 'error',
|
|
'message' => 'Invalid JSON payload'
|
|
], JSON_UNESCAPED_UNICODE);
|
|
exit;
|
|
}
|
|
|
|
$eventName = isset($data['eventName']) ? trim((string)$data['eventName']) : '';
|
|
$sessionId = isset($data['sessionId']) ? trim((string)$data['sessionId']) : '';
|
|
$tableId = isset($data['tableId']) ? trim((string)$data['tableId']) : null;
|
|
$zone = isset($data['zone']) ? trim((string)$data['zone']) : null;
|
|
$qrHash = isset($data['qrHash']) ? trim((string)$data['qrHash']) : null;
|
|
$deviceType = isset($data['deviceType']) ? trim((string)$data['deviceType']) : null;
|
|
$browser = isset($data['browser']) ? trim((string)$data['browser']) : null;
|
|
$payload = isset($data['payload']) && is_array($data['payload']) ? $data['payload'] : null;
|
|
|
|
$allowedEvents = [
|
|
'qr_scan',
|
|
'session_start',
|
|
'geo_check_started',
|
|
'geo_check_passed',
|
|
'geo_check_failed',
|
|
'geo_bypass_host',
|
|
'waiter_call_requested',
|
|
'view_status',
|
|
'view_menu',
|
|
'menu_search',
|
|
'bill_dialog_opened',
|
|
'bill_request_sent',
|
|
];
|
|
|
|
if ($eventName === '' || !in_array($eventName, $allowedEvents, true)) {
|
|
http_response_code(422);
|
|
echo json_encode([
|
|
'status' => 'error',
|
|
'message' => 'Invalid eventName'
|
|
], JSON_UNESCAPED_UNICODE);
|
|
exit;
|
|
}
|
|
|
|
if ($sessionId === '' || strlen($sessionId) > 64) {
|
|
http_response_code(422);
|
|
echo json_encode([
|
|
'status' => 'error',
|
|
'message' => 'Invalid sessionId'
|
|
], JSON_UNESCAPED_UNICODE);
|
|
exit;
|
|
}
|
|
|
|
if ($qrHash && !$tableId && isset($conn)) {
|
|
$resolved = getTableNameByHash($conn, $qrHash);
|
|
if ($resolved !== '') {
|
|
$tableId = $resolved;
|
|
}
|
|
}
|
|
|
|
if ($tableId !== null && strlen($tableId) > 32) {
|
|
$tableId = substr($tableId, 0, 32);
|
|
}
|
|
if ($zone !== null && strlen($zone) > 16) {
|
|
$zone = substr($zone, 0, 16);
|
|
}
|
|
if ($qrHash !== null && strlen($qrHash) > 128) {
|
|
$qrHash = substr($qrHash, 0, 128);
|
|
}
|
|
if ($deviceType !== null && strlen($deviceType) > 16) {
|
|
$deviceType = substr($deviceType, 0, 16);
|
|
}
|
|
if ($browser !== null && strlen($browser) > 32) {
|
|
$browser = substr($browser, 0, 32);
|
|
}
|
|
|
|
$ip = '';
|
|
if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
|
|
$parts = explode(',', (string)$_SERVER['HTTP_X_FORWARDED_FOR']);
|
|
$ip = trim($parts[0]);
|
|
} elseif (!empty($_SERVER['REMOTE_ADDR'])) {
|
|
$ip = trim((string)$_SERVER['REMOTE_ADDR']);
|
|
}
|
|
$ipHash = $ip !== '' ? hash('sha256', $ip . '|karczma_analytics_v1') : null;
|
|
$payload = is_array($payload) ? $payload : [];
|
|
if ($ip !== '' && !isset($payload['ipAddress'])) {
|
|
$payload['ipAddress'] = $ip;
|
|
}
|
|
$payloadJson = $payload ? json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) : null;
|
|
|
|
try {
|
|
$pdo = getAnalyticsPdo();
|
|
$stmt = $pdo->prepare("
|
|
INSERT INTO analytics_events (
|
|
created_at,
|
|
event_name,
|
|
session_id,
|
|
table_id,
|
|
zone,
|
|
qr_hash,
|
|
device_type,
|
|
browser,
|
|
ip_hash,
|
|
payload_json
|
|
) VALUES (
|
|
NOW(3),
|
|
:event_name,
|
|
:session_id,
|
|
:table_id,
|
|
:zone,
|
|
:qr_hash,
|
|
:device_type,
|
|
:browser,
|
|
:ip_hash,
|
|
:payload_json
|
|
)
|
|
");
|
|
|
|
$stmt->execute([
|
|
':event_name' => $eventName,
|
|
':session_id' => $sessionId,
|
|
':table_id' => $tableId,
|
|
':zone' => $zone,
|
|
':qr_hash' => $qrHash,
|
|
':device_type' => $deviceType,
|
|
':browser' => $browser,
|
|
':ip_hash' => $ipHash,
|
|
':payload_json' => $payloadJson,
|
|
]);
|
|
|
|
echo json_encode([
|
|
'status' => 'success'
|
|
], JSON_UNESCAPED_UNICODE);
|
|
} catch (Throwable $e) {
|
|
// Best-effort analytics: return success=false, but do not crash frontend flow.
|
|
http_response_code(200);
|
|
echo json_encode([
|
|
'status' => 'error',
|
|
'message' => 'Analytics insert failed'
|
|
], JSON_UNESCAPED_UNICODE);
|
|
}
|
|
|