<?php
ini_set("session.sid_length", 48);
ini_set("session.sid_bits_per_character", 5);
ini_set("session.hash_bits_per_character", 5);
class Sessions extends Buyers
{
    public $session;
    protected $sid;
    protected $cookie;
    protected $lifetime = 86400 * 30;   //30 дней - время жизни сессии.

    function __construct()
    {
        $this->sid = session_create_id();
        $this->session = new stdClass();

        if($this->cookie = $this->request->cookie('sid', 'string'))
        {
            $this->db->query("SELECT * FROM sessions WHERE session_id = ? LIMIT 1", $this->cookie);
            if(!$session = $this->db->result())
            {
                $session = (object) array('session_id' => $this->sid, 'data' => '{}');
                $this->db->query('INSERT INTO sessions SET added = NOW(), visited = NOW(), ?%', $session);
            }

            $this->sid = $session->session_id;
            $this->session = json_decode($session->data);
        }

        $options = array(
            'expires' => time() + $this->lifetime,
            'path' => '/',
            'domain' => '',
            'secure' => true,
            'httponly' => false,
            'SameSite' => 'Lax',
        );
        setcookie('sid', $this->sid, $options);
    }

    //выполним по завершению работы скрипта если кука установлена
    public function __destruct()
    {
        if($this->cookie)
        {
            $data = json_encode($this->session, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
            $this->db->query("UPDATE sessions SET data = ?, visited = NOW() WHERE session_id = ? LIMIT 1", $data, $this->sid);
        }

        //очистим старые сессии
        $this->db->query("DELETE FROM sessions WHERE UNIX_TIMESTAMP(visited) + ? < ?", $this->lifetime, time());
    }

    public function __get($name)
    {
        if($res = parent::__get($name))
            return $res;

        return $this->session->$name ?? false;

    }

    public function __set($name, $value)
    {
        if($name && $value)
            $this->session->$name = $value;
    }

    public function __unset($name)
    {
        unset($this->session->$name);
    }
}
