Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RenderView in My service

Tags:

php

symfony

I'm new of symfony world. I want to use render inside my service, but I got this error

Call to undefined method renderView

I know that renderView is shortcut of

/**  * Returns a rendered view.  *  * @param string $view       The view name  * @param array  $parameters An array of parameters to pass to the view  *  * @return string The rendered view  */ public function renderView($view, array $parameters = array()) {     return $this->container->get('templating')->render($view, $parameters); } 

But I don't know what I have to Injection in my service. I know even that with php app/console container:debug command I Can see all my services available, but I don't know how can take/choose the correct

update

I tried to add

arguments: [@mailer,@templating] 

but I got ServiceCircularReferenceException

UPDATE

I changed my service.yml with

    arguments: [@service_container] 

and even my service

$email = $this->service_container->get('mailer'); $twig = $this->service_container->get('templating'); 

for use service Mail (swift) and render.

I don't think that it's best solution. I'd like to injection Only mailer and templating

UPDATE After Jason's answer I'm using Symfony 2.3

my services.yml

services:     EmailService:         class: %EmailService.class%         arguments:  [@mailer,@templating,%EmailService.adminEmail%] 

I got this ServiceCircularReferenceException

like image 315
monkeyUser Avatar asked Dec 13 '14 16:12

monkeyUser


2 Answers

Using constructor dependency injection (tested with Symfony 3.4):

class MyService {     private $mailer;     private $templating;      public function __construct(\Swift_Mailer $mailer, \Twig_Environment $templating)     {         $this->mailer     = $mailer;         $this->templating = $templating;     }      public function sendEmail()     {         $message = $this->templating->render('emails/registration.html.twig');          // ...     } } 

No need to configure arguments.

like image 142
Mateusz Avatar answered Sep 20 '22 12:09

Mateusz


You are correct about renderView(), it's only a shortcut for Controllers. When using a service class and inject the templating service, all you have to do is change your function to render() instead. So instead of

return $this->renderView('Hello/index.html.twig', array('name' => $name)); 

you would use

return $this->render('Hello/index.html.twig', array('name' => $name)); 

Update from Olivia's response:

If you are getting circular reference errors, the only way around them is to inject the whole container. It's not considered best practice but it sometimes cannot be avoided. When I have to resort to this, I still set my class variables in the constructor so I can act as if they were injected directly. So I will do:

use Symfony\Component\DependencyInjection\ContainerInterface;  class MyClass() {     private $mailer;     private $templating;      public function __construct(ContainerInterface $container)     {         $this->mailer = $container->get('mailer');         $this->templating = $container->get('templating');     }     // rest of class will use these services as if injected directly } 

Side note, I just tested my own standalone service in Symfony 2.5 and did not receive a circular reference by injecting the mailer and templating services directly.

like image 38
Jason Roman Avatar answered Sep 19 '22 12:09

Jason Roman