312 lines
7.9 KiB
PHP
312 lines
7.9 KiB
PHP
<?php
|
|
|
|
/**
|
|
* Cookie class, Cookie.php
|
|
* Cookies management
|
|
* @category classes
|
|
*
|
|
* @author PrestaShop <support@prestashop.com>
|
|
* @copyright PrestaShop
|
|
* @license http://www.opensource.org/licenses/osl-3.0.php Open-source licence 3.0
|
|
* @version 1.3
|
|
*
|
|
*/
|
|
|
|
class Cookie
|
|
{
|
|
/** @var array Contain cookie content in a key => value format */
|
|
private $_content;
|
|
|
|
/** @var array Crypted cookie name for setcookie() */
|
|
private $_name;
|
|
|
|
/** @var array expiration date for setcookie() */
|
|
private $_expire;
|
|
|
|
/** @var array Website domain for setcookie() */
|
|
private $_domain;
|
|
|
|
/** @var array Path for setcookie() */
|
|
private $_path;
|
|
|
|
/** @var array Blowfish instance */
|
|
private $_bf;
|
|
|
|
/** @var array 56 chars Blowfish initialization key */
|
|
private $_key;
|
|
|
|
/** @var array 8 chars Blowfish initilization vector */
|
|
private $_iv;
|
|
|
|
/**
|
|
* Get data if the cookie exists and else initialize an new one
|
|
*
|
|
* @param $name Cookie name before encrypting
|
|
* @param $path
|
|
*/
|
|
function __construct($name, $path = '', $expire = NULL)
|
|
{
|
|
$this->_content = array();
|
|
$this->_expire = isset($expire) ? intval($expire) : (time() + 1728000);
|
|
$this->_name = md5($name._COOKIE_KEY_);
|
|
$this->_path = trim(__PS_BASE_URI__.$path, '/\\').'/';
|
|
if ($this->_path{0} != '/') $this->_path = '/'.$this->_path;
|
|
$this->_path = rawurlencode($this->_path);
|
|
$this->_path = str_replace('%2F', '/', $this->_path);
|
|
$this->_path = str_replace('%7E', '~', $this->_path);
|
|
$this->_key = _COOKIE_KEY_;
|
|
$this->_iv = _COOKIE_IV_;
|
|
$this->_domain = $this->getDomain();
|
|
$this->_bf = new Blowfish($this->_key, $this->_iv);
|
|
$this->update();
|
|
}
|
|
|
|
private function getDomain()
|
|
{
|
|
$r = '!(?:(\w+)://)?(?:(\w+)\:(\w+)@)?([^/:]+)?(?:\:(\d*))?([^#?]+)?(?:\?([^#]+))?(?:#(.+$))?!i';
|
|
preg_match ($r, Tools::getHttpHost(false, false), $out);
|
|
if (preg_match('/^(((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]{1}[0-9]|[1-9]).)'.
|
|
'{1}((25[0-5]|2[0-4][0-9]|[1]{1}[0-9]{2}|[1-9]{1}[0-9]|[0-9]).)'.
|
|
'{2}((25[0-5]|2[0-4][0-9]|[1]{1}[0-9]{2}|[1-9]{1}[0-9]|[0-9]){1}))$/', $out[4]))
|
|
return false;
|
|
if (!strstr(Tools::getHttpHost(false, false), '.'))
|
|
return false;
|
|
$domain = $out[4];
|
|
$subDomains = SubDomain::getSubDomains();
|
|
if ($subDomains === false)
|
|
die(Tools::displayError('Bad SubDomain SQL query!'));
|
|
foreach ($subDomains AS $subDomain)
|
|
{
|
|
$subDomainLength = strlen($subDomain) + 1;
|
|
if (strncmp($subDomain.'.', $domain, $subDomainLength) == 0)
|
|
$domain = substr($domain, $subDomainLength);
|
|
}
|
|
return $domain;
|
|
}
|
|
|
|
/**
|
|
* Set expiration date
|
|
*
|
|
* @param integer $expire Expiration time from now
|
|
*/
|
|
function setExpire($expire)
|
|
{
|
|
$this->_expire = intval($expire);
|
|
}
|
|
|
|
/**
|
|
* Magic method wich return cookie data from _content array
|
|
*
|
|
* @param $key key wanted
|
|
* @return string value corresponding to the key
|
|
*/
|
|
function __get($key)
|
|
{
|
|
return isset($this->_content[$key]) ? $this->_content[$key] : false;
|
|
}
|
|
|
|
/**
|
|
* Magic method wich check if key exists in the cookie
|
|
*
|
|
* @param $key key wanted
|
|
* @return boolean key existence
|
|
*/
|
|
function __isset($key)
|
|
{
|
|
return isset($this->_content[$key]);
|
|
}
|
|
|
|
/**
|
|
* Magic method wich add data into _content array
|
|
*
|
|
* @param $key key desired
|
|
* @param $value value corresponding to the key
|
|
*/
|
|
function __set($key, $value)
|
|
{
|
|
if (is_array($value))
|
|
die(Tools::displayError());
|
|
if (preg_match('/¤|\|/', $key) OR preg_match('/¤|\|/', $value))
|
|
throw new Exception('Forbidden chars in cookie');
|
|
$this->_content[$key] = $value;
|
|
$this->write();
|
|
}
|
|
|
|
/**
|
|
* Magic method wich delete data into _content array
|
|
*
|
|
* @param $key key wanted
|
|
*/
|
|
function __unset($key)
|
|
{
|
|
unset($this->_content[$key]);
|
|
$this->write();
|
|
}
|
|
|
|
/**
|
|
* Check customer informations saved into cookie and return customer validity
|
|
*
|
|
* @return boolean customer validity
|
|
*/
|
|
function isLogged()
|
|
{
|
|
/* Customer is valid only if it can be load and if cookie password is the same as database one */
|
|
if ($this->logged == 1 AND $this->id_customer AND Validate::isUnsignedId($this->id_customer) AND Customer::checkPassword(intval($this->id_customer), $this->passwd))
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Check employee informations saved into cookie and return employee validity
|
|
*
|
|
* @return boolean employee validity
|
|
*/
|
|
function isLoggedBack()
|
|
{
|
|
/* Employee is valid only if it can be load and if cookie password is the same as database one */
|
|
if ($this->id_employee AND Validate::isUnsignedId($this->id_employee) AND Employee::checkPassword(intval($this->id_employee), $this->passwd) AND (!isset($this->_content['remote_addr']) OR $this->_content['remote_addr'] == ip2long($_SERVER['REMOTE_ADDR'])))
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Delete cookie
|
|
*/
|
|
function logout()
|
|
{
|
|
$this->_content = array();
|
|
$this->_setcookie();
|
|
unset($_COOKIE[$this->_name]);
|
|
}
|
|
|
|
/**
|
|
* Soft logout, delete everything links to the customer
|
|
* but leave there affiliate's informations
|
|
*/
|
|
function mylogout()
|
|
{
|
|
unset($this->_content['id_customer']);
|
|
unset($this->_content['id_guest']);
|
|
unset($this->_content['id_connections']);
|
|
unset($this->_content['customer_lastname']);
|
|
unset($this->_content['customer_firstname']);
|
|
unset($this->_content['passwd']);
|
|
unset($this->_content['logged']);
|
|
unset($this->_content['email']);
|
|
unset($this->_content['id_cart']);
|
|
unset($this->_content['id_address_invoice']);
|
|
unset($this->_content['id_address_delivery']);
|
|
$this->write();
|
|
}
|
|
|
|
function makeNewLog()
|
|
{
|
|
unset($this->_content['id_customer']);
|
|
unset($this->_content['id_guest']);
|
|
Guest::setNewGuest($this);
|
|
}
|
|
|
|
/**
|
|
* Get cookie content
|
|
*/
|
|
function update($nullValues = false)
|
|
{
|
|
if (isset($_COOKIE[$this->_name]))
|
|
{
|
|
/* Decrypt cookie content */
|
|
$content = $this->_bf->decrypt($_COOKIE[$this->_name]);
|
|
|
|
/* Get cookie checksum */
|
|
$checksum = crc32($this->_iv.substr($content, 0, strrpos($content, '¤') + 2));
|
|
|
|
/* Unserialize cookie content */
|
|
$tmpTab = explode('¤', $content);
|
|
|
|
foreach ($tmpTab AS $keyAndValue)
|
|
{
|
|
$tmpTab2 = explode('|', $keyAndValue);
|
|
if (sizeof($tmpTab2) == 2)
|
|
$this->_content[$tmpTab2[0]] = $tmpTab2[1];
|
|
}
|
|
|
|
/* Blowfish fix */
|
|
if (isset($this->_content['checksum']))
|
|
$this->_content['checksum'] = intval($this->_content['checksum']);
|
|
|
|
/* Check if cookie has not been modified */
|
|
if (!isset($this->_content['checksum']) OR $this->_content['checksum'] != $checksum)
|
|
$this->logout();
|
|
}
|
|
else
|
|
$this->_content['date_add'] = date('Y-m-d H:i:s');
|
|
}
|
|
|
|
/**
|
|
* Setcookie according to php version
|
|
*/
|
|
private function _setcookie($cookie = NULL)
|
|
{
|
|
if ($cookie)
|
|
{
|
|
$content = $this->_bf->encrypt($cookie);
|
|
$time = $this->_expire;
|
|
}
|
|
else
|
|
{
|
|
$content = 0;
|
|
$time = time() - 1;
|
|
}
|
|
|
|
if (version_compare(substr(phpversion(), 0, 3), '5.2.0') == -1)
|
|
return setcookie($this->_name, $content, $time, $this->_path, $this->_domain, 0);
|
|
else
|
|
return setcookie($this->_name, $content, $time, $this->_path, $this->_domain, 0, true);
|
|
}
|
|
|
|
/**
|
|
* Save cookie with setcookie()
|
|
*/
|
|
function write()
|
|
{
|
|
$cookie = '';
|
|
|
|
/* Serialize cookie content */
|
|
if (isset($this->_content['checksum'])) unset($this->_content['checksum']);
|
|
foreach ($this->_content AS $key => $value)
|
|
$cookie .= $key.'|'.$value.'¤';
|
|
|
|
/* Add checksum to cookie */
|
|
$cookie .= 'checksum|'.crc32($this->_iv.$cookie);
|
|
|
|
/* Cookies are encrypted for evident security reasons */
|
|
return $this->_setcookie($cookie);
|
|
}
|
|
|
|
/**
|
|
* Get a family of variables (e.g. "filter_")
|
|
*/
|
|
public function getFamily($origin)
|
|
{
|
|
$result = array();
|
|
if (count($this->_content) == 0)
|
|
return $result;
|
|
foreach ($this->_content AS $key => $value)
|
|
if (strncmp($key, $origin, strlen($origin)) == 0)
|
|
$result[$key] = $value;
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
*
|
|
*/
|
|
public function unsetFamily($origin)
|
|
{
|
|
$family = $this->getFamily($origin);
|
|
foreach ($family AS $member => $value)
|
|
unset($this->$member);
|
|
}
|
|
|
|
}
|
|
|
|
?>
|