X-Cart: shopping cart software

X-Cart forums (https://forum.x-cart.com/index.php)
-   Dev Questions (https://forum.x-cart.com/forumdisplay.php?f=20)
-   -   SMTP mail function (https://forum.x-cart.com/showthread.php?t=21398)

MallRomania 04-27-2006 02:34 AM

SMTP mail function
 
I ask tehnical support how can i use SMTP function to send mail...the answer is listed below (please consider this mod as a big thanks to all who create and publish free mods here)

> 1. Download PHPMailer class
> http://prdownloads.sourceforge.net/phpmailer/phpmailer-1.73.zip?download
>
> 2. Extract the archive and copy phpmailer directory to [xcart root
> directory]/include/ folder of your x-cart (for example, using FTP client).
>
> 3. Open Patch/Upgrade page of x-cart admin area, paste the following SQL query
> into Apply SQL patch memo box:
>
> insert into xcart_config values ('use_smtp', 'Use SMTP server', '', 'Email', '',
> 'checkbox', ''), ('smtp_server', 'SMTP server', '', 'Email', '', 'text', ''),
> ('smtp_user', 'SMTP AUTH username', '', 'Email', '', 'text', ''),
> ('smtp_password', 'SMTP AUTH password', '', 'Email', '', 'text', '');
>
> 4. Open include/func.php file, find definition of func_send_mail function and
> replace in the function:

if (preg_match('/([^ @,;<>]+@[^ @,;<>]+)/S', $from, $m))
@mail($to,$mail_subject,$mail_message,$headers, "-f".$m[1]);
else
@mail($to,$mail_subject,$mail_message,$headers);


with:

//added 1
if ($config['Email']['use_smtp'] == 'Y') {
if (empty($config['Email']['smtp_server'])) {
return;
}

global $xcart_dir;
require_once $xcart_dir."/include/phpmailer/class.smtp.php";

$smtp = new SMTP();
#$smtp->do_debug = true;
if (!$smtp->Connect($config['Email']['smtp_server'])) {
$smtp->Close();
return false;
}
if (!$smtp->Hello()) {
$smtp->Close();
return false;
}
if (!empty($config['Email']['smtp_user'])) {
if (!$smtp->Authenticate($config['Email']['smtp_user'], $config['Email']['smtp_password'])) {
$smtp->Close();
return false;
}
}
if (!$smtp->Mail($m_from)) {
$smtp->Close();
return false;
}
$recipients = preg_split("/[,\s]+/", $to);
$recipients = array_map("trim", $recipients);
foreach ($recipients as $r) {
if (empty($r)) {
continue;
}
if (!$smtp->Recipient($r)) {
$smtp->Close();
return;
}
}
if (!$smtp->Data("To:" . $to . $lend . "Subject: " . $mail_subject.$lend.$headers.$lend.$mail_message)) {
$smtp->Close();
return;
}
$smtp->Quit();
$smtp->Close();
} else {
if (preg_match('/([^ @,;<>]+@[^ @,;<>]+)/S', $from, $m))
@mail($to,$mail_subject,$mail_message,$headers, "-f".$m[1]);
else
@mail($to,$mail_subject,$mail_message,$headers);
}
//end added 1
}


__________________________________________________ ___________
Next step: Function func_send_simple_mail:

replace:

if (preg_match('/([^ @,;<>]+@[^ @,;<>]+)/S', $from, $m))
@mail($to,$mail_subject,$mail_message,$headers, "-f".$m[1]);
else
@mail($to,$mail_subject,$mail_message,$headers);

with:


//added 2
if ($config['Email']['use_smtp'] == 'Y') {
if (empty($config['Email']['smtp_server'])) {
return;
}

global $xcart_dir;
require_once $xcart_dir."/include/phpmailer/class.smtp.php";

$smtp = new SMTP();
#$smtp->do_debug = true;
if (!$smtp->Connect($config['Email']['smtp_server'])) {
$smtp->Close();
return false;
}
if (!$smtp->Hello()) {
$smtp->Close();
return false;
}
if (!empty($config['Email']['smtp_user'])) {
if (!$smtp->Authenticate($config['Email']['smtp_user'], $config['Email']['smtp_password'])) {
$smtp->Close();
return false;
}
}
if (!$smtp->Mail($m_from)) {
$smtp->Close();
return false;
}
$recipients = preg_split("/[,\s]+/", $to);
$recipients = array_map("trim", $recipients);
#echo "<pre><h1>RECIPIENTS:"; var_dump($recipients); echo "</h1></pre>";
foreach ($recipients as $r) {
if (empty($r)) {
continue;
}
if (!$smtp->Recipient($r)) {
$smtp->Close();
return;
}
}
if (!$smtp->Data("To:" . $to . $lend . "Subject: " . $m_subject.$lend.$headers.$lend.$body)) {
$smtp->Close();
return;
}
$smtp->Quit();
$smtp->Close();
} else {
if (preg_match('/([^ @,;<>]+@[^ @,;<>]+)/S', $from, $m))
@mail($to,$mail_subject,$mail_message,$headers, "-f".$m[1]);
else
@mail($to,$mail_subject,$mail_message,$headers);
}
//end added 2




5. Open General settings > Email options page, tick "Use SMTP server" option and
> enter server name of the SMTP server and login/password if your server requires
> SMTP authorization. Save the changes and try, for example, change customer
> profile in customer area or place an order, you should receive an email via SMTP
> server configured at the Email options page.


Note from me: keep ticked internal PHP mailer for sending newsletters and if it need add SMTP AUTH username and password, in my case it's not working without that

Also, please note that original post from tehnical department was modified meanwhile so i hope i put here all information you need

Thanks

balinor 04-27-2006 05:19 PM

Good to know, thanks for posting!

Dongan 04-27-2006 05:54 PM

really useful. thanks for sharing ....

jvleigh 04-28-2006 03:14 PM

I just tried that mod and it caused X-cart to show a blank screen both in the admin area and customer area.

Was there anything that might have been left out?

What version did you have it working on?

Thanks.

MallRomania 04-28-2006 11:02 PM

I have x-cart gold 4.0.18 on linux.

Here is both functions for sending mail from include/func.php


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;


$from = preg_replace('![\x00-\x1f].*$!sm', '', $from);

$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,f alse));

if (X_DEF_OS_WINDOWS) {
$mail_message = preg_replace("/(?<!\r)\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.$l end;
$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;
//old function
//if (preg_match('/([^ @,;<>]+@[^ @,;<>]+)/S', $from, $m))
//@mail($to,$mail_subject,$mail_message,$headers, "-f".$m[1]);
//else
//@mail($to,$mail_subject,$mail_message,$headers);
//end old
//adaugat
if ($config['Email']['use_smtp'] == 'Y') {
if (empty($config['Email']['smtp_server'])) {
return;
}

global $xcart_dir;
require_once $xcart_dir."/include/phpmailer/class.smtp.php";

$smtp = new SMTP();
#$smtp->do_debug = true;
if (!$smtp->Connect($config['Email']['smtp_server'])) {
$smtp->Close();
return false;
}
if (!$smtp->Hello()) {
$smtp->Close();
return false;
}
if (!empty($config['Email']['smtp_user'])) {
if (!$smtp->Authenticate($config['Email']['smtp_user'], $config['Email']['smtp_password'])) {
$smtp->Close();
return false;
}
}
if (!$smtp->Mail($m_from)) {
$smtp->Close();
return false;
}
$recipients = preg_split("/[,\s]+/", $to);
$recipients = array_map("trim", $recipients);
foreach ($recipients as $r) {
if (empty($r)) {
continue;
}
if (!$smtp->Recipient($r)) {
$smtp->Close();
return;
}
}
if (!$smtp->Data("To:" . $to . $lend . "Subject: " . $mail_subject.$lend.$headers.$lend.$mail_message)) {
$smtp->Close();
return;
}
$smtp->Quit();
$smtp->Close();
} else {
if (preg_match('/([^ @,;<>]+@[^ @,;<>]+)/S', $from, $m))
@mail($to,$mail_subject,$mail_message,$headers, "-f".$m[1]);
else
@mail($to,$mail_subject,$mail_message,$headers);
}
//end adaugat
}

__________________________________________________ __________



function func_send_simple_mail($to, $subject, $body, $from) {
global $config;
global $current_language;
global $sql_tbl;

if (empty($to)) return;


$from = preg_replace('![\x00-\x1f].*$!sm', '', $from);

if (X_DEF_OS_WINDOWS) {
$body = preg_replace("/(?<!\r)\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);
//adaugat 2
if ($config['Email']['use_smtp'] == 'Y') {
if (empty($config['Email']['smtp_server'])) {
return;
}

global $xcart_dir;
require_once $xcart_dir."/include/phpmailer/class.smtp.php";

$smtp = new SMTP();
#$smtp->do_debug = true;
if (!$smtp->Connect($config['Email']['smtp_server'])) {
$smtp->Close();
return false;
}
if (!$smtp->Hello()) {
$smtp->Close();
return false;
}
if (!empty($config['Email']['smtp_user'])) {
if (!$smtp->Authenticate($config['Email']['smtp_user'], $config['Email']['smtp_password'])) {
$smtp->Close();
return false;
}
}
if (!$smtp->Mail($m_from)) {
$smtp->Close();
return false;
}
$recipients = preg_split("/[,\s]+/", $to);
$recipients = array_map("trim", $recipients);
#echo "<pre><h1>RECIPIENTS:"; var_dump($recipients); echo "</h1></pre>";
foreach ($recipients as $r) {
if (empty($r)) {
continue;
}
if (!$smtp->Recipient($r)) {
$smtp->Close();
return;
}
}
if (!$smtp->Data("To:" . $to . $lend . "Subject: " . $m_subject.$lend.$headers.$lend.$body)) {
$smtp->Close();
return;
}
$smtp->Quit();
$smtp->Close();
} else {
if (preg_match('/([^ @,;<>]+@[^ @,;<>]+)/S', $from, $m))
@mail($to,$mail_subject,$mail_message,$headers, "-f".$m[1]);
else
@mail($to,$mail_subject,$mail_message,$headers);
}
//end adaugat 2
}

jherzog 08-26-2006 03:54 PM

Re: SMTP mail function
 
Off hand, does anyone know if this should or should not work with version 4.0.17?

Thanks,
Jed

adriant 12-04-2006 07:25 AM

Re: SMTP mail function
 
I so need a mod like this so I thought I would have a poke around and see if the code was anywhere to found in 4.1.

It is... it has moved into func.mail.php. Both the sections can be found there. So I overwrote the required code with that supplied. Had to hand code the SQL as the number of fields are different from 4.0 to 4.1 but quite easy to see what was needed.

Made all the changes in the Email configuration screen in XCart.

Went to the site and did a simple Product Recomendation and it went to a white screen. Clicked refresh a couple of times, still a white screen.

Ran Outlook and checked for the emails.... nothing there so waited for 10 minutes... still nothing there.

Thought - oh well! never mind - nice if it had worked.....

Replaced the func.mail.php with the original. Went back to the white screen and clicked refresh and low and behold the product page came back.

A couple of seconds later the email came through... how weird!

Just not a programmer... can't figure out where the 'return' is failing. I just hope that someone here can. Please....

Adrian

kyngchaos 12-11-2006 09:11 AM

Re: SMTP mail function
 
Here's my version for XCart 4.1.3. I also switched to the PEAR mail functions, since my Geeklog site already uses it.

The key difference I found over the 4.0.x version is that 4.1 added a field to the config options database, so the SQL insert needed updating.

1. For PEAR Mail:

If you have access to your PHP installation, this is the easiest. In a shell type (path to your PHP bin dir must be in your PATH):

sudo pear install --alldeps Mail

This will install Mail and dependencies (just a few) in PHP's lib dir and be instantly available to all PHP programs.

If you prefer to install Mail somewhere else (ie you are using a hosting service and can't change PHP), you can install it in the XCart dir as in the XCart 4.0 example. Either download Mail, SMTP, Socket, SASL and manually install them (no details), or you might be able to set php_dir with the config-set option to pear. There are also ways to install local copies of PEAR for use on hosting services. See the PEAR documentation. If someone can fill in some of these methods, please do so.

2. XCart config options.

The new SQL insert should be: (note, I also added a SMTP Port option, and explicitly ordered the options):

insert into xcart_config values ('use_smtp', 'Use SMTP server', '', 'Email', '1', 'checkbox', '', ''), ('smtp_server', 'SMTP server', '', 'Email', '2', 'text', '', ''), ('smtp_port', 'SMTP port', '', 'Email', '3', 'numeric', '25', ''), ('smtp_user', 'SMTP AUTH username', '', 'Email', '4', 'text', '', ''), ('smtp_password', 'SMTP AUTH password', '', 'Email', '5', 'text', '', '');

The SMTP Auth option might also be useful to some, and can be added if needed.

3. Mail functions.

As mentioned, both mail functions are now in a single file: func.mail.php.

In func_send_mail(), replace the whole block:

list($message_header, $mail_message) = func_parse_mail($msgs);

$mail_from = $from;
if ($config["Email"]["use_base64_headers"] == "Y")
$mail_subject = func_mail_quote($mail_subject,$charset);

$headers = "From: ".$mail_from.$lend."X-Mailer: PHP/".phpversion().$lend."MIME-Version: 1.0".$lend.$message_header;
if (trim($mail_from) != "")
$headers .= "Reply-to: ".$mail_from.$lend;

if (preg_match('/([^ @,;<>]+@[^ @,;<>]+)/S', $from, $m)) {
return @mail($to,$mail_subject,$mail_message,$headers, "-f".$m[1]);
} else {
return @mail($to,$mail_subject,$mail_message,$headers);
}

with:

// customize
$mail_from = $from;
if ($config["Email"]["use_base64_headers"] == "Y")
$mail_subject = func_mail_quote($mail_subject,$charset);

if ($config['Email']['use_smtp'] == 'Y') {
if (empty($config['Email']['smtp_server'])) return;

include_once( 'Mail.php' );
include_once( 'Mail/RFC822.php' );

$mail_settings = array(
'host' => $config['Email']['smtp_server'],
'port' => $config['Email']['smtp_port'],
'username' => $config['Email']['smtp_user'],
'password' => $config['Email']['smtp_password']
);
$mailobj =& Mail::factory( "smtp", $mail_settings );
if (!is_object($mailobj) || !get_class($mailobj) == 'Mail_smtp') return;

list($message_header, $mail_message) = func_parse_mail($msgs, 0, true);

$message_header['To'] = $to;
$message_header['Subject'] = $mail_subject;
$message_header['From'] = $mail_from;
$message_header['X-Mailer'] = "PHP/".phpversion();

$senderr = $mailobj->send( $to, $message_header, $mail_message );
} else {

list($message_header, $mail_message) = func_parse_mail($msgs);
$headers = "From: ".$mail_from.$lend."X-Mailer: PHP/".phpversion().$lend."MIME-Version: 1.0".$lend.$message_header;
if (trim($mail_from) != "")
$headers .= "Reply-to: ".$mail_from.$lend;

if (preg_match('/([^ @,;<>]+@[^ @,;<>]+)/S', $from, $m)) {
return @mail($to,$mail_subject,$mail_message,$headers, "-f".$m[1]);
} else {
return @mail($to,$mail_subject,$mail_message,$headers);
}
}
// end customize

Replace the whole func_parse_mail() function with (PEAR Mail uses arrays for headers):

// customize
function func_parse_mail($msgs, $level = 0, $inarray = false) {

if (empty($msgs))
return false;

$lend = (X_DEF_OS_WINDOWS?"\r\n":"\n");
$head = "";
$heada = array();
$msg = "";

# Subarray
if (is_array($msgs['content'])) {
# Subarray is full
if(count($msgs['content']) > 1) {
$boundary = substr(uniqid(time()+rand()."_"), 0, 16);
$msgs['header']['Content-Type'] .= ";$lend\t boundary=\"$boundary\"";
foreach($msgs['header'] as $k => $v) {
if ($inarray) {
$heada[$k] = $v;
} else {
$head .= $k.": ".$v.$lend;
}
}

if($level > 0)
$msg = $head.$lend;

for($x = 0; $x < count($msgs['content']); $x++) {
// only top level can be returned as array
$res = func_parse_mail($msgs['content'][$x], $level+1);
$msg .= "--".$boundary.$lend.$res[1].$lend;
}

$msg .= "--".$boundary."--".$lend;
} else {
# Subarray have only one element
list($msgs['header'], $msgs['content']) = func_parse_mail($msgs['content'][0], $level, (($level>0)?false:$inarray));
}
}

# Current array - atom
if (!is_array($msgs['content'])) {
if (is_array($msgs['header']))
foreach ($msgs['header'] as $k => $v) {
if ($inarray) {
$heada[$k] = $v;
} else {
$head .= $k.": ".$v.$lend;
}
}

if ($level > 0)
$msg = $head.$lend;

$msg .= $msgs['content'].$lend;
}

# Header substitute
if (empty($head)) {
if (is_array($msgs['header'])) {
foreach ($msgs['header'] as $k => $v) {
if ($inarray) {
$heada[$k] = $v;
} else {
$head .= $k.": ".$v.$lend;
}
}
} else {
$head = $msgs['header'];
}
}

if ($inarray) {
return array($heada, $msg);
} else {
return array($head, $msg);
}
}
// end customize

And in func_send_simple_mail() replace:

$headers_str = "";
foreach ($headers as $hfield=>$hval)
$headers_str .= $hfield.": ".$hval.$lend;

if (preg_match('/([^ @,;<>]+@[^ @,;<>]+)/S', $from, $m))
@mail($to,$m_subject,$body,$headers_str, "-f".$m[1]);
else
@mail($to,$m_subject,$body,$headers_str);

with:

// customize
if ($config['Email']['use_smtp'] == 'Y') {
if (empty($config['Email']['smtp_server'])) return;

include_once( 'Mail.php' );
include_once( 'Mail/RFC822.php' );

$mail_settings = array(
'host' => $config['Email']['smtp_server'],
'port' => $config['Email']['smtp_port'],
'username' => $config['Email']['smtp_user'],
'password' => $config['Email']['smtp_password']
);
$mailobj =& Mail::factory( "smtp", $mail_settings );
if (!is_object($mailobj) || !get_class($mailobj) == 'Mail_smtp') return;

$headers['To'] = $to;
$headers['Subject'] = $m_subject;
list( $usec, $sec ) = explode( ' ', microtime());
$m = substr( $usec, 2, 5 );
$headers['Message-Id'] = '<' . date( 'YmdHis' ) . '.' . $m
. '@' . $config['Email']['smtp_server'] . '>';

return $mailobj->send( $to, $headers, $body );

} else {
$headers_str = "";
foreach ($headers as $hfield=>$hval)
$headers_str .= $hfield.": ".$hval.$lend;

if (preg_match('/([^ @,;<>]+@[^ @,;<>]+)/S', $from, $m))
@mail($to,$m_subject,$body,$headers_str, "-f".$m[1]);
else
@mail($to,$m_subject,$body,$headers_str);
}
// end customize


If you install PEAR Mail outside the PHP lib dir, you will have add that location to the PHP Include Path:

ini_set("include_path","/path/to/custom/install/dir" . ini_get("include_path"));

before including them (I think that'll work). Don't just include the full path to Mail.php, since it also includes its dependencies from the include_path.

shopccp 03-13-2007 11:54 AM

Re: SMTP mail function
 
My version of x-cart gold (4.1.6) windows does not show the smtp server configuration inside general settings/ email options.


Justin

WJ Birmingham 04-09-2007 07:49 AM

Re: SMTP mail function
 
I'd really like to know the logic behind why this is not implemented in the cart.

Not having SMTP authentication in this day/age is simply asking for your e-mail server to be router black listed when some punk starts sending thousands of e-mails through your non-authenticated server.


All times are GMT -8. The time now is 01:21 AM.

Powered by vBulletin Version 3.5.4
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.