// fonction a utilisation interne perso
// retourne true si l'adresse est du type xx@xx.xx , false autrement
function test_addresse($ad)
{
// echo "on teste l'adresse $ad";
return( ereg('^[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+'.
'@'.
'[-!#$%&\'*+\\/0-9=?A-Z^_`a-z{|}~]+\.'.
'[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+$',
$ad) );
}
// fonction a utilisation interne perso
// detecte si plusieurs adresse existent séparées par des ,
// soumet chaque adresse a la fonction precedante
// retourne true si toutes les adresses email sont correctes, false autrement
function parse_address($str)
{
$adresses = explode(",",$str);
$ret=true;
while(list(,$v) = each($adresses))
{
if(!test_addresse($v))
{
$ret = false;
// une seule adresse fausse suffit ;
}
else
{
// echo "l adresse $v est bonne ";
}
}
return $ret;
}
if(strtolower($REQUEST_METHOD) == "post")
{
// l'upload et l'encodage d'un fichier pour la piece jointe peuvent prendre du temps...
// la fonction void set_time_limit ( int seconds )fixe le délai d'expiration d'un script, en secondes.
// Si cette limite est atteinte, le script s'interrompt, et renvoie une erreur fatale
// set_time_limit(500); non valable chez online
// on récupère ici depuis la page mecontacter.html les champs suivant
// $de : contient une adresse mail pour le (dans 4° param entete, from:)
// $cc : contient une adresse mail pour le (dans 4° param entete, cc:)
// $sujet : contient le sujet du mail pour le (dans 2° param, sujet)
// $corps : contient le contenu du mail (dans 3° param, message)
// $pj : contient le fichier donné en pièce jointe. (dans 4° param entete, MIME-VERSION......)
$a="michel@cabare.net";
// fixé avec mon adresse mail pour le (dans 1° param, a)
// $erreur est un tableau qui contiendra tous les messages d'erreurs eventuels lors de la verification du formulaire
unset ($erreurs); // raz de cette variable, au cas ou, pour etre sur
$erreurs = array();
//**************************************************************************
//************** FONCTION MAIL standard php *************
//**************************************************************************
// la fonction standard mail(string to, string subject, string message, string additional_headers, string additional_parameters)
// accepte donc 5 paramètres string, séparé par des virgules, dont les 4 premiers seulement nous interessent
// appel de la fonction mail
// mail($a,$sujet,$message,$entete);
// 1° param: $a destinataire
// 2° param: $sujet objet du mail
// 3° param: $corps corps du message
// 4° param: $entete concatenation de paramètres supplémentaires
// Le quatrième argument passé sera inséré à la fin de l'en-tête. Typiquement, cela permet d'insérer des en-têtes supplémentaires.
// Les en-têtes multiples doivent être séparées par des virgules.
// sous Windows 32bits, vous devez utiliser \r\n pour séparer les en-têtes.
// les en-têtes cc: et bcc: sont sensibles à la casse et doivent être écrits Cc: et Bcc: sous Win32.
//**************************************************************************
//************** FONCTION EMAIL spécifique online *****
//**************************************************************************
// la fonction online email(string from, string to, string subject, string message, string replyto, string additional_headers)
// accepte donc 6 paramètres string, séparé par des virgules, les 6 paramètres doivent être explicités !
// De plus comme on doit expliciter tj le paramètre 1 from, IL NE FAUT PAS LE REDEFINIR DANS additionnal_headers
//************** STRUCTURE D'UN MAIL ***********************
// MIME veut dire "Multipurpose Internet Mail Extensions".
// Malgré tout, un mail n'est composé que de caractères ASCII Une conversion des fichiers non-ASCII est donc nécessaire
// et une seconde traduction vers leur format original permet de les lire à la réception.
// Un message au format MIME est composé de plusieurs parties indépendantes (attachements).
// Différents types d'encodage sont disponibles pour le transfert, dont l'encodage base64.
// Pour que les données puissent être lues sous une forme correcte, leur type et le format d'encodage doivent être précisés
// Un mail commence toujours par des champs d'en-tête qui décrivent sa structure
// Il existe 5 types de champ d'en-tête, dont 2 seulement utilisé ici, Content-Type et Content-Transfer-Encoding.
// Le champ Content-Type est constitué de deux parties, un type et un sous-type.
// Dans Content-type: text/html; "text" est le type et "html" le sous-type.
// Le message le plus simple contient du texte en caractères ASCII sans formatage.
// Le champ Content-Type sera dans ce cas : Content-type: text/plain ; charset=us-ascii
// Un message compatible MIME doit contenir un champ d'en-tête écrit exactement sous cette forme : MIME-Version: 1.0
// Mais la plupart des messages sont plus complexes et peuvent comprendre plusieurs parties de type varié :
// *********************************************************************************************************
// Chaque partie est dans ce cas délimitée par une ligne appelée "boundary" Cette ligne ne doit apparaître nulle part
// dans aucune des parties du message; sensible à la casse, elle ne doit contenir que des caractères sûrs pour le transfert
// et ne doit pas finir par un espace comme dans l'exemple dessous
// Content-Type: multipart/mixed; boundary="1995021309105517"
// Chaque nouvelle partie dans le mail commence par cette ligne préfixée d'une séquence
// (Carriage Return Line Feed : retour chariot suivi d'un retour à la ligne, "\r\n"
// en PHP ; deux "\n\n" fonctionnent aussi) et de deux tirets "--" : comme dans "--1995021309105517"
// Le dernier "boundary", qui marque la fin du message, est suivi de 2 tirets "--" : comme dans "--1995021309105517--"
// un messages peut aussi comprendre une partie encapsulée :
// *********************************************************
// Un en-tête MIME suivi de 2 séquences décrit le type des données encapsulées :
// --1995021309105517
// Content-type: image/jpeg
// Content-transfer-encoding: base64
// Le second champ d'en-tête MIME, Content-transfer-encoding, décrit le type d'encodage utilisé dans le transfert des données
// conforme à la norme RFC 2045 : scinde une chaîne en plusieurs morceaux
// en lignes de 76 caractères délimitées par les caractères "\r\n"
// test validite adresse mail
// $de = str_replace(" ", "", $de); // supression des espaces eventuels
//if (!$de=="") {
// if(!parse_address($de)) {
//$erreurs[] = "Votre adresse email -$de- semble incorrecte";
// }
// }
// test validite adresse mail // supression des espaces eventuels
$cc = str_replace(" ", "", $cc);
if (!$cc=="") {
if(!parse_address($cc)) {
$erreurs[] = "l'adresse donnée en copie conforme -$cc- semble incorrecte";
}
}
//$_FILES["monfichier"]["name"]; est équivalent à : $monfichier_name; on récupère le nom
//$_FILES["monfichier"]["size"]; est équivalent à : $monfichier_size; on récupère la taille
//$_FILES["monfichier"]["type"]; est équivalent à : $monfichier_type; on récupère son type
//$_FILES["monfichier"]["tmp_name"] ; est équivalent à : $monfichier_tmp_name; nom temporaire du fichier qui sera chargé sur la machine serveur
// test validite taille piece jointe (limite à 2 Mega pour telecherger des fichiers chez Amen.fr)
if($pj) {
if($pj_size > 2000 * 1000) {
$erreurs[] = "La taille du fichier joint dépasse la taille autorisée.
Votre fichier est de ".number_format($pj_size, 2, ",", " ")." Ko et la taille maximale autorisée est de 2000 Ko";
// la fonction number_format retourne une chaîne avec un nombre formaté. number_format accepte 1,2 ou 4 paramètres
// Avec 4 paramètres ici pour nous, formatage avec 2 décimales, "," comme séparateur décimal, et " "séparateur de milliers
}
else
{
// echo "la piece jointe 1 -$pj- se nomme $pj_name sa taille est $pj_size son type est $pj_type";
$pjnomorigine = $pj_name;
}
}
if(count($erreurs) == 0) {
// supprime les caractères d'échappement
// $de = stripslashes($de);
$sujet = stripslashes($sujet);
$corps = stripslashes($corps);
// teste si le champ de: est rempli ;
// if($de) {
// echo "cela roule";
// }
// else {
// $de = "anonyme depuis site web"; // si le demandeur n'a rien prévu, on met cette addresse
// }
// teste si le champ sujet: est rempli ; encodage de la chaîne en iso-8859-1
if($sujet) {
$sujet = "=?iso-8859-1?q?".str_replace("%", "=", rawurlencode(stripslashes($sujet))."?=");
}
else {
$sujet = "sans sujet"; // si le demandeur n'a rien prévu, on met ce sujet
}
// le 4° paramètre headers est donc une chaîne stockée dans la variable $entete
//modif online $hfrom="From: ";
// mot clé From: permet de définir l'adresse mail de l'expediteur
// adresse email de l'expéditeur
//modif online $hfrom.= "$de\n";
// mot clé Return-Path: permet de définir adresse mail retour en cas d'echec
// $retour= "Return-Path: <$de>\n"; si on s'en sert, faut concaténer ensuite dans $entete
$hcc="Cc: $cc \n";
// mot clé Cc: permet de définir une adresse mail d'envois en copie
//modif online $entete=$hfrom.$hcc;
$entete=$hcc;
// creation du 4° paramètre par concatenation des 2 chaines $from et $cc
// teste si un fichier est joint au message
//modif online if(file_exists($pj))
if($pj)
{
// génère un nombre aléatoire unique servant de délimiteur que l'on ne peut trouver nulle part dans le corps du message
$boundary = md5(uniqid(rand()));
// c'est un message au format MIME
$entete .= "MIME-Version: 1.0\n";
// ce message est composé de plusieurs parties
$entete .= "Content-Type: multipart/mixed;\n\tboundary=\"$boundary\"";
//-- corps du message --
$message = "C'est un message de format MIME en plusieurs parties.\n\n";
$message .= "--$boundary\n";
// type MIME, version du mail (HTML ou texte pur)
$message .= "Content-Type: text/$enc_texte; charset=iso-8859-1\n";
// format d'encodage des données
$message .= "Content-Transfer-Encoding: 8bit\n\n";
// contenu du message récupéré depuis le formulaire
$message .= "$corps\n\n";
// $pj_name = "=?iso-8859-1?q?".str_replace("%", "=", rawurlencode(stripslashes($pj_name))."?=");
// supprime les caractères d'échappement le nom de manière a eliminer les caractères éventuels non conformes
// echo "la piece jointe 2 se nomme après $pj_name sa taille est $pj_size son type est $pj_type";
// teste si le navigateur envoie le type MIME du fichier joint
if($pj_type)
$type_mime = $pj_type;
else
// type MIME par défaut
$type_mime = "application/octet-stream";
// ******* UPLOAD DE FICHIER N.B: particularite Provider amen ! ! ! ********************
// lorsque l'on telecharge un fichier, celui se stocke dans un dossier temporaire nommé tmp
// ce dossier tmp doit etre crée au préalable, et il faut faire un chmod 777 dessus (via ftp par exemple)
// le chemin de ce dossier est le suivant chez amen :
// /home/sites/www.domaine/web/tmp pour moi donc c'est /home/sites/www.cabare.net/web/tmp
// pour charger le fichier uploadé ds un fichier de destination on utilise
// la fonction move_uploaded_file( string filename , string destination )
//***********************************************************************************************
// ******* UPLOAD DE FICHIER N.B: particularite Provider online ! ! ! ********************
// lorsque l'on telecharge un fichier, on peut le stocker dans un dossier quelconque par exemple tmp
// ce dossier tmp doit etre crée au préalable
// le chemin de ce dossier est le suivant chez online :
// tmp/ pour moi donc c'est tmp/
// pour charger le fichier uploadé ds un fichier de destination on utilise
// la fonction copy( string filename , string destination )
//***********************************************************************************************
if ($pj) /* on a entré un nom de fichier pour l'image dans le formulaire */
{
/******* récupération du nom du fichier uploadé**********/
/* le dossier physique des pj est global au site, se trouve en tmp...*/
$fichiercible="tmp/" . $pj_name;
/******** copie du fichier dans le dossier adéquate*****/
/* copy fait une copie du fichier temp passé au fichier physique, elle renvoit TRUE en cas de succès, et FALSE sinon */
copy($pj,$fichiercible) or die("copie de fichier échouée, le nom du fichier est $fichier_name -");
/******* récupération du nom du fichier uploadé**********/
/* le dossier physique des images est tmp au site...*/
$pj_name="tmp/".$pjnomorigine;
$pj=$pj_name;
// echo "la pj vaut $pj, son nom vaut $pj_name, sa taille est $pj_size son type est $pj_type ";
// echo "le fichier cible vaut $fichiercible son nom vaut $fichiercible_name, sa taille est $fichiercible_size son type est $fichiercible_type";
}
// lecture du fichier temporaire stocké chez le provider
// son contenu est placé dans la variable $fichier_joint
$fp = fopen($pj,"r");
$fichier_joint = fread($fp,filesize($pj));
fclose($fp);
//unlink($pj); // supprime le fichier stocké sur le serveur Web (optionnel, permet de garder une trace des pj...
$message .= "--$boundary\n";
// les fichiers texte n'ont pas besoin d'être codés en BAse64, pour verifier si le fichier est un fichier texte
// on vérifie si dans son type mime on retrouve la chaine "text"
if(eregi("text",$pj_type)) { // c'est un fichier texte
// définition du champ type
$message .= "Content-Type: $type_mime;\n\tname=\"$pj_name\"\n";
// encodage en 8 bits
$message .= "Content-Transfer-Encoding: 8bit\n";
// affichage du fichier joint dans le mail ("inline"); l'autre possiblité est "attachment" (comme pièce jointe)
$message .= "Content-Disposition: inline;\n\tfilename=\"$pj_name\"\n\n";
$message .= "$fichier_joint\n";
} else { // ce n'est pas un fichier texte, faut encoder et découper...
// lecture et encodage du fichier joint en base64
// conforme à la norme RFC 2045 : scinde une chaîne en plusieurs morceaux
// en plusieurs lignes de 76 caractères délimitées par les caractères "\r\n"
$fichier_joint = chunk_split(base64_encode($fichier_joint));
// définition du champ type
// $message .= "Content-Type: $type_mime;\n\tname=\"$pj_name\"\n";
$message .= "Content-Type: $type_mime;\n\tname=\"$pjnomorigine\"\n"; // dans name= on donne le nom de la pièce jointe
// encodage du fichier joint en base64
$message .= "Content-Transfer-Encoding: base64\n";
// affichage du fichier joint dans le mail ("inline"); l'autre possiblité est "attachment" (comme pièce jointe)
// $message .= "Content-Disposition: inline;\n\tfilename=\"$pj_name\"\n\n";
$message .= "Content-Disposition: inline;\n\tfilename=\"$pjnomorigine\"\n\n"; // dans filename= on donne le nom de la pièce jointe
$message .= "$fichier_joint\n";
$message .= "--$boundary--";
}
}
// pas de fichier joint
else {
$entete .= "Content-Type: text/$enc_texte; charset=iso-8859-1\n";
$message = $corps;
}
}
// on verifie le tableau des erreurs, s'il n' est pas vide, on liste les erreurs
if(count($erreurs) > 0) {
echo "Votre message n'a pu être envoyé pour les raisons suivantes :
";
echo "";
while(list($k,$v) = each($erreurs)) {
echo "- ".$v."
";
}
echo "
";
}
else // s'il est vide, on peut lancer le(s) mail(s) avec ses 4 paramètres
{
// envois du email au destinataire principal: moi !
$rep = "webmaster";
if(!email("webmaster",$a, $sujet, $message, $rep, $entete))
echo "Le message à $a n'a pu être envoyé.";
//else
// echo "vous m'avez envoyé un message dont a: vaut -$a- sujet vaut -$sujet- message vaut -$message- et entete vaut -$entete-, je vous en remercie";
// L'envoi du email aux Cc se fait en bouclant sur les adresses mails séparées par des ,
// En cas d'échec, une erreur est ajoutée au tableau des erreurs
if($cc) {
$adresses = explode(",",$cc);
while(list(,$v) = each($adresses))
{
echo "adresse envoyée en cc $v à partir de $cc";
if(!email("webmaster",$v, $sujet, $message, $rep, $entete))
echo "Le message à $v n'a pu être envoyé.";
}
}
}
}
?>