ZF2 and Doctrine2: One form -> Two entities - forms

I would like to make one form in which I could have elements to populate two entities.
How can I do that? One of the objects is mapped to the other one.
For example I have something like this:
Table user:
id | login | password
Table user_email:
id | user_id | email
There can be more than one row user_email mapped to user - user can have more than one email.
But - when I'm adding first occurrence of the user I have to get his first email.
I know everything how to map entities but I have problem with populating objects from ZF2 form.
Can anyone suggest how should I do this? I've tried to make two fieldsets but I cannot bind object to fieldset. If this is the solution how bind objects to form which have two filedsets? Every fieldset have mapped doctrine2 hydrator but when I'm trying to bind one of the entity to form (not fieldset which i cannot do) I have error message:
Zend\Stdlib\Hydrator\ArraySerializable::extract expects the provided object to implement getArrayCopy()
Before my example I have to explan what i want to achieve. I have a table cameras - which contain link and some other information about streaming cameras. Second table: cameras_desc contain descriptions to those cameras in different languages. In my CMS i want to add two rows: one in cameras and second in cmaeras_desc in one form. cameras_desc will have first translation in polish language (which would be default language for CMS). As u can see cameras and cameras_desc are mapped with some other entites (cameras with checkpoints and cameras_desc with languages). but thats not a point. What i want to achieve is to populate two rows in two tables by one form. lang in cameras_desc is set by PHP code, but checkpoint is set by user in form by select element. everything works in code below but it isnt made honestly.
This is my code:
First entity:
namespace Granica\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Cameras
*
* #ORM\Table(name="cameras", indexes={#ORM\Index(name="IDX_6B5F276AF27C615F", columns={"checkpoint_id"})})
* #ORM\Entity
*/
class Cameras
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="link", type="text", nullable=false)
*/
private $link;
/**
* #var string
*
* #ORM\Column(name="direction", type="string", length=4, nullable=false)
*/
private $direction;
/**
* #var \Granica\Entity\Checkpoints
*
* #ORM\ManyToOne(targetEntity="Granica\Entity\Checkpoints")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="checkpoint_id", referencedColumnName="id")
* })
*/
private $checkpoint;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set link
*
* #param string $link
* #return Cameras
*/
public function setLink($link)
{
$this->link = $link;
return $this;
}
/**
* Get link
*
* #return string
*/
public function getLink()
{
return $this->link;
}
/**
* Set direction
*
* #param string $direction
* #return Cameras
*/
public function setDirection($direction)
{
$this->direction = $direction;
return $this;
}
/**
* Get direction
*
* #return string
*/
public function getDirection()
{
return $this->direction;
}
/**
* Set checkpoint
*
* #param \Granica\Entity\Checkpoints $checkpoint
* #return Cameras
*/
public function setCheckpoint(\Granica\Entity\Checkpoints $checkpoint = null)
{
$this->checkpoint = $checkpoint;
return $this;
}
/**
* Get checkpoint
*
* #return \Granica\Entity\Checkpoints
*/
public function getCheckpoint()
{
return $this->checkpoint;
}
}
Second entity:
<?php
namespace Granica\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* CamerasDesc
*
* #ORM\Table(name="camera_desc", indexes={#ORM\Index(name="lang", columns={"lang"}), #ORM\Index(name="camera_id", columns={"camera_id"})})
* #ORM\Entity
*/
class CameraDesc
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="description", type="text", nullable=false)
*/
private $description;
/**
* #var \Granica\Entity\Languages
*
* #ORM\ManyToOne(targetEntity="Granica\Entity\Languages")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="lang", referencedColumnName="id")
* })
*/
private $lang;
/**
* #var \Granica\Entity\Cameras
*
* #ORM\ManyToOne(targetEntity="Granica\Entity\Cameras")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="camera_id", referencedColumnName="id")
* })
*/
private $camera;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set description
*
* #param string $description
* #return CamerasDesc
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* #return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Set lang
*
* #param \Granica\Entity\Languages $lang
* #return CamerasDesc
*/
public function setLang(\Granica\Entity\Languages $lang = null)
{
$this->lang = $lang;
return $this;
}
/**
* Get lang
*
* #return \Granica\Entity\Languages
*/
public function getLang()
{
return $this->lang;
}
/**
* Set camera
*
* #param \Granica\Entity\Cameras $camera
* #return CamerasDesc
*/
public function setCamera(\Granica\Entity\Cameras $camera = null)
{
$this->camera = $camera;
return $this;
}
/**
* Get camera
*
* #return \Granica\Entity\Cameras
*/
public function getCamera()
{
return $this->camera;
}
}
Fieldset ( for camera_desc ):
namespace Granica\Form;
use Zend\Form\Fieldset;
use DoctrineModule\Persistence\ObjectManagerAwareInterface;
use Doctrine\Common\Persistence\ObjectManager;
use DoctrineModule\Stdlib\Hydrator\DoctrineObject as DoctrineHydrator;
use DoctrineORMModule\Stdlib\Hydrator\DoctrineEntity;
use Granica\Entity\Languages;
class CameraDescFieldset extends Fieldset implements ObjectManagerAwareInterface
{
protected $objectManager;
public function __construct(ObjectManager $objectManager)
{
parent::__construct('camera_desc');
$this->setObjectManager($objectManager);
$this->setHydrator(new DoctrineHydrator($this->getObjectManager(),'Granica\Entity\CameraDesc'));
$this->add(array(
'name' => 'description',
'attributes' => array(
'type' => 'text',
'placeholder' => 'Opis',
'required' => 'true',
),
'options' => array(
'label' => 'Opis kamery',
),
));
}
// implementacja interfajsu objectmanager
public function setObjectManager(ObjectManager $objectManager)
{
$this->objectManager = $objectManager;
return $this;
}
public function getObjectManager()
{
return $this->objectManager;
}
}
Form (for camera):
use Zend\Form\Form;
use DoctrineModule\Persistence\ObjectManagerAwareInterface;
use Doctrine\Common\Persistence\ObjectManager;
use Granica\Form\CameraDescFieldset;
class AddCameraForm extends Form implements ObjectManagerAwareInterface
{
protected $objectManager;
public function __construct(ObjectManager $objectManager)
{
parent::__construct('checkpoint');
$this->setObjectManager($objectManager);
// tworzenie formularza
$this->setAttribute('method', 'post');
$this->add(array(
'name' => 'checkpoint',
'type' => 'DoctrineModule\Form\Element\ObjectSelect',
'options' => array(
'label' => 'Punkt graniczny',
'object_manager' => $this->getObjectManager(),
'target_class' => 'Granica\Entity\Checkpoints',
'property' => 'name',
'empty_option' => '--- wybierz przejście ---'
),
));
$this->add(array(
'name' => 'link',
'attributes' => array(
'type' => 'text',
'placeholder' => 'Link',
'required' => 'true',
),
'options' => array(
'label' => 'Adres URL kamery',
),
));
$this->add(array(
'type' => 'Zend\Form\Element\Select',
'name' => 'direction',
'attributes' => array(
'required' => 'true',
),
'options' => array(
'label' => 'Kierunek',
'empty_option' => '--- wybierz kierunek ---',
'value_options' => array(
'from' => 'FROM: Wyjazd z Polski',
'to' => 'TO: Wjazd do Polski',
),
)
));
$this->add(new CameraDescFieldset($this->getObjectManager()));
$this->add(array(
'name' => 'submit',
'attributes' => array(
'type' => 'submit',
'value' => 'Zapisz',
'id' => 'submitbutton',
),
));
}
// implementacja interfajsu objectmanager
public function setObjectManager(ObjectManager $objectManager)
{
$this->objectManager = $objectManager;
return $this;
}
public function getObjectManager()
{
return $this->objectManager;
}
}
And the add controller:
public function addAction()
{
$camera = new Cameras();
$cameraDesc = new CameraDesc();
$lang = $this->getEntityManager()->getRepository('Granica\Entity\Languages')->find('pl');
$form = new AddCameraForm($this->getEntityManager());
$cameraDescFieldset = new CameraDescFieldset($this->getEntityManager());
$form->setHydrator(new DoctrineHydrator($this->getEntityManager(),'Granica\Entity\Cameras'));
$form->bind($camera);
$request = $this->getRequest();
if ($request->isPost()) {
$form->setData($request->getPost());
if ($form->isValid()) {
$data = $form->getData();
$cameraDesc->setLang($lang);
$cameraDesc->setDescription($request->getPost()['camera_desc']['description']);
$this->getEntityManager()->persist($camera);
$cameraDesc->setCamera($camera);
$this->getEntityManager()->persist($cameraDesc);
$this->getEntityManager()->flush();
return $this->redirect()->toRoute('cameras');
}
}
return new ViewModel(array('form' => $form));
}
As you can see I've managed to overcome my problem - I've populate camera_desc with data which I get from post. This work but isn't the best solution - for example filters didn't work on cameraDesc descrition.

Related

How to get an email from a imbricated form into swiftmailer?

I want to insert an email from an imbricated form into swiftmailer.
The email is the "sendTo" section of the swifmailer.
As I tried it doesn't work. The form is sent but no email is recieved.
How can I have it? Do you have an idea?
So the controller, the action to send the form and then the email is :
/**
* Creates a new Reservations entity.
*
*/
public function createAction(Request $request)
{
$entity = new Reservations();
$emailPool = new Pool();
$form = $this->createCreateForm($entity);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush();
// Get the sender's email adress
$sender = $entity->getEmail();
// Get the recipients' emails adresses (pool address)
$emailPool = $this->$pool->getEmailPool(); // mal codé >> trouver la bonne méthode
// Send email
$message = \Swift_Message::newInstance()
->setSubject('Demande de véhicule')
->setFrom($sender)
->setTo($emailPool) // email à entrer Vehicule.Esplanade#eurelien.fr
// Indicate "High" priority
->setPriority(2)
->setBody(
$this->renderView(
// View in app/Resources/views/emails/demandereservation.html.twig
'emails/demandereservation.html.twig', array(
'reservations' => $entity)),
'text/html'
);
$this->get('mailer')->send($message);
$this->get('session')->getFlashBag()->Add('notice', 'Votre réservation a bien été envoyée');
return $this->redirect($this->generateUrl('reservations_show', array('id' => $entity->getId())));
}
return $this->render('CDCarsBundle:Reservations:new.html.twig', array(
'entity' => $entity,
'form' => $form->createView(),
));
}
The form (with the imbricated form (pool)) is :
<?php
namespace CD\CarsBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use CD\CarsBundle\Entity\Reservations;
use CD\CarsBundle\Entity\Vehicules;
use Application\Sonata\UserBundle\Entity\User;
class ReservationsType extends AbstractType
{
// Form for the entity "Reservations" which is used to build the car's booking form
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('nomAgent', null, array(
'label' => 'Nom de l\'agent',
//'attr' => array(
//'readonly' => true,
//'disabled' => true
//)
))
->add('prenomAgent', null, array(
'label' => 'Prénom de l\'agent',
//'attr' => array(
//'readonly' => true,
//'disabled' => true
//)
))
->add('dga', null, array(
'label' => 'D.G.A',
//'attr' => array(
//'readonly' => true,
//'disabled' => true
//)
))
->add('direction', null, array(
'label' => 'Direction',
//'attr' => array(
//'readonly' => true,
//'disabled' => true
//)
))
->add('email', null, array(
'label' => 'Email',
//'attr' => array(
//'readonly' => true,
//'disabled' => true
//)
))
->add('telephone', null, array(
'label' => 'Téléphone',
//'attr' => array(
//'readonly' => true,
//'disabled' => true
//)
))
// ajouter le pool
->add('pool', new PoolType())
->add('heureDebut', null, array(
'label' => 'Date et heure de début',
'format' => 'dd-MM-yyyy H:i',
'years' => range(\date("Y") - 0, \date("Y") + 2),
)
)
->add('heureFin', null, array(
'label' => 'Date et heure de fin',
'format' => 'dd-MM-yyyy H:i',
'years' => range(\date("Y") - 0, \date("Y") + 2),
)
)
// ajouter type véhicule
->add('besoin', 'choice', array(
'label' => 'Type',
'choices' => array(
'V.L' => 'V.L',
'V.L.E' => 'V.L.E',
'V.U' => 'V.U',
'velo' => 'Vélo')
)
)
// ajouter nombre personnes
->add('nombrePersonne', 'choice', array(
'label' => 'Nombre de personne',
'choices' => array(
'1' => '1',
'2' => '2',
'3' => '3',
'4' => '4',
'5' => '5 +')
)
)
// ajouter demande de remisage -> si coché dévoiler champs pour le remisage (dématérialisation) => à faire dans la vue
->add('remisage', null, array('required' => false))
->add('adresseRemisage', null, array('label' => 'Adresse'))
->add('dateDebutRemisage', null, array(
'label' => 'Du',
'format' => 'dd-MM-yyyy H:i',
'years' => range(\date("Y") - 0, \date("Y") + 2),
)
)
->add('dateFinRemisage', null, array(
'label' => 'au',
'format' => 'dd-MM-yyyy H:i',
'years' => range(\date("Y") - 0, \date("Y") + 2),
)
)
->add('emailDirecteur', null, array(
'label' => 'Email du directeur',
'attr' => array(
'placeholder' => 'email#email.fr',
))
)
->add('destination', null, array('label' => 'Destination'))
->add('motifRdv', null, array('required' => false))
->add('motifFormation', null, array('required' => false))
->add('motifReunion', null, array('required' => false))
->add('motifCollecte', null, array('required' => false))
->add('motifInstallation', null, array('required' => false))
->add('motifProgrammation', null, array('required' => false))
->add('motifDepannage', null, array('required' => false))
->add('motifVad', null, array('required' => false))
->add('motifAutre', null, array('label' => 'Autre motif'))
->add('conducteur', null, array('required' => false))
// ajouter mandataire -> si coché dévoiler champs pour le mandataire (email...) => à faire dans la vue
->add('mandataire', null, array('required' => false))
->add('nomMandataire', null, array('label' => 'Votre nom'))
->add('prenomMandataire', null, array('label' => 'Votre prénom'))
->add('emailMandataire', null, array('label' => 'Votre émail'))
->add('honneur', null, array('required' => true))
;
}
The Pool form is :
<?php
namespace CD\CarsBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use CD\CarsBundle\Entity\Pool;
use CD\CarsBundle\Entity\Vehicules;
class PoolType extends AbstractType
{
// Form for the entity "pool"
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
/*->add('nom', null, array(
'label' => 'Nom',
))*/
->add('emailPool', null, array(
'label' => 'Email du pool duquel vous dépendez',
))
;
}
/**
* #param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'CD\CarsBundle\Entity\Pool'
));
}
/**
* #return string
*/
public function getName()
{
return 'cd_carsbundle_pool';
}
}
The pool entity is :
<?php
namespace CD\CarsBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Pool
*/
class Pool
{
// Code for the entity "Pool"
public function __toString()
{
return (string) $this->getEmailPool();
}
//YML GENERATED CODE
/**
* #var integer
*/
private $id;
/**
* #var string
*/
private $nom;
/**
* #var string
*/
private $emailPool;
/**
* #var \Doctrine\Common\Collections\Collection
*/
private $vehicules;
/**
* #var \Doctrine\Common\Collections\Collection
*/
private $user;
/**
* #var \Doctrine\Common\Collections\Collection
*/
private $reservations;
/**
* Constructor
*/
public function __construct()
{
$this->vehicules = new \Doctrine\Common\Collections\ArrayCollection();
$this->user = new \Doctrine\Common\Collections\ArrayCollection();
$this->reservations = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set nom
*
* #param string $nom
* #return Pool
*/
public function setNom($nom)
{
$this->nom = $nom;
return $this;
}
/**
* Get nom
*
* #return string
*/
public function getNom()
{
return $this->nom;
}
/**
* Set emailPool
*
* #param string $emailPool
* #return Pool
*/
public function setEmailPool($emailPool)
{
$this->emailPool = $emailPool;
return $this;
}
/**
* Get emailPool
*
* #return string
*/
public function getEmailPool()
{
return $this->emailPool;
}
/**
* Add vehicules
*
* #param \CD\CarsBundle\Entity\Vehicules $vehicules
* #return Pool
*/
public function addVehicule(\CD\CarsBundle\Entity\Vehicules $vehicules)
{
$this->vehicules[] = $vehicules;
return $this;
}
/**
* Remove vehicules
*
* #param \CD\CarsBundle\Entity\Vehicules $vehicules
*/
public function removeVehicule(\CD\CarsBundle\Entity\Vehicules $vehicules)
{
$this->vehicules->removeElement($vehicules);
}
/**
* Get vehicules
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getVehicules()
{
return $this->vehicules;
}
/**
* Add user
*
* #param \Application\Sonata\UserBundle\Entity\User $user
* #return Pool
*/
public function addUser(\Application\Sonata\UserBundle\Entity\User $user)
{
$this->user[] = $user;
return $this;
}
/**
* Remove user
*
* #param \Application\Sonata\UserBundle\Entity\User $user
*/
public function removeUser(\Application\Sonata\UserBundle\Entity\User $user)
{
$this->user->removeElement($user);
}
/**
* Get user
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getUser()
{
return $this->user;
}
/**
* Add reservations
*
* #param \CD\CarsBundle\Entity\Reservations $reservations
* #return Pool
*/
public function addReservation(\CD\CarsBundle\Entity\Reservations $reservations)
{
$this->reservations[] = $reservations;
return $this;
}
/**
* Remove reservations
*
* #param \CD\CarsBundle\Entity\Reservations $reservations
*/
public function removeReservation(\CD\CarsBundle\Entity\Reservations $reservations)
{
$this->reservations->removeElement($reservations);
}
/**
* Get reservations
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getReservations()
{
return $this->reservations;
}
}
The reservations entity is :
<?php
namespace CD\CarsBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Mapping\ClassMetadata;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\Email;
use Symfony\Component\Validator\Constraints as Asserts;
/**
* Reservations
*/
class Reservations
{
// Code for the entity "Reservations"
public function __toString()
{
return (string) $this->getId();
return (string) $this->getHeureDebut();
}
// YML GENERATED CODE
/**
* #var integer
*/
private $id;
/**
* #var \DateTime
*/
private $heureDebut;
/**
* #var \DateTime
*/
private $heureFin;
/**
* #var string
*/
private $nomAgent;
/**
* #var string
*/
private $prenomAgent;
/**
* #var string
*/
private $dga;
/**
* #var string
*/
private $direction;
/**
* #var string
*/
private $email;
/**
* #var string
*/
private $telephone;
/**
* #var string
*/
private $destination;
/**
* #var boolean
*/
private $reserve;
/**
* #var boolean
*/
private $annulation;
/**
* #var boolean
*/
private $remisage;
/**
* #var string
*/
private $adresseRemisage;
/**
* #var \DateTime
*/
private $dateDebutRemisage;
/**
* #var \DateTime
*/
private $dateFinRemisage;
/**
* #var string
*/
private $emailDirecteur;
/**
* #var boolean
*/
private $conducteur;
/**
* #var boolean
*/
private $mandataire;
/**
* #var boolean
*/
private $motifRdv;
/**
* #var boolean
*/
private $motifFormation;
/**
* #var boolean
*/
private $motifReunion;
/**
* #var boolean
*/
private $motifCollecte;
/**
* #var boolean
*/
private $motifInstallation;
/**
* #var boolean
*/
private $motifProgrammation;
/**
* #var boolean
*/
private $motifDepannage;
/**
* #var boolean
*/
private $motifVad;
/**
* #var string
*/
private $motifAutre;
/**
* #var string
*/
private $commentaires;
/**
* #var integer
*/
private $nombrePersonne;
/**
* #var string
*/
private $besoin;
/**
* #var string
*/
private $nomMandataire;
/**
* #var string
*/
private $prenomMandataire;
/**
* #var string
*/
private $emailMandataire;
/**
* #var boolean
*/
private $honneur;
/**
* #var boolean
*/
private $traite;
/**
* #var \CD\CarsBundle\Entity\Vehicules
*/
private $vehicules;
/**
* #var \Application\Sonata\UserBundle\Entity\User
*/
private $user;
/**
* #var \CD\CarsBundle\Entity\Pool
*/
private $pool;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set heureDebut
*
* #param \DateTime $heureDebut
* #return Reservations
*/
public function setHeureDebut($heureDebut)
{
$this->heureDebut = $heureDebut;
return $this;
}
/**
* Get heureDebut
*
* #return \DateTime
*/
public function getHeureDebut()
{
return $this->heureDebut;
}
/**
* Set heureFin
*
* #param \DateTime $heureFin
* #return Reservations
*/
public function setHeureFin($heureFin)
{
$this->heureFin = $heureFin;
return $this;
}
/**
* Get heureFin
*
* #return \DateTime
*/
public function getHeureFin()
{
return $this->heureFin;
}
/**
* Set nomAgent
*
* #param string $nomAgent
* #return Reservations
*/
public function setNomAgent($nomAgent)
{
$this->nomAgent = $nomAgent;
return $this;
}
/**
* Get nomAgent
*
* #return string
*/
public function getNomAgent()
{
return $this->nomAgent;
}
/**
* Set prenomAgent
*
* #param string $prenomAgent
* #return Reservations
*/
public function setPrenomAgent($prenomAgent)
{
$this->prenomAgent = $prenomAgent;
return $this;
}
/**
* Get prenomAgent
*
* #return string
*/
public function getPrenomAgent()
{
return $this->prenomAgent;
}
/**
* Set dga
*
* #param string $dga
* #return Reservations
*/
public function setDga($dga)
{
$this->dga = $dga;
return $this;
}
/**
* Get dga
*
* #return string
*/
public function getDga()
{
return $this->dga;
}
/**
* Set direction
*
* #param string $direction
* #return Reservations
*/
public function setDirection($direction)
{
$this->direction = $direction;
return $this;
}
/**
* Get direction
*
* #return string
*/
public function getDirection()
{
return $this->direction;
}
/**
* Set email
*
* #param string $email
* #return Reservations
*/
public function setEmail($email)
{
$this->email = $email;
return $this;
}
/**
* Get email
*
* #return string
*/
public function getEmail()
{
return $this->email;
}
/**
* Set telephone
*
* #param string $telephone
* #return Reservations
*/
public function setTelephone($telephone)
{
$this->telephone = $telephone;
return $this;
}
/**
* Get telephone
*
* #return string
*/
public function getTelephone()
{
return $this->telephone;
}
/**
* Set destination
*
* #param string $destination
* #return Reservations
*/
public function setDestination($destination)
{
$this->destination = $destination;
return $this;
}
/**
* Get destination
*
* #return string
*/
public function getDestination()
{
return $this->destination;
}
/**
* Set reserve
*
* #param boolean $reserve
* #return Reservations
*/
public function setReserve($reserve)
{
$this->reserve = $reserve;
return $this;
}
/**
* Get reserve
*
* #return boolean
*/
public function getReserve()
{
return $this->reserve;
}
/**
* Set annulation
*
* #param boolean $annulation
* #return Reservations
*/
public function setAnnulation($annulation)
{
$this->annulation = $annulation;
return $this;
}
/**
* Get annulation
*
* #return boolean
*/
public function getAnnulation()
{
return $this->annulation;
}
/**
* Set remisage
*
* #param boolean $remisage
* #return Reservations
*/
public function setRemisage($remisage)
{
$this->remisage = $remisage;
return $this;
}
/**
* Get remisage
*
* #return boolean
*/
public function getRemisage()
{
return $this->remisage;
}
/**
* Set adresseRemisage
*
* #param string $adresseRemisage
* #return Reservations
*/
public function setAdresseRemisage($adresseRemisage)
{
$this->adresseRemisage = $adresseRemisage;
return $this;
}
/**
* Get adresseRemisage
*
* #return string
*/
public function getAdresseRemisage()
{
return $this->adresseRemisage;
}
/**
* Set dateDebutRemisage
*
* #param \DateTime $dateDebutRemisage
* #return Reservations
*/
public function setDateDebutRemisage($dateDebutRemisage)
{
$this->dateDebutRemisage = $dateDebutRemisage;
return $this;
}
/**
* Get dateDebutRemisage
*
* #return \DateTime
*/
public function getDateDebutRemisage()
{
return $this->dateDebutRemisage;
}
/**
* Set dateFinRemisage
*
* #param \DateTime $dateFinRemisage
* #return Reservations
*/
public function setDateFinRemisage($dateFinRemisage)
{
$this->dateFinRemisage = $dateFinRemisage;
return $this;
}
/**
* Get dateFinRemisage
*
* #return \DateTime
*/
public function getDateFinRemisage()
{
return $this->dateFinRemisage;
}
/**
* Set emailDirecteur
*
* #param string $emailDirecteur
* #return Reservations
*/
public function setEmailDirecteur($emailDirecteur)
{
$this->emailDirecteur = $emailDirecteur;
return $this;
}
/**
* Get emailDirecteur
*
* #return string
*/
public function getEmailDirecteur()
{
return $this->emailDirecteur;
}
/**
* Set vehicules
*
* #param \CD\CarsBundle\Entity\Vehicules $vehicules
* #return Reservations
*/
public function setVehicules(\CD\CarsBundle\Entity\Vehicules $vehicules = null)
{
$this->vehicules = $vehicules;
return $this;
}
/**
* Get vehicules
*
* #return \CD\CarsBundle\Entity\Vehicules
*/
public function getVehicules()
{
return $this->vehicules;
}
/**
* Set user
*
* #param \Application\Sonata\UserBundle\Entity\User $user
* #return Reservations
*/
public function setUser(\Application\Sonata\UserBundle\Entity\User $user = null)
{
$this->user = $user;
return $this;
}
/**
* Get user
*
* #return \Application\Sonata\UserBundle\Entity\User
*/
public function getUser()
{
return $this->user;
}
/**
* Set pool
*
* #param \CD\CarsBundle\Entity\Pool $pool
* #return Reservations
*/
public function setPool(\CD\CarsBundle\Entity\Pool $pool = null)
{
$this->pool = $pool;
return $this;
}
/**
* Get pool
*
* #return \CD\CarsBundle\Entity\Pool
*/
public function getPool()
{
return $this->pool;
}
}
Thank you. Have a nice day.
I have figured it out.
In the controller, at the swiftmailer section, the line to the get the recipient's email is :
// Get the recipients' emails adresses (pool address)
$recipients = $entity->getPool()->getEmailPool();
Like this it works.
Thank you to all the people who read this post and if you have an other answer, feel free to post it.
Have a nice day!

Symfony2 translation form with a2lix_translations and Gedmo doctrine-extensions

I work in Symfony 2.5
gedmo/doctrine-extensions": "dev-master
a2lix/translation-form-bundle": "2.*#dev
I'm trying on adding a translation on my entity Collection with the values name and description.
Here is my entity collection:
/**
* Collection
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="Angeli\AdminBundle\Entity\CollectionRepository")
* #Gedmo\TranslationEntity(class="Angeli\AdminBundle\Entity\CollectionTranslation")
*/
class Collection
{
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #Gedmo\Translatable
* #ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* #var string
*
* #Gedmo\Translatable
* #ORM\Column(name="description", type="text")
*/
private $description;
/**
* #ORM\OneToMany(targetEntity="CollectionTranslation", mappedBy="object", cascade={"persist", "remove"})
*/
protected $translations;
/**
* Required for Translatable behaviour
* #Gedmo\Locale
*/
protected $locale;
public function __construct()
{
$this->translations = new ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
* #return Collection
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set description
*
* #param string $description
* #return Collection
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* #return string
*/
public function getDescription()
{
return $this->description;
}
public function getTranslations()
{
return $this->translations;
}
public function addTranslation(CollectionTranslation $t)
{
$this->translations->add($t);
$t->setObject($this);
}
public function removeTranslation(CollectionTranslation $t)
{
$this->translations->removeElement($t);
}
public function setTranslations($translations)
{
$this->translations = $translations;
}
public function __toString()
{
return $this->getName();
}
}
Here is my CollectionTranslation Class:
/**
* #ORM\Entity
* #ORM\Table(name="collection_translations",
* uniqueConstraints={#ORM\UniqueConstraint(name="lookup_unique_idx", columns={
* "locale", "object_id", "field"
* })}
* )
*/
class CollectionTranslation extends AbstractPersonalTranslation
{
/**
* Convinient constructor
*
* #param string $locale
* #param string $field
* #param string $content
*/
public function __construct($locale = null, $field = null, $content = null)
{
$this->setLocale($locale);
$this->setField($field);
$this->setContent($content);
}
/**
* #ORM\ManyToOne(targetEntity="Collection", inversedBy="translations")
* #ORM\JoinColumn(name="object_id", referencedColumnName="id", onDelete="CASCADE")
*/
protected $object;
}
Now I'm trying on building a form:
class CollectionType extends AbstractType{
public function buildForm(FormBuilderInterface $builder, array $options)
{
//$builder->add('name','text', array('required' => true, 'label'=>'Name'));
//$builder->add('description','textarea', array('required' => true, 'label'=>'Description'));
$builder->add('translations', 'a2lix_translations');
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Angeli\AdminBundle\Entity\Collection',
));
}
public function getName()
{
return 'Collection';
}
}
But my form exist of 3 language tabs
and the input fields
Field
Content
If I add
field = name
content = some text
I only translated the value "name"
I want a form with my language tabs and "name" and "description" as input fields in the translation form.
Somebody sees what I'm doing wrong?
Try this: For ex. you are using 3 languages English, French and German.
Add in your form:
$builder->add('translations', 'a2lix_translations', array(
'locales' => array('en_US','fr_FR', 'de'),
'required_locales'=>array('en_US'),
'fields' => array(
'name' => array(
'field_type' => 'text',
'label' => 'Name',
'locale_options' => array(
'fr' => array(
'label' => 'nom'
),
'de' => array(
'label' => 'Name'
),
)),
'description' => array(
'field_type' => 'textarea',
'label' => 'Description',
'locale_options' => array(
'fr' => array(
'label' => 'description'
),
'de' => array(
'label' => 'Beschreibung'
),
)),
)));
And render in view like
form_label(form.translations)
form_widget(form.translations)
I had the same problem as yours.
Please try:
"gedmo/doctrine-extensions": "dev-master",
"a2lix/translation-form-bundle": "1.*#dev"
and
$builder->add('translations', 'a2lix_translations_gedmo', array(
'translatable_class' => 'Angeli\AdminBundle\Entity\Collection',
));
You also don't need __construct in CollectionTranslation.

Working with Doctrine 2 in Zend Framework 2 Form and fieldset using DoctrineHydrator

Client Entity
<?php
namespace Application\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Client
*
* #ORM\Table(name="client", uniqueConstraints={#ORM\UniqueConstraint(name="mail", columns=
* {"mail"}), #ORM\UniqueConstraint(name="pseudo", columns={"pseudo"})}, indexes=
* {#ORM\Index(name="FK_client_situation", columns={"situation"}),
*#ORM\Index(name="FK_client_city", columns={"ville"})})
* #ORM\Entity
*/
class Client
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="firstname", type="string", length=255, nullable=true)
*/
private $firstname;
/**
* #var string
*
* #ORM\Column(name="lastname", type="string", length=255, nullable=true)
*/
private $lastname;
/**
* #var \DateTime
*
* #ORM\Column(name="birthay", type="datetime", nullable=true)
*/
private $birthay;
/**
* #var string
*
* #ORM\Column(name="mail", type="string", length=255, nullable=true)
*/
private $mail;
/**
* #var string
*
* #ORM\Column(name="phone", type="text", nullable=true)
*/
private $phone;
/**
* #var string
*
* #ORM\Column(name="pseudo", type="string", length=255, nullable=true)
*/
private $pseudo;
/**
* #var string
*
* #ORM\Column(name="password", type="string", length=255, nullable=true)
*/
private $password;
/**
* #var integer
*
* #ORM\Column(name="situation", type="integer", nullable=true)
*/
private $situation;
/**
* #var integer
*
* #ORM\Column(name="ville", type="integer", nullable=true)
*/
private $ville;
/**
* #var string
*
* #ORM\Column(name="facebook", type="string", length=255, nullable=true)
*/
private $facebook;
/**
* #var string
*
* #ORM\Column(name="picture", type="string", length=255, nullable=true)
*/
private $picture;
/**
* #var integer
*
* #ORM\Column(name="newseltter", type="integer", nullable=true)
*/
private $newseltter;
/**
* #var \DateTime
*
* #ORM\Column(name="dateinscription", type="datetime", nullable=true)
*/
private $dateinscription;
/**
* #var \DateTime
*
* #ORM\Column(name="datedelete", type="datetime", nullable=true)
*/
private $datedelete;
/**
* #var string
*
* #ORM\Column(name="statut", type="string", length=50, nullable=true)
*/
private $statut;
/**
* #var string
*
* #ORM\Column(name="contenu", type="text", nullable=true)
*/
private $contenu;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set firstname
*
* #param string $firstname
* #return Client
*/
public function setFirstname($firstname)
{
$this->firstname = $firstname;
return $this;
}
/**
* Get firstname
*
* #return string
*/
public function getFirstname()
{
return $this->firstname;
}
/**
* Set lastname
*
* #param string $lastname
* #return Client
*/
public function setLastname($lastname)
{
$this->lastname = $lastname;
return $this;
}
/**
* Get lastname
*
* #return string
*/
public function getLastname()
{
return $this->lastname;
}
/**
* Set birthay
*
* #param \DateTime $birthay
* #return Client
*/
public function setBirthay($birthay)
{
$this->birthay = $birthay;
return $this;
}
/**
* Get birthay
*
* #return \DateTime
*/
public function getBirthay()
{
return $this->birthay;
}
/**
* Set mail
*
* #param string $mail
* #return Client
*/
public function setMail($mail)
{
$this->mail = $mail;
return $this;
}
/**
* Get mail
*
* #return string
*/
public function getMail()
{
return $this->mail;
}
/**
* Set phone
*
* #param string $phone
* #return Client
*/
public function setPhone($phone)
{
$this->phone = $phone;
return $this;
}
/**
* Get phone
*
* #return string
*/
public function getPhone()
{
return $this->phone;
}
/**
* Set pseudo
*
* #param string $pseudo
* #return Client
*/
public function setPseudo($pseudo)
{
$this->pseudo = $pseudo;
return $this;
}
/**
* Get pseudo
*
* #return string
*/
public function getPseudo()
{
return $this->pseudo;
}
/**
* Set password
*
* #param string $password
* #return Client
*/
public function setPassword($password)
{
$this->password = $password;
return $this;
}
/**
* Get password
*
* #return string
*/
public function getPassword()
{
return $this->password;
}
/**
* Set situation
*
* #param integer $situation
* #return Client
*/
public function setSituation($situation)
{
$this->situation = $situation;
return $this;
}
/**
* Get situation
*
* #return integer
*/
public function getSituation()
{
return $this->situation;
}
/**
* Set ville
*
* #param integer $ville
* #return Client
*/
public function setVille($ville)
{
$this->ville = $ville;
return $this;
}
/**
* Get ville
*
* #return integer
*/
public function getVille()
{
return $this->ville;
}
/**
* Set facebook
*
* #param string $facebook
* #return Client
*/
public function setFacebook($facebook)
{
$this->facebook = $facebook;
return $this;
}
/**
* Get facebook
*
* #return string
*/
public function getFacebook()
{
return $this->facebook;
}
/**
* Set picture
*
* #param string $picture
* #return Client
*/
public function setPicture($picture)
{
$this->picture = $picture;
return $this;
}
/**
* Get picture
*
* #return string
*/
public function getPicture()
{
return $this->picture;
}
/**
* Set newseltter
*
* #param integer $newseltter
* #return Client
*/
public function setNewseltter($newseltter)
{
$this->newseltter = $newseltter;
return $this;
}
/**
* Get newseltter
*
* #return integer
*/
public function getNewseltter()
{
return $this->newseltter;
}
/**
* Set dateinscription
*
* #param \DateTime $dateinscription
* #return Client
*/
public function setDateinscription($dateinscription)
{
$this->dateinscription = $dateinscription;
return $this;
}
/**
* Get dateinscription
*
* #return \DateTime
*/
public function getDateinscription()
{
return $this->dateinscription;
}
/**
* Set datedelete
*
* #param \DateTime $datedelete
* #return Client
*/
public function setDatedelete($datedelete)
{
$this->datedelete = $datedelete;
return $this;
}
/**
* Get datedelete
*
* #return \DateTime
*/
public function getDatedelete()
{
return $this->datedelete;
}
/**
* Set statut
*
* #param string $statut
* #return Client
*/
public function setStatut($statut)
{
$this->statut = $statut;
return $this;
}
/**
* Get statut
*
* #return string
*/
public function getStatut()
{
return $this->statut;
}
/**
* Set contenu
*
* #param string $contenu
* #return Client
*/
public function setContenu($contenu)
{
$this->contenu = $contenu;
return $this;
}
/**
* Get contenu
*
* #return string
*/
public function getContenu()
{
return $this->contenu;
}
}
?>
ClienFieldset
<?php
namespace Application\Form;
use Application\Entity\Client;
use Doctrine\Common\Persistence\ObjectManager;
use DoctrineModule\Stdlib\Hydrator\DoctrineObject as DoctrineHydrator;
use Zend\Form\Fieldset;
use Zend\InputFilter\InputFilterProviderInterface;
class ClientFieldset extends Fieldset implements InputFilterProviderInterface
{
public function __construct(ObjectManager $objectManager)
{
parent::__construct('post');
//$em = Registry::get('entityManager');
$this->setHydrator(new DoctrineHydrator($objectManager,'Application\Entity\Client'))
->setObject(new Client());
$this->setLabel('Post');
$this->add(array(
'name' => 'id',
'attributes' => array(
'type' => 'hidden'
)
));
$this->add(array(
'name' => 'mail',
'options' => array(
'label' => 'Title for this Post'
),
'attributes' => array(
'type' => 'text'
)
));
$this->add(array(
'name' => 'password',
'options' => array(
'label' => 'Text-Content for this post'
),
'attributes' => array(
'type' => 'text'
)
));
}
/**
* Define InputFilterSpecifications
*
* #access public
* #return array
*/
public function getInputFilterSpecification()
{
return array(
'mail' => array(
'required' => true,
'filters' => array(
array('name' => 'StringTrim'),
array('name' => 'StripTags')
),
'properties' => array(
'required' => true
)
),
'password' => array(
'required' => true,
'filters' => array(
array('name' => 'StringTrim'),
array('name' => 'StripTags')
),
'properties' => array(
'required' => true
)
)
);
}
}
?>
Client Form
<?php
namespace Application\Form;
use Doctrine\Common\Persistence\ObjectManager;
use DoctrineModule\Stdlib\Hydrator\DoctrineObject as DoctrineHydrator;
use Zend\Form\Form;
class ClientForm extends Form
{
public function __construct(ObjectManager $objectManager)
{
parent::__construct('post');
// The form will hydrate an object of type "BlogPost"
$this->setHydrator(new DoctrineHydrator($objectManager));
// Add the user fieldset, and set it as the base fieldset
$clientFieldset = new ClientFieldset($objectManager);
$clientFieldset->setUseAsBaseFieldset(true);
$this->add($clientFieldset);
$this->add(array(
'name' => 'security',
'type' => 'Zend\Form\Element\Csrf'
));
$this->add(array(
'name' => 'submit',
'attributes' => array(
'type' => 'submit',
'value' => 'Go',
'id' => 'submitbutton'
)
));
$this->setValidationGroup(array(
'security',
'post' => array(
'title',
'text'
)
));
}
}
?>
Index Action
<?php
public function indexAction()
{
$objectManager = $this->getServiceLocator()->get('Doctrine\ORM\EntityManager');
// Create the form and inject the ObjectManager
$form = new ClientForm($objectManager);
// Create a new, empty entity and bind it to the form
$Client = new Client();
$form->bind($Client);
if ($this->request->isPost()) {
$form->setData($this->request->getPost());
if ($form->isValid()) {
$objectManager->persist($Client);
$objectManager->flush();
}
}
return array('form' => $form);
}
?>
#index View
<table class="table">
<?php
if($this->form){
echo $this->form()->openTag($form);
echo $this->formRow($form->get('id'));
echo $this->formRow($form->get('mail'));
echo $this->form()->closeTag();
}
</table> ?>
When i execute My Code i get this Error..
Warning:
include(/var/www/Colocation/Colocation/module/Visitor/config/../view/error/index.phtml):
failed to open stream: No such file or directory in
/var/www/Colocation/Colocation/vendor/zendframework/zendframework/library/Zend/View/Renderer/PhpRenderer.php
on line 506
Warning: include(): Failed opening '/var/www/Colocation/Colocation/module/Visitor/config/../view/error/index.phtml'
for inclusion (include_path='.:/usr/share/php:/usr/share/pear') in
/var/www/Colocation/Colocation/vendor/zendframework/zendframework/library/Zend/View/Renderer/PhpRenderer.php
on line 506
Pleaz Help me!
The php warning says that it cannot find the file error/index.phtml.
It is looking for this file because somewhere in your code there is an error, which would lead to the error page.
Default error page files are located in the Application module (module/Application/view/error/), but in your case, it is trying to find these files in the 'Visitor' module.
Perhaps in the 'Visitor' module you overwritten the Application's module 'view_manager' configs, so you can try ONE of the follow:
Open the 'Visitor' module config file and comment or remove all error related configs, using this config for the 'view_manager' should be enough
'view_manager' => array(
'template_path_stack' => array(
'visitor' => __DIR__ . '/../view',
),
),
Create error page templates in your 'Visitor' module like the ones you can find in the Application module. Do this only if you want to customize your error page template, keeping unchanged the Application error template, otherwise use the first solution.
After you finish you should be able to see another error but this time related to your code!

Symfony 2 Exception: Call to a member function on a non object when using Form Events

I'm trying to create a form which dinamically load all "sites" related to a "project", It seems like this would be of use, so I tried it:
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
class EngineeringType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('project','entity',array(
'class' => 'tBundle:Project',
'label' => 'Project'
;
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function(FormEvent $event) {
$form = $event->getForm();
$data = $event->getData();
$sites = $data->getProject()->getSites();
$form->add('site', 'entity', array('choices' => $sites));
}
);
}
My problem comes when I try to access the form, I get:
FatalErrorException: Error: Call to a member function getSites() on a non-object in ... tBundle\Form\EngineeringType.php line 41
Here are my entities:
namespace tBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Engineering
*
* #ORM\Table(name="engineerings")
* #ORM\Entity
*/
class Engineering
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="tBundle\Entity\Project")
* #ORM\JoinColumn(name="project_id", referencedColumnName="id",nullable=false)
*/
private $project;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set project
*
* #param string $project
* #return Engineering
*/
public function setProject(\tBundle\Entity\Project $project)
{
$this->project = $project;
return $this;
}
/**
* Get project
*
* #return string
*/
public function getProject()
{
return $this->project;
}
Project:
namespace tBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* Project
*
* #ORM\Table(name="projects")
* #ORM\Entity
*/
class Project
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* #ORM\ManyToMany(targetEntity="tBundle\Entity\Site")
* #ORM\JoinTable(name="project_sites",
* joinColumns={#ORM\JoinColumn(name="site_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="project_id", referencedColumnName="id")}
* )
*/
private $sites;
public function __construct()
{
$this->sites = new ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
* #return Project
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Get Sites
*
* #return array
*/
public function getSites()
{
return $this->sites;
}
/* Returns Project's Name */
public function __toString()
{
return $this->name;
}
What am I doing wrong?
EDIT
Controller:
/**
* Creates a form to create a Engineering entity.
*
* #param Engineering $entity The entity
*
* #return \Symfony\Component\Form\Form The form
*/
private function createCreateForm(Engineering $entity)
{
$form = $this->createForm(new EngineeringType(), $entity, array(
'action' => $this->generateUrl('engineering_create'),
'method' => 'POST',
));
$form->add('submit', 'submit', array('label' => 'Create'));
return $form;
}
/**
* Creates a form to edit a Engineering entity.
*
* #param Engineering $entity The entity
*
* #return \Symfony\Component\Form\Form The form
*/
private function createEditForm(Engineering $entity)
{
$form = $this->createForm(new EngineeringType(), $entity, array(
'action' => $this->generateUrl('engineering_update', array('id' => $entity->getId())),
'method' => 'POST',
));
$form->add('submit', 'submit', array('label' => 'Update'));
return $form;
}
The PRE_SET_DATA event is actually fired twice. The first time will not have any data. There used to be a blurb in the manual explaining why but I could not find it again.
So just:
function(FormEvent $event) {
$form = $event->getForm();
$data = $event->getData();
if ($data)
{
$sites = $data->getProject()->getSites();
$form->add('site', 'entity', array('choices' => $sites));
}
}
=======================================================
Updated answer to show how to handle non-existent $project:
if ($data)
{
$project = $data->getProject();
$sites = $project ? $project->getSites() : array();
$form->add('site', 'entity', array('choices' => $sites));
}
There is an easy solution, why don't you use the "property" property on the form builder?
$builder
->add('project','entity',array(
'class' => 'tBundle:Project',
'label' => 'Project',
'property' => 'sites');
Or even you can use a query builder if this is not enough:
$builder->add('users', 'entity', array(
'class' => 'AcmeHelloBundle:User',
'query_builder' => function(EntityRepository $er) {
return $er->createQueryBuilder('u')
->orderBy('u.username', 'ASC');
},
));
You can find here more description, if this is not enough:
Symfony documentation
EDIT:
So your problem that with the first solution, that it's going to be an array, so use my second option, and in the query builder, specify what will reflect your needs.
Or use it like the class is not Project but Sites.

symfony2 validation of child entity prevents editing of parent entity

I have run into this problem with a couple of my entities now so I thought to try and get a hang of what really goes on, and I turn to my best source here (will add a bounty to this question as soon as it is eligible).
My user is part of a user group. I have a validator for the userGroup entity to make sure no two userGroups have the same name.
The problem is that when I go to editing a user, and try to select that userGroup for the user, symfony2 is behaving as if I were trying to create another userGroup with that same name, when in reality all I am doing is I am trying to select that userGroup for the user.
A user entity
<?php
// src/BizTV/UserBundle/Entity/User.php
namespace BizTV\UserBundle\Entity;
use BizTV\UserBundle\Validator\Constraints as BizTVAssert;
use Symfony\Component\Security\Core\User\AdvancedUserInterface;
use FOS\UserBundle\Entity\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
use BizTV\BackendBundle\Entity\company as company;
/**
* #ORM\Entity
* #ORM\Table(name="fos_user")
*/
class User extends BaseUser implements AdvancedUserInterface
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
//TODO: Add constraint on $name * #BizTVAssert\NameExists (and finish coding this constraint)
/**
* #var object BizTV\BackendBundle\Entity\company
*
* #ORM\ManyToOne(targetEntity="BizTV\BackendBundle\Entity\company")
* #ORM\JoinColumn(name="company", referencedColumnName="id", nullable=false)
*/
protected $company;
/**
* #var object BizTV\UserBundle\Entity\UserGroup
* #ORM\ManyToOne(targetEntity="BizTV\UserBundle\Entity\UserGroup")
* #ORM\JoinColumn(name="userGroup", referencedColumnName="id", nullable=true)
*/
protected $userGroup;
/**
* #ORM\ManyToMany(targetEntity="BizTV\ContainerManagementBundle\Entity\Container", inversedBy="users")
* #ORM\JoinTable(name="access")
*/
private $access;
/**
* #var object BizTV\ContainerManagementBundle\Entity\Container
*
* This only applies to the BizTV server user accounts or "screen display accounts". Others will have null here.
*
* #ORM\ManyToOne(targetEntity="BizTV\ContainerManagementBundle\Entity\Container")
* #ORM\JoinColumn(name="screen", referencedColumnName="id", nullable=true)
*/
protected $screen;
/**
* #ORM\Column(type="boolean", nullable=true)
*/
protected $isServer;
public function __construct()
{
parent::__construct();
$this->access = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set company
*
* #param BizTV\BackendBundle\Entity\company $company
*/
public function setCompany(\BizTV\BackendBundle\Entity\company $company)
{
$this->company = $company;
}
/**
* Get company
*
* #return BizTV\BackendBundle\Entity\company
*/
public function getCompany()
{
return $this->company;
}
/**
* Add access
*
* #param BizTV\ContainerManagementBundle\Entity\Container $access
*/
public function addContainer(\BizTV\ContainerManagementBundle\Entity\Container $access)
{
$this->access[] = $access;
}
/**
* Get access
*
* #return Doctrine\Common\Collections\Collection
*/
public function getAccess()
{
return $this->access;
}
/**
* Set screen
*
* #param BizTV\ContainerManagementBundle\Entity\Container $screen
*/
public function setScreen(\BizTV\ContainerManagementBundle\Entity\Container $screen)
{
$this->screen = $screen;
}
/**
* Get screen
*
* #return BizTV\ContainerManagementBundle\Entity\Container
*/
public function getScreen()
{
return $this->screen;
}
/**
* Set isServer
*
* #param boolean $isServer
*/
public function setIsServer($isServer)
{
$this->isServer = $isServer;
}
/**
* Get isServer
*
* #return boolean
*/
public function getIsServer()
{
return $this->isServer;
}
/**
* Set userGroup
*
* #param BizTV\UserBundle\Entity\UserGroup $userGroup
*/
public function setUserGroup(\BizTV\UserBundle\Entity\UserGroup $userGroup = null)
{
$this->userGroup = $userGroup;
}
/**
* Get userGroup
*
* #return BizTV\UserBundle\Entity\UserGroup
*/
public function getUserGroup()
{
return $this->userGroup;
}
}
The UserGroup entity that the User is linked to:
<?php
namespace BizTV\UserBundle\Entity;
use BizTV\UserBundle\Validator\Constraints as BizTVAssert;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* BizTV\UserBundle\Entity\UserGroup
*
* #ORM\Table()
* #ORM\Entity
*/
class UserGroup
{
/**
* #var integer $id
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string $name
* #BizTVAssert\NameExists
* #ORM\Column(name="name", type="string", length=255)
* #Assert\NotBlank(message = "Du måste ange ett gruppnamn")
*/
private $name;
/**
* #var object BizTV\BackendBundle\Entity\company
*
* #ORM\ManyToOne(targetEntity="BizTV\BackendBundle\Entity\company")
* #ORM\JoinColumn(name="company", referencedColumnName="id", nullable=false)
*/
protected $company;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
*/
public function setName($name)
{
$this->name = $name;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set company
*
* #param BizTV\BackendBundle\Entity\company $company
*/
public function setCompany(\BizTV\BackendBundle\Entity\company $company)
{
$this->company = $company;
}
/**
* Get company
*
* #return BizTV\BackendBundle\Entity\company
*/
public function getCompany()
{
return $this->company;
}
}
The NameExistsValidator
<?php
namespace BizTV\UserBundle\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\DependencyInjection\ContainerInterface as Container;
use Doctrine\ORM\EntityManager as EntityManager;
class NameExistsValidator extends ConstraintValidator
{
private $container;
private $em;
public function __construct(Container $container, EntityManager $em) {
$this->container = $container;
$this->em = $em;
}
public function isValid($value, Constraint $constraint)
{
$em = $this->em;
$container = $this->container;
$company = $this->container->get('security.context')->getToken()->getUser()->getCompany();
//Fetch entities with same name
$repository = $em->getRepository('BizTVUserBundle:UserGroup');
//$repository = $this->getDoctrine()->getRepository('BizTVContainerManagementBundle:Container');
$query = $repository->createQueryBuilder('c')
->where('c.company = :company')
->setParameter('company', $company)
->orderBy('c.name', 'ASC')
->getQuery();
$groups = $query->getResult();
foreach ($groups as $g) {
if ($g->getName() == $value) {
$this->setMessage('Namnet '.$value.' är upptaget, vänligen välj ett annat', array('%string%' => $value));
return false;
}
}
return true;
}
}
User edit form
<?php
namespace BizTV\UserBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\CallbackValidator;
use Symfony\Component\Form\FormValidatorInterface;
use Symfony\Component\Form\FormError;
use Doctrine\ORM\EntityRepository;
class editUserType extends AbstractType
{
function __construct($company)
{
$this->company = $company;
}
public function buildForm(FormBuilder $builder, array $options)
{
$company = $this->company;
$builder
->add('locked', 'checkbox', array('label' => 'Kontot är låst, användaren kan inte logga in '))
->add('username', 'text', array('label' => 'Användarnamn '))
;
$builder
->add('userGroup', 'entity', array(
'label' => 'Användargrupp',
'empty_value' => 'Ingen grupptillhörighet',
'property' => 'name',
'class' => 'BizTV\UserBundle\Entity\UserGroup',
'query_builder' => function(\Doctrine\ORM\EntityRepository $er) use ($company) {
$qb = $er->createQueryBuilder('a');
$qb->where('a.company = :company');
$qb->setParameters( array('company' => $company) );
$qb->orderBy('a.name', 'ASC');
return $qb;
}
));
$builder
->add('email', 'email', array('label' => 'Epost '))
->add('plainPassword', 'repeated', array('type' => 'password', 'first_name' => 'Nytt lösenord ', 'second_name' => 'Upprepa lösenord ',));
$builder
->add('roles', 'choice', array(
'label' => 'Roller',
'expanded' => true,
'multiple' => true,
'choices' => array(
'ROLE_CONTENT' => 'Innehåll (Användaren kan lägga till, redigera och ta bort innehåll där du nedan beviljar åtkomst)',
'ROLE_LAYOUT' => 'Skärmlayout (Användaren kan skapa ny skärmlayout, redigera befintlig eller ta bort gällande skärmlayout där du nedan beviljar åtkomst)',
'ROLE_VIDEO' => 'Videouppladdning (Användaren har rätt att ladda upp videofiler till företagets mediabibliotek)',
'ROLE_ADMIN' => 'Administratör (Användaren är administratör med fulla rättigheter till allt precis som det konto du nu är inloggad på, var mycket restriktiv med att tilldela denna behörighet).',
),
))
;
$builder
->add('access', 'entity', array(
'label' => 'Behörigheter',
'multiple' => true, // Multiple selection allowed
'expanded' => true, // Render as checkboxes
'property' => 'select_label',
'class' => 'BizTV\ContainerManagementBundle\Entity\Container',
'query_builder' => function(\Doctrine\ORM\EntityRepository $er) use ($company) {
$qb = $er->createQueryBuilder('a');
$qb->innerJoin('a.containerType', 'ct');
$qb->where('a.containerType IN (:containers)', 'a.company = :company');
$qb->setParameters( array('containers' => array(1,2,3,4), 'company' => $company) );
$qb->orderBy('ct.id', 'ASC');
return $qb;
}
));
$builder-> addValidator(new CallbackValidator(function(FormInterface $form){
$email = $form->get('email')->getData();
if (empty( $email )) {
$form['email']->addError(new FormError("Du måste ange en epostadress för användaren"));
}
}));
$builder-> addValidator(new CallbackValidator(function(FormInterface $form){
$username = $form->get('username')->getData();
if (strpos($username,'#') !== false) {
$form['username']->addError(new FormError("Användarnamnet får inte innehålla tecknet #"));
}
}));
$builder-> addValidator(new CallbackValidator(function(FormInterface $form){
$username = $form->get('username')->getData();
if (empty($username)) {
$form['username']->addError(new FormError("Du måste ange ett namn för användaren"));
}
}));
//TODO check if username exists
}
public function getName()
{
return 'biztv_userbundle_newusertype';
}
}
Your NameExistsValidator does this:
Fail if I find any user-group with the name I'm checking.
But I think you want it to do this:
Fail if I find another user-group with the name I'm checking.
In other words: the validator needs the complete UserGroup entity (or at least its id and name) to check for a user-group with the same name but different id.
Symfony 2 already has a UniqueEntity validator, why don't you use it?
Using annotations this would look something like this:
/**
* #ORM\Entity
* #AssertUniqueEntity(fields={"name"}, message="This name already exists")
*/
class UserGroup
{
One possible and simplest solution is to define Validation Groups. For example, when you create a group, you can use the validation group named 'create' or 'groups' and when you create a user does not specify a group. Then validator will not apply to user creation process.
Validation Groups can be assigned dynamically in the form class. An example of this you can see in the documentation.