So in my UsersAdmin I want to send an email to that user if I confirm his account.(in my case, making Enabled = true). I do this in the configureListFields function
/**
* {#inheritdoc}
*/
protected function configureListFields(ListMapper $listMapper)
{
$listMapper
->addIdentifier('username')
->add('email')
->add('groups')
->add('enabled', null, array('editable' => true)) //here
->add('locked', null, array('editable' => true))
->add('createdAt')
;
}
By reading the documentation I think i need to use the batchAction function yes? So I made this:
public function getBatchActions()
{
// retrieve the default batch actions (currently only delete)
$actions = parent::getBatchActions();
$container = $this->getConfigurationPool()->getContainer();
$user = //how to get the user that i am editing right now?
if ($this->hasRoute('edit') && $this->isGranted('EDIT')) {
$body = $container->get('templating')->render('MpShopBundle:Registration:registrationEmail.html.twig', array('user'=> $user));
$message = Swift_message::newInstance();
$message->setSubject($container->get('translator')->trans('registration.successful'))
->setFrom($container->getParameter('customer.care.email.sender'))
->setTo('email#contact.lt')
->setBody($body, 'text/html');
$container->get('mailer')->send($message);
}
return $actions;
}
Now I am stuck with two unclear thing with this function:
How can I get the current user data hat I want to edit?
Am I even going in the right direction? Do I need to override edit or maybe some other function?
THE SOLUTION
The best way is to do your login in the postUpdate event, so that everytime you update an object it initiates the functions you want.
public function postUpdate($user)
{
if($user->getEnabled() == true) {
$container = $this->getConfigurationPool()->getContainer();
$body = $container->get('templating')->render('MpShopBundle:Registration:registrationEmail.html.twig', array('user' => $user));
$message = Swift_message::newInstance();
$message->setSubject($container->get('translator')->trans('registration.successful'))
->setFrom($container->getParameter('customer.care.email.sender'))
->setTo('email#contact.lt')
->setBody($body, 'text/html');
$container->get('mailer')->send($message);
}
}
you can use Saving hooks.
public function postUpdate($user)
{
//code to check if enabled
// code to send email
}
Related
I have a Symfony service to add an alert (bootstrap alert in DOM) to database to allow administrators to audit the usage of the application and also this service saves the alert in session storage to display the alerts until the user closes each alert.
This is the code for the service method:
public function addAlert(DateTimeInterface $eventDatetime, string $eventType, string $data, UserInterface $user, string $alertId): bool
{
$success = false;
try {
//Build alert entity
$alert = new UserAlert();
$alert->setDatetimeUTC($eventDatetime);
$alert->setEventType($eventType);
$alert->setMessage($data);
$alert->setUser($user);
//Save in database
$this->entityManager->persist($alert);
$this->entityManager->flush();
//Save in session
$success = $this->saveAlertInSession($alertId, $eventType, $data);
} catch (Throwable $throwable) {
$this->logger->critical("Add User Alert Service: Ko. Details: {$throwable->getMessage()}.");
}
return $success;
}
private function saveAlertInSession(string $alertId, string $eventType, string $data): bool
{
$alerts = [];
try {
//Check if any alert is stored to retrieve
if ($this->session->has('alerts')) {
$alerts = $this->session->get('alerts');
}
//Add new alert
$alerts[$alertId] = [
'type' => $eventType,
'data' => $data,
];
//Save to session
$this->session->set('alerts', $alerts);
$success = true;
} catch (Throwable $throwable) {
$success = false;
$message = "Save Alert Session: Ko. Details: {$throwable->getMessage()}.";
$this->logger->critical($message);
}
return $success;
}
My question is if Symfony has an event listener to automatically call this service method each time I write the following lines on controllers:
$this->addFlash('success', $message);
$this->addFlash('error', $message);
$this->addFlash('warning', $message);
Now, after I add a message to the Flash Bag message, my controller executes the following instruction:
$this->alertsService->addAlert($datetimeUTCNow, $eventType, $message, $user, $alertId);
Do you know any event listener to avoid writing this line each time the controller calls to addFlash method? I am using Symfony 5 and PHP 7.3
Thank you.
Here is my solution to override the addFlash method:
protected function addFlash(string $type, string $message): void
{
// Generate the required arguments on userAlerts service
try {
$datetimeUTC = new DateTime('now', new DateTimeZone('UTC'));
$alertId = Uuid::uuid4();
$this->userAlertsService->addAlert($datetimeUTC, $type, $message, $this->getUser(), $alertId);
} catch (Throwable $throwable) {
$this->logger->critical("Add Flash: Ko. Details: {$throwable->getMessage()}");
}
parent::addFlash($type, $message);
}
I am trying to send two emails at the same time when the user submits contact form. One email to the website owner and other to the user as autoresponse. I have been trying to do this for about last 4 hours and tried different solutions on internet but I am totally lost. Here is my code to send an email
public function contactForm(Request $request)
{
$parameters = Input::get();
$email = Input::get('email');
$inquiryType = Input::get('type_inquiry');
foreach ([
'contactmessage' => 'Message',
'email' => 'Email',
'phone' => 'Phone',
'first_name' => 'Contact Name',
'g-recaptcha-response' => 'Captcha',
] as $key => $label) {
if (!isset($parameters[$key]) || empty($parameters[$key])) {
return response()->json(
[
'success' => false,
'error' => "{$label} cannot be empty",
]
);
}
}
$recipients = 'abc#gmail.com';
// if page set, try to get recipients from the page settings
if (Input::get('page_id')) {
$page = Page::find(Input::get('page_id'));
if ($page && !empty($page->recipients)) {
$recipients = explode(',', $page->recipients);
}
}
try {
$res = Mail::send(
'emails.contact',
$parameters,
function (Message $message) use ($recipients) {
$message->subject('Contact message');
if (is_array($recipients)) {
// email to first address
$message->to(array_shift($recipients));
// cc others
$message->cc($recipients);
} else {
$message->to($recipients);
}
}
);
} catch (\Exception $e) {
return response()->json(
[
'success' => false,
'error' => $e->getMessage(),
]
);
}
if($inquiryType == 'Rental Inquiry'){
Mail::send(
'emails.autoresponse',
'',
function (Message $message) use ($email) {
$message->subject('Thank you for inquiring');
if (is_array($email) {
// email to first address
$message->to(array_shift($email);
// cc others
$message->cc($email);
} else {
$message->to($email);
}
}
);
}
return response()->json(
[
'success' => $res,
]
);
}
I have tried to do the same thing by different methods but none of them are working. Please help me. This is the first time I am sending multiple emails using laravel. I think I am doing a big and silly mistake somewhere.
Thank you.
You have a missing closing parenthesis near is_array($email)
$message->subject('Thank you for inquiring');
if (is_array($email)) {
Also i would you use laravel's validator to check for required input. Another suggestion would be to use queues for mails. Sending two mails in a single request might cause your page load time to increase significantly.
The best way is create one Laravel Jobs
php artisan queue:table
php artisan migrate
php artisan make:job SendEmail
Edit your .env
QUEUE_DRIVER=database
Edit your app /Jobs/SendEmail.php
namespace App\Jobs;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Contracts\Mail\Mailer;
class SendEmail extends Job implements ShouldQueue
{
use InteractsWithQueue, SerializesModels;
protected $subject;
protected $view;
protected $data;
protected $email;
/**
* SendEmail constructor.
* #param $subject
* #param $data
* #param $view
* #param $email
*/
public function __construct($subject, $data, $view, $email)
{
$this->subject = $subject;
$this->data = $data;
$this->email = $email;
$this->view = $view;
}
/**
* Execute the job.
* #param $mailer
* #return void
*/
public function handle(Mailer $mailer)
{
$email = $this->email;
$subject = $this->subject;
$view = $this->view;
$mailer->send($view, $this->data,
function ($message) use ($email, $subject) {
$message->to($email)
->subject($subject);
}
);
}
}
And handle in your controller
use App\Jobs\SendEmail;
public function contactForm(Request $request) {
//TODO Configure Subject
$subjectOwner = 'Your Email Subject For Owner';
$subjectUser = 'Your Email Subject For User';
//TODO Configure Email
$ownerEmail = 'ownerEmail#gmail.com';
$userEmail = 'userEmail#gmail.com';
//TODO Configure Data Email send to email blade viewer
$dataEmail = [
'lang' => 'en',
'user_name' => 'User Name'
];
//emails.owner mean emails/owner.blade.php
//emails.admin mean emails/admin.blade.php
$jobOwner = (new SendEmail($subjectOwner, $dataEmail, "emails.owner" , $ownerEmail))->onQueue('emails');
dispatch($jobOwner);
$jobUser = (new SendEmail($subjectUser, $dataEmail, "emails.admin" , $userEmail))->onQueue('emails');
dispatch($jobUser);
}
And try command
//IF You using Laravel 5.2
php artisan queue:listen --queue=emails
//IF You using Laravel >5.3
php artisan queue:work
I'm trying to create a form that would allow a manager to approve a list of time off requests (also planning to have a todo list and want to be able to mark them as done).
I have read [Generate same form type on same page multiple times Symfony2 (as well as several others) and I am close to understanding but I'm fairly to new to Symfony and not clear on what parts of the code should go in what files. I am using a form type and a controller in Symfony3 with Doctrine.
I have list of the entity instances that were returned from a query ($em->createQuery) in the controller and I am looking to produce a form for each entity instance or even two forms per entity (one for approve and one for reject).
The referenced question says you need a loop to display and save them. My intention is to only work on (submit) one at a time. I assume this part of the code would go in the controller?
I am using an indexAction for the controller but using it more like an Edit action since I will be processing forms, so I pass in a Request object and the objects as parameters.
>
class HRMgrController extends Controller
{
/**
* Lists all manager role requests and provide a means to approve/deny.
*
* #Route("/", name="hrmgr_index")
* #Method({"GET", "POST"})
* #Security("has_role('ROLE_APP_MANAGER')")
*/
public function indexAction(Request $request, TimeOffRequest $timeOffRequest)
{
if (!empty($timeOffRequest)) {
$form = $this->createForm('CockpitBundle\Form\TORApprovalType', $timeOffRequest);
print "TOR Id = " . $timeOffRequest->getId() . "<BR>";
$em = $this->getDoctrine()->getManager();
$form->handleRequest($request);
print "Form name = " . $form->getName() . "<BR>";
if ($form->isSubmitted() && $form->isValid()) {
if ($form->get('approve')->isClicked()) {
print "This puppy was approved";
$timeOffRequest['status'] = 4;
}
if ($form->get('reject')->isClicked()) {
print "This puppy was rejected";
$timeOffRequest['status'] = 1;
}
$this->getDoctrine()->getManager()->flush();
print "At least its there<BR>";
// return $this->redirectToRoute('hrmgr_index');
} else {
print "did not detect form submission<BR>";
}
}
$emp = new \CockpitBundle\Entity\Employee();
$date = new \DateTime();
$year = $date->format('Y');
$username = $this->getUser()->getUserName();
$user = $em->getRepository('CockpitBundle:Employee')->findByUsername($username);
$employees = $em->getRepository('CockpitBundle:Employee')->htmlContact($user);
$tors = $em->getRepository('CockpitBundle:TimeOffRequest')->findMgrUnapprovedTORs($user->getId());
$timeoff = "<h3>Unapproved Time Off Requests</h3>";
$actions = true;
$torforms = [];
foreach ($tors as $tor) {
$target = $this->generateUrl('hrmgr_index',array("tor_id" => $tor->getId()));
$torforms[] = $this->actionForm($tor,$target)->createView();
}
return $this->render('hrmgr/index.html.twig', array(
'torforms' => $torforms,
));
I have the forms working nowbut when I submit them the isSubmitted() doesn't seem to be working. It outputs the "did not detect form submission" currently.
So when I have multiple forms and I submit one, does the handleRequest get the right one? I think I might be confusing two concepts here as well. I recently changed the code to submit the ID of the timeOffRequest as a parameter to the route. It is properly picking that up which allows me to potentially update the form but that part of the code doesn't seem to be working.
I noticed that if I look at the debugger, I get something like:
> approval_form_2
[▼
"reject" => ""
"_token" => "IE1rGa5c0vaJYk74_ncxgFsoDU7wWlkAAWWjLe3Jr1w"
]
if I click the reject button. I get a similar form with "approve" if I click the approve button so it seems like I am close. Also, the proper ID shows up from the route given in the action.
Here is the form generator:
<?php
namespace CockpitBundle\Form;
use CockpitBundle\Entity\Employee;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\ButtonType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
class TORApprovalType extends AbstractType
{
private $nameSuffix = null;
private $name = 'time_req_approval';
public function __constructor(string $suffix = null) {
//parent::__construct();
$this->nameSuffix = $this->generateNameSuffix();
}
private function generateNameSuffix() {
if ($this->nameSuffix == null || $this->nameSuffix == '') {
$generator = new SecureRandom();
//change data to alphanumeric string
return bin2hex($generator->nextBytes(10));
}
return $this->nameSuffix;
}
public function setNameSuffix($suffix){
$this->nameSuffix = $suffix;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
// Build your form...
$builder->add('approve', SubmitType::class, array(
'label' => "Approve",
'attr' => array("class"=>"action-approve"),
));
$builder->add('reject', SubmitType::class, array(
'label' => "Reject",
'attr' => array("class"=>"action-reject"),
));
//$builder->add('employee');
}
public function getName() {
if ($this->nameSuffix == null || $this->nameSuffix == "" ) {
$this->nameSuffix = $this->generateNameSuffix();
}
return $this->name .'_'. $this->nameSuffix;
}
/**
* {#inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'CockpitBundle\Entity\TimeOffRequest'
));
}
/**
* {#inheritdoc}
*/
public function getBlockPrefix()
{
return 'cockpitbundle_timeoffrequest';
}
}
Any clues? (sorry I am on vacation so not particular quick with updates.
You can do multiple submit button: check your formtype
->add('approve', 'submit')
->add('reject', 'submit')
then in your controller
if ($form->isValid()) {
// ... do something
// the save_and_add button was clicked
if ($form->get('approve')->isClicked()) {
// probably redirect to the add page again
}
if ($form->get('reject')->isClicked()) {
// probably redirect to the add page again
}
// redirect to the show page for the just submitted item
}
I was able to get it working with the following builder.
$builder->add('approve', SubmitType::class, array(
'label' => "Approve",
'attr' => array("class"=>"action-approve"),
));
$builder->add('reject', SubmitType::class, array(
'label' => "Reject",
'attr' => array("class"=>"action-reject"),
));
Then in the controller form I generate and process the forms as such. Not sure if it is the optimal way but it works find. Of course, this approach redraws the whole list each time, but that is fine for what I'm doing.
class HRMgrController extends Controller
{
/**
* Lists all manager role requests and provide a means to approve/deny.
*
* #Route("/", name="manager_home")
* #Method({"GET"})
* #Security("has_role('ROLE_APP_MANAGER')")
*/
public function indexAction()
{
$em = $this->getDoctrine()->getManager();
$emp = new \CockpitBundle\Entity\Employee();
$employeeSummary = [];
$date = new \DateTime();
$year = $date->format('Y');
$username = $this->getUser()->getUserName();
$user = $em->getRepository('CockpitBundle:Employee')->findByUsername($username);
$myemployees = $em->getRepository('CockpitBundle:Employee')->findManagersEmployees($user);
$torRep = $em->getRepository('CockpitBundle:TimeOffRequest');
$toas = [];
$torforms = [];
foreach ($myemployees as $employee) {
$tors = $torRep->findAllMine($employee,$year);
$toas[$employee->getDisplayName()] = $em->getRepository('CockpitBundle:TimeOffAllocation')->getEmpAllocation($employee->getId(),$year);
$employeeSummary[$employee->getDisplayName()] = $torRep->mySummary($tors,$toas[$employee->getDisplayName()]);
if (array_key_exists('items',$employeeSummary[$employee->getDisplayName()]['Vacation']['Requested'])) {
foreach ($employeeSummary[$employee->getDisplayName()]['Vacation']['Requested']['items'] as $tor) {
$target = $this->generateUrl('hrmgr_tor_approval',array("tor_id" => $tor->getId()));
$torforms[] = $this->actionForm($tor,$target)->createView();
}
}
if (array_key_exists('items',$employeeSummary[$employee->getDisplayName()]['Sick Time']['Requested'])) {
foreach ($employeeSummary[$employee->getDisplayName()]['Sick Time']['Requested']['items'] as $tor) {
$target = $this->generateUrl('hrmgr_tor_approval',array("tor_id" => $tor->getId()));
$torforms[] = $this->actionForm($tor,$target)->createView();
}
}
if (array_key_exists('Time Off',$employeeSummary[$employee->getDisplayName()]) &&
array_key_exists('items',$employeeSummary[$employee->getDisplayName()]['Time Off']['Requested'])) {
foreach ($employeeSummary[$employee->getDisplayName()]['Time Off']['Requested']['items'] as $tor) {
$target = $this->generateUrl('hrmgr_tor_approval',array("tor_id" => $tor->getId()));
$torforms[] = $this->actionForm($tor,$target)->createView();
}
}
}
return $this->render('hrmgr/index.html.twig', array(
'employeeSummary' => $employeeSummary,
'torforms' => $torforms,
'year' => $year,
));
}
/**
* Lists all manager role requests and provide a means to approve/deny.
*
* #Route("/{tor_id}", name="hrmgr_tor_approval")
* #Method({ "POST" })
* #ParamConverter("timeOffRequest", class="CockpitBundle:TimeOffRequest", options={"id"="tor_id"})
* #Security("has_role('ROLE_APP_MANAGER')")
*/
public function approvalAction(Request $request, TimeOffRequest $timeOffRequest)
{
if (!empty($timeOffRequest)) {
$form = $this->createForm('CockpitBundle\Form\TORApprovalType', $timeOffRequest);
$id = $timeOffRequest->getId();
$em = $this->getDoctrine()->getManager();
$form->handleRequest($request);
$postparams = $request->request->all();
if (array_key_exists("approval_form_$id",$postparams)) {
// Form was submitted
if (array_key_exists("approve",$postparams["approval_form_$id"])) {
$status = $em->getReference('CockpitBundle\Entity\TimeOffStatus', 4);
$timeOffRequest->setStatus($status);
$timeOffRequest->setApprovedDate(new \DateTime);
$em->persist($timeOffRequest);
$em->flush($timeOffRequest);
}
if (array_key_exists("reject",$postparams["approval_form_$id"])) {
$status = $em->getReference('CockpitBundle\Entity\TimeOffStatus', 1);
$timeOffRequest->setStatus($status);
$timeOffRequest->setApprovedDate(new \DateTime);
$em->persist($timeOffRequest);
$em->flush($timeOffRequest);
}
} else {
print "Form did not exist<BR>";
}
return $this->redirectToRoute('manager_home');
}
}
public function actionForm($tor,$target) {
return $this->get('form.factory')->createNamedBuilder('approval_form_'.$tor->getId(), \CockpitBundle\Form\TORApprovalType::class, $tor,
array("action"=> $target))->getForm();
}
}
I'm still trying to add a recaptcha to my website, I want try the recaptcha from Google but I can't use it properly. Checked or not, my email is still sent.
I tried to understand the code of How to validate Google reCaptcha v2 using phalcon/volt forms?.
But i don't understand where are my problems and more over how can you create an element like
$recaptcha = new Check('recaptcha');
My controller implementation :
<?php
/**
* ContactController
*
* Allows to contact the staff using a contact form
*/
class ContactController extends ControllerBase
{
public function initialize()
{
$this->tag->setTitle('Contact');
parent::initialize();
}
public function indexAction()
{
$this->view->form = new ContactForm;
}
/**
* Saves the contact information in the database
*/
public function sendAction()
{
if ($this->request->isPost() != true) {
return $this->forward('contact/index');
}
$form = new ContactForm;
$contact = new Contact();
// Validate the form
$data = $this->request->getPost();
if (!$form->isValid($data, $contact)) {
foreach ($form->getMessages() as $message) {
$this->flash->error($message);
}
return $this->forward('contact/index');
}
if ($contact->save() == false) {
foreach ($contact->getMessages() as $message) {
$this->flash->error($message);
}
return $this->forward('contact/index');
}
$this->flash->success('Merci, nous vous contacterons très rapidement');
return $this->forward('index/index');
}
}
In my view i added :
<div class="g-recaptcha" data-sitekey="mypublickey0123456789"></div>
{{ form.messages('recaptcha') }}
But my problem is after : i create a new validator for the recaptcha like in How to validate Google reCaptcha v2 using phalcon/volt forms? :
use \Phalcon\Validation\Validator;
use \Phalcon\Validation\ValidatorInterface;
use \Phalcon\Validation\Message;
class RecaptchaValidator extends Validator implements ValidatorInterface
{
public function validate(\Phalcon\Validation $validation, $attribute)
{
if (!$this->isValid($validation)) {
$message = $this->getOption('message');
if ($message) {
$validation->appendMessage(new Message($message, $attribute, 'Recaptcha'));
}
return false;
}
return true;
}
public function isValid($validation)
{
try {
$value = $validation->getValue('g-recaptcha-response');
$ip = $validation->request->getClientAddress();
$url = $config->'https://www.google.com/recaptcha/api/siteverify'
$data = ['secret' => $config->mysecretkey123456789
'response' => $value,
'remoteip' => $ip,
];
// Prepare POST request
$options = [
'http' => [
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
'method' => 'POST',
'content' => http_build_query($data),
],
];
// Make POST request and evaluate the response
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
return json_decode($result)->success;
}
catch (Exception $e) {
return null;
}
}
}
So i don't know if tjis code is correct anyway, i have a problem too after that : how to create an object "recaptcha" in my form add
$recaptcha = new ?????('recaptcha');
$recaptcha->addValidator(new RecaptchaValidator([
'message' => 'Please confirm that you are human'
]));
$this->add($recaptcha);
PS: I apologize because i'm a noob here and my mother tongue is not english, so if you don't understand me or want give me some advices to create a proper question, don't hesitate ^^
I've made a custom form element for recaptcha. Used it for many projects so far.
The form element class:
class Recaptcha extends \Phalcon\Forms\Element
{
public function render($attributes = null)
{
$html = '<script src="https://www.google.com/recaptcha/api.js?hl=en"></script>';
$html.= '<div class="g-recaptcha" data-sitekey="YOUR_PUBLIC_KEY"></div>';
return $html;
}
}
The recaptcha validator class:
use Phalcon\Validation\Validator;
use Phalcon\Validation\ValidatorInterface;
use Phalcon\Validation\Message;
class RecaptchaValidator extends Validator implements ValidatorInterface
{
public function validate(\Phalcon\Validation $validation, $attribute)
{
$value = $validation->getValue('g-recaptcha-response');
$ip = $validation->request->getClientAddress();
if (!$this->verify($value, $ip)) {
$validation->appendMessage(new Message($this->getOption('message'), $attribute, 'Recaptcha'));
return false;
}
return true;
}
protected function verify($value, $ip)
{
$params = [
'secret' => 'YOUR_PRIVATE_KEY',
'response' => $value,
'remoteip' => $ip
];
$response = json_decode(file_get_contents('https://www.google.com/recaptcha/api/siteverify?' . http_build_query($params)));
return (bool)$response->success;
}
}
Using in your form class:
$recaptcha = new Recaptcha($name);
$recaptcha->addValidator(new RecaptchaValidator([
'message' => 'YOUR_RECAPTCHA_ERROR_MESSAGE'
]));
Note 1: You were almost there, you just missed to create custom form element (the first and last code piece from my example);
Note 2: Also there is a library in Github: https://github.com/fizzka/phalcon-recaptcha I have not used it, but few peeps at phalcon forum recommended it.
I have an error trying to use SwiftMailer with Symfony.
I'm following a tutorial from here: http://symblog.site90.net/docs/validators-and-forms.html
The error code is:
FatalErrorException: Error: Call to undefined method Swift_Message::setMessage() in C:\xampp\htdocs\TP\src\TP\MainBundle\Controller\DefaultController.php line 327
My action is:
public function newAction()
{
$contacto = new Contacto();
$form = $this->createForm(new ContactoType(), $contacto);
$request = $this->getRequest();
if ($request->getMethod() == 'POST') {
$form->bind($request);
if ($form->isValid()) {
$message = \Swift_Message::newInstance()
->setFrom('enquiries#myweb.com.ar')
->setTo($this->container->getParameter('tp_main.emails.contact_email'))
//this is the line 327 related with the error
->setMessage($this->renderView('TPMainBundle:Default:contactEmail.txt.twig', array('contacto' => $contacto)));
//
$this->get('mailer')->send($message);
$this->get('session')->setFlash('blogger-notice', 'Your contact enquiry was successfully sent. Thank you!');
return $this->redirect($this->generateUrl('contacto_new'));
}
}
return $this->render('TPMainBundle:Default:contact.html.twig', array(
'form' => $form->createView(),));}
The error says it's undefined but,
my method setMessage() is defined in my class Contacto.php with getter and setter :
/**
* #var string
*
* #ORM\Column(name="message", type="text")
*/
private $message;
/**
* Set message
*
* #param string $message
* #return Contacto
*/
public function setMessage($message)
{
$this->message = $message;
return $this;
}
/**
* Get message
*
* #return string
*/
public function getMessage()
{
return $this->message;
}
According on what I read trying to solve it myself, could the problem be related to the versions of SwiftMailer ?
Thanks
The method "setMessage" refers indeed to your Contacto entity, but to set the content of a message with SwiftMailer, you have to use setBody();
Example :
$mail = \Swift_Message::newInstance();
$mail->setFrom('me#mail.com')
->setTo('you#mail.com')
->setSubject('Email subject')
->setBody('email body, can be swift template')
->setContentType('text/html');
$this->get('mailer')->send($mail);
EDIT : save the email content in database and send it to Twig template
I added a bit of code in your function, to actually save the email content in database. It's not mandatory but I imagine you'll want to retrieve this information later in your application. Anyway, I didn't test this, but it should work : your controller set the SwiftMailer message body as a Twig template. Your template should be able to parse the "contacto" entity.
public function newAction()
{
$contacto = new Contacto();
$form = $this->createForm(new ContactoType(), $contacto);
$request = $this->getRequest();
if ($request->getMethod() == 'POST') {
$form->bind($request);
if ($form->isValid()) {
// set your "contacto" entity
$contacto->setMessage($form->get('message')->getData());
// do the rest of $contact->set{......}
// save the message in database (if you need to but I would do it)
$em = $this->getDoctrine()->getManager();
$em->persist($contacto);
$em->flush();
// SEND THE EMAIL
$message = \Swift_Message::newInstance();
$message->setFrom('enquiries#myweb.com.ar')
->setTo($this->container->getParameter('tp_main.emails.contact_email'))
->setSubject('YOUR SUBJECT')
->setBody($this->renderView('TPMainBundle:Default:contactEmail.txt.twig', array('contacto' => $contacto)))
->setContentType('text/html');
$this->get('mailer')->send($message);
$this->get('session')->setFlash('blogger-notice', 'Your contact enquiry was successfully sent. Thank you!');
return $this->redirect($this->generateUrl('contacto_new'));
}
}
return $this->render('TPMainBundle:Default:contact.html.twig', array('form' => $form->createView()));
}