enabled = ((defined('PERMANENT_LOGIN') && PERMANENT_LOGIN == 'true') && !isset($_SESSION['COWOA']) && !(function_exists('zen_in_guest_checkout') && zen_in_guest_checkout()));
if (!$this->enabled) {
return;
}
$this->secret = (defined('PERMANENT_LOGIN_SECRET')) ? PERMANENT_LOGIN_SECRET : '';
$this->cookie_lifetime = ((defined('PERMANENT_LOGIN_EXPIRES') && ((int)PERMANENT_LOGIN_EXPIRES) > 0) ? ((int)PERMANENT_LOGIN_EXPIRES) : 14) * 86400;
$this->checkbox_default = (PERMANENT_LOGIN_CHECKBOX_DEFAULT == 'true');
$this->cookie_name = 'zcrm_' . md5(STORE_NAME);
$this->debug = (PERMANENT_LOGIN_DEBUG == 'true');
$this->logfilename = DIR_FS_LOGS . '/remember_me_' . date('Ym') . '.log';
// -----
// This flag "coordinates" the customer's "remembered" login with the plugin's init_include module,
// allowing the customer's cart to be recorded within the currently-active session. Used by the
// restoreRememberedCart class-function and possibly set by the checkRememberCustomer class-function.
//
$this->customer_remembered = false;
// -----
// If a customer is not currently logged in, but there's a valid "Remember Me" cookie present ... then "Remember Them"!
//
if (!$this->customerIsLoggedIn()) {
$remember_info = $this->decodeCookie();
if ($remember_info === false) {
$this->removeCookie();
} else {
$this->checkRememberCustomer($remember_info);
}
}
// -----
// Refresh any "Remember Me" cookie currently set, updating its expiration data and recording the current
// status of the session's cartID value.
//
$this->refreshCookie();
// -----
// Set up to listen for any related observers.
//
$this->attach ($this, array(
/* From /includes/modules/create_account.php */
'NOTIFY_MODULE_CREATE_ACCOUNT_ADDED_CUSTOMER_RECORD',
/* From /includes/modules/pages/login/header_php.php */
'NOTIFY_LOGIN_SUCCESS',
/* From /includes/modules/pages/logoff/header_php.php */
'NOTIFY_HEADER_START_LOGOFF',
));
}
public function update(&$class, $eventID, $paramsArray)
{
global $db;
switch ($eventID) {
// -----
// Upon successful login or account creation, if the customer has checked the "Remember Me" field then create the required cookie to keep them logged in.
//
case 'NOTIFY_LOGIN_SUCCESS':
case 'NOTIFY_MODULE_CREATE_ACCOUNT_ADDED_CUSTOMER_RECORD':
if (isset($_POST['permLogin']) && $_POST['permLogin'] == 1) {
$password_info = $db->Execute(
"SELECT customers_password
FROM " . TABLE_CUSTOMERS . "
WHERE customers_id = " . (int)$_SESSION['customer_id'] . "
LIMIT 1"
);
if (!$password_info->EOF) {
$remember_me_info = array(
'id' => $_SESSION['customer_id'],
'password' => md5($this->secret . $password_info->fields['customers_password']),
);
$cookie_value = $this->encodeCookie($remember_me_info);
$this->setCookie($cookie_value, time() + $this->cookie_lifetime);
}
}
break;
// -----
// When the customer has chosen to click the "Logoff" link, expire any "Remember Me" cookies that might be present.
//
case 'NOTIFY_HEADER_START_LOGOFF':
$this->removeCookie();
break;
default:
break;
}
}
protected function customerIsLoggedIn()
{
return ((function_exists('zen_is_logged_in') && zen_is_logged_in()) || !empty($_SESSION['customer_id']));
}
protected function checkRememberCustomer($remember_info)
{
global $db;
$customers_id = (isset($remember_info['id'])) ? (int)$remember_info['id'] : 0;
$customers_hashed_password = (isset($remember_info['password'])) ? $remember_info['password'] : '~~~~';
$customer_info = $db->Execute(
"SELECT customers_firstname, customers_lastname, customers_password, customers_default_address_id, customers_authorization, customers_referral
FROM " . TABLE_CUSTOMERS . "
WHERE customers_id = $customers_id
LIMIT 1"
);
if ($customer_info->EOF || md5($this->secret . $customer_info->fields['customers_password']) != $customers_hashed_password) {
$this->removeCookie();
} else {
$this->customer_remembered = true; //- Indicates that the customer's cart should be restored once the cart is instantiated.
$_SESSION['customer_id'] = $customers_id;
$_SESSION['currency'] = $remember_info['currency'];
$_SESSION['language'] = $remember_info['language'];
$_SESSION['languages_id'] = $remember_info['languages_id'];
$_SESSION['languages_code'] = $remember_info['languages_code'];
$_SESSION['securityToken'] = $remember_info['securityToken'];
$this->setCartId = (isset($remember_info['cartIdSet']) && $remember_info['cartIdSet'] === true);
$check_country_query =
"SELECT entry_country_id, entry_zone_id
FROM " . TABLE_ADDRESS_BOOK . "
WHERE customers_id = $customers_id
AND address_book_id = :addressBookID
LIMIT 1";
$check_country_query = $db->bindVars($check_country_query, ':addressBookID', $customer_info->fields['customers_default_address_id'], 'integer');
$check_country = $db->Execute($check_country_query);
$_SESSION['customer_default_address_id'] = $customer_info->fields['customers_default_address_id'];
$_SESSION['customers_authorization'] = $customer_info->fields['customers_authorization'];
$_SESSION['customer_first_name'] = $customer_info->fields['customers_firstname'];
$_SESSION['customer_last_name'] = $customer_info->fields['customers_lastname'];
$_SESSION['customer_country_id'] = $check_country->fields['entry_country_id'];
$_SESSION['customer_zone_id'] = $check_country->fields['entry_zone_id'];
$_SESSION['customer_remembered'] = true;
$db->Execute(
"UPDATE " . TABLE_CUSTOMERS_INFO . "
SET customers_info_date_of_last_logon = now(),
customers_info_number_of_logons = customers_info_number_of_logons+1
WHERE customers_info_id = $customers_id
LIMIT 1"
);
}
}
public function restoreRememberedCart()
{
if ($this->enabled && $this->customer_remembered) {
$_SESSION['cart']->restore_contents();
if ($this->setCartId) {
$_SESSION['cartID'] = $_SESSION['cart']->cartID;
}
}
}
public function create_checkbox()
{
if (!$this->enabled) {
return '';
}
$return_value =
'
' .
zen_draw_checkbox_field ('permLogin', '1', $this->checkbox_default, 'id="permLogin"') .
'';
return $return_value;
}
protected function encodeCookie($cookie_data)
{
$cookie_data['currency'] = $_SESSION['currency'];
$cookie_data['language'] = $_SESSION['language'];
$cookie_data['languages_id'] = $_SESSION['languages_id'];
$cookie_data['languages_code'] = $_SESSION['languages_code'];
$cookie_data['cartIdSet'] = isset($_SESSION['cartID']);
$cookie_data['securityToken'] = $_SESSION['securityToken'];
$encoded_cookie = base64_encode(gzcompress(serialize($cookie_data), 9));
$this->debugTrace("encodeCookie, value = '$encoded_cookie': " . var_export($cookie_data, true));
return $encoded_cookie;
}
protected function removeCookie()
{
$this->customer_remembered = false;
$this->setCookie('', time() - 3600);
}
protected function decodeCookie()
{
$remember_info = false;
$cookie_value = 'Not valid';
if (isset($_COOKIE[$this->cookie_name]) && $_COOKIE[$this->cookie_name] != 'deleted') {
$cookie_value = $_COOKIE[$this->cookie_name];
$remember_info = base64_decode($cookie_value);
if ($remember_info !== false) {
$remember_info = @gzuncompress($remember_info);
if ($remember_info === false) {
$this->debugTrace("decodeCookie: gzuncompress error in decodeCookie, value = $cookie_value, remember_info = " . var_export($remember_info, true));
} else {
$remember_info = unserialize($remember_info);
if (!is_array($remember_info)) {
$this->debugTrace('decodeCookie: Non-array value found: ' . var_export($remember_info, true));
$remember_info = false;
} else {
$remember_keys = array_keys($remember_info);
$required_keys = array('id', 'password', 'language', 'languages_id', 'languages_code', 'cartIdSet', 'securityToken');
foreach ($required_keys as $key) {
if (!in_array($key, $remember_keys)) {
$this->debugTrace('decodeCookie: Missing required keys. ' . var_export($remember_info, true));
$remember_info = false;
break;
}
}
}
}
}
}
if ($remember_info !== false) {
$this->debugTrace("decodeCookie, value = '$cookie_value': " . var_export($remember_info, true));
}
return $remember_info;
}
protected function refreshCookie()
{
$cookie_data = $this->decodeCookie();
if ($cookie_data === false) {
$this->removeCookie();
} else {
$this->setCookie($this->encodeCookie($cookie_data), time() + $this->cookie_lifetime);
}
}
// -----
// Set the "remember-me" cookie for the specific path associated with the current
// store's configuration.
//
protected function setCookie($value, $expiration)
{
if (!isset($this->domain)) {
$this->domain = str_replace(
array(
'https://',
'http://',
'//'
),
'',
strtolower(HTTP_SERVER)
);
$this->path = DIR_WS_CATALOG;
}
// -----
// Starting with PHP 7.3, the setcookie function now accepts an alternate array
// input, enabling the setting of the "SameSite" cookie attribute.
//
if (PHP_VERSION_ID < 70300) {
setcookie($this->cookie_name, $value, $expiration, $this->path, $this->domain, false, true);
} else {
$cookie_options = array(
'expires' => $expiration,
'path' => $this->path,
'domain' => $this->domain,
'secure' => false,
'httponly' => true,
'samesite' => 'Strict'
);
setcookie($this->cookie_name, $value, $cookie_options);
}
}
// -----
// Output, if enabled and a customer is **not** logged in, a debug message to a log-file.
//
// The output is restricted to non-logged-in customers to capture the information only when
// a cookie is being checked so that the trace-log isn't filled with unimportant information.
//
protected function debugTrace($message)
{
if (!$this->customerIsLoggedIn() && $this->debug) {
error_log(date('Y-m-d H:i:s') . ' ' . $message . PHP_EOL, 3, $this->logfilename);
}
}
}