126 lines
4.1 KiB
PHP
126 lines
4.1 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use PHPMailer\PHPMailer\Exception as MailException;
|
|
use PHPMailer\PHPMailer\PHPMailer;
|
|
|
|
class MailService
|
|
{
|
|
/**
|
|
* @param string|array<int|string, string|array{address:string,name?:string}> $to
|
|
* @param array<int|string, string|array{address:string,name?:string}> $cc
|
|
* @param array<int|string, string|array{address:string,name?:string}> $bcc
|
|
*/
|
|
public function send($to, string $subject, string $htmlBody, ?string $textBody = null, array $cc = [], array $bcc = []): void
|
|
{
|
|
$config = config('mail');
|
|
$mailer = new PHPMailer(true);
|
|
|
|
$mailer->CharSet = 'UTF-8';
|
|
$mailer->isHTML(true);
|
|
|
|
$driver = strtolower((string)($config['driver'] ?? 'smtp'));
|
|
|
|
if ($driver === 'sendmail') {
|
|
$mailer->isSendmail();
|
|
if (!empty($config['sendmail_path'])) {
|
|
$mailer->Sendmail = $config['sendmail_path'];
|
|
}
|
|
} elseif ($driver === 'mail') {
|
|
$mailer->isMail();
|
|
} else {
|
|
$mailer->isSMTP();
|
|
$mailer->Host = (string)($config['host'] ?? 'localhost');
|
|
$mailer->Port = (int)($config['port'] ?? 25);
|
|
$mailer->Timeout = (int)($config['timeout'] ?? 30);
|
|
|
|
$username = $config['username'] ?? null;
|
|
$password = $config['password'] ?? null;
|
|
if ($username) {
|
|
$mailer->SMTPAuth = true;
|
|
$mailer->Username = $username;
|
|
$mailer->Password = (string)$password;
|
|
} else {
|
|
$mailer->SMTPAuth = false;
|
|
}
|
|
|
|
$encryption = strtolower((string)($config['encryption'] ?? ''));
|
|
if ($encryption === 'ssl') {
|
|
$mailer->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
|
|
} elseif ($encryption === 'tls') {
|
|
$mailer->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
|
|
}
|
|
}
|
|
|
|
$fromAddress = $config['from']['address'] ?? null;
|
|
$fromName = $config['from']['name'] ?? '';
|
|
if ($fromAddress) {
|
|
$mailer->setFrom($fromAddress, $fromName ?: $fromAddress);
|
|
}
|
|
|
|
foreach ($this->normalizeRecipients($to) as $recipient) {
|
|
$mailer->addAddress($recipient['address'], $recipient['name']);
|
|
}
|
|
|
|
foreach ($this->normalizeRecipients($cc) as $recipient) {
|
|
$mailer->addCC($recipient['address'], $recipient['name']);
|
|
}
|
|
|
|
foreach ($this->normalizeRecipients($bcc) as $recipient) {
|
|
$mailer->addBCC($recipient['address'], $recipient['name']);
|
|
}
|
|
|
|
$mailer->Subject = $subject;
|
|
$mailer->Body = $htmlBody;
|
|
$mailer->AltBody = $textBody ?? strip_tags($htmlBody);
|
|
|
|
try {
|
|
$mailer->send();
|
|
} catch (MailException $exception) {
|
|
throw new \RuntimeException('Unable to send mail: ' . $exception->getMessage(), previous: $exception);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param string|array<int|string, string|array{address:string,name?:string}> $addresses
|
|
* @return list<array{address:string,name:string}>
|
|
*/
|
|
private function normalizeRecipients($addresses): array
|
|
{
|
|
if ($addresses === null) {
|
|
return [];
|
|
}
|
|
|
|
if (!is_array($addresses)) {
|
|
return [['address' => (string)$addresses, 'name' => '']];
|
|
}
|
|
|
|
$normalized = [];
|
|
foreach ($addresses as $key => $value) {
|
|
if (is_array($value)) {
|
|
$address = $value['address'] ?? null;
|
|
if (!$address) {
|
|
continue;
|
|
}
|
|
$normalized[] = [
|
|
'address' => (string)$address,
|
|
'name' => (string)($value['name'] ?? ''),
|
|
];
|
|
} elseif (is_string($key) && is_string($value)) {
|
|
$normalized[] = [
|
|
'address' => $key,
|
|
'name' => $value,
|
|
];
|
|
} else {
|
|
$normalized[] = [
|
|
'address' => (string)$value,
|
|
'name' => '',
|
|
];
|
|
}
|
|
}
|
|
|
|
return $normalized;
|
|
}
|
|
}
|