103 lines
3.1 KiB
PHP
103 lines
3.1 KiB
PHP
<?php
|
|
|
|
namespace App\Mail;
|
|
|
|
use App\Models\MailingBounce;
|
|
use Illuminate\Mail\MailManager;
|
|
use Illuminate\Mail\PendingMail;
|
|
use Illuminate\Support\Facades\Log;
|
|
|
|
class BounceAwareMailManager extends MailManager
|
|
{
|
|
/**
|
|
* Begin the process of mailing a mailable class instance with bounce checking
|
|
*/
|
|
public function to($users, $name = null)
|
|
{
|
|
$pendingMail = new BounceAwarePendingMail($this);
|
|
return $pendingMail->to($users, $name);
|
|
}
|
|
|
|
/**
|
|
* Send a mailable with bounce suppression checking
|
|
*/
|
|
public function send($view, array $data = [], $callback = null)
|
|
{
|
|
// If this is called directly with a mailable, we need to intercept
|
|
if (is_object($view) && method_exists($view, 'build')) {
|
|
return $this->sendWithBounceCheck($view);
|
|
}
|
|
|
|
return parent::send($view, $data, $callback);
|
|
}
|
|
|
|
/**
|
|
* Send mailable with bounce checking
|
|
*/
|
|
protected function sendWithBounceCheck($mailable)
|
|
{
|
|
// Extract recipient email addresses
|
|
$recipients = $this->extractRecipients($mailable);
|
|
|
|
// Filter out suppressed emails
|
|
$filteredRecipients = [];
|
|
foreach ($recipients as $recipient) {
|
|
$email = is_string($recipient) ? $recipient : ($recipient['address'] ?? $recipient->email ?? null);
|
|
|
|
if ($email && MailingBounce::isSuppressed($email)) {
|
|
Log::info("Email sending blocked for suppressed address: {$email}", [
|
|
'mailable_class' => get_class($mailable),
|
|
'suppressed' => true
|
|
]);
|
|
continue;
|
|
}
|
|
|
|
$filteredRecipients[] = $recipient;
|
|
}
|
|
|
|
// If all recipients are suppressed, don't send
|
|
if (empty($filteredRecipients)) {
|
|
Log::info("All recipients suppressed, skipping email send", [
|
|
'mailable_class' => get_class($mailable),
|
|
'original_recipients' => count($recipients),
|
|
'suppressed_count' => count($recipients)
|
|
]);
|
|
return;
|
|
}
|
|
|
|
// Update mailable recipients
|
|
$this->updateMailableRecipients($mailable, $filteredRecipients);
|
|
|
|
// Add bounce tracking if the mailable supports it
|
|
if (method_exists($mailable, 'configureBounceTracking') || in_array('App\Mail\Concerns\TracksBounces', class_uses_recursive($mailable))) {
|
|
$mailable->configureBounceTracking = true;
|
|
}
|
|
|
|
return parent::send($mailable);
|
|
}
|
|
|
|
/**
|
|
* Extract recipient email addresses from mailable
|
|
*/
|
|
protected function extractRecipients($mailable): array
|
|
{
|
|
$recipients = [];
|
|
|
|
// Get recipients from the mailable's to property
|
|
if (property_exists($mailable, 'to') && $mailable->to) {
|
|
$recipients = array_merge($recipients, $mailable->to);
|
|
}
|
|
|
|
return $recipients;
|
|
}
|
|
|
|
/**
|
|
* Update mailable recipients after filtering
|
|
*/
|
|
protected function updateMailableRecipients($mailable, array $filteredRecipients): void
|
|
{
|
|
if (property_exists($mailable, 'to')) {
|
|
$mailable->to = $filteredRecipients;
|
|
}
|
|
}
|
|
} |