Search code examples
phpemailphpmailerhtml-emailbcc

PHPMailer BCC destroys Format


I recently updated our ancient email function to PHPMailer. Everything works perfectly but now I got a problem with BCC. When I add one or more adresses with

$mail->AddBCC($arr["bcc"]);

the email-format gets destroyed. Emails will look like this:

This is a multi-part message in MIME format. 

--b1_49abaa950e1203ed180ed1d5471145f7 
Content-Type: text/plain; charset=iso-8859-1 
Content-Transfer-Encoding: 8bit 

Adding a custom header doesn´t work either because then I get the error

Could not instantiate mail function.

BCC would work fine if it wouldn´t destroy the email-format.

EDIT:

This is the entire function to send an Email.

$adressen=mail_get_adressen_name();
if(!isset($arr["send_to"]))
{
    return array("fehler"=>"Kein Empfänger angegeben");
}
if(!isset($arr["subject"]))
{
    $arr["subject"]="";
}
if(!isset($arr["from"]))
{
    return array("fehler"=>"Kein Absender angegeben");
}
if(!isset($arr["disposition"]))
{
    $arr["disposition"]=false;
}
if(!isset($arr["message"]))
{
    $arr["message"]="";
}
if(!isset($arr["message_nohtml"]) or $arr["message_nohtml"]=="")
{
    $arr["message_nohtml"]=strip_tags(str_ireplace(array("<br />","<br>","<br/>","<li>"), "\r\n", $arr["message"]));
}
if(!isset($arr["cc"]))
{
    $arr["cc"]="";
}
else
{
    if(trim($arr["cc"])!="")
    {
        if(!stristr($arr["cc"],"@") && strlen($arr["cc"])<4)
        {
            $arr["cc"].="@.......";
        }
    }
}
if(!isset($arr["bcc"]))
{
    $arr["bcc"]="";
}
else
{
    if(trim($arr["bcc"])!="")
    {
        if(!stristr($arr["bcc"],"@") && strlen($arr["bcc"])<4)
        {
            $arr["bcc"].="@......";
        }
    }
}
if(!stristr($arr["send_to"],"@") && strlen($arr["send_to"])<4)
{
    $arr["send_to"].="@.......";
}
if(!stristr($arr["from"],"@") && strlen($arr["from"])<4)
{
    $arr["from"].="@.........";
}
$anhang=cache_get(HR_USER,$window,"MAIL_ANHANG",$arr);
$arr["message"]=convert_text_to_utf8($arr["message"]);
$arr["message_nohtml"]=convert_text_to_utf8($arr["message_nohtml"]);
$arr["subject"]=convert_text_to_utf8($arr["subject"]);
$arr["message"]=iconv("UTF-8","Windows-1252",$arr["message"]);
$arr["message_nohtml"]=iconv("UTF-8","Windows-1252",$arr["message_nohtml"]);
$arr["subject"]=iconv("UTF-8","Windows-1252",$arr["subject"]);
$mail = new PHPMailer;
if(isset($adressen[strtolower($arr["from"])]))
{
    $mail->setFrom($arr["from"],iconv("UTF-8","Windows-1252",convert_text_to_utf8($adressen[strtolower($arr["from"])])));
}
else
{
    $mail->setFrom($arr["from"]);
}
if(stristr($arr["send_to"],","))
{
    $arr2=explode(",",$arr["send_to"]);
    foreach($arr2 as $val)
    {
        if(isset($adressen[strtolower($val)]))
        {
            $mail->addAddress($val,iconv("UTF-8","Windows-1252",convert_text_to_utf8($adressen[strtolower($val)])));
        }
        else 
        {
            $mail->addAddress($val);
        }
    }
}
else
{
    if(isset($adressen[strtolower($arr["send_to"])]))
    {
        $mail->addAddress($arr["send_to"],iconv("UTF-8","Windows-1252",convert_text_to_utf8($adressen[strtolower($arr["send_to"])])));
    }
    else
    {
        $mail->addAddress($arr["send_to"]);
    }
}
if($arr["cc"]!="")
{
    if(stristr($arr["cc"],","))
    {
        $arr2=explode(",",$arr["cc"]);
        foreach($arr2 as $val)
        {
            if(isset($adressen[strtolower($val)]))
            {
                $mail->AddCC($val,iconv("UTF-8","Windows-1252",convert_text_to_utf8($adressen[strtolower($val)])));
            }
            else
            {
                $mail->AddCC($val);
            }
        }
    }
    else
    {
        if(isset($adressen[strtolower($arr["cc"])]))
        {
            $mail->AddCC($arr["cc"],iconv("UTF-8","Windows-1252",convert_text_to_utf8($adressen[strtolower($arr["cc"])])));
        }
        else
        {
            $mail->AddCC($arr["cc"]);
        }
    }
}
if(trim($arr["bcc"])!="" and HR_USER=="add")
{
    $mail->AddBCC($arr["bcc"]);
}
if(isset($adressen[strtolower($arr["from"])]))
{
    $mail->addReplyTo($arr["from"],iconv("UTF-8","Windows-1252",convert_text_to_utf8($adressen[strtolower($arr["from"])])));
}
else
{
    $mail->addReplyTo($arr["from"]);
}

$mail->isHTML(true);

$mail->Subject = $arr["subject"];
$mail->Body    = $arr["message"];
$mail->AltBody = $arr["message_nohtml"];

if($arr["disposition"])
{
    $mail->ConfirmReadingTo = $arr["from"];
}
if(is_array($anhang))
{
    foreach($anhang as $val)
    {
        $mail->addAttachment($val["pfad"],$val["name"]);
    }
}
if($mail->send())
{
    return array("fehler"=>"");
}
else
{
    err($mail->ErrorInfo);
    return array("fehler"=>"Mail versand fehlgeschlagen. Bitte melden Sie sich bei der EDV.<br>".$mail->ErrorInfo);
}

When I send the email without BCC it looks like this (I had to remove some Text):

Für Sie wurde ein Vorgang zu Auftrag 11EDV erstellt.
Vorgang öffnen

Kategorie:
EDV Entwicklung

Vorgangs-Bemerkung:
Gibt es eine Möglichkeit, eine E-Mail mit einer Auftragsbestätigung als Anhang direkt im HIS als Auftragsbestätigung hochzuladen?
Momentan müssen wir die PDF ja auf dem PC zwischenspeichern und dann im HIS als Event Anhang hochladen.

letzte Event-Bemerkung von hoj:
Anregung von ....some name....


.......some footer.....

When I add one or more BCC Adresses the same Email looks like this:

Planung (intern) (EDV Entwicklung) Dokumentnummer: 11EDV - 75, BVNR: 71122
.....my email adress......
27.04.2017 11:24
An: .....my email adress......,
This is a multi-part message in MIME format. 

--b1_49abaa950e1203ed180ed1d5471145f7 
Content-Type: text/plain; charset=iso-8859-1 
Content-Transfer-Encoding: 8bit 

Für Sie wurde ein Vorgang zu Auftrag 11EDV erstellt. 
Vorgang öffnen 

Kategorie: 
EDV Entwicklung 

Vorgangs-Bemerkung: 
Gibt es eine Möglichkeit, eine E-Mail mit einer Auftragsbestätigung als Anhang direkt im HIS als Auftragsbestätigung hochzuladen? 

Momentan müssen wir die PDF ja auf dem PC zwischenspeichern und dann im HIS als Event Anhang hochladen. 

letzte Event-Bemerkung von hoj: 
Anregung von ....some name.... 


......footer.......


--b1_49abaa950e1203ed180ed1d5471145f7 
Content-Type: text/html; charset=iso-8859-1 
Content-Transfer-Encoding: 8bit 

Für Sie wurde ein Vorgang zu Auftrag 11EDV erstellt.<br> <b>Vorgang öffnen</b></a><br><br>Kategorie:<br>EDV Entwicklung<br><br>Vorgangs-Bemerkung:<br>Gibt es eine Möglichkeit, eine E-Mail mit einer Auftragsbestätigung als Anhang direkt im HIS als Auftragsbestätigung hochzuladen?<br /> 
Momentan müssen wir die PDF ja auf dem PC zwischenspeichern und dann im HIS als Event Anhang hochladen.<br><br>letzte Event-Bemerkung von <b>hoj</b>:<br>Anregung von ....some name....<br>


......footer.......

--b1_49abaa950e1203ed180ed1d5471145f7-- 

I hope its clear now what I mean. I know that the BCCs cannot be shown because the email server removes them. And thats not what I want. I just want to know why the email will be shown as Source code instead of a normal email.


Solution

  • I see some problems there. I think the main problem is, that you try to send Windows-1252 encoded data, but your E-Mail header says, that you have 8 Bit ISO-8859-1 Encoding in mail body. As you might find in Wikipedia, ISO-8859-1 and Windows-1252 are not the same. The most characters are the same, but Windows-1252 is the advanced ISO-8859-1 character set. This might destroy your entire E-Mail. So, please decide, which one you would like to use. I would advice you to prefer ISO-8859-1 over Windows-1252 Encoding, because that's typically for old 8-Bit E-Mails.

    Also, the most of the data seems to come from an HTML form. If so, you could simply set the accept-charset attribute in your form Element to ISO-8859-1. So, in other words: Let the client do the hard work for you. But please validate it also on your PHP backend, that the client sends you really ISO-8859-1 encoded form data and something else. Because you cannot trust any client.

    Another reason could be, that you first convert from an unknown encoding to UTF-8 and from UTF-8 back to Windows-1252, which could cause also some problems. iconv can handle this in one step for you (I will take the first found line form the top of your code sample as an example):

    mail->addReplyTo($arr['from'], iconv(mb_detect_encoding($adressen[strtolower($arr['from'])]),'Windows-1252', $adressen[strtolower($arr['from'])]));
    

    Please note, that this line above requires the php mbstring extension. You have already chosen iconv right as your convert function, because this one was especially made for E-Mail encoding conversion and for every other purpose, we got mbstring. But the iconv functionality is very limited, so you need an mbstring function to detect the given encoding on a string.

    Another optimization hints that I found so far:

    1. There is no need for you, to use double quotes, because there is no expression inside it. So you could use single quotes, wich effects in a faster runtime. Maybe not feelable faster in this small function, but in huge applications, it is much faster. And it is also safer, because you prevent PHP from evaluating expressions, that may could have been bypassed from the client.
    2. You could also use type-safe comparsion. So, for string comparsion use $string === 'test' instead of $string == 'test
    3. Use a PSR standard Logger for your error handling, which implements the PSRLoggerInterface, like Monolog. This becomes more and more the industry de-facto standard.