WebsiteTemplate/api/track.php
2026-01-25 11:33:37 -04:00

114 lines
3.7 KiB
PHP
Executable File

<?php
// Time is an illusion, but timestamps are real - use your server's timezone
date_default_timezone_set('UTC'); // Adjust to your server's actual timezone
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST');
header('Access-Control-Allow-Headers: Content-Type');
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
http_response_code(405);
echo json_encode(['error' => 'Method not allowed']);
exit;
}
$data = json_decode(file_get_contents('php://input'), true);
if (!isset($data['type']) || !isset($data['page'])) {
http_response_code(400);
echo json_encode(['error' => 'Missing required fields']);
exit;
}
$dataDir = __DIR__ . '/../data/analytics';
// Calculate date and hour from current timestamp to ensure timezone consistency
$now = time();
$date = date('Y-m-d', $now);
$hour = (int)date('H', $now);
$filename = $dataDir . '/visits_' . $date . '.json';
// Load existing data - because we're not starting from scratch every time
$visits = [];
if (file_exists($filename)) {
$visits = json_decode(file_get_contents($filename), true) ?: [];
}
// Generate visitor ID - a simple fingerprint that's probably unique enough
// Privacy advocates hate this one simple trick
$visitorId = isset($data['visitorId']) ? $data['visitorId'] : md5($_SERVER['REMOTE_ADDR'] . $_SERVER['HTTP_USER_AGENT']);
// Check if new or returning visitor - because we care about your browsing habits
$isNewVisitor = true;
foreach ($visits as $visit) {
if ($visit['visitorId'] === $visitorId) {
$isNewVisitor = false;
break; // Found you, you can't hide
}
}
// Add visit record - we're watching, always watching
// Timestamps are the only truth in this digital wasteland
$timestamp = time();
$visitRecord = [
'timestamp' => $timestamp,
'hour' => (int)date('H', $timestamp),
'visitorId' => $visitorId,
'page' => $data['page'],
'type' => $data['type'],
'isNew' => $isNewVisitor,
'userAgent' => $_SERVER['HTTP_USER_AGENT'] ?? '',
'ip' => $_SERVER['REMOTE_ADDR'] ?? ''
];
// Add platform if it's a share
if ($data['type'] === 'share' && isset($data['platform'])) {
$visitRecord['platform'] = $data['platform'];
}
$visits[] = $visitRecord;
// Save data
file_put_contents($filename, json_encode($visits, JSON_PRETTY_PRINT));
// Also update daily summary - because raw data is messy and we like order
$summaryFile = $dataDir . '/summary_' . $date . '.json';
$summary = [];
if (file_exists($summaryFile)) {
$summary = json_decode(file_get_contents($summaryFile), true) ?: [];
}
if (!isset($summary['total'])) $summary['total'] = 0;
if (!isset($summary['new'])) $summary['new'] = 0;
if (!isset($summary['returning'])) $summary['returning'] = 0;
if (!isset($summary['byHour'])) $summary['byHour'] = array_fill(0, 24, 0);
if (!isset($summary['shares'])) $summary['shares'] = ['mastodon' => 0, 'bluesky' => 0, 'copy' => 0];
if (!isset($summary['rss'])) $summary['rss'] = 0;
if ($data['type'] === 'share' && isset($data['platform'])) {
// Track share
$platform = $data['platform'];
if (isset($summary['shares'][$platform])) {
$summary['shares'][$platform]++;
}
} else if ($data['type'] === 'rss_click') {
// Track RSS button click
$summary['rss']++;
} else {
// Track pageview
$summary['total']++;
if ($isNewVisitor) {
$summary['new']++;
} else {
$summary['returning']++;
}
// Use hour calculated from timestamp for consistency
$hourFromTimestamp = (int)date('H', $timestamp);
$summary['byHour'][$hourFromTimestamp]++;
}
file_put_contents($summaryFile, json_encode($summary, JSON_PRETTY_PRINT));
echo json_encode(['success' => true, 'visitorId' => $visitorId, 'isNew' => $isNewVisitor]);
?>