97 lines
3.0 KiB
PHP
97 lines
3.0 KiB
PHP
<?php
|
|
|
|
namespace App\Domains\Mail\Services;
|
|
|
|
use App\Domains\Integration\Models\TenantIntegration;
|
|
use App\Domains\Tenant\Models\Tenant;
|
|
use Illuminate\Contracts\Mail\Factory as MailFactory;
|
|
use Illuminate\Contracts\Mail\Mailable;
|
|
use Illuminate\Contracts\Mail\Mailer;
|
|
use Illuminate\Mail\MailManager;
|
|
use InvalidArgumentException;
|
|
|
|
class MailService
|
|
{
|
|
private const INTEGRATION_CODE = 'email';
|
|
|
|
private const REQUIRED_SMTP_FIELDS = [
|
|
'MAIL_HOST',
|
|
'MAIL_PORT',
|
|
'MAIL_USERNAME',
|
|
'MAIL_PASSWORD',
|
|
'MAIL_FROM_ADDRESS',
|
|
];
|
|
|
|
private readonly MailFactory $mailFactory;
|
|
|
|
private readonly ?TenantIntegration $emailIntegration;
|
|
|
|
private readonly Mailer $mailer;
|
|
|
|
public function __construct(
|
|
private readonly Tenant $tenant,
|
|
?MailFactory $mailFactory = null,
|
|
) {
|
|
$this->mailFactory = $mailFactory ?? app(MailFactory::class);
|
|
$this->emailIntegration = TenantIntegration::query()
|
|
->where('tenant_code', $this->tenant->codigo)
|
|
->where('integration_code', self::INTEGRATION_CODE)
|
|
->first();
|
|
$this->mailer = $this->resolveMailer();
|
|
}
|
|
|
|
public function send(string|array $recipient, Mailable $mail): void
|
|
{
|
|
$this->mailer->to($recipient)->send($mail);
|
|
}
|
|
|
|
public function mailerName(): string
|
|
{
|
|
return $this->emailIntegration ? 'tenant-smtp' : (string) config('mail.default');
|
|
}
|
|
|
|
private function resolveMailer(): Mailer
|
|
{
|
|
if (! $this->emailIntegration) {
|
|
return $this->mailFactory->mailer();
|
|
}
|
|
|
|
// MailFake implements the mail factory contract, but deliberately cannot
|
|
// build transports. Returning it keeps normal Mail::fake() assertions useful.
|
|
if (! $this->mailFactory instanceof MailManager) {
|
|
return $this->mailFactory->mailer();
|
|
}
|
|
|
|
$data = $this->emailIntegration->integration_data;
|
|
|
|
if (! is_array($data)) {
|
|
throw new InvalidArgumentException('La configuración SMTP del tenant no es válida.');
|
|
}
|
|
|
|
foreach (self::REQUIRED_SMTP_FIELDS as $field) {
|
|
if (! array_key_exists($field, $data) || $data[$field] === null || $data[$field] === '') {
|
|
throw new InvalidArgumentException("Falta {$field} en la configuración SMTP del tenant.");
|
|
}
|
|
}
|
|
|
|
$mailer = $this->mailFactory->build([
|
|
'name' => "tenant-smtp-{$this->tenant->codigo}",
|
|
'transport' => 'smtp',
|
|
'scheme' => $data['MAIL_SCHEME'] ?? null,
|
|
'host' => $data['MAIL_HOST'],
|
|
'port' => (int) $data['MAIL_PORT'],
|
|
'username' => $data['MAIL_USERNAME'],
|
|
'password' => $data['MAIL_PASSWORD'],
|
|
'timeout' => isset($data['MAIL_TIMEOUT']) ? (int) $data['MAIL_TIMEOUT'] : null,
|
|
'local_domain' => $data['MAIL_EHLO_DOMAIN'] ?? null,
|
|
]);
|
|
|
|
$mailer->alwaysFrom(
|
|
$data['MAIL_FROM_ADDRESS'],
|
|
$data['MAIL_FROM_NAME'] ?? $this->tenant->nombre,
|
|
);
|
|
|
|
return $mailer;
|
|
}
|
|
}
|