",$text);
$string = str_replace($text,$bullets,$string);
$string = str_replace("[BL]","- ",$string);
$string = str_replace("[/BL]","
",$string);
}
return $string;
}
#
# SPM functions for section header and panel corner image creation
#
function hex2rgb($hex){
// break into hex 3-tuple
$cutpoint = ceil(strlen($hex) / 2)-1;
$rgb = explode(':', wordwrap($hex, $cutpoint, ':', $cutpoint), 3);
// convert each tuple to decimal
$rgb[0] = (isset($rgb[0]) ? hexdec($rgb[0]) : 0);
$rgb[1] = (isset($rgb[1]) ? hexdec($rgb[1]) : 0);
$rgb[2] = (isset($rgb[2]) ? hexdec($rgb[2]) : 0);
return $rgb;
}
function saveHeaderImages($id,$colour){
global $imgPrefix;
# Best settings:
//$left = imagecreatetruecolor(11, 23);
//imagefilledellipse ( $left, 11, 11, 23, 25, $fill );
#change the hex colour to rgb
$rgb = hex2rgb($colour);
#set up the image
$left = imagecreatetruecolor(11, 23);
$bg = imagecolorallocate($left,255,255,255);
$fill = imagecolorallocate($left,$rgb[0],$rgb[1],$rgb[2]);
imagefill($left,0,0,$bg);
#draw coloured ellipse
imagefilledellipse ( $left, 11, 11, 23, 25, $fill );
#save file, rotate and save again
imagepng($left,"/var/www/shop/skin1/images/".$imgPrefix."section_end_left_".$id.".png");
$right = imagerotate($left,180,0);
imagepng($right,"/var/www/shop/skin1/images/".$imgPrefix."section_end_right_".$id.".png");
imagedestroy($left);
}
function createPanelCorners($id,$colour,$tintBy){
global $imgPrefix;
global $tintRGB;
#change the hex colour to rgb
$rgb = hex2rgb($colour);
# create image and fill with white
$dark = imagecreatetruecolor(9, 9);
$light = imagecreatetruecolor(9, 9);
$darkBG = imagecolorallocate($dark,255,255,255);
$lightBG = imagecolorallocate($light,255,255,255);
$full = imagecolorallocate($dark,$rgb[0],$rgb[1],$rgb[2]);
foreach($rgb as $k => $v){
$newVal = $rgb[$k] * $tintBy;
if($newVal >= 255){$newVal=255;}
$tint[$k] = intval($newVal);
}
$tint = imagecolorallocatealpha($light,$rgb[0],$rgb[1],$rgb[2],50);
imagefill($dark,0,0,$darkBG);
imagefill($light,0,0,$lightBG);
#draw coloured ellipse
imagefilledellipse ( $dark, 9, 9, 19, 19, $full );
imagefilledellipse ( $light, 9, 9, 19, 19, $tint );
# get colour from tinted image to save to database
$tintRGB = imagecolorat($light,5,5);
$r = ($tintRGB >> 16) & 0xFF;
$g = ($tintRGB >> 8) & 0xFF;
$b = $tintRGB & 0xFF;
$tintRGB = dechex($r).dechex($g).dechex($b);
#save and rotate for each file needed
imagepng($dark,"/var/www/shop/skin1/images/".$imgPrefix."section_panel_tl".$id.".png");
$bl = imagerotate($dark,-90,0);
imagepng($bl,"/var/www/shop/skin1/images/".$imgPrefix."section_panel_tr".$id.".png");
$br = imagerotate($dark,180,0);
imagepng($br,"/var/www/shop/skin1/images/".$imgPrefix."section_panel_br".$id.".png");
$tr = imagerotate($dark,90,0);
imagepng($tr,"/var/www/shop/skin1/images/".$imgPrefix."section_panel_bl".$id.".png");
imagepng($light,"/var/www/shop/skin1/images/".$imgPrefix."section_panel_tint_tl".$id.".png");
$bl_tint = imagerotate($light,-90,0);
imagepng($bl_tint,"/var/www/shop/skin1/images/".$imgPrefix."section_panel_tint_tr".$id.".png");
$br_tint = imagerotate($light,180,0);
imagepng($br_tint,"/var/www/shop/skin1/images/".$imgPrefix."section_panel_tint_br".$id.".png");
$tr_tint = imagerotate($light,90,0);
imagepng($tr_tint,"/var/www/shop/skin1/images/".$imgPrefix."section_panel_tint_bl".$id.".png");
imagedestroy($dark);
imagedestroy($tr);
imagedestroy($br);
imagedestroy($bl);
imagedestroy($light);
imagedestroy($tr_tint);
imagedestroy($br_tint);
imagedestroy($bl_tint);
}
function createCategoryHeader($id,$colour,$text,$lng){
#change the hex colour to rgb
$rgb = hex2rgb($colour);
# set up text
$pointSize = 22;
$font = "../fonts/NewsGothicBT.ttf";
$bbox=imagettfbbox($pointSize,0,$font,$text);
$textWidth = $bbox[2] - $bbox[0];
$textHeight = abs($bbox[7] - $bbox[1]);
$baseline = abs(0 - $bbox[7]);
$img = imagecreate($textWidth+2,$textHeight+2);
$bg = imagecolorallocate($img,$rgb[0],$rgb[1],$rgb[2]);
$white = imagecolorallocate($img,255,255,255);
imagefill($img,0,0,$bg);
imagettftext ($img, $pointSize, 0, 0, $baseline, $white, $font, $text);
imagepng($img,"/var/www/shop/skin1/images/".$lng."/tt_category_header".$id.".png");
imagedestroy($img);
}
#
# update panel clicks function
#
function update_panel_clicks($panelId){
global $sql_tbl;
db_query("UPDATE $sql_tbl[panels] set clicks=$sql_tbl[panels].clicks+1 where panelId=$panelId");
}
#
# Database abstract layer functions
#
function db_connect($sql_host, $sql_user, $sql_password) {
return mysql_connect($sql_host, $sql_user, $sql_password);
}
function db_select_db($sql_db) {
return mysql_select_db($sql_db) || die("Could not connect to SQL db");
}
function db_query($query) {
global $debug_mode;
global $mysql_autorepair;
if(defined("START_TIME")) {
global $__sql_time;
$t = func_microtime();
}
$result = mysql_query($query);
if(defined("START_TIME")) {
$__sql_time += func_microtime()-$t;
}
#
# Auto repair
#
if( !$result && $mysql_autorepair && preg_match("/'(\S+)\.(MYI|MYD)/",mysql_error(), $m) ){
$stm = "REPAIR TABLE $m[1]";
error_log("Repairing table $m[1]", 0);
if ($debug_mode == 1 || $debug_mode == 3) {
$mysql_error = mysql_errno()." : ".mysql_error();
echo "Repairing table $m[1]...$mysql_error
";
flush();
}
$result = mysql_query($stm);
if (!$result)
error_log("Repaire table $m[1] is failed: ".mysql_errno()." : ".mysql_error(), 0);
else
$result = mysql_query($query); # try repeat query...
}
if (db_error($result, $query) && $debug_mode==1)
exit;
return $result;
}
function db_result($result, $offset) {
return mysql_result($result, $offset);
}
function db_fetch_row($result) {
return mysql_fetch_row($result);
}
function db_fetch_array($result, $flag=MYSQL_ASSOC) {
return mysql_fetch_array($result, $flag);
}
function db_free_result($result) {
@mysql_free_result($result);
}
function db_num_rows($result) {
return mysql_num_rows($result);
}
function db_insert_id() {
return mysql_insert_id();
}
function db_affected_rows() {
return mysql_affected_rows();
}
function db_error($mysql_result, $query) {
global $debug_mode, $error_file_size_limit, $error_file_path, $PHP_SELF;
global $config, $login, $REMOTE_ADDR, $current_location;
if ($mysql_result)
return false;
else {
$back_trace = func_get_backtrace();
$mysql_error = mysql_errno()." : ".mysql_error();
if (@$config["Email_Note"]["admin_sqlerror_notify"]=="Y") {
x_session_register("login");
$err_str = "Date : ".date("d-M-Y H:i:s")."\n";
$err_str .= "Site : ".$current_location."\n";
$err_str .= "Script : ".$PHP_SELF."\n";
$err_str .= "Remote IP : $REMOTE_ADDR\n";
$err_str .= "Logged as : $login\n";
$err_str .= "SQL query : $query\n";
$err_str .= "Error code : ".mysql_errno()."\n";
$err_str .= "Description :\n\n".mysql_error()."\n";
$err_str .= "Backtrace :\n".implode("\n", $back_trace);
func_send_simple_mail($config["Company"]["site_administrator"], $config["Company"]["company_name"].": SQL Error notification", $err_str, $config["Company"]["site_administrator"]);
}
if ($debug_mode == 1 || $debug_mode == 3) {
echo "INVALID SQL: $mysql_error
";
echo "SQL QUERY FAILURE: $query
";
flush();
}
if ($debug_mode == 2 || $debug_mode == 3) {
$filename = $error_file_path."/x-errors_sql.txt";
if ($error_file_size_limit!=0 && @filesize($filename)>$error_file_size_limit*1024)
@unlink($filename);
if ($fp = @fopen($filename, "a+")) {
$err_str = date("[d-M-Y H:i:s]")." SQL error: $PHP_SELF\n".$query."\n".$mysql_error;
$err_str .= "\nBacktrace:\n".implode("\n", $back_trace);
$err_str .= "\n-------------------------------------------------\n";
fwrite($fp, $err_str);
fclose($fp);
}
}
}
return true;
}
#
# SPM same as func_query but adds given column name to top level array keys. produces array like this:
#
/*
Array
(
[x] => Array
(
[0] => Array
(
[colName] => x
)
[1] => Array
(
[colName] => x
)
)
[y] => Array
(
[0] => Array
(
[colName] => y
)
[1] => Array
(
[colName] => y
)
)
*/
function func_query_keyed($colName,$query) {
$result = false;
if ($p_result = db_query($query)) {
while($arr = db_fetch_array($p_result))
$result[$arr[$colName]][]=$arr;
db_free_result($p_result);
}
return $result;
}
#
# Execute mysql query and store result into associative array with
# column names as keys...
#
function func_query($query) {
$result = false;
if ($p_result = db_query($query)) {
while($arr = db_fetch_array($p_result))
$result[]=$arr;
db_free_result($p_result);
}
return $result;
}
#
# Execute mysql query and store result into associative array with
# column names as keys and then return first element of this array
# If array is empty return array().
#
function func_query_first($query) {
if ($p_result = db_query($query)) {
$result = db_fetch_array($p_result);
db_free_result($p_result);
}
return is_array($result)?$result:array();
}
#
# Execute mysql query and store result into associative array with
# column names as keys and then return first cell of first element of this array
# If array is empty return false.
#
function func_query_first_cell($query) {
if ($p_result = db_query($query)) {
$result = db_fetch_row($p_result);
db_free_result($p_result);
}
return is_array($result)?$result[0]:false;
}
#
# This function replaced standard PHP function header("Location...")
#
function func_header_location($location) {
global $XCART_SESSION_NAME, $XCARTSESSID, $HTTP_COOKIE_VARS;
global $use_sessions_type, $is_location;
global $HTTP_SERVER_VARS;
$is_location = 'Y';
x_session_save();
if ($use_sessions_type < 3) {
session_write_close();
}
if (!empty($XCARTSESSID) && !isset($HTTP_COOKIE_VARS[$XCART_SESSION_NAME]) && !eregi("$XCART_SESSION_NAME=", $location)) {
$location .= ((strpos($location, '?') != false)?'&':'?')."$XCART_SESSION_NAME=".$XCARTSESSID;
}
$header_location = (strpos($HTTP_SERVER_VARS["HTTP_USER_AGENT"],'Opera')!==false || @preg_match("/Microsoft|WebSTAR|Xitami/", getenv("SERVER_SOFTWARE")) ? "Refresh: 0; URL=" : "Location: ");
if (!headers_sent()) {
header($header_location.$location);
exit();
}
else {
echo "
".func_get_langvar_by_name("txt_header_location_note", array("time" => 5, "location" => $location))."
";
echo "";
}
func_flush();
exit();
}
#
# Get image size abstract function
#
function func_get_image_size($filename) {
list($width, $height, $type) = getimagesize($filename);
switch($type) {
case "1": $type = "image/gif";
break;
case "2": $type = "image/pjpeg";
break;
case "3": $type = "image/png";
break;
case "4": $type = "application/x-shockwave-flash";
break;
case "5": $type = "image/psd";
break;
case "6": $type = "image/bmp";
break;
default: $type = "";
}
if (!empty($type))
return array(@filesize($filename),$width,$height,$type);
else
return false;
}
#
# Determine that $userfile is image file with non zero size
#
function func_is_image_userfile($userfile, $userfile_size, $userfile_type) {
return (($userfile != "none") && ($userfile != "") && ($userfile_size > 0) && (substr($userfile_type, 0, 6) == 'image/' || $userfile_type == 'application/x-shockwave-flash'));
}
function func_mail_quote($string, $charset) {
return "=?".$charset."?B?".base64_encode($string)."?=";
}
#
# SPM - function to check CSV content
#
function makeDataCSVCompatible($csvData) {
$csvData = str_replace("\n", " ", $csvData);
$csvData = str_replace("\r", "", $csvData);
$csvData = str_replace("\"", "\"\"", $csvData);
return($csvData);
}
#
# SPM - function to create content for csv order file
#
function createCSVContent($order,$products){
if (($order["orderid"] > 0) && (count($order) > 0) && (count($products) > 0)) {
foreach ($products as $thisItem) {
$orderid = $order["orderid"];
/*
# add zeros to front of oerder id to make up the bytes to 9
for($i=0;$i< intval(9 - strlen($order["orderid"]));$i++){
$orderid = "0".$orderid;
}
*/
# if no delivery address present, use billing address
if($order["s_address"] == ""){
$order["s_address"] = $order["b_address"];
$order["s_address_2"] = $order["b_address_2"];
$order["s_city"] = $order["b_city"];
$order["s_county"] = $order["b_county"];
$order["s_zipcode"] = $order["b_zipcode"];
$order["s_country"] = $order["b_country"];
}
# concat delivery address from order elements
$delivery_address = $order["s_firstname"]." ".$order["s_lastname"].",".$order["s_address"].",".$order["s_address_2"].",".$order["s_city"].",".$order["s_county"].",".$order["s_zipcode"].",".$order["phone"].",".$order["email"];
$content .= 'd' . substr(makeDataCSVCompatible($orderid), 0, 9) . date("dm",$order["date"]) . ','; // Order Number
$content .= '' . substr(makeDataCSVCompatible(date("dmy",$order["date"])), 0, 6) . ','; // Order Date
$content .= '"d' . substr(makeDataCSVCompatible($orderid), 0, 9) . ',' . substr(makeDataCSVCompatible($delivery_address), 0, 200) . '",'; // Delivery Details (Name and Address etc)
$content .= '0,'; // Delivery Sequence
$content .= 'N,'; // Forward/Normal Order
$content .= '' . substr(makeDataCSVCompatible(date("dmy",$order["date"])), 0, 6) . ','; // Date Delivery Required
$content .= ','; // Class 1
$content .= ','; // Class 2
$content .= ','; // Class 3
$content .= ','; // Product Name
$content .= $order["coupon"].','; // IPaq Reference
$content .= '' . substr(makeDataCSVCompatible($thisItem["productcode"]), 0, 15) . ','; // Product Code
$content .= '' . substr(makeDataCSVCompatible($thisItem["amount"]), 0, 5) . ','; // Quantity
$content .= '' . "\r\n"; // Order Reference
}
if (strlen($content) > 0) {
// Save file in csv directory with order number
$thisFilename = CSV_DIR . $orderid . ".csv";
if (!is_file($thisFilename)) {
$fp = @fopen ($thisFilename, "w");
$write = @fwrite( $fp, $content);
@fclose( $fp );
if (is_file($thisFilename)) {
$outcome["success"] = TRUE;
$outcome["file"] = $thisFilename;
} else {
$outcome["success"] = FALSE;
$outcome["errorCode"] = "004";// failed to create file
}
} else {
$outcome["success"] = FALSE;
$outcome["errorCode"] = "003";// file exists
}
} else {
$outcome["success"] = FALSE;
$outcome["errorCode"] = "002";// failed to create csv content
}
} else {
$outcome["success"] = FALSE;
$outcome["errorCode"] = "001";// order or products empty
}
return $outcome;
}
#
# SPM - function to prepare CSV email
#
function prepOrderEmail($filePath,$fileName,$from,$message){
$lend = "\n";
$break = "\n\n";
// mime boundary
$semi_rand = md5(time());
$mime_boundary = "==Multipart_Boundary_x{$semi_rand}x";
// filePath must include the file name
// fixed by mhedley@jackel in accordance with RFC4180
// text/csv appropriate MIME for $fileType
//
$fileType = "text/csv";
$file = fopen($filePath,'rb');
$data = fread($file,filesize($filePath));
fclose($file);
$data = chunk_split(base64_encode($data));
// headers
$mail_elements["headers"] .= "From: ".$from.$lend;
$mail_elements["headers"] .= "X-Mailer: PHP/".phpversion().$lend;
$mail_elements["headers"] .= "MIME-Version: 1.0".$lend;
$mail_elements["headers"] .= "Content-Type: multipart/mixed; boundary=".$mime_boundary;
// message part
$mail_elements["body"] .= "--{$mime_boundary}".$lend;
$mail_elements["body"] .= "Content-Type:text/html; charset=\"iso-8859-1\"".$lend;
$mail_elements["body"] .= "Content-Transfer-Encoding: 7bit".$break;
$mail_elements["body"] .= $message.$break;
// attachment part
$mail_elements["body"] .= "--{$mime_boundary}".$lend;
$mail_elements["body"] .= "Content-Type: ".$fileType."; name=\"".$fileName."\"\n";
$mail_elements["body"] .= "Content-Disposition: attachment; filename=\"{$fileatt_name}\"\n";
$mail_elements["body"] .= "Content-Transfer-Encoding: base64".$break;
$mail_elements["body"] .= $data . "\n\n";
$mail_elements["body"] .= "--{$mime_boundary}--".$lend;
return $mail_elements;
}
#
# SPM - function to send CSV email
#
function func_send_csv_mail($order,$products){
global $mail_smarty, $sql_tbl;
global $config;
$csvResult = createCSVContent($order,$products);
$lend = "\n";
if (is_file($csvResult["file"])) {
// CSV file created, so needs to be attatched to email as order.csv
// Therefore, have to check the current order.csv directory to make sure one does not exist
// as that means the system is in the middle of sending an order
$orderCSVAttempt = 0;
while ((is_file(CSV_DIR . CSV_FILENAME)) && ($orderCSVAttempt < 5)) {
sleep(1);
$orderCSVAttempt++;
}
}
if (!(is_file(CSV_DIR . CSV_FILENAME))) {
if (copy($csvResult["file"], CSV_DIR . CSV_FILENAME)) {
$to = $config["Company"]["csv_orders_email"];
$subject = "Tommee Tippee Web Order #" .$order["orderid"];
$message = "The attached file contains order information for order: ".$order["orderid"].$break;
$from = "weborder@tommeetippee.com <$to>";
$mail_elements = prepOrderEmail(CSV_DIR . CSV_FILENAME, CSV_FILENAME, $from, $message);
$success = mail($to,$subject,$mail_elements["body"],$mail_elements["headers"]);
# send duplicate for testing
mail("smarlow@different-uk.com",$subject,$mail_elements["body"],$mail_elements["headers"]);
if(!$success){
$to = $config["Company"]["error_email"];
$from = "Order System <$to>";
$subject = "IMPORTANT: Order failure";
$message_header = "Content-Type: text/plain;".$lend;
$headers = "From: ".$from.$lend."X-Mailer: PHP/".phpversion().$lend."MIME-Version: 1.0".$lend.$message_header;
$body = "The website encountered an error (Error id: $csvResult[errorCode]) sending the CSV file to the JBA system for order number: ".$order["orderid"]."\r\n\r\n";
$body .= "This order will need to be manually processed - the details can be found in the Administration System under 'Orders'.\r\n\r\n";
$body .= "Please inform the site manager and/or developer to ensure this error is corrected.";
mail($to,$subject,$body,$headers);
}
unlink(CSV_DIR . CSV_FILENAME);
unlink($csvResult["file"]);
}
}
}
#
# Send mail abstract function
# $from - from/reply-to address
#
function func_send_mail($to, $subject_template, $body_template, $from, $to_admin, $crypted=false) {
global $mail_smarty, $sql_tbl;
global $config;
global $current_language, $store_language, $shop_language;
global $to_customer;
global $override_lng_code;
if (empty($to)) return;
$encrypt_mail = $crypted && $config["Security"]["crypt_method"];
$lng_code = "";
if ($to_admin) {
$lng_code = ($current_language?$current_language:$config["default_admin_language"]);
}
elseif ($to_customer) {
$lng_code = $to_customer;
}
else {
$lng_code = $shop_language;
}
$charset = func_query_first_cell ("SELECT charset FROM $sql_tbl[countries] WHERE code='$lng_code'");
$override_lng_code = $lng_code;
$mail_smarty->assign_by_ref ("config", $config);
if ($config["Email"]["html_mail"] == "Y" && !$encrypt_mail) {
# Select HTML-style templates is this option is enabled.
if (file_exists($mail_smarty->template_dir."/mail/html/".basename($body_template))) {
$mail_smarty->assign("mail_body_template","mail/html/".basename($body_template));
$body_template = "mail/html/html_message_template.tpl";
}
}
$mail_message = func_display($body_template,$mail_smarty,false);
$mail_subject = chop(func_display($subject_template,$mail_smarty,false));
if (X_DEF_OS_WINDOWS) {
$mail_message=str_replace("\n","\r\n",$mail_message);
$lend = "\r\n";
}
else
$lend = "\n";
$files = array();
if($config["Email"]["html_mail"] == "Y") {
list($mail_message, $tmp) = func_attach_images($mail_message);
if(!empty($tmp)) {
foreach($tmp as $k => $v)
$files[] = $v;
}
}
if($encrypt_mail)
$mail_message = func_pgp_encrypt ($mail_message);
if ($config["Email"]["html_mail"] == "Y" && !$encrypt_mail)
$message_header = "Content-Type: text/html; charset=".$charset.$lend;
else
$message_header = "Content-Type: text/plain; charset=".$charset.$lend;
$message_header .= "Content-Disposition: inline".$lend."Content-Transfer-Encoding: 8bit".$lend;
if(!empty($files) && is_array($files)) {
$boundary = substr(uniqid(time()."_"), 0, 16);
$mail_message = "--".$boundary.$lend.$message_header.$mail_message.$lend;
$message_header = "Content-Type: multipart/related; boundary=\"$boundary\"".$lend;
foreach($files as $k => $v) {
$mail_message .= "--".$boundary.$lend;
$mail_message .= "Content-Type: $v[type]; name=\"$v[name]\"".$lend;
$mail_message .= "Content-Disposition: inline; filename=\"$v[name]\"".$lend;
$mail_message .= "Content-Transfer-Encoding: base64".$lend;
$mail_message .= "Content-ID: <$v[name]>".$lend;
$mail_message .= $lend.chunk_split(base64_encode($v['data'])).$lend;
}
$mail_message .= "--".$boundary."--".$lend;
}
$m_from = $from;
if ($config["Email"]["use_base64_headers"] == "Y")
$mail_subject = func_mail_quote($mail_subject,$charset);
$headers = "From: ".$m_from.$lend."X-Mailer: PHP/".phpversion().$lend."MIME-Version: 1.0".$lend.$message_header;
if (trim($m_from) != "")
$headers .= "Reply-to: ".$m_from.$lend;
if (preg_match('/([^ @,;<>]+@[^ @,;<>]+)/S', $from, $m))
@mail($to,$mail_subject,$mail_message,$headers, "-f".$m[1]);
else
@mail($to,$mail_subject,$mail_message,$headers);
}
function func_send_simple_mail($to, $subject, $body, $from) {
global $config;
global $current_language;
global $sql_tbl;
if (empty($to)) return;
if (X_DEF_OS_WINDOWS) {
$body=str_replace("\n","\r\n",$body);
$lend = "\r\n";
}
else
$lend = "\n";
if (!empty($current_language))
$charset = func_query_first_cell ("SELECT charset FROM $sql_tbl[countries] WHERE code='$current_language'");
if (empty($charset))
$charset = func_query_first_cell ("SELECT charset FROM $sql_tbl[countries] WHERE code='".$config["default_admin_language"]."'");
if ($config["Email"]["use_base64_headers"] == "Y") {
$m_from = $from;
$m_subject = func_mail_quote($subject,$charset);
}
else {
$m_from = $from;
$m_subject = $subject;
}
$headers = "From: ".$m_from.$lend."X-Mailer: PHP/".phpversion().$lend;
if (trim($m_from) != "")
$headers .= "Reply-to: ".$m_from.$lend;
$headers .= "MIME-Version: 1.0".$lend;
if ($config["Email"]["html_mail"] == "Y")
$headers .= "Content-Type: text/html; charset=".$charset.$lend;
else
$headers .= "Content-Type: text/plain; charset=".$charset.$lend;
if (preg_match('/([^ @,;<>]+@[^ @,;<>]+)/S', $from, $m))
@mail($to,$m_subject,$body,$headers, "-f".$m[1]);
else
@mail($to,$m_subject,$body,$headers);
}
#
# Simple crypt function. Returns an encrypted version of argument.
# Does not matter what type of info you encrypt, the function will return
# a string of ASCII chars representing the encrypted version of argument.
# Note: text_crypt returns string, which length is 2 time larger
#
function text_crypt_symbol($c) {
# $c is ASCII code of symbol. returns 2-letter text-encoded version of symbol
global $START_CHAR_CODE;
return chr($START_CHAR_CODE + ($c & 240) / 16).chr($START_CHAR_CODE + ($c & 15));
}
function text_crypt($s, $is_blowfish = false) {
global $START_CHAR_CODE, $CRYPT_SALT, $merchant_password, $current_area, $active_modules, $blowfish, $config;
if ($s == "")
return $s;
if($is_blowfish && $merchant_password && ($current_area == 'A' || ($current_area == 'P' && $active_modules["Simple_Mode"])) && $blowfish && $config['Security']['blowfish_enabled'] == 'Y') {
$s = trim($s);
$result = addslashes("B".func_crc32($s).func_bf_crypt($s, $merchant_password));
} else {
$enc = rand(1,255); # generate random salt.
$result = "S".text_crypt_symbol($enc); # include salt in the result;
$enc ^= $CRYPT_SALT;
for ($i = 0; $i < strlen($s); $i++) {
$r = ord(substr($s, $i, 1)) ^ $enc++;
if ($enc > 255)
$enc = 0;
$result .= text_crypt_symbol($r);
}
}
return $result;
}
function text_decrypt_symbol($s, $i) {
# $s is a text-encoded string, $i is index of 2-char code. function returns number in range 0-255
global $START_CHAR_CODE;
return (ord(substr($s, $i, 1)) - $START_CHAR_CODE)*16 + ord(substr($s, $i+1, 1)) - $START_CHAR_CODE;
}
function text_decrypt($s) {
global $START_CHAR_CODE, $CRYPT_SALT, $merchant_password, $current_area, $active_modules, $blowfish;
if ($s == "")
return $s;
$crypt_method = substr($s, 0, 1);
$s = substr($s, 1);
if($crypt_method == 'B') {
if($merchant_password && ($current_area == 'A' || ($current_area == 'P' && $active_modules["Simple_Mode"])) && $blowfish) {
$crc32 = substr($s, 0, 4);
$s = substr($s, 4);
$result = func_bf_decrypt($s, $merchant_password);
if(func_crc32($result) != $crc32) {
$result = func_get_langvar_by_name('err_data_corrupted');
}
} else {
return false;
}
} elseif($crypt_method != 'B') {
if($crypt_method != 'S') {
$s = $crypt_method.$s;
}
$enc = $CRYPT_SALT ^ text_decrypt_symbol($s, 0);
$result = "";
for ($i = 2; $i < strlen($s); $i+=2) { # $i=2 to skip salt
$result .= chr(text_decrypt_symbol($s, $i) ^ $enc++);
if ($enc > 255)
$enc = 0;
}
}
return $result;
}
#
# Recursively deletes category with all its contents
#
function func_rm_dir_files ($path) {
$dir = opendir ($path);
while ($file = readdir ($dir)) {
if (($file == ".") or ($file == ".."))
continue;
if (filetype ("$path/$file") == "dir") {
func_rm_dir_files ("$path/$file");
rmdir ("$path/$file");
} else {
unlink ("$path/$file");
}
}
closedir($dir);
}
function func_rm_dir ($path) {
func_rm_dir_files ($path);
rmdir ($path);
}
#
# Delete product from products table + all associated information
# $productid - product's id
#
function func_delete_product($productid, $update_categories=true) {
global $sql_tbl, $xcart_dir;
$product_categories = func_query("SELECT categoryid FROM $sql_tbl[products_categories] WHERE productid='$productid'");
db_query("delete from $sql_tbl[pricing] where productid='$productid'");
db_query("delete from $sql_tbl[product_links] where productid1='$productid' or productid2='$productid'");
db_query("delete from $sql_tbl[featured_products] where productid='$productid'");
db_query("delete from $sql_tbl[products] where productid='$productid'");
db_query("delete from $sql_tbl[delivery] where productid='$productid'");
db_query("delete from $sql_tbl[images] where productid='$productid'");
db_query("delete from $sql_tbl[thumbnails] where productid='$productid'");
db_query("delete from $sql_tbl[extra_field_values] where productid='$productid'");
db_query("delete from $sql_tbl[products_categories] where productid='$productid'");
# Feature comparison module
if(func_query_first_cell("SELECT module_name FROM $sql_tbl[modules] WHERE module_name='Feature_Comparison'")) {
if(!isset($sql_tbl['product_features']) || !isset($sql_tbl['product_foptions'])) {
include_once $xcart_dir."/modules/Feature_Comparison/config.php";
}
db_query("DELETE FROM $sql_tbl[product_features] WHERE productid='$productid'");
db_query("DELETE FROM $sql_tbl[product_foptions] WHERE productid='$productid'");
}
# Product options module
if(func_query_first_cell("SELECT module_name FROM $sql_tbl[modules] WHERE module_name='Product_Options'")) {
if(!isset($sql_tbl['classes']) || !isset($sql_tbl['class_options'])) {
include_once $xcart_dir."/modules/Product_Options/config.php";
}
$classes = func_create_hash_keys(func_query("SELECT classid FROM $sql_tbl[classes] WHERE productid='$productid'"), "classid");
db_query("delete from $sql_tbl[classes] where productid='$productid'");
if(!empty($classes)) {
$options = array_keys(func_create_hash_keys(func_query("SELECT optionid FROM $sql_tbl[class_options] where classid IN ('".implode("','", array_keys($classes))."')"), "optionid"));
db_query("delete from $sql_tbl[class_options] where classid IN ('".implode("','", array_keys($classes))."')");
db_query("delete from $sql_tbl[class_lng] where classid IN ('".implode("','", array_keys($classes))."')");
if(!empty($options)) {
db_query("DELETE FROM $sql_tbl[product_options_lng] WHERE optionid IN ('".implode("','", $options)."')");
db_query("DELETE FROM $sql_tbl[product_options_ex] WHERE optionid IN ('".implode("','", $options)."')");
db_query("DELETE FROM $sql_tbl[variant_items] WHERE optionid IN ('".implode("','", $options)."')");
}
}
db_query("DELETE FROM $sql_tbl[product_options_js] WHERE productid='$productid'");
db_query("DELETE FROM $sql_tbl[variants] WHERE productid='$productid'");
}
db_query("DELETE FROM $sql_tbl[product_votes] WHERE productid='$productid'");
db_query("DELETE FROM $sql_tbl[product_reviews] WHERE productid='$productid'");
db_query("DELETE FROM $sql_tbl[products_lng] WHERE productid='$productid'");
db_query("DELETE FROM $sql_tbl[subscriptions] where productid='$productid'");
db_query("DELETE FROM $sql_tbl[subscription_customers] where productid='$productid'");
db_query("DELETE FROM $sql_tbl[download_keys] where productid='$productid'");
db_query("DELETE FROM $sql_tbl[discount_coupons] where productid='$productid'");
db_query("DELETE FROM $sql_tbl[stats_customers_products] where productid='$productid'");
db_query("DELETE FROM $sql_tbl[wishlist] where productid='$productid'");
db_query("DELETE FROM $sql_tbl[product_bookmarks] where productid='$productid'");
# Product configurator module
if (func_query_first_cell("SELECT module_name FROM $sql_tbl[modules] WHERE module_name='Product_Configurator'")) {
#
# If Product Configurator installed delete the related information
#
include_once $xcart_dir."/modules/Product_Configurator/config.php";
$classes = func_query("SELECT classid FROM $sql_tbl[pconf_products_classes] WHERE productid='$productid'");
if (is_array($classes)) {
#
# Delete all classification info related with this product
#
foreach ($classes as $k=>$v) {
db_query("DELETE FROM $sql_tbl[pconf_class_specifications] where classid='$v[classid]'");
db_query("DELETE FROM $sql_tbl[pconf_class_requirements] where classid='$v[classid]'");
}
}
db_query("DELETE FROM $sql_tbl[pconf_products_classes] where productid='$productid'");
#
# Delete configurable product
#
$steps = func_query("SELECT stepid FROM $sql_tbl[pconf_wizards] WHERE productid='$productid'");
if (is_array($steps)) {
#
# Delete the data related with wizards' steps
#
foreach ($steps as $k=>$v) {
$slots = func_query("SELECT slotid FROM $sql_tbl[pconf_slots] WHERE stepid='$stepid'");
if (is_array($slots)) {
#
# Delete data related with slots
#
foreach ($slots as $k1=>$v1) {
db_query("DELETE FROM $sql_tbl[pconf_slot_rules] WHERE slotid='$v1[slotid]'");
db_query("DELETE FROM $sql_tbl[pconf_slot_markups] WHERE slotid='$v1[slotid]'");
}
}
db_query("DELETE FROM $sql_tbl[pconf_slots] WHERE stepid='$v[stepid]'");
}
}
db_query("DELETE FROM $sql_tbl[pconf_wizards] where productid='$productid'");
}
#
# Update product count for categories
#
if ($update_categories && is_array($product_categories))
func_recalc_product_count($product_categories);
return true;
}
#
# Delete profile from customers table + all associated information
#
function func_delete_profile($user,$usertype) {
global $files_dir_name, $single_mode, $sql_tbl;
global $active_modules;
if ($usertype == "A" || ($active_modules["Simple_Mode"] && $usertype == "P")) {
$users_count = func_query_first_cell("SELECT COUNT(*) FROM $sql_tbl[customers] WHERE usertype='$usertype'");
if ($users_count == 1) {
func_header_location("error_message.php?last_admin");
}
}
if($usertype=="P" && !$single_mode) {
# If user is provider delete some associated info to keep DB integrity
# Delete products
#
$products = func_query("SELECT productid FROM $sql_tbl[products] WHERE provider='$user'");
if (!empty($products))
foreach($products as $product)
func_delete_product($product["productid"]);
#
# Delete Shipping, Discounts, Coupons, States/Tax, Countries/Tax
#
db_query("delete from $sql_tbl[shipping_rates] where provider='$user'");
db_query("delete from $sql_tbl[discounts] where provider='$user'");
db_query("delete from $sql_tbl[discount_coupons] where provider='$user'");
db_query("delete from $sql_tbl[extra_fields] where provider='$user'");
db_query("delete from $sql_tbl[tax_rates] where provider='$user'");
db_query("delete from $sql_tbl[zones] where provider='$user'");
#
# Delete provider's file dir
#
@func_rm_dir ("$files_dir_name/$user");
}
#
# If it is partner, then remove all his information
#
if ($usertype == "B" && func_query_first_cell("SELECT COUNT(*) FROM $sql_tbl[modules] WHERE module_name='XAffiliate'") > 0) {
if (empty($active_modules["XAffiliate"]))
include $xcart_dir."XAffiliate/config.php";
db_query ("DELETE FROM $sql_tbl[partner_clicks] WHERE login='$user'");
db_query ("DELETE FROM $sql_tbl[partner_commissions] WHERE login='$user'");
db_query ("DELETE FROM $sql_tbl[partner_payment] WHERE login='$user'");
db_query ("DELETE FROM $sql_tbl[partner_views] WHERE login='$user'");
}
db_query("DELETE FROM $sql_tbl[register_field_values] WHERE login='$user'");
db_query("DELETE FROM $sql_tbl[customers] WHERE login='$user' AND usertype='$usertype'");
}
#
# Get information associated with user
#
function func_userinfo($user,$usertype, $extended=true) {
global $sql_tbl, $single_mode, $shop_language, $default_user_profile_fields, $config;
global $active_modules;
$userinfo = func_query_first("SELECT $sql_tbl[customers].* FROM $sql_tbl[customers] WHERE $sql_tbl[customers].login='$user' AND $sql_tbl[customers].usertype='$usertype'");
if ($extended) {
$extended_info = func_query_first("SELECT * FROM $sql_tbl[orders] WHERE login='$user' ORDER BY orderid DESC LIMIT 1");
if (empty($extended_info)) {
$userinfo["b_title"] = $userinfo["s_title"] = $userinfo["title"];
$userinfo["b_firstname"] = $userinfo["s_firstname"] = $userinfo["firstname"];
$userinfo["b_lastname"] = $userinfo["s_lastname"] = $userinfo["lastname"];
}
else {
$userinfo["b_title"] = $extended_info["b_title"];
$userinfo["b_firstname"] = $extended_info["b_firstname"];
$userinfo["b_lastname"] = $extended_info["b_lastname"];
$userinfo["s_title"] = $extended_info["s_title"];
$userinfo["s_firstname"] = $extended_info["s_firstname"];
$userinfo["s_lastname"] = $extended_info["s_lastname"];
}
unset($extended_info);
}
$userinfo["passwd1"] = stripslashes(text_decrypt($userinfo["password"]));
$userinfo["passwd2"] = stripslashes(text_decrypt($userinfo["password"]));
$userinfo["password"] = stripslashes(text_decrypt($userinfo["password"]));
$userinfo["card_number"] = text_decrypt($userinfo["card_number"]);
list($userinfo["b_address"], $userinfo["b_address_2"]) = split("[\n\r]+", $userinfo["b_address"]);
$userinfo["b_statename"] = func_get_state($userinfo["b_state"], $userinfo["b_country"]);
$userinfo["b_countryname"] = func_get_country($userinfo["b_country"]);
list($userinfo["s_address"], $userinfo["s_address_2"]) = split("[\n\r]+", $userinfo["s_address"]);
$userinfo["s_statename"] = func_get_state($userinfo["s_state"], $userinfo["s_country"]);
$userinfo["s_countryname"] = func_get_country($userinfo["s_country"]);
if ($config["General"]["use_counties"] == "Y") {
$userinfo["b_countyname"] = func_get_county($userinfo["b_county"]);
$userinfo["s_countyname"] = func_get_county($userinfo["s_county"]);
}
if($userinfo["usertype"] == "B" && !empty($active_modules["XAffiliate"]))
$userinfo["plan_id"] = func_query_first_cell("SELECT plan_id FROM $sql_tbl[partner_commissions] WHERE login = '$userinfo[login]'");
$email = $userinfo["email"];
# Get additional fields
$userinfo['additional_fields'] = func_get_additional_fields($usertype, $user);
$fields = func_query("SELECT $sql_tbl[register_fields].fieldid, $sql_tbl[register_fields].section, $sql_tbl[register_field_values].value FROM $sql_tbl[register_fields] LEFT JOIN $sql_tbl[register_field_values] ON $sql_tbl[register_fields].fieldid = $sql_tbl[register_field_values].fieldid AND $sql_tbl[register_field_values].login = '$user' WHERE $sql_tbl[register_fields].avail LIKE '%$usertype%' ORDER BY $sql_tbl[register_fields].section, $sql_tbl[register_fields].orderby");
if($fields) {
foreach($fields as $k => $v) {
$fields[$k]['title'] = func_get_languages_alt("lbl_register_field_".$v['fieldid'], $shop_language);
}
$userinfo['additional_fields'] = $fields;
}
# Get default fields
$default_fields = unserialize($config["User_Profiles"]["register_fields"]);
if(!$default_fields) {
$default_fields = array();
foreach($default_user_profile_fields as $k => $v) {
$default_fields[$k] = true;
}
} else {
$tmp = array();
foreach($default_fields as $k => $v) {
if(strpos($v['avail'], $usertype) === false)
continue;
$tmp[$v['field']] = true;
}
$default_fields = $tmp;
unset($tmp);
}
if($default_fields) {
$userinfo['default_fields'] = $default_fields;
}
return $userinfo;
}
#
# Get the customer's zone
#
function func_get_customer_zone_ship ($username, $provider, $type) {
global $sql_tbl;
global $single_mode;
$zones = func_get_customer_zones_avail($username, $provider, "S");
$zone = 0; # default zone
if (is_array($zones)) {
$provider_condition = ($single_mode) ? "" : " AND provider='".addslashes($provider)."'";
$tmp = func_query("SELECT zoneid FROM $sql_tbl[shipping_rates] WHERE zoneid IN ('".implode("','",array_keys($zones))."') $provider_condition AND type='$type' GROUP BY zoneid");
if (is_array($tmp)) {
$unused = $zones;
# remove not available zones
foreach($tmp as $v) unset($unused[$v["zoneid"]]);
foreach($unused as $k=>$v) unset($zones[$k]);
reset($zones);
$zone = key($zones); #extract first zone
}
}
return $zone;
}
#
# Get the customer's zones
#
function func_get_customer_zones_avail ($username, $provider, $address_type="S") {
global $sql_tbl, $config, $single_mode;
static $results_cache = array();
# Define which address type should be compared
if ($address_type == "B")
$address_prefix = "b_";
else
$address_prefix = "s_";
$zones = array();
if (is_array($username)) {
$customer_info = $username;
}
elseif (!empty($username)) {
$customer_info = func_userinfo($username, "C");
}
elseif ($config["General"]["apply_default_country"] == "Y") {
# Set the default user address
$customer_info[$address_prefix."country"] = $config["General"]["default_country"];
$customer_info[$address_prefix."state"] = $config["General"]["default_state"];
$customer_info[$address_prefix."county"] = $config["General"]["default_county"];
$customer_info[$address_prefix."zipcode"] = $config["General"]["default_zipcode"];
$customer_info[$address_prefix."city"] = $config["General"]["default_city"];
}
$customer_login = "";
if (!empty($customer_info)) {
$customer_login = $customer_info["login"];
#
# Check local zones cache
#
if (isset($results_cache[$customer_login][$provider][$address_type]))
return $results_cache[$customer_login][$provider][$address_type];
#
# Generate the zones list
#
$provider_condition = ($single_mode ? "" : "AND provider='$provider'");
$is_country_found = true;
$is_state_found = true;
$is_county_found = true;
# Possible zones for customer's country...
$possible_zones = func_query("SELECT $sql_tbl[zone_element].zoneid FROM $sql_tbl[zone_element], $sql_tbl[zones] WHERE $sql_tbl[zone_element].zoneid=$sql_tbl[zones].zoneid AND $sql_tbl[zone_element].field='".$customer_info[$address_prefix."country"]."' AND $sql_tbl[zone_element].field_type='C' $provider_condition GROUP BY $sql_tbl[zone_element].zoneid");
if (is_array($possible_zones)) {
$cs_state = $customer_info[$address_prefix."state"];
$cs_country = $customer_info[$address_prefix."country"];
$cs_pair = $cs_country."_".$cs_state;
foreach ($possible_zones as $pzone) {
$zones[$pzone["zoneid"]] = 10;
$is_state_found = true;
$is_county_found = true;
# Possible zones for customer's state...
$state_zone = func_query_first_cell("SELECT zoneid FROM $sql_tbl[zone_element], $sql_tbl[states] WHERE $sql_tbl[zone_element].field='".addslashes($cs_pair)."' AND $sql_tbl[zone_element].field_type='S' AND $sql_tbl[states].code='".addslashes($cs_state)."' AND $sql_tbl[states].country_code='".addslashes($cs_country)."' AND $sql_tbl[zone_element].zoneid='$pzone[zoneid]'");
if (!empty($state_zone)) {
# State found: increase the priority
$zones[$pzone["zoneid"]] = 20;
if ($config["General"]["use_counties"] == "Y") {
# Possible zones for customer's county...
$county_zone = func_query_first_cell("SELECT zoneid FROM $sql_tbl[zone_element] WHERE field_type='G' AND field='".$customer_info[$address_prefix."county"]."' AND zoneid='$pzone[zoneid]'");
if (!empty($county_zone))
$zones[$pzone["zoneid"]] = 30;
else {
$is_county = func_query_first_cell("SELECT COUNT(*) FROM $sql_tbl[zone_element] WHERE $sql_tbl[zone_element].field_type='G' AND $sql_tbl[zone_element].zoneid='$pzone[zoneid]'");
if ($is_county)
unset($zones[$pzone["zoneid"]]);
$is_county_found = false;
continue;
}
}
}
else {
# State not found: check if defined other states
$is_states = func_query_first_cell("SELECT COUNT(*) FROM $sql_tbl[zone_element] WHERE $sql_tbl[zone_element].field_type='S' AND $sql_tbl[zone_element].zoneid='$pzone[zoneid]'");
if ($is_states) {
unset($zones[$pzone["zoneid"]]);
$is_state_found = false;
continue;
}
}
}
}
else
$is_country_found = false;
if ($is_country_found && $is_state_found && $is_county_found) {
$empty_condition = " AND $sql_tbl[zone_element].field<>'%'";
#
# Checking the city, address and zip code masks
#
$city_zones = func_query("SELECT $sql_tbl[zone_element].zoneid FROM $sql_tbl[zone_element], $sql_tbl[zones] WHERE $sql_tbl[zone_element].zoneid=$sql_tbl[zones].zoneid AND $sql_tbl[zone_element].field_type='T' AND '".addslashes($customer_info[$address_prefix."city"])."' LIKE $sql_tbl[zone_element].field $empty_condition $provider_condition");
if (is_array($city_zones))
foreach ($city_zones as $k=>$v)
$zones[$v["zoneid"]] += 1;
elseif (is_array($zones)) {
foreach ($zones as $k=>$v) {
$is_city = func_query_first_cell("SELECT COUNT(*) FROM $sql_tbl[zone_element] WHERE $sql_tbl[zone_element].field_type='T' AND $sql_tbl[zone_element].zoneid='$k' $empty_condition");
if ($is_city)
unset($zones[$k]);
}
}
$zipcode_zones = func_query("SELECT $sql_tbl[zone_element].zoneid FROM $sql_tbl[zone_element], $sql_tbl[zones] WHERE $sql_tbl[zone_element].zoneid=$sql_tbl[zones].zoneid AND $sql_tbl[zone_element].field_type='Z' AND '".addslashes($customer_info[$address_prefix."zipcode"])."' LIKE $sql_tbl[zone_element].field $empty_condition $provider_condition");
if (is_array($zipcode_zones))
foreach ($zipcode_zones as $k=>$v)
$zones[$v["zoneid"]] += 1;
elseif (is_array($zones)) {
foreach ($zones as $k=>$v) {
$is_zipcodes = func_query_first_cell("SELECT COUNT(*) FROM $sql_tbl[zone_element] WHERE $sql_tbl[zone_element].field_type='Z' AND $sql_tbl[zone_element].zoneid='$k' $empty_condition");
if ($is_zipcodes)
unset($zones[$k]);
}
}
$address_zones = func_query("SELECT $sql_tbl[zone_element].zoneid FROM $sql_tbl[zone_element], $sql_tbl[zones] WHERE $sql_tbl[zone_element].zoneid=$sql_tbl[zones].zoneid AND $sql_tbl[zone_element].field_type='A' AND ('".addslashes($customer_info[$address_prefix."address"])."' LIKE $sql_tbl[zone_element].field OR '".addslashes($customer_info[$address_prefix."address_2"])."' LIKE $sql_tbl[zone_element].field) $empty_condition $provider_condition");
if (is_array($address_zones))
foreach ($address_zones as $k=>$v)
$zones[$v["zoneid"]] += 1;
elseif (is_array($zones)) {
foreach ($zones as $k=>$v) {
$is_address = func_query_first_cell("SELECT COUNT(*) FROM $sql_tbl[zone_element] WHERE $sql_tbl[zone_element].field_type='A' AND $sql_tbl[zone_element].zoneid='$k' $empty_condition");
if ($is_address)
unset($zones[$k]);
}
}
}
}
$zones[0] = 0;
arsort($zones, SORT_NUMERIC);
if (!empty($customer_login)) {
$results_cache[$customer_login][$provider][$address_type] = $zones;
}
return $zones;
}
#
# Get county by code
#
function func_get_county ($countyid) {
global $sql_tbl;
$county_name = func_query_first_cell("SELECT county FROM $sql_tbl[counties] WHERE countyid='$countyid'");
return ($county_name ? $county_name : $countyid);
}
#
# Get state by code
#
function func_get_state ($state_code, $country_code) {
global $sql_tbl;
$state_name = func_query_first_cell("SELECT state FROM $sql_tbl[states] WHERE country_code='$country_code' AND code='".addslashes($state_code)."'");
return ($state_name ? $state_name : $state_code);
}
#
# Get country by code
#
function func_get_country ($country_code, $force_code = '') {
global $sql_tbl, $shop_language;
$code = (empty($force_code)?$shop_language:$force_code);
$country_name = func_query_first_cell("SELECT value as country FROM $sql_tbl[languages] WHERE name='country_$country_code' AND code = '$code'");
return ($country_name ? $country_name : $country_code);
}
#
# Convert price to "XXXXX.XX" format
#
function price_format($price) {
return sprintf("%.2f",round((double)$price+0.00000000001,2));
}
function func_get_products_providers ($products) {
$products_providers = array ();
if(!empty($products)) {
foreach ($products as $product) {
if (!in_array ($product["provider"], $products_providers)) {
$products_providers [] = $product["provider"];
}
}
}
return $products_providers;
}
function func_get_products_by_provider ($products, $provider) {
global $single_mode;
$result = array ();
if ($single_mode) {
$result = $products;
} else {
foreach ($products as $k=>$product) {
if ($product["provider"] == $provider)
$result[$k] = $product;
}
}
return $result;
}
#
# This function do real shipping calcs
#
function func_real_shipping($delivery) {
global $intershipper_rates, $sql_tbl;
$shipping_codes = func_query_first("select code, subcode from $sql_tbl[shipping] where shippingid='$delivery'");
if ($intershipper_rates) {
foreach($intershipper_rates as $rate)
if ($rate["methodid"]==$shipping_codes["subcode"])
return $rate["rate"];
} else
return "0.00";
}
#
# This function calculates costs of contents of shopping cart
#
function func_calculate($cart, $products, $login, $login_type) {
global $config, $single_mode, $sql_tbl;
global $xcart_dir, $active_modules;
$return = array ();
$return ["orders"] = array ();
if ($active_modules["Special_Offers"]) {
include $xcart_dir."/modules/Special_Offers/calculate_init.php";
}
if ($single_mode) {
$result = func_calculate_single ($cart, $products, $login, $login_type);
$return = $result;
$return ["orders"][0] = $result;
$return ["orders"][0]["provider"] = (!empty($products) ? $products[0]["provider"] : "");
if ($active_modules["Special_Offers"]) {
include $xcart_dir."/modules/Special_Offers/calculate_return.php";
}
}
else {
$products_providers = func_get_products_providers ($products);
$key = 0;
foreach ($products_providers as $provider_for) {
$_products = func_get_products_by_provider ($products, $provider_for);
$result = func_calculate_single ($cart, $_products, $login, $login_type, $provider_for);
$return ["total_cost"] += $result ["total_cost"];
$return ["shipping_cost"] += $result ["shipping_cost"];
$return ["display_shipping_cost"] += $result ["display_shipping_cost"];
$return ["tax_cost"] += $result ["tax_cost"];
$return ["discount"] += $result ["discount"];
if ($result["coupon"]) {
$return ["coupon"] = $result ["coupon"];
}
$return ["coupon_discount"] += $result ["coupon_discount"];
$return ["subtotal"] += $result ["subtotal"];
$return ["display_subtotal"] += $result ["display_subtotal"];
$return ["discounted_subtotal"] += $result ["discounted_subtotal"];
$return ["display_discounted_subtotal"] += $result ["display_discounted_subtotal"];
$return ["products"] = func_array_merge($return ["products"], $result ["products"]);
if (empty($return["taxes"]))
$return["taxes"] = $result["taxes"];
elseif (is_array($result["taxes"])) {
foreach ($result["taxes"] as $k=>$v) {
if (in_array($k, array_keys($return["taxes"])))
$return["taxes"][$k]["tax_cost"] += $v["tax_cost"];
else
$return["taxes"][$k] = $v;
}
}
$return ["orders"][$key] = $result;
$return ["orders"][$key]["provider"] = $provider_for;
if ($active_modules["Special_Offers"]) {
include $xcart_dir."/modules/Special_Offers/calculate_return.php";
}
$key ++;
}
if (!empty($cart["giftcerts"])) {
$_products = array ();
$result = func_calculate_single ($cart, $_products, $login, $login_type);
$return ["total_cost"] += $result ["total_cost"];
$return ["shipping_cost"] += $result ["shipping_cost"];
$return ["display_shipping_cost"] += $result ["display_shipping_cost"];
$return ["tax_cost"] += $result ["tax_cost"];
$return ["discount"] += $result ["discount"];
$return ["subtotal"] += $result ["subtotal"];
$return ["display_subtotal"] += $result ["display_subtotal"];
$return ["discounted_subtotal"] += $result ["discounted_subtotal"];
$return ["display_discounted_subtotal"] += $result ["display_discounted_subtotal"];
$return ["coupon_discount"] += $result ["coupon_discount"];
$return ["orders"][$key] = $result;
$return ["orders"][$key]["provider"] = ""; #$provider_for;
$key++;
}
}
$return["display_cart_products_tax_rates"] = "N";
$return["product_tax_name"] = "";
if ($config["Taxes"]["display_cart_products_tax_rates"] == "Y") {
$_taxes = array();
foreach ($return["orders"] as $k=>$v) {
if (is_array($v["products"])) {
foreach ($v["products"] as $i=>$j) {
if (is_array(@$j["taxes"])) {
foreach ($j["taxes"] as $_tn=>$_tax) {
if ($_tax["tax_value"] == 0)
continue;
if (!isset($_taxes[$_tn]))
$_taxes[] = $_tax["tax_display_name"];
}
}
}
}
}
if (count($_taxes) > 0) {
$return["display_cart_products_tax_rates"] = "Y";
if (count($_taxes) == 1)
$return["product_tax_name"] = $_taxes[0];
}
}
#
# Recalculating applied gift certificates
#
$giftcert_cost = 0;
$applied_giftcerts = array();
if (!empty($cart["applied_giftcerts"])) {
$gc_payed_sum = 0;
$applied_giftcerts = array();
foreach($cart["applied_giftcerts"] as $k=>$v) {
if (($gc_payed_sum + $v["giftcert_cost"]) <= $return["total_cost"]) {
$gc_payed_sum += $v["giftcert_cost"];
$applied_giftcerts[] = $v;
continue;
}
else
db_query("UPDATE $sql_tbl[giftcerts] SET status='A' WHERE gcid='$v[giftcert_id]'");
}
$giftcert_cost = $gc_payed_sum;
}
if ($return["total_cost"] >= $giftcert_cost)
$return["giftcert_discount"] = $giftcert_cost;
else
$return["giftcert_discount"] = $giftcert_cost - $return["total_cost"];
$return["total_cost"] = price_format($return["total_cost"] - $return["giftcert_discount"]);
$return["applied_giftcerts"] = $applied_giftcerts;
if ($single_mode)
$return ["orders"][0]["total_cost"] = $return["total_cost"];
#
# Apply GC to all orders in cart in single_mode Off
#
elseif (is_array($applied_giftcerts)) {
foreach($return["orders"] as $k=>$order) {
$giftcert_discount = 0;
foreach($applied_giftcerts as $k1=>$applied_giftcert) {
if ($applied_giftcert["giftcert_cost"] == 0)
continue;
if ($applied_giftcert["giftcert_cost"] > $order["total_cost"])
$applied_giftcert["giftcert_cost"] = $order["total_cost"];
$giftcert_discount += $applied_giftcert["giftcert_cost"];
$order["total_cost"] = $order["total_cost"] - $giftcert_discount;
$applied_giftcert["giftcert_cost"] = price_format($applied_giftcert["giftcert_cost"]);
$applied_giftcerts[$k1]["giftcert_cost"] -= $applied_giftcert["giftcert_cost"];
$return["orders"][$k]["applied_giftcerts"][] = $applied_giftcert;
$return["orders"][$k]["giftcert_discount"] = price_format($giftcert_discount);
}
$return["orders"][$k]["total_cost"] = price_format($return["orders"][$k]["total_cost"] - $return["orders"][$k]["giftcert_discount"]);
}
}
return $return;
}
#
# This function distributes the discount among the product prices and
# decreases the subtotal
#
function func_distribute_discount($field_name, $products, $discount, $discount_type, $avail_discount_total=0) {
$sum_discount = 0;
if ($discount_type=="absolute" && $avail_discount_total > 0) {
# Distribute absolute discount among the products
foreach ($products as $k=>$product) {
if (@$product["deleted"]) continue; # for Advanced_Order_Management module
if ($field_name == "coupon_discount" || $product["discount_avail"] == "Y") {
$koefficient = $product["price"] / $avail_discount_total;
$products[$k][$field_name] = $discount * $koefficient;
$products[$k]["discounted_price"] = max($products[$k]["discounted_price"] - $products[$k][$field_name], 0.00);
}
}
}
elseif ($discount_type=="percent") {
# Distribute percent discount among the products
foreach ($products as $k=>$product) {
if (@$product["deleted"]) continue; # for Advanced_Order_Management module
if ($field_name == "coupon_discount" || $product["discount_avail"] == "Y") {
$products[$k][$field_name] = price_format($product["discounted_price"] * $discount / 100);
$products[$k]["discounted_price"] = $product["discounted_price"] - $products[$k][$field_name];
}
}
}
foreach($products as $product) {
if (@$product["deleted"]) continue; # for Advanced_Order_Management module
$sum_discount += $product[$field_name]*$product["amount"];
}
$return["products"] = $products;
$return[$field_name] = $sum_discount;
return $return;
}
#
# This function calculates discounts on subtotal
#
function func_calculate_discounts($membership, $products, $discount_coupon = "", $provider="") {
global $sql_tbl, $config, $active_modules, $single_mode;
#
# Prepare provider condition for discounts gathering
#
$provider_condition = ($single_mode ? "" : "AND provider='$provider'");
#
# Search for subtotal to apply the global discounts
#
$avail_discount_total = 0;
$total = 0;
foreach($products as $k=>$product) {
if (@$product["deleted"]) continue; # for Advanced_Order_Management module
$product["price"] = price_format($product["price"]);
$products[$k]["discount"] = 0;
$products[$k]["coupon_discount"] = 0;
$products[$k]["discounted_price"] = $product["price"];
if ($product["discount_avail"] == "Y")
$avail_discount_total += $product["price"] * $product["amount"];
$total += $product["price"] * $product["amount"];
}
$return = array("discount" => 0,
"coupon_discount" => 0,
"discount_coupon" => $discount_coupon,
"products" => $products);
if ($avail_discount_total > 0) {
#
# Calculate global discount
#
$discount_info = func_query_first("SELECT * FROM $sql_tbl[discounts] WHERE minprice<='$avail_discount_total' $provider_condition AND membership IN ('','$membership') ORDER BY minprice DESC");
if (!empty($discount_info)) {
if ($discount_info["discount_type"]=="absolute")
$return["discount"] += $discount_info["discount"];
elseif ($discount_info["discount_type"]=="percent")
$return["discount"] += price_format($avail_discount_total * $discount_info["discount"] / 100);
#
# Distribute the discount among the products prices
#
$updated = func_distribute_discount("discount", $products, $discount_info["discount"], $discount_info["discount_type"], $avail_discount_total);
#
# $products and $discount are extracted from the array $updated
#
extract($updated);
unset($updated);
$return["products"] = $products;
$return["discount"] = $discount;
}
}
#
# Apply discount coupon
#
if ($active_modules["Discount_Coupons"] and !empty($discount_coupon)) {
#
# Calculate discount value of the discount coupon
#
$coupon_total = 0;
$coupon_amount = 0;
$discount_coupon_data = func_query_first("select * from $sql_tbl[discount_coupons] where coupon='$discount_coupon' $provider_condition");
$return["discount_coupon_data"] = $discount_coupon_data;
if (!$single_mode and ($discount_coupon_data["provider"] != $provider or empty($products)))
$return["discount_coupon"] = $discount_coupon_data = "";
$return["coupon_type"] = $discount_coupon_data["coupon_type"];
if (!empty($discount_coupon_data) and (($discount_coupon_data["coupon_type"] == "absolute") || ($discount_coupon_data["coupon_type"] == "percent"))) {
$coupon_discount = 0;
if ($discount_coupon_data["productid"] > 0) {
#
# Apply coupon to product
#
foreach($products as $k=>$product) {
if (@$product["deleted"]) continue; # for Advanced_Order_Management module
if ($product["productid"] == $discount_coupon_data["productid"]) {
$price = $product["price"] - $product["discount"];
if ($discount_coupon_data["coupon_type"]=="absolute") {
$coupon_discount = price_format($product["amount"] * $discount_coupon_data["discount"]);
$products[$k]["coupon_discount"] = $discount_coupon_data["discount"];
$products[$k]["discounted_price"] = max($price - $products[$k]["coupon_discount"], 0.00);
}
else {
$coupon_discount = price_format(($price * $discount_coupon_data["discount"] / 100 )) * $product["amount"];
$products[$k]["coupon_discount"] = price_format($price * $discount_coupon_data["discount"] / 100);
$products[$k]["discounted_price"] = max($price - $products[$k]["coupon_discount"], 0.00);
}
$return["coupon_discount"] += $coupon_discount;
}
}
}
elseif ($discount_coupon_data["categoryid"] > 0) {
#
# Apply coupon to category (and subcategories)
#
$category_ids[] = $discount_coupon_data["categoryid"];
if ($discount_coupon_data["recursive"] == "Y") {
$categoryid_path = func_query_first_cell("SELECT categoryid_path FROM $sql_tbl[categories] WHERE categoryid='$discount_coupon_data[categoryid]'");
if (!empty($categoryid_path))
$tmp = db_query("SELECT categoryid FROM $sql_tbl[categories] WHERE categoryid_path LIKE '$categoryid_path/%'");
while($row = db_fetch_array($tmp))
$category_ids[] = $row["categoryid"];
}
#
# Apply coupon to one category
#
foreach ($products as $k=>$product) {
if (@$product["deleted"]) continue; # for Advanced_Order_Management module
$product_categories = func_query("SELECT categoryid FROM $sql_tbl[products_categories] WHERE productid='$product[productid]'");
$is_valid_product = false;
foreach ($product_categories as $pc) {
if (in_array($pc["categoryid"], $category_ids)) {
$is_valid_product = true;
break;
}
}
if ($is_valid_product) {
$price = $product["price"] - $product["discount"];
if ($discount_coupon_data["coupon_type"]=="absolute") {
$products[$k]["coupon_discount"] = $discount_coupon_data["discount"];
$products[$k]["discounted_price"] = max($price - $products[$k]["coupon_discount"], 0.00);
$coupon_discount += $product["amount"] * $discount_coupon_data["discount"];
}
else {
$products[$k]["coupon_discount"] = price_format($price * $discount_coupon_data["discount"] / 100);
$products[$k]["discounted_price"] = max($price - $products[$k]["coupon_discount"], 0.00);
$coupon_discount += price_format($price * $discount_coupon_data["discount"] / 100) * $product["amount"];
}
$return["coupon_discount"] = $coupon_discount;
}
}
}
else {
#
# Apply coupon to subtotal
#
if ($discount_coupon_data["coupon_type"]=="absolute")
$return["coupon_discount"] = $discount_coupon_data["discount"];
elseif ($discount_coupon_data["coupon_type"]=="percent")
$return["coupon_discount"] = $total * $discount_coupon_data["discount"] / 100;
$updated = func_distribute_discount("coupon_discount", $products, $discount_coupon_data["discount"], $discount_coupon_data["coupon_type"], $total);
#
# $products and $discount are extracted from the array $updated
#
extract($updated);
unset($updated);
$return["coupon_discount"] = $coupon_discount;
}
}
$return["products"] = $products;
}
return $return;
}
#
# This function calculates delivery cost
#
# Shipping also calculated based on zones
#
# Advanced shipping formula:
# AMOUNT = amount of ordered products
# SUM = total sum of order
# TOTAL_WEIGHT = total weight of products
#
# SHIPPING = rate+TOTAL_WEIGHT*weight_rate+AMOUNT*item_rate+SUM*rate_p/100
#
function func_calculate_shippings($products, $shipping_id, $customer_info, $provider="") {
global $sql_tbl, $config, $active_modules, $single_mode;
$return = array("shipping_cost" => 0);
#
# Prepare provider condition for shipping rates gathering
#
$provider_condition = ($single_mode ? "" : "AND provider='$provider'");
#
# Initial definitions
#
$total_shipping = 0;
$total_weight_shipping = 0;
$total_ship_items = 0;
$shipping_cost = 0;
$shipping_freight = 0;
$free_shipping_products_cost = 0;
if(!empty($products)) {
foreach($products as $k=>$product) {
if (@$product["deleted"]) continue; # for Advanced_Order_Management module
if ($product["free_shipping"] == "Y" || $product['product_type'] == 'C') {
$free_shipping_products_cost += $product["taxed_price"] * $product["amount"];
continue;
} elseif ($active_modules["Egoods"] && $product["distribution"] != "") {
continue;
} else {
if (!($config["Shipping"]["replace_shipping_with_freight"] == "Y" and $product["shipping_freight"] > 0)) {
$total_shipping += $product["taxed_price"] * $product["amount"];
$total_weight_shipping += $product["weight"] * $product["amount"];
$total_ship_items += $product["amount"];
}
$shipping_freight += $product["shipping_freight"] * $product["amount"];
}
}
}
#
# Nothing to ship
#
if ($total_ship_items == 0 and $shipping_freight == 0)
return $return;
#
# Get defined shipping rates for $shipping_id
#
$total_shipping_abs = $total_shipping;
if ($total_shipping > 0) {
$total_shipping_abs += $free_shipping_products_cost;
}
$customer_zone = func_get_customer_zone_ship($customer_info, $provider,"D");
$shipping = func_query("SELECT * FROM $sql_tbl[shipping_rates] WHERE shippingid='$shipping_id' $provider_condition AND zoneid='$customer_zone' AND maxtotal>='$total_shipping_abs' AND maxweight>='$total_weight_shipping' AND type='D' ORDER BY maxtotal, maxweight");
if ($shipping and $total_ship_items > 0)
$shipping_cost = $shipping[0]["rate"] + ($total_weight_shipping * $shipping[0]["weight_rate"]) + ($total_ship_items * $shipping[0]["item_rate"]) + ($total_shipping * $shipping[0]["rate_p"] / 100);
#
# Get realtime shipping rates
#
$result = func_query_first ("SELECT * FROM $sql_tbl[shipping] WHERE shippingid='$shipping_id' AND code!=''");
if ($config["Shipping"]["realtime_shipping"]=="Y" and $result and $total_ship_items>0) {
$shipping_cost = func_real_shipping($shipping_id);
$customer_zone = func_get_customer_zone_ship($customer_info, $provider,"R");
$shipping_rt = func_query("SELECT * FROM $sql_tbl[shipping_rates] WHERE shippingid='$shipping_id' $provider_condition AND zoneid='$customer_zone' AND maxtotal>=$total_shipping_abs AND maxweight>=$total_weight_shipping AND type='R' ORDER BY maxtotal, maxweight");
if($shipping_rt && $shipping_cost > 0)
$shipping_cost += $shipping_rt[0]["rate"]+$total_weight_shipping*$shipping_rt[0]["weight_rate"]+$total_ship_items*$shipping_rt[0]["item_rate"]+$total_shipping*$shipping_rt[0]["rate_p"]/100;
}
$return["shipping_cost"] = $shipping_cost += $shipping_freight;
return $return;
}
#
# This function calculates taxes
#
# SUM = total sum of order
#
# TAX_US = country_tax_flat + SUM*country_tax_percent/100 + state_tax_flat + SUM*state_tax_percent/100;
#
# TAX_CAN = SUM*gst_tax/100 + SUM*pst_tax/100;
#
function func_calculate_taxes(&$products, $customer_info, $shipping_cost, $provider="") {
global $sql_tbl, $config, $active_modules, $single_mode, $shop_language;
global $xcart_dir;
$taxes = array();
$taxes["total"] = 0;
$taxes["shipping"] = 0;
$__taxes = array();
foreach($products as $k=>$product) {
if (@$product["deleted"]) continue; # for Advanced_Order_Management module
if ($product["free_tax"] != "Y") {
$product_taxes = func_get_product_taxes($products[$k], $customer_info["login"], true);
if ($config["Taxes"]["display_taxed_order_totals"] =="Y")
$products[$k]["display_price"] = doubleval($product["taxed_price"]);
if (is_array($product_taxes)) {
$formula_data = array();
$formula_data["ST"] = $product["price"] * $product["amount"];
$formula_data["DST"] = $product["discounted_price"] * $product["amount"];
$formula_data["SH"] = 0;
$tax_result = array();
if (empty($shipping_cost)) {
$index = 1;
$tax_result[1] = 0;
}
else
$index = 0;
while ($index < 2) {
$index++;
foreach ($product_taxes as $tax_name=>$v) {
if ($v["skip"])
continue;
if (!isset($taxes["taxes"][$tax_name])) {
$taxes["taxes"][$tax_name] = $v;
$taxes["taxes"][$tax_name]["tax_cost"] = 0;
}
if ($index == 2) {
$formula_data["SH"] = $shipping_cost;
if (!empty($__taxes[$tax_name]))
$formula_data["SH"] = 0;
else
$__taxes[$tax_name] = true;
}
if ($v["rate_type"] == "%") {
$assessment = func_calculate_assessment($v["formula"], $formula_data);
$tax_value = $assessment * $v["rate_value"] / 100;
}
else
$tax_value = $v["rate_value"];
$formula_data[$tax_name] = $tax_value;
$tax_result[$index] += $tax_value;
if ($index == 2) {
$taxes["taxes"][$tax_name]["tax_cost"] += $tax_value;
}
}
}
$taxes["shipping"] += max(0,($tax_result[2] - $tax_result[1]));
}
}
}
if ($shipping_cost == 0)
$taxes["shipping"] = 0;
if (is_array($taxes["taxes"])) {
foreach ($taxes["taxes"] as $tax_name=>$tax) {
$taxes["taxes"][$tax_name]["tax_cost"] = price_format($tax["tax_cost"]);
$taxes["total"] += $taxes["taxes"][$tax_name]["tax_cost"];
}
}
return $taxes;
}
#
# Calculate total products price
# 1) calculate total sum,
# 2) a) total = total - discount
# b) total = total - coupon_discount
# 3) calculate shipping
# 4) calculate tax
# 5) total_cost = total + shipping + tax
# 6) total_cost = total_cost + giftcerts_cost
#
function func_calculate_single($cart, $products, $login, $login_type, $provider_for="") {
global $single_mode;
global $active_modules, $config, $sql_tbl;
global $xcart_dir;
if ($products) {
#
# Set the fields filter to avoid storing too much redundant data
# in the session
#
list($tmp_k, $tmp_v) = each($cart["products"]);
foreach(array_keys($tmp_v) as $k)
$product_keys[] = $k;
unset($tmp_k, $tmp_v);
reset($cart["products"]);
$product_keys[] = "cartid";
$product_keys[] = "product";
$product_keys[] = "productcode";
$product_keys[] = "product_options";
$product_keys[] = "price";
$product_keys[] = "display_price";
$product_keys[] = "display_discounted_price";
$product_keys[] = "display_subtotal";
$product_keys[] = "free_price";
$product_keys[] = "discount";
$product_keys[] = "coupon_discount";
$product_keys[] = "discounted_price";
$product_keys[] = "taxes";
$product_keys[] = "subtotal";
$product_keys[] = "product_type";
$product_keys[] = "options_surcharge";
$product_keys[] = "extra_data"; # Additional data for storing in the DB
if ($active_modules["Wishlist"])
$product_keys[] = "wishlistid";
if ($active_modules["Egoods"])
$product_keys[] = "distribution";
if ($active_modules["Advanced_Order_Management"]) {
$product_keys[] = "deleted";
$product_keys[] = "new";
$product_keys[] = "use_shipping_cost_alt";
$product_keys[] = "shipping_cost_alt";
}
if ($active_modules["Product_Configurator"]) {
$product_keys[] = "hidden";
$product_keys[] = "pconf_price";
$product_keys[] = "pconf_display_price";
$product_keys[] = "pconf_data";
$product_keys[] = "slotid";
$product_keys[] = "price_modifier";
}
if ($active_modules["Subscriptions"]) {
$product_keys[] = "catalogprice";
$product_keys[] = "sub_plan";
$product_keys[] = "sub_days_remain";
$product_keys[] = "sub_onedayprice";
}
if ($active_modules["Special_Offers"]) {
$product_keys[] = "free_amount";
$product_keys[] = "have_offers";
$product_keys[] = "special_price_used";
$product_keys[] = "free_shipping_used";
$product_keys[] = "saved_original_price";
}
}
else
$products = array();
#
# Calculate totals for one provider only or for all ($single_mode=true)
#
$provider_condition=($single_mode?"":"and provider='$provider_for'");
$shipping_id = @$cart["shippingid"];
$giftcerts = @$cart["giftcerts"];
$discount_coupon = @$cart["discount_coupon"];
#
# Get the user information
#
if (!empty($login)) $customer_info = func_userinfo($login,$login_type);
if (!empty($active_modules["Special_Offers"])) {
include $xcart_dir."/modules/Special_Offers/calculate_prepare.php";
include $xcart_dir."/modules/Special_Offers/calculate.php";
}
if (!empty($products)) {
#
# Apply discounts to the products
#
$discounts_ret = func_calculate_discounts($customer_info["membership"], $products, $discount_coupon, $provider_for);
#
# Extract returned variables to global variables set:
# $discount, $coupon_discount, $discount_coupon, $products
#
extract($discounts_ret);
unset($discounts_ret);
}
#
# Initial definitions
#
$subtotal = 0;
$discounted_subtotal = 0;
$shipping_cost = 0;
$total_tax = 0;
$giftcerts_cost = 0;
#
# Update $products array: calculate discounted prices, subtotal and
# discounted subtotal
#
foreach($products as $k=>$product) {
if (@$product["deleted"]) continue; # for Advanced_Order_Management module
if (empty($product["discount"]) and empty($product["coupon_discount"]))
$product["discounted_price"] = $product["price"];
if ($product["product_type"] == "C") {
# Corrections for Product Configurator module
$product["pconf_price"] = $product["price"] = max(doubleval($product["options_surcharge"]), 0);
$product["discounted_price"] = $product["price"];
foreach ($products as $k1=>$v1) {
if ($v1["hidden"] == $product["cartid"]) {
$product["pconf_price"] += price_format($v1["price"]);
}
}
$product["pconf_display_price"] = $product["pconf_price"];
}
$product["subtotal"] = price_format($product["discounted_price"] * $product["amount"]);
$product["display_price"] = price_format($product["price"]);
$product["display_discounted_price"] = $product["discounted_price"];
$product["display_subtotal"] = $product["subtotal"];
$products[$k] = $product;
if (!empty($active_modules["Special_Offers"])) {
include $xcart_dir."/modules/Special_Offers/calculate_subtotal.php";
} else {
$subtotal += price_format($product["price"]) * $product["amount"];
$discounted_subtotal += price_format($product["discounted_price"]) * $product["amount"];
}
}
$total = $subtotal;
$display_subtotal = $subtotal;
$display_discounted_subtotal = $discounted_subtotal;
#
# Enable shipping and taxes calculation if "apply_default_country" is ticked.
#
$calculate_enable_flag = true;
if (empty($login)) {
#
# If user is not logged in
#
if ($config["General"]["apply_default_country"] == "Y") {
$customer_info["s_country"] = $config["General"]["default_country"];
$customer_info["s_state"] = $config["General"]["default_state"];
$customer_info["s_zipcode"] = $config["General"]["default_zipcode"];
$customer_info["s_city"] = $config["General"]["default_city"];
}
else
$calculate_enable_flag = false;
}
if ($config["Shipping"]["disable_shipping"] != "Y" && $calculate_enable_flag || $cart["use_shipping_cost_alt"] == "Y") {
#
# Calculate shipping cost
#
if ($cart["use_shipping_cost_alt"] == "Y")
$shipping_cost = $cart["shipping_cost_alt"];
else {
$shippings_ret = func_calculate_shippings($products, $shipping_id, $customer_info, $provider_for);
#
# Extract returned variables to global variables set:
# $shipping_cost
#
extract($shippings_ret);
unset($shippings_ret);
}
if (!empty($coupon_type) and $coupon_type == "free_ship") {
#
# Apply discount coupon 'Free shipping'
#
if (($single_mode) or ($provider_for == $discount_coupon_data["provider"])) {
$coupon_discount = $shipping_cost;
$shipping_cost = 0;
}
}
}
$display_shipping_cost = $shipping_cost;
if ($calculate_enable_flag) {
#
# Calculate taxes cost
#
$taxes = func_calculate_taxes($products, $customer_info, $shipping_cost, $provider_for);
$total_tax = $taxes["total"];
if ($config["Taxes"]["display_taxed_order_totals"] == "Y") {
$_display_discounted_subtotal_tax = 0;
if (is_array($taxes["taxes"])) {
# Calculate the additional tax value if "display_including_tax"
# option for tax is disabled (for $_display_discounted_subtotal)
foreach ($taxes["taxes"] as $k=>$v)
if ($v["display_including_tax"] != "Y")
$_display_discounted_subtotal_tax += $v["tax_value"];
}
$display_shipping_cost = $shipping_cost + $taxes["shipping"];
$_display_subtotal = 0;
$_display_discounted_subtotal = 0;
if (is_array($products)) {
foreach ($products as $k=>$v) {
$v["display_price"] = $products[$k]["display_price"] = price_format($products[$k]["display_price"]);
if (is_array($v["taxes"])) {
# Correct $_display_subtotal if "display_including_tax"
# option for the tax is disabled
foreach ($v["taxes"] as $tn=>$tv) {
if ($tv["display_including_tax"] == "N")
$_display_subtotal += $tv["tax_value"];
}
}
$_display_subtotal += $v["display_price"] * $v["amount"];
if (!empty($v["discount"]) || !empty($v["coupon_discount"]))
$_taxes = func_tax_price($v["price"], $v["productid"], false, $v["discounted_price"], $customer_info, "", true);
else
$_taxes = func_tax_price($v["price"], $v["productid"], false, 0, $customer_info, "", true);
$products[$k]["display_discounted_price"] = price_format($_taxes["taxed_price"]);
$products[$k]["display_subtotal"] = $products[$k]["display_discounted_price"] * $v["amount"];
$_display_discounted_subtotal += $products[$k]["display_subtotal"];
if ($v["product_type"] == "C") {
# Corrections for Product Configurator module
$products[$k]["display_price"] = $_pconf_display_price = max(doubleval($products[$k]["options_surcharge"]), 0);
$_display_subtotal += ($_pconf_display_price * $products[$k]["amount"]);
$_pconf_taxes = array();
foreach ($products as $k1=>$v1) {
if ($v1["hidden"] == $v["cartid"]) {
$_pconf_display_price += price_format($v1["display_price"]);
if (is_array($v1["taxes"])) {
foreach ($v1["taxes"] as $_tax_name=>$_tax) {
if (!isset($_pconf_taxes[$_tax_name])) {
$_pconf_taxes[$_tax_name] = $_tax;
$_pconf_taxes[$_tax_name]["tax_value"] = 0;
}
$_pconf_taxes[$_tax_name]["tax_value"] += $_tax["tax_value"];
}
}
}
}
$products[$k]["taxes"] = $_pconf_taxes;
$products[$k]["pconf_display_price"] = $_pconf_display_price;
}
}
if ($display_subtotal == $display_discounted_subtotal)
$display_discounted_subtotal = $_display_subtotal;
else
$display_discounted_subtotal = $_display_discounted_subtotal + $_display_discounted_subtotal_tax;
$display_subtotal = $_display_subtotal;
}
}
}
#
# Calculate Gift Certificates cost (purchased giftcerts)
#
if ((($single_mode) or (!$provider_for)) and ($giftcerts)) {
foreach($giftcerts as $giftcert) {
if (@$giftcert["deleted"]) continue; # for Advanced_Order_Management module
$giftcerts_cost+=$giftcert["amount"];
}
}
$subtotal += $giftcerts_cost;
$display_subtotal += $giftcerts_cost;
$discounted_subtotal += $giftcerts_cost;
$display_discounted_subtotal += $giftcerts_cost;
#
# Calculate total
#
if ($config["Taxes"]["display_taxed_order_totals"] == "Y")
$total = $display_discounted_subtotal + $display_shipping_cost;
else
$total = $discounted_subtotal + $shipping_cost + $total_tax;
$_products = array();
foreach($products as $index=>$product) {
foreach($product as $key=>$value)
if (in_array($key, $product_keys))
$_products[$index][$key] = $value;
}
$return = array("total_cost"=>price_format($total),
"shipping_cost"=>price_format($shipping_cost),
"taxes" => $taxes["taxes"],
"tax_cost"=>price_format($taxes["total"]),
"discount"=>price_format($discount),
"coupon"=>$discount_coupon,
"coupon_discount"=>price_format($coupon_discount),
"subtotal"=>price_format($subtotal),
"display_subtotal"=>price_format($display_subtotal),
"discounted_subtotal"=>price_format($discounted_subtotal),
"display_shipping_cost"=>price_format($display_shipping_cost),
"display_discounted_subtotal"=>price_format($display_discounted_subtotal),
"products"=>$_products);
if (!empty($active_modules["Special_Offers"])) {
include $xcart_dir."/modules/Special_Offers/calculate_result.php";
}
return $return;
}
#
# Search for products in products database
#
function func_search_products($query, $membership, $orderby="", $limit="") {
global $current_area, $user_account;
global $store_language, $sql_tbl;
global $config;
global $cart, $login;
global $active_modules;
#
# Generate ORDER BY rule
#
if (empty($orderby)) {
$orderby = ($config["Appearance"]["products_order"] ? $config["Appearance"]["products_order"] : "orderby");
if($orderby == 'title') {
$orderby = 'product';
} elseif($orderby == 'quantity') {
$orderby = "$sql_tbl[products].avail";
} elseif($orderby == "orderby") {
$orderby = "$sql_tbl[products_categories].orderby";
} elseif($orderby == "quantity") {
$orderby = "$sql_tbl[products].avail";
} elseif($orderby == "price") {
$orderby = "price";
} elseif($orderby == "productcode") {
$orderby = "$sql_tbl[products].productcode";
}
}
#
# Generate membership condition
#
if ($current_area == "C") {
$membership_condition = " AND ($sql_tbl[categories].membership='$membership' OR $sql_tbl[categories].membership='') AND $sql_tbl[products].forsale='Y'";
}
else
$membership_condition = "";
#
# Generate products availability condition
#
if ($config["General"]["unlimited_products"]=="N" && (($current_area == "C" || $current_area == "B") && $config["General"]["disable_outofstock_products"] == "Y"))
$avail_condition = " AND $sql_tbl[products].avail>0 ";
else
$avail_condition = "";
$select_query = "SELECT $sql_tbl[products].productid, $sql_tbl[products].product, $sql_tbl[products].productcode, $sql_tbl[products].avail, MIN($sql_tbl[pricing].price) AS price";
$from_query = " FROM $sql_tbl[products], $sql_tbl[categories], $sql_tbl[products_categories], $sql_tbl[pricing]";
$where_query = " WHERE $sql_tbl[products].productid=$sql_tbl[products_categories].productid AND $sql_tbl[products_categories].categoryid=$sql_tbl[categories].categoryid AND $sql_tbl[products].productid=$sql_tbl[pricing].productid AND $sql_tbl[pricing].quantity=1 AND ($sql_tbl[pricing].membership='$membership' OR $sql_tbl[pricing].membership='') $membership_condition $avail_condition";
if($current_area == 'C' && !empty($active_modules['Product_Options'])) {
$where_query .= " AND ($sql_tbl[pricing].variantid = 0 OR ($sql_tbl[variants].variantid = $sql_tbl[pricing].variantid".(($config["General"]["disable_outofstock_products"] == "Y" && $config["General"]["unlimited_products"] != "Y")?" AND $sql_tbl[variants].avail > 0":"")."))";
} else {
$where_query .= " AND $sql_tbl[pricing].variantid = 0";
}
if ($current_area == 'C' && empty($active_modules['Product_Configurator'])) {
$where_query .= " AND $sql_tbl[products].product_type <> 'C' AND $sql_tbl[products].product_type <> 'B' ";
}
$groupby_query = " GROUP BY $sql_tbl[products].productid";
$orderby_query = " ORDER BY $orderby";
if (!empty($limit))
$limit_query = " LIMIT $limit";
#
# Check if product have prodyct class (Feature comparison)
#
if(!empty($active_modules['Feature_Comparison']) && $current_area == "C") {
global $comparison_list_ids;
$from_query .= " LEFT JOIN $sql_tbl[product_features] ON $sql_tbl[product_features].productid = $sql_tbl[products].productid";
$select_query .= ", $sql_tbl[product_features].fclassid";
if(($config['Feature_Comparison']['fcomparison_show_product_list'] == 'Y') && $config['Feature_Comparison']['fcomparison_max_product_list'] > @count((array)$comparison_list_ids)) {
$select_query .= ", IF($sql_tbl[product_features].fclassid IS NULL || $sql_tbl[product_features].productid IN ('".@implode("','",@array_keys((array)$comparison_list_ids))."'),'','Y') as is_clist";
}
}
#
# Check if product have product options (Product options)
#
if(!empty($active_modules['Product_Options'])) {
$from_query .= " LEFT JOIN $sql_tbl[classes] ON $sql_tbl[classes].productid = $sql_tbl[products].productid LEFT JOIN $sql_tbl[variants] ON $sql_tbl[variants].productid = $sql_tbl[products].productid";
$select_query .= ", IF ($sql_tbl[classes].classid IS NULL,'','Y') as is_product_options, IF($sql_tbl[variants].variantid IS NULL,'','Y') as is_variant";
}
if ($current_area == "C" && $store_language != $config["default_customer_language"])
$from_query .= " LEFT JOIN $sql_tbl[products_lng] ON $sql_tbl[products].productid=$sql_tbl[products_lng].productid";
#
# Generate search query
#
$search_query = $select_query.$from_query.$where_query.$query.$groupby_query.$orderby_query.$limit_query;
$result = func_query($search_query);
if ($result && ($current_area=="C" || $current_area=="B") ) {
#
# Post-process the result products array
#
foreach ($result as $key=>$value) {
if (!empty($cart) and !empty($cart["products"]) && $current_area=="C") {
#
# Update quantity for products that already placed into the cart
#
$in_cart = 0;
foreach ($cart["products"] as $cart_item)
if ($cart_item["productid"] == $value["productid"])
$in_cart += $cart_item["amount"];
$result[$key]["avail"] -= $in_cart;
}
#
# Get thumbnail's URL (uses only if images stored in FS)
#
$result[$key]["tmbn_url"] = func_get_thumbnail_url($result[$key]["productid"]);
if ($current_area == "C") {
$result[$key]["taxes"] = func_get_product_taxes($result[$key], $login);
}
#
# Check if product have product options
#
if(!empty($active_modules['Product_Options'])) {
$result[$key]["product_options"] = func_query_first_cell("SELECT COUNT(*) FROM $sql_tbl[classes] WHERE productid='".$value["productid"]."'");
}
$int_res = func_query_first("SELECT * FROM $sql_tbl[products_lng] WHERE code='$store_language' AND productid='$value[productid]'");
if (!empty($int_res["product"]))
$result[$key]["product"] = stripslashes($int_res["product"]);
if (!empty($int_res["descr"]))
$result[$key]["descr"] = stripslashes($int_res["descr"]);
if ($result[$key]["descr"] == strip_tags($result[$key]["descr"]))
$result[$key]["descr"] = str_replace("\n", "
", $result[$key]["descr"]);
if (!empty($int_res["full_descr"]))
$result[$key]["full_descr"] = stripslashes($int_res["full_descr"]);
if ($result[$key]["full_descr"] == strip_tags($result[$key]["full_descr"]))
$result[$key]["full_descr"] = str_replace("\n", "
", $result[$key]["full_descr"]);
}
}
return $result;
}
#
# Delete category recursively and all subcategories and products
#
function func_delete_category($cat) {
global $sql_tbl;
$catpair = func_query_first("SELECT categoryid_path, parentid FROM $sql_tbl[categories] WHERE categoryid='$cat'");
if ($catpair === false) # category is missing
return 0;
#
# Delete products from subcategories
#
$categoryid_path = $catpair["categoryid_path"];
$parent_categoryid = $catpair["parentid"];
$prods = func_query("SELECT $sql_tbl[products_categories].productid FROM $sql_tbl[categories], $sql_tbl[products_categories] WHERE ($sql_tbl[categories].categoryid='$cat' OR $sql_tbl[categories].categoryid_path LIKE '$categoryid_path/%') AND $sql_tbl[products_categories].categoryid=$sql_tbl[categories].categoryid");
if($prods)
while(list($key,$prod)=each($prods))
func_delete_product($prod["productid"],false);
#
# Delete subcategories
#
$subcats = func_query("SELECT categoryid FROM $sql_tbl[categories] WHERE categoryid='$cat' OR categoryid_path LIKE '$categoryid_path/%'");
if (is_array($subcats))
while(list($key,$subcat)=each($subcats)) {
$cat_id=$subcat["categoryid"];
db_query("DELETE FROM $sql_tbl[categories] WHERE categoryid='$cat_id'");
db_query("DELETE FROM $sql_tbl[products_categories] WHERE categoryid='$cat_id'");
db_query("DELETE FROM $sql_tbl[icons] WHERE categoryid='$cat_id'");
}
#
# Delete associated data
#
db_query("DELETE FROM $sql_tbl[icons] WHERE categoryid='$cat'");
db_query("DELETE FROM $sql_tbl[featured_products] WHERE categoryid='$cat'");
$product_categories = func_query("SELECT categoryid FROM $sql_tbl[categories]");
func_recalc_product_count($product_categories);
return $parent_categoryid;
}
#
# Put all product info into $product array
#
function func_select_product($id, $membership, $redirect_if_error=true, $clear_price=false, $always_select=false) {
global $login, $login_type, $current_area, $single_mode, $cart;
global $store_language, $sql_tbl, $config, $active_modules;
$in_cart = 0;
if ($current_area == "C") {
$membership_condition = " AND ($sql_tbl[categories].membership='$membership' OR $sql_tbl[categories].membership='') ";
}
else {
$membership_condition = "";
}
if ($current_area == "C" and !empty($cart) and !empty($cart["products"])) {
foreach($cart["products"] as $cart_item) {
if ($cart_item["productid"] == $id) {
$in_cart += $cart_item["amount"];
}
}
}
$login_condition = "";
if (!$single_mode)
$login_condition = (($login != "" and $login_type == "P") ? "AND $sql_tbl[products].provider='$login'" : "");
$add_fields = "";
$join = "";
if(!empty($active_modules['Product_Options'])) {
$add_fields .= ", IF($sql_tbl[variants].variantid IS NOT NULL,'Y','') as is_variant";
$join .= "LEFT JOIN $sql_tbl[variants] ON $sql_tbl[variants].productid = $sql_tbl[products].productid";
}
$product = func_query_first("SELECT $sql_tbl[products].*, $sql_tbl[products].avail-$in_cart AS avail, min($sql_tbl[pricing].price) AS price $add_fields FROM $sql_tbl[products], $sql_tbl[pricing] $join WHERE $sql_tbl[products].productid='$id' ".$login_condition." AND $sql_tbl[pricing].productid=$sql_tbl[products].productid AND $sql_tbl[pricing].quantity=1 AND $sql_tbl[pricing].variantid = 0 AND ($sql_tbl[pricing].membership = '$membership' OR $sql_tbl[pricing].membership = '') GROUP BY $sql_tbl[products].productid");
$categoryid = func_query_first_cell("SELECT $sql_tbl[products_categories].categoryid FROM $sql_tbl[products_categories] USE INDEX (cpm), $sql_tbl[categories] WHERE $sql_tbl[products_categories].categoryid=$sql_tbl[categories].categoryid $membeship_condition AND $sql_tbl[products_categories].productid='$id' AND $sql_tbl[products_categories].main='Y'");
#
# Error handling
#
if (!$product || !$categoryid) {
if ($redirect_if_error)
func_header_location("error_message.php?access_denied&id=33");
else
return false;
}
$product["categoryid"] = $categoryid;
if ($current_area == "C" || $current_area == "B") {
#
# Check if product is not available for sale
#
global $pconf;
if ($product["forsale"] == "B" && empty($pconf) && is_array(@$cart["products"])) {
foreach ($cart["products"] as $k=>$v) {
if ($v["productid"] == $product["productid"]) {
$pconf = $product["productid"];
break;
}
}
}
$product['taxed_price'] = $product['price'];
if (!$always_select && ($product["forsale"] == "N" || ($product["forsale"] == "B" && empty($pconf)))) {
if ($redirect_if_error)
func_header_location("error_message.php?product_disabled");
else
return false;
}
if ($current_area == "C") {
#
# Calculate taxes and price including taxes
#
global $login;
$product["taxes"] = func_get_product_taxes($product, $login);
}
}
# Add product features
if (!empty($active_modules['Feature_Comparison'])) {
$product['fclassid'] = func_query_first_cell("SELECT fclassid FROM $sql_tbl[product_features] WHERE productid = '$product[productid]'");
$product['features'] = func_get_product_features($product['productid']);
$product['is_clist'] = func_check_comparison($product['productid']);
}
$int_res = func_query_first ("SELECT * FROM $sql_tbl[products_lng] WHERE code='$store_language' AND productid='$id'");
if ($current_area == "C" and !empty($int_res)) {
if ($int_res["product"])
$product["product"] = stripslashes($int_res["product"]);
if ($int_res["descr"])
$product["descr"] = stripslashes($int_res["descr"]);
if ($int_res["full_descr"])
$product["fulldescr"] = stripslashes($int_res["full_descr"]);
}
$product["producttitle"] = "$product[product] #$product[productid]";
if ($current_area == "C" || $current_area == "B") {
if ($product["descr"] == strip_tags($product["descr"]))
$product["descr"] = str_replace("\n", "
", $product["descr"]);
if ($product["fulldescr"] == strip_tags($product["fulldescr"]))
$product["fulldescr"] = str_replace("\n", "
", $product["fulldescr"]);
}
#
# Get thumbnail's URL (uses only if images stored in FS)
#
$product["tmbn_url"] = func_get_thumbnail_url($product["productid"]);
#
# Add Manufacturer information
#
if (!empty($active_modules["Manufacturers"]))
$product['manufacturer'] = func_query_first_cell("SELECT manufacturer FROM $sql_tbl[manufacturers] WHERE manufacturerid = '$product[manufacturerid]'");
return $product;
}
#
# Get delivery options by product ID
#
function func_select_product_delivery($id) {
global $sql_tbl;
return func_query("select $sql_tbl[shipping].*, count($sql_tbl[delivery].productid) as avail from $sql_tbl[shipping] left join $sql_tbl[delivery] on $sql_tbl[delivery].shippingid=$sql_tbl[shipping].shippingid and $sql_tbl[delivery].productid='$id' where $sql_tbl[shipping].active='Y' group by shippingid");
}
#
# Return number of available products
#
function insert_productsonline() {
global $sql_tbl;
return func_query_first_cell("SELECT COUNT(*) FROM $sql_tbl[products] WHERE forsale!='N'");
}
#
# Return number of available items
#
function insert_itemsonline() {
global $sql_tbl;
return func_query_first_cell("SELECT SUM(avail) FROM $sql_tbl[products] WHERE forsale!='N'");
}
#
# Return string of search
#
function insert_stripslashes() {
global $substring;
$substring=trim($substring);
while(strstr($substring,"\\")) {
$substring=stripslashes($substring);
}
return $substring;
}
#
# Generate products array in $cart
#
function func_products_in_cart($cart, $membership) {
if (empty($cart) or empty($cart["products"])) return array();
return func_products_from_scratch($cart["products"], $membership, false);
}
#
# Generate products array from scratch
#
function func_products_from_scratch($scratch_products, $membership, $persistent_products) {
global $active_modules, $sql_tbl, $config, $xcart_dir;
global $current_area, $store_language;
$products = array();
if ($scratch_products)
foreach($scratch_products as $product_data) {
$productid = $product_data["productid"];
$amount = $product_data["amount"];
if (!is_numeric($amount))
$amount = 0;
$options = $product_data["options"];
$product_options = false;
if(!empty($active_modules['Product_Options']) && $options)
list($variant, $product_options) = func_get_product_options_data($productid, $options, $membership);
$avail_condition = "";
if ($config["General"]["unlimited_products"]=="N" && !$persistent_products && empty($variant))
$avail_condition = "($sql_tbl[products].avail>=".doubleval($amount)." OR $sql_tbl[products].product_type='C') AND ";
if ($current_area == 'C' && empty($active_modules['Product_Configurator'])) {
$avail_condition .= " $sql_tbl[products].product_type <> 'C' AND $sql_tbl[products].product_type <> 'B' AND ";
}
$products_array = func_query_first("select $sql_tbl[products].*, min($sql_tbl[pricing].price) as price from $sql_tbl[products], $sql_tbl[pricing] where $sql_tbl[pricing].productid=$sql_tbl[products].productid and $sql_tbl[products].productid='$productid' and $avail_condition $sql_tbl[pricing].quantity<=$amount and ($sql_tbl[pricing].membership='$membership' or $sql_tbl[pricing].membership='') AND $sql_tbl[pricing].variantid = 0 group by $sql_tbl[products].productid order by $sql_tbl[pricing].quantity desc");
if ($products_array) {
$products_array = func_array_merge($product_data, $products_array);
if(!empty($active_modules['Product_Options']) && $options) {
if(!empty($variant))
$products_array = func_array_merge($products_array, $variant);
if($config["General"]["unlimited_products"]=="N" && !$persistent_products && $products_array['avail'] < $amount && $products_array['product_type'] == '')
continue;
if($product_options === false)
unset($product_options);
else {
if(empty($variant['price']))
$variant['price'] = $products_array['price'];
$products_array['price'] = $variant['price'];
$products_array["options_surcharge"] = 0;
if($product_options)
foreach($product_options as $o)
$products_array["options_surcharge"] += ($o['modifier_type'] == '%'?($products_array['price']*$o['price_modifier']/100):$o['price_modifier']);
}
}
#
# Get thumbnail's URL (uses only if images stored in FS)
#
$products_array["tmbn_url"] = func_get_thumbnail_url($products_array["productid"]);
#
# If priduct's price is 0 then use customer-defined price
#
if ($products_array["price"]==0 && empty($products_array["slotid"])) {
$free_price = true;
$products_array["price"]=price_format($product_data["free_price"]?$product_data["free_price"]:0);
}
else
$free_price = false;
if ($products_array["product_type"] == "C")
$products_array["price"] = $products_array["options_surcharge"];
else
$products_array["price"] += $products_array["options_surcharge"];
if ($current_area == "C" && $products_array["product_type"] != "C") {
#
# Calculate taxes and price including taxes
#
global $login;
$products_array["taxes"] = func_get_product_taxes($products_array, $login);
}
if (!empty($active_modules["Product_Configurator"])) {
include $xcart_dir."/modules/Product_Configurator/pconf_customer_price_modifier.php";
}
$products_array["total"]=price_format($amount*$products_array["price"]);
$products_array["product_options"]=$product_options;
$products_array["options"]=$options;
$products_array["amount"]=$amount;
$int_res = func_query_first ("SELECT * FROM $sql_tbl[products_lng] WHERE code='$store_language' AND productid=$productid");
if (!empty($int_res["product"]))
$products_array["product"] = stripslashes($int_res["product"]);
if (!empty($int_res["descr"]))
$products_array["descr"] = stripslashes($int_res["descr"]);
if (!empty($int_res["full_descr"]))
$products_array["fulldescr"] = stripslashes($int_res["full_descr"]);
if ($products_array["descr"] == strip_tags($products_array["descr"]))
$products_array["descr"] = str_replace("\n", "
", $products_array["descr"]);
if ($products_array["fulldescr"] == strip_tags($products_array["fulldescr"]))
$products_array["fulldescr"] = str_replace("\n", "
", $products_array["fulldescr"]);
$products[] = $products_array;
}
}
return $products;
}
#
# Calculate total weight of all products in cart
#
function func_weight_products($products) {
foreach($products as $product)
$total_weight+=$product["weight"]*$product["amount"];
if (!$total_weight)
$total_weight = 1;
return $total_weight;
}
function func_weight_shipping_products ($products) {
global $active_modules, $config;
$total_weight = 0;
foreach ($products as $product) {
if ($product["free_shipping"] == "Y" or ($active_modules["Egoods"] and $product["distribution"] != "") or ($config["Shipping"]["replace_shipping_with_freight"] == "Y" and $product["shipping_freight"] > 0))
continue;
elseif (@$product["deleted"])
continue;
else
$total_weight += $product["weight"] * $product["amount"];
}
return $total_weight;
}
#
# This function increments product rating
#
function func_increment_rating($productid) {
global $sql_tbl;
db_query("update $sql_tbl[products] set rating=rating+1 where productid='$productid'");
}
#
# This function creates array with order data
#
function func_select_order($orderid) {
global $sql_tbl, $config, $merchant_password, $current_area, $active_modules;
$o_date = "date+'".$config["General"]["timezone_offset"]."' as date";
$order = func_query_first("select *, $o_date from $sql_tbl[orders] where $sql_tbl[orders].orderid='$orderid'");
if (empty($order))
return false;
$order["discounted_subtotal"] = $order["subtotal"] - $order["discount"] - $order["coupon_discount"];
if ($order["giftcert_ids"]) {
$order["applied_giftcerts"] = split("\*", $order["giftcert_ids"]);
if ($order["applied_giftcerts"]) {
$tmp = array();
foreach($order["applied_giftcerts"] as $k=>$v) {
if ($v) {
list($arr["giftcert_id"], $arr["giftcert_cost"]) = split(":", $v);
$tmp[] = $arr;
}
}
$order["applied_giftcerts"] = $tmp;
}
}
$shipping = func_query_first("select shipping from $sql_tbl[shipping] where shippingid='".$order["shippingid"]."'");
$order["shipping"] = $shipping["shipping"];
$order["details"]=text_decrypt($order["details"]);
if($order["details"] === false) {
$order["details"] = func_get_langvar_by_name("txt_this_data_encrypted");
}
$order["details"]=stripslashes($order["details"]);
$order["notes"]=stripslashes($order["notes"]);
$order["extra"] = @unserialize($order["extra"]);
$extras = func_query("SELECT khash, value FROM $sql_tbl[order_extras] WHERE orderid = '$orderid'");
if(!empty($extras)) {
foreach($extras as $v)
$order["extra"][$v["khash"]] = $v["value"];
}
if ($current_area != "C" && !empty($active_modules["Stop_List"]))
if(func_ip_exist_slist($order["extra"]["ip"]))
$order["blocked"] = "Y";
if ($order["taxes_applied"])
$order["applied_taxes"] = unserialize($order["taxes_applied"]);
if(preg_match("/NetBanx Reference: ([\w\d]+)/iSs", $order["details"], $preg)) {
$order['netbanx_reference'] = $preg[1];
}
#
# Assign the display_* vars for displaying in the invoice
#
if (@$order["extra"]["tax_info"]["display_taxed_order_totals"] == "Y" && !empty($order["extra"]["tax_info"]["taxed_subtotal"]))
$order["display_subtotal"] = $order["extra"]["tax_info"]["taxed_subtotal"];
else
$order["display_subtotal"] = $order["subtotal"];
if (@$order["extra"]["tax_info"]["display_taxed_order_totals"] == "Y" && !empty($order["extra"]["tax_info"]["taxed_discounted_subtotal"]))
$order["display_discounted_subtotal"] = $order["extra"]["tax_info"]["taxed_discounted_subtotal"];
else
$order["display_discounted_subtotal"] = $order["discounted_subtotal"];
if (@$order["extra"]["tax_info"]["display_taxed_order_totals"] == "Y" && !empty($order["extra"]["tax_info"]["taxed_shipping"]))
$order["display_shipping_cost"] = $order["extra"]["tax_info"]["taxed_shipping"];
else
$order["display_shipping_cost"] = $order["shipping_cost"];
list($order["b_address"], $order["b_address_2"]) = explode("\n", $order["b_address"]);
$order["b_statename"] = func_get_state($order["b_state"], $order["b_country"]);
$order["b_countryname"] = func_get_country($order["b_country"]);
list($order["s_address"], $order["s_address_2"]) = explode("\n", $order["s_address"]);
$order["s_statename"] = func_get_state($order["s_state"], $order["s_country"]);
$order["s_countryname"] = func_get_country($order["s_country"]);
if ($config["General"]["use_counties"] == "Y") {
$order["b_countyname"] = func_get_county($order["b_county"]);
$order["s_countyname"] = func_get_county($order["s_county"]);
}
return $order;
}
#
# This function returns data about specified order ($orderid)
#
function func_order_data($orderid) {
global $sql_tbl, $config, $smarty, $active_modules, $current_area, $xcart_dir;
$gc_add_date = "add_date+'".$config["General"]["timezone_offset"]."' as add_date";
$o_date = "date+'".$config["General"]["timezone_offset"]."' as date";
if (!empty($active_modules["Egoods"]))
$products = func_query("SELECT $sql_tbl[products].*, $gc_add_date, $sql_tbl[order_details].*, $sql_tbl[download_keys].download_key, $sql_tbl[download_keys].expires FROM $sql_tbl[order_details], $sql_tbl[products] LEFT JOIN $sql_tbl[download_keys] ON $sql_tbl[order_details].itemid=$sql_tbl[download_keys].itemid AND $sql_tbl[download_keys].productid=$sql_tbl[order_details].productid WHERE $sql_tbl[order_details].orderid='$orderid' AND $sql_tbl[order_details].productid=$sql_tbl[products].productid");
else
$products = func_query("SELECT $sql_tbl[products].*, $gc_add_date, $sql_tbl[order_details].* FROM $sql_tbl[order_details], $sql_tbl[products] WHERE $sql_tbl[order_details].orderid='$orderid' AND $sql_tbl[order_details].productid=$sql_tbl[products].productid");
if (!is_array($products)) $products = array();
#
# If products are not present in products table, but they are present in
# order_details, then create fake $products from order_details data
#
$tmp = func_query("select productid from $sql_tbl[order_details] where orderid='$orderid'");
if (is_array($tmp) && count($products) != count($tmp)) {
$missing = array();
foreach ($tmp as $v) $missing[$v["productid"]] = 1;
foreach ($products as $v) unset($missing[$v["productid"]]);
$products_2 = func_query("select $sql_tbl[order_details].*, 'PRODUCT (deleted from database)' as product from $sql_tbl[order_details] where $sql_tbl[order_details].orderid='$orderid' and $sql_tbl[order_details].productid in ('".join("','",array_keys($missing))."')");
if (is_array($products_2))
$products = func_array_merge($products, $products_2);
}
$giftcerts = func_query("select *, $gc_add_date from $sql_tbl[giftcerts] where orderid='$orderid'");
$order = func_select_order($orderid);
if (!$order) {
func_header_location("error_message.php?page_not_found");
}
if($current_area == "A" || ($current_area == "P" && !empty($active_modules['Simple_Mode']))) {
if(strpos($order['details'], "Card number:") !== false && file_exists($xcart_dir."/payment/cmpi.php"))
$order['is_cc_payment'] = "Y";
}
if(func_query_first_cell("SELECT COUNT(*) FROM $sql_tbl[order_details], $sql_tbl[download_keys] WHERE $sql_tbl[order_details].orderid = '$orderid' AND $sql_tbl[order_details].itemid = $sql_tbl[download_keys].itemid"))
$order['is_egood'] = 'Y';
elseif(func_query_first_cell("SELECT COUNT(*) FROM $sql_tbl[order_details], $sql_tbl[products] WHERE $sql_tbl[order_details].orderid = '$orderid' AND $sql_tbl[order_details].productid = $sql_tbl[products].productid AND $sql_tbl[products].distribution != ''"))
$order['is_egood'] = 'E';
$userinfo = func_query_first("select *, $o_date from $sql_tbl[orders] where orderid='$orderid'");
if(isset($order["extra"]['additional_fields'])) {
$userinfo['additional_fields'] = $order["extra"]['additional_fields'];
}
$userinfo = func_array_merge(func_userinfo($userinfo["login"], "C"), $userinfo);
list($userinfo["b_address"], $userinfo["b_address_2"]) = split("[\n\r]+", $userinfo["b_address"]);
list($userinfo["s_address"], $userinfo["s_address_2"]) = split("[\n\r]+", $userinfo["s_address"]);
$userinfo["s_countryname"] = $userinfo["s_country_text"] = func_get_country($userinfo["s_country"]);
$userinfo["s_statename"] = $userinfo["s_state_text"] = func_get_state($userinfo["s_state"], $userinfo["s_country"]);
$userinfo["b_statename"] = func_get_state($userinfo["b_state"], $userinfo["b_country"]);
$userinfo["b_countryname"] = func_get_country($userinfo["b_country"]);
if ($config["General"]["use_counties"] == "Y") {
$userinfo["b_countyname"] = func_get_county($userinfo["b_county"]);
$userinfo["s_countyname"] = func_get_county($userinfo["s_county"]);
}
if (!$products)
$products = array ();
if (preg_match("/(free_ship|percent|absolute)(``)(.+)/", $order["coupon"], $found)) {
$order["coupon"] = $found[3];
$order["coupon_type"] = $found[1];
}
$order["extra"]["tax_info"]["product_tax_name"] = "";
$_product_taxes = array();
foreach ($products as $k=>$v) {
$v['product_options_txt'] = $v['product_options'];
if ($v["extra_data"]) {
$v["extra_data"] = unserialize($v["extra_data"]);
if (is_array(@$v["extra_data"]["display"])) {
foreach ($v["extra_data"]["display"] as $i=>$j) {
$v["display_".$i] = $j;
}
}
if (is_array($v["extra_data"]["taxes"])) {
foreach ($v["extra_data"]["taxes"] as $i=>$j) {
if ($j["tax_value"] > 0)
$_product_taxes[$i] = $j["tax_display_name"];
}
}
}
$v["ordered_price"] = $v["price"];
$v["price_deducted_tax"] = "Y";
#
# Get the original price (current price in the database)
#
$v["original_price"] = func_query_first_cell("SELECT MIN(price) FROM $sql_tbl[pricing] WHERE productid='$v[productid]' AND (membership='' OR membership='$userinfo[membership]') AND quantity <='$v[amount]' AND $sql_tbl[pricing].variantid = 0");
if (!empty($active_modules['Product_Options']) && $v['extra_data']['product_options']) {
list($variant, $product_options) = func_get_product_options_data($v['productid'], $v['extra_data']['product_options'],$userinfo['membership']);
if($product_options === false)
unset($product_options);
else {
if(empty($variant['price']))
$variant['price'] = $v["original_price"];
$v["original_price"] = $variant['price'];
unset($variant['price']);
if($product_options)
foreach($product_options as $o)
$v["original_price"] += ($o['modifier_type'] == '%'?($v["original_price"]*$o['price_modifier']/100):$o['price_modifier']);
$v['product_options'] = $product_options;
if($v['product_options_txt']) {
$flag_txt = false;
foreach($v['product_options'] as $opt) {
$flag_txt = preg_match("/".preg_quote($opt['class'],"/").": ".preg_quote($opt['option_name'], "/")."/Sm", $v['product_options_txt']);
}
if(!$flag_txt)
$v['force_product_options_txt'] = true;
}
if(!empty($variant)) {
$v = func_array_merge($v, $variant);
}
}
}
$products[$k] = $v;
}
if (count($_product_taxes) > 0) {
$order["extra"]["tax_info"]["display_cart_products_tax_rates"] = "Y";
if (count($_product_taxes) == 1)
$order["extra"]["tax_info"]["product_tax_name"] = array_pop($_product_taxes);
}
else
$order["extra"]["tax_info"]["display_cart_products_tax_rates"] = "N";
if ($order["coupon_type"] == "free_ship") {
$order["shipping_cost"] = $order["coupon_discount"];
$order["discounted_subtotal"] += $order["coupon_discount"];
}
return(array("order"=>$order,"products"=>$products,"userinfo"=>$userinfo, "giftcerts"=>$giftcerts));
}
#
# Decrease number of products in stock and increase product rating
#
function func_decrease_quantity($products) {
foreach ($products as $product) {
func_increment_rating($product["productid"]);
}
func_update_quantity($products, false);
}
#
# This function creates order entry in orders table
#
function func_place_order($payment_method, $order_status, $order_details, $extra = array(), $extras = array()) {
global $cart, $userinfo, $discount_coupon, $mail_smarty, $config, $active_modules, $single_mode, $partner, $adv_campaignid, $partner_clickid;
global $sql_tbl, $to_customer;
global $wlid;
global $xcart_dir, $REMOTE_ADDR, $PROXY_IP, $CLIENT_IP, $add_to_cart_time;
global $arb_account_used, $arb_account;
$mintime = 10;
#
# Lock place order process
#
$LOCK = func_lock("place_order");
$check_order = func_query_first("SELECT orderid FROM $sql_tbl[orders] WHERE login='".addslashes($userinfo["login"])."' AND '".time()."'-date<'$mintime'");
if ($check_order) {
func_unlock($LOCK);
return false;
}
if (($order_status != "I") && ($order_status != "Q")) {
func_unlock($LOCK);
return false;
}
$userinfo["email"] = addslashes($userinfo["email"]);
$orderids = array ();
#
# REMOTE_ADDR and PROXY_IP
#
$extras['ip'] = $CLIENT_IP;
$extras['proxy_ip'] = $PROXY_IP;
if($add_to_cart_time > 0)
$extras['add_to_cart_time'] = time() - $add_to_cart_time;
$products = func_products_in_cart($cart, $userinfo["membership"]);
func_decrease_quantity($products);
$giftcert_discount = $cart["giftcert_discount"];
if ($cart["applied_giftcerts"]) {
foreach($cart["applied_giftcerts"] as $k=>$v) {
$giftcert_str = join("*", array(@$giftcert_str, "$v[giftcert_id]:$v[giftcert_cost]"));
db_query("UPDATE $sql_tbl[giftcerts] SET status='U' WHERE gcid='$v[giftcert_id]'");
}
}
$giftcert_id = @$cart["giftcert_id"];
$extra = "";
if (!empty($active_modules["Anti_Fraud"]))
include $xcart_dir."/modules/Anti_Fraud/anti_fraud.php";
#
# Store Airborne account information into $order_details
#
x_session_register("arb_account_used");
x_session_register("arb_account");
if ($arb_account_used) {
$_code = func_query_first_cell("SELECT code FROM $sql_tbl[shipping] WHERE shippingid='$cart[shippingid]'");
if ($_code == "ARB")
$order_details = func_get_langvar_by_name("lbl_arb_account").": ".$arb_account."\n".$order_details;
}
$extra['additional_fields'] = $userinfo['additional_fields'];
foreach ($cart["orders"] as $current_order) {
$_extra = $extra;
$_extra["tax_info"] = array (
"display_taxed_order_totals" => $config["Taxes"]["display_taxed_order_totals"],
"display_cart_products_tax_rates" => $config["Taxes"]["display_cart_products_tax_rates"] == "Y",
"taxed_subtotal" => $current_order["display_subtotal"],
"taxed_discounted_subtotal" => $current_order["display_discounted_subtotal"],
"taxed_shipping" => $current_order["display_shipping_cost"]
);
if (!empty($active_modules["Special_Offers"]))
include $xcart_dir."/modules/Special_Offers/place_order_extra.php";
if (!$single_mode) {
$giftcert_discount = $current_order["giftcert_discount"];
$giftcert_str = "";
if ($current_order["applied_giftcerts"]) {
foreach($current_order["applied_giftcerts"] as $k=>$v)
$giftcert_str = join("*", array($giftcert_str, "$v[giftcert_id]:$v[giftcert_cost]"));
}
}
$taxes_applied = addslashes(serialize($current_order["taxes"]));
$discount_coupon = $current_order["coupon"];
if (!empty($current_order["coupon"])) {
$current_order["coupon"] = func_query_first_cell("SELECT coupon_type FROM $sql_tbl[discount_coupons] WHERE coupon='".addslashes($current_order["coupon"])."'")."``".$current_order["coupon"];
}
$save_info = $userinfo;
$userinfo["b_address"] .= "\n".$userinfo["b_address_2"];
$userinfo["s_address"] .= "\n".$userinfo["s_address_2"];
#
# Insert into orders
#
db_query("INSERT INTO $sql_tbl[orders] (login, membership, total, giftcert_discount, giftcert_ids, subtotal, shipping_cost, shippingid, tax, taxes_applied, discount, coupon, coupon_discount, date, status, payment_method, flag, details, title, firstname, lastname, company, b_title, b_firstname, b_lastname, b_address, b_city, b_county, b_state, b_country, b_zipcode, s_title, s_firstname, s_lastname, s_address, s_city, s_county, s_state, s_country, s_zipcode, phone, fax, email, url, clickid, extra) VALUES ('".addslashes($userinfo["login"])."', '".addslashes($userinfo["membership"])."', '$current_order[total_cost]', '$giftcert_discount', '".@$giftcert_str."', '$current_order[subtotal]','$current_order[shipping_cost]', '$cart[shippingid]', '$current_order[tax_cost]', '$taxes_applied', '$current_order[discount]', '".addslashes(@$current_order["coupon"])."', '$current_order[coupon_discount]', '".time()."', '$order_status', '".addslashes($payment_method)."', 'N', '".addslashes(text_crypt($order_details))."', '".addslashes($userinfo["title"])."', '".addslashes($userinfo["firstname"])."', '".addslashes($userinfo["lastname"])."', '".addslashes($userinfo["company"])."', '".addslashes($userinfo["b_title"])."', '".addslashes($userinfo["b_firstname"])."', '".addslashes($userinfo["b_lastname"])."', '".addslashes($userinfo["b_address"])."', '".addslashes($userinfo["b_city"])."', '".addslashes(@$userinfo["b_county"])."', '".addslashes($userinfo["b_state"])."', '".addslashes($userinfo["b_country"])."', '".addslashes(strtoupper($userinfo["b_zipcode"]))."', '".addslashes($userinfo["s_title"])."', '".addslashes($userinfo["s_firstname"])."', '".addslashes($userinfo["s_lastname"])."', '".addslashes($userinfo["s_address"])."', '".addslashes($userinfo["s_city"])."', '".addslashes(@$userinfo["s_county"])."', '".addslashes($userinfo["s_state"])."', '".addslashes($userinfo["s_country"])."', '".addslashes(strtoupper($userinfo["s_zipcode"]))."', '".addslashes($userinfo["phone"])."', '".addslashes($userinfo["fax"])."', '$userinfo[email]', '".addslashes($userinfo["url"])."', '$partner_clickid', '".addslashes(serialize($_extra))."')");
$orderid=db_insert_id();
if(!empty($extras)) {
foreach($extras as $k => $v) {
if(!empty($v))
db_query("INSERT INTO $sql_tbl[order_extras] (orderid, khash, value) VALUES ('$orderid', '".addslashes($k)."', '".addslashes($v)."')");
}
}
$userinfo = $save_info;
$orderids[] = $orderid;
$order=func_select_order($orderid);
#
# Insert into order details
#
foreach($products as $pk => $product) {
if (($single_mode) or ($product["provider"] == $current_order["provider"])) {
$product["price"] = price_format($product["price"]);
$product["extra_data"]["product_options"] = $product["options"];
$product["extra_data"]["taxes"] = $product["taxes"];
$product["extra_data"]["display"]["price"] = price_format($product["display_price"]);
$product["extra_data"]["display"]["discounted_price"] = price_format($product["display_discounted_price"]);
$product["extra_data"]["display"]["subtotal"] = price_format($product["display_subtotal"]);
if(!empty($active_modules['Product_Options']))
$product["product_options"] = func_serialize_options($product["options"]);
db_query("INSERT INTO $sql_tbl[order_details] (orderid, productid, product_options, amount, price, provider, extra_data, productcode) VALUES ('$orderid','$product[productid]','".addslashes($product["product_options"])."','$product[amount]','$product[price]','".addslashes($product["provider"])."','".addslashes(serialize($product["extra_data"]))."','".addslashes($product['productcode'])."')");
$products[$pk]['itemid'] = db_insert_id();
#
# Insert into subscription_customers table (for subscription products)
#
if (!empty($active_modules["Subscriptions"]))
include $xcart_dir."/modules/Subscriptions/subscriptions_cust.php";
#
# Check if this product is in Wish list
#
if (!empty($active_modules["Wishlist"]))
include $xcart_dir."/modules/Wishlist/place_order.php";
if (!empty($active_modules["Recommended_Products"])) {
$rec_counter = func_query_first_cell("SELECT COUNT(*) FROM $sql_tbl[stats_customers_products] WHERE productid='$product[productid]' AND login='".addslashes($userinfo["login"])."'");
if (!empty($rec_counter))
db_query("UPDATE $sql_tbl[stats_customers_products] SET counter='".($rec_counter+1)."' WHERE productid='$product[productid]' AND login='".addslashes($userinfo["login"])."'");
else
db_query("INSERT INTO $sql_tbl[stats_customers_products] (productid, login, counter) VALUES ('$product[productid]', '".addslashes($userinfo["login"])."', '1')");
}
}
}
#
# Partner commission
#
if ($partner)
include $xcart_dir."/include/partner_commission.php";
#
# Save link order -> advertising campaign
#
if ($adv_campaignid)
include $xcart_dir."/include/adv_campaign_commission.php";
if ((($single_mode) or (empty($current_order["provider"]))) and (!empty($cart["giftcerts"]))) {
foreach($cart["giftcerts"] as $giftcert) {
$gcid = strtoupper(md5(uniqid(rand())));
#
# status == Pending!
#
db_query("insert into $sql_tbl[giftcerts] (gcid, orderid, purchaser, recipient, send_via, recipient_email, recipient_firstname, recipient_lastname, recipient_address, recipient_city, recipient_state, recipient_country, recipient_zipcode, recipient_phone, message, amount, debit, status, add_date) values ('$gcid', '$orderid','".addslashes($giftcert["purchaser"])."','".addslashes($giftcert["recipient"])."','$giftcert[send_via]','".@$giftcert["recipient_email"]."','".addslashes(@$giftcert["recipient_firstname"])."','".addslashes(@$giftcert["recipient_lastname"])."','".addslashes(@$giftcert["recipient_address"])."','".addslashes(@$giftcert["recipient_city"])."','".@$giftcert["recipient_state"]."','".@$giftcert["recipient_country"]."','".@$giftcert["recipient_zipcode"]."','".@$giftcert["recipient_phone"]."','".addslashes($giftcert["message"])."','$giftcert[amount]','$giftcert[amount]','P','".time()."')");
#
# Check if this giftcertificate is in Wish list
#
if (!empty($active_modules["Wishlist"]))
include $xcart_dir."/modules/Wishlist/place_order.php";
}
}
#
# Mark discount coupons used
#
if ($discount_coupon) {
db_query("update $sql_tbl[discount_coupons] set times_used=times_used+1 where coupon='$discount_coupon'");
db_query("update $sql_tbl[discount_coupons] set status='U' where coupon='$discount_coupon' and times_used=times");
$discount_coupon="";
}
#
# Mail template processing
#
$admin_notify = (($order_status == "Q") || ($order_status == "I" && $config["Email_Note"]["enable_init_order_notif"] == "Y"));
$customer_notify = (($order_status == "Q") || ($order_status == "I" && $config["Email_Note"]["enable_init_order_notif_customer"] == "Y"));
$order_data = func_order_data($orderid);
$mail_smarty->assign("products",$order_data["products"]);
$mail_smarty->assign("giftcerts",$order_data["giftcerts"]);
$mail_smarty->assign("order",$order_data["order"]);
$mail_smarty->assign("userinfo",$order_data["userinfo"]);
$prefix = ($order_status=="I"?"init_":"");
if ($customer_notify) {
#
# Notify customer by email
#
$to_customer = ($userinfo['language']?$userinfo['language']:$config['default_customer_language']);
$mail_smarty->assign("products", func_translate_products($order_data["products"], $to_customer));
func_send_mail($userinfo["email"], "mail/".$prefix."order_customer_subj.tpl", "mail/".$prefix."order_customer.tpl", $config["Company"]["orders_department"], false);
}
$mail_smarty->assign("products",$order_data["products"]);
if ($admin_notify) {
#
# Notify orders department by email
#
$mail_smarty->assign("show_order_details", "Y");
func_send_mail($config["Company"]["orders_department"], "mail/".$prefix."order_notification_subj.tpl", "mail/order_notification_admin.tpl", $userinfo["email"], true, true);
$mail_smarty->assign("show_order_details", "");
#
# Notify provider (or providers) by email
#
if ((!$single_mode) and ($current_order["provider"])) {
$pr_result = func_query_first ("SELECT email, language FROM $sql_tbl[customers] WHERE login='$current_order[provider]'");
$prov_email = $pr_result ["email"];
if ($prov_email != $config["Company"]["orders_department"]) {
$to_customer = $pr_result['language'];
if(empty($to_customer))
$to_customer = $config['default_admin_language'];
func_send_mail($prov_email, "mail/".$prefix."order_notification_subj.tpl", "mail/order_notification.tpl", $userinfo["email"], false);
}
}
elseif ($config["Email_Note"]["send_notifications_to_provider"] == "Y") {
$providers = array();
foreach($products as $product) {
$pr_result = func_query_first("select email, language from $sql_tbl[customers] where login='$product[provider]'");
if ($pr_result["email"])
$providers[$product['provider']] = $pr_result;
}
if ($providers) {
foreach($providers as $prov_data)
if ($prov_data['email'] != $config["Company"]["orders_department"]) {
$to_customer = $prov_data['language'];
if(empty($to_customer))
$to_customer = $config['default_admin_language'];
func_send_mail($prov_data['email'], "mail/".$prefix."order_notification_subj.tpl", "mail/order_notification.tpl", $userinfo["email"], false);
}
}
}
}
}
#
# Send notifications to orders department and providers when product amount in stock is low
#
if ($config["General"]["unlimited_products"]!="Y")
foreach($order_data["products"] as $product) {
if (!empty($product["distribution"]) && $active_modules["Egoods"])
continue;
if ($product['product_type'] == 'C' && !empty($active_modules['Product_Configurator']))
continue;
if($active_modules['Product_Options'] && $product['extra_data']['product_options']) {
$avail_now = func_get_options_amount($product['extra_data']['product_options'], $product['productid']);
} else {
$avail_now = func_query_first_cell("SELECT avail FROM $sql_tbl[products] WHERE productid=".$product["productid"]);
}
if ($product['low_avail_limit'] >= $avail_now && $config['Email_Note']['eml_lowlimit_warning'] == 'Y') {
#
# Mail template processing
#
$product['avail'] = $avail_now;
$mail_smarty->assign("product", $product);
func_send_mail($config["Company"]["orders_department"], "mail/lowlimit_warning_notification_subj.tpl", "mail/lowlimit_warning_notification_admin.tpl", $config["Company"]["orders_department"], true);
$pr_result = func_query_first ("SELECT email, language FROM $sql_tbl[customers] WHERE login='".$product["provider"]."'");
if((!$single_mode) and ($pr_result["email"]!=$config["Company"]["orders_department"]) && $config['Email_Note']['eml_lowlimit_warning_provider'] == 'Y') {
$to_customer = $pr_result['language'];
if(empty($to_customer))
$to_customer = $config['default_admin_language'];
func_send_mail($pr_result["email"], "mail/lowlimit_warning_notification_subj.tpl", "mail/lowlimit_warning_notification_admin.tpl", $config["Company"]["orders_department"], false);
}
}
}
#
# Release previously created lock
#
func_unlock($LOCK);
return $orderids;
}
#
# This function change order status in orders table
#
function func_change_order_status($orderids, $status, $advinfo="")
{
global $config, $mail_smarty, $active_modules, $current_area;
global $sql_tbl;
global $session_failed_transaction;
if(!is_array($orderids))$orderids = array($orderids);
foreach($orderids as $orderid) {
$order_data = func_order_data($orderid);
$order=$order_data["order"];
if($advinfo)
$info = addslashes(text_crypt($order["details"]."\n--- Advanced info ---\n".$advinfo));
db_query("update $sql_tbl[orders] set status='$status'".(($advinfo)? ", details='".$info."'" : "")." where orderid='$orderid'");
if($status == "P" && $order["status"] != "P") {
func_process_order($orderid);
if($order["status"] == 'I' && !empty($active_modules["Anti_Fraud"]) && $config['Modules']['anti_fraud_license'] && ($current_area != 'A' && $current_area != 'P')) {
$total_trust_score = $order['Anti_Fraud']['total_trust_score'];
$available_request = $order['Anti_Fraud']['available_request'];
$used_request = $order['Anti_Fraud']['used_request'];
if($order['Anti_Fraud']['total_trust_score'] > $config['Modules']['anti_fraud_limit'] || ($available_request <= $used_request && $available_request > 0)) {
db_query("UPDATE $sql_tbl[orders] set status='Q' WHERE orderid='$orderid'");
}
}
}
elseif($status == "D" && $order["status"] != "D" && $order["status"] != "F") {
func_decline_order($orderid, $status);
}
elseif($status == "F" && $order["status"] != "F" && $order["status"] != "D") {
func_update_quantity($order_data["products"]);
if($current_area == 'C')
$session_failed_transaction++;
}
elseif ($status == "C" && $order["status"] != "C") {
func_complete_order($orderid);
}
#
# Decrease quantity in stock when "declined" or "failed" order is became "completed", "processed" or "queued"
#
if ($status != $order["status"] && strpos("DF",$order["status"])!==false && strpos("CPQ",$status)!==false) {
func_update_quantity($order_data["products"],false);
}
}
}
#
# This function performs activities needed when order is processed
#
function func_process_order($orderids) {
global $config, $mail_smarty, $active_modules;
global $sql_tbl, $partner, $to_customer;
global $single_mode;
global $xcart_dir;
if (empty($orderids))
return false;
if (!is_array($orderids))
$orderids = array($orderids);
foreach($orderids as $orderid) {
if (empty($orderid))
continue;
$order_data = func_order_data($orderid);
$order = $order_data["order"];
$userinfo = $order_data["userinfo"];
$products = $order_data["products"];
$giftcerts = $order_data["giftcerts"];
$mail_smarty->assign("customer",$userinfo);
$mail_smarty->assign("products",$products);
$mail_smarty->assign("giftcerts",$giftcerts);
$mail_smarty->assign("order",$order);
#
# Order processing routine
# Send gift certificates
#
if ($order["applied_giftcerts"]) {
#
# Search for enabled to applying GC
#
$flag = true;
foreach($order["applied_giftcerts"] as $k=>$v) {
$res = func_query_first("SELECT gcid FROM $sql_tbl[giftcerts] WHERE gcid='$v[giftcert_id]' AND debit>='$v[giftcert_cost]'");
if (!$res["gcid"]) {
$flag = false;
break;
}
}
#
# Decrease debit for applied GC
#
if ($flag)
foreach($order["applied_giftcerts"] as $k=>$v) {
db_query("UPDATE $sql_tbl[giftcerts] SET debit=debit-'$v[giftcert_cost]' WHERE gcid='$v[giftcert_id]'");
db_query("UPDATE $sql_tbl[giftcerts] SET status='A' WHERE debit>0 AND gcid='$v[giftcert_id]'");
db_query("UPDATE $sql_tbl[giftcerts] SET status='U' WHERE debit<=0 AND gcid='$v[giftcert_id]'");
}
else
return false;
}
if ($giftcerts)
foreach($giftcerts as $giftcert) {
db_query("update $sql_tbl[giftcerts] set status='A' where gcid='$giftcert[gcid]'");
if ($giftcert["send_via"] == "E")
func_send_gc($userinfo["email"], $giftcert, $userinfo['login']);
}
#
# Send mail notifications
#
if (!$single_mode) {
$providers= func_query("select provider from $sql_tbl[order_details] where $sql_tbl[order_details].orderid='$orderid' group by provider");
if ($providers && $config['Email_Note']['eml_order_p_notif_provider'] == 'Y') {
foreach($providers as $provider) {
$email_pro = func_query_first_cell("SELECT email FROM $sql_tbl[customers] WHERE login='$provider[provider]'");
if (!empty($email_pro) && $email_pro != $config["Company"]["orders_department"]) {
$to_customer = func_query_first_cell ("SELECT language FROM $sql_tbl[customers] WHERE login='$provider[provider]'");
if(empty($to_customer))
$to_customer = $config['default_admin_language'];
func_send_mail($email_pro, "mail/order_notification_subj.tpl", "mail/order_notification.tpl", $config["Company"]["orders_department"], false);
}
}
}
}
$to_customer = func_query_first_cell ("SELECT language FROM $sql_tbl[customers] WHERE login='$userinfo[login]'");
if(empty($to_customer))
$to_customer = $config['default_customer_language'];
if($config['Email_Note']['eml_order_p_notif_customer'] == 'Y') {
$mail_smarty->assign("products", func_translate_products($products, $to_customer));
func_send_mail($userinfo["email"], "mail/order_cust_processed_subj.tpl", "mail/order_customer_processed.tpl", $config["Company"]["orders_department"], false);
}
$mail_smarty->assign("products",$products);
$mail_smarty->assign("show_order_details", "Y");
if($config['Email_Note']['eml_order_p_notif_admin'] == 'Y') {
func_send_mail($config["Company"]["orders_department"], "mail/order_notification_subj.tpl", "mail/order_notification_admin.tpl", $config["Company"]["orders_department"], true, true);
}
# SPM added below to send CSV order email
func_send_csv_mail($order,$products);
$mail_smarty->assign("show_order_details", "");
#
# Send E-goods download keys
#
if(!empty($active_modules["Egoods"]))
include $xcart_dir."/modules/Egoods/send_keys.php";
#
# Update statistics for sold products
#
if ($active_modules["Advanced_Statistics"]) {
include $xcart_dir."/modules/Advanced_Statistics/prod_sold.php";
}
}
}
#
# This function performs activities needed when order is complete
#
function func_complete_order($orderid) {
global $config, $mail_smarty, $active_modules;
global $sql_tbl, $to_customer;
global $xcart_dir;
$order_data = func_order_data($orderid);
$order = $order_data["order"];
$userinfo = $order_data["userinfo"];
$products = $order_data["products"];
$giftcerts = $order_data["giftcerts"];
$mail_smarty->assign("customer",$userinfo);
$mail_smarty->assign("products",$products);
$mail_smarty->assign("giftcerts",$giftcerts);
$mail_smarty->assign("order",$order);
if (!empty($active_modules["Special_Offers"])) {
include $xcart_dir."/modules/Special_Offers/complete_order.php";
}
#
# Send mail notifications
#
if ($config['Email_Note']['eml_order_c_notif_customer'] == 'Y') {
$to_customer = func_query_first_cell ("SELECT language FROM $sql_tbl[customers] WHERE login='$userinfo[login]'");
if(empty($to_customer))
$to_customer = $config['default_customer_language'];
$mail_smarty->assign("products", func_translate_products($products, $to_customer));
func_send_mail($userinfo["email"], "mail/order_cust_complete_subj.tpl", "mail/order_customer_complete.tpl", $config["Company"]["orders_department"], false);
}
if (!empty($active_modules["SnS_connector"])) {
func_generate_sns_action("Order", $orderid);
}
}
#
# This function joins order_id's and urlencodes 'em
#
function func_get_urlencoded_orderids ($orderids) {
if (is_array($orderids))
return urlencode (join (",", $orderids));
}
#
# This function performs activities nedded when order is declined
# status may be assign (D)ecline or (F)ail
# (D)ecline order sent mail to customer, (F)ail - not
#
function func_decline_order($orderids, $status = "D") {
global $config, $mail_smarty;
global $sql_tbl, $to_customer;
if(($status != "D") && ($status != "F")) return;
if(!is_array($orderids))$orderids = array($orderids);
foreach($orderids as $orderid)
{
#
# Order decline routine
#
$order_data = func_order_data($orderid);
$order = $order_data["order"];
$userinfo = $order_data["userinfo"];
$products = $order_data["products"];
$giftcerts = $order_data["giftcerts"];
# Send mail notifications
if($status == "D")
{
$mail_smarty->assign("customer",$userinfo);
$mail_smarty->assign("products",$products);
$mail_smarty->assign("giftcerts",$giftcerts);
$mail_smarty->assign("order",$order);
if($config['Email_Note']['eml_order_d_notif_customer'] == 'Y') {
$to_customer = func_query_first_cell ("SELECT language FROM $sql_tbl[customers] WHERE login='$userinfo[login]'");
if(empty($to_customer))
$to_customer = $config['default_customer_language'];
$mail_smarty->assign("products", func_translate_products($products, $to_customer));
func_send_mail($userinfo["email"], "mail/decline_notification_subj.tpl","mail/decline_notification.tpl", $config["Company"]["orders_department"], false);
}
}
#
# Discount restoring
#
$discount_coupon = $order["coupon"];
if ($discount_coupon) {
db_query("update $sql_tbl[discount_coupons] set status='A' where coupon='$discount_coupon' and times_used=times");
db_query("update $sql_tbl[discount_coupons] set times_used=times_used-1 where coupon='$discount_coupon'");
$discount_coupon="";
}
#
# Increase debit for declined GC
#
if ($order["applied_giftcerts"])
foreach($order["applied_giftcerts"] as $k=>$v)
{
if($order["status"]=="P" || $order["status"]=="C") {
db_query("UPDATE $sql_tbl[giftcerts] SET debit=debit+'$v[giftcert_cost]' WHERE gcid='$v[giftcert_id]'");
}
db_query("UPDATE $sql_tbl[giftcerts] SET status='A' WHERE debit>0 and gcid='$v[giftcert_id]'");
}
# Set GC's status to 'D'
if ($giftcerts)
foreach($giftcerts as $giftcert)
{
db_query("update $sql_tbl[giftcerts] set status='D' where gcid='$giftcert[gcid]'");
}
if ($config["General"]["unlimited_products"] != "Y")
func_update_quantity ($products);
}
}
#
# This function returns true if $cart is empty
#
function func_is_cart_empty($cart) {
return (empty($cart) or !(@$cart["products"] || @$cart["giftcerts"]));
}
#
# This function sends GC emails (called from func_place_order
# and provider/order.php"
#
function func_send_gc($from_email, $giftcert, $from_login = '') {
global $mail_smarty, $config, $to_customer, $sql_tbl;
$giftcert["purchaser_email"] = $from_email;
$mail_smarty->assign("giftcert", $giftcert);
#
# Send notifs to $orders_department & purchaser
#
if($config['Email_Note']['eml_giftcert_notif_purchaser'] == 'Y') {
if(!empty($from_login)) {
$to_customer = func_query_first_cell("SELECT language FROM $sql_tbl[customers] WHERE login = '$from_login'");
if(empty($to_customer))
$to_customer = $config['default_customer_language'];
}
func_send_mail($from_email, "mail/giftcert_notification_subj.tpl", "mail/giftcert_notification.tpl", $config["Company"]["orders_department"], false);
}
if($config['Email_Note']['eml_giftcert_notif_admin'] == 'Y') {
func_send_mail($config["Company"]["orders_department"], "mail/giftcert_notification_subj.tpl", "mail/giftcert_notification.tpl", $from_email, true);
}
#
# Send GC to recipient
#
$to_customer = '';
func_send_mail($giftcert["recipient_email"], "mail/giftcert_subj.tpl", "mail/giftcert.tpl", $from_email, false);
}
function func_pgp_encrypt($message) {
global $config;
if(!$config['Security']['crypt_method']) {
return $message;
}
$fn = func_temp_store($message);
$gfile = func_temp_store("");
if($config['Security']['crypt_method'] == 'G') {
putenv("GNUPGHOME=".$config["GnuPG"]["gpg_home_dir"]);
$gpg_prog = func_shellquote($config["GnuPG"]["gpg_prog"]);
$gpg_key = $config["GnuPG"]["gpg_key"];
@exec($gpg_prog.' --always-trust -a --batch --yes --recipient "'.$gpg_key.'" --encrypt '.func_shellquote($fn)." 2>".func_shellquote($gfile));
} else {
putenv("PGPPATH=".$config["PGP"]["pgp_home_dir"]);
putenv("PGPHOME=".$config["PGP"]["pgp_home_dir"]);
$pgp_prog = func_shellquote($config["PGP"]["pgp_prog"]);
$pgp_key = $config["PGP"]["pgp_key"];
if ($config["PGP"]["use_pgp6"] == "Y") {
@exec($pgp_prog." +batchmode +force -ea ".func_shellquote($fn)." \"$pgp_key\" 2>".func_shellquote($gfile));
} else {
@exec($pgp_prog.' +batchmode +force -fea "'.$pgp_key.'" < '.func_shellquote($fn).' > '.func_shellquote($fn).".asc 2>".func_shellquote($gfile));
}
}
$af = preg_replace('!\.[^\\\/]+$!', '', $fn).".asc";
$message = func_temp_read($af, true);
$config["PGP_output"] = func_temp_read($gfile, true);
@unlink($fn);
return $message;
}
#
# Move products back to the inventory
#
function func_update_quantity($products,$increase=true) {
global $config, $sql_tbl, $active_modules;
$symbol = ($increase?"+":"-");
if ($config["General"]["unlimited_products"] != "Y" && is_array($products)) {
foreach ($products as $product) {
if ($product['product_type'] == 'C' && !empty($active_modules['Product_Configurator']))
continue;
$variantid = "";
if(!empty($active_modules['Product_Options']) && (!empty($product['extra_data']['product_options']) || !empty($product['options']))) {
$options = (!empty($product['extra_data']['product_options'])?$product['extra_data']['product_options']:$product['options']);
$variantid = func_get_variantid($options);
}
if(!empty($variantid)) {
db_query("UPDATE $sql_tbl[variants] SET avail=avail$symbol'$product[amount]' WHERE variantid = '$variantid'");
func_set_product_by_variants($product['productid']);
} else {
$egoods_cond = $active_modules["Egoods"]?" AND distribution=''":"";
db_query("UPDATE $sql_tbl[products] SET avail=avail$symbol'$product[amount]' WHERE productid='$product[productid]'".$egoods_cond);
}
}
}
}
function func_pgp_remove_key() {
global $config;
if(!$config['Security']['crypt_method']) {
return false;
}
if($config['Security']['crypt_method'] == 'G') {
putenv("GNUPGHOME=".$config["GnuPG"]["gpg_home_dir"]);
$gpg_prog = func_shellquote($config["GnuPG"]["gpg_prog"]);
$gpg_key = $config["GnuPG"]["gpg_key"];
@exec($gpg_prog." --batch --yes --delete-key '$gpg_key'");
} else {
putenv("PGPPATH=".$config["PGP"]["pgp_home_dir"]);
putenv("PGPHOME=".$config["PGP"]["pgp_home_dir"]);
$pgp_prog = func_shellquote($config["PGP"]["pgp_prog"]);
$pgp_key = $config["PGP"]["pgp_key"];
if ($config["PGP"]["use_pgp6"] == "Y") {
@exec($pgp_prog." -kr +force +batchmode '$pgp_key'");
} else {
@exec($pgp_prog." -kr +force '$pgp_key'");
}
}
}
function func_pgp_add_key() {
global $config;
if(!$config['Security']['crypt_method']) {
return false;
}
if($config['Security']['crypt_method'] == 'G') {
putenv("GNUPGHOME=".$config["GnuPG"]["gpg_home_dir"]);
$gpg_prog = func_shellquote($config["GnuPG"]["gpg_prog"]);
$gpg_key = $config["GnuPG"]["gpg_key"];
$fn = func_temp_store($config["GnuPG"]["gpg_public_key"]);
chmod($fn, 0666);
@exec($gpg_prog.' --batch --yes --import '.func_shellquote($fn));
} else {
putenv("PGPPATH=".$config["PGP"]["pgp_home_dir"]);
putenv("PGPHOME=".$config["PGP"]["pgp_home_dir"]);
$fn = func_temp_store( $config["PGP"]["pgp_public_key"]);
$pgp_prog = func_shellquote($config["PGP"]["pgp_prog"]);
$pgp_key = $config["PGP"]["pgp_key"];
$ftmp = func_temp_store('');
if ($config["PGP"]["use_pgp6"] == "Y") {
@exec($pgp_prog.' +batchmode -ka '.func_shellquote($fn).' 2> '.func_shellquote($ftmp));
@exec($pgp_prog.' +batchmode -ks "'.$pgp_key.'"');
} else {
@exec($pgp_prog.' -ka +force +batchmode '.func_shellquote($fn).' 2> '.func_shellquote($ftmp));
@exec($pgp_prog.' +batchmode -ks "'.$pgp_key.'"');
}
unlink($ftmp);
}
unlink($fn);
}
function func_update_pgp() {
global $config;
func_pgp_remove_key();
func_pgp_add_key();
}
#
# Get value of language variable by its name and usertype
#
function func_get_langvar_by_name($lang_name, $replace_to=NULL, $force_code = '') {
global $sql_tbl, $current_area, $config, $shop_language;
global $smarty, $user_agent;
global $predefined_lng_variables;
$language_code = $shop_language;
if(!empty($force_code))
$language_code = $force_code;
$result = func_query_first_cell("SELECT value FROM $sql_tbl[languages] WHERE code='$language_code' AND name='$lang_name'");
if(empty($result)) {
$language_code = ($current_area == "C" ? $config["default_customer_language"] : $config["default_admin_language"]);
$result = func_query_first_cell("SELECT value FROM $sql_tbl[languages] WHERE code='$language_code' AND name='$lang_name'");
if(empty($result))
$result = func_query_first_cell("SELECT value FROM $sql_tbl[languages] WHERE code='US' AND name='$lang_name'");
}
$predefined_lng_variables[] = $lang_name;
if (is_array($replace_to))
foreach ($replace_to as $k=>$v)
$result = str_replace("{{".$k."}}", $v, $result);
if ($smarty->webmaster_mode)
$result = func_webmaster_label($user_agent, $lang_name, $result);
return $result;
}
function func_parse_cookie_array(&$http_header, $cookies) {
$deleted = array();
$valid = array();
foreach ($cookies as $line) {
if (preg_match_all('!^\s*([^\n\r=]+)=([^\r\n; ]+)?!S', $line, $m)) {
if (!empty($m[1]) && is_array($m[1])) {
foreach ($m[1] as $k=>$v) {
if ($m[2][$k] == 'deleted') {
$deleted[$v] = true;
if (isset($valid[$v])) unset($valid[$v]);
}
else {
$valid[$v] = $m[2][$k];
if (isset($deleted[$v])) unset($deleted[$v]);
}
}
}
}
}
$http_header['cookies_deleted'] = $deleted;
$http_header['cookies'] = $valid;
}
function func_http_get_request($host, $post_url, $post_str, $post_cookies=array()) {
$hp = explode(':',$host);
$cookie = "";
$result = "";
$header_passed = false;
if( !isset($hp[1]) || !is_numeric($hp[1]) ) $hp[1] = 80;
$host = implode(':', $hp);
$fp = fsockopen($hp[0], $hp[1], $errno, $errstr, 30);
if (!$fp) {
return array ("", "");
} else {
fputs ($fp, "GET $post_url?$post_str HTTP/1.0\r\n");
fputs ($fp, "Host: $host\r\n");
fputs ($fp, "User-Agent: Mozilla/4.5 [en]\r\n");
if (!empty($post_cookies))
fputs ($fp, "Cookie: ".join('; ',$post_cookies)."\r\n");
fputs ($fp,"\r\n");
$http_header = array ();
$http_header["ERROR"] = chop(fgets($fp,4096));
$cookies = array ();
while (!feof($fp)) {
if (!$header_passed)
$line = fgets($fp, 4096);
else
$result .= fread($fp, 65536);
if ($header_passed == false && ($line == "\n" || $line == "\r\n")) {
$header_passed = true;
continue;
}
if ($header_passed == false) {
$header_line = explode(": ", $line, 2);
$header_line[0] = strtoupper($header_line[0]);
$http_header[$header_line[0]] = chop($header_line[1]);
if ($header_line[0] == 'SET-COOKIE')
array_push($cookies, chop($header_line[1]));
}
}
fclose($fp);
}
func_parse_cookie_array($http_header, $cookies);
return array($http_header, $result);
}
function func_http_post_request($host, $post_url, $post_str, $cook = "") {
$hp = explode(':',$host);
$result = "";
$header_passed = false;
if( !isset($hp[1]) || !is_numeric($hp[1]) ) $hp[1] = 80;
$host = implode(':', $hp);
$fp = fsockopen($hp[0], $hp[1], $errno, $errstr, 30);
if (!$fp) {
#die("Cant connect ($errno)
\n");
return array ("", "");
} else {
#fputs ($fp, "POST $post_url HTTP/1.0\r\n");
fputs($fp, "POST http://$host$post_url HTTP/1.0\r\n");
fputs($fp, "Host: $host\r\n");
if (!empty($cook))
fputs($fp, "Cookie: ".$cook."\r\n");
fputs($fp, "User-Agent: Mozilla/4.5 [en]\r\n");
fputs($fp, "Content-Type: application/x-www-form-urlencoded\r\n");
fputs($fp, "Content-Length: ".strlen($post_str)."\r\n");
fputs($fp, "\r\n");
fputs($fp, $post_str."\r\n\r\n");
$http_header = array();
$http_header["ERROR"] = chop(fgets($fp,4096));
$cookies = array();
while (!feof($fp)) {
$line = fgets($fp,4096);
if ($header_passed == false && ($line == "\n" || $line == "\r\n")) {
$header_passed = true;
continue;
}
if ($header_passed == false) {
$header_line = explode(": ", $line, 2);
$header_line[0] = strtoupper($header_line[0]);
$http_header[$header_line[0]] = chop($header_line[1]);
if ($header_line[0] == 'SET-COOKIE')
array_push($cookies, chop($header_line[1]));
continue;
}
$result .= $line;
}
fclose ($fp);
}
func_parse_cookie_array($http_header, $cookies);
return array($http_header, $result, $cookies);
}
#
# This function compare file extension with disallowed extensions list
#
function func_is_allowed_file($file) {
global $config;
$disallowed_file_extensions = split('[ ,]+',$config["Security"]["disallowed_file_exts"]);
$disallowed_file_extensions = func_array_map('strtolower', $disallowed_file_extensions);
$disallowed_file_extensions = array_flip($disallowed_file_extensions);
unset($disallowed_file_extensions[""]);
$info = pathinfo($file);
return !isset($disallowed_file_extensions[strtolower($info["extension"])]);
}
#
# Checking that posted image is exist
#
function func_check_image_posted($file_upload_data, $type) {
global $config;
$return = false;
if ($file_upload_data["imtype"] != $type)
return false;
if (!func_allow_file($file_upload_data["file_path"], true))
return false;
if ($file_upload_data["source"] == "U") {
if ($fd = func_fopen($file_upload_data["file_path"], "rb", true)) {
fclose($fd);
$return = true;
}
}
else
$return = file_exists($file_upload_data["file_path"]);
if ($return) {
switch ($file_upload_data["imtype"]) {
case "C":
$return = ($file_upload_data["file_size"] <= $config["Images"]["icons_size_limit"] || $config["Images"]["icons_size_limit"]=="0");
break;
case "T":
$return = ($file_upload_data["file_size"] <= $config["Images"]["thumbnails_size_limit"] || $config["Images"]["thumbnails_size_limit"]=="0");
break;
case "D":
$return = ($file_upload_data["file_size"] <= $config["Images"]["det_images_size_limit"] || $config["Images"]["det_images_size_limit"]=="0");
break;
case "W":
$return = ($file_upload_data["file_size"] <= $config["Images"]["pcicons_size_limit"] || $config["Images"]["pcicons_size_limit"]=="0");
}
}
return $return;
}
function createThumbnail($srcPath,$dstPath,$max_width,$max_height,$fileType){
$size = GetImageSize($srcPath);
$width = $size[0];
$height = $size[1];
$x_ratio = $max_width / $width;
$y_ratio = $max_height / $height;
if ( ($width <= $max_width) && ($height <= $max_height) ) {
$tn_width = $width;
$tn_height = $height;
}
else if (($x_ratio * $height) < $max_height) {
$tn_height = ceil($x_ratio * $height);
$tn_width = $max_width;
}
else {
$tn_width = ceil($y_ratio * $width);
$tn_height = $max_height;
}
if($fileType=="image/jpeg" || $fileType=="image/pjpeg"){
if($width >= $max_width || $height >= $max_height){
$srcImg = imagecreatefromjpeg($srcPath);
$dstImg = imagecreatetruecolor($tn_width,$tn_height);
imagecopyresampled($dstImg, $srcImg, 0, 0, 0, 0, $tn_width,$tn_height,$width,$height);
imagejpeg($dstImg, $dstPath);
imagedestroy($dstImg);
imagedestroy($srcImg);
}else{
# image is already smaller than max size so just copy it to the specified path
copy($srcPath,$dstPath);
}
}elseif($fileType=="image/gif"){
if($width >= $max_width || $height >= $max_height){
$srcImg = imagecreatefromgif($srcPath);
$dstImg = imagecreate($tn_width,$tn_height);
imagecopyresampled($dstImg, $srcImg, 0, 0, 0, 0, $tn_width,$tn_height,$width,$height);
imagegif($dstImg, $dstPath);
imagedestroy($dstImg);
imagedestroy($srcImg);
}else{
# image is already smaller than max size so just copy it to the specified path
copy($srcPath,$dstPath);
}
}elseif($fileType=="image/png"){
if($width >= $max_width || $height >= $max_height){
$srcImg = imagecreatefrompng($srcPath);
$dstImg = imagecreatetruecolor($tn_width,$tn_height);
imagecopyresampled($dstImg, $srcImg, 0, 0, 0, 0, $tn_width,$tn_height,$width,$height);
imagepng($dstImg, $dstPath);
imagedestroy($dstImg);
imagedestroy($srcImg);
}else{
# image is already smaller than max size so just copy it to the specified path
copy($srcPath,$dstPath);
}
}
}
#
# Get image content function
#
function func_get_image_content($file_upload_data, $id) {
global $config, $active_modules;
$file_aliases_count_max = 99;
switch($file_upload_data["imtype"]) {
case "P":
$config_data["location"] = "/var/www/shop/panel_images/";
break;
case "C":
$config_data["location"] = $config["Images"]["icons_location"];
break;
case "W":
$config_data["location"] = $config["Images"]["pcicons_location"];
break;
case "T":
$config_data["location"] = $config["Images"]["thumbnails_location"];
break;
case "D":
$config_data["location"] = $config["Images"]["det_images_location"];
break;
case "F":
if(empty($active_modules['Feature_Comparison']))
return false;
$config_data["location"] = $config["Images"]["feature_images_location"];
break;
default:
return false;
}
if ($file_upload_data["source"] == "U")
$file_path = $file_upload_data["file_path"];
else
$file_path = func_realpath($file_upload_data["file_path"]);
if ($fd = func_fopen($file_path, "rb", true)) {
if ($config_data["location"] == "FS") {
#
# ...else image is path to file
#
$image = $file_path;
}
else
{
#
# If image should be stored in the database, get image content from file
#
if ($file_upload_data["source"] == "U") {
$image = "";
do {
$tmpdata = fread($fd, 8192);
if (strlen($tmpdata) == 0) break;
$image .= $tmpdata;
} while(true);
}
else
$image = fread($fd, filesize($file_path));
$image = addslashes($image);
}
fclose($fd);
if ($file_upload_data["source"] == "L" && !empty($file_upload_data["dir_upload"])) {
if ($config_data["location"] == "FS") {
#
# For FS storing. If image has been uploaded, move it to specified directory
#
$file_name = ($file_upload_data["imtype"]=="W"?"w_$id":($file_upload_data["imtype"]=="C"?"c_$id":($file_upload_data["imtype"]=="T"?"t_$id":"d_$id")));
$file_type = (strstr($file_path,"gif")?"gif":(strstr($file_path,"png")?"png":"jpg"));
#
# Check the existing file
#
# SPM removed file name counter feature
//$counter = 1;
//$file_name_tmp = $file_name;
//while (file_exists($file_upload_data["dir_upload"].DIRECTORY_SEPARATOR.$file_name_tmp.".".$file_type) && $counter<$file_aliases_count_max) {
// $file_name_tmp = $file_name."_".sprintf("%02d", $counter);
// $counter++;
//}
//$file_name = $file_name_tmp;
$image = $file_upload_data["dir_upload"].DIRECTORY_SEPARATOR.$file_name.".".$file_type;
copy($file_path, $image);
@chmod($image, 0666);
}
#
# Delete temporary file
#
@unlink($file_path);
}
}
if($file_upload_data["imtype"] == 'D') {
if($config_data["location"] == "FS") {
$fp = fopen($image, "rb");
if($fp) {
$i = "";
$s = "";
while($s = fread($fp, 8192)) {
$i .= $s;
}
$md5 = md5($i);
fclose($fp);
}
} else
$md5 = md5($image);
}
return array("image"=>$image, "image_type"=>$file_upload_data["image_type"], "image_x"=>$file_upload_data["image_x"], "image_y"=>$file_upload_data["image_y"], "file_size"=>$file_upload_data["file_size"], "md5" => $md5);
}
function func_weight_in_grams($weight) {
global $config;
return $weight*$config["General"]["weight_symbol_grams"];
}
#
# This module generates download key which is sent to customer
# and inserts this key into database
#
function keygen($productid, $key_TTL, $itemid) {
global $sql_tbl;
$key = md5(uniqid(rand()));
$expires = time() + $key_TTL*3600;
db_query("REPLACE INTO $sql_tbl[download_keys] (download_key, expires, productid, itemid) VALUES('$key', '$expires', '$productid', '$itemid')");
return $key;
}
#
# Flush output
#
function func_flush() {
if (preg_match("/Apache(.*)Win/", getenv("SERVER_SOFTWARE")))
echo str_repeat(" ", 2500);
elseif (preg_match("/(.*)MSIE(.*)\)$/", getenv("HTTP_USER_AGENT")))
echo str_repeat(" ", 256);
ob_end_flush();
flush();
}
#
# For testing purpose: outputs contents of requested variables
# example:
# func_print_r($categories,$cart,$userinfo,$GLOBALS);
#
function func_print_r() {
static $count = 0;
$args = func_get_args();
if (!empty($args)) {
?>$variable_content){
?>Debug []: Debug notice: try to use func_print_d("varname1","varname2") instead of func_print_d($varname1,$varname2); $variable_name = ";
ob_start();
if ($variable_name == 'GLOBALS')
print_r($GLOBALS);
else {
if (!@isset($GLOBALS[$variable_name])) {
echo "is unset!";
}
else
print_r($GLOBALS[$variable_name]);
}
$data = ob_get_contents(); ob_end_clean();
echo htmlspecialchars($data);
}
echo "\n";
}
}
else {
?>Debug notice: try to use func_print_d("varname1","varname2") instead of func_print_d($varname1,$varname2); 0);
$xrma = (func_query_first_cell("SELECT COUNT(*) FROM $sql_tbl[modules] WHERE module_name='RMA'") > 0);
if($xaff && !isset($sql_tbl['partner_payment'])) {
@include_once $xcart_dir."/modules/XAffiliate/config.php";
}
if($xrma && !isset($sql_tbl['returns'])) {
@include_once $xcart_dir."/modules/RMA/config.php";
}
db_query("LOCK TABLES $sql_tbl[orders] WRITE, $sql_tbl[order_details] WRITE, $sql_tbl[order_extras] WRITE, $sql_tbl[giftcerts] WRITE, $sql_tbl[subscription_customers] WRITE".(@$xaff?", $sql_tbl[partner_payment] WRITE, $sql_tbl[partner_product_commissions] WRITE, $sql_tbl[partner_adv_orders] WRITE":"").(@$xrma?", $sql_tbl[returns] WRITE":""));
foreach($_orders as $orderid) {
$itemids = func_query("SELECT itemid FROM $sql_tbl[order_details] WHERE orderid='$orderid'");
if(!empty($itemids)) {
foreach($itemids as $k => $v) {
$itemids[$k] = $v['itemid'];
}
}
db_query("DELETE FROM $sql_tbl[orders] WHERE orderid='$orderid'");
db_query("DELETE FROM $sql_tbl[order_details] WHERE orderid='$orderid'");
db_query("DELETE FROM $sql_tbl[order_extras] WHERE orderid='$orderid'");
db_query("DELETE FROM $sql_tbl[giftcerts] WHERE orderid='$orderid'");
if (@$xaff) {
db_query("DELETE FROM $sql_tbl[partner_payment] WHERE orderid='$orderid'");
db_query("DELETE FROM $sql_tbl[partner_product_commissions] WHERE orderid='$orderid'");
db_query("DELETE FROM $sql_tbl[partner_adv_orders] WHERE orderid='$orderid'");
}
if (@$xrma && !empty($itemids)) {
db_query("DELETE FROM $sql_tbl[returns] WHERE itemid IN ('".implode("','", $itemids)."')");
}
db_query("DELETE FROM $sql_tbl[subscription_customers] WHERE orderid='$orderid'");
}
#
# Check if no orders in the database
#
$total_orders = func_query_first_cell("SELECT COUNT(*) FROM $sql_tbl[orders]");
if ($total_orders == 0) {
#
# Clear Order ID counter (auto increment field in the xcart_orders table)
#
db_query("DELETE FROM $sql_tbl[orders]");
db_query("DELETE FROM $sql_tbl[order_details]");
if (@$xaff)
db_query("DELETE FROM $sql_tbl[partner_payment]");
db_query("DELETE FROM $sql_tbl[subscription_customers]");
}
db_query("UNLOCK TABLES");
}
#
# Get information about directory:
# - how many files does directory contain
# - what size does directory have
#
function func_get_dir_status( $directory ) {
$result = array("files"=>0, "size"=>0);
$dp = opendir ($directory);
while ($file = readdir ($dp)) {
if( $file == "." || $file == ".." ) continue;
$path = $directory.DIRECTORY_SEPARATOR.$file;
if( is_file( $path ) ) {
$result["files"] ++;
$result["size"] += filesize($path);
}
else {
$temp = func_get_dir_status($path);
$result["files"] += $temp["files"];
$result["size"] += $temp["size"];
}
}
closedir($dp);
return $result;
}
#
# This function added the ability to redirect a user to another page using HTML meta tags
# (without using header() function or Javascript)
#
function func_html_location($url, $time=3) {
x_session_save();
echo "
".func_get_langvar_by_name("txt_header_location_note", array("time" => $time, "location" => $url));
echo "";
func_flush();
exit;
}
#
# This function generates the unique cartid number
#
function func_generate_cartid($cart_products) {
global $cart;
if (empty($cart["max_cartid"]))
$cart["max_cartid"] = 0;
$cart["max_cartid"]++;
return $cart["max_cartid"];
}
#
# This function determine the files location for current user
#
function func_get_files_location () {
global $login, $current_area, $active_modules, $single_mode, $files_dir_name;
if ($single_mode || $current_area=="A" || ($active_modules["Simple_Mode"] && $current_area=="P"))
return $files_dir_name;
return $files_dir_name.DIRECTORY_SEPARATOR.$login;
}
#
# This function updates/inserts the language variable into 'languages_alt'
#
function func_languages_alt_insert($name, $value, $code="") {
global $sql_tbl, $all_languages;
$result = true;
if (is_array($all_languages)) {
if (empty($code)) {
#
# For empty code update/insert variables for all languages
#
foreach($all_languages as $k=>$v) {
if (func_query_first_cell("SELECT COUNT(*) FROM $sql_tbl[languages_alt] WHERE code='$v[code]' AND name='$name'") == 0)
db_query("INSERT INTO $sql_tbl[languages_alt] (code,name,value) VALUES ('$v[code]', '$name', '$value')");
else
db_query("UPDATE $sql_tbl[languages_alt] SET value='$value' WHERE code='$v[code]' AND name='$name'");
}
}
else {
#
# For not empty $code...
#
$result = false;
#
# Check if $code is valid
#
foreach($all_languages as $k=>$v) {
if ($code == $v["code"]) {
$result = true;
break;
}
}
if (!$result)
return false;
#
# Update/insert variable for $code
#
if (func_query_first_cell("SELECT COUNT(*) FROM $sql_tbl[languages_alt] WHERE code='$code' AND name='$name'") == 0)
db_query("INSERT INTO $sql_tbl[languages_alt] (code,name,value) VALUES ('$code', '$name', '$value')");
else
db_query("UPDATE $sql_tbl[languages_alt] SET value='$value' WHERE code='$code' AND name='$name'");
}
}
else
$result = false;
return $result;
}
#
# This function returns the language variable value by name and language code
#
function func_get_languages_alt($name, $lng_code) {
global $sql_tbl;
return func_query_first_cell("SELECT value FROM $sql_tbl[languages_alt] WHERE code='$lng_code' AND name='$name'");
}
#
# This function creates a temporary file and store some data in it
# It will return filename if successful and "false" if it fails.
#
function func_temp_store($data) {
global $file_temp_dir;
$tmpfile = @tempnam($file_temp_dir,"xctmp");
if (empty($tmpfile)) return false;
$fp = @fopen($tmpfile,"w");
if (!$fp) {
@unlink($tmpfile);
return false;
}
fwrite($fp,$data);
fclose($fp);
return $tmpfile;
}
#
# This function validate accordance a county ID to a state and country code
#
function func_check_county($countyid, $statecode, $countrycode) {
global $sql_tbl;
$return = true;
if (is_numeric($countyid)) {
if(func_query_first_cell("SELECT COUNT(*) FROM $sql_tbl[states] WHERE code='$statecode' AND country_code='$countrycode'") > 0) {
$return = (func_query_first_cell("SELECT COUNT(*) FROM $sql_tbl[counties], $sql_tbl[states] WHERE $sql_tbl[counties].stateid=$sql_tbl[states].stateid AND $sql_tbl[counties].countyid='$countyid' AND $sql_tbl[states].code='$statecode' AND $sql_tbl[states].country_code='$countrycode'") == 1);
}
}
return $return;
}
#
# This function validate accordance a state code to a country code
#
function func_check_state($states, $statecode, $countrycode) {
$country_flag = $state_flag = $state_flag2 = false;
$return = true;
foreach ($states as $val) {
if ($val["country_code"] == $countrycode) {
$country_flag = true;
if ($val["state_code"] == $statecode)
$state_flag = true;
}
if ($val["state_code"] == $statecode)
$state_flag2 = true;
}
if (($country_flag && !$state_flag) ||(!$country_flag && $state_flag2))
$return = false;
return $return;
}
#
# This function quotes arguments for shell command according
# to the host operation system
#
function func_shellquote() {
static $win_s = '!([\t \&\<\>\?]+)!S';
static $win_r = '"\\1"';
$result = "";
$args = func_get_args();
foreach ($args as $idx=>$arg)
$args[$idx] = X_DEF_OS_WINDOWS ? (preg_replace($win_s,$win_r,$arg)) : (escapeshellarg($arg));
return implode(' ', $args);
}
#
# realpath() wrapper
#
function func_realpath($path) {
if (empty($path)) return false;
$path = preg_replace("/[\\\\\/]+/S",DIRECTORY_SEPARATOR,$path);
$dir = dirname($path); if ($dir != "\\") $dir .= DIRECTORY_SEPARATOR;
$dir = realpath($dir);
if (empty($dir) || $dir[strlen($dir)-1] != DIRECTORY_SEPARATOR) $dir .= DIRECTORY_SEPARATOR;
$path = $dir.basename($path);
return $path;
}
#
# This function decide to allow/deny to use path for files
# Returns: full path for the file if path is allowed,
# 'false', if path is not allowed to use.
#
function func_allowed_path($allowed_path, $path) {
if (empty($allowed_path) || empty($path)) return false;
if (X_DEF_OS_WINDOWS) {
$allowed_path = strtolower($allowed_path);
$path = strtolower($path);
}
$allowed_path = func_realpath($allowed_path);
if (empty($allowed_path)) return false;
# absolute path
if ( (X_DEF_OS_WINDOWS && preg_match("/^(\\\\)|(\w:)/S",$path)) || !X_DEF_OS_WINDOWS && $path[0] == '/') {
$path = func_realpath($path);
}
else {
$path = func_realpath($allowed_path.DIRECTORY_SEPARATOR.$path);
}
if ($allowed_path == $path) return $allowed_path;
if ($allowed_path[strlen($allowed_path)-1] != DIRECTORY_SEPARATOR)
$allowed_path .= DIRECTORY_SEPARATOR;
if (!strncmp($path, $allowed_path, strlen($allowed_path)))
return $path;
return false;
}
function func_check_webinput($check_php=1)
{
global $config,$sql_tbl,$HTTP_SERVER_VARS;
$php = $HTTP_SERVER_VARS["PHP_SELF"];
$allow_php = array();
$list = func_query("select c.processor from $sql_tbl[ccprocessors] as c, $sql_tbl[payment_methods] as m where m.active='Y' and m.paymentid=c.paymentid and c.background!='Y'");
if($list)
foreach($list as $a)
switch(array_pop($a))
{
case "cc_epdq.php":
$allow_php[] = "cc_epdq_result.php"; break;
case "cc_smartpag.php":
$allow_php[] = "cc_smartpag_final.php"; break;
case "cc_payzip.php":
$allow_php[] = "cc_payzip_result.php"; break;
case "cc_verisignl.php":
$allow_php[] = "cc_verisignl_result.php"; break;
case "cc_hsbc.php":
$allow_php[] = "cc_hsbc_result.php"; break;
case "cc_ogoneweb.php":
$allow_php[] = "cc_ogoneweb_result.php"; break;
case "cc_pswbill.php":
$allow_php[] = "cc_pswbill_result.php"; break;
case "cc_triple.php":
$allow_php[] = "cc_triple_result.php"; break;
case "cc_paybox.php":
$allow_php[] = "cc_paybox_result.php"; break;
case "cc_pp3.php":
$allow_php[] = "ebank_ok.php";
$allow_php[] = "ebank_nok.php"; break;
default: $allow_php[] = $a["processor"]; break;
}
#$allow_php[] = "payment_cc.php";
$ip = $HTTP_SERVER_VARS["REMOTE_ADDR"];
$allow_ip = $config["Security"]["allow_ips"];
$not_found=1;
if($check_php && $allow_php)
foreach($allow_php as $allow)
if(preg_match("/".$allow."$/",$php))
{$not_found=0;break;}
if($not_found)
{ header("Location: ../"); die("Access denied"); }
if($allow_ip)
{
$not_found=1;
$a = split(",",$allow_ip);
foreach($a as $v)
{
list($aip,$amsk) = split("/",trim($v));
$amsk = 4294967296 - ($amsk ? pow(2,(32-$amsk)) : 1);
if((ip2long($ip) & $amsk) == ip2long($aip))
{$not_found=0;break;}
}
return ($not_found ? "err" : "pass");
}
else
return "pass";
}
#
# This function recrypts data with the Blowfish method.
#
function func_data_recrypt() {
global $sql_tbl, $merchant_password, $current_area, $active_modules, $config;
if(!$merchant_password || !($current_area == 'A' || ($current_area == 'P' && $active_modules["Simple_Mode"])) || $config['Security']['blowfish_enabled'] != 'Y') {
return false;
}
$orders = func_query("SELECT orderid, details FROM $sql_tbl[orders] WHERE details NOT LIKE 'B%'");
if($orders) {
$cnt = 0;
set_time_limit(86400);
foreach($orders as $order) {
if(++$cnt / 100 == 0 && $cnt) {
echo ".";
if($cnt / 5000 == 0) {
echo "
\n";
}
func_flush();
}
$details = text_decrypt($order['details']);
$details = text_crypt($details, true);
db_query("UPDATE $sql_tbl[orders] SET details = '".addslashes($details)."' WHERE orderid = '$order[orderid]'");
}
}
return true;
}
#
# This function decrypts data Blowfish method -> Standart method.
#
function func_data_decrypt() {
global $sql_tbl, $merchant_password, $current_area, $active_modules;
if(!$merchant_password || !($current_area == 'A' || ($current_area == 'P' && $active_modules["Simple_Mode"]))) {
return false;
}
$orders = func_query("SELECT orderid, details FROM $sql_tbl[orders] WHERE details LIKE 'B%'");
if($orders) {
$cnt = 0;
set_time_limit(86400);
foreach($orders as $order) {
if(++$cnt / 100 == 0 && $cnt) {
echo ".";
if($cnt / 5000 == 0) {
echo "
\n";
}
func_flush();
}
$details = text_decrypt($order['details']);
$details = text_crypt($details);
db_query("UPDATE $sql_tbl[orders] SET details = '".addslashes($details)."' WHERE orderid = '$order[orderid]'");
}
}
return true;
}
#
# This function recrypts Blowfish-crypted data with new password
# where:
# old_password - old Merchant password
function func_change_mpassword_recrypt($old_password) {
global $sql_tbl, $merchant_password, $current_area, $active_modules, $blowfish;
if(!$old_password || !$merchant_password || !($current_area == 'A' || ($current_area == 'P' && $active_modules["Simple_Mode"]))) {
return false;
}
$orders = func_query("SELECT orderid, details FROM $sql_tbl[orders] WHERE details LIKE 'B%'");
if($orders) {
$_merchant_password = $merchant_password;
$cnt = 0;
set_time_limit(86400);
foreach($orders as $order) {
if(++$cnt / 100 == 0 && $cnt) {
echo ".";
if($cnt / 5000 == 0) {
echo "
\n";
}
func_flush();
}
$merchant_password = $old_password;
$details = text_decrypt($order['details']);
$merchant_password = $_merchant_password;
$details = text_crypt($details, true);
db_query("UPDATE $sql_tbl[orders] SET details = '".addslashes($details)."' WHERE orderid = '$order[orderid]'");
}
$merchant_password = $_merchant_password;
}
return true;
}
#
# Java script redirect
#
function func_js_redirect($location) {
global $http_location;
x_session_save();
echo "".func_get_langvar_by_name("txt_no_js_redirect_1")." ".$http_location."/".$location." ".func_get_langvar_by_name("txt_no_js_redirect_2")." ".func_get_langvar_by_name("txt_no_js_redirect_3")."";
exit;
}
#
# Get CRC32 as 4-symbols
#
function func_crc32($str) {
$int = crc32($str);
return chr($int >> 24).chr(($int >> 16) & 0xff). chr(($int >> 8) & 0xff).chr($int & 0xff);
}
#
# Insert array data to table
#
function func_array2insert ($tbl, $arr, $is_replace = false) {
global $sql_tbl;
if($sql_tbl[$tbl])
$tbl = $sql_tbl[$tbl];
if(db_query(($is_replace?"REPLACE":"INSERT")." INTO $tbl (" . implode(", ", array_keys($arr)) . ") VALUES ('" . implode("', '", $arr) . "')")) {
return db_insert_id();
} else {
return false;
}
}
#
# Update array data to table + where statament
#
function func_array2update ($tbl, $arr, $where = '') {
global $sql_tbl;
if($sql_tbl[$tbl])
$tbl = $sql_tbl[$tbl];
foreach($arr as $k => $v) {
$r .= ($r ? ", " : "") . $k . "='" . $v . "'";
}
return db_query("UPDATE $tbl SET $r" . ($where ? " WHERE " . $where : ""));
}
#
# Check filename for present in X-Cart directory
#
function func_allow_file($file, $is_root = false) {
global $xcart_dir, $login, $single_mode, $current_area, $active_modules, $files_dir_name;
if (empty($file) || !func_is_allowed_file($file))
return false;
$dir = $xcart_dir;
if (strncasecmp($file, "http://", 7) && strncasecmp($file, "ftp://", 6) && strncasecmp($file, "https://", 8)) {
if (!$is_root) {
if ($current_area=="A" || (($active_modules["Simple_Mode"] || $single_mode)&& $current_area=="P"))
$dir = $files_dir_name;
elseif ($current_area=="P" || $current_area == 'A')
$dir = $files_dir_name.DIRECTORY_SEPARATOR.$login;
else
$dir = $files_dir_name;
}
$file = func_allowed_path($dir, $file);
}
return $file;
}
#
# Get default field's name
#
function func_get_default_field($name) {
$suffix = str_replace("name", "_name", preg_replace("/^(s_|b_)(.+)$/S", "\\2", $name));
if ($suffix == "zipcode")
$suffix = "zip_code";
return func_get_langvar_by_name("lbl_".$suffix);
}
#
# fopen() wrapper
#
function func_fopen($file, $perm = 'r', $is_root = false) {
$file = func_allow_file($file, $is_root);
if ($file === false)
return false;
return @fopen($file, $perm);
}
#
# fopen + fread wrapper
#
function func_file_get($file, $is_root = false) {
$fp = func_fopen($file, 'rb', $is_root);
if ($fp === false) return false;
while (strlen($str = fread($fp, 8192)) > 0 )
$data .= $str;
fclose($fp);
return $data;
}
#
# readfile() wrapper
#
function func_readfile($file, $is_root = false) {
$file = func_allow_file($file, $is_root);
if ($file === false) return false;
return readfile($file);
}
#
# Get tmpfile content
#
function func_temp_read($tmpfile, $delete = false) {
if (empty($tmpfile))
return false;
$fp = @fopen($tmpfile,"rb");
if(!$fp)
return false;
while (strlen($str = fread($fp, 4096)) > 0 )
$data .= $str;
fclose($fp);
if ($delete) {
@unlink($tmpfile);
}
return $data;
}
#
# move_uploaded_file() wrapper
#
function func_move_uploaded_file($file) {
global $HTTP_POST_FILES, $file_temp_dir;
if(empty($file) || !isset($HTTP_POST_FILES[$file]))
return false;
$path = func_allow_file(tempnam($file_temp_dir,preg_replace('/^.*[\/\\\]/S', '', $HTTP_POST_FILES[$file]['name'])), true);
if ($path === false)
return false;
if (move_uploaded_file($HTTP_POST_FILES[$file]['tmp_name'],$path))
return $path;
chmod($path, 0644);
return false;
}
#
# file() wrapper
#
function func_file($file, $is_root = false) {
$file = func_allow_file($file, $is_root);
if ($file === false) return array();
return file($file);
}
#
# This function checks if email is valid
#
function func_check_email($email) {
#
# Simplified checking
#
$email_regular_expression = "^([-\d\w][-.\d\w]*)?[-\d\w]@([-!#\$%&*+\\/=?\w\d^_`{|}~]+\.)+[a-zA-Z]{2,6}$";
#
# Full checking according to RFC 822
# Uncomment the line below to use it (change also check_email_script.tpl)
# $email_regular_expression = "^[^.]{1}([-!#\$%&'*+.\\/0-9=?A-Z^_`a-z{|}~])+[^.]{1}@([-!#\$%&'*+\\/0-9=?A-Z^_`a-z{|}~]+\\.)+[a-zA-Z]{2,6}$";
return preg_match("/".$email_regular_expression."/i", stripslashes($email));
}
#
# Hash table for func_lock & func_unlock
#
function & func_lock_hash_tbl() {
static $hash = array();
return $hash;
}
#
# This function create file lock in temporaly directory
# It will return file descriptor, or false.
#
function func_lock($lockname) {
global $file_temp_dir;
if (empty($lockname)) return false;
$fname = $file_temp_dir.DIRECTORY_SEPARATOR.$lockname;
$fp = fopen($fname, "w+");
if (!$fp) return false;
$attempts = 3;
while ($attempts > 0) {
if (flock($fp, LOCK_EX)) {
$hash =& func_lock_hash_tbl();
$hash[$fp] = $fname;
return $fp;
}
sleep(5);
$attempts--;
}
return false;
}
#
# This function releases file lock which is previously created by func_lock
#
function func_unlock($fp) {
global $file_temp_dir;
$hash =& func_lock_hash_tbl();
if ($fp === false || empty($hash[$fp])) return false;
$fname = $hash[$fp];
unset($hash[$fp]);
@fclose($fp);
@unlink($fname);
return true;
}
#
# Get additional register fields settings
#
function func_get_additional_fields($area = '', $user = '') {
global $sql_tbl, $shop_language;
if($area)
$fields = func_query("SELECT $sql_tbl[register_fields].*, IF($sql_tbl[register_fields].avail LIKE '%$area%', 'Y', '') as avail, IF($sql_tbl[register_fields].required LIKE '%$area%', 'Y', '') as required, $sql_tbl[register_field_values].value FROM $sql_tbl[register_fields] LEFT JOIN $sql_tbl[register_field_values] ON $sql_tbl[register_fields].fieldid = $sql_tbl[register_field_values].fieldid AND $sql_tbl[register_field_values].login = '$user' ORDER BY $sql_tbl[register_fields].section, $sql_tbl[register_fields].orderby");
else
$fields = func_query("SELECT * FROM $sql_tbl[register_fields] ORDER BY section, orderby");
if($fields) {
foreach($fields as $k => $v) {
$fields[$k]['title'] = func_get_languages_alt("lbl_register_field_".$v['fieldid'], $shop_language);
if(!$area) {
$fields[$k]['avail'] = func_keys2hash($v['avail']);
$fields[$k]['required'] = func_keys2hash($v['required']);
} elseif($v['type'] == 'S' && $v['variants'])
$fields[$k]['variants'] = @explode(";", $v['variants']);
}
}
return $fields;
}
#
# Get additional register fields settings
#
function func_get_add_contact_fields($area = '', $user = '') {
global $sql_tbl, $current_language, $store_language;
if($area)
$fields = func_query("SELECT $sql_tbl[contact_fields].*, IF($sql_tbl[contact_fields].avail LIKE '%$area%', 'Y', '') as avail, IF($sql_tbl[contact_fields].required LIKE '%$area%', 'Y', '') as required, $sql_tbl[contact_field_values].value FROM $sql_tbl[contact_fields] LEFT JOIN $sql_tbl[contact_field_values] ON $sql_tbl[contact_fields].fieldid = $sql_tbl[contact_field_values].fieldid AND $sql_tbl[contact_field_values].login = '$user' ORDER BY $sql_tbl[contact_fields].orderby");
else
$fields = func_query("SELECT * FROM $sql_tbl[contact_fields] ORDER BY orderby");
if($fields) {
foreach($fields as $k => $v) {
$fields[$k]['title'] = func_get_languages_alt("lbl_contact_field_".$v['fieldid'], ($current_language?$current_language:$store_language));
if(!$area) {
$fields[$k]['avail'] = func_keys2hash($v['avail']);
$fields[$k]['required'] = func_keys2hash($v['required']);
} elseif($v['type'] == 'S' && $v['variants'])
$fields[$k]['variants'] = @explode(";", $v['variants']);
}
}
return $fields;
}
#
# Transform key string to hash-array
#
function func_keys2hash($arr) {
if(!$arr)
return array();
for($x = 0; $x < strlen($arr); $x++)
$tmp[$arr[$x]] = 'Y';
return $tmp;
}
#
# Callback function: determination of empty field
#
function func_callback_empty($value) {
return !empty($value);
}
#
# Get language variables name from templates chain
#
function func_get_lng_chain($name, &$templater) {
global $sql_tbl, $config, $shop_language, $current_area;
global $override_lng_code, $predefined_lng_variables;
$debug = $templater->debugging;
$templater->debugging = true;
$templater->fetch($name);
$templater->debugging = $debug;
if (!$templater->_smarty_debug_info)
return false;
$files = array();
if(!empty($predefined_lng_variables) && is_array($predefined_lng_variables))
$variables = $predefined_lng_variables;
else
$variables = array();
$exist = array();
foreach($templater->_smarty_debug_info as $v) {
if ($v['type'] != 'template' || $exist[$v['filename']])
continue;
$fp = @fopen($templater->template_dir."/".$v['filename'], "r");
if (!$fp)
continue;
$body = fread($fp, filesize($templater->template_dir."/".$v['filename']));
fclose($fp);
if (preg_match_all('/\$lng\.([\w\d_]+)[\}\s`\|]/US', $body, $preg))
$variables = array_merge($variables, $preg[1]);
$exist[$v['filename']] = true;
}
$page_content = $templater->get_template_vars("page_content");
if (!empty($page_content)) {
if (preg_match_all('/\$lng\.([\w\d_]+)[\}\s`\|]/US', $page_content, $preg))
$variables = array_merge($variables, $preg[1]);
}
unset($exist);
$lng = array();
if (!empty($variables)) {
$variables = array_flip($variables);
$lng_code = $override_lng_code;
if (empty($override_lng_code)) {
$lng_code = $shop_language;
}
func_get_lang_vars($lng_code, $variables, $lng);
if (!empty($variables)) {
func_get_lang_vars(($current_area == 'C'?$config['default_customer_language']:$config['default_admin_language']), $variables, $lng);
if (!empty($variables))
func_get_lang_vars('US', $variables, $lng);
}
if ($templater->webmaster_mode) {
func_webmaster_convert_labels($lng);
}
}
$templater->assign("lng", $lng);
unset($lng);
# clear info
$templater->_smarty_debug_info = array();
return true;
}
#
# Subroutine for the func_get_lng_chain()
#
function func_get_lang_vars($code, &$variables, &$lng) {
global $sql_tbl;
$labels = db_query("SELECT name, value FROM $sql_tbl[languages] WHERE code = '$code' AND name IN ('".implode("','", array_keys($variables))."')");
if ($labels) {
while ($v = db_fetch_array($labels)) {
$lng[$v['name']] = $v['value'];
unset($variables[$v['name']]);
}
db_free_result($labels);
}
}
#
# This function checks the user passwords with default values
#
function func_check_default_passwords($uname=false) {
global $sql_tbl, $active_modules;
$default_accounts["A"] = array("admin");
$default_accounts["P"] = array("provider", "master", "root");
if (!empty($active_modules["Simple_Mode"]))
unset($default_accounts["A"]);
$return = array();
if (!empty($uname)) {
#
# Check password security for specified user name
#
$account = func_query_first("SELECT login, password FROM $sql_tbl[customers] WHERE login='$uname'");
if ($account["login"] == text_decrypt($account["password"]))
$return[] = $account["login"];
}
else {
#
# Check password security for all default user names
#
foreach ($default_accounts as $usertype=>$accounts) {
foreach ($accounts as $login_) {
if (!empty($uname) and $uname != $login_)
continue;
$account = func_query_first("SELECT login, password FROM $sql_tbl[customers] WHERE login='$login_' AND usertype='$usertype'");
if (!empty($account)) {
if ($account["login"] == text_decrypt($account["password"]))
$return[] = $account["login"];
}
}
}
}
return $return;
}
#
# Smarty->display wrapper
#
function func_display($tpl, &$templater, $to_display = true) {
func_get_lng_chain($tpl, $templater);
if($to_display == true) {
$templater->display($tpl);
if(defined("START_TIME")) {
global $__sql_time;
$all_time = func_microtime()-START_TIME;
echo '';
}
} else
return $templater->fetch($tpl);
}
#
# Check CC processor's transaction type
#
function func_check_cc_trans_type($module_name, $type, $hash = array("P" => "P", "C" => "C", "R" => "R")) {
global $sql_tbl;
$return = false;
if(empty($type) || $type == 'P')
$return = $hash['P'];
elseif($type == 'C')
if(func_query_firest_cell("SELECT is_check FROM $sql_tbl[ccprocessors] WHERE module_name = '$module_name'"))
$return = $hash['C'];
elseif($type == 'R')
if(func_query_firest_cell("SELECT is_refund FROM $sql_tbl[ccprocessors] WHERE module_name = '$module_name'"))
$return = $hash['R'];
if(empty($return) && $return !== false)
$return = false;
return $return;
}
#
# Check CC processor's transaction type
#
function func_check_cc_trans ($module_name, $type, $hash = array()) {
global $sql_tbl;
$return = false;
if(empty($hash) && is_array($hash))
$hash = array("P" => "P", "C" => "C", "R" => "R");
if(empty($type))
$type = 'P';
if( $type == 'P') {
$return = $hash[$type];
} elseif($type == 'C') {
if(func_query_first_cell("SELECT is_check FROM $sql_tbl[ccprocessors] WHERE module_name = '$module_name'"))
$return = $hash[$type];
} elseif($type == 'R') {
if(func_query_first_cell("SELECT is_refund FROM $sql_tbl[ccprocessors] WHERE module_name = '$module_name'"))
$return = $hash[$type];
}
if(empty($return) && $return !== false)
$return = false;
return $return;
}
#
# Copy key field to hash key
#
function func_create_hash_keys($array, $key) {
if(empty($array) || empty($key) || !is_array($array))
return $array;
$return = array();
foreach($array as $v)
$return[$v[$key]] = $v;
return $return;
}
#
# Recalculate product count in Categories table and Categories counts table
#
function func_recalc_product_count($categoryid) {
global $sql_tbl, $config;
if(!is_array($categoryid))
$categoryid = array($categoryid);
if(empty($categoryid))
return false;
foreach($categoryid as $c) {
if(is_array($c))
$c = $c['categoryid'];
$product_count = func_query_first_cell ("SELECT COUNT(*) FROM $sql_tbl[products], $sql_tbl[products_categories] WHERE $sql_tbl[products].productid=$sql_tbl[products_categories].productid AND $sql_tbl[products].forsale='Y' AND $sql_tbl[products_categories].categoryid='$c'");
db_query("UPDATE $sql_tbl[categories] SET product_count='$product_count' WHERE categoryid='$c'");
$lvls = $config['membership_levels'];
$lvls[] = array("usertype" => "C", "membership" => "");
foreach($lvls as $m) {
if($m['usertype'] == 'C') {
$m['membership'] = addslashes($m['membership']);
if(func_query_first_cell("SELECT COUNT(*) FROM $sql_tbl[categories_subcount] WHERE categoryid = '$c' AND membership = '$m[membership]'")) {
db_query("UPDATE $sql_tbl[categories_subcount] SET product_count = '$product_count' WHERE categoryid = '$c' AND membership = '$m[membership]'");
} else {
db_query("INSERT INTO $sql_tbl[categories_subcount] (categoryid,membership,product_count) VALUES ('$c','$m[membership]','$product_count')");
}
}
}
}
return true;
}
#
# Recalculate child categories count in Categories counts table
#
function func_recalc_subcat_count($categoryid) {
global $sql_tbl, $config;
if(!is_array($categoryid))
$categoryid = array($categoryid);
if(empty($categoryid))
return false;
foreach($categoryid as $c) {
if(is_array($c))
$c = $c['categoryid'];
$path = func_query_first_cell("SELECT categoryid_path FROM $sql_tbl[categories] WHERE categoryid = '$c'")."/%";
$subcat_count = func_query_first_cell ("SELECT COUNT(*) FROM $sql_tbl[categories] USE INDEX (pam) WHERE categoryid_path LIKE '$path' AND avail = 'Y' AND membership = ''");
$lvls = $config['membership_levels'];
$lvls[] = array("usertype" => "C", "membership" => "");
foreach($lvls as $m) {
if($m['usertype'] == 'C') {
$m['membership'] = addslashes($m['membership']);
$subcat_count = func_query_first_cell ("SELECT COUNT(*) FROM $sql_tbl[categories] WHERE categoryid_path LIKE '$path' AND avail = 'Y' AND membership = '$m[membership]'");
db_query("REPLACE INTO $sql_tbl[categories_subcount] (categoryid,subcategory_count,membership) VALUES ('$c','$subcat_count','$m[membership]')");
}
}
func_recalc_product_count($c);
}
return true;
}
#
# This function gathers the product taxes information
#
function func_get_product_taxes(&$product, $login, $calculate_discounted_price=false, $taxes="") {
global $sql_tbl, $config, $active_modules;
if ($calculate_discounted_price && isset($product["discounted_price"]))
$price = $product["discounted_price"];
else
$price = $product["price"];
$amount = (isset($product["amount"]) ? $product["amount"] : 1);
if (empty($taxes))
$taxes = func_get_product_tax_rates($product, $login);
foreach ($taxes as $k=>$tax_rate) {
if ($tax_rate["price_includes_tax"] != "Y" or $product["price_deducted_tax"] == "Y")
continue;
if ($tax_rate["rate_type"] == "%") {
$_tax_value = $price - $price*100/($tax_rate["rate_value"] + 100);
$price = $price - $_tax_value;
}
else
$price = $price - $tax_rate["rate_value"];
$product["price"] = $price;
$product["price_deducted_tax"] = "Y";
}
$taxed_price = $price;
$formula_data["ST"] = $price;
foreach ($taxes as $k=>$tax_rate) {
#
# Calculate the tax value
#
if (!empty($tax_rate["skip"]) or (empty($login) and $config["General"]["apply_default_country"] != "Y"))
continue;
$assessment = func_calculate_assessment($tax_rate["formula"], $formula_data);
if ($tax_rate["rate_type"] == "%") {
$tax_rate["tax_value_precise"] = $assessment * $tax_rate["rate_value"] / 100;
$tax_rate["tax_value"] = price_format($tax_rate["tax_value_precise"]);
}
else
$tax_rate["tax_value"] = $tax_rate["tax_value_precise"] = $tax_rate["rate_value"];
$tax_rate["taxed_price"] = $price + $tax_rate["tax_value"];
if ($tax_rate["display_including_tax"] == "Y")
$taxed_price += $tax_rate["tax_value"];
$taxes[$k] = $tax_rate;
$formula_data[$k] = $tax_rate["tax_value"];
}
if (is_array($taxes)) {
foreach ($taxes as $k=>$v) {
$taxes[$k]["tax_value"] = $v["tax_value_precise"] * $amount;
}
}
$product["taxed_price"] = price_format($taxed_price);
//print_r($taxes);
return $taxes;
}
#
# This function generate the product tax rates array
#
function func_get_product_tax_rates($product, $login) {
global $sql_tbl, $shop_language;
global $user_account;
$productid = $product["productid"];
$tax_rates = array();
#
# Gather all taxes defined for store
#
$taxes = func_query("SELECT $sql_tbl[taxes].* FROM $sql_tbl[taxes], $sql_tbl[product_taxes] WHERE $sql_tbl[taxes].taxid=$sql_tbl[product_taxes].taxid AND $sql_tbl[product_taxes].productid='$productid' AND $sql_tbl[taxes].active='Y' ORDER BY $sql_tbl[taxes].priority");
if (is_array($taxes)) {
#
# Generate tax rates array
#
$membership = $user_account["membership"];
foreach ($taxes as $k=>$v) {
if (!isset($address_zones[$v["address_type"]]))
if (defined('XAOM')) {
$address_zones[$v["address_type"]] = func_get_customer_zones_avail($user_account, $product["provider"], $v["address_type"]);
}
else {
$address_zones[$v["address_type"]] = func_get_customer_zones_avail($login, $product["provider"], $v["address_type"]);
}
$zones = $address_zones[$v["address_type"]];
$tax_rate = "";
foreach ($zones as $zoneid=>$p) {
$tax_rate = func_query_first("SELECT taxid, formula, rate_value, rate_type FROM $sql_tbl[tax_rates] WHERE taxid='$v[taxid]' AND zoneid='$zoneid' AND (membership='$membership' OR membership='') ORDER BY membership DESC");
if (!empty($tax_rate))
break;
}
if (empty($tax_rate)) {
if ($v["price_includes_tax"] != "Y")
continue;
$tax_rate = func_query_first("SELECT taxid, formula, rate_value, rate_type FROM $sql_tbl[tax_rates] WHERE taxid='$v[taxid]' ORDER BY rate_value DESC LIMIT 1");
$tax_rate["skip"] = true;
}
if (empty($tax_rate["formula"]))
$tax_rate["formula"] = $v["formula"];
$tax_rate["rate_value"] *= 1;
$tax_rate["tax_display_name"] = func_get_languages_alt("tax_".$v["taxid"], $shop_language);
$tax_rate = func_array_merge($v, $tax_rate);
$tax_rates[$v["tax_name"]] = $tax_rate;
}
}
return $tax_rates;
}
#
# This function get the taxed price
#
function func_tax_price($price, $productid=0, $disable_abs=false, $discounted_price=0, $customer_info="", $taxes="", $price_deducted_tax=false) {
global $sql_tbl, $config, $active_modules, $shop_language;
if (empty($customer_info)) {
global $login;
$customer_info["login"] = $login;
}
$return_taxes = array();
if ($discounted_price == 0)
$discounted_price = $price;
if ($productid > 0) {
#
# Get product taxes
#
$product = func_query_first("SELECT productid, provider, free_shipping, shipping_freight, distribution, '$price' as price FROM $sql_tbl[products] WHERE productid='$productid'");
$taxes = func_get_product_tax_rates($product, $customer_info["login"]);
}
if (is_array($taxes)) {
#
# Calculate price and tax_value
#
foreach ($taxes as $k=>$tax_rate) {
if ($tax_rate["price_includes_tax"] != "Y" or $price_deducted_tax)
continue;
if ($tax_rate["rate_type"] == "%") {
$_tax_value = $price - $price*100/($tax_rate["rate_value"] + 100);
$price -= $_tax_value;
if ($discounted_price > 0)
$_tax_value = $discounted_price - $discounted_price*100/($tax_rate["rate_value"] + 100);
$discounted_price -= $_tax_value;
}
else {
$price -= $tax_rate["rate_value"];
$discounted_price -= $tax_rate["rate_value"];
}
}
$taxed_price = $discounted_price;
$formula_data["ST"] = $price;
$formula_data["DST"] = $discounted_price;
foreach ($taxes as $k=>$v) {
if (!empty($v["skip"]))
continue;
if ($v["display_including_tax"] != "Y")
continue;
if ($v["rate_type"] == "%") {
$assessment = func_calculate_assessment($v["formula"], $formula_data);
$tax_value = price_format($assessment * $v["rate_value"] / 100);
}
elseif (!$disable_abs)
$tax_value = $v["rate_value"];
$formula_data[$v["tax_name"]] = $tax_value;
$taxed_price += $tax_value;
$return_taxes["taxes"][$v["taxid"]] = $tax_value;
}
}
$return_taxes["taxed_price"] = $taxed_price;
return $return_taxes;
}
#
# This function cacluate the assessment according to the formula string
#
function func_calculate_assessment($formula, $formula_data) {
$return = 0;
if (is_array($formula_data)) {
# Correct the default values...
if (empty($formula_data["DST"]))
$formula_data["DST"] = $formula_data["ST"];
if (empty($formula_data["SH"]))
$formula_data["SH"] = 0;
# Preparing math expression...
$_formula = $formula;
foreach ($formula_data as $unit=>$value) {
if (!is_numeric($value))
$value = 0;
$_formula = preg_replace("/\b".preg_quote($unit)."\b/", $value, $_formula);
}
$to_eval = "\$return = $_formula;";
# Perform math expression...
eval($to_eval);
}
return $return;
}
#
# Search images in message body and return message body and images array
#
function func_attach_images($message) {
global $http_location, $xcart_web_dir, $xcart_dir, $current_location;
# Get images location
$hash = array();
if(preg_match_all("/\s(?:src=|background=|(?:style=['\"].*url\())['\"]([^'\"]+)['\"]/SsUi", $message, $preg))
$hash = $preg[1];
if(empty($hash))
return array($message, array());
# Get images data
$names = array();
$images = array();
foreach($hash as $v) {
$orig_name = $v;
$parse = parse_url($v);
$data = "";
$file_path = "";
if(empty($parse['scheme'])) {
$v = str_replace($xcart_web_dir, "", $parse['path']);
$file_path = $xcart_dir.str_replace("/", DIRECTORY_SEPARATOR, $v);
$v = $http_location.$v;
} elseif(strpos($v, $current_location) === 0) {
$file_path = $xcart_dir.str_replace("/", DIRECTORY_SEPARATOR,substr($v, strlen($current_location)));
}
if(file_exists($file_path) && is_readable($file_path)) {
$fp = @fopen($file_path, "rb");
if($fp) {
$data = fread($fp, filesize($file_path));
fclose($fp);
}
}
if(!empty($images[$v])) {
continue;
}
$tmp = array("name" => basename($v), "url" => $v, "data" => $data);
if($names[$tmp['name']]) {
$cnt = 1;
$name = $tmp['name'];
while ($names[$tmp['name']]) {
$tmp['name'] = $name.$cnt++;
}
}
$names[$tmp['name']] = true;
if (empty($tmp['data'])) {
if ($fp = @fopen($tmp['url'], "rb")) {
do {
$tmpdata = fread($fp, 8192);
if (strlen($tmpdata) == 0) {
break;
}
$tmp['data'] .= $tmpdata;
} while (true);
fclose($fp);
} else {
continue;
}
}
list($tmp1, $tmp2, $tmp3, $tmp['type']) = func_get_image_size(empty($data)?$tmp['url']:$file_path);
$message = preg_replace("/(['\"])".str_replace("/", "\/", preg_quote($orig_name))."(['\"])/Ss", "\\1cid:".$tmp['name']."\\2", $message);
$images[$tmp['url']] = $tmp;
}
return array($message, $images);
}
#
# Normalize path: remove "../", "./" and duplicated slashes
#
function func_normalize_path($path, $separator=DIRECTORY_SEPARATOR) {
$qs = preg_quote($separator);
$path = preg_replace("/[\\\\\/]+/S",$separator,$path);
$path = preg_replace("!".$qs."\.".$qs."!S", $separator, $path);
$regexp = "!".$qs."[^".$qs."]+".$qs."\.\.".$qs."!S";
for ($old="", $prev="1"; $old != $path; $path = preg_replace($regexp, $separator, $path)) {
$old = $path;
}
return $path;
}
#
# Get MD5 hash files data
#
function func_md5_hash_files_data($filename) {
global $xcart_dir;
$fp = @fopen($filename, 'r');
if(!$fp)
return false;
$return = array();
while($arr = fgetcsv($fp, 1024, "=")) {
$name = $xcart_dir."/".$arr[0];
$md5 = @md5_file($name);
$falg = true;
if($md5 != $arr[1])
$flag = false;
$return[] = array("file" => $arr[0], "orig_md5" => $arr[1], "md5" => $md5, "equal" => $flag);
}
return $return;
}
#
# Translate products names to local product names
#
function func_translate_products($products, $code) {
global $sql_tbl;
if(!is_array($products) || empty($products) || empty($code))
return $products;
$hash = array();
foreach($products as $k => $p) {
$hash[$p['productid']][] = $k;
}
if(!empty($hash)) {
foreach($hash as $pid => $keys) {
$local = func_query_first("SELECT product, descr, full_descr as fulldescr FROM $sql_tbl[products_lng] WHERE productid = '$pid' AND code = '$code'");
if(!empty($local)) {
foreach($keys as $k) {
$products[$k] = func_array_merge($products[$k], $local);
}
}
}
}
return $products;
}
#
# Remove parameters from QUERY_STRING by name
#
function func_qs_remove($qs, $param_name) {
$pn = preg_quote($param_name,"!")."(\[[^&]*\])?";
$qs = preg_replace("!(&?)(".$pn.")=\w*!S", "", $qs);
$qs = preg_replace("!^&!S", "", $qs);
return $qs;
}
#
# Detectd ESD product(s) in cart
#
function func_esd_in_cart($cart) {
if(!empty($cart['products'])) {
foreach($cart['products'] as $p) {
if(!empty($p['distribution'])) {
return true;
}
}
}
return false;
}
#
# Covert XML string to hash array
#
function func_xml2hash($str) {
$str = (string)$str;
$hash = array();
for($x = 0; $x < strlen($str); $x++) {
if ($str[$x] == '<') {
$x++;
if($str[$x] == "?") {
$x = strpos(substr($str, $x), ">");
continue;
}
$tmp = substr($str, $x);
$c_name = substr($tmp, 0, strpos($tmp, ">"));
$sub_data = array();
$x += strlen($c_name)+1;
$is_single = false;
if (strpos($c_name, " ") !== false) {
if(substr($c_name, -1) == '/') {
$c_name = substr($c_name, 0, -1);
$is_single = true;
}
$sub_data = explode(" ", $c_name);
$c_name = trim(array_shift($sub_data));
}
if(empty($c_name))
return false;
$tmp = substr($str, $x);
if(preg_match("/^(.*)<\/".preg_quote($c_name).">/USs", $tmp, $data)) {
$hash[$c_name] = func_xml2hash($data[1]);
$x += strlen($data[1])+2+strlen($c_name);
} elseif(!$is_single) {
return false;
} elseif($sub_data) {
foreach($sub_data as $sd) {
list($key, $value) = explode("=", trim($sd));
$hash[$c_name][][$key] = preg_replace("/^['\"](.+)['\"]$/S", "\\1", $value);
}
}
}
}
if(empty($hash))
$hash = $str;
return $hash;
}
#
# Convert hash array to XML string
#
function func_hash2xml($hash, $level = 0) {
if(!is_array($hash) || empty($hash))
return $hash;
foreach($hash as $k => $v) {
$xml .= str_repeat("\t", $level)."<$k>".func_hash2xml($v, $level+1)."$k>\n";
}
if($level > 0) {
$xml = "\n".$xml."\n".str_repeat("\t", $level);;
}
return $xml;
}
#
# Convert array to suitable-for-search string
#
function func_sql_serialize($arr) {
if(empty($arr) || !is_array($arr))
return $arr;
return "|".implode("||", $arr)."|";
}
#
# Convert suitable-for-search string to array
#
function func_sql_unserialize($str) {
if(empty($str) || is_array($str))
return $str;
return explode("||", substr($str, 1, -1));
}
#
# Function to get backtrace for debugging
#
function func_get_backtrace($skip=0) {
$result = array();
if (!function_exists('debug_backtrace')) {
$result[] = '[func_get_backtrace() is supported only for PHP version 4.3.0 or better]';
return $result;
}
$trace = debug_backtrace();
if (is_array($trace) && !empty($trace)) {
if ($skip>0) {
if ($skip < count($trace))
$trace = array_splice($trace, $skip);
else
$trace = array();
}
foreach ($trace as $item) {
$result[] = $item['file'].':'.$item['line'];
}
}
if (empty($result)) {
$result[] = '[empty backtrace]';
}
return $result;
}
?>