Jump to content
nikola

Processing contact forms

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

Share this post


Link to post
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

Share this post


Link to post
Share on other sites

Ryan,

are you willing to post the complete code of one of your contact forms so I can take look into it?

Thanks in advance.

Share this post


Link to post
Share on other sites

I can post one on Tuesday when I'm back in my office. I'm just on mobile till then.

Share this post


Link to post
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.

Share this post


Link to post
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

Share this post


Link to post
Share on other sites

Ryan, I tried following your example here, but the form is not being displayed. Is there an else statement missing from the example you posted above?

Actually, I figured it out!!

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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"); 

Share this post


Link to post
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)

Share this post


Link to post
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

Share this post


Link to post
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.


tooltip.png

Share this post


Link to post
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?

Share this post


Link to post
Share on other sites

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??

Share this post


Link to post
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!!

Share this post


Link to post
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.

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

Actually I came from that page not knowing what to do with it ))) Would you be so kind to show how to implement that in the context of this simple form?

Share this post


Link to post
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

Share this post


Link to post
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!

Share this post


Link to post
Share on other sites

I don't know how much it matter, I do a redirect 301 and it works fine.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...