php Laravel ->replyTo()in mailable not overwriting global 'reply_to' setting

cedebl8k  于 2023-05-27  发布在  PHP
关注(0)|答案(3)|浏览(262)

bounty还有2天到期。此问题的答案有资格获得+50声望奖励。Josh Mountain希望引起更多关注这个问题。

config/mail.php中,我们有:

'reply_to' => [
    'address' => env('MAIL_REPLY_TO_ADDRESS', 'default@company.com'),
    'name' => env('MAIL_REPLY_TO_NAME', 'Company')
],

邮件如下所示:

<?php

namespace App\Mail;

use App\User;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;

class SupportMessage extends Mailable implements ShouldQueue
{
    use Queueable, SerializesModels;

    public $user;

    public $senderEmail;

    public $message;

    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct(User $user, $email, $message)
    {
        $this->user = $user;
        $this->senderEmail = $email;
        $this->message = $message;
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        return $this->markdown('emails.support-message')
            ->subject('Support Message')
            ->replyTo(['email' => $this->senderEmail]);
    }
}

由于某种原因,Laravel没有替换电子邮件中默认的reply-to头,而是将$this->senderEmail连接到现有的default@company.com上,而电子邮件客户端似乎没有响应(回复时的空白电子邮件列表)。header看起来像这样:reply-to: Company <default@company.com>, sender_email@company.com
我还尝试了->replyTo($this->senderEmail),结果是相同的串联。
有没有一种方法可以取代全局reply-to而不是连接?

pcww981p

pcww981p1#

我会尝试在你的mailable类中覆盖函数setAddress(),或者如果我有多个电子邮件,然后创建一个扩展mailable的新类,并在相关的电子邮件中扩展这个新类。
就像这样:

protected function setAddress($address, $name = null, $property = 'to')
{
    if (empty($address)) {
        return $this;
    }

    foreach ($this->addressesToArray($address, $name) as $recipient) {
        $recipient = $this->normalizeRecipient($recipient);
        if($this->property === 'replyTo'){
           $this->{$property} = [[
              'name' => $recipient->name ?? null,
              'address' => $recipient->email,
           ]];
        }
        else{
           $this->{$property}[] = [
              'name' => $recipient->name ?? null,
              'address' => $recipient->email,
           ];
        }
    }

    $this->{$property} = collect($this->{$property})
        ->reverse()
        ->unique('address')
        ->reverse()
        ->values()
        ->all();

    return $this;
}
pgx2nnw8

pgx2nnw82#

尝试使用addTextHeader()方法添加新的Reply-To头。

$message = $this->markdown('emails.support-message')->subject('Support Message');

$message->getHeaders()->addTextHeader('Reply-To', $this->senderEmail);
        
return $message;
ccrfmcuu

ccrfmcuu3#

所以,简单地说:Mailable::send()调用Mailer::send()并传递一个闭包。将创建一个包含全局Reply-To地址的Message对象。然后闭包用Message对象运行,该对象被传递给Mailable::buildRecipients()Mailable::buildRecipients()调用Message::replyTo()Message::replyTo()将新地址连接到旧地址。
真实的的解决方案是覆盖Message::replyTo(),这样它就不会再连接这些值。我有done this kind of thing before,而且一路往回改变依赖链是一件痛苦的事。因此,一种简单的5分钟解决方案是像这样重写Mailable::buildRecipients()

<?php

namespace App\Mail;

use Illuminate\Mail\Mailable as MailableBase;

class Mailable extends MailableBase
{
    protected function buildRecipients($message): static
    {
        parent::buildRecipients($message);

        if (count($this->replyTo)) {
            // erase any existing Reply-To header
            $message->getSymfonyMessage()->getHeaders()->remove('ReplyTo');

            // re-apply just ours
            foreach ($this->replyTo as $recipient) {
                $message->replyTo($recipient['address'], $recipient['name']);
            }
        }

        return $this;
    }
}

它所做的就是运行内置的Mailable::buildRecipients(),然后在添加定义的值之前删除任何添加的Reply-To头。如果你还没有运行Mailable::replyTo(),那么它什么也不做。
只需将其保存在app\Mail\Mailable.php中并使App\Mail\SupportMessage扩展新类,而不是Laravel的内置mailable。

相关问题