ccdbc47642
Replaced polling with a single queued cursor worker, timeout recovery, backoff, deduplication, chronological insertion, and capped DOM history in cyberchat-v4.js. Removed Groups UI, API, configuration, tier features, admin controls, and archive exposure. Legacy group records remain stored but inaccessible. Added configurable polling limits in config.json.
60 lines
2.8 KiB
PHP
60 lines
2.8 KiB
PHP
<?php
|
|
define('CYBERCHAT_API', true);
|
|
require_once __DIR__ . '/../bootstrap.php';
|
|
sendCorsHeaders();
|
|
|
|
$user = authRequired();
|
|
$action = $_POST['action'] ?? $_GET['action'] ?? 'list';
|
|
$search = trim((string)($_GET['search'] ?? $_POST['search'] ?? ''));
|
|
$rows = personalArchiveRows($user, $search, min(1000, max(1, (int)($_GET['limit'] ?? 500))));
|
|
|
|
if ($action === 'export') {
|
|
if (!featureValue($user, 'text_export', false)) jsonResponse(['error' => 'Your plan does not include exports'], 403);
|
|
$canVoiceExport = (bool)featureValue($user, 'voice_export', false);
|
|
$format = strtolower((string)($_GET['format'] ?? 'json'));
|
|
$export = array_map(function(array $row) use ($canVoiceExport): array {
|
|
$item = [
|
|
'id' => (int)$row['id'],
|
|
'username' => $row['username'], 'message' => $row['message'],
|
|
'type' => $row['message_type'], 'created_at' => date(DATE_ATOM, (int)$row['created_at']),
|
|
];
|
|
if ($row['message_type'] === 'voice' && $canVoiceExport && !empty($row['voice_file'])) {
|
|
$item['voice_url'] = appBaseUrl() . '/' . voicePublicPath($row['voice_file']);
|
|
}
|
|
return $item;
|
|
}, $rows);
|
|
$filename = 'cyberchat-archive-' . date('Y-m-d');
|
|
if ($format === 'csv') {
|
|
header('Content-Type: text/csv; charset=utf-8');
|
|
header('Content-Disposition: attachment; filename="' . $filename . '.csv"');
|
|
$out = fopen('php://output', 'w');
|
|
fputcsv($out, ['id', 'username', 'message', 'type', 'created_at', 'voice_url']);
|
|
foreach ($export as $row) fputcsv($out, [
|
|
$row['id'], $row['username'], $row['message'], $row['type'],
|
|
$row['created_at'], $row['voice_url'] ?? '',
|
|
]);
|
|
fclose($out);
|
|
exit;
|
|
}
|
|
header('Content-Type: application/json; charset=utf-8');
|
|
header('Content-Disposition: attachment; filename="' . $filename . '.json"');
|
|
echo json_encode(['exported_at' => date(DATE_ATOM), 'messages' => $export], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
|
|
exit;
|
|
}
|
|
|
|
$payload = array_map(function(array $row): array {
|
|
return [
|
|
'id' => (int)$row['id'],
|
|
'message' => $row['message'], 'message_type' => $row['message_type'],
|
|
'voice_url' => $row['message_type'] === 'voice' && !empty($row['voice_file']) ? voicePublicPath($row['voice_file']) : null,
|
|
'voice_duration' => $row['voice_duration'] !== null ? (float)$row['voice_duration'] : null,
|
|
'created_at' => (int)$row['created_at'], 'day_key' => $row['day_key'],
|
|
];
|
|
}, $rows);
|
|
jsonResponse([
|
|
'messages' => $payload,
|
|
'retention_days' => max(30, (int)featureValue($user, 'text_archive_days', 30)),
|
|
'can_export' => (bool)featureValue($user, 'text_export', false),
|
|
'voice_included' => (bool)featureValue($user, 'voice_archive', false),
|
|
]);
|