NucleosUserBundle mit SwiftMailer

      0
NucleosUserBundle mit SwiftMailer

Auf der Arbeit bin ich über das Problem gestolpert, dass bei einem Symfony Projekt keine Mail mehr beim Passwort Reset versandt wurde. Das Projekt wurde vor kurzem von einer sehr alten Version auf Symfony 4 aktualisiert. Dabei wurde das bekannte FOSUserBundle mit dem NucleosUserBundle ersetzt. Leider musste ich dann feststellen, dass das neue Bundle den Symfony Mailer nutzt, der in Symfony 4 den SwiftMailer abgelöst hat. Das Projekt verschickte aber diverse Mails bereits über den SwiftMailer. Bevor ich also sämtliche Emails auf den Symfony Mailer umstelle, musste eine Lösung her, damit das NucleosUserBundle mit SwiftMailer funktioniert. Hier kommt die Lösung.

Du musst insgesamt drei Dateien anfassen. Die Umsetzung ist aber denkbar einfach.

Als erstes legen wir die Mailer Klasse an. Diese baut auf dem MailerInterface vom NucleosUserBundle auf und sammelt alle Inhalte zusammen, um sie dann in die SwiftMailer Klassen zu kippen.

// src/Service/NucleosSwitfMailer.php

namespace App\Service;

use Nucleos\UserBundle\Mailer\MailerInterface;
use Nucleos\UserBundle\Model\UserInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
use Twig\Error\LoaderError;
use Twig\Error\RuntimeError;
use Twig\Error\SyntaxError;

class NucleosMailer implements MailerInterface
{
    /** @var \Swift_Mailer */
    private \Swift_Mailer $mailer;

    /** @var UrlGeneratorInterface */
    private UrlGeneratorInterface $router;

    /** @var TranslatorInterface */
    private TranslatorInterface $translator;

    /** @var \Twig_Environment */
    private \Twig_Environment $twig;

    /** @var string */
    private string $fromAddress;

    /**
     * NucleosMailer constructor.
     *
     * @param \Swift_Mailer         $mailer
     * @param UrlGeneratorInterface $router
     * @param TranslatorInterface   $translator
     * @param \Twig_Environment     $twig
     * @param string                $fromAddress
     */
    public function __construct(\Swift_Mailer $mailer, UrlGeneratorInterface $router, TranslatorInterface $translator, \Twig_Environment $twig, string $fromAddress)
    {
        $this->mailer = $mailer;
        $this->router = $router;
        $this->translator = $translator;
        $this->twig = $twig;
        $this->fromAddress = $fromAddress;
    }

    /**
     * Send an email to a user to confirm the password reset
     *
     * @param UserInterface $user
     *
     * @throws \Throwable
     * @throws LoaderError
     * @throws RuntimeError
     * @throws SyntaxError
     */
    public function sendResettingEmailMessage(UserInterface $user): void
    {
        $url = $this->router->generate('nucleos_user_resetting_reset', [
            'token' => $user->getConfirmationToken(),
        ], UrlGeneratorInterface::ABSOLUTE_URL);

        $template = $this->twig->loadTemplate('@NucleosUser/Resetting/email.txt.twig');
        $htmlBody = $template->render(['user' => $user, 'confirmationUrl' => $url]);

        $mail = (new \Swift_Message())
            ->setFrom($this->fromAddress)
            ->setTo($user->getEmail())
            ->setSubject($this->translator->trans('resetting.email.subject', [
                '%username%' => $user->getUsername(),
            ], 'NucleosUserBundle'))
            ->setBody($htmlBody, 'text/plain');

        $this->mailer->send($mail);
    }
}

Als nächstes registrieren wir unsere Klasse als Service und übergeben die benötigten Services/Variablen.

# config/services.yaml

app.nucleos_swift_mailer:
    class: App\Service\NucleosSwiftMailer
    public: false
    arguments:
        - '@mailer'
        - '@router'
        - '@translator'
        - '@twig'
        - '%env(MAILER_SENDER_ADDRESS)%'

Zu guter letzt geben wir dem NucleosUserBundle bescheid, dass es von nun an unsere eigene Mailer Klasse nutzen soll.

# config/packages/nucleos_user.yaml

nucleos_user:
    service:
        mailer: app.nucleos_swift_mailer

Und das war es auch schon. Damit funktioniert das NucleosUserBundle mit SwiftMailer. Als kleines Extra noch ein Command um den Mailversand zu prüfen. Du kannst ihn via php bin/console app:mail-test --env=prod aufrufen.

// Command/MailChecker.php

namespace App\Command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class MailChecker extends Command
{
    /** @var string $defaultName */
    protected static $defaultName = 'app:mail-test';

    private \Swift_Mailer $mailer;

    public function __construct(\Swift_Mailer $mailer)
    {
        $this->mailer = $mailer;

        parent::__construct();
    }

    protected function configure(): void
    {
        $this->setDescription('Check if mail sending works.');
    }

    /**
     * @return int|void
     */
    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $message = (new \Swift_Message('[DEBUG] Mailversand'))
            ->setFrom($_ENV['MAILER_SENDER_ADDRESS'])
            ->setTo('test@test.de')
            ->setBody('If you can read this text, you know that the mail server works.')
        ;

        $this->mailer->send($message);

        $output->writeln('Mail sent.');
    }
}

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert