From f1d160fcea68d3b5bdde7c47c16cf5447760a5ca Mon Sep 17 00:00:00 2001 From: Dries Vints Date: Fri, 20 Aug 2021 18:23:35 +0200 Subject: [PATCH 01/37] Implement Symfony Mailer --- composer.json | 2 +- src/Illuminate/Mail/Events/MessageSending.php | 10 +- src/Illuminate/Mail/Events/MessageSent.php | 14 +- src/Illuminate/Mail/MailManager.php | 85 ++++------ src/Illuminate/Mail/Mailable.php | 6 +- src/Illuminate/Mail/Mailer.php | 33 ++-- src/Illuminate/Mail/Message.php | 155 ++++++++---------- src/Illuminate/Mail/composer.json | 2 +- 8 files changed, 135 insertions(+), 172 deletions(-) diff --git a/composer.json b/composer.json index ca1e555fde81..8353b43b688e 100644 --- a/composer.json +++ b/composer.json @@ -29,12 +29,12 @@ "psr/container": "^1.1.1|^2.0.1", "psr/simple-cache": "^1.0", "ramsey/uuid": "^4.0", - "swiftmailer/swiftmailer": "^6.2.7", "symfony/console": "^6.0", "symfony/error-handler": "^6.0", "symfony/finder": "^6.0", "symfony/http-foundation": "^6.0", "symfony/http-kernel": "^6.0", + "symfony/mailer": "^6.0", "symfony/mime": "^6.0", "symfony/process": "^6.0", "symfony/routing": "^6.0", diff --git a/src/Illuminate/Mail/Events/MessageSending.php b/src/Illuminate/Mail/Events/MessageSending.php index bf5bccfdf2df..31435fb6e0e7 100644 --- a/src/Illuminate/Mail/Events/MessageSending.php +++ b/src/Illuminate/Mail/Events/MessageSending.php @@ -2,12 +2,14 @@ namespace Illuminate\Mail\Events; +use Symfony\Component\Mime\Email; + class MessageSending { /** - * The Swift message instance. + * The Symfony Email instance. * - * @var \Swift_Message + * @var \Symfony\Component\Mime\Email */ public $message; @@ -21,11 +23,11 @@ class MessageSending /** * Create a new event instance. * - * @param \Swift_Message $message + * @param \Symfony\Component\Mime\Email $message * @param array $data * @return void */ - public function __construct($message, $data = []) + public function __construct(Email $message, array $data = []) { $this->data = $data; $this->message = $message; diff --git a/src/Illuminate/Mail/Events/MessageSent.php b/src/Illuminate/Mail/Events/MessageSent.php index 64aef94312b6..a95148fcc285 100644 --- a/src/Illuminate/Mail/Events/MessageSent.php +++ b/src/Illuminate/Mail/Events/MessageSent.php @@ -2,14 +2,14 @@ namespace Illuminate\Mail\Events; -use Swift_Attachment; +use Symfony\Component\Mime\Email; class MessageSent { /** - * The Swift message instance. + * The Symfony Email instance. * - * @var \Swift_Message + * @var \Symfony\Component\Mime\Email */ public $message; @@ -23,11 +23,11 @@ class MessageSent /** * Create a new event instance. * - * @param \Swift_Message $message + * @param \Symfony\Component\Mime\Email $message * @param array $data * @return void */ - public function __construct($message, $data = []) + public function __construct(Email $message, array $data = []) { $this->data = $data; $this->message = $message; @@ -40,9 +40,7 @@ public function __construct($message, $data = []) */ public function __serialize() { - $hasAttachments = collect($this->message->getChildren()) - ->whereInstanceOf(Swift_Attachment::class) - ->isNotEmpty(); + $hasAttachments = collect($this->message->getAttachments())->isNotEmpty(); return $hasAttachments ? [ 'message' => base64_encode(serialize($this->message)), diff --git a/src/Illuminate/Mail/MailManager.php b/src/Illuminate/Mail/MailManager.php index aef832ccef23..be0a535718ac 100644 --- a/src/Illuminate/Mail/MailManager.php +++ b/src/Illuminate/Mail/MailManager.php @@ -17,11 +17,11 @@ use Postmark\ThrowExceptionOnFailurePlugin; use Postmark\Transport as PostmarkTransport; use Psr\Log\LoggerInterface; -use Swift_DependencyContainer; -use Swift_FailoverTransport as FailoverTransport; -use Swift_Mailer; -use Swift_SendmailTransport as SendmailTransport; -use Swift_SmtpTransport as SmtpTransport; +use Symfony\Component\Mailer\Mailer as SymfonyMailer; +use Symfony\Component\Mailer\Transport\FailoverTransport; +use Symfony\Component\Mailer\Transport\SendmailTransport; +use Symfony\Component\Mailer\Transport\Smtp\EsmtpTransport; +use Symfony\Component\Mailer\Transport\Smtp\Stream\SocketStream; /** * @mixin \Illuminate\Mail\Mailer @@ -117,7 +117,7 @@ protected function resolve($name) $mailer = new Mailer( $name, $this->app['view'], - $this->createSwiftMailer($config), + $this->createSymfonyMailer($config), $this->app['events'] ); @@ -136,27 +136,21 @@ protected function resolve($name) } /** - * Create the SwiftMailer instance for the given configuration. + * Create the Symfony Mailer instance for the given configuration. * * @param array $config - * @return \Swift_Mailer + * @return \Symfony\Component\Mailer\MailerInterface */ - protected function createSwiftMailer(array $config) + protected function createSymfonyMailer(array $config) { - if ($config['domain'] ?? false) { - Swift_DependencyContainer::getInstance() - ->register('mime.idgenerator.idright') - ->asValue($config['domain']); - } - - return new Swift_Mailer($this->createTransport($config)); + return new SymfonyMailer($this->createTransport($config)); } /** * Create a new transport instance. * * @param array $config - * @return \Swift_Transport + * @return \Symfony\Component\Mailer\Transport\TransportInterface * * @throws \InvalidArgumentException */ @@ -179,25 +173,22 @@ public function createTransport(array $config) } /** - * Create an instance of the SMTP Swift Transport driver. + * Create an instance of the Symfony SMTP Transport driver. * * @param array $config - * @return \Swift_SmtpTransport + * @return \Symfony\Component\Mailer\Transport\Smtp\EsmtpTransport */ protected function createSmtpTransport(array $config) { // The Swift SMTP transport instance will allow us to use any SMTP backend // for delivering mail such as Sendgrid, Amazon SES, or a custom server // a developer has available. We will just pass this configured host. - $transport = new SmtpTransport( + $transport = new EsmtpTransport( $config['host'], - $config['port'] + $config['port'], + ! empty($config['encryption']) && $config['encryption'] === 'tls' ? true : null ); - if (! empty($config['encryption'])) { - $transport->setEncryption($config['encryption']); - } - // Once we have the transport we will check for the presence of a username // and password. If we have it we will set the credentials on the Swift // transporter instance so that we'll properly authenticate delivery. @@ -213,40 +204,36 @@ protected function createSmtpTransport(array $config) /** * Configure the additional SMTP driver options. * - * @param \Swift_SmtpTransport $transport + * @param \Symfony\Component\Mailer\Transport\Smtp\EsmtpTransport $transport * @param array $config - * @return \Swift_SmtpTransport + * @return \Symfony\Component\Mailer\Transport\Smtp\EsmtpTransport */ - protected function configureSmtpTransport($transport, array $config) + protected function configureSmtpTransport(EsmtpTransport $transport, array $config) { - if (isset($config['stream'])) { - $transport->setStreamOptions($config['stream']); - } + $stream = $transport->getStream(); - if (isset($config['source_ip'])) { - $transport->setSourceIp($config['source_ip']); + if ($stream instanceof SocketStream) { + if (isset($config['source_ip'])) { + $stream->setSourceIp($config['source_ip']); + } + + if (isset($config['timeout'])) { + $stream->setTimeout($config['timeout']); + } } if (isset($config['local_domain'])) { $transport->setLocalDomain($config['local_domain']); } - if (isset($config['timeout'])) { - $transport->setTimeout($config['timeout']); - } - - if (isset($config['auth_mode'])) { - $transport->setAuthMode($config['auth_mode']); - } - return $transport; } /** - * Create an instance of the Sendmail Swift Transport driver. + * Create an instance of the Symfony Sendmail Transport driver. * * @param array $config - * @return \Swift_SendmailTransport + * @return \Symfony\Component\Mailer\Transport\SendmailTransport */ protected function createSendmailTransport(array $config) { @@ -293,9 +280,9 @@ protected function addSesCredentials(array $config) } /** - * Create an instance of the Mail Swift Transport driver. + * Create an instance of the Symfony Mail Transport driver. * - * @return \Swift_SendmailTransport + * @return \Symfony\Component\Mailer\Transport\SendmailTransport */ protected function createMailTransport() { @@ -343,10 +330,10 @@ protected function createPostmarkTransport(array $config) } /** - * Create an instance of the Failover Swift Transport driver. + * Create an instance of the Symfony Failover Transport driver. * * @param array $config - * @return \Swift_FailoverTransport + * @return \Symfony\Component\Mailer\Transport\FailoverTransport */ protected function createFailoverTransport(array $config) { @@ -371,7 +358,7 @@ protected function createFailoverTransport(array $config) } /** - * Create an instance of the Log Swift Transport driver. + * Create an instance of the Log Transport driver. * * @param array $config * @return \Illuminate\Mail\Transport\LogTransport @@ -390,7 +377,7 @@ protected function createLogTransport(array $config) } /** - * Create an instance of the Array Swift Transport Driver. + * Create an instance of the Array Transport Driver. * * @return \Illuminate\Mail\Transport\ArrayTransport */ diff --git a/src/Illuminate/Mail/Mailable.php b/src/Illuminate/Mail/Mailable.php index 30cf75030aec..c2ab41b2c1ed 100644 --- a/src/Illuminate/Mail/Mailable.php +++ b/src/Illuminate/Mail/Mailable.php @@ -450,7 +450,7 @@ protected function buildDiskAttachments($message) protected function runCallbacks($message) { foreach ($this->callbacks as $callback) { - $callback($message->getSwiftMessage()); + $callback($message->getSymfonyMessage()); } return $this; @@ -972,12 +972,12 @@ public function mailer($mailer) } /** - * Register a callback to be called with the Swift message instance. + * Register a callback to be called with the Symfony message instance. * * @param callable $callback * @return $this */ - public function withSwiftMessage($callback) + public function withSymfonyMessage($callback) { $this->callbacks[] = $callback; diff --git a/src/Illuminate/Mail/Mailer.php b/src/Illuminate/Mail/Mailer.php index 128f211f7651..012ae19c0c75 100755 --- a/src/Illuminate/Mail/Mailer.php +++ b/src/Illuminate/Mail/Mailer.php @@ -15,7 +15,8 @@ use Illuminate\Support\HtmlString; use Illuminate\Support\Traits\Macroable; use InvalidArgumentException; -use Swift_Mailer; +use Symfony\Component\Mailer\MailerInterface; +use Symfony\Component\Mime\Email; class Mailer implements MailerContract, MailQueueContract { @@ -36,11 +37,11 @@ class Mailer implements MailerContract, MailQueueContract protected $views; /** - * The Swift Mailer instance. + * The Symfony Mailer instance. * - * @var \Swift_Mailer + * @var \Symfony\Component\Mailer\MailerInterface */ - protected $swift; + protected $mailer; /** * The event dispatcher instance. @@ -96,15 +97,15 @@ class Mailer implements MailerContract, MailQueueContract * * @param string $name * @param \Illuminate\Contracts\View\Factory $views - * @param \Swift_Mailer $swift + * @param \Symfony\Component\Mailer\MailerInterface $mailer * @param \Illuminate\Contracts\Events\Dispatcher|null $events * @return void */ - public function __construct(string $name, Factory $views, Swift_Mailer $swift, Dispatcher $events = null) + public function __construct(string $name, Factory $views, MailerInterface $mailer, Dispatcher $events = null) { $this->name = $name; $this->views = $views; - $this->swift = $swift; + $this->mailer = $mailer; $this->events = $events; } @@ -484,7 +485,7 @@ public function laterOn($queue, $delay, $view) */ protected function createMessage() { - $message = new Message($this->swift->createMessage('message')); + $message = new Message(new Email()); // If a global from address has been specified we will set it on every message // instance so the developer does not have to repeat themselves every time @@ -581,13 +582,13 @@ public function failures() } /** - * Get the Swift Mailer instance. + * Get the Symfony Mailer instance. * - * @return \Swift_Mailer + * @return \Symfony\Component\Mailer\MailerInterface */ - public function getSwiftMailer() + public function getSymfonyMailer() { - return $this->swift; + return $this->mailer; } /** @@ -601,14 +602,14 @@ public function getViewFactory() } /** - * Set the Swift Mailer instance. + * Set the Symfony Mailer instance. * - * @param \Swift_Mailer $swift + * @param \Symfony\Component\Mailer\MailerInterface $mailer * @return void */ - public function setSwiftMailer($swift) + public function setSymfonyMailer($mailer) { - $this->swift = $swift; + $this->mailer = $mailer; } /** diff --git a/src/Illuminate/Mail/Message.php b/src/Illuminate/Mail/Message.php index cab6c026d9fe..955d3a5d5a2c 100755 --- a/src/Illuminate/Mail/Message.php +++ b/src/Illuminate/Mail/Message.php @@ -3,22 +3,22 @@ namespace Illuminate\Mail; use Illuminate\Support\Traits\ForwardsCalls; -use Swift_Attachment; -use Swift_Image; +use Symfony\Component\Mime\Address; +use Symfony\Component\Mime\Email; /** - * @mixin \Swift_Message + * @mixin \Symfony\Component\Mime\Email */ class Message { use ForwardsCalls; /** - * The Swift Message instance. + * The Symfony Email instance. * - * @var \Swift_Message + * @var \Symfony\Component\Mime\Email */ - protected $swift; + protected $email; /** * CIDs of files embedded in the message. @@ -30,12 +30,12 @@ class Message /** * Create a new message instance. * - * @param \Swift_Message $swift + * @param \Symfony\Component\Mime\Email $email * @return void */ - public function __construct($swift) + public function __construct(Email $email) { - $this->swift = $swift; + $this->email = $email; } /** @@ -47,7 +47,11 @@ public function __construct($swift) */ public function from($address, $name = null) { - $this->swift->setFrom($address, $name); + if (is_array($address)) { + $this->email->from(...$address); + } else { + $this->email->from(new Address($address, (string) $name)); + } return $this; } @@ -61,7 +65,11 @@ public function from($address, $name = null) */ public function sender($address, $name = null) { - $this->swift->setSender($address, $name); + if (is_array($address)) { + $this->email->sender(...$address); + } else { + $this->email->sender(new Address($address, (string) $name)); + } return $this; } @@ -74,7 +82,7 @@ public function sender($address, $name = null) */ public function returnPath($address) { - $this->swift->setReturnPath($address); + $this->email->returnPath($address); return $this; } @@ -90,7 +98,11 @@ public function returnPath($address) public function to($address, $name = null, $override = false) { if ($override) { - $this->swift->setTo($address, $name); + if (is_array($address)) { + $this->email->to(...$address); + } else { + $this->email->to(new Address($address, (string) $name)); + } return $this; } @@ -109,7 +121,11 @@ public function to($address, $name = null, $override = false) public function cc($address, $name = null, $override = false) { if ($override) { - $this->swift->setCc($address, $name); + if (is_array($address)) { + $this->email->cc(...$address); + } else { + $this->email->cc(new Address($address, (string) $name)); + } return $this; } @@ -128,7 +144,11 @@ public function cc($address, $name = null, $override = false) public function bcc($address, $name = null, $override = false) { if ($override) { - $this->swift->setBcc($address, $name); + if (is_array($address)) { + $this->email->bcc(...$address); + } else { + $this->email->bcc(new Address($address, (string) $name)); + } return $this; } @@ -159,9 +179,19 @@ public function replyTo($address, $name = null) protected function addAddresses($address, $name, $type) { if (is_array($address)) { - $this->swift->{"set{$type}"}($address, $name); + $type = lcfirst($type); + + $addresses = collect($address)->map(function (string|array $address) { + if (is_array($address)) { + return new Address($address['email'] ?? $address['address'], $address['name'] ?? null); + } + + return $address; + })->all(); + + $this->email->{"{$type}"}(...$addresses); } else { - $this->swift->{"add{$type}"}($address, $name); + $this->email->{"add{$type}"}(new Address($address, (string) $name)); } return $this; @@ -175,7 +205,7 @@ protected function addAddresses($address, $name, $type) */ public function subject($subject) { - $this->swift->setSubject($subject); + $this->email->subject($subject); return $this; } @@ -188,7 +218,7 @@ public function subject($subject) */ public function priority($level) { - $this->swift->setPriority($level); + $this->email->priority($level); return $this; } @@ -202,20 +232,9 @@ public function priority($level) */ public function attach($file, array $options = []) { - $attachment = $this->createAttachmentFromPath($file); - - return $this->prepAttachment($attachment, $options); - } + $this->email->attachFromPath($file, $options['as'] ?? null, $options['mime'] ?? null); - /** - * Create a Swift Attachment instance. - * - * @param string $file - * @return \Swift_Mime_Attachment - */ - protected function createAttachmentFromPath($file) - { - return Swift_Attachment::fromPath($file); + return $this; } /** @@ -228,42 +247,26 @@ protected function createAttachmentFromPath($file) */ public function attachData($data, $name, array $options = []) { - $attachment = $this->createAttachmentFromData($data, $name); + $this->email->attach($data, $name, $options['mime'] ?? null); - return $this->prepAttachment($attachment, $options); - } - - /** - * Create a Swift Attachment instance from data. - * - * @param string $data - * @param string $name - * @return \Swift_Attachment - */ - protected function createAttachmentFromData($data, $name) - { - return new Swift_Attachment($data, $name); + return $this; } /** - * Embed a file in the message and get the CID. + * Embed a file in the message. * * @param string $file - * @return string + * @return $this */ public function embed($file) { - if (isset($this->embeddedFiles[$file])) { - return $this->embeddedFiles[$file]; - } + $this->email->embedFromPath($file); - return $this->embeddedFiles[$file] = $this->swift->embed( - Swift_Image::fromPath($file) - ); + return $this; } /** - * Embed in-memory data in the message and get the CID. + * Embed in-memory data in the message. * * @param string $data * @param string $name @@ -272,51 +275,23 @@ public function embed($file) */ public function embedData($data, $name, $contentType = null) { - $image = new Swift_Image($data, $name, $contentType); - - return $this->swift->embed($image); - } - - /** - * Prepare and attach the given attachment. - * - * @param \Swift_Attachment $attachment - * @param array $options - * @return $this - */ - protected function prepAttachment($attachment, $options = []) - { - // First we will check for a MIME type on the message, which instructs the - // mail client on what type of attachment the file is so that it may be - // downloaded correctly by the user. The MIME option is not required. - if (isset($options['mime'])) { - $attachment->setContentType($options['mime']); - } - - // If an alternative name was given as an option, we will set that on this - // attachment so that it will be downloaded with the desired names from - // the developer, otherwise the default file names will get assigned. - if (isset($options['as'])) { - $attachment->setFilename($options['as']); - } - - $this->swift->attach($attachment); + $this->email->embed($data, $name, $contentType); return $this; } /** - * Get the underlying Swift Message instance. + * Get the underlying Symfony Email instance. * - * @return \Swift_Message + * @return \Symfony\Component\Mime\Email */ - public function getSwiftMessage() + public function getSymfonyMessage() { - return $this->swift; + return $this->email; } /** - * Dynamically pass missing methods to the Swift instance. + * Dynamically pass missing methods to the Symfony instance. * * @param string $method * @param array $parameters @@ -324,6 +299,6 @@ public function getSwiftMessage() */ public function __call($method, $parameters) { - return $this->forwardCallTo($this->swift, $method, $parameters); + return $this->forwardCallTo($this->email, $method, $parameters); } } diff --git a/src/Illuminate/Mail/composer.json b/src/Illuminate/Mail/composer.json index 53e88e315bd3..202d5b8499e9 100755 --- a/src/Illuminate/Mail/composer.json +++ b/src/Illuminate/Mail/composer.json @@ -23,7 +23,7 @@ "illuminate/support": "^9.0", "league/commonmark": "^2.0", "psr/log": "^1.0", - "swiftmailer/swiftmailer": "^6.2.7", + "symfony/mailer": "^6.0", "tijsverkoyen/css-to-inline-styles": "^2.2.2" }, "autoload": { From 9b70c701590d2da21a05370bede0e41b0e7977fc Mon Sep 17 00:00:00 2001 From: Taylor Otwell Date: Fri, 20 Aug 2021 16:24:35 +0000 Subject: [PATCH 02/37] Apply fixes from StyleCI --- src/Illuminate/Mail/Message.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Illuminate/Mail/Message.php b/src/Illuminate/Mail/Message.php index 955d3a5d5a2c..ee80fff225ab 100755 --- a/src/Illuminate/Mail/Message.php +++ b/src/Illuminate/Mail/Message.php @@ -181,7 +181,7 @@ protected function addAddresses($address, $name, $type) if (is_array($address)) { $type = lcfirst($type); - $addresses = collect($address)->map(function (string|array $address) { + $addresses = collect($address)->map(function (string | array $address) { if (is_array($address)) { return new Address($address['email'] ?? $address['address'], $address['name'] ?? null); } From f9f8ad3393bee9aef22ac8b10c283b82fc57ab4c Mon Sep 17 00:00:00 2001 From: Dries Vints Date: Sat, 21 Aug 2021 17:55:47 +0200 Subject: [PATCH 03/37] Update src/Illuminate/Mail/Message.php Co-authored-by: michael-rubel --- src/Illuminate/Mail/Message.php | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/Illuminate/Mail/Message.php b/src/Illuminate/Mail/Message.php index ee80fff225ab..0b3239f876bd 100755 --- a/src/Illuminate/Mail/Message.php +++ b/src/Illuminate/Mail/Message.php @@ -47,11 +47,9 @@ public function __construct(Email $email) */ public function from($address, $name = null) { - if (is_array($address)) { - $this->email->from(...$address); - } else { - $this->email->from(new Address($address, (string) $name)); - } + is_array($address) + ? $this->email->from(...$address) + : $this->email->from(new Address($address, (string) $name)); return $this; } From b821c6183a5c71f3e5ceecd3b42ff82ad9dca814 Mon Sep 17 00:00:00 2001 From: Dries Vints Date: Sat, 21 Aug 2021 17:55:53 +0200 Subject: [PATCH 04/37] Update src/Illuminate/Mail/Message.php Co-authored-by: michael-rubel --- src/Illuminate/Mail/Message.php | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/Illuminate/Mail/Message.php b/src/Illuminate/Mail/Message.php index 0b3239f876bd..dbf922d3893d 100755 --- a/src/Illuminate/Mail/Message.php +++ b/src/Illuminate/Mail/Message.php @@ -63,11 +63,9 @@ public function from($address, $name = null) */ public function sender($address, $name = null) { - if (is_array($address)) { - $this->email->sender(...$address); - } else { - $this->email->sender(new Address($address, (string) $name)); - } + is_array($address) + ? $this->email->sender(...$address) + : $this->email->sender(new Address($address, (string) $name)); return $this; } From d4801030cb3afd7c39d6808ff59d82cac16ec882 Mon Sep 17 00:00:00 2001 From: Dries Vints Date: Sat, 21 Aug 2021 17:55:58 +0200 Subject: [PATCH 05/37] Update src/Illuminate/Mail/Message.php Co-authored-by: michael-rubel --- src/Illuminate/Mail/Message.php | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/Illuminate/Mail/Message.php b/src/Illuminate/Mail/Message.php index dbf922d3893d..3799802a26ba 100755 --- a/src/Illuminate/Mail/Message.php +++ b/src/Illuminate/Mail/Message.php @@ -117,11 +117,9 @@ public function to($address, $name = null, $override = false) public function cc($address, $name = null, $override = false) { if ($override) { - if (is_array($address)) { - $this->email->cc(...$address); - } else { - $this->email->cc(new Address($address, (string) $name)); - } + is_array($address) + ? $this->email->cc(...$address) + : $this->email->cc(new Address($address, (string) $name)); return $this; } From 4abbc80026d6c1c2e047d5af70abcd777c4f69f6 Mon Sep 17 00:00:00 2001 From: Dries Vints Date: Sat, 21 Aug 2021 17:56:03 +0200 Subject: [PATCH 06/37] Update src/Illuminate/Mail/Message.php Co-authored-by: michael-rubel --- src/Illuminate/Mail/Message.php | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/Illuminate/Mail/Message.php b/src/Illuminate/Mail/Message.php index 3799802a26ba..230d1ca0ea1b 100755 --- a/src/Illuminate/Mail/Message.php +++ b/src/Illuminate/Mail/Message.php @@ -138,11 +138,9 @@ public function cc($address, $name = null, $override = false) public function bcc($address, $name = null, $override = false) { if ($override) { - if (is_array($address)) { - $this->email->bcc(...$address); - } else { - $this->email->bcc(new Address($address, (string) $name)); - } + is_array($address) + ? $this->email->bcc(...$address) + : $this->email->bcc(new Address($address, (string) $name)); return $this; } From e157c9308e72cb3e4bb27945541f4b078843b486 Mon Sep 17 00:00:00 2001 From: Dries Vints Date: Sat, 21 Aug 2021 17:56:10 +0200 Subject: [PATCH 07/37] Update src/Illuminate/Mail/Message.php Co-authored-by: michael-rubel --- src/Illuminate/Mail/Message.php | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/Illuminate/Mail/Message.php b/src/Illuminate/Mail/Message.php index 230d1ca0ea1b..53c742c26397 100755 --- a/src/Illuminate/Mail/Message.php +++ b/src/Illuminate/Mail/Message.php @@ -94,11 +94,9 @@ public function returnPath($address) public function to($address, $name = null, $override = false) { if ($override) { - if (is_array($address)) { - $this->email->to(...$address); - } else { - $this->email->to(new Address($address, (string) $name)); - } + is_array($address) + ? $this->email->to(...$address) + : $this->email->to(new Address($address, (string) $name)); return $this; } From eddfab4353ba0e4904a523e61494aca45fb904aa Mon Sep 17 00:00:00 2001 From: Dries Vints Date: Mon, 23 Aug 2021 15:27:23 +0200 Subject: [PATCH 08/37] Update Array and Log transports --- src/Illuminate/Mail/MailManager.php | 6 +- .../Mail/Transport/ArrayTransport.php | 23 +++- .../Mail/Transport/LogTransport.php | 41 +++---- src/Illuminate/Mail/Transport/Transport.php | 108 ------------------ 4 files changed, 35 insertions(+), 143 deletions(-) delete mode 100644 src/Illuminate/Mail/Transport/Transport.php diff --git a/src/Illuminate/Mail/MailManager.php b/src/Illuminate/Mail/MailManager.php index be0a535718ac..a35c6be0d2df 100644 --- a/src/Illuminate/Mail/MailManager.php +++ b/src/Illuminate/Mail/MailManager.php @@ -321,12 +321,10 @@ protected function createPostmarkTransport(array $config) 'X-PM-Message-Stream' => $config['message_stream_id'], ] : []; - return tap(new PostmarkTransport( + return new PostmarkTransport( $config['token'] ?? $this->app['config']->get('services.postmark.token'), $headers - ), function ($transport) { - $transport->registerPlugin(new ThrowExceptionOnFailurePlugin); - }); + ); } /** diff --git a/src/Illuminate/Mail/Transport/ArrayTransport.php b/src/Illuminate/Mail/Transport/ArrayTransport.php index fbedec9560aa..8b454843cc08 100644 --- a/src/Illuminate/Mail/Transport/ArrayTransport.php +++ b/src/Illuminate/Mail/Transport/ArrayTransport.php @@ -3,9 +3,12 @@ namespace Illuminate\Mail\Transport; use Illuminate\Support\Collection; -use Swift_Mime_SimpleMessage; +use Symfony\Component\Mailer\Envelope; +use Symfony\Component\Mailer\SentMessage; +use Symfony\Component\Mailer\Transport\TransportInterface; +use Symfony\Component\Mime\RawMessage; -class ArrayTransport extends Transport +class ArrayTransport extends TransportInterface { /** * The collection of Swift Messages. @@ -27,13 +30,11 @@ public function __construct() /** * {@inheritdoc} */ - public function send(Swift_Mime_SimpleMessage $message, &$failedRecipients = null) + public function send(RawMessage $message, Envelope $envelope = null): ?SentMessage { - $this->beforeSendPerformed($message); - $this->messages[] = $message; - return $this->numberOfRecipients($message); + return new SentMessage($message, $envelope); } /** @@ -55,4 +56,14 @@ public function flush() { return $this->messages = new Collection; } + + /** + * Get the string representation of the message. + * + * @return string + */ + public function __toString(): string + { + return 'array'; + } } diff --git a/src/Illuminate/Mail/Transport/LogTransport.php b/src/Illuminate/Mail/Transport/LogTransport.php index 43a2faa204ce..15f83e4dac42 100644 --- a/src/Illuminate/Mail/Transport/LogTransport.php +++ b/src/Illuminate/Mail/Transport/LogTransport.php @@ -3,10 +3,12 @@ namespace Illuminate\Mail\Transport; use Psr\Log\LoggerInterface; -use Swift_Mime_SimpleMessage; -use Swift_Mime_SimpleMimeEntity; +use Symfony\Component\Mailer\Envelope; +use Symfony\Component\Mailer\SentMessage; +use Symfony\Component\Mailer\Transport\TransportInterface; +use Symfony\Component\Mime\RawMessage; -class LogTransport extends Transport +class LogTransport extends TransportInterface { /** * The Logger instance. @@ -29,41 +31,30 @@ public function __construct(LoggerInterface $logger) /** * {@inheritdoc} */ - public function send(Swift_Mime_SimpleMessage $message, &$failedRecipients = null) + public function send(RawMessage $message, Envelope $envelope = null): ?SentMessage { - $this->beforeSendPerformed($message); + $this->logger->debug($message->toString()); - $this->logger->debug($this->getMimeEntityString($message)); - - $this->sendPerformed($message); - - return $this->numberOfRecipients($message); + return new SentMessage($message, $envelope); } /** - * Get a loggable string out of a Swiftmailer entity. + * Get the logger for the LogTransport instance. * - * @param \Swift_Mime_SimpleMimeEntity $entity - * @return string + * @return \Psr\Log\LoggerInterface */ - protected function getMimeEntityString(Swift_Mime_SimpleMimeEntity $entity) + public function logger() { - $string = (string) $entity->getHeaders().PHP_EOL.$entity->getBody(); - - foreach ($entity->getChildren() as $children) { - $string .= PHP_EOL.PHP_EOL.$this->getMimeEntityString($children); - } - - return $string; + return $this->logger; } /** - * Get the logger for the LogTransport instance. + * Get the string representation of the transport. * - * @return \Psr\Log\LoggerInterface + * @return string */ - public function logger() + public function __toString(): string { - return $this->logger; + return 'log'; } } diff --git a/src/Illuminate/Mail/Transport/Transport.php b/src/Illuminate/Mail/Transport/Transport.php deleted file mode 100644 index b26bff3ff57d..000000000000 --- a/src/Illuminate/Mail/Transport/Transport.php +++ /dev/null @@ -1,108 +0,0 @@ -plugins, $plugin); - } - - /** - * Iterate through registered plugins and execute plugins' methods. - * - * @param \Swift_Mime_SimpleMessage $message - * @return void - */ - protected function beforeSendPerformed(Swift_Mime_SimpleMessage $message) - { - $event = new Swift_Events_SendEvent($this, $message); - - foreach ($this->plugins as $plugin) { - if (method_exists($plugin, 'beforeSendPerformed')) { - $plugin->beforeSendPerformed($event); - } - } - } - - /** - * Iterate through registered plugins and execute plugins' methods. - * - * @param \Swift_Mime_SimpleMessage $message - * @return void - */ - protected function sendPerformed(Swift_Mime_SimpleMessage $message) - { - $event = new Swift_Events_SendEvent($this, $message); - - foreach ($this->plugins as $plugin) { - if (method_exists($plugin, 'sendPerformed')) { - $plugin->sendPerformed($event); - } - } - } - - /** - * Get the number of recipients. - * - * @param \Swift_Mime_SimpleMessage $message - * @return int - */ - protected function numberOfRecipients(Swift_Mime_SimpleMessage $message) - { - return count(array_merge( - (array) $message->getTo(), (array) $message->getCc(), (array) $message->getBcc() - )); - } -} From 1f68e4b9c7e6ab148916f0990b74ef874cc3e8d1 Mon Sep 17 00:00:00 2001 From: Taylor Otwell Date: Mon, 23 Aug 2021 13:28:35 +0000 Subject: [PATCH 09/37] Apply fixes from StyleCI --- src/Illuminate/Mail/MailManager.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Illuminate/Mail/MailManager.php b/src/Illuminate/Mail/MailManager.php index a35c6be0d2df..814ec7d2310e 100644 --- a/src/Illuminate/Mail/MailManager.php +++ b/src/Illuminate/Mail/MailManager.php @@ -14,7 +14,6 @@ use Illuminate\Support\Arr; use Illuminate\Support\Str; use InvalidArgumentException; -use Postmark\ThrowExceptionOnFailurePlugin; use Postmark\Transport as PostmarkTransport; use Psr\Log\LoggerInterface; use Symfony\Component\Mailer\Mailer as SymfonyMailer; From c74447793b54fa2a4dd0a4e24c4db11298eacf45 Mon Sep 17 00:00:00 2001 From: Dries Vints Date: Mon, 23 Aug 2021 16:44:08 +0200 Subject: [PATCH 10/37] Fix interface implementation --- src/Illuminate/Mail/Transport/ArrayTransport.php | 2 +- src/Illuminate/Mail/Transport/LogTransport.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Illuminate/Mail/Transport/ArrayTransport.php b/src/Illuminate/Mail/Transport/ArrayTransport.php index 8b454843cc08..955c06949d47 100644 --- a/src/Illuminate/Mail/Transport/ArrayTransport.php +++ b/src/Illuminate/Mail/Transport/ArrayTransport.php @@ -8,7 +8,7 @@ use Symfony\Component\Mailer\Transport\TransportInterface; use Symfony\Component\Mime\RawMessage; -class ArrayTransport extends TransportInterface +class ArrayTransport implements TransportInterface { /** * The collection of Swift Messages. diff --git a/src/Illuminate/Mail/Transport/LogTransport.php b/src/Illuminate/Mail/Transport/LogTransport.php index 15f83e4dac42..df6783b480df 100644 --- a/src/Illuminate/Mail/Transport/LogTransport.php +++ b/src/Illuminate/Mail/Transport/LogTransport.php @@ -8,7 +8,7 @@ use Symfony\Component\Mailer\Transport\TransportInterface; use Symfony\Component\Mime\RawMessage; -class LogTransport extends TransportInterface +class LogTransport implements TransportInterface { /** * The Logger instance. From aa88fa1dbaa4e8d2d8b32cd7370bca6dbc06ee83 Mon Sep 17 00:00:00 2001 From: Dries Vints Date: Mon, 23 Aug 2021 17:10:08 +0200 Subject: [PATCH 11/37] Update Mailer --- src/Illuminate/Contracts/Mail/Mailer.php | 7 --- src/Illuminate/Mail/MailManager.php | 13 +--- src/Illuminate/Mail/Mailer.php | 79 +++++++++--------------- src/Illuminate/Mail/Message.php | 48 +++++++------- 4 files changed, 53 insertions(+), 94 deletions(-) diff --git a/src/Illuminate/Contracts/Mail/Mailer.php b/src/Illuminate/Contracts/Mail/Mailer.php index 255b6789da82..38f9e3b56cc1 100644 --- a/src/Illuminate/Contracts/Mail/Mailer.php +++ b/src/Illuminate/Contracts/Mail/Mailer.php @@ -38,11 +38,4 @@ public function raw($text, $callback); * @return void */ public function send($view, array $data = [], $callback = null); - - /** - * Get the array of failed recipients. - * - * @return array - */ - public function failures(); } diff --git a/src/Illuminate/Mail/MailManager.php b/src/Illuminate/Mail/MailManager.php index 814ec7d2310e..a3aaa217a322 100644 --- a/src/Illuminate/Mail/MailManager.php +++ b/src/Illuminate/Mail/MailManager.php @@ -116,7 +116,7 @@ protected function resolve($name) $mailer = new Mailer( $name, $this->app['view'], - $this->createSymfonyMailer($config), + $this->createTransport($config), $this->app['events'] ); @@ -134,17 +134,6 @@ protected function resolve($name) return $mailer; } - /** - * Create the Symfony Mailer instance for the given configuration. - * - * @param array $config - * @return \Symfony\Component\Mailer\MailerInterface - */ - protected function createSymfonyMailer(array $config) - { - return new SymfonyMailer($this->createTransport($config)); - } - /** * Create a new transport instance. * diff --git a/src/Illuminate/Mail/Mailer.php b/src/Illuminate/Mail/Mailer.php index 012ae19c0c75..c2ddfa4571c7 100755 --- a/src/Illuminate/Mail/Mailer.php +++ b/src/Illuminate/Mail/Mailer.php @@ -15,7 +15,7 @@ use Illuminate\Support\HtmlString; use Illuminate\Support\Traits\Macroable; use InvalidArgumentException; -use Symfony\Component\Mailer\MailerInterface; +use Symfony\Component\Mailer\Transport\TransportInterface; use Symfony\Component\Mime\Email; class Mailer implements MailerContract, MailQueueContract @@ -37,11 +37,11 @@ class Mailer implements MailerContract, MailQueueContract protected $views; /** - * The Symfony Mailer instance. + * The Symfony Transport instance. * - * @var \Symfony\Component\Mailer\MailerInterface + * @var \Symfony\Component\Mailer\Transport\TransportInterface */ - protected $mailer; + protected $transport; /** * The event dispatcher instance. @@ -85,28 +85,21 @@ class Mailer implements MailerContract, MailQueueContract */ protected $queue; - /** - * Array of failed recipients. - * - * @var array - */ - protected $failedRecipients = []; - /** * Create a new Mailer instance. * * @param string $name * @param \Illuminate\Contracts\View\Factory $views - * @param \Symfony\Component\Mailer\MailerInterface $mailer + * @param \Symfony\Component\Mailer\Transport\TransportInterface $transport * @param \Illuminate\Contracts\Events\Dispatcher|null $events * @return void */ - public function __construct(string $name, Factory $views, MailerInterface $mailer, Dispatcher $events = null) + public function __construct(string $name, Factory $views, TransportInterface $transport, Dispatcher $events = null) { $this->name = $name; $this->views = $views; - $this->mailer = $mailer; $this->events = $events; + $this->transport = $transport; } /** @@ -283,10 +276,10 @@ public function send($view, array $data = [], $callback = null) // Next we will determine if the message should be sent. We give the developer // one final chance to stop this message and then we will send it to all of // its recipients. We will then fire the sent event for the sent message. - $swiftMessage = $message->getSwiftMessage(); + $symfonyMessage = $message->getSymfonyMessage(); - if ($this->shouldSendMessage($swiftMessage, $data)) { - $this->sendSwiftMessage($swiftMessage); + if ($this->shouldSendMessage($symfonyMessage, $data)) { + $this->sendSymfonyMessage($symfonyMessage); $this->dispatchSentEvent($message, $data); } @@ -353,19 +346,15 @@ protected function parseView($view) protected function addContent($message, $view, $plain, $raw, $data) { if (isset($view)) { - $message->setBody($this->renderView($view, $data) ?: ' ', 'text/html'); + $message->html($this->renderView($view, $data) ?: ' '); } if (isset($plain)) { - $method = isset($view) ? 'addPart' : 'setBody'; - - $message->$method($this->renderView($plain, $data) ?: ' ', 'text/plain'); + $message->text($this->renderView($plain, $data) ?: ' '); } if (isset($raw)) { - $method = (isset($view) || isset($plain)) ? 'addPart' : 'setBody'; - - $message->$method($raw, 'text/plain'); + $message->text($raw); } } @@ -509,26 +498,24 @@ protected function createMessage() } /** - * Send a Swift Message instance. + * Send a Symfony Email instance. * - * @param \Swift_Message $message + * @param \Symfony\Component\Mime\Email $message * @return int|null */ - protected function sendSwiftMessage($message) + protected function sendSymfonyMessage(Email $message) { - $this->failedRecipients = []; - try { - return $this->swift->send($message, $this->failedRecipients); + return $this->transport->send($message); } finally { $this->forceReconnection(); } } /** - * Determines if the message can be sent. + * Determines if the email can be sent. * - * @param \Swift_Message $message + * @param \Symfony\Component\Mime\Email $message * @param array $data * @return bool */ @@ -568,27 +555,17 @@ protected function dispatchSentEvent($message, $data = []) */ protected function forceReconnection() { - $this->getSwiftMailer()->getTransport()->stop(); - } - - /** - * Get the array of failed recipients. - * - * @return array - */ - public function failures() - { - return $this->failedRecipients; + $this->getSymfonyMailer()->getTransport()->stop(); } /** - * Get the Symfony Mailer instance. + * Get the Symfony Transport instance. * - * @return \Symfony\Component\Mailer\MailerInterface + * @return \Symfony\Component\Mailer\Transport\TransportInterface */ - public function getSymfonyMailer() + public function getSymfonyTransport() { - return $this->mailer; + return $this->transport; } /** @@ -602,14 +579,14 @@ public function getViewFactory() } /** - * Set the Symfony Mailer instance. + * Set the Symfony Transport instance. * - * @param \Symfony\Component\Mailer\MailerInterface $mailer + * @param \Symfony\Component\Mailer\Transport\TransportInterface $transport * @return void */ - public function setSymfonyMailer($mailer) + public function setSymfonyTransport($transport) { - $this->mailer = $mailer; + $this->transport = $transport; } /** diff --git a/src/Illuminate/Mail/Message.php b/src/Illuminate/Mail/Message.php index 53c742c26397..d0c1412c7be9 100755 --- a/src/Illuminate/Mail/Message.php +++ b/src/Illuminate/Mail/Message.php @@ -18,7 +18,7 @@ class Message * * @var \Symfony\Component\Mime\Email */ - protected $email; + protected $message; /** * CIDs of files embedded in the message. @@ -30,12 +30,12 @@ class Message /** * Create a new message instance. * - * @param \Symfony\Component\Mime\Email $email + * @param \Symfony\Component\Mime\Email $message * @return void */ - public function __construct(Email $email) + public function __construct(Email $message) { - $this->email = $email; + $this->message = $message; } /** @@ -48,8 +48,8 @@ public function __construct(Email $email) public function from($address, $name = null) { is_array($address) - ? $this->email->from(...$address) - : $this->email->from(new Address($address, (string) $name)); + ? $this->message->from(...$address) + : $this->message->from(new Address($address, (string) $name)); return $this; } @@ -64,8 +64,8 @@ public function from($address, $name = null) public function sender($address, $name = null) { is_array($address) - ? $this->email->sender(...$address) - : $this->email->sender(new Address($address, (string) $name)); + ? $this->message->sender(...$address) + : $this->message->sender(new Address($address, (string) $name)); return $this; } @@ -78,7 +78,7 @@ public function sender($address, $name = null) */ public function returnPath($address) { - $this->email->returnPath($address); + $this->message->returnPath($address); return $this; } @@ -95,8 +95,8 @@ public function to($address, $name = null, $override = false) { if ($override) { is_array($address) - ? $this->email->to(...$address) - : $this->email->to(new Address($address, (string) $name)); + ? $this->message->to(...$address) + : $this->message->to(new Address($address, (string) $name)); return $this; } @@ -116,8 +116,8 @@ public function cc($address, $name = null, $override = false) { if ($override) { is_array($address) - ? $this->email->cc(...$address) - : $this->email->cc(new Address($address, (string) $name)); + ? $this->message->cc(...$address) + : $this->message->cc(new Address($address, (string) $name)); return $this; } @@ -137,8 +137,8 @@ public function bcc($address, $name = null, $override = false) { if ($override) { is_array($address) - ? $this->email->bcc(...$address) - : $this->email->bcc(new Address($address, (string) $name)); + ? $this->message->bcc(...$address) + : $this->message->bcc(new Address($address, (string) $name)); return $this; } @@ -179,9 +179,9 @@ protected function addAddresses($address, $name, $type) return $address; })->all(); - $this->email->{"{$type}"}(...$addresses); + $this->message->{"{$type}"}(...$addresses); } else { - $this->email->{"add{$type}"}(new Address($address, (string) $name)); + $this->message->{"add{$type}"}(new Address($address, (string) $name)); } return $this; @@ -195,7 +195,7 @@ protected function addAddresses($address, $name, $type) */ public function subject($subject) { - $this->email->subject($subject); + $this->message->subject($subject); return $this; } @@ -208,7 +208,7 @@ public function subject($subject) */ public function priority($level) { - $this->email->priority($level); + $this->message->priority($level); return $this; } @@ -222,7 +222,7 @@ public function priority($level) */ public function attach($file, array $options = []) { - $this->email->attachFromPath($file, $options['as'] ?? null, $options['mime'] ?? null); + $this->message->attachFromPath($file, $options['as'] ?? null, $options['mime'] ?? null); return $this; } @@ -237,7 +237,7 @@ public function attach($file, array $options = []) */ public function attachData($data, $name, array $options = []) { - $this->email->attach($data, $name, $options['mime'] ?? null); + $this->message->attach($data, $name, $options['mime'] ?? null); return $this; } @@ -250,7 +250,7 @@ public function attachData($data, $name, array $options = []) */ public function embed($file) { - $this->email->embedFromPath($file); + $this->message->embedFromPath($file); return $this; } @@ -265,7 +265,7 @@ public function embed($file) */ public function embedData($data, $name, $contentType = null) { - $this->email->embed($data, $name, $contentType); + $this->message->embed($data, $name, $contentType); return $this; } @@ -277,7 +277,7 @@ public function embedData($data, $name, $contentType = null) */ public function getSymfonyMessage() { - return $this->email; + return $this->message; } /** From f6b10e118ed0f92ad49aa50c78f6f590d9d6d6d9 Mon Sep 17 00:00:00 2001 From: Taylor Otwell Date: Mon, 23 Aug 2021 15:10:29 +0000 Subject: [PATCH 12/37] Apply fixes from StyleCI --- src/Illuminate/Mail/MailManager.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Illuminate/Mail/MailManager.php b/src/Illuminate/Mail/MailManager.php index a3aaa217a322..584d9dd13f40 100644 --- a/src/Illuminate/Mail/MailManager.php +++ b/src/Illuminate/Mail/MailManager.php @@ -16,7 +16,6 @@ use InvalidArgumentException; use Postmark\Transport as PostmarkTransport; use Psr\Log\LoggerInterface; -use Symfony\Component\Mailer\Mailer as SymfonyMailer; use Symfony\Component\Mailer\Transport\FailoverTransport; use Symfony\Component\Mailer\Transport\SendmailTransport; use Symfony\Component\Mailer\Transport\Smtp\EsmtpTransport; From fa4441420c59a122d97771c028d2b2b8e12a7e56 Mon Sep 17 00:00:00 2001 From: Dries Vints Date: Mon, 23 Aug 2021 17:16:10 +0200 Subject: [PATCH 13/37] Rename --- src/Illuminate/Mail/MailManager.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Illuminate/Mail/MailManager.php b/src/Illuminate/Mail/MailManager.php index 584d9dd13f40..5820337f5d4a 100644 --- a/src/Illuminate/Mail/MailManager.php +++ b/src/Illuminate/Mail/MailManager.php @@ -115,7 +115,7 @@ protected function resolve($name) $mailer = new Mailer( $name, $this->app['view'], - $this->createTransport($config), + $this->createSymfonyTransport($config), $this->app['events'] ); @@ -141,7 +141,7 @@ protected function resolve($name) * * @throws \InvalidArgumentException */ - public function createTransport(array $config) + public function createSymfonyTransport(array $config) { // Here we will check if the "transport" key exists and if it doesn't we will // assume an application is still using the legacy mail configuration file @@ -335,8 +335,8 @@ protected function createFailoverTransport(array $config) // the transport configuration parameter in order to offer compatibility // with any Laravel <= 6.x application style mail configuration files. $transports[] = $this->app['config']['mail.driver'] - ? $this->createTransport(array_merge($config, ['transport' => $name])) - : $this->createTransport($config); + ? $this->createSymfonyTransport(array_merge($config, ['transport' => $name])) + : $this->createSymfonyTransport($config); } return new FailoverTransport($transports); From ecea2e6ba351ff40c834462bd6989f6cab00f17f Mon Sep 17 00:00:00 2001 From: Dries Vints Date: Mon, 23 Aug 2021 17:29:37 +0200 Subject: [PATCH 14/37] Remove method --- src/Illuminate/Mail/Mailer.php | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/Illuminate/Mail/Mailer.php b/src/Illuminate/Mail/Mailer.php index c2ddfa4571c7..72cd84a5529a 100755 --- a/src/Illuminate/Mail/Mailer.php +++ b/src/Illuminate/Mail/Mailer.php @@ -546,18 +546,6 @@ protected function dispatchSentEvent($message, $data = []) } } - /** - * Force the transport to re-connect. - * - * This will prevent errors in daemon queue situations. - * - * @return void - */ - protected function forceReconnection() - { - $this->getSymfonyMailer()->getTransport()->stop(); - } - /** * Get the Symfony Transport instance. * From 9ef4747a4995b2ad43022326b90046196cffe2d0 Mon Sep 17 00:00:00 2001 From: Dries Vints Date: Mon, 23 Aug 2021 18:28:47 +0200 Subject: [PATCH 15/37] Fix tests --- src/Illuminate/Mail/Message.php | 2 +- tests/Mail/MailFailoverTransportTest.php | 22 ++----- tests/Mail/MailLogTransportTest.php | 4 +- tests/Mail/MailMessageTest.php | 77 +++++++++--------------- tests/Mail/MailableQueuedTest.php | 4 +- 5 files changed, 40 insertions(+), 69 deletions(-) diff --git a/src/Illuminate/Mail/Message.php b/src/Illuminate/Mail/Message.php index d0c1412c7be9..706519ec7789 100755 --- a/src/Illuminate/Mail/Message.php +++ b/src/Illuminate/Mail/Message.php @@ -289,6 +289,6 @@ public function getSymfonyMessage() */ public function __call($method, $parameters) { - return $this->forwardCallTo($this->email, $method, $parameters); + return $this->forwardCallTo($this->message, $method, $parameters); } } diff --git a/tests/Mail/MailFailoverTransportTest.php b/tests/Mail/MailFailoverTransportTest.php index 6d8c8fec8bd9..96d5453143a2 100644 --- a/tests/Mail/MailFailoverTransportTest.php +++ b/tests/Mail/MailFailoverTransportTest.php @@ -4,6 +4,8 @@ use Illuminate\Mail\Transport\ArrayTransport; use Orchestra\Testbench\TestCase; +use Symfony\Component\Mailer\Transport\FailoverTransport; +use Symfony\Component\Mailer\Transport\SendmailTransport; class MailFailoverTransportTest extends TestCase { @@ -30,14 +32,8 @@ public function testGetFailoverTransportWithConfiguredTransports() ], ]); - $transport = app('mailer')->getSwiftMailer()->getTransport(); - $this->assertInstanceOf(\Swift_FailoverTransport::class, $transport); - - $transports = $transport->getTransports(); - $this->assertCount(2, $transports); - $this->assertInstanceOf(\Swift_SendmailTransport::class, $transports[0]); - $this->assertEquals('/usr/sbin/sendmail -bs', $transports[0]->getCommand()); - $this->assertInstanceOf(ArrayTransport::class, $transports[1]); + $transport = app('mailer')->getSymfonyTransport(); + $this->assertInstanceOf(FailoverTransport::class, $transport); } public function testGetFailoverTransportWithLaravel6StyleMailConfiguration() @@ -51,13 +47,7 @@ public function testGetFailoverTransportWithLaravel6StyleMailConfiguration() $this->app['config']->set('mail.sendmail', '/usr/sbin/sendmail -bs'); - $transport = app('mailer')->getSwiftMailer()->getTransport(); - $this->assertInstanceOf(\Swift_FailoverTransport::class, $transport); - - $transports = $transport->getTransports(); - $this->assertCount(2, $transports); - $this->assertInstanceOf(\Swift_SendmailTransport::class, $transports[0]); - $this->assertEquals('/usr/sbin/sendmail -bs', $transports[0]->getCommand()); - $this->assertInstanceOf(ArrayTransport::class, $transports[1]); + $transport = app('mailer')->getSymfonyTransport(); + $this->assertInstanceOf(FailoverTransport::class, $transport); } } diff --git a/tests/Mail/MailLogTransportTest.php b/tests/Mail/MailLogTransportTest.php index 5848734d2eec..ff6bab6c74ca 100644 --- a/tests/Mail/MailLogTransportTest.php +++ b/tests/Mail/MailLogTransportTest.php @@ -22,7 +22,7 @@ public function testGetLogTransportWithConfiguredChannel() 'path' => 'mail.log', ]); - $transport = app('mailer')->getSwiftMailer()->getTransport(); + $transport = app('mailer')->getSymfonyTransport(); $this->assertInstanceOf(LogTransport::class, $transport); $logger = $transport->logger(); @@ -38,7 +38,7 @@ public function testGetLogTransportWithPsrLogger() $this->app['config']->set('mail.driver', 'log'); $logger = $this->app->instance('log', new NullLogger); - $transportLogger = app('mailer')->getSwiftMailer()->getTransport()->logger(); + $transportLogger = app('mailer')->getSymfonyTransport()->logger(); $this->assertEquals($logger, $transportLogger); } diff --git a/tests/Mail/MailMessageTest.php b/tests/Mail/MailMessageTest.php index fa752a960c16..14ec855d2cc4 100755 --- a/tests/Mail/MailMessageTest.php +++ b/tests/Mail/MailMessageTest.php @@ -6,15 +6,11 @@ use Mockery as m; use PHPUnit\Framework\TestCase; use stdClass; -use Swift_Mime_Message; +use Symfony\Component\Mime\Address; +use Symfony\Component\Mime\Email; class MailMessageTest extends TestCase { - /** - * @var \Mockery::mock - */ - protected $swift; - /** * @var \Illuminate\Mail\Message */ @@ -24,8 +20,7 @@ protected function setUp(): void { parent::setUp(); - $this->swift = m::mock(Swift_Mime_Message::class); - $this->message = new Message($this->swift); + $this->message = new Message(new Email()); } protected function tearDown(): void @@ -35,89 +30,75 @@ protected function tearDown(): void public function testFromMethod() { - $this->swift->shouldReceive('setFrom')->once()->with('foo@bar.baz', 'Foo'); - $this->assertInstanceOf(Message::class, $this->message->from('foo@bar.baz', 'Foo')); + $this->assertInstanceOf(Message::class, $message = $this->message->from('foo@bar.baz', 'Foo')); + $this->assertEquals(new Address('foo@bar.baz', 'Foo'), $message->getSymfonyMessage()->getFrom()[0]); } public function testSenderMethod() { - $this->swift->shouldReceive('setSender')->once()->with('foo@bar.baz', 'Foo'); - $this->assertInstanceOf(Message::class, $this->message->sender('foo@bar.baz', 'Foo')); + $this->assertInstanceOf(Message::class, $message = $this->message->sender('foo@bar.baz', 'Foo')); + $this->assertEquals(new Address('foo@bar.baz', 'Foo'), $message->getSymfonyMessage()->getSender()); } public function testReturnPathMethod() { - $this->swift->shouldReceive('setReturnPath')->once()->with('foo@bar.baz'); - $this->assertInstanceOf(Message::class, $this->message->returnPath('foo@bar.baz')); + $this->assertInstanceOf(Message::class, $message = $this->message->returnPath('foo@bar.baz')); + $this->assertEquals(new Address('foo@bar.baz'), $message->getSymfonyMessage()->getReturnPath()); } public function testToMethod() { - $this->swift->shouldReceive('addTo')->once()->with('foo@bar.baz', 'Foo'); - $this->assertInstanceOf(Message::class, $this->message->to('foo@bar.baz', 'Foo', false)); + $this->assertInstanceOf(Message::class, $message = $this->message->to('foo@bar.baz', 'Foo', false)); + $this->assertEquals(new Address('foo@bar.baz', 'Foo'), $message->getSymfonyMessage()->getTo()[0]); } public function testToMethodWithOverride() { - $this->swift->shouldReceive('setTo')->once()->with('foo@bar.baz', 'Foo'); - $this->assertInstanceOf(Message::class, $this->message->to('foo@bar.baz', 'Foo', true)); + $this->assertInstanceOf(Message::class, $message = $this->message->to('foo@bar.baz', 'Foo', true)); + $this->assertEquals(new Address('foo@bar.baz', 'Foo'), $message->getSymfonyMessage()->getTo()[0]); } public function testCcMethod() { - $this->swift->shouldReceive('addCc')->once()->with('foo@bar.baz', 'Foo'); - $this->assertInstanceOf(Message::class, $this->message->cc('foo@bar.baz', 'Foo')); + $this->assertInstanceOf(Message::class, $message = $this->message->cc('foo@bar.baz', 'Foo')); + $this->assertEquals(new Address('foo@bar.baz', 'Foo'), $message->getSymfonyMessage()->getCc()[0]); } public function testBccMethod() { - $this->swift->shouldReceive('addBcc')->once()->with('foo@bar.baz', 'Foo'); - $this->assertInstanceOf(Message::class, $this->message->bcc('foo@bar.baz', 'Foo')); + $this->assertInstanceOf(Message::class, $message = $this->message->bcc('foo@bar.baz', 'Foo')); + $this->assertEquals(new Address('foo@bar.baz', 'Foo'), $message->getSymfonyMessage()->getBcc()[0]); } public function testReplyToMethod() { - $this->swift->shouldReceive('addReplyTo')->once()->with('foo@bar.baz', 'Foo'); - $this->assertInstanceOf(Message::class, $this->message->replyTo('foo@bar.baz', 'Foo')); + $this->assertInstanceOf(Message::class, $message = $this->message->replyTo('foo@bar.baz', 'Foo')); + $this->assertEquals(new Address('foo@bar.baz', 'Foo'), $message->getSymfonyMessage()->getReplyTo()[0]); } public function testSubjectMethod() { - $this->swift->shouldReceive('setSubject')->once()->with('foo'); - $this->assertInstanceOf(Message::class, $this->message->subject('foo')); + $this->assertInstanceOf(Message::class, $message = $this->message->subject('foo')); + $this->assertEquals('foo', $message->getSymfonyMessage()->getSubject()); } public function testPriorityMethod() { - $this->swift->shouldReceive('setPriority')->once()->with(1); - $this->assertInstanceOf(Message::class, $this->message->priority(1)); - } - - public function testGetSwiftMessageMethod() - { - $this->assertInstanceOf(Swift_Mime_Message::class, $this->message->getSwiftMessage()); + $this->assertInstanceOf(Message::class, $message = $this->message->priority(1)); + $this->assertEquals(1, $message->getSymfonyMessage()->getPriority()); } public function testBasicAttachment() { - $swift = m::mock(stdClass::class); - $message = $this->getMockBuilder(Message::class)->onlyMethods(['createAttachmentFromPath'])->setConstructorArgs([$swift])->getMock(); - $attachment = m::mock(stdClass::class); - $message->expects($this->once())->method('createAttachmentFromPath')->with($this->equalTo('foo.jpg'))->willReturn($attachment); - $swift->shouldReceive('attach')->once()->with($attachment); - $attachment->shouldReceive('setContentType')->once()->with('image/jpeg'); - $attachment->shouldReceive('setFilename')->once()->with('bar.jpg'); - $message->attach('foo.jpg', ['mime' => 'image/jpeg', 'as' => 'bar.jpg']); + $message = new Message(new Email()); + $message->attach('foo.jpg', ['as' => 'foo.jpg', 'mime' => 'image/jpeg']); } public function testDataAttachment() { - $swift = m::mock(stdClass::class); - $message = $this->getMockBuilder(Message::class)->onlyMethods(['createAttachmentFromData'])->setConstructorArgs([$swift])->getMock(); - $attachment = m::mock(stdClass::class); - $message->expects($this->once())->method('createAttachmentFromData')->with($this->equalTo('foo'), $this->equalTo('name'))->willReturn($attachment); - $swift->shouldReceive('attach')->once()->with($attachment); - $attachment->shouldReceive('setContentType')->once()->with('image/jpeg'); - $message->attachData('foo', 'name', ['mime' => 'image/jpeg']); + $message = new Message(new Email()); + $message->attachData('foo', 'foo.jpg', ['mime' => 'image/jpeg']); + + $this->assertEquals('foo', $message->getSymfonyMessage()->getAttachments()[0]->getBody()); } } diff --git a/tests/Mail/MailableQueuedTest.php b/tests/Mail/MailableQueuedTest.php index 47b93429e62e..274dea386754 100644 --- a/tests/Mail/MailableQueuedTest.php +++ b/tests/Mail/MailableQueuedTest.php @@ -15,7 +15,7 @@ use Illuminate\Support\Testing\Fakes\QueueFake; use Mockery as m; use PHPUnit\Framework\TestCase; -use Swift_Mailer; +use Symfony\Component\Mailer\Transport\TransportInterface; class MailableQueuedTest extends TestCase { @@ -91,7 +91,7 @@ public function testQueuedMailableWithAttachmentFromDiskSent() protected function getMocks() { - return ['smtp', m::mock(Factory::class), m::mock(Swift_Mailer::class)]; + return ['smtp', m::mock(Factory::class), m::mock(TransportInterface::class)]; } } From 0d8450e6155d7f0d091e5938fa877e58306f1abd Mon Sep 17 00:00:00 2001 From: Taylor Otwell Date: Mon, 23 Aug 2021 16:29:19 +0000 Subject: [PATCH 16/37] Apply fixes from StyleCI --- tests/Mail/MailFailoverTransportTest.php | 2 -- tests/Mail/MailMessageTest.php | 1 - 2 files changed, 3 deletions(-) diff --git a/tests/Mail/MailFailoverTransportTest.php b/tests/Mail/MailFailoverTransportTest.php index 96d5453143a2..15f9c0ed02a9 100644 --- a/tests/Mail/MailFailoverTransportTest.php +++ b/tests/Mail/MailFailoverTransportTest.php @@ -2,10 +2,8 @@ namespace Illuminate\Tests\Mail; -use Illuminate\Mail\Transport\ArrayTransport; use Orchestra\Testbench\TestCase; use Symfony\Component\Mailer\Transport\FailoverTransport; -use Symfony\Component\Mailer\Transport\SendmailTransport; class MailFailoverTransportTest extends TestCase { diff --git a/tests/Mail/MailMessageTest.php b/tests/Mail/MailMessageTest.php index 14ec855d2cc4..8e98bc3a8fcf 100755 --- a/tests/Mail/MailMessageTest.php +++ b/tests/Mail/MailMessageTest.php @@ -5,7 +5,6 @@ use Illuminate\Mail\Message; use Mockery as m; use PHPUnit\Framework\TestCase; -use stdClass; use Symfony\Component\Mime\Address; use Symfony\Component\Mime\Email; From 66ad5fa3884c57cd011b6f4b5c3dc81e736de5a4 Mon Sep 17 00:00:00 2001 From: Dries Vints Date: Tue, 24 Aug 2021 16:33:32 +0200 Subject: [PATCH 17/37] Work on Mailer tests --- src/Illuminate/Mail/Mailable.php | 4 +- src/Illuminate/Mail/Mailer.php | 29 ++-- .../Mail/Transport/ArrayTransport.php | 2 +- .../Mail/Transport/LogTransport.php | 2 +- tests/Mail/MailMailerTest.php | 140 ++++++------------ tests/Mail/MailMessageTest.php | 6 - 6 files changed, 64 insertions(+), 119 deletions(-) diff --git a/src/Illuminate/Mail/Mailable.php b/src/Illuminate/Mail/Mailable.php index c2ab41b2c1ed..ccd52802f4c6 100644 --- a/src/Illuminate/Mail/Mailable.php +++ b/src/Illuminate/Mail/Mailable.php @@ -167,11 +167,11 @@ class Mailable implements MailableContract, Renderable * Send the message using the given mailer. * * @param \Illuminate\Contracts\Mail\Factory|\Illuminate\Contracts\Mail\Mailer $mailer - * @return void + * @return \Symfony\Component\Mailer\SentMessage|null */ public function send($mailer) { - $this->withLocale($this->locale, function () use ($mailer) { + return $this->withLocale($this->locale, function () use ($mailer) { Container::getInstance()->call([$this, 'build']); $mailer = $mailer instanceof MailFactory diff --git a/src/Illuminate/Mail/Mailer.php b/src/Illuminate/Mail/Mailer.php index 72cd84a5529a..424ff0b885f9 100755 --- a/src/Illuminate/Mail/Mailer.php +++ b/src/Illuminate/Mail/Mailer.php @@ -15,6 +15,7 @@ use Illuminate\Support\HtmlString; use Illuminate\Support\Traits\Macroable; use InvalidArgumentException; +use Symfony\Component\Mailer\Envelope; use Symfony\Component\Mailer\Transport\TransportInterface; use Symfony\Component\Mime\Email; @@ -187,11 +188,11 @@ public function bcc($users) * * @param string $html * @param mixed $callback - * @return void + * @return \Symfony\Component\Mailer\SentMessage|null */ public function html($html, $callback) { - $this->send(['html' => new HtmlString($html)], [], $callback); + return $this->send(['html' => new HtmlString($html)], [], $callback); } /** @@ -199,11 +200,11 @@ public function html($html, $callback) * * @param string $text * @param mixed $callback - * @return void + * @return \Symfony\Component\Mailer\SentMessage|null */ public function raw($text, $callback) { - $this->send(['raw' => $text], [], $callback); + return $this->send(['raw' => $text], [], $callback); } /** @@ -212,11 +213,11 @@ public function raw($text, $callback) * @param string $view * @param array $data * @param mixed $callback - * @return void + * @return \Symfony\Component\Mailer\SentMessage|null */ public function plain($view, array $data, $callback) { - $this->send(['text' => $view], $data, $callback); + return $this->send(['text' => $view], $data, $callback); } /** @@ -244,7 +245,7 @@ public function render($view, array $data = []) * @param \Illuminate\Contracts\Mail\Mailable|string|array $view * @param array $data * @param \Closure|string|null $callback - * @return void + * @return \Symfony\Component\Mailer\SentMessage|null */ public function send($view, array $data = [], $callback = null) { @@ -262,7 +263,9 @@ public function send($view, array $data = [], $callback = null) // Once we have retrieved the view content for the e-mail we will set the body // of this message using the HTML type, which will provide a simple wrapper // to creating view based emails that are able to receive arrays of data. - $callback($message); + if (! is_null($callback)) { + $callback($message); + } $this->addContent($message, $view, $plain, $raw, $data); @@ -279,9 +282,11 @@ public function send($view, array $data = [], $callback = null) $symfonyMessage = $message->getSymfonyMessage(); if ($this->shouldSendMessage($symfonyMessage, $data)) { - $this->sendSymfonyMessage($symfonyMessage); + $sentMessage = $this->sendSymfonyMessage($symfonyMessage); $this->dispatchSentEvent($message, $data); + + return $sentMessage; } } @@ -501,14 +506,14 @@ protected function createMessage() * Send a Symfony Email instance. * * @param \Symfony\Component\Mime\Email $message - * @return int|null + * @return \Symfony\Component\Mailer\SentMessage|null */ protected function sendSymfonyMessage(Email $message) { try { - return $this->transport->send($message); + return $this->transport->send($message, Envelope::create($message)); } finally { - $this->forceReconnection(); + // } } diff --git a/src/Illuminate/Mail/Transport/ArrayTransport.php b/src/Illuminate/Mail/Transport/ArrayTransport.php index 955c06949d47..072cd4230578 100644 --- a/src/Illuminate/Mail/Transport/ArrayTransport.php +++ b/src/Illuminate/Mail/Transport/ArrayTransport.php @@ -34,7 +34,7 @@ public function send(RawMessage $message, Envelope $envelope = null): ?SentMessa { $this->messages[] = $message; - return new SentMessage($message, $envelope); + return new SentMessage($message, $envelope ?? Envelope::create($message)); } /** diff --git a/src/Illuminate/Mail/Transport/LogTransport.php b/src/Illuminate/Mail/Transport/LogTransport.php index df6783b480df..d9ec8ac09d7e 100644 --- a/src/Illuminate/Mail/Transport/LogTransport.php +++ b/src/Illuminate/Mail/Transport/LogTransport.php @@ -35,7 +35,7 @@ public function send(RawMessage $message, Envelope $envelope = null): ?SentMessa { $this->logger->debug($message->toString()); - return new SentMessage($message, $envelope); + return new SentMessage($message, $envelope ?? Envelope::create($message)); } /** diff --git a/tests/Mail/MailMailerTest.php b/tests/Mail/MailMailerTest.php index b14b9ba285cd..e796818fca9b 100755 --- a/tests/Mail/MailMailerTest.php +++ b/tests/Mail/MailMailerTest.php @@ -7,81 +7,73 @@ use Illuminate\Mail\Events\MessageSending; use Illuminate\Mail\Events\MessageSent; use Illuminate\Mail\Mailer; +use Illuminate\Mail\Message; +use Illuminate\Mail\Transport\ArrayTransport; use Illuminate\Support\HtmlString; use Mockery as m; use PHPUnit\Framework\TestCase; use stdClass; -use Swift_Mailer; use Swift_Message; use Swift_Mime_SimpleMessage; use Swift_Transport; +use Symfony\Component\Mailer\Transport\TransportInterface; +use Symfony\Component\Mime\Email; class MailMailerTest extends TestCase { protected function tearDown(): void { + unset($_SERVER['__mailer.test']); + m::close(); } public function testMailerSendSendsMessageWithProperViewContent() { - unset($_SERVER['__mailer.test']); - $mailer = $this->getMockBuilder(Mailer::class)->onlyMethods(['createMessage'])->setConstructorArgs($this->getMocks())->getMock(); - $message = m::mock(Swift_Mime_SimpleMessage::class); - $mailer->expects($this->once())->method('createMessage')->willReturn($message); - $view = m::mock(stdClass::class); - $mailer->getViewFactory()->shouldReceive('make')->once()->with('foo', ['data', 'message' => $message])->andReturn($view); + $view = m::mock(Factory::class); + $view->shouldReceive('make')->once()->andReturn($view); $view->shouldReceive('render')->once()->andReturn('rendered.view'); - $message->shouldReceive('setBody')->once()->with('rendered.view', 'text/html'); - $message->shouldReceive('setFrom')->never(); - $this->setSwiftMailer($mailer); - $message->shouldReceive('getSwiftMessage')->once()->andReturn($message); - $mailer->getSwiftMailer()->shouldReceive('send')->once()->with($message, []); - $mailer->send('foo', ['data'], function ($m) { - $_SERVER['__mailer.test'] = $m; + + $mailer = new Mailer('array', $view, new ArrayTransport); + + $sentMessage = $mailer->send('foo', ['data'], function (Message $message) { + $message->to('taylor@laravel.com')->from('hello@laravel.com'); }); - unset($_SERVER['__mailer.test']); + + $this->assertStringContainsString('rendered.view', $sentMessage->toString()); } public function testMailerSendSendsMessageWithProperViewContentUsingHtmlStrings() { - unset($_SERVER['__mailer.test']); - $mailer = $this->getMockBuilder(Mailer::class)->onlyMethods(['createMessage'])->setConstructorArgs($this->getMocks())->getMock(); - $message = m::mock(Swift_Mime_SimpleMessage::class); - $mailer->expects($this->once())->method('createMessage')->willReturn($message); - $view = m::mock(stdClass::class); - $mailer->getViewFactory()->shouldReceive('make')->never(); + $view = m::mock(Factory::class); $view->shouldReceive('render')->never(); - $message->shouldReceive('setBody')->once()->with('rendered.view', 'text/html'); - $message->shouldReceive('addPart')->once()->with('rendered.text', 'text/plain'); - $message->shouldReceive('setFrom')->never(); - $this->setSwiftMailer($mailer); - $message->shouldReceive('getSwiftMessage')->once()->andReturn($message); - $mailer->getSwiftMailer()->shouldReceive('send')->once()->with($message, []); - $mailer->send(['html' => new HtmlString('rendered.view'), 'text' => new HtmlString('rendered.text')], ['data'], function ($m) { - $_SERVER['__mailer.test'] = $m; - }); - unset($_SERVER['__mailer.test']); + + $mailer = new Mailer('array', $view, new ArrayTransport); + + $sentMessage = $mailer->send( + ['html' => new HtmlString('

Hello Laravel

'), 'text' => new HtmlString('Hello World')], + ['data'], + function (Message $message) { + $message->to('taylor@laravel.com')->from('hello@laravel.com'); + } + ); + + $this->assertStringContainsString('

Hello Laravel

', $sentMessage->toString()); + $this->assertStringContainsString('Hello World', $sentMessage->toString()); } public function testMailerSendSendsMessageWithProperViewContentUsingHtmlMethod() { - unset($_SERVER['__mailer.test']); - $mailer = $this->getMockBuilder(Mailer::class)->onlyMethods(['createMessage'])->setConstructorArgs($this->getMocks())->getMock(); - $message = m::mock(Swift_Mime_SimpleMessage::class); - $mailer->expects($this->once())->method('createMessage')->willReturn($message); - $view = m::mock(stdClass::class); - $mailer->getViewFactory()->shouldReceive('make')->never(); + $view = m::mock(Factory::class); $view->shouldReceive('render')->never(); - $message->shouldReceive('setBody')->once()->with('rendered.view', 'text/html'); - $message->shouldReceive('setFrom')->never(); - $this->setSwiftMailer($mailer); - $message->shouldReceive('getSwiftMessage')->once()->andReturn($message); - $mailer->getSwiftMailer()->shouldReceive('send')->once()->with($message, []); - $mailer->html('rendered.view', function ($m) { - $_SERVER['__mailer.test'] = $m; + + $mailer = new Mailer('array', $view, new ArrayTransport); + + $sentMessage = $mailer->html('

Hello World

', function (Message $message) { + $message->to('taylor@laravel.com')->from('hello@laravel.com'); }); - unset($_SERVER['__mailer.test']); + + $this->assertStringContainsString('

Hello World

', $sentMessage->toString()); } public function testMailerSendSendsMessageWithProperPlainViewContent() @@ -103,12 +95,10 @@ public function testMailerSendSendsMessageWithProperPlainViewContent() $mailer->send(['foo', 'bar'], ['data'], function ($m) { $_SERVER['__mailer.test'] = $m; }); - unset($_SERVER['__mailer.test']); } public function testMailerSendSendsMessageWithProperPlainViewContentWhenExplicit() { - unset($_SERVER['__mailer.test']); $mailer = $this->getMockBuilder(Mailer::class)->onlyMethods(['createMessage'])->setConstructorArgs($this->getMocks())->getMock(); $message = m::mock(Swift_Mime_SimpleMessage::class); $mailer->expects($this->once())->method('createMessage')->willReturn($message); @@ -125,12 +115,10 @@ public function testMailerSendSendsMessageWithProperPlainViewContentWhenExplicit $mailer->send(['html' => 'foo', 'text' => 'bar'], ['data'], function ($m) { $_SERVER['__mailer.test'] = $m; }); - unset($_SERVER['__mailer.test']); } public function testGlobalFromIsRespectedOnAllMessages() { - unset($_SERVER['__mailer.test']); $mailer = $this->getMailer(); $view = m::mock(stdClass::class); $mailer->getViewFactory()->shouldReceive('make')->once()->andReturn($view); @@ -147,7 +135,6 @@ public function testGlobalFromIsRespectedOnAllMessages() public function testGlobalReturnPathIsRespectedOnAllMessages() { - unset($_SERVER['__mailer.test']); $mailer = $this->getMailer(); $view = m::mock(stdClass::class); $mailer->getViewFactory()->shouldReceive('make')->once()->andReturn($view); @@ -162,28 +149,8 @@ public function testGlobalReturnPathIsRespectedOnAllMessages() }); } - public function testFailedRecipientsAreAppendedAndCanBeRetrieved() - { - unset($_SERVER['__mailer.test']); - $mailer = $this->getMailer(); - $mailer->getSwiftMailer()->shouldReceive('getTransport')->andReturn($transport = m::mock(Swift_Transport::class)); - $transport->shouldReceive('stop'); - $view = m::mock(stdClass::class); - $mailer->getViewFactory()->shouldReceive('make')->once()->andReturn($view); - $view->shouldReceive('render')->once()->andReturn('rendered.view'); - $swift = new FailingSwiftMailerStub; - $mailer->setSwiftMailer($swift); - - $mailer->send('foo', ['data'], function ($m) { - // - }); - - $this->assertEquals(['taylorotwell@gmail.com'], $mailer->failures()); - } - public function testEventsAreDispatched() { - unset($_SERVER['__mailer.test']); $events = m::mock(Dispatcher::class); $events->shouldReceive('until')->once()->with(m::type(MessageSending::class)); $events->shouldReceive('dispatch')->once()->with(m::type(MessageSent::class)); @@ -213,43 +180,22 @@ public function testMacroable() protected function getMailer($events = null) { - return new Mailer('smtp', m::mock(Factory::class), m::mock(Swift_Mailer::class), $events); + return new Mailer('smtp', m::mock(Factory::class), m::mock(TransportInterface::class), $events); } public function setSwiftMailer($mailer) { - $swift = m::mock(Swift_Mailer::class); - $swift->shouldReceive('createMessage')->andReturn(new Swift_Message); - $swift->shouldReceive('getTransport')->andReturn($transport = m::mock(Swift_Transport::class)); + $transport = m::mock(TransportInterface::class); + $transport->shouldReceive('createMessage')->andReturn(new Message(new Email())); + $transport->shouldReceive('getTransport')->andReturn($transport = m::mock(Swift_Transport::class)); $transport->shouldReceive('stop'); - $mailer->setSwiftMailer($swift); + $mailer->setSymfonyTransport($transport); return $mailer; } protected function getMocks() { - return ['smtp', m::mock(Factory::class), m::mock(Swift_Mailer::class)]; - } -} - -class FailingSwiftMailerStub -{ - public function send($message, &$failed) - { - $failed[] = 'taylorotwell@gmail.com'; - } - - public function getTransport() - { - $transport = m::mock(Swift_Transport::class); - $transport->shouldReceive('stop'); - - return $transport; - } - - public function createMessage() - { - return new Swift_Message; + return ['smtp', m::mock(Factory::class), m::mock(TransportInterface::class)]; } } diff --git a/tests/Mail/MailMessageTest.php b/tests/Mail/MailMessageTest.php index 8e98bc3a8fcf..d36812492df4 100755 --- a/tests/Mail/MailMessageTest.php +++ b/tests/Mail/MailMessageTest.php @@ -3,7 +3,6 @@ namespace Illuminate\Tests\Mail; use Illuminate\Mail\Message; -use Mockery as m; use PHPUnit\Framework\TestCase; use Symfony\Component\Mime\Address; use Symfony\Component\Mime\Email; @@ -22,11 +21,6 @@ protected function setUp(): void $this->message = new Message(new Email()); } - protected function tearDown(): void - { - m::close(); - } - public function testFromMethod() { $this->assertInstanceOf(Message::class, $message = $this->message->from('foo@bar.baz', 'Foo')); From c0220cd4d140771700f7d0c479dbd91abceef341 Mon Sep 17 00:00:00 2001 From: Dries Vints Date: Tue, 24 Aug 2021 16:46:13 +0200 Subject: [PATCH 18/37] type-hint --- src/Illuminate/Mail/Mailer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Illuminate/Mail/Mailer.php b/src/Illuminate/Mail/Mailer.php index 424ff0b885f9..274df5a7fc04 100755 --- a/src/Illuminate/Mail/Mailer.php +++ b/src/Illuminate/Mail/Mailer.php @@ -577,7 +577,7 @@ public function getViewFactory() * @param \Symfony\Component\Mailer\Transport\TransportInterface $transport * @return void */ - public function setSymfonyTransport($transport) + public function setSymfonyTransport(TransportInterface $transport) { $this->transport = $transport; } From 2463633b4d65e6b3a405d6325993bfe0cd9be0ad Mon Sep 17 00:00:00 2001 From: Dries Vints Date: Wed, 25 Aug 2021 15:05:50 +0200 Subject: [PATCH 19/37] Fix Mailer tests --- src/Illuminate/Mail/MailManager.php | 4 +- src/Illuminate/Mail/Mailer.php | 2 +- .../Mail/Transport/ArrayTransport.php | 2 +- .../Notifications/Channels/MailChannel.php | 2 +- .../Notifications/Messages/MailMessage.php | 4 +- tests/Mail/MailMailerTest.php | 168 +++++++++--------- .../NotificationMailMessageTest.php | 2 +- 7 files changed, 90 insertions(+), 94 deletions(-) diff --git a/src/Illuminate/Mail/MailManager.php b/src/Illuminate/Mail/MailManager.php index 5820337f5d4a..d3e5f7d8b282 100644 --- a/src/Illuminate/Mail/MailManager.php +++ b/src/Illuminate/Mail/MailManager.php @@ -167,7 +167,7 @@ public function createSymfonyTransport(array $config) */ protected function createSmtpTransport(array $config) { - // The Swift SMTP transport instance will allow us to use any SMTP backend + // The Symfony ESMTP transport instance will allow use of any SMTP backend // for delivering mail such as Sendgrid, Amazon SES, or a custom server // a developer has available. We will just pass this configured host. $transport = new EsmtpTransport( @@ -177,7 +177,7 @@ protected function createSmtpTransport(array $config) ); // Once we have the transport we will check for the presence of a username - // and password. If we have it we will set the credentials on the Swift + // and password. If we have it we'll set the credentials on the Symfony // transporter instance so that we'll properly authenticate delivery. if (isset($config['username'])) { $transport->setUsername($config['username']); diff --git a/src/Illuminate/Mail/Mailer.php b/src/Illuminate/Mail/Mailer.php index 274df5a7fc04..e91d5ee38f74 100755 --- a/src/Illuminate/Mail/Mailer.php +++ b/src/Illuminate/Mail/Mailer.php @@ -546,7 +546,7 @@ protected function dispatchSentEvent($message, $data = []) { if ($this->events) { $this->events->dispatch( - new MessageSent($message->getSwiftMessage(), $data) + new MessageSent($message->getSymfonyMessage(), $data) ); } } diff --git a/src/Illuminate/Mail/Transport/ArrayTransport.php b/src/Illuminate/Mail/Transport/ArrayTransport.php index 072cd4230578..0a348f9b28f6 100644 --- a/src/Illuminate/Mail/Transport/ArrayTransport.php +++ b/src/Illuminate/Mail/Transport/ArrayTransport.php @@ -11,7 +11,7 @@ class ArrayTransport implements TransportInterface { /** - * The collection of Swift Messages. + * The collection of Symfony Messages. * * @var \Illuminate\Support\Collection */ diff --git a/src/Illuminate/Notifications/Channels/MailChannel.php b/src/Illuminate/Notifications/Channels/MailChannel.php index 2a30bcdacc84..77885b87a88e 100644 --- a/src/Illuminate/Notifications/Channels/MailChannel.php +++ b/src/Illuminate/Notifications/Channels/MailChannel.php @@ -244,7 +244,7 @@ protected function addAttachments($mailMessage, $message) protected function runCallbacks($mailMessage, $message) { foreach ($message->callbacks as $callback) { - $callback($mailMessage->getSwiftMessage()); + $callback($mailMessage->getSymfonyMessage()); } return $this; diff --git a/src/Illuminate/Notifications/Messages/MailMessage.php b/src/Illuminate/Notifications/Messages/MailMessage.php index 94342f30b2bc..24c2515ca52c 100644 --- a/src/Illuminate/Notifications/Messages/MailMessage.php +++ b/src/Illuminate/Notifications/Messages/MailMessage.php @@ -322,12 +322,12 @@ public function render() } /** - * Register a callback to be called with the Swift message instance. + * Register a callback to be called with the Symfony message instance. * * @param callable $callback * @return $this */ - public function withSwiftMessage($callback) + public function withSymfonyMessage($callback) { $this->callbacks[] = $callback; diff --git a/tests/Mail/MailMailerTest.php b/tests/Mail/MailMailerTest.php index e796818fca9b..5efc1b7019eb 100755 --- a/tests/Mail/MailMailerTest.php +++ b/tests/Mail/MailMailerTest.php @@ -12,12 +12,6 @@ use Illuminate\Support\HtmlString; use Mockery as m; use PHPUnit\Framework\TestCase; -use stdClass; -use Swift_Message; -use Swift_Mime_SimpleMessage; -use Swift_Transport; -use Symfony\Component\Mailer\Transport\TransportInterface; -use Symfony\Component\Mime\Email; class MailMailerTest extends TestCase { @@ -78,90 +72,113 @@ public function testMailerSendSendsMessageWithProperViewContentUsingHtmlMethod() public function testMailerSendSendsMessageWithProperPlainViewContent() { - unset($_SERVER['__mailer.test']); - $mailer = $this->getMockBuilder(Mailer::class)->onlyMethods(['createMessage'])->setConstructorArgs($this->getMocks())->getMock(); - $message = m::mock(Swift_Mime_SimpleMessage::class); - $mailer->expects($this->once())->method('createMessage')->willReturn($message); - $view = m::mock(stdClass::class); - $mailer->getViewFactory()->shouldReceive('make')->once()->with('foo', ['data', 'message' => $message])->andReturn($view); - $mailer->getViewFactory()->shouldReceive('make')->once()->with('bar', ['data', 'message' => $message])->andReturn($view); - $view->shouldReceive('render')->twice()->andReturn('rendered.view'); - $message->shouldReceive('setBody')->once()->with('rendered.view', 'text/html'); - $message->shouldReceive('addPart')->once()->with('rendered.view', 'text/plain'); - $message->shouldReceive('setFrom')->never(); - $this->setSwiftMailer($mailer); - $message->shouldReceive('getSwiftMessage')->once()->andReturn($message); - $mailer->getSwiftMailer()->shouldReceive('send')->once()->with($message, []); - $mailer->send(['foo', 'bar'], ['data'], function ($m) { - $_SERVER['__mailer.test'] = $m; + $view = m::mock(Factory::class); + $view->shouldReceive('make')->twice()->andReturn($view); + $view->shouldReceive('render')->once()->andReturn('rendered.view'); + $view->shouldReceive('render')->once()->andReturn('rendered.plain'); + + $mailer = new Mailer('array', $view, new ArrayTransport); + + $sentMessage = $mailer->send(['foo', 'bar'], ['data'], function (Message $message) { + $message->to('taylor@laravel.com')->from('hello@laravel.com'); }); + + $expected = <<assertStringContainsString($expected, $sentMessage->toString()); + + $expected = <<assertStringContainsString($expected, $sentMessage->toString()); } public function testMailerSendSendsMessageWithProperPlainViewContentWhenExplicit() { - $mailer = $this->getMockBuilder(Mailer::class)->onlyMethods(['createMessage'])->setConstructorArgs($this->getMocks())->getMock(); - $message = m::mock(Swift_Mime_SimpleMessage::class); - $mailer->expects($this->once())->method('createMessage')->willReturn($message); - $view = m::mock(stdClass::class); - $mailer->getViewFactory()->shouldReceive('make')->once()->with('foo', ['data', 'message' => $message])->andReturn($view); - $mailer->getViewFactory()->shouldReceive('make')->once()->with('bar', ['data', 'message' => $message])->andReturn($view); - $view->shouldReceive('render')->twice()->andReturn('rendered.view'); - $message->shouldReceive('setBody')->once()->with('rendered.view', 'text/html'); - $message->shouldReceive('addPart')->once()->with('rendered.view', 'text/plain'); - $message->shouldReceive('setFrom')->never(); - $this->setSwiftMailer($mailer); - $message->shouldReceive('getSwiftMessage')->once()->andReturn($message); - $mailer->getSwiftMailer()->shouldReceive('send')->once()->with($message, []); - $mailer->send(['html' => 'foo', 'text' => 'bar'], ['data'], function ($m) { - $_SERVER['__mailer.test'] = $m; + $view = m::mock(Factory::class); + $view->shouldReceive('make')->twice()->andReturn($view); + $view->shouldReceive('render')->once()->andReturn('rendered.view'); + $view->shouldReceive('render')->once()->andReturn('rendered.plain'); + + $mailer = new Mailer('array', $view, new ArrayTransport); + + $sentMessage = $mailer->send(['html' => 'foo', 'text' => 'bar'], ['data'], function (Message $message) { + $message->to('taylor@laravel.com')->from('hello@laravel.com'); }); + + $expected = <<assertStringContainsString($expected, $sentMessage->toString()); + + $expected = <<assertStringContainsString($expected, $sentMessage->toString()); } public function testGlobalFromIsRespectedOnAllMessages() { - $mailer = $this->getMailer(); - $view = m::mock(stdClass::class); - $mailer->getViewFactory()->shouldReceive('make')->once()->andReturn($view); + $view = m::mock(Factory::class); + $view->shouldReceive('make')->once()->andReturn($view); $view->shouldReceive('render')->once()->andReturn('rendered.view'); - $this->setSwiftMailer($mailer); - $mailer->alwaysFrom('taylorotwell@gmail.com', 'Taylor Otwell'); - $mailer->getSwiftMailer()->shouldReceive('send')->once()->with(m::type(Swift_Message::class), [])->andReturnUsing(function ($message) { - $this->assertEquals(['taylorotwell@gmail.com' => 'Taylor Otwell'], $message->getFrom()); - }); - $mailer->send('foo', ['data'], function ($m) { - // + $mailer = new Mailer('array', $view, new ArrayTransport); + $mailer->alwaysFrom('hello@laravel.com'); + + $sentMessage = $mailer->send('foo', ['data'], function (Message $message) { + $message->to('taylor@laravel.com'); }); + + $this->assertSame('taylor@laravel.com', $sentMessage->getEnvelope()->getRecipients()[0]->getAddress()); } public function testGlobalReturnPathIsRespectedOnAllMessages() { - $mailer = $this->getMailer(); - $view = m::mock(stdClass::class); - $mailer->getViewFactory()->shouldReceive('make')->once()->andReturn($view); + $view = m::mock(Factory::class); + $view->shouldReceive('make')->once()->andReturn($view); $view->shouldReceive('render')->once()->andReturn('rendered.view'); - $this->setSwiftMailer($mailer); + + $mailer = new Mailer('array', $view, new ArrayTransport); $mailer->alwaysReturnPath('taylorotwell@gmail.com'); - $mailer->getSwiftMailer()->shouldReceive('send')->once()->with(m::type(Swift_Message::class), [])->andReturnUsing(function ($message) { - $this->assertSame('taylorotwell@gmail.com', $message->getReturnPath()); - }); - $mailer->send('foo', ['data'], function ($m) { - // + + $sentMessage = $mailer->send('foo', ['data'], function (Message $message) { + $message->to('taylor@laravel.com')->from('hello@laravel.com'); }); + + $this->assertStringContainsString('Return-Path: ', $sentMessage->toString()); } public function testEventsAreDispatched() { + $view = m::mock(Factory::class); + $view->shouldReceive('make')->once()->andReturn($view); + $view->shouldReceive('render')->once()->andReturn('rendered.view'); + $events = m::mock(Dispatcher::class); $events->shouldReceive('until')->once()->with(m::type(MessageSending::class)); $events->shouldReceive('dispatch')->once()->with(m::type(MessageSent::class)); - $mailer = $this->getMailer($events); - $view = m::mock(stdClass::class); - $mailer->getViewFactory()->shouldReceive('make')->once()->andReturn($view); - $view->shouldReceive('render')->once()->andReturn('rendered.view'); - $this->setSwiftMailer($mailer); - $mailer->getSwiftMailer()->shouldReceive('send')->once()->with(m::type(Swift_Message::class), []); - $mailer->send('foo', ['data'], function ($m) { - // + + $mailer = new Mailer('array', $view, new ArrayTransport, $events); + + $mailer->send('foo', ['data'], function (Message $message) { + $message->to('taylor@laravel.com')->from('hello@laravel.com'); }); } @@ -171,31 +188,10 @@ public function testMacroable() return 'bar'; }); - $mailer = $this->getMailer(); + $mailer = new Mailer('array', m::mock(Factory::class), new ArrayTransport); $this->assertSame( 'bar', $mailer->foo() ); } - - protected function getMailer($events = null) - { - return new Mailer('smtp', m::mock(Factory::class), m::mock(TransportInterface::class), $events); - } - - public function setSwiftMailer($mailer) - { - $transport = m::mock(TransportInterface::class); - $transport->shouldReceive('createMessage')->andReturn(new Message(new Email())); - $transport->shouldReceive('getTransport')->andReturn($transport = m::mock(Swift_Transport::class)); - $transport->shouldReceive('stop'); - $mailer->setSymfonyTransport($transport); - - return $mailer; - } - - protected function getMocks() - { - return ['smtp', m::mock(Factory::class), m::mock(TransportInterface::class)]; - } } diff --git a/tests/Notifications/NotificationMailMessageTest.php b/tests/Notifications/NotificationMailMessageTest.php index ba31b96df353..94db5b6d284c 100644 --- a/tests/Notifications/NotificationMailMessageTest.php +++ b/tests/Notifications/NotificationMailMessageTest.php @@ -128,7 +128,7 @@ public function testCallbackIsSetCorrectly() }; $message = new MailMessage; - $message->withSwiftMessage($callback); + $message->withSymfonyMessage($callback); $this->assertSame([$callback], $message->callbacks); } From eb33afd3468150aaf2994d5a80572a5c5f52268f Mon Sep 17 00:00:00 2001 From: Dries Vints Date: Wed, 25 Aug 2021 17:12:59 +0200 Subject: [PATCH 20/37] Fix more tests --- .../Mail/Transport/ArrayTransport.php | 4 +- src/Illuminate/Support/Facades/Mail.php | 8 +- .../Mail/SendingMailWithLocaleTest.php | 22 +-- .../SendingNotificationsWithLocaleTest.php | 30 ++-- tests/Mail/MailLogTransportTest.php | 3 +- tests/Mail/MailSesTransportTest.php | 140 ------------------ 6 files changed, 34 insertions(+), 173 deletions(-) delete mode 100644 tests/Mail/MailSesTransportTest.php diff --git a/src/Illuminate/Mail/Transport/ArrayTransport.php b/src/Illuminate/Mail/Transport/ArrayTransport.php index 0a348f9b28f6..cd7ce976109d 100644 --- a/src/Illuminate/Mail/Transport/ArrayTransport.php +++ b/src/Illuminate/Mail/Transport/ArrayTransport.php @@ -32,9 +32,7 @@ public function __construct() */ public function send(RawMessage $message, Envelope $envelope = null): ?SentMessage { - $this->messages[] = $message; - - return new SentMessage($message, $envelope ?? Envelope::create($message)); + return $this->messages[] = new SentMessage($message, $envelope ?? Envelope::create($message)); } /** diff --git a/src/Illuminate/Support/Facades/Mail.php b/src/Illuminate/Support/Facades/Mail.php index 36796e752e55..ad69ed494736 100755 --- a/src/Illuminate/Support/Facades/Mail.php +++ b/src/Illuminate/Support/Facades/Mail.php @@ -10,6 +10,10 @@ * @method static \Illuminate\Mail\PendingMail to($users) * @method static \Illuminate\Support\Collection queued(string $mailable, \Closure|string $callback = null) * @method static \Illuminate\Support\Collection sent(string $mailable, \Closure|string $callback = null) + * @method static \Symfony\Component\Mailer\SentMessage|null raw(string $text, $callback) + * @method static \Symfony\Component\Mailer\SentMessage|null plain(string $view, array $data, $callback) + * @method static \Symfony\Component\Mailer\SentMessage|null html(string $html, $callback) + * @method static \Symfony\Component\Mailer\SentMessage|null send(\Illuminate\Contracts\Mail\Mailable|string|array $view, array $data = [], \Closure|string $callback = null) * @method static array failures() * @method static bool hasQueued(string $mailable) * @method static bool hasSent(string $mailable) @@ -23,10 +27,6 @@ * @method static void assertNothingSent() * @method static void assertQueued(string|\Closure $mailable, callable|int $callback = null) * @method static void assertSent(string|\Closure $mailable, callable|int $callback = null) - * @method static void raw(string $text, $callback) - * @method static void plain(string $view, array $data, $callback) - * @method static void html(string $html, $callback) - * @method static void send(\Illuminate\Contracts\Mail\Mailable|string|array $view, array $data = [], \Closure|string $callback = null) * * @see \Illuminate\Mail\Mailer * @see \Illuminate\Support\Testing\Fakes\MailFake diff --git a/tests/Integration/Mail/SendingMailWithLocaleTest.php b/tests/Integration/Mail/SendingMailWithLocaleTest.php index 5421e308d460..0031461f2e96 100644 --- a/tests/Integration/Mail/SendingMailWithLocaleTest.php +++ b/tests/Integration/Mail/SendingMailWithLocaleTest.php @@ -44,7 +44,7 @@ public function testMailIsSentWithDefaultLocale() Mail::to('test@mail.com')->send(new TestMail); $this->assertStringContainsString('name', - app('mailer')->getSwiftMailer()->getTransport()->messages()[0]->getBody() + app('mailer')->getSymfonyTransport()->messages()[0]->toString() ); } @@ -53,7 +53,7 @@ public function testMailIsSentWithSelectedLocale() Mail::to('test@mail.com')->locale('ar')->send(new TestMail); $this->assertStringContainsString('esm', - app('mailer')->getSwiftMailer()->getTransport()->messages()[0]->getBody() + app('mailer')->getSymfonyTransport()->messages()[0]->toString() ); } @@ -65,7 +65,7 @@ public function testMailIsSentWithLocaleFromMailable() Mail::to('test@mail.com')->send($mailable); $this->assertStringContainsString('esm', - app('mailer')->getSwiftMailer()->getTransport()->messages()[0]->getBody() + app('mailer')->getSymfonyTransport()->messages()[0]->toString() ); } @@ -79,8 +79,8 @@ public function testMailIsSentWithLocaleUpdatedListenersCalled() Mail::to('test@mail.com')->locale('es')->send(new TimestampTestMail); - Assert::assertMatchesRegularExpression('/nombre (en|dentro de) (un|1) día/', - app('mailer')->getSwiftMailer()->getTransport()->messages()[0]->getBody() + Assert::assertMatchesRegularExpression('/nombre (en|dentro de) (un|1) d=C3=ADa/', + app('mailer')->getSymfonyTransport()->messages()[0]->toString() ); $this->assertSame('en', Carbon::getLocale()); @@ -96,7 +96,7 @@ public function testLocaleIsSentWithModelPreferredLocale() Mail::to($recipient)->send(new TestMail); $this->assertStringContainsString('esm', - app('mailer')->getSwiftMailer()->getTransport()->messages()[0]->getBody() + app('mailer')->getSymfonyTransport()->messages()[0]->toString() ); } @@ -110,7 +110,7 @@ public function testLocaleIsSentWithSelectedLocaleOverridingModelPreferredLocale Mail::to($recipient)->locale('ar')->send(new TestMail); $this->assertStringContainsString('esm', - app('mailer')->getSwiftMailer()->getTransport()->messages()[0]->getBody() + app('mailer')->getSymfonyTransport()->messages()[0]->toString() ); } @@ -129,7 +129,7 @@ public function testLocaleIsSentWithModelPreferredLocaleWillIgnorePreferredLocal Mail::to($toRecipient)->cc($ccRecipient)->send(new TestMail); $this->assertStringContainsString('esm', - app('mailer')->getSwiftMailer()->getTransport()->messages()[0]->getBody() + app('mailer')->getSymfonyTransport()->messages()[0]->toString() ); } @@ -149,7 +149,7 @@ public function testLocaleIsNotSentWithModelPreferredLocaleWhenThereAreMultipleR Mail::to($recipients)->send(new TestMail); $this->assertStringContainsString('name', - app('mailer')->getSwiftMailer()->getTransport()->messages()[0]->getBody() + app('mailer')->getSymfonyTransport()->messages()[0]->toString() ); } @@ -161,11 +161,11 @@ public function testLocaleIsSetBackToDefaultAfterMailSent() $this->assertSame('en', app('translator')->getLocale()); $this->assertStringContainsString('esm', - app('mailer')->getSwiftMailer()->getTransport()->messages()[0]->getBody() + app('mailer')->getSymfonyTransport()->messages()[0]->toString() ); $this->assertStringContainsString('name', - app('mailer')->getSwiftMailer()->getTransport()->messages()[1]->getBody() + app('mailer')->getSymfonyTransport()->messages()[1]->toString() ); } } diff --git a/tests/Integration/Notifications/SendingNotificationsWithLocaleTest.php b/tests/Integration/Notifications/SendingNotificationsWithLocaleTest.php index c474742c3538..57fb3aa55ede 100644 --- a/tests/Integration/Notifications/SendingNotificationsWithLocaleTest.php +++ b/tests/Integration/Notifications/SendingNotificationsWithLocaleTest.php @@ -76,7 +76,7 @@ public function testMailIsSentWithDefaultLocale() NotificationFacade::send($user, new GreetingMailNotification); $this->assertStringContainsString('hello', - app('mailer')->getSwiftMailer()->getTransport()->messages()[0]->getBody() + app('mailer')->getSymfonyTransport()->messages()[0]->toString() ); } @@ -90,7 +90,7 @@ public function testMailIsSentWithFacadeSelectedLocale() NotificationFacade::locale('fr')->send($user, new GreetingMailNotification); $this->assertStringContainsString('bonjour', - app('mailer')->getSwiftMailer()->getTransport()->messages()[0]->getBody() + app('mailer')->getSymfonyTransport()->messages()[0]->toString() ); } @@ -110,14 +110,15 @@ public function testMailIsSentWithNotificationSelectedLocale() NotificationFacade::send($users, (new GreetingMailNotification)->locale('fr')); $this->assertStringContainsString('bonjour', - app('mailer')->getSwiftMailer()->getTransport()->messages()[0]->getBody() + app('mailer')->getSymfonyTransport()->messages()[0]->toString() ); $this->assertStringContainsString('bonjour', - app('mailer')->getSwiftMailer()->getTransport()->messages()[1]->getBody() + app('mailer')->getSymfonyTransport()->messages()[1]->toString() ); } + public function testMailableIsSentWithSelectedLocale() { $user = NotifiableLocalizedUser::forceCreate([ @@ -128,7 +129,7 @@ public function testMailableIsSentWithSelectedLocale() NotificationFacade::locale('fr')->send($user, new GreetingMailNotificationWithMailable); $this->assertStringContainsString('bonjour', - app('mailer')->getSwiftMailer()->getTransport()->messages()[0]->getBody() + app('mailer')->getSymfonyTransport()->messages()[0]->toString() ); } @@ -148,11 +149,11 @@ public function testMailIsSentWithLocaleUpdatedListenersCalled() $user->notify((new GreetingMailNotification)->locale('fr')); $this->assertStringContainsString('bonjour', - app('mailer')->getSwiftMailer()->getTransport()->messages()[0]->getBody() + app('mailer')->getSymfonyTransport()->messages()[0]->toString() ); Assert::assertMatchesRegularExpression('/dans (1|un) jour/', - app('mailer')->getSwiftMailer()->getTransport()->messages()[0]->getBody() + app('mailer')->getSymfonyTransport()->messages()[0]->toString() ); $this->assertTrue($this->app->isLocale('en')); @@ -170,7 +171,7 @@ public function testLocaleIsSentWithNotifiablePreferredLocale() $recipient->notify(new GreetingMailNotification); $this->assertStringContainsString('bonjour', - app('mailer')->getSwiftMailer()->getTransport()->messages()[0]->getBody() + app('mailer')->getSymfonyTransport()->messages()[0]->toString() ); } @@ -195,13 +196,13 @@ public function testLocaleIsSentWithNotifiablePreferredLocaleForMultipleRecipien ); $this->assertStringContainsString('bonjour', - app('mailer')->getSwiftMailer()->getTransport()->messages()[0]->getBody() + app('mailer')->getSymfonyTransport()->messages()[0]->toString() ); $this->assertStringContainsString('hola', - app('mailer')->getSwiftMailer()->getTransport()->messages()[1]->getBody() + app('mailer')->getSymfonyTransport()->messages()[1]->toString() ); $this->assertStringContainsString('hello', - app('mailer')->getSwiftMailer()->getTransport()->messages()[2]->getBody() + app('mailer')->getSymfonyTransport()->messages()[2]->toString() ); } @@ -217,7 +218,7 @@ public function testLocaleIsSentWithNotificationSelectedLocaleOverridingNotifiab ); $this->assertStringContainsString('bonjour', - app('mailer')->getSwiftMailer()->getTransport()->messages()[0]->getBody() + app('mailer')->getSymfonyTransport()->messages()[0]->toString() ); } @@ -233,7 +234,7 @@ public function testLocaleIsSentWithFacadeSelectedLocaleOverridingNotifiablePref ); $this->assertStringContainsString('bonjour', - app('mailer')->getSwiftMailer()->getTransport()->messages()[0]->getBody() + app('mailer')->getSymfonyTransport()->messages()[0]->toString() ); } } @@ -285,7 +286,8 @@ public function via($notifiable) public function toMail($notifiable) { - return new GreetingMailable; + return (new GreetingMailable) + ->to($notifiable->email); } } diff --git a/tests/Mail/MailLogTransportTest.php b/tests/Mail/MailLogTransportTest.php index ff6bab6c74ca..9062347c9a54 100644 --- a/tests/Mail/MailLogTransportTest.php +++ b/tests/Mail/MailLogTransportTest.php @@ -30,12 +30,13 @@ public function testGetLogTransportWithConfiguredChannel() $this->assertInstanceOf(Logger::class, $monolog = $logger->getLogger()); $this->assertCount(1, $handlers = $monolog->getHandlers()); - $this->assertInstanceOf(StreamHandler::class, $handler = $handlers[0]); + $this->assertInstanceOf(StreamHandler::class, $handlers[0]); } public function testGetLogTransportWithPsrLogger() { $this->app['config']->set('mail.driver', 'log'); + $logger = $this->app->instance('log', new NullLogger); $transportLogger = app('mailer')->getSymfonyTransport()->logger(); diff --git a/tests/Mail/MailSesTransportTest.php b/tests/Mail/MailSesTransportTest.php deleted file mode 100644 index a6852b344364..000000000000 --- a/tests/Mail/MailSesTransportTest.php +++ /dev/null @@ -1,140 +0,0 @@ -singleton('config', function () { - return new Repository([ - 'services.ses' => [ - 'key' => 'foo', - 'secret' => 'bar', - 'region' => 'us-east-1', - ], - ]); - }); - - $manager = new MailManager($container); - - /** @var \Illuminate\Mail\Transport\SesTransport $transport */ - $transport = $manager->createTransport(['transport' => 'ses']); - - $ses = $transport->ses(); - - $this->assertSame('us-east-1', $ses->getRegion()); - } - - public function testSend() - { - $message = new Swift_Message('Foo subject', 'Bar body'); - $message->setSender('myself@example.com'); - $message->setTo('me@example.com'); - $message->setBcc('you@example.com'); - - $client = $this->getMockBuilder(SesV2Client::class) - ->addMethods(['sendEmail']) - ->disableOriginalConstructor() - ->getMock(); - $transport = new SesTransport($client); - - // Generate a messageId for our mock to return to ensure that the post-sent message - // has X-Message-ID in its headers - $messageId = Str::random(32); - $sendRawEmailMock = new SendRawEmailMock($messageId); - $client->expects($this->once()) - ->method('sendEmail') - ->with($this->equalTo([ - 'Content' => [ - 'Raw' => ['Data' => (string) $message], - ], - ])) - ->willReturn($sendRawEmailMock); - - $transport->send($message); - - $this->assertEquals($messageId, $message->getHeaders()->get('X-Message-ID')->getFieldBody()); - $this->assertEquals($messageId, $message->getHeaders()->get('X-SES-Message-ID')->getFieldBody()); - } - - public function testSesLocalConfiguration() - { - $container = new Container; - - $container->singleton('config', function () { - return new Repository([ - 'mail' => [ - 'mailers' => [ - 'ses' => [ - 'transport' => 'ses', - 'region' => 'eu-west-1', - 'options' => [ - 'ConfigurationSetName' => 'Laravel', - 'EmailTags' => [ - ['Name' => 'Laravel', 'Value' => 'Framework'], - ], - ], - ], - ], - ], - 'services' => [ - 'ses' => [ - 'region' => 'us-east-1', - ], - ], - ]); - }); - - $container->instance('view', $this->createMock(Factory::class)); - - $container->bind('events', function () { - return null; - }); - - $manager = new MailManager($container); - - /** @var \Illuminate\Mail\Mailer $mailer */ - $mailer = $manager->mailer('ses'); - - /** @var \Illuminate\Mail\Transport\SesTransport $transport */ - $transport = $mailer->getSwiftMailer()->getTransport(); - - $this->assertSame('eu-west-1', $transport->ses()->getRegion()); - - $this->assertSame([ - 'ConfigurationSetName' => 'Laravel', - 'EmailTags' => [ - ['Name' => 'Laravel', 'Value' => 'Framework'], - ], - ], $transport->getOptions()); - } -} - -class SendRawEmailMock -{ - protected $getResponse; - - public function __construct($responseValue) - { - $this->getResponse = $responseValue; - } - - public function get($key) - { - return $this->getResponse; - } -} From b5aba0eea3a3788570b4f4c9e3c0d9d16e7b923b Mon Sep 17 00:00:00 2001 From: Taylor Otwell Date: Wed, 25 Aug 2021 15:13:22 +0000 Subject: [PATCH 21/37] Apply fixes from StyleCI --- .../Notifications/SendingNotificationsWithLocaleTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/Integration/Notifications/SendingNotificationsWithLocaleTest.php b/tests/Integration/Notifications/SendingNotificationsWithLocaleTest.php index 57fb3aa55ede..f309390f0d5a 100644 --- a/tests/Integration/Notifications/SendingNotificationsWithLocaleTest.php +++ b/tests/Integration/Notifications/SendingNotificationsWithLocaleTest.php @@ -118,7 +118,6 @@ public function testMailIsSentWithNotificationSelectedLocale() ); } - public function testMailableIsSentWithSelectedLocale() { $user = NotifiableLocalizedUser::forceCreate([ From f35a83cbecc53bbc809fe15d0188575d6c9654ab Mon Sep 17 00:00:00 2001 From: Dries Vints Date: Fri, 27 Aug 2021 14:34:45 +0200 Subject: [PATCH 22/37] Migrate Mailgun transport --- composer.json | 5 +- src/Illuminate/Mail/MailManager.php | 39 ++-- .../Mail/Transport/MailgunTransport.php | 216 ------------------ src/Illuminate/Mail/composer.json | 3 +- 4 files changed, 22 insertions(+), 241 deletions(-) delete mode 100644 src/Illuminate/Mail/Transport/MailgunTransport.php diff --git a/composer.json b/composer.json index 8353b43b688e..be9a0cb25c8b 100644 --- a/composer.json +++ b/composer.json @@ -91,7 +91,8 @@ "phpstan/phpstan": "^0.12.94", "phpunit/phpunit": "^9.4", "predis/predis": "^1.1.2", - "symfony/cache": "^6.0" + "symfony/cache": "^6.0", + "symfony/mailgun-mailer": "^6.0" }, "provide": { "psr/container-implementation": "1.0" @@ -154,6 +155,8 @@ "pusher/pusher-php-server": "Required to use the Pusher broadcast driver (^5.0|^6.0).", "symfony/cache": "Required to PSR-6 cache bridge (^6.0).", "symfony/filesystem": "Required to enable support for relative symbolic links (^6.0).", + "symfony/http-client": "Required to enable support for the Mailgun mail driver when using the https or api scheme (^6.0).", + "symfony/mailgun-mailer": "Required to enable support for the Mailgun mail driver (^6.0).", "symfony/psr-http-message-bridge": "Required to use PSR-7 bridging features (^2.0).", "wildbit/swiftmailer-postmark": "Required to use Postmark mail driver (^3.0)." }, diff --git a/src/Illuminate/Mail/MailManager.php b/src/Illuminate/Mail/MailManager.php index d3e5f7d8b282..51803c40e19b 100644 --- a/src/Illuminate/Mail/MailManager.php +++ b/src/Illuminate/Mail/MailManager.php @@ -4,18 +4,18 @@ use Aws\SesV2\SesV2Client; use Closure; -use GuzzleHttp\Client as HttpClient; use Illuminate\Contracts\Mail\Factory as FactoryContract; use Illuminate\Log\LogManager; use Illuminate\Mail\Transport\ArrayTransport; use Illuminate\Mail\Transport\LogTransport; -use Illuminate\Mail\Transport\MailgunTransport; use Illuminate\Mail\Transport\SesTransport; use Illuminate\Support\Arr; use Illuminate\Support\Str; use InvalidArgumentException; use Postmark\Transport as PostmarkTransport; use Psr\Log\LoggerInterface; +use Symfony\Component\Mailer\Bridge\Mailgun\Transport\MailgunTransportFactory; +use Symfony\Component\Mailer\Transport\Dsn; use Symfony\Component\Mailer\Transport\FailoverTransport; use Symfony\Component\Mailer\Transport\SendmailTransport; use Symfony\Component\Mailer\Transport\Smtp\EsmtpTransport; @@ -280,20 +280,28 @@ protected function createMailTransport() * Create an instance of the Mailgun Swift Transport driver. * * @param array $config - * @return \Illuminate\Mail\Transport\MailgunTransport + * @return \Symfony\Component\Mailer\Transport\TransportInterface */ protected function createMailgunTransport(array $config) { + $factory = new MailgunTransportFactory(); + + if (isset($config['dsn'])) { + return $factory->create( + Dsn::fromString($config['dsn']) + ); + } + if (! isset($config['secret'])) { $config = $this->app['config']->get('services.mailgun', []); } - return new MailgunTransport( - $this->guzzle($config), + return $factory->create(new Dsn( + 'mailgun+api', + $config['endpoint'] ?? 'default', $config['secret'], - $config['domain'], - $config['endpoint'] ?? null - ); + $config['domain'] + )); } /** @@ -371,21 +379,6 @@ protected function createArrayTransport() return new ArrayTransport; } - /** - * Get a fresh Guzzle HTTP client instance. - * - * @param array $config - * @return \GuzzleHttp\Client - */ - protected function guzzle(array $config) - { - return new HttpClient(Arr::add( - $config['guzzle'] ?? [], - 'connect_timeout', - 60 - )); - } - /** * Set a global address on the mailer by type. * diff --git a/src/Illuminate/Mail/Transport/MailgunTransport.php b/src/Illuminate/Mail/Transport/MailgunTransport.php deleted file mode 100644 index 1c862b1a7f30..000000000000 --- a/src/Illuminate/Mail/Transport/MailgunTransport.php +++ /dev/null @@ -1,216 +0,0 @@ -key = $key; - $this->client = $client; - $this->endpoint = $endpoint ?? 'api.mailgun.net'; - - $this->setDomain($domain); - } - - /** - * {@inheritdoc} - */ - public function send(Swift_Mime_SimpleMessage $message, &$failedRecipients = null) - { - $this->beforeSendPerformed($message); - - $to = $this->getTo($message); - - $bcc = $message->getBcc(); - - $message->setBcc([]); - - $response = $this->client->request( - 'POST', - "https://{$this->endpoint}/v3/{$this->domain}/messages.mime", - $this->payload($message, $to) - ); - - $messageId = $this->getMessageId($response); - - $message->getHeaders()->addTextHeader('X-Message-ID', $messageId); - $message->getHeaders()->addTextHeader('X-Mailgun-Message-ID', $messageId); - - $message->setBcc($bcc); - - $this->sendPerformed($message); - - return $this->numberOfRecipients($message); - } - - /** - * Get the HTTP payload for sending the Mailgun message. - * - * @param \Swift_Mime_SimpleMessage $message - * @param string $to - * @return array - */ - protected function payload(Swift_Mime_SimpleMessage $message, $to) - { - return [ - 'auth' => [ - 'api', - $this->key, - ], - 'multipart' => [ - [ - 'name' => 'to', - 'contents' => $to, - ], - [ - 'name' => 'message', - 'contents' => $message->toString(), - 'filename' => 'message.mime', - ], - ], - ]; - } - - /** - * Get the "to" payload field for the API request. - * - * @param \Swift_Mime_SimpleMessage $message - * @return string - */ - protected function getTo(Swift_Mime_SimpleMessage $message) - { - return collect($this->allContacts($message))->map(function ($display, $address) { - return $display ? $display." <{$address}>" : $address; - })->values()->implode(','); - } - - /** - * Get all of the contacts for the message. - * - * @param \Swift_Mime_SimpleMessage $message - * @return array - */ - protected function allContacts(Swift_Mime_SimpleMessage $message) - { - return array_merge( - (array) $message->getTo(), (array) $message->getCc(), (array) $message->getBcc() - ); - } - - /** - * Get the message ID from the response. - * - * @param \Psr\Http\Message\ResponseInterface $response - * @return string - */ - protected function getMessageId($response) - { - return object_get( - json_decode($response->getBody()->getContents()), 'id' - ); - } - - /** - * Get the API key being used by the transport. - * - * @return string - */ - public function getKey() - { - return $this->key; - } - - /** - * Set the API key being used by the transport. - * - * @param string $key - * @return string - */ - public function setKey($key) - { - return $this->key = $key; - } - - /** - * Get the domain being used by the transport. - * - * @return string - */ - public function getDomain() - { - return $this->domain; - } - - /** - * Set the domain being used by the transport. - * - * @param string $domain - * @return string - */ - public function setDomain($domain) - { - return $this->domain = $domain; - } - - /** - * Get the API endpoint being used by the transport. - * - * @return string - */ - public function getEndpoint() - { - return $this->endpoint; - } - - /** - * Set the API endpoint being used by the transport. - * - * @param string $endpoint - * @return string - */ - public function setEndpoint($endpoint) - { - return $this->endpoint = $endpoint; - } -} diff --git a/src/Illuminate/Mail/composer.json b/src/Illuminate/Mail/composer.json index 202d5b8499e9..33c4a7c05ea7 100755 --- a/src/Illuminate/Mail/composer.json +++ b/src/Illuminate/Mail/composer.json @@ -38,7 +38,8 @@ }, "suggest": { "aws/aws-sdk-php": "Required to use the SES mail driver (^3.189.0).", - "guzzlehttp/guzzle": "Required to use the Mailgun mail driver (^7.2).", + "symfony/http-client": "Required to use the Mailgun mail driver (^6.0).", + "symfony/mailgun-mailer": "Required to enable support for the Mailgun mail driver (^6.0).", "wildbit/swiftmailer-postmark": "Required to use Postmark mail driver (^3.0)." }, "config": { From 58e7343e880fd168db1a9c83018eb17902d146ff Mon Sep 17 00:00:00 2001 From: Dries Vints Date: Fri, 27 Aug 2021 16:03:53 +0200 Subject: [PATCH 23/37] Migrate Postmark transport --- composer.json | 13 +++++++------ src/Illuminate/Mail/MailManager.php | 21 +++++++-------------- src/Illuminate/Mail/composer.json | 2 +- 3 files changed, 15 insertions(+), 21 deletions(-) diff --git a/composer.json b/composer.json index be9a0cb25c8b..b75549624d1d 100644 --- a/composer.json +++ b/composer.json @@ -92,7 +92,8 @@ "phpunit/phpunit": "^9.4", "predis/predis": "^1.1.2", "symfony/cache": "^6.0", - "symfony/mailgun-mailer": "^6.0" + "symfony/mailgun-mailer": "^6.0", + "symfony/postmark-mailer": "^6.0" }, "provide": { "psr/container-implementation": "1.0" @@ -141,7 +142,7 @@ "doctrine/dbal": "Required to rename columns and drop SQLite columns (^2.12|^3.0).", "filp/whoops": "Required for friendly error pages in development (^2.8).", "fakerphp/faker": "Required to use the eloquent factory builder (^1.9.1).", - "guzzlehttp/guzzle": "Required to use the HTTP Client, Mailgun mail driver and the ping methods on schedules (^7.2).", + "guzzlehttp/guzzle": "Required to use the HTTP Client and the ping methods on schedules (^7.2).", "laravel/tinker": "Required to use the tinker console command (^2.0).", "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (^2.0).", "league/flysystem-ftp": "Required to use the Flysystem FTP driver (^2.0).", @@ -155,10 +156,10 @@ "pusher/pusher-php-server": "Required to use the Pusher broadcast driver (^5.0|^6.0).", "symfony/cache": "Required to PSR-6 cache bridge (^6.0).", "symfony/filesystem": "Required to enable support for relative symbolic links (^6.0).", - "symfony/http-client": "Required to enable support for the Mailgun mail driver when using the https or api scheme (^6.0).", - "symfony/mailgun-mailer": "Required to enable support for the Mailgun mail driver (^6.0).", - "symfony/psr-http-message-bridge": "Required to use PSR-7 bridging features (^2.0).", - "wildbit/swiftmailer-postmark": "Required to use Postmark mail driver (^3.0)." + "symfony/http-client": "Required to enable support for the Mailgun mail transport (^6.0).", + "symfony/mailgun-mailer": "Required to enable support for the Mailgun mail transport (^6.0).", + "symfony/postmark-mailer": "Required to enable support for the Postmark mail transport (^6.0).", + "symfony/psr-http-message-bridge": "Required to use PSR-7 bridging features (^2.0)." }, "config": { "sort-packages": true diff --git a/src/Illuminate/Mail/MailManager.php b/src/Illuminate/Mail/MailManager.php index 51803c40e19b..3d1c235efae6 100644 --- a/src/Illuminate/Mail/MailManager.php +++ b/src/Illuminate/Mail/MailManager.php @@ -12,9 +12,9 @@ use Illuminate\Support\Arr; use Illuminate\Support\Str; use InvalidArgumentException; -use Postmark\Transport as PostmarkTransport; use Psr\Log\LoggerInterface; use Symfony\Component\Mailer\Bridge\Mailgun\Transport\MailgunTransportFactory; +use Symfony\Component\Mailer\Bridge\Postmark\Transport\PostmarkTransportFactory; use Symfony\Component\Mailer\Transport\Dsn; use Symfony\Component\Mailer\Transport\FailoverTransport; use Symfony\Component\Mailer\Transport\SendmailTransport; @@ -286,12 +286,6 @@ protected function createMailgunTransport(array $config) { $factory = new MailgunTransportFactory(); - if (isset($config['dsn'])) { - return $factory->create( - Dsn::fromString($config['dsn']) - ); - } - if (! isset($config['secret'])) { $config = $this->app['config']->get('services.mailgun', []); } @@ -312,14 +306,13 @@ protected function createMailgunTransport(array $config) */ protected function createPostmarkTransport(array $config) { - $headers = isset($config['message_stream_id']) ? [ - 'X-PM-Message-Stream' => $config['message_stream_id'], - ] : []; + $factory = new PostmarkTransportFactory(); - return new PostmarkTransport( - $config['token'] ?? $this->app['config']->get('services.postmark.token'), - $headers - ); + return $factory->create(new Dsn( + 'postmark+api', + 'default', + $config['token'] + )); } /** diff --git a/src/Illuminate/Mail/composer.json b/src/Illuminate/Mail/composer.json index 33c4a7c05ea7..6c0439c3d86f 100755 --- a/src/Illuminate/Mail/composer.json +++ b/src/Illuminate/Mail/composer.json @@ -40,7 +40,7 @@ "aws/aws-sdk-php": "Required to use the SES mail driver (^3.189.0).", "symfony/http-client": "Required to use the Mailgun mail driver (^6.0).", "symfony/mailgun-mailer": "Required to enable support for the Mailgun mail driver (^6.0).", - "wildbit/swiftmailer-postmark": "Required to use Postmark mail driver (^3.0)." + "symfony/postmark-mailer": "Required to enable support for the Postmark mail transport (^6.0)." }, "config": { "sort-packages": true From 17c78891fc87039f58536c71b8537afc7c89e05f Mon Sep 17 00:00:00 2001 From: Dries Vints Date: Mon, 30 Aug 2021 17:37:36 +0200 Subject: [PATCH 24/37] Replace SesTransport --- composer.json | 6 +- src/Illuminate/Mail/MailManager.php | 38 ++------ .../Mail/Transport/SesTransport.php | 94 ------------------- src/Illuminate/Mail/composer.json | 6 +- 4 files changed, 17 insertions(+), 127 deletions(-) delete mode 100644 src/Illuminate/Mail/Transport/SesTransport.php diff --git a/composer.json b/composer.json index b75549624d1d..be43c75dedf7 100644 --- a/composer.json +++ b/composer.json @@ -91,6 +91,7 @@ "phpstan/phpstan": "^0.12.94", "phpunit/phpunit": "^9.4", "predis/predis": "^1.1.2", + "symfony/amazon-mailer": "^6.0", "symfony/cache": "^6.0", "symfony/mailgun-mailer": "^6.0", "symfony/postmark-mailer": "^6.0" @@ -137,7 +138,7 @@ "ext-pcntl": "Required to use all features of the queue worker.", "ext-posix": "Required to use all features of the queue worker.", "ext-redis": "Required to use the Redis cache and queue drivers (^4.0|^5.0).", - "aws/aws-sdk-php": "Required to use the SQS queue driver, DynamoDb failed job storage and SES mail driver (^3.189.0).", + "aws/aws-sdk-php": "Required to use the SQS queue driver and DynamoDb failed job storage (^3.189.0).", "brianium/paratest": "Required to run tests in parallel (^6.0).", "doctrine/dbal": "Required to rename columns and drop SQLite columns (^2.12|^3.0).", "filp/whoops": "Required for friendly error pages in development (^2.8).", @@ -154,9 +155,10 @@ "predis/predis": "Required to use the predis connector (^1.1.2).", "psr/http-message": "Required to allow Storage::put to accept a StreamInterface (^1.0).", "pusher/pusher-php-server": "Required to use the Pusher broadcast driver (^5.0|^6.0).", + "symfony/amazon-mailer": "Required to enable support for the SES mail transport (^6.0).", "symfony/cache": "Required to PSR-6 cache bridge (^6.0).", "symfony/filesystem": "Required to enable support for relative symbolic links (^6.0).", - "symfony/http-client": "Required to enable support for the Mailgun mail transport (^6.0).", + "symfony/http-client": "Required to enable support for the Symfony mail transports (^6.0).", "symfony/mailgun-mailer": "Required to enable support for the Mailgun mail transport (^6.0).", "symfony/postmark-mailer": "Required to enable support for the Postmark mail transport (^6.0).", "symfony/psr-http-message-bridge": "Required to use PSR-7 bridging features (^2.0)." diff --git a/src/Illuminate/Mail/MailManager.php b/src/Illuminate/Mail/MailManager.php index 3d1c235efae6..cba62f2a9abe 100644 --- a/src/Illuminate/Mail/MailManager.php +++ b/src/Illuminate/Mail/MailManager.php @@ -2,17 +2,16 @@ namespace Illuminate\Mail; -use Aws\SesV2\SesV2Client; use Closure; use Illuminate\Contracts\Mail\Factory as FactoryContract; use Illuminate\Log\LogManager; use Illuminate\Mail\Transport\ArrayTransport; use Illuminate\Mail\Transport\LogTransport; -use Illuminate\Mail\Transport\SesTransport; use Illuminate\Support\Arr; use Illuminate\Support\Str; use InvalidArgumentException; use Psr\Log\LoggerInterface; +use Symfony\Component\Mailer\Bridge\Amazon\Transport\SesTransportFactory; use Symfony\Component\Mailer\Bridge\Mailgun\Transport\MailgunTransportFactory; use Symfony\Component\Mailer\Bridge\Postmark\Transport\PostmarkTransportFactory; use Symfony\Component\Mailer\Transport\Dsn; @@ -237,33 +236,16 @@ protected function createSendmailTransport(array $config) */ protected function createSesTransport(array $config) { - $config = array_merge( - $this->app['config']->get('services.ses', []), - ['version' => 'latest', 'service' => 'email'], - $config - ); - - $config = Arr::except($config, ['transport']); - - return new SesTransport( - new SesV2Client($this->addSesCredentials($config)), - $config['options'] ?? [] - ); - } + $factory = new SesTransportFactory(); - /** - * Add the SES credentials to the configuration array. - * - * @param array $config - * @return array - */ - protected function addSesCredentials(array $config) - { - if (! empty($config['key']) && ! empty($config['secret'])) { - $config['credentials'] = Arr::only($config, ['key', 'secret', 'token']); - } - - return $config; + return $factory->create(new Dsn( + 'ses+api', + 'default', + $config['key'], + $config['secret'], + $config['port'] ?? null, + $config + )); } /** diff --git a/src/Illuminate/Mail/Transport/SesTransport.php b/src/Illuminate/Mail/Transport/SesTransport.php deleted file mode 100644 index cae80810fd20..000000000000 --- a/src/Illuminate/Mail/Transport/SesTransport.php +++ /dev/null @@ -1,94 +0,0 @@ -ses = $ses; - $this->options = $options; - } - - /** - * {@inheritdoc} - */ - public function send(Swift_Mime_SimpleMessage $message, &$failedRecipients = null) - { - $this->beforeSendPerformed($message); - - $result = $this->ses->sendEmail( - array_merge( - $this->options, [ - 'Content' => [ - 'Raw' => ['Data' => $message->toString()], - ], - ] - ) - ); - - $messageId = $result->get('MessageId'); - - $message->getHeaders()->addTextHeader('X-Message-ID', $messageId); - $message->getHeaders()->addTextHeader('X-SES-Message-ID', $messageId); - - $this->sendPerformed($message); - - return $this->numberOfRecipients($message); - } - - /** - * Get the Amazon SES client for the SesTransport instance. - * - * @return \Aws\SesV2\SesV2Client - */ - public function ses() - { - return $this->ses; - } - - /** - * Get the transmission options being used by the transport. - * - * @return array - */ - public function getOptions() - { - return $this->options; - } - - /** - * Set the transmission options being used by the transport. - * - * @param array $options - * @return array - */ - public function setOptions(array $options) - { - return $this->options = $options; - } -} diff --git a/src/Illuminate/Mail/composer.json b/src/Illuminate/Mail/composer.json index 6c0439c3d86f..4f45de3a3dac 100755 --- a/src/Illuminate/Mail/composer.json +++ b/src/Illuminate/Mail/composer.json @@ -37,9 +37,9 @@ } }, "suggest": { - "aws/aws-sdk-php": "Required to use the SES mail driver (^3.189.0).", - "symfony/http-client": "Required to use the Mailgun mail driver (^6.0).", - "symfony/mailgun-mailer": "Required to enable support for the Mailgun mail driver (^6.0).", + "symfony/amazon-mailer": "Required to enable support for the SES mail transport (^6.0).", + "symfony/http-client": "Required to use the Symfony mail transports (^6.0).", + "symfony/mailgun-mailer": "Required to enable support for the Mailgun mail transport (^6.0).", "symfony/postmark-mailer": "Required to enable support for the Postmark mail transport (^6.0)." }, "config": { From 8e87678a9d89949b7a79c09c2f98015c0a399400 Mon Sep 17 00:00:00 2001 From: Dries Vints Date: Mon, 30 Aug 2021 17:46:25 +0200 Subject: [PATCH 25/37] Remove transports from dev dependencies --- composer.json | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/composer.json b/composer.json index be43c75dedf7..6be3ed4d453a 100644 --- a/composer.json +++ b/composer.json @@ -91,10 +91,7 @@ "phpstan/phpstan": "^0.12.94", "phpunit/phpunit": "^9.4", "predis/predis": "^1.1.2", - "symfony/amazon-mailer": "^6.0", - "symfony/cache": "^6.0", - "symfony/mailgun-mailer": "^6.0", - "symfony/postmark-mailer": "^6.0" + "symfony/cache": "^6.0" }, "provide": { "psr/container-implementation": "1.0" From 3c1d1dcb2f2551020dcf67d62f053bd0c1533dee Mon Sep 17 00:00:00 2001 From: Dries Vints Date: Thu, 2 Sep 2021 16:06:10 +0200 Subject: [PATCH 26/37] Allow setting options on esmtp transport --- src/Illuminate/Mail/MailManager.php | 30 ++++++++++------------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/src/Illuminate/Mail/MailManager.php b/src/Illuminate/Mail/MailManager.php index cba62f2a9abe..5cddf0ac93b7 100644 --- a/src/Illuminate/Mail/MailManager.php +++ b/src/Illuminate/Mail/MailManager.php @@ -18,6 +18,7 @@ use Symfony\Component\Mailer\Transport\FailoverTransport; use Symfony\Component\Mailer\Transport\SendmailTransport; use Symfony\Component\Mailer\Transport\Smtp\EsmtpTransport; +use Symfony\Component\Mailer\Transport\Smtp\EsmtpTransportFactory; use Symfony\Component\Mailer\Transport\Smtp\Stream\SocketStream; /** @@ -166,23 +167,16 @@ public function createSymfonyTransport(array $config) */ protected function createSmtpTransport(array $config) { - // The Symfony ESMTP transport instance will allow use of any SMTP backend - // for delivering mail such as Sendgrid, Amazon SES, or a custom server - // a developer has available. We will just pass this configured host. - $transport = new EsmtpTransport( - $config['host'], - $config['port'], - ! empty($config['encryption']) && $config['encryption'] === 'tls' ? true : null - ); - - // Once we have the transport we will check for the presence of a username - // and password. If we have it we'll set the credentials on the Symfony - // transporter instance so that we'll properly authenticate delivery. - if (isset($config['username'])) { - $transport->setUsername($config['username']); + $factory = new EsmtpTransportFactory; - $transport->setPassword($config['password']); - } + $transport = $factory->create(new Dsn( + ! empty($config['encryption']) && $config['encryption'] === 'tls' ? 'smtps' : '', + $config['host'], + $config['username'] ?? null, + $config['password'] ?? null, + $config['port'] ?? null, + $config + )); return $this->configureSmtpTransport($transport, $config); } @@ -208,10 +202,6 @@ protected function configureSmtpTransport(EsmtpTransport $transport, array $conf } } - if (isset($config['local_domain'])) { - $transport->setLocalDomain($config['local_domain']); - } - return $transport; } From 66bbe6a9d5624c44d4461d30b84dbf4e46e6d399 Mon Sep 17 00:00:00 2001 From: Dries Vints Date: Fri, 3 Sep 2021 22:25:42 +0200 Subject: [PATCH 27/37] Fix Postmark transport --- src/Illuminate/Mail/MailManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Illuminate/Mail/MailManager.php b/src/Illuminate/Mail/MailManager.php index 5cddf0ac93b7..c2a4f58309fe 100644 --- a/src/Illuminate/Mail/MailManager.php +++ b/src/Illuminate/Mail/MailManager.php @@ -283,7 +283,7 @@ protected function createPostmarkTransport(array $config) return $factory->create(new Dsn( 'postmark+api', 'default', - $config['token'] + $config['token'] ?? $this->app['config']->get('services.postmark.token') )); } From c2c97dad748651d2878fee55792a5873e6016d25 Mon Sep 17 00:00:00 2001 From: Dries Vints Date: Fri, 3 Sep 2021 22:26:14 +0200 Subject: [PATCH 28/37] Fix embedding files --- src/Illuminate/Mail/Message.php | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/Illuminate/Mail/Message.php b/src/Illuminate/Mail/Message.php index 706519ec7789..6dc2badf7423 100755 --- a/src/Illuminate/Mail/Message.php +++ b/src/Illuminate/Mail/Message.php @@ -2,6 +2,7 @@ namespace Illuminate\Mail; +use Illuminate\Support\Str; use Illuminate\Support\Traits\ForwardsCalls; use Symfony\Component\Mime\Address; use Symfony\Component\Mime\Email; @@ -243,20 +244,22 @@ public function attachData($data, $name, array $options = []) } /** - * Embed a file in the message. + * Embed a file in the message and get the CID. * * @param string $file - * @return $this + * @return string */ public function embed($file) { - $this->message->embedFromPath($file); + $cid = Str::random(10); - return $this; + $this->message->embedFromPath($file, $cid); + + return "cid:$cid"; } /** - * Embed in-memory data in the message. + * Embed in-memory data in the message and get the CID. * * @param string $data * @param string $name @@ -267,7 +270,7 @@ public function embedData($data, $name, $contentType = null) { $this->message->embed($data, $name, $contentType); - return $this; + return "cid:$name"; } /** From 8724b1f83ea280b41edad068a61794b4de369ea2 Mon Sep 17 00:00:00 2001 From: Dries Vints Date: Fri, 3 Sep 2021 22:27:22 +0200 Subject: [PATCH 29/37] Clarify API transports --- composer.json | 2 +- src/Illuminate/Mail/composer.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 6be3ed4d453a..0b705afe0d47 100644 --- a/composer.json +++ b/composer.json @@ -155,7 +155,7 @@ "symfony/amazon-mailer": "Required to enable support for the SES mail transport (^6.0).", "symfony/cache": "Required to PSR-6 cache bridge (^6.0).", "symfony/filesystem": "Required to enable support for relative symbolic links (^6.0).", - "symfony/http-client": "Required to enable support for the Symfony mail transports (^6.0).", + "symfony/http-client": "Required to enable support for the Symfony API mail transports (^6.0).", "symfony/mailgun-mailer": "Required to enable support for the Mailgun mail transport (^6.0).", "symfony/postmark-mailer": "Required to enable support for the Postmark mail transport (^6.0).", "symfony/psr-http-message-bridge": "Required to use PSR-7 bridging features (^2.0)." diff --git a/src/Illuminate/Mail/composer.json b/src/Illuminate/Mail/composer.json index 4f45de3a3dac..a5de844a8a33 100755 --- a/src/Illuminate/Mail/composer.json +++ b/src/Illuminate/Mail/composer.json @@ -38,7 +38,7 @@ }, "suggest": { "symfony/amazon-mailer": "Required to enable support for the SES mail transport (^6.0).", - "symfony/http-client": "Required to use the Symfony mail transports (^6.0).", + "symfony/http-client": "Required to use the Symfony API mail transports (^6.0).", "symfony/mailgun-mailer": "Required to enable support for the Mailgun mail transport (^6.0).", "symfony/postmark-mailer": "Required to enable support for the Postmark mail transport (^6.0)." }, From d61b7a9f34e371acd7802836943ef92f21e18811 Mon Sep 17 00:00:00 2001 From: Taylor Otwell Date: Tue, 7 Sep 2021 14:52:55 +0000 Subject: [PATCH 30/37] Apply fixes from StyleCI --- src/Illuminate/Mail/Message.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Illuminate/Mail/Message.php b/src/Illuminate/Mail/Message.php index 6dc2badf7423..e225da983963 100755 --- a/src/Illuminate/Mail/Message.php +++ b/src/Illuminate/Mail/Message.php @@ -172,7 +172,7 @@ protected function addAddresses($address, $name, $type) if (is_array($address)) { $type = lcfirst($type); - $addresses = collect($address)->map(function (string | array $address) { + $addresses = collect($address)->map(function (string|array $address) { if (is_array($address)) { return new Address($address['email'] ?? $address['address'], $address['name'] ?? null); } From eb24e34de9e8c04a9fd288b415cb7d949643cd55 Mon Sep 17 00:00:00 2001 From: Dries Vints Date: Wed, 8 Sep 2021 17:35:02 +0200 Subject: [PATCH 31/37] Fix SES transport setup --- src/Illuminate/Mail/MailManager.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Illuminate/Mail/MailManager.php b/src/Illuminate/Mail/MailManager.php index c2a4f58309fe..f901975e23bb 100644 --- a/src/Illuminate/Mail/MailManager.php +++ b/src/Illuminate/Mail/MailManager.php @@ -226,6 +226,14 @@ protected function createSendmailTransport(array $config) */ protected function createSesTransport(array $config) { + $config = array_merge( + $this->app['config']->get('services.ses', []), + ['version' => 'latest', 'service' => 'email'], + $config + ); + + $config = Arr::except($config, ['transport']); + $factory = new SesTransportFactory(); return $factory->create(new Dsn( From d6fc4202bf7cda6c46de8ef256e660d21ed47eb2 Mon Sep 17 00:00:00 2001 From: Julius Kiekbusch Date: Fri, 10 Sep 2021 17:39:10 +0200 Subject: [PATCH 32/37] Add MessageStreamId to Postmark Transport again (#38748) --- src/Illuminate/Mail/MailManager.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/Illuminate/Mail/MailManager.php b/src/Illuminate/Mail/MailManager.php index f901975e23bb..61fa39d216aa 100644 --- a/src/Illuminate/Mail/MailManager.php +++ b/src/Illuminate/Mail/MailManager.php @@ -288,10 +288,17 @@ protected function createPostmarkTransport(array $config) { $factory = new PostmarkTransportFactory(); + $options = isset($config['message_stream_id']) + ? ['message_stream' => $config['message_stream_id']] + : []; + return $factory->create(new Dsn( 'postmark+api', 'default', - $config['token'] ?? $this->app['config']->get('services.postmark.token') + $config['token'] ?? $this->app['config']->get('services.postmark.token'), + null, + null, + $options )); } From c63ade9139f16cea57de5a489269fdd379314e6c Mon Sep 17 00:00:00 2001 From: Julius Kiekbusch Date: Sun, 12 Sep 2021 19:35:05 +0200 Subject: [PATCH 33/37] Update symfony mailer docblocks (#38773) * Update docblocks from Swift Mailer to Symfony Mailer * Make TransportInterface more specific --- src/Illuminate/Mail/MailManager.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Illuminate/Mail/MailManager.php b/src/Illuminate/Mail/MailManager.php index 61fa39d216aa..510b49d1a12c 100644 --- a/src/Illuminate/Mail/MailManager.php +++ b/src/Illuminate/Mail/MailManager.php @@ -219,10 +219,10 @@ protected function createSendmailTransport(array $config) } /** - * Create an instance of the Amazon SES Swift Transport driver. + * Create an instance of the Symfony Amazon SES Transport driver. * * @param array $config - * @return \Illuminate\Mail\Transport\SesTransport + * @return \Symfony\Component\Mailer\Bridge\Amazon\Transport\SesApiAsyncAwsTransport */ protected function createSesTransport(array $config) { @@ -257,10 +257,10 @@ protected function createMailTransport() } /** - * Create an instance of the Mailgun Swift Transport driver. + * Create an instance of the Symfony Mailgun Transport driver. * * @param array $config - * @return \Symfony\Component\Mailer\Transport\TransportInterface + * @return \Symfony\Component\Mailer\Bridge\Mailgun\Transport\MailgunApiTransport */ protected function createMailgunTransport(array $config) { @@ -279,10 +279,10 @@ protected function createMailgunTransport(array $config) } /** - * Create an instance of the Postmark Swift Transport driver. + * Create an instance of the Symfony Postmark Transport driver. * * @param array $config - * @return \Swift_Transport + * @return \Symfony\Component\Mailer\Bridge\Postmark\Transport\PostmarkApiTransport */ protected function createPostmarkTransport(array $config) { From 78dccf185e35b032060c9a118f5b2520f32189ae Mon Sep 17 00:00:00 2001 From: Julius Kiekbusch Date: Mon, 13 Sep 2021 18:09:42 +0200 Subject: [PATCH 34/37] Add Session Token to SES Transport (#38797) --- src/Illuminate/Mail/MailManager.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Illuminate/Mail/MailManager.php b/src/Illuminate/Mail/MailManager.php index 510b49d1a12c..5b546738365d 100644 --- a/src/Illuminate/Mail/MailManager.php +++ b/src/Illuminate/Mail/MailManager.php @@ -236,6 +236,10 @@ protected function createSesTransport(array $config) $factory = new SesTransportFactory(); + if (! isset($config['session_token']) && isset($config['token'])) { + $config['session_token'] = $config['token']; + } + return $factory->create(new Dsn( 'ses+api', 'default', From 5e1baff7eabacffeeb7db98f80ef423fb2702c73 Mon Sep 17 00:00:00 2001 From: Taylor Otwell Date: Mon, 13 Sep 2021 17:04:43 -0500 Subject: [PATCH 35/37] Update src/Illuminate/Mail/Transport/ArrayTransport.php Co-authored-by: Julius Kiekbusch --- src/Illuminate/Mail/Transport/ArrayTransport.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Illuminate/Mail/Transport/ArrayTransport.php b/src/Illuminate/Mail/Transport/ArrayTransport.php index cd7ce976109d..6e1a499861ad 100644 --- a/src/Illuminate/Mail/Transport/ArrayTransport.php +++ b/src/Illuminate/Mail/Transport/ArrayTransport.php @@ -56,7 +56,7 @@ public function flush() } /** - * Get the string representation of the message. + * Get the string representation of the transport driver. * * @return string */ From e23e57ecdf7b353a582c4cd3bc22cb8fe5bbb8f6 Mon Sep 17 00:00:00 2001 From: Taylor Otwell Date: Mon, 13 Sep 2021 17:05:02 -0500 Subject: [PATCH 36/37] fix docblock --- src/Illuminate/Mail/Transport/ArrayTransport.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Illuminate/Mail/Transport/ArrayTransport.php b/src/Illuminate/Mail/Transport/ArrayTransport.php index 6e1a499861ad..dc26ed69d90b 100644 --- a/src/Illuminate/Mail/Transport/ArrayTransport.php +++ b/src/Illuminate/Mail/Transport/ArrayTransport.php @@ -56,7 +56,7 @@ public function flush() } /** - * Get the string representation of the transport driver. + * Get the string representation of the transport. * * @return string */ From c8d16545df39de602d61998bdeb9326521e0bd9c Mon Sep 17 00:00:00 2001 From: Julius Kiekbusch Date: Tue, 14 Sep 2021 11:31:30 +0200 Subject: [PATCH 37/37] Add Wrapper for Symfony SentMessage (#38803) * Create SentMessage wrapper for Symfony's SentMessage * Wrap Symfony SentMessage * Update Docblocks to Illuminate\Mail\SentMessage * Fix sendMailable * Update SentMessage.php Co-authored-by: Dries Vints --- src/Illuminate/Mail/Mailable.php | 2 +- src/Illuminate/Mail/Mailer.php | 12 +++--- src/Illuminate/Mail/SentMessage.php | 54 +++++++++++++++++++++++++ src/Illuminate/Support/Facades/Mail.php | 8 ++-- 4 files changed, 65 insertions(+), 11 deletions(-) create mode 100644 src/Illuminate/Mail/SentMessage.php diff --git a/src/Illuminate/Mail/Mailable.php b/src/Illuminate/Mail/Mailable.php index ccd52802f4c6..b37d47531559 100644 --- a/src/Illuminate/Mail/Mailable.php +++ b/src/Illuminate/Mail/Mailable.php @@ -167,7 +167,7 @@ class Mailable implements MailableContract, Renderable * Send the message using the given mailer. * * @param \Illuminate\Contracts\Mail\Factory|\Illuminate\Contracts\Mail\Mailer $mailer - * @return \Symfony\Component\Mailer\SentMessage|null + * @return \Illuminate\Mail\SentMessage|null */ public function send($mailer) { diff --git a/src/Illuminate/Mail/Mailer.php b/src/Illuminate/Mail/Mailer.php index e91d5ee38f74..7ca202c3ae79 100755 --- a/src/Illuminate/Mail/Mailer.php +++ b/src/Illuminate/Mail/Mailer.php @@ -188,7 +188,7 @@ public function bcc($users) * * @param string $html * @param mixed $callback - * @return \Symfony\Component\Mailer\SentMessage|null + * @return \Illuminate\Mail\SentMessage|null */ public function html($html, $callback) { @@ -200,7 +200,7 @@ public function html($html, $callback) * * @param string $text * @param mixed $callback - * @return \Symfony\Component\Mailer\SentMessage|null + * @return \Illuminate\Mail\SentMessage|null */ public function raw($text, $callback) { @@ -213,7 +213,7 @@ public function raw($text, $callback) * @param string $view * @param array $data * @param mixed $callback - * @return \Symfony\Component\Mailer\SentMessage|null + * @return \Illuminate\Mail\SentMessage|null */ public function plain($view, array $data, $callback) { @@ -245,7 +245,7 @@ public function render($view, array $data = []) * @param \Illuminate\Contracts\Mail\Mailable|string|array $view * @param array $data * @param \Closure|string|null $callback - * @return \Symfony\Component\Mailer\SentMessage|null + * @return \Illuminate\Mail\SentMessage|null */ public function send($view, array $data = [], $callback = null) { @@ -286,7 +286,7 @@ public function send($view, array $data = [], $callback = null) $this->dispatchSentEvent($message, $data); - return $sentMessage; + return $sentMessage === null ? null : new SentMessage($sentMessage); } } @@ -294,7 +294,7 @@ public function send($view, array $data = [], $callback = null) * Send the given mailable. * * @param \Illuminate\Contracts\Mail\Mailable $mailable - * @return mixed + * @return \Illuminate\Mail\SentMessage|null */ protected function sendMailable(MailableContract $mailable) { diff --git a/src/Illuminate/Mail/SentMessage.php b/src/Illuminate/Mail/SentMessage.php new file mode 100644 index 000000000000..cce42dbd009f --- /dev/null +++ b/src/Illuminate/Mail/SentMessage.php @@ -0,0 +1,54 @@ +sentMessage = $sentMessage; + } + + /** + * Get the underlying Symfony Email instance. + * + * @return \Symfony\Component\Mailer\SentMessage + */ + public function getSymfonySentMessage() + { + return $this->sentMessage; + } + + /** + * Dynamically pass missing methods to the Symfony instance. + * + * @param string $method + * @param array $parameters + * @return mixed + */ + public function __call($method, $parameters) + { + return $this->forwardCallTo($this->sentMessage, $method, $parameters); + } +} diff --git a/src/Illuminate/Support/Facades/Mail.php b/src/Illuminate/Support/Facades/Mail.php index ad69ed494736..1408480d7768 100755 --- a/src/Illuminate/Support/Facades/Mail.php +++ b/src/Illuminate/Support/Facades/Mail.php @@ -10,10 +10,10 @@ * @method static \Illuminate\Mail\PendingMail to($users) * @method static \Illuminate\Support\Collection queued(string $mailable, \Closure|string $callback = null) * @method static \Illuminate\Support\Collection sent(string $mailable, \Closure|string $callback = null) - * @method static \Symfony\Component\Mailer\SentMessage|null raw(string $text, $callback) - * @method static \Symfony\Component\Mailer\SentMessage|null plain(string $view, array $data, $callback) - * @method static \Symfony\Component\Mailer\SentMessage|null html(string $html, $callback) - * @method static \Symfony\Component\Mailer\SentMessage|null send(\Illuminate\Contracts\Mail\Mailable|string|array $view, array $data = [], \Closure|string $callback = null) + * @method static \Illuminate\Mail\SentMessage|null raw(string $text, $callback) + * @method static \Illuminate\Mail\SentMessage|null plain(string $view, array $data, $callback) + * @method static \Illuminate\Mail\SentMessage|null html(string $html, $callback) + * @method static \Illuminate\Mail\SentMessage|null send(\Illuminate\Contracts\Mail\Mailable|string|array $view, array $data = [], \Closure|string $callback = null) * @method static array failures() * @method static bool hasQueued(string $mailable) * @method static bool hasSent(string $mailable)