Как создать коллекцию наборов полей с помощью фабрики форм в zf2

#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,
            ),
        ),
    ),
));
  

И сейчас это работает нормально. Надеюсь, это кому-то помогло.