Symfony 1.4 Validation - forms

Can anyone tell me how could i validate the data on the other page (where was not created the form object)?
The thing is: on the page 'A' i am creating the form object with its own validators and showing the form to the user. But the action goes to the page 'B', where i need to validate the data.
I want to do something like this (page 'B'):
$form = new someForm();
$form->bind($this->getRequest()->getParameter('data'));
if($form->isValid())
{
print 'true';
}
else
{
print 'false';
}
But as you can imagine, it will print 'false'.

I guess it happens due to CSRF protection of forms in Symfony
Try to use this code
$form = new someForm();
$form->disableLocalCSRFProtection();
$form->bind($this->getRequest()->getParameter('data'));
if($form->isValid())
{
print 'true';
}
else
{
print 'false';
}

maybe you could solve this like:
public function executeFoo($request){
$this->form = new fooForm();
$this->getUser()->setAttribute('tmpForm', $this->form);
}
in your form the action has to point to module/bar
there you can do:
public function executeBar($request){
$this->forward404Unless($form = $this->getUser()->getAttribute('tmpForm'));
$form->bind($this->getRequest()->getParameter('data'))
// and so on
}

Related

Symfony compare the value in the session and the value sent by the form

I generate a random code and then save it in the session.
The user has an input and a "validate" button.
The goal is that the value sent by the user is equal to the value generated in session
I save the code in the session
//Get session
$session = $request->getSession();
//Set random code in session
$session->set("code", $code);
dump($session->get('code'));
I create the form
$form = $this->createForm(ValidCodeType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
if ($form["code"]->getData() === $session->get('code')){
echo "OK";
}else {
echo "FAILED";
}
}
When I get to the page a code is generated (wnt) (and when I reload the page)
The "null" corespond to the value sent by the form
dump($form["code"]->getData());
I submit the form. The value sent is good but a new code has been generated
Return FAILED
The code I'm sending is exactly the one that's generated, it should return "OK" to me.
Any ideas? Thank you
Symfony 4
This is kind of a guess here but I suspect you are generating your code and setting it on every request before the form is processed. Hence it changes when the form is posted. If this is indeed the problem then just move the code past the $form->isValid block.
class MyController {
function myAction() {
$form = $this->createForm(ValidCodeType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
if ($form["code"]->getData() === $session->get('code')){
echo "OK";
}else {
echo "FAILED";
}
}
$code = some_random_code();
$request->getSession()->set("code", $code);
By the way, you seem to be duplicating Symfony's csrf functionality.

Access Form values in my Symfony executeAction backend

So one of my pages consists of a quiz form that has several questions of type multiple choice, the choices are specified as radio buttons. I have been scanning the Symfony documentation to find out how to access form field values inputted by the user. Thing is, this isn;t a doctrine or propel based form, and neither do I require the values to be stored in the database, hence executing a $form->save() makes little sense to me. But I do require access to specific values of my form in my backend once the user hits submit.
Most of Symfony documentation that i have run into doesn't necessarily explain how this can be done. I would assume it would be something to the effect of :
$request->getParameter( 'radio_choices_id selected value ').
Thanks to all who read this and Cheers to the ones who respond to it :)
Parijat
Hm, it is very simple if I understand your question right)
For widget:
$this->widgetSchema['name'] = new sfWidgetFormChoice(array('choices' => array('ch_1', 'ch_2')));
Ok,in action:
$this->form = new FaqContactForm();
if ($request->isMethod('post')) {
$this->form->bind($request->getParameter($this->form->getName()));
if ($this->form->isValid()) {
$your_val=$this->form->getValue('name');
//or
$your_val=$this->form['name']->getValue());
}
}
In backend in protected function processForm(sfWebRequest $request, sfForm $form)
you have
$form->bind($request->getParameter($form->getName()), $request->getFiles($form->getName()));
if ($form->isValid())
{
$notice = $form->getObject()->isNew() ? 'The item was created successfully.' : 'The item was updated successfully.';
try {
$product = $form->save();
} catch (Doctrine_Validator_Exception $e) {
$errorStack = $form->getObject()->getErrorStack();
$message = get_class($form->getObject()) . ' has ' . count($errorStack) . " field" . (count($errorStack) > 1 ? 's' : null) . " with validation errors: ";
foreach ($errorStack as $field => $errors) {
$message .= "$field (" . implode(", ", $errors) . "), ";
}
$message = trim($message, ', ');
$this->getUser()->setFlash('error', $message);
return sfView::SUCCESS;
}
Before $product = $form->save(); try
$your_val=$form->getValue('name');
//or
$your_val=$form['name']->getValue());

Session won't be created in Mozilla Firefox

I am working on a purchase system in my assignment and trying to solve the problem by using a session to store data in the process.
Although I'm experiencing a problem in Mozilla Firefox, which cannot for some reason work with the session I have created. There's most likely no doubt that I must have made some kind of mistake.
The process is as follows:
User fills form -> Clicks submit -> [Validation process] -> User reviews confirm page
Here is the relevant code from the controller:
public function indexAction() {
$this->gatewayForm = new Payment_Form_Gateway;
$save = $this->validate();
$this->view->gatewayForm = $save['form'];
$this->view->alert = $save['alert'];
}
public function validate() {
# get form
$form = $this->gatewayForm;
if ($this->_request->isPost()) {
# get params
$data = $this->_request->getPost();
# check validate form
if ($form->isValid($data)) {
$session = new Zend_Session_Namespace('formData'); // name space creation
$session->data = $data;
$this->_helper->redirector('confirm', 'gateway', 'payment');
} else {
$alert = array('Pay failed');
}
$form->populate($data);
}
return array('form' => $form, 'alert' => empty($alert) ? null : $alert );
}
public function confirmAction() {
$this->_helper->viewRenderer->setNoRender(true); // disable std. view
$session = new Zend_Session_Namespace('formData');
$data = $session->data;
if(isset($data)) {
$this->_helper->viewRenderer->setNoRender(false);
} else {
$this->_helper->redirector('index', 'gateway', 'payment');
}
}
Things go wrong in the confirmAction in Firefox, the session namespace seems to be empty? Although this does not occur in Safari, Chrome, IE etc.
Thanks in advance.
I reinstalled Firefox and removed config and cache files which did the magic. Problems solved!

how to email form on submit using zend_form?

OK. I finally got my zend form working, validating, filtering and sending the contents to my process page (by using $form->populate($formData);)
Now, how do I email myself the contents of a form when submitted? Is this a part of Zend_form or some other area I need to be looking in?
Thanks!
You can use Zend Mail for this, Zend form does not offer such functions.. but its an nice idea.
In your controleller, after $form->isValid();
if ($form->isValid($_POST)) {
$mail = new Zend_Mail();
$values = $form->getValues();
$mailText = 'My form valueS: ';
foreach ($values as $v) {
$mailText .= 'Value ' . $v . PHP_EOL;
}
$mail->setFrom('user#user.de', 'user');
$mail->AddTo('Me#me.de', 'me');
$mail->setSubject->$form->getName();
$mail->send();
} else {
// what ever
}

How can I make a Zend Decorator to allow a default value?

I want a basic:
<input type="text" />
And I would like the default value to clear when the user puts in a value (kinda like this). It would be ideal if the default value returned onBlur.
I don't want the default value to be submitted if they leave it and click submit.
I'm generating the form using Zend, and imagine my solution can fit entirely into a Zend Form Decorator.
I can't find any existing ones, so I ask:
Do you have said decorator? Or something that will help me make one?
Just use corresponding jQuery plugins: defaultvalue
Ok, I've built a decorator which allows me to implement the jquery plugin Ololo posted.
It checks to see if the element has a Label set, and if it does, defaults to that:
require_once 'Zend/Form/Decorator/Abstract.php';
class Application_Form_Decorator_DefaultEnabledInput extends Zend_Form_Decorator_Abstract
{
private $attribs = array();
public function render($content)
{
$element = $this->getElement();
if(get_class($element) != 'Zend_Form_Element_Text') throw new Exception("Application_Form_Decorator_DefaultEnabledInput only works on text fields");
$element->setAttrib('type', 'text');
$element->setAttrib('name', htmlspecialchars($element->getName()));
$element->setAttrib('value', htmlspecialchars($element->getValue()));
$attribs = '';
$default = $element->getLabel();
if($default)
{
$element->setAttrib('rel', $default);
$element->setAttrib('title', $default);
$class = $element->getAttrib('class');
$element->setAttrib('class', "$class hasDefault");
$default = "";
}
foreach($element->getAttribs() as $key => $val) $attribs .= "$key='$val' ";
return "<input $attribs/>";
}
}
It allows me to define a default value in the form object (using setLabel).
$element = $this->createElement('text', 'suburb');
$element->setDecorators(array('DefaultEnabledInput'));
$element->setLabel('enter suburb here');
$this->addElement($element);
And all I need to do then is ensure that query and plugin are included on the page, and this piece of code:
$(document).ready(function() {
// default values
$('.hasDefault').each(function(){
$(this).defaultValue();
});
});
Then in the template, I can display the object like this:
<?= $this->form->getElement('suburb') ?>