#php #forms #zend-framework2
#php #формы #zend-framework2
Вопрос:
Я пытаюсь создать форму, содержащую коллекцию наборов полей, используя только спецификации массива и ZendFormFactory
.
Вот как я создаю форму с использованием фабрики:
$factory = new ZendFormFactory();
$fieldset = $factory->createFieldset(array(
'elements' => array(
array(
'spec' => array(
'name' => 'name',
'type' => 'Text',
'attributes' => array(
'class' => 'form-control input-sm',
),
'options' => array(
'label' => 'Name',
),
),
),
array(
'spec' => array(
'name' => 'driverClass',
'type' => 'Text',
'attributes' => array(
'class' => 'form-control input-sm',
),
'options' => array(
'label' => 'Driver',
),
),
),
),
'input_filter' => array(
'name' => array(
'required' => true,
),
),
));
$form = $factory->createForm(array(
'name' => 'application-form',
'attributes' => array(
'role' => 'form',
),
'elements' => array(
array(
'spec' => array(
'type' => 'Collection',
'name' => 'connection',
'options' => array(
'label' => 'Connections',
'allow_add' => true,
'allow_remove' => true,
'should_create_template' => true,
'count' => 2,
'target_element' => $fieldset,
),
),
),
array(
'spec' => array(
'name' => 'security',
'type' => 'Csrf',
'attributes' => array(
'required' => 'required',
),
),
),
array(
'spec' => array(
'name' => 'submit',
'type' => 'Submit',
'attributes' => array(
'class' => 'btn btn-sm btn-primary',
),
'options' => array(
'label' => 'Apply',
),
),
),
),
));
Результирующая форма отлично работает, когда я пытаюсь задать данные и отобразить элементы формы. Но когда я проверяю это и извлекаю данные, вот так (в контроллере):
$form->setData($this->getRequest()->getPost());
if ($form->isValid() === true) {
$data = $form->getData();
var_dump($this->getRequest()->getPost());
var_dump($data);
}
С этим набором данных в виде POST:
object(ZendStdlibParameters)[141]
private 'storage' (ArrayObject) =>
array (size=3)
'connection' =>
array (size=2)
0 =>
array (size=2)
'name' => string 'orm_default' (length=11)
'driverClass' => string 'DoctrineDBALDriverPDOMySqlDriver' (length=36)
1 =>
array (size=2)
'name' => string 'blog' (length=4)
'driverClass' => string 'DoctrineDBALDriverPDOMySqlDriver' (length=36)
'submit' => string '' (length=0)
'security' => string '20d5c146d8874dc804948e962d5de91b-87c9e4097f9140d259efb5c589a05d6b' (length=65)
Массив, возвращаемый вызовом $form->getData()
, показывает пустую коллекцию:
array (size=3)
'security' => string '20d5c146d8874dc804948e962d5de91b-87c9e4097f9140d259efb5c589a05d6b' (length=65)
'submit' => string '' (length=0)
'connection' =>
array (size=0)
empty
Чего мне не хватает?
Ожидаемым результатом является коллекция, названная в этом примере ‘connection’, содержащая два массива, представляющих два набора полей, как указано в данных POST. У меня такое чувство, что это связано с отсутствующим InputFilter (или, по крайней мере, с его спецификациями), потому что мне удалось получить ожидаемый результат при реализации класса fieldset, который расширяет ZendFormFieldset
и реализует ZendInputFilterInputFilterProviderInterface
.
Ответ №1:
Только что обнаружил этот класс ZendFormInputFilterProviderFieldset
, который делает именно то, что я пропустил.
Я добавил тип в спецификации набора полей и изменил спецификации входного фильтра (что обязательно) следующим образом:
$fieldset = $factory->createFieldset(array(
'type' => 'ZendFormInputFilterProviderFieldset',
'elements' => array(
array(
'spec' => array(
'name' => 'name',
'type' => 'Text',
'attributes' => array(
'class' => 'form-control input-sm',
),
'options' => array(
'label' => 'Name',
),
),
),
array(
'spec' => array(
'name' => 'driverClass',
'type' => 'Text',
'attributes' => array(
'class' => 'form-control input-sm',
),
'options' => array(
'label' => 'Driver',
),
),
),
),
'options' => array(
'input_filter_spec' => array(
'name' => array(
'required' => true,
),
),
),
));
И сейчас это работает нормально. Надеюсь, это кому-то помогло.