PHP Developers Network

A community of PHP developers offering assistance, advice, discussion, and friendship.
 
Loading
It is currently Fri Sep 22, 2017 6:55 am

All times are UTC - 5 hours




Post new topic Reply to topic  [ 37 posts ]  Go to page 1, 2, 3  Next
Author Message
 Post subject: Swift Mailer tutorial
PostPosted: Thu Feb 01, 2007 9:36 am 
Offline
Forum Newbie

Joined: Thu Feb 01, 2007 9:17 am
Posts: 15
After searching on Google and Yahoo, I have been unable to find any sort of tutorial explaining how to implement Swift Mailer as a contact form.
http://www.swiftmailer.org/

I have been to the official site and there is documentation aimed at developers who are able to make (probably reasonable) assumptions, but there is not really a low-level walkthrough about how to use the library to drive a contact form. In fact, it seems to have more information for folks trying to integrate it into their web application. (I saw info about CakePHP, for example, which I do not understand).

Here is a link to the 'basic instructions' which I do not understand.
http://www.swiftmailer.org/docs/tutorials/basics

Where does this code go? How do I use it? Does it just dump *any* form data into a text email or ?

I'd like to use it with a somewhat typical contact form: first name, last name, address, city, state, zip, phone, email address, maybe a radio button, maybe a dropdown select, maybe a textarea, definitely an upload button which should include the object as an attachment. Upon submission, it gets mailed to one or more pre-defined addresses. It'd be very nice if there were instructions on how to manipulate the format of the email (something clean and organized instead of "firstname = Jeff, lastname = Bell, variable=value" dumps).

I don't imagine it's as simple as
Syntax: [ Download ] [ Hide ]
form action="swiftmailer.php"
and suddenly everything works magically.

Can anyone point me in the right direction for some kind of step-by-step tutorial or explanation of how to use SwiftMailer? I'm somewhat capable of following clear instructions or examples.

I'm happy to share an example of a PHP mail script that does have sufficient information for newbies/non-programmers, just so you can understand what I refer to.
http://www.dagondesign.com/articles/sec ... er-script/

Unfortunately, that nicely documented implementation does include the ability to add attachments and other goodies which Swift Mailer appears to have. Hence, my interest in using Swift.

Thanks for your help.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 01, 2007 10:10 am 
Offline
Forum Contributor
User avatar

Joined: Tue May 23, 2006 10:42 am
Posts: 351
You would set your form action to the page that you want to handle sending the email. The code example is the code you would put inside the email handler (ie, form action='mypage.php', put that code in mypage.php).

Syntax: [ Download ] [ Hide ]
$swift->send('recipient@address.com', 'sender@address.com', 'The subject', 'The body');


That's where the email is actually being sent. Just fill out the required pieces and you have an email. If you want to have a little bit more format to your email, you can do something along the lines of:

Syntax: [ Download ] [ Hide ]
$body = "Hello  " . $_POST['name'] . "!";

$swift->send('recipient@address.com', 'sender@address.com', 'Good Morning!', $body);


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 01, 2007 11:10 am 
Offline
Breakbeat Nuttzer
User avatar

Joined: Wed Mar 24, 2004 8:57 am
Posts: 13098
Location: Melbourne, Australia
I will improve the documentation over time. Right now I'm working on the library itself but because it's only me developing the library and maintaining the documentation on a purely voluntary "on my own time" basis things may not move as quickly as people would like. I'm sorry about that :(

However, I would suggest that you should perhaps try getting to grasps with the basics of PHP and forms (using $_POST, $_GET etc) by reading some more generic tutorials at php.net and by searching Google until I can find time to improve the documentation.

I'm moving documentation to a wiki which I can perhaps put some trust (of course I can :)) in users to edit in the long run.

Have you looked at general contact form tutorials? The Swift part is basic once you know how a contact form would generally be implemented with something like the mail() function.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 01, 2007 11:13 am 
Offline
Breakbeat Nuttzer
User avatar

Joined: Wed Mar 24, 2004 8:57 am
Posts: 13098
Location: Melbourne, Australia
If I get time when I get home from work I'll post a tutorial here.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 01, 2007 12:10 pm 
Offline
Forum Newbie

Joined: Thu Feb 01, 2007 9:17 am
Posts: 15
Thanks for the replies. I appreciate the the responses, because I get the idea that Swift Mailer is very flexible for people who have more complicated needs like list management, newsletters, or other large/frequent tasks whereas I want a fairly simple contact form to allow website visitors to email me.

I'll take a look at some generic documentation on POST, compare that to what I see in the Dagon code, and try to piece something together.

It seems the basic idea is
1. Design the form (of course)
2. Submit the action to a PHP document (of course)
3. In that document #2, you have to catch the POSTed variables and values somehow.
4. Temporarily store the uploaded attachment somewhere?
5. Use the Swift Mailer to run some anti-spam / anti-injector routine
6. Use the Swift Mailer to write the variables/values into the body (which can be designed however you like)
7. Use the Swift Mailer to actually attach the attachment
8. Use the Swift Mailer to make the headers (using the TO/SUBJECT/SMTP defined in #2 but inserting the FROMNAME/EMAIL from the user input)
9. Use the Swift Mailer to send the mail to me ("instantiate the connection" I think was the term)

Is that roughly correct as an overview?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 01, 2007 2:15 pm 
Offline
Breakbeat Nuttzer
User avatar

Joined: Wed Mar 24, 2004 8:57 am
Posts: 13098
Location: Melbourne, Australia
That's roughly correct, but it's actually even simpler than that. You needn't think about injection, headers or storing the attachment anywhere. PHP and Swift will both do most of that work for you. All you need to do is put the POST data into the relevant methods Swift uses. Since formmail seems to be the only thing out there for sending emails from forms I'm semi-considering writing a wrapper myself and putting it in the library.

Here's an option for the procedural programmer...

First you need to create the form. If it will send attachments, make sure to set the enctype to "multipart/form-data". Set the action attribute to point to a PHP script which we'll create in a few moments. I'm making the attachment upload optional here. I'll call the file form.php and it will send data to mail_handler.php.

Syntax: [ Download ] [ Hide ]
<form action="mail_handler.php" method="post" enctype"multipart/form-data">

    <div class="row">

        <div class="label">Your name*:</div>

        <div class="field"><input type="text" name="user_name" /></div>

    </div>

    <div class="row">

        <div class="label">Your e-mail*:</div>

        <div class="field"><input type="text" name="email" /></div>

    </div>

    <div class="row">

        <div class="label">Subject*:</div>

        <div class="field"><input type="text" name="subject" /></div>

    </div>

    <div class="row">

        <div class="label">Attachment:</div>

        <div class="field"><input type="file" name="attachment" /></div>

    </div>

    <div class="row">

        <div class="label">Comments*:</div>

        <div class="field"><textarea name="comments"></textarea></div>

    </div>

    <div class="row">

        <div class="label">&nbsp;</div>

        <div class="field"><input type="submit" name="submit" value="Send" />

    </div>

</form>


Now you need to create the script which will send the email. Make sure you have uploaded the Swift library to the web server so that you can use it in your script.

The script will:

    1. Start a session so if we redirect we don't lose entered data in the form
    2. Fix any mess PHP made with magic_quotes on
    3. Copy POST data into the session so we can use it on the form page again if there's a problem
    4. Load in the Swift files
    5. Check if all POST data was sent that was required
    6. Check if the email address is in a valid format
    7. Check if the file upload was performed and no errors occured (file too big etc)
    8. Connect to the SMTP server
    9. Construct the message body using the POST data
    10. Attach the file if it was uploaded
    11. Add the message body
    12. Send the email to your address
    13. Redirect to a success page if everything worked or go back to the form page with an error if there was a problem


In the script, we'll open a <?php tag immediately and we *won't* output anything at all because we are going to send HTTP headers to redirect the browser once our work is done.

Syntax: [ Download ] [ Hide ]
<?php



/** 1 **/

session_start();



/** 2 **/

//See if evil magic_quotes is enabled, and fix problems if it is

$quotes_on = (get_magic_quotes_gpc() || get_magic_quotes_runtime());

if ($quotes_on)

{

    foreach ($_POST as $key => $value)

    {

        $_POST[$key] = stripslashes($value);

    }

}



/** 3 **/

$_SESSION["post"] = $_POST;



/** 4 **/

//Load in the required Swift files

require_once "classes/Swift.php";

require_once "classes/Swift/Connection/SMTP.php";



/** 5 **/

//Create an empty array where we can catch any fields which were not filled in

$fields_not_set = array();



//Check if all POST data was sent, redirect with an error if not

if (empty($_POST["user_name"])) $fields_not_set[] = "user_name";

if (empty($_POST["email"])) $fields_not_set[] = "email";

if (empty($_POST["subject"])) $fields_not_set[] = "subject";

if (empty($_POST["comments"])) $fields_not_set[] = "comments";



//If $fields_not_set contains any values, then something wasn't filled in. Time to redirect.

if (!empty($fields_not_set))

{

    //Read further down to see how we'll modify form.php to handle the error

    header("Location: form.php?error=incomplete&fields=" . implode(",", $fields_not_set));

    exit();

}



//Copy the POST data to standard globals

$user_name = $_POST["user_name"];

$email = $_POST["email"];

$subject = $_POST["subject"];

$comments = $_POST["comments"];



/** 6 **/

//This is a RegExp I've adopted for validating email addresses.  NOTE that it's NOT RFC compliant.

// Use another regexp at your own choice

$email_re = '(?#Start of dot-atom

                )[-!#\$%&\'\*\+\/=\?\^_`{}\|~0-9A-Za-z]+(?:\.[-!#\$%&\'\*\+\/=\?\^_`{}\|~0-9A-Za-z]+)*(?#

                End of dot-atom)(?:@(?#Start of domain)[-0-9A-Za-z]+(?:\.[-0-9A-Za-z]+)*(?#End of domain))?'
;



//Now check if the email address they gave is valid, redirect back to the form if not

if (!preg_match($email_re, $email))

{

    header("Location: form.php?error=email_invalid");

    exit();

}



/** 7 **/

$attachment_data = array();

//Now check if there's an attachment they've sent

if (!empty($_FILES["attachment"]))

{

    //If an attachment was sent, but there was an error, redirect

    if ($_FILES["attachment"]["error"] != 0)

    {

        header("Location: form.php?error=attachment_failed");

        exit();

    }

    else $attachment_data = $_FILES["attachment"];

}



/** 8 **/

//Everything looks ok to send an email, create an instance of Swift

$swift = new Swift(new Swift_Connection_SMTP("your.smtp.server.tld"));



/** 9 **/

//Now build your message body

$body = "A message was sent from " . $user_name . " with the title '" . $subject . "'";

if (!empty($attachment_data))

{

    $body .= "\r\nAn attachment with the name '" . $attachment_data["name"] . "' was added";

}



/** 10 **/

//Attach any files if they were sent

// PHP stores files in a temporary location and cleans up itself, so we'll just read the temporary file

if (!empty($attachment_data))

{

    $attachment_str = file_get_contents($attachment_data["tmp_name"]);

    //Check if we need to remove slashes (again!!)

    if ($quotes_on)

    {

        $attachment_str = stripslashes($attachment_str);

    }

    $swift->addAttachment(

        $attachment_str, $attachment_data["name"], $attachment_data["type"]);

}



/** 11 **/

//Add the email body

$swift->addPart($body);



/** 12 **/

//Try sending the email.

// Redirect to success page on success, or form on failure

if ($swift->send("your@address.com", $email, $subject))

{

    unset($_SESSION["post"]); //It worked, we have no reason to keep this data

    $swift->close();

    header("Location: success.php"); /** 13 **/

    exit();

}

else

{

    $swift->close();

    header("Location: form.php?error=runtime_error"); /** 13 **/

    exit();

}





//End of script


For the sake of clarity and brevity, earlier I didn't mention how we'd make the form deal with errors, so lets look at modifying it to do that.

First we'll make sure we start a session at the top of the page, because we don't want the user to have to type everything out again.

Syntax: [ Download ] [ Hide ]
<?php



session_start();



?>


Make sure there's no whitespace at all before that opening <?php tag or it won't work.

Now, we'll make a function to "paint" any already submitted values into the form value calling it in the form's [i]value[i] attributes.

Syntax: [ Download ] [ Hide ]
function paint_value($field)

{

    if (!empty($_SESSION["post"][$field]))

    {

        echo $_SESSION["post"][$field];

    }

    else { echo ""; }

}


We also need to display error messages on the page, so we'll add some code for that too. Putting it all together, the form now looks like this.

Syntax: [ Download ] [ Hide ]
<?php



//Start session

session_start();



//Function to display the values in the fields

function paint_value($field)

{

    if (!empty($_SESSION["post"][$field]))

    {

        echo $_SESSION["post"][$field];

    }

    else { echo ""; }

}



//Check if errors were sent

if (!empty($_GET["error"]))

{

    switch ($_GET["error"])

    {

        case "incomplete":

            $field_labels = array("user_name" => "Name", "email" => "E-mail address", "subject" => "Subject", "comments" => "Comments");

            $incomplete = explode(",", $_GET["fields"]);

            ?><div class="error">All required fields (*) were not completed.  Please check the following fields:

                <ul>

                    <?php foreach ($incomplete as $field) {

                        if (isset($field_labels[$field])) { echo "<li>" . $field_labels[$field] . "</li>"; }

                    } ?>

                </ul></div><?php

            break;

        case "email_invalid":

            ?><div class="error">The email address entered does not appear to be a valid format</div><?php

            break;

        case "attachment_failed":

            ?><div class="error">The attachment upload failed.  Perhaps the file is too large?</div><?php

            break;

        case "runtime_error":

            ?><div class="error">There was a problem processing your request.  Please try again later.</div><?php

            break;

    }

}



?>

<form action="mail_handler.php" method="post" enctype"multipart/form-data">

    <div class="row">

        <div class="label">Your name*:</div>

        <div class="field"><input type="text" name="user_name" value="<?php paint_value("user_name"); ?>" /></div>

    </div>

    <div class="row">

        <div class="label">Your e-mail*:</div>

        <div class="field"><input type="text" name="email" value="<?php paint_value("email"); ?>" /></div>

    </div>

    <div class="row">

        <div class="label">Subject*:</div>

        <div class="field"><input type="text" name="subject" value="<?php paint_value("subject"); ?>" /></div>

    </div>

    <div class="row">

        <div class="label">Attachment:</div>

        <div class="field"><input type="file" name="attachment" /></div>

    </div>

    <div class="row">

        <div class="label">Comments*:</div>

        <div class="field"><textarea name="comments"><?php paint_value("comments"); ?></textarea></div>

    </div>

    <div class="row">

        <div class="label">&nbsp;</div>

        <div class="field"><input type="submit" name="submit" value="Send" />

    </div>

</form>


The above should give you a fairly solid working form-mail set up. Obviously, I could have gone into a lot more detail, but if you don't know much about PHP development it would be too overwhelming as the above is fairly lengthy as it is.

Hopefully it will clear a few things up though.

Cheers,

Chris


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 01, 2007 3:42 pm 
Offline
Forum Newbie

Joined: Thu Feb 01, 2007 9:17 am
Posts: 15
A quick update to let you know I think I've understood what you laid out here.

Currently, I'm debugging to try to get the example to run.

Once that's done, then I'll try modifying some bits and pieces based on what I learn by experimenting... and from the documentation because I am already guessing it will be more valuable/understandable to me once I've gotten this leg-up you're giving me.

I can't say how much I appreciate the instruction. I'll probably be back before long with an intelligent question and two stupid ones as I get this test version to work.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 01, 2007 4:21 pm 
Offline
Forum Newbie

Joined: Thu Feb 01, 2007 9:17 am
Posts: 15
I think I am stumped by a problem I cannot figure a way around.

Syntax: [ Download ] [ Hide ]
Warning: preg_match() [function.preg-match]: Unknown modifier '[' in mail_handler.php on line 57

Warning: Cannot modify header information - headers already sent by (output started at mail_handler.php:57) in mail_handler.php on line 59


Now, I searched around on the error preg_match and understand there is, basically, an unexpected "[" character at line 57, which I checked and there is no [ bracket on that line (or on line 59).

However, there is a [ in the RegExp above on line 53 which is used in the variable $email_re (the email validator) and that is referenced/called/used in line 57. So, it must be the RegExp, where there are two in the code. The first [ appears to be a functional bracket that's holding the other characters, if I guess right. Which means it must be the second [ which causes the problem. I read that the problem character should be "escaped" with a backslash, so I tried that. It continued to fail.

Syntax: [ Download ] [ Hide ]
$email_re = '(?#Start of dot-atom
                )[-!#\$%&\'\*\+\/=\?\^_`{}\|~0-9A-Za-z]+(?:\.\[-!#\$%&\'\*\+\/=\?\^_`{}\|~0-9A-Za-z]+)*(?#
                End of dot-atom)(?:@(?#Start of domain)[-0-9A-Za-z]+(?:\.[-0-9A-Za-z]+)*(?#End of domain))?'
;


After some thought, I decided to put the backslash on the first [ which didn't work either.
Syntax: [ Download ] [ Hide ]
$email_re = '(?#Start of dot-atom
                )\[-!#\$%&\'\*\+\/=\?\^_`{}\|~0-9A-Za-z]+(?:\.[-!#\$%&\'\*\+\/=\?\^_`{}\|~0-9A-Za-z]+)*(?#
                End of dot-atom)(?:@(?#Start of domain)[-0-9A-Za-z]+(?:\.[-0-9A-Za-z]+)*(?#End of domain))?'
;


Stoically, I then proceed to try backslashing them both, but that didn't work either.

Syntax: [ Download ] [ Hide ]
$email_re = '(?#Start of dot-atom
                )\[-!#\$%&\'\*\+\/=\?\^_`{}\|~0-9A-Za-z]+(?:\.\[-!#\$%&\'\*\+\/=\?\^_`{}\|~0-9A-Za-z]+)*(?#
                End of dot-atom)(?:@(?#Start of domain)[-0-9A-Za-z]+(?:\.[-0-9A-Za-z]+)*(?#End of domain))?'
;


So, there it is. I'll need to understand how to properly escape the character, so it doesn't foul up line 57.

Further, I'm under the assumption that if this error is fixed, then the note about headers being set in 59 won't be a problem, but I'm off to pre-emptively research that next.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 01, 2007 4:39 pm 
Offline
Forum Newbie

Joined: Thu Feb 01, 2007 9:17 am
Posts: 15
JeffBell wrote:
Further, I'm under the assumption that if this error is fixed, then the note about headers being set in 59 won't be a problem, but I'm off to pre-emptively research that next.


Just looked into that and it's a whitespace/extra line problem. I checked both files very carefully and the ONLY whitespace appearing before a php tag is on line 26 of form.php where there are some tabs/indentations. After removing that whitespacing/tabbing, the second error about headers still appears.

Perhaps my initial guess was right; it's caused by the RegExp. I'll wait for a little help.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 01, 2007 4:40 pm 
Offline
Breakbeat Nuttzer
User avatar

Joined: Wed Mar 24, 2004 8:57 am
Posts: 13098
Location: Melbourne, Australia
Doh... that was just a token for part of a regexp since I use it in larger expressions:

Syntax: [ Download ] [ Hide ]
//Now check if the email address they gave is valid, redirect back to the form if not

if (!preg_match('/^' . $email_re . '$/', $email))

{

    header("Location: form.php?error=email_invalid");

    exit();

}


PS: I didn't test the code. Was in a rush to type it. It was supposed to be a guide rather than a copy & paste example ;)


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 01, 2007 5:27 pm 
Offline
Forum Newbie

Joined: Thu Feb 01, 2007 9:17 am
Posts: 15
I don't mean to drain your time or anything. Since I'm not really too bright in these areas, I thought it best to crack the example into shape first before going it alone and building what I really want. Okay, I'll update accordingly. Thank you very much for the help.

I'm not sure what these changes do, but I did lookup preg_match at
http://www.php.net/preg_match

It seems that the ^ hat is some kind of "assertion" (a term I do not understand the context of).
Quote:
pattern can contain assertions such as ^, $ or (?<=x)


Also, I noticed on that page, in the comments, there are a couple people talking about these RegExp functions as email filters. Of course, I don't quite understand what it *means* but they also use the /^ with the "pattern" -- however, they don't use $/ with the "string" so I'll have to search for more examples of this to learn.

(Incorrect edit removed.)


Last edited by JeffBell on Thu Feb 01, 2007 6:48 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 01, 2007 6:28 pm 
Offline
Breakbeat Nuttzer
User avatar

Joined: Wed Mar 24, 2004 8:57 am
Posts: 13098
Location: Melbourne, Australia
Here are the tested working scripts. All I changed was the regexp which was already posted earlier, and a missing "=" iin enctype in the form.

Syntax: [ Download ] [ Hide ]
<?php



/** 1 **/

session_start();



/** 2 **/

//See if evil magic_quotes is enabled, and fix problems if it is

$quotes_on = (get_magic_quotes_gpc() || get_magic_quotes_runtime());

if ($quotes_on)

{

    foreach ($_POST as $key => $value)

    {

        $_POST[$key] = stripslashes($value);

    }

}



/** 3 **/

$_SESSION["post"] = $_POST;



/** 4 **/

//Load in the required Swift files

require_once "classes/Swift.php";

require_once "classes/Swift/Connection/SMTP.php";



/** 5 **/

//Create an empty array where we can catch any fields which were not filled in

$fields_not_set = array();



//Check if all POST data was sent, redirect with an error if not

if (empty($_POST["user_name"])) $fields_not_set[] = "user_name";

if (empty($_POST["email"])) $fields_not_set[] = "email";

if (empty($_POST["subject"])) $fields_not_set[] = "subject";

if (empty($_POST["comments"])) $fields_not_set[] = "comments";



//If $fields_not_set contains any values, then something wasn't filled in. Time to redirect.

if (!empty($fields_not_set))

{

    //Read further down to see how we'll modify form.php to handle the error

    header("Location: form.php?error=incomplete&fields=" . implode(",", $fields_not_set));

    exit();

}



//Copy the POST data to standard globals

$user_name = $_POST["user_name"];

$email = $_POST["email"];

$subject = $_POST["subject"];

$comments = $_POST["comments"];



/** 6 **/

//This is a RegExp I've adopted for validating email addresses.  NOTE that it's NOT RFC compliant.

// Use another regexp at your own choice

$email_re = '(?#Start of dot-atom

                )[-!#\$%&\'\*\+\/=\?\^_`{}\|~0-9A-Za-z]+(?:\.[-!#\$%&\'\*\+\/=\?\^_`{}\|~0-9A-Za-z]+)*(?#

                End of dot-atom)(?:@(?#Start of domain)[-0-9A-Za-z]+(?:\.[-0-9A-Za-z]+)*(?#End of domain))?'
;



//Now check if the email address they gave is valid, redirect back to the form if not

if (!preg_match('/^' . $email_re . '$/', $email))

{

    header("Location: form.php?error=email_invalid");

    exit();

}



/** 7 **/

$attachment_data = array();

//Now check if there's an attachment they've sent

if (!empty($_FILES["attachment"]["tmp_name"]))

{

    //If an attachment was sent, but there was an error, redirect

    if ($_FILES["attachment"]["error"] != 0)

    {

        header("Location: form.php?error=attachment_failed");

        exit();

    }

    else $attachment_data = $_FILES["attachment"];

}



/** 8 **/

//Everything looks ok to send an email, create an instance of Swift

$swift = new Swift(new Swift_Connection_SMTP("mail.w3style.co.uk"));



/** 9 **/

//Now build your message body

$body = "A message was sent from " . $user_name . " with the title '" . $subject . "'";

if (!empty($attachment_data))

{

    $body .= "\r\nAn attachment with the name '" . $attachment_data["name"] . "' was added";

}



/** 10 **/

//Attach any files if they were sent

// PHP stores files in a temporary location and cleans up itself, so we'll just read the temporary file

if (!empty($attachment_data))

{

    $attachment_str = file_get_contents($attachment_data["tmp_name"]);

    //Check if we need to remove slashes (again!!)

    if ($quotes_on)

    {

        $attachment_str = stripslashes($attachment_str);

    }

    $swift->addAttachment(

        $attachment_str, $attachment_data["name"], $attachment_data["type"]);

}



/** 11 **/

//Add the email body

$swift->addPart($body);



/** 12 **/

//Try sending the email.

// Redirect to success page on success, or form on failure

if ($swift->send("chris@w3style.co.uk", $email, $subject))

{

    unset($_SESSION["post"]); //It worked, we have no reason to keep this data

    $swift->close();

    header("Location: success.php"); /** 13 **/

    exit();

}

else

{

    $swift->close();

    header("Location: form.php?error=runtime_error"); /** 13 **/

    exit();

}





//End of script


Syntax: [ Download ] [ Hide ]
<?php



//Start session

session_start();



//Function to display the values in the fields

function paint_value($field)

{

    if (!empty($_SESSION["post"][$field]))

    {

        echo $_SESSION["post"][$field];

    }

    else { echo ""; }

}



//Check if errors were sent

if (!empty($_GET["error"]))

{

    switch ($_GET["error"])

    {

        case "incomplete":

            $field_labels = array("user_name" => "Name", "email" => "E-mail address", "subject" => "Subject", "comments" => "Comments");

            $incomplete = explode(",", $_GET["fields"]);

            ?><div class="error">All required fields (*) were not completed.  Please check the following fields:

                <ul>

                    <?php foreach ($incomplete as $field) {

                        if (isset($field_labels[$field])) { echo "<li>" . $field_labels[$field] . "</li>"; }

                    } ?>

                </ul></div><?php

            break;

        case "email_invalid":

            ?><div class="error">The email address entered does not appear to be a valid format</div><?php

            break;

        case "attachment_failed":

            ?><div class="error">The attachment upload failed.  Perhaps the file is too large?</div><?php

            break;

        case "runtime_error":

            ?><div class="error">There was a problem processing your request.  Please try again later.</div><?php

            break;

    }

}



?>

<form action="mail_handler.php" method="post" enctype="multipart/form-data">

    <div class="row">

        <div class="label">Your name*:</div>

        <div class="field"><input type="text" name="user_name" value="<?php paint_value("user_name"); ?>" /></div>

    </div>

    <div class="row">

        <div class="label">Your e-mail*:</div>

        <div class="field"><input type="text" name="email" value="<?php paint_value("email"); ?>" /></div>

    </div>

    <div class="row">

        <div class="label">Subject*:</div>

        <div class="field"><input type="text" name="subject" value="<?php paint_value("subject"); ?>" /></div>

    </div>

    <div class="row">

        <div class="label">Attachment:</div>

        <div class="field"><input type="file" name="attachment" /></div>

    </div>

    <div class="row">

        <div class="label">Comments*:</div>

        <div class="field"><textarea name="comments"><?php paint_value("comments"); ?></textarea></div>

    </div>

    <div class="row">

        <div class="label">&nbsp;</div>

        <div class="field"><input type="submit" name="submit" value="Send" />

    </div>

</form>


This works, I have tested it. End your files with a blank new line by the way.

EDIT | Also fixed the check for if a file was uploaded to check for non-empty tmp_name.

You can download it here to save copy & pasting. Note that the file was written on a Mac so the line ending is \n and some windows editors won't display it correctly.

http://www.w3style.co.uk/~d11wtq/swifttest.zip 51Kb


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 01, 2007 6:46 pm 
Offline
Forum Newbie

Joined: Thu Feb 01, 2007 9:17 am
Posts: 15
I can see now that I fat-fingered the disappearing } bracket. Your original code was just fine. Strictly my doing and I've removed those comments.

I did correct the enctype= earlier, but thanks for covering it just in case.

I set up a successful test! 8) I can get the email sent with the attachment on it. One small problem, I was attaching a PDF and it arrived at full size (78K) but it was blank. The original file is definitely not blank.

Any ideas on where I went wrong? I did close the php tag on mail_handler, but I now see you say to leave it open. Could that be the reason the attachment was corrupted? Or is it because the mime type was not set, as talked about here?
http://www.swiftmailer.org/docs/composi ... attachment

Also, my first attachment returned a "too big" error. I didn't see any notation on the Swift Mailer site about sizes; what is the limit? Is that configurable? Just curious. I don't need 800mb attachment limits, but it would be nice to how it's set up.

Thanks again!


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 01, 2007 7:03 pm 
Offline
Breakbeat Nuttzer
User avatar

Joined: Wed Mar 24, 2004 8:57 am
Posts: 13098
Location: Melbourne, Australia
JeffBell wrote:
I can see now that I fat-fingered the disappearing } bracket. Your original code was just fine. Strictly my doing and I've removed those comments.

I did correct the enctype= earlier, but thanks for covering it just in case.

I set up a successful test! 8) I can get the email sent with the attachment on it. One small problem, I was attaching a PDF and it arrived at full size (78K) but it was blank. The original file is definitely not blank.

Any ideas on where I went wrong? I did close the php tag on mail_handler, but I now see you say to leave it open. Could that be the reason the attachment was corrupted? Or is it because the mime type was not set, as talked about here?
http://www.swiftmailer.org/docs/composi ... attachment

Also, my first attachment returned a "too big" error. I didn't see any notation on the Swift Mailer site about sizes; what is the limit? Is that configurable? Just curious. I don't need 800mb attachment limits, but it would be nice to how it's set up.

Thanks again!


The "too" big error is just the error I display if there's a problem with the upload. It "suggests" that the file may have been too large purely because that's the most common error. I'm afraid I won't be taking time to explain how you determine the actual error but basically, if you search php.net for file uploads you'll come across the integer values contains in $_FILES["fieldname"]["error"]. There is no "maximum" upload size set by Swift. PHP has a max memory limit of 8MB and a max upload of 2MB. Even if the attachment is not uploaded you won't get more than about 3MB before exhausting the 8MB limit of the script because there's some caching and encoding going on.

The logic was wrong in the first example before I made the edit above after I posted since I was looking for empty ($_FILES["fieldname"]) rather than checking if there was actually a temporary file uploaded.

For the attachment issue, I suspect I may have stripped slashes from it where I didn't need to. Does removing the following line fix it?

Syntax: [ Download ] [ Hide ]
$attachment_str = stripslashes($attachment_str);


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 02, 2007 7:12 am 
Offline
Forum Newbie

Joined: Thu Feb 01, 2007 9:17 am
Posts: 15
I've been meaning to try this earlier today, but only now got the time. I commented out that line and, yes, the attachments arrive unharmed now.

I will check my example code against the last version you posted above and compare for any differences. And then I'll look into this subject of stripslashes and the issue of forcedownload versus octetstream mime types.

After that, I'll be off creating the forms and functions I want. If I have new questions, I'll write in either a new thread or an existing one (if its on topic).

But, you've essentially provided an excellent tutorial right here which really gets a newbie/non-programmer up and running!

Thank you very much for your effort.

I noticed that you seem to be the main developer of Swift Mailer, actually. (I guess I stumbled into the right place to ask!) I will become a modest donor, for sure, and will make sure it includes a note to reference this discussion so that you know.

EDIT

I was just looking up the tmp_name issue and I found it's a matter of security, apparently.
http://shiflett.org/articles/file-uploads

There, that author suggests using an extra 'if' to verify the attachment is the same as what was uploaded (how that could not be true is something I do not understand). I had been thinking to try to implement that, but it turned out very complicated for me to try integrating it. Nonetheless, I'll leave the link for others.

Also, at the same site, the guy suggests a possible way to check file size. Frankly, I'm not too sure I understand what would happen (in terms of what the user would see) if that code were used and the attachment was deemed too big. But, I was just noting it here for future reference because it seems to address the issue on some level or other.


Last edited by JeffBell on Fri Feb 02, 2007 10:15 am, edited 2 times in total.

Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 37 posts ]  Go to page 1, 2, 3  Next

All times are UTC - 5 hours


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Jump to:  
Powered by phpBB® Forum Software © phpBB Group