Commençons par créer un nouveau document FLA en 600×400 px et posons sur un même calque (par exemple nommé “scène”) les différents composants utilisés par notre interface.
La fenêtre des composants est accessible via le raccourci clavier “CTRL F7”. Ouvrez ensuite le sous-menu “User Interface” et faites glisser sur la scène :

*
3 TextInput : nom, prénom, email,
*
2 TextArea : un pour le commentaire de l’utilisateur et un pour le tenir informé du bon déroulement (ou pas) du formulaire,
*
1 CheckBox : s’il est sélectionné, l’utilisateur souhaite recevoir la lettre d’informations,
*
1 Button : pour valider l’envoi du formulaire

Ajoutons à ceci quelques TextField (champs de texte) statiques pour indiquer à l’utilisateur à quoi correspondent les différents champs.

Pour finir, indiquons-lui quels sont les champs qui doivent obligatoirement être renseignés avec un petit astérisque rouge.

Donner des noms d'occurence aux composants

Comme nous aurons besoin d’accéder aux occurences des composants via du code ActionScript, nous allons leur donner des noms d’occurence :

*
nom_ti pour le champs nom,
*
prenom_ti pour le champs prénom,
*
email_ti pour le champs email,
*
commentaire_ta pour le champs commentaire,
*
lettre_cb pour la checkBox,
*
sortie_ta pour le champs destiné à l’affichage des erreurs et validation du formulaire,
*
envoyer_mc pour le bouton d’envoi.

L’interface est prête,
Nous allons maintenant nous attaquer au plus intéressant : le code ActionScript !
Le code ActionScript
Vision d'ensemble

Avant de nous lancer tête baissée dans le code, faisons une petite liste des actions nécessaires au fonctionnement d’un formulaire :

*
Vérifier la validité des informations. Par exemple, s’assurer que les champs obligatoires sont renseignés, que l’adresse email ressemble à une adresse valide, etc,
*
Mettre en forme le message de l’email, nous le ferons en texte simple et en HTML,
*
Envoyer les informations au script PHP, pour qu’il envoie le mail,
*
Recevoir un retour du script PHP, pour s’assurer qu’aucun problème n’est survenu côté PHP,
*
Tenir l’utilisateur au courant de l’avancement des opérations, qu’il sache s’il a bien rempli le formulaire, si l’envoi s’est bien déroulé, etc,

Nous pourrions encore détailler certaines opérations, mais nous y viendrons par la suite. ;-)
Un peu de préparation

Commençons pas créer un calque nommé “as - init et fonctions” sur lequel nous écrirons le code ActionScript.
Typer les données pour plus de rigueur

Afin d’utiliser le typage strict de l’AS2, nous allons référencer les composants par le biais de variables en indiquant explicitement leur type. Celà nous permettra de profiter de l’aide à la saisie et facillitera la correction d’erreur par le compilateur (plutôt que par nous-même ;-)).

La première chose à faire est d’importer les classes utilisées, pour que le compilo en connaisse les définitions :
    
import mx.controls.TextInput;
import mx.controls.TextArea;
import mx.controls.CheckBox;
import mx.controls.Button;


Ensuite, on référence nos composants en indiquant le type de donnée de chaque variable :
    
var tiNom:TextInput = this.nom_ti;
var tiPrenom:TextInput = this.prenom_ti;
var tiEmail:TextInput = this.email_ti;
var taCommentaire:TextArea = this.commentaire_ta;
var taSortie:TextArea = this.sortie_ta;
var cbLettre:CheckBox = this.lettre_cb;
var mcEnvoyer:Button = this.envoyer_mc;


Par la suite, on utilisera ces variables pour accéder aux composants. Si vous deviez changer le ciblage d’un compo, il n’y aurait qu’à le changer ici, plutôt que partout où il est utilisé.

Ces étapes ne sont pas indispensables, mais peuvent nous faciliter le code par la suite.
Initialiser les composants

Si vous désirez personnaliser les composants, vous pouvez le faire ici. Pour l’instant nous allons juste nous contenter de modifier le rendu du TextArea destiné aux messages d’erreur et de confirmation. Nous allons supprimer son fond (background) et son contour (border), lui donner une police de couleur rouge en italique et faire en sorte qu’il ne soit pas sélectionnable :
    
taSortie["depthChild0"]._visible = false;
taSortie.setStyle("color", "0xB13501");
taSortie.setStyle("fontStyle", "italic");
taSortie.label.selectable = false;


La première ligne est en fait un “hack”. Ce n’est pas la méthode conseillée par Macromedia pour supprimer le fond et le contour d’un TextArea, mais c’est la plus simple et la moins contraignante. ;-)

Si vous n’avez pas défini le label du CheckBox dans les paramètres du composant, vous pouvez le faire en code :

cbLettre.label = "Recevoir la lettre d'information";


Définir les ordres de tabulation

Ceux qui sont habitués à remplir des formulaires (demandez à un employé de La Poste ÆÆ) connaissent l’importance de la touche de tabulation.

Par défaut, l’ordre de tabulation est l’ordre dans lequel les composants ont été glissés sur la scène, mais nous pouvons le redéfinir grâce à la propriété tabIndex. Les compos pour lesquels nous n’aurons pas défini tabIndex seront exclus de l’ordre de tabulation, comme notre TextArea destiné aux messages d’erreur.
    
tiNom.tabIndex = 1;
tiPrenom.tabIndex = 2;
tiEmail.tabIndex = 3;
cbLettre.tabIndex = 4;
taCommentaire.tabIndex = 5;
mcEnvoyer.tabIndex = 6;


Avec la touche TAB on se déplace vers l’index supérieur ; et vers l’index inférieur avec la combinaison de touches “MAJ TAB”.

Note : si vous souhaitez tester çà dans Flash, il est nécessaire de “désactiver les raccourcis clavier” dans le Flash Player intégré à Flash (menu “Contrôle” du Flash Player après avoir fait “CTRL ENTREE”).
Stocker les valeurs récurrentes dans des variables

Allez, pour finir cette préparation, car nous aimons bien faire les choses :-) nous allons stocker les valeurs auxquelles on aura souvent besoin d’accéder dans des variables. Celà rendra le code plus lisible et un poil plus optimisé.
Nous ne connaissons pas encore les valeurs à stocker, mais nous pouvons déclarer les variables qui les contiendront pour qu’elles soient accessibles de n’importe quel script du formulaire.
    
var nom:String;
var prenom:String;
var email:String;
var recevoirLettre:Boolean;
var commentaire:String;


Rédiger les fonctions outils

Nous allons maintenant rédiger les fonctions qui permettront d’effectuer les opérations décrites dans la section Vision d'ensemble.
Afficher les messages à l'attention de l'utilisateur

Commençons simple, on sait qu’on va devoir afficher des messages de confirmation ou d’erreur, alors faisons une petite fonction toute simple :

function afficherEnSortie(pChaine:String):Void
    
{
taSortie.text = pChaine;
}


Si l’on devait complexifier cet affichage d’erreur, par exemple en utilisant une fenêtre d’alerte, on pourrait alors modifier le contenu de cette fonction.
Réinitialiser le formulaire

Continuons dans la simplicité avec une fonction qui sera exécutée après l’envoi du mail (sans erreur) pour réinitialiser le formulaire. Elle vide les champs de texte et décoche le CheckBox :

function reinitFormulaire():Void
    
{
tiNom.text = tiPrenom.text = tiEmail.text = taCommentaire.text = "";
cbLettre.selected = false;
}


Valider le formulaire

Avant de mettre en forme le mail et d’envoyer les infos au script PHP, nous allons nous assurer que le formulaire est correctement rempli. Uniquement les champs nom, prénom et email sont obligatoires, nous n’aurons pas besoin de vérifier les autres.
Pour le nom et le prénom, nous allons uniquement vérifier que le champs est rempli (propriété text différente d’une chaîne vide -”“-), pour l’email nous allons faire de même, plus :

*
vérifier qu’il contient un “@”
*
vérifier qu’il contient un “.” au moins un caractère après le “@”

Ces vérifications sont assez sommaires, mais dans le contexte de ce tutoriel nous n’en ferons pas plus (libre à vous de les améliorer ÆÆ).

Première chose à faire dans cette fonction, récupérer les valeurs des champs dans les variables préalablement déclarées, car cette fonction sera la première appellée lors de la demande d’envoi.
Ensuite, nous déclarons une variable locale à la fonction, “erreur”, contenant une chaîne vide. Nous stockerons dans cette variable les différentes erreurs recontrées et retourneront sa valeur.
Si aucune erreur n’est recontrée, c’est une chaîne vide qui sera retournée.

function validerFormulaire ():String
    
{
nom = tiNom.text;
prenom = tiPrenom.text;
email = tiEmail.text;
commentaire = taCommentaire.text;
recevoirLettre = cbLettre.selected;

var erreurs:String = "";

if (nom == "") erreurs += "Merci de remplir le champ 'nom'" + newline;
if (prenom == "") erreurs += "Merci de remplir le champ 'prénom'" + newline;
if (email == "") erreurs += "Merci de remplir le champ 'email'" + newline;
else
{
var atIndex:Number = email.indexOf("@");
var dotIndex:Number = email.indexOf(".", atIndex);
if (atIndex == -1 || dotIndex == -1 || dotIndex - atIndex <= 1)
erreurs += "L'email n'est pas valide" + newline;
}
return erreurs;
}


Lorsque nous appellerons cette fonction, nous vérifierons son retour : si c’est une chaîne vide le formulaire est OK, sinon il faudra avertir l’utilisateur en utilisant le message d’erreur retourné. ;-)
Mettre en forme le message du mail

La mise en forme se passe en deux étapes, la première est la mise en forme du message en texte brut.

Pour garder un peu de clarté dans le code, on peut faire çà sur plusieurs lignes.

La propriété de MovieClip _url nous permet d’indiquer quelle est l’URL du swf d’où provient le formulaire.

Si l’utilisateur a coché la CheckBox, on ajoute une phrase concernant la lettre d’informations. De même s’il a écrit un commentaire, on l’ajoute. On retourne le message mis en forme.

function formerMessageText ():String
    
{
var message:String = "Formulaire :";
message += "Origine : " + this._url + "\r\n";
message += "Nom : " + nom + "\r\n";
message += "Prénom : " + prenom + "\r\n";
message += "Adresse email : " + email +"\r\n";
if (recevoirLettre)
message += "Personne souhaitant recevoir la lettre d'information.\r\n";
if (commentaire != "")
message += "Commentaire :\r\n";
message += commentaire;

return message;
}


Nous allons utiliser des balises HTML pour mettre le message en forme.

Nous ne sommes pas limité aux balises reconnues par Flash car le logiciel qui lira le message sera un client mail (qui possède tout de même ses limites).

Entre les balises head, nous pouvons déclarer une feuille de style qui, pour l’instant, est très sommaire, mais deviendra sûrement un chef d’oeuvre en passant entre vos mains. :-) On fait attention à bien refermer les balises ouvertes et on retourne le message mis en forme.

function formerMessageHtml ():String
    
{
var message:String = "<html><head><style type='text/css'> p{font: 12px Arial} </style></head><body>";
message += "<h4>Formulaire : </h4>";
message += "<p>Origine : " + this._url + "</p>";
message += "<p>Nom : " + nom + "<br />";
message += "Prénom : " + prenom + "<br />";
message += "Adresse email : <a href='mailto:" + email + "'>" + email +"</a></p>";
if (recevoirLettre)
message += "<p>Personne souhaitant recevoir la lettre d'information.</p>";
if (commentaire != "")
message += "<p><u>Commentaire :</u><br />";
message += commentaire;
message += "</p></body></html>";

return message;
}


Envoyer les infos au script PHP

Pour se faire nous allons utiliser la classe LoadVars.

Au début de la fonction “envoyerMail” nous allons verrouiller le bouton d’envoi, pour éviter que l’utilisateur clique plusieurs fois dessus.

Nous créons ensuite deux objets (instances) LoadVars, un pour l’envoi (il contiendra donc les variables à envoyer) et un pour le retour du script PHP (il contiendra les variables retournées par PHP).

L’objet LoadVars d’envoi contiendra sous forme de propriétés les valeurs pour :

*
le sujet du mail,
*
le message, formaté en texte,
*
le message, formaté en HTML,
*
l’expéditeur du mail (nom et prénom),
*
l’adresse mail de réponse, qui servira si nous répondons au mail reçu du formulaire.

Toutes les propriétés ajoutées sur l’objet LoadVars d’envoi seront accessibles côté PHP.

La classe LoadVars met à notre disposition un gestionnaire “onLoad”, appellé dès le retour d’exécution du PHP. On référence dans ce gestionnaire une fonction “onMailEnvoye” (que nous implémenterons après), qui sera donc exécutée en retour de l’envoi au PHP.

La méthode “sendAndLoad” permet d’appeller le script PHP, de définir en second paramètre l’objet LoadVars qui sera utilisé pour récupérer le retour de PHP et la méthode d’envoi des variables, ici POST.

Pour terminer, on indique à l’utilisateur que les données sont en cours d’envoi.

function envoyerMail ():Void
    
{
mcEnvoyer.enabled = false;

var envoyeur:LoadVars = new LoadVars();
var receveur:LoadVars = new LoadVars();

envoyeur.sujet = "Formulaire";
envoyeur.messageText = formerMessageText ();
envoyeur.messageHtml = formerMessageHtml ();
envoyeur.expediteur = prenom + " " + nom;
envoyeur.mailReponse = email;

receveur.onLoad = onMailEnvoye;

envoyeur.sendAndLoad("php/envoyer_mail.php", receveur, "POST");
afficherEnSortie("Envoi en cours...");
}


Recevoir les infos de retour d'exécution du script PHP

OK, nous avons envoyé tout çà à PHP, mais qu’en a-t’il fait ? Est-ce que tout s’est bien déroulé ou y-a-t-il eu un problème ?

Si tout s’est bien déroulé et que le mail est parti, on peut formater notre formulaire en appellant la fonction “reinitFormulaire”.

Dans le cas contraire, même si notre pauvre utilisateur ne pourra rien y faire, il faudrait tout de même l’avertir qu’il y a eu un problème lors de l’envoi. Il pourra toujours réessayer plus tard ou nous prévenir que “çà marche pas !”. :-P

Le premier moyen pour détecter un problème nous est fourni par la classe LoadVars, méthode onLoad, grâce au paramètre “pSuccess”.
Si ce paramètre a pour valeur false, c’est probablement que le script PHP n’a pu être trouvé.

Quels autres problèmes pourrait-on rencontrer ?

*
Les variables attendues par PHP en méthode POST n’ont pas été transmises (faute de frappe dans les noms de variables, mauvaise méthode d’envoi, etc)
*
Le mail n’a pu être envoyé et la fonction PHP “mail” renvoie false.

Dans le script PHP que nous verrons à la fin, nous renvoyons une variable “erreurPHP” qui contient soit un message d’erreur, à afficher pour l’utilisateur, soit une chaîne vide (aucune erreur), comme le fait notre fonction AS validerFormulaire. Et dans la fonction qui suit, nous vérifions la valeur de cette variable, soit pour formater le formulaire, soit pour afficher les erreurs.

A noter qu’on commence par déverrouiller le bouton d’envoi.

function onMailEnvoye (pSuccess:Boolean):Void
    
{
mcEnvoyer.enabled = true;
if (!pSuccess)
{
afficherEnSortie("Problème avec le script PHP.");
}
else if (this.erreurPHP == "")
{
afficherEnSortie("L'envoi s'est terminé avec succès.");
reinitFormulaire();
}
else
{
afficherEnSortie("Erreurs PHP : \n" + this.erreurPHP);
}
}


Notez que la fonction onMailEnvoye s’exécute dans la portée de l’objet LoadVars receveur. Le this dans cette fonction cible donc cet objet, et on s’en sert pour accéder aux variables renvoyées par PHP, elles sont des propriétés de cet objet.
Actions de l'utilisateur

Et voilà, nos fonctions sont prêtes, nous n’avons plus qu’à déclencher leur exécution via le bouton “envoyer”.

Nous pouvons éventuellement les placer sur un autre calque nommé “as - actions”.

Le code est ici sommaire : on vérifie la validité du formulaire, s’il n’y a pas d’erreurs on envoie le formulaire, sinon on informe l’utilisateur des erreurs à corriger.

mcEnvoyer.onRelease = function():Void
    
{
var erreurs:String = validerFormulaire();
if (erreurs == "") envoyerMail();
else afficherEnSortie(erreurs);
}


Le code PHP

Terminons ce tutoriel avec le code PHP présent dans le fichier envoyer_mail.php.

La fonction “decoder” permet de convertir les chaînes de caractère reçues de Flash (en UTF-8) en ISO-8859-1. On enlève aussi les caractères d’échappement utilisés pour échapper les caractères comme les guillemets. La fonction “decoderHtml” ajoute la fonction nl2br qui converti les retours à la ligne de type “\r” en “<br />”. Les seuls qui sont envoyés par Flash dans cet exemple proviennent du TextArea “taCommentaire”. Celà nous permet d’une manière simple de conserver dans le mail au format HTML les retours à la ligne entrés par l’utilisateur.

Ensuite, comme pour la validation du formulaire dans le FLA (fonction validerFormulaire), nous déclarons une variable d’erreur contenant une chaîne vide, que nous remplirons avec les éventuels messages d’erreur.
On ajoute une erreur si une variable censée être transmise n’est pas reçue puis, à la fin du script, si la fonction mail nous renvoie false.
Cette variable est finalement transmise à Flash, via le gestionnaire onLoad de LoadVars, après encodage en UTF-8.

Le mail est ensuite formé avec ses deux parties texte brut et html séparés par une frontière. Après préparation des entêtes (headers), la fonction mail... envoie le mail ! :-D

N’oubliez pas de remplacer l’adresse mail d’envoi (ici : destinataire@fai.fr) par celle de votre choix. ;-)

    <?php
    
function decoder($texte){
$texte = utf8_decode($texte); // converti en iso-8859-1
$texte = stripslashes($texte); // élimine les anti-slashs d'échappement
$texte = nl2br($texte); // converti les retours en <br />
$texte = trim($texte); // élimine les '\n', '\r', '\t' etc
return $texte;
}

$erreurPHP="";

/* Paragraphe à decommenter pour tester le script php seul, sans le fla
$_POST['sujet'] = 'formulaire Test';
$_POST['messageHtml'] = '<html><body>Salut<br /> mon cher<br /><br />Bye</body></html>';
$_POST['messageText'] = "Salut mon cher Bye";
$_POST['expediteur'] = "expediteur@fai.fr";
$_POST['mailReponse'] = "expediteur@fai.fr";
*/

if(isset($_POST['sujet']))$sujet = $_POST['sujet'];
else $erreurPHP .= "Variable 'sujet' non transmise\n";

if(isset($_POST['messageHtml']))$messageHtml = $_POST['messageHtml'];
else $erreurPHP .= "Variable 'message' non transmise\n";

if(isset($_POST['messageText']))$messageTexte = $_POST['messageText'];
else $erreurPHP .= "Variable 'message' non transmise\n";

if(isset($_POST['expediteur']))$expediteur = $_POST['expediteur'];
else $erreurPHP .= "Variable 'expediteur' non transmise\n";

if(isset($_POST['mailReponse']))$mailReponse = $_POST['mailReponse'];
else $erreurPHP .= "Variable 'mailReponse' non transmise\n";

if($erreurPHP != "") echo utf8_encode("erreurPHP=".$erreurPHP);
else
{
$to = "destinataire@fai.fr";
$sujet = decoder($sujet);
$expediteur = decoder($expediteur);
$messagehtml = decoder($messageHtml);
$messageTexte = utf8_decode($messageTexte);

//-----------------------------------------------
//GENERE LA FRONTIERE DU MAIL ENTRE TEXTE ET HTML
//-----------------------------------------------

$frontiere = '-----=' . md5(uniqid(rand()));

//-----------------------------------------------
//HEADERS DU MAIL
//-----------------------------------------------

$headers = 'From: '.$expediteur.' <'.$mailReponse.'>'."\n";
$headers .= 'Return-Path: <'.$mailReponse.'>'."\n";
$headers .= 'MIME-Version: 1.0'."\n";
$headers .= 'Content-Type: multipart/alternative; boundary="'.$frontiere.'"'."\n";
$headers .= 'Content-Transfer-Encoding: 8bit';

//-----------------------------------------------
//MESSAGE TEXTE
//-----------------------------------------------
$message = "This is a multi-part message in MIME format\n\n";

$message = "--$frontiere\n";
$message .= "Content-Type: text/plain; charset=UTF-8\n";
$message .= "Content-Transfer-Encoding: 8bit\n\n";
$message .= $messageTexte."\n\n";


//-----------------------------------------------
//MESSAGE HTML
//-----------------------------------------------
$message .= "--$frontiere\n";
$message .= "Content-Type: text/html; charset=UTF-8\n";
$message .= "Content-Transfer-Encoding: 8bit\n\n";
$message .= $messageHtml."\n\n";

$message .= "--$frontiere--\n";

$mail_OK = mail($to, $sujet, $message, $headers) ;


if (!$mail_OK)
{
$erreurPHP .= "Problème lors de l'envoi du mail";

}
echo utf8_encode("erreurPHP=".$erreurPHP);
}
?>


Note : chez certains FAI, la fonction mail est désactivée.