ZF2表单将所有选择选项设置为在绑定时选择

时间:2014-04-02 08:24:21

标签: php doctrine-orm zend-framework2

我的ZF2表单元素有问题(选择)。当我将我的学说实体绑定到此表单时,我的所有选择选项都会获得所选属性,而不仅仅是应该选择的属性。该实体刚刚获得了一个连接对象,并且Hydrator也设置在for中。

以下是我的一些代码。希望我只是错过了一些小事。

AddressEntity.php

<?php

namespace Application\Entity;

use Doctrine\ORM\Mapping as ORM;
use ZF2Core\Entity\AbstractEntity;

/**
 * @ORM\Entity
 * @ORM\Table(name="`address`")
 */
class Address extends AbstractEntity
{

    /**
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     * @ORM\Column(type="bigint", options={"unsigned":true})
     */
    protected $addressId;

    /**
     * @ORM\ManyToOne(targetEntity="SNOrganisation\Entity\Organisation", inversedBy="organisationId")
     * @ORM\JoinColumn(name="organisationId", referencedColumnName="organisationId", nullable=false)
     */
    protected $organisation;

    /**
     * @ORM\ManyToOne(targetEntity="AddressType")
     * @ORM\JoinColumn(name="addressTypeId", referencedColumnName="addressTypeId", nullable=false)
     */
    protected $addressType;

    /** @ORM\Column(type="string", nullable=true) */
    protected $otys;

    /** @ORM\Column(type="string") */
    protected $address;

    /** @ORM\Column(type="string", nullable=true) */
    protected $postalcode;

    /** @ORM\Column(type="string") */
    protected $city;

    /** @ORM\Column(type="string", nullable=true) */
    protected $email;

    /**
     * @ORM\ManyToOne(targetEntity="ZF2Country\Entity\Country")
     * @ORM\JoinColumn(name="countryId", referencedColumnName="countryId", nullable=false)
     */
    protected $country;

    /** @ORM\Column(type="datetime") */
    protected $created;

    /** @ORM\Column(type="datetime", nullable=true) */
    protected $deleted;

    public function getAddressId()
    {
        return $this->addressId;
    }

    public function getOrganisation()
    {
        return $this->organisation;
    }

    public function getAddressType()
    {
        return $this->addressType;
    }

    public function getOtys()
    {
        return $this->otys;
    }

    public function getAddress()
    {
        return $this->address;
    }

    public function getPostalcode()
    {
        return $this->postalcode;
    }

    public function getCity()
    {
        return $this->city;
    }

    public function getEmail()
    {
        return $this->email;
    }

    public function getCreated()
    {
        return $this->created;
    }

    public function getDeleted()
    {
        return $this->deleted;
    }

    public function setAddressId($addressId)
    {
        $this->addressId = $addressId;
        return $this;
    }

    public function setOrganisation($organisation)
    {
        $this->organisation = $organisation;
        return $this;
    }

    public function setAddressType($addressType)
    {
        $this->addressType = $addressType;
        return $this;
    }

    public function setOtys($otys)
    {
        $this->otys = $otys;
        return $this;
    }

    public function setAddress($address)
    {
        $this->address = $address;
        return $this;
    }

    public function setPostalcode($postalcode)
    {
        $this->postalcode = $postalcode;
        return $this;
    }

    public function setCity($city)
    {
        $this->city = $city;
        return $this;
    }

    public function setEmail($email)
    {
        $this->email = $email;
        return $this;
    }

    public function setCreated($created)
    {
        $this->created = $created;
        return $this;
    }

    public function setDeleted($deleted)
    {
        $this->deleted = $deleted;
        return $this;
    }

    public function getCountry()
    {
        return $this->country;
    }

    public function setCountry($country)
    {
        $this->country = $country;
        return $this;
    }

}

AddressForm.php

<?php

namespace SNOrganisation\Form;

use Zend\Form\Form;
use DoctrineModule\Stdlib\Hydrator\DoctrineObject as DoctrineHydrator;
use Application\Entity\Address;
use Zend\ServiceManager\ServiceManager;

class AddressForm extends Form
{

    public function __construct($name = null, $entityManager, ServiceManager $serviceManager)
    {
        parent::__construct($name);

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

        $this->setHydrator(new DoctrineHydrator($entityManager, 'Application\Entity\Address'));
        $this->setObject(new Address());

        $this->add(array(
            'name'       => 'addressType',
            'type'       => 'select',
            'options'    => array(
                'label'              => _('Type'),
                'label_attributes'   => array(
                    'class' => 'col-lg-2 control-label'
                ),
                'value_options' => $this->getAddressTypeOptions($serviceManager),
            ),
            'attributes' => array(
                'class'      => 'form-control',
            ),
        ));

        $this->add(array(
            'name'       => 'address',
            'type'       => 'text',
            'options'    => array(
                'label'              => _('Address'),
                'label_attributes'   => array(
                    'class' => 'col-lg-2 control-label'
                ),
            ),
            'attributes' => array(
                'class'          => 'form-control',
                'placeholder'    => 'Abbey Road 1',
            ),
        ));

        $this->add(array(
            'name'       => 'postalcode',
            'type'       => 'text',
            'options'    => array(
                'label'              => _('Postalcode'),
                'label_attributes'   => array(
                    'class' => 'col-lg-2 control-label'
                ),
            ),
            'attributes' => array(
                'class'      => 'form-control',
                'placeholder'    => '1234 AB',
            ),
        ));

        $this->add(array(
            'name'       => 'city',
            'type'       => 'text',
            'options'    => array(
                'label'              => _('City'),
                'label_attributes'   => array(
                    'class' => 'col-lg-2 control-label'
                ),
            ),
            'attributes' => array(
                'class'      => 'form-control',
                'placeholder'    => 'Amsterdam',
            ),
        ));

        $this->add(array(
            'name'       => 'country',
            'type'       => 'select',
            'options'    => array(
                'label'              => _('Country'),
                'label_attributes'   => array(
                    'class' => 'col-lg-2 control-label'
                ),
                'value_options' => $this->getCountryOptions($serviceManager),
            ),
            'attributes' => array(
                'class'      => 'form-control',
            ),
        ));

        $this->add(array(
            'name'       => 'email',
            'type'       => 'email',
            'options'    => array(
                'label'              => _('Email'),
                'label_attributes'   => array(
                    'class' => 'col-lg-2 control-label'
                ),
            ),
            'attributes' => array(
                'class'      => 'form-control',
                'placeholder'    => 'name@domain.tld',
            ),
        ));
        $this->add(array(
            'name'       => 'submit',
            'type'       => 'submit',
            'options'    => array(
                'label' => _('Save'),
            ),
            'attributes' => array(
                'class' => 'btn btn-large btn-primary',
            ),
        ));
    }

    protected function getAddressTypeOptions($serviceManager)
    {
        $data = array();
        $addressTypeService = $serviceManager->get('application_service_addresstype');
        $addressTypeCollection = $addressTypeService->getAddressTypes()->getResult();

        foreach($addressTypeCollection as $addressType)
        {
            $data[$addressType->getAddressTypeId()] = $addressType->getName();
        }
        return $data;
    }

    protected function getCountryOptions($serviceManager)
    {
        $data = array();
        $countryService = $serviceManager->get('zf2country_service_country');
        $countryCollection = $countryService->getCountries()->getResult();

        foreach($countryCollection as $country)
        {
            $data[$country->getCountryId()] = $country->getName();
        }
        return $data;
    }
}

AddressController.php

<?php

namespace SNOrganisation\Controller;

use ZF2Core\Controller\AbstractController;
use Zend\View\Model\ViewModel;
use Application\Entity\Address;

class AddressController extends AbstractController
{
    public function editAction()
    {
        $organisationId = (int)$this->params()->fromRoute('id');
        $addressId = (int)$this->params()->fromRoute('addressId');
        $request = $this->getRequest();
        $address = $this->getEntityManager()->getRepository('Application\Entity\Address')->find($addressId);

        if ($address)
        {
            $addressForm = $this->getServiceLocator()->get('snorganisation_form_address');
            $addressForm->bind($address);
        }
        else
        {
            $this->resultMessenger()->addFatalMessage($this->getTranslator()->translate('The address could not be found'));
            $this->redirect()->toRoute('organisation');
        }

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

实体转储

<?php
object(Application\Entity\Address)[700]
  protected 'addressId' => string '487956' (length=6)
  protected 'organisation' => 
    object(DoctrineORMModule\Proxy\__CG__\SenetOrganisation\Entity\Organisation)[701]
      public '__initializer__' => 
        object(Closure)[583]
      public '__cloner__' => 
        object(Closure)[584]
      public '__isInitialized__' => boolean false
      protected 'organisationId' => string '412705' (length=6)
      protected 'ownerPerson' => null
      protected 'otys' => null
      protected 'name' => null
      protected 'paymentInterval' => null
      protected 'vatNumber' => null
      protected 'debtor' => null
      protected 'invoiceByEmail' => null
      protected 'active' => null
      protected 'reasonInactive' => null
      protected 'created' => null
      protected 'addressCollection' => null
      protected 'personCollection' => null
      protected 'orderCollection' => null
      protected 'serviceManager' => null
  protected 'addressType' => 
    object(DoctrineORMModule\Proxy\__CG__\Application\Entity\AddressType)[714]
      public '__initializer__' => 
        object(Closure)[704]
      public '__cloner__' => 
        object(Closure)[705]
      public '__isInitialized__' => boolean false
      protected 'addressTypeId' => string '2' (length=1)
      protected 'name' => null
      protected 'serviceManager' => null
  protected 'otys' => null
  protected 'address' => string 'Langebrug 87 b' (length=14)
  protected 'postalcode' => string '2311 TJ' (length=7)
  protected 'city' => string 'Leiden' (length=6)
  protected 'email' => null
  protected 'country' => 
    object(DoctrineORMModule\Proxy\__CG__\ZF2Country\Entity\Country)[724]
      public '__initializer__' => 
        object(Closure)[711]
      public '__cloner__' => 
        object(Closure)[710]
      public '__isInitialized__' => boolean false
      protected 'countryId' => string '157' (length=3)
      protected 'nameIso' => null
      protected 'name' => null
      protected 'iso' => null
      protected 'iso3' => null
      protected 'serviceManager' => null
  protected 'created' => 
    object(DateTime)[698]
      public 'date' => string '2014-03-22 16:05:49' (length=19)
      public 'timezone_type' => int 3
      public 'timezone' => string 'Europe/Amsterdam' (length=16)
  protected 'deleted' => null
  protected 'serviceManager' => null

2 个答案:

答案 0 :(得分:2)

让我调查一下,原因是什么。有时使用Zend \ Form \ Select元素很方便,而不是Doctrine元素。但Zend元素有时无法处理主义实体。原因在于方法Zend\Form\View\Helper\FormSelect.php的以下文件renderOptions代码。

if (ArrayUtils::inArray($value, $selectedOptions)) {
    $selected = true;
}

这段代码会选中每个选项。$selectedOptions不是实体ID,而是实体对象。这个对象通过魔术方法转换为数组,所以我们错了$selectedOptions

所以我决定改变表格元素类型来选择&#39;选择&#39;到DoctrineModule\Form\Element\ObjectSelect并注入entityManager。

'type' => 'DoctrineModule\Form\Element\ObjectSelect',
'options' => array(
    'object_manager' => $entityManager,
    'target_class' => 'Telecom\Entity\Name',
)

我不知道,为什么有时这不是问题。可能我应该看一下由Doctrine生成的Proxy对象。如果我理解了什么,我会更新答案。

答案 1 :(得分:0)

DoctrineModule \ Form \ Element \ ObjectSelect诀窍