9

I can use with success the followig code to send emails from the controller:

$message = \Swift_Message::newInstance()
    ->setSubject('Hello Email')
    ->setFrom('send@example.com')
    ->setTo('recipient@example.com')
    ->setBody($this->renderView('HelloBundle:Hello:email.txt.twig', array('name' => $name)))
;
$this->get('mailer')->send($message);

How must i modify the code to use it from a service class?

Mils
  • 1,479
  • 3
  • 19
  • 42
Udan
  • 5,429
  • 2
  • 28
  • 34

2 Answers2

11

Your service has an external dependency, notably the mailer service. You can either inject the service container itself, or inject the mailer service.

If your service only requires the mailer service and nothing else, I would suggest injecting just the mailer service.

Here is how you would configure the DIC to inject the mailer service using a setter:

<service id="my.service" class="Acme\DemoBundle\Service\Hello">
    <call method="setMailer">
        <argument type="service" id="mailer" />
    </call>
</service>

Within your class, write your setter:

class Hello
{
    protected $mailer;

    public function setMailer($mailer)
    {
        $this->mailer = $mailer;
    }

    public function sendEmail()
    {
        $message = \Swift_Message::newInstance()
            ->setSubject('Hello Email')
            ->setFrom('send@example.com')
            ->setTo('recipient@example.com')
            ->setBody($this->renderView('HelloBundle:Hello:email.txt.twig', array('name' => $name)))
        ;
        $this->mailer->send($message);
    }
}

Note: You will have to render your template within your controller and pass to this email function, or inject the templating service and render within your service.

noetix
  • 4,773
  • 3
  • 26
  • 47
  • 3
    Why not constructor injection? – igorw Oct 18 '12 at 22:40
  • Personal preference really. If this class is only going to do this one thing then sure, make it a constructor. Though if the service was doing more, say had constructor arguments, initialisation and multiple external dependencies, it can get extremely messy very quickly. – noetix Oct 18 '12 at 22:47
  • 2
    Where does `renderView` come from here? :p – RedactedProfile Dec 24 '14 at 21:02
  • 1
    @RedactedProfile, that's a fantastic point. You would need to inject the templating service (named "templating") and call `renderView` from that. – noetix Dec 27 '14 at 10:39
  • 2
    @noetix also, and bare in mind im using 2.6.1 here (though I think this is universal?), but `renderView` doesn't exist in `Templating`, that's a controller shortcut. However, it's only a 1:1 alias to `templating`'s `render()` lol I only bring this up because this tripped me up a little the other day – RedactedProfile Dec 27 '14 at 16:13
  • That seems easier to say than doing it, i'm totally lost about the "doing it". I just posted a question about it. I really don't see how to use the templating's render method. http://stackoverflow.com/questions/28675913/symfony-2-how-to-render-a-template-outside-a-controller-or-in-a-service – Brieuc Feb 23 '15 at 14:57
2

It depends how you have declared the service. If you are passing whole service container to it you wouldn't need to change anything, otherwise you will need at least mailer and templating service passed to it and called more directly ($this->get('service') will result in fatal error sinc it depends on container)

See also https://stackoverflow.com/a/12905319/258674

Community
  • 1
  • 1
dev-null-dweller
  • 29,274
  • 3
  • 65
  • 85