<?php
namespace PassGram\Core;
/**
* Session Class
*
* Secure session management for PassGram.
*/
class Session
{
private static bool $started = false;
/**
* Start session with secure settings
*
* @param array|null $config Session configuration
* @return bool
*/
public static function start(?array $config = null): bool
{
if (self::$started) {
return true;
}
// Default session configuration
$defaults = [
'name' => 'PASSGRAM_SESSION',
'lifetime' => 3600,
'cookie_httponly' => true,
'cookie_secure' => false,
'cookie_samesite' => 'Strict',
'regenerate_interval' => 300,
];
$sessionConfig = $config ? array_merge($defaults, $config) : $defaults;
// Configure session settings
ini_set('session.cookie_httponly', $sessionConfig['cookie_httponly'] ? '1' : '0');
ini_set('session.cookie_secure', $sessionConfig['cookie_secure'] ? '1' : '0');
ini_set('session.cookie_samesite', $sessionConfig['cookie_samesite']);
ini_set('session.use_strict_mode', '1');
ini_set('session.use_only_cookies', '1');
ini_set('session.cookie_lifetime', (string)$sessionConfig['lifetime']);
session_name($sessionConfig['name']);
$result = session_start();
self::$started = $result;
// Check if session should be regenerated
self::checkRegenerate($sessionConfig['regenerate_interval']);
return $result;
}
/**
* Check if session ID should be regenerated
*
* @param int $interval Regeneration interval in seconds
* @return void
*/
private static function checkRegenerate(int $interval = 300): void
{
if (!isset($_SESSION['last_regenerate'])) {
$_SESSION['last_regenerate'] = time();
return;
}
if (time() - $_SESSION['last_regenerate'] > $interval) {
self::regenerate();
}
}
/**
* Regenerate session ID
*
* @return bool
*/
public static function regenerate(): bool
{
$result = session_regenerate_id(true);
$_SESSION['last_regenerate'] = time();
return $result;
}
/**
* Set session value
*
* @param string $key
* @param mixed $value
* @return void
*/
public static function set(string $key, $value): void
{
$_SESSION[$key] = $value;
}
/**
* Get session value
*
* @param string $key
* @param mixed $default
* @return mixed
*/
public static function get(string $key, $default = null)
{
return $_SESSION[$key] ?? $default;
}
/**
* Check if session key exists
*
* @param string $key
* @return bool
*/
public static function has(string $key): bool
{
return isset($_SESSION[$key]);
}
/**
* Remove session value
*
* @param string $key
* @return void
*/
public static function remove(string $key): void
{
unset($_SESSION[$key]);
}
/**
* Destroy session
*
* @return bool
*/
public static function destroy(): bool
{
$_SESSION = [];
if (ini_get('session.use_cookies')) {
$params = session_get_cookie_params();
setcookie(
session_name(),
'',
time() - 42000,
$params['path'],
$params['domain'],
$params['secure'],
$params['httponly']
);
}
self::$started = false;
return session_destroy();
}
/**
* Get session ID
*
* @return string
*/
public static function getId(): string
{
return session_id();
}
/**
* Flash message (set and retrieve once)
*
* @param string $key
* @param mixed $value
* @return void
*/
public static function flash(string $key, $value = null)
{
if ($value === null) {
// Get and remove
$val = self::get('_flash_' . $key);
self::remove('_flash_' . $key);
return $val;
}
// Set
self::set('_flash_' . $key, $value);
}
/**
* Check if session is active
*
* @return bool
*/
public static function isActive(): bool
{
return self::$started && session_status() === PHP_SESSION_ACTIVE;
}
}