Post by SubCon » Fri Sep 11, 2009 8:21 am

Ok some people have asked me to post a this tutorial, finally I got around to it, so here goes:
===================
Why: I had a problem with mail on may host (leadhoster.com), info on my other post here: http://forum.opencart.com/viewtopic.php?f=20&t=5850.
------------------------------------
1. Download PHPMailer script here: http://sourceforge.net/projects/phpmailer/files/
There are 2 versions for PHP4 and PHP5/6, choose ther latest from what php version you need. Also in PHP5/6 there is a jump from v2.3 to v5.0.2 You actually can use either but obviously v5.0.2 is the latest.

2. Now we need to integrate this script into the system. The PHPMailer script actually built of 3 files:

Code: Select all

class.phpmailer.php
class.pop3.php
class.smtp.php
So we gonna put them in the system/library folder. To be more precise only the class.phpmailer.php is essential but the others needed if you use smtp or pop3 mail system (may be host dependent). Please refer to the documentation for more info on this.

3. To make the system use PHPMailer instead of the other mailing script we need to edit system/startup.php:
find

Code: Select all

require_once(DIR_SYSTEM . 'library/mail.php');
comment or replace it by:

Code: Select all

require_once(DIR_SYSTEM . 'library/class.phpmailer.php');
4. Now we need to edit the relevant code that actually sends the mail, to use the correct syntax for PHPMailer:
I am going to show how its done on one of the files so you get the idea for the rest of them.
Lets use the file which sends the confirmation mail at the end of the order. The mail is sent to the customer and another one to the owner, both in the same file: catalog/model/checkout/order.php

Send to customer starts at line 100:

Code: Select all

$mail = new Mail($this->config->get('config_mail_protocol'), $this->config->get('config_smtp_host'), $this->config->get('config_smtp_username'), html_entity_decode($this->config->get('config_smtp_password')), $this->config->get('config_smtp_port'), $this->config->get('config_smtp_timeout')); 
			$mail->setTo($order_query->row['email']);
			$mail->setFrom($this->config->get('config_email'));
			$mail->setSender($this->config->get('config_store'));
			$mail->setSubject($subject);
			$mail->setText($message);
			$mail->send();
PHPMailer code will look like this (replace the original or comment out):

Code: Select all

 $mail = new PHPMailer();

 $mail->IsSMTP();  // telling the class to use SMTP  
 $mail->Host     = $this->config->get('config_smtp_host'); // SMTP server  
 $mail->SMTPAuth = true;     // turn on SMTP authentication
 $mail->Username = $this->config->get('config_smtp_username');  // SMTP username
 $mail->Password = html_entity_decode($this->config->get('config_smtp_password')); // SMTP password
   
 $mail->From     = $this->config->get('config_email');
 $mail->FromName = $this->config->get('config_store');  
 $mail->AddAddress($order_query->row['email']);
   
 $mail->IsHTML(false); 
   
 $mail->Subject  = $subject;  
 $mail->Body     = $message;
 $mail->CharSet  = 'utf-8'; 
 
 $mail->Send();
Of course there are many more options you can use so refer to the PHPMailer documentation, this is pretty basic and gets the job done for my needs.

Send to store owner starts on line 139:

Code: Select all

				$mail = new Mail($this->config->get('config_mail_protocol'), $this->config->get('config_smtp_host'), $this->config->get('config_smtp_username'), $this->config->get('config_smtp_password'), $this->config->get('config_smtp_port'), $this->config->get('config_smtp_timeout')); 
				$mail->setTo($this->config->get('config_email'));
				$mail->setFrom($this->config->get('config_email'));
				$mail->setSender($this->config->get('config_store'));
				$mail->setSubject($subject);
				$mail->setText($message);
				$mail->send();
PHPMailer code will look like this (replace the original or comment out):

Code: Select all

 $mail2 = new PHPMailer();

 $mail2->IsSMTP();  // telling the class to use SMTP  
 $mail2->Host     = $this->config->get('config_smtp_host'); // SMTP server  
 $mail2->SMTPAuth = true;     // turn on SMTP authentication
 $mail2->Username = $this->config->get('config_smtp_username');  // SMTP username
 $mail2->Password = html_entity_decode($this->config->get('config_smtp_password')); // SMTP password
   
 $mail2->From     = $this->config->get('config_email');
 $mail2->FromName = $this->config->get('config_store');  
 $mail2->AddAddress($this->config->get('config_email'));  
   
 $mail2->IsHTML(false); 
   
 $mail2->Subject  = $subject;  
 $mail2->Body     = $message;
 $mail2->CharSet  = 'utf-8';  
 
 $mail2->Send();
I like to use another variable like $mail2, $mail3 and so on for each new mail in the same file, but you don't have to.

So thats pretty much covers the steps, the rest is up to you, so good luck ;)

Side note for Daniel:
I think it will make sense to make a mail send function, which will be the only function which will use a mail script syntax, and in the model and controller files you will just gather the info into some array and pass it to that function. That way if someone wants to use another mail script he won't have to edit all the model and controller files, but just the one function.. Just a thought :)

Newbie

Posts

Joined
Thu Aug 13, 2009 6:10 am

Post by ckanoab » Wed Jun 23, 2010 10:16 am

You can skip step 4 and instead change the send function in the opencart mailer class to the following code

Code: Select all

	public function send() {   
		if (!$this->to) {
			exit('Error: E-Mail to required!');
		}
	
		if (!$this->from) {
			exit('Error: E-Mail from required!');
		}
	
		if (!$this->sender) {
			exit('Error: E-Mail sender required!');
		}
	
		if (!$this->subject) {
			exit('Error: E-Mail subject required!');
		}
	
		if ((!$this->text) && (!$this->html)) {
			exit('Error: E-Mail message required!');
		}
	
		if (is_array($this->to)) {
			$to = implode(',', $this->to);
		} else {
			$to = $this->to;
		}
		
		
		$mail = new PHPMailer(True); //True parameter tells PHPMailer to throw errors, remove for production once you have it working.
		$mail->CharSet = 'utf-8';
		
		
		$boundary = '----=_NextPart_' . md5(time()); 
	
		$header = '';
	
		if ($this->protocol != 'mail') {
			$header .= 'To: ' . $to . $this->newline;
			$header .= 'Subject: ' . $this->subject . $this->newline;
			$mail->AddAddress($to);
			$mail->Subject = $this->subject;

		}
		
		
		$header .= 'From: ' . $this->sender . '<' . $this->from . '>' . $this->newline;
		$mail->SetFrom($this->from,$this->sender);
		$header .= 'Reply-To: ' . $this->sender . '<' . $this->from . '>' . $this->newline;   
		$mail->AddReplyTo($this->from,$this->sender);

		$header .= 'Return-Path: ' . $this->from . $this->newline;
		$header .= 'X-Mailer: PHP/' . phpversion() . $this->newline; 
		$header .= 'MIME-Version: 1.0' . $this->newline;
		$header .= 'Content-Type: multipart/mixed; boundary="' . $boundary . '"' . $this->newline; 
	

		if (!$this->html) {
			$message  = '--' . $boundary . $this->newline; 
			$message .= 'Content-Type: text/plain; charset="utf-8"' . $this->newline;
			$message .= 'Content-Transfer-Encoding: 8bit' . $this->newline . $this->newline;
			$message .= $this->text . $this->newline;
			$mail->AltBody = $this->text;
		} else {
			$message  = '--' . $boundary . $this->newline;
			$message .= 'Content-Type: multipart/alternative; boundary="' . $boundary . '_alt"' . $this->newline . $this->newline;
			$message .= '--' . $boundary . '_alt' . $this->newline;
			$message .= 'Content-Type: text/plain; charset="utf-8"' . $this->newline;
			$message .= 'Content-Transfer-Encoding: 8bit' . $this->newline;
		
			if ($this->text) {
				$message .= $this->text . $this->newline;
			} else {
				$message .= 'This is a HTML email and your email client software does not support HTML email!' . $this->newline;
			}   
		
			$message .= '--' . $boundary . '_alt' . $this->newline;
			$message .= 'Content-Type: text/html; charset="utf-8"' . $this->newline;
			$message .= 'Content-Transfer-Encoding: 8bit' . $this->newline . $this->newline;
			$message .= $this->html . $this->newline;
			$message .= '--' . $boundary . '_alt--' . $this->newline;      
			$mail->AltBody = $this->text;
			$mail->MsgHTML($this->html);
			
		}
	
		foreach ($this->attachments as $attachment) { 
			if (file_exists($attachment['file'])) {
				$mail->AddAttachment($attachment['file']);	
				$handle = fopen($attachment['file'], 'r');
				$content = fread($handle, filesize($attachment['file']));
		
				fclose($handle); 
		
				$message .= '--' . $boundary . $this->newline;
				$message .= 'Content-Type: application/octetstream' . $this->newline;   
				$message .= 'Content-Transfer-Encoding: base64' . $this->newline;
				$message .= 'Content-Disposition: attachment; filename="' . basename($attachment['filename']) . '"' . $this->newline;
				$message .= 'Content-ID: <' . basename($attachment['filename']) . '>' . $this->newline . $this->newline;
				$message .= chunk_split(base64_encode($content));
			}
		} 
	
		$message .= '--' . $boundary . '--' . $this->newline; 
	
		if ($this->protocol == 'mail') {
			ini_set('sendmail_from', $this->from);
	
			if ($this->parameter) {
				mail($to, $this->subject, $message, $header, $this->parameter);
			} else {
				mail($to, $this->subject, $message, $header);
			}
			
		} elseif ($this->protocol == 'smtp') {
			$mail->Username = $this->username;
			$mail->Password = $this->password;
			$mail->Port = $this->port;
			if (strpos($this->hostname,'gmail')) {
				$mail->SMTPSecure = 'ssl';
				$mail->SMTPAuth   = true; 
			}
			$mail->Host = $this->hostname;
			$mail->IsSMTP();
			if(!$mail->Send()) {
				error_log($mail->ErrorInfo);
			}
		}
	}
This way you can cut down the # of mods you have to do at upgrade time.

Newbie

Posts

Joined
Wed Jul 22, 2009 11:20 pm

Post by Xsecrets » Wed Jun 23, 2010 11:55 am

ckanoab wrote:You can skip step 4 and instead change the send function in the opencart mailer class to the following code

Code: Select all

	public function send() {   
		if (!$this->to) {
			exit('Error: E-Mail to required!');
		}
	
		if (!$this->from) {
			exit('Error: E-Mail from required!');
		}
	
		if (!$this->sender) {
			exit('Error: E-Mail sender required!');
		}
	
		if (!$this->subject) {
			exit('Error: E-Mail subject required!');
		}
	
		if ((!$this->text) && (!$this->html)) {
			exit('Error: E-Mail message required!');
		}
	
		if (is_array($this->to)) {
			$to = implode(',', $this->to);
		} else {
			$to = $this->to;
		}
		
		
		$mail = new PHPMailer(True); //True parameter tells PHPMailer to throw errors, remove for production once you have it working.
		$mail->CharSet = 'utf-8';
		
		
		$boundary = '----=_NextPart_' . md5(time()); 
	
		$header = '';
	
		if ($this->protocol != 'mail') {
			$header .= 'To: ' . $to . $this->newline;
			$header .= 'Subject: ' . $this->subject . $this->newline;
			$mail->AddAddress($to);
			$mail->Subject = $this->subject;

		}
		
		
		$header .= 'From: ' . $this->sender . '<' . $this->from . '>' . $this->newline;
		$mail->SetFrom($this->from,$this->sender);
		$header .= 'Reply-To: ' . $this->sender . '<' . $this->from . '>' . $this->newline;   
		$mail->AddReplyTo($this->from,$this->sender);

		$header .= 'Return-Path: ' . $this->from . $this->newline;
		$header .= 'X-Mailer: PHP/' . phpversion() . $this->newline; 
		$header .= 'MIME-Version: 1.0' . $this->newline;
		$header .= 'Content-Type: multipart/mixed; boundary="' . $boundary . '"' . $this->newline; 
	

		if (!$this->html) {
			$message  = '--' . $boundary . $this->newline; 
			$message .= 'Content-Type: text/plain; charset="utf-8"' . $this->newline;
			$message .= 'Content-Transfer-Encoding: 8bit' . $this->newline . $this->newline;
			$message .= $this->text . $this->newline;
			$mail->AltBody = $this->text;
		} else {
			$message  = '--' . $boundary . $this->newline;
			$message .= 'Content-Type: multipart/alternative; boundary="' . $boundary . '_alt"' . $this->newline . $this->newline;
			$message .= '--' . $boundary . '_alt' . $this->newline;
			$message .= 'Content-Type: text/plain; charset="utf-8"' . $this->newline;
			$message .= 'Content-Transfer-Encoding: 8bit' . $this->newline;
		
			if ($this->text) {
				$message .= $this->text . $this->newline;
			} else {
				$message .= 'This is a HTML email and your email client software does not support HTML email!' . $this->newline;
			}   
		
			$message .= '--' . $boundary . '_alt' . $this->newline;
			$message .= 'Content-Type: text/html; charset="utf-8"' . $this->newline;
			$message .= 'Content-Transfer-Encoding: 8bit' . $this->newline . $this->newline;
			$message .= $this->html . $this->newline;
			$message .= '--' . $boundary . '_alt--' . $this->newline;      
			$mail->AltBody = $this->text;
			$mail->MsgHTML($this->html);
			
		}
	
		foreach ($this->attachments as $attachment) { 
			if (file_exists($attachment['file'])) {
				$mail->AddAttachment($attachment['file']);	
				$handle = fopen($attachment['file'], 'r');
				$content = fread($handle, filesize($attachment['file']));
		
				fclose($handle); 
		
				$message .= '--' . $boundary . $this->newline;
				$message .= 'Content-Type: application/octetstream' . $this->newline;   
				$message .= 'Content-Transfer-Encoding: base64' . $this->newline;
				$message .= 'Content-Disposition: attachment; filename="' . basename($attachment['filename']) . '"' . $this->newline;
				$message .= 'Content-ID: <' . basename($attachment['filename']) . '>' . $this->newline . $this->newline;
				$message .= chunk_split(base64_encode($content));
			}
		} 
	
		$message .= '--' . $boundary . '--' . $this->newline; 
	
		if ($this->protocol == 'mail') {
			ini_set('sendmail_from', $this->from);
	
			if ($this->parameter) {
				mail($to, $this->subject, $message, $header, $this->parameter);
			} else {
				mail($to, $this->subject, $message, $header);
			}
			
		} elseif ($this->protocol == 'smtp') {
			$mail->Username = $this->username;
			$mail->Password = $this->password;
			$mail->Port = $this->port;
			if (strpos($this->hostname,'gmail')) {
				$mail->SMTPSecure = 'ssl';
				$mail->SMTPAuth   = true; 
			}
			$mail->Host = $this->hostname;
			$mail->IsSMTP();
			if(!$mail->Send()) {
				error_log($mail->ErrorInfo);
			}
		}
	}
This way you can cut down the # of mods you have to do at upgrade time.
if you're going to do that wouldn't you need to change step three in one way or another as well?

OpenCart commercial mods and development http://spotonsolutions.net
Layered Navigation
Shipment Tracking
Vehicle Year/Make/Model Filter


Guru Member

Posts

Joined
Sun Oct 25, 2009 3:51 am
Location - FL US

Post by ckanoab » Fri Jun 25, 2010 1:53 pm

If you skip step 3 you'd need to add a require call inside the send function

EDIT: sorry read skip not change, yes, you'd actually leave the mail require in the startup and just add a require for library/class.phpmailer.php

Newbie

Posts

Joined
Wed Jul 22, 2009 11:20 pm

Post by keclap » Fri Jul 16, 2010 5:34 pm

Hi,

my server is linux based and i'm running OC v1.4.8b.
I'm still confused how to integrate PHPmailer. Copying those 3 files to /system/library/ goes well, also adding this code

Code: Select all

require_once(DIR_SYSTEM . 'library/class.phpmailer.php');
(to sysytem/startup.php)

But changing 'the send function in the opencart mailer class' causes me troubles. Page stays blank, therefor i asume simple syntax error is troubling me... but can not find it ???

Can somebody help me to merge this piece of ckanoab's code with mail.php?

Thanks!

Newbie

Posts

Joined
Tue Jul 13, 2010 9:54 pm

Post by keclap » Fri Jul 16, 2010 10:59 pm

I made it! ;D Finally, my store not only sends Contact Form email, but order notifications too!! To both customer and admin!!

I managed to integrate PHPmailer in order to replace built in mail function which never worked for me.
Please note I'm kind of newbie, so the code is probably messed up and I'm sure it could use some improvement - whoever's coding skills are better than mine, please feel free (or better: obligated ;) ) to comment and improve!

Good to know:
  • - my server is linux based
  • - OC version is 1.4.8b (clean install)
  • - I set PHPmailer to use SMTP protocol
  • - I integrated PHPmailer beacuse I was one of the unlucky ones for whom built-in mail function never worked (no matter what!). I still recommend first to experiment with built-in mail function.
First, download PHPmailer (http://sourceforge.net/projects/phpmail ... %20php5_6/)

1. Upload PHPmailer files
Only 3 files are essential:

Code: Select all

class.phpmailer.php
class.pop3.php
class.smtp.php
Upload these 3 files to /system/library

2. Include PHPmailer in startup.php
Open /system/startup.php

Find:

Code: Select all

require_once(DIR_SYSTEM . 'library/mail.php');
After, add:

Code: Select all

require_once(DIR_SYSTEM . 'library/class.phpmailer.php');
3. Replace built-in mail function with PHPmailer in mail.php
Open: /system/library/mail.php

Find:

Code: Select all

	public function send() {   
		if (!$this->to) {
			exit('Error: E-Mail to required!');
		}
	
		if (!$this->from) {
			exit('Error: E-Mail from required!');
		}
	
		if (!$this->sender) {
			exit('Error: E-Mail sender required!');
		}
	
		if (!$this->subject) {
			exit('Error: E-Mail subject required!');
		}
	
		if ((!$this->text) && (!$this->html)) {
			exit('Error: E-Mail message required!');
		}
	
		if (is_array($this->to)) {
			$to = implode(',', $this->to);
		} else {
			$to = $this->to;
		}
	
		$boundary = '----=_NextPart_' . md5(time()); 
	
		$header = '';
	
		if ($this->protocol != 'mail') {
			$header .= 'To: ' . $to . $this->newline;
			$header .= 'Subject: ' . $this->subject . $this->newline;
		}
	
		$header .= 'From: ' . $this->sender . '<' . $this->from . '>' . $this->newline;
		$header .= 'Reply-To: ' . $this->sender . '<' . $this->from . '>' . $this->newline;   
		$header .= 'Return-Path: ' . $this->from . $this->newline;
		$header .= 'X-Mailer: PHP/' . phpversion() . $this->newline; 
		$header .= 'MIME-Version: 1.0' . $this->newline;
		$header .= 'Content-Type: multipart/mixed; boundary="' . $boundary . '"' . $this->newline; 
	
		if (!$this->html) {
			$message  = '--' . $boundary . $this->newline; 
			$message .= 'Content-Type: text/plain; charset="utf-8"' . $this->newline;
			$message .= 'Content-Transfer-Encoding: 8bit' . $this->newline . $this->newline;
			$message .= $this->text . $this->newline;
		} else {
			$message  = '--' . $boundary . $this->newline;
			$message .= 'Content-Type: multipart/alternative; boundary="' . $boundary . '_alt"' . $this->newline . $this->newline;
			$message .= '--' . $boundary . '_alt' . $this->newline;
			$message .= 'Content-Type: text/plain; charset="utf-8"' . $this->newline;
			$message .= 'Content-Transfer-Encoding: 8bit' . $this->newline;
		
			if ($this->text) {
				$message .= $this->text . $this->newline;
			} else {
				$message .= 'This is a HTML email and your email client software does not support HTML email!' . $this->newline;
			}   
		
			$message .= '--' . $boundary . '_alt' . $this->newline;
			$message .= 'Content-Type: text/html; charset="utf-8"' . $this->newline;
			$message .= 'Content-Transfer-Encoding: 8bit' . $this->newline . $this->newline;
			$message .= $this->html . $this->newline;
			$message .= '--' . $boundary . '_alt--' . $this->newline;      
		}
	
		foreach ($this->attachments as $attachment) { 
			if (file_exists($attachment['file'])) {
				$handle = fopen($attachment['file'], 'r');
				$content = fread($handle, filesize($attachment['file']));
		
				fclose($handle); 
		
				$message .= '--' . $boundary . $this->newline;
				$message .= 'Content-Type: application/octetstream' . $this->newline;   
				$message .= 'Content-Transfer-Encoding: base64' . $this->newline;
				$message .= 'Content-Disposition: attachment; filename="' . basename($attachment['filename']) . '"' . $this->newline;
				$message .= 'Content-ID: <' . basename($attachment['filename']) . '>' . $this->newline . $this->newline;
				$message .= chunk_split(base64_encode($content));
			}
		} 
	
		$message .= '--' . $boundary . '--' . $this->newline; 
	
		if ($this->protocol == 'mail') {
			ini_set('sendmail_from', $this->from);
	
			if ($this->parameter) {
				mail($to, $this->subject, $message, $header, $this->parameter);
			} else {
				mail($to, $this->subject, $message, $header);
			}
			
		} elseif ($this->protocol == 'smtp') {
			$handle = fsockopen($this->hostname, $this->port, $errno, $errstr, $this->timeout);   
	
			if (!$handle) {
				error_log('Error: ' . $errstr . ' (' . $errno . ')');
			} else {
				if (substr(PHP_OS, 0, 3) != 'WIN') {
					socket_set_timeout($handle, $this->timeout, 0);
				}
		
				while ($line = fgets($handle, 515)) {
					if (substr($line, 3, 1) == ' ') {
						break;
					}
				}
		
				if (substr($this->hostname, 0, 3) == 'tls') {
					fputs($handle, 'STARTTLS' . $this->crlf);
				
					while ($line = fgets($handle, 515)) {
						$reply .= $line;
					
						if (substr($line, 3, 1) == ' ') {
							break;
						}
					}
		
					if (substr($reply, 0, 3) != 220) {
						error_log('Error: STARTTLS not accepted from server!');
					}               
				}
		
				if (!empty($this->username)  && !empty($this->password)) {
					fputs($handle, 'EHLO ' . getenv('SERVER_NAME') . $this->crlf);
				
					$reply = '';
				
					while ($line = fgets($handle, 515)) {
						$reply .= $line;
				
						if (substr($line, 3, 1) == ' ') {
							break;
						}
					}
		
					if (substr($reply, 0, 3) != 250) {
						error_log('Error: EHLO not accepted from server!');
					}
		
					fputs($handle, 'AUTH LOGIN' . $this->crlf);
		
					$reply = '';
		
					while ($line = fgets($handle, 515)) {
						$reply .= $line;
					
						if (substr($line, 3, 1) == ' ') {
							break;
						}
					}
		
					if (substr($reply, 0, 3) != 334) {
						error_log('Error: AUTH LOGIN not accepted from server!');
					}
		
					fputs($handle, base64_encode($this->username) . $this->crlf);
		
					$reply = '';
		
					while ($line = fgets($handle, 515)) {
						$reply .= $line;
						
						if (substr($line, 3, 1) == ' ') {
							break;
						}
					}
		
					if (substr($reply, 0, 3) != 334) {
						error_log('Error: Username not accepted from server!');
					}            
		
					fputs($handle, base64_encode($this->password) . $this->crlf);
		
					$reply = '';
		
					while ($line = fgets($handle, 515)) {
						$reply .= $line;
					
						if (substr($line, 3, 1) == ' ') {
							break;
						}
					}
		
					if (substr($reply, 0, 3) != 235) {
						error_log('Error: Password not accepted from server!');               
					}   
				} else {
					fputs($handle, 'HELO ' . getenv('SERVER_NAME') . $this->crlf);
		
					$reply = '';
		
					while ($line = fgets($handle, 515)) {
						$reply .= $line;
					
						if (substr($line, 3, 1) == ' ') {
							break;
						}
					}
		
					if (substr($reply, 0, 3) != 250) {
						error_log('Error: HELO not accepted from server!');
					}            
				}
				
				if ($this->verp) {
					fputs($handle, 'MAIL FROM: <' . $this->from . '>XVERP' . $this->crlf);
				} else {
					fputs($handle, 'MAIL FROM: <' . $this->from . '>' . $this->crlf);
				}
				
				$reply = '';
				
				while ($line = fgets($handle, 515)) {
					$reply .= $line;
				
					if (substr($line, 3, 1) == ' ') {
						break;
					}
				}
		
				if (substr($reply, 0, 3) != 250) {
					error_log('Error: MAIL FROM not accepted from server!');
				}
		
				if (!is_array($this->to)) {
					fputs($handle, 'RCPT TO: <' . $this->to . '>' . $this->crlf);
				
					$reply = '';
				
					while ($line = fgets($handle, 515)) {
						$reply .= $line;
				
						if (substr($line, 3, 1) == ' ') {
							break;
						}
					}
		
					if ((substr($reply, 0, 3) != 250) && (substr($reply, 0, 3) != 251)) {
						error_log('Error: RCPT TO not accepted from server!');
					}         
				} else {
					foreach ($this->to as $recipient) {
						fputs($handle, 'RCPT TO: <' . $recipient . '>' . $this->crlf);
		
						$reply = '';
		
						while ($line = fgets($handle, 515)) {
							$reply .= $line;
							
							if (substr($line, 3, 1) == ' ') {
								break;
							}
						}
		
						if ((substr($reply, 0, 3) != 250) && (substr($reply, 0, 3) != 251)) {
							error_log('Error: RCPT TO not accepted from server!');
						}                  
					}
				}
				
				fputs($handle, 'DATA' . $this->crlf);
				
				$reply = '';
					
				while ($line = fgets($handle, 515)) {
					$reply .= $line;
					
					if (substr($line, 3, 1) == ' ') {
						break;
					}
				}
			
				if (substr($reply, 0, 3) != 354) {
					error_log('Error: DATA not accepted from server!');
				}
			
				fputs($handle, $header . $message . $this->crlf);
				fputs($handle, '.' . $this->crlf);
			
				$reply = '';
			
				while ($line = fgets($handle, 515)) {
					$reply .= $line;
				
					if (substr($line, 3, 1) == ' ') { 
						break;
					}
				}
			
				if (substr($reply, 0, 3) != 250) {
					error_log('Error: DATA not accepted from server!');
				}
			
				fputs($handle, 'QUIT' . $this->crlf);
				
				$reply = '';
				
				while ($line = fgets($handle, 515)) {
					$reply .= $line;
				
					if (substr($line, 3, 1) == ' ') {
						break;
					}
				}
			
				if (substr($reply, 0, 3) != 221) {
					error_log('Error: QUIT not accepted from server!');
				}         
			
				fclose($handle);
			}
		}
	}
Replace with:

Code: Select all

   public function send() {   
      if (!$this->to) {
         exit('Error: E-Mail to required!');
      }
   
      if (!$this->from) {
         exit('Error: E-Mail from required!');
      }
   
      if (!$this->sender) {
         exit('Error: E-Mail sender required!');
      }
   
      if (!$this->subject) {
         exit('Error: E-Mail subject required!');
      }
   
      if ((!$this->text) && (!$this->html)) {
         exit('Error: E-Mail message required!');
      }
   
      if (is_array($this->to)) {
         $to = implode(',', $this->to);
      } else {
         $to = $this->to;
      }
      
      
      $mail = new PHPMailer; //True parameter tells PHPMailer to throw errors, remove for production once you have it working.
      $mail->CharSet = 'utf-8';
      
      
      $boundary = '----=_NextPart_' . md5(time()); 
   
      $header = '';
   
      if ($this->protocol != 'mail') {
         $header .= 'To: ' . $to . $this->newline;
         $header .= 'Subject: ' . $this->subject . $this->newline;
         $mail->AddAddress($to);
         $mail->Subject = $this->subject;

      }
      
      
      $header .= 'From: ' . $this->sender . '<' . $this->from . '>' . $this->newline;
      $mail->SetFrom($this->from,$this->sender);
      $header .= 'Reply-To: ' . $this->sender . '<' . $this->from . '>' . $this->newline;   
      $mail->AddReplyTo($this->from,$this->sender);

      $header .= 'Return-Path: ' . $this->from . $this->newline;
      $header .= 'X-Mailer: PHP/' . phpversion() . $this->newline; 
      $header .= 'MIME-Version: 1.0' . $this->newline;
      $header .= 'Content-Type: multipart/mixed; boundary="' . $boundary . '"' . $this->newline; 
   

      if (!$this->html) {
         $message  = '--' . $boundary . $this->newline; 
         $message .= 'Content-Type: text/plain; charset="utf-8"' . $this->newline;
         $message .= 'Content-Transfer-Encoding: 8bit' . $this->newline . $this->newline;
         $message .= $this->text . $this->newline;
         $mail->AltBody = $this->text;
      } else {
         $message  = '--' . $boundary . $this->newline;
         $message .= 'Content-Type: multipart/alternative; boundary="' . $boundary . '_alt"' . $this->newline . $this->newline;
         $message .= '--' . $boundary . '_alt' . $this->newline;
         $message .= 'Content-Type: text/plain; charset="utf-8"' . $this->newline;
         $message .= 'Content-Transfer-Encoding: 8bit' . $this->newline;
      
         if ($this->text) {
            $message .= $this->text . $this->newline;
         } else {
            $message .= 'This is a HTML email and your email client software does not support HTML email!' . $this->newline;
         }   
      
         $message .= '--' . $boundary . '_alt' . $this->newline;
         $message .= 'Content-Type: text/html; charset="utf-8"' . $this->newline;
         $message .= 'Content-Transfer-Encoding: 8bit' . $this->newline . $this->newline;
         $message .= $this->html . $this->newline;
         $message .= '--' . $boundary . '_alt--' . $this->newline;      
         $mail->AltBody = $this->text;
         $mail->MsgHTML($this->html);
         
      }
   
      foreach ($this->attachments as $attachment) { 
         if (file_exists($attachment['file'])) {
            $mail->AddAttachment($attachment['file']);   
            $handle = fopen($attachment['file'], 'r');
            $content = fread($handle, filesize($attachment['file']));
      
            fclose($handle); 
      
            $message .= '--' . $boundary . $this->newline;
            $message .= 'Content-Type: application/octetstream' . $this->newline;   
            $message .= 'Content-Transfer-Encoding: base64' . $this->newline;
            $message .= 'Content-Disposition: attachment; filename="' . basename($attachment['filename']) . '"' . $this->newline;
            $message .= 'Content-ID: <' . basename($attachment['filename']) . '>' . $this->newline . $this->newline;
            $message .= chunk_split(base64_encode($content));
         }
      } 
   
      $message .= '--' . $boundary . '--' . $this->newline; 
   
      if ($this->protocol == 'mail') {
         ini_set('sendmail_from', $this->from);
   
         if ($this->parameter) {
            mail($to, $this->subject, $message, $header, $this->parameter);
         } else {
            mail($to, $this->subject, $message, $header);
         }
         
      } elseif ($this->protocol == 'smtp') {
         $mail->Username = $this->username;
         $mail->Password = $this->password;
         $mail->Port = $this->port;
         if (strpos($this->hostname,'gmail')) {
            $mail->SMTPSecure = 'ssl';
            $mail->SMTPAuth   = true; 
         }
         $mail->Host = $this->hostname;
         $mail->IsSMTP();
         if(!$mail->Send()) {
            error_log($mail->ErrorInfo);
         }
      }
   }
4. Do the same with Contact Form
Open: /catalog/controller/information/contact.php

Find:

Code: Select all

			$mail = new Mail();
			$mail->protocol = $this->config->get('config_mail_protocol');
			$mail->parameter = $this->config->get('config_mail_parameter');
			$mail->hostname = $this->config->get('config_smtp_host');
			$mail->username = $this->config->get('config_smtp_username');
			$mail->password = $this->config->get('config_smtp_password');
			$mail->port = $this->config->get('config_smtp_port');
			$mail->timeout = $this->config->get('config_smtp_timeout');				
			$mail->setTo($this->config->get('config_email'));
	  		$mail->setFrom($this->request->post['email']);
	  		$mail->setSender($this->request->post['name']);
	  		$mail->setSubject(sprintf($this->language->get('email_subject'), $this->request->post['name']));
	  		$mail->setText(strip_tags(html_entity_decode($this->request->post['enquiry'], ENT_QUOTES, 'UTF-8')));
      		$mail->send();
Replace with:

Code: Select all

$mail = new PHPMailer(true); //New instance, with exceptions enabled

	$body             = strip_tags(html_entity_decode($this->request->post['enquiry'], ENT_QUOTES, 'UTF-8'));
	$body             = preg_replace('/\\\\/','', $body); //Strip backslashes

	$mail->IsSMTP();                           // tell the class to use SMTP
	$mail->SMTPAuth   = true;                  // enable SMTP authentication
	$mail->Port       = $this->config->get('config_smtp_port');                    // set the SMTP server port
	$mail->Host       = $this->config->get('config_smtp_host'); // SMTP server
	$mail->Username   = $this->config->get('config_smtp_username');     // SMTP server username
	$mail->Password   = $this->config->get('config_smtp_password');            // SMTP server password

	//$mail->IsSendmail();  // tell the class to use Sendmail

	$mail->AddReplyTo($this->config->get('config_email'));

	$mail->From       = $this->request->post['email'];
	$mail->FromName   = $this->request->post['name'];

	$to = $this->config->get('config_email');

	$mail->AddAddress($to);

	$mail->Subject  = sprintf($this->language->get('email_subject'), $this->request->post['name']);

	$mail->AltBody    = "To view the message, please use an HTML compatible email viewer!"; // optional, comment out and test
	$mail->WordWrap   = 80; // set word wrap

	$mail->MsgHTML($body);

	$mail->IsHTML(true); // send as HTML

	$mail->Send();
At last but not least, do not forget to configure your mail section in admin!
Login to admin and go to System > Settings > Mail
Mail Protocol: SMTP
SMTP Host: localhost
SMTP Username: info@mydomain.com
SMTP Password: *******
SMTP Port: 25
SMTP Timeout: 5
Alert Mail: Yes
Additional Alert E-Mails: additional@gmail.com

Note: I set host to localhost as I use info@mydomain.com. If you use Gmal/Yahoo/etc, set it to proper SMTP server.

Important: Im not an experienced in php coding. There might be some flaws in this code as I don't understand it fully (hey, at least I'm being honest! :) ).
Example of potential flaw: in 3rd step the replacement code includes this line:

Code: Select all

if (strpos($this->hostname,'gmail'))
I have no idea what is the purpose of gmail part! Please advise :)

I hope it works for you too!

Newbie

Posts

Joined
Tue Jul 13, 2010 9:54 pm

Post by danlanphear » Fri Jul 16, 2010 11:44 pm

@keclap. Thanks, this looks very tempting to try.

Are there any second opinions out there on this idea before I hack up my store to get e-mail working?

New member

Posts

Joined
Wed Jun 30, 2010 7:36 am

Post by keclap » Sat Jul 17, 2010 6:11 am

danlanphear, in case you decide to give it a try, please let me know if this modification works for you.

Newbie

Posts

Joined
Tue Jul 13, 2010 9:54 pm

Post by ckanoab » Sat Jul 17, 2010 9:58 am

sorry i missed the previous posts...

@keclap,
what was the error message it gave you?

@danlanphear. my code definitely works, and will cut down on the # of files you have to modify during upgrades...


here's my mail.php file in it's entirety..

Code: Select all

<?php
final class Mail {
	protected $to;
	protected $from;
	protected $sender;
	protected $subject;
	protected $text;
	protected $html;
	protected $attachments = array();
	public $protocol = 'mail';
	public $hostname;
	public $username;
	public $password;
	public $port = 25;
	public $timeout = 5;
	public $newline = "\n";
	public $crlf = "\r\n";
	public $verp = FALSE;
	public $parameter = '';
	
	public function setTo($to) {
		$this->to = $to;
	}
   
	public function setFrom($from) {
		$this->from = $from;
	}
	
	public function addheader($header, $value) {
		$this->headers[$header] = $value;
	}
	
	public function setSender($sender) {
		$this->sender = $sender;
	}
	
	public function setSubject($subject) {
		$this->subject = $subject;
	}
	
	public function setText($text) {
		$this->text = $text;
	}
	
	public function setHtml($html) {
		$this->html = $html;
	}
	
	public function addAttachment($file, $filename = '') {
		if (!$filename) {
			$filename = basename($file);
		}
	  
		$this->attachments[] = array(
			'filename' => $filename,
			'file'     => $file
		);
	}
	
	public function send() {   
		if (!$this->to) {
			exit('Error: E-Mail to required!');
		}
	
		if (!$this->from) {
			exit('Error: E-Mail from required!');
		}
	
		if (!$this->sender) {
			exit('Error: E-Mail sender required!');
		}
	
		if (!$this->subject) {
			exit('Error: E-Mail subject required!');
		}
	
		if ((!$this->text) && (!$this->html)) {
			exit('Error: E-Mail message required!');
		}
	
		if (is_array($this->to)) {
			$to = implode(',', $this->to);
		} else {
			$to = $this->to;
		}
		
		
		$mail = new PHPMailer(True); //True parameter tells PHPMailer to throw errors, remove for production once you have it working.
		$mail->CharSet = 'utf-8';
		
		
		$boundary = '----=_NextPart_' . md5(time()); 
	
		$header = '';
	
		if ($this->protocol != 'mail') {
			$header .= 'To: ' . $to . $this->newline;
			$header .= 'Subject: ' . $this->subject . $this->newline;
			$mail->AddAddress($to);
			$mail->Subject = $this->subject;

		}
		
		
		$header .= 'From: ' . $this->sender . '<' . $this->from . '>' . $this->newline;
		$mail->SetFrom($this->from,$this->sender);
		$header .= 'Reply-To: ' . $this->sender . '<' . $this->from . '>' . $this->newline;   
		$mail->AddReplyTo($this->from,$this->sender);

		$header .= 'Return-Path: ' . $this->from . $this->newline;
		$header .= 'X-Mailer: PHP/' . phpversion() . $this->newline; 
		$header .= 'MIME-Version: 1.0' . $this->newline;
		$header .= 'Content-Type: multipart/mixed; boundary="' . $boundary . '"' . $this->newline; 
	

		if (!$this->html) {
			$message  = '--' . $boundary . $this->newline; 
			$message .= 'Content-Type: text/plain; charset="utf-8"' . $this->newline;
			$message .= 'Content-Transfer-Encoding: 8bit' . $this->newline . $this->newline;
			$message .= $this->text . $this->newline;
			$mail->AltBody = $this->text;
		} else {
			$message  = '--' . $boundary . $this->newline;
			$message .= 'Content-Type: multipart/alternative; boundary="' . $boundary . '_alt"' . $this->newline . $this->newline;
			$message .= '--' . $boundary . '_alt' . $this->newline;
			$message .= 'Content-Type: text/plain; charset="utf-8"' . $this->newline;
			$message .= 'Content-Transfer-Encoding: 8bit' . $this->newline;
		
			if ($this->text) {
				$message .= $this->text . $this->newline;
			} else {
				$message .= 'This is a HTML email and your email client software does not support HTML email!' . $this->newline;
			}   
		
			$message .= '--' . $boundary . '_alt' . $this->newline;
			$message .= 'Content-Type: text/html; charset="utf-8"' . $this->newline;
			$message .= 'Content-Transfer-Encoding: 8bit' . $this->newline . $this->newline;
			$message .= $this->html . $this->newline;
			$message .= '--' . $boundary . '_alt--' . $this->newline;      
			$mail->AltBody = $this->text;
			$mail->MsgHTML($this->html);
			
		}
	
		foreach ($this->attachments as $attachment) { 
			if (file_exists($attachment['file'])) {
				$mail->AddAttachment($attachment['file']);	
				$handle = fopen($attachment['file'], 'r');
				$content = fread($handle, filesize($attachment['file']));
		
				fclose($handle); 
		
				$message .= '--' . $boundary . $this->newline;
				$message .= 'Content-Type: application/octetstream' . $this->newline;   
				$message .= 'Content-Transfer-Encoding: base64' . $this->newline;
				$message .= 'Content-Disposition: attachment; filename="' . basename($attachment['filename']) . '"' . $this->newline;
				$message .= 'Content-ID: <' . basename($attachment['filename']) . '>' . $this->newline . $this->newline;
				$message .= chunk_split(base64_encode($content));
			}
		} 
	
		$message .= '--' . $boundary . '--' . $this->newline; 
	
		if ($this->protocol == 'mail') {
			ini_set('sendmail_from', $this->from);
	
			if ($this->parameter) {
				mail($to, $this->subject, $message, $header, $this->parameter);
			} else {
				mail($to, $this->subject, $message, $header);
			}
			
		} elseif ($this->protocol == 'smtp') {
			$mail->Username = $this->username;
			$mail->Password = $this->password;
			$mail->Port = $this->port;
			if (strpos($this->hostname,'gmail')) {
				$mail->SMTPSecure = 'ssl';
				$mail->SMTPAuth   = true; 
			}
			$mail->Host = $this->hostname;
			$mail->IsSMTP();
			if(!$mail->Send()) {
				error_log($mail->ErrorInfo);
			}
		}
	}
}
?>

Newbie

Posts

Joined
Wed Jul 22, 2009 11:20 pm

Post by ckanoab » Sat Jul 17, 2010 10:49 am

keclap wrote: Important: Im not an experienced in php coding. There might be some flaws in this code as I don't understand it fully (hey, at least I'm being honest! :) ).
Example of potential flaw: in 3rd step the replacement code includes this line:

Code: Select all

if (strpos($this->hostname,'gmail'))
I have no idea what is the purpose of gmail part! Please advise :)
this line is checking if your hostname is set to gmail, and if it is, it sets 2 parameters needed for gmail.. if you use google apps, you should add another condition to the if statement to set things up correctly

again, sorry i didn't see these posts sooner

Newbie

Posts

Joined
Wed Jul 22, 2009 11:20 pm

Post by keclap » Sat Jul 17, 2010 4:10 pm

@ckanoab, thanks for your replies. It gave me no errors, everything works fine :) But I have noticed the customer doesn't receive notice when order status is updated (just in case: Notify Customer is ticked).

And thanks for answering the "gmail" question!

Newbie

Posts

Joined
Tue Jul 13, 2010 9:54 pm

Post by ckanoab » Mon Jul 19, 2010 5:43 pm

I'm having the same issue, also got a fatal error upon new customer registration, will work on it and get back to you...

Newbie

Posts

Joined
Wed Jul 22, 2009 11:20 pm

Post by al3xandr1a » Thu Sep 16, 2010 11:29 pm

Hi guys.
I am experiencing same email notification problem, and from a quick read of this thread, going to phpmailer seems to be the solution.
I use Google Apps for my emails in my domain name, and im really confused where to go from here. There was a mention of adding 2 conditions to an "if" statement for my situation (on Google Apps). Any idea what those conditions are?

~al3xandr1a
Newbie / Student


User avatar
New member

Posts

Joined
Fri Jul 02, 2010 7:27 pm

Post by keclap » Thu Sep 16, 2010 11:41 pm

I'm sorry, I have no idea :-\
Maybe you should try it anyway to see if it works...

Good luck!

Newbie

Posts

Joined
Tue Jul 13, 2010 9:54 pm

Post by al3xandr1a » Fri Sep 17, 2010 12:17 am

What about on the latest version 1.4.9? Was this email issue taken on board and resolved?

~al3xandr1a
Newbie / Student


User avatar
New member

Posts

Joined
Fri Jul 02, 2010 7:27 pm

Post by keclap » Fri Sep 17, 2010 12:36 am

I don't think so, because v1.4.9 changelog has no reference of modified mail script. Besides, it is great chance that this problem is server related and therefor OC doesn't have anything to do with it.

Newbie

Posts

Joined
Tue Jul 13, 2010 9:54 pm

Post by dynamodaveo » Thu Oct 28, 2010 10:58 pm

Hi there,

total newbie,
but I got the existing mail settings to work without any other install or additional software.

SMTP Host: localhost
did not work for me.

I used
Protocol: SMTP
SMTP Host: mail.domain.com
SMTP Username: full email address
Password: whatever it is.
Port: 25
Timeout: 5
Alert mail: Y

and Bob's yer uncle

Newbie

Posts

Joined
Mon Jan 18, 2010 11:49 pm

Post by xisura » Mon Dec 19, 2011 4:52 pm

Hi,

i already tried those things but it always show this error: Could not execute: /var/qmail/bin/sendmail'
Help me please :(

Newbie

Posts

Joined
Mon Dec 19, 2011 4:39 pm

Post by angela » Thu Jan 26, 2017 12:16 am

For anyone using PHPMailer with OpenCart, there is a security vulnerability (in PHPMailer):
https://legalhackers.com/advisories/PHP ... ypass.html

User avatar
New member

Posts

Joined
Fri Dec 02, 2016 2:14 am

Post by rupinder@vismaad.com » Thu Jan 25, 2018 1:41 pm

@SubCon
Or anybody
Can you please put the working code in vqmod file opencart 2.2.0.0.
Thank You in advance


Posts

Joined
Fri Aug 04, 2017 11:05 pm
Who is online

Users browsing this forum: No registered users and 206 guests