pdo = $db->getConnection(); // Start session if not already started if (session_status() === PHP_SESSION_NONE) { session_start(); } // Check for remember me token if user is not logged in if (!$this->isLoggedIn() && isset($_COOKIE['remember_token'])) { $this->checkRememberToken($_COOKIE['remember_token']); } } public function isLoggedIn() { return isset($_SESSION['logged_in']) && $_SESSION['logged_in'] === true && isset($_SESSION['user_id']) && !empty($_SESSION['user_id']); } public function getCurrentUser() { if (!$this->isLoggedIn()) { return null; } try { $stmt = $this->pdo->prepare(" SELECT id, email, gender, date_of_birth, postcode, email_verified, status, created_at, last_login FROM users WHERE id = ? AND status = 'active' "); $stmt->execute([$_SESSION['user_id']]); return $stmt->fetch(); } catch (Exception $e) { logError('Error fetching current user', [ 'error' => $e->getMessage(), 'user_id' => $_SESSION['user_id'] ]); return null; } } public function requireLogin() { if (!$this->isLoggedIn()) { $this->redirectToLogin(); } // Check if user still exists and is active $user = $this->getCurrentUser(); if (!$user) { $this->logout(); $this->redirectToLogin('Your session has expired. Please log in again.'); } } public function logout() { // Delete remember me token if exists if (isset($_COOKIE['remember_token'])) { try { $stmt = $this->pdo->prepare("DELETE FROM user_sessions WHERE session_token = ?"); $stmt->execute([$_COOKIE['remember_token']]); setcookie('remember_token', '', time() - 3600, '/', '', true, true); } catch (Exception $e) { logError('Error deleting remember token during logout', ['error' => $e->getMessage()]); } } // Destroy session session_destroy(); // Clear session variables $_SESSION = array(); // Delete session cookie if (isset($_COOKIE[session_name()])) { setcookie(session_name(), '', time() - 3600, '/'); } } public function redirectToLogin($message = null) { $url = 'login.html'; if ($message) { $url .= '?message=' . urlencode($message); } header('Location: ' . $url); exit; } public function redirectToDashboard() { header('Location: dashboard.php'); exit; } private function checkRememberToken($token) { try { // Find valid session token $stmt = $this->pdo->prepare(" SELECT us.user_id, u.email, u.status, u.email_verified FROM user_sessions us JOIN users u ON us.user_id = u.id WHERE us.session_token = ? AND us.expires_at > NOW() AND u.status = 'active' AND u.email_verified = 1 "); $stmt->execute([$token]); $session = $stmt->fetch(); if ($session) { // Restore session $_SESSION['user_id'] = $session['user_id']; $_SESSION['user_email'] = $session['email']; $_SESSION['logged_in'] = true; $_SESSION['login_time'] = time(); // Update last login $stmt = $this->pdo->prepare("UPDATE users SET last_login = NOW() WHERE id = ?"); $stmt->execute([$session['user_id']]); logError('User auto-logged in via remember token', [ 'user_id' => $session['user_id'], 'email' => $session['email'] ]); } else { // Invalid or expired token - delete it setcookie('remember_token', '', time() - 3600, '/', '', true, true); } } catch (Exception $e) { logError('Error checking remember token', ['error' => $e->getMessage()]); } } public function getUserAge() { $user = $this->getCurrentUser(); if (!$user || !$user['date_of_birth']) { return null; } $birthDate = new DateTime($user['date_of_birth']); $today = new DateTime(); return $today->diff($birthDate)->y; } public function updateLastActivity() { if ($this->isLoggedIn()) { $_SESSION['last_activity'] = time(); } } public function checkSessionTimeout($timeoutMinutes = 120) { if ($this->isLoggedIn() && isset($_SESSION['last_activity'])) { $timeoutSeconds = $timeoutMinutes * 60; if (time() - $_SESSION['last_activity'] > $timeoutSeconds) { $this->logout(); $this->redirectToLogin('Your session has expired due to inactivity.'); } } $this->updateLastActivity(); } } // Global function to get session manager instance function getSessionManager() { static $instance = null; if ($instance === null) { $instance = new SessionManager(); } return $instance; } // Convenience functions function requireLogin() { getSessionManager()->requireLogin(); } function getCurrentUser() { return getSessionManager()->getCurrentUser(); } function isLoggedIn() { return getSessionManager()->isLoggedIn(); } function logout() { getSessionManager()->logout(); } ?>