Créer un Mail Eevent Listener

Besoin

Vous avez besoin d'un formulaire de contact pour transmettre des demandes de contact à vos collaborateurs en fonction de leur secteur géographique et envisagez pour plusieurs solutions. Vous optez d'abord pour le protocle mailto assosié au lien HTML. C'est une bonne approche mais trés contraignant pour votre utilisateur d'utiliser sa propre boîte mail et soritr de votre site.

Alors vous établisser un jolie formualaire de contact HTML. Comme Celui-ci :

  • <form action="contact.php" method="POST">
    • <div class="compoment">
      • <label for="nom">NOM : </label>
      • <input type="text" name="FNAME" id="nom">
    • </div>
    • < div class="compoment">
      • <label for="prenom">NOM : </label>
      • <input type="text" name="NAME" id="prenom">
    • </div>
    • < div class="compoment">
      • <label for="mail">MAIL : </label>
      • <input type="mail" name="MAIL" id="mail">
    • </div>
    • < div class="compoment">
      • <label for="message">Message : </label>
      • <textarea name="MESS" id="message"></textarea>
    • </div>
  • <form>

Puis vous créez votre page contact.php qui retiend la method mail en PHP pour envoyer la demande

  • <?php>
    • $mail=$_POST["MAIL"];
    • $header='FROM:'.$mail.'\r\n'.
    • 'Reply-To:'.$mail.'\r\n'
    • .'X-Mailer:PHP/'.phpversion();
    • mail("votremail@exemple.fr","Demande de contact",$_POST["MESS"],$header);
  • ?>

Un probleme se pose, il va falloir rétintéger ses demandes dans la base de données et redispatcher les demandes vers le bon collaborateur.

Le design pattern Observer

Imaginez une corbeille de fruit qui sert de modèle pour plusieurs peintres au même moment. Tout les peintres ne retiennent pas la même chose de ce qu'ils voient. Certain se concentre sur la lumière d'autres la couleur ou encore seulement le volume etc.

La corbeille de fruit fait office de sujet et les peintre sont des observateurs, leur toiles le resultat de leur observations.

On va créer une classe sujet sendmail qui jouera le role de Subjet va se charger d'envoyer le mail. En parallèle on va créer une autre classe Observer qui se contentera uniquement de dispatcher les informations dans la BDD

Les Interfaces

Comme ce projet peut être rééxploité on va s'assurer qu'il suivra un modèl strict

Commençons par le sujet on doit s'assurer :

  • que l'on puisse lui associer des observateurs
  • que l'on puisse lui en retirer
  • que l'on puisse les déclencher

Donc on créer un ficher Iobservers.php avec

  • <?php>
    • Interface ISubject {
      • public function attach($obs);
      • public function detach($obs);
      • public function notifyObs();
    • }

Que va faire l'observateur ? Bha il va observer et faire les mises à jour.

Donc dans le même ficher on aura

    • Interface Iobserver {
      • public function update($sujet);
    • }
  • ?>

La classe Abstraite

A présent nous allons faire une classe abstraite pour déterminer comment nos observateurs doivent être construits

Donc on aura un fichierMailEListener.php

  • <?php>
    • abstract class MailEListener implements iObserver {
      • public function update($mail) {
        • $this->exec($mail);
      • }
      • public function exec($mail) {}
    • }

La classe SendMail

Enfin nous passons au chose serieuse la classe qui fera office de sujet

On aura besoins :

  • d'un tableau pour stocker nos observers
  • le mail du destinataire
  • Le sujet
  • Le message
  • Le mail de l'émeteur
  • getters
  • setters
  • constructeur
  • LA méthode d'envoi

Donc, toujous sur le fichier fichierMailEListener.php

  • class sendMail implements ISubject{
    • private $obs; // array des observers
    • private $des; // destinataire
    • private $message; // contenu du message
    • private $from; // emeteur
    • private $sujet; // subject
    • public function __construct($r,$s,$m,$f){
      • $this->des=$r;
      • $this->message=$m;
      • $this->from=$f;
      • $this->sujet=$s;
      • $this->obs=array();
    • }
    • public function __set($item,$val)[//ici les setters
    • public function __get($item)[//ici les getters
    • public function send($header){}

La classe implémente ISubject donc on aura aussi besoin de nos trois méthodes obligatoire

    • public function attach($observer){
      • $this->obs[]=$observer;
    • }
    • public function detach($observer){
      • if(is_int($key= array_search($observer, $this->obs, true))){
        • unset($this->obs[$key]);
      • }
    • }
    • public function notifyObs(){
      • foreach($this->obs as $o){
        • $o->update($this);
      • }
    • }
  • }

Plus qu'un truc à faire : s'assurer que l'on appelle notifyObs() au moment où on envoi le mail

    • public function send($header){
      • if(mail($this->des,$this->sujet,$this->message,$header){ Rappel mail() renvoi un booleen
        • $this->notifyObs();
        • return true;
      • }else
        • return false;
    • }

Voila la classe est finie. Maintenant on va faire un observer et le fichier sera fait.

On va créer un observer qui va mettre à jour un fichier CVS pour faire office d'exemple.

    • class MailCSV extends MailEListener{
      • private $filename;//nom du fichier CSV
      • public funtion __construct($file){
        • $this->filename=$file
      • }
      • private funtion write($mail){ //fonction qui va écrire ou créer notre fichier CSV
        • $content="";
        • if(file_exist($this->filename)){
          • $content=file_get_contents($this->filename)."\n";
        • }
        • $content.=$mail->from."#".$mail->sujet."#".date("Y m d");
        • file_put_contents($this->filename, $content);
      • }
      • public funtion exec($mail){
        • $this->write($mail);
      • }
    • }
  • ?>

Mise en place et exécution

La dernière chose à faire instancier nos classes et les tester. Retour sur notre fichier contact.php

  • <?php
    • //Appel des classes
    • require_once "./iObserver.php";
    • require_once "./MailEListener.php";
    • //Refaire notre header
    • $mail=$_POST["MAIL"];
    • $header='FROM:'.$mail.'\r\n'.
    • 'Reply-To:'.$mail.'\r\n'
    • .'X-Mailer:PHP/'.phpversion();
    • //instancier notre object SendMail
    • $message="message de ".$_POST["FNAME"]." ".$_POST["NAME"]."<br>".$_POST["MESS"];
    • $smail=new sendMail("votremail@exemple.fr", "Demande de contact", $message, $mail);
    • //instancier l'observer
    • $CSV=new MailCSV('mailcsv.csv');
    • $smail->attach($CSV);
    • $r=$smail->send($header);
    • if(r){
      • echo "<h2>Mail Envoyé</h2>";
    • }else
      • echo "une erreur est survenue";
  • ?>