Bonjour à tous,

Je suis confronté à un problème d'envoie de mail.

Pour suivre les conseils de mail-tester.com, j'envoie une version texte et une version html de chacun de mes mails.

J'ai codé un objet en PHP pour envoyer le mail, l'objet en lui même fonctionne très bien, il signe même le tout avec DKIM pour passer les test anti-spams, je pense juste avoir un problème de config dans les headers etc...

Pour convertir les messages html en texte, j'utilise cette petite fonction qui marche à merveille :

//Remplace les balises qui vont à la ligne par un retour chariot format texte
$tab =  array('<br/>', '<br />', '<br>', '<li>', '</li>', '</p>');
$txt = 'Version Texte : ' . strip_tags( str_replace( $tab, '\n', $this->content ) );
//J'intègre 'version texte' en début de chaine pour identifier ce qui s'affiche dans mon mail.

Ensuite je prépare mes headers :

$this->limit = '-----=' . md5( uniqid( microtime(), TRUE ) );

//PHP_EOL  est ma constante de retour chariot en fonction du système windows ou unix

$this->headers = 'From: ' . $this->from . PHP_EOL;
$this->headers .= 'To: ' . $this->dest . PHP_EOL; //Obligatoire pour DKIM ...
$this->headers .= 'MIME-Version: 1.0' . PHP_EOL;
$this->headers .= 'Priority: normal' . PHP_EOL;
$this->headers .= 'Reply-To: ' . $this->reply_to . PHP_EOL;
$this->headers .= 'X-Confirm-Reading-To: '. $this->reply_to . PHP_EOL;
$this->headers .= 'X-Mailer: PHP/' . phpversion() . PHP_EOL;
$this->headers .= 'X-Priority: 3' . PHP_EOL;
$this->headers .= 'Content-Type: multipart/alternative; boundary="'.$this->limit.'"' . PHP_EOL;

Et ensuite le corps du message :

$this->message = 'This is a multi-part message in MIME format.'. PHP_EOL; 
$this->message .= PHP_EOL . '--' . $this->limit . PHP_EOL;
$this->message .= 'Content-Type: text/plain; charset=utf-8' . PHP_EOL;
$this->message .= 'Content-Transfer-Encoding: 8bit' . PHP_EOL;
$this->message .= PHP_EOL . $this->txt . PHP_EOL;

$this->message .= PHP_EOL . '--' . $this->limit . '--' . PHP_EOL;
$this->message .= 'Content-Type: text/html; charset=utf-8' . PHP_EOL;
$this->message .= 'Content-Transfer-Encoding: 8bit' . PHP_EOL;
$this->message .= PHP_EOL . $this->content . PHP_EOL;               

$this->message .= PHP_EOL . '--' . $this->limit . '--' . PHP_EOL;
$this->message .= PHP_EOL . '--' . $this->limit . '--' . PHP_EOL;

Le problème comme indiqué dans le titre, c'est que je ne reçois que la version texte dans mon mail.

D'ailleurs mail-tester semble me le rappeller :

Je m'en suis aperçu car j'avais un bug d'encodage qui cassait mes liens, il supprimait les =

C'est là que j'ai rajouté le 'version texte' pour servir de témoin, et surprise, je ne vois que la version texte dans mon mail reçu...

Si vous savez d'ou ça peut venir ça m'intéresse. :D

Merci !

5 réponses


RiderFx3
Auteur
Réponse acceptée

Bon comme j'arrivais pas à résoudre mon problème,
J'ai installé la classe PHPMailer (au final j'avais codé ma classe sur le même principe ! :D )
Cette classe est vraiment très poussée, me reste plus qu'a configurer DKIM sur celle là.

Lien pour la classe PHP Mailer : https://github.com/Synchro/PHPMailer

Voici comment envoyer un mail simple :

        $mail = new PHPMailer;
        $mail->isMail();
        $mail->isHTML(true);
        $mail->setFrom('noreply@onepowerteam.com', 'One Power Team');
        $mail->addAddress('riderfx3@gmail.com', 'Romain GALVEZ');     // Add a recipient
        $mail->addReplyTo('noreply@onepowerteam.com', 'One Power Team');
        //$mail->addCC('cc@example.com');
        //$mail->addBCC('bcc@example.com');
        $mail->Subject = 'Nouveau PROSPECT !';
        $mail->Body    = 'Envoyé à '.date('H:i:s').' <br/><br/><p>mails de test</p><ul><li>liste1</li><li>liste2</li></ul>
                        <br/><br/>Pour ne plus recevoir nos newsletter, merci de cliquer sur ce lien :<br/>
                        <a href="https://onepowerteam.com/pannel/index.php? c=User&a=emailconfirm&u_id=1&token=7b0576873ffcbb4ca61c5a225b94e7">
                        https://onepowerteam.com/pannel/index.php?c=User&a=emailconfirm&u_id=1&token=7b0576873ffcbb4ca61c5a225b94e7</a>';

        $tab =  array('<br/>', '<br />', '<br>', '<li>', '</li>', '</p>');
        $mail->AltBody = 'Version Texte : ' . strip_tags( str_replace( $tab, PHP_EOL, $mail->Body ) );

        if( $mail->send() == false ) {
            echo 'Message could not be sent.';
            echo 'Mailer Error: ' . $mail->ErrorInfo;
        } else {
            echo 'Message has been sent at '.date('d/m/Y H:i:s');
        }

Il me semble que les fins de lignes sont \r\n (quelles que soient les plateformes)
est-ce qu'en mode 'mixed' ça fonctionne ?
en mode "alternative" c'est le client mail qui choisit la meilleure version (texte / html). la préférée est placée en général à la fin
source
et la vidéo de B zontag (à partir de 52')

RiderFx3
Auteur

Merci beaucoup huggy, je vais regarder ça et je reviens vers toi !
EDIT : je reviens vers toi, même problème en mode mixed.

Après avoir regardé quelques partie de la vidéo (très complète d'ailleurs) et la page web que tu m'as envoyé :
mixed c'est quand tu as des pièces jointes,
alternative c'est quand tu as un format mis en forme et une format texte (le meilleur à la fin effectivement.)

Voilà ou j'en suis, ça me semble parfaitement correct en rapport à tout ce que j'ai vu :
MAIS je ne reçois encore et toujours QUE la partie TXT :(

private function headers(){
        $this->headers = 'MIME-Version: 1.0' . PHP_EOL;
        $this->headers .= 'From: ' . $this->from . PHP_EOL;
        $this->headers .= 'Reply-To: ' . $this->reply_to . PHP_EOL;
        $this->headers .= 'To: ' . $this->dest . PHP_EOL;
        $this->headers .= 'Priority: normal' . PHP_EOL;
        $this->headers .= 'X-Confirm-Reading-To: '. $this->reply_to . PHP_EOL;
        $this->headers .= 'X-Mailer: PHP/' . phpversion() . PHP_EOL;
        $this->headers .= 'X-Priority: 3' . PHP_EOL;

        $this->headers .= 'Content-Type: multipart/alternative; boundary="'.$this->limit.'"' . PHP_EOL;     
}

private function set_message_text_and_html(){
        //----------------------------------------------- 
        //DEBUT
        //-----------------------------------------------
        $this->message = 'This is a multi-part message in MIME format.'. PHP_EOL;
        //----------------------------------------------- 
        //MESSAGE TEXTE
        //-----------------------------------------------
        $this->message .= PHP_EOL . '--' . $this->limit . PHP_EOL;
        $this->message .= 'Content-Type: text/plain; charset=utf-8' . PHP_EOL;
        $this->message .= 'Content-Disposition: inline' . PHP_EOL;
        $this->message .= 'Content-Transfer-Encoding: 8bit' . PHP_EOL;
        $this->message .= PHP_EOL . $this->txt . PHP_EOL . PHP_EOL;

        //----------------------------------------------- 
        //MESSAGE HTML
        //-----------------------------------------------
        $this->message .= PHP_EOL . '--' . $this->limit . '--' . PHP_EOL;
        $this->message .= 'Content-Type: text/html; charset=utf-8' . PHP_EOL;        
        $this->message .= 'Content-Disposition: inline' . PHP_EOL;
        $this->message .= 'Content-Transfer-Encoding: 8bit' . PHP_EOL;
        $this->message .= PHP_EOL . $this->content . PHP_EOL. PHP_EOL;              

        //----------------------------------------------- 
        //FIN
        //-----------------------------------------------
        $this->message .= PHP_EOL . '--' . $this->limit . '--' . PHP_EOL;

        var_dump( $this->content );
}

J'ai var_dump mon contenu html et mon contenu texte pour vérifier, et ils sont bien différents et formatés correctement.

le plus simple serait de récupérer le mail reçu et de l'enregistrer en tant que fichier.
puis le modifier jusqu'à ce qu'il soit accepté par Thunderbird ou autre client
je pense à un problème de boundary mal reconnu.

RiderFx3
Auteur

Voici mon boundary, il correspond à ce qu'on trouve partout sur le net, avec un id unique etc.

$this->limit = '-----=' . md5( uniqid( microtime(), TRUE ) );

Quoi qu'il en soit maintenant que j'ai configuré PHPMailer je pense utiliser cette classe pour éviter les problèmes, mais je restre frustré d'avoir codé une classe que je ne peux pas utiliser ^^

Merci pour ton aide ! :D