Il y a un aspect de la configuration de dotclear 2 qui est assez méconnu, c'est celui de la configuration de l'envoi de mail. C'est un problème que l'on rencontre fréquemment dans les applications php.

Lorsque l'on utilise la fonction mail de php il est très fréquent de voir les mails envoyés atterrir eu spam. Ceci est dû au fait que l'adresse de l'expéditeur n'est pas la même dans l'enveloppe et dans les headers ; les filtres antispam vérifient que ces deux champs sont égaux à la réception d'un mail.

Par défaut php (ou le serveur de mail, je ne suis pas sûr) va générer une adresse bidon pour l'expéditeur, à partir de l'utilisateur dans lequel le processus apache tourne. Ceci n'est pas pertinent, et pose problème dans notre cas.

Dotclear 2 fournit une solution par défaut dans son fichier de configuration, la fonction mail est en fait surchargée par une fonction maison de clearbricks, qui joue le rôle d'un serveur de mail, et qui envoie un mail bien formé. Pour plus d'infos voir le fichier de configuration et cette page de la doc : Personnaliser l'envoi des mails.

Cependant cette solution n'est pas optimale, notamment en termes de performance (sur un de mes sites, le script met plus de 30 secondes à s'exécuter à la soumission du formulaire). Il existe une solution qui n'est pas portable mais qui fonctionne mieux dans certains cas, il s'agit de passer les bonnes options à la fonction mail. Si on se trouve sur un serveur linux, avec sendmail ou postfix, il est possible d'envoyer des mails via la fonction mail, en ajoutant un argument dans le 5e paramètre de cette fonction mail, qui contient l'adresse de l'expéditeur.

Voici un exemple de fonction mail à placer dans votre config.php :

function _mail($to,$subject,$message,$headers)
{
        // recherche de l'adresse de l'expéditeur
        $h = explode("\n", $headers);
        $from = '';
        $p = null;
        foreach ($h as $l) {
                if (strpos($l, 'From:') === 0) {
                        if (preg_match('|<(.*)>|', $l, $matches))
                             $from = $matches[1];
                        break;
                }       
        }       

        // si l'adresse de l'expéditeur est trouvée, on ajoute le paramètre
        if (!empty($from)) {
                $p = '-f'.$from;
        }
        // appel à la fonction mail classique
        @mail($to, $subject, $message, $headers, $p);
}

Remarques :

  • Il est nécessaire de vérifier que votre "sendmail" supporte bien l'option -f (en tapant par exemple la commande suivante : echo test | sendmail -ftest@test.com monadresse@mondomaine.com).
  • D'apès la doc php, il faut vérifier que l'utilisateur dans lequel le serveur web tourne fait bien partie des utilisateurs de confiance du serveur de mail, sinon le mail sera envoyé avec un header X-Warning, qui risque de le bloquer au niveau des antispams. Personnellement j'ai envoyé un mail, et X-Warning n'est pas apparu dans les headers, donc tout va bien :) Pour plus de détails, voir la doc php pour la fonction mail, dans la description du paramètre additional_parameters.

Si vous avez des suggestions ou des remarques sur cette fonction, n'hésitez pas à les formuler ici dans les commentaires.