Initial commit
This commit is contained in:
103
app/Mail/BounceAwareMailManager.php
Normal file
103
app/Mail/BounceAwareMailManager.php
Normal file
@@ -0,0 +1,103 @@
|
||||
<?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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user