Search code examples
phpsymfonyservicefosuserbundlemailer

Symfony2 and FOSUserBundle : Override Mailer


i come here because i have a problem with OVH and my symfony2 application, i can't send mail with SwiftMailer. It's rather problematic for FOSUserBundle to reset the password or activate my account after inscription. So i want to use the MAIL function implemented in PHP, i followed the documentation here . So i created my class MailerInterface.phpand the class Mailer.php because this class send the mail with the function sendEmailMessage

Here, you can see how i implemented the class :

<?php
      namespace MonApp\UserBundle\Mailer;

      use FOS\UserBundle\Model\UserInterface;

      interface MailerInterface
      {
           function sendConfirmationEmailMessage(UserInterface $user);

           function sendResettingEmailMessage(UserInterface $user);
      }
?>

And the Mailer.php :

<?php
      namespace MonApp\UserBundle\Mailer;

      use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface;
      use Symfony\Component\Routing\RouterInterface;
      use FOS\UserBundle\Model\UserInterface;
      use MonApp\UserBundle\Mailer\MailerInterface;

      class Mailer implements MailerInterface
      {
          protected $mailerMonApp;
          protected $router;
          protected $templating;
          protected $parameters;

          public function __construct($mailerMonApp, RouterInterface $router, EngineInterface $templating, array $parameters) {
               $this->mailerMonApp = $mailerMonApp;
               $this->router = $router;
               $this->templating = $templating;
               $this->parameters = $parameters;
          }

          public function sendConfirmationEmailMessage(UserInterface $user) {
               The function...
          }

          public function sendResettingEmailMessage(UserInterface $user) {
               The function...
          }

          protected function sendEmailMessage($renderedTemplate, $fromEmail, $toEmail) {
              $renderedLines = explode("\n", trim($renderedTemplate));
              $subject = $renderedLines[0];
              $body = implode("\n", array_slice($renderedLines, 1));

              mail($toEmail, $subject, $body, 'noreply@nondedomaine.fr');
          }
     }

I added my class as service :

services:
     monapp.mailer:
          class: MonApp\UserBundle\Mailer\Mailer

And changed the config.yml :

service:
    mailer: monapp.mailer

Here the ERROR in Dev env :

     Warning: Missing argument 1 for MonApp\UserBundle\Mailer\Mailer::__construct(), called in /home/domaine/www/nomappli/app/cache/dev/appDevDebugProjectContainer.php on line 831 and defined in /home/domaine/www/nomappli/src/MonApp/UserBundle/Mailer/Mailer.php line 29

My problem is : When i arrive on my reset password page, i write my pseudo and after validation of the form i got a white page. I think i call the class and use used in the tutorial so i don't understand my problem, maybe i forgot a use ?

Thanks

EDIT Here the logs errors (Thanks to Michael & Yann for helped me) :

[2015-03-31 14:55:35] request.INFO: Matched route "fos_user_resetting_send_email" (parameters: "_controller": "FOS\UserBundle\Controller\ResettingController::sendEmailAction", "_route": "fos_user_resetting_send_email") [] []
[2015-03-31 14:55:35] security.INFO: Populated SecurityContext with an anonymous Token [] []
[2015-03-31 14:55:35] request.CRITICAL: Uncaught PHP Exception InvalidArgumentException: "Unable to find template ""." at /home/nomappli/www/monapp/vendor/symfony/symfony/src/Symfony/Bridge/Twig/TwigEngine.php line 128 {"exception":"[object] (InvalidArgumentException: Unable to find template \"\". at /home/nomappli/www/monapp/vendor/symfony/symfony/src/Symfony/Bridge/Twig/TwigEngine.php:128, Twig_Error_Loader: Unable to find template \"\". at /home/nomappli/www/monapp/vendor/symfony/symfony/src/Symfony/Bundle/TwigBundle/Loader/FilesystemLoader.php:106, InvalidArgumentException: Template name \"\" is not valid (format is \"bundle:section:template.format.engine\"). at /home/nomappli/www/monapp/app/cache/prod/classes.php:742)"} []
[2015-03-31 14:55:35] security.DEBUG: Write SecurityContext in the session [] []

Solution

  • You don't need to copy-paste interface code. It should be at its place: in FOSUserBundle. You just need to implement this interface. It means that you need to create class in which you place implements MailerInterface.

    You already have this class. Just replace use MonApp\UserBundle\Mailer\MailerInterface; by use FOS\UserBundle\Mailer\MailerInterface and delete your copy of original interface.

    UPDATE

    As you updated your question I have updated my answer. Your current problem is about service configuration. You need to inject arguments for constructor in service definition:

    services:
         monapp.mailer:
              class: MonApp\UserBundle\Mailer\Mailer
              arguments:
                  - @router
                  - @templating
                  - {from_email: {confirmation: %fos_user.registration.confirmation.from_email%, resetiing: %fos_user.resetting.email.from_email%}}
    

    Also modify your constructor method: remove $mailerMonApp from arguments:

          public function __construct(RouterInterface $router, EngineInterface $templating, array $parameters) {
               $this->router = $router;
               $this->templating = $templating;
               $this->parameters = $parameters;
          }