用Doctrine实体保湿ZF2形式

时间:2014-09-15 08:37:21

标签: php forms doctrine-orm zend-framework2

我有问题保湿我的表格。当我从数据库中提取我的实体时,我的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

3 个答案:

答案 0 :(得分:1)

替换整个字段集

$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',
    ],
]);

Fieldsets是表示绑定对象属性的元素集合。 因此,使用您的配置,对象OrderLine具有依赖对象OrderLinePerson,该对象本身具有依赖对象SenetPerson\Entity\Person。我猜那不是你的意图吗?

答案 1 :(得分:0)

在validationGroup

缺少orderLinePerson

答案 2 :(得分:0)

我有一个类似的设置,其中包含一个包含自定义Select with DB依赖关系的表单。表单不会自动使用POST值水合实体。我一直无法确定原因,因此在此期间我必须实施一个解决方法:

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

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

更新:

我发现原因是因为我正在扩展Zend \ Form \ Form并覆盖getInputFilter()方法。这使水合实体减少了。一旦我创建了自己的方法来填充过滤器并调用它们,实体就完好无损了。