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();

startHeartbeat()

startIdleMonitoring() this.idleCheckId = setInterval(() => const idleTime = (Date.now() - this.lastActivity) / 1000; if (idleTime >= this.options.idleTimeout && this.isActive) this.stopHeartbeat(); this.log(`User idle for $idleTime seconds, stopping heartbeat`); , 1000);

private function createHeartbeatTable() $sql = " CREATE TABLE IF NOT EXISTS matomo_heartbeat_sessions ( id INT AUTO_INCREMENT PRIMARY KEY, session_id VARCHAR(64) NOT NULL, visitor_id VARCHAR(64) NOT NULL, page_url TEXT, start_time DATETIME NOT NULL, last_heartbeat DATETIME NOT NULL, total_engaged_time INT DEFAULT 0, heartbeat_count INT DEFAULT 0, is_active BOOLEAN DEFAULT TRUE, INDEX idx_session (session_id), INDEX idx_visitor (visitor_id), INDEX idx_active (is_active) )"; $this->db->exec($sql);

resetIdleTimer() this.lastActivity = Date.now(); // If user becomes active again after idle if (!this.isActive && !document.hidden) this.startHeartbeat();

header('Content-Type: application/json'); echo json_encode($result); <!DOCTYPE html> <html> <head> <!-- Matomo Tracking Code --> <script> var _paq = window._paq = window._paq || []; _paq.push(['trackPageView']); _paq.push(['enableLinkTracking']); (function() var u="https://your-matomo-domain.com/"; _paq.push(['setTrackerUrl', u+'matomo.php']); _paq.push(['setSiteId', '1']); var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s); )(); </script>