Pragmatism in the real world

Exclude elements from Zend\Form's getData()

If you need to exclude some elements from a Zend\Form‘s getData(), the easiest way is to use a validation group.

For example:

class SomeForm extends \Zend\Form\Form implements
    \Zend\InputFilter\InputFilterProviderInterface
{
    public function init()
    {
        $this->add([
            'name' => 'name',
            'options' => ['label' => 'Name'],
        ]);
        
        $this->add([
            'name' => 'email',
            'options' => ['label' => 'Email'],
        ]);

        $this->add([
            'name' => 'submit',
            'type' => 'button',
            'options' => [
                'label' => 'Filter',
            ],
        ]);

        $this->setValidationGroup(['name', 'email']);
    }

    public function getInputFilterSpecification()
    {
        // return input filter specification here
    }
}

The call to setValidationGroup() contains an array of all the elements you want to be validated. In this case we list all elements except the submit button. The side-effect is that when you called $form->getData(), only the values for those elements are returned which can sometimes be useful.

Generalise

Rather than having to re-list all the elements again, it’s more usually to only want to exclude one or two elements. The easiest way to do this is to extend Zend\Form\Form and override isValid() to set up a validation group based on an option called 'exclude' that you apply to the relevant elements:

<?php
namespace My;

class Form extends \Zend\Form\Form
{
    /**
     * Override isValid() to set an validation group of all elements that do not
     * have an 'exclude' option, if at least one element has this option set.
     *
     * @return boolean
     */
    public function isValid()
    {
        if ($this->hasValidated) {
            return $this->isValid;
        }

        if ($this->getValidationGroup() === null) {
            // Add all non-excluded elements to the validation group
            $validationGroup = null;
            foreach ($this->getElements() as $element) {
                if ($element->getOption('exclude') !== true) {
                    $validationGroup[] = $element->getName();
                }
            }
            if ($validationGroup) {
                $this->setValidationGroup($validationGroup);
            }
        }
        
        return parent::isValid();
    }
}
?>

Then, to exclude an element, we extend SomeForm from \My\Form and just add a new 'exclude' option to the elements we wish to exclude. For example:

// in SomeForm::init()
$this->add([
    'name' => 'submit',
    'type' => 'button',
    'options' => [
        'label' => 'Filter',
        'exclude' => true,
    ],
]);

and this element will be automatically excluded when you call $form->getData().