delegate()->send($message, $envelope); } public function __toString(): string { return 'mailbox://'.$this->purpose.'/'.($this->describe() ?? 'unconfigured'); } /** What this transport currently points at — used by __toString and tests. */ private function describe(): ?string { if ($this->isLogging()) { return 'log'; } return app(MailboxResolver::class)->for($this->purpose)?->address; } /** * Delivery is off wherever the default mailer is the log. * * This is what keeps a development machine from mailing real customers: the * mailables name a purpose, so without this check they would bypass * MAIL_MAILER=log entirely and send for real. */ private function isLogging(): bool { return config('mail.default') === 'log'; } private function delegate(): TransportInterface { if ($this->isLogging()) { return new LogTransport(Log::channel(config('mail.mailers.log.channel'))); } $box = app(MailboxResolver::class)->for($this->purpose); if ($box === null || ! $box->isConfigured()) { // Loud, not silent: a mail with no mailbox behind it must not look // like it was sent. throw new \RuntimeException( "No configured mailbox for mail purpose [{$this->purpose}]." ); } $host = (string) Settings::get('mail.host', ''); $port = (int) Settings::get('mail.port', 587); $encryption = (string) Settings::get('mail.encryption', 'tls'); $fingerprint = md5(implode('|', [ $host, $port, $encryption, $box->smtpUsername(), (string) $box->password, ])); if ($this->delegate === null || $this->fingerprint !== $fingerprint) { // The third argument is IMPLICIT TLS (smtps, port 465) — not // STARTTLS. EsmtpTransport negotiates STARTTLS by itself on a // plain connection, which is what port 587 wants. Passing true for // 'tls' here would open an SSL socket against a server expecting // STARTTLS and hang. $transport = new EsmtpTransport($host, $port, $encryption === 'ssl' || $port === 465); $transport->setUsername($box->smtpUsername()); $transport->setPassword((string) $box->password); $this->delegate = $transport; $this->fingerprint = $fingerprint; } return $this->delegate; } }