Class mail gestion complète

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

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)