0
votes

I followed the the ZF2.4 manual book chapter 12(Introducing our first “Blog” Module), and i have create a Blog module. I have Post Form:

class PostForm extends Form{
    public function __construct($name = null, $options = array()){
    parent::__construct($name, $options);

    $this->add(array(
       'name' => 'post-fieldset', 
       'type' => 'Blog\Form\PostFieldset',
        'options' => array(
            'use_as_base_fieldset' => true
        )
      )
    );

    $this->add(array(
        'type' => 'submit',
        'name' => 'submit',
        'attributes' => array(
            'value' => 'Insert new Post',
            'class' => 'btn btn-primary'
        )
    ));
  }
}

and the Post fieldset:

class PostFieldset extends Fieldset{
public function __construct($name = null, $options = array()){
    parent::__construct($name, $options);

    $this->setHydrator(new ClassMethods(false));
    $this->setObject(new Post());

    $this->add(array(
        'type' => 'hidden',
        'name' => 'id'
    ));

    $this->add(array(
        'type' => 'text',
        'name' => 'text',
        'options' => array(
            'label' => 'The Text'
        ),
        'attributes' => array(
            'class' => 'form-control'
        )
    ));

    $this->add(array(
        'type' => 'text',
        'name' => 'title',
        'options' => array(
            'label' => 'Blog Title'
        ),
        'attributes' => array(
            'class' => 'form-control'
        )
    ));
}
}

this is my action:

public function addAction(){ 
    $request = $this->getRequest();
    if ($request->isPost()) {
        $this->postForm->setInputFilter(new PostFilter());
        $this->postForm->setData($request->getPost());
        if ($this->postForm->isValid()) { 
            echo "The form is valid\n"; 
            //Debug:: dump($this->postForm->getData()); die();
            // save post...
        }else{
            echo "The form is not valid\n"; 
             Debug:: dump($this->postForm->getData()); die();    
        }
    }
    return new ViewModel(array(
        'form' => $this->postForm
    ));
    }

and the Post InputFilter:

class PostFilter extends InputFilter {
public function __construct(){
    $title = new Input('title');
    $title->setRequired(true);
    $title->setValidatorChain($this->getTextTitleValidatorChain());
    $title->setFilterChain($this->getStringTrimFilterChain());

    $text = new Input('text');
    $text->setRequired(true);
    $text->setValidatorChain($this->getTextTitleValidatorChain());
    $text->setFilterChain($this->getStringTrimFilterChain());

    $this->add($title);
    $this->add($text);
    }
 protected function getTextTitleValidatorChain(){
    $notEmpty = new NotEmpty();
    $stringLength = new StringLength();
    $stringLength->setMin(5);
    $stringLength->setMax(20);

    $validatorChain = new ValidatorChain();
    $validatorChain->attach($notEmpty);
    $validatorChain->attach($stringLength);

    return $validatorChain;
}
protected function getStringTrimFilterChain(){
    $filterChain = new FilterChain();
    $filterChain->attach(new StringTrim());

    return $filterChain;
}
}

and add.phtml view:

<?php 
 $form = $this->form;
 $form->setAttribute('action', $this->url());
 $form->prepare();
 echo $this->form()->openTag($form);
?>
<div class="form-group" >
  <?php echo $this->formRow($form->get('post-fieldset')->get('title')); ?>
</div>

<div class="form-group" >
  <?php echo $this->formRow($form->get('post-fieldset')->get('text')); ?>
</div>
<?php echo $this->formSubmit($form->get('submit')); ?>
<?php echo $this->form()->closeTag(); ?>

If i submit the form, form errors not showing. Also if i enter valid data i see the data dump like the following:

 The form is not valid
array(4) {
   ["title"] => NULL
   ["text"] => NULL
   ["submit"] => string(15) "Insert new Post"
 ["post-fieldset"] => array(3) {
   ["id"] => NULL
   ["text"] => string(7) "my text"
   ["title"] => string(8) "my title"
 }
}

the data NOT hydrated into Post object, also dump data shows two title and two text and fieldset name, i don't understand. and if i remove $this->postForm->setInputFilter(new PostFilter()); the data hydrate into Post object.

Why the validation not working and form errors not showing, and why data not hydrated into Post object ?

1

1 Answers

0
votes

I can only redirect you to the docs : https://framework.zend.com/manual/2.3/en/modules/zend.input-filter.intro.html

To resume :

  • you can't declare a new InputFilter object like this, this will create new inputs, but your object already has them. So this is why you have them both in you var_dump
  • I advise you to use in your Fieldset's object the InputFilterProviderInterface with this method : public function getInputFilterSpecification() in there you can set your filters and validators, since there is no changes in your controller, you'll have a simpler code docs :https://framework.zend.com/manual/2.0/en/modules/zend.form.quick-start.html#hinting-to-the-input-filter

Your validation not working because your hydration fails due to your inputfilter.

EDIT :

I saw your comments and i disagree here's why :

 $this->add(array(
       'name' => 'post-fieldset', 
       'type' => 'Blog\Form\PostFieldset',
        'options' => array(
            'use_as_base_fieldset' => true
        )
      )
    );

When you do this you tell to your form to add some fields, and since you have no validation group set, il will be validate_all. But when you add in your controller your class PostFilter you add again new inputs, so you'll have 2 inputs titles and 2 inputs text, one into a fieldset with an hydrator, and one with no hydrator at all. That's why you have your inputs into the fieldset hydrated and your other inputs failing because the validator of your inputfilter's class fails !

So as I said, try my solution and see what happens.

This link can help you to understand why your PostFilter is not correctly configured into your form : Adding input filter to fieldset in ZF2