Yii 2 Mailer and Auto-Responder

I needed a way to send mail, so, remembering that there is a contact page on the advanced template that sends a mail message, I used it as a guide for what I wanted to build. I only mention this to point out that you can use a lot of what Yii 2 hands you in its templates as a guide for what you want to build.

After studying the ContactForm model, I came up with my mail method:

public static function sendTheMail($message_id)  
{
   return Yii::$app->mailer->compose()
       ->setTo(\Yii::$app->user->identity->email)
       ->setFrom(['no-reply@yii2build.com' => 'Yii 2 Build'])
       ->setSubject(RecordHelpers::getMessageSubject($message_id))
       ->setTextBody(RecordHelpers::getMessageBody($message_id))
       ->send();
} 

Ok, so Yii 2 has a mailer class, accessed from the application instance Yii::$app. Here we have a whole bunch of methods chained together. And so now we see the logic behind what we were doing if it was not already clear. Mailer’s setTo method takes a parameter of the current user’s email address. For now we are hard-coding the from address and name. For setSubject, we use our handy static call to:

RecordHelpers::getMessageSubject($message_id)

Nice concise code and for the message body, same type of thing:


RecordHelpers::getMessageBody($message_id)

You can see that the method takes $message_id as a parameter, so now all we need is a method that will call sendTheMail, that has the ability to hand in the $message_id.

So Now I go back to the beginning question because before I build the method, I need to know how I’m going to call it.

I was very happy with something like:

public function afterAction($action, $result)
{
   MailCall::isMailable($action->id, getUniqueId());
    return parent::afterAction($action, $result);
}

The plan was to create a method named isMailable on my newly created MailCall class. Since I’m using a static method, I can just pop it in there. I do that a lot for these helper methods.

$action->id returns ‘action’, so if this were the site controller and the index action were being called, it would return ‘index.’ And getUniqueId() returns the controller name. So that gave me the two things I need to look up a record, see if it existed, if so, return the message id, and hand it into the sendTheMail method.

So I was pretty happy. So much so, I took a break and went for a walk. And as I was enjoying the nice cool ocean air, clearing my head, I realized I was making a mistake.

The method afterAction fires after every action, which is what I wanted, but it has no way to know what I intended the success of the action to be. For example, let’s say you had an action that says save a record or show form for input, which we see a lot in our controllers. The afterAction method will fire in both cases, no matter what, because as far as it is concerned, it has called the action. But you would only want to send an email in certain cases, saving for example, not showing the form, so using afterAction just went out the window.

And so it goes in programming. I needed a more discrete way of determining what would trigger the email, and since that could vary greatly from action to action, the only way to do it correctly is to place the method call inside of the action at precisely the point where I want it to execute.

Advertisements

One thought on “Yii 2 Mailer and Auto-Responder”

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s