initTable(); } private function initTable() { $sql = "CREATE TABLE IF NOT EXISTS user_logs ( id INT AUTO_INCREMENT PRIMARY KEY, user_id INT, action VARCHAR(255), description TEXT, ip_address VARCHAR(45), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;"; $this->db->exec($sql); } /** * Log an action */ public function logAction($userId, $action, $description = '') { $ip = $_SERVER['REMOTE_ADDR'] ?? '127.0.0.1'; // Handle Kiosk logs (null user_id) by assigning to the first admin user // to prevent foreign key constraint violations if ($userId === null) { try { $stmtUser = $this->db->query("SELECT id FROM users ORDER BY id ASC LIMIT 1"); $userId = $stmtUser->fetchColumn(); } catch (\Exception $e) { $userId = 1; } if (!$userId) $userId = 1; // Fallback } $sql = "INSERT INTO user_logs (user_id, action, description, ip_address) VALUES (?, ?, ?, ?)"; try { $stmt = $this->db->prepare($sql); return $stmt->execute([$userId, $action, $description, $ip]); } catch (\PDOException $e) { // Prevent crashing if log insertion fails return false; } } /** * Get logs with optional filters */ public function getLogs($filters = []) { $sql = "SELECT l.*, u.username, u.first_name, u.last_name FROM user_logs l LEFT JOIN users u ON l.user_id = u.id WHERE 1=1"; $params = []; if (!empty($filters['user_id'])) { $sql .= " AND l.user_id = ?"; $params[] = $filters['user_id']; } if (!empty($filters['action'])) { $sql .= " AND l.action = ?"; $params[] = $filters['action']; } if (!empty($filters['date_start'])) { $sql .= " AND DATE(l.created_at) >= ?"; $params[] = $filters['date_start']; } if (!empty($filters['date_end'])) { $sql .= " AND DATE(l.created_at) <= ?"; $params[] = $filters['date_end']; } $sql .= " ORDER BY l.created_at DESC LIMIT 1000"; $stmt = $this->db->prepare($sql); $stmt->execute($params); return $stmt->fetchAll(PDO::FETCH_ASSOC); } } ?>