Как правильно увлажнять и извлекать Учения из Zend Forms

Я только начинаю с Doctrine и переписываю некоторый код для использования сущностей Doctrine в некоторых формах.

У меня есть Entity Business, который имеет отношения 1:n с адресами, сотрудниками, электронными письмами и т. Д. Настройка действительно проста и работает нормально.

Чтобы добавить новые предприятия, я создал BusinessForm и Fieldsets для каждой из моих сущностей. Вот конструктор формы:

public function __construct($scenario='create', $entityManager = null) {
    parent::__construct('business_form');
    $this->scenario = $scenario;
    $this->entityManager = $entityManager;
    $this->setAttribute('method', 'post');

    $businessFieldset = new BusinessFieldset($this->entityManager);
    $businessFieldset->setUseAsBaseFieldset(true);
    $this->add($businessFieldset);

    $hydrator = new DoctrineHydrator($this->entityManager, new Business());
    $this->setHydrator($hydrator);
    $this->addElements();
    $this->addInputFilter();
}

addElements просто добавляет данные Submit и CSRF.

А вот действие контроллера:

public function addAction(){
    $form = new BusinessForm('create', $this->entityManager);
    if ($this->getRequest()->isPost()) {
        $data = $this->params()->fromPost();                
        $form->setData($data);
        if($form->isValid()) {
            // save Object
            return $this->redirect()->toRoute('subcontractor', ['action'=>'index']);                
        }      
    } 
    return new ViewModel([
        'form' => $form
    ]);
}

Форма проверяется, и я могу получить данные из формы с $form->getData(), Но я не могу понять, как получить заполненный объект из формы, используя гидратор формы. Когда я использую setObject(new Business()) в начале контроллера я получаю ошибку в то время как $form->isValid() бежит:

Zend\Hydrator\ArraySerializable::extract expects the provided object to implement getArrayCopy()

Разве это не неправильный гидратор вызывается?

Если я не setObject() но вместо этого используйте $form->bind(new Business()) после проверки я получаю пустой объект из $form->getObject(), Если я получу данные и увлажню новый объект с помощью гидратора формы, вот так: $form->getHydrator()->hydrate($data['business], new Business()) я получаю населенный объект, который я ожидал. (Бизнес является названием базового набора полей)

Итак, мой вопрос, как я могу получить результат последнего вызова от просто использования $form->getObject() после проверки?

[РЕДАКТИРОВАТЬ]

Проблема, по-видимому, связана с коллекциями наборов полей, используемых в качестве наборов подполей в наборе бизнес-полей. Если я проверяю форму без использования коллекций, я получаю ожидаемый бизнес-объект от $form->getData()

Вот пример, как я могу добавить коллекцию (в бизнес-fieldset):

$this->add([
        'name' => 'emails',
        'type' => 'Zend\Form\Element\Collection',
        'attributes' => [
            'id' => 'business_emails',
        ],
        'options' => [
            'label' => 'Emails',
            'count' => 1,
            'should_create_template' => true,
            'template_placeholder' => '__index__',
            'allow_add' => true,
            'target_element' => [
                'type' => 'LwsSubcontractor\Form\EmailFieldset',
            ],
            'target_class' => 'LwsSubcontractor\Entity\Email'
        ],
    ]);

и вот EmailFieldset:

public function __construct() {
    parent::__construct('email');
    $this->setObject(new Email());
    $this->addElements();        
}

protected function addElements() {
    $this->add([
        'name' => 'email',
        'type' => 'Zend\Form\Element\Email',
        'attributes' => [
            'placeholder' => 'E-Mail (z.B. email@muster-email.de)',
            'class' => 'form-control',
            'required' => true,
            'size' => 50,
        ],
        'options' => [
            'label' => 'Email',
        ],
    ]);        

}

}

При использовании коллекций я получаю сообщение об ошибке сверху. Так что после добавления гидратора к каждому Fieldset я был в порядке.

Хотя у меня сложилось впечатление, что установка гидратора для формы приведет к тому, что используемые наборы полей наследуют этот гидратор. Или это произошло из-за использования наборов полей в качестве коллекций, а не напрямую?

1 ответ

Решение

Вы должны добавить гидратор для всех ваших наборов полей, лично я использую DoctrineModule\Stdlib\Hydrator\DoctrineObject для доктринальных сущностей.

Я также хотел бы посмотреть на использование init() метод для инициализации ваших форм и добавления элементов, а затем регистрации и извлечения ваших форм и наборов полей через FormElementManager, $serviceLocator->get('FormElementManager')->get(yourFieldsetorForm::class), Форма может быть затем введена в ваш контроллер.

Надеюсь, это поможет.

Другие вопросы по тегам