Transformer du texte ou de l'html en texte conforme à la norme d'envoi d'email rfc2045 quoted printable

Soyez le premier à donner votre avis sur cette source.

Snippet vu 5 756 fois - Téléchargée 17 fois


Contenu du snippet

suite à des envois de mail pour une newsletter, hotmail, msn live, yahoo et ymail ont mis en spam pour non conformité à la rfc2045
j'ai essayé avec la fonction "chunk_split(base64_encode($messhtml))" qui est conforme en tout point par la rfc2045, mais c'est normalement réservé au codage de fichier donc interprété comme du spam !

voici tout ce que ce script fait :
- transformation des caractères ascci ISO_8859-1 non supportés par quoted-printable en leurs équivalent hexadécimal (ex: "=" en "=3D" ou "é" en "=E9"
lien vers la table de conversion : http://fr.wikipedia.org/wiki/ISO_8859-1
- des lignes de 76 caractères maxi
- le 76ème caractère doit être "=\r\n"
- il ne faut pas couper un caractère quoted-printable sur 2 lignes (ex: "=E9")

Source / Exemple :


<?php

function RFC2045_quoted_printable($str, $html)
{
  if ($html==1)
  {
    //remplacement des caracteres en leur équivalent html
    $str=htmlentities($str);

    //enlevons les retours chariots et tabulations qui ne servent à rien dans le html
    $str = str_replace(array("\t", "\r", "\n","\r\n" )," ",$str);
    // enlever les espaces en trop qui ne servent à rien dans le html
    $str = ereg_replace("[ ]+", " ",$str);
  }
  //echo $str;
  $out = '';

  //transformation en quoted printable
  for ($j = 0; $j <= strlen($str) - 1; $j++)
  {
    //ne supporte pas l'unicode si caractère  sont encodés sur 2 caractères
    $char = substr ( $str, $j, 1 );
    $ascii = ord ( $char );

    if ( $ascii < 32 || $ascii == 61 || $ascii > 126 )
    {
      $char = '=' . strtoupper ( sprintf("%02X", $ascii ) );
    }
    $out .= $char;
  }

  $line = $out;
  $out = '';
  //coupure du texte en ligne de 76 caracteres ou plus
  while ( strlen($line)  >= 76 )
  {
    //controle si le 74eme caractere est un =
    if ($line[73]=='=')
    {
      $out.=substr($line,0,73)."=\r\n";
      $line=substr($line,73)  ;
    }
    else {
      //controle si le 75eme caractere est un =
      if ($line[74]=='=')
      {
        $out.=substr($line,0,74)."=\r\n";
        $line=substr($line,74)  ;
      }
      else {
          //remplacement du 76ème
          $out.=substr($line,0,75)."=\r\n";
          $line=substr($line,75) ;
        }
      }
    }
  }
  $out.=$line."\r\n";
  return $out;
}

//echo RFC2045_quoted_printable($message,0);
//echo RFC2045_quoted_printable($messagehtml,1);

?>

Conclusion :


merci de faire part d'améliorations à apporter

A voir également

Ajouter un commentaire

Commentaires

Messages postés
575
Date d'inscription
dimanche 23 décembre 2001
Statut
Membre
Dernière intervention
23 octobre 2012

merci pour cette fonction bien pratique, je compte l'utiliser dans un module de newsletter
Messages postés
654
Date d'inscription
jeudi 3 avril 2003
Statut
Membre
Dernière intervention
10 février 2009
1
Sinon (pour rappel) il y a les fonctions :
- imap_8bit (nécessite l'extension imap activée)
- quoted_printable_encode (nécessite php 5.3)

Niveau code j'ai quelques remarques à faire, il vaut mieux utiliser les fonctions preg_* plutot que ereg_* qui sont maintenant dépreciées et
for ($j = 0; $j <= strlen($str) - 1; $j++)
devientfor ($j 0, $k strlen($str); $j < $k; $j++)
ça évitera de recalculer la taille de $str à chaque itération
je chipote mais il y a aussi
substr ( $str, $j, 1 )
qui pourrait devenir
$str[$j]
"strtoupper ( sprintf("%02X", $ascii ) )", le strtoupper est inutile comme X veut déjà dire qu'on veut le résultat en majuscule
et une dernière chose
substr($line,73,strlen($line))
devient
substr($line,73)
la fonction substr, si tu spécifie pas de 3ème argument prend automatiquement la longueur totale de la chaine

voilà ça sera tout :-)
Messages postés
4580
Date d'inscription
samedi 19 janvier 2002
Statut
Modérateur
Dernière intervention
9 janvier 2013
27
Mouais...
Quelques suggestions ou remarques :
1 - simplification du code :
Les tableaux $arrayaccent, $arraysansaccent et l'appel de la fonction str_replace($arrayaccent, $arraysansaccent, $str) sont inutiles. Un appel à la fonction native htmlentities fera l'affaire et sera nettement plus performant.

2 - Ce code ne supporte pas l'unicode comme ici :
$char = substr ( $str, $j, 1 );
puisque certains caractères (accentués, etc.) sont encodés sur 2 caractères et non 1.

Sinon, merci de nous avoir rappelé l'existence de la RFC-2045. :)

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.