Bonjour,

J'ai besoin d'un coup de pouce pour l'utilisation de swift mailer

Ce que je fais

Je cherche simplement à créer une classe mail avec dans le futur plusieurs fonctions, mais pour le moment qu'une seule.
La fonction SendWelcomeMessage prend un objet user en argument

class MailController extends AbstractController

{

    public function SendWelcomeMessage(users $user)
    {
        $mailer = new \Swift_Mailer();
        $surname=$user->getSurname();
        $message = (new \Swift_Message('Hello Email'))
            ->setFrom('biofutur@free.fr')
            ->setTo($user->getEmail())
            ->setBody(
                $this->renderView(
                    // templates/emails/registration.html.twig
                    'emails/registration.html.twig',
                    ['surname' => $surname]

                ),
                'text/html'
            )

            // you can remove the following code if you don't define a text version for your emails
            ->addPart(
                $this->renderView(
                    // templates/emails/registration.txt.twig
                    'emails/registration.txt.twig',
                    ['surname' => $surname]
                ),
                'text/plain'
            )
        ;

        $mailer->send($message);

    }

j'obtiens l'erreur suivante :
Too few arguments to function Swift_Mailer::__construct(), 0 passed in /home/johann/dev/biofutur/src/Controller/MailController.php on line 15 and exactly 1 expected

je sais qu'il attend un transport en argument (un serveur smtp) mais j'ai spécifié dans le swiftmailer.yaml la confid suivante :

swiftmailer:
    url: 'smtp.free.fr'
    spool: { type: 'memory' }

Pourquoi ne la prend t-il pas en compte et comment faire pour qu'il le fasse ?

Merci d'avance pour vos réponse :)

5 réponses


Salut !

Une petite question pourquoi fais-tu cette fonction dans un controller ? Je pense qu'elle a plus sa place dans un service :)

Ensuite pour répondre à ta question, au lieu d'instancier swift mailer comme ça

$mailer = new \Swift_Mailer();

Tu devrais plutot utiliser les injections de dépendences de cette manière

public function SendWelcomeMessage(users $user, \Swift_Mailer $mailer)

De cette manière il se chargera automatiquement de charger le mailer avec tes paramètres.

Maxime

JohnDoe
Auteur

Salut,
Pour ne rien te cacher je suis débutant en Symfony, j'ai commencé à faire comme tu me l'a montré mais j'ai eu d'autres problèmes. Je crois que quand j'appelais la fonction je ne savais pas quoi mettre en 2 eme argument.

Concernant le service, je n'ai pas essayé, mais j'ai eu pleinnnn de problèmes en essayant de mettre ça dans une "command" en fait il ne me trouvait pas la fonction render, même si je mettais use AbstractController.

Si tu as une doc sur comment faire un service je veux bien.

Merci a toi :)

Je pense qu'il faut que tu recommences la formation Symfony pour que tout soit clair dans ta tête :)

Le controller sert a orchestrer les différents éléments. Aller chercher les données dans la base de données, et ensuite les rendre avec la view.

Les fonctions annexe du genre l'envoie d'un mail au client, ou tout autre fonction de traitement ne doivent pas se retrouver dans ton controller.
C'est la qu'intervient les services qui sont en faite des class PHP que tu peux appeler dans ton controller.

Par exemple dans ton cas il faudait faire un truc du genre :

class UserController extends AbstractController
{
    /**
    ** @ORM\Route('/welcome')
    **/
    public function welcome(MailerService $mailer){
        // Tu récupères l'utilisateur courant (qui vient de se connecter)
        $currentUser = $this->getUser();
        $mailer->sendWelcomeMessage($currentUser);

        return $this->render('welcome.html.twig');
    }
}

Et ensuite tu défini ton service Mailer que tu pourras réutiliser un peux partout dans tes controller.

class MailerService
{
    // Ici tu peux spécifier le type que tu attends, j'ai mis user mais je pense qu'il vaut mieux mettre UserInterface de mémoire
    public function sendWelcomeMessage(User $user){
        // Ici tu met ta fonction que tu as créer plus haut
    }
}

Le soucis que tu aura de faire cela c'est qu'en effet dans le service tu n'as pas accèdes a certaines fonctions du controller comme le render de twig.
Mais tu peux l'importer dans ton service pour t'en servir de cette manière

use Twig\Environment;

class MailerService
{

    // Ici tu charge le twig environment pour pouvoir faire tes renders.
    public function __contruct(Environment $twig){
        $this->twig = $twig;
    }

    // Ici tu peux spécifier le type que tu attends, j'ai mis user mais je pense qu'il vaut mieux mettre UserInterface de mémoire
    public function sendWelcomeMessage(User $user){
        // Ici tu met ta fonction que tu as créer plus haut

        // Au lieu de faire $this->renderView() tu fais à la place $this->twig->render('welcome.html.twig')
    }
}

Mais vraiment essaye de relire le cours c'est une notion qui est un peu compliqué a appréhender mais une fois compris tout te paraitra logique ;)

JohnDoe
Auteur

Super !! Bon je vais faire ça et je reprendrai un cours. en fait j'ai commencé symfony avec le livre de fabien potencier "symfony the fast track" qui est très bien mais il est vrai passe vite sur certaines notions importantes.
du coup quand tu parles du cours tu parles de celui sur grafikart ?
celui- ci : https://www.grafikart.fr/formations/symfony-4-pratique

Merci à toi encore

Tout à fait ;)