Jump to content

Processing contact forms


nikola

Recommended Posts

I have a contact form that uses external php file for validation and sending mail. If I use it as a standalone it works in a normal way, but when I import it into Proccesswire form action input 403 forbidden page.

External php file is declared in form action (sendemail.php)

<form id="form" name="form" method="post" action="sendemail.php">

It also occurs if I specify direct path to sendemail.php using:

<!--?php echo $config--->urls->templates?>sendemail.php

sendemail.php file includes phpmailer.class.php which is also located in templates folder.</form>

Edited by adamkiss
Fixed code tags in the new IPB forums
Link to comment
Share on other sites

For security reasons, PW forces a "403 forbidden" if someone tries to directly access any PHP files in the /site/templates/ dir, as well as several other locations in PW's file system. So it's best not to put any PHP files that you need to directly access in any of ProcessWire's directories, because there's a good chance it'll block access to them. Here are a few alternatives:

Option 1.

Place your sendemail (and optionally phpmailer include) files somewhere outside of PW's directories. For instance, maybe you could create a dir called /form/ off your web root and place them in there. Then set your form to: action='/forms/sendemail.php'

Option 2.

Use your sendemail.php as a ProcessWire template. Create a page using that template, and make your form post to that page.

Option 3. (the one that I use most often)

Make your form post to the same page that it's on (i.e. action='./'). When you see one of your POST vars present, include your form processing script. i.e.

<?php
if($input->post->submit) {
    // process contact form
    include("./includes/sendemail.php");
} else {
    // output contact form
}
  • Like 3
Link to comment
Share on other sites

The problem was in my PHP settings, I've tried the same code that I've used in my previous contact forms on my pc at work and it worked.

But this type of form uses PHP mail function embedded directly in template, rather then using external PHP file for processing the form in the "action" parameter.

I'll try other options in next few days, but currently I have working forms on my project web site.

P.S. The web site I've been working on will be public in a day or so and I'll post it into the showcase section.

Link to comment
Share on other sites

Sounds great, I look forward to seeing it. As promised, here's a full example of a simple contact form. This is bare bones, but safe. I've left out spam prevention measures, which I'll be happy to follow-up with if you'd like. Below is an entire template file. I figured it was simpler to show this way rather than splitting into multiple files. Though when forms get really large, I tend to split them in multiple files (and include them). But for smaller forms, I do it like the example below.

/site/templates/contact.php

<?php

$sent = false;
$error = '';
$emailTo = 'nikola@company.com'; // or pull from PW page field

// sanitize form values or create empty
$form = array(
    'fullname' => $sanitizer->text($input->post->fullname),
    'email' => $sanitizer->email($input->post->email),
    'comments' => $sanitizer->textarea($input->post->comments),
    ); 

// check if the form was submitted
if($input->post->submit) {

    // determine if any fields were ommitted or didn't validate
    foreach($form as $key => $value) {
        if(empty($value)) $error = "<p class='error'>Please check that you have completed all fields.</p>";
    }

    // if no errors, email the form results
    if(!$error) {
        $msg = "Full name: $form[fullname]\n" . 
               "Email: $form[email]\n" . 
               "Comments: $form[comments]"; 

        mail($emailTo, "Contact Form", $message, "From: $form[email]");

        // populate body with success message, or pull it from another PW field
        $page->body = "<h2>Thank you, your message has been sent.</h2>"; 
        $sent = true;	
    }
}

if(!$sent) {

    // sanitize values for placement in markup
    foreach($form as $key => $value) {
        $form[$key] = htmlentities($value, ENT_QUOTES, "UTF-8"); 
    }

    // append form to body copy
    $page->body .= <<< _OUT

        $error
        <form action="./" method="post">
        <p>
        <label for="fullname">Your Name</label><br />
        <input type="text" id="fullname" name="fullname" value="$form[fullname]" />
        </p>

        <p>
        <label for="email">Your Email</label><br />
        <input type="email" name="email" id="email" value="$form[email]" />
        </p>

        <p>
        <label for="comments">Comments</label><br />
        <textarea id="comments" name="comments">$form[comments]</textarea>
        </p>

        <p><input type="submit" name="submit" value="Submit" /></p>
        </form>

_OUT;

}

// include site's main template which outputs everything
include("./main.php"); 
  • Like 9
Link to comment
Share on other sites

  • 4 months later...

You'll probably need to change these lines to be consistent with the approach you are taking with your templates:

$page->body .= <<< _OUT

That line assumes that you want to append the form to the 'body' field, and that it hasn't already been output. If you are using head/foot includes (like in the default profile), then you'll probably just want to echo the output, i.e.

echo <<< _OUT

Likewise, you'd want to change any other instances that append to $page->body, and instead echo that output (or assign it to another variable).

The bottom of the example says this:

include("./main.php"); 

It has that because it's assuming main.php handles all the output (rather than a head/foot include). So you may want to remove that line.

Link to comment
Share on other sites

  • 1 year later...

also small variable typo in ryans code here:

$message and $msg should have the same variable name, otherwise your passing an empty $message variable into the email.

Sounds great, I look forward to seeing it. As promised, here's a full example of a simple contact form. This is bare bones, but safe. I've left out spam prevention measures, which I'll be happy to follow-up with if you'd like. Below is an entire template file. I figured it was simpler to show this way rather than splitting into multiple files. Though when forms get really large, I tend to split them in multiple files (and include them). But for smaller forms, I do it like the example below.

/site/templates/contact.php

<?php

$sent = false;
$error = '';
$emailTo = 'nikola@company.com'; // or pull from PW page field

// sanitize form values or create empty
$form = array(
    'fullname' => $sanitizer->text($input->post->fullname),
    'email' => $sanitizer->email($input->post->email),
    'comments' => $sanitizer->textarea($input->post->comments),
    ); 

// check if the form was submitted
if($input->post->submit) {
	
    // determine if any fields were ommitted or didn't validate
    foreach($form as $key => $value) {
        if(empty($value)) $error = "<p class='error'>Please check that you have completed all fields.</p>";
    }

    // if no errors, email the form results
    if(!$error) {
        $msg = "Full name: $form[fullname]\n" . 
               "Email: $form[email]\n" . 
               "Comments: $form[comments]"; 

        mail($emailTo, "Contact Form", $message, "From: $form[email]");

        // populate body with success message, or pull it from another PW field
        $page->body = "<h2>Thank you, your message has been sent.</h2>"; 
        $sent = true;	
    }
}

if(!$sent) {

    // sanitize values for placement in markup
    foreach($form as $key => $value) {
        $form[$key] = htmlentities($value, ENT_QUOTES, "UTF-8"); 
    }

    // append form to body copy
    $page->body .= <<< _OUT

        $error
        <form action="./" method="post">
        <p>
        <label for="fullname">Your Name</label><br />
        <input type="text" id="fullname" name="fullname" value="$form[fullname]" />
        </p>

        <p>
        <label for="email">Your Email</label><br />
        <input type="email" name="email" id="email" value="$form[email]" />
        </p>

        <p>
        <label for="comments">Comments</label><br />
        <textarea id="comments" name="comments">$form[comments]</textarea>
        </p>

        <p><input type="submit" name="submit" value="Submit" /></p>
        </form>

_OUT;

}

// include site's main template which outputs everything
include("./main.php"); 
Link to comment
Share on other sites

also is there any spam filtering going on here?

i've implemented some basic empty field stuff in my code (where there are extra inputs hidden with css which cause an error if filled in)

Link to comment
Share on other sites

Hi all,

i am new to PS and didn't have enough time to learn it. I think will be great platform for my future projects. For start I use default template and create the /site/templates/contact.php . The form shows well and submit sends the mail, but after that i got page with empty body. No "Thank you ..." message neither option to go back to home page. Please ryan, point me to the right code after sending email which says "thanks" and show button to go to home. Thanks in advance! Edited: changed $page->body with simple echo solved the problem. The working code is:

<?php

include("./head.inc"); 

echo $page->body;

$sent = false;
$error = '';
$emailTo = 'my@email'; // or pull from PW page field

// sanitize form values or create empty
$form = array(
    'fullname' => $sanitizer->text($input->post->fullname),
    'email' => $sanitizer->email($input->post->email),
    'comments' => $sanitizer->textarea($input->post->comments),
    ); 

// check if the form was submitted
if($input->post->submit) {
	
    // determine if any fields were ommitted or didn't validate
    foreach($form as $key => $value) {
        if(empty($value)) $error = "<p class='error'>Please check that you have completed all fields.</p>";
    }

    // if no errors, email the form results
    if(!$error) {
        $msg = "Full name: $form[fullname]\n" . 
               "Email: $form[email]\n" . 
               "Comments: $form[comments]"; 

        mail($emailTo, "Contact Form", $msg, "From: $form[email]");

        // populate body with success message, or pull it from another PW field
        echo "<h2>Thank you, your message has been sent.</h2>"; 
        $sent = true;	
    }
}

if(!$sent) {

    // sanitize values for placement in markup
    foreach($form as $key => $value) {
        $form[$key] = htmlentities($value, ENT_QUOTES, "UTF-8"); 
    }

    // append form to body copy
    echo <<< _OUT

        $error
        <form action="./" method="post">
		<fieldset>
        <p>
        <label for="fullname">Your Name</label><br />
        <input style="width:300px;" type="text" id="fullname" name="fullname" value="$form[fullname]" />
        </p>

        <p>
        <label for="email">Your Email</label><br />
        <input style="width:300px;" type="email" name="email" id="email" value="$form[email]" />
        </p>

        <p>
        <label for="comments">Comments</label><br />
        <textarea style="width:300px;" id="comments" name="comments" rows="6">$form[comments]</textarea>
        </p>

        <p><input type="submit" name="submit" value="Submit" /></p>
		</fieldset>
        </form>

_OUT;

}

// include site's footer
include("./foot.inc"); 
Edited by Angel
  • Like 2
Link to comment
Share on other sites

anyone happen to know where this tooltip is spring up from so that I can style it??? Im using jquery and the code above, thats it.

I'm guessing that's client side, coming from your browser?

Link to comment
Share on other sites

  • 10 months later...

I have tried this contact form from Starter and it works quite well, but I have problems with the German letters like ü,ä,ö and so on. They will be sent like üü. The charset is utf-8 but it doesnt work in the emails.

Has anyone a sugguestion to solve this problem??

Link to comment
Share on other sites

I found the solution :rolleyes:

This is the example for the fullname. You have to decode it to utf-8:

dont use this: Name: $form[fullname]

Use this instead: Name:utf8_decode($form[fullname]);

Make this for all fields in the email and it works!!

Link to comment
Share on other sites

Never have this problem. Make sure your template file and code is utf8. Also it depends how you send the email if you don't set a correct header it may cause troubles with chars. Then usually a utf8_decode isn't needed.

Link to comment
Share on other sites

  • 1 month later...

This is a general question, but relates closely to what is covered above.

I built a form the way shown above. When i submit a form i get the proper message. And then if i refresh a page a message gets sent again. I know it is because same post variables are sent and processesed while refreshing a page. Please suggest a workaround for dealing with this.

Link to comment
Share on other sites

One way is to well redirect to another page that is only a text page instead after sending email...

// if no errors, email the form results
    if(!$error) {
        $msg = "Full name: $form[fullname]\n" .
              "Email: $form[email]\n" .
              "Comments: $form[comments]";

        mail($emailTo, "Contact Form", $message, "From: $form[email]");
        $session->redirect("/some/thankyoupage/");

        // populate body with success message, or pull it from another PW field
        // $page->body = "<h2>Thank you, your message has been sent.</h2>";
        // $sent = true;    
    }

  • Like 3
Link to comment
Share on other sites

Oh thank you. As I was reading the PRG docs, i mentioned that you should redirect with 303 code. I see that $session->redirect("/some/thankyoupage/") throws a 301 code and $session->redirect($url, false) a 302. So it is not even possible to do it the recommended way. Anyway $session->redirect($url, false) seems to be the right choice according to that wikipedia page.

Thank you very much for help!

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...