Dimitrios Desyllas Dimitrios Desyllas - 2 months ago 21
Twig Question

How to render twig templates into a service. Is it Best practice?

I have the following Symfony 3 controller:

public function register(Request $request)
{

$username=$request->get('username');
$password=$request->get('password');
$email=$request->get('email');
$captchaResponse=$request->get('g-recaptcha-response');

$session =$request->getSession();

$res1 = new Response();
$response_data=array('status'=>0);

if($session->get('captcha')===$captchaResponse)
{
$en = $this->container->get('user_model');

$data=$en->register($username,$password,$email);

$res1->headers->set('Content-Type','text/json');

if($data['status']===false)
{
$response_data['data']="An Internal error Happened";
error_log($data['data']);
}
else if($data['status']===-1)
{
$response_data['data']=$data['data'];
}
else
{
$response_data['status']=1;
$response_data['data']="Please check your mail to confirm your registration.";

/*Send Email*/
$message = \Swift_Message::newInstance()
->setSubject('Please confirm your registration')
->setFrom('symphotest@openmailbox.org')
->setTo($email)
->setBody($this->renderView('emails/confirm.html.twig',array('token'=>$data['data'])))
->addPart(
$this->renderView('emails/registration.txt.twig',array('token'=>$data['data'])),
'text/plain'
);
$this->get('mailer')->send($message);
}
}
else
{
$response_data['data']="You have not given a correct captcha";
}

$res1->setContent(json_encode($response_data));


$session->set('captcha',uniqid());//Generate gibberish in order not to reuse the very same captcha again
return $res1;
}


And I have made the following service:

namespace AppBundle\Models;

use Doctrine\ORM\EntityManager;
use AppBundle\Util\ModelStatus;
use AppBundle\Exceptions\InvalidArgumentException;
use \SwiftMessage;

class UserModel
{
/** @var EntityManager */
private $em;

/** @var \Swift_Mailer */
private $mailer;

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

/**
*
* @param EntityManager $em
* @param \Swift_Mailer $mailer
* @param \Twig_Environment $twig
*/
public function construct(EntityManager $em, \Swift_Mailer $mailer,\Twig_Environment $twig)
{
$this->em=$em;
$this->$mailer=$mailer;
}

/**
* Performs the actions needed for Registration
*
* @param unknown $username
* @param unknown $password
* @param unknown $email
* @param \Swift_Message $registrationMessage
*
* @return ModelStatus
*/
public function register($username,$password,$email)
{
$modelStatus=new ModelStatus();

try
{
/** @var \AppBundle\Entity\UserRepository */
$repository=$this->em->getRepository('AppBundle::Users');

$token=$repository->register($username,$password,$email);

$modelStatus->setData($token);
$modelStatus->setStatus(ModelStatus::STATUS_SUCCESS);

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

$message = Swift_Message::newInstance()
->setSubject('Please confirm your registration')
->setFrom('symphotest@openmailbox.org')
->setTo($email)
->setBody($this->twig->//->renderView('emails/confirm.html.twig',array('token'=>$data['data'])))
->addPart(
$this->renderView('emails/registration.txt.twig',array('token'=>$data['data'])),
'text/plain'
);
$this->get('mailer')->send($message);
}
catch(InvalidArgumentException $arg)
{
$modelStatus->setStatus(ModelStatus::STATUS_FAILURE);
$modelStatus->setMessage($arg->getMessage());
}
catch (\Exception $e)
{
$modelStatus->setStatus(ModelStatus::STATUS_FAILURE);
$modelStatus->setMessage($e->getMessage());
}

return $modelStatus;
}
}


And I am refactoring the following section:

$message = \Swift_Message::newInstance()
->setSubject('Please confirm your registration')
->setFrom('symphotest@openmailbox.org')
->setTo($email)
->setBody($this->renderView('emails/confirm.html.twig',array('token'=>$data['data'])))
->addPart(
$this->renderView('emails/registration.txt.twig',array('token'=>$data['data'])),
'text/plain'
);
$this->get('mailer')->send($message);


Into the Model method register.

But As you can see I render some twig templates and I do know the best Option on how to do it. So far I thought the following options:


  • To render the templates as string and pass them to the the register method, create and send the email there.

  • Load the twig rendering service into the model and the render into the model. If not exists create one.



In the second bullet I may need to load the Twig rendering engine into a service. How can I do that?

Answer

In the end having the constructor like this:

public function __construct(EntityManager $em, \Swift_Mailer $mailer,\Twig_Environment $twig)
{
    $this->em=$em;
    $this->mailer=$mailer;
    $this->twig=$twig;
}

And loading the service like this:

   user_model:
      class: AppBundle\Models\UserModel
      arguments: ['@doctrine.orm.entity_manager','@mailer','@twig']

Seems that solved the problem.