Files
timebank-cc-public/app/Mail/BounceAwarePendingMail.php
Ronald Huynen 2547717edb Initial commit
2026-03-23 21:37:59 +01:00

130 lines
3.7 KiB
PHP

<?php
namespace App\Mail;
use App\Models\MailingBounce;
use Illuminate\Mail\PendingMail;
use Illuminate\Support\Facades\Log;
class BounceAwarePendingMail extends PendingMail
{
/**
* Send a new mailable message instance with bounce checking
*/
public function send($mailable)
{
// Filter out suppressed recipients before sending
$this->filterSuppressedRecipients();
// If no valid recipients remain, don't send
if (empty($this->to) && empty($this->cc) && empty($this->bcc)) {
Log::info("All recipients suppressed, skipping email send", [
'mailable_class' => get_class($mailable)
]);
return;
}
// Add bounce tracking headers if the mailable supports it
if (method_exists($mailable, 'configureBounceTracking') || $this->usesBounceTrackingTrait($mailable)) {
$this->addBounceTrackingToMailable($mailable);
}
return parent::send($mailable);
}
/**
* Queue a new e-mail message for sending with bounce checking
*/
public function queue($mailable)
{
// Filter out suppressed recipients before queuing
$this->filterSuppressedRecipients();
// If no valid recipients remain, don't queue
if (empty($this->to) && empty($this->cc) && empty($this->bcc)) {
Log::info("All recipients suppressed, skipping email queue", [
'mailable_class' => get_class($mailable)
]);
return;
}
// Add bounce tracking headers if the mailable supports it
if (method_exists($mailable, 'configureBounceTracking') || $this->usesBounceTrackingTrait($mailable)) {
$this->addBounceTrackingToMailable($mailable);
}
return parent::queue($mailable);
}
/**
* Filter out suppressed email addresses from recipients
*/
protected function filterSuppressedRecipients(): void
{
$this->to = $this->filterRecipientList($this->to);
$this->cc = $this->filterRecipientList($this->cc);
$this->bcc = $this->filterRecipientList($this->bcc);
}
/**
* Filter a specific recipient list
*/
protected function filterRecipientList(array $recipients): array
{
$filtered = [];
foreach ($recipients as $recipient) {
$email = $this->extractEmailAddress($recipient);
if ($email && MailingBounce::isSuppressed($email)) {
Log::info("Email sending blocked for suppressed address: {$email}", [
'suppressed' => true
]);
continue;
}
$filtered[] = $recipient;
}
return $filtered;
}
/**
* Extract email address from recipient
*/
protected function extractEmailAddress($recipient): ?string
{
if (is_string($recipient)) {
return $recipient;
}
if (is_array($recipient)) {
return $recipient['address'] ?? null;
}
if (is_object($recipient)) {
return $recipient->email ?? null;
}
return null;
}
/**
* Check if mailable uses the bounce tracking trait
*/
protected function usesBounceTrackingTrait($mailable): bool
{
return in_array('App\Mail\Concerns\TracksBounces', class_uses_recursive($mailable));
}
/**
* Add bounce tracking to mailable
*/
protected function addBounceTrackingToMailable($mailable): void
{
// Mark that bounce tracking should be enabled
if (property_exists($mailable, 'bounceTrackingEnabled')) {
$mailable->bounceTrackingEnabled = true;
}
}
}