Aufgrund der höheren Preise möchten Sie manchmal lieber sendmail als Dienste wie Mailgun verwenden.
Wenn Sie beispielsweise bei TransIP einen VPS bestellen, erhalten Sie zum Zeitpunkt des Schreibens 1.000 kostenlose E-Mail-Sendungen.
Leider unterstützt Laravels Fallback dies nicht, wenn Postfix ausgefallen ist. Aus diesem Grund habe ich + GPT diesen benutzerdefinierten Mailer geschrieben.
Erstellen Sie eine Datei mit dem Namen 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';
}
}
Als nächstes registrieren Sie Ihren benutzerdefinierten Transport in der Boot-Methode Ihrer Anwendung. App\Anbieter\AppServiceProvider
Dienstanbieter:
php verwende App\Mail\ConditionalTransport; verwende Illuminate\Mail\MailManager; verwende Illuminate\Support\Facades\Mail; /** * Bootstrap aller Anwendungsdienste. */ public function boot(): void { Mail::extend('conditional', function (array $config = []) { return new ConditionalTransport(app(MailManager::class)); }); }
Fügen Sie dann eine neue Mailer-Definition zu Ihrer Anwendung hinzu. config/mail.php
Konfigurationsdatei, die das neue Transportmittel nutzt:
php 'mailers' => [ // Andere Mailer... 'conditional' => [ 'transport' => 'conditional', ], ],
Mit dieser Konfiguration verwendet Ihre Laravel-Anwendung den Sendmail-Treiber zum Senden von E-Mails, wenn der Postfix-Dienst ausgeführt wird und das Tageslimit nicht erreicht wurde. Sobald das Limit überschritten wird oder Postfix nicht ausgeführt wird, wird automatisch zum Mailgun-Treiber gewechselt.
Hinweise:
- Die
isPostfixRunning
Methode prüft, ob der Postfix-Dienst läuft, indem sie denAusführung
aufzurufende Funktionsystemctl ist aktiv Postfix
. Passen Sie diese Methode an, wenn Ihre Umgebung eine andere Methode zur Verwaltung von Diensten verwendet oder wenn „exec“ deaktiviert ist. - Die Anzahl der E-Mails wird mithilfe der Cache-Fassade von Laravel mit einem Schlüssel zwischengespeichert, der das aktuelle Datum enthält (unter Verwendung des Ymd-Formats).
- Stellen Sie sicher, dass Ihre Sendmail- und Mailgun-Konfigurationen in Ihrem
config/mail.php
Datei.
Diese Implementierung entspricht der Laravel-Dokumentation zu benutzerdefinierten Transporten und sollte nahtlos in Ihre Anwendung passen.
Als Alternative wird Mailgun ausgewählt, Sie können aber auch andere Treiber angeben, wenn Sie möchten.
Derzeit ist das Limit auf 1.000 Sendungen pro Tag festgelegt, Sie können es jedoch auf die von Ihnen gewünschte Häufigkeit ändern.
Getestet mit Laravel 10. Verwendung natürlich auf eigene Gefahr :).