Reputation: 969
I am using the PHPMailer library integrated in Joomla for an email component in Joomla. It does work quite well, however I am having an issue with users running the script with 1and1 mail servers. They can get errors like that:
2012-06-14 18:20:34 u65913791 1x1et0-1RocCH2xzU-00qzkq EE transaction error after sending of mail text: msmtp.kundenserver.de[172.19.35.7] 500 Line limit exceeded
Another example from a different user:
SMTP error from remote mail server after end of data: host mx00.1and1.co.uk [212.227.15.134]: 500 Line limit exceeded
The line limit is not about how many lines but how many characters are actually used in a single line which 1and1 limits to 10240 characters (support answer) - which is actually 10 times more than required in RFC 2822.
I assume the issue is caused by using "wrong" line seperators when the emails is submitted so that the whole email reaches the email server as a single line. I guess that I need to make sure to insert line breaks in my script as PHPMailer fails do so.
Currently I am just receiving the HTML content from a WYSIWYG-editor and put into the PHPMailer object:
// snip, $mail2send is the JMail instance, which inherits PHPMailer
$mail2send->setSubject($mail->subject);
$mail2send->IsHTML(true);
$mail2send->setBody($mail->body);
// snip
How can I insert the appropiate line breaks?
Upvotes: 5
Views: 6085
Reputation: 969
After further investigation the error could be identified: after several replies in an email thread an embedded HTML message had no lines break anymore. I guess an email client involved in the conversation did this.
To overcome this problem I do a HTML-tag-safe wrapping using the following function:
/* HTML-tag-safe wordwrap
* from http://php.net/manual/de/function.wordwrap.php
* by nbenitezl[arroba]gmail[dot]com
*/
function htmlwrap(&$str, $maxLength=76, $char="\r\n"){
$count = 0;
$newStr = '';
$openTag = false;
$lenstr = strlen($str);
for($i=0; $i<$lenstr; $i++){
$newStr .= $str{$i};
if($str{$i} == '<'){
$openTag = true;
continue;
}
if(($openTag) && ($str{$i} == '>')){
$openTag = false;
continue;
}
if(!$openTag){
if($str{$i} == ' '){
if ($count == 0) {
$newStr = substr($newStr,0, -1);
continue;
} else {
$lastspace = $count + 1;
}
}
$count++;
if($count==$maxLength){
if ($str{$i+1} != ' ' && $lastspace && ($lastspace < $count)) {
$tmp = ($count - $lastspace)* -1;
$newStr = substr($newStr,0, $tmp) . $char . substr($newStr,$tmp);
$count = $tmp * -1;
} else {
$newStr .= $char;
$count = 0;
}
$lastspace = 0;
}
}
}
return $newStr;
}
Upvotes: -1
Reputation: 189307
Convert to a content transfer encoding such as base64 or quoted-printable, both of which have been devised for encapsulating free-form data. QP is more efficient for predominantly US-ASCII data with the occasional 8-bit character and/or overlong lines.
Of course, if your data is HTML and it is otherwise safe for SMTP, merely adding line terminators where you otherwise have whitespace is a slightly brittle workaround (are you sure you don't have a line-initial "From" anywhere, etc?)
Upvotes: 0
Reputation: 46040
Use chunk_split. This function was designed for tasks like yours and even its default (split at 76 chars) says so.
So your code will be
$mail2send->setSubject($mail->subject);
$mail2send->IsHTML(true);
$mail2send->setBody(chunk_split($mail->body));
Upvotes: 5