Skip to content

Instantly share code, notes, and snippets.

@Halanson
Created January 23, 2020 22:52
Show Gist options
  • Save Halanson/3bd977d8c22c823da8c8889abb4f95e2 to your computer and use it in GitHub Desktop.
Save Halanson/3bd977d8c22c823da8c8889abb4f95e2 to your computer and use it in GitHub Desktop.
How to validating a collection in Zend Framework 2 or 3

How to validating a collection in Zend Framework 2 or 3

What to use for

An HTML <form> post request may looks like:

$post = [
    'idUser' => 1,
    'address' => 'foo street',
];

You can easily create a Zend Form for this, filter and validate the user input. But what if you have to validate a list of users? Something more like:

$post = [
    [
        'idUser' => 1,
        'address' => 'foo street',
    ],
    [
        'idUser' => 2,
        'address' => 'bar street',
    ],
];

There is no name you could use to tell Zend Form how to validate the input. Thats where the Zend Collection Element comes in handy.

Structure of form/fieldset composition

UserAddressesForm
-> CollectionElement
  -> UserFieldset
    -> idUser
    -> (may other elements/fieldsets here)
    -> CollectionElement
      -> AddressesFieldset
        -> idAddress
        -> street
        -> (may other elements/fieldsets here)

Pay attention to

  • the CollectionElement within the UserAddressesForm and UserFieldset. It is the only element in this form because of the form of the post request data.
  • the validation group within UserAddressesForm::getValidationGroup()
  • how to set the collections name within the controller: $form->setData(['collection' => $request->getPost()]);

For more information, have a look at the Zend Form Documentation Example

<?php
namespace Application\Form;
use Zend\Form\Element\Number;
use Zend\Form\Element\Text;
use Zend\Form\Fieldset;
use Zend\InputFilter\InputFilterProviderInterface;
class AddressesFieldset extends Fieldset implements InputFilterProviderInterface
{
/**
* AddressesFieldset constructor.
*/
public function __construct() {
parent::__construct('AddressesFieldset');
}
/**
*/
public function init()
{
$this->addElementIdAddress();
$this->addElementStreet();
}
/**
*/
protected function addElementIdAddress()
{
$this->add(
[
'type' => Number::class,
'name' => 'idAddress',
]
);
}
/**
*/
protected function addElementStreet()
{
$this->add(
[
'type' => Text::class,
'name' => 'street',
]
);
}
public function isValid()
/**
* @inheritDoc
*/
public function getInputFilterSpecification()
{
return [
'idStreet' => [
'required' => true,
'filters' => [
// add your filters here
],
'validators' => [
// add your validators here
],
],
'street' => [
'required' => true,
'filters' => [
// add your filters here
],
'validators' => [
// add your validators here
],
],
];
}
}
<?php
namespace Application\Controller;
class IndexController extends AbstractController
{
/**
* @return array
*/
public function indexAction()
{
$request = $this->getRequest();
if ($request->isPost()) {
$form = new UserAddressesForm();
// check the 'collection' here, this is the important trick
$form->setData(['collection' => $request->getPost()]);
if ($form->isValid()) {
var_dump($product);
}
}
return [
'form' => $form,
];
}
}
[
{
"idUser": "1",
"addresses": [
{
"idAddress": "1",
"street": "foo street"
},
{
"idAddress": "2",
"street": "bar street"
}
]
},
{
"idUser": "2",
"addresses": [
{
"idAddress": "3",
"street": "miep street"
}
]
}
]
<?php
namespace Application\Form;
use Zend\Form\Element\Collection;
use Zend\Form\Form;
use Zend\InputFilter\InputFilter;
class UserAddressesForm extends Form
{
/**
* UserAddressesForm constructor.
*/
public function __construct()
{
parent::__construct('UserAddressesForm');
$this->setInputFilter(new InputFilter());
$this->addCollectionElement();
}
/**
*/
public function addCollectionElement(): void
{
$this->add(
[
'type' => Collection::class,
'name' => 'collection',
'options' => [
'target_element' => [
'type' => UserFieldset::class,
],
],
]
);
}
/**
* @return array
*/
public function getValidationGroup()
{
return [
'collection' => [
'idUser',
'address' => [
'idAddress',
'street',
],
],
];
}
}
<?php
namespace Application\Form;
use Zend\Form\Element\Collection;
use Zend\Form\Element\Number;
use Zend\Form\Element\Text;
use Zend\Form\Fieldset;
use Zend\InputFilter\InputFilterProviderInterface;
class UserFieldset extends Fieldset implements InputFilterProviderInterface
{
/**
* GroupFieldset constructor.
*/
public function __construct()
{
parent::__construct('UserFieldset');
$this->addIdUserElement();
$this->addCollectionElement();
}
/**
*/
protected function addIdUserElement(): void
{
$this->add(
[
'type' => Number::class,
'name' => 'idUser',
]
);
}
/**
*/
public function addCollectionElement(): void
{
$this->add(
[
'type' => Collection::class,
'name' => 'addresses',
'options' => [
'target_element' => [
'type' => AddressFieldset::class,
],
],
]
);
}
/**
* @inheritDoc
*/
public function getInputFilterSpecification()
{
return [
'idUser' => [
'required' => true,
'filters' => [
// add your filters here
],
'validators' => [
// add your validators here
],
],
];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment