Changeset 2994

Show
Ignore:
Timestamp:
07/07/2008 08:30:32 PM (5 months ago)
Author:
Shadowhand
Message:

Fixing #660 and #674, thanks edam and alexsancho.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/system/libraries/drivers/Session/Database.php

    r2727 r2994  
    1313 
    1414        /* 
    15         CREATE TABLE kohana_session 
     15        CREATE TABLE sessions 
    1616        ( 
    17                 session_id VARCHAR(40) NOT NULL, 
    18                 last_activity INT(11) NOT NULL, 
     17                session_id VARCHAR(127) NOT NULL, 
     18                last_activity INT(10) UNSIGNED NOT NULL, 
    1919                data TEXT NOT NULL, 
    2020                PRIMARY KEY (session_id) 
     
    2222        */ 
    2323 
    24         protected $db; 
     24        // Database settings 
     25        protected $db = 'default'; 
     26        protected $table = 'sessions'; 
     27 
     28        // Encryption 
    2529        protected $encrypt; 
    2630 
    27         protected $db_group; 
    28         protected $db_table; 
    29         protected $new_session = TRUE; 
    30         protected $old_id; 
    31  
    32         // Session has been written? 
     31        // Session settings 
     32        protected $session_id; 
    3333        protected $written = FALSE; 
    3434 
    3535        public function __construct() 
    3636        { 
    37                 $this->db_group = Config::item('session.storage'); 
    38                 $this->db_table = Config::item('session.name'); 
     37                // Load configuration 
     38                $config = Config::item('session'); 
    3939 
    40                 // Load Encrypt library 
    41                 if (Config::item('session.encryption')) 
     40                if ( ! empty($config['encryption'])) 
    4241                { 
     42                        // Load encryption 
    4343                        $this->encrypt = Encrypt::instance(); 
    4444                } 
    4545 
    46                 // Write the session when PHP shuts down, this stops the database 
    47                 // being connected to twice when exit is called manually 
    48                 register_shutdown_function('session_write_close'); 
     46                if (is_array($config['storage'])) 
     47                { 
     48                        if ( ! empty($config['storage']['group'])) 
     49                        { 
     50                                // Set the group name 
     51                                $this->db = $config['storage']['group']; 
     52                        } 
     53 
     54                        if ( ! empty($config['storage']['table'])) 
     55                        { 
     56                                // Set the table name 
     57                                $this->table = $config['storage']['table']; 
     58                        } 
     59                } 
     60 
     61                // Load database 
     62                $this->db = Database::instance($this->db); 
    4963 
    5064                Log::add('debug', 'Session Database Driver Initialized'); 
     
    5367        public function open($path, $name) 
    5468        { 
    55  
    56                 if (Config::item('database.'.$this->db_group) === NULL) 
    57                 { 
    58                         // There's no defined group, use the default database 
    59                         Log::add('debug', 'Warning: Session Storage database group not found, using default'); 
    60                         $this->db = Database::instance(); 
    61                 } 
    62                 else 
    63                 { 
    64                         // Connect to the database using a database group, defined 
    65                         // by the 'session.storage' config item. 
    66                         $this->db = Database::instance($this->db_group); 
    67                 } 
    68  
    69                 return is_object($this->db); 
     69                return TRUE; 
    7070        } 
    7171 
     
    7777        public function read($id) 
    7878        { 
    79                 $query = $this->db->from($this->db_table)->where('session_id', $id)->get()->result(TRUE); 
     79                // Load the session 
     80                $query = $this->db->from($this->table)->where('session_id', $id)->limit(1)->get()->result(TRUE); 
    8081 
    81                 if ($query->count() > 0) 
     82                if ($query->count() === 0) 
    8283                { 
    83                         // No new session, this is used when writing the data 
    84                         $this->new_session = FALSE; 
    85                         return empty($this->encrypt) ? base64_decode($query->current()->data) : $this->encrypt->decode($query->current()->data); 
     84                        // No current session 
     85                        $this->session_id = NULL; 
     86 
     87                        return ''; 
    8688                } 
    8789 
    88                 // Return value must be string, NOT a boolean 
    89                 return ''; 
     90                // Set the current session id 
     91                $this->session_id = $id; 
     92 
     93                // Load the data 
     94                $data = $query->current()->data; 
     95 
     96                return ($this->encrypt === NULL) ? base64_decode($data) : $this->encrypt->decode($data); 
    9097        } 
    9198 
    9299        public function write($id, $data) 
    93100        { 
    94                 // Has the session already been written? 
    95                 if ($this->written) 
    96                         return TRUE; 
    97  
    98                 $session = array 
     101                $data = array 
    99102                ( 
    100103                        'session_id' => $id, 
    101104                        'last_activity' => time(), 
    102                         'data' => empty($this->encrypt) ? base64_encode($data) : $this->encrypt->encode($data) 
     105                        'data' => ($this->encrypt === NULL) ? base64_encode($data) : $this->encrypt->encode($data) 
    103106                ); 
    104107 
    105                 // Existing session, with regenerated session id 
    106                 if ( ! empty($this->old_id)) 
     108                if ($this->session_id === NULL) 
    107109                { 
    108                         $query = $this->db->update($this->db_table, $session, array('session_id' => $this->old_id)); 
     110                        // Insert a new session 
     111                        $query = $this->db->insert($this->table, $data); 
    109112                } 
    110                 // New session 
    111                 elseif ($this->new_session) 
     113                elseif ($id === $this->session_id) 
    112114                { 
    113                         $query = $this->db->insert($this->db_table, $session); 
     115                        // Do not update the session_id 
     116                        unset($data['session_id']); 
     117 
     118                        // Update the existing session 
     119                        $query = $this->db->update($this->table, $data, array('session_id' => $id)); 
    114120                } 
    115                 // Existing session, without regenerated session id 
    116121                else 
    117122                { 
    118                         // No need to update session_id 
    119                         unset($session['session_id']); 
     123                        // Update the session and id 
     124                        $query = $this->db->update($this->table, $data, array('session_id' => $this->session_id)); 
    120125 
    121                         $query = $this->db->update($this->db_table, $session, array('session_id' => $id)); 
    122  
    123                         $this->written = TRUE; 
     126                        // Set the new session id 
     127                        $this->session_id = $id; 
    124128                } 
    125129 
     
    129133        public function destroy($id) 
    130134        { 
    131                 $config = Config::item('session'); 
     135                // Delete the requested session 
     136                $this->db->delete($this->table, array('session_id' => $id)); 
    132137 
    133         ($config['regenerate'] > 0 AND ($_SESSION['total_hits'] % $config['regenerate']) === 0) AND $id = $this->old_id; 
     138                // Session id is no longer valid 
     139                $this->session_id = NULL; 
    134140 
    135                 return (bool) $this->db->delete($this->db_table, array('session_id' => $id))->count(); 
     141                return TRUE; 
    136142        } 
    137143 
    138144        public function regenerate() 
    139145        { 
    140                 // It's wasteful to delete the old session and insert a whole new one so 
    141                 // we cache the old id to simply update the db with the new one 
    142                 $this->old_id = session_id(); 
     146                // Cache the session id 
     147                $this->session_id = session_id(); 
    143148 
     149                // Generate a new session id 
    144150                session_regenerate_id(); 
    145151 
     
    150156        public function gc($maxlifetime) 
    151157        { 
    152                 $query = $this->db->delete($this->db_table, array('last_activity <' => time() - $maxlifetime)); 
     158                // Delete all expired sessions 
     159                $query = $this->db->delete($this->table, array('last_activity <' => time() - $maxlifetime)); 
    153160 
    154161                Log::add('debug', 'Session garbage collected: '.$query->count().' row(s) deleted.');