I have a problem with my ZF2 form element (select). When i bind my doctrine entity to this form, all my select options get the selected attribute instead of just the one that should. The entity just got a connected object and the Hydrator is set in the for aswell.
Here is some of my code. Hope i just missed something small.
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' => '[email protected]',
),
));
$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,
));
}
}
Entity Dump
<?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
Let me investigate, what is the reason. Sometimes it is convenient to use Zend\Form\Select element, not Doctrine element. But Zend element sometimes can not deal with doctrine Entities. The reason is in the following code of file Zend\Form\View\Helper\FormSelect.php
at method renderOptions
.
if (ArrayUtils::inArray($value, $selectedOptions)) {
$selected = true;
}
This piece of code makes every option selected. But $selectedOptions
is not entity id, it is Entity object. This object is transformed into array via magic method, so we have wrong $selectedOptions
.
So I've decided to change form element type from 'Select' to DoctrineModule\Form\Element\ObjectSelect
and inject entityManager.
'type' => 'DoctrineModule\Form\Element\ObjectSelect',
'options' => array(
'object_manager' => $entityManager,
'target_class' => 'Telecom\Entity\Name',
)
I dont know, why sometimes it is not a problem. Probably I should take a look at Proxy object, generated by Doctrine. I will update the answer if I understand something.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With