Увлажняющая форма ZF2 с учениями

У меня проблемы с увлажнением формы. Когда я вытаскиваю свою сущность из базы данных, OrderLinePerson Поле заполнено правильно с подключенным объектом. При попытке увлажнить форму это не так.

Ниже приведен пример кода:

<?php

namespace SenetOrder\Form;

use ZF2Core\Form\AbstractForm;
use DoctrineModule\Stdlib\Hydrator\DoctrineObject as DoctrineHydrator;
use SenetOrder\Entity\OrderLine;
use SenetOrder\Form\OrderLinePersonFieldset;

class OrderLineForm extends AbstractForm
{

protected $organisation;

public function __construct($name, $organisation)
{
$this->organisation = $organisation;

parent::__construct($name);

$this->setAttribute('method', 'post');
$this->setAttribute('class', 'form-horizontal');
}

public function init()
{
$this->setHydrator(new DoctrineHydrator($this->getEntityManager()));
$this->setObject(new OrderLine());

$this->add([
'name'       => 'orderLineType',
'type'       => 'DoctrineModule\Form\Element\ObjectSelect',
'options'    => [
'object_manager'             => $this->getEntityManager(),
'target_class'               => 'SenetOrder\Entity\OrderLineType',
'property'                   => 'name',
'disable_inarray_validator'  => true,
'empty_option'               => '',
'label'                      => _('Type'),
'label_attributes'           => [
'class' => 'col-lg-3 control-label'
],
],
'attributes' => [
'class' => 'form-control',
],
]);

$this->add(array(
'name'       => 'start',
'type'       => 'date',
'options'    => array(
'label'              => _('Start date:'),
'label_attributes'   => array(
'class' => 'col-lg-3 control-label'
),
'format'             => 'd-m-Y',
),
'attributes' => array(
'type'           => 'text',
'class'          => 'form-control datepicker',
'placeholder'    => 'dd-mm-yyyy',
'value'          => date('d-m-Y'),
),
));

$this->add(array(
'name'       => 'end',
'type'       => 'date',
'options'    => array(
'label'              => _('End date:'),
'label_attributes'   => array(
'class' => 'col-lg-3 control-label'
),
'format'             => 'd-m-Y',
),
'attributes' => array(
'type'           => 'text',
'class'          => 'form-control datepicker',
'placeholder'    => 'dd-mm-yyyy',
),
));

$this->add([
'type'       => 'SenetOrder\Form\OrderLinePersonFieldset',
]);

$this->add([
'name'       => 'submit',
'type'       => 'submit',
'options'    => [
'label' => _('Save'),
],
'attributes' => [
'class' => 'btn btn-large btn-primary',
],
]);
}

}

Подключенный Fieldset

namespace SenetOrder\Form;

use Zend\Form\Fieldset;
use SenetOrder\Entity\OrderLinePerson;
use DoctrineModule\Stdlib\Hydrator\DoctrineObject as DoctrineHydrator;

class OrderLinePersonFieldset extends Fieldset
{
protected $serviceManager;

public function __construct($name, $entityManager, $serviceManager, $organisation)
{
$this->organisation = $organisation;
$this->serviceManager = $serviceManager;

parent::__construct($name);

$this->setHydrator(new DoctrineHydrator($entityManager));
$this->setObject(new OrderLinePerson());

$this->add([
'name'       => 'person',
'type'       => 'DoctrineModule\Form\Element\ObjectSelect',
'options'    => [
'disable_inarray_validator'  => true,
'object_manager'             => $entityManager,
'target_class'               => 'SenetPerson\Entity\Person',
'label'                      => _('Person'),
'label_attributes'           => [
'class' => 'col-lg-3 control-label'
],
'value_options'              => $this->getOrganisationPersonOptions(),
],
'attributes' => [
'class' => 'form-control',
],
]);
}

protected function getOrganisationPersonOptions()
{
$data = [''];
if(!is_null($this->organisation))
{
$service = $this->serviceManager->get('senetperson_service_person');
$collection = $service->getBySearch(null, null, 'employee')->getResult();
$data = [];
foreach($collection as $person)
{
$data[$person->getPersonId()] = $person->parseFullname();
}
}
return count($data) === 0 ? [''] : $data;
}

}

Действие, как обрабатывать форму

<?php
public function addAction()
{
$orderLine = new OrderLine();
$orderLine->setOrder($this->order);

$request = $this->getRequest();
$form = $this->getServiceLocator()->get('FormElementManager')->get('SenetOrder\Form\OrderLineForm');
$form->bind($orderLine);

// Handle request
if($request->isPost())
{
$form->setData($request->getPost());
if($form->isValid())
{
$orderLine->setCreated(new \DateTime());

var_dump($request->getPost());
var_dump($orderLine);die;
die('hi there ok form');

$this->getEntityManager()->persist($orderLine);
$this->getEntityManager()->flush();

$this->resultMessenger()->addSuccessMessage($this->getTranslator()->translate('The order has been successfully added'));
return $this->redirect()->toRoute('order/view', array('orderId'=>$order->getOrderId()));
}
$this->resultMessenger()->addErrorMessage('There are errors in your form', $form->getMessages());
}

// Set breadcrumb label
$nav = $this->getServiceLocator()->get('breadcrumb_navigation');
$page = $nav->findByLabel(':name');
$page->setLabel($this->order->getName());

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

Выше приведен код, который выполняется. Ниже дампа сущности после $form->setData() выполнен. Также дамп объекта запроса

<?php
## REQUEST
object(Zend\Stdlib\Parameters)[193]
public 'orderLineType' => string '1' (length=1)
public 'start' => string '01-09-2014' (length=10)
public 'end' => string '29-09-2014' (length=10)
public 'orderLinePerson' =>
array (size=1)
'person' => string '286512' (length=6)
public 'submit' => string '' (length=0)

## ENTITY DUMP
object(SenetOrder\Entity\OrderLine)[861]
protected 'orderLineId' => null
protected 'order' =>
object(SenetOrder\Entity\Order)[864]
protected 'orderId' => string '1' (length=1)
protected 'name' => string 'Hé leuk, orders in ZF2!' (length=24)
protected 'description' => string 'Hé floepert, stiekem verder programmeren he!' (length=45)
protected 'organisation' =>
object(DoctrineORMModule\Proxy\__CG__\SenetOrganisation\Entity\Organisation)[901]
public '__initializer__' =>
object(Closure)[867]
...
public '__cloner__' =>
object(Closure)[868]
...
public '__isInitialized__' => boolean false
protected 'organisationId' => string '6300' (length=4)
protected 'ownerPerson' => null
protected 'otys' => null
protected 'name' => null
protected 'paymentInterval' => null
protected 'vatNumber' => null
protected 'debtor' => null
protected 'invoiceByEmail' => null
protected 'deleted' => null
protected 'created' => null
protected 'addressCollection' => null
protected 'orderCollection' => null
protected 'invoiceCollection' => null
protected 'address' =>
object(DoctrineORMModule\Proxy\__CG__\Application\Entity\Address)[904]
public '__initializer__' =>
object(Closure)[897]
...
public '__cloner__' =>
object(Closure)[896]
...
public '__isInitialized__' => boolean false
protected 'addressId' => string '56' (length=2)
protected 'organisation' => null
protected 'addressType' => null
protected 'otys' => null
protected 'address' => null
protected 'postalcode' => null
protected 'city' => null
protected 'email' => null
protected 'department' => null
protected 'country' => null
protected 'created' => null
protected 'deleted' => null
protected 'person' =>
object(DoctrineORMModule\Proxy\__CG__\SenetPerson\Entity\Person)[933]
public '__initializer__' =>
object(Closure)[900]
...
public '__cloner__' =>
object(Closure)[881]
...
public '__isInitialized__' => boolean false
protected 'personId' => string '286278' (length=6)
protected 'otys' => null
protected 'initials' => null
protected 'firstname' => null
protected 'middlename' => null
protected 'lastname' => null
protected 'position' => null
protected 'birthday' => null
protected 'gender' => null
protected 'file' => null
protected 'created' => null
protected 'deleted' => null
protected 'personRoleCollection' => null
protected 'personOrganisationCollection' => null
protected 'personLogin' => null
protected 'ownedOrderCollection' => null
protected 'personOrderCollection' => null
protected 'personHourCollection' => null
protected 'personPhoneCollection' => null
protected 'personEmailCollection' => null
protected 'personContractCollection' => null
protected 'created' =>
object(DateTime)[862]
public 'date' => string '2014-09-08 11:55:11.000000' (length=26)
public 'timezone_type' => int 3
public 'timezone' => string 'Europe/Amsterdam' (length=16)
protected 'orderLineCollection' =>
object(Doctrine\ORM\PersistentCollection)[921]
private 'snapshot' =>
array (size=0)
...
private 'owner' =>
&object(SenetOrder\Entity\Order)[864]
private 'association' =>
array (size=16)
...
private 'em' =>
object(Doctrine\ORM\EntityManager)[351]
...
private 'backRefFieldName' => string 'order' (length=5)
private 'typeClass' =>
object(Doctrine\ORM\Mapping\ClassMetadata)[932]
...
private 'isDirty' => boolean false
private 'initialized' => boolean false
private 'coll' =>
object(Doctrine\Common\Collections\ArrayCollection)[920]
...
protected 'orderLineType' =>
object(SenetOrder\Entity\OrderLineType)[1353]
protected 'orderLineTypeId' => string '1' (length=1)
protected 'name' => string 'Secondment' (length=10)
protected 'start' =>
object(DateTime)[1350]
public 'date' => string '2014-09-01 00:00:00.000000' (length=26)
public 'timezone_type' => int 3
public 'timezone' => string 'Europe/Amsterdam' (length=16)
protected 'end' =>
object(DateTime)[1348]
public 'date' => string '2014-09-29 00:00:00.000000' (length=26)
public 'timezone_type' => int 3
public 'timezone' => string 'Europe/Amsterdam' (length=16)
protected 'created' =>
object(DateTime)[1354]
public 'date' => string '2014-09-12 12:18:38.000000' (length=26)
public 'timezone_type' => int 3
public 'timezone' => string 'Europe/Amsterdam' (length=16)
protected 'deleted' => null
protected 'orderLinePerson' => null

Чего я хочу достичь, так это того, что orderLinePerson поле заполнено своим объектом OrderLinePerson

0

Решение

заменить весь набор полей

$this->add([
'type'       => 'SenetOrder\Form\OrderLinePersonFieldset',
]);

с элементом внутри этого набора полей:

$this->add([
'name'       => 'orderLinePerson',
'type'       => 'DoctrineModule\Form\Element\ObjectSelect',
'options'    => [
'disable_inarray_validator'  => true,
'object_manager'             => $entityManager,
'target_class'               => 'SenetPerson\Entity\Person',
'label'                      => _('Person'),
'label_attributes'           => [
'class' => 'col-lg-3 control-label'
],
'value_options'              => $this->getOrganisationPersonOptions(),
],
'attributes' => [
'class' => 'form-control',
],
]);

Наборы полей — это наборы элементов, которые представляют свойства связанного объекта.
Так что с вашим конфигом есть объект OrderLine с зависимым объектом OrderLinePerson который сам имеет зависимый объект SenetPerson\Entity\Person, Я думаю, что это не ваше намерение?

1

Другие решения

Отсутствует orderLinePerson в группе проверки

0

У меня была похожая настройка с формой, содержащей настраиваемые зависимости Select с БД. Форма не будет автоматически гидрировать объект значениями POST. Я не смог определить причину, поэтому мне пришлось применить обходной путь:

if ($form->isValid() === false){
...show form
}

$hydrator = $form->getHydrator();
$userEntity = $hydrator->hydrate($httpRequest->getPost()->toArray(), $userEntity);

ОБНОВИТЬ:

Я обнаружил, что причина была в том, что я расширял Zend \ Form \ Form и переопределял метод getInputFilter (). Это депопулирует гидратированную сущность. После того, как я создал свои собственные методы для заполнения фильтра и вызвал их, сущность не изменилась.

0
По вопросам рекламы [email protected]