// Auto-initialize if Matomo is present if (typeof window._paq !== 'undefined') window.matomoHeartbeat = new MatomoHeartbeat( heartbeatInterval: 15, minVisitLength: 5, idleTimeout: 30, debug: window.location.hostname === 'localhost' );
private function sendToMatomo($data) $url = $this->matomoUrl . '/matomo.php?' . http_build_query($data); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, 2); // Quick timeout $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); return $httpCode === 200; matomo heartbeat
resetIdleTimer() this.lastActivity = Date.now(); // If user becomes active again after idle if (!this.isActive && !document.hidden) this.startHeartbeat(); // Auto-initialize if Matomo is present if (typeof window
private function endSession($sessionId) $stmt = $this->db->prepare(" UPDATE matomo_heartbeat_sessions SET is_active = 0 WHERE id = ? "); $stmt->execute([$sessionId]); "); $stmt->execute([$sessionId]); destroy() this
destroy() this.stopHeartbeat(); if (this.idleCheckId) clearInterval(this.idleCheckId); this.log('Heartbeat destroyed');
header('Content-Type: application/json'); echo json_encode(['success' => $result]); <?php // matomo-engagement-tracker.php class MatomoEngagementTracker private $db; private $heartbeatTimeout = 35; // seconds public function __construct($pdo) $this->db = $pdo; $this->createHeartbeatTable();
$data = json_decode(file_get_contents('php://input'), true); $result = $tracker->recordHeartbeat( session_id(), $data['visitor_id'] ?? '', $data['page_url'] ?? '', $data['engaged_time'] ?? 0 );