PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
];
try {
$pdo = new PDO($dsn, DB_USER, DB_PASS, $options);
} catch (PDOException $e) {
header('Content-Type: application/json');
echo json_encode(['error' => 'Database connection failed: ' . $e->getMessage()]);
exit;
}
// Bearer Token für Mastodon-API (falls benötigt)
$bearerToken = 'your_bearer_token_here';
// -----------------------
// AJAX-Anfragen (POST)
// -----------------------
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) {
$action = $_POST['action'];
header('Content-Type: application/json');
if ($action === 'save_config') {
// Erwartet: from_date, to_date, refresh_interval
$from_date = $_POST['from_date']; // z. B. "2025-03-17T14:00"
$to_date = $_POST['to_date'];
$refresh_interval = $_POST['refresh_interval'];
// Aktualisieren – wir gehen davon aus, dass die Config-Tabelle eine einzelne Zeile mit id=1 hat.
$stmt = $pdo->prepare("UPDATE config SET from_date = :from_date, to_date = :to_date, refresh_interval = :refresh_interval WHERE id = 1");
$stmt->execute([
'from_date' => date('Y-m-d H:i:s', strtotime($from_date)),
'to_date' => date('Y-m-d H:i:s', strtotime($to_date)),
'refresh_interval' => $refresh_interval
]);
echo json_encode(['status' => 'ok']);
exit;
} elseif ($action === 'save_hashtags') {
// Erwartet ein Array "hashtags" mit den Feldern: hashtag_id, hashtag, active
$hashtags = isset($_POST['hashtags']) ? $_POST['hashtags'] : [];
$response = ['saved' => 0, 'updated' => 0];
foreach ($hashtags as $row) {
if (isset($row['hashtag_id']) && !empty($row['hashtag_id'])) {
// Update
$stmt = $pdo->prepare("UPDATE hashtags SET hashtag = :hashtag, active = :active WHERE hashtag_id = :hashtag_id");
$stmt->execute([
'hashtag' => $row['hashtag'],
'active' => !empty($row['active']) ? 1 : 0,
'hashtag_id' => $row['hashtag_id']
]);
$response['updated']++;
} else {
// Insert neuer Eintrag
$stmt = $pdo->prepare("INSERT INTO hashtags (hashtag, active) VALUES (:hashtag, :active)");
$stmt->execute([
'hashtag' => $row['hashtag'],
'active' => !empty($row['active']) ? 1 : 0
]);
$response['saved']++;
}
}
echo json_encode($response);
exit;
} elseif ($action === 'save_accounts') {
// Erwartet ein Array "accounts" (Felder: acc_id, active)
$accounts = isset($_POST['accounts']) ? $_POST['accounts'] : [];
$response = ['updated' => 0];
foreach ($accounts as $row) {
// Anpassen: WHERE user_id = :acc_id
$stmt = $pdo->prepare("UPDATE users SET active = :active WHERE user_id = :acc_id");
$stmt->execute([
'active' => !empty($row['active']) ? 1 : 0,
'acc_id' => $row['acc_id']
]);
$response['updated']++;
}
echo json_encode($response);
exit;
} elseif ($action === 'sync_accounts') {
// Synchronisation: Aus der findings-Tabelle werden alle getrackten Accounts (acc_id, username) ermittelt
// Für jeden Account, der noch nicht in der "users"-Tabelle existiert, erfolgt ein Insert mit active=0
$stmt = $pdo->query("SELECT DISTINCT f.acc_id, f.username FROM findings f LEFT JOIN users u ON f.acc_id = u.user_id WHERE u.user_id IS NULL");
$newAccounts = $stmt->fetchAll();
foreach ($newAccounts as $acc) {
// Neuer Account – unaktiv in die Tabelle schreiben
$insertStmt = $pdo->prepare("INSERT INTO users (user_id, username, active) VALUES (:acc_id, :username, 0)");
$insertStmt->execute([
'acc_id' => $acc['acc_id'],
'username' => $acc['username']
]);
}
// Nun alle Accounts aus der users-Tabelle abrufen
$stmt = $pdo->query("SELECT user_id as acc_id, username, active FROM users ORDER BY username ASC");
$accountsList = $stmt->fetchAll();
echo json_encode($accountsList);
exit;
} elseif ($action === 'get_dashboard_data') {
// Lese den Zeitraum und Refresh-Intervall aus der config-Tabelle (id=1)
$configStmt = $pdo->query("SELECT from_date, to_date, refresh_interval FROM config WHERE id = 1");
$config = $configStmt->fetch();
if (!$config) {
$config = ['from_date' => date('Y-m-d H:i:s', strtotime('-1 day')), 'to_date' => date('Y-m-d H:i:s'), 'refresh_interval' => 20];
}
// Aggregation: Nur Beiträge innerhalb des Zeitraums, zu aktiven Hashtags und von aktiven Usern
$query = "SELECT f.username, h.hashtag,
SUM(f.replies_count) AS total_replies,
SUM(f.reblogs_count) AS total_reblogs,
SUM(f.favorites_count) AS total_favorites
FROM findings f
JOIN hashtags h ON f.hashtag_id = h.hashtag_id
JOIN users u ON f.acc_id = u.user_id
WHERE f.created_at BETWEEN :from_date AND :to_date
AND h.active = 1
AND u.active = 1
GROUP BY h.hashtag, f.username
ORDER BY h.hashtag, f.username";
$stmt = $pdo->prepare($query);
$stmt->execute([
'from_date' => $config['from_date'],
'to_date' => $config['to_date']
]);
$data = $stmt->fetchAll();
// Bestimme globale Maximalwerte für jeden Metrik, um die Balkenhöhen zu skalieren
$maxReplies = $maxReblogs = $maxFavorites = 0;
foreach ($data as $row) {
if ($row['total_replies'] > $maxReplies) { $maxReplies = $row['total_replies']; }
if ($row['total_reblogs'] > $maxReblogs) { $maxReblogs = $row['total_reblogs']; }
if ($row['total_favorites'] > $maxFavorites) { $maxFavorites = $row['total_favorites']; }
}
echo json_encode([
'data' => $data,
'max' => ['replies' => $maxReplies, 'reblogs' => $maxReblogs, 'favorites' => $maxFavorites]
]);
exit;
}
exit;
}
// -----------------------
// GET-Anfragen: Anzeige der Seite
// -----------------------
// Wenn action=setup in der URL übergeben wurde, wird der Konfigurationsbereich angezeigt.
if (isset($_GET['action']) && $_GET['action'] == 'setup') {
// Lese Konfiguration aus der config-Tabelle (angenommen, es gibt eine einzelne Zeile mit id=1)
$configStmt = $pdo->query("SELECT from_date, to_date, refresh_interval FROM config WHERE id = 1");
$config = $configStmt->fetch();
if (!$config) {
$config = ['from_date' => date('Y-m-d\TH:i'), 'to_date' => date('Y-m-d\TH:i'), 'refresh_interval' => 20];
} else {
// Für datetime-local Eingabefelder im Format "YYYY-MM-DDTHH:MM"
$config['from_date'] = date('Y-m-d\TH:i', strtotime($config['from_date']));
$config['to_date'] = date('Y-m-d\TH:i', strtotime($config['to_date']));
}
// Lade Hashtag-Konfiguration
$hashtagStmt = $pdo->query("SELECT hashtag_id, hashtag, active FROM hashtags ORDER BY hashtag ASC");
$hashtags = $hashtagStmt->fetchAll();
// Lade getrackte User: Alle unterschiedlichen User aus findings, verknüpft mit der users-Tabelle
$userStmt = $pdo->query("SELECT DISTINCT f.acc_id, f.username, IFNULL(u.active, 0) as active
FROM findings f
LEFT JOIN users u ON f.acc_id = u.user_id
ORDER BY f.username ASC");
$users = $userStmt->fetchAll();
?>
Dashboard Konfiguration
Dashboard Konfiguration
Zeitraum
Dashboard Übersicht
Dashboard Übersicht