VirtueMart's SMTP problems

More and more users are switching to Google Mail, Hotmail and other free mail services these days. It's a great move... unless you have VirtueMart and your Joomla is set to send your mails through SMTP. You may easily end seeing something like:

Warning: fsockopen() [function.fsockopen]: unable to connect to smtp.gmail.com:25

The mails from other Joomla apps are sent, just the VirtueMart is behaving badly. Weird thing is, that you can see in the main Joomla config the mailer set up properly, and the port to be used is 465, as required for Google Mail, but as you can see the error message indicates that VirtueMart tries to use port 25! The problem is that VirtueMart has a code flaw, when sending mails through SMTP the port 25 is hardcoded, and isn't inherited from main Joomla configuration file.

The fix is relatively easy, but you must get your hands dirty with some PHP code.

Be aware that the following hack comes with absolutely no guarantee. Just works, out of the box.

Save everything, make a backup, then make backup of your backup, put your seat belts, and go grab a code editor.

Hunt down the file /administrator/components/com_virtuemart/classes/ps_main.php, open it!

Search for "function vmCreateMail", you will find it (depending on the exact version you have, and the hacks you already performed) around line 467.

Locate the line:

 global $mosConfig_smtppass, $mosConfig_smtphost;

Add after that:

 global $mosConfig_smtpsecure, $mosConfig_smtpport; // ADDED BY ME TO FIX THE SMTP ISSUE

Then search for this line:

 $mail->Host = $mosConfig_smtphost;

And add after that:

 $mail->SMTPSecure = $mosConfig_smtpsecure; // ADDED BY ME TO FIX THE SMTP ISSUE
$mail->Port = $mosConfig_smtpport; // ADDED BY ME TO FIX THE SMTP ISSUE

You can leave out the "// ADDED BY ME TO FIX THE SMTP ISSUE" comments, or replace them with your own code, but is highly recommended to mark the changes you made.

After that, the function should looks like:

/**
* Function to create an email object for further use (uses phpMailer)
* @param string From e-mail address
* @param string From name
* @param string E-mail subject
* @param string Message body
* @return phpMailer Mail object
*/
function vmCreateMail( $from='', $fromname='', $subject='', $body='' ) {
global $mosConfig_absolute_path, $mosConfig_sendmail;
global $mosConfig_smtpauth, $mosConfig_smtpuser;
global $mosConfig_smtppass, $mosConfig_smtphost;
global $mosConfig_mailfrom, $mosConfig_fromname, $mosConfig_mailer;
global $mosConfig_smtpsecure, $mosConfig_smtpport; // ADDED BY ME TO FIX THE SMTP ISSUE
$phpmailer_classname='phpmailer';
if( file_exists( $mosConfig_absolute_path . '/libraries/phpmailer/phpmailer.php') ) {
$phpmailer_path = $mosConfig_absolute_path . '/libraries/phpmailer/phpmailer.php';
}elseif( file_exists( $mosConfig_absolute_path . '/includes/phpmailer/class.phpmailer.php')) {
$phpmailer_path = $mosConfig_absolute_path . '/includes/phpmailer/class.phpmailer.php';
$phpmailer_classname = 'mosphpmailer';
}
require_once( $phpmailer_path );
if( class_exists( $phpmailer_classname )) {
$mail = new $phpmailer_classname();
}
$phpmailer_path = dirname( $phpmailer_path );
$mail->PluginDir = $phpmailer_path .'/';
$mail->SetLanguage( 'en', $phpmailer_path . '/language/' );
$mail->CharSet = vmGetCharset();
$mail->IsMail();
$mail->From = $from ? $from : $mosConfig_mailfrom;
$mail->FromName = $fromname ? $fromname : $mosConfig_fromname;
$mail->Sender = $from ? $from : $mosConfig_mailfrom;
$mail->Mailer = $mosConfig_mailer;
// Add smtp values if needed
if ( $mosConfig_mailer == 'smtp' ) {
$mail->SMTPAuth = $mosConfig_smtpauth;
$mail->Username = $mosConfig_smtpuser;
$mail->Password = $mosConfig_smtppass;
$mail->Host = $mosConfig_smtphost;
$mail->SMTPSecure = $mosConfig_smtpsecure; // ADDED BY ME TO FIX THE SMTP ISSUE
$mail->Port = $mosConfig_smtpport; // ADDED BY ME TO FIX THE SMTP ISSUE
} else
// Set sendmail path
if ( $mosConfig_mailer == 'sendmail' ) {
if (isset($mosConfig_sendmail))
$mail->Sendmail = $mosConfig_sendmail;
} // if
if( $subject ) {
$mail->Subject = vmAbstractLanguage::safe_utf8_encode( $subject, $mail->CharSet );
}
if( $body) {
$mail->Body = $body;
}
// Patch to get correct Line Endings
switch( substr( strtoupper( PHP_OS ), 0, 3 ) ) {
case "WIN":
$mail->LE = "\r\n";
break;
case "MAC": // fallthrough
case "DAR": // Does PHP_OS return 'Macintosh' or 'Darwin' ?
$mail->LE = "\r";
default: // change nothing
break;/>

}
return $mail;
} 

Save it, and enjoy!