Ci sono momenti in cui potresti voler usare Sendmail invece di servizi come Mailgun, dati i loro prezzi.
Ad esempio, se ordini un VPS su TransIP, al momento della scrittura riceverai 1000 invii di posta gratuiti.
Sfortunatamente, il fallback di Laravel non lo supporta quando Postfix è inattivo. Ecco perché io + GPT abbiamo scritto questo mailer personalizzato.
Crea un file denominato App\Mail\ConditionalTransport.php:
php
<?php
namespace App\Mail;
use Illuminate\Mail\MailManager;
use Illuminate\Support\Facades\Cache;
use Symfony\Component\Mailer\SentMessage;
use Symfony\Component\Mailer\Transport\AbstractTransport;
class ConditionalTransport extends AbstractTransport
{
protected $sendmailTransport;
protected $mailgunTransport;
protected $cacheKey;
/**
* Create a new Conditional transport instance.
*/
public function __construct(MailManager $mailManager)
{
parent::__construct();
$this->cacheKey = 'email_sendmail_count_' . date('Y-m-d');
// Create the sendmail transport
$this->sendmailTransport = $mailManager->createSymfonyTransport(['transport' => 'sendmail']);
// Create the mailgun transport
$this->mailgunTransport = $mailManager->createSymfonyTransport(['transport' => 'mailgun']);
}
/**
* Send the given message.
*
* @param \Symfony\Component\Mailer\SentMessage $message
*/
protected function doSend(SentMessage $message): void
{
// Check if Postfix service is running
if ($this->isPostfixRunning()) {
// Get the current count from cache
$count = Cache::get($this->cacheKey, 0);
if ($count < 1000) {
// Send with Sendmail
$this->sendmailTransport->send($message->getOriginalMessage(), $message->getEnvelope());
// Increment the count
Cache::increment($this->cacheKey);
return;
}
}
// If Postfix is not running or count >= 2000, send with Mailgun
$this->mailgunTransport->send($message->getOriginalMessage(), $message->getEnvelope());
}
/**
* Check if Postfix service is running.
*
* @return bool
*/
protected function isPostfixRunning(): bool
{
$isDisabled = in_array('exec', explode(',', ini_get('disable_functions')));
if ($isDisabled) {
// If exec is disabled, we can't check; assume it's not running
return false;
}
try {
$output = [];
$returnVar = null;
exec('systemctl is-active postfix', $output, $returnVar);
if (isset($output[0]) && trim($output[0]) === 'active') {
return true;
}
} catch (\Exception $e) {
// Handle exception or log error if necessary
}
return false;
}
/**
* Get the string representation of the transport.
*/
public function __toString(): string
{
return 'conditional';
}
}
Successivamente, registra il tuo trasporto personalizzato all'interno del metodo di avvio della tua applicazione App\Provider\AppServiceProvider fornitore di servizi:
php usa App\Mail\ConditionalTransport; usa Illuminate\Mail\MailManager; usa Illuminate\Support\Facades\Mail; /** * Avvia tutti i servizi dell'applicazione. */ public function boot(): void { Mail::extend('conditional', function (array $config = []) { return new ConditionalTransport(app(MailManager::class)); }); }
Quindi, aggiungi una nuova definizione di mailer alla tua applicazione configurazione/mail.php file di configurazione che utilizza il nuovo trasporto:
php 'mailers' => [ // Altri mailer... 'conditional' => [ 'transport' => 'conditional', ], ],
Con questa configurazione, la tua applicazione Laravel utilizzerà il driver sendmail per inviare email se il servizio Postfix è in esecuzione e il limite giornaliero non è stato raggiunto. Una volta superato il limite o se Postfix non è in esecuzione, passerà automaticamente al driver Mailgun.
Note:
- IL
èPostfixIn esecuzioneil metodo verifica se il servizio Postfix è in esecuzione utilizzandoesecutivofunzione da chiamaresystemctl è-attivo postfissoAdatta questo metodo se il tuo ambiente utilizza un modo diverso per gestire i servizi o se exec è disabilitato. - Il conteggio delle email viene memorizzato nella cache utilizzando la facciata Cache di Laravel con una chiave che include la data corrente (utilizzando il formato Ymd).
- Assicurati che le configurazioni di sendmail e mailgun siano impostate correttamente nel tuo
configurazione/mail.phpfile.
Questa implementazione rispetta la documentazione di Laravel sui trasporti personalizzati e dovrebbe adattarsi perfettamente alla tua applicazione.
Seleziona Mailgun come alternativa, ma puoi anche specificare altri driver se lo desideri.
Attualmente il limite è di 1000 invii al giorno, ma puoi modificarlo in base alla frequenza che preferisci.
Testato con Laravel 10. Ovviamente, usatelo a vostro rischio e pericolo :).
Ultimo aggiornamento il 21 ottobre 2024
