0

I'm trying to develop a contact form for a language school website that runs on Wordpress. Disclaimer: I'm about 6 months into coding, so please forgive me for being new to this. I'm developing my own theme and I wanted to limit usage of plugins to bare minimum for safety reasons - I prefer to learn how to write stuff myself instead on relying on updates of a third-party plus the courses I follow on Wordpress dev listed it as a good practice to avoid unnecessary plugins.

The problem is listed below in bold.

What I want to achieve:

  1. Simple contact form that takes following info: name, email, course, phone (optional) and a message.
  2. Validate the form if user provided correct info - I can't make the user provide valid info, but at least I want to lock number into numbers only range and check if email is correct.
  3. Check if user is human (Captcha).
  4. Send the email to my address and provide a copy to the sender.
  5. Inform the user whether the action was a success or a failure.

What I succeeded with:

  • Mail gets sent.
  • Captacha seems to be working and filtering out attempts that do not click on it.

What 'kinda works':

  • The PHP doesn't seem to validate the form. I used HTML type and require instead, but I've read that solution is not ideal. I tried to use JS to write some functions that would prevent unwanted input, but I couldn't get it to work properly. I decided to ask the question first in case it might be a dead end. JS seems to be working on my Wordpress as I'm using Bootstrap and some custom JS for certain features so I'm pretty sure the code gets executed, but I wanted to ask first if that's the correct way of approach it before I invest my time in it.

What I have a problem with:

It is imperative to me that the user gets feedback from the page whether the email has been sent or not for obvious business-client communication reasons. I tried two solutions found on SO:

  • Injecting JS alert into PHP's echo inside conditional (JS doesn't get executed)
  • Using header method to redirect into thank-you.page that informs about success or error.page that informs about a failure and recommends another avenue of contact

What went wrong: the second solution got executed properly, the user gets redirected to site.com/thank-you or site.com/error, however the browser crashes due to 'too many redirects'.

I tried googling, I tried different solutions from tutorials. What would be your recommendation?

My code:

<?php 
$nameErr = $emailErr = $courseErr = $phoneErr = "";
$name = $email = $course = $comment = $phone = "";
$thank_you = wp_redirect( '"'.home_url().'/thank-you"', 301 );
$error = wp_redirect( '"'.home_url().'/error', 301 );

if ($_SERVER["REQUEST_METHOD"] == "POST") {
    if (empty($_POST["name"])) {
      $nameErr = "Give name";
    } else {
      $name = test_input($_POST["name"]);
      // check if name only contains letters and whitespace
      if (!preg_match("/^[a-zA-Z-' ]*$/",$name)) {
        $nameErr = "Only letters allowed";
      }
    }
    
    if (empty($_POST["email"])) {
      $emailErr = "Need email";
    } else {
      $email = test_input($_POST["email"]);
      // check if e-mail address is well-formed
      if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        $emailErr = "Email incorrect";
      }
    }
  
if (empty($_POST["phone"])) {
  $phone = "";
} else {
  $phone = test_input($_POST["phone"]);
  // check if URL address syntax is valid (this regular expression also allows dashes in the URL)
  if (!is_numeric($number)) {
    $phoneErr = "Bad number";
  }
}

if (empty($_POST["comment"])) {
  $comment = "";
} else {
  $comment = test_input($_POST["comment"]);
}

if (empty($_POST["course"])) {
  $courseErr = "Pick course";
} else {
  $course = test_input($_POST["course"]);
}
  }
 function test_input($data) {
    $data = trim($data);
    $data = stripslashes($data);
    $data = htmlspecialchars($data);
    return $data;
  }
    if(!empty($_POST['g-recaptcha-response']))
    {
          $secret = 'mySecretKey';
          $verifyResponse = file_get_contents('https://www.google.com/recaptcha/api/siteverify?secret='.$secret.'&response='.$_POST['g-recaptcha-response']);
          $responseData = json_decode($verifyResponse);
if($responseData->success)
              $message = "g-recaptcha verified successfully";
              if(isset($_POST['submit'])){
                $to = "[email protected]"; // this is your Email address
                $from = $_POST['email']; // this is the sender's Email address
                $name = $_POST['name'];
                $course = $_POST['course'];
                $phone = $_POST['phone'];
                $comment = "Form submission";
                $comment2 = "Copy of your form submission";
                $message =  "Name:" . $name . "Interested in " . $course. " Number" . $phone . " " . " Wrote" . "\n\n" . $_POST['comment'];
                $message2 = "Copy " . $name ."\n\n" . "Interested in:" . $course . "\n\n" . $_POST['comment'];
                $headers = "From:" . $from;
                $headers2 = "From:" . $to;
                mail($to,$comment,$message,$headers);
                mail($from,$comment2,$message2,$headers2);
                 // sends a copy of the message to the sender
                 header($thank_you);
                // This redirects to page thanking for contact.
                }
          else 
          header($error);
// This redirects to page informing about failure.
              $message = "couldn't verify Captcha. Email not sent.";
         echo '<script type="text/javascript">mailNotSent();</script>';
     }
?>
<section id="contact" class="contact">
    <div class="container pseudonest">
        <div class="pseudonest contact__head--nest">
            <h1 class="display-5 lh-1 mb-2 contact__head--pseudocircle contact__head--header mx-auto">Enroll now</h1>
        </div>
        <div class="container m-auto">
             <div class="d-flex justify-content-center contact__form">
                <div class="col-md-7 col-lg-8">
                    <form action="" method="post">
                        <form class="needs-validation" novalidate>
                            <div class="row g-3">
                                <div class="col">
                                    <label for="name" id="nameHeader" class="form-label">Name</label>
                                    <input type="text" class="form-control radio__margin" id="name" name="name"
                                        placeholder="" value="<?php echo $name;?>" required>
                                    <div class="invalid-feedback">
                                        <?php echo $nameErr;?>
                                    </div>
                                    <label for="email" class="form-label">Email</label></label>
                                    <input type="email" class="form-control radio__margin" id="email" name="email"
                                        placeholder="[email protected]" value="<?php echo $email;?>" required>
                                    <div class="invalid-feedback">
                                        <?php echo $emailErr;?>
                                    </div>
                                    <label for="phone" class="form-label">Phone</label></label>
                                    <input type="number" class="form-control radio__margin" id="phone" name="phone"
                                        pattern="[0-9]+" placeholder="+48 111 222 333" value="<?php echo $phone;?>">
                                    <div class="invalid-feedback">
                                        <?php echo $phoneErr;?>
                                    </div>
                                </div>
                                <div class="col radio__col">
                                    <label for="firstName" class="form-label">Course?</label>
                                    <div class="row radio__section">
                                        <label class="radio__container">English
                                            <input type="radio" name="course"
                                                <?php if (isset($course) && $course=="English") echo "checked";?>
                                                value="English">
                                            <span class="radio__checkmark"></span>
                                        </label>
                                        <label class="radio__container">
                                            <input type="radio" name="course"
                                                <?php if (isset($course) && $course=="Polish") echo "checked";?>
                                                value="Polish">
                                            <span class="radio__checkmark"></span>Polish
                                        </label>
                                        <label class="radio__container">
                                            <input type="radio" name="course"
                                                <?php if (isset($course) && $course=="Italian") echo "checked";?>
                                                value="Italian">
                                            <span class="radio__checkmark"></span>Italian
                                        </label>
                                        <span class="error"> <?php echo $courseErr;?></span>
                                    </div>
                                </div>
                            </div>
                            <div class="col-12 mb-5">
                                <label for="email-content" class="form-label">Content</label>
                                <div class="input-group has-validation">
                                    <textarea class="form-control" rows="5" name="comment"
                                        cols="30"><?php echo $comment;?></textarea>
                                    <div class="invalid-feedback">
                                    </div>
                                </div>
                            </div>
                            <form id="frmContact" action="varify_captcha.php" method="POST" novalidate="novalidate">
                                <div class="g-recaptcha my-3" data-sitekey="mySiteKey">
                                </div>
                                <input type="submit" name="submit" value="Send" id="submit"
                                    class="btn btn-primary contact__form--btn">
                                <div id="fakeSubmit" class="btn btn-primary contact__form--btn hidden">Fill the form
                                </div>
                            </form>
                        </form>
                </div>
            </div>
</section>

1 Answer 1

0

I understand your hesitation about using 3rd party plugins, but form handling is a primary candidate to offload to one. That's coming from someone who always tries to build bespoke.

There is a reason why several well-established WP form plugins exist - forms are tedious to build & handle manually, prone to errors & unwittingly introducing security vulnerabilities. There are so many elements to consider & cater for.

If you still wish to pursue your own form building, I would strongly suggest using an existing PHP framework or library (I can't recommend one personally but you can check out a bunch on packagist).

It'll mean you can code your forms more expressively & less verbosely, focusing on what the form is rather than dealing with all the repetitive & tedious mechanics of standard form processing.

3
  • I appreciate the help. However I tried just now to create a form with WPForms and it totally broke my page. Is there any plugin that's actually safe? Jun 17, 2022 at 11:55
  • @ScorpVisual WPForms is very well established & respected, can you elaborate by "totally broke [your] page?" Jun 17, 2022 at 16:52
  • Basically white screen of death due to too many redirects. I tried it on localhost too and it injected some weird PHP code as text on top of the header. Removing the plugin turned the page back up. Jun 18, 2022 at 6:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.