Location: PHPKode > projects > Simple Way to Usenet > libs/core/sessions/cooky.class.php
<?php
/**
 *  
 * @author  Benjamin Gillissen <hide@address.com>
 * 
 *	**************************************************************

	Copyright (C) 2009  Benjamin Gillissen
	
	This program is free software; you can redistribute it and/or
	modify it under the terms of the GNU General Public License
	as published by the Free Software Foundation; either version 2
	of the License, or (at your option) any later version.
	
	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details at:
	http://www.gnu.org/copyleft/gpl.html

 *	**************************************************************
 */
class cooky {
	
	private $ref, $exp, $dir;
	private $crypt;			//Ref to crypt object
	
	public function __construct($ref, $exp, $cipher=FALSE, $mode='ECB', $key=NULL){
		if ( headers_sent($file, $line) ){
		    errors::raise('No Cookies operation possible, Output started at : '.$file.':'.$line, CORE_LOG_ERR, 'COOK');
		    return;
		}
		$this->ref = $ref;
		$this->exp = time()+$exp;
		$this->dir = browsing::basedir();
		if ( empty($this->dir) ){ $this->dir = '/'; }
		if ( FALSE !== $cipher ){ $this->crypt_update($key, $cipher, $mode); } //do we crypt our cookies ?
	}
	
	private function crypt_update($key, $cipher, $mode){
		$this->crypt = new crypt($cipher, $mode);
		$key 	= CORE::hash($key, 24);				//site key.
		$lokey 	= CORE::hash(NULL, 24);				//a random key
		$enkey 	= CORE::hash($key.$lokey, 24);		//new encryption key, sitekey + randomkey (clientkey) 
		if ( isset($_COOKIE[$this->ref."_key"]) ){
			$this->crypt->setkey($key);									//clientkey is crypted using the site key
			$ckey = $this->crypt->decrypt($_COOKIE[$this->ref."_key"]);	//we got the clear clientkey
			$dekey = CORE::hash($key.$ckey, 24);						//now we got the cooky decrypt key (site key + client key)			
			if ( isset($_COOKIE[$this->ref]) ){
				$this->crypt->setkey($dekey);							//we use computed key to decrypt cookies
				$buf = $this->crypt->decrypt($_COOKIE[$this->ref]);		//we decrypt
				$this->crypt->setkey($enkey);							//we use encrypt key to set cookies
				$buf = $this->crypt->encrypt($buf);		//we reencrypt.
				setcookie($this->ref, $buf, $this->exp, $this->dir); //we update client cooky eh,
				$_COOKIE[$this->ref] = $buf; 
			}
		}
		$this->crypt->setkey($key);									//we use the site key to crypt the remote key
		$buf = $this->crypt->encrypt($lokey);						//we encrypt client key using site key
		setcookie($this->ref.'_key', $buf, $this->exp, $this->dir);	//we update client key
		$this->crypt->setkey($enkey);								//we use encrypt key to crypt cookies
	}
	
	public function read($var){
		if ( !isset($_COOKIE[$this->ref])  ){ return FALSE; }
		$buf = urldecode($_COOKIE[$this->ref]);
		if ( isset($this->crypt) ){ $buf = $this->crypt->decrypt($buf); }
		$buf = unserialize($buf); 
		if ( ! isset($buf[$var]) ){ return FALSE; }
		return ($buf[$var]);
		return FALSE;
	}
	
	public function isdefined($var){
		if ( !isset($_COOKIE[$this->ref])  ){ return FALSE; } 
		$buf = urldecode($_COOKIE[$this->ref]);
		if ( isset($this->crypt) ){ $buf = $this->crypt->decrypt($buf); }
		$buf = unserialize($buf); 
		return isset($buf[$var]);
	}
	
	public function set($var, $val){
		if ( headers_sent($file, $line) ){
		    errors::raise('Cookies could not be defined : Output started at : '.$file.':'.$line, CORE_LOG_ERR, 'COOK');
		    return FALSE;
		}
		if ( isset($_COOKIE[$this->ref]) ){ 
			$buf = urldecode($_COOKIE[$this->ref]);
			if ( isset($this->crypt) ){ $buf = $this->crypt->decrypt($buf); }
			$buf = @unserialize($buf);
			//errors::raise("Adding Cooky '$var' in channel $this->ref, to already set : ".print_r($buf, TRUE), CORE_LOG_DEBUG, 'COOK'); 
		} else {
			//errors::raise("Creating Cooky '$var' in channel $this->ref", CORE_LOG_DEBUG, 'COOK');
			$buf = Array();
		}
		
		$buf[$var] = $val;
		$buf = serialize($buf);
		if ( isset($this->crypt) ){ $buf = $this->crypt->encrypt($buf); }
		$buf = urlencode($buf);
		
		$r  = setcookie($this->ref, $buf, $this->exp, $this->dir);
		if ( FALSE === $r ){ return FALSE; }
		errors::raise("Cooky '$var' in channel $this->ref, has been defined", CORE_LOG_DEBUG, 'COOK');
		$_COOKIE[$this->ref] = $buf;
		return TRUE;
	}
	
	public function del($var){
		if ( headers_sent($file, $line) ){
		    errors::raise('Cookies could not be unset : Output started at : '.$file.':'.$line, CORE_LOG_ERR, 'COOK');
		    return FALSE;
		}
		if ( !isset($_COOKIE[$this->ref]) ){ return TRUE; }
		$buf = urldecode($_COOKIE[$this->ref]);
		if ( isset($this->crypt) ){ $buf = $this->crypt->decrypt($buf); }
		$buf = unserialize($buf); 
		if ( isset($buf[$var]) ){ unset($buf[$var]); } 
		$buf = serialize($buf);
		if ( isset($this->crypt) ){ $buf = $this->crypt->encrypt($buf); }
		$buf = urlencode($buf);
		$r = setcookie($this->ref, $buf, $this->exp, $this->dir);
		if ( FALSE === $r ){ return FALSE; }
		$_COOKIE[$this->ref] = $buf;	
	}
	
	public function clear(){
		if ( headers_sent($file, $line) ){
		    errors::raise('Cookies channel could not be cleared : Output started at : '.$file.':'.$line, CORE_LOG_ERR, 'COOK');
		    return FALSE;
		}
		if ( !isset($_COOKIE[$this->ref]) ){ return TRUE; }
		$r = setcookie($this->ref, '', 0, $this->dir);
		if ( FALSE === $r ){ return FALSE; }
		unset($_COOKIE[$this->ref]);
		return TRUE;
	}
	
}
Return current item: Simple Way to Usenet