<?php

class Session
{
    private $cookie;
    
    private $db;
    
    public $level = 0;
    
    public $values = array();
    
    public function __construct($profile = null)
    {
        global $session_config;
            
        if (!empty($session_config['profile'])) {
            $profile = $session_config['profile'];
        }
            
        $cookie = strhex(base64_decode(gpc($session_config['cookie'], 'cookie')));
        $ip = encode_ip();
            
        $table = $session_config['db']['table'];
            
        $this->db = new BDD($profile);
            
        $this->clean();
            
        if (!$cookie) {
            $this->new_cookie();
            $this->db->deconnexion();
            return false;
        }
            
        $this->db->escape($cookie);
            
        $query = $this->db->unique_query("SELECT session,level,var FROM $table WHERE session= X'$cookie' AND ip= X'$ip' AND active= TRUE");
            
        if ($this->db->num_rows == 1) {
            $time = time();
            
            $this->db->query("UPDATE $table SET time='$time' WHERE session= X'$cookie'");
                    
            $this->db->deconnexion();
                    
            $this->cookie = bithex($query['session']);
            $this->level = $query['level'];
            if (!empty($query['var'])) {
                $this->values = unserialize($query['var']);
            }
                    
            setcookie($session_config['cookie'], base64_encode(hexstr($this->cookie)), time() + $session_config['time']);
        } else {
            $this->new_cookie();
            $this->db->deconnexion();
        }
            
        return true;
    }
    
    private function clean()
    {
        global $session_config;
            
        if (!$this->db->connected) {
            return false;
        }
            
        $time = time()-$session_config['time'];
        $ip = encode_ip();
        $ipmax = $session_config['maxip'];
            
        $table = $session_config['db']['table'];
            
        $this->db->query("DELETE FROM $table WHERE time < $time AND active = TRUE");
            
        if ($ipmax > 0) {
            $this->db->query("DELETE FROM $table WHERE ip = (SELECT ip FROM $table GROUP BY ip HAVING COUNT(ip) > $ipmax)");
        }
    }
    
    private function new_cookie()
    {
        global $session_config;
            
        if (!$this->db->connected) {
            return false;
        }
            
        $time = time();
            
        $level = (is_int($this->level) && strlen($this->level) <= 2) ? $this->level : 0 ;
            
        $sess_cookie = random(256);
        $ip = encode_ip();
            
        $this->cookie = $sess_cookie;
            
        $table = $session_config['db']['table'];
            
        $this->db->escape($sess_cookie);
            
        $this->db->query("INSERT INTO $table(session,time,ip,var,level,active) VALUES(X'$sess_cookie',$time,X'$ip',$level,0,TRUE)");
            
        setcookie($session_config['cookie'], base64_encode(hexstr($this->cookie)), time() + $session_config['time']);
    }
    
    public function put($uid = null)
    {
        global $session_config;
        
        if (empty($this->cookie)) {
            return false;
        }
        
        $var = serialize($this->values);
        
        $cookie = $this->cookie;
        
        $uid = empty($uid) ? '0' : md5($uid);
        
        $level = (is_int($this->level) || (ctype_digit($this->level)) && strlen($this->level) <= 2) ? $this->level : 0 ;
        
        $table = $session_config['db']['table'];
        
        $this->db->reconnexion();
        
        $this->db->escape($var);
        
        if ($uid != '0') {
            $this->db->query("DELETE FROM $table WHERE uid = X'$uid' AND session != X'$cookie' AND active = TRUE");
        }
        
        $this->db->query("UPDATE $table SET var='$var', level='$level', uid= X'$uid'  WHERE session= X'$cookie'");
        
        $this->db->deconnexion();
    }
    
    public function close()
    {
        global $session_config;
            
        if (empty($this->cookie)) {
            return false;
        }
            
        $cookie = $this->cookie;
        
        $table = $session_config['db']['table'];
        
        $this->db->reconnexion();
        
        $this->db->query("DELETE FROM $table WHERE session = X'$cookie' AND active = TRUE");

        $this->db->deconnexion();
        
        setcookie($session_config['cookie'], '', 0);
        
        $this->values = array();
        $this->level = 0;
    }
}
