A super easy PHP Framework for web development!
				https://github.com/exacti/phacil-framework
			
			
		
			You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							243 lines
						
					
					
						
							6.3 KiB
						
					
					
				
			
		
		
	
	
							243 lines
						
					
					
						
							6.3 KiB
						
					
					
				<?php
 | 
						|
/*
 | 
						|
 * Copyright © 2021 ExacTI Technology Solutions. All rights reserved.
 | 
						|
 * GPLv3 General License.
 | 
						|
 * https://exacti.com.br
 | 
						|
 * Phacil PHP Framework - https://github.com/exacti/phacil-framework
 | 
						|
 */
 | 
						|
 | 
						|
namespace Phacil\Framework;
 | 
						|
 | 
						|
use Phacil\Framework\Credis;
 | 
						|
use Phacil\Framework\Config;
 | 
						|
 | 
						|
/** 
 | 
						|
 * The session manipulation class
 | 
						|
 * 
 | 
						|
 * You can activate the Redis session instead use the default PHP session manipulation.
 | 
						|
 * 
 | 
						|
 * @param bool $redis Active or not the Redis session
 | 
						|
 * @param string|null $redisDSN (optional) Redis DSN like unix:///path/to/redis.sock, tcp://host[:port][/persistence_identifier] or tls://host[:port][/persistence_identifier]. If not specified, the default value is connect to localhost in 6379 port.
 | 
						|
 * @param int|null $redisPort (optional) If is not in the DSN specification, we can pass as separated value. The default is 6379.
 | 
						|
 * @param string|null $redisPass (optional) Redis conection password
 | 
						|
 * @param int|null $redis_expire (optional) Redis session expiration, the defaul is your session_cache_expire configurated in PHP *60.
 | 
						|
 * @param string $redis_prefix (optional) The default prefis is 'phacil_'.
 | 
						|
 * 
 | 
						|
 * @since 1.0.0
 | 
						|
 * @package Phacil\Framework 
 | 
						|
 */
 | 
						|
final class Session
 | 
						|
{
 | 
						|
    /**
 | 
						|
     * 
 | 
						|
     * @var array
 | 
						|
     */
 | 
						|
    public $data = array();
 | 
						|
 | 
						|
    /**
 | 
						|
     * Redis object
 | 
						|
     * @var Credis
 | 
						|
     */
 | 
						|
    public $redis = null;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Name of session
 | 
						|
     * 
 | 
						|
     * @var string
 | 
						|
     */
 | 
						|
    public $name;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Redis prefix
 | 
						|
     * 
 | 
						|
     * @var string
 | 
						|
     */
 | 
						|
    private $redisPrefix = "phacil_";
 | 
						|
 | 
						|
    /**
 | 
						|
     * Redis Key
 | 
						|
     * 
 | 
						|
     * @var string
 | 
						|
     */
 | 
						|
    public $redisKey;
 | 
						|
 | 
						|
    /**
 | 
						|
     * 
 | 
						|
     * @param bool $redis 
 | 
						|
     * @param string|null $redisDSN 
 | 
						|
     * @param int|null $redisPort 
 | 
						|
     * @param string|null $redisPass 
 | 
						|
     * @param int|null $redis_expire 
 | 
						|
     * @param string $redis_prefix 
 | 
						|
     * @return void 
 | 
						|
     */
 | 
						|
    public function __construct($redis = false, $redisDSN = null, $redisPort = null, $redisPass = null, $redis_expire = null, $redis_prefix = 'phacil_')
 | 
						|
    {
 | 
						|
        $this->name = (Config::SESSION_PREFIX() ?: 'SESS') . (isset($_SERVER['REMOTE_ADDR']) ? md5($_SERVER['REMOTE_ADDR']) : md5(date("dmY")));
 | 
						|
 | 
						|
        if (!session_id()) {
 | 
						|
            $this->openSession();
 | 
						|
        }
 | 
						|
 | 
						|
        $this->redis($redis, $redisDSN, $redisPort, $redisPass, $redis_expire, $redis_prefix);
 | 
						|
 | 
						|
        if (session_name() === $this->name) {
 | 
						|
            $this->data =& $_SESSION;
 | 
						|
        } else {
 | 
						|
            $this->openSession();
 | 
						|
            $this->data =& $_SESSION;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /** 
 | 
						|
     * Open the PHP session
 | 
						|
     * 
 | 
						|
     * @return void  
 | 
						|
     */
 | 
						|
    private function openSession()
 | 
						|
    {
 | 
						|
 | 
						|
        $this->closeSession();
 | 
						|
 | 
						|
        ini_set('session.use_cookies', 'On');
 | 
						|
        ini_set('session.use_trans_sid', 'Off');
 | 
						|
        ini_set('session.cookie_httponly', 1);
 | 
						|
        if ($this->isSecure())
 | 
						|
            ini_set('session.cookie_secure', 1);
 | 
						|
 | 
						|
        session_set_cookie_params(0, '/');
 | 
						|
        //session_id(md5());
 | 
						|
        session_name($this->name);
 | 
						|
        session_start();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Check and iniciate the Redis connection
 | 
						|
     * 
 | 
						|
     * @param bool $redis 
 | 
						|
     * @param string|null $redisDSN 
 | 
						|
     * @param string|null $redisPort 
 | 
						|
     * @param string|null $redisPass 
 | 
						|
     * @param int|null $redis_expire 
 | 
						|
     * @param string $redis_prefix 
 | 
						|
     * 
 | 
						|
     * @since 2.0.0
 | 
						|
     * @return false|Credis 
 | 
						|
     */
 | 
						|
    private function redis($redis = false, $redisDSN = null, $redisPort = null, $redisPass = null, $redis_expire = null, $redis_prefix = 'phacil_')
 | 
						|
    {
 | 
						|
 | 
						|
        if (!$redis)
 | 
						|
            return false;
 | 
						|
 | 
						|
        $this->redisExpire = ($redis_expire) ?: session_cache_expire() * 60;
 | 
						|
        $this->redisPrefix = ($redis_prefix) ?: 'phacil_';
 | 
						|
        $this->generateRedisKey();
 | 
						|
 | 
						|
        /**
 | 
						|
         * Instanciate the Credis object
 | 
						|
         * 
 | 
						|
         * @var \Phacil\Framework\Credis
 | 
						|
         */
 | 
						|
        $this->redis = new Credis((($redisDSN) ?: '127.0.0.1'), (($redisPort) ?: '6379'), (($redisPass) ?: null));
 | 
						|
 | 
						|
        $_SESSION = unserialize($this->redis->get($this->redisKey));
 | 
						|
 | 
						|
        return $this->redis;
 | 
						|
    }
 | 
						|
 | 
						|
    /** 
 | 
						|
     * Generate the Redis Session KEY
 | 
						|
     * 
 | 
						|
     * @return void  
 | 
						|
     */
 | 
						|
    private function generateRedisKey()
 | 
						|
    {
 | 
						|
        if (session_id())
 | 
						|
            $this->redisKey = $this->redisPrefix . session_name() . session_id();
 | 
						|
 | 
						|
        return $this->redisKey;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Close sessions
 | 
						|
     * 
 | 
						|
     * @param bool $force 
 | 
						|
     * @return void 
 | 
						|
     */
 | 
						|
    private function closeSession($force = false)
 | 
						|
    {
 | 
						|
        if (session_status() == PHP_SESSION_ACTIVE || $force) {
 | 
						|
            session_unset();
 | 
						|
            session_destroy();
 | 
						|
        }
 | 
						|
        if ($this->redis && $force) {
 | 
						|
            $this->redis->close();
 | 
						|
            unset($this->redis);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /** 
 | 
						|
     * Check if is secure (SSL) connection
 | 
						|
     * @return bool  
 | 
						|
     */
 | 
						|
    private function isSecure()
 | 
						|
    {
 | 
						|
        return (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || $_SERVER['SERVER_PORT'] == 443;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Set the Redis session data
 | 
						|
     * @return void 
 | 
						|
     * @since 2.0.0
 | 
						|
     */
 | 
						|
    public function __destruct()
 | 
						|
    {
 | 
						|
        if ($this->redis) {
 | 
						|
            $this->generateRedisKey();
 | 
						|
 | 
						|
            $this->redis->set($this->redisKey, serialize($_SESSION));
 | 
						|
 | 
						|
            $this->redis->expire($this->redisKey, ($this->redisExpire));
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Flush all session data
 | 
						|
     * @return void 
 | 
						|
     * @since 2.0.0
 | 
						|
     */
 | 
						|
    public function flushAll()
 | 
						|
    {
 | 
						|
        $this->data = [];
 | 
						|
        if ($this->redis) {
 | 
						|
            ($this->redis->flushAll());
 | 
						|
        }
 | 
						|
        $this->closeSession(true);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Flush current session data
 | 
						|
     * @return void 
 | 
						|
     * @since 2.0.0
 | 
						|
     */
 | 
						|
    public function flush()
 | 
						|
    {
 | 
						|
        $this->data = [];
 | 
						|
        if ($this->redis) {
 | 
						|
            ($this->redis->del($this->generateRedisKey()));
 | 
						|
        }
 | 
						|
        $this->closeSession(true);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Return the current session ID
 | 
						|
     * 
 | 
						|
     * @since 2.0.0
 | 
						|
     * @return string|false 
 | 
						|
     */
 | 
						|
    public function getSessionId()
 | 
						|
    {
 | 
						|
        return session_id();
 | 
						|
    }
 | 
						|
}
 | 
						|
 |