Cant send contact form in Symfony 2 - php

I trying to send contact form in Symfony2, but i have the error:
Variable "form" does not exist in VputiMainBundle:Main:contact.html.twig at line 20
Here is my controller:
public function contactAction(Request $request)
{
$form = $this->createForm(new ContactType());
$formView = $form->createView();
$form->handleRequest($request);
if ($form->isValid()) {
$message = \Swift_Message::newInstance()
->setSubject($form->get('subject')->getData())
->setFrom($form->get('email')->getData())
->setTo('mail.com.deu')
->setBody(
$this->renderView(
'VputiMainBundle:Main:contact.html.twig',
array(
'ip' => $request->getClientIp(),
'name' => $form->get('name')->getData(),
'message' => $form->get('body')->getData()
)
)
);
if ($this->get('mailer')->send($message)) {
$this->get('session')->getFlashBag()->add('message_send', 'thanks!');
} else {
$this->get('session')->getFlashBag()->add('send_error', 'error!');
}
}
return $this->render('VputiMainBundle:Main:contact.html.twig', array('form' => $formView));
}
Where is my problem, what I doing wrong?

You are using the same template both for showing the form to send a contact request and the body of the mail. Notice the two VputiMainBundle:Main:contact.html.twig. If the form is valid it tries to render contact.html.twig which needs a form variable obviously.
Create a new template for the mail body which does not rely on the form view.

Related

PHP - Zend3, Jquery, Ajax (post)

I have built a website using php and the zend framework. In one of the pages I have a zend form and a table. The user can fill in the form, click the search button(page refresh occurs) and then get the corresponding results in the table.
What I am trying to do is to implement the same functionality using Ajax so the page won't have to refresh or ask for re-submission when reloaded.
From my controller I pass the data I want to display to view.phtml.
When the page first opens all the data from database gets displayed in the table. Somehow after the user clicks search :
the ajax post data should be retrieved in the controller
compared to the rest of the data to see if there are any matches
return the data matched
public function searchAction(): ViewModel
{
$persons = $this->personsService->getAllPersons();
$form = $this->personsForm;
if ($this->getRequest()->isPost()) {
$formData = $this->params()->fromPost();
$form->setData($formData);
if ($form->isValid()) {
$validFilteredData = $form->getData();
$persons = $this->personsService->getPersonsAfterSearch($validFilteredData);
}
}
return new ViewModel([
'persons' => $persons,
'form' => $form,
]);
}
I would like any suggestions on how to implement ajax since I am a beginner in web development and I don't experience working with ajax.
Thanks in advance.
Before you do this:
return new ViewModel([
'persons' => $persons,
'form' => $form,
]);
Add this:
if ($this->getRequest()->isXmlHttpRequest()) {
return new \Zend\View\Model\JsonModel(
[
'persons' => $persons,
'form' => $form,
]
);
}
Note: you've tagged "zend-framework" but mentioned "zend3". Above solution works for ZF2 and ZF3, don't know about ZF1.
Update due to comments:
Full function would be:
public function searchAction() : ViewModel
{
$persons = $this->personsService->getAllPersons();
$form = $this->personsForm;
if ($this->getRequest()->isPost()) {
$formData = $this->params()->fromPost();
$form->setData($formData);
if ($form->isValid()) {
$validFilteredData = $form->getData();
$persons = $this->personsService->getPersonsAfterSearch($validFilteredData);
}
}
$data = [
'persons' => $persons,
'form' => $form,
];
// AJAX response
if ($this->getRequest()->isXmlHttpRequest()) {
return new \Zend\View\Model\JsonModel($data);
}
return $data; // No need to return "new ViewModel", handled via ZF magic
}

Symfony form submit and validate from another method

I have made a form created after an Ajax request (after the first form (Test1Type) is submitted)
public function indexAction(Request $request): Response
{
$form = $this->createForm(Test1Type::class);
$form->handleRequest($request);
if ($request->isXmlHttpRequest()) {
$form = $this->createForm(Test2Type::class);
return new Response($this->renderView('test/_results.html.twig', [
'form' => $form->createView(),
]));
}
return $this->render('test/index.html.twig', [
'form' => $form->createView(),
]);
}
Then I want to submit, validate and get the datas from this Test2Type in another method
public function confirmAction(Request $request): Response
{
dump($form->getData());
return $this->render('test/confirm.html.twig', [
]);
}
But I don't have acces to my form variable and I will not re-use $form = $this->createForm(Test2Type::class);...
I think this is possible but I really don't have any clues to made this work...
Do you have some ideas ?
It's not possible, you must create $form variable before using it for submittion and validation. To avoid duplicate code on create Test2Type form, you should redirect to confirmAction in indexAction after the form submitted and valid.
public function indexAction(Request $request)
{
$form = $this->createForm(Test1Type::class)->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
return $this->redirectToRoute('confirm.action.route_name');
}
return $this->render('test/index.html.twig', [
'form' => $form->createView(),
]);
}
public function confirmAction(Request $request)
{
$form = $this->createForm(Test2Type::class)->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
return $this->render('test/confirm.html.twig', [
'data' => $form->getData()
]);
}
return $this->render('test/_results.html.twig', [
'form' => $form->createView(),
]);
}
You should add another action in your controller for the ajax request with another route!!
This is better readable code and works better with the history button of your browser. (less cache problems) furthermore you can of course simply change the 'action' attribute of the HTML <form> element. Follow this link to read how: http://symfony.com/doc/current/form/action_method.html

Silex second form behind first form

What I want to do is quite simple. I have a first form. When this form is submitted, I have another form. When this second form is submitted, I want execute somes actions.
So here is my controller simplified:
$app->post('/path', function(Request $request) use ($app) {
$app['request'] = $request;
$token = $app['security.token_storage']->getToken();
if (null !== $token) {
$user = $token->getUser();
// First form
$form = $app['form.factory']->createBuilder(FormType::class)
->add('field_form1', TextType::class, [
'required' => true,
])
->getForm();
// Second form
$formcb = $app['form.factory']->createBuilder(FormType::class)
->add('field_form2', TextType::class, [
'required' => true,
])
->getForm();
// When second form is submitted
$formcb->handleRequest($request);
if($formcb->isSubmitted() && $formcb->isValid()) {
// isValid is never true
$data = $formcb->getData();
}
// When first form is submitted
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()) {
$data = $form->getData();
switch ($data["paiementType"]) {
[...]
case 'mycase':
// Render of the second form
return $app['twig']->render('page2.twig', [
'form' => $formcb->createView(),
]);
default: break;
}
}
// Render of the first form
return $app['twig']->render('page1.twig', [
'form' => $form->createView(),
]);
}
})->bind('path');
But,
No problems for the first form, it works well.
The second form seems to have already been validated when it is render, because the fields errors message are display on the form.
When I submit the second form, I never enter in the if($formcb->isSubmitted() && $formcb->isValid()) { clause, because isValid is never true... However, the form is submitted...
So I don't know what is wrong, maybe it is not the good way to render a form behind another form...

Symfony 2 upload file simple form

Hello I want simple upload no database for now.
Inside of controller:
public function UploadAction(Request $request)
{
$form = $this->createFormBuilder( array('csrf_protection' => false))
->add('file', 'file')
->add('Send', 'submit')
->getForm();
if ($form->isValid()) {
$extension = $file->guessExtension();
if (!$extension) {
// extension cannot be guessed
$extension = 'bin';
}
$file->move('blah', rand(1, 99999).'.'.$extension);
}
return $this->render(
'FelekFosBundle:Plik:Upload.html.twig',
array(
'form' => $form->createView(),
)
);
}
Also I want to disable csrf_protection still code used seems not working.
Form is rendering well except csrf_protection. Still it's not preform any upload action. And I get errors.
csrf_message The CSRF token is invalid. Please try to resubmit the
form.
You have to call $form->handleRequest($request); before testing your form_validity.
The form isn't submited if you don't call handleRequest.
Options is on argument 2 of createFormBuilder method. Maybe
$form = $this->createFormBuilder( null, array('csrf_protection' => false))
could be better. Take a look here

Unique email check in zend framework is not working properly

I am working on a project based on Zend framework. In user registration I have to check for unique email. My code is working fine when I register a user for the first time, but when I try to update the user information and press the update button, it gives the error message:
Email already taken
Please help me to solve this problem. My code is attached below:
$this->addElement('text', 'email', array(
'label' => 'Your email address:',
'required' => true,
'filters' => array('StringTrim'),
'validators' => array(
'EmailAddress',
array('Db_NoRecordExists', true, array(
'table' => 'users',
'field' => 'email',
'messages' => array(
'recordFound' => 'Email already taken'
)
)
)
)
));
I have changed my controller to this:
public function addAction()
{
$modelUsers = new Model_Users();
$userId = $this->_getParam('userId');
$form = $this->_getAddForm();
if ($userId) {
$populateData = array();
$user = $modelUsers->fetch($userId);
if ($user instanceof Model_User) {
$populateData = $user->toArray();
}
$form->populate($populateData);
}
$request = $this->getRequest();
if ($request->isPost()) {
$email = $this->getRequest()->getParam('email');
if (strtolower(trim($email)) == $modelUsers->fetchByEmail($email)) {
// change $this->_user->getAccount()->getEmail() to retrieve the user's current email address
// remove validator from form
$form->getElement('email')->removeValidator('Db_NoRecordExists');
}
$post = $request->getPost();
if ($form->isValid($post)) {
$values = $form->getValidValues($post);
$data = array(
'firstName' => $values['firstName'],
'userTypeId' => 2,
'lastName' => $values['lastName'],
'email' => $values['email'],
'userName' => $values['userName'],
'password' => $values['password'],
'role' => $values['role']
);
if ($userId) {
$user = $modelUsers->fetch($userId);
if ($user instanceof Model_User) {
$user->setFromArray($data);
$success = $user->save();
if ($success) {
echo Zend_Json::encode(array('status' => self::STATUS_SUCCESS, 'message' => 'Successfully updated the user!'));
exit;
}
}
} else {
$user = $modelUsers->createRow($data);
$success = $user->save();
if ($success) {
echo Zend_Json::encode(array('status' => self::STATUS_SUCCESS, 'message' => 'Successfully added the user!'));
exit;
}
}
echo Zend_Json::encode(array('status' => self::STATUS_FAILED, 'message' => 'user not added'));
exit;
} else {
$errors = array();
$errors = $form->errors();
echo Zend_Json::encode(array('status' => self::STATUS_ERROR, 'data' => $errors));
exit;
}
}
$this->view->form = $form;
$this->_helper->layout->disableLayout();
}
Model:
public function fetchByEmail($email)
{
$email=fetchOne('SELECT email FROM users WHERE email = $email');
//$select->where('email=?',$email) ;
//$student = $this->fetchRow($select);
return $email;
}
But still this is not working
One simple way you can solve this problem is to remove the validator from that form element when the form is being edited. You may also want to keep the validator if they are attempting to change their email address since they shouldn't be able to change their email to one that already exists in the database.
Leave the validator in your Zend_Form class, add this code only when a user is being edited.
if ($this->getRequest->isPost()) {
$email = $this->getRequest()->getParam('email'); // get email from form
// if email address has not changed, remove validator from form
if (strtolower(trim($email)) == $this->_user->getAccount()->getEmail()) {
// change $this->_user->getAccount()->getEmail() to retrieve the user's current email address
// remove validator from form
$form->getElement('email')->removeValidator('Db_NoRecordExists');
}
// validate form
if ($form->isValid($this->getRequest()->getPost()) {
//...
}
}
So what you are doing is removing the Db_NoRecordExists validator from the form element when the form is being edited, and only if they are not attempting to change their email address if they are allowed to do so.
It will give you allways this error because you are using validation , that email is present in DB table or not.
But the email is existing in database that's why it is giving error.
Remove this validation , it will help you.
if(isset($_SESSION['session_id']))
{
// code for update query
}
else
{
// code for insert query
}

Categories