phpvalidationzend-framework2zend-form-elementzend-form2

Zend 2 - Add validator and filter to custom form


I'm going bananas here. I created a simple form containing two fields. One is a text field, the other a textarea. The form looks great but I won't validate - no matter what I try.

Here is my form class:

class MyForm extends Form
{

public function __construct()
{

    parent::__construct();

    $this->add(array(
        'name' => 'subject',
        'required' => true,
        'allowEmpty' => false,
        'options' => array(
            'label' => 'Betreff*',
        ),
        'type' => 'Zend\Form\Element\Text',
        'validators' => array(
            // validators for field "name"
            new \Zend\Validator\NotEmpty(),
        ),
        'filters' => array(
            // filters for field "name"
            array('name' => 'Zend\Filter\StringTrim'),
        ),
    ));

    $this->add(array(
        'name' => 'text',
        'required' => true,
        'allowEmpty' => false,
        'options' => array(
            'label' => 'Nachricht*',
        ),
        'type' => 'Zend\Form\Element\Textarea',
    ));

    $this->add(new Element\Csrf('security'));
}
}

The valdiators and filters are just one of many things I tried...

In my controller here, the form is always valid:

    $form = new MyForm();

    $request = $this->getRequest();
    if ($request->isPost()) {

        $form = new MyForm();
        $form->setData($request->getPost());

        echo $form->isValid();

        if($form->isValid()) { ... }

I always pass the if.

I wonder: Why do I need a validator anyway when I set required=true? Why do they implement such an attribute when it's not doing anything?

But still: How can I validate my form? I just want a clenup filter like trim and a NotEmpty validator.


Solution

  • Adding required => true on a field is just for cosmetic purposes.

    Which "if" are you talking about? I only see you echo the isValid?

    ( sorry about asking questions here, I cant comment tour question yet, low rep... )

    Edit:

    As promised, a "solution". I started writing this after you said you found the solution yourself, so I'll just writ down how I create forms and keep my form and validators together. I like keeping the validators next to my forms for clarity, although technically situating the validators in the entity they're for will give you more flexibility in terms of, say, and API.

    Enough said, here's an example of a ( very basic ) Fieldset which I use in a Form:

    ( I left comments out as all should be very self-explanatory )

    class RaceUserFieldset extends Fieldset implements InputFilterProviderInterface {
    
        public function __construct() {
            parent::__construct('hosts');
    
            $this   ->setHydrator(new \Zend\Stdlib\Hydrator\ClassMethods(false))
                   ->setObject(new RaceUser());
    
            $this->add(array(
                'name' => 'userid',
                'type' => 'hidden',
            ));
            $this->add(array(
                'name' => 'username',
                'type' => 'Text',
            ));
        }
    
        public function getInputFilterSpecification() {
            return array(
                'username' => array(
                    'required' => true,
                ),
            );
        }
    }
    

    It's all right here, the entity, the hydrator, the fields ( no filters, but that's easy ) and the validators.

    To use it in a form ( simplyfied ):

    class RaceUserForm extends Form
    {
        public function __construct()
        {
            parent::__construct('raceuser');
    
            $this->setAttribute('method', 'post');
    
            $this->add(array(
                'type' => 'YCRFront\Form\EditRaceFieldset',
                'options' => array(
                    'use_as_base_fieldset' => true
                )
            ));
    
            $this->add(array(
                'name' => 'submit',
                'attributes' => array(
                    'type' => 'submit',
                    'value' => 'Send'
                )
            ));
        }
    }