Yassine Qoraiche
Yassine Qoraiche

Reputation: 1158

Laravel Get Mail className from MessageSending event

I'm using laravel 5.7, when sending an email using the Mail interface two events fired Mail\Events\MessageSending and Mail\Events\MessageSent, so my goal is to catch the MessageSending event and get the mailable class used to send the email (example mail\Ordershipped) and stop it.

<?php

namespace App\Listeners;

use Illuminate\Mail\Events\MessageSending;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;

class LogSendingMessage
{
    /**
     * Create the event listener.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Handle the event.
     *
     * @param  MessageSending  $event
     * @return void
     */
    public function handle(MessageSending $event)
    {

        //here i want to check what mailable class used and stop it.
        if ($mailable == 'Ordershipped')
        return false;

        // if another mailable class (example: userVerification)
        else
        
         return true;
    }
}

Upvotes: 5

Views: 2921

Answers (1)

Tom Headifen
Tom Headifen

Reputation: 1996

At this point in time the Event does not know what the mailable type is since the HTML has already been built from the blade.

However you can append values to the underlying swift mail class in your mailable.

In your App\Mail folder create a file called Mailable.php. This is now your new mailable class that all your mailables will extend off of.

namespace App\Mail;
use Illuminate\Contracts\Mail\Mailer as MailerContract;
use Illuminate\Mail\Mailable as BaseMailable; // Extend off laravel mailable

abstract class Mailable extends BaseMailable
{
    public function send(MailerContract $mailer)
    {
        //Initializes properties on the Swift Message object
        $this->withSwiftMessage(function ($message) {
            $message->mailable = get_class($this);
        });

        parent::send($mailer);
    }
}

Use this class for all of your mailables like so:

use App\Mail\Mailable; // This is your new mailable parent class

class UserConfirmEmail extends Mailable
{
    public function build()
    {
         // Build email
    }
}

You can then get the mailable name from your swift_mail object which is the message attribute off of the $event variable e.g. $event->message.

// App\Listeners\LogMessageSending.php
public function handle(MessageSending $event)
{

    //here i want to check what mailable class used and stop it.
    if ($event->message->mailable == 'Ordershipped') {
        return false;
    }
    // if another mailable class (example: userVerification)
    else {
     return true;
    }
}

Upvotes: 8

Related Questions