Laravel Contact Form

Published 2 months ago by zarcoder

I purchased a html template from themeforest and I'm in the process of converting all the files into blade files. Bit of a mission I must say.

I now need to setup my contact form. I'm quite lost at the moment. I did read through the Laravel mail docs but I'm struggling. So the theme included the contact form (in html obviously) as well as the php 'contact-process file. Both files are shown below.

My question is, how do I convert this to laravel? I'm not sure which steps to follow. How can I make this contact form work in laravel?

The Form:

<form method="post" id="contact-form" action='contact-process.php'>
                         <label>Name</label>
                         <p><input type="text" name="name" class="reservation-fields" /></p>
                         <label>Email</label>
                         <p><input type="text" name="email" class="reservation-fields"/></p>
                         <label>Subject</label>
                         <p><input type="text" name="subject" class="reservation-fields" /></p>
                         <label>Message</label>
                         <p> <textarea name="message" id="msg-contact" class="reservation-fields" rows="7"></textarea></p>
                         <p class="antispam">Leave this empty: <input type="text" name="url" /></p>
                         <p class="contact-btn"><input type="submit" value="Send message" id="submit"/></p>
                      </form>

PHP File:

<?php

$recipient = "[email protected]";
$name = $_POST['name'];
$email = $_POST['email'];
$subject = $_POST['subject'];
$message = $_POST['message'];

if (isset($_POST['email'])) {   
    if (preg_match('(\w[-._\w]*\[email protected]\w[-._\w]*\w\.\w{2,})', $_POST['email'])) {
        $msg = 'E-mail address is valid';
    } else {
        $msg = 'Invalid email address';
    }

  $ip = getenv('REMOTE_ADDR');
  $host = gethostbyaddr($ip);   
  $mess = "Name: ".$name."\n";
  $mess .= "Email: ".$email."\n";
  $mess .= "Subject: ".$subject."\n";
  $mess .= "Message: ".$message."\n\n";
  $mess .= "IP:".$ip." HOST: ".$host."\n";
  
  $headers = "From: <".$email.">\r\n"; 
  
   if(isset($_POST['url']) && $_POST['url'] == ''){

       $sent = mail($recipient, $subject, $mess, $headers); 
} 

  

} else {
    die('Invalid entry!');
}
Best Answer (As Selected By zarcoder)
Cronix

This doesn't seem too difficult. How familiar are you with laravel? I mean, do you know how to make forms/controllers/views/routes/validation, etc?

In short,

  1. create a post route, pointing to a controller/method
  2. In the form, change action to point to that route
  3. In form, add {{ csrf_field() }}
  4. In controller, set up validation rules for name/subject/email/message
  5. In controller, change all $_POST['var'] to $request->var
  6. In controller, use laravel Mailables to send the email
  7. In form, display validation errors. If validation fails it will send you back to the form so show the errors
newbie360

I purchased a html template is just for front-end ? just like https://adminlte.io/themes/AdminLTE/index2.html ?

the php file is write by yourself ?

Cronix
Cronix
2 months ago (737,880 XP)

This doesn't seem too difficult. How familiar are you with laravel? I mean, do you know how to make forms/controllers/views/routes/validation, etc?

In short,

  1. create a post route, pointing to a controller/method
  2. In the form, change action to point to that route
  3. In form, add {{ csrf_field() }}
  4. In controller, set up validation rules for name/subject/email/message
  5. In controller, change all $_POST['var'] to $request->var
  6. In controller, use laravel Mailables to send the email
  7. In form, display validation errors. If validation fails it will send you back to the form so show the errors
zarcoder

@Cronix, I am a beginner but have done a few projects in laravel focussing on the basics. But I do know how to create, forms, controllers, views, routes and validation. I will follow your guidance and give feedback. Thanks for the reply

@newbie360 - Don't know what you're on about? I know it's front-end but has back-end functionality, hence the question.

pardeepkumar

Let's follow the article steps to create Laravel Contact Form with easy steps

https://www.cloudways.com/blog/laravel-contact-form/

zarcoder

@Cronin, so I got the message to work. It's being sent to mailtrap so I know it works. After the mail has been sent, I'm also being redirected to the contact page as per my redirect.

However, my success message does not display? I can't seem to get the success message right. Any thoughts?

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Session;

class PageController extends Controller
{

    public function getContact()
    {
        return view('contact');
    }

    public function postContact(Request $request)
    {
        $this->validate($request, [
            'name' => 'required|min:2|string',
            'email' => 'required|email',
            'mobile' => 'required|digits:10',
            'message' => 'required|min:10'
        ]);

        $data = array(
          'name' => $request->name,
          'email' => $request->email,
          'mobile' => $request->mobile,
          'bodyMessage' => $request->message
        );

        Mail::send('emails.contact', $data, function($message) use ($data){
            $message->from($data['email']);
            $message->to('[email protected]');
            $message->subject($data['name']);
        });

        Session::flash('success', 'Your email has been sent');

        return redirect('contact');
    }

}
Cronix
Cronix
2 months ago (737,880 XP)

So in the contact view, you have something like this?

@if ( session('success'))
    {{ session('success') }}
@endif 

Try

return redirect('dashboard')->with('success', 'Your email has been sent');

https://laravel.com/docs/5.6/redirects#redirecting-with-flashed-session-data

An unrelated question, is the from email address an address on your domain? If not, you will run into problems with mail delivery and possibly labeled as a spammer and have your domain put in blacklists like Spamhaus. That can take months to fix and you don't want to have to do that. You should always send from an email on your domain. You can always use the replyTo in addition and set the foreign email address there.

Mail::send('emails.contact', $data, function($message) use ($data){
    $message->from('[email protected]');
    $message->replyTo($data['email']);
    $message->to('[email protected]');
    $message->subject($data['name']);
});

Then if you hit reply in your email client, it will address it to the person who it was actually from, and ISP spam filters will be happy bc the from is your real domain.

zarcoder

Not to worry, I figured it out. Should not use

Session::flash('success', 'Your email has been sent');

Should use

$request->session()->flash('status', 'Good One');

instead

zarcoder

Sorry man, we were typing the same time it seems :). Only saw your message now

Cronix
Cronix
2 months ago (737,880 XP)

Good deal, please see my warning about the from address.

zarcoder

please see my warning about the from address.

Thanks for the warning. So this is something new... again :). Here's my context. I'm creating a simple website for my 1st client (restaurant owner) who has a contact form on his site. He just wants to receive emails from people who want to contact him from his website.

He will then take that email and copy it into his personal email host and answer any questions.

So, as I understand it, the 'from' attribute will identify the from email address of the person enquiring. But now that I think about that, this detail is captured in one of my form fields (email).

Hhmm, ok so I should hardcode the 'from' attribute to my personal email address in order to avoid ending up in a spambox.

Isn't it better just to avoid the 'from' attribute altogether?

May be basics to you, but I'm still climbing the mountain of learning php / laravel :)

Cronix
Cronix
2 months ago (737,880 XP)

He will then take that email and copy it into his personal email host and answer any questions.

I would just send it to his email address to begin with.

No the from field is required. When you send an email to an isp, lets say google, it checks the domain the email came from, let's say abc.com. Then it looks at the from header. If it's from anything other than abc.com, it's spam, which makes total sense.

What we do with contact forms...

  1. from is "[email protected]"
  2. to is "[email protected]"
  3. reply-to is email address person entered on form (their email, [email protected])
  4. In body of email, first thing we put is
From: [persons name] [persons email]
--------
[persons message]

So the person who receives these emails ([email protected]) can easily identify the person. If they want to reply to the email, they just hit reply like normal, but the email program will address it to the person in the "reply-to" field instead of the "from" field. This is the proper way to send email on someone elses behalf from your domain.

If the from doesn't match the domain it was actually sent from, it's spam. Some isps will bounce it, some will just discard it and you'll never know what happened to it, some will put it in the spam folder. There are millions of ISPs, and each one does things differently.

In addition, the email server needs to be set up correctly (or better yet use a service like sendgrid, etc, who know what they're doing and set it all up properly). It needs DKIM headers, RDNS set up, SPF, DMARC, and other things. The IP of the server sending the email, as well as the domain name, can't have a bad reputation or be in any blacklists. If it's a transaction email, it also needs an "opt out" link where they can remove themselves from receiving emails from your company.

Email is actually one of the more complicated things to do properly on the internet. Spam is a huge issue, and at one point (before all of these things like spf/dkim/dmarc/etc) it actually was the majority of the traffic on the internet.

Think about it. If you can just send email from a domain as another domain, that's impersonation and makes the domain that it was sent from look bad, even though they didn't actually send it.

Once you get on a blacklist (like spamhaus), it will be very difficult for other isps to receive your emails, as most of them monitor these lists in realtime and actively block emails from domains/ips that are on the lists. It will take a lot of work on your part, and several months, to get it fixed. You might end up on 10 different blacklists.

https://sendgrid.com/blog/10-tips-to-keep-email-out-of-the-spam-folder/

zarcoder

Fantastic, very helpful! Thank you @Cronix

Please sign in or create an account to participate in this conversation.