Laravel 4 Swift Mailer with dynamic config to send mail through Gmail

Laravel

Laravel 4 comes with the Swift Mailer library which works great in sending emails from your application. Just set the mail.php configuration file with the required variables and you are good to send emails. Inline images, attachment are like one line code. But the problem with a config file is that the parameters are fixed. I had a requirement where user would send email using their Gmail username and password. So, in this tutorial I will show you how to create a Swift Mailer instance and send a mail with a dynamic username, password and other parameters.

The Starting point

To start with, I have created a form which takes the email address which is used inside from field of the email and also this would be your username when you are going to send the email through your Gmail id. Then I am taking the password which is required to send the email and the third text box is the Subject which can be set. For now the body is hard coded and I have not done anything on it because it would be a very simple process of giving a CKEditor or something for the end user to put the text and then send email with that text. The rest of the SMTP settings are hard coded because they are not going to change.

The view

@layout('html')
  
@section('pageHeadSection')
@parent
<title>Welcome to Learning Laravel 4 - Send mail login page</title>
@stop
  
@section('content')
<div class="row">
<div class="col-md-12">
<h2>Login to send mail</h2>
</div>
</div>

<div class="row">
 
<div class="col-md-8">
    {{Form::open(array('url' => 'send-mail/authenticate'))}}

<div class="form-group">
      {{ Form::text('email', Input::old('email'), array('class' => 'form-control', 'placeholder' => 'Enter your email address')) }}
      <span class="error-display">{{$errors->first('email')}}</span>
    </div>

<div class="form-group">
      {{ Form::password('password', array('class' => 'form-control', 'placeholder' => 'Enter your password')) }}
      <span class="error-display">{{$errors->first('password')}}</span>
    </div>

<div class="form-group">
      <input type="text" id="subject" placeholder="Enter the subject of the email" class="form-control" name="subject" />
      <span class="error-display">{{$errors->first('subject')}}</span>
</div>
 
    <input type="submit" name="login" value="Login" class="btn btn-success">
    {{Form::close()}}
  </div>
</div>
@stop

If you see, the code is very simple; I am taking the data from the three fields and posting it to send-mail/authenticate. It also has the basic validations which I have showed in this tutorial – Laravel 4 forms custom validations and retain data.

The Controller

I have written almost all of the logic in my controller for now. Here is the code for my controller and I will go through the code.

public function authenticateUserDetails()
{
  // setting up the rules for validatoin
  $rules = array(
    'email' => 'required|email',
    'password' => 'required',
    'subject' => 'required',
  );
  
  // doing the validation, passing post data and rules
  $validator = Validator::make(Input::all(), $rules);
  
  if ($validator->fails())
  {
    // send back to the page with the input data and errors
    GlobalHelper::setMessage('Fix the errors.', 'warning'); // settig the error message
    return Redirect::to('send-mail/login')->withInput()->withErrors($validator);
  }
  
  // setting the username and password from post data
  $username = Input::get('email');
  $password = Input::get('password');
  $body = View::make('emails.sendmail-body');
  $subject = Input::get('subject');;
  
  // setting the server, port and encryption
  $transport = Swift_SmtpTransport::newInstance('smtp.gmail.com', 465, 'ssl')
    ->setUsername($username)
    ->setPassword($password);
  
  // creating the Swift_Mailer instance and pass the config settings
  $mailer = Swift_Mailer::newInstance($transport);
  
  // configuring the Swift mail instance with all details
  $message = Swift_Message::newInstance($subject)
    ->setFrom(array('amitavroy@gmail.com' => 'Amitav Roy'))
    ->setTo(array('amitav.roy@focalworks.in' => 'Amitav Office'))
    ->setBody($body, 'text/html');
    
  try
  {
    $mailer->send($message);
    echo 'Mail sent... Enoy.';
  }
  catch (Exception $e)
  {
    die('Error sending email. ' . $e);
  }
}

First I have created the rules array and then validated the data using Laravel’s Validator class. If the validation is successful then we proceed.

The username, password and the subject is something which I am getting through post data and the mail body is something which for now is a hardcoded value which I am generating a view.

Once these basic values have been defined, I create a new instance of “Swift_SmtpTransport” and set some very important configurations which are – smtp server, the outgoing port and encryption method followed by the username and password which will be used to authenticate at the SMTP server.

Once that is done, I create a new “Swift_Mailer” instance and password the transport instance. This is something which I have done as shown in the Switch Mailer documentation on their own website (nothing special).

Then I create a new instance of “Swift_Message” and pass the values like the from field, the from name, to field and the body followed by the content type which I have set to text/html which ensured that basic HTML tags are rendered and not shown as plain text.

Then we execute the “$mailer->send($message)” function in a try catch block. If the send function is successful, we redirect the user with a mail success message or else the Catch block will throw the exception.

This works for almost all kind of errors like wrong username/password, server not reachable (I disabled my internet connection). The only thing which we can do is to treat the errors in a better manner in the catch block.

As always, I have created a new branch for this tutorial. You can find the code for this tutorial on this URL: Git code