Enviar Formulario de Contacto

Flash y PHPPara poder enviar un formulario de contacto en Flash es necesario utilizar un lenguaje del lado del servidor que permita enviar el correo con los datos que el usuario introdujo en Flash. Algunos ejemplos de estos lenguajes del lado de servidor son PHP, JSP y ASP.
En este ejemplo veremos cómo enviar por mail un formulario de contacto usando PHP.

Para fines de este tutorial, se pondrán en el formulario algunos de los componentes que ya vimos en los post pasados. Estos componentes son ComboBox, RadioButton y CheckBox.

Para este tutorial usaremos Flash 8. El ejemplo y los archivos de este tutorial los encuentras al final de esta entrada.

Nota Por razones de seguridad, el ejemplo que se encuentra al final de este post no enviará  ningún correo electrónico (para evitar que se llene el buzón o llegue puro correo basura). En lugar de mandar el correo electrónico mostraré el resultado final de cómo se vería el correo electrónico (tanto en formato HTML como en formato de texto plano). Sin embargo, los archivos de esta entrada y el código aquí pegado, sí tienen la instrucción para enviar el correo electrónico.

Tutorial

I. Haciendo el formulario en Flash

1. Crea un nuevo documento de Flash de 420px por 380px.

2. Arrastra al escenario los siguientes componentes (recuerda que estos componentes están dentro de la sección User Interface del panel Components (Ctrl. + F7) :

Además, crea 5 textos dinámicos con el (*) como texto (estos los usaremos para mostrar los campos obligatorios que el usuario debe llenar. Para este ejemplo, haremos que todos los datos sean obligatorios). A estos textos, ponles como nombre de instancia msj1, msj2, msj3, etc.

3. Selecciona cada componente que arrastraste al escenario y ponle los siguientes nombres de instancia (dentro del Panel Propiedades):

4. Además, cambia los siguientes parámetros (tercera pestaña del panel Propiedades) a estos componentes:

5. Acomoda todos los componentes anteriores para que te queden similar a la siguiente imagen:

6. Es momento de escribir el código. A la capa (layer) existente asígnale el nombre de Forma. Crea una nueva capa llamada Acciones. En el panel Actions de esta capa escribe lo siguiente:

Actionscript:
  1. // Importamos la librería del componente Alert
  2. import mx.controls.Alert;
  3. // Sólo por estética, cambiamos el color del tema (cambiamos el verde que aparece por default)
  4. _global.style.setStyle("themeColor", 0xCCFFFF);
  5. /* Esta línea es importante para que todo lo que el usuario escriba o seleccione tenga acentos, se muestren de forma correcta y no con caracteres raros (Ej. Ã) */
  6. System.useCodepage = true;
  7. /* Creamos un arreglo para guardar los temas seleccionados por el usuario (es decir, las opciones de los checkboxes que el usuario seleccionó) */
  8. var temas:Array = new Array();
  9. /* En el arrelgo paises gaurdaremos los datos que aparecerán en el combobox de países */
  10. var paises:Array = new Array();
  11. /* Creamos dos objetos de la clase LoadVars, uno para enviar los datos introducidos por el usuario y el otro para recibir la respuesta enviada por el archivo de PHP */
  12. var enviar_lv:LoadVars = new LoadVars();
  13. var resultado_lv:LoadVars = new LoadVars();
  14. /* Hacemos la llamada a la función initForm, la cual a su vez llamará a otras funciones para, por ejemplo, llenar el combobox de los paises, cambiarle el estilo a los botones de radio, etc. El código de esta función está en el siguiente bloque de código ActionScript. */
  15. initForm();

El código anterior muestra la declaración variables e importación de clases necesarias (en este caso sólo una clase). Ahora nos enfocaremos en las funciones que escribiremos en nuestro código.

Actionscript:
  1. /* Esta función llama a los métodos encargados de cambiar los estilos de los botones de radio, checkboxes, etc. */
  2. function initForm() {
  3.     escondeMensajes();
  4.     setEstilosRadioButtons();
  5.     setEstilosCheckBoxes();
  6.     llenaComboPaises();
  7. }
  8. /* Escondemos (no mostramos) los mensajes que le indicarán al usuario qué campos le faltó introducir. Es decir, los campos obligarios marcados por (*). */
  9. function escondeMensajes() {
  10.     for(var i = 1; i <7; i++) {
  11.         this["msj" + i]._visible = false;
  12.     }
  13. }
  14. /* Le cambiamos el formato a los botones de radio. Si no entiendes esta parte, por favor revisa el post sobre el componente RadioButton */
  15. function setEstilosRadioButtons() {
  16.     for(var i = 1; i <3; i++) {
  17.         this["radio" + i].setStyle("color", 0x990000);
  18.         this["radio" + i].setStyle("fontWeight", "bold");
  19.         this["radio" + i].setStyle("marginLeft", 2);
  20.     }
  21. }
  22. /* Le cambiamos el formato a los checkboxes. Si no entiendes esta parte, por favor revisa el post sobre el componente CheckBox */
  23. function setEstilosCheckBoxes() {
  24.     for(var i = 1; i <6; i++) {
  25.         this["check" + i].setStyle("color", 0x990000);
  26.         this["check" + i].setStyle("fontWeight", "bold");
  27.         this["check" + i].setStyle("marginLeft", 2);
  28.     }
  29. }
  30. /* Esta función llena el arreglo países con las opciones que nos interesa mostrar en el combobox de países. Después de llenar el arreglo se lo asignamos como dataProvider al combobox pais_cb y le decimos que ordene las opciones de acuerdo a su etiqueta (label). Si no entiendes esta parte, por favor revisa el post sobre el componente ComboBox */
  31. function llenaComboPaises() {
  32.     paises.push({label:"-- Selecciona --",  data:0});
  33.     paises.push({label:"México",       data:"MEX"});
  34.     paises.push({label:"España",       data:"ESP"});
  35.     paises.push({label:"Colombia",    data:"COL"});
  36.     paises.push({label:"Argentina",         data:"ARG"});
  37.     paises.push({label:"Chile",       data:"CHI"});
  38.     paises.push({label:"Perú",   data:"PER"});
  39.     paises.push({label:"Venezuela",         data:"VEN"});
  40.  
  41.     paises.push({label:"Ecuador",     data:"ECU"});
  42.     paises.push({label:"Costa Rica",       data:"COS"});
  43.     paises.push({label:"Uruguay",     data:"URU"});
  44.     paises.push({label:"Bolivia",       data:"BOL"});
  45.     paises.push({label:"Estados Unidos",    data:"EUA"});
  46.     paises.push({label:"Guatemala",         data:"GUA"});
  47.     paises.push({label:"Brasil",          data:"BRA"});
  48.     paises.push({label:"Cuba",    data:"CUB"});
  49.     paises.push({label:"Panamá",       data:"PAN"});
  50.     paises.push({label:"El Salvador",     data:"SAL"});
  51.     paises.push({label:"Nicaragua",         data:"NIC"});
  52.     paises.push({label:"Otro",      data:"Otr"});
  53.     pais_cb.dataProvider = paises;
  54.     pais_cb.sortItemsBy("label");
  55. }

Las siguientes funciones son vitales para el tratamiento del formulario:

Actionscript:
  1. /* Asignamos las acciones al botón de Enviar. En este caso, el botón de Enviar hará el llamado a la función validaForma para verificar que el usuario haya llenado los campos obligatorios. Como lo dije anteriormente, para este ejemplo haremos que el usuario tenga que llenar todos los campos. */
  2. enviar_btn.onRelease = function() {
  3.     validaForma();
  4. }
  5. /* Esta función se encarga de validar que todos los campos obligatorios fueron llenados. Primero hacemos llamamos a la función escondeMensajes para no mostrar los campos dinámicos (msj1, msj2, etc.) en caso de que sea la segunda vez que se llama a la función validaForma. */
  6. function validaForma() {
  7.     escondeMensajes();
  8.     if(nombre_txt.text == "") { // Vemos si el campo de texto del nombre está vacío
  9.         msj1._visible = true; // Como el campo del nombre no fue llenado, mostramos el primer mensaje
  10.         nombre_txt.setFocus(); // Colocamos el foco o cursor en el campo del nombre
  11.     } else if(correo_txt.text == "" || !esCorreo(correo_txt.text)) { /* Vemos si el campo del correo está vacío y sí el formato del correo es correcto */
  12.         msj2._visible = true; /* Mostramos el segundo mensaje ya que el campo del correo está vacío o bien el formato es incorrecto */
  13.         correo_txt.setFocus(); // Ponemos el cursos en el campo del correo
  14.     } else if(sexoGroup.selection.data == undefined) { /* Si se cumple esta sentencia quiere decir que el usuario no seleccionó ninguna opción de los botones de radio */
  15.         msj3._visible = true; // Mostramos el tercer mensaje
  16.         radio1.setFocus(); // Ponemos el cursor en el primer botón de radio
  17.     } else if(pais_cb.selectedIndex == 0) { /* Si se cumple este condicional quiere decir que el usuario no seleccionó ninguna opción del combobox de los países. Si el índice seleccionado (selectedIndex) es igual a 0, entonces la opción seleccionada es la que dice "-- Seleccionar --", por lo tanto no nos interesa que el usuario use esa opción */
  18.         msj4._visible = true;
  19.         pais_cb.setFocus();
  20.     } else {
  21.         temas = buscaChecksSeleccionados(); /* Guardamos en el arreglo temas los valores de los checkboxes que el usuario seleccionó. La función buscaChecksSeleccionados nos regresa un arreglo con los valores de los checkboxes seleccionados */
  22.         if(temas.length == 0) { /* Si la longitud del arreglo temas es igual a 0, entonces el usuario no seleccionó ninguna opción; por lo tanto, mostramos el quinto mensaje y ponemos el cursor en el primer checkbox */
  23.             msj5._visible = true;
  24.             check1.setFocus();
  25.         } else if(comentarios_txt.text == "") { /* Si la caja de texto de los comentarios está vacía, mostramos el sexto mensaje y posicionamos el cursor en la caja de texto (TextArea) */
  26.             msj6._visible = true;
  27.             comentarios_txt.setFocus();
  28.         } else { /* Si ninguno de los condicionales anteriores se cumplió, quiere decir que el usuario llenó todos los campos necesarios. Mandamos a llamar la función enviarCorreo */
  29.             enviarCorreo();
  30.         }
  31.     }
  32. }
  33. /* Esta función regresa un arreglo con los valores de los CheckBox(es) seleccionados. Recorremos todos los componentes checkbox por medio de un ciclo for y vemos el valor de la propiedad "selected" de cada uno de ellos. Si no entiendes esta parte, por favor revisa el post sobre el componente CheckBox  */
  34. function buscaChecksSeleccionados():Array {
  35.     var temp = new Array();
  36.     for(var i = 1; i <6; i++) {
  37.         if(this["check" + i].selected) {
  38.             temp.push(this["check" + i].label);
  39.         }
  40.     }
  41.     return temp;
  42. }
  43. /* Esta función nos permite revisar si el formato del correo electrónico es correcto. Es decir, que contenga @, el punto xxx, etc. */
  44. function esCorreo(email:String):Boolean
  45. {
  46.     var res:Boolean = false;<br />
  47.     if(email.indexOf("@")>0 &#038;& email.indexOf("@") == email.lastIndexOf("@"))
  48.     {
  49.         if(email.lastIndexOf(".")>email.indexOf("@") &#038;& email.lastIndexOf(".")<email.length-1)
  50.         {
  51.             res = true;
  52.         }
  53.     }
  54.     return res;
  55. }

El siguiente código muestra el script de la función enviarCorreo.

Actionscript:
  1. /* Explicación: Primero desactivamos el botón de enviar para que el usuario no haga click más de una vez. Al objeto enviar_lv de la clase LoadVars le copiamos el valor de cada uno de los campos del formulario y los enviamos al archivo de PHP (enviar_formulario_de_contacto.php). A la función sendAndLoad del objeto enviar_lv, le pasamos como parámetro el path del archivo que recibirá los datos, el objeto de la clase LoadVars que recibirá la respuesta y el método en cómo se enviarán los datos (POST o GET). Este último parámetro es opcional y por default el valor es de POST.  NOTA: Si quieres cargar el resultado del archivo pasado como primer parámetro, deberás usar la función send. En los archivos de este tutorial que encuentras más abajo en un archivo zip, usamos la función sendAndLoad ya que nos interesa mostrar un mensaje de alerta (con el resultado) dentro del mismo Flash y no dentro del PHP. Sin embargo, el ejemplo que se encuentra más abajo utiliza la función send para mostrar dentro del mismo PHP el mensaje del correo electrónico en formato HTML y Texto Plano. */
  2. function enviarCorreo() {
  3.     enviar_btn.enabled = false;
  4.     enviar_lv.nombre = nombre_txt.text;
  5.     enviar_lv.correo = correo_txt.text;
  6.     enviar_lv.sexo = sexoGroup.selection.data;
  7.     enviar_lv.pais = pais_cb.selectedItem.label;
  8.     enviar_lv.temas = temas;
  9.     enviar_lv.comentarios = comentarios_txt.text;
  10.     enviar_lv.sendAndLoad("enviar_formulario_de_contacto.php", resultado_lv, "POST");
  11. }
  12. /* El evento onLoad del objeto resultado_lv es invocado cuando la llamada a los métodos load() o sendAndLoad() ha sido terminada. Asignamos el resultado regresado por el PHP a la variable respuesta. Si la llamada fue exitosa, vemos si la respuesta es igual a 'S', si es así mostramos un mensaje señalando que el mensaje ha sido enviado y llamamos a la función reestablecerForma para borrar los datos ingresados por el usuario. Si la respuesta es distinto a 'S' o bien si la llamada no fue exitosa, mostramos un mensaje señalando que hubo un error en el envío. Por último, volvemos a activar el botón de enviar. */
  13. resultado_lv.onLoad = function(success:Boolean)
  14. {
  15.     var respuesta = this.resultado;
  16.     if(success)
  17.     {
  18.         if(respuesta == "S")
  19.         {
  20.             Alert.show("Su mensaje ha sido enviado.", "Gracias", Alert.OK, null, "alerta", Alert.OK);
  21.             reestablecerForma();
  22.         }
  23.         else
  24.         {
  25.             Alert.show("Hubo un error en el envío del mensaje, por favor intente más tarde.", "Error", Alert.OK, null, "alerta", Alert.OK);
  26.         }
  27.     }
  28.     else
  29.         Alert.show("Hubo un error en el envío del mensaje, por favor intente más tarde.", "Error", Alert.OK, null, "alerta", Alert.OK);
  30.         enviar_btn.enabled = true;
  31. };
  32. /* Esta función borra los datos introducidos por el usuario. */
  33. function reestablecerForma() {
  34.     nombre_txt.text = "";
  35.     correo_txt.text = "";
  36.     desactivarSexo();
  37.     desactivarTemas();
  38.     pais_cb.selectedIndex = 0;
  39.     comentarios_txt.text = "";
  40. }
  41. /* Su función es poner todos los botones de radio como no seleccionados */
  42. function desactivarSexo() {
  43.     for(var i = 1; i <3; i++) {
  44.         this["radio" + i].selected = false;
  45.     }
  46. }
  47. /* Su función es poner todos los CheckBox(es) como no seleccionados */
  48. function desactivarTemas() {
  49.     for(var i = 1; i <6; i++) {
  50.         this["check" + i].selected = false;
  51.     }
  52. }

Ese es todo el código que deberá llevar el documento de Flash.

II. Programando el script en PHP para el envío del correo

A continuación pegaré todo el código del archivo enviar_formulario_de_contacto.php. Dentro del código están los comentarios para que puedas entender qué hace cada línea de código.

PHP:
  1. <html>
  2. <head>
  3. </head>
  4. <body>
  5. <?php
  6. /**
  7. * @author Carla Macías
  8. * @copyright 2008
  9. * @url http://codigometropoli.com/
  10. */
  11. /* 1. Recibimos las variables que mandamos por Flash.
  12.      Para recibirlas usaremos la matriz asociativa $_POST, la cual contiene los valores del formulario enviados por medio de LoadVars.
  13.       Importante: Los nombres de variables que recibe $_POST deberán ser
  14.       iguales a las variables enviadas por Flash. Con lo anterior, me refiero a la variable que está dentro de los [] de $_POST. */
  15. $nombre = stripslashes($_POST["nombre"]); /* Campo de texto corto (TextField) */
  16. $correo = $_POST["correo"]; /* Campo de texto corto (TextField) */
  17. $sexo   = $_POST["sexo"]; /* Botón de Radio. Esta variable trae la etiqueta del botón de radio seleccionado por el usuario. Debido a que el usuario solamete puede escoger una opción, basta con recibir el valor por medio de $_POST */
  18. $pais   = $_POST["pais"]; /* ComboBox. Igual que en el anterior, estamos recibiendo el valor de la etiqueta de la opción seleccionada por el usuario; basta con recibirla por medio de $_POST */
  19. $temas  = explode(',',$_POST["temas"]); /* CheckBox. Debido a que el usuario pudo haber seleccionado más de una opción, esta variable hay que tratarla de forma distinta. Esta variable trae todos los valores del arreglo (que usamos para guardar los valores de los checkbox seleccionados) separados por comas. Por ejemplo: opcion 1,opcion 2,opcion 3.
  20. En este ejemplo, vamos a mostrar los temas en forma de lista, por lo que haremos uso del método explode en PHP. Para más información sobre el método explode visita http://www.php.net/manual/es/function.explode.php para más información  */
  21. $comentarios = $_POST["comentarios"]; /* TextArea. Es posible que la información en este campo introducida por el usuario sea larga y que lleve saltos de línea. Para mostrarlo de igual forma en el correo usaremos la función nl2br (ver más adelante). */
  22. $formatos = array("text/html", "text/plain"); /* No modificar, solamente estoy declarando un arreglo */
  23. /* 2. Declaramos las variables sobre el correo electrónico. */
  24. $remitente = "no-reply@codigometropoli.com"; /* Cuenta de correo de donde se "manda"" el mail. En este caso no importa que la cuenta de correo exista, ni que sea similar a no-reply@, web@, contacto@, etc ya que este formulario de contacto le estaría llegando al webmaster o los de ventas, relaciones públicas, etc. */
  25. $para = "webmaster@codigometropoli.com,contacto@codigometropoli.com"; /* Cuenta de correo a donde se enviarán los mails. Separar por comas en caso de que sean más de uno. */
  26. $asunto = "Mensaje desde Código Metrópoli"; /* Asunto que aparecerá en el correo electrónico */
  27. $formato_correo = 0; /* IMPORTANTE: Aquí pon el valor de 0 si quieres que el formato del correo sea HTML y 1 si quieres que sea texto plano. 0 --> HTML,    1 -> Texto Plano */
  28. <p>/* 3. Establecemos las cabeceras (headers) del mail. "Bcc: " . $cc . */
  29. $header  = "MIME-Version: 1.0\r\n";
  30. $header .= "Content-type: " . $formatos[$formato_correo] . "; charset=iso-8859-1\r\n";
  31. $header .= "From: " . $remitente . "\n";
  32. /* Nota: Si deseas agregar correos de copia o copia oculta, descomenta las siguientes líneas (es decir, borra las // de las siguientes dos líneas) */
  33. //$header .= "Cc: copia1@codigometropoli.com,copia2@codigometropoli.com \n";
  34. //$header .= "Bcc: copiaoculta1@codigometropoli.com,copiaoculta2@codigometropoli.com \n";
  35. if($nombre != "" &#038;& $correo != "") { // Siempre es bueno asegurarse que recibimos los datos más importantes para no mandar correos vacíos
  36.     if($formato_correo == 0) { /* HTML */
  37.         $mensaje = '
  38. <style type="text/css">
  39.         <!--
  40.         .Estilo1 {
  41.             font-family: Arial;
  42.             font-size: 14px;
  43.         }
  44.         .Tabla_Contacto td {
  45.             padding:5px 5px 10px 5px;   
  46.         }
  47.         .Estilo2 {
  48.             color: #990000;
  49.             font-weight: bold;
  50.         }
  51.         hr {
  52.             color:#003366;
  53.             background-color:#003366;
  54.             height:5px;
  55.             width:450px;
  56.             margin-left:0px;
  57.         }
  58.         -->
  59.         </style>
  60. <p>  <span class="Estilo1"><span class="Estilo2">' . $asunto . '</span></span></p>
  61. <hr />
  62. <table width="438" border="0" cellspacing="0" cellpadding="0" class="Tabla_Contacto">
  63. <tr>
  64. <td width="111" class="Estilo1"><strong>Nombre:</strong></td>
  65. <td width="327" class="Estilo1">' . $nombre . '</td>
  66. </tr>
  67. <tr>
  68. <td class="Estilo1"><strong>Email:</strong></td>
  69. <td class="Estilo1">' . $correo . '</td>
  70. </tr>
  71. <tr>
  72. <td class="Estilo1"><strong>Sexo:</strong></td>
  73. <td class="Estilo1">' . $sexo . '</td>
  74. </tr>
  75. <tr>
  76. <td class="Estilo1"><strong>Pa&iacute;s:</strong></td>
  77. <td class="Estilo1">' . $pais . '</td>
  78. </tr>
  79. <tr>
  80. <td class="Estilo1"><strong>Temas:</strong></td>
  81. <td class="Estilo1">&nbsp;</td>
  82. </tr>
  83. <tr>
  84. <td class="Estilo1">&nbsp;</td>
  85. <td class="Estilo1">';
  86.                 for($i = 0; $i <count($temas); $i++) {
  87.                     $mensaje .= $temas[$i] . "<br />";
  88.                 } $mensaje .=  '</td>
  89. </tr>
  90. <tr>
  91. <td class="Estilo1"><strong>Comentarios:</strong></td>
  92. <td class="Estilo1">&nbsp;</td>
  93. </tr>
  94. <tr>
  95. <td colspan="2" class="Estilo1">' . nl2br(stripslashes($comentarios)) . '</td>
  96. </tr>
  97. </table>
  98. <hr />
  99. <hr style="height:10px" />';
  100.     }
  101.     else { /* Texto Plano */
  102. $mensaje = "
  103. ----------------------------------------------------------------------------\n
  104. Nombre: " . $nombre . "\n
  105. Email: " . $correo . "\n
  106. Sexo: " . $sexo . "\n
  107. País: " . $pais . "\n
  108. Temas: ";
  109.         for($i = 0; $i <count($temas); $i++) {
  110.             $mensaje .= $temas[$i] . "\n";
  111.         } $mensaje .=  "
  112. Comentarios: " . $comentarios . "\n
  113. ----------------------------------------------------------------------------\n";
  114.     }
  115. }
  116. if($mensaje != "")
  117. {
  118.     if(mail($para, $asunto, $mensaje, $header))
  119.         echo '&resultado=S&;';
  120.     else<br />
  121.         echo '&resultado=N&';
  122. }
  123. else
  124.     echo '&resultado=N&';
  125. ?>
  126. </body>
  127. </html>

Hemos llegado al final de este largo tutorial. No olvides ver el ejemplo y bajar el archivo.

NotaComo lo dije al principio del tutorial, por razones de seguridad, el ejemplo que se encuentra a continuación no enviará ningún correo electrónico (para evitar que se llene el buzón o llegue puro correo basura). En lugar de mandar el correo electrónico mostraré el resultado final de cómo se vería el correo electrónico (tanto en formato HTML como en formato