Reputation: 486
I'm hoping someone can point me in the right direction here. This is my first Symfony project, and I'm stumped on why the form won't validate.
To test the application, I fill out all of the form inputs and click the submit button and it fails to validate every time. No idea why.
Any help will be appreciated!
The view -- modules/content/templates/commentSuccess.php :
<?php echo $form->renderFormTag('/index.php/content/comment') ?>
<table>
<?php echo $form['name']->renderRow(array('size' => 25, 'class' => 'content'), 'Your Name') ?>
<?php echo $form['email']->renderRow(array('onclick' => 'this.value = "";'), 'Your Email') ?>
<?php echo $form['subject']->renderRow() ?>
<?php echo $form['message']->renderRow() ?>
<tr>
<td colspan="2">
<input type="submit" />
</td>
</tr>
</table>
</form>
The controller -- modules/content/actions/actions.class.php :
public function executeComment($request)
{
$this->form = new ContentForm();
// Deal with the request
if ($request->isMethod('post'))
{
$this->form->bind($request->getParameter("content"));
if ($this->form->isValid())
{
// Do stuff
//$this->redirect('foo/bar');
echo "valid";
}
else
{
echo "invalid";
}
}
}
The form -- /lib/form/ContentForm.class.php :
class ContentForm extends sfForm {
protected static $subjects = array('Subject A', 'Subject B', 'Subject C');
public function configure()
{
$this->widgetSchema->setNameFormat('content[%s]');
$this->widgetSchema->setIdFormat('my_form_%s');
$this->setWidgets(array(
'name' => new sfWidgetFormInputText(),
'email' => new sfWidgetFormInput(array('default' => '[email protected]')),
'subject' => new sfWidgetFormChoice(array('choices' => array('Subject A', 'Subject B', 'Subject C'))),
'message' => new sfWidgetFormTextarea(),
));
$this->setValidators(array(
'name' => new sfValidatorString(),
'email' => new sfValidatorEmail(),
'subject' => new sfValidatorString(),
'message' => new sfValidatorString(array('min_length' => 4))
));
$this->setDefaults(array(
'email' => '[email protected]'
));
}
}
Thanks in advance! I'll edit this post as needed during progress.
EDIT I've changed my view code to this:
<?php echo $form->renderFormTag('/frontend_dev.php/content/comment') ?>
<table>
<?php if ($form->isCSRFProtected()) : ?>
<?php echo $form['_csrf_token']->render(); ?>
<?php endif; ?>
<?php echo $form['name']->renderRow(array('size' => 25, 'class' => 'content'), 'Your Name') ?>
<?php echo $form['email']->renderRow(array('onclick' => 'this.value = "";'), 'Your Email') ?>
<?php echo $form['subject']->renderRow() ?>
<?php echo $form['message']->renderRow() ?>
<?php if ($form['name']->hasError()): ?>
<?php echo $form['name']->renderError() ?>
<?php endif ?>
<?php echo $form->renderGlobalErrors() ?>
<tr>
<td colspan="2">
<input type="submit" />
</td>
</tr>
</table>
</form>
This gives a required error on all fields, and gives " csrf token: Required. " too.
My controller has been updated to include $this->form->getCSRFToken(); :
public function executeComment($request)
{
$this->form = new ContentForm();
//$form->addCSRFProtection('flkd445rvvrGV34G');
$this->form->getWidgetSchema()->setNameFormat('contact[%s]');
$this->form->getCSRFToken();
// Deal with the request
if ($request->isMethod('post'))
{
$this->form->bind($request->getParameter("content[%s]"));
if ($this->form->isValid())
{
// Do stuff
//$this->redirect('foo/bar');
echo "valid";
}
else
{
$this->_preWrap($_POST);
}
}
}
Still don't know why it's giving me an error on all fields and why I'm getting the csrf token: Required.
Upvotes: 0
Views: 7514
Reputation:
I ran into the same problem with an admin generated backend form. When I tried to apply css schema changes with this code, it broke the token. It didn't break right away. That signals to me this is a bug in Symfony 1.4
$this->setWidgetSchema(new sfWidgetFormSchema(array(
'id' => new sfWidgetFormInputHidden(),
'category' => new sfWidgetFormDoctrineChoice(array('model' => $this->getRelatedModelName('RidCategories'), 'add_empty' => false)),
'location_id' => new sfWidgetFormInputText(),
'title' => new sfWidgetFormInputText(array(), array('class' => 'content')),
'content' => new sfWidgetFormTextarea(array(), array('class' => 'content')),
'content_type' => new sfWidgetFormInputText(),
'schedule_date' => new sfWidgetFormInputText(),
'post_date' => new sfWidgetFormInputText(),
'display_status' => new sfWidgetFormInputText(),
'parent_id' => new sfWidgetFormInputText(),
'keyword' => new sfWidgetFormInputText(),
'meta_description' => new sfWidgetFormInputText(),
'update_frequency' => new sfWidgetFormInputText(),
'keywords' => new sfWidgetFormInputText(),
'allow_content_vote' => new sfWidgetFormInputText(),
'rating_score' => new sfWidgetFormInputText()
)));
Upvotes: 0
Reputation: 2333
Don't you have a typo in your executeComment function ?
$this->form->getWidgetSchema()->setNameFormat('contact[%s]');
and later:
$this->form->bind($request->getParameter("content[%s]"));
You should write:
$this->form->getWidgetSchema()->setNameFormat('content[%s]');
But this line is not necessary you can delete it (the NameFormat is already done in your form class).
And the $request->getParameter("content[%s]") will not word ("content[%s]" is the format of the data sent by the form), you should use:
$this->form->bind($request->getParameter("content"));
Or best, to avoid this kind of typo:
public function executeComment($request)
{
$this->form = new ContentForm();
// Deal with the request
if ($request->isMethod('post'))
{
$this->form->bind($request->getParameter($this->form->getName()));
if ($this->form->isValid())
{
// Do stuff
//$this->redirect('foo/bar');
echo "valid";
}
else
{
$this->_preWrap($_POST);
}
}
}
Upvotes: 0
Reputation: 19999
When you take full control of a Symfony form, as you are doing according to the code snippets in your OP, you will have to manually add the error and csrf elements to your form:
// Manually render an error
<?php if ($form['name']->hasError()): ?>
<?php echo $form['name']->renderError() ?>
<?php endif ?>
<?php echo $form['name']->renderRow(array('size' => 25, 'class' => 'content'), 'Your Name') ?>
// This will echo out the CSRF token (hidden)
<?php echo $form['_csrf_token']->render() ?>
Check out Symfony Docs on custom forms for more info. Also, be sure to add CSRF back to your form, there is no reason to leave it out, and will protect from outside sites posting to your forms.
Upvotes: 4
Reputation: 5820
It might be wise to render any global form errors:
$form->renderGlobalErrors()
Upvotes: 1