Il y a des moments où vous aimeriez utiliser sendmail plutôt que des services comme Mailgun, compte tenu de leur prix.
Par exemple, lorsque vous commandez un VPS chez TransIP, ils vous offriront 1000 envois de courrier gratuits au moment de la rédaction.
Malheureusement, la solution de secours de Laravel ne le prend pas en charge lorsque Postfix est en panne. C'est pourquoi j'ai écrit ce mailer personnalisé avec GPT.
Créez un fichier nommé 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';
}
}
Ensuite, enregistrez votre transport personnalisé dans la méthode de démarrage de votre application. App\Fournisseurs\AppServiceProvider
prestataire de services:
php utilise App\Mail\ConditionalTransport; utilise Illuminate\Mail\MailManager; utilise Illuminate\Support\Facades\Mail; /** * Amorce tous les services d'application. */ public function boot(): void { Mail::extend('conditional', function (array $config = []) { return new ConditionalTransport(app(MailManager::class)); }); }
Ensuite, ajoutez une nouvelle définition de messagerie à votre application config/mail.php
fichier de configuration qui utilise le nouveau transport :
php 'mailers' => [ // Autres mailers... 'conditional' => [ 'transport' => 'conditional', ], ],
Avec cette configuration, votre application Laravel utilisera le pilote sendmail pour envoyer des e-mails si le service Postfix est en cours d'exécution et que la limite quotidienne n'a pas été atteinte. Une fois la limite dépassée ou si Postfix n'est pas en cours d'exécution, il basculera automatiquement vers le pilote Mailgun.
Remarques :
- Les
estPostfixEn cours d'exécution
La méthode vérifie si le service Postfix est en cours d'exécution en utilisant leexécutif
fonction à appelersystemctl est-actif postfix
. Ajustez cette méthode si votre environnement utilise une manière différente de gérer les services ou si exec est désactivé. - Le nombre d'e-mails est mis en cache à l'aide de la façade Cache de Laravel avec une clé qui inclut la date actuelle (en utilisant le format Ymd).
- Assurez-vous que vos configurations sendmail et mailgun sont correctement configurées dans votre
config/mail.php
déposer.
Cette implémentation adhère à la documentation de Laravel sur les transports personnalisés et devrait s'intégrer parfaitement à votre application.
Il sélectionne Mailgun comme alternative, mais vous pouvez également spécifier d'autres pilotes si vous le souhaitez.
Il a actuellement une limite de 1000 envois par jour, mais modifiez-la à la fréquence souhaitée.
Testé avec Laravel 10. À utiliser à vos risques et périls, bien sûr :).