59 lines
2.1 KiB
PHP
59 lines
2.1 KiB
PHP
<?php
|
|
|
|
namespace App\Mail\Concerns;
|
|
|
|
use App\Services\Mail\MailboxResolver;
|
|
use Illuminate\Mail\Mailables\Address;
|
|
use Illuminate\Mail\Mailables\Envelope;
|
|
|
|
/**
|
|
* From and Reply-To, taken from the mailbox behind a purpose.
|
|
*
|
|
* Reply-To is the whole reason sending alone is enough: a customer answering a
|
|
* support reply lands in the support mailbox, read in an ordinary mail client,
|
|
* so no IMAP is needed to close the loop.
|
|
*
|
|
* Except on a no-reply mailbox. A "no-reply" address you can reply to is a lie
|
|
* in the sender, and the one place the promise is made is the address itself.
|
|
*/
|
|
trait SendsFromMailbox
|
|
{
|
|
protected function mailboxEnvelope(string $purpose, string $subject): Envelope
|
|
{
|
|
[$from, $replyTo] = $this->mailboxAddresses($purpose);
|
|
|
|
return new Envelope(
|
|
from: $from,
|
|
replyTo: $replyTo ? [$replyTo] : [],
|
|
subject: $subject,
|
|
);
|
|
}
|
|
|
|
/**
|
|
* The From and Reply-To addresses for $purpose's mailbox — the ONE place
|
|
* that decides "no configured mailbox means no sender fields at all" and
|
|
* "no_reply means no Reply-To". Shared by every consumer of a purpose
|
|
* mailbox regardless of the shape it builds — an Envelope here (a
|
|
* Mailable), a MailMessage in CloudReady (a Notification, which cannot
|
|
* use mailboxEnvelope() directly since it is not building an Envelope).
|
|
* Two independent copies of this same decision is exactly the shape of
|
|
* gap Task 4 found and fixed in MailboxTransport::resolution().
|
|
*
|
|
* @return array{0: ?Address, 1: ?Address} [from, replyTo]
|
|
*/
|
|
protected function mailboxAddresses(string $purpose): array
|
|
{
|
|
$box = app(MailboxResolver::class)->for($purpose);
|
|
|
|
if ($box === null) {
|
|
// No mailbox configured yet — both null, so a caller falls back
|
|
// to its own framework default rather than dereferencing null.
|
|
return [null, null];
|
|
}
|
|
|
|
$from = new Address($box->address, $box->display_name ?: null);
|
|
|
|
return [$from, $box->no_reply ? null : $from];
|
|
}
|
|
}
|