Symfony2.7 FOSUser save user and user info into different tables - php

Ok, so I am trying to save User to users table in my database and User info like name, surname to user_info table, using FosUserBundle what I have now is OneToOne bidirectional relation between these tables, form which save User and User info correctly but user_id in user_info table is always null I am trying to do this since 4 hours and now I have no idea what to do.
Edit:
I've managed it myself, didn't need bidirectional relation, will mark changes in files
Entity Users
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use FOS\UserBundle\Entity\User as BaseUser;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Users
* #ORM\Entity(repositoryClass="AppBundle\Entity\UsersRepository")
* #ORM\Table()
* #ORM\Entity
*/
class Users extends BaseUser
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
//don't need mappedBy option and that is whole relation statement
/**
* #ORM\OneToOne(targetEntity="UserInfo", //mappedBy="user", cascade={"persist","remove"})
*/
private $profil;
public function __construct(){
parent::__construct();
}
/**
* Set profil
*
* #param \AppBundle\Entity\UserInfo $profil
*
* #return Users
*/
public function setProfil(\AppBundle\Entity\UserInfo $profil = null)
{
$this->profil = $profil;
return $this;
}
/**
* Get profil
*
* #return \AppBundle\Entity\UserInfo
*/
public function getProfil()
{
return $this->profil;
}
}
UserInfo entity
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* UserInfo
*
* #ORM\Table()
* #ORM\Entity
*/
class UserInfo
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="user_name", type="string", length=255)
*/
private $userName;
/**
* #var string
* #ORM\Column(name="user_surname", type="string", length=255)
*/
private $userSurname;
/**
* #var integer
* #ORM\Column(name="blood_donated")
*/
private $bloodDonated;
/**
* Get id
*
* #return integer
*/
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set userName
*
* #param string $userName
*
* #return UserInfo
*/
public function setUserName($userName)
{
$this->userName = $userName;
return $this;
}
/**
* Get userName
*
* #return string
*/
public function getUserName()
{
return $this->userName;
}
/**
* Set userSurname
*
* #param string $userSurname
*
* #return UserInfo
*/
public function setUserSurname($userSurname)
{
$this->userSurname = $userSurname;
return $this;
}
/**
* Get userSurname
*
* #return string
*/
public function getUserSurname()
{
return $this->userSurname;
}
/**
* Set bloodDonated
*
* #param string $bloodDonated
*
* #return UserInfo
*/
public function setBloodDonated($bloodDonated)
{
$this->bloodDonated = $bloodDonated;
return $this;
}
/**
* Get bloodDonated
*
* #return string
*/
public function getBloodDonated()
{
return $this->bloodDonated;
}
}
And forms:
RegistrationFormType:
namespace UsersBundle\Form\Type;
use Symfony\Component\Form\FormBuilderInterface;
use FOS\UserBundle\Form\Type\RegistrationFormType as BaseType;
use AppBundle\Form\UserInfoType as UserInfoType;
class RegistrationFormType extends BaseType{
public function buildForm(FormBuilderInterface $builder, array $options){
parent::buildForm($builder, $options);
//adding profil hidden field to set profil in table, here whole magic happens at $builder -> add('profil','hidden')
$builder ->add('profil','hidden')
->add('profil', new UserInfoType(), array('data_class' => 'AppBundle\Entity\UserInfo'))
;
}
public function getName()
{
return 'my_user_registration';
}
}
and UserInfoType:
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class UserInfoType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('userName')
->add('userSurname')
;
}
/**
* #param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\UserInfo'
));
}
/**
* #return string
*/
public function getName()
{
return 'appbundle_userinfo';
}
}
Edit So I needed 2 changes actually add profil input to form and fix my relation between tables, hope it will help someone

Related

Symfony 3 multiple entities in one form

I stuck with this for past two days. I am creating bus traveling website. Currently I am in phase of adding new bus to database.
One bus (or all of them) have many amenities (like AirCon, WiFi, Kitchen, ...) and each of these needs to have custom prices. Let says that our bus have AirCon. AirCon for this bus will cost 50 USD but for other bus AirCon might cost 100 USD. To do that I created 3 Entities (Bus Vehicles Entity, Amenities Entity and Bus Vehicles Amenities Entity). Inside Amenities Entity I iwll store Id of bus, ID of amenity and price for that amenity for that bus ID.
Problem is that I can't get it work. I got blank HTML element when rendering form for that field.I can't add or delete multiple amenities and I am not sure why it is not working.
Does someone knows where is the problem?
Here is the code that I use:
Amenities Entity:
<?php
namespace AppBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* Amenities
*
* #ORM\Table(name="amenities", indexes={#ORM\Index(name="administrator_id", columns={"administrator_id"})})
* #ORM\Entity
*/
class Amenities
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=100, nullable=true)
*/
private $name;
/**
* #var \DateTime
*
* #ORM\Column(name="created_at", type="datetime", nullable=false)
*/
private $createdAt = 'CURRENT_TIMESTAMP';
/**
* #var \DateTime
*
* #ORM\Column(name="modified_at", type="datetime", nullable=false)
*/
private $modifiedAt = 'CURRENT_TIMESTAMP';
/**
* #var \AppBundle\Entity\Users
*
* #ORM\ManyToOne(targetEntity="Users")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="administrator_id", referencedColumnName="id")
* })
*/
private $administrator;
/**
* #ORM\OneToMany(targetEntity="BusVehiclesAmenities", mappedBy="amenities")
*/
private $amenities;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
*
* #return Amenities
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set createdAt
*
* #param \DateTime $createdAt
*
* #return Amenities
*/
public function setCreatedAt($createdAt)
{
$this->createdAt = $createdAt;
return $this;
}
/**
* Get createdAt
*
* #return \DateTime
*/
public function getCreatedAt()
{
return $this->createdAt;
}
/**
* Constructor
*/
public function __construct()
{
$this->amenities = new ArrayCollection();
}
/**
* Add amenities
*
* #param \AppBundle\Entity\BusVehiclesAmenities $amenities
* #return Amenities
*/
public function addAmenities(BusVehiclesAmenities $amenities)
{
$this->amenities[] = $amenities;
return $this;
}
/**
* Remove amenities
*
* #param \AppBundle\Entity\BusVehiclesAmenities $amenities
*/
public function removeAmenities(BusVehiclesAmenities $amenities)
{
$this->amenities->removeElement($amenities);
}
/**
* Get amenities_bus_vehicles
*
* #return ArrayCollection
*/
public function getAmenities()
{
return $this->amenities;
}
}
Bus Vehicles Entity:
namespace AppBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* BusVehicles
*
* #ORM\Table(name="bus_vehicles", indexes={#ORM\Index(name="company_id", columns={"company_id"}), #ORM\Index(name="bus_type", columns={"bus_type"}), #ORM\Index(name="fuel_type", columns={"fuel_type"}), #ORM\Index(name="emission_class", columns={"emission_class"})})
* #ORM\Entity
*/
class BusVehicles
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="licence_plate", type="string", length=100, nullable=false)
*/
private $licencePlate;
/**
* #var \AppBundle\Entity\Companies
*
* #ORM\ManyToOne(targetEntity="Companies")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="company_id", referencedColumnName="id")
* })
*/
private $company;
/**
* #var \AppBundle\Entity\BusTypes
*
* #ORM\ManyToOne(targetEntity="BusTypes", inversedBy="busType")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="bus_type", referencedColumnName="id")
* })
*/
/**
* #ORM\OneToMany(targetEntity="BusVehiclesAmenities", mappedBy="bus")
*/
private $busVehiclesAmenities;
public function __construct()
{
$this->busVehiclesAmenities = new ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Add busVehiclesAmenities
*
* #param \AppBundle\Entity\BusVehiclesAmenities busVehiclesAmenities
* #return BusVehicles
*/
public function addBusVehiclesAmenities(BusVehiclesAmenities $busVehiclesAmenities)
{
$this->busVehiclesAmenities[] = $busVehiclesAmenities;
return $this;
}
/**
* Remove busVehiclesAmenities
*
* #param \AppBundle\Entity\BusVehiclesAmenities $busVehiclesAmenities
*/
public function removeBusVehiclesAmenities(BusVehiclesAmenities $busVehiclesAmenities)
{
$this->busVehiclesAmenities->removeElement($busVehiclesAmenities);
}
/**
* Get busVehiclesAmenities
*
* #return ArrayCollection
*/
public function getBusVehiclesAmenities()
{
return $this->busVehiclesAmenities;
}
/**
* Set licencePlate
*
* #param string $licencePlate
*
* #return BusVehicles
*/
public function setLicencePlate($licencePlate)
{
$this->licencePlate = $licencePlate;
return $this;
}
/**
* Set company
*
* #param \AppBundle\Entity\Companies $company
*
* #return BusVehicles
*/
public function setCompany(Companies $company = null)
{
$this->company = $company;
return $this;
}
/**
* Get company
*
* #return \AppBundle\Entity\Companies
*/
public function getCompany()
{
return $this->company;
}
}
Bus Amenities Entity:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* BusVehiclesAmenities
*
* #ORM\Table(name="bus_vehicles_amenities", indexes={#ORM\Index(name="amenities_id", columns={"amenities_id"}), #ORM\Index(name="bus_id", columns={"bus_id"})})
* #ORM\Entity
*/
class BusVehiclesAmenities
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
*
* #ORM\ManyToOne(targetEntity="BusVehicles", inversedBy="busVehiclesAmenities")
* #ORM\JoinColumn(name="bus_id", referencedColumnName="id")
*
*/
private $bus;
/**
*
* #ORM\ManyToOne(targetEntity="Amenities", inversedBy="amenities")
* #ORM\JoinColumn(name="amenities_id", referencedColumnName="id")
*
*/
private $amenities;
/**
* #var float
* #ORM\Column(name="price", type="float", scale=2)
*/
protected $price;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set Bus
*
* #param \AppBundle\Entity\BusVehicles
*
* #return BusVehiclesAmenities
*/
public function setBus($bus)
{
$this->bus = $bus;
return $this;
}
/**
* Get busId
*
* #return integer
*/
public function getBus()
{
return $this->bus;
}
/**
* Set amenities
*
* #param \AppBundle\Entity\Amenities
*
* #return BusVehiclesAmenities
*/
public function setAmenities($amenities)
{
$this->amenities = $amenities;
return $this;
}
/**
* Get amenities
*
* #return \AppBundle\Entity\Amenities
*/
public function getAmenities()
{
return $this->amenities;
}
/**
* Set price
*
* #param float $price
*
* #return BusVehiclesAmenities
*/
public function sePrice($price)
{
$this->price = $price;
return $this;
}
/**
* Get price
*
* #return float
*/
public function getPrice()
{
return $this->price;
}
}
FORMS:
Add new bus form:
<?php
namespace AdminBundle\Form\Type;
use AdminBundle\Form\Type\BusVehiclesAmenitiesType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
class BusVehiclesType extends AbstractType
{
/**
* {#inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('licencePlate')
->add('company', EntityType::class, array(
'class' => 'AppBundle:Companies',
'choice_label' => 'name',
->add('busVehiclesAmenities', CollectionType::class, array(
'entry_type' => BusVehiclesAmenitiesType::class,
'allow_add' => true,
));
}
/**
* {#inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\BusVehicles'
));
}
/**
* {#inheritdoc}
*/
public function getBlockPrefix()
{
return 'adminbundle_busvehicles';
}
}
Bus Vehicles Amenities Form
<?php
namespace AdminBundle\Form\Type;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\MoneyType;
use Symfony\Component\Form\FormBuilderInterface;
use AppBundle\Entity\BusVehiclesAmenities;
use Symfony\Component\OptionsResolver\OptionsResolver;
class BusVehiclesAmenitiesType extends AbstractType
{
/**
* {#inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('price', MoneyType::class, array(
'scale' => 2,
))
->add('amenities', EntityType::class, array(
'class' =>'AppBundle:Amenities',
'choice_label' => 'name',
))
;
}
/**
* {#inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => BusVehiclesAmenities::class
));
}
/**
* {#inheritdoc}
*/
public function getBlockPrefix()
{
return 'appbundle_busvehiclesamenities';
}
}
I would not use the entity classes for form binding.
I would create a new class, (e.g. BusVehicle) which contains all properties that need to be on the form (particular fields) and use that as the 'data_class'. This way you would not only solve your problem, but you would also decouple presentation layer from business layer (see Multitier Architecture).
I usually put these classes in Form/Model directory.
In your case the class would be Form/Model/BusVehicle, and it would have $amenities property.
The amenities would be an array of Form/Model/Amenity objects.
You would probably need to use embedded forms just don't use entity classes as 'data_object'. After a successful bind, you instantiate and populate entities for persist or update.
And you don't need the third entity ("Bus Vehicles Amenities").

Symfony Form with Doctrine Entity - Relation not loading for editing

I'm having an issue with something I think is probably fairly basic but the cause is escaping me.
I have a two entities, an Organisation and a Subscription. An organisation is linked with one subscription.
I want to be able to edit this via a form (creating via form already works). When I do the following:
$organisation = $this->getDoctrine()->getRepository('AppBundle\Entity\Organisation')
->findOneBy(array(
'id' => $id
));
$form = $this->createForm(new OrganisationType(), $organisation, array(
'method' => 'POST'
));
$form->submit($paramFetcher->all());
I get an exception because the subscription property of the organisation entity is not set (despite passing one which has a subscription into the form defaults). The exception is as follows:
Expected argument of type "AppBundle\Entity\Subscription", "NULL" given
This is obviously being thrown by the setSubscription method on the Organisation entity but I'm not sure why as the form should be converting the int value passed to a Subscription entity automatically.
Am I doing something stupid here? I have attached the relevant code below. Thank you!
The simplest controller action that replicates this issue
public function testAction(Request $request)
{
$organisation = $this->getDoctrine()->getRepository('AppBundle\Entity\Organisation')
->findOneBy(array('id' => 7));
$form = $this->createForm(new OrganisationType(), $organisation);
$form->submit($request->request->all());
return $this->render('test.html.twig', array(
'testform' => $form->createView()
));
}
Organisation.php
<?php
namespace AppBundle\Entity;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation as JMS;
use Gedmo\Mapping\Annotation as Gedmo;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Organisation
*
* #ORM\Table(name="organisation")
* #ORM\Entity(repositoryClass="AppBundle\Repository\OrganisationRepository")
*/
class Organisation
{
const ENABLED = 1;
const DISABLED = 2;
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #JMS\Groups({"default", "list-organisation"})
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255)
* #JMS\Groups({"default", "list-organisation"})
*/
private $name;
/**
* #var Subscription|null The subscription this organisation is currently linked to
* #ORM\ManyToOne(targetEntity="Subscription", inversedBy="organisations")
* #ORM\JoinColumn(name="subscription_id", referencedColumnName="id", onDelete="set null")
* #JMS\Groups({"default", "list-organisation"})
*/
private $subscription;
/**
* #var Collection
* #ORM\OneToMany(targetEntity="User", mappedBy="organisation")
* #JMS\Groups({})
*/
private $users;
/**
* #var Collection
* #ORM\OneToMany(targetEntity="Subgroup", mappedBy="organisation")
* #JMS\Groups({"default"})
*/
private $subgroups;
/**
* #var string $enabled
*
* #ORM\Column(type="string")
*/
private $enabled = self::ENABLED;
/**
* #var datetime $created
*
* #Gedmo\Timestampable(on="create")
* #ORM\Column(type="datetime")
* #JMS\Groups({"default", "list-organisation"})
*/
private $created;
/**
* #var datetime $updated
*
* #Gedmo\Timestampable(on="update")
* #ORM\Column(type="datetime")
* #JMS\Groups({"default", "list-organisation"})
*/
private $updated;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
* #return Organisation
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Sets subscription
*
* #param Subscription $subscription
* #return $this
*/
public function setSubscription(Subscription $subscription)
{
$this->subscription = $subscription;
return $this;
}
/**
* Gets subscription
*
* #return Subscription|null
*/
public function getSubscription()
{
return $this->subscription;
}
/**
* Sets enabled
*
* #param $enabled
*/
public function setEnabled($enabled)
{
if (!in_array($enabled, array(self::ENABLED, self::DISABLED))) {
throw new \InvalidArgumentException('Invalid enabled status');
}
$this->enabled = $enabled;
}
/**
* Gets enabled
*
* #return string
*/
public function getEnabled()
{
return $this->enabled;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Returns Users belonging to this organisation
*
* #return Collection
*/
public function getUsers()
{
return $this->users;
}
public function __toString()
{
return $this->getName();
}
}
Subscription.php
<?php
namespace AppBundle\Entity;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation as JMS;
use Gedmo\Mapping\Annotation as Gedmo;
/**
* Organisation
*
* #ORM\Table(name="subscription")
* #ORM\Entity(repositoryClass="AppBundle\Repository\SubscriptionRepository")
*/
class Subscription
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #JMS\Groups({"default", "list-organisation"})
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255)
* #JMS\Groups({"default", "list-organisation"})
*/
private $name;
/**
* #var Collection
* #ORM\OneToMany(targetEntity="Organisation", mappedBy="subscription")
* #JMS\Groups({"default"})
*/
private $organisations;
/**
* #var datetime $created
*
* #Gedmo\Timestampable(on="create")
* #ORM\Column(type="datetime")
* #JMS\Groups({"default"})
*/
private $created;
/**
* #var datetime $updated
*
* #Gedmo\Timestampable(on="update")
* #ORM\Column(type="datetime")
* #JMS\Groups({"default"})
*/
private $updated;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
* #return Subscription
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Returns Organisations with this subscription type
*
* #return Collection
*/
public function getOrganisations()
{
return $this->organisations;
}
/**
* #return string
*/
public function __toString()
{
return $this->getName();
}
}
OrganisationType.php
<?php
namespace AppBundle\Form;
use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class OrganisationType extends AbstractType
{
private $manager;
public function __construct(ObjectManager $objectManager)
{
$this->manager = $objectManager;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('name');
$builder->add('subscription', EntityType::class, array(
'class' => 'AppBundle\Entity\Subscription'
));
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Organisation',
'csrf_protection' => false
));
}
}
On a fresh Symfony 3.1, this works like a charm (and this is the recommended way to handle form submission, as stated in a previous comment) :
public function testAction(Request $request)
{
$organisation = $this->getDoctrine()->getRepository('AppBundle\Entity\Organisation')
->find(1);
$form = $this->createForm(OrganisationType::class, $organisation);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$this->getDoctrine()->getManager()->persist($organisation);
$this->getDoctrine()->getManager()->flush();
die('saved into database.');
}
return $this->render('test.html.twig', array(
'testform' => $form->createView()
));
}

Symfony one to many with checkbox list in form view

I have two Entities
Employee and FreeDay
One employee can have one or more free days. The free days are defined as day of the week so Monday => 1, Tuesday => 2 etc..
In the Employee Form View I would like to show the FreeDay entity as checkbox list like this:
Days Form View
But I got this error:
Warning: spl_object_hash() expects parameter 1 to be object, integer given
I'm really confused and I don't know how to get out of this issue.
The entity code is the following:
Employee Entity:
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Employee
*
* #Gedmo\SoftDeleteable(fieldName="deletedAt")
*/
class Employee
{
/**
* #ORM\OneToMany(targetEntity="FreeDay", mappedBy="employee", cascade={"persist","remove"},orphanRemoval=true)
*/
private $freedays;
/**
* Constructor
*/
public function __construct()
{
$this->freedays = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add freedays
*
* #param \AppBundle\Entity\Free $freeday
*
* #return Employee
*/
public function addFreeDay(\AppBundle\Entity\FreeDay $freeday)
{
$this->freedays[] = $freeday;
return $this;
}
/**
* Remove freeday
*
* #param \AppBundle\Entity\FreeDay $freeday
*/
public function removeFreeDay(\AppBundle\Entity\FreeDay $freeday)
{
$this->freedays->removeElement($freeday);
}
/**
* Get freeday
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getFreeDays()
{
return $this->freedays;
}
}
Free Day Entity:
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use Symfony\Component\Validator\Constraints as Assert;
class FreeDay
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var int
* #ORM\ManyToOne(targetEntity="Employee", inversedBy="freedays")
* #ORM\JoinColumn(name="employee_id", referencedColumnName="id", onDelete="CASCADE")
*/
private $employee;
/**
* #var int
*
* #ORM\Column(name="day", type="integer")
*/
private $day;
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set day
*
* #param integer $day
*
* #return FreeDay
*/
public function setDay($day)
{
$this->day = $day;
return $this;
}
/**
* Get day
*
* #return int
*/
public function getDay()
{
return $this->day;
}
/**
* Set employee
*
* #param \AppBundle\Entity\Employee $employee
*
* #return FreeDay
*/
public function setEmployee(\AppBundle\Entity\Employee $employee = null)
{
$this->employee = $employee;
return $this;
}
/**
* Get employee
*
* #return \AppBundle\Entity\Employee
*/
public function getEmployee()
{
return $this->employee;
}
EmployeeType.php
class EmployeeType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('freedays', EntityType::class, array(
'class'=>'AppBundle:FreeDay',
'choices'=>$this->getDays(),
'expanded'=>true,
'multiple'=>true
))
->add('save', SubmitType::class, array('label' => 'Salva'))
;
}
private function getDays() {
return array(
'Monday'=>1,
'Tuesday'=>2,
'Wednesday'=>3,
'Thursday'=>4,
'Friday'=>5,
'Saturday'=>6,
);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Employee',
));
}
}
Using the entity option in your form builder requires the options to be objects of that entity, see here in the symfony documentation: http://symfony.com/doc/current/reference/forms/types/entity.html#using-choices
as you're passing an array to it you will always come across this error.
to achieve what you outline in your question you will need to have the freedays in your database with the relevant id and name like you list in your getDays function, so Monday will have an id in your database of 1.
if you just want all the options see this section of the documentation: http://symfony.com/doc/current/reference/forms/types/entity.html#basic-usage
however if you want filter the results you will need a query builder, described here in the documentation: http://symfony.com/doc/current/reference/forms/types/entity.html#using-a-custom-query-for-the-entities
Please let me know if this doesn't work for you or I've misunderstood the question.

Symfony Catchable Fatal Error: Object of class AppBundle\Entity\Email could not be converted to string

i'm new in symfony, i created a small DB schema attached:
Email Class:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Email
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="AppBundle\Entity\EmailRepository")
*/
class Email extends Service
{
/**
* #var string
*
* #ORM\Column(name="emailAddress", type="string", length=255)
*/
private $emailAddress;
/**
* Set emailAddress
*
* #param string $emailAddress
*
* #return Email
*/
public function setEmailAddress($emailAddress)
{
$this->emailAddress = $emailAddress;
return $this;
}
/**
* Get emailAddress
*
* #return string
*/
public function getEmailAddress()
{
return $this->emailAddress;
}
}
and my service class:
<?php
namespace AppBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* Service
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="AppBundle\Entity\ServiceRepository")
* #ORM\InheritanceType("JOINED")
* #ORM\DiscriminatorColumn(name="type", type="string")
* #ORM\DiscriminatorMap({"newsletter" = "Newsletter", "email" = "Email", "service" = "Service"})
*
*/
class Service
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="serviceTitle", type="string", length=255)
*/
private $serviceTitle;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set serviceTitle
*
* #param string $serviceTitle
*
* #return Service
*/
public function setServiceTitle($serviceTitle)
{
$this->serviceTitle = $serviceTitle;
return $this;
}
/**
* Get serviceTitle
*
* #return string
*/
public function getServiceTitle()
{
return $this->serviceTitle;
}
/**
* #ORM\ManyToOne(targetEntity="Service", inversedBy="children")
*/
private $parent;
/**
* #ORM\OneToMany(targetEntity="Service", mappedBy="parent")
*/
private $children;
/**
* Constructor
*/
public function __construct()
{
$this->children = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Set parent
*
* #param \AppBundle\Entity\Service $parent
*
* #return Service
*/
public function setParent(\AppBundle\Entity\Service $parent = null)
{
$this->parent = $parent;
return $this;
}
/**
* Get parent
*
* #return \AppBundle\Entity\Service
*/
public function getParent()
{
return $this->parent;
}
/**
* Add child
*
* #param \AppBundle\Entity\Service $child
*
* #return Service
*/
public function addChild(\AppBundle\Entity\Service $child)
{
$this->children[] = $child;
return $this;
}
/**
* Remove child
*
* #param \AppBundle\Entity\Service $child
*/
public function removeChild(\AppBundle\Entity\Service $child)
{
$this->children->removeElement($child);
}
/**
* Get children
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getChildren()
{
return $this->children;
}
}
then i generate crud for email, it was working perfect, now i actually want to add two fields for service (SERVICE TITLE, and PARENT SERVICE)
what i did, i just opened email type form and added two fields for (service title and Parent service):
<?php
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class EmailType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('emailAddress')
->add('serviceTitle')
->add('parent')
;
}
after saving, when i create new email service browser return exception:
Catchable Fatal Error: Object of class AppBundle\Entity\Email could not be converted to string
right now i just add parent ID in text box (input type text) but actually i want to use (choice lise) from which user can set a parent service at the time of creating new service, and that choice list having all previously created services
add a __toString() method to your email class:
public function __toString()
{
return $this->emailAddress;
}

How to get the value of a form field through the form class in symfony2?

I would like to know how to get the value of a form field through the form class in symfony2. The explanation is as below:
This is the code of the entity class:
<?php
namespace Ikproj\HomeBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* User
*
* #ORM\Table(name="user")
* #ORM\Entity(repositoryClass="Ikproj\HomeBundle\Entity\UserRepository")
*/
class User
{
/**
* #var integer
*
* #ORM\Column(name="id_user", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* #var string
*
* #ORM\Column(name="username", type="string", length=255)
*/
private $email;
/**
* #var string
*
* #ORM\Column(name="pseudo", type="string", length=255)
*/
private $pseudo;
/**
* #var string
*
* #ORM\Column(name="password", type="string", length=255)
*/
private $passWD;
/**
* #var string
*
* #ORM\Column(name="sexeuser", type="string", length=255)
*/
private $sexeuser;
/**
* #var \DateTime
*
* #ORM\Column(name="dateanniv", type="date")
*/
private $dateanniv;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
* #return User
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set email
*
* #param string $email
* #return User
*/
public function setEmail($email)
{
$this->email = $email;
return $this;
}
/**
* Get email
*
* #return string
*/
public function getEmail()
{
return $this->email;
}
/**
* Set pseudo
*
* #param string $pseudo
* #return User
*/
public function setPseudo($pseudo)
{
$this->pseudo = $pseudo;
return $this;
}
/**
* Get pseudo
*
* #return string
*/
public function getPseudo()
{
return $this->pseudo;
}
/**
* Set passWD
*
* #param string $passWD
* #return User
*/
public function setPassWD($passWD)
{
$this->passWD = $passWD;
return $this;
}
/**
* Get passWD
*
* #return string
*/
public function getPassWD()
{
return $this->passWD;
}
/**
* Set sexeuser
*
* #param string $sexeuser
* #return User
*/
public function setSexeuser($sexeuser)
{
$this->sexeuser = $sexeuser;
return $this;
}
/**
* Get sexeuser
*
* #return string
*/
public function getSexeuser()
{
return $this->sexeuser;
}
/**
* Set dateanniv
*
* #param \DateTime $dateanniv
* #return User
*/
public function setDateanniv($dateanniv)
{
$this->dateanniv = $dateanniv;
return $this;
}
/**
* Get dateanniv
*
* #return \DateTime
*/
public function getDateanniv()
{
return $this->dateanniv;
}
}
And this is the code of the form class (the form builder):
<?php
namespace Ikproj\HomeBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class UserprofilechangeType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('sexeuser', 'text');
$def = $builder->add('sexeuser', 'text');
}
/**
* #param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Ikproj\HomeBundle\Entity\User'
));
}
/**
* #return string
*/
public function getName()
{
return 'ikproj_homebundle_user';
}
}
Actually, what I would like to know is how to put the value of the field "sexeuser" inside the variable $def. In other words, how shall I change this line $def = $builder->add('sexeuser', 'text'); in order to get the value of the field sexeuser?
You need dynamically modify Form using Form Events:
In this case, everything happens before loading data into the form (PRE_SET_DATA)
// src/Acme/DemoBundle/Form/Type/FriendMessageFormType.php
namespace Acme\DemoBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Security\Core\SecurityContext;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class FriendMessageFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('subject', 'text')
->add('body', 'textarea');
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function (FormEvent $event) {
$data = $event->getData();
var_dump($data);die;
}
);
}
public function getName()
{
return 'acme_friend_message';
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
}
}
http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html

Categories