Symfony: Creating a new user results in overwriting of properties - symfony

When someone creates a new user on our application, some of his own properties get overwritten by the new users properties. I have no clue yet, where to look for the mistake, since in the controller or entities, nothing was changed.
Here are some information: the user entity (we are using the FOS User Bundle)
class User extends BaseUser{
/**
* #Solr\Id
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #Solr\Field(type="string")
* #Assert\NotBlank()
* #var string
* #ORM\Column(type="string", length=32, nullable=false)
*/
protected $firstName;
/**
* #Solr\Field(type="string")
* #Assert\NotBlank()
* #var string
* #ORM\Column(type="string", length=32, nullable=false)
*/
protected $lastName;
/**
* #ORM\ManyToMany(targetEntity="AppBundle\Entity\Agency", inversedBy="useragencies", cascade={"persist"})
* #ORM\JoinTable(name="user_user_agencies",
* joinColumns={#ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="iata8", referencedColumnName="iata8")})
* #var \AppBundle\Entity\Agency
**/
private $agencies;
/**
* #ORM\ManyToMany(targetEntity="AppBundle\Entity\Product", inversedBy="users", cascade={"persist"})
* #ORM\JoinTable(name="user_user_products",
* joinColumns={#ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="product_id", referencedColumnName="id")})
* #var \AppBundle\Entity\Product
**/
private $products;
/**
* #ORM\ManyToMany(targetEntity="AppBundle\Entity\Market", inversedBy="users", cascade={"persist"})
* #ORM\JoinTable(name="user_user_markets",
* joinColumns={#ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="market_id", referencedColumnName="id")})
* #var \AppBundle\Entity\Market
* #Solr\Field(type="string", getter="getId")
**/
private $markets;
/**
* #ORM\ManyToMany(targetEntity="AppBundle\Entity\Airline", inversedBy="users", cascade={"persist"})
* #ORM\JoinTable(name="user_user_airlines",
* joinColumns={#ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="airline_id", referencedColumnName="id")})
* #var \AppBundle\Entity\Airline
* #Solr\Field(type="string", getter="getId")
**/
private $airlines;
...
The properties that get overwritten are products and airlines. There is no prePersist() or preUpdate() function for this entity!
The create controller
class CreateController extends Controller
{
/**
* #Security("has_role('ROLE_USER_INVITER')")
* #Route("/user/create/{employer}", defaults={"employer": 1}
* , requirements={"employer": "\d+"}, name="userBundle_create")
*/
public function createAction($employer, Request $request)
{
$currentUser=$this->container->get('security.token_storage')->getToken()->getUser();
// get employer Object
$em = $this->getDoctrine ()->getManager ();
$repository = $this->getDoctrine()
->getRepository('UserBundle:Employer');
$employerObj = $repository->findOneByIdInContext($employer, $currentUser);
$userManager = $this->get('fos_user.user_manager');
$user = $userManager->createUser();
$url = $this->get('router')->generate('userBundle_create', array(
'employer' => $employerObj->getId()
));
// generate form and handle
$form = $this->createForm(CreateType::class, $user
, array('employer' => $employerObj,
'action' => $url,)
);
$form->handleRequest($request);
if ($form->isValid()) {
$tokenGenerator = $this->container->get('fos_user.util.token_generator');
$user->setConfirmationToken($tokenGenerator->generateToken());
$user->setUsername($user->getEmail());
$user->setEnabled(false);
$user->setApprover($currentUser);
$user->setInviter($currentUser);
$user->addRole($user->getMainRole()->getName());
$userManager->updateUser($user);
if(count($user->getAgencies()) > 0){
$userId = rtrim($user->getId(),"_user");
$query = $em->createQuery("SELECT DISTINCT (a.market) FROM UserBundle\Entity\User u JOIN u.agencies a WHERE u.id = $userId");
$marketIds = $query->getResult();
$em = $this->getDoctrine ()->getManager ();
$repository = $this->getDoctrine()
->getRepository('AppBundle:Market');
$markets = $repository->findOneById($marketIds[0]);
$user->addMarket($markets);
$userManager->updateUser($user);
}
$this->addFlash(
'success',
'The user was created and an activation email was sent!'
);
return $this->redirectToRoute('userBundle_list');
}
return $this->render('UserBundle:User:create.html.twig', array(
'form' => $form->createView(),
'user'=>$user,
));
}
}
Here are more classes that may be useful for helping to point me in the right direction.
CreateType
class CreateType extends AbstractType
{
private $tokenStorage;
public function __construct(TokenStorageInterface $tokenStorage)
{
$this->tokenStorage = $tokenStorage;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => User::class,
'employer' => null
));
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$employer = $options['employer'];
$builder
->add('firstName', 'text', array('label' => 'label.firstname',
'translation_domain' => 'User',))
->add('lastName', 'text', array('label' => 'label.lastname',
'translation_domain' => 'User',))
;
$user = $this->tokenStorage->getToken()->getUser();
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($user, $employer){
$form = $event->getForm();
// show iata selection if empoyer is any agency
$employerArr = array(10, 11);
if (in_array($employer->getId(), $employerArr)) {
// only show iata based on user's employer
if($user->hasRoles(array('ROLE_AGENCY_TC_ONLY',
'ROLE_AGENCY_WAIVER_REQUEST_ONLY',
'ROLE_AGENCY_CORE_TEAM',
'ROLE_AGENCY',
'ROLE_AGENCY_MANAGEMENT',
'ROLE_AGENCY_SIGNEE','ROLE_CORPORATION_TRAVEL_MANAGER' ))){
$form
->add('agencies', EntityType::class, array(
'class' => 'AppBundle:Agency',
'query_builder' => function (EntityRepository $er) use ($user) {
return $er->createQueryBuilder('a')
->addOrderBy('a.id', 'ASC')
->andWhere('a.id IN (:ids)')
->setParameter('ids',$user->getAgencies());
},
'choice_label' => 'agencyName',
// 'data' => $user->getAgencies(),
'label' => 'label.iata',
'empty_value' => "label.select.agency",
'property' => 'id',
'expanded' => false, 'multiple' => true,
'required' => true,
'translation_domain' => 'User',
'choice_translation_domain' => 'User'));
} else {
// only show iata based on user's context
$form
->add('agencies', EntityType::class, array(
'class' => 'AppBundle:Agency',
'query_builder' => function (EntityRepository $er) use ($user) {
return $er->createQueryBuilder('a')
->addOrderBy('a.id', 'ASC')
->andWhere('a.market IN (:markets)')
->setParameter('markets',$user->getMarkets());
},
'choice_label' => 'agencyName',
'label' => 'label.iata',
'empty_value' => "label.select.agency",
'property' => 'id',
'expanded' => false, 'multiple' => true,
'required' => true,
'translation_domain' => 'User',
'choice_translation_domain' => 'User'));
}
// show market only if not agency user
} else {
// only show specific markets based on user's context
$form->add('markets', 'entity', array(
'class' => 'AppBundle:Market', 'property' => 'id',
'query_builder' => function (EntityRepository $er) use ($user) {
$markets = $user->getMarkets();
return $er->createQueryBuilder('m')
->addOrderBy('m.id', 'ASC')
->andWhere('m.id IN (?1)')
->setParameter(1,$markets);
},
// 'choice_value' => 'id',
'choice_label' => 'id', 'label' => 'label.markets',
'translation_domain' => 'User',
'expanded' => false, 'multiple' => true,));
}
// only show specific roles based on user's employer
$form->add('mainRole', 'entity', array(
'class' => 'UserBundle:Role',
'query_builder' => function (EntityRepository $er) use ($employer){
$roles = $employer->getRoles();
return $er->createQueryBuilder('r')
->orderBy('r.sort', 'ASC')
->andWhere('r.id IN (?1)')
->setParameter(1,$roles);
},
'choice_label' => 'translationKey',
'choices_as_values' => true, 'label' => 'label.role',
'expanded' => true, 'multiple' => false,
'translation_domain' => 'User',
'choice_translation_domain' => 'Role',));
// only show specific airlines based on user's context
$form->add('airlines', 'entity', array(
'class' => 'AppBundle:Airline', 'property' => 'id',
'query_builder' => function (EntityRepository $er) use ($user) {
$airlines = $user->getAirlines();
return $er->createQueryBuilder('a')
->addOrderBy('a.id', 'ASC')
->andWhere('a.id IN (?1)')
->setParameter(1,$airlines);
},
'choice_value' => 'id',
'data' => $user->getAirlines(),
'choice_label' => 'id', 'label' => 'label.airlines',
'translation_domain' => 'User',
'expanded' => false, 'multiple' => true,));
// only show specific products based on user's context
$form->add('products', 'entity', array(
'class' => 'AppBundle:Product', 'property' => 'id',
'query_builder' => function (EntityRepository $er) use ($user) {
$products = $user->getProducts();
return $er->createQueryBuilder('p')
->addOrderBy('p.id', 'ASC')
->andWhere('p.id IN (?1)')
->setParameter(1,$products);
},
'choice_value' => 'id',
'data' => $user->getProducts(),
'choice_label' => 'translationKey', 'label' => 'label.products',
'translation_domain' => 'User',
'expanded' => false, 'multiple' => true,
'choice_translation_domain' => 'AppBundle',));
});
}
public function getParent()
{
return 'FOS\UserBundle\Form\Type\RegistrationFormType';
}
public function getBlockPrefix()
{
return 'userBundle_create';
}
}

Your issue is caused by these to lines:
'data' => $user->getAirlines(),
and
'data' => $user->getProducts(),
To change the new user s airlines & products collection, symfony form uses the loggedin users airlines & products collection reference.
Clone the collection when setting it as default, to remove the reference to the logged in user.
'data' => clone $user->getAirlines(),
and
'data' => clone $user->getProducts(),
Hope it helps.
Wrong assumption: Your error is in CreateType class. You use the loggedin user s properties to populate agencies, airlines and products fields of your form:
$user = $this->tokenStorage->getToken()->getUser();
...
'query_builder' => function (EntityRepository $er) use ($user) {
You should instead use the user you edit. Add in your buildForm function:
$userEdited = $builder->getData();
and then change:
'query_builder' => function (EntityRepository $er) use ($userEdited) {
in all places.
Do not forget to change also:
$user->getMarkets()
to
$userEdited->getMarkets()
in your callbacks, same for ailines & products.

Related

Symfony2 Cannot instantiate interface Doctrine\Common\Collections\Collection

Symfony version 2.8
I have a problem when I try to add new Collection(); in construct function of User Entity.
public function __construct()
{
$this->sectors = new Collection();
parent::__construct();
}
Sector has many to many relationship
/**
* #ORM\ManyToMany(targetEntity="UserBundle\Entity\Sectors", fetch="EAGER")
* #ORM\JoinTable(
* joinColumns={#ORM\JoinColumn(onDelete="CASCADE")},
* inverseJoinColumns={#ORM\JoinColumn(onDelete="CASCADE")}
* )
*/
public $sectors;
and getter/setter methods are
/**
* Add sector
*
* #param UserBundle\Entity\Sectors $sector
*
* #return User
*/
public function addSector(UserBundle\Entity\Sectors $sector)
{
$this->sectors[] = $sector;
return $this;
}
/**
* Remove sector
*
* #param UserBundle\Entity\Sectors $sector
*/
public function removeSector(UserBundle\Entity\Sectors $sector)
{
$this->sectors->removeElement($sector);
}
/**
* Get sectors
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getSectors()
{
return $this->sectors;
}
When in a FormType I do:
$builder
->add('sectors', EntityType::class, array(
'class' => 'UserBundle\Entity\Sectors',
'placeholder' => 'Select Sector ...',
'label' => 'Sector',
'required' => false,
'attr' => ['placeholder' => 'Select Sector ...', 'data-jcf' => '{"wrapNative": false, "wrapNativeOnMobile": false, "useCustomScroll": true, "multipleCompactStyle": true}'],
'multiple' => true,
'expanded' => false,
'query_builder' => function(EntityRepository $er) {
return $er->createQueryBuilder('u')
->orderBy('u.name', 'ASC');
},
));
$formModify = function (FormInterface $form, \Doctrine\Common\Collections\ArrayCollection $sector, $factory) {
$output = [];
foreach($sector as $sec) {
$output[] = $sec->id;
}
$formOption = array(
'class' => 'UserBundle\Entity\UserAccreditation',
'multiple' => true,
'auto_initialize' => false,
'required' => false,
'expanded' => true,
'choice_attr' => function ($output) {
return ['class' => 'attr_checkbox'];
},
'query_builder' => function(EntityRepository $ertt) use ($output) {
$qb = $ertt->createQueryBuilder('g');
$qb->select(array('g'));
$qb->where('g.sector IN (:sector_id)');
$qb->setParameters( array('sector_id' => $output) );
$qb->orderBy('g.name', 'ASC');
return $qb;
},
);
$form->add($factory->createNamed('accreditationdata', EntityType::class, null, $formOption));
};
$builder->addEventListener(FormEvents::PRE_SET_DATA,function (FormEvent $event) use ($formModify,$factory) {
$data = $event->getData();
$form = $event->getForm();
if ($data != null) {
//print_r(get_object_vars($data->getSectors()));
$formModify($event->getForm(), $data->getSectors(),$factory);
}
}
);
$factory = $builder->getFormFactory();
$builder->get('sectors')->addEventListener(FormEvents::POST_SUBMIT,function (FormEvent $event) use ($formModify,$factory) {
$sector = $event->getForm()->getData();
//print_r($sector);
$formModify($event->getForm()->getParent(), $sector,$factory);
}
);
I get following error:
Fatal error: Cannot instantiate interface Doctrine\Common\Collections\Collection
Earlier I am using ArrayCollection instead of Collection, I have to do this because I am getting error
Type error: Argument 2 passed to UserBundle\Form\Type\ProfileAboutMeFormType::UserBundle\Form\Type{closure}() must be an instance of Doctrine\Common\Collections\ArrayCollection, instance of Doctrine\ORM\PersistentCollection given,
and by searching on google I found this solution on github link
https://github.com/doctrine/orm/issues/5946
but still I am facing the problem. can anyone tell me What goes wrong here ?

many to many save data

I have two entity that have manytomany relation
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Esame
*
* #ORM\Table(name="esame", indexes={#ORM\Index(name="id_tipologia_esame", columns={"id_tipologia_esame"}), #ORM\Index(name="id_analisi", columns={"id_analisi"})})
* #ORM\Entity(repositoryClass="AppBundle\Repository\EsameRepository")
*/
class Esame
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var \AppBundle\Entity\Nome_esame
*
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Nome_esame")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="id_tipologia_esame", referencedColumnName="id")
* })
*/
private $idTipologiaEsame;
/**
* #var \AppBundle\Entity\Analisi
*
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Analisi")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="id_analisi", referencedColumnName="id")
* })
*/
private $idAnalisi;
/**
* #ORM\ManyToMany(targetEntity="AppBundle\Entity\TipologiaCampione", inversedBy="esami")
*/
private $campioni;
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set idAnalisi
*
* #param \AppBundle\Entity\Analisi $idAnalisi
*
* #return Esame
*/
public function setIdAnalisi($idAnalisi)
{
$this->idAnalisi = $idAnalisi;
return $this;
}
/**
* Get idAnalisi
*
* #return int
*/
public function getIdAnalisi()
{
return $this->idAnalisi;
}
/**
* Constructor
*/
public function __construct()
{
$this->campioni = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add campioni
*
* #param \AppBundle\Entity\TipologiaCampione $campioni
*
* #return Esame
*/
public function addCampioni(\AppBundle\Entity\TipologiaCampione $campioni)
{
$this->campioni[] = $campioni;
return $this;
}
/**
* Remove campioni
*
* #param \AppBundle\Entity\TipologiaCampione $campioni
*/
public function removeCampioni(\AppBundle\Entity\TipologiaCampione $campioni)
{
$this->campioni->removeElement($campioni);
}
/**
* Get campioni
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getCampioni()
{
return $this->campioni;
}
/**
* Set idTipologiaEsame
*
* #param \AppBundle\Entity\Nome_esame $idTipologiaEsame
*
* #return Esame
*/
public function setIdTipologiaEsame(\AppBundle\Entity\Nome_esame $idTipologiaEsame = null)
{
$this->idTipologiaEsame = $idTipologiaEsame;
return $this;
}
/**
* Get idTipologiaEsame
*
* #return \AppBundle\Entity\Nome_esame
*/
public function getIdTipologiaEsame()
{
return $this->idTipologiaEsame;
}
}
and Entity 2
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* TipologiaCampione
*
* #ORM\Table(name="tipologia_campione")
* #ORM\Entity(repositoryClass="AppBundle\Repository\TipologiaCampioneRepository")
*/
class TipologiaCampione
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="tipologia", type="string", length=255, nullable=true)
*/
private $tipologia;
/**
* #var string
*
* #ORM\Column(name="matricola", type="string", length=255, nullable=true)
*/
private $matricola;
/**
* #var string
*
* #ORM\ManyToMany(targetEntity="AppBundle\Entity\Esame",mappedBy="campioni")
*/
private $esami;
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set tipologia
*
* #param string $tipologia
*
* #return TipologiaCampione
*/
public function setTipologia($tipologia)
{
$this->tipologia = $tipologia;
return $this;
}
/**
* Get tipologia
*
* #return string
*/
public function getTipologia()
{
return $this->tipologia;
}
/**
* Set matricola
*
* #param string $matricola
*
* #return TipologiaCampione
*/
public function setMatricola($matricola)
{
$this->matricola = $matricola;
return $this;
}
/**
* Get matricola
*
* #return string
*/
public function getMatricola()
{
return $this->matricola;
}
/**
* Constructor
*/
public function __construct()
{
$this->esami = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add esami
*
* #param \AppBundle\Entity\Esame $esami
*
* #return TipologiaCampione
*/
public function addEsami(\AppBundle\Entity\Esame $esami)
{
$this->esami[] = $esami;
return $this;
}
/**
* Remove esami
*
* #param \AppBundle\Entity\Esame $esami
*/
public function removeEsami(\AppBundle\Entity\Esame $esami)
{
$this->esami->removeElement($esami);
}
/**
* Get esami
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getEsami()
{
return $this->esami;
}
}
now i must save data and in my controller i write this:
for($i=0;$i<$form->get('numero_campioni')->getData();$i++) {
$campione=new TipologiaCampione();
$campione->setMatricola($form['matricola_'.$i]->getData());
$campione->setTipologia($form['tipologia_'.$i]->getData());
foreach($form['esame_'.$i]->getData() as $value){
$tipo_esame = $this->getDoctrine()
->getRepository('AppBundle:nome_esame')
->find($value->getId());
$esame=new Esame();
$esame->setIdAnalisi($analisi);
$esame->setIdTipologiaEsame($tipo_esame);
$em->persist($esame);
$em->flush();
$campione->addEsami($esame); -> this don't work
}
$em->persist($campione);
$em->flush();
}
I expect that $campione->addEsami($esame); creates a new record in my table esame_tipologia_campione for each $campione but it doesn't work ..
My form Type:
<?php
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Validator\Constraints\DateTime;
use AppBundle\Entity\anagrafica;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use AppBundle\Form\anagraficaType;
use Symfony\Component\Form\Extension\Core\Type\CurrencyType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\NumberType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use AppBundle\Form\EsameType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\ButtonType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
class AnalisiType extends AbstractType {
/**
* {#inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options) {
$province = array(
'AG' => 'Agrigento',
'AL' => 'Alessandria',
'AN' => 'Ancona',
);
$builder->add('ruminanti', ChoiceType::class, array(
'label' => false,
'mapped' => false,
'placeholder' => 'Tipologia di modulo',
'choices' => array('Ruminanti' => 'Ruminanti', 'Suini' => 'Suini'),
'required' => true,
'data' => ($options['data']->getTipoModulo() != NULL ? $options['data']->getTipoModulo() : ''),
'attr' => array(
'placeholder' => 'Provincia',
)))
->add('idLaboratorio', EntityType::class, array(
'label' => false,
'placeholder' => 'Laboratorio a cui inviare i dati',
'class' => 'AppBundle:Laboratorio',
'choice_label' => 'nome',
// 'data'=>5
))
// Dati proprietario
->add('privato', ChoiceType::class, array(
'label' => false,
'choices' => array('Privato' => 'Privato', 'Azienda' => 'Azienda'),
'data' => 'Privato',
'expanded' => true,
'multiple' => false,
'mapped' => false,
))
->add('Nome_proprietario', TextType::class, array(
'label' => false,
'mapped' => false,
'data' => ($options['data']->getIdProprietario() != NULL ? $options['data']->getIdProprietario()->getNome() : ''),
'attr' => array(
'placeholder' => 'Nome',
'novalidate' => 'novalidate'
)))
->add('Cognome_proprietario', TextType::class, array(
'label' => false,
'mapped' => false,
'data' => ($options['data']->getIdProprietario() != NULL ? $options['data']->getIdProprietario()->getCognome() : ''),
'attr' => array(
'placeholder' => 'Cognome',
'novalidate' => 'novalidate'
)))
->add('Ragione_sociale_proprietario', TextType::class, array(
'label' => false,
'mapped' => false,
'required' => false,
'data' => ($options['data']->getIdProprietario() != NULL ? $options['data']->getIdProprietario()->getRagioneSociale() : ''),
'attr' => array(
'placeholder' => 'Ragione Sociale',
'novalidate' => 'novalidate'
)))
->add('Via_proprietario', TextType::class, array(
'label' => false,
'mapped' => false,
'data' => ($options['data']->getIdProprietario() != NULL ? $options['data']->getIdProprietario()->getvia() : ''),
'attr' => array(
'placeholder' => 'Via'
)))
->add('Comune_proprietario', TextType::class, array(
'label' => false,
'mapped' => false,
'data' => ($options['data']->getIdProprietario() != NULL ? $options['data']->getIdProprietario()->getComune() : ''),
'attr' => array(
'placeholder' => 'Comune'
)))
->add('Provincia_proprietario', ChoiceType::class, array(
'label' => false,
'mapped' => false,
'data' => ($options['data']->getIdProprietario() != NULL ? $options['data']->getIdProprietario()->getProvincia() : ''),
'choices' => $province,
'placeholder' => 'Provincia'
))
->add('Telefono_proprietario', TextType::class, array(
'label' => false,
'mapped' => false,
'data' => ($options['data']->getIdProprietario() != NULL ? $options['data']->getIdProprietario()->gettel() : NULL),
'attr' => array(
'placeholder' => 'Telefono'
)))
->add('email_proprietario', EmailType::class, array(
'label' => false,
'mapped' => false,
'data' => ($options['data']->getIdProprietario() != NULL ? $options['data']->getIdProprietario()->getemail() : ''),
'attr' => array(
'placeholder' => 'E-mail'
)
))
->add('Cod_allev_proprietario', TextType::class, array(
'label' => false,
'mapped' => false,
'data' => ($options['data']->getIdProprietario() != NULL ? $options['data']->getIdProprietario()->getCodiceAllievo() : ''),
'attr' => array(
'placeholder' => 'Codice Allevamento'
)))
// Dati Veterinario
->add('Nome_veterinario', TextType::class, array(
'label' => false,
'mapped' => false,
'data' => ($options['data']->getIdVeterinario() != NULL ? $options['data']->getIdProprietario()->getNome() : ''),
'attr' => array(
'placeholder' => 'Nome'
)))
->add('Cognome_veterinario', TextType::class, array(
'label' => false,
'mapped' => false,
'data' => ($options['data']->getIdVeterinario() != NULL ? $options['data']->getIdProprietario()->getCognome() : ''),
'attr' => array(
'placeholder' => 'Cognome'
)))
->add('Via_veterinario', TextType::class, array(
'label' => false,
'mapped' => false,
'data' => ($options['data']->getIdVeterinario() != NULL ? $options['data']->getIdVeterinario()->getvia() : ''),
'attr' => array(
'placeholder' => 'Via'
)))
->add('Comune_veterinario', TextType::class, array(
'label' => false,
'mapped' => false,
'data' => ($options['data']->getIdVeterinario() != NULL ? $options['data']->getIdVeterinario()->getComune() : ''),
'attr' => array(
'placeholder' => 'Comune'
)))
->add('Provincia_veterinario', ChoiceType::class, array(
'label' => false,
'mapped' => false,
'data' => ($options['data']->getIdVeterinario() != NULL ? $options['data']->getIdVeterinario()->getProvincia() : ''),
'choices' => $province,
'attr' => array(
'placeholder' => 'Provincia'
)))
->add('Telefono_veterinario', TextType::class, array(
'label' => false,
'mapped' => false,
'data' => ($options['data']->getIdVeterinario() != NULL ? $options['data']->getIdVeterinario()->getTel() : NULL),
'attr' => array(
'placeholder' => 'Telefono'
)))
->add('email_veterinario', EmailType::class, array(
'label' => false,
'mapped' => false,
'data' => ($options['data']->getIdVeterinario() != NULL ? $options['data']->getIdVeterinario()->getEmail() : ''),
'attr' => array(
'placeholder' => 'E-mail'
)
))
->add('trattamenti', TextareaType::class, array(
'label' => false,
'attr' => array(
'placeholder' => 'Trattamenti(inserire ANAMNESI; SINTOMATOLOGIA; TRATTAMENTI)'
)
))
->add('vacinazione', TextareaType::class, array(
'label' => false,
'attr' => array(
'placeholder' => 'Vacinazioni(obbligatorio)'
)
))
->add('numero_campioni', NumberType::class, array(
'label' => false,
'attr' => array(
'placeholder' => 'Numero Totale di campioni'
)
));
//->add('save', SubmitType::class, array('label' => 'Create Task'));
$builder->add('idTipologiaEsame', EntityType::class, array(
'label' => false,
'mapped' => false,
'class' => 'AppBundle:Nome_esame',
'choice_label' => 'nome',
'group_by' => 'idCategoriaEsame.tipo',
))
->add('Aggiungi', ButtonType::class, array(
'attr' => array(
'class' => 'btn-primary col-md-2 conferma_esame'),
))
->add('Rimuovi', ButtonType::class, array(
'attr' => array(
'class' => 'btn-primary col-md-2 conferma_esame'),
));
// for($i=0;$i<$options['data']->getNumeroCampioni();$i++){
for ($i = 0; $i < 60; $i++) {
$builder->add('checkbox_' . $i, CheckboxType::class, array(
'label' => false,
'required' => false,
'mapped' => false,
'attr' => array(
'class' => 'check_box_table',
// 'class'=>'col-md-1 col-xs-3 allineare_sinistra',
)
))
->add('matricola_' . $i, TextType::class, array(
'label' => false,
'mapped' => false,
'required' => false,
'attr' => array(
'placeholder' => 'Matricola (FACOLTATIVA)',
// 'class'=>'col-md-2 col-xs-9 allineare_sinistra',
)))
->add('tipologia_' . $i, TextType::class, array(
'label' => false,
'mapped' => false,
'required' => false,
'attr' => array(
'placeholder' => 'Tipologia (FACOLTATIVA)',
// 'class'=>'col-md-2 col-md-offset-0 col-xs-9 col-xs-offset-3 allineare_sinistra',
)))
->add('esame_' . $i, EntityType::class, array(
'label' => false,
'mapped' => false,
'class' => 'AppBundle:Nome_esame',
'required'=>true,
'multiple'=>true,
'choice_label' => 'nome',
// 'disabled' => 'disabled',
'attr' => array(
'placeholder' => 'Esami',
'class' => 'max_width esame_row select_esame',
// 'class'=>'col-md-12 col-md-offset-0 col-xs-9 col-xs-offset-3 ',
)
))
->add('Stampa', ButtonType::class, array(
'disabled' => 'disabled',
'attr' => array(
'class' => 'btn-primary text-center',
)
))
->add('saveAndAdd', SubmitType::class, array('label' => 'Save and Add'))
;
}
}
/**
* {#inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver) {
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Analisi'
));
}
/**
* {#inheritdoc}
*/
public function getBlockPrefix() {
return 'appbundle_analisi';
}
}
$esame entity and $campione entity are correctly saved.
Can anybody say to me what I'm doing wrong??
You need to create a Join Table
After that you need to choose which entity is the owner of the association (just after the manytomany chapter in the doc).
For exampre, if you may want to add "campioni" via the "esami" entity you should code a setter like this:
public function addCampioni(\AppBundle\Entity\TipologiaCampione($campioni) {
$campioni->addEsami($this);
$this->campioni[] = $campioni;
return $this;
}
Ciao!

Controller - No access in class - Entity

I got this error message, but I don't really understand why.
Neither the property "categories" nor one of the methods "addCategory()"/"removeCategory()", "setCategories()", "categories()", "__set()" or "__call()" exist and have public access in class "Checkout\Bundle\ItemBundle\Entity\Item".
The thing is, in my entity "Item" I really have all of this stuff:
/**
* #ORM\ManyToMany(targetEntity="Checkout\Bundle\ItemBundle\Entity\Category", mappedBy="items")
**/
private $categories;
and
/**
* Add categories
*
* #param Category $categories
* #return Item
*/
public function addCategory(Category $categories)
{
$this->categories[] = $categories;
return $this;
}
/**
* Remove categories
*
* #param Category $categories
*/
public function removeCategory(Category $categories)
{
$this->categories->removeElement($categories);
}
/**
* Get categories
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getCategories()
{
return $this->categories;
}
Okay, okay - and what is in my Controller?
/**
* Creates a new Item entity.
*
* #Route("/create", name="item_create")
* #param Request $request
* #return \Symfony\Component\HttpFoundation\Response
*/
public function createAction(Request $request)
{
$entity = new Item();
$currentUser = $this->getUser();
$form = $this->createFormBuilder($entity)
->add('name', null, array(
'label' => 'Item Name',
'required' => true,
))
->add('categories', 'entity', array(
'label' => 'Select a Category',
'required' => false,
'class' => 'CheckoutItemBundle:Category',
'property' => 'name',
'query_builder' => function (EntityRepository $er) use ($currentUser) {
return $er->createQueryBuilder('c')
->where('c.user = :user')
->setParameter('user', $currentUser);
},
))
->add('submit', 'submit', array('label' => 'Speichern'))
->getForm();
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush();
}
return $this->render(
'CheckoutItemBundle:Item:create.html.twig',
array(
'entity' => 'entity',
'form' => $form->createView()
)
);
}
So, the big question is, why he say that he didn't find it, when it is obviously there. Any idea? Thank you in advance!
->add('categories', 'entity', array(
'label' => 'Select a Category',
'required' => false,
'class' => 'CheckoutItemBundle:Category',
'property' => 'name',
'multiple' => true,
'query_builder' => function (EntityRepository $er) use ($currentUser) {
return $er->createQueryBuilder('c')
->where('c.user = :user')
->setParameter('user', $currentUser);
},
))
You have a Many-To-Many relation, but your form expects a Many-To-One. To fix this behavior need to set multiple to true.

Symfony2 form queryBuilder find distinct object

I have an Organization entity.
Acme\BaseBundle\Entity\Organization:
type: entity
...
oneToMany:
childOrganizations:
targetEntity: Organization
mappedBy: parentOrganization
manyToOne:
parentOrganization:
targetEntity: Organization
inversedBy: childOrganizations
nullable: true
I have this form:
->add('parentOrganization', 'entity', array(
'class' => "AcmeBaseBundle:Organization",
'property' => 'name',
'required' => false,
'query_builder' => function(EntityRepository $er)
{
return $er
->createQueryBuilder('o')
->select('o')
->add('groupBy', 'o.name');
},
))
Then I would like to show only different organizations. I mean if I have first, second and third organization. Then I have a form for the first organization and I would like to have just two choices in parentOrganization entity field (second and third), but in this case I have three choices (first can be parent of first).
Is there some way to leave out possibility to connect with own org?
EDIT: The problem is that I am working in form class and I don't know how to handle Organization object here. This is my code:
class OrganizationType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name', null, array('max_length' => 100))
->add('type')
->add('parentOrganization', 'entity', array(
'class' => "AcmeBaseBundle:Organization",
'property' => 'name',
'required' => false,
'query_builder' => function(EntityRepository $er)
{
return $er->createQueryBuilder('o')
->select('o')
->add('groupBy', 'o.name');
}
))
->add('addresses', 'bootstrap_collection', array(
'type' => new AddressType(),
'allow_add' => true,
'allow_delete' => true,
'add_button_text' => '+',
'delete_button_text' => '-',
'by_reference' => false,
'sub_widget_col' => 9,
'button_col' => 3
))
}
/**
* #param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Acme\BaseBundle\Entity\Organization'
));
}
public function getName()
{
return 'acme_basebundle_organization';
}
}
If you create form as written in doc (through method createForm of controller), then your current entity available in $options['data']. And your code will look like:
$entity = $options['data'];
...
'query_builder' => function(EntityRepository $er) use ($entity)
{
return $er->createQueryBuilder('o')
->select('o')
->add('groupBy', 'o.name')
->add('where', 'o.id != ?1')
->setParameter(1, $entity->getId());
}

Showing name and saving id in symfony dropdown

I want to show the 'name' of my departments as a dropdown to my users and when they choose one, save its 'id' into the database. How can i do that? Below is my code. Currentlt its showing id and saving id.
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name')
->add('adress')
->add('city')
->add('area')
->add('departments', 'entity', array(
'empty_value' => '',
'class' => 'YdyaHospitalBundle:Department',
'query_builder' => function($repository) { return $repository->createQueryBuilder('t')->orderBy('t.id', 'ASC'); },
'property' => 'id',
'multiple' =>false,
'expanded' =>true,
))
;
}
Update
My controller action:
/**
* Creates a new Hospitals entity.
*
* #Route("/", name="hospitals_create")
* #Method("POST")
* #Template("YdyaHospitalBundle:Hospitals:new.html.twig")
*/
public function createAction(Request $request)
{
$entity = new Hospitals();
$form = $this->createForm(new HospitalsType(), $entity);
$form->bind($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('hospitals_show', array('id' => $entity->getId())));
}
return array(
'entity' => $entity,
'form' => $form->createView(),
);
}
/**
* Displays a form to create a new Hospitals entity.
*
* #Route("/new", name="hospitals_new")
* #Method("GET")
* #Template()
*/
public function newAction()
{
$entity = new Hospitals();
$form = $this->createForm(new HospitalsType(), $entity);
return array(
'entity' => $entity,
'form' => $form->createView(),
);
}
You can either implement a __toString() for your entity, or specify the property to display with:
->add('departments', 'entity', array(
'empty_value' => '',
'class' => 'YdyaHospitalBundle:Department',
'query_builder' => function($repository) { return $repository->createQueryBuilder('t')->orderBy('t.id', 'ASC'); },
// 'property' => 'id', --> Remove this
'multiple' => false,
'expanded' => true,
'property' => 'name' // Property used to display the entity
))
In your Controller you'll still be able to save your entity or the id of your entity to the db.
See documentation: http://symfony.com/doc/current/reference/forms/types/entity.html#property

Resources