I switched from sending my mails immediately to adding them to the queue, here is my code, the $attachments
is an array of temporary paths, I've commented out what I've tried, which throws errors about files not existing.
Mail::queue($view, $data, function(\Illuminate\Mail\Message $message) use($mail,$attachments){
foreach($mail->getRecipients() as $recipient){
$message->to($recipient);
}
$message->subject($mail->getSubject());
foreach($attachments as $attachment){
$message->attach($attachment);
//this deletes the attachment before being sent
//unlink($attachment);
}
});
/* This code only works when using Mail::send() instead of Mail:queue()
foreach($attachments as $attachment){
unlink($attachment);
}
*/
Basically I want to clean up and remove my temporary attachments after the mail was sent. I am guessing this would not work with the out of the box laravel mail solutions. How can I trigger code post-queue-mail-sent
?
Expanding on Deric Lima's answer a bit, you don't necessarily need a new Job class for this. You can do it with a Mailable object as well. Just override the send
method.
/**
* @param MailerContract $mailer
*/
public function send(MailerContract $mailer)
{
parent::send($mailer);
//$this->clearAttachments is something you can defined in your constructor,
//making it the responsibility of whatever is applying the attachment
//to know whether it needs to remain in tact after the email is transmitted.
if ($this->clearAttachments) {
foreach ($this->attachments as $attachment) {
if (\File::exists($attachment['file'])) {
\File::delete($attachment['file']);
}
}
}
}
Personally, I'd make a BaseMailable
class that all other Mailable
classes extend, as opposed to the Illuminate\Mail\Mailable
directly. Then you don't even have to worry about it from then on.
You have to wait until the queue is processed before removing the file.
Without knowing the implementation details of the queue it is hard to answer your question, but if your queue is processed before the script ends, you can use register_shutdown_function http://www.php.net/manual/en/function.register-shutdown-function.php to run a cleanup function that removes the file
register_shutdown_function(function() use (filename){
if (file_exists($filename)) {
unlink($filename);
}
})
I had similar problem and I solved using Laravel Jobs. Basically, you can create a Job class to send the email:
class MailJob extends Job implements SelfHandling, ShouldQueue
{
use InteractsWithQueue, SerializesModels;
public function handle()
{
Mail::send($view, $data, function (\Illuminate\Mail\Message $message) use ($mail, $attachments) {
foreach ($mail->getRecipients() as $recipient) {
$message->to($recipient);
}
$message->subject($mail->getSubject());
foreach ($attachments as $attachment) {
$message->attach($attachment);
unlink($attachment);
}
});
foreach ($attachments as $attachment) {
unlink($attachment);
}
}
}
And then you just dispatch the Job inside the controller that you want to send the email:
$this->dispatch(new MailJob());
P.S: The job is running asynchronous on the background, so I used Mail::send instead of Mail::queue.
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