Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Translate queued mails (localization)

I am looking for a working solution, to translate queued emails in laravel-5. Unfortunately, all emails use the default locale (defined under app.locale).

Let's assume, we have two emails in the pipeline, one for an English en user and another for an Japanese jp user.

What data should I pass to the Mail facade to translate (localize) the queued emails?

  // User model
  $user = User:find(1)->first();

  Mailer::queue($email, 'Party at Batman\'s cave (Batcave)', 'emails.party-invitation', [

    ...

    'locale' => $user->getLocale(), // value: "jp", but does not work
    'lang' => $user->getLocale(), // value: "jp", but does not work
    'language' => $user->getLocale(), // value: "jp", but does not work
  ]);
like image 599
mate64 Avatar asked Mar 05 '15 22:03

mate64


2 Answers

I have been struggling to get this done in a more efficient way. Currently I have it set up like this. Hopefully this helps someone in the future with this issue:

// Fetch the locale of the receiver.
$user = Auth::user();
$locale = $user->locale;
Mail::queue('emails.welcome.template', ['user' => $user, 'locale' => $locale], function($mail) use ($user, $locale) {
     $mail->to($user->email);
     $mail->subject(
          trans(
               'mails.subject_welcome',
               [], null, $locale
          )
     );
});

And use the following in your template:

{{ trans('mails.welcome', ['name' => ucfirst($user['first_name'])], null, $locale) }}

Note: do not forget to restart your queue

like image 132
kendepelchin Avatar answered Sep 23 '22 11:09

kendepelchin


If your emails inherits the built-in Illuminate\Mail\Mailable class you can build your own Mailable class that will take care of translations.

Create your own SendQueuedMailable class that inherits from Illuminate\Mail\SendQueuedMailable. Class constructor will take current app.location from config and remember it in a property (because laravel queues serializes it). In queue worker it will take the property back from config and set the setting to the current environment.

<?php

namespace App\Mail;

use Illuminate\Contracts\Mail\Mailer as MailerContract;
use Illuminate\Contracts\Mail\Mailable as MailableContract;
use Illuminate\Mail\SendQueuedMailable as IlluminateSendQueuedMailable;

class SendQueuedMailable extends IlluminateSendQueuedMailable
{
    protected $locale;

    public function __construct(MailableContract $mailable)
    {
        parent::__construct($mailable);

        $this->locale = config('app.locale');
    }

    public function handle(MailerContract $mailer)
    {
        config(['app.locale' => $this->locale]);
        app('translator')->setLocale($this->locale);

        parent::handle($mailer);
    }
}

Then, create your own Mail class that inherits from Illuminate\Mail\Mailable

<?php

namespace App\Mail;

use Illuminate\Contracts\Queue\Factory as Queue;
use Illuminate\Mail\Mailable as IlluminateMailable;

class Mailable extends IlluminateMailable
{
    public function queue(Queue $queue)
    {
        $connection = property_exists($this, 'connection') ? $this->connection : null;

        $queueName = property_exists($this, 'queue') ? $this->queue : null;

        return $queue->connection($connection)->pushOn(
            $queueName ?: null, new SendQueuedMailable($this)
        );
    }
}

And, voila, all your queued mailables inherited from App\Mailable class automatically will take care of current locale.

like image 43
pinguinjkeke Avatar answered Sep 23 '22 11:09

pinguinjkeke