Search code examples
phpmysqlzend-frameworkzend-framework2zend-form

Zend Form isValid() return false


My Zend Form isValid() method is return false even though there is no errors showing in anywhere. Because of that i cannot execute the isValid() method and store my form value into mysql. I have no idea why it will return false when there is no errors.

My Controller:

class IndexController extends AbstractActionController
{
    private $usersTable;

    public function indexAction()
    {
        return new ViewModel();
    }

    public function addAction()
    {
        $form = new Add();

        if($this->request->isPost())
        {
            $complaintPost = new Post();
            $form->bind($complaintPost);
            $form->setInputFilter(new AddPost());
            $form->setData($this->request->getPost());
            $a = 'apple';
            $b = 'boy';
            if($form->isValid()) // Check whether it is running or not 
            {
              echo "<script>console.log($a);</script>";
              $complaintPost = $form->getData();
              //"<script>console.log($this->getUsersTable()->insert($data));</script>";
              $this->getUsersTable()->insert($complaintPost); //checking whether is it null
            }
            else
            {
              echo "<script>console.log($form->isValid());</script>";
            }
        }

        return new ViewModel(array(
                'form' => $form,
                ));
    }

    public function getUsersTable()
    {
        if(!$this->usersTable)
        {
            $this->usersTable = new TableGateway(
                    'complaint',
                 $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter')
            );
        }
        return $this->usersTable;
    }

}

My phtml file:

<h1>Add Complaint</h1>

<?php
/** @var \Zend\Form\Form $form */
    $form = $this->form;
    $form->prepare();
    echo $this->form()->openTag($form);
?> 

<div class="form-group">
    <?php echo $this->formRow($form->get('name'));?>
</div>
<div class="form-group">
    <?php echo $this->formRow($form->get('icno'));?>
</div>
<div class="form-group">
    <?php echo $this->formRow($form->get('address'));?>
</div>
<div class="form-group">
    <?php echo $this->formRow($form->get('phoneno'));?>
</div>
<div class="form-group">
    <?php echo $this->formRow($form->get('complaintdetail'));?>
</div>
<div class="form-group">
    <?php echo $this->formRow($form->get('datetime'));?>
</div>
<div class="form-group">
    <?php echo $this->formRow($form->get('image'));?>
</div>
<div class="form-group">
    <?php echo $this->formRow($form->get('location'));?>
</div>
<div class="form-group">
    <?php echo $this->formRow($form->get('remarks'));?>
</div>

<?php echo $this->formSubmit($form->get('submit'));?>
<?php echo $this->form()->closeTag();?>

My form:

class Add extends Form 
{
    public function __construct() 
    {
        parent::__construct('add');
        $this->setHydrator(new ClassMethods());

        //More to add
        $name = new Element\Text('name');
        $name->setLabel("Name");
        $name->setAttribute('class', 'form-control');

        $nric = new Element\Text('icno');
        $nric->setLabel("NRIC");
        $nric->setAttribute('class', 'form-control');

        $address = new Element\Text('address');
        $address->setLabel("Address");
        $address->setAttribute('class', 'form-control');

        $phonenum = new Element\Text('phoneno');
        $phonenum->setLabel("Phone Number");
        $phonenum->setAttribute('class', 'form-control');

        $complaintdetail = new Element\Text('complaintdetail');
        $complaintdetail->setLabel("Things to Complaint");
        $complaintdetail->setAttribute('class', 'form-control');

        $dateHappen = new Element\Text('datetime');
        $dateHappen->setLabel("Date and time");
        $dateHappen->setAttribute('class', 'form-control');

        $picture = new Element\File('image');
        $picture->setLabel('Photo');
        $picture->setAttribute('id', 'image');

        $location = new Element\Text('location');
        $location->setLabel("Location");
        $location->setAttribute('class', 'form-control');

        $remarks = new Element\Text('remarks');
        $remarks->setLabel("Remarks");
        $remarks->setAttribute('class', 'form-control');

        $submit = new Element\Submit('submit');
        $submit->setValue('Sent Complaint');
        $submit->setAttribute('class', 'btn btn-primary');

        $this->add($name);
        $this->add($nric);
        $this->add($address);
        $this->add($phonenum);
        $this->add($complaintdetail);
        $this->add($dateHappen);
        $this->add($picture);
        $this->add($location);
        $this->add($remarks);
        $this->add($submit);
    }
}

My Form Validator:

class AddPost extends InputFilter
{
    public function __construct()
    {
        $name = new Input('name');
        $name->setRequired(true);
        $name->setValidatorChain($this->getNameValidatorChain());
        $name->setFilterChain($this->getStringTrimFilterChain());

        $nric = new Input('icno');
        $nric->setRequired(true);
        $nric->setValidatorChain($this->getICValidatorChain());
        $nric->setFilterChain($this->getStringTrimFilterChain());

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

        $phonenum = new Input('phoneno');
        $phonenum->setRequired(true);
        $phonenum->setValidatorChain($this->getPhoneValidatorChain());
        $phonenum->setFilterChain($this->getStringTrimFilterChain());

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

        $datetime = new Input('datetime');
        $datetime->setRequired(true);
        $datetime->setFilterChain($this->getStringTrimFilterChain());

        $picture = new Input('image');
        $picture->setRequired(true);

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

        $remark = new Input('remarks');
        $remark->setRequired(true);
        $remark->setValidatorChain($this->getICValidatorChain());
        $remark->setFilterChain($this->getStringTrimFilterChain());

        $this->add($name);
        $this->add($nric);
        $this->add($address);
        $this->add($phonenum);
        $this->add($complaintdetail);
        $this->add($datetime);
        $this->add($picture);
        $this->add($location);
        $this->add($remark);
    }

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

        return $filterChain;
    }

    protected function getLocationValidatorChain()
    {
        $stringLength = new StringLength();
        $stringLength->setMin(3);
        $stringLength->setMax(100);

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

        return $validatorChain;
    }

    protected function getComplaintValidatorChain()
    {
        $stringLength = new StringLength();
        $stringLength->setMin(3);
        $stringLength->setMax(100);

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

        return $validatorChain;
    }

    protected function getPhoneValidatorChain()
    {
        $stringLength = new StringLength();
        $stringLength->setMin(3);
        $stringLength->setMax(15);

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

        return $validatorChain;
    }

    protected function getAddressValidatorChain() 
    {
        $stringLength = new StringLength();
        $stringLength->setMin(3);
        $stringLength->setMax(70);

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

        return $validatorChain;
    }

    protected function getICValidatorChain() 
    {
        $stringLength = new StringLength();
        $stringLength->setMin(3);
        $stringLength->setMax(50);

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

        return $validatorChain;
    }

    protected function getNameValidatorChain()
    {
        $stringLength = new StringLength();
        $stringLength->setMin(3);
        $stringLength->setMax(50);

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

        return $validatorChain;
    }
}

Solution

  • If you read the documentation on the Zend-Framework input-filter class you can see that you have to get the messages yourself from the input-filter class after checking invalid:

    if ($inputFilter->isValid()) {
        echo "The form is valid\n";
    } else {
        echo "The form is not valid\n";
        foreach ($inputFilter->getInvalidInput() as $error) {
            print_r($error->getMessages());
        }
    }
    

    So to see the validation error messages you need to get those messages and output them yourself in some way. Most likely you would attach them to a response object and return them to the client in some orderly way.