Как правильно сохранить данные Zend\Form + Doctrine 2?

Приветствую!
Изучаю ZF2+Doctrine 2.
Ситуация следующая:
1) Имеется набор сущностей для управления данными Пользователя.
down.php?i=rtmufdy&view

2) Zend\Form + Fieldset
Форма состоит из 2х наборов полей, Основной (Entity\User) и Второстепеннный (Entity\UserInfo). В них структура согласно документации.

function __construct( ObjectManager $objectManager ) {

        parent::__construct('ProfileEdit');

        $this->setName('ProfileEdit');
        $this->setAttribute('method', 'post');

// objectManager = $this->getServiceLocator()->get('Doctrine\ORM\EntityManager')
        $this->setHydrator(new DoctrineHydrator($objectManager));

        $userFieldset = new UserBasicFieldset($objectManager);
        $userFieldset->setUseAsBaseFieldset(true);
        $this->add($userFieldset);

        $userInfoFieldset = new UserInfoFieldset($objectManager);
        $this->add($userInfoFieldset);

        $this->add(array(
            'type' => 'Zend\Form\Element\Csrf',
            'name' => 'security'
        ));

        $this->add(array(
            'name'       => 'submit',
            'attributes' => array(
                'type'  => 'submit',
                'value' => 'Save',
            )
        ));
    }


3) Контроллер
Так же достаточно прост
if ($this->zfcUserAuthentication()->hasIdentity()) {

            $userId        = $this->zfcUserAuthentication()->getIdentity()->getId();
            $objectManager = $this->getOrmEntityManager();
            $form          = new ProfileEditForm($objectManager);
            $user          = $objectManager->find('User\Entity\User', $userId);

            $form->bind($user);

            if ($this->request->isPost()) {

                $form->setData($this->request->getPost());

                if ($form->isValid()) {

                    $objectManager->flush();
                }
            }

            return new ViewModel(array(
                'form' => $form
            ));
        }

Если я не добавляю Второстепенный (Entity\UserInfo) набор полей в форму, то вывод и сохранение работают как нужно. В противном случае работает только вывод.
  • Вопрос задан
  • 3000 просмотров
Пригласить эксперта
Ответы на вопрос 1
Keanor
@Keanor
Ведущий разработчик
Что за DoctrineHydrator? Я у себя только DoctrineObject нашел, всегда его и использовал.

Как происходит гидрация через DoctrineObject - Doctrine получает метадату для сущности которую вы гидрируете, и итерируясь по массиву переданому в hydrate обрабатывает только записи ключи которых есть в св-вах сущности. При обработки каждого ключа массива гидратор проверяет - связь ли это, и если связь то какая: в нём есть два метода для гидрации данных по связям: toOne() и toMany(), так как у вас судя по схеме ManyToMany вызовется метод toMany(), я его сюда скопирую:

// If the collection contains identifiers, fetch the objects from database
        foreach ($values as $value) {
            if ($value instanceof $target) {
                $collection[] = $value;
            } elseif ($value !== null) {
                $targetObject = $this->find($value, $target);

                if ($targetObject !== null) {
                    $collection[] = $targetObject;
                }
            }
        }


Как видите он умеет работать только с 2 видами данных:
1) с набором ID (тогда он сам ищет сущность, и проставляет связи)
2) с набором сущностей

В вашем случае передается набор массивов, поэтому не работает.

Чтобы заработало, нужно использовать гидратор в том числе и для Fieldset'а, тогда в момент когда будет гидрироваться основная форма элементы уже будут сгидрированы, и вместо массива массивов toMany() получит массив сущностей.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы