Com enviar correu amb PHPMailer

Aquest és un problema típic: com enviar un correu electrònic des d’una aplicació web.

Amb PHP  la resposta típica és: fent servir el PHPMailer.

Vet aquí un exemple: un mini formulari que permet introduir un "Subject" i un "Cos del missatge" i envia aquest missatge a una llista d’adreces de correu. Àquest codi el posem en un fitxer font "enviar.php" que deixem en una carpeta del nostre servidor, en la mateixa carpeta deixarem les classes que composen el PHPMailer, class.phpmailer.php i class.smtp.php. Et voila, ja funciona. Senzill, no?

Bé, ens caldrà també configurar correctament el servidor SMTP. El port estàndar de SMTP és el 25, ara bé, si és SMTP sobre SSL, aleshores és el 465. Vet aquí el codi:

<?php

require("class.phpmailer.php");

header("Cache-Control: no-cache, must-revalidate");

    $mail_address[0] = "compte@eservidor0.cat";

    $mail_address[1] = "
compte@eservidor1.cat";

    $mail_address[2] = "
compte@eservidor2.cat";

    $mail_address[3] = "
compte@eservidor3.cat";    
    $mail_address[4] = "
compte@eservidor4.cat";

    $mail_address[5] = "
compte@eservidor5.cat";

    $mail_address[6] = "
compte@eservidor6.cat";

    $mail_address[7] = "
compte@eservidor7.cat";

    $mail_address[8] = "
compte@eservidor8.cat";

    $mail_address[9] = "
compte@eservidor9.cat"; 

 
    if (isset($_POST["subject"]) && isset($_POST["body"]) && isset($_POST["boto"])) {

        $subject = $_POST["subject"];

        $body = $_POST["body"];

        $boto = $_POST["boto"];

    } else {

        $subject = "";

        $body = "";

        $boto = "";

    }    

?>

<html>

<head>

<title>Enviament de missatges</title>

</head>

<body bgcolor="#eeeeee">

<center>

<font face="Arial">

<h1>Enviament de missatges</h1>

<br />

<table border="0">

<tr>

<?php

echo "<form method=\"POST\" action=\"http://localhost/php/enviar.php\" >";

echo "<td>Subject:</td> <td><input name=\"subject\" value=\"$subject\" size=\"50\"/></td></tr>";

echo "<tr><td colspan=\"2\" align=\"left\">Text del missatge</td></tr><tr><td colspan=\"2\" align=\"center\"><textarea name=\"body\" cols=\"80\" rows=\"18\" >";

echo $body;

echo "</textarea></td></tr>";

echo "<tr><td colspan=\"2\" align=\"left\"><input type=\"submit\" name=\"boto\" value=\"Enviar\"></td>";

echo "</form>";

?>

</tr>

</table>

</font>

</center>

<?php

if ($boto == "Enviar") {

    $mail = new PHPMailer();

    $mail->IsSMTP();          
    $mail->SMTPDebug = 1;      // : 1 = errors i missatges, 2 = només missatges   
    $mail->SMTPAuth = true;   
    //$mail->SMTPSecure = "ssl"; // si cal SSL
    $mail->Host = "smtp.elmeuservidor.com";            
    $mail->Port = 25;        // o 465, si SSL     

    $mail->Username = "usuari";   

    $mail->Password = "password"; 
     
     
    foreach ($mail_address as $the_mail_address) {

        echo "Enviant a $the_mail_address<br />";

        $mail->From = "elmeucompte@servidor.cat";

        $mail->FromName = "El meu nom";

        $mail->Subject = $subject;

        $mail->AddAddress($the_mail_address,$the_mail_address);

        $mail->Body = $body;

        // afegir tractament pel cas que hi hagin adjunts

        if(!$mail->Send()) {

            echo "Error d’enviament: " . $mail->ErrorInfo."<br />";

        } else {

            echo "Missatge enviat<br />";

        }

        $mail->ClearAddresses ();

    }

     
    $mail->SmtpClose();

}

?>

</body>

</html>

GMail fa servir TLS, en comptes de SSL, per a prevenir l’spam. Per a GMail, la configuració que funciona és:

    $mail->SMTPAuth = true;
    $mail->SMTPSecure = "tls";
    $mail->Host = "smtp.gmail.com";
    $mail->Port = 587;

Les versions antigues de PHPMailer no suportaven TLS, així que val la pena descarregar-se la darrera versió, tenint en compte que l’opció d’enviar per GMail pren un caràcter "universal".

PHPMailer ofereix moltes possibilitats més: adjunts, enviament com HTML… O sigui que és una bona inversió llegir-ne el manual i fer proves. Es tracta d’un clàssic imprescindible al PHP.

Com fer un estalvi de pantalla del tipus pas de diapositives

Farem un pas de diapositives amb imatges del Pirineu oriental. Les fotos les agafo de la web de Vall de Ribes. L’autor de les fotos és Pep Hubach. Una mostra del seu treball es pot trobar a la web Corriols de Llum.

El motor de pas de diapositives i transicions el farem amb Flex. Caldrà que ens descarreguem el  JDK de Java (J2SE 1.4 o superior) i l’instal·lem. El java és necessari per a poder executar l’eina que de debò ens interessa: El Flex SDK. Per obtenir-lo anem a la  pàgina de descàrregues de Flex 3 SDK d’Adobe OpenSource. Amb l’Open Source Flex SDK n’hi ha prou. Per instal·lar-lo només cal descomprimir el paquet ZIP que triem en una carpeta.

Ara crearem una carpeta per guardar el codi font i les imatges. A dins de la carpeta  en crearem una altre que anomenarem assets. En aquesta carpeta assets copiarem les imatges  que ens hem descarregat. A la web de Vall de Ribes les podem trobar en format d’alta resolució o de mitja. He agafat les de mitja, per a no incrementar massa la mida del SWF. També hi afegirem una imatge de "portada". En el meu cas l’he anomenat corriols.jpg i l’he agafada de la web del Pep Hubach.

Ja tenim tot el que cal. Farem l’estalvi de pantalla en dues passes: primer crearem un .swf que contindrà les imatges i el motor de pas i transicions. Després convertirem aquest swf en un estalvi de pantalla (un fitxer .scr), amb instal·lador i tot, fent servir l’utilitat freeware InstantStorm.

InstantStorm té una cosa molt bona: no afegeix marques d’aigua a les imatges, ni missatges demanant diners ni anunciant versions pro, ni està limitat en el temps, ni res d’això. Només en l’about de la configuració se’ns diu que l’estalvi de pantalla s’ha realitzat amb InstantStorm. I, a més, és freeware. Una eina senzilla però molt útil.

L’swf el crearé a partir del següent fitxer slideshow.mxml

<?xml version="1.0"?>
    <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml&quot;
        layout="absolute"
        backgroundColor="0x00000"
        horizontalAlign="center"
        verticalAlign="center"       
        creationComplete="init()">
   
    <!–timer –>

    <mx:Script>

        var timControl:Timer = new Timer(9000, 0);
        var iComptador:int = 0;

         
        [Bindable]

        var boolVisible1:Boolean = false;


        [Bindable]

        var boolVisible2:Boolean = false;

        [Bindable]

        var boolVisible3:Boolean = false;

        [Bindable]

        var boolVisible4:Boolean = false;         
       
        [Bindable]

        var boolVisible5:Boolean = false;


        [Bindable]

        var boolVisible6:Boolean = false;

        [Bindable]

        var boolVisible7:Boolean = false;

        [Bindable]

        var boolVisible8:Boolean = false;
       
        [Bindable]

        var boolVisible9:Boolean = false;
       
        [Bindable]

        var boolVisible10:Boolean = false;         
       
        [Bindable]

        var boolVisible11:Boolean = false;


        [Bindable]

        var boolVisible12:Boolean = false;

        [Bindable]

        var boolVisible13:Boolean = false;

        [Bindable]

        var boolVisible14:Boolean = false;
       
        [Bindable]

        var boolVisible15:Boolean = false;               
       
         
        function Intermitent(event:TimerEvent):void {

            iComptador++;

            boolVisible1 = (iComptador == 1);

            boolVisible2 = (iComptador == 2);

            boolVisible3 = (iComptador == 3);

            boolVisible4 = (iComptador == 4);
            boolVisible5 = (iComptador == 5);

            boolVisible6 = (iComptador == 6);

            boolVisible7 = (iComptador == 7);

            boolVisible8 = (iComptador == 8);
            boolVisible9 = (iComptador == 9);
            boolVisible10 = (iComptador == 10);
            boolVisible11 = (iComptador == 11);

            boolVisible12 = (iComptador == 12);

            boolVisible13 = (iComptador == 13);

            boolVisible14 = (iComptador == 14);
            boolVisible15 = (iComptador == 15);
            // simpleLabel.text = iComptador.toString();
            if (iComptador >= 15) {iComptador = 0;}
        } 

    

        function init(): void {

            timControl.addEventListener(TimerEvent.TIMER, Intermitent);

            timControl.start();

        }

    </mx:Script>

     
    <mx:Dissolve id="dissolveOut" duration="1000" alphaFrom="1.0" alphaTo="0.0"/>

    <mx:Dissolve id="dissolveIn" duration="1000" alphaFrom="0.0" alphaTo="1.0"/> 

    <!– carrega les imatges –>
    <mx:Image id="Imatge1" left="0" top="0" source="@Embed(‘assets/corriols.jpg’)" visible="{boolVisible1}" width="100%" height="100%" horizontalAlign="center" verticalAlign="middle" scaleContent="true" maintainAspectRatio="true" hideEffect="{dissolveOut}" showEffect="{dissolveIn}"/>
       
    <mx:Image id="Imatge2" left="0" top="0" source="@Embed(‘assets/phoca_thumb_l_fons1.jpg’)" visible="{boolVisible2}" width="100%" height="100%" horizontalAlign="center" verticalAlign="middle" scaleContent="true" maintainAspectRatio="true" hideEffect="{dissolveOut}" showEffect="{dissolveIn}"/>
       
    <mx:Image id="Imatge3" left="0" top="0" source="@Embed(‘assets/phoca_thumb_l_fons2.jpg’)" visible="{boolVisible3}" width="100%" height="100%" horizontalAlign="center" verticalAlign="middle" scaleContent="true" maintainAspectRatio="true" hideEffect="{dissolveOut}" showEffect="{dissolveIn}"/>
       
    <mx:Image id="Imatge4" left="0" top="0" source="@Embed(‘assets/phoca_thumb_l_fons3.jpg’)" visible="{boolVisible4}" width="100%" height="100%" horizontalAlign="center" verticalAlign="middle" scaleContent="true" maintainAspectRatio="true" hideEffect="{dissolveOut}" showEffect="{dissolveIn}"/>
       
    <mx:Image id="Imatge5" left="0" top="0" source="@Embed(‘assets/phoca_thumb_l_fons4.jpg’)" visible="{boolVisible5}" width="100%" height="100%" horizontalAlign="center" verticalAlign="middle" scaleContent="true" maintainAspectRatio="true" hideEffect="{dissolveOut}" showEffect="{dissolveIn}"/>
       
    <mx:Image id="Imatge6" left="0" top="0" source="@Embed(‘assets/phoca_thumb_l_fons5.jpg’)" visible="{boolVisible6}" width="100%" height="100%" horizontalAlign="center" verticalAlign="middle" scaleContent="true" maintainAspectRatio="true" hideEffect="{dissolveOut}" showEffect="{dissolveIn}"/>
       
    <mx:Image id="Imatge7" left="0" top="0" source="@Embed(‘assets/phoca_thumb_l_fons6.jpg’)" visible="{boolVisible7}" width="100%" height="100%" horizontalAlign="center" verticalAlign="middle" scaleContent="true" maintainAspectRatio="true" hideEffect="{dissolveOut}" showEffect="{dissolveIn}"/>
       
    <mx:Image id="Imatge8" left="0" top="0" source="@Embed(‘assets/phoca_thumb_l_fons7.jpg’)" visible="{boolVisible8}" width="100%" height="100%" horizontalAlign="center" verticalAlign="middle" scaleContent="true" maintainAspectRatio="true" hideEffect="{dissolveOut}" showEffect="{dissolveIn}"/>    
   
    <mx:Image id="Imatge9" left="0" top="0" source="@Embed(‘assets/phoca_thumb_l_fons8.jpg’)" visible="{boolVisible9}" width="100%" height="100%" horizontalAlign="center" verticalAlign="middle" scaleContent="true" maintainAspectRatio="true" hideEffect="{dissolveOut}" showEffect="{dissolveIn}"/>
   
    <mx:Image id="Imatge10" left="0" top="0" source="@Embed(‘assets/phoca_thumb_l_fons9.jpg’)" visible="{boolVisible10}" width="100%" height="100%" horizontalAlign="center" verticalAlign="middle" scaleContent="true" maintainAspectRatio="true" hideEffect="{dissolveOut}" showEffect="{dissolveIn}"/>
       
    <mx:Image id="Imatge11" left="0" top="0" source="@Embed(‘assets/phoca_thumb_l_fons10.jpg’)" visible="{boolVisible11}" width="100%" height="100%" horizontalAlign="center" verticalAlign="middle" scaleContent="true" maintainAspectRatio="true" hideEffect="{dissolveOut}" showEffect="{dissolveIn}"/>
       
    <mx:Image id="Imatge12" left="0" top="0" source="@Embed(‘assets/phoca_thumb_l_fons11.jpg’)" visible="{boolVisible12}" width="100%" height="100%" horizontalAlign="center" verticalAlign="middle" scaleContent="true" maintainAspectRatio="true" hideEffect="{dissolveOut}" showEffect="{dissolveIn}"/>
       
    <mx:Image id="Imatge13" left="0" top="0" source="@Embed(‘assets/phoca_thumb_l_fons12.jpg’)" visible="{boolVisible13}" width="100%" height="100%" horizontalAlign="center" verticalAlign="middle" scaleContent="true" maintainAspectRatio="true" hideEffect="{dissolveOut}" showEffect="{dissolveIn}"/>
       
    <mx:Image id="Imatge14" left="0" top="0" source="@Embed(‘assets/phoca_thumb_l_fons13.jpg’)" visible="{boolVisible14}" width="100%" height="100%" horizontalAlign="center" verticalAlign="middle" scaleContent="true" maintainAspectRatio="true" hideEffect="{dissolveOut}" showEffect="{dissolveIn}"/>    
   
    <mx:Image id="Imatge15" left="0" top="0" source="@Embed(‘assets/phoca_thumb_l_fons14.jpg’)" visible="{boolVisible15}" width="100%" height="100%" horizontalAlign="center" verticalAlign="middle" scaleContent="true" maintainAspectRatio="true" hideEffect="{dissolveOut}" showEffect="{dissolveIn}"/>
   
    <!–
    <mx:Label id="simpleLabel" text="This Label displays plain text."/>
    –>        
     
</mx:Application>   


El codi exposat és extraordinàriament senzill i no calen moltes explicacions. Tanmateix, allà van:

Les imatges s’inclouen al swf amb @Embed.
L’atribut "visible" de cada imatge s’associa a una variable bind. visible="{boolVisiblenn}
Les imatges es redimensionen per ocupar tota la pantalla, però sense distorsió. Això s’aconsegueix amb la combinació de valors dels atributs width="100%" height="100%" horizontalAlign="center" verticalAlign="middle" scaleContent="true" maintainAspectRatio="true"
Per a cada imatge s’associa un efecte de transició al mostrar-la i ocultar-la. En tot els casos he fet servir el Dissolve . Però hauria pogut posar altres. hideEffect="{dissolveOut}" showEffect="{dissolveIn}"
La variable bind que controla l’atribut  "visible" de cada imatge s’actualitza en la funció del temporitzador. Es fa servir un  comptador per determinar quina imatge és visible en cada tic.

        function Intermitent(event:TimerEvent):void {


            iComptador++;



            boolVisible1 = (iComptador == 1);


            boolVisible2 = (iComptador == 2);


            boolVisible3 = (iComptador == 3);


            boolVisible4 = (iComptador == 4);

            boolVisible5 = (iComptador == 5);


            boolVisible6 = (iComptador == 6);


            boolVisible7 = (iComptador == 7);


            boolVisible8 = (iComptador == 8);

            boolVisible9 = (iComptador == 9);

            boolVisible10 = (iComptador == 10);

            boolVisible11 = (iComptador == 11);


            boolVisible12 = (iComptador == 12);


            boolVisible13 = (iComptador == 13);


            boolVisible14 = (iComptador == 14);

            boolVisible15 = (iComptador == 15);

            // simpleLabel.text = iComptador.toString();

            if (iComptador >= 15) {iComptador = 0;}

        }

El temporitzador, d’un periode de 9 segons,  s’activa en la funció init.
        var timControl:Timer = new Timer(9000, 0);

        var iComptador:int = 0;

        function init(): void {


            timControl.addEventListener(TimerEvent.TIMER, Intermitent);


            timControl.start();


        }


Només cal compilar per obtenir el swf. Obrim un terminal i ens posem en la carpeta on hem deixat el fitxer slideshow.mxml, i executo l mxmlc. En el meu cas es tracta de la següent ordre

/home/albert/flex/sdk/bin/mxmlc ./slideshow.mxml

Et voila! després d’alguns missatges d’advertència obtenim un slideshow.swf

http://sites.google.com/site/albertbaranguer/magatzem/slideshow.swf?attredirects=0

El podriem executar amb el Firefox, per exemple.

EL darrer pas és executar el wizard de InstantStorm. Per fer-ho més bonic, podem proporcionar una imatge per a l’instal·lador. La imatge ha de ser de format BMP i de 164×314 píxels. El resultat és un fitxer .exe amb el que podrem instal·lar l’screensaver.

Per un altre dia deixo afegir-li música a l’screensaver.