symfony form handling subcontroller - symfony

I have a working contactform, which allows the user to send a e-mail to me and additionally gets a confirmation mail.
I would like to add a confirmation message to the page, so the user is sure the message was sent.
default.html.twig
<div>
{% include 'includes/overview.html.twig' %}
{% include 'includes/service.html.twig' %}
{% include 'includes/offer.html.twig' %}
{% include 'includes/aboutus.html.twig' %}
{% include 'Advanced/contactForm.html.twig' %}
</div>
contactForm.html.twig
<div class="col-lg-6 col-md-6 contactfrom nopadding">
{# request has to go further to the contactCormController -> {'request' : app.request} #}
{{ render(controller('AppBundle\\Controller\\ContactFormController::contactForm', {'request' : app.request})) }}
</div>
ContactController.php
public function contactForm(Request $request, \Swift_Mailer $mailer)
{
$contactForm = new ContactForm();
$form = $this->createForm(ContactFormType::class, $contactForm);
$form->handleRequest($request);
if ($form->isSubmitted()){ //&& $form->isValid()
$message = (new \Swift_Message)
->setFrom($contactForm->getEmail())
->setTo('mail')
->setSubject("Kontaktformular - ". $contactForm->getFirstname() ." ". $contactForm->getLastname())
->setBody($contactForm->getMessage())
;
if ($contactForm->getHonigtopfRoboter() == "") {
try {
// Sending message to the Host
// Sending confirmation message to the user
$mailer->send($message);
$this->confirmationMail($mailer, $contactForm->getEmail());
// empty ContactForm
unset($contactForm);
unset($form);
$contactForm = new ContactForm();
$form = $this->createForm(ContactFormType::class, $contactForm);
// add succes flashmessage
// $this->addFlash('success', 'message');
}
catch (\Swift_TransportException $Ste){
//TODO: Exception Handling
//echo $Ste->getMessage();
// add error flashmessage
// $this->addFlash('danger', 'message');
}
}
else{
}
}
$contactFormEntity = $form->getData();
return $this->render('form/contactForm.html.twig',
['contactform' => $form->createView()
]);
}
The most common solution I found was to use "flash message", sadly flash messages only work, if you redirect to a new page. Due to the fact, that my contact form stays on the same page it does not work.
My form is embedded and rendered in a sub-html.twig page, so I have the problem to get the information to my ContentController.php and further to the page.
I am really stuck and don't really know the best workflow for this scenario. How do i handle the submit and:
Success -> empty contact form -> success message on page
Error -> leave contact form -> error message on page
Thanks for your help.

If your form is valid, you should redirect the user after the form submission
public function contactForm(Request $request, \Swift_Mailer $mailer)
{
$form = ...
if ($form->isSubmitted() && $form->isValid()) {
$message = ...
$mailer->send($message);
$this->addFlash('success', 'Wohoo, we got it!');
return $this->redirectToRoute('app_contact_form');
}
return $this->render('form/contactForm.html.twig', ['contactform' => $form->createView()]);
}
Doing this, you don't need to empty the form like you do and then re-create it. And as the user is redirected, he will see the flash message.
Also, always check if the form is valid !

Related

Symfony render controller

want to display a form in a modal in the header. In order to make the form work I call the controller Homecontroller.
I called the controller with render controller in the branch but I got a blank page.
Thanks for your help.
header.html.Twig
<h1 class="fw-bold"></h1>
<p class="lead fw-bold"></p>
{{include ('fragments/modal_form.html.twig') }}
</main>
</div>
</div>
modal_form.html.twig
{{ render(controller(
'App\\Controller\\HomeController::index',{'form' : form.createForm()} )) }}
</div>
Controller :
* #Route("/", name="home")
*/
public function index(PostsRepository $postsRepository,TagRepository $tagRepository, Request $request ):Response
{
$listTag = $tagRepository->findAll();
$listPost = $postsRepository->findByPostPHp('php');
$posts = $postsRepository->findByExampleField($value = 6);
$partage = New Posts();
$form = $this->createForm(PartagePostType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$partage = $form->getData();
$this->entityManager->persist($partage);
$this->entityManager->flush();
$this->addFlash('success', 'Votre post a bien été partagé');
}
return $this->render('home/index.html.twig', [
'posts' => $posts,
'tag' => $listTag,
'listPost' => $listPost,
'form' => $form->createView(),
]);
}
I dont' really get how you are trying to render you form but it doesn't work that way, in your modal_form.html.twig you should use the {{ form_start() }} and {{ form_end() }} twig helpers. They take in parameters the created view of the form, i.e, the variable "form" in your case (created in your render with the createView() method).
It should look like that:
{{ form_start(form}}
{{ form_row(form.field) }}
<input type="submit" value="submit">
{{ form_end(form) }}
"field" is whatever name you defined in your FormType. Notice how I added raw HTML for the submit button, it is suggested by Symfony you add the send button that way, even though you can add it in your FormType.
You can learn more about form rendering here : How to Customize Form Rendering
And forms in general there : Forms
Last thing, if you want to use multiple forms with this modal, don't forget to change the name of the variable (also don't forget to add this variable in your controller when you render a template with a form in it, obviously)

Symfony Twig: send a set parameter with a form submit request

I have a form in my twig, i want that by clicking on its submit button, another parameter (that i've set in the twig) get sent to the same action that handles the form :
this is the variable i've set
{% set idprof = profil.id %}
I want to send it with the submit request : ( i know this code is false)
{{ form_widget(form.id),{'idprof': idprof} }}
and the action will look like this :
public function gestProfAction(Request $request, $idprof)
{
}
I'm sorry i know this is a stupid question, but I'm still new in symfony, I couldn't find a solution by myself.
Just pass it in the form start line
{{ form_start(form, {'action': path('idprof', { 'idprof': idprof })}) }}
Remember to add the annotation or yaml for the routing
/**
* #Route("/idprof/{idprof}", name="idprof")
*/
public function gestProfAction(Request $request, $idprof)
{
}
For reference:
http://symfony.com/doc/current/forms.html#rendering-the-form
http://symfony.com/doc/current/form/action_method.html
http://symfony.com/doc/current/templating.html#linking-to-pages

After return redirect to a page the variable doesnot show on view page

In controller i have this code. When i want to show company variable on view it gives the error.
This is my controller.
public function login(Request $request){
$email = $request->input('email');
$password = $request->input('password');
$validation = array(
'email' =>'required',
'password' => 'required');
//dd($email);
$validator = Validator::make($request->all(), $validation);
if ($validator->fails()) {
$messages = $validator->messages();
return redirect('login_with_assismo')
->withErrors($validator)
->withInput(Input::except('password'));
} else {
$admin = DB::table('admin')
->where('email',$email)
->where('password', $password)
->where('is_admin', 1)
->first();
if (!empty($admin)) {
$company = DB::table('company_details')
->where('id', $admin->company_id)
->pluck('company_name');
if (!empty($company)) {
return redirect('company_details')->with('company', $company);
}
}
}
}
and this is my view
<input type="text" name="company_name" class="form-control" placeholder="Company name" value = "{{ company }}">
This is the error when i execute this code:
Use of undefined constant company_name - assumed 'company_name' (View: /opt/lampp/htdocs/assismo/resources/views/company_details.blade.php)
The undefined constant error means that you probably tried something like
<div><!-- or other html -->
{{ company_name}}
</div><!-- ... -->
Even though it should be
<div><!-- or other html -->
{{ $company_name}}
</div><!-- ... -->
Howveer, it does not seem you return a company name variable at all so probably it should be
<div><!-- or other html -->
{{ $company }}
</div><!-- ... -->
Additional remarks:
Your code is highly insecure. You should never ever use this in a productive enviroment. You dont crypt the password or anything. It actually seems like your passwords are stored plain.
You should also consider to write your own requests (php artisan:make request) and move validation somewhere else.
I also don't see a reason to use DB Facade here instead of the actual Object you are interested in.

How to get params in twig file

how can i use $_GET params in TWIG file like using PHP and alerting with JS.
URI-> ?comment=added...
in TWIG,
if($_GET['comment'] == "added"){
...echo '<script>alert("in TWIG file!");</script>';
}
hope it will help you
{% if app.request.get('comment') == "added" %}
<script>alert("in TWIG file!");</script>
{% endif %}
Depending on what you're really trying to achieve, the "Symfony way" of showing confirmation messages would be to use "Flash Messages":
YourController.php:
public function updateAction()
{
$form = $this->createForm(...);
$form->handleRequest($this->getRequest());
if ($form->isValid()) {
// do some sort of processing
$this->get('session')->getFlashBag()->add(
'notice',
'Your changes were saved!'
);
return $this->redirect($this->generateUrl(...));
}
return $this->render(...);
}
Your TwigTemplate.twig:
{% for flashMessage in app.session.flashbag.get('notice') %}
<div class="flash-notice">
{{ flashMessage }}
</div>
{% endfor %}
This way you have multiple advantages:
Redirecting after action prevents form reloading.
Message cannot be triggered from outside.
Flash messages are only fetched once.
See the official documentation on this topic.
The "correct" solution would be use your controller to provide a function to Twig rather than switching on the querystring. This will be more robust and provide better security:
Controller:
function someAction()
{
$params = array('added' => false);
if( /* form logic post */ )
{
//some logic to define 'added'
$params['added'] = true;
}
$this->render('template_name', $params);
}
view:
{% if added %}
<script>alert('added');</script>
{% endif %}
The reasoning is that this is more secure (I can't trigger the alert by just browsing to the url), it maintains all business logic in the controller and you're also able to handle any errors - e.g. if you browse to foo.php?comment=added and there is an error wherein your comment isn't added, the user will still receive the alert.

Swiftmailer//Twig email not rendering correctly

I'm experimenting with symfony2 framework and i'm trying to send emails using swiftmailer and twig. The problem is, with my current implementation, the email is sent in html (you can see the tags, everything).
Here is the controller i'm using:
public function formularioAction()
{
$enquiry = new Enquiry();
$form = $this->createForm(new EnquiryType(), $enquiry);
$request = $this->getRequest();
if($request->getMethod() == 'POST'){
$form->bindRequest($request);
if($form->isValid()){
$message = \Swift_Message::newInstance()
->setSubject('Mail from the App')
->setFrom('no-reply#app.com')
->setTo('******#gmail.com')
->setBody($this->render( 'AcmeDemoBundle:Demo:email.html.twig' ));
$this->get('mailer')->send($message);
//end of mail sending
//redirect - it's important to prevent users from reposting the form if
//they refresh the page
return $this->redirect($this->generateUrl( '_formulario'));
}
}
return $this->render('AcmeDemoBundle:Demo:formulario.html.twig', array('form' => $form->createView()));
}
And the twig template the email is using:
{% extends "AcmeDemoBundle::layout.html.twig" %}
{% block title "Email de teste" %}
{% block content%}
<H1>Este é um render de um email de teste!</H1>
{% endblock%}
What am i doing wrong?
You have to specify the Content-type of the body, by calling the setBody() method like this.
$message->setBody($messageBody, 'text/html');
For more information, see: http://swiftmailer.org/docs/messages.html#setting-the-body-content

Resources