관리-도구
편집 파일: functions_customers.php
<?php /** * functions_customers * * @copyright Copyright 2003-2020 Zen Cart Development Team * @copyright Portions Copyright 2003 osCommerce * @license http://www.zen-cart.com/license/2_0.txt GNU Public License V2.0 * @version $Id: DrByte 2020 Jun 13 Modified in v1.5.7 $ */ /** * Returns the address_format_id for the given country */ function zen_get_address_format_id($country_id) { global $db; $address_format_query = "select address_format_id as format_id from " . TABLE_COUNTRIES . " where countries_id = " . (int)$country_id; $address_format = $db->Execute($address_format_query); if ($address_format->RecordCount() > 0) { return $address_format->fields['format_id']; } return 1; } /** * Return a formatted address, based on specified formatting pattern id */ function zen_address_format($address_format_id = 1, $incoming = array(), $html = false, $boln = '', $eoln = "\n") { global $db; $address = array(); $address['hr'] = $html ? '<hr>' : '----------------------------------------'; $address['cr'] = $html ? ($boln == '' && $eoln == "\n" ? '<br>' : $eoln . $boln) : $eoln; if (ACCOUNT_SUBURB !== 'true') $incoming['suburb'] = ''; $address['company'] = !empty($incoming['company']) ? zen_output_string_protected($incoming['company']) : ''; $address['firstname'] = !empty($incoming['firstname']) ? zen_output_string_protected($incoming['firstname']) : (!empty($incoming['name']) ? zen_output_string_protected($incoming['name']) : ''); $address['lastname'] = !empty($incoming['lastname']) ? zen_output_string_protected($incoming['lastname']) : ''; $address['street'] = !empty($incoming['street_address']) ? zen_output_string_protected($incoming['street_address']) : ''; $address['suburb'] = !empty($incoming['suburb']) ? zen_output_string_protected($incoming['suburb']) : ''; $address['city'] = !empty($incoming['city']) ? zen_output_string_protected($incoming['city']) : ''; $address['state'] = !empty($incoming['state']) ? zen_output_string_protected($incoming['state']) : ''; $address['postcode'] = !empty($incoming['postcode']) ? zen_output_string_protected($incoming['postcode']) : ''; $address['zip'] = $address['postcode']; $address['streets'] = !empty($address['suburb']) ? $address['street'] . $address['cr'] . $address['suburb'] : $address['street']; $address['statecomma'] = !empty($address['state']) ? $address['state'] . ', ' : ''; $country = ''; if (!empty($incoming['country_id'])) { $country = zen_get_country_name($incoming['country_id']); if (!empty($incoming['zone_id'])) { $address['state'] = zen_get_zone_code($incoming['country_id'], $incoming['zone_id'], $address['state']); } } elseif (!empty($incoming['country'])) { if (is_array($incoming['country'])) { $country = zen_output_string_protected($incoming['country']['countries_name']); } else { $country = zen_output_string_protected($incoming['country']); } } $address['country'] = $country; // add uppercase variants for backward compatibility $address['HR'] = $address['hr']; $address['CR'] = $address['cr']; $sql = "select address_format as format from " . TABLE_ADDRESS_FORMAT . " where address_format_id = " . (int)$address_format_id; $result = $db->Execute($sql); $fmt = (!$result->EOF ? $result->fields['format'] : ''); // sort to put longer keys at the top of the array so that longer variants are replaced before shorter ones array_multisort(array_map('strlen', array_keys($address)), SORT_DESC, $address); // store translated values into original array, just for the sake of the notifier $incoming = $address; // convert into $-prefixed keys foreach ($address as $key => $value) { $address['$' . $key] = $value; unset($address[$key]); } // do the substitutions $address_out = str_replace(array_keys($address), array_values($address), $fmt); if (ACCOUNT_COMPANY == 'true' && !empty($address['$company']) && false === strpos($fmt, '$company')) { $address_out = $address['$company'] . $address['$cr'] . $address_out; } if (ACCOUNT_SUBURB !== 'true') $address['suburb'] = ''; // ----- // "Package up" the various elements of an address and issue a notification that will enable // an observer to make modifications if needed. // $GLOBALS['zco_notifier']->notify( 'NOTIFY_END_ZEN_ADDRESS_FORMAT', array( 'format' => $fmt, 'address' => $incoming, 'firstname' => $address['$firstname'], 'lastname' => $address['$lastname'], 'street' => $address['$street'], 'suburb' => $address['$suburb'], 'city' => $address['$city'], 'state' => $address['$state'], 'country' => $address['$country'], 'postcode' => $address['$postcode'], 'company' => $address['$company'], 'streets' => $address['$streets'], 'statecomma' => $address['$statecomma'], 'zip' => $address['$zip'], 'cr' => $address['$cr'], 'hr' => $address['$hr'], ), $address_out ); return $address_out; } /** * Return a formatted address, based on customer's address's country format */ function zen_address_label($customers_id, $address_id = 1, $html = false, $boln = '', $eoln = "\n") { global $db; $address_query = "select entry_firstname as firstname, entry_lastname as lastname, entry_company as company, entry_street_address as street_address, entry_suburb as suburb, entry_city as city, entry_postcode as postcode, entry_state as state, entry_zone_id as zone_id, entry_country_id as country_id from " . TABLE_ADDRESS_BOOK . " where customers_id = " . (int)$customers_id . " and address_book_id = " . (int)$address_id; $address = $db->Execute($address_query); $GLOBALS['zco_notifier']->notify('NOTIFY_ZEN_ADDRESS_LABEL', array(), $customers_id, $address_id, $address->fields); $format_id = zen_get_address_format_id($address->fields['country_id']); return zen_address_format($format_id, $address->fields, $html, $boln, $eoln); } // look up customers default or primary address function zen_get_customers_address_primary($customer_id) { global $db; $lookup_customers_primary_address_query = "SELECT customers_default_address_id from " . TABLE_CUSTOMERS . " WHERE customers_id = " . (int)$customer_id; $lookup_customers_primary_address = $db->Execute($lookup_customers_primary_address_query); return $lookup_customers_primary_address->fields['customers_default_address_id']; } //// // Return a customer greeting function zen_customer_greeting() { if (zen_is_logged_in() && !zen_in_guest_checkout() && !empty($_SESSION['customer_first_name'])) { $greeting_string = sprintf(TEXT_GREETING_PERSONAL, zen_output_string_protected($_SESSION['customer_first_name']), zen_href_link(FILENAME_PRODUCTS_NEW)); } else { $greeting_string = sprintf(TEXT_GREETING_GUEST, zen_href_link(FILENAME_LOGIN, '', 'SSL'), zen_href_link(FILENAME_CREATE_ACCOUNT, '', 'SSL')); } return $greeting_string; } function zen_count_customer_orders($id = '', $check_session = true) { global $db; // ----- // Quick return if no customer is logged in or if the current customer is in a // guest-checkout. // if (!zen_is_logged_in() || zen_in_guest_checkout()) { return 0; } if (is_numeric($id) == false) { if (!empty($_SESSION['customer_id'])) { $id = $_SESSION['customer_id']; } else { return 0; } } if ($check_session == true) { if (empty($_SESSION['customer_id']) || $id != $_SESSION['customer_id']) { return 0; } } $orders_check_query = "select count(*) as total from " . TABLE_ORDERS . " where customers_id = " . (int)$id; $orders_check = $db->Execute($orders_check_query); return $orders_check->fields['total']; } function zen_count_customer_address_book_entries($id = '', $check_session = true) { global $db; // ----- // Quick return if no customer is logged in or if the customer is in a guest checkout. // if (!zen_is_logged_in() || zen_in_guest_checkout()) { return 0; } if (is_numeric($id) == false) { if (!empty($_SESSION['customer_id'])) { $id = $_SESSION['customer_id']; } else { return 0; } } if ($check_session == true) { if (empty($_SESSION['customer_id']) || $id != $_SESSION['customer_id']) { return 0; } } $addresses_query = "select count(*) as total from " . TABLE_ADDRESS_BOOK . " where customers_id = " . (int)$id; $addresses = $db->Execute($addresses_query); return $addresses->fields['total']; } //// // validate customer matches session function zen_get_customer_validate_session($customer_id) { global $db, $messageStack; $zc_check_customer = $db->Execute("SELECT customers_id, customers_authorization from " . TABLE_CUSTOMERS . " WHERE customers_id=" . (int)$customer_id); if ($zc_check_customer->EOF || $zc_check_customer->fields['customers_authorization'] == 4) { // Banned status is 4 $db->Execute("DELETE from " . TABLE_CUSTOMERS_BASKET . " WHERE customers_id= " . $customer_id); $db->Execute("DELETE from " . TABLE_CUSTOMERS_BASKET_ATTRIBUTES . " WHERE customers_id= " . $customer_id); $_SESSION['cart']->reset(TRUE); unset($_SESSION['customer_id']); if ($zc_check_customer->fields['customers_authorization'] != 4) { $messageStack->add_session('header', ERROR_CUSTOMERS_ID_INVALID, 'error'); } return false; } return true; } /** * This function identifies whether (true) or not (false) the current customer session is * associated with a guest-checkout process. */ function zen_in_guest_checkout() { $in_guest_checkout = false; $GLOBALS['zco_notifier']->notify('NOTIFY_ZEN_IN_GUEST_CHECKOUT', '', $in_guest_checkout); return (bool)$in_guest_checkout; } /** * This function identifies whether (true) or not (false) a customer is currently logged into the site. */ function zen_is_logged_in() { $is_logged_in = (!empty($_SESSION['customer_id'])); $GLOBALS['zco_notifier']->notify('NOTIFY_ZEN_IS_LOGGED_IN', '', $is_logged_in); return (bool)$is_logged_in; } /** * This function determines if the login-password supplied is associated with a permitted * admin's admin-password, returning (bool)true if so. Normally called during the login-page's * header_php.php processing. */ function zen_validate_storefront_admin_login($password, $email_address) { global $db; $admin_authorized = false; // Before v1.5.7 Admin passwords might be 'sanitized', e.g. this&that becomes this&that, so we'll check both versions. $pwd2 = htmlspecialchars($password, ENT_COMPAT, CHARSET); if (!empty(EMP_LOGIN_ADMIN_ID)) { $check = $db->Execute( "SELECT admin_id, admin_pass FROM " . TABLE_ADMIN . " WHERE admin_id = " . (int)EMP_LOGIN_ADMIN_ID . " LIMIT 1" ); if (!$check->EOF && (zen_validate_password($password, $check->fields['admin_pass']) || zen_validate_password($pwd2, $check->fields['admin_pass']))) { $admin_authorized = true; $_SESSION['emp_admin_login'] = true; $_SESSION['emp_admin_id'] = (int)EMP_LOGIN_ADMIN_ID; } } if (!$admin_authorized && empty(EMP_LOGIN_ADMIN_PROFILE_ID)) { return false; } $profile_array = explode(',', str_replace(' ', '', EMP_LOGIN_ADMIN_PROFILE_ID)); foreach ($profile_array as $index => $current_id) { if (empty($current_id)) { unset($profile_array[$index]); } } if (count($profile_array)) { $profile_list = implode(',', $profile_array); $admin_profiles = $db->Execute( "SELECT admin_id, admin_pass FROM " . TABLE_ADMIN . " WHERE admin_profile IN (" . $profile_list . ")" ); foreach ($admin_profiles as $profile) { $admin_authorized = (zen_validate_password($pwd2, $profile['admin_pass']) || zen_validate_password($pwd2, $profile['admin_pass'])); if ($admin_authorized) { $_SESSION['emp_admin_login'] = true; $_SESSION['emp_admin_id'] = (int)$profile['admin_id']; break; } } } if ($admin_authorized) { $_SESSION['emp_customer_email_address'] = $email_address; $params['action'] = 'emp_admin_login'; $params['emailAddress'] = $email_address; $params['message'] = 'EMP admin login'; zen_log_hmac_login($params); } return $admin_authorized; } function zen_update_customers_secret($customerId) { global $db; $hashable = openssl_random_pseudo_bytes(64); $secret = hash('sha256', $hashable); $sql = "UPDATE " . TABLE_CUSTOMERS . " SET customers_secret = :secret: WHERE customers_id = :id:"; $sql = $db->bindVars($sql, ':secret:', $secret, 'string'); $sql = $db->bindVars($sql, ':id:', $customerId, 'integer'); $db->execute($sql); return $secret; } function zen_create_hmac_uri($data, $secret) { $secret = hash('sha256', $secret . GLOBAL_AUTH_KEY); foreach ($data as $k => $val) { $k = str_replace('%', '%25', $k); $k = str_replace('&', '%26', $k); $k = str_replace('=', '%3D', $k); $val = str_replace('%', '%25', $val); $val = str_replace('&', '%26', $val); $params[$k] = $val; } ksort($params); $hmacData = implode('&', $params); foreach ($data as $k => $val) { unset($params[$k]); } $hmac = hash_hmac('sha256', $hmacData, $secret); $params['hmac'] = $hmac; $uri = http_build_query($params); return $uri; } function zen_is_hmac_login() { if (!isset($_GET['main_page']) || $_GET['main_page'] != FILENAME_LOGIN) { return false; } if (!isset($_GET['hmac'])) return false; if (!isset($_POST['timestamp'])) return false; return true; } function zen_validate_hmac_login() { global $db; $postCheck = ['cid', 'aid', 'email_address']; foreach ($postCheck as $entry) { if (!isset($_POST[$entry])) return false; } $data = $_REQUEST; $unsetArray = ['action', 'main_page', 'securityToken', 'zenid', 'zenInstallerId']; foreach ($unsetArray as $entry) { unset($data[$entry]); } foreach ($data as $k => $val) { $k = str_replace('%', '%25', $k); $k = str_replace('&', '%26', $k); $k = str_replace('=', '%3D', $k); $val = str_replace('%', '%25', $val); $val = str_replace('&', '%26', $val); $params[$k] = $val; } $sql = "SELECT customers_secret FROM " . TABLE_CUSTOMERS . " WHERE customers_id = :id: LIMIT 1"; $sql = $db->bindVars($sql, ':id:', $params['cid'], 'integer'); $result = $db->execute($sql); $secret = $result->fields['customers_secret']; $secret = hash('sha256', $secret . GLOBAL_AUTH_KEY); $hmacOriginal = $data['hmac']; unset($params['hmac']); ksort($params); $hmacData = implode('&', $params); $hmac = hash_hmac('sha256', $hmacData, $secret); return true; } function zen_validate_hmac_timestamp() { $currentTime = time(); $hmacTime = (isset($_POST['timestamp'])) ? $_POST['timestamp'] : 0; return (($currentTime - $hmacTime) <= 20); } function zen_validate_hmac_admin_id($adminId) { global $db; if (!empty(EMP_LOGIN_ADMIN_ID)) { $check = $db->Execute( "SELECT admin_id FROM " . TABLE_ADMIN . " WHERE admin_id = " . (int)EMP_LOGIN_ADMIN_ID . " LIMIT 1" ); if ($check->RecordCount() > 0 && (int)EMP_LOGIN_ADMIN_ID == (int)$adminId) { return (int)$adminId; } } $profile_array = explode(',', str_replace(' ', '', EMP_LOGIN_ADMIN_PROFILE_ID)); foreach ($profile_array as $index => $current_id) { if (empty($current_id)) { unset($profile_array[$index]); } } if (empty($profile_array)) return false; $profile_list = implode(',', $profile_array); $admin_profiles = $db->Execute( "SELECT admin_id FROM " . TABLE_ADMIN . " WHERE admin_id = " . (int)$adminId . " AND admin_profile IN (" . $profile_list . ")" ); if ($admin_profiles->RecordCount() > 0) { return (int)$adminId; } return false; } function zen_log_hmac_login($params) { $sql_data_array = array( 'access_date' => 'now()', 'admin_id' => $_SESSION['emp_admin_id'], 'page_accessed' => 'login.php', 'page_parameters' => '', 'ip_address' => substr($_SERVER['REMOTE_ADDR'],0,45), 'gzpost' => gzdeflate(json_encode(array('action' => $params['action'], 'customer_email_address' => $params['emailAddress'])), 7), 'flagged' => 0, 'attention' => '', 'severity' => 'info', 'logmessage' => $params['message'], ); zen_db_perform(TABLE_ADMIN_ACTIVITY_LOG, $sql_data_array); }