One of my modules will be a worker used e.g to send e-mails.
Is it possible not to define a view service in such module? When I try not to define a view a get an Exception.
I know that view is one of three parts of MVC but still, is it possible?
|
Aug '14 |
2 |
735 |
0 |
In any module you can define custome services, and views too.
But if you want to post email from HTML template just do something like this:
First variant:
class EmailSender extends \Phalcon\Mvc\User\Component {
public function sendNotificationEmail($user){
$this->view->setRenderLevel(\Phalcon\Mvc\View::LEVEL_ACTION_VIEW);
$this->view->setVar('login', $user->email);
$this->view->start();
$this->view->render('email','activation-info');
$this->view->finish();
$template = $this->view->getContent(); //here u will be have a full prepared and compiled HTML template
//process send email here
$this->view->setRenderLevel(\Phalcon\Mvc\View::LEVEL_LAYOUT); // back to the normal rendering
}
}
Second variant:
class EmailSender extends \Phalcon\Mvc\User\Component {
public function sendNotificationEmail($user){
$this->view->setRenderLevel(\Phalcon\Mvc\View::LEVEL_ACTION_VIEW);
$this->view->setVar('login', $user->email);
$this->view->start();
$this->view->pick('email/activation-info');
$this->view->finish();
$template = $this->view->getContent(); //here u will be have a full prepared and compiled HTML template
//process send email here
$this->view->setRenderLevel(\Phalcon\Mvc\View::LEVEL_LAYOUT); // back to the normal rendering
}
}
In Controller
public function signUpAction(){
//some stuff here validation, post data and save user
$email = new \EmailSender();
$email->sendNotificationEmail($user); //this it will set render level for ACTION and send your email after send email don't forget to set renderLevel back to \Phalcon\Mvc\View::LEVEL_LAYOUT
}
I hope this help!!
And how about set custom views for any module just look at my AutoRoute plugin how i set views and where. https://github.com/softdream/Phalcon-autorouter
Thanks a lot for your reply @softdream ! Fortunately have similiar code but have some questions.
(A) As I understand, your code is for such situation: you both render an e-mail and send it within the same request? Let's say registering a user will be this request.
(B) Setting rendering levels for \Phalcon\Mvc\View::LEVEL_ACTION_VIEW
and then back for \Phalcon\Mvc\View::LEVEL_LAYOUT
is done not to have any collision with a HTML that should be shown to the user?
My situation is a bit different.
In user's request I only save in the database an information that an e-mail should be sent (with some its parameters). Actual e-mail sending is not performed in this request (user experience). I have a worker in another module under cron which is sending e-mails, SMSes etc. I want it working via some queue like beanstalkd but I have not learned how to do it yet.
So my worker is not showing any output to the user (in fact there is no user). It only need to produce html/text for e-mails/SMS.
For now my code to produce HTML is similiar to yours:
$view = new \Phalcon\Mvc\View();
$view->setViewsDir('somedir');
$view->setVar("parameters", $someparameters);
$view->start();
$view->render('subdirectory','file');
$view->finish();
$html = $view->getContent();
The difference is that I don't change render levels.
My questions:
(C) Let's say my worker in one request sends 100 e-mails and each has different HTML. Is there any risk with my code that there will be some mess in produced HTMLs?
Still, my first question. Must I define any view in service container? For now I don't know how to achive NOT defining any.
A Yes in one request, look at my controller action part:
$user->save();
$email = new \Manager\Library\Components\Email();
$email->sendVerifyEmail($user);
$this->flash->success('Vše proběhlo v pořádku, neradi to děláme ale snažíme se chránit jak nás tak Vaše soukromí<br />
a právě proto potřebujeme ověřit Váš email, jenom klikněte na odkaz uvedený v emailu a hned budeme pokračovat.');
$this->flash->warning('Pozor! Platnost ověřovacího emailu je 24 hodin.');
It will continue render your controller view.
B No it will not have any collision look above.
C Just do some global template which u can store into variable and replace the vars inside for example i'm using something like this:
<div>
##myCustomVar##
{{ phalconVar }}
<div>##myNextCustomVar##</div>
</div>
Then pick or render the template and get it into variable
and in loop you can do something like this
foreach($items as $item){
$findVars = array('##myCustomVar##','##myNexCustomVar##');
$replaceVars = array($item['myvalue'],$item['mynextValue']);
$emailHtml = str_replace($findVars,$replaceVars,$template);
//send email
}
This will save you many unneccessary rendering template.
I have found answer for my question in another topic here https://forum.phalcon.io/discussion/2819/how-to-disable-views-in-restful-api-app.
So the answer is: Yes, defining a view is a must.
Sorry for starting an old issue again!