Charlie
Charlie

Reputation: 486

Symfony 1.4 form won't validate

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

Answers (4)

user1003932
user1003932

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

Visav&#236;
Visav&#236;

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

Mike Purcell
Mike Purcell

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

Ian Gregory
Ian Gregory

Reputation: 5820

It might be wise to render any global form errors:

$form->renderGlobalErrors() 

Upvotes: 1

Related Questions