如何更改从控制器发送的电子邮件中的语言环境 - laravel 5.4

Pet*_*ter 6 php locale laravel laravel-5.3 laravel-5.4

我使用这段代码成功发送电子邮件:

 \App::setLocale('pl');
 Mail::send('emails.new_'.$itemtype, ['object' => $object, 'email' =>     $email_recipee], function ($m) use ( $email_recipee, $object, $itemtype) {
 $m->to($email_recipee, 'Title')->subject(' Subject of email');
 //
 });
Run Code Online (Sandbox Code Playgroud)

但是电子邮件被翻译成en应用程序的默认语言。

我的问题

如何让 Laravel 发送带有仅针对特定电子邮件声明的语言环境的电子邮件(每个收件人都有不同的语言集)。

我试过的:

  • \App::setLocale('pl');就在Mail命令之前
  • 在控制器中全局设置我的工作中间件__construct()

    $this->middleware('setLocale'); // sets the locale to the recipee locale

脏 (?) 解决方案

现在我只是在电子邮件视图中添加一行:

{{ \App::setLocale($lead->client->lang)}}
Run Code Online (Sandbox Code Playgroud)

有什么更好的方法吗?谢谢你。

jac*_*ach 11

TL;DR:$locale只需在类的对象中设置一个字段Mailable

class ResetPassword extends Mailable
{
   // ...

    /**
     * Create a new message instance.
     */
    public function __construct(User $user, string $token)
    {
        $this->user = $user;
        $this->token = $token;
        /*
         * Set locale of mail to User's locale
         */
        $this->locale = $this->user->locale; // <-- of course adapt this line to YOUR User model :]
    }
Run Code Online (Sandbox Code Playgroud)

很长的故事:

有一个特质Localizable。它声明一个方法withLocale,该方法调用指定语言环境中“封装”的给定函数。我所说的“封装”的意思是:记住当前的语言环境,设置新的语言环境,调用函数,恢复记住的语言环境。

可以在以下位置找到使用示例\Illuminate\Mail\Mailable::send

public function send(MailerContract $mailer)
{
    return $this->withLocale($this->locale, function () use ($mailer) {
        Container::getInstance()->call([$this, 'build']);

        return $mailer->send($this->buildView(), $this->buildViewData(), function ($message) {
            $this->buildFrom($message)
                 ->buildRecipients($message)
                 ->buildSubject($message)
                 ->runCallbacks($message)
                 ->buildAttachments($message);
        });
    });
}
Run Code Online (Sandbox Code Playgroud)

但是,此方法为我们提供了如何更改邮件区域设置的线索- 在第一行中有$this->locale. 事实上,Mailable该字段已定义:

class Mailable implements MailableContract, Renderable
{
   // ...

    /**
     * The locale of the message.
     *
     * @var string
     */
    public $locale;
Run Code Online (Sandbox Code Playgroud)


Alm*_*itt 6

对于任何使用 Laravel 6.* 并查看这篇文章的人来说,最近情况似乎发生了变化。

现在,您可以在控制器本身内定义区域设置,只需添加->locale()到 Mail.

例如:

Mail::to($request->user())->locale('es')->send(
    new OrderShipped($order)
);
Run Code Online (Sandbox Code Playgroud)

更多信息请查看官方文档

快乐编码!


Ada*_*dam 4

更新:从 Laravel 5.7 开始,您可以使用localize mailables

Mail::to($request->user())->locale('es')->send(
    new OrderShipped($order)
);
Run Code Online (Sandbox Code Playgroud)

Laravel 5.7 之前:

你建议的应该有效。只需在发送邮件之前更改区域设置即可。但是您应该确保重置区域设置:

$temp = \App::getLocale();
\App::setLocale($user->language);
\Mail::to($user)->send(new OrderShipped($order));
\App::setLocale($temp);
Run Code Online (Sandbox Code Playgroud)

由于这有点臃肿,您可以将其简化为

\App\Mail\SendMail::to($user, '\App\Mail\OrderShipped', [$order]);
Run Code Online (Sandbox Code Playgroud)

如果您创建以下SendMail类:

<?php

namespace App\Mail;

use App\User;

class SendMail
{

  /**
   * Send Mail to correct emailadress and set correct language
   * @param  User   $user
   * @param  String $classname
   * @param  Array  $data
   * @return void
   */
  public static function to(User $user, String $class, Array $params)
  {
    $temp = \App::getLocale();
    \App::setLocale($user->lang);

    $reflection_class = new \ReflectionClass($class);
    $mailclass = $reflection_class->newInstanceArgs($params);

    \Mail::to($user)->send($mailclass);

    \App::setLocale($temp);
  }
}
Run Code Online (Sandbox Code Playgroud)

也许知道您无需 . 也可以获得语言内容也很有用setLocale。例如,__('birthday_parole', [], 'pl')尽管设置了 ,但仍会尝试为您提供波兰语版本setLocale