plugins/session/classes/yf_session.class.php
<?php
/**
* Core session handler.
*/
class yf_session
{
/** @var string Current session name */
public $NAME = '';
/** @var bool Disable sessions or not */
public $OFF = false;
/** @var string Custom session save dir (leave ampty to skip), example: 'session_data/' */
public $SAVE_DIR = '';
/** @var int Session life time (in seconds) */
public $LIFE_TIME = 18000; // 5 hours
/** @var string */
public $DOMAIN = ''; // Default empty, means current domain
/** @var string */
public $COOKIE_PATH = '/';
/** @var bool */
public $COOKIE_SECURE = false;
/** @var bool */
public $COOKIE_HTTPONLY = true;
/** @var string */
public $REFERER_CHECK = ''; // WEB_PATH
/** @var string */
public $DESTROY_EXPIRED = false;
/** @var string Custom session name */
public $USE_UNIQUE_NAME = true;
/** @var string Custom handler name */
public $CUSTOM_HANDLER = '';
/** @var bool @conf_skip */
public $_driver = null;
/** @var bool @conf_skip */
public $_started = false;
/**
* Catch missing method call.
* @param mixed $name
* @param mixed $args
*/
public function __call($name, $args)
{
return main()->extend_call($this, $name, $args);
}
public function _init()
{
$main = main();
// Import session settings from main class, but prefixed with "SESSION_"
$prefix = 'SESSION_';
$plen = strlen($prefix);
foreach (get_object_vars($main) as $k => $v) {
if (substr($k, 0, $plen) !== $prefix) {
continue;
}
$name = substr($k, $plen);
$this->$name = $v;
}
}
public function start()
{
$main = main();
if ( ! empty($this->_started) || $main->is_console() || conf('SESSION_OFF') || $this->OFF) {
return false;
}
// Set custom session name
if ($this->USE_UNIQUE_NAME) {
$force_name_path = conf('_SESSION_FORCE_NAME_PATH');
$_name_path = isset($force_name_path) ? $force_name_path : (MAIN_TYPE_ADMIN ? ADMIN_SITE_PATH : SITE_PATH);
$_name_path = str_replace('\\', '/', OS_WINDOWS ? strtolower($_name_path) : $_name_path);
$this->NAME = 'sid_' . (int) (abs(crc32($_name_path)));
session_name($this->NAME);
} else {
$this->NAME = ini_get('session.name'); // Usually PHPSESSID
}
$main->SESSION_NAME = $this->NAME;
if (session_id() !== '') { // (session_status() == PHP_SESSION_ACTIVE) => PHP 5.4+ only
return true;
}
@ini_set('session.use_trans_sid', 0); // We need @ here to avoid error when session already started
ini_set('url_rewriter.tags', '');
if ( ! empty($this->LIFE_TIME)) {
ini_set('session.cookie_lifetime', $this->LIFE_TIME);
ini_set('session.gc_probability', 0);
ini_set('session.gc_maxlifetime', $this->LIFE_TIME);
}
ini_set('session.use_cookies', 1);
ini_set('session.use_only_cookies', 1);
if ($this->COOKIE_PATH) {
ini_set('session.cookie_path', $this->COOKIE_PATH);
}
if ($this->DOMAIN) {
ini_set('session.cookie_domain', $this->DOMAIN);
}
if ($this->COOKIE_SECURE) {
ini_set('session.cookie_secure', 1);
}
if ($this->COOKIE_HTTPONLY) {
ini_set('session.cookie_httponly', 1);
}
if ($this->REFERER_CHECK) { // WEB_PATH
ini_set('session.referer_check', $this->REFERER_CHECK);
}
conf('COOKIES_ENABLED', $_COOKIE[$this->NAME] !== null ? 1 : 0);
// Check if we have valid session name
if ($_COOKIE[$this->NAME] !== null) {
$_test_result = preg_replace('/[^a-z0-9]/i', '', $_COOKIE[$this->NAME]);
if ($_test_result !== $_COOKIE[$this->NAME]) {
$_COOKIE[$this->NAME] = abs(crc32(microtime(true)));
session_id($_COOKIE[$this->NAME]);
}
}
if ( ! empty($this->SAVE_DIR)) {
$s_path = STORAGE_PATH . $this->SAVE_DIR;
if ( ! file_exists($s_path)) {
mkdir($s_path, 0755, true);
}
session_save_path($s_path);
}
if ($this->CUSTOM_HANDLER && $this->_driver_setup($this->CUSTOM_HANDLER)) {
$main->session = $this->_driver;
}
session_start();
// Instruct bots to totally ignore current page
if (DEBUG_MODE || MAIN_TYPE_ADMIN || conf('ROBOTS_NO_INDEX')) {
header('X-Robots-Tag: noindex,nofollow,noarchive,nosnippet');
}
$now = time();
$last_update = $_SESSION['last_update'];
if ($last_update) {
$diff = $now - $last_update;
$percent = $diff / $this->LIFE_TIME * 100;
// Session expired
if ($percent > 100 && $this->DESTROY_EXPIRED) {
session_regenerate_id($destroy = true);
// Session need to be regenerated
} elseif ($percent > 10) {
session_regenerate_id();
$_SESSION['last_update'] = $now;
}
} else {
$_SESSION['last_update'] = $now;
}
$_SESSION['sys_main_type'] = MAIN_TYPE;
$_SESSION['sys_requests_count']++;
$_SESSION['sys_user_ip'] = common()->get_ip();
$_SESSION['sys_user_geo_country'] = $_SERVER['GEOIP_COUNTRY_CODE'];
// $_SESSION['sys_user_ua'] = $_SERVER['HTTP_USER_AGENT'];
$_SESSION['sys_user_current_url'] = (is_https() ? 'https://' : 'http://') . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
$main->_session_init_complete = true;
$this->_started = true;
return $this->_started;
}
public function stop()
{
session_write_close();
return true;
}
/**
* @param mixed $driver_name
*/
public function _driver_setup($driver_name)
{
$session_class_name = 'session_driver_' . $driver_name;
$session_loaded_class_name = $this->load_class_file($session_class_name, 'classes/session/');
if (empty($session_loaded_class_name)) {
return false;
}
$this->_driver = new $session_loaded_class_name();
main()->set_module_conf($session_class_name, $this->_driver);
session_set_save_handler(
[$this->_driver, 'open'],
[$this->_driver, 'close'],
[$this->_driver, 'read'],
[$this->_driver, 'write'],
[$this->_driver, 'destroy'],
[$this->_driver, 'gc']
);
return $this->_driver;
}
}