MailChannel.php
TLDR
The MailChannel.php
file is a part of the Illuminate\Notifications\Channels namespace in the Demo Projects
project. It contains the MailChannel
class, which is responsible for sending email notifications. The class has a send()
method for sending the notifications using various mail transport methods. The class also has several protected helper methods for building and customizing the email message.
Methods
send
The send
method is responsible for sending the given notification. It takes the $notifiable
and $notification
as the arguments. It returns the SentMessage
object if the notification was sent successfully, otherwise, it returns null
.
messageBuilder
The messageBuilder
method returns a closure that takes a $mailMessage
argument. This closure is used to build the mail message by calling the buildMessage
method.
buildView
The buildView
method is responsible for building the notification's view. It takes the $message
argument and returns an array with HTML and text views for the message.
buildMarkdownHtml
The buildMarkdownHtml
method returns a closure that takes a $data
argument. This closure is used to render the HTML view for a Markdown message.
buildMarkdownText
The buildMarkdownText
method returns a closure that takes a $data
argument. This closure is used to render the text view for a Markdown message.
markdownRenderer
The markdownRenderer
method returns the Markdown implementation. It takes the $message
argument and uses the config repository to determine the theme for the Markdown renderer.
additionalMessageData
The additionalMessageData
method returns additional metadata to pass along with the view data. It takes the $notification
argument and returns an array with the notification ID, class, and queuing information.
buildMessage
The buildMessage
method is responsible for building the mail message. It takes the $mailMessage
, $notifiable
, $notification
, and $message
arguments. It sets the address, subject, attachments, priority, tags, metadata, and runs callbacks for the mail message.
addressMessage
The addressMessage
method is responsible for addressing the mail message. It takes the $mailMessage
, $notifiable
, $notification
, and $message
arguments. It sets the sender and recipients of the mail message.
addSender
The addSender
method adds the "from" and "reply to" addresses to the message. It takes the $mailMessage
and $message
arguments.
getRecipients
The getRecipients
method returns the recipients of the given message. It takes the $notifiable
, $notification
, and $message
arguments. It maps the recipients and their email addresses.
addAttachments
The addAttachments
method adds the attachments to the mail message. It takes the $mailMessage
and $message
arguments.
runCallbacks
The runCallbacks
method runs the callbacks for the mail message. It takes the $mailMessage
and $message
arguments and calls each callback on the Symfony message.
Classes
No classes in the file.
<?php
namespace Illuminate\Notifications\Channels;
use Illuminate\Config\Repository as ConfigRepository;
use Illuminate\Container\Container;
use Illuminate\Contracts\Mail\Factory as MailFactory;
use Illuminate\Contracts\Mail\Mailable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Markdown;
use Illuminate\Notifications\Notification;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Symfony\Component\Mailer\Header\MetadataHeader;
use Symfony\Component\Mailer\Header\TagHeader;
class MailChannel
{
/**
* The mailer implementation.
*
* @var \Illuminate\Contracts\Mail\Factory
*/
protected $mailer;
/**
* The markdown implementation.
*
* @var \Illuminate\Mail\Markdown
*/
protected $markdown;
/**
* Create a new mail channel instance.
*
* @param \Illuminate\Contracts\Mail\Factory $mailer
* @param \Illuminate\Mail\Markdown $markdown
* @return void
*/
public function __construct(MailFactory $mailer, Markdown $markdown)
{
$this->mailer = $mailer;
$this->markdown = $markdown;
}
/**
* Send the given notification.
*
* @param mixed $notifiable
* @param \Illuminate\Notifications\Notification $notification
* @return \Illuminate\Mail\SentMessage|null
*/
public function send($notifiable, Notification $notification)
{
$message = $notification->toMail($notifiable);
if (! $notifiable->routeNotificationFor('mail', $notification) &&
! $message instanceof Mailable) {
return;
}
if ($message instanceof Mailable) {
return $message->send($this->mailer);
}
return $this->mailer->mailer($message->mailer ?? null)->send(
$this->buildView($message),
array_merge($message->data(), $this->additionalMessageData($notification)),
$this->messageBuilder($notifiable, $notification, $message)
);
}
/**
* Get the mailer Closure for the message.
*
* @param mixed $notifiable
* @param \Illuminate\Notifications\Notification $notification
* @param \Illuminate\Notifications\Messages\MailMessage $message
* @return \Closure
*/
protected function messageBuilder($notifiable, $notification, $message)
{
return function ($mailMessage) use ($notifiable, $notification, $message) {
$this->buildMessage($mailMessage, $notifiable, $notification, $message);
};
}
/**
* Build the notification's view.
*
* @param \Illuminate\Notifications\Messages\MailMessage $message
* @return string|array
*/
protected function buildView($message)
{
if ($message->view) {
return $message->view;
}
return [
'html' => $this->buildMarkdownHtml($message),
'text' => $this->buildMarkdownText($message),
];
}
/**
* Build the HTML view for a Markdown message.
*
* @param \Illuminate\Notifications\Messages\MailMessage $message
* @return \Closure
*/
protected function buildMarkdownHtml($message)
{
return fn ($data) => $this->markdownRenderer($message)->render(
$message->markdown, array_merge($data, $message->data()),
);
}
/**
* Build the text view for a Markdown message.
*
* @param \Illuminate\Notifications\Messages\MailMessage $message
* @return \Closure
*/
protected function buildMarkdownText($message)
{
return fn ($data) => $this->markdownRenderer($message)->renderText(
$message->markdown, array_merge($data, $message->data()),
);
}
/**
* Get the Markdown implementation.
*
* @param \Illuminate\Notifications\Messages\MailMessage $message
* @return \Illuminate\Mail\Markdown
*/
protected function markdownRenderer($message)
{
$config = Container::getInstance()->get(ConfigRepository::class);
$theme = $message->theme ?? $config->get('mail.markdown.theme', 'default');
return $this->markdown->theme($theme);
}
/**
* Get additional meta-data to pass along with the view data.
*
* @param \Illuminate\Notifications\Notification $notification
* @return array
*/
protected function additionalMessageData($notification)
{
return [
'__laravel_notification_id' => $notification->id,
'__laravel_notification' => get_class($notification),
'__laravel_notification_queued' => in_array(
ShouldQueue::class,
class_implements($notification)
),
];
}
/**
* Build the mail message.
*
* @param \Illuminate\Mail\Message $mailMessage
* @param mixed $notifiable
* @param \Illuminate\Notifications\Notification $notification
* @param \Illuminate\Notifications\Messages\MailMessage $message
* @return void
*/
protected function buildMessage($mailMessage, $notifiable, $notification, $message)
{
$this->addressMessage($mailMessage, $notifiable, $notification, $message);
$mailMessage->subject($message->subject ?: Str::title(
Str::snake(class_basename($notification), ' ')
));
$this->addAttachments($mailMessage, $message);
if (! is_null($message->priority)) {
$mailMessage->priority($message->priority);
}
if ($message->tags) {
foreach ($message->tags as $tag) {
$mailMessage->getHeaders()->add(new TagHeader($tag));
}
}
if ($message->metadata) {
foreach ($message->metadata as $key => $value) {
$mailMessage->getHeaders()->add(new MetadataHeader($key, $value));
}
}
$this->runCallbacks($mailMessage, $message);
}
/**
* Address the mail message.
*
* @param \Illuminate\Mail\Message $mailMessage
* @param mixed $notifiable
* @param \Illuminate\Notifications\Notification $notification
* @param \Illuminate\Notifications\Messages\MailMessage $message
* @return void
*/
protected function addressMessage($mailMessage, $notifiable, $notification, $message)
{
$this->addSender($mailMessage, $message);
$mailMessage->to($this->getRecipients($notifiable, $notification, $message));
if (! empty($message->cc)) {
foreach ($message->cc as $cc) {
$mailMessage->cc($cc[0], Arr::get($cc, 1));
}
}
if (! empty($message->bcc)) {
foreach ($message->bcc as $bcc) {
$mailMessage->bcc($bcc[0], Arr::get($bcc, 1));
}
}
}
/**
* Add the "from" and "reply to" addresses to the message.
*
* @param \Illuminate\Mail\Message $mailMessage
* @param \Illuminate\Notifications\Messages\MailMessage $message
* @return void
*/
protected function addSender($mailMessage, $message)
{
if (! empty($message->from)) {
$mailMessage->from($message->from[0], Arr::get($message->from, 1));
}
if (! empty($message->replyTo)) {
foreach ($message->replyTo as $replyTo) {
$mailMessage->replyTo($replyTo[0], Arr::get($replyTo, 1));
}
}
}
/**
* Get the recipients of the given message.
*
* @param mixed $notifiable
* @param \Illuminate\Notifications\Notification $notification
* @param \Illuminate\Notifications\Messages\MailMessage $message
* @return mixed
*/
protected function getRecipients($notifiable, $notification, $message)
{
if (is_string($recipients = $notifiable->routeNotificationFor('mail', $notification))) {
$recipients = [$recipients];
}
return collect($recipients)->mapWithKeys(function ($recipient, $email) {
return is_numeric($email)
? [$email => (is_string($recipient) ? $recipient : $recipient->email)]
: [$email => $recipient];
})->all();
}
/**
* Add the attachments to the message.
*
* @param \Illuminate\Mail\Message $mailMessage
* @param \Illuminate\Notifications\Messages\MailMessage $message
* @return void
*/
protected function addAttachments($mailMessage, $message)
{
foreach ($message->attachments as $attachment) {
$mailMessage->attach($attachment['file'], $attachment['options']);
}
foreach ($message->rawAttachments as $attachment) {
$mailMessage->attachData($attachment['data'], $attachment['name'], $attachment['options']);
}
}
/**
* Run the callbacks for the message.
*
* @param \Illuminate\Mail\Message $mailMessage
* @param \Illuminate\Notifications\Messages\MailMessage $message
* @return $this
*/
protected function runCallbacks($mailMessage, $message)
{
foreach ($message->callbacks as $callback) {
$callback($mailMessage->getSymfonyMessage());
}
return $this;
}
}