Symfony2 translation form with a2lix_translations and Gedmo doctrine-extensions - forms

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.

Related

Editing entity - choicetype are reset

I am creating my first app on symfony, and am currently working on a form in order to edit an pretty big entity. My issue is : i have some choiceType in order to choose from definied values... BUT when i enter in the form, the default value of these choiceType is set to the first one in the list, not the value of the entity...
Same goes for an EntityType...
There is my buildform :
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('classePSI', NumberType::class, array(
'attr' => array(
'min' => 0,
'max' => 5
)
))
->add('codeSA', TextType::class)
->add('nom', TextType::class)
->add('host', TextType::class)
->add('cluster', TextType::class)
->add('besoin', ChoiceType::class, array(
'choices' => array(
'0 - Non concerné' => 0,
'1 - A remonter' => 1,
'2 - Composant commun' => 2
)
))
->add('estVirtuel', ChoiceType::class, array(
'choices' => array(
'Reel' => false,
'Virtuel' => true
)
))
->add('instancePartage', TextType::class, array('required' => false))
->add('perimetre', EntityType::class, array(
'class' => 'GGMOPSIBundle:Perimetre',
'choice_label' => 'libellePerimetre',
'multiple' => false,
'expanded' => false,
'query_builder' => function (PerimetreRepository $repository) {
return $repository->getVisibleQB();
}
))
->add('type', EntityType::class, array(
'class' => 'GGMOPSIBundle:SousType',
'choice_label' => 'nom',
'multiple' => false,
'expanded' => false
))->add('save', SubmitType::class, array("label" => "Editer composant"));;
}
My entity :
namespace G\GMOPSIBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Composant
*
* #ORM\Table(name="gmo_psi_composant")
* #ORM\Entity(repositoryClass="G\GMOPSIBundle\Repository\ComposantRepository")
*/
class Composant
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var int
*
* #ORM\Column(name="classePSI", type="integer")
*/
private $classePSI;
/**
* #var string
*
* #ORM\Column(name="codeSA", type="string", length=20)
*/
private $codeSA;
/**
* #var string
*
* #ORM\Column(name="nom", type="string", length=255)
*/
private $nom;
/**
* #var string
*
* #ORM\Column(name="host", type="string", length=255)
*/
private $host;
/**
* #var string
*
* #ORM\Column(name="cluster", type="string", length=255)
*/
private $cluster;
/**
* #var int
*
* #ORM\Column(name="besoin", type="integer",nullable=true)
*/
private $besoin=null;
/**
* #var bool
*
* #ORM\Column(name="estVirtuel", type="boolean")
*/
private $estVirtuel;
/**
* #var string
*
* #ORM\Column(name="InstancePartage", type="string", length=255,nullable=true)
*/
private $instancePartage;
/**
* #ORM\ManyToOne(targetEntity="G\GMOPSIBundle\Entity\Perimetre")
* #ORM\JoinColumn(nullable=true)
*/
private $perimetre;
/**
* #ORM\ManyToOne(targetEntity="G\GMOPSIBundle\Entity\SousType")
* #ORM\JoinColumn(nullable=true)
*/
private $type;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set classePSI
*
* #param integer $classePSI
*
* #return Composant
*/
public function setClassePSI($classePSI)
{
$this->classePSI = $classePSI;
return $this;
}
/**
* Get classePSI
*
* #return integer
*/
public function getClassePSI()
{
return $this->classePSI;
}
/**
* Set codeSA
*
* #param string $codeSA
*
* #return Composant
*/
public function setCodeSA($codeSA)
{
$this->codeSA = $codeSA;
return $this;
}
/**
* Get codeSA
*
* #return string
*/
public function getCodeSA()
{
return $this->codeSA;
}
/**
* Set nom
*
* #param string $nom
*
* #return Composant
*/
public function setNom($nom)
{
$this->nom = $nom;
return $this;
}
/**
* Get nom
*
* #return string
*/
public function getNom()
{
return $this->nom;
}
/**
* Set host
*
* #param string $host
*
* #return Composant
*/
public function setHost($host)
{
$this->host = $host;
return $this;
}
/**
* Get host
*
* #return string
*/
public function getHost()
{
return $this->host;
}
/**
* Set cluster
*
* #param string $cluster
*
* #return Composant
*/
public function setCluster($cluster)
{
$this->cluster = $cluster;
return $this;
}
/**
* Get cluster
*
* #return string
*/
public function getCluster()
{
return $this->cluster;
}
/**
* Set besoin
*
* #param integer $besoin
*
* #return Composant
*/
public function setBesoin($besoin)
{
$this->besoin = $besoin;
return $this;
}
/**
* Get besoin
*
* #return integer
*/
public function getBesoin()
{
return $this->besoin;
}
/**
* Set estVirtuel
*
* #param boolean $estVirtuel
*
* #return Composant
*/
public function setEstVirtuel($estVirtuel)
{
$this->estVirtuel = $estVirtuel;
return $this;
}
/**
* Get estVirtuel
*
* #return boolean
*/
public function getEstVirtuel()
{
return $this->estVirtuel;
}
/**
* Set instancePartage
*
* #param string $instancePartage
*
* #return Composant
*/
public function setInstancePartage($instancePartage)
{
$this->instancePartage = $instancePartage;
return $this;
}
/**
* Get instancePartage
*
* #return string
*/
public function getInstancePartage()
{
return $this->instancePartage;
}
/**
* #return mixed
*/
public function getPerimetre()
{
return $this->perimetre;
}
/**
* #param mixed $perimetre
*/
public function setPerimetre($perimetre)
{
$this->perimetre = $perimetre;
}
/**
* #return Type
*/
public function getType()
{
return $this->type;
}
/**
* #param mixed $type
*/
public function setType($type)
{
$this->type = $type;
}
}
My editAction :
public function editAction($id, Request $request)
{
$em = $this->getDoctrine()->getManager();
$composant = $em->getRepository('GGMOPSIBundle:Composant')->find($id);
if (null === $composant) {
throw new NotFoundHttpException("Le composant d'id ".$id." n'existe pas.");
}
$form = $this->createForm(ComposantType::class, $composant);
$handle =$form->handleRequest($request);
if ($request->isMethod('POST') && $handle->isSubmitted() && $handle->isValid()) {
$em->flush();
$request->getSession()->getFlashBag()->add('notice', 'Composant bien modifié.');
return $this->redirectToRoute('g_gmopsi_viewcomposants');
}
return $this->render('GGMOPSIBundle:Composant:edit.html.twig', array(
'comp' => $composant,
'form' => $form->createView(),
));
}
Every textype is correctly pre-entered with values from entity so i don't know what to do...
Thanks in advance
If you are using Symfony < 3.0, try to add 'choices_as_values' => true
like this
->add('besoin', ChoiceType::class, array(
'choices' => array(
'0 - Non concerné' => 0,
'1 - A remonter' => 1,
'2 - Composant commun' => 2
),
'choices_as_values' => true
))
Ok i am just plain dumb. I had things like that in my twig :
{{ form_label(form.perimetre, "Perimetre : ") }}
{{ form_widget(form.perimetre,{'value' : comp.perimetre}) }}
Removing value atttribute fixes the issue.
{{ form_label(form.perimetre, "Perimetre : ") }}
{{ form_widget(form.perimetre) }}
Thanks loic anyway

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!

Error when embedding form in Symfony whith collection

I have 2 "simple" entities, and i want to do the classical form embedding
but i have this error : "Neither the property "itemcode" nor one of the methods "getItemcode()", "itemcode()", "isItemcode()", "hasItemcode()", "__get()" exist and have public access in class "NWA\ItemSelectorBundle\Entity\ItemSelector"."
I've seen many posts with this error, but none provided the solution
In the entities i have getItemCode() but why would it be public ?
What is wrong with my construction?
Thank you in advance
Here are my entities (parts relevant to the properties at fault)
class ItemSelector
{
/**
* #var Items[]
*
* #ORM\OneToMany(targetEntity="NWA\ItemSelectorBundle\Entity\Item", mappedBy="itemselector", cascade={"all"})
*/
protected $items;
/**
* Class constructor
*/
public function __construct()
{
$this->items = new ArrayCollection();
}
/**
* Add item
*
* #param \NWA\ItemSelectorBundle\Entity\Item $item
*
* #return ItemSelector
*/
public function addItem(\NWA\ItemSelectorBundle\Entity\Item $item)
{
$this->items[] = $item;
//$item->setItemselector($this);
return $this;
}
/**
* Remove item
*
* #param \NWA\ItemSelectorBundle\Entity\Item $item
*/
public function removeItem(\NWA\ItemSelectorBundle\Entity\Item $item)
{
$this->items->removeElement($item);
}
/**
* Get items
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getItems()
{
return $this->items;
}
}
and
class Item
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="itemcode", type="string", length=255)
*/
protected $itemcode;
/**
* #var ItemSelector
*
* #ORM\ManyToOne(targetEntity="NWA\ItemSelectorBundle\Entity\ItemSelector", inversedBy="items")
* #ORM\JoinColumn(name="itemselector_id", referencedColumnName="id")
*/
protected $itemselector;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set itemcode
*
* #param string $itemcode
*
* #return Item
*/
public function setItemcode($itemcode)
{
$this->itemcode = $itemcode;
return $this;
}
/**
* Get itemcode
*
* #return string
*/
public function getItemcode()
{
return $this->itemcode;
}
/**
* Set itemselector
*
* #param \NWA\ItemSelectorBundle\Entity\ItemSelector $itemselector
*
* #return Item
*/
public function setItemselector(\NWA\ItemSelectorBundle\Entity\ItemSelector $itemselector = null)
{
$this->itemselector = $itemselector;
return $this;
}
/**
* Get itemselector
*
* #return \NWA\ItemSelectorBundle\Entity\ItemSelector
*/
public function getItemselector()
{
return $this->itemselector;
}
}
Then the Form constructors
class ItemSelectorType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add(
'itemcode', 'collection', array(
'type' => new ItemType(),
'prototype' => true,
'allow_add' => true,
'allow_delete' => true
)
);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'NWA\ItemSelectorBundle\Entity\ItemSelector',
'translation_domain' => 'resource'
));
}
/**
* #return string
*/
public function getName()
{
return 'nwa_itemselector';
}
}
and
class ItemType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add(
'itemcode', 'text', array(
'label' => 'Code'
)
);
;
}
/**
* #param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'NWA\ItemSelectorBundle\Entity\Item'
));
}
/**
* #return string
*/
public function getName()
{
return 'nwa_itemselectorbundle_item';
}
}
And finally the call in the Controller
public function chooseAction(Request $request, ItemSelector $itemSelector)
{
$form = $this->get('form.factory')
->create(new ItemSelectorType(), $itemSelector);
$form->handleRequest($request);
if ($form->isValid()) {
}
return array(
'_resource' => $itemSelector,
'form' => $form->createView(),
);
}
Maybe you need to rename your field name itemcode to items in ItemSelectorType.
->add(
'items', 'collection', array(
'type' => new ItemType(),
'prototype' => true,
'allow_add' => true,
'allow_delete' => true
)
);

ZF2 and Doctrine2: One form -> Two entities

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.

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.