Class mail gestion complète

Soyez le premier à donner votre avis sur cette source.

Vue 18 369 fois - Téléchargée 2 065 fois

Description

Bonjour,

Voici une petite class Mail que j'ai codé.
Elle permet l'envoi de mail texte et/ou html, avec pièces jointes.
Destinataires, copies conformes, copies cachées et attachements multiples.
Méthode permettant de voir les paramètres d'envoi, et une méthode de vérification de mail.

Par defaut l'envoi se fait en mode texte, meme si votre message est en html il sera automatique converti pour l'envoi en texte avec une supression des balises html.

Pour ce qui concerne l'utilisation, et les options regarder plus bas ;)

Edit: Ajout de la commande supplémentaire. Modification de la gestions des erreurs.
Edit2: Mise en place d'un journal d'erreur. verifMail passe en static on peut donc l'utiliser sans instancier la class.
Grande nouveauté mise en place d'un système antispam, autrement dit vous ne pouvez mettre qu'une seule fois la meme adresse dans destinataire, et dans les copies.
Edit3: Possibilité de mettre des pieces jointes directement dans le html. Pour cela code html normal. Par exemple pour mettre une image <img src="image.gif" /> et votre image sera automatique jointe...

Toutes les pices jointes html ou non, doivent evidemment se trouver sur le serveur pour etre envoyé.

Laissez vos commentaires, j'espère que ca vous plaira ;)

Source / Exemple :


<?php
/************ Class Mail V2.5 by Benjy ************/

class Mail {
	protected $destinataire;
	protected $sujet;
	protected $message;
	protected $attachement;
	protected $attachementhtml;
	protected $expediteur;
	protected $copieconforme;
	protected $copiecachee;
	protected $boundary;
	protected $priority;
	protected $sendmail_path;
	protected $errolog;

/************ Methodes propre a la class Mail ************/

	function __construct() {
		$this->destinataire = array();
		$this->sujet = '';
		$this->message = '';
		$this->boundary = "_" . md5(uniqid(rand()));
		$this->attachement = array();
		$this->attachementhtml = '';
		$this->expediteur = '';
		$this->copieconforme = array();
		$this->copiecachee = array();
		$this->priority = 3;
		$this->sendmail_path = '';
		$this->errolog = '';
	}

	function __destruct() {
	}

	protected function BodyLineWrap($Value) {
		return wordwrap($Value, 78, "\n ");
	}

	protected function constructheader($type) {
		$entete = "Date: ". date('r') ."\n";
		$entete .= "MIME-Version: 1.0\n";

		$entete .= "X-Sender: $this->expediteur\n";
		$entete .= "X-Mailer: PHP\n";
		$entete .= "X-auth-smtp-user: webmaster@votresite.com \n";
		$entete .= "X-abuse-contact: abuse@votresite.com \n";
		$entete .= "X-Priority: $this->priority \n";

		$entete .= "Disposition-Notification-To: $this->expediteur\n";
		$entete .= "X-Confirm-Reading-To: $this->expediteur\n";
		$entete .= "Return-receipt-to: $this->expediteur\n";
		$entete .= "Errors-To: $this->expediteur\n";
		$entete .= "From: $this->expediteur\n";
		$entete .= "Reply-to: $this->expediteur\n";
		$entete .= "Return-Path: $this->expediteur\n";

		if(!empty($this->copieconforme))
			$entete .= "Cc: " . implode(',', $this->copieconforme) . "\n";
		if(!empty($this->copiecachee))
			$entete .= "Bcc: " . implode(',', $this->copiecachee) . "\n";

		if($type == 'texte' && empty($this->attachement))
			$entete .= "Content-Type: text/plain;\nContent-Transfer-Encoding: 8bit";
		elseif($type == 'html' && empty($this->attachement) && empty($this->attachementhtml)) {
			$entete .= "Content-Type: text/html; charset=\"iso-8859-1\"; format=flowed\n";
			$entete .= "Content-Transfer-Encoding: quoted-printable";
		}
		else {
			if(empty($this->attachementhtml))
				$entete .= "Content-Type: multipart/mixed;\n boundary=\"$this->boundary\"\n";
			else
				$entete .= "Content-Type: multipart/related;\n boundary=\"$this->boundary\"\n";
		}

		return $entete;
	}

	protected function constructbody($type) {
		if(!empty($this->message)) {
			$body = '';
			$message = $this->message;

			if($type == 'texte' || $type == 'tout') {
				if(empty($this->attachement) && $type == 'texte')
					$body .= strip_tags($message);
				else {
					$body .= "This is a multi-part message in MIME format.\n";
					$body .= "--$this->boundary\n";

					$body .= "Content-Type: text/plain;\nContent-Transfer-Encoding: 8bit\n\n";
					$body .= $this->BodyLineWrap(strip_tags($message));
					$body .= "\n--$this->boundary\n";
				}
			}

			if($type == 'html' || $type == 'tout') {
				if(empty($this->attachement) && empty($this->attachementhtml) && $type == 'html') {
					$message = nl2br(html_entity_decode(stripslashes($message)));
					$body .= $message;
				}
				else {
					$body .= "This is a multi-part message in MIME format.\n";
					$body .= "--$this->boundary\n";

					$body .= "Content-Type: text/html; charset=\"iso-8859-1\"; format=flowed\n";
					$body .= "Content-Transfer-Encoding: 8bit\n\n";
					$message = nl2br(html_entity_decode(stripslashes($message)));
					$body .= $message;
					$body .= "\n--$this->boundary\n";

					if(!empty($this->attachementhtml))
						$body .= $this->attachementhtml;
				}
			}

			foreach($this->attachement as $attach) {
				$body .= "Content-Type: application/octetstream;\n name=\"".$attach."\"\n";
				$body .= "Content-Transfer-Encoding: base64\n";
				$body .= "Content-Disposition: attachment;\n filename=\"".$attach."\"\n\n";
				$body .= chunk_split(base64_encode(file_get_contents($attach)))."\n\n";
				$body .= "\n--$this->boundary\n";
			}

			return $body;
		}
	}

	protected function htmlattachement() {
		$erreur = '';
		preg_match_all('`\<[\w]+ src="([\w.]+)" [\</\w]+\>`im', $this->message, $out);
		$file[0] = array();
		foreach($out[1] as $name) {
			if(file_exists($name)) {
				if(!in_array($name,$file[0])) {
					$ID = md5( uniqid ( rand() ) ).$_SERVER['SERVER_NAME'];
					$file[0][$name] = $ID;
					$file[1][$name] = '`(\<[\w]+ )src="' . $name . '"( [\</\w]+\>)`';
					$file[2][$name] = '$1src="cid:'.$ID.'"$2';
				}
			}
			else {
				$erreur .= 'Erreur, fichier '. $name .' pour l\'attachement inexistant<br />';
			}
		}
		$this->message = preg_replace($file[1],$file[2], $this->message);
		foreach($file[0] as $name => $ID) {
			$this->attachementhtml .= "Content-Type: ".mime_content_type($name)."; name=\"$name\"\n";
			$this->attachementhtml .= "Content-Transfer-Encoding: base64\n";
			$this->attachementhtml .= "Content-ID: <$ID>\n\n";
			$this->attachementhtml .= chunk_split(base64_encode(file_get_contents($name)))."\n\n";
			$this->attachementhtml .= "\n--$this->boundary\n";
		}
		if(empty($erreur))
			return TRUE;
		else {
			$this->errolog .= $erreur;
			return FALSE;
		}
	}

/************ Methodes utilisateur ************/

	function addDestinataire() {
		$erreur = '';
		if(func_num_args() == 0)
			$erreur .= 'Erreur, vous devez specifiez un destinataire<br />';
		else {
			$arg = func_get_args();
			foreach($arg as $dest) {
				if(!in_array($dest, $this->destinataire) && !in_array($dest, $this->copieconforme) && !in_array($dest, $this->copiecachee)) {
					if($res = $this->verifMail($dest, TRUE)) {
						array_push($this->destinataire, $res);
					}
					else
						$erreur .= 'Erreur, destinataire "'. $dest .'" incorrect<br />';
				}
				else
					$erreur .= 'Erreur, destinataire "'. $dest .'" deja presente<br />';
			}
		}
		if(empty($erreur))
			return TRUE;
		else {
			$this->errolog .= $erreur;
			return FALSE;
		}
	}

	function defSujet($subject) {
		if(!empty($subject) && is_string($subject)) {
			$this->sujet = nl2br(html_entity_decode(stripslashes($subject)));
			return TRUE;
		}
		else
			$this->errolog .= 'Erreur, sujet '. $subject .' incorrect<br />';
	}

	function addAttach() {
		$erreur = '';
		if(func_num_args() == 0)
			$erreur .= 'Erreur, vous devez specifiez un fichier<br />';
		else {
			$arg = func_get_args();
			foreach($arg as $attch) {
				if(!in_array($dest, $this->attachement) && is_string($attch) && file_exists($attch))
					array_push($this->attachement, $attch);
				else
					$erreur .= 'Erreur, fichier '. $attch .' pour l\'attachement incorrect ou inexistant<br />';
			}
		}
		if(empty($erreur))
			return TRUE;
		else {
			$this->errolog .= $erreur;
			return FALSE;
		}
	}

	function addCc() {
		$erreur = '';
		if(func_num_args() == 0)
			$erreur .=  'Erreur, vous devez specifiez une adresse pour la copie conforme<br />';
		else {
			$arg = func_get_args();
			foreach($arg as $cc) {
				if(!in_array($dest, $this->destinataire) && !in_array($dest, $this->copieconforme) && !in_array($dest, $this->copiecachee)) {
					if($res = $this->verifMail($cc, TRUE)) {
						array_push($this->copieconforme, $res);
					}
					else
						$erreur .=  'Erreur, adresse "'. $cc .'" pour la copie conforme incorrect<br />';
				}
				else
					$erreur .=  'Erreur, adresse "'. $cc .'" pour la copie conforme deja presente<br />';
			}
		}
		if(empty($erreur))
			return TRUE;
		else {
			$this->errolog .= $erreur;
			return FALSE;
		}
	}

	function addBcc() {
		$erreur = '';
		if(func_num_args() == 0)
			$erreur .= 'Erreur, vous devez specifiez une adresse pour la copie cachee<br />';
		else {
			$arg = func_get_args();
			foreach($arg as $bcc) {
				if(!in_array($dest, $this->destinataire) && !in_array($dest, $this->copieconforme) && !in_array($dest, $this->copiecachee)) {
					if($res = $this->verifMail($bcc, TRUE)) {
						array_push($this->copiecachee, $res);
					}
					else
						$erreur .= 'Erreur, adresse "'. $bcc .'" pour la copie cachee incorrect<br />';
				}
				else
					$erreur .= 'Erreur, adresse "'. $bcc .'" pour la copie cachee deja presente<br />';
			}
		}
		if(empty($erreur))
			return TRUE;
		else {
			$this->errolog .= $erreur;
			return FALSE;
		}
	}

	function defMessage($mess) {
		if(!empty($mess) && is_string($mess)) {
			$this->message = $mess;
			return TRUE;
		}
		else {
			$this->errolog .= 'Erreur, message '. $mess .' incorrect<br />';
			return FALSE;
		}
	}

	function defExpediteur($exp) {
		if($exp = $this->verifMail($exp, TRUE)) {
			$this->expediteur = $exp;
			return TRUE;
		}
		else {
			$this->errolog .= 'Erreur, expediteur "'. $exp .'" incorrect<br />';
			return FALSE;
		}
	}

	function defPriority($prio) {
		if(!empty($prio) && is_string($prio)) {
			switch($prio) {
				case 'urgent':
					$this->priority = 1;
				break;

				case 'normal':
					$this->priority = 3;
				break;

				case 'bas':
					$this->priority = 5;
				break;
			}
			return TRUE;
		}
		else {
			$this->errolog .= 'Erreur, priorite "'. $prio .'" incorrect<br />';
			return FALSE;
		}
	}

	function defSendmailpath($sendpath) {
		if(!empty($sendpath) && is_string($sendpath)) {
			$this->sendmail_path = $sendpath;
			return TRUE;
		}
		else {
			$this->errolog .= 'Erreur, parametre '. $sendpath .' incorrect<br />';
			return FALSE;
		}
	}

	function getInfo() {
		echo '<u>Destinataire(s):</u> ' . htmlspecialchars(implode(',', $this->destinataire)) . '<br />';
		echo '<u>Sujet:</u> ' . $this->sujet . '<br />';
		echo '<u>Message:</u><br />' . $this->message . '<br />';
		echo '<u>Expediteur:</u> ' . htmlspecialchars($this->expediteur) . '<br />';
		if(!empty($this->copieconforme))
			echo '<u>Copie(s) conforme(s):</u> ' . htmlspecialchars(implode(',', $this->copieconforme)) . '<br />';
		if(!empty($this->copiecachee))
			echo '<u>Copie(s) cachee(s):</u> ' . htmlspecialchars(implode(',', $this->copiecachee)) . '<br />';
		if(!empty($this->attachement))
			echo '<u>Piece(s) jointe(s):</u> ' . implode(',', $this->attachement) . '<br />';
		if(!empty($this->sendmail_path))
			echo '<u>Commande:</u> ' . $this->sendmail_path . '<br />';
	}

	function getErrorlog() {
		return $this->errolog;
	}

	static function verifMail($mail, $fct = NULL) {
		if(preg_match('`^(\w(?:[-_. ]?\w)* )?((\w(?:[-_.]?\w)*)@\w(?:[-_.]?\w)*\.(?:[a-z]{2,4}))$`', $mail, $out)) {
			if($fct) {
				$nom = empty($out[1]) ? $out[3] : $out[1];
				return ($nom.'<'.$out[2].'>');
			}
			else
				return TRUE;
		}
		else
			return FALSE;
	}

	function envoi($type = 'texte') {
		$erreur = '';
		if(empty($this->destinataire))
			$erreur .= 'Erreur, vous devez definir au moins un destinataire!';
		elseif(empty($this->expediteur))
			$erreur .= 'Erreur, vous devez definir un expediteur!';
		elseif(empty($this->sujet))
			$erreur .= 'Erreur, vous devez definir un sujet!';
		elseif(empty($this->message))
			$erreur .= 'Erreur, vous devez definir un message!';
		elseif(!$this->htmlattachement())
			$erreur .= 'Erreur lors de l\'attachement des fichiers present dans le message html!';
		else {
			if(empty($erreur)) {
				if(empty($this->sendmail_path))
					if(mail(implode(',', $this->destinataire), $this->sujet, $this->constructbody($type), $this->constructheader($type)))
						return TRUE;
					else {
						$erreur .= 'Erreur, mail non envoye<br />';
						$this->errolog .= $erreur;
						return FALSE;
					}
				else
					if(mail(implode(',', $this->destinataire), $this->sujet, $this->constructbody($type), $this->constructheader($type), $this->sendmail_path))
						return TRUE;
					else {
						$erreur .= 'Erreur, mail non envoye<br />';
						$this->errolog .= $erreur;
						return FALSE;
					}
			}
			else {
				$this->errolog .= $erreur;
				return FALSE;
			}
		}
	}

}
?>

Conclusion :


Pour envoyer un mail c'est simple:

Obligatoire:
$mail = new Mail();
$mail->addDestinataire('nom mail@domaine.fr');
$mail->defSujet('Bonjour ceci est le sujet');
$mail->defMessage('<b>Bonjour</b>, ceci est un test de ma classe mail :D');
$mail->defExpediteur('nom mail@domaine.fr');
//Par defaut envoi en texte
$mail->envoi();

Options:
//Piece jointe
$mail->addAttach('attach.txt');
//Copie conforme
$mail->addCc('nom mail@domaine.fr');
//Copie cachée
$mail->addBcc('nom mail@domaine.fr');
//Afficher les parametres d'envoi
$mail->getInfo();
//Envoi en html
$mail->envoi('html');
//Envoi en texte + html
$mail->envoi('tout');

Edit:
La classe possède aussi une methode interne de vérification d'une adresse mail a utiliser comme ceci:
if($mail->verifMail('adress@domaine.com'))
echo 'Adresse correct';
Elle verifie les adresses "adresse@domaine.com" et "nom adresse@domaine.com"

Pour l'ajout des destinaire, des pieces jointes, des copies conforme et caché, vous avez deux possibilitées:
Soit normalement un par un
$mail->methode('truc a ajouter');
Ou alors plusieurs a la fois:
$mail->methode('truc a ajouter', 'truc 2 a ajouter', 'truc 3 a ajouter' ...);

Precision: pour les destinataires, les copies, l'expediteur... Bref a chaque fois quoi vous avez a mettre une adresse mail, deux possibilités encore:
Soit classique: adresse@domaine.fr
Soit avec un alias: alias adresse@domaine.fr

Edit2: Ajout de la commande supplémentaire $mail->defSendmailpath('commande');

Edit3: Mise en place d'une journal d'erreur. Désormais les méthodes retourne True si pas de probleme False sinon.
Et pour consulter le journal d'erreur nouvelle méthode $mail->getErrorlog();

Edit4: Pieces jointes html automatique.

La methode verifMail passe en static on peut donc l'utilise sans instance de la classe comme ceci: Mail::verifMail('adresse@domaine.fr');

Aucun bug connu, n'hésitez pas a les signalés.

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

yassine_910
Messages postés
1
Date d'inscription
dimanche 8 juillet 2007
Statut
Membre
Dernière intervention
27 mars 2010

slt ,je veux savoir avec quel serveur tu as travaille??
calfou
Messages postés
24
Date d'inscription
dimanche 16 février 2003
Statut
Membre
Dernière intervention
18 mars 2010

Merci pour cette class qui fonctionne super bien et est très facile à intégrer!!

En revanche comme le dit Masternico, il aurait été bon d'ajouter la modif qu'il cite afin de ne pas avoir cette erreur.
masternico
Messages postés
494
Date d'inscription
dimanche 5 octobre 2003
Statut
Membre
Dernière intervention
1 septembre 2011

Bon, a-y-est... j'ai fini par débusquer mon bug... qui en fait était lié à un post précédent de neoced75.
Le problème, c'est que je n'avait pas d'affichage d'erreur et que la variable errorlog était toujours vide (en passant par geterrorlog())
Donc en fait la soluce avait été donnée par tomguide:

<<
à la ligne 148 (sur le visuel du code)

Vous avez "$this->message = preg_replace($file[1],$file[2], $this->message);"

Seulement, $file[1] et $file[2] n'étant pas toujours renseigné faites une petite verif avant, par exemple, remplacez le code ci-dessus par le suivant :

if(!empty($file[1]) && !empty($file[2])) {
$this->message = preg_replace($file[1],$file[2], $this->message);
}

ça vous évitera d'avoir une petite erreur.

>>

Il serait bien que la modif soit intégrée à la source car j'y ai passé du temps... pour rien puisque la soluce était déja donnée
masternico
Messages postés
494
Date d'inscription
dimanche 5 octobre 2003
Statut
Membre
Dernière intervention
1 septembre 2011

Salut,
mon soucis est que la variable $this->message se perd en cour de route.
Quand je fait un echo $this->message; à la fin de la proc Defmessage($mess), j'ai bien mon message, mais la variable se retrouve vide lorsque j'arrive dans constructbody()... je pige pas très bien pourquoi...
Si quelqu'un avait une piste pour m'aider

Merci
jdeheyn
Messages postés
23
Date d'inscription
vendredi 14 avril 2006
Statut
Membre
Dernière intervention
14 janvier 2010

Salut!
J'ai la même erreur que TOINE64 : "Parse error: syntax error, unexpected T_STRING, expecting T_OLD_FUNCTION or T_FUNCTION or T_VAR or '}' in /mnt/160/sda/3/4/avolpoet/classes/Mail.class.php on line 5"

Cela peut-il venir du fait que ce script doit être exécuté sous PHP5, et non PHP4 ?

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.

Du même auteur (cerede2000)