Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access Mail data from MessageSent event on Laravel?

I'm using laravel 5.5, and trying to send emails with an image that is the sign of the client. To make the image accessible from the views I'm copying it into public folder and queued emails will access to it.

With a single action I can send multiple emails to the client, with sign into email, and pdf like the email attached, with sign image too. Then, the same image can be called multiple times from different emails. Is for this that I copy one image with a codified name for each email and passing the name of the image to the Mailable.

The problem is to make a sign of client public with a limited time. Then I'm trying to make listener for Illuminate\Mail\Events\MessageSent event that deletes the image of public folder getting the image name from the event... but I can't access to it.

  • How can I access to data of mailable from the event?
  • Do you know a better way to do this?

Thanks in advance.

Mailable class

class SEPA extends Mailable
{
    use Queueable, SerializesModels;

    public $client;

    /**
     * Create a new message instance.
     *
     * @param Client $client
     */
    public function __construct(Client $client)
    {
        $this->client = $client;
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        $date = Carbon::now();

        // Name codified
        $fileName = md5(microtime()).".png";

        // Making the image accessible from views
        Storage::copy("clients/{$this->client->id}/firma.png", "public/tmp/{$fileName}");
        $pdfName = "SEPA - {$this->client->name}{$this->client->cognom1}{$this->client->cognom2}.pdf";
        $dades = [
            'data'      => $date,
            'client'    => $this->client,
            'firma'     => $fileName
        ];

        // Generating PDF
        $pdf = PDF::loadView('pdfs.SEPA', $dades);
        if (!Storage::has("tmp/clients/{$this->client->id}")) Storage::makeDirectory("tmp/clients/{$this->client->id}");
        $pdf->save(storage_path()."/app/tmp/clients/{$this->client->id}/".$pdfName);

        return $this
            ->from(['address' => '[email protected]'])
            ->view('emails.SEPA')
            ->with($dades)
            ->attach(storage_path()."/app/tmp/clients/{$this->client->id}/".$pdfName);
    }
}

EventServiceProvider.php

protected $listen = [
    'Illuminate\Mail\Events\MessageSent' => [
        'App\Listeners\DeleteTempResources'
    ]
];

Listener

public function handle(MessageSent $event)
    {
        // Trying to access on data message
        Log::info($event->message->firma);
    }
like image 653
axsor Avatar asked Mar 09 '18 09:03

axsor


1 Answers

You might be able to just set the additional data you need to access from the event via the withSwiftMessage() method, as extra fields on the actual swiftMessage, since that's what will be accessible in the event, as $message.

I saw someone did this here, e.g. to add a $user object:

$this->withSwiftMessage(function ($message) {
    $message->user = $this->user; // any crazy field of your choosing
});

This seemed pretty unorthodox to me - adding rogue fields like that.

Note you don't need to use the $user object to get it into the closure as it's available in scope via $this, so long as it's a member property of the containing class.

To see it in the event when the message comes off the queue, you can Log::info('The user: ', [$event->message->user]) in the MessageSending event.

I've just tested this, and it works (I'm on 5.5), but I'm not yet using this myself in code as it does seem a little strange, adding a rogue field like that. I mention it though as it might actually solve your problem if you're comfortable with the method! If anyone knows a less ugly way to do it, I'm all ears...

P.S. I may consider just tacking on $message->lara_user_id = $this->user->id in the closure, for my own case, as that seems unlikely to collide with anything, and can be conveniently pulled back in the event. discussion welcome!

like image 52
mwal Avatar answered Nov 12 '22 02:11

mwal