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.
Thanks in advance.
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);
}
}
protected $listen = [
'Illuminate\Mail\Events\MessageSent' => [
'App\Listeners\DeleteTempResources'
]
];
public function handle(MessageSent $event)
{
// Trying to access on data message
Log::info($event->message->firma);
}
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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With